diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index 8e583b25d..48a9ac210 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -122,6 +122,8 @@ struct GBAVideoSoftwareRenderer { uint32_t row[256]; uint32_t spriteLayer[256]; + uint8_t alphaA[256]; + uint8_t alphaB[256]; int32_t spriteCyclesRemaining; // BLDCNT diff --git a/src/ds/renderers/software.c b/src/ds/renderers/software.c index 3425710bd..e8f9fe9e9 100644 --- a/src/ds/renderers/software.c +++ b/src/ds/renderers/software.c @@ -372,6 +372,8 @@ static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* rend GBAVideoSoftwareRendererPreprocessBuffer(softwareRenderer, y); int spriteLayers = GBAVideoSoftwareRendererPreprocessSpriteLayer(softwareRenderer, y); + memset(softwareRenderer->alphaA, softwareRenderer->blda, sizeof(softwareRenderer->alphaA)); + memset(softwareRenderer->alphaB, softwareRenderer->bldb, sizeof(softwareRenderer->alphaB)); int w; unsigned priority; @@ -394,7 +396,14 @@ static void DSVideoSoftwareRendererDrawGBAScanline(struct GBAVideoRenderer* rend int x; for (x = softwareRenderer->start; x < softwareRenderer->end; ++x) { if (scanline[x] & 0xF8000000) { - _compositeBlendNoObjwin(softwareRenderer, &softwareRenderer->row[x], (scanline[x] & 0x00FFFFFF) | flags, softwareRenderer->row[x]); + if (flags & FLAG_TARGET_1) { + // TODO: More precise values + softwareRenderer->alphaA[x] = (scanline[x] >> 28) + 1; + softwareRenderer->alphaB[x] = 0x10 - softwareRenderer->alphaA[x]; + _compositeBlendNoObjwin(softwareRenderer, x, (scanline[x] & 0x00FFFFFF) | flags, softwareRenderer->row[x]); + } else { + _compositeNoBlendNoObjwin(softwareRenderer, x, (scanline[x] & 0x00FFFFFF) | flags, softwareRenderer->row[x]); + } } } } else { diff --git a/src/gba/renderers/software-bg.c b/src/gba/renderers/software-bg.c index e155a3da5..7c78e436e 100644 --- a/src/gba/renderers/software-bg.c +++ b/src/gba/renderers/software-bg.c @@ -34,11 +34,11 @@ } #define MODE_2_LOOP(MOSAIC, COORD, BLEND, OBJWIN) \ - for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) { \ + for (outX = renderer->start; outX < renderer->end; ++outX) { \ x += background->dx; \ y += background->dy; \ \ - uint32_t current = *pixel; \ + uint32_t current = renderer->row[outX]; \ MOSAIC(COORD) \ if (pixelData) { \ COMPOSITE_256_ ## OBJWIN (BLEND, 0); \ @@ -69,7 +69,6 @@ void GBAVideoSoftwareRendererDrawBackgroundMode2(struct GBAVideoSoftwareRenderer uint8_t pixelData = 0; int outX; - uint32_t* pixel; if (!objwinSlowPath) { if (!(flags & FLAG_TARGET_2)) { @@ -92,8 +91,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode3(struct GBAVideoSoftwareRenderer uint32_t color = renderer->normalPalette[0]; int outX; - uint32_t* pixel; - for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) { + for (outX = renderer->start; outX < renderer->end; ++outX) { BACKGROUND_BITMAP_ITERATE(renderer->masterEnd, VIDEO_VERTICAL_PIXELS); if (!mosaicWait) { @@ -118,18 +116,18 @@ void GBAVideoSoftwareRendererDrawBackgroundMode3(struct GBAVideoSoftwareRenderer --mosaicWait; } - uint32_t current = *pixel; + uint32_t current = renderer->row[outX]; if (!objwinSlowPath || (!(current & FLAG_OBJWIN)) != objwinOnly) { unsigned mergedFlags = flags; if (current & FLAG_OBJWIN) { mergedFlags = objwinFlags; } if (!variant) { - _compositeBlendObjwin(renderer, pixel, color | mergedFlags, current); + _compositeBlendObjwin(renderer, outX, color | mergedFlags, current); } else if (renderer->blendEffect == BLEND_BRIGHTEN) { - _compositeBlendObjwin(renderer, pixel, _brighten(color, renderer->bldy) | mergedFlags, current); + _compositeBlendObjwin(renderer, outX, _brighten(color, renderer->bldy) | mergedFlags, current); } else if (renderer->blendEffect == BLEND_DARKEN) { - _compositeBlendObjwin(renderer, pixel, _darken(color, renderer->bldy) | mergedFlags, current); + _compositeBlendObjwin(renderer, outX, _darken(color, renderer->bldy) | mergedFlags, current); } } } @@ -145,8 +143,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer } int outX; - uint32_t* pixel; - for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) { + for (outX = renderer->start; outX < renderer->end; ++outX) { BACKGROUND_BITMAP_ITERATE(renderer->masterEnd, VIDEO_VERTICAL_PIXELS); if (!mosaicWait) { @@ -157,17 +154,17 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer --mosaicWait; } - uint32_t current = *pixel; + uint32_t current = renderer->row[outX]; if (color && IS_WRITABLE(current)) { if (!objwinSlowPath) { - _compositeBlendNoObjwin(renderer, pixel, palette[color] | flags, current); + _compositeBlendNoObjwin(renderer, outX, palette[color] | flags, current); } else if (objwinForceEnable || (!(current & FLAG_OBJWIN)) == objwinOnly) { color_t* currentPalette = (current & FLAG_OBJWIN) ? objwinPalette : palette; unsigned mergedFlags = flags; if (current & FLAG_OBJWIN) { mergedFlags = objwinFlags; } - _compositeBlendObjwin(renderer, pixel, currentPalette[color] | mergedFlags, current); + _compositeBlendObjwin(renderer, outX, currentPalette[color] | mergedFlags, current); } } } @@ -183,8 +180,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode5(struct GBAVideoSoftwareRenderer } int outX; - uint32_t* pixel; - for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) { + for (outX = renderer->start; outX < renderer->end; ++outX) { BACKGROUND_BITMAP_ITERATE(160, 128); if (!mosaicWait) { @@ -208,18 +204,18 @@ void GBAVideoSoftwareRendererDrawBackgroundMode5(struct GBAVideoSoftwareRenderer --mosaicWait; } - uint32_t current = *pixel; + uint32_t current = renderer->row[outX]; if (!objwinSlowPath || (!(current & FLAG_OBJWIN)) != objwinOnly) { unsigned mergedFlags = flags; if (current & FLAG_OBJWIN) { mergedFlags = objwinFlags; } if (!variant) { - _compositeBlendObjwin(renderer, pixel, color | mergedFlags, current); + _compositeBlendObjwin(renderer, outX, color | mergedFlags, current); } else if (renderer->blendEffect == BLEND_BRIGHTEN) { - _compositeBlendObjwin(renderer, pixel, _brighten(color, renderer->bldy) | mergedFlags, current); + _compositeBlendObjwin(renderer, outX, _brighten(color, renderer->bldy) | mergedFlags, current); } else if (renderer->blendEffect == BLEND_DARKEN) { - _compositeBlendObjwin(renderer, pixel, _darken(color, renderer->bldy) | mergedFlags, current); + _compositeBlendObjwin(renderer, outX, _darken(color, renderer->bldy) | mergedFlags, current); } } } diff --git a/src/gba/renderers/software-mode0.c b/src/gba/renderers/software-mode0.c index f543c5407..115c2757f 100644 --- a/src/gba/renderers/software-mode0.c +++ b/src/gba/renderers/software-mode0.c @@ -33,14 +33,14 @@ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ tileData >>= 4 * mod8; \ - for (; outX < end; ++outX, ++pixel) { \ + for (; outX < end; ++outX) { \ BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ } else { \ for (outX = end - 1; outX >= renderer->start; --outX) { \ - uint32_t* pixel = &renderer->row[outX]; \ BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ + outX = end; \ } \ } @@ -53,14 +53,12 @@ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 4; \ palette = &mainPalette[paletteData]; \ - pixel = &renderer->row[outX]; \ if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ if (outX < renderer->start) { \ tileData >>= 4 * (renderer->start - outX); \ outX = renderer->start; \ - pixel = &renderer->row[outX]; \ } \ - for (; outX < renderer->end; ++outX, ++pixel) { \ + for (; outX < renderer->end; ++outX) { \ BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ } else { \ @@ -70,14 +68,12 @@ end = -1; \ } \ outX = renderer->end - 1; \ - pixel = &renderer->row[outX]; \ - for (; outX > end; --outX, --pixel) { \ + for (; outX > end; --outX) { \ BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ /* Needed for consistency checks */ \ if (VIDEO_CHECKS) { \ outX = renderer->end; \ - pixel = &renderer->row[outX]; \ } \ } @@ -142,7 +138,7 @@ } \ --mosaicWait; \ BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ - ++pixel; \ + ++outX; \ } \ x = 0; \ } @@ -155,7 +151,7 @@ charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 5)) + (localY << 2); \ vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \ if (UNLIKELY(!vram)) { \ - pixel += 8; \ + outX += 8; \ continue; \ } \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ @@ -180,7 +176,7 @@ BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \ } \ } \ - pixel += 8; \ + outX += 8; \ } #define DRAW_BACKGROUND_MODE_0_TILE_SUFFIX_256(BLEND, OBJWIN) \ @@ -194,7 +190,7 @@ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ tileData >>= 8 * shift; \ shift = 0; \ - for (; outX < end2; ++outX, ++pixel) { \ + for (; outX < end2; ++outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } \ @@ -203,18 +199,17 @@ if (LIKELY(vram)) { \ LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \ tileData >>= 8 * shift; \ - for (; outX < end; ++outX, ++pixel) { \ + for (; outX < end; ++outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } \ } else { \ int start = outX; \ outX = end - 1; \ - pixel = &renderer->row[outX]; \ if (LIKELY(vram)) { \ if (end2 > start) { \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ - for (; outX >= end2; --outX, --pixel) { \ + for (; outX >= end2; --outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ charBase += 4; \ @@ -223,12 +218,11 @@ \ if (LIKELY(vram)) { \ LOAD_32(tileData, charBase, vram); \ - for (; outX >= renderer->start; --outX, --pixel) { \ + for (; outX >= renderer->start; --outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } \ outX = end; \ - pixel = &renderer->row[outX]; \ } #define DRAW_BACKGROUND_MODE_0_TILE_PREFIX_256(BLEND, OBJWIN) \ @@ -238,29 +232,27 @@ return; \ } \ int end = mod8 - 4; \ - pixel = &renderer->row[outX]; \ if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ if (end > 0) { \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ - for (; outX < renderer->end - end; ++outX, ++pixel) { \ + for (; outX < renderer->end - end; ++outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ charBase += 4; \ } \ \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ - for (; outX < renderer->end; ++outX, ++pixel) { \ + for (; outX < renderer->end; ++outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } else { \ int shift = (8 - mod8) & 0x3; \ int start = outX; \ outX = renderer->end - 1; \ - pixel = &renderer->row[outX]; \ if (end > 0) { \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ tileData >>= 8 * shift; \ - for (; outX >= start + 4; --outX, --pixel) { \ + for (; outX >= start + 4; --outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ shift = 0; \ @@ -268,13 +260,12 @@ \ LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \ tileData >>= 8 * shift; \ - for (; outX >= start; --outX, --pixel) { \ + for (; outX >= start; --outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ /* Needed for consistency checks */ \ if (VIDEO_CHECKS) { \ outX = renderer->end; \ - pixel = &renderer->row[outX]; \ } \ } @@ -284,7 +275,7 @@ charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 6)) + (localY << 3); \ vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \ if (UNLIKELY(!vram)) { \ - pixel += 8; \ + outX += 8; \ continue; \ } \ if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ @@ -295,7 +286,7 @@ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ } \ - pixel += 4; \ + outX += 4; \ LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \ if (tileData) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ @@ -303,7 +294,7 @@ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ } \ - pixel += 4; \ + outX += 4; \ } else { \ LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \ if (tileData) { \ @@ -312,7 +303,7 @@ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ - pixel += 4; \ + outX += 4; \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ if (tileData) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ @@ -320,7 +311,7 @@ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ - pixel += 4; \ + outX += 4; \ } \ } @@ -360,7 +351,7 @@ tileData |= tileData << 8; \ --mosaicWait; \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ - ++pixel; \ + ++outX; \ } \ } @@ -377,7 +368,7 @@ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ tileData >>= 8 * shift; \ shift = 0; \ - for (; outX < end2; ++outX, ++pixel) { \ + for (; outX < end2; ++outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } \ @@ -386,18 +377,17 @@ if (LIKELY(vram)) { \ LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \ tileData >>= 8 * shift; \ - for (; outX < end; ++outX, ++pixel) { \ + for (; outX < end; ++outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } \ } else { \ int start = outX; \ outX = end - 1; \ - pixel = &renderer->row[outX]; \ if (LIKELY(vram)) { \ if (end2 > start) { \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ - for (; outX >= end2; --outX, --pixel) { \ + for (; outX >= end2; --outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ charBase += 4; \ @@ -406,12 +396,11 @@ \ if (LIKELY(vram)) { \ LOAD_32(tileData, charBase, vram); \ - for (; outX >= renderer->start; --outX, --pixel) { \ + for (; outX >= renderer->start; --outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } \ outX = end; \ - pixel = &renderer->row[outX]; \ } #define DRAW_BACKGROUND_MODE_0_TILE_PREFIX_256EXT(BLEND, OBJWIN) \ @@ -423,29 +412,27 @@ paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 8; \ palette = &mainPalette[paletteData]; \ int end = mod8 - 4; \ - pixel = &renderer->row[outX]; \ if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ if (end > 0) { \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ - for (; outX < renderer->end - end; ++outX, ++pixel) { \ + for (; outX < renderer->end - end; ++outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ charBase += 4; \ } \ \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ - for (; outX < renderer->end; ++outX, ++pixel) { \ + for (; outX < renderer->end; ++outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ } else { \ int shift = (8 - mod8) & 0x3; \ int start = outX; \ outX = renderer->end - 1; \ - pixel = &renderer->row[outX]; \ if (end > 0) { \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ tileData >>= 8 * shift; \ - for (; outX >= start + 4; --outX, --pixel) { \ + for (; outX >= start + 4; --outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ shift = 0; \ @@ -453,13 +440,12 @@ \ LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \ tileData >>= 8 * shift; \ - for (; outX >= start; --outX, --pixel) { \ + for (; outX >= start; --outX) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ /* Needed for consistency checks */ \ if (VIDEO_CHECKS) { \ outX = renderer->end; \ - pixel = &renderer->row[outX]; \ } \ } @@ -471,7 +457,7 @@ charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 6)) + (localY << 3); \ vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \ if (UNLIKELY(!vram)) { \ - pixel += 8; \ + outX += 8; \ continue; \ } \ if (!GBA_TEXT_MAP_HFLIP(mapData)) { \ @@ -482,7 +468,7 @@ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ } \ - pixel += 4; \ + outX += 4; \ LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \ if (tileData) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ @@ -490,7 +476,7 @@ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ } \ - pixel += 4; \ + outX += 4; \ } else { \ LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \ if (tileData) { \ @@ -499,7 +485,7 @@ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ - pixel += 4; \ + outX += 4; \ LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \ if (tileData) { \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \ @@ -507,7 +493,7 @@ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ } \ - pixel += 4; \ + outX += 4; \ } \ } @@ -549,12 +535,11 @@ tileData |= tileData << 8; \ --mosaicWait; \ BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \ - ++pixel; \ + ++outX; \ } \ } #define DRAW_BACKGROUND_MODE_0(BPP, BLEND, OBJWIN) \ - uint32_t* pixel = &renderer->row[outX]; \ if (background->mosaic && GBAMosaicControlGetBgH(renderer->mosaic)) { \ int mosaicH = GBAMosaicControlGetBgH(renderer->mosaic) + 1; \ int x; \ @@ -590,13 +575,6 @@ } \ length -= end - renderer->start; \ } \ - /*! TODO: Make sure these lines can be removed */ \ - /*!*/ pixel = &renderer->row[outX]; \ - outX += (tileEnd - tileX) * 8; \ - /*!*/ if (VIDEO_CHECKS && UNLIKELY(outX > renderer->masterEnd)) { \ - /*!*/ mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw would occur!"); \ - /*!*/ return; \ - /*!*/ } \ DRAW_BACKGROUND_MODE_0_TILES_ ## BPP (BLEND, OBJWIN) \ if (length & 0x7) { \ BACKGROUND_TEXT_SELECT_CHARACTER; \ @@ -608,9 +586,6 @@ } \ DRAW_BACKGROUND_MODE_0_TILE_PREFIX_ ## BPP (BLEND, OBJWIN) \ } \ - if (VIDEO_CHECKS && UNLIKELY(&renderer->row[outX] != pixel)) { \ - mLOG(GBA_VIDEO, FATAL, "Background draw ended in the wrong place! Diff: %" PRIXPTR, &renderer->row[outX] - pixel); \ - } \ if (VIDEO_CHECKS && UNLIKELY(outX > renderer->masterEnd)) { \ mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw occurred!"); \ return; \ diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index 938bff1dd..b2030a15f 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -402,7 +402,6 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re void GBAVideoSoftwareRendererPostprocessSprite(struct GBAVideoSoftwareRenderer* renderer, unsigned priority) { int x; - uint32_t* pixel = &renderer->row[renderer->start]; uint32_t flags = FLAG_TARGET_2 * renderer->target2Obj; int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt); @@ -416,29 +415,29 @@ void GBAVideoSoftwareRendererPostprocessSprite(struct GBAVideoSoftwareRenderer* } if (objwinDisable) { - for (x = renderer->start; x < renderer->end; ++x, ++pixel) { + for (x = renderer->start; x < renderer->end; ++x) { uint32_t color = renderer->spriteLayer[x] & ~FLAG_OBJWIN; - uint32_t current = *pixel; + uint32_t current = renderer->row[x]; if ((color & FLAG_UNWRITTEN) != FLAG_UNWRITTEN && !(current & FLAG_OBJWIN) && (color & FLAG_PRIORITY) >> OFFSET_PRIORITY == priority) { - _compositeBlendObjwin(renderer, pixel, color | flags, current); + _compositeBlendObjwin(renderer, x, color | flags, current); } } return; } else if (objwinOnly) { - for (x = renderer->start; x < renderer->end; ++x, ++pixel) { + for (x = renderer->start; x < renderer->end; ++x) { uint32_t color = renderer->spriteLayer[x] & ~FLAG_OBJWIN; - uint32_t current = *pixel; + uint32_t current = renderer->row[x]; if ((color & FLAG_UNWRITTEN) != FLAG_UNWRITTEN && (current & FLAG_OBJWIN) && (color & FLAG_PRIORITY) >> OFFSET_PRIORITY == priority) { - _compositeBlendObjwin(renderer, pixel, color | flags, current); + _compositeBlendObjwin(renderer, x, color | flags, current); } } return; } else { - for (x = renderer->start; x < renderer->end; ++x, ++pixel) { + for (x = renderer->start; x < renderer->end; ++x) { uint32_t color = renderer->spriteLayer[x] & ~FLAG_OBJWIN; - uint32_t current = *pixel; + uint32_t current = renderer->row[x]; if ((color & FLAG_UNWRITTEN) != FLAG_UNWRITTEN && (color & FLAG_PRIORITY) >> OFFSET_PRIORITY == priority) { - _compositeBlendObjwin(renderer, pixel, color | flags, current); + _compositeBlendObjwin(renderer, x, color | flags, current); } } return; @@ -446,11 +445,11 @@ void GBAVideoSoftwareRendererPostprocessSprite(struct GBAVideoSoftwareRenderer* } else if (!GBAWindowControlIsObjEnable(renderer->currentWindow.packed)) { return; } - for (x = renderer->start; x < renderer->end; ++x, ++pixel) { + for (x = renderer->start; x < renderer->end; ++x) { uint32_t color = renderer->spriteLayer[x] & ~FLAG_OBJWIN; - uint32_t current = *pixel; + uint32_t current = renderer->row[x]; if ((color & FLAG_UNWRITTEN) != FLAG_UNWRITTEN && (color & FLAG_PRIORITY) >> OFFSET_PRIORITY == priority) { - _compositeBlendNoObjwin(renderer, pixel, color | flags, current); + _compositeBlendNoObjwin(renderer, x, color | flags, current); } } } diff --git a/src/gba/renderers/software-private.h b/src/gba/renderers/software-private.h index 45fad5015..5c73903b5 100644 --- a/src/gba/renderers/software-private.h +++ b/src/gba/renderers/software-private.h @@ -42,36 +42,36 @@ static unsigned _mix(int weightA, unsigned colorA, int weightB, unsigned colorB) // The lower the number, the higher the priority, and sprites take precedence over backgrounds // We want to do special processing if the color pixel is target 1, however -static inline void _compositeBlendObjwin(struct GBAVideoSoftwareRenderer* renderer, uint32_t* pixel, uint32_t color, uint32_t current) { +static inline void _compositeBlendObjwin(struct GBAVideoSoftwareRenderer* renderer, int x, uint32_t color, uint32_t current) { if (color >= current) { if (current & FLAG_TARGET_1 && color & FLAG_TARGET_2) { - color = _mix(renderer->blda, current, renderer->bldb, color); + color = _mix(renderer->alphaA[x], current, renderer->alphaB[x], color); } else { color = (current & 0x00FFFFFF) | ((current << 1) & FLAG_REBLEND); } } else { color = (color & ~FLAG_TARGET_2) | (current & FLAG_OBJWIN); } - *pixel = color; + renderer->row[x] = color; } -static inline void _compositeBlendNoObjwin(struct GBAVideoSoftwareRenderer* renderer, uint32_t* pixel, uint32_t color, uint32_t current) { +static inline void _compositeBlendNoObjwin(struct GBAVideoSoftwareRenderer* renderer, int x, uint32_t color, uint32_t current) { if (!IS_WRITABLE(current)) { \ return; \ } \ if (color >= current) { if (current & FLAG_TARGET_1 && color & FLAG_TARGET_2) { - color = _mix(renderer->blda, current, renderer->bldb, color); + color = _mix(renderer->alphaA[x], current, renderer->alphaB[x], color); } else { color = (current & 0x00FFFFFF) | ((current << 1) & FLAG_REBLEND); } } else { color = color & ~FLAG_TARGET_2; } - *pixel = color; + renderer->row[x] = color; } -static inline void _compositeNoBlendObjwin(struct GBAVideoSoftwareRenderer* renderer, uint32_t* pixel, uint32_t color, +static inline void _compositeNoBlendObjwin(struct GBAVideoSoftwareRenderer* renderer, int x, uint32_t color, uint32_t current) { UNUSED(renderer); if (color < current) { @@ -79,16 +79,16 @@ static inline void _compositeNoBlendObjwin(struct GBAVideoSoftwareRenderer* rend } else { color = (current & 0x00FFFFFF) | ((current << 1) & FLAG_REBLEND); } - *pixel = color; + renderer->row[x] = color; } -static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* renderer, uint32_t* pixel, uint32_t color, +static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* renderer, int x, uint32_t color, uint32_t current) { UNUSED(renderer); if (color >= current) { color = (current & 0x00FFFFFF) | ((current << 1) & FLAG_REBLEND); } - *pixel = color; + renderer->row[x] = color; } #define COMPOSITE_16_OBJWIN(BLEND, IDX) \ @@ -101,11 +101,11 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re if (current & FLAG_OBJWIN) { \ mergedFlags = objwinFlags; \ } \ - _composite ## BLEND ## Objwin(renderer, &pixel[IDX], color | mergedFlags, current); \ + _composite ## BLEND ## Objwin(renderer, outX + IDX, color | mergedFlags, current); \ } #define COMPOSITE_16_NO_OBJWIN(BLEND, IDX) \ - _composite ## BLEND ## NoObjwin(renderer, &pixel[IDX], palette[pixelData] | flags, current); + _composite ## BLEND ## NoObjwin(renderer, outX + IDX, palette[pixelData] | flags, current); #define COMPOSITE_256_OBJWIN(BLEND, IDX) \ if (!IS_WRITABLE(current)) { \ @@ -117,14 +117,14 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re if (current & FLAG_OBJWIN) { \ mergedFlags = objwinFlags; \ } \ - _composite ## BLEND ## Objwin(renderer, &pixel[IDX], color | mergedFlags, current); \ + _composite ## BLEND ## Objwin(renderer, outX + IDX, color | mergedFlags, current); \ } #define COMPOSITE_256_NO_OBJWIN COMPOSITE_16_NO_OBJWIN #define BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, IDX) \ pixelData = tileData & 0xF; \ - current = pixel[IDX]; \ + current = renderer->row[outX + IDX]; \ if (pixelData && IS_WRITABLE(current)) { \ COMPOSITE_16_ ## OBJWIN (BLEND, IDX); \ } \ @@ -132,7 +132,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re #define BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, IDX) \ pixelData = tileData & 0xFF; \ - current = pixel[IDX]; \ + current = renderer->row[outX + IDX]; \ if (pixelData && IS_WRITABLE(current)) { \ COMPOSITE_256_ ## OBJWIN (BLEND, IDX); \ } \ diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 5f0b8f690..240a6d53a 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -268,6 +268,7 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender if (softwareRenderer->bldb > 0x10) { softwareRenderer->bldb = 0x10; } + softwareRenderer->blendDirty = true; value &= 0x1F1F; break; case REG_BLDY: @@ -768,7 +769,7 @@ void GBAVideoSoftwareRendererPostprocessBuffer(struct GBAVideoSoftwareRenderer* for (; x < end; ++x) { uint32_t color = softwareRenderer->row[x]; if (color & FLAG_TARGET_1) { - softwareRenderer->row[x] = _mix(softwareRenderer->bldb, backdrop, softwareRenderer->blda, color); + softwareRenderer->row[x] = _mix(softwareRenderer->alphaB[x], backdrop, softwareRenderer->alphaA[x], color); } } } @@ -842,6 +843,8 @@ int GBAVideoSoftwareRendererPreprocessSpriteLayer(struct GBAVideoSoftwareRendere static void _updatePalettes(struct GBAVideoSoftwareRenderer* renderer) { int i; + memset(renderer->alphaA, renderer->blda, sizeof(renderer->alphaA)); + memset(renderer->alphaB, renderer->bldb, sizeof(renderer->alphaB)); if (renderer->blendEffect == BLEND_BRIGHTEN) { for (i = 0; i < 512; ++i) { renderer->variantPalette[i] = _brighten(renderer->normalPalette[i], renderer->bldy);