GB Video: Fix window being enabled mid-scanline (fixes #1328)
Vicki Pfau vi@endrift.com
Sun, 03 Mar 2019 17:27:53 -0800
3 files changed,
19 insertions(+),
4 deletions(-)
M
CHANGES
→
CHANGES
@@ -8,6 +8,7 @@ - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208)
- GBA: Reset now reloads multiboot ROMs - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) + - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325)
M
include/mgba/internal/gb/renderers/software.h
→
include/mgba/internal/gb/renderers/software.h
@@ -32,7 +32,9 @@ uint8_t scx;
uint8_t wy; uint8_t wx; uint8_t currentWy; + uint8_t currentWx; int lastY; + int lastX; bool hasWindow; GBRegisterLCDC lcdc;
M
src/gb/renderers/software.c
→
src/gb/renderers/software.c
@@ -190,7 +190,9 @@ softwareRenderer->scy = 0;
softwareRenderer->scx = 0; softwareRenderer->wy = 0; softwareRenderer->currentWy = 0; + softwareRenderer->currentWx = 0; softwareRenderer->lastY = GB_VIDEO_VERTICAL_PIXELS; + softwareRenderer->lastX = 0; softwareRenderer->hasWindow = false; softwareRenderer->wx = 0; softwareRenderer->model = model;@@ -232,6 +234,9 @@ if (renderer->lastY > renderer->wy) {
renderer->currentWy = GB_VIDEO_VERTICAL_PIXELS; } else { renderer->currentWy = renderer->lastY - renderer->wy; + if (renderer->lastY == renderer->wy && renderer->lastX > renderer->wx) { + ++renderer->currentWy; + } } } else { renderer->currentWy += renderer->lastY;@@ -489,6 +494,7 @@
static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; softwareRenderer->lastY = y; + softwareRenderer->lastX = endX; uint8_t* maps = &softwareRenderer->d.vram[GB_BASE_MAP]; if (GBRegisterLCDCIsTileMap(softwareRenderer->lcdc)) { maps += GB_SIZE_MAP;@@ -498,9 +504,10 @@ memset(&softwareRenderer->row[startX], 0, endX - startX);
} if (GBRegisterLCDCIsBgEnable(softwareRenderer->lcdc) || softwareRenderer->model >= GB_MODEL_CGB) { int wy = softwareRenderer->wy + softwareRenderer->currentWy; - if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy <= y && endX >= softwareRenderer->wx - 7) { - if (softwareRenderer->wx - 7 > 0 && !softwareRenderer->d.disableBG) { - GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, softwareRenderer->wx - 7, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); + int wx = softwareRenderer->wx + softwareRenderer->currentWx - 7; + if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy <= y && wx <= endX) { + if (wx > 0 && !softwareRenderer->d.disableBG) { + GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, wx, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); } maps = &softwareRenderer->d.vram[GB_BASE_MAP];@@ -508,7 +515,7 @@ if (GBRegisterLCDCIsWindowTileMap(softwareRenderer->lcdc)) {
maps += GB_SIZE_MAP; } if (!softwareRenderer->d.disableWIN) { - GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, softwareRenderer->wx - 7, endX, 7 - softwareRenderer->wx - softwareRenderer->offsetWx, y - wy - softwareRenderer->offsetWy); + GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, wx, endX, -wx - softwareRenderer->offsetWx, y - wy - softwareRenderer->offsetWy); } } else if (!softwareRenderer->d.disableBG) { GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, endX, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy);@@ -612,6 +619,9 @@
static void GBVideoSoftwareRendererFinishScanline(struct GBVideoRenderer* renderer, int y) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; + softwareRenderer->lastX = 0; + softwareRenderer->currentWx = 0; + if (softwareRenderer->sgbTransfer == 1) { size_t offset = 2 * ((y & 7) + (y >> 3) * GB_VIDEO_HORIZONTAL_PIXELS); if (offset >= 0x1000) {@@ -702,7 +712,9 @@ break;
} } softwareRenderer->lastY = GB_VIDEO_VERTICAL_PIXELS; + softwareRenderer->lastX = 0; softwareRenderer->currentWy = 0; + softwareRenderer->currentWx = 0; softwareRenderer->hasWindow = false; }