#define LF_PLANE (1 << 0) // must be = 1\r
#define LF_SH (1 << 1) // must be = 2\r
//#define LF_FORCE (1 << 2)\r
-#define LF_LINE (1 << 3) // covers the line\r
-#define LF_LPRIO (1 << 8) // seen low prio tile\r
+#define LF_LINE (1 << 3) // layer covers line\r
+#define LF_LPRIO (1 << 8) // line has low prio tiles\r
\r
#define LF_PLANE_A 0\r
#define LF_PLANE_B 1\r
// NB s/h already resolved by non-forced drawing\r
// forced both layer draw (through debug reg)\r
#define pix_and(x) \\r
- pal |= 0xc0; /* leave s/h bits untouched in pixel "and" */ \\r
pd[x] &= pal|t\r
\r
TileNormMaker(TileNorm_and, pix_and)\r
\r
// forced sprite draw (through debug reg)\r
#define pix_sh_as_and(x) \\r
- pal |= 0xc0; /* leave s/h bits untouched in pixel "and" */ \\r
if (likely(m & (1<<(x+8)))) { \\r
m &= ~(1<<(x+8)); \\r
/* if (!t) pd[x] |= 0x40; as per titan hw notes? */ \\r
\r
// --------------------------------------------\r
\r
-#ifndef _ASM_DRAW_C\r
-#define DrawTile(mask,masked) { \\r
+#define DrawTile(mask,yshift,ymask,hpcode,cache) { \\r
if (code!=oldcode) { \\r
oldcode = code; \\r
\\r
pack = 0; \\r
if (code != blank) { \\r
/* Get tile address/2: */ \\r
- u32 addr = ((code&0x7ff)<<4) + ty; \\r
- if (code & 0x1000) addr ^= 0xe; /* Y-flip */ \\r
+ u32 addr = ((code<<yshift)&0x7ff0) + ty; \\r
+ if (code & 0x1000) addr ^= ymask<<1; /* Y-flip */ \\r
\\r
pal = ((code>>9)&0x30) | sh; /* shadow */ \\r
- \\r
pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr)); \\r
if (!pack) \\r
blank = code; \\r
} \\r
} \\r
- \\r
- if (code & 0x8000) { /* (un-forced) high priority tile */ \\r
+ if (cache && (code & 0x8000)) { /* (un-forced) high priority tile */ \\r
if (sh | (pack&mask)) { \\r
- code |= (dx<<16) | (ty<<26) | (masked<<25); \\r
- if (code & 0x1000) code ^= 0xe<<26; \\r
- *hc++ = code, *hc++ = pack&mask; /* cache it */ \\r
+ code = hpcode | (dx<<16); \\r
+ if (code & 0x1000) code ^= ymask<<(26+1); /* Y-flip */ \\r
+ *hc++ = code; *hc++ = pack&mask; /* cache it */ \\r
} \\r
} else { \\r
- lflags |= LF_LPRIO; \\r
+ if (cache) lflags |= LF_LPRIO; \\r
if (pack&mask) { \\r
if (code & 0x0800) TileFlip(pd + dx, pack&mask, pal); \\r
else TileNorm(pd + dx, pack&mask, pal); \\r
} \\r
}\r
\r
-static void DrawStrip(struct TileStrip *ts, int lflags, int cellskip)\r
-{\r
- unsigned char *pd = Pico.est.HighCol;\r
- u32 *hc = ts->hc;\r
- int tilex, dx, ty, cells;\r
- u32 code, oldcode = -1, blank = -1; // The tile we know is blank\r
- u32 pal = 0, pack = 0, sh, mask;\r
-\r
- // Draw tiles across screen:\r
- sh = (lflags & LF_SH) << 6; // shadow\r
- tilex=((-ts->hscroll)>>3)+cellskip;\r
- ty=(ts->line&7)<<1; // Y-Offset into tile\r
- dx=((ts->hscroll-1)&7)+1;\r
- cells = ts->cells - cellskip;\r
- dx+=cellskip<<3;\r
-\r
- if (dx & 7) {\r
- code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];\r
-// code &= ~force; // forced always draw everything\r
-\r
- mask = 0xffffffff<<((dx&7)*4);\r
- if (code & 0x0800) mask = 0xffffffff>>((dx&7)*4);\r
- mask = (~mask << 16) | (~mask >> 16);\r
-\r
- DrawTile(mask,1);\r
- dx += 8, tilex++, cells--;\r
- }\r
-\r
-// int force = (lflags&LF_FORCE) << 13;\r
- for (; cells > 0; dx+=8, tilex++, cells--)\r
- {\r
- code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];\r
-// code &= ~force; // forced always draw everything\r
-\r
- if (code != blank || ((code & 0x8000) && sh))\r
- DrawTile(~0,0);\r
- }\r
-\r
- if (dx & 7) {\r
- code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];\r
-// code &= ~force; // forced always draw everything\r
-\r
- if (code != blank || ((code & 0x8000) && sh)) {\r
- mask = 0xffffffff<<((dx&7)*4);\r
- if (code & 0x0800) mask = 0xffffffff>>((dx&7)*4);\r
- mask = (mask << 16) | (mask >> 16);\r
-\r
- DrawTile(mask,1);\r
- }\r
- }\r
-\r
- // terminate the cache list\r
- *hc = 0;\r
-\r
- // flags bit is clear if all layer is hi priority\r
- if (!(lflags & LF_LPRIO) && (lflags & LF_LINE)) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO;\r
-}\r
-\r
-#define DrawTileVSRam(mask,masked) { \\r
- if (code!=oldcode) { \\r
- oldcode = code; \\r
- /* Get tile address/2: */ \\r
- addr = (code&0x7ff)<<4; \\r
+#define DrawStripMaker(funcname,yshift,ymask,hpcode,drawtile,cache) \\r
+void funcname(struct TileStrip *ts, int lflags, int cellskip) \\r
+{ \\r
+ unsigned char *pd = Pico.est.HighCol; \\r
+ u32 *hc = ts->hc; \\r
+ int tilex, dx, ty, cells; \\r
+ u32 code, oldcode = -1, blank = -1; /* The tile we know is blank */ \\r
+ u32 pal = 0, pack = 0, sh, mask = ~0; \\r
+ \\r
+ /* Draw tiles across screen: */ \\r
+ sh = (lflags & LF_SH) << 6; /* shadow */ \\r
+ tilex=((-ts->hscroll)>>3)+cellskip; \\r
+ ty=(ts->line&ymask)<<1; /* Y-Offset into tile */ \\r
+ dx=((ts->hscroll-1)&7)+1; \\r
+ cells = ts->cells - cellskip; \\r
+ dx+=cellskip<<3; \\r
\\r
- pal = ((code>>9)&0x30) | sh; /* shadow */ \\r
+/* int force = (plane_sh&LF_FORCE) << 13; */ \\r
+ if (dx & 7) { \\r
+ code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)]; \\r
+/* code &= ~force; *//* forced always draw everything */ \\r
\\r
- pack = (code & 0x1000 ? ty^0xe : ty); /* Y-flip */ \\r
- pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr+pack)); \\r
- if (!pack) \\r
- blank = code; \\r
+ mask = 0xffffffff<<((dx&7)*4); \\r
+ if (code & 0x0800) mask = 0xffffffff>>((dx&7)*4); \\r
+ mask = (~mask << 16) | (~mask >> 16); \\r
+ \\r
+ drawtile(mask,yshift,ymask,hpcode | (ty<<26) | (1<<25),cache); \\r
+ dx += 8, tilex++, cells--; \\r
} \\r
\\r
- if (code & 0x8000) { /* (un-forced) high priority tile */ \\r
- if (sh | (pack&mask)) { \\r
- code |= (dx<<16) | (masked<<25); \\r
- if (code & 0x1000) code ^= 0xe<<26; \\r
- *hc++ = code, *hc++ = pack&mask; /* cache it */ \\r
- } \\r
- } else { \\r
- plane_sh |= LF_LPRIO; \\r
- if (pack&mask) { \\r
- if (code & 0x0800) TileFlip(pd + dx, pack&mask, pal); \\r
- else TileNorm(pd + dx, pack&mask, pal); \\r
+ for (; cells > 0; dx+=8, tilex++, cells--) \\r
+ { \\r
+ code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)]; \\r
+/* code &= ~force; *//* forced always draw everything */ \\r
+ \\r
+ if (code != blank || ((code & 0x8000) && sh)) \\r
+ drawtile(~0,yshift,ymask,hpcode | (ty<<26),cache); \\r
+ } \\r
+ \\r
+ if (dx & 7) { \\r
+ code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)]; \\r
+/* code &= ~force; *//* forced always draw everything */ \\r
+ \\r
+ if (code != blank || ((code & 0x8000) && sh)) { \\r
+ mask = 0xffffffff<<((dx&7)*4); \\r
+ if (code & 0x0800) mask = 0xffffffff>>((dx&7)*4); \\r
+ mask = (mask << 16) | (mask >> 16); \\r
+ \\r
+ drawtile(mask,yshift,ymask,hpcode | (ty<<26) | (1<<25),cache); \\r
} \\r
} \\r
+ \\r
+ /* terminate the cache list */ \\r
+ if (cache) *hc = 0; \\r
+ \\r
+ /* if oldcode wasn't changed, it means all layer is hi priority */ \\r
+ if (cache && (lflags & (LF_LINE|LF_LPRIO)) == LF_LINE) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO; \\r
}\r
\r
-// this is messy\r
-static void DrawStripVSRam(struct TileStrip *ts, int plane_sh, int cellskip)\r
-{\r
- unsigned char *pd = Pico.est.HighCol;\r
- u32 *hc = ts->hc;\r
- int tilex, dx, ty = 0, addr = 0, cell = 0, nametabadd = 0;\r
- u32 code, oldcode = -1, blank = -1; // The tile we know is blank\r
- u32 pal = 0, pack, scan = Pico.est.DrawScanline, sh, plane, mask;\r
-\r
- // Draw tiles across screen:\r
- sh = (plane_sh & LF_SH) << 6; // shadow\r
- plane = (plane_sh & LF_PLANE); // plane to draw\r
- tilex=(-ts->hscroll)>>3;\r
- dx=((ts->hscroll-1)&7)+1;\r
- if (ts->hscroll & 0x0f) {\r
- int adj = ((ts->hscroll ^ dx) >> 3) & 1;\r
- cell -= adj + 1;\r
- ts->cells -= adj;\r
- PicoMem.vsram[0x3e] = PicoMem.vsram[0x3f] = plane_sh >> 16;\r
- }\r
- cell+=cellskip;\r
- tilex+=cellskip;\r
- dx+=cellskip<<3;\r
-\r
-// int force = (plane_sh&LF_FORCE) << 13;\r
- if ((cell&1)==1 || (dx&7)) {\r
- int line,vscroll;\r
- vscroll = PicoMem.vsram[plane + (cell&0x3e)];\r
-\r
- // Find the line in the name table\r
- line=(vscroll+scan)&ts->line&0xffff; // ts->line is really ymask ..\r
- nametabadd=(line>>3)<<(ts->line>>24); // .. and shift[width]\r
- ty=(line&7)<<1; // Y-Offset into tile\r
- }\r
- if (dx & 7) {\r
- code= PicoMem.vram[ts->nametab + nametabadd + (tilex & ts->xmask)];\r
- code |= ty<<26; // add ty since that can change pixel row for every 2nd tile\r
-// code &= ~force; // forced always draw everything\r
-\r
- mask = 0xffffffff<<((dx&7)*4);\r
- if (code & 0x0800) mask = 0xffffffff>>((dx&7)*4);\r
- mask = (~mask << 16) | (~mask >> 16);\r
-\r
- DrawTileVSRam(mask,1);\r
-\r
- dx += 8, tilex++, cell++;\r
- }\r
- for (; cell < ts->cells; dx+=8,tilex++,cell++)\r
- {\r
- if ((cell&1)==0) {\r
- int line,vscroll;\r
- vscroll = PicoMem.vsram[plane + (cell&0x3e)];\r
-\r
- // Find the line in the name table\r
- line=(vscroll+scan)&ts->line&0xffff; // ts->line is really ymask ..\r
- nametabadd=(line>>3)<<(ts->line>>24); // .. and shift[width]\r
- ty=(line&7)<<1; // Y-Offset into tile\r
- }\r
-\r
- code= PicoMem.vram[ts->nametab + nametabadd + (tilex & ts->xmask)];\r
- code |= ty<<26; // add ty since that can change pixel row for every 2nd tile\r
-// code &= ~force; // forced always draw everything\r
-\r
- if (code != blank || ((code & 0x8000) && sh))\r
- DrawTileVSRam(~0,0);\r
- }\r
- if (dx & 7) {\r
- if ((cell&1)==0) {\r
- int line,vscroll;\r
- vscroll = PicoMem.vsram[plane + (cell&0x3e)];\r
-\r
- // Find the line in the name table\r
- line=(vscroll+scan)&ts->line&0xffff; // ts->line is really ymask ..\r
- nametabadd=(line>>3)<<(ts->line>>24); // .. and shift[width]\r
- ty=(line&7)<<1; // Y-Offset into tile\r
- }\r
-\r
- code= PicoMem.vram[ts->nametab + nametabadd + (tilex & ts->xmask)];\r
- code |= ty<<26; // add ty since that can change pixel row for every 2nd tile\r
-// code &= ~force; // forced always draw everything\r
-\r
- if (code != blank || ((code & 0x8000) && sh)) {\r
- mask = 0xffffffff<<((dx&7)*4);\r
- if (code & 0x0800) mask = 0xffffffff>>((dx&7)*4);\r
- mask = (mask << 16) | (mask >> 16);\r
-\r
- DrawTileVSRam(mask,1);\r
- }\r
- }\r
-\r
- // terminate the cache list\r
- *hc = 0;\r
+#ifndef _ASM_DRAW_C\r
+static DrawStripMaker(DrawStrip, 4, 0x7, code, DrawTile, 1);\r
\r
- if (!(plane_sh & LF_LPRIO) && (plane_sh & LF_LINE)) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO;\r
-}\r
+static\r
#endif\r
+ DrawStripMaker(DrawStripInterlace, 5, 0xf, (code&0xfc00) | ((code&0x3ff)<<1), DrawTile, 1);\r
\r
-#define DrawTileInterlace(mask,masked) { \\r
- if (code!=oldcode) { \\r
- oldcode = code; \\r
+// this is messy\r
+#define DrawStripVSRamMaker(funcname,yshift,ymask,hpcode,drawtile,cache) \\r
+void funcname(struct TileStrip *ts, int lflags, int cellskip) \\r
+{ \\r
+ unsigned char *pd = Pico.est.HighCol; \\r
+ u32 *hc = ts->hc; \\r
+ int tilex, dx, ty = 0, cell = 0, nametabadd = 0; \\r
+ u32 code, oldcode = -1, blank = -1; /* The tile we know is blank */ \\r
+ u32 pal = 0, pack = 0, sh, plane, mask; \\r
+ int scan = Pico.est.DrawScanline<<(yshift-4); \\r
\\r
- pack = 0; \\r
- if (code != blank) { \\r
- /* Get tile address/2: */ \\r
- u32 addr = ((code&0x3ff)<<5) + ty; \\r
- if (code & 0x1000) addr ^= 0x1e; /* Y-flip */ \\r
+ /* Draw tiles across screen: */ \\r
+ sh = (lflags & LF_SH) << 6; /* shadow */ \\r
+ plane = (lflags & LF_PLANE); /* plane to draw */ \\r
+ tilex=(-ts->hscroll)>>3; \\r
+ dx=((ts->hscroll-1)&7)+1; \\r
+ if (ts->hscroll & 0x0f) { \\r
+ int adj = ((ts->hscroll ^ dx) >> 3) & 1; \\r
+ cell -= adj + 1; \\r
+ ts->cells -= adj; \\r
+ PicoMem.vsram[0x3e] = PicoMem.vsram[0x3f] = lflags >> 16; \\r
+ } \\r
+ cell+=cellskip; \\r
+ tilex+=cellskip; \\r
+ dx+=cellskip<<3; \\r
\\r
- pal = ((code>>9)&0x30) | sh; /* shadow */ \\r
+/* int force = (lflags&LF_FORCE) << 13; */ \\r
+ if ((cell&1)==1 || (dx&7)) { \\r
+ int line,vscroll; \\r
+ vscroll = PicoMem.vsram[plane + (cell&0x3e)]; \\r
\\r
- pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr)); \\r
- if (!pack) \\r
- blank = code; \\r
+ /* Find the line in the name table */ \\r
+ line=(vscroll+scan)&(u16)ts->line; /* ts->line is really ymask, */ \\r
+ nametabadd=(line>>(yshift-1))<<(ts->line>>24); /* and shift[width] */ \\r
+ ty=((line<<(yshift-4))&ymask)<<1; /* Y-Offset into tile */ \\r
+ } \\r
+ if (dx & 7) { \\r
+ code = PicoMem.vram[ts->nametab + nametabadd + (tilex & ts->xmask)]; \\r
+ code |= ty<<26; /* add ty since that can change pixel row for every 2nd tile */ \\r
+/* code &= ~force; *//* forced always draw everything */ \\r
+ \\r
+ mask = 0xffffffff<<((dx&7)*4); \\r
+ if (code & 0x0800) mask = 0xffffffff>>((dx&7)*4); \\r
+ mask = (~mask << 16) | (~mask >> 16); \\r
+ \\r
+ drawtile(mask,yshift,ymask,hpcode | (1<<25),cache); \\r
+ \\r
+ dx += 8, tilex++, cell++; \\r
+ } \\r
+ for (; cell < ts->cells; dx+=8,tilex++,cell++) \\r
+ { \\r
+ if ((cell&1)==0) \\r
+ { \\r
+ int line,vscroll; \\r
+ vscroll = PicoMem.vsram[plane + (cell&0x3e)]; \\r
+ \\r
+ /* Find the line in the name table */ \\r
+ line=(vscroll+scan)&(u16)ts->line; /* ts->line is really ymask, */ \\r
+ nametabadd=(line>>(yshift-1))<<(ts->line>>24); /* and shift[width] */ \\r
+ ty=((line<<(yshift-4))&ymask)<<1; /* Y-Offset into tile */ \\r
} \\r
+ \\r
+ code = PicoMem.vram[ts->nametab + nametabadd + (tilex & ts->xmask)]; \\r
+ code |= ty<<26; /* add ty since that can change pixel row for every 2nd tile */ \\r
+/* code &= ~force; *//* forced always draw everything */ \\r
+ \\r
+ if (code != blank || ((code & 0x8000) && sh)) \\r
+ drawtile(~0,yshift,ymask,hpcode,cache); \\r
} \\r
+ if (dx & 7) { \\r
+ if ((cell&1)==0) \\r
+ { \\r
+ int line,vscroll; \\r
+ vscroll = PicoMem.vsram[plane + (cell&0x3e)]; \\r
\\r
- if (code & 0x8000) { /* high priority tile */ \\r
- if (sh | (pack&mask)) { \\r
- code = (code&0xfc00) | ((code&0x3ff)<<1) | (dx<<16) | (ty<<26) | (masked<<25); \\r
- if (code & 0x1000) code ^= 0x1e<<26; \\r
- *hc++ = code, *hc++ = pack&mask; /* cache it */ \\r
+ /* Find the line in the name table */ \\r
+ line=(vscroll+scan)&(u16)ts->line; /* ts->line is really ymask, */ \\r
+ nametabadd=(line>>(yshift-1))<<(ts->line>>24); /* and shift[width] */ \\r
+ ty=((line<<(yshift-4))&ymask)<<1; /* Y-Offset into tile */ \\r
} \\r
- } else { \\r
- plane_sh |= LF_LPRIO; \\r
- if (pack&mask) { \\r
- if (code & 0x0800) TileFlip(pd + dx, pack&mask, pal); \\r
- else TileNorm(pd + dx, pack&mask, pal); \\r
+ \\r
+ code = PicoMem.vram[ts->nametab + nametabadd + (tilex & ts->xmask)]; \\r
+ code |= ty<<26; /* add ty since that can change pixel row for every 2nd tile */ \\r
+/* code &= ~force; *//* forced always draw everything */ \\r
+ \\r
+ if (code != blank || ((code & 0x8000) && sh)) { \\r
+ mask = 0xffffffff<<((dx&7)*4); \\r
+ if (code & 0x0800) mask = 0xffffffff>>((dx&7)*4); \\r
+ mask = (mask << 16) | (mask >> 16); \\r
+ \\r
+ drawtile(mask,yshift,ymask,hpcode | (1<<25),cache); \\r
} \\r
} \\r
+ \\r
+ /* terminate the cache list */ \\r
+ if (cache) *hc = 0; \\r
+ \\r
+ if (cache && (lflags & (LF_LINE|LF_LPRIO)) == LF_LINE) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO; \\r
}\r
\r
#ifndef _ASM_DRAW_C\r
+static DrawStripVSRamMaker(DrawStripVSRam, 4, 0x7, code, DrawTile, 1);\r
+\r
static\r
#endif\r
-void DrawStripInterlace(struct TileStrip *ts, int plane_sh)\r
-{\r
- unsigned char *pd = Pico.est.HighCol;\r
- u32 *hc = ts->hc;\r
- int tilex = 0, dx = 0, ty = 0, cells;\r
- u32 code, oldcode = -1, blank = -1; // The tile we know is blank\r
- u32 pal = 0, pack = 0, sh, mask;\r
-\r
- // Draw tiles across screen:\r
- sh = (plane_sh & LF_SH) << 6; // shadow\r
- tilex=(-ts->hscroll)>>3;\r
- ty=(ts->line&15)<<1; // Y-Offset into tile\r
- dx=((ts->hscroll-1)&7)+1;\r
- cells = ts->cells;\r
-\r
- if (dx & 7) {\r
- code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];\r
-// code &= ~force; // forced always draw everything\r
-\r
- mask = 0xffffffff<<(dx*4);\r
- if (code & 0x0800) mask = 0xffffffff>>(dx*4);\r
- mask = (~mask << 16) | (~mask >> 16);\r
-\r
- DrawTileInterlace(mask,1);\r
- dx += 8, tilex++, cells--;\r
- }\r
-\r
-// int force = (plane_sh&LF_FORCE) << 13;\r
- for (; cells; dx+=8,tilex++,cells--)\r
- {\r
- u32 code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];\r
-// code &= ~force; // forced always draw everything\r
-\r
- if (code != blank || ((code & 0x8000) && sh))\r
- DrawTileInterlace(~0,0);\r
- }\r
-\r
- if (dx & 7) {\r
- code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];\r
-// code &= ~force; // forced always draw everything\r
-\r
- if (code != blank || ((code & 0x8000) && sh)) {\r
- mask = 0xffffffff<<((dx&7)*4);\r
- if (code & 0x0800) mask = 0xffffffff>>((dx&7)*4);\r
- mask = (mask << 16) | (mask >> 16);\r
-\r
- DrawTileInterlace(mask,1);\r
- }\r
- }\r
-\r
- // terminate the cache list\r
- *hc = 0;\r
-\r
- if (!(plane_sh & LF_LPRIO) && (plane_sh & LF_LINE)) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO;\r
-}\r
+ DrawStripVSRamMaker(DrawStripVSRamInterlace, 5, 0xf, (code&0xfc00) | ((code&0x3ff)<<1), DrawTile, 1);\r
\r
// --------------------------------------------\r
\r
-#ifndef _ASM_DRAW_C\r
-static void DrawLayer(int plane_sh, u32 *hcache, int cellskip, int maxcells,\r
- struct PicoEState *est)\r
-{\r
- struct PicoVideo *pvid=&est->Pico->video;\r
- const char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps (2 is invalid)\r
- struct TileStrip ts;\r
- int width, height, ymask;\r
- int vscroll, htab;\r
-\r
- ts.hc=hcache;\r
- ts.cells=maxcells;\r
-\r
- // Work out the TileStrip to draw\r
-\r
- // Work out the name table size: 32 64 or 128 tiles (0-3)\r
- width=pvid->reg[16];\r
- height=(width>>4)&3; width&=3;\r
-\r
- ts.xmask=(1<<shift[width])-1; // X Mask in tiles (0x1f-0x7f)\r
- ymask=(height<<8)|0xff; // Y Mask in pixels\r
- switch (width) {\r
- case 1: ymask &= 0x1ff; break;\r
- case 2: ymask = 0x007; break;\r
- case 3: ymask = 0x0ff; break;\r
- }\r
-\r
- // Find name table:\r
- if (plane_sh&LF_PLANE) ts.nametab=(pvid->reg[4]&0x07)<<12; // B\r
- else ts.nametab=(pvid->reg[2]&0x38)<< 9; // A\r
-\r
- htab=pvid->reg[13]<<9; // Horizontal scroll table address\r
- switch (pvid->reg[11]&3) {\r
- case 1: htab += (est->DrawScanline<<1) & 0x0f; break;\r
- case 2: htab += (est->DrawScanline<<1) & ~0x0f; break; // Offset by tile\r
- case 3: htab += (est->DrawScanline<<1); break; // Offset by line\r
- }\r
- htab+=plane_sh&LF_PLANE; // A or B\r
-\r
- // Get horizontal scroll value, will be masked later\r
- ts.hscroll = PicoMem.vram[htab & 0x7fff];\r
-\r
- if((pvid->reg[12]&6) == 6) {\r
- // interlace mode 2\r
- vscroll = PicoMem.vsram[plane_sh&LF_PLANE]; // Get vertical scroll value\r
-\r
- // Find the line in the name table\r
- ts.line=(vscroll+(est->DrawScanline<<1))&((ymask<<1)|1);\r
- ts.nametab+=(ts.line>>4)<<shift[width];\r
-\r
- DrawStripInterlace(&ts, plane_sh);\r
- } else if (pvid->reg[11]&4) {\r
- // shit, we have 2-cell column based vscroll\r
- // luckily this doesn't happen too often\r
- ts.line=ymask|(shift[width]<<24); // save some stuff instead of line\r
- // vscroll value for leftmost cells in case of hscroll not on 16px boundary\r
- // XXX it's unclear what exactly the hw is doing. Continue reading where it\r
- // stopped last seems to work best (H40: 0x50 (wrap->0x00), H32 0x40).\r
- plane_sh |= PicoMem.vsram[(pvid->reg[12]&1?0x00:0x20) + (plane_sh&LF_PLANE)] << 16;\r
- DrawStripVSRam(&ts, plane_sh, cellskip);\r
- } else {\r
- vscroll = PicoMem.vsram[plane_sh&LF_PLANE]; // Get vertical scroll value\r
-\r
- // Find the line in the name table\r
- ts.line=(vscroll+est->DrawScanline)&ymask;\r
- ts.nametab+=(ts.line>>3)<<shift[width];\r
-\r
- DrawStrip(&ts, plane_sh, cellskip);\r
- }\r
+#define DrawLayerMaker(funcname,drawstrip,drawstripinterlace,drawstripvsram,drawstripvsraminterlace) \\r
+void funcname(int plane_sh, u32 *hcache, int cellskip, int maxcells, struct PicoEState *est) \\r
+{ \\r
+ struct PicoVideo *pvid=&est->Pico->video; \\r
+ const char shift[4]={5,6,5,7}; /* 32,64 or 128 sized tilemaps (2 is invalid) */ \\r
+ struct TileStrip ts; \\r
+ int width, height, ymask; \\r
+ int vscroll, htab; \\r
+ \\r
+ ts.hc=hcache; \\r
+ ts.cells=maxcells; \\r
+ \\r
+ /* Work out the TileStrip to draw */ \\r
+ \\r
+ /* Work out the name table size: 32 64 or 128 tiles (0-3) */ \\r
+ width=pvid->reg[16]; \\r
+ height=(width>>4)&3; width&=3; \\r
+ \\r
+ ts.xmask=(1<<shift[width])-1; /* X Mask in tiles (0x1f-0x7f) */ \\r
+ ymask=(height<<8)|0xff; /* Y Mask in pixels */ \\r
+ switch (width) { \\r
+ case 1: ymask &= 0x1ff; break; \\r
+ case 2: ymask = 0x007; break; \\r
+ case 3: ymask = 0x0ff; break; \\r
+ } \\r
+ \\r
+ /* Find name table: */ \\r
+ if (plane_sh&LF_PLANE) ts.nametab=(pvid->reg[4]&0x07)<<12; /* B */ \\r
+ else ts.nametab=(pvid->reg[2]&0x38)<< 9; /* A */ \\r
+ \\r
+ htab=pvid->reg[13]<<9; /* Horizontal scroll table address */ \\r
+ switch (pvid->reg[11]&3) { \\r
+ case 1: htab += (est->DrawScanline<<1) & 0x0f; break; \\r
+ case 2: htab += (est->DrawScanline<<1) & ~0x0f; break; /* Offset by tile */ \\r
+ case 3: htab += (est->DrawScanline<<1); break; /* Offset by line */ \\r
+ } \\r
+ htab+=plane_sh&LF_PLANE; /* A or B */ \\r
+ \\r
+ /* Get horizontal scroll value, will be masked later */ \\r
+ ts.hscroll = PicoMem.vram[htab & 0x7fff]; \\r
+ \\r
+ if (likely(!(pvid->reg[11]&4))) { \\r
+ vscroll = PicoMem.vsram[plane_sh&LF_PLANE]; /* Get vertical scroll value */ \\r
+ \\r
+ if(likely((pvid->reg[12]&6) != 6)) { \\r
+ /* Find the line in the name table */ \\r
+ ts.line=(vscroll+est->DrawScanline)&ymask; \\r
+ ts.nametab+=(ts.line>>3)<<shift[width]; \\r
+ \\r
+ drawstrip(&ts, plane_sh, cellskip); \\r
+ } else { \\r
+ /* interlace mode 2 */ \\r
+ \\r
+ /* Find the line in the name table */ \\r
+ ts.line=(vscroll+(est->DrawScanline<<1))&((ymask<<1)|1); \\r
+ ts.nametab+=(ts.line>>4)<<shift[width]; \\r
+ \\r
+ drawstripinterlace(&ts, plane_sh, cellskip); \\r
+ } \\r
+ } else { \\r
+ /* shit, we have 2-cell column based vscroll */ \\r
+ /* luckily this doesn't happen too often */ \\r
+ \\r
+ /* vscroll value for leftmost cells in case of hscroll not on 16px boundary */ \\r
+ /* NB it's unclear what exactly the hw is doing. Continue reading where it */ \\r
+ /* stopped last seems to work best (H40: 0x50 (wrap->0x00), H32 0x40). */ \\r
+ plane_sh |= PicoMem.vsram[(pvid->reg[12]&1?0x00:0x20) + (plane_sh&LF_PLANE)] << 16; \\r
+ \\r
+ if (likely((pvid->reg[12]&6) != 6)) { \\r
+ ts.line=ymask|(shift[width]<<24); /* save some stuff instead of line */ \\r
+ drawstripvsram(&ts, plane_sh, cellskip); \\r
+ } else { \\r
+ ts.line=(ymask<<1)|1|(shift[width]<<24); /* save some stuff instead of line */ \\r
+ drawstripvsraminterlace(&ts, plane_sh, cellskip); \\r
+ } \\r
+ } \\r
}\r
\r
+#ifndef _ASM_DRAW_C\r
+static DrawLayerMaker(DrawLayer,DrawStrip,DrawStripInterlace,DrawStripVSRam,DrawStripVSRamInterlace);\r
\r
// --------------------------------------------\r
\r
{\r
unsigned char *pd = est->HighCol;\r
struct PicoVideo *pvid = &est->Pico->video;\r
- int tilex,ty,nametab,code=0;\r
- int blank=-1; // The tile we know is blank\r
+ int tilex,ty,nametab,code,oldcode=-1,blank=-1; // The tile we know is blank\r
+ int yshift,ymask;\r
+ u32 pack;\r
+ u32 *hc=NULL, lflags=0; // referenced in DrawTile\r
+\r
+ yshift = 4, ymask = 0x7;\r
+ if(likely((pvid->reg[12]&6) == 6))\r
+ yshift = 5, ymask = 0xf;\r
+ ty=((est->DrawScanline<<(yshift-4))&ymask)<<1; // Y-Offset into tile\r
\r
// Find name table line:\r
if (pvid->reg[12]&1)\r
{\r
nametab=(pvid->reg[3]&0x3c)<<9; // 40-cell mode\r
- nametab+=(est->DrawScanline>>3)<<6;\r
+ nametab+=(est->DrawScanline>>(yshift-1))<<6;\r
}\r
else\r
{\r
nametab=(pvid->reg[3]&0x3e)<<9; // 32-cell mode\r
- nametab+=(est->DrawScanline>>3)<<5;\r
+ nametab+=(est->DrawScanline>>(yshift-1))<<5;\r
}\r
\r
- tilex=tstart<<1;\r
-\r
if (prio && !(est->rendstatus & PDRAW_WND_DIFF_PRIO)) {\r
// all tiles processed in low prio pass\r
return;\r
}\r
\r
+ tilex=tstart<<1;\r
tend<<=1;\r
- ty=(est->DrawScanline&7)<<1; // Y-Offset into tile\r
\r
// Draw tiles across screen:\r
if (!sh)\r
{\r
for (; tilex < tend; tilex++)\r
{\r
- unsigned int pack;\r
- int dx, addr;\r
- int pal;\r
+ int dx, pal;\r
\r
code = PicoMem.vram[nametab + tilex];\r
if ((code>>15) != prio) {\r
}\r
if (code==blank) continue;\r
\r
- // Get tile address/2:\r
- addr=(code&0x7ff)<<4;\r
- if (code&0x1000) addr+=14-ty; else addr+=ty; // Y-flip\r
-\r
- pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
- if (!pack) {\r
- blank = code;\r
- continue;\r
- }\r
-\r
- pal = ((code >> 9) & 0x30);\r
dx = 8 + (tilex << 3);\r
\r
- if (code & 0x0800) TileFlip(pd + dx, pack, pal);\r
- else TileNorm(pd + dx, pack, pal);\r
+ DrawTile(~0,yshift,ymask,code,0);\r
}\r
}\r
else\r
{\r
for (; tilex < tend; tilex++)\r
{\r
- unsigned int pack;\r
- int dx, addr;\r
- int pal;\r
+ int dx, pal;\r
\r
code = PicoMem.vram[nametab + tilex];\r
if((code>>15) != prio) {\r
pal |= 0x80;\r
}\r
if(code==blank) continue;\r
-\r
- // Get tile address/2:\r
- addr=(code&0x7ff)<<4;\r
- if (code&0x1000) addr+=14-ty; else addr+=ty; // Y-flip\r
-\r
- pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
- if (!pack) {\r
- blank = code;\r
- continue;\r
- }\r
-\r
dx = 8 + (tilex << 3);\r
\r
- if (code & 0x0800) TileFlip(pd + dx, pack, pal);\r
- else TileNorm(pd + dx, pack, pal);\r
+ DrawTile(~0,yshift,ymask,code,0);\r
}\r
}\r
}\r
static void DrawTilesFromCache(u32 *hc, int sh, int rlim, struct PicoEState *est)\r
{\r
unsigned char *pd = est->HighCol;\r
- u32 code, dx;\r
- u32 pack;\r
- int pal;\r
- int hs;\r
+ u32 code, dx, pack;\r
+ int pal, hs;\r
\r
// *ts->hc++ = code | (dx<<16) | (ty<<26); // cache it\r
\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 *zb = (int *)(Pico.est.HighCol+8);\r
- int c = 320/4;\r
+ int c = 320 / 4;\r
while (c--)\r
{\r
*zb++ &= 0x7f7f7f7f;\r
if (!sh)\r
{\r
while ((code=*hc++)) {\r
- dx = (code >> 16) & 0x1ff;\r
pack = *hc++;\r
- if (!pack)\r
- continue;\r
-\r
+ dx = (code >> 16) & 0x1ff;\r
pal = ((code >> 9) & 0x30);\r
\r
if (code & 0x0800) TileFlip(pd + dx, pack, pal);\r
while ((code=*hc++)) {\r
unsigned char *zb;\r
\r
- dx = (code >> 16) & 0x1ff;\r
pack = *hc++;\r
+ dx = (code >> 16) & 0x1ff;\r
+ pal = ((code >> 9) & 0x30);\r
\r
zb = est->HighCol+dx;\r
- if (likely(~code&(1<<25))) {\r
+ if (likely(~code & (1<<25))) {\r
*zb++ &= 0x7f; *zb++ &= 0x7f; *zb++ &= 0x7f; *zb++ &= 0x7f;\r
*zb++ &= 0x7f; *zb++ &= 0x7f; *zb++ &= 0x7f; *zb++ &= 0x7f;\r
} else {\r
hs = dx & 7;\r
if (*hc == 0) // last tile?\r
- for ( pal = hs; pal < 8; pal++) *zb++ &= 0x7f;\r
- else // first tile\r
- for (zb += 8-hs, pal = 0; pal < hs; pal++) *zb++ &= 0x7f;\r
+ switch (8-hs) { case 7: *zb++ &= 0x7f;\r
+ case 6: *zb++ &= 0x7f; case 5: *zb++ &= 0x7f; case 4: *zb++ &= 0x7f;\r
+ case 3: *zb++ &= 0x7f; case 2: *zb++ &= 0x7f; case 1: *zb++ &= 0x7f;\r
+ }\r
+ else { // first tile\r
+ zb += 8-hs;\r
+ switch (hs) { case 7: *zb++ &= 0x7f;\r
+ case 6: *zb++ &= 0x7f; case 5: *zb++ &= 0x7f; case 4: *zb++ &= 0x7f;\r
+ case 3: *zb++ &= 0x7f; case 2: *zb++ &= 0x7f; case 1: *zb++ &= 0x7f;\r
+ }\r
+ }\r
}\r
\r
- if (!pack)\r
- continue;\r
-\r
- pal = ((code >> 9) & 0x30);\r
-\r
- if (code & 0x0800) TileFlip(pd + dx, pack, pal);\r
- else TileNorm(pd + dx, pack, pal);\r
+ if (pack) {\r
+ if (code & 0x0800) TileFlip(pd + dx, pack, pal);\r
+ else TileNorm(pd + dx, pack, pal);\r
+ }\r
}\r
}\r
}\r
#ifdef FORCE\r
// NB lots of duplicate code, all for the sake of a small performance gain.\r
\r
-static void DrawStripForced(struct TileStrip *ts, int cellskip)\r
-{\r
- unsigned char *pd = Pico.est.HighCol;\r
- int tilex, dx, ty, addr=0, cells;\r
- u32 code = 0, oldcode = -1;\r
- int pal = 0;\r
-\r
- // Draw tiles across screen:\r
- tilex=((-ts->hscroll)>>3)+cellskip;\r
- ty=(ts->line&7)<<1; // Y-Offset into tile\r
- dx=((ts->hscroll-1)&7)+1;\r
- cells = ts->cells - cellskip;\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
- {\r
- u32 pack;\r
-\r
- code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];\r
-\r
- if (code!=oldcode) {\r
- oldcode = code;\r
- // Get tile address/2:\r
- addr = ((code&0x7ff)<<4) + ty;\r
- if (code & 0x1000) addr^=0xe; // Y-flip\r
-\r
- pal = (code>>9)&0x30;\r
- }\r
-\r
- pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
-\r
- if (code & 0x0800) TileFlip_and(pd + dx, pack, pal);\r
- else TileNorm_and(pd + dx, pack, pal);\r
- }\r
-}\r
-\r
-static void DrawStripVSRamForced(struct TileStrip *ts, int plane_sh, int cellskip)\r
-{\r
- unsigned char *pd = Pico.est.HighCol;\r
- int tilex, dx, ty=0, addr=0, cell=0, nametabadd=0;\r
- u32 code=0, oldcode=-1;\r
- int pal=0, scan=Pico.est.DrawScanline, plane;\r
-\r
- // Draw tiles across screen:\r
- plane = plane_sh & LF_PLANE;\r
- tilex=(-ts->hscroll)>>3;\r
- dx=((ts->hscroll-1)&7)+1;\r
- if (ts->hscroll & 0x0f) {\r
- int adj = ((ts->hscroll ^ dx) >> 3) & 1;\r
- cell -= adj + 1;\r
- ts->cells -= adj;\r
- PicoMem.vsram[0x3e] = PicoMem.vsram[0x3f] = plane_sh >> 16;\r
- }\r
- cell+=cellskip;\r
- tilex+=cellskip;\r
- dx+=cellskip<<3;\r
-\r
- if ((cell&1)==1)\r
- {\r
- int line,vscroll;\r
- vscroll = PicoMem.vsram[plane + (cell&0x3e)];\r
-\r
- // Find the line in the name table\r
- line=(vscroll+scan)&ts->line&0xffff; // ts->line is really ymask ..\r
- nametabadd=(line>>3)<<(ts->line>>24); // .. and shift[width]\r
- ty=(line&7)<<1; // Y-Offset into tile\r
- }\r
- for (; cell < ts->cells; dx+=8,tilex++,cell++)\r
- {\r
- unsigned int pack;\r
-\r
- if ((cell&1)==0)\r
- {\r
- int line,vscroll;\r
- vscroll = PicoMem.vsram[plane + (cell&0x3e)];\r
-\r
- // Find the line in the name table\r
- line=(vscroll+scan)&ts->line&0xffff; // ts->line is really ymask ..\r
- nametabadd=(line>>3)<<(ts->line>>24); // .. and shift[width]\r
- ty=(line&7)<<1; // Y-Offset into tile\r
- }\r
-\r
- code=PicoMem.vram[ts->nametab+nametabadd+(tilex&ts->xmask)];\r
-\r
- if (code!=oldcode) {\r
- oldcode = code;\r
- // Get tile address/2:\r
- addr=(code&0x7ff)<<4;\r
-\r
- pal = (code>>9)&0x30; // shadow\r
- }\r
-\r
- pack = code & 0x1000 ? ty^0xe : ty; // Y-flip\r
- pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr+pack));\r
-\r
- if (code & 0x0800) TileFlip_and(pd + dx, pack, pal);\r
- else TileNorm_and(pd + dx, pack, pal);\r
- }\r
-}\r
-\r
-void DrawStripInterlaceForced(struct TileStrip *ts)\r
-{\r
- unsigned char *pd = Pico.est.HighCol;\r
- int tilex = 0, dx = 0, ty = 0, cells;\r
- int oldcode = -1;\r
- unsigned int pal = 0, pack = 0;\r
-\r
- // Draw tiles across screen:\r
- tilex=(-ts->hscroll)>>3;\r
- ty=(ts->line&15)<<1; // Y-Offset into tile\r
- dx=((ts->hscroll-1)&7)+1;\r
- cells = ts->cells;\r
- if(dx != 8) cells++; // have hscroll, need to draw 1 cell more\r
-\r
- for (; cells; dx+=8,tilex++,cells--)\r
- {\r
- u32 code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];\r
-\r
- if (code!=oldcode) {\r
- oldcode = code;\r
-\r
- // Get tile address/2:\r
- u32 addr = ((code&0x3ff)<<5) + ty;\r
- if (code & 0x1000) addr ^= 0x1e; // Y-flip\r
-\r
- pal = (code>>9)&0x30; // shadow\r
-\r
- pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr));\r
- }\r
-\r
- if (code & 0x0800) TileFlip_and(pd + dx, pack, pal);\r
- else TileNorm_and(pd + dx, pack, pal);\r
- }\r
+// Forced tile drawing, without any masking and blank handling\r
+#define DrawTileForced(mask,yshift,ymask,hpcode,cache) { \\r
+ if (code!=oldcode) { \\r
+ oldcode = code; \\r
+ \\r
+ /* Get tile address/2: */ \\r
+ u32 addr = ((code<<yshift)&0x7ff0) + ty; \\r
+ if (code & 0x1000) addr ^= ymask<<1; /* Y-flip */ \\r
+ \\r
+ pal = ((code>>9)&0x30); \\r
+ pal |= 0xc0; /* leave s/h bits untouched in pixel "and" */ \\r
+ \\r
+ pack = CPU_LE2(*(u32 *)(PicoMem.vram + addr)); \\r
+ } \\r
+ if (code & 0x0800) TileFlip_and(pd + dx, pack, pal); \\r
+ else TileNorm_and(pd + dx, pack, pal); \\r
}\r
\r
-// XXX only duplicated to avoid ARM asm hassles\r
-static void DrawLayerForced(int plane_sh, int cellskip, int maxcells,\r
- struct PicoEState *est)\r
-{\r
- struct PicoVideo *pvid=&est->Pico->video;\r
- const char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps (2 is invalid)\r
- struct TileStrip ts;\r
- int width, height, ymask;\r
- int vscroll, htab;\r
+static DrawStripMaker(DrawStripForced, 4, 0x7, 0, DrawTileForced, 0);\r
\r
- ts.cells=maxcells;\r
+static DrawStripMaker(DrawStripInterlaceForced, 5, 0xf, 0, DrawTileForced, 0);\r
\r
- // Work out the TileStrip to draw\r
+static DrawStripVSRamMaker(DrawStripVSRamForced, 4, 0x7, 0, DrawTileForced, 0);\r
\r
- // Work out the name table size: 32 64 or 128 tiles (0-3)\r
- width=pvid->reg[16];\r
- height=(width>>4)&3; width&=3;\r
-\r
- ts.xmask=(1<<shift[width])-1; // X Mask in tiles (0x1f-0x7f)\r
- ymask=(height<<8)|0xff; // Y Mask in pixels\r
- switch (width) {\r
- case 1: ymask &= 0x1ff; break;\r
- case 2: ymask = 0x007; break;\r
- case 3: ymask = 0x0ff; break;\r
- }\r
+static DrawStripVSRamMaker(DrawStripVSRamInterlaceForced, 5, 0xf, 0, DrawTileForced, 0);\r
\r
- // Find name table:\r
- if (plane_sh&1) ts.nametab=(pvid->reg[4]&0x07)<<12; // B\r
- else ts.nametab=(pvid->reg[2]&0x38)<< 9; // A\r
-\r
- htab=pvid->reg[13]<<9; // Horizontal scroll table address\r
- switch (pvid->reg[11]&3) {\r
- case 1: htab += (est->DrawScanline<<1) & 0x0f; break;\r
- case 2: htab += (est->DrawScanline<<1) & ~0x0f; break; // Offset by tile\r
- case 3: htab += (est->DrawScanline<<1); break; // Offset by line\r
- }\r
- htab+=plane_sh&1; // A or B\r
-\r
- // Get horizontal scroll value, will be masked later\r
- ts.hscroll = PicoMem.vram[htab & 0x7fff];\r
-\r
- if((pvid->reg[12]&6) == 6) {\r
- // interlace mode 2\r
- vscroll = PicoMem.vsram[plane_sh & 1]; // Get vertical scroll value\r
-\r
- // Find the line in the name table\r
- ts.line=(vscroll+(est->DrawScanline<<1))&((ymask<<1)|1);\r
- ts.nametab+=(ts.line>>4)<<shift[width];\r
-\r
- DrawStripInterlaceForced(&ts);\r
- } else if( pvid->reg[11]&4) {\r
- // shit, we have 2-cell column based vscroll\r
- // luckily this doesn't happen too often\r
- ts.line=ymask|(shift[width]<<24); // save some stuff instead of line\r
- // vscroll value for leftmost cells in case of hscroll not on 16px boundary\r
- // XXX it's unclear what exactly the hw is doing. Continue reading where it\r
- // stopped last seems to work best (H40: 0x50 (wrap->0x00), H32 0x40).\r
- plane_sh |= PicoMem.vsram[(pvid->reg[12]&1?0x00:0x20) + (plane_sh&1)] << 16;\r
- DrawStripVSRamForced(&ts, plane_sh, cellskip);\r
- } else {\r
- vscroll = PicoMem.vsram[plane_sh & 1]; // Get vertical scroll value\r
-\r
- // Find the line in the name table\r
- ts.line=(vscroll+est->DrawScanline)&ymask;\r
- ts.nametab+=(ts.line>>3)<<shift[width];\r
-\r
- DrawStripForced(&ts, cellskip);\r
- }\r
-}\r
+static DrawLayerMaker(DrawLayerForced,DrawStripForced,DrawStripInterlaceForced,DrawStripVSRamForced,DrawStripVSRamInterlaceForced);\r
\r
static void DrawSpritesForced(unsigned char *sprited)\r
{\r
sprite = Pico.est.HighPreSpr + offs;\r
code = sprite[1];\r
pal = (code>>9)&0x30;\r
+ pal |= 0xc0; // leave s/h bits untouched in pixel "and"\r
\r
if (code&0x800) fTileFunc = TileFlipSH_AS_and;\r
else fTileFunc = TileNormSH_AS_and;\r
}\r
\r
// anything not covered by a sprite is off \r
- // XXX Titan hw notes say that transparent pixels remove shadow. Is this also\r
+ // TODO Titan hw notes say that transparent pixels remove shadow. Is this also\r
// the case in areas where no sprites are displayed?\r
for (cnt = 1; cnt < sizeof(mb)-1; cnt++)\r
if (mb[cnt] == 0xff) {\r
DrawWindow(0, maxcells>>1, 1, sh, est);\r
else if (hvwind == 2) {\r
if (HighCacheA[0])\r
- DrawTilesFromCache(HighCacheA, sh, (win&0x80) ? edge<<4 : -edge<<4, est);\r
+ DrawTilesFromCache(HighCacheA, sh, (win&0x80) ? edge<<4 : maxw, est);\r
DrawWindow((win&0x80) ? edge : 0, (win&0x80) ? maxcells>>1 : edge, 1, sh, est);\r
} else\r
if (HighCacheA[0])\r
#ifdef FORCE\r
if (pvid->debug_p & PVD_FORCE_B) {\r
lflags = LF_PLANE_B | (sh<<1);\r
- DrawLayerForced(lflags, 0, maxcells, est);\r
+ DrawLayerForced(lflags, NULL, 0, maxcells, est);\r
} else if (pvid->debug_p & PVD_FORCE_A) {\r
+ // TODO what happens in windowed mode? \r
lflags = LF_PLANE_A | (sh<<1);\r
- DrawLayerForced(lflags, 0, maxcells, est);\r
+ DrawLayerForced(lflags, NULL, 0, maxcells, est);\r
} else if (pvid->debug_p & PVD_FORCE_S)\r
DrawSpritesForced(sprited);\r
#endif\r