mirror of https://github.com/mgba-emu/mgba.git
GB Video: Fix SCX timing
This commit is contained in:
parent
80472c9f3a
commit
781f2fbb90
1
CHANGES
1
CHANGES
|
@ -40,6 +40,7 @@ Bugfixes:
|
|||
- GBA SIO: Fix unconnected SIOCNT for multi mode (fixes mgba.io/i/1105)
|
||||
- GBA BIOS: Fix BitUnPack final byte
|
||||
- GB I/O: DMA register is R/W
|
||||
- GB Video: Fix SCX timing
|
||||
Misc:
|
||||
- GBA Timer: Use global cycles for timers
|
||||
- GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722)
|
||||
|
|
|
@ -128,7 +128,7 @@ struct GBVideo {
|
|||
struct mTimingEvent modeEvent;
|
||||
struct mTimingEvent frameEvent;
|
||||
|
||||
uint32_t dotClock;
|
||||
int32_t dotClock;
|
||||
|
||||
uint8_t* vram;
|
||||
uint8_t* vramBank;
|
||||
|
|
|
@ -224,8 +224,7 @@ void _endMode0(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
GBRegisterSTAT oldStat = video->stat;
|
||||
video->stat = GBRegisterSTATSetLYC(video->stat, lyc == video->ly);
|
||||
if (video->ly < GB_VIDEO_VERTICAL_PIXELS) {
|
||||
// TODO: Cache SCX & 7 in case it changes during mode 2
|
||||
next = GB_VIDEO_MODE_2_LENGTH + (video->p->memory.io[REG_SCX] & 7);
|
||||
next = GB_VIDEO_MODE_2_LENGTH;
|
||||
video->mode = 2;
|
||||
video->modeEvent.callback = _endMode2;
|
||||
} else {
|
||||
|
@ -262,7 +261,7 @@ void _endMode1(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
if (video->ly == GB_VIDEO_VERTICAL_TOTAL_PIXELS + 1) {
|
||||
video->ly = 0;
|
||||
video->p->memory.io[REG_LY] = video->ly;
|
||||
next = GB_VIDEO_MODE_2_LENGTH + (video->p->memory.io[REG_SCX] & 7);
|
||||
next = GB_VIDEO_MODE_2_LENGTH;
|
||||
video->mode = 2;
|
||||
video->modeEvent.callback = _endMode2;
|
||||
} else if (video->ly == GB_VIDEO_VERTICAL_TOTAL_PIXELS) {
|
||||
|
@ -290,9 +289,9 @@ void _endMode1(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
void _endMode2(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
||||
struct GBVideo* video = context;
|
||||
_cleanOAM(video, video->ly);
|
||||
video->x = 0;
|
||||
video->dotClock = mTimingCurrentTime(timing) - cyclesLate;
|
||||
int32_t next = GB_VIDEO_MODE_3_LENGTH_BASE + video->objMax * 6 - (video->p->memory.io[REG_SCX] & 7);
|
||||
video->x = -(video->p->memory.io[REG_SCX] & 7);
|
||||
video->dotClock = mTimingCurrentTime(timing) - cyclesLate + 5 - (video->x << video->p->doubleSpeed);
|
||||
int32_t next = GB_VIDEO_MODE_3_LENGTH_BASE + video->objMax * 6 - video->x;
|
||||
video->mode = 3;
|
||||
video->modeEvent.callback = _endMode3;
|
||||
GBRegisterSTAT oldStat = video->stat;
|
||||
|
@ -323,7 +322,8 @@ void _endMode3(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
GBUpdateIRQs(video->p);
|
||||
}
|
||||
video->p->memory.io[REG_STAT] = video->stat;
|
||||
int32_t next = GB_VIDEO_MODE_0_LENGTH_BASE - video->objMax * 6;
|
||||
// TODO: Cache SCX & 7 in case it changes
|
||||
int32_t next = GB_VIDEO_MODE_0_LENGTH_BASE - video->objMax * 6 - (video->p->memory.io[REG_SCX] & 7);
|
||||
mTimingSchedule(timing, &video->modeEvent, (next << video->p->doubleSpeed) - cyclesLate);
|
||||
}
|
||||
|
||||
|
@ -402,12 +402,14 @@ void GBVideoProcessDots(struct GBVideo* video, uint32_t cyclesLate) {
|
|||
return;
|
||||
}
|
||||
int oldX = video->x;
|
||||
video->x = (mTimingCurrentTime(&video->p->timing) - video->dotClock - cyclesLate) >> video->p->doubleSpeed;
|
||||
video->x = (int32_t) (mTimingCurrentTime(&video->p->timing) - cyclesLate - video->dotClock) >> video->p->doubleSpeed;
|
||||
if (video->x > GB_VIDEO_HORIZONTAL_PIXELS) {
|
||||
video->x = GB_VIDEO_HORIZONTAL_PIXELS;
|
||||
} else if (video->x < 0) {
|
||||
mLOG(GB, FATAL, "Video dot clock went negative!");
|
||||
video->x = oldX;
|
||||
return;
|
||||
}
|
||||
if (oldX < 0) {
|
||||
oldX = 0;
|
||||
}
|
||||
if (video->frameskipCounter <= 0) {
|
||||
video->renderer->drawRange(video->renderer, oldX, video->x, video->ly, video->objThisLine, video->objMax);
|
||||
|
|
Loading…
Reference in New Issue