#define blockcpy memcpy\r
#endif\r
\r
-#define TileNormMaker_(pix_func) \\r
+#define TileNormMaker_(pix_func,ret) \\r
{ \\r
unsigned int t; \\r
\\r
t = (pack&0x0f000000)>>24; pix_func(5); \\r
t = (pack&0x00f00000)>>20; pix_func(6); \\r
t = (pack&0x000f0000)>>16; pix_func(7); \\r
+ return ret; \\r
}\r
\r
-#define TileFlipMaker_(pix_func) \\r
+#define TileFlipMaker_(pix_func,ret) \\r
{ \\r
unsigned int t; \\r
\\r
t = (pack&0x000000f0)>> 4; pix_func(5); \\r
t = (pack&0x00000f00)>> 8; pix_func(6); \\r
t = (pack&0x0000f000)>>12; pix_func(7); \\r
+ return ret; \\r
}\r
\r
#define TileNormMaker(funcname, pix_func) \\r
static void funcname(unsigned char *pd, unsigned int pack, int pal) \\r
-TileNormMaker_(pix_func)\r
+TileNormMaker_(pix_func,)\r
\r
#define TileFlipMaker(funcname, pix_func) \\r
static void funcname(unsigned char *pd, unsigned int pack, int pal) \\r
-TileFlipMaker_(pix_func)\r
+TileFlipMaker_(pix_func,)\r
\r
#define TileNormMakerAS(funcname, pix_func) \\r
-static void funcname(unsigned char *pd, unsigned char *mb, unsigned int pack, int pal) \\r
-TileNormMaker_(pix_func)\r
+static unsigned funcname(unsigned char *pd, unsigned m, unsigned int pack, int pal) \\r
+TileNormMaker_(pix_func,m)\r
\r
#define TileFlipMakerAS(funcname, pix_func) \\r
-static void funcname(unsigned char *pd, unsigned char *mb, unsigned int pack, int pal) \\r
-TileFlipMaker_(pix_func)\r
+static unsigned funcname(unsigned char *pd, unsigned m, unsigned int pack, int pal) \\r
+TileFlipMaker_(pix_func,m)\r
\r
#define pix_just_write(x) \\r
if (t) pd[x]=pal|t\r
\r
#endif\r
\r
+// AS: sprite mask bits in m shifted to bits 8-15, see DrawSpritesHiAS\r
+\r
// draw a sprite pixel (AS)\r
#define pix_as(x) \\r
- if (t & mb[x]) mb[x] = 0, pd[x] = pal | t\r
+ if (t && (m & (1<<(x+8)))) m &= ~(1<<(x+8)), pd[x] = pal | t\r
\r
TileNormMakerAS(TileNormAS, pix_as)\r
TileFlipMakerAS(TileFlipAS, pix_as)\r
\r
// draw a sprite pixel, process operator colors (AS)\r
#define pix_sh_as(x) \\r
- if (t & mb[x]) { \\r
- mb[x] = 0; \\r
+ if (t && (m & (1<<(x+8)))) { \\r
+ m &= ~(1<<(x+8)); \\r
if (t>=0xe) pd[x]=(pd[x]&0x3f)|(t<<6); /* c0 shadow, 80 hilight */ \\r
else pd[x] = pal | t; \\r
}\r
TileFlipMakerAS(TileFlipSH_AS, pix_sh_as)\r
\r
#define pix_sh_as_onlyop(x) \\r
- if (t & mb[x]) { \\r
- mb[x] = 0; \\r
+ if (t && (m & (1<<(x+8)))) { \\r
+ m &= ~(1<<(x+8)); \\r
pix_sh_onlyop(x); \\r
}\r
\r
\r
// mark pixel as sprite pixel (AS)\r
#define pix_sh_as_onlymark(x) \\r
- if (t) mb[x] = 0\r
+ if (t) m &= ~(1<<(x+8))\r
\r
TileNormMakerAS(TileNormAS_onlymark, pix_sh_as_onlymark)\r
TileFlipMakerAS(TileFlipAS_onlymark, pix_sh_as_onlymark)\r
*/\r
static void DrawSpritesSHi(unsigned char *sprited, const struct PicoEState *est)\r
{\r
+ static void (*tilefuncs[2][2][2])(unsigned char *, unsigned, int) = {\r
+ { {NULL, NULL}, {TileNorm, TileFlip} },\r
+ { {TileNormSH_onlyop_lp, TileFlipSH_onlyop_lp}, {TileNormSH, TileFlipSH} }\r
+ }; // [sh?][hi?][flip?]\r
void (*fTileFunc)(unsigned char *pd, unsigned int pack, int pal);\r
unsigned char *pd = Pico.est.HighCol;\r
unsigned char *p;\r
code = sprite[1];\r
pal = (code>>9)&0x30;\r
\r
- if (pal == 0x30)\r
- {\r
- if (code & 0x8000) // hi priority\r
- {\r
- if (code&0x800) fTileFunc=TileFlipSH;\r
- else fTileFunc=TileNormSH;\r
- } else {\r
- if (code&0x800) fTileFunc=TileFlipSH_onlyop_lp;\r
- else fTileFunc=TileNormSH_onlyop_lp;\r
- }\r
- } else {\r
- if (!(code & 0x8000)) continue; // non-operator low sprite, already drawn\r
- if (code&0x800) fTileFunc=TileFlip;\r
- else fTileFunc=TileNorm;\r
- }\r
+ fTileFunc = tilefuncs[pal == 0x30][!!(code & 0x8000)][!!(code & 0x800)];\r
+ if (fTileFunc == NULL) continue; // non-operator low sprite, already drawn\r
\r
// parse remaining sprite data\r
sy=sprite[0];\r
\r
static void DrawSpritesHiAS(unsigned char *sprited, int sh)\r
{\r
- void (*fTileFunc)(unsigned char *pd, unsigned char *mb,\r
- unsigned int pack, int pal);\r
+ static unsigned (*tilefuncs[2][2][2])(unsigned char *, unsigned, unsigned, int) = {\r
+ { {TileNormAS_onlymark, TileFlipAS_onlymark}, {TileNormAS, TileFlipAS} },\r
+ { {TileNormSH_AS_onlyop_lp, TileFlipSH_AS_onlyop_lp}, {TileNormSH_AS, TileFlipSH_AS} }\r
+ }; // [sh?][hi?][flip?]\r
+ unsigned (*fTileFunc)(unsigned char *pd, unsigned m, unsigned int pack, int pal);\r
unsigned char *pd = Pico.est.HighCol;\r
- unsigned char mb[8+320+8];\r
- unsigned char *p;\r
+ unsigned char mb[1+320/8+1];\r
+ unsigned char *p, *mp;\r
+ unsigned m;\r
int entry, cnt;\r
\r
cnt = sprited[0] & 0x7f;\r
code = sprite[1];\r
pal = (code>>9)&0x30;\r
\r
- if (sh && pal == 0x30)\r
- {\r
- if (code & 0x8000) // hi priority\r
- {\r
- if (code&0x800) fTileFunc = TileFlipSH_AS;\r
- else fTileFunc = TileNormSH_AS;\r
- } else {\r
- if (code&0x800) fTileFunc = TileFlipSH_AS_onlyop_lp;\r
- else fTileFunc = TileNormSH_AS_onlyop_lp;\r
- }\r
- } else {\r
- if (code & 0x8000) // hi priority\r
- {\r
- if (code&0x800) fTileFunc = TileFlipAS;\r
- else fTileFunc = TileNormAS;\r
- } else {\r
- if (code&0x800) fTileFunc = TileFlipAS_onlymark;\r
- else fTileFunc = TileNormAS_onlymark;\r
- }\r
- }\r
+ fTileFunc = tilefuncs[(sh && pal == 0x30)][!!(code&0x8000)][!!(code&0x800)];\r
\r
// parse remaining sprite data\r
sy=sprite[0];\r
if(sx>=328) break; // Offscreen\r
\r
pack = *(unsigned int *)(PicoMem.vram + (tile & 0x7fff));\r
- fTileFunc(pd + sx, mb + sx, pack, pal);\r
- }\r
+\r
+ m = (m >> 8) | mp[1] << 8; // next mask byte\r
+ // shift mask bits to bits 8-15 for easier load/store handling\r
+ m = fTileFunc(pd + sx, m << (8-(sx&0x7)), pack, pal) >> (8-(sx&0x7));\r
+ } \r
+ *mp = m >> 8; // write last mask byte\r
}\r
}\r
\r
delta<<=4; // Delta of address\r
\r
if (entry+1 == cnt) width = p[entry+1]; // last sprite width limited?\r
- for (; width; width--,sx+=8,tile+=delta)\r
+ mp = mb+(sx>>3);\r
+ for (m = *mp << 8; width; width--, sx+=8, *mp++ = m, tile+=delta)\r
{\r
unsigned int pack;\r
\r