new 32x renderers, auto fskip change, massive refactoring
[picodrive.git] / pico / draw.c
index 180045d..168a6ea 100644 (file)
 int (*PicoScanBegin)(unsigned int num) = NULL;\r
 int (*PicoScanEnd)  (unsigned int num) = NULL;\r
 \r
-#if OVERRIDE_HIGHCOL\r
 static unsigned char DefHighCol[8+320+8];\r
-unsigned char *HighCol=DefHighCol;\r
-#else\r
-unsigned char  HighCol[8+320+8];\r
-#endif\r
+unsigned char *HighCol = DefHighCol;\r
+static unsigned char *HighColBase = DefHighCol;\r
+static int HighColIncrement;\r
+\r
 static unsigned int DefOutBuff[320*2/2];\r
-void *DrawLineDest=DefOutBuff; // pointer to dest buffer where to draw this line to\r
+void *DrawLineDest = DefOutBuff; // pointer to dest buffer where to draw this line to\r
+void *DrawLineDestBase = DefOutBuff;\r
+int DrawLineDestIncrement;\r
 \r
 static int  HighCacheA[41+1];   // caches for high layers\r
 static int  HighCacheB[41+1];\r
@@ -54,6 +55,7 @@ int  HighPreSpr[80*2+1]; // slightly preprocessed sprites
 unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; // sprite_count, ^flags, tile_count, [spritep]...\r
 \r
 int rendstatus, rendstatus_old;\r
+int rendlines;\r
 int DrawScanline;\r
 int PicoDrawMask = -1;\r
 \r
@@ -1192,6 +1194,7 @@ void PicoDoHighPal555(int sh)
   }\r
 }\r
 \r
+#if 0\r
 static void FinalizeLineBGR444(int sh, int line)\r
 {\r
   unsigned short *pd=DrawLineDest;\r
@@ -1228,9 +1231,10 @@ static void FinalizeLineBGR444(int sh, int line)
   for(i = 0; i < len; i++)\r
     pd[i] = pal[ps[i] & mask];\r
 }\r
+#endif\r
 \r
 \r
