sms, add vdp midframe cram change handling for 8bit renderer
authorkub <derkub@gmail.com>
Sun, 17 Oct 2021 20:50:07 +0000 (22:50 +0200)
committerkub <derkub@gmail.com>
Sun, 17 Oct 2021 20:50:07 +0000 (22:50 +0200)
pico/draw.c
pico/mode4.c

index 236e347..38b920d 100644 (file)
@@ -1688,13 +1688,13 @@ void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
   int len;\r
   static int dirty_line;\r
 \r
+  // a hack for mid-frame palette changes\r
   if (Pico.m.dirtyPal == 1)\r
   {\r
-    // a hack for mid-frame palette changes\r
-    if (!(est->rendstatus & PDRAW_SONIC_MODE) | (line - dirty_line > 4)) {\r
-      // store a maximum of 3 additional palettes in SonicPal\r
-      if (est->SonicPalCount < 3)\r
-        est->SonicPalCount ++;\r
+    // store a maximum of 2 additional palettes in SonicPal\r
+    if (est->SonicPalCount < 2 &&\r
+        (!(est->rendstatus & PDRAW_SONIC_MODE) || (line - dirty_line > 4))) {\r
+      est->SonicPalCount ++;\r
       dirty_line = line;\r
       est->rendstatus |= PDRAW_SONIC_MODE;\r
     }\r
@@ -1854,7 +1854,6 @@ static int DrawDisplay(int sh)
 PICO_INTERNAL void PicoFrameStart(void)\r
 {\r
   int loffs = 8, lines = 224, coffs = 0, columns = 320;\r
-  int dirty = ((Pico.est.rendstatus & PDRAW_SONIC_MODE) || Pico.m.dirtyPal);\r
   int sprep = Pico.est.rendstatus & (PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES);\r
   int skipped = Pico.est.rendstatus & PDRAW_SKIP_FRAME;\r
 \r
@@ -1896,7 +1895,7 @@ PICO_INTERNAL void PicoFrameStart(void)
   if (FinalizeLine == FinalizeLine8bit) {\r
     // make a backup of the current palette in case Sonic mode is detected later\r
     Pico.est.SonicPalCount = 0;\r
-    Pico.m.dirtyPal = (dirty ? 2 : 0); // mark as dirty but already copied\r
+    Pico.m.dirtyPal = (Pico.m.dirtyPal ? 2 : 0); // mark as dirty but copied\r
     blockcpy(Pico.est.SonicPal, PicoMem.cram, 0x40*2);\r
   }\r
 }\r
@@ -2011,6 +2010,8 @@ void PicoDrawUpdateHighPal(void)
       blockcpy(est->HighPal+0x40, est->HighPal, 0x40*2);\r
       blockcpy(est->HighPal+0x80, est->HighPal, 0x80*2);\r
     }\r
+    Pico.est.HighPal[0xe0] = 0x0000; // black and white, reserved for OSD\r
+    Pico.est.HighPal[0xf0] = 0xffff;\r
   }\r
 }\r
 \r
index 0525b93..9d9235a 100644 (file)
@@ -465,6 +465,7 @@ static void DrawDisplayM2(int scanline)
 /*===============*/
 
 static void FinalizeLineRGB555SMS(int line);
+static void FinalizeLine8bitSMS(int line);
 
 void PicoFrameStartSMS(void)
 {
@@ -513,6 +514,12 @@ void PicoFrameStartSMS(void)
 
   Pico.est.HighCol = HighColBase + screen_offset * HighColIncrement;
   Pico.est.DrawLineDest = (char *)DrawLineDestBase + screen_offset * DrawLineDestIncrement;
+
+  if (FinalizeLineSMS == FinalizeLine8bitSMS) {
+    Pico.est.SonicPalCount = 0;
+    Pico.m.dirtyPal = (Pico.m.dirtyPal ? 2 : 0);
+    memcpy(Pico.est.SonicPal, PicoMem.cram, 0x20*2);
+  }
 }
 
 void PicoLineSMS(int line)
@@ -557,32 +564,45 @@ static u16 tmspal[32] = {
 
 void PicoDoHighPal555SMS(void)
 {
-  u32 *spal=(void *)PicoMem.cram;
-  u32 *dpal=(void *)Pico.est.HighPal;
+  u32 *spal = (void *)Pico.est.SonicPal;
+  u32 *dpal = (void *)Pico.est.HighPal;
+  unsigned int cnt = Pico.est.SonicPalCount+1;
   unsigned int t;
-  int i;
+  int i, j;
+  if (FinalizeLineSMS != FinalizeLine8bitSMS || Pico.m.dirtyPal == 2)
+    Pico.m.dirtyPal = 0;
+
+  // use hardware palette for 16bit accurate mode
+  if (FinalizeLineSMS == FinalizeLineRGB555SMS)
+    spal = (void *)PicoMem.cram;
 
-  Pico.m.dirtyPal = 0;
-  if (!(Pico.video.reg[0] & 0x4))
+  // fixed palette in TMS modes
+  if (!(Pico.video.reg[0] & 0x4)) {
     spal = (u32 *)tmspal;
+    cnt = 1;
+  }
 
   /* SMS 6 bit cram data was already converted to MD/GG format by vdp write,
    * hence GG/SMS/TMS can all be handled the same here */
-  for (i = 0x20/2; i > 0; i--, spal++, dpal++) { 
-    t = *spal;
+  for (j = cnt; j > 0; j--) {
+    for (i = 0x20/2; i > 0; i--, spal++, dpal++) { 
+     t = *spal;
 #if defined(USE_BGR555)
-    t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<2) | ((t & 0x0f000f00)<<3);
-    t |= (t >> 4) & 0x04210421;
+     t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<2) | ((t & 0x0f000f00)<<3);
+     t |= (t >> 4) & 0x04210421;
 #elif defined(USE_BGR565)
-    t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)<<4);
-    t |= (t >> 4) & 0x08610861;
+     t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)<<4);
+     t |= (t >> 4) & 0x08610861;
 #else
-    t = ((t & 0x000f000f)<<12) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)>>7);
-    t |= (t >> 4) & 0x08610861;
+     t = ((t & 0x000f000f)<<12) | ((t & 0x00f000f0)<<3) | ((t & 0x0f000f00)>>7);
+     t |= (t >> 4) & 0x08610861;
 #endif
-    *dpal = t;
+     *dpal = t;
+    }
+    memcpy(dpal, dpal-0x20/2, 0x20*2); // for prio bit
+    spal += 0x20/2, dpal += 0x20/2;
   }
-  memcpy(&Pico.est.HighPal[0x20], Pico.est.HighPal, 0x20*2); // for prio bit
   Pico.est.HighPal[0xe0] = 0;
 }