all repos — mgba @ 2ee192d868a452ff0e562925dd76cd8c805a0d67

mGBA Game Boy Advance Emulator

GB Video: Frame end callback should only happen on instruction boundary
Jeffrey Pfau jeffrey@endrift.com
Sat, 28 May 2016 10:50:17 -0700
commit

2ee192d868a452ff0e562925dd76cd8c805a0d67

parent

334963511b513bcfc64d2b506337fea5774a18d7

2 files changed, 21 insertions(+), 4 deletions(-)

jump to
M src/gb/video.csrc/gb/video.c

@@ -50,6 +50,7 @@ video->eventDiff = 0;

video->nextMode = INT_MAX; video->dotCounter = INT_MIN; + video->nextFrame = INT_MAX; video->frameCounter = 0; video->frameskipCounter = 0;

@@ -88,6 +89,7 @@ }

if (video->nextEvent <= 0) { if (video->nextEvent != INT_MAX) { video->nextMode -= video->eventDiff; + video->nextFrame -= video->eventDiff; } video->nextEvent = INT_MAX; GBVideoProcessDots(video);

@@ -116,12 +118,10 @@ video->renderer->finishFrame(video->renderer);

mCoreSyncPostFrame(video->p->sync); video->frameskipCounter = video->frameskip; } - GBFrameEnded(video->p); ++video->frameCounter; - struct mCoreThread* thread = mCoreThreadGet(); - if (thread && thread->frameCallback) { - thread->frameCallback(thread); + if (video->nextFrame != 0) { + video->nextFrame = 0; } if (video->p->stream && video->p->stream->postVideoFrame) {

@@ -197,6 +197,21 @@ break;

} video->stat = GBRegisterSTATSetMode(video->stat, video->mode); video->p->memory.io[REG_STAT] = video->stat; + } + if (video->nextFrame <= 0) { + if (video->p->cpu->executionState == LR35902_CORE_FETCH) { + GBFrameEnded(video->p); + struct mCoreThread* thread = mCoreThreadGet(); + if (thread && thread->frameCallback) { + thread->frameCallback(thread); + } + video->nextFrame = GB_VIDEO_TOTAL_LENGTH; + } else { + video->nextFrame = 4 - ((video->p->cpu->executionState + 1) & 3); + if (video->nextFrame < video->nextEvent) { + video->nextEvent = video->nextFrame; + } + } } if (video->nextMode < video->nextEvent) { video->nextEvent = video->nextMode;
M src/gb/video.hsrc/gb/video.h

@@ -104,6 +104,8 @@

int32_t nextMode; int32_t dotCounter; + int32_t nextFrame; + uint8_t* vram; uint8_t* vramBank; int vramCurrentBank;