DS Video: Fix OBJ sorting and bounds

This commit is contained in:
Vicki Pfau 2017-03-27 17:14:50 -07:00
parent a5bcfc7c80
commit 3d22afe0aa
3 changed files with 29 additions and 14 deletions

View File

@ -164,6 +164,7 @@ struct GBAVideoSoftwareRenderer {
int oamMax;
struct GBAVideoSoftwareSprite sprites[128];
int tileStride;
bool combinedObjSort;
int start;
int end;

View File

@ -148,8 +148,11 @@ void DSVideoSoftwareRendererCreate(struct DSVideoSoftwareRenderer* renderer) {
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) {

View File

@ -62,6 +62,7 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) {
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 _breakWindowInner(struct GBAVideoSoftwareRenderer* softwareRenderer,
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;
}
}
}
}