GB Video: Fix loading states while in mode 3
Vicki Pfau vi@endrift.com
Tue, 17 Oct 2017 21:25:35 -0700
4 files changed,
12 insertions(+),
9 deletions(-)
M
CHANGES
→
CHANGES
@@ -19,6 +19,7 @@ - GB: Revamp IRQ handling based on new information
- GBA Video: Don't mask out high bits of BLDY (fixes mgba.io/i/899) - GBA Video: Force align 256-color tiles - GBA DMA: ROM reads are forced to increment + - GB Video: Fix loading states while in mode 3 Misc: - GBA Timer: Use global cycles for timers - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722)
M
include/mgba/internal/gb/video.h
→
include/mgba/internal/gb/video.h
@@ -159,7 +159,7 @@ void GBVideoInit(struct GBVideo* video);
void GBVideoReset(struct GBVideo* video); void GBVideoDeinit(struct GBVideo* video); void GBVideoAssociateRenderer(struct GBVideo* video, struct GBVideoRenderer* renderer); -void GBVideoProcessDots(struct GBVideo* video); +void GBVideoProcessDots(struct GBVideo* video, uint32_t cyclesLate); void GBVideoWriteLCDC(struct GBVideo* video, GBRegisterLCDC value); void GBVideoWriteSTAT(struct GBVideo* video, GBRegisterSTAT value);
M
src/gb/io.c
→
src/gb/io.c
@@ -392,7 +392,7 @@ GBUpdateIRQs(gb);
return; case REG_LCDC: // TODO: handle GBC differences - GBVideoProcessDots(&gb->video); + GBVideoProcessDots(&gb->video, 0); value = gb->video.renderer->writeVideoRegister(gb->video.renderer, address, value); GBVideoWriteLCDC(&gb->video, value); break;@@ -406,13 +406,13 @@ case REG_SCY:
case REG_SCX: case REG_WY: case REG_WX: - GBVideoProcessDots(&gb->video); + GBVideoProcessDots(&gb->video, 0); value = gb->video.renderer->writeVideoRegister(gb->video.renderer, address, value); break; case REG_BGP: case REG_OBP0: case REG_OBP1: - GBVideoProcessDots(&gb->video); + GBVideoProcessDots(&gb->video, 0); GBVideoWritePalette(&gb->video, address, value); break; case REG_STAT:@@ -459,7 +459,7 @@ gb->video.bcpIncrement = value & 0x80;
gb->memory.io[REG_BCPD] = gb->video.palette[gb->video.bcpIndex >> 1] >> (8 * (gb->video.bcpIndex & 1)); break; case REG_BCPD: - GBVideoProcessDots(&gb->video); + GBVideoProcessDots(&gb->video, 0); GBVideoWritePalette(&gb->video, address, value); return; case REG_OCPS:@@ -468,7 +468,7 @@ gb->video.ocpIncrement = value & 0x80;
gb->memory.io[REG_OCPD] = gb->video.palette[8 * 4 + (gb->video.ocpIndex >> 1)] >> (8 * (gb->video.ocpIndex & 1)); break; case REG_OCPD: - GBVideoProcessDots(&gb->video); + GBVideoProcessDots(&gb->video, 0); GBVideoWritePalette(&gb->video, address, value); return; case REG_SVBK:
M
src/gb/video.c
→
src/gb/video.c
@@ -310,7 +310,7 @@ }
void _endMode3(struct mTiming* timing, void* context, uint32_t cyclesLate) { struct GBVideo* video = context; - GBVideoProcessDots(video); + GBVideoProcessDots(video, cyclesLate); if (video->ly < GB_VIDEO_VERTICAL_PIXELS && video->p->memory.isHdma && video->p->memory.io[REG_HDMA5] != 0xFF) { video->p->memory.hdmaRemaining = 0x10; video->p->cpuBlocked = true;@@ -400,12 +400,12 @@ }
video->objMax = o; } -void GBVideoProcessDots(struct GBVideo* video) { +void GBVideoProcessDots(struct GBVideo* video, uint32_t cyclesLate) { if (video->mode != 3) { return; } int oldX = video->x; - video->x = (video->p->timing.masterCycles - video->dotClock + video->p->cpu->cycles) >> video->p->doubleSpeed; + video->x = (mTimingCurrentTime(&video->p->timing) - video->dotClock - cyclesLate) >> video->p->doubleSpeed; if (video->x > GB_VIDEO_HORIZONTAL_PIXELS) { video->x = GB_VIDEO_HORIZONTAL_PIXELS; } else if (video->x < 0) {@@ -786,6 +786,7 @@ void GBVideoSerialize(const struct GBVideo* video, struct GBSerializedState* state) {
STORE_16LE(video->x, 0, &state->video.x); STORE_16LE(video->ly, 0, &state->video.ly); STORE_32LE(video->frameCounter, 0, &state->video.frameCounter); + STORE_32LE(video->dotClock, 0, &state->video.dotCounter); state->video.vramCurrentBank = video->vramCurrentBank; GBSerializedVideoFlags flags = 0;@@ -814,6 +815,7 @@ void GBVideoDeserialize(struct GBVideo* video, const struct GBSerializedState* state) {
LOAD_16LE(video->x, 0, &state->video.x); LOAD_16LE(video->ly, 0, &state->video.ly); LOAD_32LE(video->frameCounter, 0, &state->video.frameCounter); + LOAD_32LE(video->dotClock, 0, &state->video.dotCounter); video->vramCurrentBank = state->video.vramCurrentBank; GBSerializedVideoFlags flags = state->video.flags;