GB Video: Implement DMG-style sprite ordering

This commit is contained in:
Vicki Pfau 2023-03-03 00:17:08 -08:00
parent 30fc000734
commit 59ebf1c12d
9 changed files with 31 additions and 6 deletions

View File

@ -5,6 +5,7 @@ Features:
- New unlicensed GB mappers: NT (older types 1 and 2), Li Cheng, GGB-81 - New unlicensed GB mappers: NT (older types 1 and 2), Li Cheng, GGB-81
- Debugger: Add range watchpoints - Debugger: Add range watchpoints
Emulation fixes: Emulation fixes:
- GB Video: Implement DMG-style sprite ordering
- GBA Audio: Fix improperly deserializing GB audio registers (fixes mgba.io/i/2793) - GBA Audio: Fix improperly deserializing GB audio registers (fixes mgba.io/i/2793)
- GBA Memory: Make VRAM access stalls only apply to BG RAM - GBA Memory: Make VRAM access stalls only apply to BG RAM
- GBA SIO: Fix SIOCNT SI pin value after attaching player 2 (fixes mgba.io/i/2805) - GBA SIO: Fix SIOCNT SI pin value after attaching player 2 (fixes mgba.io/i/2805)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

View File

@ -0,0 +1,6 @@
[testinfo]
skip=15
frames=1
[ports.cinema]
sgb.borders=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 702 B

After

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 711 B

View File

@ -571,20 +571,38 @@ static void _cleanOAM(struct GBVideoSoftwareRenderer* renderer, int y) {
} }
int o = 0; int o = 0;
int i; int i;
int16_t ids[GB_VIDEO_MAX_LINE_OBJ];
for (i = 0; i < GB_VIDEO_MAX_OBJ && o < GB_VIDEO_MAX_LINE_OBJ; ++i) { for (i = 0; i < GB_VIDEO_MAX_OBJ && o < GB_VIDEO_MAX_LINE_OBJ; ++i) {
uint8_t oy = renderer->d.oam->obj[i].y; uint8_t oy = renderer->d.oam->obj[i].y;
if (y < oy - 16 || y >= oy - 16 + spriteHeight) { if (y < oy - 16 || y >= oy - 16 + spriteHeight) {
continue; continue;
} }
// TODO: Sort ids[o] = (renderer->d.oam->obj[i].x << 7) | i;
renderer->obj[o].obj = renderer->d.oam->obj[i];
renderer->obj[o].index = i;
++o; ++o;
if (o == 10) {
break;
}
} }
renderer->objMax = o; renderer->objMax = o;
if (renderer->model < GB_MODEL_CGB) {
// Terrble n^2 sort, but it's only 10 elements so it shouldn't be that bad
int16_t ids2[GB_VIDEO_MAX_LINE_OBJ];
int min = -1;
int j;
for (i = 0; i < o; ++i) {
int min2 = 0xFFFF;
for (j = 0; j < o; ++j) {
if (ids[j] > min && ids[j] < min2) {
min2 = ids[j];
}
}
min = min2;
ids2[i] = min;
}
memcpy(ids, ids2, sizeof(ids));
}
for (i = 0; i < o; ++i) {
int id = ids[i] & 0x7F;
renderer->obj[i].obj = renderer->d.oam->obj[id];
renderer->obj[i].index = id;
}
} }
static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y) { static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y) {