scroll size improvement
[picodrive.git] / pico / draw.c
index ff84be5..2aa37f8 100644 (file)
@@ -35,18 +35,16 @@ int (*PicoScanBegin)(unsigned int num) = NULL;
 int (*PicoScanEnd)  (unsigned int num) = NULL;\r
 \r
 static unsigned char DefHighCol[8+320+8];\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 *DrawLineDestBase = DefOutBuff;\r
 int DrawLineDestIncrement;\r
 \r
 static int  HighCacheA[41+1];   // caches for high layers\r
 static int  HighCacheB[41+1];\r
-int  HighPreSpr[80*2+1]; // slightly preprocessed sprites\r
+static int  HighPreSpr[80*2+1]; // slightly preprocessed sprites\r
 \r
 #define SPRL_HAVE_HI     0x80 // have hi priority sprites\r
 #define SPRL_HAVE_LO     0x40 // *lo*\r
@@ -100,7 +98,7 @@ void blockcpy_or(void *dst, void *src, size_t n, int pat)
 #define TileNormMaker(funcname,pix_func)                     \\r
 static int funcname(int sx,int addr,int pal)                 \\r
 {                                                            \\r
-  unsigned char *pd = HighCol+sx;                            \\r
+  unsigned char *pd = Pico.est.HighCol+sx;                   \\r
   unsigned int pack=0; unsigned int t=0;                     \\r
                                                              \\r
   pack=*(unsigned int *)(Pico.vram+addr); /* Get 8 pixels */ \\r
@@ -124,7 +122,7 @@ static int funcname(int sx,int addr,int pal)                 \
 #define TileFlipMaker(funcname,pix_func)                     \\r
 static int funcname(int sx,int addr,int pal)                 \\r
 {                                                            \\r
-  unsigned char *pd = HighCol+sx;                            \\r
+  unsigned char *pd = Pico.est.HighCol+sx;                   \\r
   unsigned int pack=0; unsigned int t=0;                     \\r
                                                              \\r
   pack=*(unsigned int *)(Pico.vram+addr); /* Get 8 pixels */ \\r
@@ -396,8 +394,11 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells,
 \r
   ts.xmask=(1<<shift[width])-1; // X Mask in tiles (0x1f-0x7f)\r
   ymask=(height<<8)|0xff;       // Y Mask in pixels\r
-  if(width == 1)   ymask&=0x1ff;\r
-  else if(width>1) ymask =0x0ff;\r
+  switch (width) {\r
+    case 1: ymask &= 0x1ff; break;\r
+    case 2: ymask =  0x007; break;\r
+    case 3: ymask =  0x0ff; break;\r
+  }\r
 \r
   // Find name table:\r
   if (plane_sh&1) ts.nametab=(pvid->reg[4]&0x07)<<12; // B\r
@@ -515,7 +516,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh,
       pal=((code>>9)&0x30);\r
 \r
       if (prio) {\r
-        int *zb = (int *)(HighCol+8+(tilex<<3));\r
+        int *zb = (int *)(est->HighCol+8+(tilex<<3));\r
         *zb++ &= 0xbfbfbfbf;\r
         *zb   &= 0xbfbfbfbf;\r
       } else {\r
@@ -541,7 +542,7 @@ static void DrawTilesFromCacheShPrep(void)
   // as some layer has covered whole line with hi priority tiles,\r
   // we can process whole line and then act as if sh/hi mode was off,\r
   // but leave lo pri op sprite markers alone\r
-  int c = 320/4, *zb = (int *)(HighCol+8);\r
+  int c = 320/4, *zb = (int *)(Pico.est.HighCol+8);\r
   Pico.est.rendstatus |= PDRAW_SHHI_DONE;\r
   while (c--)\r
   {\r
@@ -591,7 +592,7 @@ static void DrawTilesFromCache(int *hc, int sh, int rlim, struct PicoEState *est
       addr=(code&0x7ff)<<4;\r
       addr+=(unsigned int)code>>25; // y offset into tile\r
       dx=(code>>16)&0x1ff;\r
-      zb = HighCol+dx;\r
+      zb = est->HighCol+dx;\r
       *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf;\r
       *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf;\r
 \r
@@ -607,7 +608,7 @@ static void DrawTilesFromCache(int *hc, int sh, int rlim, struct PicoEState *est
 last_cut_tile:\r
   {\r
     unsigned int t, pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
-    unsigned char *pd = HighCol+dx;\r
+    unsigned char *pd = est->HighCol+dx;\r
     if (!pack) return;\r
     if (code&0x0800)\r
     {\r
@@ -812,7 +813,7 @@ static void DrawSpritesSHi(unsigned char *sprited, const struct PicoEState *est)
     int offs, delta, width, height, row;\r
 \r
     offs = (p[cnt] & 0x7f) * 2;\r
-    sprite = HighPreSpr + offs;\r
+    sprite = est->HighPreSpr + offs;\r
     code = sprite[1];\r
     pal = (code>>9)&0x30;\r
 \r
@@ -936,7 +937,7 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh)
 \r
   /* nasty 1: remove 'sprite' flags */\r
   {\r
-    int c = 320/4/4, *zb = (int *)(HighCol+8);\r
+    int c = 320/4/4, *zb = (int *)(Pico.est.HighCol+8);\r
     while (c--)\r
     {\r
       *zb++ &= 0x7f7f7f7f; *zb++ &= 0x7f7f7f7f;\r
@@ -956,7 +957,7 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh)
 // Index + 0  :    hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: vert./horiz. size\r
 // Index + 4  :    xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
 \r
-void PrepareSprites(int full)\r
+static NOINLINE void PrepareSprites(int full)\r
 {\r
   const struct PicoVideo *pvid=&Pico.video;\r
   const struct PicoEState *est=&Pico.est;\r
@@ -1119,16 +1120,9 @@ found:;
 static void DrawAllSprites(unsigned char *sprited, int prio, int sh,\r
                            struct PicoEState *est)\r
 {\r
-  int rs = est->rendstatus;\r
   unsigned char *p;\r
   int cnt;\r
 \r
-  if (rs & (PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES)) {\r
-    //elprintf(EL_STATUS, "PrepareSprites(%i)", (rs>>4)&1);\r
-    PrepareSprites(rs & PDRAW_DIRTY_SPRITES);\r
-    est->rendstatus = rs & ~(PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES);\r
-  }\r
-\r
   cnt = sprited[0] & 0x7f;\r
   if (cnt == 0) return;\r
 \r
@@ -1147,7 +1141,7 @@ static void DrawAllSprites(unsigned char *sprited, int prio, int sh,
 \r
 // --------------------------------------------\r
 \r
-void BackFill(int reg7, int sh)\r
+void BackFill(int reg7, int sh, struct PicoEState *est)\r
 {\r
   unsigned int back;\r
 \r
@@ -1157,14 +1151,12 @@ void BackFill(int reg7, int sh)
   back|=back<<8;\r
   back|=back<<16;\r
 \r
-  memset32((int *)(HighCol+8), back, 320/4);\r
+  memset32((int *)(est->HighCol+8), back, 320/4);\r
 }\r
 #endif\r
 \r
 // --------------------------------------------\r
 \r
-unsigned short HighPal[0x100];\r
-\r
 #ifndef _ASM_DRAW_C\r
 void PicoDoHighPal555(int sh, int line, struct PicoEState *est)\r
 {\r
@@ -1174,7 +1166,7 @@ void PicoDoHighPal555(int sh, int line, struct PicoEState *est)
   Pico.m.dirtyPal = 0;\r
 \r
   spal = (void *)Pico.cram;\r
-  dpal = (void *)HighPal;\r
+  dpal = (void *)est->HighPal;\r
 \r
   for (i = 0; i < 0x40 / 2; i++) {\r
     t = spal[i];\r
@@ -1204,11 +1196,11 @@ void PicoDoHighPal555(int sh, int line, struct PicoEState *est)
   }\r
 }\r
 \r
-void FinalizeLine555(int sh, int line)\r
+void FinalizeLine555(int sh, int line, struct PicoEState *est)\r
 {\r
-  unsigned short *pd=DrawLineDest;\r
-  unsigned char  *ps=HighCol+8;\r
-  unsigned short *pal=HighPal;\r
+  unsigned short *pd=est->DrawLineDest;\r
+  unsigned char  *ps=est->HighCol+8;\r
+  unsigned short *pal=est->HighPal;\r
   int len;\r
 \r
   if (Pico.m.dirtyPal)\r
@@ -1242,7 +1234,7 @@ void FinalizeLine555(int sh, int line)
 \r
 static void FinalizeLine8bit(int sh, int line, struct PicoEState *est)\r
 {\r
-  unsigned char *pd = DrawLineDest;\r
+  unsigned char *pd = est->DrawLineDest;\r
   int len, rs = est->rendstatus;\r
   static int dirty_count;\r
 \r
@@ -1255,9 +1247,9 @@ static void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
     rs |= PDRAW_SONIC_MODE;\r
     est->rendstatus = rs;\r
     if (dirty_count == 3) {\r
-      blockcpy(HighPal, Pico.cram, 0x40*2);\r
+      blockcpy(est->HighPal, Pico.cram, 0x40*2);\r
     } else if (dirty_count == 11) {\r
-      blockcpy(HighPal+0x40, Pico.cram, 0x40*2);\r
+      blockcpy(est->HighPal+0x40, Pico.cram, 0x40*2);\r
     }\r
   }\r
 \r
@@ -1271,12 +1263,12 @@ static void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
 \r
   if (!sh && (rs & PDRAW_SONIC_MODE)) {\r
     if (dirty_count >= 11) {\r
-      blockcpy_or(pd, HighCol+8, len, 0x80);\r
+      blockcpy_or(pd, est->HighCol+8, len, 0x80);\r
     } else {\r
-      blockcpy_or(pd, HighCol+8, len, 0x40);\r
+      blockcpy_or(pd, est->HighCol+8, len, 0x40);\r
     }\r
   } else {\r
-    blockcpy(pd, HighCol+8, len);\r
+    blockcpy(pd, est->HighCol+8, len);\r
   }\r
 }\r
 \r
@@ -1292,6 +1284,12 @@ static int DrawDisplay(int sh)
   int win=0,edge=0,hvwind=0;\r
   int maxw,maxcells;\r
 \r
+  if (est->rendstatus & (PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES)) {\r
+    // elprintf(EL_STATUS, "PrepareSprites(%i)", (est->rendstatus>>4)&1);\r
+    PrepareSprites(est->rendstatus & PDRAW_DIRTY_SPRITES);\r
+    est->rendstatus &= ~(PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES);\r
+  }\r
+\r
   est->rendstatus &= ~(PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO);\r
 \r
   if (pvid->reg[12]&1) {\r
@@ -1335,7 +1333,7 @@ static int DrawDisplay(int sh)
     DrawLayer(0|(sh<<1), HighCacheA, 0, maxcells, est);\r
   /* - sprites low - */\r
   if (!(PicoDrawMask & PDRAW_SPRITES_LOW_ON));\r
-  else if (Pico.est.rendstatus & PDRAW_INTERLACE)\r
+  else if (est->rendstatus & PDRAW_INTERLACE)\r
     DrawAllSpritesInterlace(0, sh);\r
   else if (sprited[1] & SPRL_HAVE_LO)\r
     DrawAllSprites(sprited, 0, sh, est);\r
@@ -1356,7 +1354,7 @@ static int DrawDisplay(int sh)
       DrawTilesFromCache(HighCacheA, sh, maxw, est);\r
   /* - sprites hi - */\r
   if (!(PicoDrawMask & PDRAW_SPRITES_HI_ON));\r
-  else if (Pico.est.rendstatus & PDRAW_INTERLACE)\r
+  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] & 0xd0) == 0xd0 && (PicoOpt & POPT_ACC_SPRITES))\r
@@ -1403,8 +1401,8 @@ PICO_INTERNAL void PicoFrameStart(void)
     rendstatus_old = Pico.est.rendstatus;\r
   }\r
 \r
-  HighCol = HighColBase + offs * HighColIncrement;\r
-  DrawLineDest = (char *)DrawLineDestBase + offs * DrawLineDestIncrement;\r
+  Pico.est.HighCol = HighColBase + offs * HighColIncrement;\r
+  Pico.est.DrawLineDest = (char *)DrawLineDestBase + offs * DrawLineDestIncrement;\r
   Pico.est.DrawScanline = 0;\r
   skip_next_line = 0;\r
 \r
@@ -1421,7 +1419,7 @@ static void DrawBlankedLine(int line, int offs, int sh, int bgc)
   if (PicoScanBegin != NULL)\r
     PicoScanBegin(line + offs);\r
 \r
-  BackFill(bgc, sh);\r
+  BackFill(bgc, sh, &Pico.est);\r
 \r
   if (FinalizeLine != NULL)\r
     FinalizeLine(sh, line, &Pico.est);\r
@@ -1429,8 +1427,8 @@ static void DrawBlankedLine(int line, int offs, int sh, int bgc)
   if (PicoScanEnd != NULL)\r
     PicoScanEnd(line + offs);\r
 \r
-  HighCol += HighColIncrement;\r
-  DrawLineDest = (char *)DrawLineDest + DrawLineDestIncrement;\r
+  Pico.est.HighCol += HighColIncrement;\r
+  Pico.est.DrawLineDest = (char *)Pico.est.DrawLineDest + DrawLineDestIncrement;\r
 }\r
 \r
 static void PicoLine(int line, int offs, int sh, int bgc)\r
@@ -1452,7 +1450,7 @@ static void PicoLine(int line, int offs, int sh, int bgc)
   }\r
 \r
   // Draw screen:\r
-  BackFill(bgc, sh);\r
+  BackFill(bgc, sh, &Pico.est);\r
   if (Pico.video.reg[1]&0x40)\r
     DrawDisplay(sh);\r
 \r
@@ -1462,8 +1460,8 @@ static void PicoLine(int line, int offs, int sh, int bgc)
   if (PicoScanEnd != NULL)\r
     skip_next_line = PicoScanEnd(line + offs);\r
 \r
-  HighCol += HighColIncrement;\r
-  DrawLineDest = (char *)DrawLineDest + DrawLineDestIncrement;\r
+  Pico.est.HighCol += HighColIncrement;\r
+  Pico.est.DrawLineDest = (char *)Pico.est.DrawLineDest + DrawLineDestIncrement;\r
 }\r
 \r
 void PicoDrawSync(int to, int blank_last_line)\r
@@ -1498,15 +1496,16 @@ void PicoDrawSync(int to, int blank_last_line)
 // also works for fast renderer\r
 void PicoDrawUpdateHighPal(void)\r
 {\r
+  struct PicoEState *est = &Pico.est;\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, 0, &Pico.est);\r
-  if (Pico.est.rendstatus & PDRAW_SONIC_MODE) {\r
+  if (est->rendstatus & PDRAW_SONIC_MODE) {\r
     // FIXME?\r
-    memcpy(HighPal + 0x40, HighPal, 0x40*2);\r
-    memcpy(HighPal + 0x80, HighPal, 0x40*2);\r
+    memcpy(est->HighPal + 0x40, est->HighPal, 0x40*2);\r
+    memcpy(est->HighPal + 0x80, est->HighPal, 0x40*2);\r
   }\r
 }\r
 \r
@@ -1539,7 +1538,7 @@ void PicoDrawSetOutBuf(void *dest, int increment)
 {\r
   DrawLineDestBase = dest;\r
   DrawLineDestIncrement = increment;\r
-  DrawLineDest = DrawLineDestBase + Pico.est.DrawScanline * increment;\r
+  Pico.est.DrawLineDest = DrawLineDestBase + Pico.est.DrawScanline * increment;\r
 }\r
 \r
 void PicoDrawSetInternalBuf(void *dest, int increment)\r
@@ -1547,7 +1546,7 @@ void PicoDrawSetInternalBuf(void *dest, int increment)
   if (dest != NULL) {\r
     HighColBase = dest;\r
     HighColIncrement = increment;\r
-    HighCol = HighColBase + Pico.est.DrawScanline * increment;\r
+    Pico.est.HighCol = HighColBase + Pico.est.DrawScanline * increment;\r
   }\r
   else {\r
     HighColBase = DefHighCol;\r
@@ -1572,4 +1571,12 @@ void PicoDrawSetCallbacks(int (*begin)(unsigned int num), int (*end)(unsigned in
   }\r
 }\r
 \r
-// vim:ts=4:sw=4:expandtab\r
+void PicoDrawInit(void)\r
+{\r
+  Pico.est.DrawLineDest = DefOutBuff;\r
+  Pico.est.HighCol = HighColBase;\r
+  Pico.est.HighPreSpr = HighPreSpr;\r
+  rendstatus_old = -1;\r
+}\r
+\r
+// vim:ts=2:sw=2:expandtab\r