From: kub <derkub@gmail.com>
Date: Sun, 17 Oct 2021 20:50:07 +0000 (+0200)
Subject: sms, add vdp midframe cram change handling for 8bit renderer
X-Git-Tag: v2.00~462
X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=646be42e9d8805121cd500ffb1660e26a440f1ec;p=picodrive.git

sms, add vdp midframe cram change handling for 8bit renderer
---

diff --git a/pico/draw.c b/pico/draw.c
index 236e347e..38b920d6 100644
--- a/pico/draw.c
+++ b/pico/draw.c
@@ -1688,13 +1688,13 @@ void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
   int len;
   static int dirty_line;
 
+  // a hack for mid-frame palette changes
   if (Pico.m.dirtyPal == 1)
   {
-    // a hack for mid-frame palette changes
-    if (!(est->rendstatus & PDRAW_SONIC_MODE) | (line - dirty_line > 4)) {
-      // store a maximum of 3 additional palettes in SonicPal
-      if (est->SonicPalCount < 3)
-        est->SonicPalCount ++;
+    // store a maximum of 2 additional palettes in SonicPal
+    if (est->SonicPalCount < 2 &&
+        (!(est->rendstatus & PDRAW_SONIC_MODE) || (line - dirty_line > 4))) {
+      est->SonicPalCount ++;
       dirty_line = line;
       est->rendstatus |= PDRAW_SONIC_MODE;
     }
@@ -1854,7 +1854,6 @@ static int DrawDisplay(int sh)
 PICO_INTERNAL void PicoFrameStart(void)
 {
   int loffs = 8, lines = 224, coffs = 0, columns = 320;
-  int dirty = ((Pico.est.rendstatus & PDRAW_SONIC_MODE) || Pico.m.dirtyPal);
   int sprep = Pico.est.rendstatus & (PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES);
   int skipped = Pico.est.rendstatus & PDRAW_SKIP_FRAME;
 
@@ -1896,7 +1895,7 @@ PICO_INTERNAL void PicoFrameStart(void)
   if (FinalizeLine == FinalizeLine8bit) {
     // make a backup of the current palette in case Sonic mode is detected later
     Pico.est.SonicPalCount = 0;
-    Pico.m.dirtyPal = (dirty ? 2 : 0); // mark as dirty but already copied
+    Pico.m.dirtyPal = (Pico.m.dirtyPal ? 2 : 0); // mark as dirty but copied
     blockcpy(Pico.est.SonicPal, PicoMem.cram, 0x40*2);
   }
 }
@@ -2011,6 +2010,8 @@ void PicoDrawUpdateHighPal(void)
       blockcpy(est->HighPal+0x40, est->HighPal, 0x40*2);
       blockcpy(est->HighPal+0x80, est->HighPal, 0x80*2);
     }
+    Pico.est.HighPal[0xe0] = 0x0000; // black and white, reserved for OSD
+    Pico.est.HighPal[0xf0] = 0xffff;
   }
 }
 
diff --git a/pico/mode4.c b/pico/mode4.c
index 0525b935..9d9235ab 100644
--- a/pico/mode4.c
+++ b/pico/mode4.c
@@ -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;
 }