From 59ebf1c12dcbbe0141000cddccf667cd42e386a1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 3 Mar 2023 00:17:08 -0800 Subject: [PATCH] GB Video: Implement DMG-style sprite ordering --- CHANGES | 1 + cinema/gb/acid/cgb-acid2/baseline_0000.png | Bin 0 -> 1362 bytes cinema/gb/acid/cgb-acid2/test.gbc | Bin 0 -> 32768 bytes cinema/gb/acid/config.ini | 6 ++++ cinema/gb/acid/dmg-acid2/baseline_0000.png | Bin 0 -> 1360 bytes cinema/gb/acid/dmg-acid2/test.gb | Bin 0 -> 32768 bytes .../sprite_priority/baseline_0000.png | Bin 702 -> 703 bytes .../sprite_priority/xbaseline_0000.png | Bin 711 -> 0 bytes src/gb/renderers/software.c | 30 ++++++++++++++---- 9 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 cinema/gb/acid/cgb-acid2/baseline_0000.png create mode 100644 cinema/gb/acid/cgb-acid2/test.gbc create mode 100644 cinema/gb/acid/config.ini create mode 100644 cinema/gb/acid/dmg-acid2/baseline_0000.png create mode 100644 cinema/gb/acid/dmg-acid2/test.gb delete mode 100644 cinema/gb/mooneye-gb/manual-only/sprite_priority/xbaseline_0000.png diff --git a/CHANGES b/CHANGES index ffda80576..169a69a15 100644 --- a/CHANGES +++ b/CHANGES @@ -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) diff --git a/cinema/gb/acid/cgb-acid2/baseline_0000.png b/cinema/gb/acid/cgb-acid2/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..4baff34257e5a33acb5b125d16ffa5dea6b3be52 GIT binary patch literal 1362 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Tq1r;B4q#hkZu4pu%^5O8b% zyG=`eGT$AiK0nKohPpeLpTF3)g*|7cYl8z*=9ka=_1jyfwhQ_zGk?0pb67$5=bzYr zx7KejklAi~qqW?@&n`ayp~b<+d%s1@yUZ+_IUlf#{H+iYJK0`apL8d_}?WPa=h1WJk?Xb|MXwI<-v{5-d@zcvGsM|1B+kp zw&uSVJ{D3iNAmu%6j^Ui&HSFYgPgm|UYtF@`huM9u{9+zBKJ$zgl)LwIjy$+b4TyL zAJ2miAM(3?gkNn9lPJC{``3U`SCvo)Yb?rZCc**bgDpR-I+&9d9wBT ze9AL)oL441{cbz`fs-G<7whV|Q;r49-Vk)~)0)o0vMh1+V>2Eq@8XfNW80k&yCEn_ z?EbRl+iF}lCs;f3-doztCzRxMvVVQOy7%w6E!&?;-|hGzactkLoRXGD;<@hcw~DWg zEzo!%aqzxZjPSP78oQhmsSUPB@bXNeAbm{8{L0;F-E|saRi9iW1aLAo|c>SOXuQnnR zWO1$A`d+@r*ld=1>E(j>P?4H#yKlC17iqiR-Tubo6Jwv@`po^mt3`7T?CM{>N@dS8 z6K;TWZ+G=I@7yWr7cHbRiF00Qm4i{cQuqgxwF!$h zKemuQB7Og5=hHb4A1(UG$M@`+oN;bs!|I#77S;-ufAw~{KA+zoUH|Uu4vUut`zP`?c(PL9(%xBFM#Ta)(L<4Vb|^O@os zvoep literal 0 HcmV?d00001 diff --git a/cinema/gb/acid/cgb-acid2/test.gbc b/cinema/gb/acid/cgb-acid2/test.gbc new file mode 100644 index 0000000000000000000000000000000000000000..5f71bd36060b46eefcf7785f81ce16a5a6c5fc67 GIT binary patch literal 32768 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/acid/dmg-acid2/test.gb b/cinema/gb/acid/dmg-acid2/test.gb new file mode 100644 index 0000000000000000000000000000000000000000..a25ef9485e1ab176c80415548f053ca950b3e4f5 GIT binary patch literal 32768 zcmeI4e`s6R700iB*s@&zcyg5DQDaNSPSdg!FIkCFwCCqvjqIhxGgD&v&r~;4#AY(Z zra?)?ldO!AnBqAJ+iXbVtbt}TrD+EnjI_nAsT<)R>0g7eW_=`?&0t%!xH!%%-rc$P zzGumDvi;MI(Vg>ndiQ(JdFP({xli}M_XzoN?9X3Ln*V;5>2AxyU&GQ0^_6`#!=Uc7PR`uLSAhh92d@t3(9pN&sk`Q0wL{kgq6TG~3>cNSJV@vCnx ze}i6|-xrv#33%Trb`jk&O6Io&yvg&jRN=1omwVQpx?nWCn$?vYvk)r_(CjX9&Z6*O zPmxO*Guojd7fD(q3yXoVcDSNb5dArsne^2|iSD~{j>}P@fEV3W{vQ{aVXdPaUwYYTcD5=h}-dAM_x^`Hv zGchy!H@OL ziM&iZ^K9KON$br#x6|yjfSK*hev8ElW=3rCb1#qJDGL4Iwq3AV&Geh^%8|H}WsMa{ck zR15{=_2oC$i#8gx&OtY_Y&avoNv8~zG z*c{m;GELbUT1joJ&#~fItek81(F{a`WwV)OZArT`_4(B2-Q9MnyVu^-+imae?X^dJ z%EeJdx%jCs1lQ2TPo?bvA~k)VNWOj|DR2gUM5NvWL<+$*GC-s#^u-Pm2{zS;uZ%>L zG9?m#vm4IdawQUiGXiI{ob-IlNqYRHq^F;qPU3r}h$zn#6W`$?k8-%!6Z>vu-sDTb zUU?<21DbpHZq$Y9)~#GmNeLliV>!KLi`$*aa+HJ$@ktH8cKqR2)Fx-FWm0sWuXY^>~uOiJI|dnHKXQs z-@9jOao^OGsXMsEVy2e3WipbaX{^s>nCZ9M{r>iLzu(l1+L<#izG!N8RTQ&2LYRMe z_{b5{|HKp9!LD94b!TS_SX-N^>+Ah~k0)2Z*>7G&eWj&Nr`>L|v3;(k#bPNfy?fVg zudWs~o3VIB0!RP}AOR$R1dsp{Kmter2_OL^fCP{L5*^Akz0x=`l1kmYDfH7%cXTv1Zryt5kkH|9Fc=QEg9*KD zTQInPe=ykCDD>c9LqmPN*K59Q$=;o0Z8Z8JFPv6P!z+DIKS0p*IazcwIRj*JnU~3}-r#AS9Pxfn=_#mon%xtR$J?P2_U!ZghJTrl3G?B4oc`U6H~6IVyR}ud zwY=Vxex9D7_vr~%ud3=Fac$%WK11|=rIR1<`mm92+RT?o&<~;gVd5A>fZyQ7|AlP6 zrZ)N1)g_M5PqOFeCy66D=@WwJ~JwK>mPyd zG{p1qz|Zbwqw(?h+J*fMtP1{ov6;YHXK!bJoXwigm;Nd|Pdq-8fxK{-CeUee0?S$##moIKe1Qx=f#-MdVWJs z!)##p z>a+3q`hKv!U&%7;ZVRhp`T{%=G9mE1rs-Ms&wQ|D+VxS-Kho^WF6z~J5}5rU{bbda zM`G`KR@3n1nQEJhjCzS;Atmrdne>5r@ErHtPuG`wvgwK+R9h<|E6JN>Pu?u@tfl82 zfy-Kp)&`%LxvF)*M`mtodoO$8^EJdX|5N~4dc}qL-2wSKnv$l8-|YY4jtAF-y+{BF zAOR$R1dsp{Kmter2_OL^fCP{L5xg88td#JK|n)1Nz+9g%S6IIDjs=}w*FHomy2 z{BPIh=Pj4nQ|VP~z4-C`cjqO2+0M1^yI*9yIyfI(* z#(tfcWq0Mym9(e#emwj2>t*q6OVj(!4{P`lL9oL+qju^J9q+ibny4R9^9~|{=Xv?X z0%U%A0xY=x*-M-=28A0aC^>*(`KR7sPC76$DkcjsnTXwym5-MelPPLC!~g`Iu6{1- HoD!M<*n{Xy delta 459 zcmV;+0W|)<1-=E4Br}CcL_t(|+U?p=a)K}b0MVr5eeo#XIDTYIGbBWab}Z|@FN%R8 zD~L)=DFt!;e0l@)x03+^Auqd>sq6KcCvLafr?*P)lTu14Ez6P~>S>*wr)W3>!xO_6MwkN^pY{g5JLBhuo%~0kmbQy{m|C@?t1FMt3|r&IXeF7 z_MFjV;Iiw-Emwob%RbE+cE6t5!S$HA?K!EL!1XgvDXn%yo>PzC+H2#w?RvtS&IGG9 z11b*8pQ4Z2I;FSs_Z*So;A>@T!TQhcOX}=qF0$$!vGY8ZhjmZpWq*FXb7PG8&(+MM zn|ky#Ti@*R(tiCn=HF(IVy8U%%Ej8C?)O||5w0UN;OAht$-w3Qo-)yWbTFr# zS+BFUXZ+S`5B=Xg+k86nr|A6r+Z(vrd%M~_)qSYDs@2S`@!k3D;&bacHQ$5bd=G{* zFr0zm3=C&rxJ&4Ll^eJ$OPOYTTKHNX!EgqKGccTi;S3DtchPVj!IO~!6czp+4CfIH zXJ9x3!xb*0|Qf^r;B4q#hkad0*jgq7#J=t zdCa+2JSd1XdUD+#}M?WUzGM4RDV{av3`xL>Mom@sD% znr^Uxdj0J=9foZJyW(4pM$|h_V^4qT9DRECYfbiW|Cj5YzxdI9yVz}V(E4^0U60G#Jtjk{C`+D1J&UzE!kZiUPnHlpJ_1~Ix z>Gsp=z7qu>_HO!m-o=}if{dE`{RmD6T+x-_nRN0@Nq;J emKYo$p?!?nozi0Sr7|yq5~!!EpUXO@geCyFDmo?r diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index a5e41162f..d157920fa 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -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) {