all repos — mgba @ 3d22afe0aaf82e87bc27687a01d22210e4c8f75d

mGBA Game Boy Advance Emulator

DS Video: Fix OBJ sorting and bounds
Vicki Pfau vi@endrift.com
Mon, 27 Mar 2017 17:14:50 -0700
commit

3d22afe0aaf82e87bc27687a01d22210e4c8f75d

parent

a5bcfc7c80db49fadd652677ed4a3b87c6f235e5

M include/mgba/internal/gba/renderers/video-software.hinclude/mgba/internal/gba/renderers/video-software.h

@@ -164,6 +164,7 @@ int oamDirty;

int oamMax; struct GBAVideoSoftwareSprite sprites[128]; int tileStride; + bool combinedObjSort; int start; int end;
M src/ds/renderers/software.csrc/ds/renderers/software.c

@@ -148,8 +148,11 @@ renderer->d.putPixels = DSVideoSoftwareRendererPutPixels;

renderer->engA.d.cache = NULL; GBAVideoSoftwareRendererCreate(&renderer->engA); + renderer->engA.combinedObjSort = true; + renderer->engB.d.cache = NULL; GBAVideoSoftwareRendererCreate(&renderer->engB); + renderer->engB.combinedObjSort = true; } static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer) {
M src/gba/renderers/video-software.csrc/gba/renderers/video-software.c

@@ -62,6 +62,7 @@ renderer->d.disableBG[2] = false;

renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; renderer->tileStride = 0x20; + renderer->combinedObjSort = false; renderer->masterEnd = VIDEO_HORIZONTAL_PIXELS; renderer->masterHeight = VIDEO_VERTICAL_PIXELS; renderer->masterScanlines = VIDEO_VERTICAL_TOTAL_PIXELS;

@@ -477,22 +478,32 @@ }

static void _cleanOAM(struct GBAVideoSoftwareRenderer* renderer) { int i; + int p; int oamMax = 0; - for (i = 0; i < 128; ++i) { - struct GBAObj obj; - LOAD_16(obj.a, 0, &renderer->d.oam->obj[i].a); - LOAD_16(obj.b, 0, &renderer->d.oam->obj[i].b); - LOAD_16(obj.c, 0, &renderer->d.oam->obj[i].c); - if (GBAObjAttributesAIsTransformed(obj.a) || !GBAObjAttributesAIsDisable(obj.a)) { - int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(obj.a) * 4 + GBAObjAttributesBGetSize(obj.b)][1]; - if (GBAObjAttributesAIsTransformed(obj.a)) { - height <<= GBAObjAttributesAGetDoubleSize(obj.a); + int maxP = 1; + if (renderer->combinedObjSort) { + maxP = 4; + } + for (p = 0; p < maxP; ++p) { + for (i = 0; i < 128; ++i) { + struct GBAObj obj; + LOAD_16(obj.a, 0, &renderer->d.oam->obj[i].a); + LOAD_16(obj.b, 0, &renderer->d.oam->obj[i].b); + LOAD_16(obj.c, 0, &renderer->d.oam->obj[i].c); + if (renderer->combinedObjSort && GBAObjAttributesCGetPriority(obj.c) != p) { + continue; } - if (GBAObjAttributesAGetY(obj.a) < renderer->masterHeight || GBAObjAttributesAGetY(obj.a) + height >= renderer->masterScanlines) { - renderer->sprites[oamMax].y = GBAObjAttributesAGetY(obj.a); - renderer->sprites[oamMax].endY = GBAObjAttributesAGetY(obj.a) + height; - renderer->sprites[oamMax].obj = obj; - ++oamMax; + if (GBAObjAttributesAIsTransformed(obj.a) || !GBAObjAttributesAIsDisable(obj.a)) { + int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(obj.a) * 4 + GBAObjAttributesBGetSize(obj.b)][1]; + if (GBAObjAttributesAIsTransformed(obj.a)) { + height <<= GBAObjAttributesAGetDoubleSize(obj.a); + } + if (GBAObjAttributesAGetY(obj.a) < renderer->masterHeight || GBAObjAttributesAGetY(obj.a) + height >= 256) { + renderer->sprites[oamMax].y = GBAObjAttributesAGetY(obj.a); + renderer->sprites[oamMax].endY = GBAObjAttributesAGetY(obj.a) + height; + renderer->sprites[oamMax].obj = obj; + ++oamMax; + } } } }