changed sh/hi handling for Pirates! Gold
authornotaz <notasas@gmail.com>
Tue, 7 Oct 2008 16:16:14 +0000 (16:16 +0000)
committernotaz <notasas@gmail.com>
Tue, 7 Oct 2008 16:16:14 +0000 (16:16 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@594 be3aeb3a-fb24-0410-a615-afba39da0efa

pico/draw.c

index 551b3d6..b915514 100644 (file)
  * The renderer has 4 modes now:\r
  * - normal\r
  * - shadow/hilight (s/h)\r
- * - "sonic mode" for midline palette changes\r
- * - accurate sprites (AS)\r
+ * - "sonic mode" for midline palette changes (8bit mode only)\r
+ * - accurate sprites (AS) [+ s/h]\r
  *\r
  * AS and s/h both use upper bits for both priority and shadow/hilight flags.\r
  * "sonic mode" is autodetected, shadow/hilight is enabled by emulated game.\r
  * AS is enabled by user and takes priority over "sonic mode".\r
+ *\r
+ * not handled properly:\r
+ * - hilight op on shadow tile\r
+ * - AS + s/h (s/h sprite flag interferes with and cleared by AS code)\r
  */\r
 \r
 #include "pico_int.h"\r
@@ -150,25 +154,25 @@ TileFlipMaker(TileFlip,pix_just_write)
 // draw a sprite pixel, process operator colors\r
 #define pix_sh(x) \\r
   if (!t); \\r
-  else if (t==0xe) pd[x]=(pd[x]&0x3f)|0x80; /* hilight */ \\r
-  else if (t==0xf) pd[x]= pd[x]      |0xc0; /* shadow  */ \\r
+  else if (t>=0xe) pd[x]=(pd[x]&0x3f)|(t<<6); /* c0 shadow, 80 hilight */ \\r
   else pd[x]=pal|t\r
 \r
 TileNormMaker(TileNormSH, pix_sh)\r
 TileFlipMaker(TileFlipSH, pix_sh)\r
 \r
-// draw a sprite pixel ignoring operator colors\r
-#define pix_sh_noop(x) \\r
-  if (t && t < 0xe) \\r
-    pd[x]=pal|t\r
+// draw a sprite pixel, mark operator colors\r
+#define pix_sh_markop(x) \\r
+  if (!t); \\r
+  else if (t>=0xe) pd[x]|=0x80; \\r
+  else pd[x]=pal|t\r
 \r
-TileNormMaker(TileNormSH_noop, pix_sh_noop)\r
-TileFlipMaker(TileFlipSH_noop, pix_sh_noop)\r
+TileNormMaker(TileNormSH_markop, pix_sh_markop)\r
+TileFlipMaker(TileFlipSH_markop, pix_sh_markop)\r
 \r
-// process operator pixels only, apply only on low pri tiles\r
+// process operator pixels only, apply only on low pri tiles and other op pixels\r
 #define pix_sh_onlyop(x) \\r
-  if      (t==0xe && (pd[x]&0x40)) pd[x]=(pd[x]&0x3f)|0x80; /* hilight */ \\r
-  else if (t==0xf && (pd[x]&0x40)) pd[x]= pd[x]      |0xc0; /* shadow  */\r
+  if (t>=0xe && (pd[x]&0xc0)) \\r
+    pd[x]=(pd[x]&0x3f)|(t<<6); /* c0 shadow, 80 hilight */ \\r
 \r
 TileNormMaker(TileNormSH_onlyop_lp, pix_sh_onlyop)\r
 TileFlipMaker(TileFlipSH_onlyop_lp, pix_sh_onlyop)\r
@@ -524,12 +528,13 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
 static void DrawTilesFromCacheShPrep(void)\r
 {\r
   // 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
+  // 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
   while (c--)\r
   {\r
-    *zb++ &= 0x3f3f3f3f;\r
+    *zb++ &= 0xbfbfbfbf;\r
   }\r
 }\r
 \r
@@ -576,8 +581,8 @@ static void DrawTilesFromCache(int *hc, int sh, int rlim)
       addr+=(unsigned int)code>>25; // y offset into tile\r
       dx=(code>>16)&0x1ff;\r
       zb = HighCol+dx;\r
-      *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f;\r
-      *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f;\r
+      *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf;\r
+      *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf;\r
 \r
       pal=((code>>9)&0x30);\r
       if (rlim-dx < 0) goto last_cut_tile;\r
@@ -661,8 +666,8 @@ static void DrawSprite(int *sprite, int sh)
   pal|=sh<<6;\r
 \r
   if (sh && (code&0x6000) == 0x6000) {\r
-    if(code&0x0800) fTileFunc=TileFlipSH_noop;\r
-    else            fTileFunc=TileNormSH_noop;\r
+    if(code&0x0800) fTileFunc=TileFlipSH_markop;\r
+    else            fTileFunc=TileNormSH_markop;\r
   } else {\r
     if(code&0x0800) fTileFunc=TileFlip;\r
     else            fTileFunc=TileNorm;\r
@@ -771,8 +776,13 @@ static void DrawAllSpritesInterlace(int pri, int sh)
 \r
 \r
 #ifndef _ASM_DRAW_C\r
-// Index + 0  :    hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: vert./horiz. size\r
-// Index + 4  :    xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
+/*\r
+ * s/h drawing: lo_layers|40, lo_sprites|40 && mark_op,\r
+ *        hi_layers&=~40, hi_sprites\r
+ *\r
+ * 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
 {\r
   int (*fTileFunc)(int sx,int addr,int pal);\r