vdp rendering, fix window with mixed prio tiles
authorkub <derkub@gmail.com>
Fri, 25 Sep 2020 19:16:44 +0000 (21:16 +0200)
committerkub <derkub@gmail.com>
Fri, 25 Sep 2020 19:19:29 +0000 (21:19 +0200)
pico/draw.c
pico/draw_arm.S
pico/pico.h

index 3ddc553..02dffec 100644 (file)
@@ -549,11 +549,9 @@ static void DrawWindow(int tstart, int tend, int prio, int sh,
 \r
   tilex=tstart<<1;\r
 \r
-  if (!(est->rendstatus & PDRAW_WND_DIFF_PRIO)) {\r
-    // check the first tile code\r
-    code = PicoMem.vram[nametab + tilex];\r
-    // if the whole window uses same priority (what is often the case), we may be able to skip this field\r
-    if ((code>>15) != prio) return;\r
+  if (prio && !(est->rendstatus & PDRAW_WND_HIGH_PRIO)) {\r
+    // all tiles processed in low prio pass\r
+    return;\r
   }\r
 \r
   tend<<=1;\r
@@ -569,11 +567,11 @@ static void DrawWindow(int tstart, int tend, int prio, int sh,
       int pal;\r
 \r
       code = PicoMem.vram[nametab + tilex];\r
-      if (code==blank) continue;\r
       if ((code>>15) != prio) {\r
-        est->rendstatus |= PDRAW_WND_DIFF_PRIO;\r
+        est->rendstatus |= PDRAW_WND_HIGH_PRIO;\r
         continue;\r
       }\r
+      if (code==blank) continue;\r
 \r
       // Get tile address/2:\r
       addr=(code&0x7ff)<<4;\r
@@ -601,9 +599,8 @@ static void DrawWindow(int tstart, int tend, int prio, int sh,
       int pal;\r
 \r
       code = PicoMem.vram[nametab + tilex];\r
-      if(code==blank) continue;\r
       if((code>>15) != prio) {\r
-        est->rendstatus |= PDRAW_WND_DIFF_PRIO;\r
+        est->rendstatus |= PDRAW_WND_HIGH_PRIO;\r
         continue;\r
       }\r
 \r
@@ -616,6 +613,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh,
       } else {\r
         pal |= 0x80;\r
       }\r
+      if(code==blank) continue;\r
 \r
       // Get tile address/2:\r
       addr=(code&0x7ff)<<4;\r
@@ -1404,8 +1402,10 @@ static NOINLINE void PrepareSprites(int max_lines)
     int y;\r
     printf("c%03i: f %x c %2i/%2i w %2i: ", u, HighLnSpr[u][1],\r
            HighLnSpr[u][0], HighLnSpr[u][3], HighLnSpr[u][2]);\r
-    for (y = 0; y < HighLnSpr[u][0]; y++)\r
-      printf(" %i", HighLnSpr[u][y+4]);\r
+    for (y = 0; y < HighLnSpr[u][0]; y++) {\r
+      int *sp = HighPreSpr + (HighLnSpr[u][y+4]&0x7f) * 2;\r
+      printf(" %i(%x/%x)", HighLnSpr[u][y+4],sp[0],sp[1]);\r
+    }\r
     printf("\n");\r
   }\r
 #endif\r
@@ -1634,7 +1634,7 @@ static int DrawDisplay(int sh)
   int win=0, edge=0, hvwind=0, lflags;\r
   int maxw, maxcells;\r
 \r
-  est->rendstatus &= ~(PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO);\r
+  est->rendstatus &= ~(PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO|PDRAW_WND_HIGH_PRIO);\r
 \r
   if (pvid->reg[12]&1) {\r
     maxw = 328; maxcells = 40;\r
index 54d0227..7dab089 100644 (file)
@@ -14,7 +14,7 @@
 .extern DrawStripInterlace\r
 \r
 .equ PDRAW_SPRITES_MOVED, (1<<0)\r
-.equ PDRAW_WND_DIFF_PRIO, (1<<1)\r
+.equ PDRAW_WND_HIGH_PRIO, (1<<1)\r
 .equ PDRAW_PARSE_SPRITES, (1<<2)\r
 .equ PDRAW_DIRTY_SPRITES, (1<<4)\r
 .equ PDRAW_PLANE_HI_PRIO, (1<<6)\r
@@ -946,8 +946,8 @@ DrawSpritesSHi:
 \r
 DrawSpriteSHi:\r
     @ draw next sprite\r
-    ldrb    r0, [r10,#-1]!\r
     ldr     r7, [sp]        @ est\r
+    ldrb    r0, [r10,#-1]!\r
     ldr     r1, [r7, #OFS_EST_HighPreSpr]\r
     cmp     r0, #0xff\r
     ldmeqfd sp!, {r1,r3-r11,pc} @ end of list\r
@@ -966,6 +966,7 @@ DrawSpriteSHi:
     orr     r9, r9, #0x90000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)\r
     cmp     r12,r9, lsr #28 @ sh/hi with pal3?\r
     cmpne   r3, #1          @ if not, is it hi prio?\r
+    strne   r3, [sp, #4]    @ reset last sprite width\r
     bne     DrawSpriteSHi   @ non-operator low sprite, already drawn\r
 \r
     ldr     r3, [r0]        @ sprite[0]\r
@@ -1309,13 +1310,11 @@ DrawWindow:
     @ fetch the first code now\r
     ldrh    r7, [lr, r12]\r
 \r
-    ands    r6, r6, #PDRAW_WND_DIFF_PRIO\r
-    orr     r6, r6, r2\r
-\r
-    eoreq   r8, r2, r7, lsr #15   @ do prio bits differ?\r
-    cmpeq   r8, #1\r
+    ands    r6, r6, #PDRAW_WND_HIGH_PRIO\r
+    cmpeq   r2, #1                @ prio && !(rendstatus & WND_HIGH_PRIO)?\r
     ldmeqfd sp!, {r4-r11,pc}      @ yes, assume that whole window uses same priority\r
 \r
+    orr     r6, r6, r2\r
     orr     r6, r6, r3, lsl #8    @ shadow mode\r
 \r
     sub     r8, r1, r0\r
@@ -1340,7 +1339,7 @@ DrawWindow:
 \r
     eor     r5, r6, r7, lsr #15\r
     tst     r5, #1\r
-    orrne   r6, r6, #2      @ wrong pri\r
+    orrne   r6, r6, #PDRAW_WND_HIGH_PRIO @ wrong pri\r
     bne     .dwloop\r
 \r
     cmp     r7, r9\r
@@ -1406,7 +1405,7 @@ DrawWindow:
     b       .dw_shadow_done\r
 \r
 .dwloop_end:\r
-    and     r2, r6, #PDRAW_WND_DIFF_PRIO\r
+    and     r2, r6, #PDRAW_WND_HIGH_PRIO\r
     ldmfd   sp!, {r4-r11,lr}\r
     ldr     r0, [sp]\r
     ldr     r1, [r0, #OFS_EST_rendstatus]\r
index 3c800f6..6e99045 100644 (file)
@@ -199,7 +199,7 @@ void vidConvCpyRGB565(void *to, void *from, int pixels);
 void PicoDoHighPal555(int sh, int line, struct PicoEState *est);\r
 // internals, NB must keep in sync with ASM draw functions\r
 #define PDRAW_SPRITES_MOVED (1<<0) // SAT address modified\r
-#define PDRAW_WND_DIFF_PRIO (1<<1) // not all window tiles use same priority\r
+#define PDRAW_WND_HIGH_PRIO (1<<1) // have window with high prio tiles\r
 #define PDRAW_PARSE_SPRITES (1<<2) // SAT needs parsing\r
 #define PDRAW_INTERLACE     (1<<3)\r
 #define PDRAW_DIRTY_SPRITES (1<<4) // SAT modified\r