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
- Debugger: Add range watchpoints
Emulation fixes:
- GB Video: Implement DMG-style sprite ordering
- 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 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 i;
int16_t ids[GB_VIDEO_MAX_LINE_OBJ];
for (i = 0; i < GB_VIDEO_MAX_OBJ && o < GB_VIDEO_MAX_LINE_OBJ; ++i) {
uint8_t oy = renderer->d.oam->obj[i].y;
if (y < oy - 16 || y >= oy - 16 + spriteHeight) {
continue;
}
// TODO: Sort
renderer->obj[o].obj = renderer->d.oam->obj[i];
renderer->obj[o].index = i;
ids[o] = (renderer->d.oam->obj[i].x << 7) | i;
++o;
if (o == 10) {
break;
}
}
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) {