32x, fix softscale enabled by 32x
authorkub <derkub@gmail.com>
Sun, 11 Jun 2023 19:11:18 +0000 (19:11 +0000)
committerkub <derkub@gmail.com>
Sun, 11 Jun 2023 19:11:18 +0000 (19:11 +0000)
also some streamlining cleanup in the drawing code

pico/32x/draw.c
pico/draw.c
pico/draw2.c
pico/draw_arm.S
pico/pico.h

index a027ad1..0ec5669 100644 (file)
@@ -348,9 +348,6 @@ void PicoDrawSetOutFormat32x(pdso_t which, int use_32x_line_mode)
     PicoDrawSetInternalBuf(NULL, 0);
     PicoDrawSetOutBufMD(Pico.est.Draw2FB, 328);
   }
-  // always need upscaling for H32, before mixing in 32X layer
-  PicoIn.opt |= POPT_EN_SOFTSCALE;
-  PicoIn.opt &= ~POPT_DIS_32C_BORDER;
 
   if (use_32x_line_mode)
     // we'll draw via FinalizeLine32xRGB555 (rare)
index 9966412..7560e2a 100644 (file)
@@ -519,7 +519,7 @@ void DrawStripInterlace(struct TileStrip *ts, int plane_sh)
 static void DrawLayer(int plane_sh, u32 *hcache, int cellskip, int maxcells,\r
   struct PicoEState *est)\r
 {\r
-  struct PicoVideo *pvid=&Pico.video;\r
+  struct PicoVideo *pvid=&est->Pico->video;\r
   const char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps (2 is invalid)\r
   struct TileStrip ts;\r
   int width, height, ymask;\r
@@ -593,8 +593,8 @@ static void DrawLayer(int plane_sh, u32 *hcache, int cellskip, int maxcells,
 static void DrawWindow(int tstart, int tend, int prio, int sh,\r
                        struct PicoEState *est)\r
 {\r
-  unsigned char *pd = Pico.est.HighCol;\r
-  struct PicoVideo *pvid = &Pico.video;\r
+  unsigned char *pd = est->HighCol;\r
+  struct PicoVideo *pvid = &est->Pico->video;\r
   int tilex,ty,nametab,code=0;\r
   int blank=-1; // The tile we know is blank\r
 \r
@@ -713,7 +713,7 @@ static void DrawTilesFromCacheShPrep(void)
 \r
 static void DrawTilesFromCache(u32 *hc, int sh, int rlim, struct PicoEState *est)\r
 {\r
-  unsigned char *pd = Pico.est.HighCol;\r
+  unsigned char *pd = est->HighCol;\r
   u32 code, dx;\r
   u32 pack;\r
   int pal;\r
@@ -919,7 +919,7 @@ static NOINLINE void DrawAllSpritesInterlace(int pri, int sh)
   struct PicoVideo *pvid=&Pico.video;\r
   int i,u,table,link=0,sline=Pico.est.DrawScanline<<1;\r
   u32 *sprites[80]; // Sprite index\r
-  int max_sprites = Pico.video.reg[12]&1 ? 80 : 64;\r
+  int max_sprites = pvid->reg[12]&1 ? 80 : 64;\r
 \r
   table=pvid->reg[5]&0x7f;\r
   if (pvid->reg[12]&1) table&=0x7e; // Lowest bit 0 in 40-cell mode\r
@@ -1252,7 +1252,7 @@ void DrawStripInterlaceForced(struct TileStrip *ts)
 static void DrawLayerForced(int plane_sh, int cellskip, int maxcells,\r
   struct PicoEState *est)\r
 {\r
-  struct PicoVideo *pvid=&Pico.video;\r
+  struct PicoVideo *pvid=&est->Pico->video;\r
   const char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps (2 is invalid)\r
   struct TileStrip ts;\r
   int width, height, ymask;\r
@@ -1411,8 +1411,8 @@ static void DrawSpritesForced(unsigned char *sprited)
 // Sprite parsing 1 line in advance: determine sprites on line by Y pos\r
 static NOINLINE void ParseSprites(int max_lines, int limit)\r
 {\r
-  const struct PicoVideo *pvid=&Pico.video;\r
   const struct PicoEState *est=&Pico.est;\r
+  const struct PicoVideo *pvid=&est->Pico->video;\r
   int u,link=0,sh;\r
   int table=0;\r
   s32 *pd = HighPreSpr + HighPreSprBank*2;\r
@@ -1429,12 +1429,12 @@ static NOINLINE void ParseSprites(int max_lines, int limit)
   // line are limited if display was disabled during HBLANK before current line\r
   if (limit) limit = 16; // max sprites/pixels processed\r
 \r
-  if (!(Pico.video.reg[12]&1))\r
+  if (!(pvid->reg[12]&1))\r
     max_sprites = 64, max_line_sprites = 16, max_width = 264;\r
   if (*est->PicoOpt & POPT_DIS_SPRITE_LIM)\r
     max_line_sprites = MAX_LINE_SPRITES;\r
 \r
-  sh = Pico.video.reg[0xC]&8; // shadow/hilight?\r
+  sh = pvid->reg[0xC]&8; // shadow/hilight?\r
 \r
   table=pvid->reg[5]&0x7f;\r
   if (pvid->reg[12]&1) table&=0x7e; // Lowest bit 0 in 40-cell mode\r
@@ -1606,8 +1606,8 @@ void PicoDoHighPal555_8bit(int sh, int line, struct PicoEState *est)
   unsigned int t, i;\r
 \r
   // reset dirty only if there are no outstanding changes\r
-  if (Pico.m.dirtyPal == 2)\r
-    Pico.m.dirtyPal = 0;\r
+  if (est->Pico->m.dirtyPal == 2)\r
+    est->Pico->m.dirtyPal = 0;\r
 \r
   // In Sonic render mode palettes were backuped in SonicPal\r
   spal = (void *)est->SonicPal;\r
@@ -1646,7 +1646,7 @@ void PicoDoHighPal555(int sh, int line, struct PicoEState *est)
   unsigned int *spal, *dpal;\r
   unsigned int t, i;\r
 \r
-  Pico.m.dirtyPal = 0;\r
+  est->Pico->m.dirtyPal = 0;\r
 \r
   spal = (void *)PicoMem.cram;\r
   dpal = (void *)est->HighPal;\r
@@ -1688,14 +1688,14 @@ void FinalizeLine555(int sh, int line, struct PicoEState *est)
   PicoDrawUpdateHighPal();\r
 \r
   len = 256;\r
-  if (!(PicoIn.AHW & PAHW_8BIT) && (Pico.video.reg[12]&1))\r
+  if (!(PicoIn.AHW & PAHW_8BIT) && (est->Pico->video.reg[12]&1))\r
     len = 320;\r
-  else if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD))\r
+  else if ((PicoIn.AHW & PAHW_GG) && (est->Pico->m.hardware & PMS_HW_LCD))\r
     len = 160;\r
-  else if ((PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[0] & 0x20))\r
+  else if ((PicoIn.AHW & PAHW_SMS) && (est->Pico->video.reg[0] & 0x20))\r
     len -= 8, ps += 8;\r
 \r
-  if ((*est->PicoOpt & POPT_EN_SOFTSCALE) && len < 320) {\r
+  if ((est->rendstatus & PDRAW_SOFTSCALE) && len < 320) {\r
     if (len >= 240 && len <= 256) {\r
       pd += (256-len)>>1;\r
       switch (PicoIn.filter) {\r
@@ -1715,7 +1715,7 @@ void FinalizeLine555(int sh, int line, struct PicoEState *est)
       default: h_upscale_nn_1_2(pd, 320, ps, 160, len, f_pal); break;\r
       }\r
   } else {\r
-    if (!(*est->PicoOpt & POPT_DIS_32C_BORDER) && len < 320)\r
+    if ((est->rendstatus & PDRAW_BORDER_32) && len < 320)\r
       pd += (320-len) / 2;\r
 #if 1\r
     h_copy(pd, 320, ps, 320, len, f_pal);\r
@@ -1738,7 +1738,7 @@ void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
   static int dirty_line;\r
 \r
   // a hack for mid-frame palette changes\r
-  if (Pico.m.dirtyPal == 1)\r
+  if (est->Pico->m.dirtyPal == 1)\r
   {\r
     // store a maximum of 3 additional palettes in SonicPal\r
     if (est->SonicPalCount < 3 &&\r
@@ -1748,21 +1748,21 @@ void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
       est->rendstatus |= PDRAW_SONIC_MODE;\r
     }\r
     blockcpy(est->SonicPal+est->SonicPalCount*0x40, PicoMem.cram, 0x40*2);\r
-    Pico.m.dirtyPal = 2;\r
+    est->Pico->m.dirtyPal = 2;\r
   }\r
 \r
   len = 256;\r
-  if (!(PicoIn.AHW & PAHW_8BIT) && (Pico.video.reg[12]&1))\r
+  if (!(PicoIn.AHW & PAHW_8BIT) && (est->Pico->video.reg[12]&1))\r
     len = 320;\r
-  else if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD))\r
+  else if ((PicoIn.AHW & PAHW_GG) && (est->Pico->m.hardware & PMS_HW_LCD))\r
     len = 160;\r
-  else if ((PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[0] & 0x20))\r
+  else if ((PicoIn.AHW & PAHW_SMS) && (est->Pico->video.reg[0] & 0x20))\r
     len -= 8, ps += 8;\r
 \r
   if (DrawLineDestIncrement == 0)\r
     pd = est->HighCol+8;\r
 \r
-  if ((PicoIn.opt & POPT_EN_SOFTSCALE) && len < 320) {\r
+  if ((est->rendstatus  & PDRAW_SOFTSCALE) && len < 320) {\r
     unsigned char pal = 0;\r
 \r
     if (!sh && (est->rendstatus & PDRAW_SONIC_MODE))\r
@@ -1774,7 +1774,7 @@ void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
     else\r
       rh_upscale_nn_1_2(pd, 320, ps, 256, len, f_or);\r
   } else {\r
-    if (!(*est->PicoOpt & POPT_DIS_32C_BORDER) && len < 320)\r
+    if ((est->rendstatus & PDRAW_BORDER_32) && len < 320)\r
       pd += (320-len) / 2;\r
     if (!sh && (est->rendstatus & PDRAW_SONIC_MODE))\r
       // select active backup palette\r
@@ -1792,7 +1792,7 @@ static int DrawDisplay(int sh)
 {\r
   struct PicoEState *est=&Pico.est;\r
   unsigned char *sprited = &HighLnSpr[est->DrawScanline][0];\r
-  struct PicoVideo *pvid=&Pico.video;\r
+  struct PicoVideo *pvid=&est->Pico->video;\r
   int win=0, edge=0, hvwind=0, lflags;\r
   int maxw, maxcells;\r
 \r
@@ -1872,7 +1872,7 @@ static int DrawDisplay(int sh)
   else if (est->rendstatus & PDRAW_INTERLACE)\r
     DrawAllSpritesInterlace(1, sh);\r
   // have sprites without layer pri bit ontop of sprites with that bit\r
-  else if ((sprited[1] & SPRL_LO_ABOVE_HI) && (PicoIn.opt & POPT_ACC_SPRITES))\r
+  else if ((sprited[1] & SPRL_LO_ABOVE_HI) && (*est->PicoOpt & POPT_ACC_SPRITES))\r
     DrawSpritesHiAS(sprited, sh);\r
   else if (sh && (sprited[1] & SPRL_MAY_HAVE_OP))\r
     DrawSpritesSHi(sprited, est);\r
@@ -1914,21 +1914,31 @@ PICO_INTERNAL void PicoFrameStart(void)
 \r
   // prepare to do this frame\r
   est->rendstatus = 0;\r
-  if ((Pico.video.reg[12] & 6) == 6)\r
+\r
+  if ((PicoIn.AHW & PAHW_32X) && (*est->PicoOpt & POPT_ALT_RENDERER))\r
+    est->rendstatus |= PDRAW_BORDER_32; // no scaling for fastest\r
+  else if (PicoIn.AHW & PAHW_32X) // H32 upscaling, before mixing in 32X layer\r
+    est->rendstatus |= PDRAW_32X_SCALE|PDRAW_SOFTSCALE;\r
+  else if (PicoIn.opt & POPT_EN_SOFTSCALE)\r
+    est->rendstatus |= PDRAW_SOFTSCALE;\r
+  else if (!(PicoIn.opt & POPT_DIS_32C_BORDER))\r
+    est->rendstatus |= PDRAW_BORDER_32;\r
+\r
+  if ((est->Pico->video.reg[12] & 6) == 6)\r
     est->rendstatus |= PDRAW_INTERLACE; // interlace mode\r
-  if (!(Pico.video.reg[12] & 1)) {\r
+  if (!(est->Pico->video.reg[12] & 1)) {\r
     est->rendstatus |= PDRAW_32_COLS;\r
-    if (!(PicoIn.opt & POPT_EN_SOFTSCALE)) {\r
+    if (est->rendstatus & PDRAW_BORDER_32) {\r
       columns = 256;\r
       coffs = 32;\r
     }\r
   }\r
-  if (Pico.video.reg[1] & 8) {\r
+  if (est->Pico->video.reg[1] & 8) {\r
     est->rendstatus |= PDRAW_30_ROWS;\r
     lines = 240;\r
     loffs = 0;\r
   }\r
-  if (PicoIn.opt & POPT_DIS_32C_BORDER)\r
+  if (!(est->rendstatus & PDRAW_BORDER_32))\r
     coffs = 0;\r
 \r
   if (est->rendstatus != rendstatus_old || lines != rendlines) {\r
@@ -1946,8 +1956,6 @@ PICO_INTERNAL void PicoFrameStart(void)
     est->rendstatus |= PDRAW_SKIP_FRAME;\r
   if (sprep | skipped)\r
     est->rendstatus |= PDRAW_PARSE_SPRITES;\r
-  if (PicoIn.AHW & PAHW_32X)\r
-    est->rendstatus |= PDRAW_32X_SCALE;\r
 \r
   est->HighCol = HighColBase + loffs * HighColIncrement;\r
   est->DrawLineDest = (char *)DrawLineDestBase + loffs * DrawLineDestIncrement;\r
@@ -1956,7 +1964,7 @@ PICO_INTERNAL void PicoFrameStart(void)
 \r
   if (FinalizeLine == FinalizeLine8bit) {\r
     // make a backup of the current palette in case Sonic mode is detected later\r
-    Pico.m.dirtyPal = (Pico.m.dirtyPal || est->SonicPalCount ? 2 : 0);\r
+    est->Pico->m.dirtyPal = (est->Pico->m.dirtyPal || est->SonicPalCount ? 2 : 0);\r
     blockcpy(est->SonicPal, PicoMem.cram, 0x40*2);\r
   }\r
   est->SonicPalCount = 0;\r
@@ -2001,13 +2009,13 @@ static void PicoLine(int line, int offs, int sh, int bgc, int off, int on)
     return;\r
   }\r
 \r
-  if (Pico.video.debug_p & (PVD_FORCE_A | PVD_FORCE_B | PVD_FORCE_S))\r
+  if (est->Pico->video.debug_p & (PVD_FORCE_A | PVD_FORCE_B | PVD_FORCE_S))\r
     bgc = 0x3f;\r
 \r
   // Draw screen:\r
   BackFill(bgc, sh, est);\r
-  if (Pico.video.reg[1]&0x40) {\r
-    int width = (Pico.video.reg[12]&1) ? 320 : 256;\r
+  if (est->Pico->video.reg[1]&0x40) {\r
+    int width = (est->Pico->video.reg[12]&1) ? 320 : 256;\r
     DrawDisplay(sh);\r
     // partial line blanking (display on or off inside the line)\r
     if (unlikely(off|on)) {\r
@@ -2032,8 +2040,8 @@ void PicoDrawSync(int to, int off, int on)
 {\r
   struct PicoEState *est = &Pico.est;\r
   int line, offs = 0;\r
-  int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
-  int bgc = Pico.video.reg[7] & 0x3f;\r
+  int sh = (est->Pico->video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
+  int bgc = est->Pico->video.reg[7] & 0x3f;\r
 \r
   pprof_start(draw);\r
 \r
@@ -2060,7 +2068,7 @@ void PicoDrawSync(int to, int off, int on)
   // last line\r
   if (line <= to)\r
   {\r
-    int width2 = (Pico.video.reg[12]&1) ? 160 : 128;\r
+    int width2 = (est->Pico->video.reg[12]&1) ? 160 : 128;\r
 \r
     // technically, VDP starts active display output at slot 12\r
     if (unlikely(on|off) && (off >= width2 ||\r
@@ -2106,9 +2114,9 @@ void PicoDrawRefreshSprites(void)
 void PicoDrawUpdateHighPal(void)\r
 {\r
   struct PicoEState *est = &Pico.est;\r
-  if (Pico.m.dirtyPal) {\r
-    int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
-    if ((PicoIn.opt & POPT_ALT_RENDERER) | (est->rendstatus & PDRAW_SONIC_MODE))\r
+  if (est->Pico->m.dirtyPal) {\r
+    int sh = (est->Pico->video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
+    if ((*est->PicoOpt & POPT_ALT_RENDERER) | (est->rendstatus & PDRAW_SONIC_MODE))\r
       sh = 0; // no s/h support\r
 \r
     if (PicoIn.AHW & PAHW_SMS)\r
index 9a491ea..952c13e 100644 (file)
@@ -597,11 +597,6 @@ static void DrawDisplayFull(void)
        }\r
        est->Draw2Start = scrstart;\r
 \r
-       // 32C border for centering? (for asm)\r
-       est->rendstatus &= ~PDRAW_BORDER_32;\r
-       if ((est->rendstatus&PDRAW_32_COLS) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
-               est->rendstatus |= PDRAW_BORDER_32;\r
-\r
        planestart = scrstart, planeend = scrend;\r
        winstart = scrstart, winend = scrend;\r
 \r
index 64ddc74..e3ef3e2 100644 (file)
@@ -18,7 +18,9 @@
 .equ PDRAW_WND_DIFF_PRIO, (1<<1)\r
 .equ PDRAW_PLANE_HI_PRIO, (1<<6)\r
 .equ PDRAW_SHHI_DONE,     (1<<7)\r
+.equ PDRAW_BORDER_32,     (1<<9)\r
 .equ PDRAW_32X_SCALE,     (1<<12)\r
+.equ PDRAW_SOFTSCALE,     (1<<15)\r
 \r
 @ helpers\r
 .macro add_c24 d s c\r
@@ -1642,7 +1644,7 @@ FinalizeLine555:
     ldr     r5, [r11, #OFS_EST_PicoOpt]\r
     ldr     r1, [r11, #OFS_EST_HighCol]\r
     ldr     r0, [r11, #OFS_EST_DrawLineDest]\r
-    ldr     r4, [r5]\r
+    ldr     r4, [r11, #OFS_EST_rendstatus]\r
     ldr     r7, [r5, #OFS_PicoIn_AHW-OFS_PicoIn_opt]\r
     ldrb    r12,[r8, #OFS_Pico_video_reg+12]\r
     ldrb    r6, [r8, #OFS_Pico_video_reg+0]\r
@@ -1664,7 +1666,7 @@ FinalizeLine555:
 \r
 .fl_gg20col:\r
     mov     r2, #160/8         @ len = 160\r
-    tst     r4, #0x4000                @ EN_SOFTSCALE?\r
+    tst     r4, #PDRAW_SOFTSCALE\r
     bne     .fl_20scale_RGB555 @ scale 160->320\r
     b       .fl_checkborder\r
 \r
@@ -1675,15 +1677,15 @@ FinalizeLine555:
     mov     r2, #256/8         @ len = 256\r
 \r
 .fl_check32scaling:\r
-    tst     r4, #0x4000                @ EN_SOFTSCALE?\r
+    tst     r4, #PDRAW_SOFTSCALE\r
     rsbne   r7, r2, #256/8\r
     addne   r0, r0, r7, lsl #3 @ pd += (256-len)>>1\r
     bne     .fl_32scale_RGB555 @ scale 256->320\r
 \r
 .fl_checkborder:\r
-    tst     r4, #0x0100                @ DIS_32C_BORDER?\r
-    rsbeq   r7, r2, #320/8     @ pd += (320-len)/2\r
-    addeq   r0, r0, r7, lsl #3\r
+    tst     r4, #PDRAW_BORDER_32\r
+    rsbne   r7, r2, #320/8     @ pd += (320-len)/2\r
+    addne   r0, r0, r7, lsl #3\r
 \r
 .fl_40colRGB555:\r
 #ifdef UNALIGNED_DRAWLINEDEST\r
index 40a1c66..2ef4692 100644 (file)
@@ -223,7 +223,6 @@ void vidConvCpyRGB565(void *to, void *from, int pixels);
 #endif\r
 void PicoDoHighPal555(int sh, int line, struct PicoEState *est);\r
 // internals, NB must keep in sync with ASM draw functions\r
-#define PDRAW_SYNC_NEEDED   (1<<0) // redraw needed\r
 #define PDRAW_WND_DIFF_PRIO (1<<1) // not all window tiles use same priority\r
 #define PDRAW_PARSE_SPRITES (1<<2) // SAT needs parsing\r
 #define PDRAW_INTERLACE     (1<<3)\r
@@ -237,7 +236,9 @@ void PicoDoHighPal555(int sh, int line, struct PicoEState *est);
 #define PDRAW_30_ROWS      (1<<11) // 30 rows mode (240 lines)\r
 #define PDRAW_32X_SCALE    (1<<12) // scale CLUT layer for 32X\r
 #define PDRAW_SMS_BLANK_1  (1<<13) // 1st column blanked\r
-#define PDRAW_SYNC_NEXT    (1<<14) // sync next frame\r
+#define PDRAW_SOFTSCALE    (1<<15) // H32 upscaling\r
+#define PDRAW_SYNC_NEEDED  (1<<16) // redraw needed\r
+#define PDRAW_SYNC_NEXT    (1<<17) // redraw next frame\r
 extern int rendstatus_old;\r
 extern int rendlines;\r
 \r