* 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
// 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
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
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
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
\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