mirror of https://github.com/mgba-emu/mgba.git
GB Video: Fix loading states while in mode 3
This commit is contained in:
parent
65665324ef
commit
7ebd2d6e75
1
CHANGES
1
CHANGES
|
@ -19,6 +19,7 @@ Bugfixes:
|
|||
- 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)
|
||||
|
|
|
@ -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);
|
||||
|
|
10
src/gb/io.c
10
src/gb/io.c
|
@ -392,7 +392,7 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
|
|||
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 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
|
|||
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 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
|
|||
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 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
|
|||
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:
|
||||
|
|
|
@ -310,7 +310,7 @@ void _endMode2(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
|
||||
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 @@ static void _cleanOAM(struct GBVideo* video, int y) {
|
|||
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* sta
|
|||
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* s
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue