eliminate texrels (wip)
[picodrive.git] / pico / draw.c
index ca9a140..ff84be5 100644 (file)
@@ -54,9 +54,8 @@ int  HighPreSpr[80*2+1]; // slightly preprocessed sprites
 #define SPRL_LO_ABOVE_HI 0x10 // low priority sprites may be on top of hi\r
 unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; // sprite_count, ^flags, tile_count, [spritep]...\r
 \r
-int rendstatus, rendstatus_old;\r
+int rendstatus_old;\r
 int rendlines;\r
-int DrawScanline;\r
 int PicoDrawMask = -1;\r
 \r
 static int skip_next_line=0;\r
@@ -75,12 +74,15 @@ struct TileStrip
 \r
 // stuff available in asm:\r
 #ifdef _ASM_DRAW_C\r
-void DrawWindow(int tstart, int tend, int prio, int sh);\r
-void DrawAllSprites(unsigned char *sprited, int prio, int sh);\r
-void DrawTilesFromCache(int *hc, int sh, int rlim);\r
-void DrawSpritesSHi(unsigned char *sprited);\r
-void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells);\r
-void FinalizeLineBGR444(int sh, int line);\r
+void DrawWindow(int tstart, int tend, int prio, int sh,\r
+                struct PicoEState *est);\r
+void DrawAllSprites(unsigned char *sprited, int prio, int sh,\r
+                    struct PicoEState *est);\r
+void DrawTilesFromCache(int *hc, int sh, int rlim,\r
+                    struct PicoEState *est);\r
+void DrawSpritesSHi(unsigned char *sprited, struct PicoEState *est);\r
+void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells,\r
+               struct PicoEState *est);\r
 void *blockcpy(void *dst, const void *src, size_t n);\r
 void blockcpy_or(void *dst, void *src, size_t n, int pat);\r
 #else\r
@@ -258,7 +260,7 @@ static void DrawStrip(struct TileStrip *ts, int plane_sh, int cellskip)
   // terminate the cache list\r
   *ts->hc = 0;\r
   // if oldcode wasn't changed, it means all layer is hi priority\r
-  if (oldcode == -1) rendstatus |= PDRAW_PLANE_HI_PRIO;\r
+  if (oldcode == -1) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO;\r
 }\r
 \r
 // this is messy\r
@@ -266,7 +268,7 @@ void DrawStripVSRam(struct TileStrip *ts, int plane_sh, int cellskip)
 {\r
   int tilex,dx,code=0,addr=0,cell=0;\r
   int oldcode=-1,blank=-1; // The tile we know is blank\r
-  int pal=0,scan=DrawScanline;\r
+  int pal=0,scan=Pico.est.DrawScanline;\r
 \r
   // Draw tiles across screen:\r
   tilex=(-ts->hscroll)>>3;\r
@@ -317,7 +319,7 @@ void DrawStripVSRam(struct TileStrip *ts, int plane_sh, int cellskip)
 \r
   // terminate the cache list\r
   *ts->hc = 0;\r
-  if (oldcode == -1) rendstatus |= PDRAW_PLANE_HI_PRIO;\r
+  if (oldcode == -1) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO;\r
 }\r
 #endif\r
 \r
@@ -374,7 +376,8 @@ void DrawStripInterlace(struct TileStrip *ts)
 // --------------------------------------------\r
 \r
 #ifndef _ASM_DRAW_C\r
-static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells)\r
+static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells,\r
+  struct PicoEState *est)\r
 {\r
   struct PicoVideo *pvid=&Pico.video;\r
   const char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps (2 is invalid)\r
@@ -401,7 +404,7 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells)
   else            ts.nametab=(pvid->reg[2]&0x38)<< 9; // A\r
 \r
   htab=pvid->reg[13]<<9; // Horizontal scroll table address\r
-  if ( pvid->reg[11]&2)     htab+=DrawScanline<<1; // Offset by line\r
+  if ( pvid->reg[11]&2)     htab+=est->DrawScanline<<1; // Offset by line\r
   if ((pvid->reg[11]&1)==0) htab&=~0xf; // Offset by tile\r
   htab+=plane_sh&1; // A or B\r
 \r
@@ -413,7 +416,7 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells)
     vscroll=Pico.vsram[plane_sh&1]; // Get vertical scroll value\r
 \r
     // Find the line in the name table\r
-    ts.line=(vscroll+(DrawScanline<<1))&((ymask<<1)|1);\r
+    ts.line=(vscroll+(est->DrawScanline<<1))&((ymask<<1)|1);\r
     ts.nametab+=(ts.line>>4)<<shift[width];\r
 \r
     DrawStripInterlace(&ts);\r
@@ -426,7 +429,7 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells)
     vscroll=Pico.vsram[plane_sh&1]; // Get vertical scroll value\r
 \r
     // Find the line in the name table\r
-    ts.line=(vscroll+DrawScanline)&ymask;\r
+    ts.line=(vscroll+est->DrawScanline)&ymask;\r
     ts.nametab+=(ts.line>>3)<<shift[width];\r
 \r
     DrawStrip(&ts, plane_sh, cellskip);\r
@@ -437,7 +440,8 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells)
 // --------------------------------------------\r
 \r
 // tstart & tend are tile pair numbers\r
-static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache\r
+static void DrawWindow(int tstart, int tend, int prio, int sh,\r
+                       struct PicoEState *est)\r
 {\r
   struct PicoVideo *pvid=&Pico.video;\r
   int tilex,ty,nametab,code=0;\r
@@ -447,17 +451,17 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
   if (pvid->reg[12]&1)\r
   {\r
     nametab=(pvid->reg[3]&0x3c)<<9; // 40-cell mode\r
-    nametab+=(DrawScanline>>3)<<6;\r
+    nametab+=(est->DrawScanline>>3)<<6;\r
   }\r
   else\r
   {\r
     nametab=(pvid->reg[3]&0x3e)<<9; // 32-cell mode\r
-    nametab+=(DrawScanline>>3)<<5;\r
+    nametab+=(est->DrawScanline>>3)<<5;\r
   }\r
 \r
   tilex=tstart<<1;\r
 \r
-  if (!(rendstatus & PDRAW_WND_DIFF_PRIO)) {\r
+  if (!(est->rendstatus & PDRAW_WND_DIFF_PRIO)) {\r
     // check the first tile code\r
     code=Pico.vram[nametab+tilex];\r
     // if the whole window uses same priority (what is often the case), we may be able to skip this field\r
@@ -465,7 +469,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
   }\r
 \r
   tend<<=1;\r
-  ty=(DrawScanline&7)<<1; // Y-Offset into tile\r
+  ty=(est->DrawScanline&7)<<1; // Y-Offset into tile\r
 \r
   // Draw tiles across screen:\r
   if (!sh)\r
@@ -478,7 +482,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
       code=Pico.vram[nametab+tilex];\r
       if (code==blank) continue;\r
       if ((code>>15) != prio) {\r
-        rendstatus |= PDRAW_WND_DIFF_PRIO;\r
+        est->rendstatus |= PDRAW_WND_DIFF_PRIO;\r
         continue;\r
       }\r
 \r
@@ -504,7 +508,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
       code=Pico.vram[nametab+tilex];\r
       if(code==blank) continue;\r
       if((code>>15) != prio) {\r
-        rendstatus |= PDRAW_WND_DIFF_PRIO;\r
+        est->rendstatus |= PDRAW_WND_DIFF_PRIO;\r
         continue;\r
       }\r
 \r
@@ -538,23 +542,23 @@ static void DrawTilesFromCacheShPrep(void)
   // 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
-  rendstatus |= PDRAW_SHHI_DONE;\r
+  Pico.est.rendstatus |= PDRAW_SHHI_DONE;\r
   while (c--)\r
   {\r
     *zb++ &= 0xbfbfbfbf;\r
   }\r
 }\r
 \r
-static void DrawTilesFromCache(int *hc, int sh, int rlim)\r
+static void DrawTilesFromCache(int *hc, int sh, int rlim, struct PicoEState *est)\r
 {\r
   int code, addr, dx;\r
   int pal;\r
 \r
   // *ts->hc++ = code | (dx<<16) | (ty<<25); // cache it\r
 \r
-  if (sh && (rendstatus & (PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO)))\r
+  if (sh && (est->rendstatus & (PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO)))\r
   {\r
-    if (!(rendstatus & PDRAW_SHHI_DONE))\r
+    if (!(est->rendstatus & PDRAW_SHHI_DONE))\r
       DrawTilesFromCacheShPrep();\r
     sh = 0;\r
   }\r
@@ -658,7 +662,7 @@ static void DrawSprite(int *sprite, int sh)
   height=(sy>>24)&7; // Width and height in tiles\r
   sy=(sy<<16)>>16; // Y\r
 \r
-  row=DrawScanline-sy; // Row of the sprite we are on\r
+  row=Pico.est.DrawScanline-sy; // Row of the sprite we are on\r
 \r
   if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
 \r
@@ -706,7 +710,7 @@ static void DrawSpriteInterlace(unsigned int *sprite)
   width=(height>>2)&3; height&=3;\r
   width++; height++; // Width and height in tiles\r
 \r
-  row=(DrawScanline<<1)-sy; // Row of the sprite we are on\r
+  row=(Pico.est.DrawScanline<<1)-sy; // Row of the sprite we are on\r
 \r
   code=sprite[1];\r
   sx=((code>>16)&0x1ff)-0x78; // X\r
@@ -738,7 +742,7 @@ static void DrawSpriteInterlace(unsigned int *sprite)
 static void DrawAllSpritesInterlace(int pri, int sh)\r
 {\r
   struct PicoVideo *pvid=&Pico.video;\r
-  int i,u,table,link=0,sline=DrawScanline<<1;\r
+  int i,u,table,link=0,sline=Pico.est.DrawScanline<<1;\r
   unsigned int *sprites[80]; // Sprite index\r
 \r
   table=pvid->reg[5]&0x7f;\r
@@ -790,7 +794,7 @@ static void DrawAllSpritesInterlace(int pri, 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
-static void DrawSpritesSHi(unsigned char *sprited)\r
+static void DrawSpritesSHi(unsigned char *sprited, const struct PicoEState *est)\r
 {\r
   int (*fTileFunc)(int sx,int addr,int pal);\r
   unsigned char *p;\r
@@ -835,7 +839,7 @@ static void DrawSpritesSHi(unsigned char *sprited)
     height=(sy>>24)&7; // Width and height in tiles\r
     sy=(sy<<16)>>16; // Y\r
 \r
-    row=DrawScanline-sy; // Row of the sprite we are on\r
+    row=est->DrawScanline-sy; // Row of the sprite we are on\r
 \r
     if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
 \r
@@ -867,7 +871,7 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh)
   cnt = sprited[0] & 0x7f;\r
   if (cnt == 0) return;\r
 \r
-  rendstatus |= PDRAW_SPR_LO_ON_HI;\r
+  Pico.est.rendstatus |= PDRAW_SPR_LO_ON_HI;\r
 \r
   p = &sprited[3];\r
 \r
@@ -906,7 +910,7 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh)
     height=(sy>>24)&7; // Width and height in tiles\r
     sy=(sy<<16)>>16; // Y\r
 \r
-    row=DrawScanline-sy; // Row of the sprite we are on\r
+    row=Pico.est.DrawScanline-sy; // Row of the sprite we are on\r
 \r
     if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
 \r
@@ -942,7 +946,7 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh)
 \r
   /* nasty 2: sh operator pass */\r
   sprited[0] = sh_cnt;\r
-  DrawSpritesSHi(sprited);\r
+  DrawSpritesSHi(sprited, &Pico.est);\r
 }\r
 \r
 \r
@@ -954,7 +958,8 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh)
 \r
 void PrepareSprites(int full)\r
 {\r
-  struct PicoVideo *pvid=&Pico.video;\r
+  const struct PicoVideo *pvid=&Pico.video;\r
+  const struct PicoEState *est=&Pico.est;\r
   int u,link=0,sh;\r
   int table=0;\r
   int *pd = HighPreSpr;\r
@@ -991,10 +996,11 @@ void PrepareSprites(int full)
       sy = (pack << 16) >> 16;\r
       height = (pack >> 24) & 0xf;\r
 \r
-      if (sy < max_lines && sy + (height<<3) > DrawScanline && // sprite onscreen (y)?\r
+      if (sy < max_lines &&\r
+         sy + (height<<3) > est->DrawScanline && // sprite onscreen (y)?\r
           (sx > -24 || sx < max_width))                   // onscreen x\r
       {\r
-        int y = (sy >= DrawScanline) ? sy : DrawScanline;\r
+        int y = (sy >= est->DrawScanline) ? sy : est->DrawScanline;\r
         int entry = ((pd - HighPreSpr) / 2) | ((code2>>8)&0x80);\r
         for (; y < sy + (height<<3) && y < max_lines; y++)\r
         {\r
@@ -1047,7 +1053,7 @@ found:;
       sx = (code2>>16)&0x1ff;\r
       sx -= 0x78; // Get X coordinate + 8\r
 \r
-      if (sy < max_lines && sy + (height<<3) > DrawScanline) // sprite onscreen (y)?\r
+      if (sy < max_lines && sy + (height<<3) > est->DrawScanline) // sprite onscreen (y)?\r
       {\r
         int entry, y, sx_min, onscr_x, maybe_op = 0;\r
 \r
@@ -1057,7 +1063,7 @@ found:;
           maybe_op = SPRL_MAY_HAVE_OP;\r
 \r
         entry = ((pd - HighPreSpr) / 2) | ((code2>>8)&0x80);\r
-        y = (sy >= DrawScanline) ? sy : DrawScanline;\r
+        y = (sy >= est->DrawScanline) ? sy : est->DrawScanline;\r
         for (; y < sy + (height<<3) && y < max_lines; y++)\r
         {\r
          unsigned char *p = &HighLnSpr[y][0];\r
@@ -1110,16 +1116,17 @@ found:;
 }\r
 \r
 #ifndef _ASM_DRAW_C\r
-static void DrawAllSprites(unsigned char *sprited, int prio, int sh)\r
+static void DrawAllSprites(unsigned char *sprited, int prio, int sh,\r
+                           struct PicoEState *est)\r
 {\r
-  int rs = rendstatus;\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
-    rendstatus = rs & ~(PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES);\r
+    est->rendstatus = rs & ~(PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES);\r
   }\r
 \r
   cnt = sprited[0] & 0x7f;\r
@@ -1159,7 +1166,7 @@ void BackFill(int reg7, int sh)
 unsigned short HighPal[0x100];\r
 \r
 #ifndef _ASM_DRAW_C\r
-void PicoDoHighPal555(int sh)\r
+void PicoDoHighPal555(int sh, int line, struct PicoEState *est)\r
 {\r
   unsigned int *spal, *dpal;\r
   unsigned int t, i;\r
@@ -1205,7 +1212,7 @@ void FinalizeLine555(int sh, int line)
   int len;\r
 \r
   if (Pico.m.dirtyPal)\r
-    PicoDoHighPal555(sh);\r
+    PicoDoHighPal555(sh, line, est);\r
 \r
   if (Pico.video.reg[12]&1) {\r
     len = 320;\r
@@ -1217,7 +1224,7 @@ void FinalizeLine555(int sh, int line)
   {\r
 #ifndef PSP\r
     int i, mask=0xff;\r
-    if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI))\r
+    if (!sh && (est->rendstatus & PDRAW_SPR_LO_ON_HI))\r
       mask=0x3f; // accurate sprites, upper bits are priority stuff\r
 \r
     for (i = 0; i < len; i++)\r
@@ -1225,7 +1232,7 @@ void FinalizeLine555(int sh, int line)
 #else\r
     extern void amips_clut(unsigned short *dst, unsigned char *src, unsigned short *pal, int count);\r
     extern void amips_clut_6bit(unsigned short *dst, unsigned char *src, unsigned short *pal, int count);\r
-    if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI))\r
+    if (!sh && (est->rendstatus & PDRAW_SPR_LO_ON_HI))\r
          amips_clut_6bit(pd, ps, pal, len);\r
     else amips_clut(pd, ps, pal, len);\r
 #endif\r
@@ -1233,10 +1240,10 @@ void FinalizeLine555(int sh, int line)
 }\r
 #endif\r
 \r
-static void FinalizeLine8bit(int sh, int line)\r
+static void FinalizeLine8bit(int sh, int line, struct PicoEState *est)\r
 {\r
   unsigned char *pd = DrawLineDest;\r
-  int len, rs = rendstatus;\r
+  int len, rs = est->rendstatus;\r
   static int dirty_count;\r
 \r
   if (!sh && Pico.m.dirtyPal == 1)\r
@@ -1246,7 +1253,7 @@ static void FinalizeLine8bit(int sh, int line)
          dirty_count = 1;\r
     else dirty_count++;\r
     rs |= PDRAW_SONIC_MODE;\r
-    rendstatus = rs;\r
+    est->rendstatus = rs;\r
     if (dirty_count == 3) {\r
       blockcpy(HighPal, Pico.cram, 0x40*2);\r
     } else if (dirty_count == 11) {\r
@@ -1273,18 +1280,19 @@ static void FinalizeLine8bit(int sh, int line)
   }\r
 }\r
 \r
-static void (*FinalizeLine)(int sh, int line);\r
+static void (*FinalizeLine)(int sh, int line, struct PicoEState *est);\r
 \r
 // --------------------------------------------\r
 \r
 static int DrawDisplay(int sh)\r
 {\r
-  unsigned char *sprited = &HighLnSpr[DrawScanline][0];\r
+  struct PicoEState *est=&Pico.est;\r
+  unsigned char *sprited = &HighLnSpr[est->DrawScanline][0];\r
   struct PicoVideo *pvid=&Pico.video;\r
   int win=0,edge=0,hvwind=0;\r
   int maxw,maxcells;\r
 \r
-  rendstatus &= ~(PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO);\r
+  est->rendstatus &= ~(PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO);\r
 \r
   if (pvid->reg[12]&1) {\r
     maxw = 328; maxcells = 40;\r
@@ -1296,8 +1304,8 @@ static int DrawDisplay(int sh)
   win=pvid->reg[0x12];\r
   edge=(win&0x1f)<<3;\r
 \r
-  if (win&0x80) { if (DrawScanline>=edge) hvwind=1; }\r
-  else          { if (DrawScanline< edge) hvwind=1; }\r
+  if (win&0x80) { if (est->DrawScanline>=edge) hvwind=1; }\r
+  else          { if (est->DrawScanline< edge) hvwind=1; }\r
 \r
   if (!hvwind) // we might have a vertical window here\r
   {\r
@@ -1315,53 +1323,56 @@ static int DrawDisplay(int sh)
 \r
   /* - layer B low - */\r
   if (PicoDrawMask & PDRAW_LAYERB_ON)\r
-    DrawLayer(1|(sh<<1), HighCacheB, 0, maxcells);\r
+    DrawLayer(1|(sh<<1), HighCacheB, 0, maxcells, est);\r
   /* - layer A low - */\r
   if (!(PicoDrawMask & PDRAW_LAYERA_ON));\r
   else if (hvwind == 1)\r
-    DrawWindow(0, maxcells>>1, 0, sh);\r
+    DrawWindow(0, maxcells>>1, 0, sh, est);\r
   else if (hvwind == 2) {\r
-    DrawLayer(0|(sh<<1), HighCacheA, (win&0x80) ?    0 : edge<<1, (win&0x80) ?     edge<<1 : maxcells);\r
-    DrawWindow(                      (win&0x80) ? edge :       0, (win&0x80) ? maxcells>>1 : edge, 0, sh);\r
+    DrawLayer(0|(sh<<1), HighCacheA, (win&0x80) ?    0 : edge<<1, (win&0x80) ?     edge<<1 : maxcells, est);\r
+    DrawWindow(                      (win&0x80) ? edge :       0, (win&0x80) ? maxcells>>1 : edge, 0, sh, est);\r
   } else\r
-    DrawLayer(0|(sh<<1), HighCacheA, 0, maxcells);\r
+    DrawLayer(0|(sh<<1), HighCacheA, 0, maxcells, est);\r
   /* - sprites low - */\r
   if (!(PicoDrawMask & PDRAW_SPRITES_LOW_ON));\r
-  else if (rendstatus & PDRAW_INTERLACE)\r
+  else if (Pico.est.rendstatus & PDRAW_INTERLACE)\r
     DrawAllSpritesInterlace(0, sh);\r
   else if (sprited[1] & SPRL_HAVE_LO)\r
-    DrawAllSprites(sprited, 0, sh);\r
+    DrawAllSprites(sprited, 0, sh, est);\r
 \r
   /* - layer B hi - */\r
   if ((PicoDrawMask & PDRAW_LAYERB_ON) && HighCacheB[0])\r
-    DrawTilesFromCache(HighCacheB, sh, maxw);\r
+    DrawTilesFromCache(HighCacheB, sh, maxw, est);\r
   /* - layer A hi - */\r
   if (!(PicoDrawMask & PDRAW_LAYERA_ON));\r
   else if (hvwind == 1)\r
-    DrawWindow(0, maxcells>>1, 1, sh);\r
+    DrawWindow(0, maxcells>>1, 1, sh, est);\r
   else if (hvwind == 2) {\r
-    if (HighCacheA[0]) DrawTilesFromCache(HighCacheA, sh, (win&0x80) ? edge<<4 : maxw);\r
-    DrawWindow((win&0x80) ? edge : 0, (win&0x80) ? maxcells>>1 : edge, 1, sh);\r
+    if (HighCacheA[0])\r
+      DrawTilesFromCache(HighCacheA, sh, (win&0x80) ? edge<<4 : maxw, est);\r
+    DrawWindow((win&0x80) ? edge : 0, (win&0x80) ? maxcells>>1 : edge, 1, sh, est);\r
   } else\r
-    if (HighCacheA[0]) DrawTilesFromCache(HighCacheA, sh, maxw);\r
+    if (HighCacheA[0])\r
+      DrawTilesFromCache(HighCacheA, sh, maxw, est);\r
   /* - sprites hi - */\r
   if (!(PicoDrawMask & PDRAW_SPRITES_HI_ON));\r
-  else if (rendstatus & PDRAW_INTERLACE)\r
+  else if (Pico.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
     DrawSpritesHiAS(sprited, sh);\r
   else if (sh && (sprited[1] & SPRL_MAY_HAVE_OP))\r
-    DrawSpritesSHi(sprited);\r
+    DrawSpritesSHi(sprited, est);\r
   else if (sprited[1] & SPRL_HAVE_HI)\r
-    DrawAllSprites(sprited, 1, 0);\r
+    DrawAllSprites(sprited, 1, 0, est);\r
 \r
 #if 0\r
   {\r
     int *c, a, b;\r
     for (a = 0, c = HighCacheA; *c; c++, a++);\r
     for (b = 0, c = HighCacheB; *c; c++, b++);\r
-    printf("%i:%03i: a=%i, b=%i\n", Pico.m.frame_count, DrawScanline, a, b);\r
+    printf("%i:%03i: a=%i, b=%i\n", Pico.m.frame_count,\r
+           Pico.est.DrawScanline, a, b);\r
   }\r
 #endif\r
 \r
@@ -1374,27 +1385,27 @@ PICO_INTERNAL void PicoFrameStart(void)
   int offs = 8, lines = 224;\r
 \r
   // prepare to do this frame\r
-  rendstatus = 0;\r
+  Pico.est.rendstatus = 0;\r
   if ((Pico.video.reg[12] & 6) == 6)\r
-    rendstatus |= PDRAW_INTERLACE; // interlace mode\r
+    Pico.est.rendstatus |= PDRAW_INTERLACE; // interlace mode\r
   if (!(Pico.video.reg[12] & 1))\r
-    rendstatus |= PDRAW_32_COLS;\r
+    Pico.est.rendstatus |= PDRAW_32_COLS;\r
   if (Pico.video.reg[1] & 8) {\r
     offs = 0;\r
     lines = 240;\r
   }\r
 \r
-  if (rendstatus != rendstatus_old || lines != rendlines) {\r
+  if (Pico.est.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
+    rendstatus_old = Pico.est.rendstatus;\r
   }\r
 \r
   HighCol = HighColBase + offs * HighColIncrement;\r
   DrawLineDest = (char *)DrawLineDestBase + offs * DrawLineDestIncrement;\r
-  DrawScanline = 0;\r
+  Pico.est.DrawScanline = 0;\r
   skip_next_line = 0;\r
 \r
   if (PicoOpt & POPT_ALT_RENDERER)\r
@@ -1413,7 +1424,7 @@ static void DrawBlankedLine(int line, int offs, int sh, int bgc)
   BackFill(bgc, sh);\r
 \r
   if (FinalizeLine != NULL)\r
-    FinalizeLine(sh, line);\r
+    FinalizeLine(sh, line, &Pico.est);\r
 \r
   if (PicoScanEnd != NULL)\r
     PicoScanEnd(line + offs);\r
@@ -1431,7 +1442,7 @@ static void PicoLine(int line, int offs, int sh, int bgc)
     return;\r
   }\r
 \r
-  DrawScanline = line;\r
+  Pico.est.DrawScanline = line;\r
   if (PicoScanBegin != NULL)\r
     skip = PicoScanBegin(line + offs);\r
 \r
@@ -1446,7 +1457,7 @@ static void PicoLine(int line, int offs, int sh, int bgc)
     DrawDisplay(sh);\r
 \r
   if (FinalizeLine != NULL)\r
-    FinalizeLine(sh, line);\r
+    FinalizeLine(sh, line, &Pico.est);\r
 \r
   if (PicoScanEnd != NULL)\r
     skip_next_line = PicoScanEnd(line + offs);\r
@@ -1466,7 +1477,7 @@ void PicoDrawSync(int to, int blank_last_line)
   if (rendlines != 240)\r
     offs = 8;\r
 \r
-  for (line = DrawScanline; line < to; line++)\r
+  for (line = Pico.est.DrawScanline; line < to; line++)\r
   {\r
     PicoLine(line, offs, sh, bgc);\r
   }\r
@@ -1479,7 +1490,7 @@ void PicoDrawSync(int to, int blank_last_line)
     else PicoLine(line, offs, sh, bgc);\r
     line++;\r
   }\r
-  DrawScanline = line;\r
+  Pico.est.DrawScanline = line;\r
 \r
   pprof_end(draw);\r
 }\r
@@ -1491,8 +1502,8 @@ void PicoDrawUpdateHighPal(void)
   if (PicoOpt & POPT_ALT_RENDERER)\r
     sh = 0; // no s/h support\r
 \r
-  PicoDoHighPal555(sh);\r
-  if (rendstatus & PDRAW_SONIC_MODE) {\r
+  PicoDoHighPal555(sh, 0, &Pico.est);\r
+  if (Pico.est.rendstatus & PDRAW_SONIC_MODE) {\r
     // FIXME?\r
     memcpy(HighPal + 0x40, HighPal, 0x40*2);\r
     memcpy(HighPal + 0x80, HighPal, 0x40*2);\r
@@ -1528,7 +1539,7 @@ void PicoDrawSetOutBuf(void *dest, int increment)
 {\r
   DrawLineDestBase = dest;\r
   DrawLineDestIncrement = increment;\r
-  DrawLineDest = DrawLineDestBase + DrawScanline * increment;\r
+  DrawLineDest = DrawLineDestBase + Pico.est.DrawScanline * increment;\r
 }\r
 \r
 void PicoDrawSetInternalBuf(void *dest, int increment)\r
@@ -1536,7 +1547,7 @@ void PicoDrawSetInternalBuf(void *dest, int increment)
   if (dest != NULL) {\r
     HighColBase = dest;\r
     HighColIncrement = increment;\r
-    HighCol = HighColBase + DrawScanline * increment;\r
+    HighCol = HighColBase + Pico.est.DrawScanline * increment;\r
   }\r
   else {\r
     HighColBase = DefHighCol;\r
@@ -1560,3 +1571,5 @@ void PicoDrawSetCallbacks(int (*begin)(unsigned int num), int (*end)(unsigned in
     PicoScanEnd = end;\r
   }\r
 }\r
+\r
+// vim:ts=4:sw=4:expandtab\r