From d44470f56f1cf89110e96047ffa4f4dd7997f72e Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 31 Dec 2014 19:59:26 -0800 Subject: [PATCH] GBA Video: Fix window interactions with 16-color mode 0 mosaic --- CHANGES | 1 + src/gba/renderers/video-software.c | 38 +++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 8e349e6eb..c4d250e29 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Bugfixes: - Debugger: Align PC-relative loads in Thumb - Debugger: Fix watchpoints triggering too late - GBA Video: Fix sprite mis-ordering behavior in some cases (fixes #168) + - GBA Video: Fix window interactions with 16-color mode 0 mosaic Misc: - Qt: Disable sync to video by default - GBA: Exit cleanly on FATAL if the port supports it diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index bb4d3a00c..55e2dc10f 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -933,11 +933,42 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re } #define DRAW_BACKGROUND_MODE_0_MOSAIC_16(BLEND, OBJWIN) \ - for (; tileX < tileEnd; ++tileX) { \ + x = inX & 7; \ + if (mosaicWait) { \ + int baseX = x - (mosaicH - mosaicWait); \ + if (baseX < 0) { \ + int disturbX = (16 + baseX) >> 3; \ + inX -= disturbX << 3; \ + BACKGROUND_TEXT_SELECT_CHARACTER; \ + baseX -= disturbX << 3; \ + inX += disturbX << 3; \ + } else { \ + BACKGROUND_TEXT_SELECT_CHARACTER; \ + } \ + charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 5)) + (localY << 2); \ + paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 4; \ + palette = &mainPalette[paletteData]; \ + LOAD_32(tileData, charBase, vram); \ + if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ + tileData >>= 4 * baseX; \ + } else { \ + tileData >>= 4 * (7 - baseX); \ + } \ + tileData &= 0xF; \ + tileData |= tileData << 4; \ + tileData |= tileData << 8; \ + tileData |= tileData << 12; \ + tileData |= tileData << 16; \ + tileData |= tileData << 20; \ + tileData |= tileData << 24; \ + tileData |= tileData << 28; \ + carryData = tileData; \ + } \ + for (; length; ++tileX) { \ BACKGROUND_TEXT_SELECT_CHARACTER; \ charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 5)) + (localY << 2); \ tileData = carryData; \ - for (x = 0; x < 8; ++x) { \ + for (; x < 8 && length; ++x, --length) { \ if (!mosaicWait) { \ paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 4; \ palette = &mainPalette[paletteData]; \ @@ -962,6 +993,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN); \ ++pixel; \ } \ + x = 0; \ } #define DRAW_BACKGROUND_MODE_0_TILES_16(BLEND, OBJWIN) \ @@ -1194,7 +1226,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re if (background->mosaic && GBAMosaicControlGetBgH(renderer->mosaic)) { \ int mosaicH = GBAMosaicControlGetBgH(renderer->mosaic) + 1; \ int x; \ - int mosaicWait = outX % mosaicH; \ + int mosaicWait = (mosaicH - outX + VIDEO_HORIZONTAL_PIXELS * mosaicH) % mosaicH; \ int carryData = 0; \ paletteData = 0; /* Quiets compiler warning */ \ DRAW_BACKGROUND_MODE_0_MOSAIC_ ## BPP (BLEND, OBJWIN) \