ソースを参照

vdp rendering, fix window with mixed prio tiles

kub 3 年 前
コミット
47548249a0
3 ファイル変更21 行追加22 行削除
  1. 12 12
      pico/draw.c
  2. 8 9
      pico/draw_arm.S
  3. 1 1
      pico/pico.h

+ 12 - 12
pico/draw.c

@@ -549,11 +549,9 @@ static void DrawWindow(int tstart, int tend, int prio, int sh,
 
   tilex=tstart<<1;
 
-  if (!(est->rendstatus & PDRAW_WND_DIFF_PRIO)) {
-    // check the first tile code
-    code = PicoMem.vram[nametab + tilex];
-    // if the whole window uses same priority (what is often the case), we may be able to skip this field
-    if ((code>>15) != prio) return;
+  if (prio && !(est->rendstatus & PDRAW_WND_HIGH_PRIO)) {
+    // all tiles processed in low prio pass
+    return;
   }
 
   tend<<=1;
@@ -569,11 +567,11 @@ static void DrawWindow(int tstart, int tend, int prio, int sh,
       int pal;
 
       code = PicoMem.vram[nametab + tilex];
-      if (code==blank) continue;
       if ((code>>15) != prio) {
-        est->rendstatus |= PDRAW_WND_DIFF_PRIO;
+        est->rendstatus |= PDRAW_WND_HIGH_PRIO;
         continue;
       }
+      if (code==blank) continue;
 
       // Get tile address/2:
       addr=(code&0x7ff)<<4;
@@ -601,9 +599,8 @@ static void DrawWindow(int tstart, int tend, int prio, int sh,
       int pal;
 
       code = PicoMem.vram[nametab + tilex];
-      if(code==blank) continue;
       if((code>>15) != prio) {
-        est->rendstatus |= PDRAW_WND_DIFF_PRIO;
+        est->rendstatus |= PDRAW_WND_HIGH_PRIO;
         continue;
       }
 
@@ -616,6 +613,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh,
       } else {
         pal |= 0x80;
       }
+      if(code==blank) continue;
 
       // Get tile address/2:
       addr=(code&0x7ff)<<4;
@@ -1404,8 +1402,10 @@ static NOINLINE void PrepareSprites(int max_lines)
     int y;
     printf("c%03i: f %x c %2i/%2i w %2i: ", u, HighLnSpr[u][1],
            HighLnSpr[u][0], HighLnSpr[u][3], HighLnSpr[u][2]);
-    for (y = 0; y < HighLnSpr[u][0]; y++)
-      printf(" %i", HighLnSpr[u][y+4]);
+    for (y = 0; y < HighLnSpr[u][0]; y++) {
+      int *sp = HighPreSpr + (HighLnSpr[u][y+4]&0x7f) * 2;
+      printf(" %i(%x/%x)", HighLnSpr[u][y+4],sp[0],sp[1]);
+    }
     printf("\n");
   }
 #endif
@@ -1634,7 +1634,7 @@ static int DrawDisplay(int sh)
   int win=0, edge=0, hvwind=0, lflags;
   int maxw, maxcells;
 
-  est->rendstatus &= ~(PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO);
+  est->rendstatus &= ~(PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO|PDRAW_WND_HIGH_PRIO);
 
   if (pvid->reg[12]&1) {
     maxw = 328; maxcells = 40;

+ 8 - 9
pico/draw_arm.S

@@ -14,7 +14,7 @@
 .extern DrawStripInterlace
 
 .equ PDRAW_SPRITES_MOVED, (1<<0)
-.equ PDRAW_WND_DIFF_PRIO, (1<<1)
+.equ PDRAW_WND_HIGH_PRIO, (1<<1)
 .equ PDRAW_PARSE_SPRITES, (1<<2)
 .equ PDRAW_DIRTY_SPRITES, (1<<4)
 .equ PDRAW_PLANE_HI_PRIO, (1<<6)
@@ -946,8 +946,8 @@ DrawSpritesSHi:
 
 DrawSpriteSHi:
     @ draw next sprite
-    ldrb    r0, [r10,#-1]!
     ldr     r7, [sp]        @ est
+    ldrb    r0, [r10,#-1]!
     ldr     r1, [r7, #OFS_EST_HighPreSpr]
     cmp     r0, #0xff
     ldmeqfd sp!, {r1,r3-r11,pc} @ end of list
@@ -966,6 +966,7 @@ DrawSpriteSHi:
     orr     r9, r9, #0x90000000 @ r9=scc1 ???? ... <code> (s=shadow/hilight, cc=pal)
     cmp     r12,r9, lsr #28 @ sh/hi with pal3?
     cmpne   r3, #1          @ if not, is it hi prio?
+    strne   r3, [sp, #4]    @ reset last sprite width
     bne     DrawSpriteSHi   @ non-operator low sprite, already drawn
 
     ldr     r3, [r0]        @ sprite[0]
@@ -1309,13 +1310,11 @@ DrawWindow:
     @ fetch the first code now
     ldrh    r7, [lr, r12]
 
-    ands    r6, r6, #PDRAW_WND_DIFF_PRIO
-    orr     r6, r6, r2
-
-    eoreq   r8, r2, r7, lsr #15   @ do prio bits differ?
-    cmpeq   r8, #1
+    ands    r6, r6, #PDRAW_WND_HIGH_PRIO
+    cmpeq   r2, #1                @ prio && !(rendstatus & WND_HIGH_PRIO)?
     ldmeqfd sp!, {r4-r11,pc}      @ yes, assume that whole window uses same priority
 
+    orr     r6, r6, r2
     orr     r6, r6, r3, lsl #8    @ shadow mode
 
     sub     r8, r1, r0
@@ -1340,7 +1339,7 @@ DrawWindow:
 
     eor     r5, r6, r7, lsr #15
     tst     r5, #1
-    orrne   r6, r6, #2      @ wrong pri
+    orrne   r6, r6, #PDRAW_WND_HIGH_PRIO @ wrong pri
     bne     .dwloop
 
     cmp     r7, r9
@@ -1406,7 +1405,7 @@ DrawWindow:
     b       .dw_shadow_done
 
 .dwloop_end:
-    and     r2, r6, #PDRAW_WND_DIFF_PRIO
+    and     r2, r6, #PDRAW_WND_HIGH_PRIO
     ldmfd   sp!, {r4-r11,lr}
     ldr     r0, [sp]
     ldr     r1, [r0, #OFS_EST_rendstatus]

+ 1 - 1
pico/pico.h

@@ -199,7 +199,7 @@ void vidConvCpyRGB565(void *to, void *from, int pixels);
 void PicoDoHighPal555(int sh, int line, struct PicoEState *est);
 // internals, NB must keep in sync with ASM draw functions
 #define PDRAW_SPRITES_MOVED (1<<0) // SAT address modified
-#define PDRAW_WND_DIFF_PRIO (1<<1) // not all window tiles use same priority
+#define PDRAW_WND_HIGH_PRIO (1<<1) // have window with high prio tiles
 #define PDRAW_PARSE_SPRITES (1<<2) // SAT needs parsing
 #define PDRAW_INTERLACE     (1<<3)
 #define PDRAW_DIRTY_SPRITES (1<<4) // SAT modified