-// 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
\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
\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
}\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
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
}\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
}\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
\r
HighCache2A[1] = HighCache2B[1] = 0;\r
if (PicoDrawMask & PDRAW_LAYERB_ON)\r
- DrawLayerFull(1, HighCache2B, START_ROW, (maxcolc<<16)|END_ROW);\r
+ DrawLayerFull(1, HighCache2B, START_ROW, (maxcolc<<16)|END_ROW, est);\r
if (PicoDrawMask & PDRAW_LAYERA_ON) 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
DrawAllSpritesFull(0, maxw);\r
\r
- if (HighCache2B[1]) DrawTilesFromCacheF(HighCache2B);\r
- if (HighCache2A[1]) DrawTilesFromCacheF(HighCache2A);\r
+ if (HighCache2B[1]) DrawTilesFromCacheF(HighCache2B, est);\r
+ if (HighCache2A[1]) DrawTilesFromCacheF(HighCache2A, est);\r
if (PicoDrawMask & PDRAW_LAYERA_ON) 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
\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