Fix LCDC for DMG on CGB

This commit is contained in:
TiKevin83 2020-02-16 21:45:04 -05:00 committed by Travis
parent 23c1c74030
commit 0a6a221653
13 changed files with 62 additions and 63 deletions

View File

@ -73,8 +73,8 @@ public:
mem_.setLinkCallback(callback); mem_.setLinkCallback(callback);
} }
LoadRes load(char const *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) { LoadRes load(char const *romfiledata, unsigned romfilelength, unsigned flags) {
return mem_.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat); return mem_.loadROM(romfiledata, romfilelength, flags);
} }
bool loaded() const { return mem_.loaded(); } bool loaded() const { return mem_.loaded(); }
@ -94,7 +94,6 @@ public:
void setRtcDivisorOffset(long const rtcDivisorOffset) { mem_.setRtcDivisorOffset(rtcDivisorOffset); } void setRtcDivisorOffset(long const rtcDivisorOffset) { mem_.setRtcDivisorOffset(rtcDivisorOffset); }
void setBios(char const *buffer, std::size_t size) { mem_.setBios(buffer, size); } void setBios(char const *buffer, std::size_t size) { mem_.setBios(buffer, size); }
bool gbIsCgb() { return mem_.gbIsCgb(); }
unsigned char externalRead(unsigned short addr) {return mem_.peek(addr); } unsigned char externalRead(unsigned short addr) {return mem_.peek(addr); }

View File

