video: formatting
This commit is contained in:
parent
6bda071d5f
commit
3d3de54485
File diff suppressed because it is too large
Load Diff
|
@ -45,134 +45,56 @@ private:
|
|||
};
|
||||
|
||||
class LCD {
|
||||
enum Event { MEM_EVENT, LY_COUNT }; enum { NUM_EVENTS = LY_COUNT + 1 };
|
||||
enum MemEvent { ONESHOT_LCDSTATIRQ, ONESHOT_UPDATEWY2, MODE1_IRQ, LYC_IRQ, SPRITE_MAP,
|
||||
HDMA_REQ, MODE2_IRQ, MODE0_IRQ }; enum { NUM_MEM_EVENTS = MODE0_IRQ + 1 };
|
||||
|
||||
class EventTimes {
|
||||
MinKeeper<NUM_EVENTS> eventMin_;
|
||||
MinKeeper<NUM_MEM_EVENTS> memEventMin_;
|
||||
VideoInterruptRequester memEventRequester_;
|
||||
|
||||
void setMemEvent() {
|
||||
const unsigned long nmet = nextMemEventTime();
|
||||
eventMin_.setValue<MEM_EVENT>(nmet);
|
||||
memEventRequester_.setNextEventTime(nmet);
|
||||
}
|
||||
|
||||
public:
|
||||
explicit EventTimes(const VideoInterruptRequester memEventRequester) : memEventRequester_(memEventRequester) {}
|
||||
|
||||
Event nextEvent() const { return static_cast<Event>(eventMin_.min()); }
|
||||
unsigned long nextEventTime() const { return eventMin_.minValue(); }
|
||||
unsigned long operator()(const Event e) const { return eventMin_.value(e); }
|
||||
template<Event e> void set(const unsigned long time) { eventMin_.setValue<e>(time); }
|
||||
void set(const Event e, const unsigned long time) { eventMin_.setValue(e, time); }
|
||||
|
||||
MemEvent nextMemEvent() const { return static_cast<MemEvent>(memEventMin_.min()); }
|
||||
unsigned long nextMemEventTime() const { return memEventMin_.minValue(); }
|
||||
unsigned long operator()(const MemEvent e) const { return memEventMin_.value(e); }
|
||||
template<MemEvent e> void setm(const unsigned long time) { memEventMin_.setValue<e>(time); setMemEvent(); }
|
||||
void set(const MemEvent e, const unsigned long time) { memEventMin_.setValue(e, time); setMemEvent(); }
|
||||
|
||||
void flagIrq(const unsigned bit) { memEventRequester_.flagIrq(bit); }
|
||||
void flagHdmaReq() { memEventRequester_.flagHdmaReq(); }
|
||||
|
||||
template<bool isReader>
|
||||
void SyncState(NewState *ns)
|
||||
{
|
||||
SSS(eventMin_);
|
||||
SSS(memEventMin_);
|
||||
//SSS(memEventRequester_); // not needed
|
||||
}
|
||||
};
|
||||
|
||||
PPU ppu;
|
||||
unsigned long dmgColorsRgb32[3 * 4];
|
||||
unsigned long cgbColorsRgb32[32768];
|
||||
unsigned char bgpData[8 * 8];
|
||||
unsigned char objpData[8 * 8];
|
||||
|
||||
EventTimes eventTimes_;
|
||||
M0Irq m0Irq_;
|
||||
LycIrq lycIrq;
|
||||
NextM0Time nextM0Time_;
|
||||
|
||||
unsigned char statReg;
|
||||
unsigned char m2IrqStatReg_;
|
||||
unsigned char m1IrqStatReg_;
|
||||
|
||||
static void setDmgPalette(unsigned long palette[], const unsigned long dmgColors[], unsigned data);
|
||||
void setDmgPaletteColor(unsigned index, unsigned long rgb32);
|
||||
|
||||
unsigned long gbcToRgb32(const unsigned bgr15);
|
||||
void doCgbColorChange(unsigned char *const pdata, unsigned long *const palette, unsigned index, const unsigned data);
|
||||
|
||||
void refreshPalettes();
|
||||
void setDBuffer();
|
||||
|
||||
void doMode2IrqEvent();
|
||||
void event();
|
||||
|
||||
unsigned long m0TimeOfCurrentLine(unsigned long cc);
|
||||
bool cgbpAccessible(unsigned long cycleCounter);
|
||||
|
||||
void mode3CyclesChange();
|
||||
void doCgbBgColorChange(unsigned index, unsigned data, unsigned long cycleCounter);
|
||||
void doCgbSpColorChange(unsigned index, unsigned data, unsigned long cycleCounter);
|
||||
|
||||
void (*scanlinecallback)();
|
||||
int scanlinecallbacksl;
|
||||
|
||||
public:
|
||||
LCD(const unsigned char *oamram, const unsigned char *vram_in, VideoInterruptRequester memEventRequester);
|
||||
void reset(const unsigned char *oamram, const unsigned char *vram, bool cgb);
|
||||
LCD(unsigned char const *oamram, unsigned char const *vram,
|
||||
VideoInterruptRequester memEventRequester);
|
||||
void reset(unsigned char const *oamram, unsigned char const *vram, bool cgb);
|
||||
void setStatePtrs(SaveState &state);
|
||||
void loadState(const SaveState &state, const unsigned char *oamram);
|
||||
void loadState(SaveState const &state, unsigned char const *oamram);
|
||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
|
||||
void setCgbPalette(unsigned *lut);
|
||||
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 blackScreen();
|
||||
|
||||
int debugGetLY() const { return ppu.lyCounter().ly(); }
|
||||
int debugGetLY() const { return ppu_.lyCounter().ly(); }
|
||||
|
||||
void dmgBgPaletteChange(const unsigned data, const unsigned long cycleCounter) {
|
||||
void dmgBgPaletteChange(unsigned data, unsigned long cycleCounter) {
|
||||
update(cycleCounter);
|
||||
bgpData[0] = data;
|
||||
setDmgPalette(ppu.bgPalette(), dmgColorsRgb32, data);
|
||||
bgpData_[0] = data;
|
||||
setDmgPalette(ppu_.bgPalette(), dmgColorsRgb32_, data);
|
||||
}
|
||||
|
||||
void dmgSpPalette1Change(const unsigned data, const unsigned long cycleCounter) {
|
||||
void dmgSpPalette1Change(unsigned data, unsigned long cycleCounter) {
|
||||
update(cycleCounter);
|
||||
objpData[0] = data;
|
||||
setDmgPalette(ppu.spPalette(), dmgColorsRgb32 + 4, data);
|
||||
objpData_[0] = data;
|
||||
setDmgPalette(ppu_.spPalette(), dmgColorsRgb32_ + 4, data);
|
||||
}
|
||||
|
||||
void dmgSpPalette2Change(const unsigned data, const unsigned long cycleCounter) {
|
||||
void dmgSpPalette2Change(unsigned data, unsigned long cycleCounter) {
|
||||
update(cycleCounter);
|
||||
objpData[1] = data;
|
||||
setDmgPalette(ppu.spPalette() + 4, dmgColorsRgb32 + 8, data);
|
||||
objpData_[1] = data;
|
||||
setDmgPalette(ppu_.spPalette() + 4, dmgColorsRgb32_ + 8, data);
|
||||
}
|
||||
|
||||
void cgbBgColorChange(unsigned index, const unsigned data, const unsigned long cycleCounter) {
|
||||
if (bgpData[index] != data)
|
||||
void cgbBgColorChange(unsigned index, unsigned data, unsigned long cycleCounter) {
|
||||
if (bgpData_[index] != data)
|
||||
doCgbBgColorChange(index, data, cycleCounter);
|
||||
}
|
||||
|
||||
void cgbSpColorChange(unsigned index, const unsigned data, const unsigned long cycleCounter) {
|
||||
if (objpData[index] != data)
|
||||
void cgbSpColorChange(unsigned index, unsigned data, unsigned long cycleCounter) {
|
||||
if (objpData_[index] != data)
|
||||
doCgbSpColorChange(index, data, cycleCounter);
|
||||
}
|
||||
|
||||
unsigned cgbBgColorRead(const unsigned index, const unsigned long cycleCounter) {
|
||||
return ppu.cgb() & cgbpAccessible(cycleCounter) ? bgpData[index] : 0xFF;
|
||||
unsigned cgbBgColorRead(unsigned index, unsigned long cycleCounter) {
|
||||
return ppu_.cgb() & cgbpAccessible(cycleCounter) ? bgpData_[index] : 0xFF;
|
||||
}
|
||||
|
||||
unsigned cgbSpColorRead(const unsigned index, const unsigned long cycleCounter) {
|
||||
return ppu.cgb() & cgbpAccessible(cycleCounter) ? objpData[index] : 0xFF;
|
||||
unsigned cgbSpColorRead(unsigned index, unsigned long cycleCounter) {
|
||||
return ppu_.cgb() & cgbpAccessible(cycleCounter) ? objpData_[index] : 0xFF;
|
||||
}
|
||||
|
||||
void updateScreen(bool blanklcd, unsigned long cc);
|
||||
|
@ -187,53 +109,149 @@ public:
|
|||
void oamChange(const unsigned char *oamram, unsigned long cycleCounter);
|
||||
void scxChange(unsigned newScx, unsigned long cycleCounter);
|
||||
void scyChange(unsigned newValue, unsigned long cycleCounter);
|
||||
|
||||
void vramChange(const unsigned long cycleCounter) { update(cycleCounter); }
|
||||
|
||||
void vramChange(unsigned long cycleCounter) { update(cycleCounter); }
|
||||
unsigned getStat(unsigned lycReg, unsigned long cycleCounter);
|
||||
|
||||
unsigned getLyReg(const unsigned long cycleCounter) {
|
||||
unsigned getLyReg(unsigned long const cc) {
|
||||
unsigned lyReg = 0;
|
||||
|
||||
if (ppu.lcdc() & 0x80) {
|
||||
if (cycleCounter >= ppu.lyCounter().time())
|
||||
update(cycleCounter);
|
||||
if (ppu_.lcdc() & lcdc_en) {
|
||||
if (cc >= ppu_.lyCounter().time())
|
||||
update(cc);
|
||||
|
||||
lyReg = ppu.lyCounter().ly();
|
||||
lyReg = ppu_.lyCounter().ly();
|
||||
|
||||
if (lyReg == 153) {
|
||||
if (isDoubleSpeed()) {
|
||||
if (ppu.lyCounter().time() - cycleCounter <= 456 * 2 - 8)
|
||||
if (ppu_.lyCounter().time() - cc <= 456 * 2 - 8)
|
||||
lyReg = 0;
|
||||
} else
|
||||
lyReg = 0;
|
||||
} else if (ppu.lyCounter().time() - cycleCounter <= 4)
|
||||
} else if (ppu_.lyCounter().time() - cc <= 4)
|
||||
++lyReg;
|
||||
}
|
||||
|
||||
return lyReg;
|
||||
}
|
||||
|
||||
unsigned long nextMode1IrqTime() const { return eventTimes_(MODE1_IRQ); }
|
||||
|
||||
unsigned long nextMode1IrqTime() const { return eventTimes_(memevent_m1irq); }
|
||||
void lcdcChange(unsigned data, unsigned long cycleCounter);
|
||||
void lcdstatChange(unsigned data, unsigned long cycleCounter);
|
||||
void lycRegChange(unsigned data, unsigned long cycleCounter);
|
||||
|
||||
void enableHdma(unsigned long cycleCounter);
|
||||
void disableHdma(unsigned long cycleCounter);
|
||||
bool hdmaIsEnabled() const { return eventTimes_(HDMA_REQ) != disabled_time; }
|
||||
|
||||
bool hdmaIsEnabled() const { return eventTimes_(memevent_hdma) != disabled_time; }
|
||||
void update(unsigned long cycleCounter);
|
||||
bool isCgb() const { return ppu_.cgb(); }
|
||||
bool isDoubleSpeed() const { return ppu_.lyCounter().isDoubleSpeed(); }
|
||||
|
||||
bool isCgb() const { return ppu.cgb(); }
|
||||
bool isDoubleSpeed() const { return ppu.lyCounter().isDoubleSpeed(); }
|
||||
|
||||
unsigned long *bgPalette() { return ppu.bgPalette(); }
|
||||
unsigned long *spPalette() { return ppu.spPalette(); }
|
||||
unsigned long *bgPalette() { return ppu_.bgPalette(); }
|
||||
unsigned long *spPalette() { return ppu_.spPalette(); }
|
||||
|
||||
void setScanlineCallback(void (*callback)(), int sl) { scanlinecallback = callback; scanlinecallbacksl = sl; }
|
||||
|
||||
private:
|
||||
enum Event { event_mem,
|
||||
event_ly, event_last = event_ly };
|
||||
|
||||
enum MemEvent { memevent_oneshot_statirq,
|
||||
memevent_oneshot_updatewy2,
|
||||
memevent_m1irq,
|
||||
memevent_lycirq,
|
||||
memevent_spritemap,
|
||||
memevent_hdma,
|
||||
memevent_m2irq,
|
||||
memevent_m0irq, memevent_last = memevent_m0irq };
|
||||
|
||||
enum { num_events = event_last + 1 };
|
||||
enum { num_memevents = memevent_last + 1 };
|
||||
|
||||
class EventTimes {
|
||||
public:
|
||||
explicit EventTimes(VideoInterruptRequester memEventRequester)
|
||||
: eventMin_(disabled_time)
|
||||
, memEventMin_(disabled_time)
|
||||
, memEventRequester_(memEventRequester)
|
||||
{
|
||||
}
|
||||
|
||||
Event nextEvent() const { return static_cast<Event>(eventMin_.min()); }
|
||||
unsigned long nextEventTime() const { return eventMin_.minValue(); }
|
||||
unsigned long operator()(Event e) const { return eventMin_.value(e); }
|
||||
template<Event e> void set(unsigned long time) { eventMin_.setValue<e>(time); }
|
||||
void set(Event e, unsigned long time) { eventMin_.setValue(e, time); }
|
||||
|
||||
MemEvent nextMemEvent() const { return static_cast<MemEvent>(memEventMin_.min()); }
|
||||
unsigned long nextMemEventTime() const { return memEventMin_.minValue(); }
|
||||
unsigned long operator()(MemEvent e) const { return memEventMin_.value(e); }
|
||||
|
||||
template<MemEvent e>
|
||||
void setm(unsigned long time) { memEventMin_.setValue<e>(time); setMemEvent(); }
|
||||
void set(MemEvent e, unsigned long time) { memEventMin_.setValue(e, time); setMemEvent(); }
|
||||
|
||||
void flagIrq(unsigned bit) { memEventRequester_.flagIrq(bit); }
|
||||
void flagHdmaReq() { memEventRequester_.flagHdmaReq(); }
|
||||
|
||||
private:
|
||||
MinKeeper<num_events> eventMin_;
|
||||
MinKeeper<num_memevents> memEventMin_;
|
||||
VideoInterruptRequester memEventRequester_;
|
||||
|
||||
void setMemEvent() {
|
||||
unsigned long nmet = nextMemEventTime();
|
||||
eventMin_.setValue<event_mem>(nmet);
|
||||
memEventRequester_.setNextEventTime(nmet);
|
||||
}
|
||||
|
||||
public:
|
||||
template<bool isReader>
|
||||
void SyncState(NewState *ns)
|
||||
{
|
||||
SSS(eventMin_);
|
||||
SSS(memEventMin_);
|
||||
//SSS(memEventRequester_); // not needed
|
||||
}
|
||||
};
|
||||
|
||||
PPU ppu_;
|
||||
unsigned long dmgColorsRgb32_[3 * 4];
|
||||
unsigned long cgbColorsRgb32_[32768];
|
||||
unsigned char bgpData_[8 * 8];
|
||||
unsigned char objpData_[8 * 8];
|
||||
EventTimes eventTimes_;
|
||||
M0Irq m0Irq_;
|
||||
LycIrq lycIrq_;
|
||||
NextM0Time nextM0Time_;
|
||||
unsigned char statReg_;
|
||||
unsigned char m2IrqStatReg_;
|
||||
unsigned char m1IrqStatReg_;
|
||||
|
||||
static void setDmgPalette(unsigned long palette[], const unsigned long dmgColors[], unsigned data);
|
||||
void setDmgPaletteColor(unsigned index, unsigned long rgb32);
|
||||
|
||||
unsigned long gbcToRgb32(const unsigned bgr15);
|
||||
void doCgbColorChange(unsigned char *const pdata, unsigned long *const palette, unsigned index, const unsigned data);
|
||||
|
||||
void refreshPalettes();
|
||||
void setDBuffer();
|
||||
void doMode2IrqEvent();
|
||||
void event();
|
||||
unsigned long m0TimeOfCurrentLine(unsigned long cc);
|
||||
bool cgbpAccessible(unsigned long cycleCounter);
|
||||
bool lycRegChangeStatTriggerBlockedByM0OrM1Irq(unsigned long cc);
|
||||
bool lycRegChangeTriggersStatIrq(unsigned old, unsigned data, unsigned long cc);
|
||||
bool statChangeTriggersM0LycOrM1StatIrqCgb(unsigned old, unsigned data, unsigned long cc);
|
||||
bool statChangeTriggersStatIrqCgb(unsigned old, unsigned data, unsigned long cc);
|
||||
bool statChangeTriggersStatIrqDmg(unsigned old, unsigned long cc);
|
||||
bool statChangeTriggersStatIrq(unsigned old, unsigned data, unsigned long cc);
|
||||
void mode3CyclesChange();
|
||||
void doCgbBgColorChange(unsigned index, unsigned data, unsigned long cycleCounter);
|
||||
void doCgbSpColorChange(unsigned index, unsigned data, unsigned long cycleCounter);
|
||||
|
||||
void (*scanlinecallback)();
|
||||
int scanlinecallbacksl;
|
||||
|
||||
public:
|
||||
template<bool isReader>void SyncState(NewState *ns);
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue