static int HighCacheB[41+1];\r
static int HighPreSpr[80*2+1]; // slightly preprocessed sprites\r
\r
+#define LF_PLANE_1 (1 << 0)\r
+#define LF_SH (1 << 1) // must be = 2\r
+#define LF_FORCE (1 << 2)\r
+\r
#define SPRL_HAVE_HI 0x80 // have hi priority sprites\r
#define SPRL_HAVE_LO 0x40 // *lo*\r
#define SPRL_MAY_HAVE_OP 0x20 // may have operator sprites on the line\r
\r
int rendstatus_old;\r
int rendlines;\r
-int PicoDrawMask = -1;\r
\r
static int skip_next_line=0;\r
\r
-//unsigned short ppt[] = { 0x0f11, 0x0ff1, 0x01f1, 0x011f, 0x01ff, 0x0f1f, 0x0f0e, 0x0e7c };\r
-\r
struct TileStrip\r
{\r
int nametab; // Position in VRAM of name table (for this tile line)\r
}\r
\r
\r
-#ifdef _ASM_DRAW_C_AMIPS\r
-int TileNorm(int sx, unsigned int pack, int pal);\r
-int TileFlip(int sx, unsigned int pack, int pal);\r
-#else\r
-\r
#define pix_just_write(x) \\r
if (t) pd[x]=pal|t\r
\r
TileNormMaker(TileNorm,pix_just_write)\r
TileFlipMaker(TileFlip,pix_just_write)\r
\r
-#endif\r
-\r
#ifndef _ASM_DRAW_C\r
\r
// draw a sprite pixel, process operator colors\r
TileNormMaker(TileNormAS_onlymark, pix_sh_as_onlymark)\r
TileFlipMaker(TileFlipAS_onlymark, pix_sh_as_onlymark)\r
\r
+// mark pixel as sprite pixel (AS)\r
+#define pix_and(x) \\r
+ pd[x] = (pd[x] & 0xc0) | (pd[x] & (pal | t))\r
+\r
+TileNormMaker(TileNorm_and, pix_and)\r
+TileFlipMaker(TileFlip_and, pix_and)\r
\r
// --------------------------------------------\r
\r
#ifndef _ASM_DRAW_C\r
-static void DrawStrip(struct TileStrip *ts, int plane_sh, int cellskip)\r
+static void DrawStrip(struct TileStrip *ts, int lflags, int cellskip)\r
{\r
int tilex,dx,ty,code=0,addr=0,cells;\r
int oldcode=-1,blank=-1; // The tile we know is blank\r
int pal=0,sh;\r
\r
// Draw tiles across screen:\r
- sh=(plane_sh<<5)&0x40;\r
+ sh = (lflags & LF_SH) << 5; // 0x40\r
tilex=((-ts->hscroll)>>3)+cellskip;\r
ty=(ts->line&7)<<1; // Y-Offset into tile\r
dx=((ts->hscroll-1)&7)+1;\r
if(dx != 8) cells++; // have hscroll, need to draw 1 cell more\r
dx+=cellskip<<3;\r
\r
- for (; cells > 0; dx+=8,tilex++,cells--)\r
+ for (; cells > 0; dx+=8, tilex++, cells--)\r
{\r
unsigned int pack;\r
\r
- code=Pico.vram[ts->nametab+(tilex&ts->xmask)];\r
- if (code==blank) continue;\r
- if (code>>15) { // high priority tile\r
+ code = Pico.vram[ts->nametab + (tilex & ts->xmask)];\r
+ if (code == blank)\r
+ continue;\r
+ if ((code >> 15) | (lflags & LF_FORCE)) { // high priority tile\r
int cval = code | (dx<<16) | (ty<<25);\r
if(code&0x1000) cval^=7<<26;\r
*ts->hc++ = cval; // cache it\r
{\r
short blank=-1; // The tile we know is blank\r
while ((code=*hc++)) {\r
- if((short)code == blank) continue;\r
+ if (!(code & 0x8000) || (short)code == blank)\r
+ continue;\r
// Get tile address/2:\r
- addr=(code&0x7ff)<<4;\r
- addr+=(unsigned int)code>>25; // y offset into tile\r
+ addr = (code & 0x7ff) << 4;\r
+ addr += code >> 25; // y offset into tile\r
\r
pack = *(unsigned int *)(Pico.vram + addr);\r
if (!pack) {\r
}\r
#endif\r
\r
+static NOINLINE void DrawTilesFromCacheForced(const int *hc)\r
+{\r
+ int code, addr, dx;\r
+ unsigned int pack;\r
+ int pal;\r
+\r
+ // *ts->hc++ = code | (dx<<16) | (ty<<25);\r
+ while ((code = *hc++)) {\r
+ // Get tile address/2:\r
+ addr = (code & 0x7ff) << 4;\r
+ addr += (code >> 25) & 0x0e; // y offset into tile\r
+\r
+ dx = (code >> 16) & 0x1ff;\r
+ pal = ((code >> 9) & 0x30);\r
+ pack = *(unsigned int *)(Pico.vram + addr);\r
+\r
+ if (code & 0x0800) TileFlip_and(dx, pack, pal);\r
+ else TileNorm_and(dx, pack, pal);\r
+ }\r
+}\r
+\r
static void DrawSpriteInterlace(unsigned int *sprite)\r
{\r
int width=0,height=0;\r
}\r
\r
\r
-static void DrawAllSpritesInterlace(int pri, int sh)\r
+static NOINLINE void DrawAllSpritesInterlace(int pri, int sh)\r
{\r
struct PicoVideo *pvid=&Pico.video;\r
int i,u,table,link=0,sline=Pico.est.DrawScanline<<1;\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
+ int win=0, edge=0, hvwind=0, lflags;\r
+ int maxw, maxcells;\r
\r
if (est->rendstatus & (PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES)) {\r
// elprintf(EL_STATUS, "PrepareSprites(%i)", (est->rendstatus>>4)&1);\r
}\r
\r
/* - layer B low - */\r
- if (PicoDrawMask & PDRAW_LAYERB_ON)\r
- DrawLayer(1|(sh<<1), HighCacheB, 0, maxcells, est);\r
+ if (!(pvid->debug_p & PVD_KILL_B)) {\r
+ lflags = LF_PLANE_1 | (sh << 1);\r
+ if (pvid->debug_p & PVD_FORCE_B)\r
+ lflags |= LF_FORCE;\r
+ DrawLayer(lflags, HighCacheB, 0, maxcells, est);\r
+ }\r
/* - layer A low - */\r
- if (!(PicoDrawMask & PDRAW_LAYERA_ON));\r
+ lflags = 0 | (sh << 1);\r
+ if (pvid->debug_p & PVD_FORCE_A)\r
+ lflags |= LF_FORCE;\r
+ if (pvid->debug_p & PVD_KILL_A)\r
+ ;\r
else if (hvwind == 1)\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, 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, est);\r
+ DrawLayer(lflags, 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
+ }\r
+ else\r
+ DrawLayer(lflags, HighCacheA, 0, maxcells, est);\r
/* - sprites low - */\r
- if (!(PicoDrawMask & PDRAW_SPRITES_LOW_ON));\r
+ if (pvid->debug_p & PVD_KILL_S_LO)\r
+ ;\r
else if (est->rendstatus & PDRAW_INTERLACE)\r
DrawAllSpritesInterlace(0, sh);\r
else if (sprited[1] & SPRL_HAVE_LO)\r
DrawAllSprites(sprited, 0, sh, est);\r
\r
/* - layer B hi - */\r
- if ((PicoDrawMask & PDRAW_LAYERB_ON) && HighCacheB[0])\r
+ if (!(pvid->debug_p & PVD_KILL_B) && HighCacheB[0])\r
DrawTilesFromCache(HighCacheB, sh, maxw, est);\r
/* - layer A hi - */\r
- if (!(PicoDrawMask & PDRAW_LAYERA_ON));\r
+ if (pvid->debug_p & PVD_KILL_A)\r
+ ;\r
else if (hvwind == 1)\r
DrawWindow(0, maxcells>>1, 1, sh, est);\r
else if (hvwind == 2) {\r
if (HighCacheA[0])\r
DrawTilesFromCache(HighCacheA, sh, maxw, est);\r
/* - sprites hi - */\r
- if (!(PicoDrawMask & PDRAW_SPRITES_HI_ON));\r
+ if (pvid->debug_p & PVD_KILL_S_HI)\r
+ ;\r
else if (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] & SPRL_HAVE_HI)\r
DrawAllSprites(sprited, 1, 0, est);\r
\r
+ if (pvid->debug_p & PVD_FORCE_B)\r
+ DrawTilesFromCacheForced(HighCacheB);\r
+ else if (pvid->debug_p & PVD_FORCE_A)\r
+ DrawTilesFromCacheForced(HighCacheA);\r
+\r
#if 0\r
{\r
int *c, a, b;\r
return;\r
}\r
\r
+ if (Pico.video.debug_p & (PVD_FORCE_A | PVD_FORCE_B))\r
+ bgc = 0x3f;\r
+\r
// Draw screen:\r
BackFill(bgc, sh, &Pico.est);\r
if (Pico.video.reg[1]&0x40)\r
\r
pprof_start(draw);\r
\r
- if (rendlines != 240)\r
+ if (rendlines != 240) {\r
offs = 8;\r
+ if (to > 223)\r
+ to = 223;\r
+ }\r
\r
for (line = Pico.est.DrawScanline; line < to; line++)\r
- {\r
PicoLine(line, offs, sh, bgc);\r
- }\r
\r
// last line\r
if (line <= to)\r