@ -88,7 +88,7 @@ void GB::reset() {
SaveState state; SaveState state;
p_->cpu.setStatePtrs(state); p_->cpu.setStatePtrs(state);
setInitState(state, !(p_->loadflags & FORCE_DMG), p_->loadflags & GBA_CGB); setInitState(state, !(p_->loadflags & FORCE_DMG));
p_->cpu.loadState(state); p_->cpu.loadState(state);
if (length > 0) if (length > 0)
{ {
@ -139,13 +139,13 @@ void GB::setRtcDivisorOffset(long const rtcDivisorOffset) {
} }
LoadRes GB::load(char const *romfiledata, unsigned romfilelength, unsigned const flags) { LoadRes GB::load(char const *romfiledata, unsigned romfilelength, unsigned const flags) {
LoadRes const loadres = p_->cpu.load(romfiledata, romfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT); LoadRes const loadres = p_->cpu.load(romfiledata, romfilelength, flags);
if (loadres == LOADRES_OK) { if (loadres == LOADRES_OK) {
SaveState state; SaveState state;
p_->cpu.setStatePtrs(state); p_->cpu.setStatePtrs(state);
p_->loadflags = flags; p_->loadflags = flags;
setInitState(state, !(flags & FORCE_DMG), flags & GBA_CGB); setInitState(state, !(flags & FORCE_DMG));
p_->cpu.loadState(state); p_->cpu.loadState(state);
} }

View File

@ -1147,7 +1147,7 @@ static void setInitialDmgIoamhram(unsigned char ioamhram[]) {
} // anon namespace } // anon namespace
void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode) { void gambatte::setInitState(SaveState &state, const bool cgb) {
static unsigned char const cgbObjpDump[0x40] = { static unsigned char const cgbObjpDump[0x40] = {
0x00, 0x00, 0xF2, 0xAB, 0x00, 0x00, 0xF2, 0xAB,
0x61, 0xC2, 0xD9, 0xBA, 0x61, 0xC2, 0xD9, 0xBA,
@ -1182,8 +1182,6 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
state.cpu.prefetched = false; state.cpu.prefetched = false;
state.cpu.skip = false; state.cpu.skip = false;
state.mem.biosMode = true; state.mem.biosMode = true;
state.mem.cgbSwitching = false;
state.mem.agbMode = gbaCgbMode;
std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.size()); std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.size());
@ -1222,7 +1220,6 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
state.mem.enableRam = false; state.mem.enableRam = false;
state.mem.rambankMode = false; state.mem.rambankMode = false;
state.mem.hdmaTransfer = false; state.mem.hdmaTransfer = false;
state.mem.gbIsCgb = cgb;
state.mem.stopped = false; state.mem.stopped = false;
@ -1269,7 +1266,7 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
state.ppu.nextM0Irq = 0; state.ppu.nextM0Irq = 0;
state.ppu.oldWy = state.mem.ioamhram.get()[0x14A]; state.ppu.oldWy = state.mem.ioamhram.get()[0x14A];
state.ppu.pendingLcdstatIrq = false; state.ppu.pendingLcdstatIrq = false;
state.ppu.isCgb = cgb; state.ppu.notCgbDmg = true;
// spu.cycleCounter >> 12 & 7 represents the frame sequencer position. // spu.cycleCounter >> 12 & 7 represents the frame sequencer position.
state.spu.cycleCounter = state.cpu.cycleCounter >> 1; state.spu.cycleCounter = state.cpu.cycleCounter >> 1;

View File

@ -23,7 +23,7 @@
namespace gambatte { namespace gambatte {
void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode); void setInitState(struct SaveState &state, bool cgb);
} }
#endif #endif

View File

@ -43,7 +43,7 @@ void Time::loadState(SaveState const &state) {
lastTime_.tv_sec = state.time.lastTimeSec; lastTime_.tv_sec = state.time.lastTimeSec;
lastTime_.tv_usec = state.time.lastTimeUsec; lastTime_.tv_usec = state.time.lastTimeUsec;
lastCycles_ = state.time.lastCycles; lastCycles_ = state.time.lastCycles;
ds_ = state.ppu.isCgb & state.mem.ioamhram.get()[0x14D] >> 7; ds_ = state.mem.ioamhram.get()[0x14D] >> 7;
} }
std::uint32_t Time::get(unsigned long const cc) { std::uint32_t Time::get(unsigned long const cc) {

View File

@ -17,6 +17,7 @@
// //
#include "memory.h" #include "memory.h"
#include "gambatte.h"
#include "savestate.h" #include "savestate.h"
#include "sound.h" #include "sound.h"
#include "video.h" #include "video.h"
@ -80,9 +81,6 @@ void Memory::setStatePtrs(SaveState &state) {
void Memory::loadState(SaveState const &state) { void Memory::loadState(SaveState const &state) {
biosMode_ = state.mem.biosMode; biosMode_ = state.mem.biosMode;
cgbSwitching_ = state.mem.cgbSwitching;
agbMode_ = state.mem.agbMode;
gbIsCgb_ = state.mem.gbIsCgb;
stopped_ = state.mem.stopped; stopped_ = state.mem.stopped;
psg_.loadState(state); psg_.loadState(state);
lcd_.loadState(state, state.mem.oamDmaPos < oam_size ? cart_.rdisabledRam() : ioamhram_); lcd_.loadState(state, state.mem.oamDmaPos < oam_size ? cart_.rdisabledRam() : ioamhram_);
@ -1014,17 +1012,17 @@ void Memory::nontrivial_ff_write(unsigned const p, unsigned data, unsigned long
oamDmaInitSetup(); oamDmaInitSetup();
return; return;
case 0x47: case 0x47:
if (!isCgb()) if (!isCgb() || isCgbDmg())
lcd_.dmgBgPaletteChange(data, cc); lcd_.dmgBgPaletteChange(data, cc);
break; break;
case 0x48: case 0x48:
if (!isCgb()) if (!isCgb() || isCgbDmg())
lcd_.dmgSpPalette1Change(data, cc); lcd_.dmgSpPalette1Change(data, cc);
break; break;
case 0x49: case 0x49:
if (!isCgb()) if (!isCgb() || isCgbDmg())
lcd_.dmgSpPalette2Change(data, cc); lcd_.dmgSpPalette2Change(data, cc);
break; break;
@ -1033,25 +1031,34 @@ void Memory::nontrivial_ff_write(unsigned const p, unsigned data, unsigned long
break; break;
case 0x4B: case 0x4B:
lcd_.wxChange(data, cc); lcd_.wxChange(data, cc);
break;
case 0x4C:
if (!biosMode_)
return;
break; break;
case 0x4D: case 0x4D:
if (isCgb()) if (isCgb() && !isCgbDmg())
ioamhram_[0x14D] = (ioamhram_[0x14D] & ~1u) | (data & 1); ioamhram_[0x14D] = (ioamhram_[0x14D] & ~1u) | (data & 1);
return; return;
case 0x4F: case 0x4F:
if (isCgb()) { if (isCgb() && !isCgbDmg()) {
cart_.setVrambank(data & 1); cart_.setVrambank(data & 1);
ioamhram_[0x14F] = 0xFE | data; ioamhram_[0x14F] = 0xFE | data;
} }
return; return;
case 0x50: case 0x50:
biosMode_ = false; if (!biosMode_)
if(cgbSwitching_) { return;
if (isCgb() && (ioamhram_[0x14C] & 0x04)) {
lcd_.copyCgbPalettesToDmg(); lcd_.copyCgbPalettesToDmg();
lcd_.setCgb(false); lcd_.setCgbDmg(true);
} }
biosMode_ = false;
return; return;
case 0x51: case 0x51:
dmaSource_ = data << 8 | (dmaSource_ & 0xFF); dmaSource_ = data << 8 | (dmaSource_ & 0xFF);
@ -1120,14 +1127,12 @@ void Memory::nontrivial_ff_write(unsigned const p, unsigned data, unsigned long
return; return;
case 0x6C: case 0x6C:
if (isCgb()) { if (isCgb())
ioamhram_[0x16C] = data | 0xFE; ioamhram_[0x16C] = data | 0xFE;
cgbSwitching_ = true;
}
return; return;
case 0x70: case 0x70:
if (isCgb()) { if (isCgb() && !isCgbDmg()) {
cart_.setWrambank(data & 0x07 ? data & 0x07 : 1); cart_.setWrambank(data & 0x07 ? data & 0x07 : 1);
ioamhram_[0x170] = data | 0xF8; ioamhram_[0x170] = data | 0xF8;
} }
@ -1211,13 +1216,18 @@ void Memory::nontrivial_write(unsigned const p, unsigned const data, unsigned lo
ioamhram_[p - mm_oam_begin] = data; ioamhram_[p - mm_oam_begin] = data;
} }
LoadRes Memory::loadROM(char const *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) { LoadRes Memory::loadROM(char const *romfiledata, unsigned romfilelength, unsigned const flags) {
bool const forceDmg = flags & GB::LoadFlag::FORCE_DMG;
bool const multicartCompat = flags & GB::LoadFlag::MULTICART_COMPAT;
if (LoadRes const fail = cart_.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat)) if (LoadRes const fail = cart_.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat))
return fail; return fail;
psg_.init(cart_.isCgb()); psg_.init(cart_.isCgb());
lcd_.reset(ioamhram_, cart_.vramdata(), cart_.isCgb()); lcd_.reset(ioamhram_, cart_.vramdata(), cart_.isCgb());
agbMode_ = flags & GB::LoadFlag::GBA_CGB;
return LOADRES_OK; return LOADRES_OK;
} }
@ -1300,9 +1310,6 @@ SYNCFUNC(Memory)
NSS(serialCnt_); NSS(serialCnt_);
NSS(blanklcd_); NSS(blanklcd_);
NSS(biosMode_); NSS(biosMode_);
NSS(cgbSwitching_);
NSS(agbMode_);
NSS(gbIsCgb_);
NSS(stopped_); NSS(stopped_);
NSS(LINKCABLE_); NSS(LINKCABLE_);
NSS(linkClockTrigger_); NSS(linkClockTrigger_);

View File

@ -55,12 +55,12 @@ public:
memcpy(bios_, buffer, size); memcpy(bios_, buffer, size);
biosSize_ = size; biosSize_ = size;
} }
bool gbIsCgb() { return gbIsCgb_; }
bool getMemoryArea(int which, unsigned char **data, int *length); bool getMemoryArea(int which, unsigned char **data, int *length);
unsigned long stop(unsigned long cycleCounter, bool& skip); unsigned long stop(unsigned long cycleCounter, bool& skip);
bool isCgb() const { return lcd_.isCgb(); } bool isCgb() const { return lcd_.isCgb(); }
bool isCgbDmg() const { return lcd_.isCgbDmg(); }
bool ime() const { return intreq_.ime(); } bool ime() const { return intreq_.ime(); }
bool halted() const { return intreq_.halted(); } bool halted() const { return intreq_.halted(); }
unsigned long nextEventTime() const { return intreq_.minEventTime(); } unsigned long nextEventTime() const { return intreq_.minEventTime(); }
@ -226,7 +226,7 @@ public:
unsigned long event(unsigned long cycleCounter); unsigned long event(unsigned long cycleCounter);
unsigned long resetCounters(unsigned long cycleCounter); unsigned long resetCounters(unsigned long cycleCounter);
LoadRes loadROM(char const *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat); LoadRes loadROM(char const *romfiledata, unsigned romfilelength, unsigned flags);
void setInputGetter(unsigned (*getInput)()) { void setInputGetter(unsigned (*getInput)()) {
getInput_ = getInput; getInput_ = getInput;
@ -299,9 +299,7 @@ private:
unsigned char serialCnt_; unsigned char serialCnt_;
bool blanklcd_; bool blanklcd_;
bool biosMode_; bool biosMode_;
bool cgbSwitching_;
bool agbMode_; bool agbMode_;
bool gbIsCgb_;
unsigned long basetime_; unsigned long basetime_;
bool stopped_; bool stopped_;
enum HdmaState { hdma_low, hdma_high, hdma_requested } haltHdmaState_; enum HdmaState { hdma_low, hdma_high, hdma_requested } haltHdmaState_;

View File

@ -36,7 +36,7 @@ struct SaveState {
void set(T *p, std::size_t size) { ptr = p; size_ = size; } void set(T *p, std::size_t size) { ptr = p; size_ = size; }
friend class SaverList; friend class SaverList;
friend void setInitState(SaveState &, bool, bool); friend void setInitState(SaveState &, bool);
private: private:
T *ptr; T *ptr;
std::size_t size_; std::size_t size_;
@ -83,9 +83,6 @@ struct SaveState {
unsigned char /*bool*/ rambankMode; unsigned char /*bool*/ rambankMode;
unsigned char /*bool*/ hdmaTransfer; unsigned char /*bool*/ hdmaTransfer;
unsigned char /*bool*/ biosMode; unsigned char /*bool*/ biosMode;
unsigned char /*bool*/ cgbSwitching;
unsigned char /*bool*/ agbMode;
unsigned char /*bool*/ gbIsCgb;
unsigned char /*bool*/ stopped; unsigned char /*bool*/ stopped;
} mem; } mem;
@ -122,7 +119,7 @@ struct SaveState {
unsigned char wscx; unsigned char wscx;
unsigned char /*bool*/ weMaster; unsigned char /*bool*/ weMaster;
unsigned char /*bool*/ pendingLcdstatIrq; unsigned char /*bool*/ pendingLcdstatIrq;
unsigned char /*bool*/ isCgb; unsigned char /*bool*/ notCgbDmg;
} ppu; } ppu;
struct SPU { struct SPU {

View File

@ -96,6 +96,7 @@ inline void Channel4::Lfsr::event() {
void Channel4::Lfsr::nr3Change(unsigned newNr3, unsigned long cc) { void Channel4::Lfsr::nr3Change(unsigned newNr3, unsigned long cc) {
updateBackupCounter(cc); updateBackupCounter(cc);
nr3_ = newNr3; nr3_ = newNr3;
counter_ = cc;
} }
void Channel4::Lfsr::nr4Init(unsigned long cc) { void Channel4::Lfsr::nr4Init(unsigned long cc) {

View File

@ -24,8 +24,8 @@
using namespace gambatte; using namespace gambatte;
unsigned long LCD::gbcToRgb32(const unsigned bgr15) { unsigned long LCD::gbcToRgb32(const unsigned bgr15) {
unsigned long const r = bgr15 & 0x1F; unsigned long const r = bgr15 & 0x1F;
unsigned long const g = bgr15 >> 5 & 0x1F; unsigned long const g = bgr15 >> 5 & 0x1F;
unsigned long const b = bgr15 >> 10 & 0x1F; unsigned long const b = bgr15 >> 10 & 0x1F;
return cgbColorsRgb32_[bgr15 & 0x7FFF]; return cgbColorsRgb32_[bgr15 & 0x7FFF];
@ -69,18 +69,13 @@ namespace {
&& cc >= m0TimeOfCurrentLy; && cc >= m0TimeOfCurrentLy;
} }
void doCgbColorChange(unsigned char* pdata,
unsigned long* palette, unsigned index, unsigned data, bool trueColor) {
pdata[index] = data;
index /= 2;
palette[index] = gbcToRgb32(pdata[index * 2] | pdata[index * 2 + 1] * 0x100l);
}
} // unnamed namespace. } // unnamed namespace.
void LCD::setDmgPalette(unsigned long palette[], const unsigned long dmgColors[], unsigned data) { void LCD::setDmgPalette(unsigned long palette[], const unsigned long dmgColors[], unsigned data) {
for (int i = 0; i < num_palette_entries; ++i, data /= num_palette_entries) palette[0] = dmgColors[data & 3];
palette[i] = gbcToRgb32(dmgColors[data % num_palette_entries]); palette[1] = dmgColors[data >> 2 & 3];
palette[2] = dmgColors[data >> 4 & 3];
palette[3] = dmgColors[data >> 6 & 3];
} }
void LCD::setCgbPalette(unsigned *lut) { void LCD::setCgbPalette(unsigned *lut) {
@ -114,10 +109,6 @@ void LCD::reset(unsigned char const *oamram, unsigned char const *vram, bool cgb
refreshPalettes(); refreshPalettes();
} }
void LCD::setCgb(bool cgb) {
ppu_.setCgb(cgb);
}
void LCD::setStatePtrs(SaveState &state) { void LCD::setStatePtrs(SaveState &state) {
state.ppu.bgpData.set( bgpData_, sizeof bgpData_); state.ppu.bgpData.set( bgpData_, sizeof bgpData_);
state.ppu.objpData.set(objpData_, sizeof objpData_); state.ppu.objpData.set(objpData_, sizeof objpData_);
@ -162,7 +153,7 @@ void LCD::loadState(SaveState const &state, unsigned char const *const oamram) {
} }
void LCD::refreshPalettes() { void LCD::refreshPalettes() {
if (ppu_.cgb()) { if (isCgb() && !isCgbDmg()) {
for (int i = 0; i < max_num_palettes * num_palette_entries; ++i) { for (int i = 0; i < max_num_palettes * num_palette_entries; ++i) {
ppu_.bgPalette()[i] = gbcToRgb32(bgpData_[2 * i] | bgpData_[2 * i + 1] * 0x100l); ppu_.bgPalette()[i] = gbcToRgb32(bgpData_[2 * i] | bgpData_[2 * i + 1] * 0x100l);
ppu_.spPalette()[i] = gbcToRgb32(objpData_[2 * i] | objpData_[2 * i + 1] * 0x100l); ppu_.spPalette()[i] = gbcToRgb32(objpData_[2 * i] | objpData_[2 * i + 1] * 0x100l);
@ -186,7 +177,7 @@ void LCD::copyCgbPalettesToDmg() {
namespace { namespace {
template<typename T> template<typename T>
static void clear(T *buf, unsigned long color, std::ptrdiff_t dpitch) { void clear(T *buf, unsigned long color, std::ptrdiff_t dpitch) {
unsigned lines = 144; unsigned lines = 144;
while (lines--) { while (lines--) {
@ -856,6 +847,4 @@ SYNCFUNC(LCD)
SSS(lycIrq_); SSS(lycIrq_);
SSS(nextM0Time_); SSS(nextM0Time_);
NSS(statReg_); NSS(statReg_);
NSS(m2IrqStatReg_);
NSS(m1IrqStatReg_);
} }

View File

@ -50,13 +50,13 @@ public:
LCD(unsigned char const *oamram, unsigned char const *vram, LCD(unsigned char const *oamram, unsigned char const *vram,
VideoInterruptRequester memEventRequester); VideoInterruptRequester memEventRequester);
void reset(unsigned char const *oamram, unsigned char const *vram, bool cgb); void reset(unsigned char const *oamram, unsigned char const *vram, bool cgb);
void setCgbDmg(bool enabled) { ppu_.setCgbDmg(enabled); }
void setStatePtrs(SaveState &state); void setStatePtrs(SaveState &state);
void loadState(SaveState const &state, unsigned char const *oamram); void loadState(SaveState const &state, unsigned char const *oamram);
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32); void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
void setCgbPalette(unsigned *lut); void setCgbPalette(unsigned *lut);
void setVideoBuffer(uint_least32_t *videoBuf, std::ptrdiff_t pitch); void setVideoBuffer(uint_least32_t *videoBuf, std::ptrdiff_t pitch);
void setLayers(unsigned mask) { ppu_.setLayers(mask); } void setLayers(unsigned mask) { ppu_.setLayers(mask); }
void setCgb(bool cgb);
void copyCgbPalettesToDmg(); void copyCgbPalettesToDmg();
int debugGetLY() const { return ppu_.lyCounter().ly(); } int debugGetLY() const { return ppu_.lyCounter().ly(); }
@ -147,6 +147,7 @@ public:
bool hdmaIsEnabled() const { return eventTimes_(memevent_hdma) != disabled_time; } bool hdmaIsEnabled() const { return eventTimes_(memevent_hdma) != disabled_time; }
void update(unsigned long cycleCounter); void update(unsigned long cycleCounter);
bool isCgb() const { return ppu_.cgb(); } bool isCgb() const { return ppu_.cgb(); }
bool isCgbDmg() const { return ppu_.cgbDmg(); }
bool isDoubleSpeed() const { return ppu_.lyCounter().isDoubleSpeed(); } bool isDoubleSpeed() const { return ppu_.lyCounter().isDoubleSpeed(); }
unsigned long *bgPalette() { return ppu_.bgPalette(); } unsigned long *bgPalette() { return ppu_.bgPalette(); }

View File

@ -140,6 +140,13 @@ inline void nextCall(int const cycles, PPUState const &state, PPUPriv &p) {
p.nextCallPtr = &state; p.nextCallPtr = &state;
} }
inline unsigned long const* cgbSpPalette(PPUPriv const& p, unsigned const attrib) {
if (!p.cgbDmg)
return p.spPalette + (attrib & attr_cgbpalno) * num_palette_entries;
else
return p.spPalette + (attrib & attr_dmgpalno ? num_palette_entries : 0);
}
namespace M2_Ly0 { namespace M2_Ly0 {
void f0(PPUPriv& p) { void f0(PPUPriv& p) {
p.weMaster = lcdcWinEn(p) && 0 == p.wy; p.weMaster = lcdcWinEn(p) && 0 == p.wy;
@ -444,6 +451,7 @@ namespace M3Loop {
+ expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[1]] * 2; + expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[1]] * 2;
} while (dst != dstend); } while (dst != dstend);
p.ntileword = ntileword; p.ntileword = ntileword;
continue; continue;
} }
@ -455,6 +463,7 @@ namespace M3Loop {
p.cycles = cycles; p.cycles = cycles;
} }
uint_least32_t* const dst = dbufline + (xpos - tile_len); uint_least32_t* const dst = dbufline + (xpos - tile_len);
unsigned const tileword = -(p.lcdc & 1u * lcdc_bgen) & p.ntileword; unsigned const tileword = -(p.lcdc & 1u * lcdc_bgen) & p.ntileword;
@ -541,6 +550,7 @@ namespace M3Loop {
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len); } while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
} }
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len]; unsigned const tno = tileMapLine[tileMapXpos % tile_map_len];
int const ts = tile_size; int const ts = tile_size;
tileMapXpos = tileMapXpos % tile_map_len + 1; tileMapXpos = tileMapXpos % tile_map_len + 1;
@ -766,6 +776,7 @@ namespace M3Loop {
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len); } while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
} }
{ {
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len]; unsigned const tno = tileMapLine[tileMapXpos % tile_map_len];
unsigned const nattrib = tileMapLine[tileMapXpos % tile_map_len + vram_bank_size]; unsigned const nattrib = tileMapLine[tileMapXpos % tile_map_len + vram_bank_size];
@ -786,7 +797,6 @@ namespace M3Loop {
p.xpos = xpos; p.xpos = xpos;
} }
void doFullTilesUnrolled(PPUPriv& p) { void doFullTilesUnrolled(PPUPriv& p) {
int xpos = p.xpos; int xpos = p.xpos;
int const xend = p.wx < p.xpos || p.wx >= xpos_end int const xend = p.wx < p.xpos || p.wx >= xpos_end
@ -1768,6 +1778,7 @@ void PPU::loadState(SaveState const& ss, unsigned char const* const oamram) {
void PPU::reset(unsigned char const *oamram, unsigned char const *vram, bool cgb) { void PPU::reset(unsigned char const *oamram, unsigned char const *vram, bool cgb) {
p_.vram = vram; p_.vram = vram;
p_.cgb = cgb; p_.cgb = cgb;
p_.cgbDmg = false;
p_.spriteMapper.reset(oamram, cgb); p_.spriteMapper.reset(oamram, cgb);
} }

View File

@ -150,7 +150,6 @@ public:
unsigned long * spPalette() { return p_.spPalette; } unsigned long * spPalette() { return p_.spPalette; }
void update(unsigned long cc); void update(unsigned long cc);
void setLayers(unsigned mask) { p_.layersMask = mask; } void setLayers(unsigned mask) { p_.layersMask = mask; }
void setCgb(bool cgb) { p_.cgb = cgb; }
private: private:
PPUPriv p_; PPUPriv p_;