-// This is part of Pico Library\r
-\r
-// (c) Copyright 2007, Grazvydas "notaz" Ignotas\r
-// Free for non-commercial use.\r
-\r
-// For commercial use, separate licencing terms must be obtained.\r
-\r
-\r
-// this is a frame-based renderer, alternative to Dave's line based which is in Draw.c\r
-\r
+/*\r
+ * tile renderer\r
+ * (C) notaz, 2006-2008\r
+ *\r
+ * This work is licensed under the terms of MAME license.\r
+ * See COPYING file in the top-level directory.\r
+ */\r
\r
#include "pico_int.h"\r
\r
-// port_config.h include must define these 2 defines:\r
-// #define START_ROW 1 // which row of tiles to start rendering at?\r
-// #define END_ROW 27 // ..end\r
-// one row means 8 pixels. If above example was used, (27-1)*8=208 lines would be rendered.\r
+#define START_ROW 0 // which row of tiles to start rendering at?\r
+#define END_ROW 28 // ..end\r
\r
#define TILE_ROWS END_ROW-START_ROW\r
\r
-#define USE_CACHE\r
-\r
// note: this is not implemented in ARM asm\r
#if defined(DRAW2_OVERRIDE_LINE_WIDTH)\r
#define LINE_WIDTH DRAW2_OVERRIDE_LINE_WIDTH\r
#define LINE_WIDTH 328\r
#endif\r
\r
+static unsigned char PicoDraw2FB_[(8+320) * (8+240+8)];\r
+\r
static int HighCache2A[41*(TILE_ROWS+1)+1+1]; // caches for high layers\r
static int HighCache2B[41*(TILE_ROWS+1)+1+1];\r
\r
-unsigned short *PicoCramHigh=Pico.cram; // pointer to CRAM buff (0x40 shorts), converted to native device color (works only with 16bit for now)\r
+unsigned short *PicoCramHigh=PicoMem.cram; // pointer to CRAM buff (0x40 shorts), converted to native device color (works only with 16bit for now)\r
void (*PicoPrepareCram)()=0; // prepares PicoCramHigh for renderer to use\r
\r
\r
// stuff available in asm:\r
#ifdef _ASM_DRAW_C\r
-void BackFillFull(int reg7);\r
-void DrawLayerFull(int plane, int *hcache, int planestart, int planeend);\r
-void DrawTilesFromCacheF(int *hc);\r
-void DrawWindowFull(int start, int end, int prio);\r
-void DrawSpriteFull(unsigned int *sprite);\r
+void BackFillFull(void *dst, int reg7);\r
+void DrawLayerFull(int plane, int *hcache, int planestart, int planeend,\r
+ struct PicoEState *est);\r
+void DrawTilesFromCacheF(int *hc, struct PicoEState *est);\r
+void DrawWindowFull(int start, int end, int prio, struct PicoEState *est);\r
+void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est);\r
#else\r
\r
\r
int i;\r
\r
for(i=8; i; i--, addr+=2, pd += LINE_WIDTH) {\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
+ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
if(!pack) continue;\r
\r
t=pack&0x0000f000; if (t) pd[0]=(unsigned char)((t>>12)|pal);\r
int i;\r
\r
for(i=8; i; i--, addr+=2, pd += LINE_WIDTH) {\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
+ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
if(!pack) continue;\r
\r
t=pack&0x000f0000; if (t) pd[0]=(unsigned char)((t>>16)|pal);\r
\r
addr+=14;\r
for(i=8; i; i--, addr-=2, pd += LINE_WIDTH) {\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
+ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
if(!pack) continue;\r
\r
t=pack&0x0000f000; if (t) pd[0]=(unsigned char)((t>>12)|pal);\r
\r
addr+=14;\r
for(i=8; i; i--, addr-=2, pd += LINE_WIDTH) {\r
- pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
+ pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
if(!pack) continue;\r
\r
t=pack&0x000f0000; if (t) pd[0]=(unsigned char)((t>>16)|pal);\r
\r
\r
// start: (tile_start<<16)|row_start, end: [same]\r
-static void DrawWindowFull(int start, int end, int prio)\r
+static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)\r
{\r
struct PicoVideo *pvid=&Pico.video;\r
int nametab, nametab_step, trow, tilex, blank=-1, code;\r
- unsigned char *scrpos = PicoDraw2FB;\r
+ unsigned char *scrpos = est->Draw2FB;\r
int tile_start, tile_end; // in cells\r
\r
// parse ranges\r
nametab += nametab_step*start;\r
\r
// check priority\r
- code=Pico.vram[nametab+tile_start];\r
+ code=PicoMem.vram[nametab+tile_start];\r
if ((code>>15) != prio) return; // hack: just assume that whole window uses same priority\r
\r
scrpos+=8*LINE_WIDTH+8;\r
// unsigned short *pal=NULL;\r
unsigned char pal;\r
\r
- code=Pico.vram[nametab+tilex];\r
+ code=PicoMem.vram[nametab+tilex];\r
if (code==blank) continue;\r
\r
// Get tile address/2:\r
}\r
\r
\r
-static void DrawLayerFull(int plane, int *hcache, int planestart, int planeend)\r
+static void DrawLayerFull(int plane, int *hcache, int planestart, int planeend,\r
+ struct PicoEState *est)\r
{\r
struct PicoVideo *pvid=&Pico.video;\r
static char shift[4]={5,6,6,7}; // 32,64 or 128 sized tilemaps\r
\r
if(!(pvid->reg[11]&3)) { // full screen scroll\r
// Get horizontal scroll value\r
- hscroll=Pico.vram[htab&0x7fff];\r
+ hscroll=PicoMem.vram[htab&0x7fff];\r
htab = 0; // this marks that we don't have to update scroll value\r
}\r
\r
if (plane==0) nametab=(pvid->reg[2]&0x38)<< 9; // A\r
else nametab=(pvid->reg[4]&0x07)<<12; // B\r
\r
- scrpos = PicoDraw2FB;\r
+ scrpos = est->Draw2FB;\r
scrpos+=8*LINE_WIDTH*(planestart-START_ROW);\r
\r
// Get vertical scroll value:\r
- vscroll=Pico.vsram[plane]&0x1ff;\r
+ vscroll=PicoMem.vsram[plane]&0x1ff;\r
scrpos+=(8-(vscroll&7))*LINE_WIDTH;\r
if(vscroll&7) planeend++; // we have vertically clipped tiles due to vscroll, so we need 1 more row\r
\r
if(htab) {\r
int htaddr=htab+(trow<<4);\r
if(trow) htaddr-=(vscroll&7)<<1;\r
- hscroll=Pico.vram[htaddr&0x7fff];\r
+ hscroll=PicoMem.vram[htaddr&0x7fff];\r
}\r
\r
// Draw tiles across screen:\r
// unsigned short *pal=NULL;\r
unsigned char pal;\r
\r
- code=Pico.vram[nametab_row+(tilex&xmask)];\r
+ code=PicoMem.vram[nametab_row+(tilex&xmask)];\r
if (code==blank) continue;\r
\r
if (code>>15) { // high priority tile\r
}\r
\r
\r
-static void DrawTilesFromCacheF(int *hc)\r
+static void DrawTilesFromCacheF(int *hc, struct PicoEState *est)\r
{\r
int code, addr, zero = 0;\r
unsigned int prevy=0xFFFFFFFF;\r
// unsigned short *pal;\r
unsigned char pal;\r
short blank=-1; // The tile we know is blank\r
- unsigned char *scrpos = PicoDraw2FB, *pd = 0;\r
+ unsigned char *scrpos = est->Draw2FB, *pd = 0;\r
\r
// *hcache++ = code|(dx<<16)|(trow<<27); // cache it\r
scrpos+=(*hc++)*LINE_WIDTH - START_ROW*LINE_WIDTH*8;\r
\r
\r
// sx and sy are coords of virtual screen with 8pix borders on top and on left\r
-static void DrawSpriteFull(unsigned int *sprite)\r
+static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)\r
{\r
int width=0,height=0;\r
// unsigned short *pal=NULL;\r
// goto first vertically visible tile\r
while(sy <= START_ROW*8) { sy+=8; tile+=tdeltay; height--; }\r
\r
- scrpos = PicoDraw2FB;\r
+ scrpos = est->Draw2FB;\r
scrpos+=(sy-START_ROW*8)*LINE_WIDTH;\r
\r
for (; height > 0; height--, sy+=8, tile+=tdeltay)\r
unsigned int *sprite=NULL;\r
int code, code2, sx, sy, height;\r
\r
- sprite=(unsigned int *)(Pico.vram+((table+(link<<2))&0x7ffc)); // Find sprite\r
+ sprite=(unsigned int *)(PicoMem.vram+((table+(link<<2))&0x7ffc)); // Find sprite\r
\r
// get sprite info\r
code = sprite[0];\r
}\r
\r
// Go through sprites backwards:\r
- for (i-- ;i>=0; i--)\r
+ for (i--; i >= 0; i--)\r
{\r
- DrawSpriteFull(sprites[i]);\r
+ DrawSpriteFull(sprites[i], &Pico.est);\r
}\r
}\r
\r
#ifndef _ASM_DRAW_C\r
-static void BackFillFull(int reg7)\r
+static void BackFillFull(void *dst, int reg7)\r
{\r
unsigned int back;\r
\r
// Start with a background color:\r
-// back=PicoCramHigh[reg7&0x3f];\r
back=reg7&0x3f;\r
back|=back<<8;\r
back|=back<<16;\r
\r
- memset32((int *)PicoDraw2FB, back, LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/4);\r
+ memset32(dst, back, LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/4);\r
}\r
#endif\r
\r
static void DrawDisplayFull(void)\r
{\r
+ struct PicoEState *est = &Pico.est;\r
struct PicoVideo *pvid=&Pico.video;\r
int win, edge=0, hvwin=0; // LSb->MSb: hwin&plane, vwin&plane, full\r
int planestart=START_ROW, planeend=END_ROW; // plane A start/end when window shares display with plane A (in tile rows or columns)\r
if (hvwin==1) { winend|=maxcolc<<16; planeend|=maxcolc<<16; }\r
\r
HighCache2A[1] = HighCache2B[1] = 0;\r
- if (PicoDrawMask & PDRAW_LAYERB_ON)\r
- DrawLayerFull(1, HighCache2B, START_ROW, (maxcolc<<16)|END_ROW);\r
- if (PicoDrawMask & PDRAW_LAYERA_ON) switch (hvwin)\r
+ if (!(pvid->debug_p & PVD_KILL_B))\r
+ DrawLayerFull(1, HighCache2B, START_ROW, (maxcolc<<16)|END_ROW, est);\r
+ if (!(pvid->debug_p & PVD_KILL_A)) switch (hvwin)\r
{\r
case 4:\r
// fullscreen window\r
- DrawWindowFull(START_ROW, (maxcolc<<16)|END_ROW, 0);\r
+ DrawWindowFull(START_ROW, (maxcolc<<16)|END_ROW, 0, est);\r
break;\r
\r
case 3:\r
// we have plane A and both v and h windows\r
- DrawLayerFull(0, HighCache2A, planestart, planeend);\r
- DrawWindowFull( winstart&~0xff0000, (winend&~0xff0000)|(maxcolc<<16), 0); // h\r
- DrawWindowFull((winstart&~0xff)|START_ROW, (winend&~0xff)|END_ROW, 0); // v\r
+ DrawLayerFull(0, HighCache2A, planestart, planeend, est);\r
+ DrawWindowFull( winstart&~0xff0000, (winend&~0xff0000)|(maxcolc<<16), 0, est); // h\r
+ DrawWindowFull((winstart&~0xff)|START_ROW, (winend&~0xff)|END_ROW, 0, est); // v\r
break;\r
\r
case 2:\r
case 1:\r
// both window and plane A visible, window is vertical XOR horizontal\r
- DrawLayerFull(0, HighCache2A, planestart, planeend);\r
- DrawWindowFull(winstart, winend, 0);\r
+ DrawLayerFull(0, HighCache2A, planestart, planeend, est);\r
+ DrawWindowFull(winstart, winend, 0, est);\r
break;\r
\r
default:\r
// fullscreen plane A\r
- DrawLayerFull(0, HighCache2A, START_ROW, (maxcolc<<16)|END_ROW);\r
+ DrawLayerFull(0, HighCache2A, START_ROW, (maxcolc<<16)|END_ROW, est);\r
break;\r
}\r
- if (PicoDrawMask & PDRAW_SPRITES_LOW_ON)\r
+ if (!(pvid->debug_p & PVD_KILL_S_LO))\r
DrawAllSpritesFull(0, maxw);\r
\r
- if (HighCache2B[1]) DrawTilesFromCacheF(HighCache2B);\r
- if (HighCache2A[1]) DrawTilesFromCacheF(HighCache2A);\r
- if (PicoDrawMask & PDRAW_LAYERA_ON) switch (hvwin)\r
+ if (HighCache2B[1]) DrawTilesFromCacheF(HighCache2B, est);\r
+ if (HighCache2A[1]) DrawTilesFromCacheF(HighCache2A, est);\r
+ if (!(pvid->debug_p & PVD_KILL_A)) switch (hvwin)\r
{\r
case 4:\r
// fullscreen window\r
- DrawWindowFull(START_ROW, (maxcolc<<16)|END_ROW, 1);\r
+ DrawWindowFull(START_ROW, (maxcolc<<16)|END_ROW, 1, est);\r
break;\r
\r
case 3:\r
// we have plane A and both v and h windows\r
- DrawWindowFull( winstart&~0xff0000, (winend&~0xff0000)|(maxcolc<<16), 1); // h\r
- DrawWindowFull((winstart&~0xff)|START_ROW, (winend&~0xff)|END_ROW, 1); // v\r
+ DrawWindowFull( winstart&~0xff0000, (winend&~0xff0000)|(maxcolc<<16), 1, est); // h\r
+ DrawWindowFull((winstart&~0xff)|START_ROW, (winend&~0xff)|END_ROW, 1, est); // v\r
break;\r
\r
case 2:\r
case 1:\r
// both window and plane A visible, window is vertical XOR horizontal\r
- DrawWindowFull(winstart, winend, 1);\r
+ DrawWindowFull(winstart, winend, 1, est);\r
break;\r
}\r
- if (PicoDrawMask & PDRAW_SPRITES_HI_ON)\r
+ if (!(pvid->debug_p & PVD_KILL_S_HI))\r
DrawAllSpritesFull(1, maxw);\r
}\r
\r
\r
PICO_INTERNAL void PicoFrameFull()\r
{\r
+ pprof_start(draw);\r
+\r
// prepare cram?\r
if (PicoPrepareCram) PicoPrepareCram();\r
\r
// Draw screen:\r
- BackFillFull(Pico.video.reg[7]);\r
- if (Pico.video.reg[1]&0x40) DrawDisplayFull();\r
+ BackFillFull(Pico.est.Draw2FB, Pico.video.reg[7]);\r
+ if (Pico.video.reg[1] & 0x40)\r
+ DrawDisplayFull();\r
+\r
+ pprof_end(draw);\r
}\r
\r
+void PicoDraw2Init(void)\r
+{\r
+ Pico.est.Draw2FB = PicoDraw2FB_;\r
+}\r