static int HighCacheB[41+1];\r
static int HighCacheS[80+1]; // and sprites\r
static int HighPreSpr[80*2+1]; // slightly preprocessed sprites\r
+int *HighCacheS_ptr;\r
\r
int rendstatus = 0;\r
int Scanline = 0; // Scanline\r
#ifdef _ASM_DRAW_C\r
void DrawWindow(int tstart, int tend, int prio, int sh);\r
void BackFill(int reg7, int sh);\r
-void DrawSprite(int *sprite, int **hc, int sh, int as);\r
+void DrawSprite(int *sprite, int sh, int as);\r
void DrawTilesFromCache(int *hc, int sh, int rlim);\r
void DrawSpritesFromCache(int *hc, int maxwidth, int prio, int sh);\r
void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells);\r
#endif\r
\r
\r
-#ifdef _ASM_DRAW_C_AMIPS\r
-int TileNorm(int sx,int addr,int pal);\r
-int TileFlip(int sx,int addr,int pal);\r
-#else\r
-static int TileNorm(int sx,int addr,int pal)\r
-{\r
- unsigned char *pd = HighCol+sx;\r
- unsigned int pack=0; unsigned int t=0;\r
-\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
- if (pack)\r
- {\r
- t=pack&0x0000f000; if (t) pd[0]=(unsigned char)(pal|(t>>12));\r
- t=pack&0x00000f00; if (t) pd[1]=(unsigned char)(pal|(t>> 8));\r
- t=pack&0x000000f0; if (t) pd[2]=(unsigned char)(pal|(t>> 4));\r
- t=pack&0x0000000f; if (t) pd[3]=(unsigned char)(pal|(t ));\r
- t=pack&0xf0000000; if (t) pd[4]=(unsigned char)(pal|(t>>28));\r
- t=pack&0x0f000000; if (t) pd[5]=(unsigned char)(pal|(t>>24));\r
- t=pack&0x00f00000; if (t) pd[6]=(unsigned char)(pal|(t>>20));\r
- t=pack&0x000f0000; if (t) pd[7]=(unsigned char)(pal|(t>>16));\r
- return 0;\r
- }\r
-\r
- return 1; // Tile blank\r
+#define TileNormMaker(funcname,pix_func) \\r
+static int funcname(int sx,int addr,int pal) \\r
+{ \\r
+ unsigned char *pd = HighCol+sx; \\r
+ unsigned int pack=0; unsigned int t=0; \\r
+ \\r
+ pack=*(unsigned int *)(Pico.vram+addr); /* Get 8 pixels */ \\r
+ if (pack) \\r
+ { \\r
+ t=(pack&0x0000f000)>>12; pix_func(0); \\r
+ t=(pack&0x00000f00)>> 8; pix_func(1); \\r
+ t=(pack&0x000000f0)>> 4; pix_func(2); \\r
+ t=(pack&0x0000000f) ; pix_func(3); \\r
+ t=(pack&0xf0000000)>>28; pix_func(4); \\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 0; \\r
+ } \\r
+ \\r
+ return 1; /* Tile blank */ \\r
}\r
\r
-static int TileFlip(int sx,int addr,int pal)\r
-{\r
- unsigned char *pd = HighCol+sx;\r
- unsigned int pack=0; unsigned int t=0;\r
\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
- if (pack)\r
- {\r
- t=pack&0x000f0000; if (t) pd[0]=(unsigned char)(pal|(t>>16));\r
- t=pack&0x00f00000; if (t) pd[1]=(unsigned char)(pal|(t>>20));\r
- t=pack&0x0f000000; if (t) pd[2]=(unsigned char)(pal|(t>>24));\r
- t=pack&0xf0000000; if (t) pd[3]=(unsigned char)(pal|(t>>28));\r
- t=pack&0x0000000f; if (t) pd[4]=(unsigned char)(pal|(t ));\r
- t=pack&0x000000f0; if (t) pd[5]=(unsigned char)(pal|(t>> 4));\r
- t=pack&0x00000f00; if (t) pd[6]=(unsigned char)(pal|(t>> 8));\r
- t=pack&0x0000f000; if (t) pd[7]=(unsigned char)(pal|(t>>12));\r
- return 0;\r
- }\r
- return 1; // Tile blank\r
+#define TileFlipMaker(funcname,pix_func) \\r
+static int funcname(int sx,int addr,int pal) \\r
+{ \\r
+ unsigned char *pd = HighCol+sx; \\r
+ unsigned int pack=0; unsigned int t=0; \\r
+ \\r
+ pack=*(unsigned int *)(Pico.vram+addr); /* Get 8 pixels */ \\r
+ if (pack) \\r
+ { \\r
+ t=(pack&0x000f0000)>>16; pix_func(0); \\r
+ t=(pack&0x00f00000)>>20; pix_func(1); \\r
+ t=(pack&0x0f000000)>>24; pix_func(2); \\r
+ t=(pack&0xf0000000)>>28; pix_func(3); \\r
+ t=(pack&0x0000000f) ; pix_func(4); \\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 0; \\r
+ } \\r
+ \\r
+ return 1; /* Tile blank */ \\r
}\r
-#endif\r
\r
-// tile renderers for hacky operator sprite support\r
-#define sh_pix(x) \\r
- if(!t); \\r
- else if(t==0xe) pd[x]=(unsigned char)((pd[x]&0x3f)|0x80); /* hilight */ \\r
- else if(t==0xf) pd[x]=(unsigned char)( pd[x] |0xc0); /* shadow */ \\r
- else pd[x]=(unsigned char)(pal|t)\r
\r
-#ifndef _ASM_DRAW_C\r
-static int TileNormSH(int sx,int addr,int pal)\r
-{\r
- unsigned int pack=0; unsigned int t=0;\r
- unsigned char *pd = HighCol+sx;\r
-\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
- if (pack)\r
- {\r
- t=(pack&0x0000f000)>>12; sh_pix(0);\r
- t=(pack&0x00000f00)>> 8; sh_pix(1);\r
- t=(pack&0x000000f0)>> 4; sh_pix(2);\r
- t=(pack&0x0000000f) ; sh_pix(3);\r
- t=(pack&0xf0000000)>>28; sh_pix(4);\r
- t=(pack&0x0f000000)>>24; sh_pix(5);\r
- t=(pack&0x00f00000)>>20; sh_pix(6);\r
- t=(pack&0x000f0000)>>16; sh_pix(7);\r
- return 0;\r
- }\r
+#ifdef _ASM_DRAW_C_AMIPS\r
+int TileNorm(int sx,int addr,int pal);\r
+int TileFlip(int sx,int addr,int pal);\r
+#else\r
\r
- return 1; // Tile blank\r
-}\r
+#define pix_just_write(x) \\r
+ if (t) pd[x]=pal|t\r
\r
-static int TileFlipSH(int sx,int addr,int pal)\r
-{\r
- unsigned int pack=0; unsigned int t=0;\r
- unsigned char *pd = HighCol+sx;\r
+TileNormMaker(TileNorm,pix_just_write)\r
+TileFlipMaker(TileFlip,pix_just_write)\r
\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
- if (pack)\r
- {\r
- t=(pack&0x000f0000)>>16; sh_pix(0);\r
- t=(pack&0x00f00000)>>20; sh_pix(1);\r
- t=(pack&0x0f000000)>>24; sh_pix(2);\r
- t=(pack&0xf0000000)>>28; sh_pix(3);\r
- t=(pack&0x0000000f) ; sh_pix(4);\r
- t=(pack&0x000000f0)>> 4; sh_pix(5);\r
- t=(pack&0x00000f00)>> 8; sh_pix(6);\r
- t=(pack&0x0000f000)>>12; sh_pix(7);\r
- return 0;\r
- }\r
- return 1; // Tile blank\r
-}\r
#endif\r
\r
-#define tilepixelAS(mask,index,shift) \\r
- if (!(pd[index]&0xc0)) { t=pack&mask; if (t) pd[index]=(pal|(t>>shift)); }\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 pd[x]=pal|t\r
\r
-static int TileNormAS(int sx,int addr,int pal)\r
-{\r
- unsigned char *pd = HighCol+sx;\r
- unsigned int pack=0; unsigned int t=0;\r
+TileNormMaker(TileNormSH, pix_sh)\r
+TileFlipMaker(TileFlipSH, pix_sh)\r
\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
- if (pack)\r
- {\r
- tilepixelAS(0x0000f000, 0, 12);\r
- tilepixelAS(0x00000f00, 1, 8);\r
- tilepixelAS(0x000000f0, 2, 4);\r
- tilepixelAS(0x0000000f, 3, 0);\r
- tilepixelAS(0xf0000000, 4, 28);\r
- tilepixelAS(0x0f000000, 5, 24);\r
- tilepixelAS(0x00f00000, 6, 20);\r
- tilepixelAS(0x000f0000, 7, 16);\r
- return 0;\r
- }\r
+#ifndef _ASM_DRAW_C\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
\r
- return 1; // Tile blank\r
-}\r
+TileNormMaker(TileNormSH_noop, pix_sh_noop)\r
+TileFlipMaker(TileFlipSH_noop, pix_sh_noop)\r
+#endif\r
\r
-static int TileFlipAS(int sx,int addr,int pal)\r
-{\r
- unsigned char *pd = HighCol+sx;\r
- unsigned int pack=0; unsigned int t=0;\r
+// process operator pixels only, apply only on low pri tiles\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
\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
- if (pack)\r
- {\r
- tilepixelAS(0x000f0000, 0, 16);\r
- tilepixelAS(0x00f00000, 1, 20);\r
- tilepixelAS(0x0f000000, 2, 24);\r
- tilepixelAS(0xf0000000, 3, 28);\r
- tilepixelAS(0x0000000f, 4, 0);\r
- tilepixelAS(0x000000f0, 5, 4);\r
- tilepixelAS(0x00000f00, 6, 8);\r
- tilepixelAS(0x0000f000, 7, 12);\r
- return 0;\r
- }\r
- return 1; // Tile blank\r
-}\r
+TileNormMaker(TileNormSH_onlyop_lp, pix_sh_onlyop)\r
+TileFlipMaker(TileFlipSH_onlyop_lp, pix_sh_onlyop)\r
\r
-// there is a problem with transparent hi pri tiles (on layer), it will clear high bits\r
-// and sprite tiles will be drawn needlessly. Hopefully that won't happen much..\r
-#define sh_pixAS(x) \\r
- if(!t); \\r
- else if(t==0xe) pd[x]=(unsigned char)((pd[x]&0x3f)|0x80); /* hilight */ \\r
- else if(t==0xf) pd[x]=(unsigned char)( pd[x] |0xc0); /* shadow */ \\r
- else if(!(pd[x]&0xc0)) pd[x]=(unsigned char)(pal|t)\r
+// draw a sprite pixel (AS)\r
+#define pix_as(x) \\r
+ if (t && !(pd[x]&0x80)) pd[x]=pal|t\r
\r
-static int TileNormSHAS(int sx,int addr,int pal)\r
-{\r
- unsigned int pack=0; unsigned int t=0;\r
- unsigned char *pd = HighCol+sx;\r
+TileNormMaker(TileNormAS, pix_as)\r
+TileFlipMaker(TileFlipAS, pix_as)\r
\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
- if (pack)\r
- {\r
- t=(pack&0x0000f000)>>12; sh_pixAS(0);\r
- t=(pack&0x00000f00)>> 8; sh_pixAS(1);\r
- t=(pack&0x000000f0)>> 4; sh_pixAS(2);\r
- t=(pack&0x0000000f) ; sh_pixAS(3);\r
- t=(pack&0xf0000000)>>28; sh_pixAS(4);\r
- t=(pack&0x0f000000)>>24; sh_pixAS(5);\r
- t=(pack&0x00f00000)>>20; sh_pixAS(6);\r
- t=(pack&0x000f0000)>>16; sh_pixAS(7);\r
- return 0;\r
- }\r
+// draw a sprite pixel, skip operator colors (AS)\r
+#define pix_sh_as_noop(x) \\r
+ if (t && t < 0xe && !(pd[x]&0x80)) pd[x]=pal|t\r
\r
- return 1; // Tile blank\r
-}\r
+TileNormMaker(TileNormAS_noop, pix_sh_as_noop)\r
+TileFlipMaker(TileFlipAS_noop, pix_sh_as_noop)\r
\r
-static int TileFlipSHAS(int sx,int addr,int pal)\r
-{\r
- unsigned int pack=0; unsigned int t=0;\r
- unsigned char *pd = HighCol+sx;\r
+// mark pixel as sprite pixel (AS)\r
+#define pix_sh_as_onlymark(x) \\r
+ if (t) pd[x]|=0x80\r
\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
- if (pack)\r
- {\r
- t=(pack&0x000f0000)>>16; sh_pixAS(0);\r
- t=(pack&0x00f00000)>>20; sh_pixAS(1);\r
- t=(pack&0x0f000000)>>24; sh_pixAS(2);\r
- t=(pack&0xf0000000)>>28; sh_pixAS(3);\r
- t=(pack&0x0000000f) ; sh_pixAS(4);\r
- t=(pack&0x000000f0)>> 4; sh_pixAS(5);\r
- t=(pack&0x00000f00)>> 8; sh_pixAS(6);\r
- t=(pack&0x0000f000)>>12; sh_pixAS(7);\r
- return 0;\r
- }\r
- return 1; // Tile blank\r
-}\r
+TileNormMaker(TileNormAS_onlymark, pix_sh_as_onlymark)\r
+TileFlipMaker(TileFlipAS_onlymark, pix_sh_as_onlymark)\r
\r
\r
// --------------------------------------------\r
static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache\r
{\r
struct PicoVideo *pvid=&Pico.video;\r
- int tilex=0,ty=0,nametab,code=0;\r
+ int tilex,ty,nametab,code=0;\r
int blank=-1; // The tile we know is blank\r
\r
// Find name table line:\r
}\r
\r
tilex=tstart<<1;\r
- tend<<=1;\r
-\r
- ty=(Scanline&7)<<1; // Y-Offset into tile\r
\r
if (!(rendstatus & PDRAW_WND_DIFF_PRIO)) {\r
// check the first tile code\r
if ((code>>15) != prio) return;\r
}\r
\r
+ tend<<=1;\r
+ ty=(Scanline&7)<<1; // Y-Offset into tile\r
+\r
// Draw tiles across screen:\r
if (!sh)\r
{\r
for (; tilex < tend; tilex++)\r
{\r
int addr=0,zero=0;\r
- int pal, tmp, *zb;\r
+ int pal;\r
\r
code=Pico.vram[nametab+tilex];\r
if(code==blank) continue;\r
\r
pal=((code>>9)&0x30);\r
\r
- zb = (int *)(HighCol+8+(tilex<<3));\r
- if(prio) {\r
- tmp = *zb;\r
- if(!(tmp&0x00000080)) tmp&=~0x000000c0; if(!(tmp&0x00008000)) tmp&=~0x0000c000;\r
- if(!(tmp&0x00800000)) tmp&=~0x00c00000; if(!(tmp&0x80000000)) tmp&=~0xc0000000;\r
- *zb++=tmp; tmp = *zb;\r
- if(!(tmp&0x00000080)) tmp&=~0x000000c0; if(!(tmp&0x00008000)) tmp&=~0x0000c000;\r
- if(!(tmp&0x00800000)) tmp&=~0x00c00000; if(!(tmp&0x80000000)) tmp&=~0xc0000000;\r
- *zb++=tmp;\r
+ if (prio) {\r
+ int *zb = (int *)(HighCol+8+(tilex<<3));\r
+ *zb++ &= 0x3f3f3f3f;\r
+ *zb &= 0x3f3f3f3f;\r
} else {\r
pal |= 0x40;\r
}\r
rendstatus |= PDRAW_SHHI_DONE;\r
while (c--)\r
{\r
- int tmp = *zb;\r
- if (!(tmp & 0x80808080)) *zb=tmp&0x3f3f3f3f;\r
- else {\r
- if(!(tmp&0x00000080)) tmp&=~0x000000c0; if(!(tmp&0x00008000)) tmp&=~0x0000c000;\r
- if(!(tmp&0x00800000)) tmp&=~0x00c00000; if(!(tmp&0x80000000)) tmp&=~0xc0000000;\r
- *zb=tmp;\r
- }\r
- zb++;\r
+ *zb++ &= 0x3f3f3f3f;\r
}\r
}\r
\r
addr+=(unsigned int)code>>25; // y offset into tile\r
dx=(code>>16)&0x1ff;\r
zb = HighCol+dx;\r
- if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++;\r
- if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++;\r
- if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++;\r
- if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++;\r
+ *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f;\r
+ *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f;\r
\r
pal=((code>>9)&0x30);\r
if (rlim-dx < 0) goto last_cut_tile;\r
// Index + 0 : hhhhvvvv ab--hhvv yyyyyyyy yyyyyyyy // a: offscreen h, b: offs. v, h: horiz. size\r
// Index + 4 : xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
\r
-static void DrawSprite(int *sprite, int **hc, int sh, int as)\r
+static void DrawSprite(int *sprite, int sh, int as)\r
{\r
int width=0,height=0;\r
int row=0,code=0;\r
\r
if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
\r
- tile=code&0x7ff; // Tile number\r
- tile+=row>>3; // Tile number increases going down\r
+ tile=code + (row>>3); // Tile number increases going down\r
delta=height; // Delta to increase tile by going right\r
if (code&0x0800) { tile+=delta*(width-1); delta=-delta; } // Flip X\r
\r
- tile<<=4; tile+=(row&7)<<1; // Tile address\r
+ tile &= 0x7ff; tile<<=4; tile+=(row&7)<<1; // Tile address\r
+\r
+ pal=(code>>9)&0x30;\r
\r
- if (code&0x8000) { // high priority - cache it\r
- *(*hc)++ = (tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|((code>>9)&0x30)|((sprite[0]>>16)&0xf);\r
- // we need all for accurate sprites, cached will be used to recover ones overwritten by high layer\r
- if (!as) return;\r
+ // assume there will be no sprites with both normal and operator pixels..\r
+ if ((code&0x8000) || (sh && pal == 0x30) || as) {\r
+ *HighCacheS_ptr++ = ((code&0x8000)<<16)|(tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|pal|((sprite[0]>>16)&0xf);\r
+ // we need all for accurate sprites, cached will be used to do proper priorities\r
+ if (!as && (code&0x8000)) return;\r
}\r
\r
delta<<=4; // Delta of address\r
- pal=((code>>9)&0x30)|((sh|as)<<6);\r
+ pal|=((sh|as)<<6);\r
\r
if (sh && (code&0x6000) == 0x6000) {\r
- if(code&0x0800) fTileFunc=TileFlipSH;\r
- else fTileFunc=TileNormSH;\r
+ if(code&0x0800) fTileFunc=TileFlipSH_noop;\r
+ else fTileFunc=TileNormSH_noop;\r
} else {\r
if(code&0x0800) fTileFunc=TileFlip;\r
else fTileFunc=TileNorm;\r
int pal;\r
int (*fTileFunc)(int sx,int addr,int pal);\r
\r
- // *(*hc)++ = (tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|((code>>9)&0x30)|((sprite[0]>>24)&0xf);\r
+ // prio[31]:tile[30:17]:flipx[16]:sx[15:6]:pal[5:4]:delta_width[3:0]\r
\r
- while((code=*hc++)) {\r
+ while ((code=*hc++))\r
+ {\r
pal=(code&0x30);\r
delta=code&0xf;\r
width=delta>>2; delta&=3;\r
width++; delta++; // Width and height in tiles\r
if (code&0x10000) delta=-delta; // Flip X\r
delta<<=4;\r
- tile=((unsigned int)code>>17)<<1;\r
+ tile=((unsigned int)code>>17)<<1; // also has prio\r
sx=(code<<16)>>22; // sx can be negative (start offscreen), so sign extend\r
\r
- if(sh && pal == 0x30) { //\r
- if(code&0x10000) fTileFunc=TileFlipSH;\r
- else fTileFunc=TileNormSH;\r
+ if (sh && pal == 0x30)\r
+ {\r
+ if (code & 0x80000000) // hi priority\r
+ {\r
+ if(code&0x10000) fTileFunc=TileFlipSH;\r
+ else fTileFunc=TileNormSH;\r
+ } else {\r
+ if(code&0x10000) fTileFunc=TileFlipSH_onlyop_lp;\r
+ else fTileFunc=TileNormSH_onlyop_lp;\r
+ }\r
} else {\r
if(code&0x10000) fTileFunc=TileFlip;\r
else fTileFunc=TileNorm;\r
static void DrawSpritesFromCacheAS(int *hc, int maxwidth, int prio, int sh)\r
{\r
int code, tile, sx, delta, width;\r
- int pal;\r
+ int pal, *hce, *hco;\r
int (*fTileFunc)(int sx,int addr,int pal);\r
\r
- // *(*hc)++ = (tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|((code>>9)&0x30)|((sprite[0]>>24)&0xf);\r
+ // prio[31]:tile[30:17]:flipx[16]:sx[15:6]:pal[5:4]:delta_width[3:0]\r
\r
- while((code=*hc++)) {\r
+ /* walk the sprite cache backwards.. */\r
+ hco = hce = HighCacheS_ptr;\r
+ while (hce > hc)\r
+ {\r
+ code=*(--hce);\r
pal=(code&0x30);\r
delta=code&0xf;\r
width=delta>>2; delta&=3;\r
tile=((unsigned int)code>>17)<<1;\r
sx=(code<<16)>>22; // sx can be negative (start offscreen), so sign extend\r
\r
- if(sh && pal == 0x30) { //\r
- if(code&0x10000) fTileFunc=TileFlipSHAS;\r
- else fTileFunc=TileNormSHAS;\r
+ if (code & 0x80000000) // hi priority\r
+ {\r
+ if (sh && pal == 0x30)\r
+ {\r
+ if(code&0x10000) fTileFunc=TileFlipAS_noop;\r
+ else fTileFunc=TileNormAS_noop;\r
+ *(--hco) = code; /* save for later */\r
+ } else {\r
+ if(code&0x10000) fTileFunc=TileFlipAS;\r
+ else fTileFunc=TileNormAS;\r
+ }\r
} else {\r
- if(code&0x10000) fTileFunc=TileFlipAS;\r
- else fTileFunc=TileNormAS;\r
+ if(code&0x10000) fTileFunc=TileFlipAS_onlymark;\r
+ else fTileFunc=TileNormAS_onlymark;\r
}\r
\r
+ pal |= 0x80;\r
+ for (; width; width--,sx+=8,tile+=delta)\r
+ {\r
+ if(sx<=0) continue;\r
+ if(sx>=328) break; // Offscreen\r
+\r
+ tile&=0x7fff; // Clip tile address\r
+ fTileFunc(sx,tile,pal);\r
+ }\r
+ }\r
+\r
+ if (!sh) return;\r
+\r
+ /* nasty 1: remove 'sprite' flags */\r
+ {\r
+ int c = 320/4, *zb = (int *)(HighCol+8);\r
+ while (c--)\r
+ {\r
+ *zb++ &= 0x7f7f7f7f;\r
+ }\r
+ }\r
+\r
+ /* nasty 2: loop once more and do operator colors */\r
+ while ((code=*hco++))\r
+ {\r
+ pal=(code&0x30);\r
+ if (pal != 0x30) continue;\r
+ delta=code&0xf;\r
+ width=delta>>2; delta&=3;\r
+ width++; delta++;\r
+ if (code&0x10000) delta=-delta; // Flip X\r
+ delta<<=4;\r
+ tile=((unsigned int)code>>17)<<1;\r
+ sx=(code<<16)>>22;\r
+\r
+ if (code & 0x80000000)\r
+ {\r
+ if(code&0x10000) fTileFunc=TileFlipSH;\r
+ else fTileFunc=TileNormSH;\r
+ } else {\r
+ if(code&0x10000) fTileFunc=TileFlipSH_onlyop_lp;\r
+ else fTileFunc=TileNormSH_onlyop_lp;\r
+ }\r
+\r
+ pal |= 0x80;\r
for (; width; width--,sx+=8,tile+=delta)\r
{\r
if(sx<=0) continue;\r
}\r
\r
\r
+\r
// Index + 0 : ----hhvv -lllllll -------y yyyyyyyy\r
// Index + 4 : -------x xxxxxxxx pccvhnnn nnnnnnnn\r
// v\r
if (PicoOpt & POPT_DIS_SPRITE_LIM)\r
max_line_sprites = 80;\r
\r
+ HighCacheS_ptr = hcache;\r
ps = HighPreSpr;\r
\r
// Index + 0 : hhhhvvvv ab--hhvv yyyyyyyy yyyyyyyy // a: offscreen h, b: offs. v, h: horiz. size\r
\r
// Go through sprites backwards:\r
for (i--; i>=0; i--)\r
- DrawSprite(sprites[i],&hcache,sh,n);\r
+ DrawSprite(sprites[i],sh,n);\r
\r
// terminate cache list\r
- *hcache = 0;\r
+ *HighCacheS_ptr = 0;\r
}\r
\r
\r
DrawWindow((win&0x80) ? edge : 0, (win&0x80) ? maxcells>>1 : edge, 1, sh);\r
} else\r
if (HighCacheA[0]) DrawTilesFromCache(HighCacheA, sh, 328);\r
- DrawAllSpritesHiPri(HighCacheS, maxw, 1, sh);\r
+ if (HighCacheS[0]) DrawAllSpritesHiPri(HighCacheS, maxw, 1, sh);\r
\r
#if 0\r
{\r
@ vim:filetype=armasm\r
\r
-@ assembly "optimized" version of some funtions from draw.c\r
+@ ARM assembly versions of some funtions from draw.c\r
@ this is highly specialized, be careful if changing related C code!\r
\r
-@ (c) Copyright 2007, Grazvydas "notaz" Ignotas\r
+@ (c) Copyright 2007-2008, Grazvydas "notaz" Ignotas\r
@ All Rights Reserved\r
\r
.include "port_config.s"\r
.extern rendstatus\r
.extern DrawLineDest\r
.extern DrawStripInterlace\r
+.extern HighCacheS_ptr\r
\r
\r
@ helper\r
.endif\r
ldreqb r4, [r1,#\offs]\r
orrne r4, r3, r4\r
- strneb r4, [r1,#\offs]\r
- tsteq r4, #0x80\r
andeq r4, r4, #0x3f\r
- streqb r4, [r1,#\offs]\r
+ strb r4, [r1,#\offs]\r
.endm\r
\r
@ TileNormShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: register with helper pattern 0xf, touches r3 high bits\r
.else\r
ands r4, r12, r2\r
.endif\r
- beq 3f\r
+ beq 0f\r
cmp r4, #0xe\r
- beq 2f\r
- bgt 1f\r
- orr r4, r3, r4\r
- strb r4, [r1,#\ofs]\r
- b 3f\r
-1:\r
- ldrb r4, [r1,#\ofs] @ 2ci\r
- orr r4, r4, #0xc0\r
- strb r4, [r1,#\ofs]\r
- b 3f\r
-2:\r
- ldrb r4, [r1,#\ofs] @ 2ci\r
- bic r4, r4, #0xc0\r
- orr r4, r4, #0x80\r
+ ldrgeb r4, [r1,#\ofs]\r
+ orrlt r4, r3, r4 @ normal\r
+\r
+ biceq r4, r4, #0xc0 @ hilight\r
+ orreq r4, r4, #0x80\r
+ orrgt r4, r4, #0xc0 @ shadow\r
+\r
strb r4, [r1,#\ofs]\r
-3:\r
+0:\r
.endm\r
\r
@ TileFlipSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
TileDoShGenPixel 16, 7 @ #0x000f0000\r
.endm\r
\r
+.macro TileDoShGenPixel_noop shift ofs\r
+.if \shift\r
+ and r4, r12, r2, lsr #\shift\r
+.else\r
+ and r4, r12, r2\r
+.endif\r
+ sub r7, r4, #1\r
+ cmp r7, #0xd\r
+ orrcc r4, r3, r4 @ 0-0xc (was 1-0xd)\r
+ strccb r4, [r1,#\ofs]\r
+.endm\r
+\r
+.macro TileFlipSh_noop\r
+ TileDoShGenPixel_noop 16, 0 @ #0x000f0000\r
+ TileDoShGenPixel_noop 20, 1 @ #0x00f00000\r
+ TileDoShGenPixel_noop 24, 2 @ #0x0f000000\r
+ TileDoShGenPixel_noop 28, 3 @ #0xf0000000\r
+ TileDoShGenPixel_noop 0, 4 @ #0x0000000f\r
+ TileDoShGenPixel_noop 4, 5 @ #0x000000f0\r
+ TileDoShGenPixel_noop 8, 6 @ #0x00000f00\r
+ TileDoShGenPixel_noop 12, 7 @ #0x0000f000\r
+.endm\r
+\r
+.macro TileNormSh_noop\r
+ TileDoShGenPixel_noop 12, 0 @ #0x0000f000\r
+ TileDoShGenPixel_noop 8, 1 @ #0x00000f00\r
+ TileDoShGenPixel_noop 4, 2 @ #0x000000f0\r
+ TileDoShGenPixel_noop 0, 3 @ #0x0000000f\r
+ TileDoShGenPixel_noop 28, 4 @ #0xf0000000\r
+ TileDoShGenPixel_noop 24, 5 @ #0x0f000000\r
+ TileDoShGenPixel_noop 20, 6 @ #0x00f00000\r
+ TileDoShGenPixel_noop 16, 7 @ #0x000f0000\r
+.endm\r
+\r
+.macro TileDoShGenPixel_onlyop_lp shift ofs\r
+.if \shift\r
+ ands r7, r12, r2, lsr #\shift\r
+.else\r
+ ands r7, r12, r2\r
+.endif\r
+ ldrneb r4, [r1,#\ofs]\r
+ tstne r4, #0x40\r
+ beq 0f\r
+\r
+ cmp r7, #0xe\r
+ biceq r4, r4, #0xc0 @ hilight\r
+ orreq r4, r4, #0x80\r
+ orrgt r4, r4, #0xc0 @ shadow\r
+ strgeb r4, [r1,#\ofs]\r
+0:\r
+.endm\r
+\r
+.macro TileFlipSh_onlyop_lp\r
+ TileDoShGenPixel_onlyop_lp 16, 0 @ #0x000f0000\r
+ TileDoShGenPixel_onlyop_lp 20, 1 @ #0x00f00000\r
+ TileDoShGenPixel_onlyop_lp 24, 2 @ #0x0f000000\r
+ TileDoShGenPixel_onlyop_lp 28, 3 @ #0xf0000000\r
+ TileDoShGenPixel_onlyop_lp 0, 4 @ #0x0000000f\r
+ TileDoShGenPixel_onlyop_lp 4, 5 @ #0x000000f0\r
+ TileDoShGenPixel_onlyop_lp 8, 6 @ #0x00000f00\r
+ TileDoShGenPixel_onlyop_lp 12, 7 @ #0x0000f000\r
+.endm\r
+\r
+.macro TileNormSh_onlyop_lp\r
+ TileDoShGenPixel_onlyop_lp 12, 0 @ #0x0000f000\r
+ TileDoShGenPixel_onlyop_lp 8, 1 @ #0x00000f00\r
+ TileDoShGenPixel_onlyop_lp 4, 2 @ #0x000000f0\r
+ TileDoShGenPixel_onlyop_lp 0, 3 @ #0x0000000f\r
+ TileDoShGenPixel_onlyop_lp 28, 4 @ #0xf0000000\r
+ TileDoShGenPixel_onlyop_lp 24, 5 @ #0x0f000000\r
+ TileDoShGenPixel_onlyop_lp 20, 6 @ #0x00f00000\r
+ TileDoShGenPixel_onlyop_lp 16, 7 @ #0x000f0000\r
+.endm\r
+\r
\r
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
\r
b .dtfc_loop\r
\r
.dtfc_shadow_blank:\r
- ldrb r4, [r1] @ 1ci\r
- ldrb r12,[r1,#1]\r
- tst r4, #0x80\r
- andeq r4, r4,#0x3f\r
- streqb r4, [r1]\r
- tst r12,#0x80\r
- ldrb r4, [r1,#2]\r
- andeq r12,r12,#0x3f\r
- streqb r12,[r1,#1]\r
- tst r4, #0x80\r
- ldrb r12,[r1,#3]\r
- andeq r4, r4,#0x3f\r
- streqb r4, [r1,#2]\r
- tst r12,#0x80\r
- ldrb r4, [r1,#4]\r
- andeq r12,r12,#0x3f\r
- streqb r12,[r1,#3]\r
- tst r4, #0x80\r
- ldrb r12,[r1,#5]\r
- andeq r4, r4,#0x3f\r
- streqb r4, [r1,#4]\r
- tst r12,#0x80\r
- ldrb r4, [r1,#6]\r
- andeq r12,r12,#0x3f\r
- streqb r12,[r1,#5]\r
- tst r4, #0x80\r
- ldrb r12,[r1,#7]\r
- andeq r4, r4,#0x3f\r
- streqb r4, [r1,#6]\r
- tst r12,#0x80\r
- andeq r12,r12,#0x3f\r
- streqb r12,[r1,#7]\r
- mov r12, #0xf\r
+ tst r1, #1\r
+ ldrneb r4, [r1]\r
+ mov r6, #0x3f\r
+ and r4, r4, #0x3f\r
+ strneb r4, [r1], #1\r
+ ldrh r4, [r1]\r
+ orr r6, r6, r6, lsl #8\r
+ and r4, r4, r6\r
+ strh r4, [r1], #2\r
+ ldrh r4, [r1]\r
+ and r4, r4, r6\r
+ strh r4, [r1], #2\r
+ ldrh r4, [r1]\r
+ and r4, r4, r6\r
+ strh r4, [r1], #2\r
+ ldrh r4, [r1]\r
+ and r4, r4, r6\r
+ streqh r4, [r1]\r
+ strneb r4, [r1]\r
b .dtfc_loop\r
\r
.dtfc_cut_tile:\r
str r2, [r1]\r
\r
add r1, r11,#8\r
- mov r3, #320/4\r
- mov r7, #0x80\r
- orr r7, r7, r7, lsl #8\r
- orr r7, r7, r7, lsl #16\r
+ mov r3, #320/4/4\r
mov r6, #0x3f\r
orr r6, r6, r6, lsl #8\r
orr r6, r6, r6, lsl #16\r
.dtfc_loop_shprep:\r
+ ldmia r1, {r2,r4,r5,r7}\r
subs r3, r3, #1\r
- bmi .dtfc_loop @ done\r
- ldr r2, [r1]\r
- tst r2, r7\r
- andeq r2, r2, r6\r
- streq r2, [r1], #4\r
- beq .dtfc_loop_shprep\r
- tst r2, #0x80000000\r
- biceq r2, r2, #0xc0000000\r
- tst r2, #0x00800000\r
- biceq r2, r2, #0x00c00000\r
- tst r2, #0x00008000\r
- biceq r2, r2, #0x0000c000\r
- tst r2, #0x00000080\r
- biceq r2, r2, #0x000000c0\r
- str r2, [r1], #4\r
- b .dtfc_loop_shprep\r
+ and r2, r2, r6\r
+ and r4, r4, r6\r
+ and r5, r5, r6\r
+ and r7, r7, r6\r
+ stmia r1!,{r2,r4,r5,r7}\r
+ bne .dtfc_loop_shprep\r
+\r
+ mvn r5, #0 @ r5=prevcode=-1\r
+ b .dtfc_loop\r
\r
.pool\r
\r
b .dsfc_inloop\r
\r
.dsfc_shadow:\r
+ tst r9, #0x80000000\r
+ beq .dsfc_shadow_lowpri\r
+\r
cmp r2, r2, ror #4\r
beq .dsfc_singlec_sh\r
\r
TileSingleSh\r
b .dsfc_inloop\r
\r
+.dsfc_shadow_lowpri:\r
+ tst r9, #0x10000\r
+ bne .dsfc_TileFlip_sh_lp\r
+\r
+.dsfc_TileNorm_sh_lp:\r
+ TileNormSh_onlyop_lp\r
+ b .dsfc_inloop\r
+\r
+.dsfc_TileFlip_sh_lp:\r
+ TileFlipSh_onlyop_lp\r
+ b .dsfc_inloop\r
+\r
.pool\r
\r
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
@ + 0 : hhhhvvvv ab--hhvv yyyyyyyy yyyyyyyy // a: offscreen h, b: offs. v, h: horiz. size\r
@ + 4 : xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
\r
-.global DrawSprite @ unsigned int *sprite, int **hc, int sh, int acc_sprites\r
+.global DrawSprite @ unsigned int *sprite, int sh, int acc_sprites\r
\r
DrawSprite:\r
stmfd sp!, {r4-r9,r11,lr}\r
\r
- orr r8, r3, r2, lsl #4\r
+ orr r8, r2, r1, lsl #4\r
ldr r3, [r0] @ sprite[0]\r
ldr r7, =Scanline\r
mov r6, r3, lsr #28\r
subne r4, r4, #1\r
subne r7, r4, r7 @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
\r
- mov r8, r9, lsl #21\r
- mov r8, r8, lsr #21\r
- add r8, r8, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
- \r
+ add r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
tst r9, #0x0800\r
mlane r8, r5, r6, r8 @ if (code&0x0800) { tile+=delta*(width-1);\r
rsbne r5, r5, #0 @ delta=-delta; } // r5=delta now\r
\r
- mov r8, r8, lsl #4\r
+ mov r8, r8, lsl #21\r
+ mov r8, r8, lsr #17\r
and r7, r7, #7\r
add r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
\r
tst r9, #0x8000\r
- bne .dspr_cache @ if(code&0x8000) // high priority - cache it\r
+ tsteq r9, #(1<<27)\r
+ bne .dspr_cache @ if(code&0x8000) || as\r
+ tst r6, #0x4000\r
+ tstne r6, #0x2000\r
+ tstne r9, #(1<<31)\r
+ bne .dspr_cache @ (sh && pal == 0x30)\r
\r
.dspr_continue:\r
@ cache some stuff to avoid mem access\r
TileFlip r12\r
b .dspr_loop\r
\r
+.dspr_singlec_sh:\r
+ cmp r2, #0xe0000000\r
+ bcs .dspr_loop @ operator tileline, ignore\r
+\r
.dspr_SingleColor:\r
and r4, r2, #0xf\r
orr r4, r3, r4\r
\r
@ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
.dspr_TileNorm_sh:\r
- TileNormSh\r
+ TileNormSh_noop\r
b .dspr_loop\r
\r
.dspr_TileFlip_sh:\r
- TileFlipSh\r
- b .dspr_loop\r
-\r
-.dspr_singlec_sh:\r
- cmp r2, #0xe0000000\r
- bcc .dspr_SingleColor @ normal tileline\r
- tst r2, #0x10000000\r
- bne .dspr_sh_sh\r
- TileSingleHi\r
- b .dspr_loop\r
-\r
-.dspr_sh_sh:\r
- TileSingleSh\r
+ TileFlipSh_noop\r
b .dspr_loop\r
\r
\r
.dspr_cache:\r
- @ *(*hc)++ = (tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|((code>>9)&0x30)|((sprite[0]>>24)&0xf);\r
+ @ *HighCacheS_ptr++ = ((code&0x8000)<<16)|(tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|pal|((sprite[0]>>16)&0xf);\r
+ ldr r1, =HighCacheS_ptr\r
mov r4, r8, lsl #16 @ tile\r
tst r9, #0x0800\r
orrne r4, r4, #0x10000 @ code&0x0800\r
and r0, r9, #0x6000\r
orr r4, r4, r0, lsr #9 @ (code>>9)&0x30\r
mov r3, r3, lsl #12\r
- ldr r0, [r1]\r
orr r4, r4, r3, lsr #28 @ (sprite[0]>>24)&0xf\r
\r
+ ldr r0, [r1]\r
+ tst r9, #0x8000\r
+ orrne r4, r4, #0x80000000 @ prio\r
+\r
str r4, [r0], #4\r
str r0, [r1]\r
\r
- tst r9, #(1<<27)\r
- ldmeqfd sp!, {r4-r9,r11,lr}\r
- bne .dspr_continue @ draw anyway if accurate sprites enabled\r
- bxeq lr\r
+ and r0, r9, #(1<<27) @ as\r
+ teqne r0, #(1<<27) @ (code&0x8000) && !as\r
+ ldmnefd sp!, {r4-r9,r11,pc}\r
+ b .dspr_continue @ draw anyway if accurate sprites enabled\r
\r
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
\r
\r
ldr r6, =rendstatus\r
ldr lr, =(Pico+0x10000) @ lr=Pico.vram\r
- ldrb r6, [r6]\r
+ ldr r6, [r6]\r
\r
@ fetch the first code now\r
ldrh r7, [lr, r12]\r
\r
ands r6, r6, #2 @ we care about bit 1 only\r
orr r6, r6, r2\r
- bne .dw_no_sameprio\r
\r
- cmp r2, r7, lsr #15\r
- ldmnefd sp!, {r4-r11,pc} @ assume that whole window uses same priority\r
+ teqne r2, r7, lsr #15 @ do prio bits differ?\r
+ ldmnefd sp!, {r4-r11,pc} @ yes, assume that whole window uses same priority\r
\r
-.dw_no_sameprio:\r
orr r6, r6, r3, lsl #8 @ shadow mode\r
\r
sub r8, r1, r0\r
mov r8, r8, lsl #1 @ cells\r
mvn r9, #0 @ r9=prevcode=-1\r
.endif\r
- add r1, r11, r0, lsl #4 @ r1=pdest\r
+ add r1, r11, r0, lsl #4 @ r1=pdest\r
mov r0, #0xf\r
b .dwloop_enter\r
\r
- @ r4,r5 & r7 are scratch in this loop\r
+ @ r4,r5 are scratch in this loop\r
.dwloop:\r
add r1, r1, #8\r
.dwloop_nor1:\r
orreq r3, r3, #0x40\r
beq .dw_shadow_done\r
ldr r4, [r1]\r
- tst r4, #0x00000080\r
- biceq r4, r4, #0x000000c0\r
- tst r4, #0x00008000\r
- biceq r4, r4, #0x0000c000\r
- tst r4, #0x00800000\r
- biceq r4, r4, #0x00c00000\r
- tst r4, #0x80000000\r
- biceq r4, r4, #0xc0000000\r
+ mov r5, #0x3f\r
+ orr r5, r5, r5, lsl #8\r
+ orr r5, r5, r5, lsl #16\r
+ and r4, r4, r5\r
str r4, [r1]\r
ldr r4, [r1,#4]\r
- tst r4, #0x00000080\r
- biceq r4, r4, #0x000000c0\r
- tst r4, #0x00008000\r
- biceq r4, r4, #0x0000c000\r
- tst r4, #0x00800000\r
- biceq r4, r4, #0x00c00000\r
- tst r4, #0x80000000\r
- biceq r4, r4, #0xc0000000\r
+ and r4, r4, r5\r
str r4, [r1,#4]\r
b .dw_shadow_done\r
\r