-void FinalizeLineRGB555(int sh, int line)\r
+void FinalizeLine555(int sh, int line)\r
 {\r
   unsigned short *pd=DrawLineDest;\r
   unsigned char  *ps=HighCol+8;\r
@@ -1404,21 +1408,30 @@ static int DrawDisplay(int sh)
 // MUST be called every frame\r
 PICO_INTERNAL void PicoFrameStart(void)\r
 {\r
+  int offs = 8, lines = 224;\r
+\r
   // prepare to do this frame\r
   rendstatus = 0;\r
-  if ((Pico.video.reg[12]&6) == 6)\r
+  if ((Pico.video.reg[12] & 6) == 6)\r
     rendstatus |= PDRAW_INTERLACE; // interlace mode\r
-  if (Pico.video.reg[1] & 8)\r
-    rendstatus |= PDRAW_240LINES;\r
+  if (!(Pico.video.reg[12] & 1))\r
+    rendstatus |= PDRAW_32_COLS;\r
+  if (Pico.video.reg[1] & 8) {\r
+    offs = 0;\r
+    lines = 240;\r
+  }\r
 \r
+  HighCol = HighColBase;\r
+  DrawLineDest = (char *)DrawLineDestBase + offs * DrawLineDestIncrement;\r
   DrawScanline = 0;\r
   skip_next_line = 0;\r
 \r
-  if (rendstatus != rendstatus_old) {\r
+  if (rendstatus != rendstatus_old || lines != rendlines) {\r
+    rendlines = lines;\r
+    // mode_change() might reset rendstatus_old by calling SetColorFormat\r
+    emu_video_mode_change((lines == 240) ? 0 : 8,\r
+      lines, (Pico.video.reg[12] & 1) ? 0 : 1);\r
     rendstatus_old = rendstatus;\r
-    emu_video_mode_change((rendstatus & PDRAW_240LINES) ? 0 : 8,\r
-      (rendstatus & PDRAW_240LINES) ? 240 : 224,\r
-      (Pico.video.reg[12] & 1) ? 0 : 1);\r
   }\r
 \r
   if (PicoOpt & POPT_ALT_RENDERER)\r
@@ -1445,6 +1458,8 @@ static void DrawBlankedLine(int line, int offs, int sh, int bgc)
 \r
 static void PicoLine(int line, int offs, int sh, int bgc)\r
 {\r
+  int skip = 0;\r
+\r
   if (skip_next_line > 0) {\r
     skip_next_line--;\r
     return;\r
@@ -1452,7 +1467,12 @@ static void PicoLine(int line, int offs, int sh, int bgc)
 \r
   DrawScanline = line;\r
   if (PicoScanBegin != NULL)\r
-    skip_next_line = PicoScanBegin(line + offs);\r
+    skip = PicoScanBegin(line + offs);\r
+\r
+  if (skip) {\r
+    skip_next_line = skip - 1;\r
+    return;\r
+  }\r
 \r
   // Draw screen:\r
   BackFill(bgc, sh);\r
@@ -1464,6 +1484,9 @@ static void PicoLine(int line, int offs, int sh, int bgc)
 \r
   if (PicoScanEnd != NULL)\r
     skip_next_line = PicoScanEnd(line + offs);\r
+\r
+  HighCol += HighColIncrement;\r
+  DrawLineDest = (char *)DrawLineDest + DrawLineDestIncrement;\r
 }\r
 \r
 void PicoDrawSync(int to, int blank_last_line)\r
@@ -1472,12 +1495,10 @@ void PicoDrawSync(int to, int blank_last_line)
   int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
   int bgc = Pico.video.reg[7];\r
 \r
-  if (!(rendstatus & PDRAW_240LINES))\r
-    offs = 8;\r
+  pprof_start(draw);\r
 \r
-  // need to know which pixels are bg for 32x\r
-  if (PicoAHW & PAHW_32X)\r
-    bgc = 0;\r
+  if (rendlines != 240)\r
+    offs = 8;\r
 \r
   for (line = DrawScanline; line < to; line++)\r
   {\r
@@ -1503,21 +1524,63 @@ void PicoDrawSync(int to, int blank_last_line)
     line++;\r
   }\r
   DrawScanline = line;\r
+\r
+  pprof_end(draw);\r
 }\r
 \r
-void PicoDrawSetColorFormat(int which)\r
+// also works for fast renderer\r
+void PicoDrawUpdateHighPal(void)\r
+{\r
+  int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
+  if (PicoOpt & POPT_ALT_RENDERER)\r
+    sh = 0; // no s/h support\r
+\r
+  PicoDoHighPal555(sh);\r
+  if (rendstatus & PDRAW_SONIC_MODE) {\r
+    // FIXME?\r
+    memcpy(HighPal + 0x40, HighPal, 0x40*2);\r
+    memcpy(HighPal + 0x80, HighPal, 0x40*2);\r
+  }\r
+}\r
+\r
+void PicoDrawSetOutFormat(pdso_t which, int allow_32x)\r
 {\r
   switch (which)\r
   {\r
-    case 2: FinalizeLine = FinalizeLine8bit;   break;\r
-    case 1: FinalizeLine = (PicoAHW & PAHW_32X) ? FinalizeLine32xRGB555 : FinalizeLineRGB555; break;\r
-    case 0: FinalizeLine = FinalizeLineBGR444; break;\r
-    default:FinalizeLine = NULL; break;\r
+    case PDF_8BIT:\r
+      FinalizeLine = FinalizeLine8bit;\r
+      break;\r
+\r
+    case PDF_RGB555:\r
+      if ((PicoAHW & PAHW_32X) && allow_32x)\r
+        FinalizeLine = FinalizeLine32xRGB555;\r
+      else\r
+        FinalizeLine = FinalizeLine555;\r
+      break;\r
+\r
+    default:\r
+      FinalizeLine = NULL;\r
+      break;\r
+  }\r
+  PicoDrawSetOutputMode4(which);\r
+  rendstatus_old = -1;\r
+}\r
+\r
+void PicoDrawSetOutBuf(void *dest, int increment)\r
+{\r
+  DrawLineDestBase = dest;\r
+  DrawLineDestIncrement = increment;\r
+}\r
+\r
+void PicoDrawSetInternalBuf(void *dest, int increment)\r
+{\r
+  if (dest != NULL) {\r
+    HighColBase = dest;\r
+    HighColIncrement = increment;\r
+  }\r
+  else {\r
+    HighColBase = DefHighCol;\r
+    HighColIncrement = 0;\r
   }\r
-  PicoDrawSetColorFormatMode4(which);\r
-#if OVERRIDE_HIGHCOL\r
-  if (which)\r
-    HighCol=DefHighCol;\r
-#endif\r
 }\r
 \r