all repos — mgba @ f1b4e7039f0c61699788f1ef95fcd305a61d649d

mGBA Game Boy Advance Emulator

Fix sprites whose tiles go out of bounds
Jeffrey Pfau jeffrey@endrift.com
Wed, 09 Jul 2014 01:32:02 -0700
commit

f1b4e7039f0c61699788f1ef95fcd305a61d649d

parent

79cfc4fd0a945761bd6d9bbf82c9282af3d4b668

1 files changed, 8 insertions(+), 6 deletions(-)

jump to
M src/gba/renderers/video-software.csrc/gba/renderers/video-software.c

@@ -1420,14 +1420,14 @@ #define SPRITE_XBASE_16(localX) unsigned xBase = (localX & ~0x7) * 4 + ((localX >> 1) & 2);

#define SPRITE_YBASE_16(localY) unsigned yBase = (localY & ~0x7) * (renderer->dispcnt.objCharacterMapping ? width >> 1 : 0x80) + (localY & 0x7) * 4; #define SPRITE_DRAW_PIXEL_16_NORMAL(localX) \ - unsigned tileData = renderer->d.vram[(yBase + charBase + xBase) >> 1]; \ + unsigned tileData = vramBase[((yBase + charBase + xBase) & 0x7FFF) >> 1]; \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ if (tileData && (renderer->spriteLayer[outX] & FLAG_ORDER_MASK) > flags) { \ renderer->spriteLayer[outX] = palette[tileData] | flags; \ } #define SPRITE_DRAW_PIXEL_16_OBJWIN(localX) \ - unsigned tileData = renderer->d.vram[(yBase + charBase + xBase) >> 1]; \ + unsigned tileData = vramBase[((yBase + charBase + xBase) & 0x7FFF) >> 1]; \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ if (tileData) { \ renderer->row[outX] |= FLAG_OBJWIN; \

@@ -1437,14 +1437,14 @@ #define SPRITE_XBASE_256(localX) unsigned xBase = (localX & ~0x7) * 8 + (localX & 6);

#define SPRITE_YBASE_256(localY) unsigned yBase = (localY & ~0x7) * (renderer->dispcnt.objCharacterMapping ? width : 0x80) + (localY & 0x7) * 8; #define SPRITE_DRAW_PIXEL_256_NORMAL(localX) \ - unsigned tileData = renderer->d.vram[(yBase + charBase + xBase) >> 1]; \ + unsigned tileData = vramBase[((yBase + charBase + xBase) & 0x7FFF) >> 1]; \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ if (tileData && (renderer->spriteLayer[outX] & FLAG_ORDER_MASK) > flags) { \ renderer->spriteLayer[outX] = palette[tileData] | flags; \ } #define SPRITE_DRAW_PIXEL_256_OBJWIN(localX) \ - unsigned tileData = renderer->d.vram[(yBase + charBase + xBase) >> 1]; \ + unsigned tileData = vramBase[((yBase + charBase + xBase) & 0x7FFF) >> 1]; \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ if (tileData) { \ renderer->row[outX] |= FLAG_OBJWIN; \

@@ -1459,7 +1459,8 @@ uint32_t flags = sprite->priority << OFFSET_PRIORITY;

flags |= FLAG_TARGET_1 * ((renderer->currentWindow.blendEnable && renderer->target1Obj && renderer->blendEffect == BLEND_ALPHA) || sprite->mode == OBJ_MODE_SEMITRANSPARENT); flags |= FLAG_OBJWIN * (sprite->mode == OBJ_MODE_OBJWIN); int x = sprite->x; - unsigned charBase = BASE_TILE + sprite->tile * 0x20; + uint16_t* vramBase = &renderer->d.vram[BASE_TILE >> 1]; + unsigned charBase = sprite->tile * 0x20; int variant = renderer->target1Obj && renderer->currentWindow.blendEnable && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); if (sprite->mode == OBJ_MODE_SEMITRANSPARENT && renderer->target2Bd) { // Hack: if a sprite is blended, then the variant palette is not used, but we don't know if it's blended in advance

@@ -1527,7 +1528,8 @@ uint32_t flags = sprite->priority << OFFSET_PRIORITY;

flags |= FLAG_TARGET_1 * ((renderer->currentWindow.blendEnable && renderer->target1Obj && renderer->blendEffect == BLEND_ALPHA) || sprite->mode == OBJ_MODE_SEMITRANSPARENT); flags |= FLAG_OBJWIN * (sprite->mode == OBJ_MODE_OBJWIN); int x = sprite->x; - unsigned charBase = BASE_TILE + sprite->tile * 0x20; + uint16_t* vramBase = &renderer->d.vram[BASE_TILE >> 1]; + unsigned charBase = sprite->tile * 0x20; struct GBAOAMMatrix* mat = &renderer->d.oam->mat[sprite->matIndex]; int variant = renderer->target1Obj && renderer->currentWindow.blendEnable && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); if (sprite->mode == OBJ_MODE_SEMITRANSPARENT && renderer->target2Bd) {