|
@@ -23,7 +23,7 @@
|
|
|
#define LINE_WIDTH 328
|
|
|
#endif
|
|
|
|
|
|
-static unsigned char PicoDraw2FB_[(8+320) * (8+240+8) + 8];
|
|
|
+static unsigned char PicoDraw2FB_[LINE_WIDTH * (8+240+8) + 8];
|
|
|
|
|
|
static u32 HighCache2A[2*41*(TILE_ROWS+1)+1+1]; // caches for high layers
|
|
|
static u32 HighCache2B[2*41*(TILE_ROWS+1)+1+1];
|
|
@@ -43,16 +43,17 @@ void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est);
|
|
|
#else
|
|
|
|
|
|
|
|
|
-static int TileXnormYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)
|
|
|
+static int TileXnormYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoEState *est)
|
|
|
{
|
|
|
unsigned int pack=0; unsigned int t=0, blank = 1;
|
|
|
+ unsigned short *vram = est->PicoMem_vram;
|
|
|
int i, inc=2;
|
|
|
|
|
|
#if INTERLACE
|
|
|
- if ((pvid->reg[12]&6) == 6) inc = 4;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE) inc = 4;
|
|
|
#endif
|
|
|
- for(i=8; i; i--, addr+=inc, pd += LINE_WIDTH) {
|
|
|
- pack=*(u32 *)(PicoMem.vram+addr); // Get 8 pixels
|
|
|
+ for(i=8; i; i--, addr+=inc, pd += est->Draw2Width) {
|
|
|
+ pack=*(u32 *)(vram+addr); // Get 8 pixels
|
|
|
if(!pack) continue;
|
|
|
|
|
|
t=pack&0x0000f000; if (t) pd[0]=(unsigned char)((t>>12)|pal);
|
|
@@ -69,16 +70,17 @@ static int TileXnormYnorm(unsigned char *pd,int addr,unsigned char pal, struct P
|
|
|
return blank; // Tile blank?
|
|
|
}
|
|
|
|
|
|
-static int TileXflipYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)
|
|
|
+static int TileXflipYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoEState *est)
|
|
|
{
|
|
|
unsigned int pack=0; unsigned int t=0, blank = 1;
|
|
|
+ unsigned short *vram = est->PicoMem_vram;
|
|
|
int i, inc=2;
|
|
|
|
|
|
#if INTERLACE
|
|
|
- if ((pvid->reg[12]&6) == 6) inc = 4;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE) inc = 4;
|
|
|
#endif
|
|
|
- for(i=8; i; i--, addr+=inc, pd += LINE_WIDTH) {
|
|
|
- pack=*(u32 *)(PicoMem.vram+addr); // Get 8 pixels
|
|
|
+ for(i=8; i; i--, addr+=inc, pd += est->Draw2Width) {
|
|
|
+ pack=*(u32 *)(vram+addr); // Get 8 pixels
|
|
|
if(!pack) continue;
|
|
|
|
|
|
t=pack&0x000f0000; if (t) pd[0]=(unsigned char)((t>>16)|pal);
|
|
@@ -94,17 +96,18 @@ static int TileXflipYnorm(unsigned char *pd,int addr,unsigned char pal, struct P
|
|
|
return blank; // Tile blank?
|
|
|
}
|
|
|
|
|
|
-static int TileXnormYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)
|
|
|
+static int TileXnormYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoEState *est)
|
|
|
{
|
|
|
unsigned int pack=0; unsigned int t=0, blank = 1;
|
|
|
+ unsigned short *vram = est->PicoMem_vram;
|
|
|
int i, inc=2;
|
|
|
|
|
|
#if INTERLACE
|
|
|
- if ((pvid->reg[12]&6) == 6) inc = 4, addr += 16;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE) inc = 4, addr += 16;
|
|
|
#endif
|
|
|
addr+=14;
|
|
|
- for(i=8; i; i--, addr-=inc, pd += LINE_WIDTH) {
|
|
|
- pack=*(u32 *)(PicoMem.vram+addr); // Get 8 pixels
|
|
|
+ for(i=8; i; i--, addr-=inc, pd += est->Draw2Width) {
|
|
|
+ pack=*(u32 *)(vram+addr); // Get 8 pixels
|
|
|
if(!pack) continue;
|
|
|
|
|
|
t=pack&0x0000f000; if (t) pd[0]=(unsigned char)((t>>12)|pal);
|
|
@@ -121,17 +124,18 @@ static int TileXnormYflip(unsigned char *pd,int addr,unsigned char pal, struct P
|
|
|
return blank; // Tile blank?
|
|
|
}
|
|
|
|
|
|
-static int TileXflipYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)
|
|
|
+static int TileXflipYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoEState *est)
|
|
|
{
|
|
|
unsigned int pack=0; unsigned int t=0, blank = 1;
|
|
|
+ unsigned short *vram = est->PicoMem_vram;
|
|
|
int i, inc=2;
|
|
|
|
|
|
#if INTERLACE
|
|
|
- if ((pvid->reg[12]&6) == 6) inc = 4, addr += 16;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE) inc = 4, addr += 16;
|
|
|
#endif
|
|
|
addr+=14;
|
|
|
- for(i=8; i; i--, addr-=inc, pd += LINE_WIDTH) {
|
|
|
- pack=*(u32 *)(PicoMem.vram+addr); // Get 8 pixels
|
|
|
+ for(i=8; i; i--, addr-=inc, pd += est->Draw2Width) {
|
|
|
+ pack=*(u32 *)(vram+addr); // Get 8 pixels
|
|
|
if(!pack) continue;
|
|
|
|
|
|
t=pack&0x000f0000; if (t) pd[0]=(unsigned char)((t>>16)|pal);
|
|
@@ -151,9 +155,10 @@ static int TileXflipYflip(unsigned char *pd,int addr,unsigned char pal, struct P
|
|
|
// start: (tile_start<<16)|row_start, end: [same]
|
|
|
static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
|
|
|
{
|
|
|
- struct PicoVideo *pvid=&Pico.video;
|
|
|
+ struct PicoVideo *pvid=&est->Pico->video;
|
|
|
int nametab, nametab_step, trow, tilex, blank=-1, code;
|
|
|
unsigned char *scrpos = est->Draw2FB;
|
|
|
+ int scrstart = est->Draw2Start;
|
|
|
int tile_start, tile_end; // in cells
|
|
|
|
|
|
// parse ranges
|
|
@@ -172,17 +177,17 @@ static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
|
|
|
{
|
|
|
nametab=(pvid->reg[3]&0x3e)<<9; // 32-cell mode
|
|
|
nametab_step = 1<<5;
|
|
|
- if (!(PicoIn.opt&POPT_DIS_32C_BORDER))
|
|
|
+ if (est->rendstatus & PDRAW_BORDER_32)
|
|
|
scrpos += 32;
|
|
|
}
|
|
|
- nametab += nametab_step*start;
|
|
|
+ nametab += nametab_step*(start-scrstart);
|
|
|
|
|
|
// check priority
|
|
|
code=PicoMem.vram[nametab+tile_start];
|
|
|
if ((code>>15) != prio) return; // hack: just assume that whole window uses same priority
|
|
|
|
|
|
- scrpos+=8*LINE_WIDTH+8;
|
|
|
- scrpos+=8*LINE_WIDTH*(start-START_ROW);
|
|
|
+ scrpos+=8*est->Draw2Width+8;
|
|
|
+ scrpos+=8*est->Draw2Width*(start-scrstart);
|
|
|
|
|
|
// do a window until we reach planestart row
|
|
|
for(trow = start; trow < end; trow++, nametab+=nametab_step) { // current tile row
|
|
@@ -196,21 +201,26 @@ static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
|
|
|
if (code==blank) continue;
|
|
|
|
|
|
// Get tile address/2:
|
|
|
- addr=(code&0x7ff)<<4;
|
|
|
+#if INTERLACE
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE)
|
|
|
+ addr=(code&0x3ff)<<5;
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ addr=(code&0x7ff)<<4;
|
|
|
|
|
|
// pal=PicoCramHigh+((code>>9)&0x30);
|
|
|
pal=(unsigned char)((code>>9)&0x30);
|
|
|
|
|
|
switch((code>>11)&3) {
|
|
|
- case 0: zero=TileXnormYnorm(scrpos+(tilex<<3),addr,pal,pvid); break;
|
|
|
- case 1: zero=TileXflipYnorm(scrpos+(tilex<<3),addr,pal,pvid); break;
|
|
|
- case 2: zero=TileXnormYflip(scrpos+(tilex<<3),addr,pal,pvid); break;
|
|
|
- case 3: zero=TileXflipYflip(scrpos+(tilex<<3),addr,pal,pvid); break;
|
|
|
+ case 0: zero=TileXnormYnorm(scrpos+(tilex<<3),addr,pal,est); break;
|
|
|
+ case 1: zero=TileXflipYnorm(scrpos+(tilex<<3),addr,pal,est); break;
|
|
|
+ case 2: zero=TileXnormYflip(scrpos+(tilex<<3),addr,pal,est); break;
|
|
|
+ case 3: zero=TileXflipYflip(scrpos+(tilex<<3),addr,pal,est); break;
|
|
|
}
|
|
|
if(zero) blank=code; // We know this tile is blank now
|
|
|
}
|
|
|
|
|
|
- scrpos += LINE_WIDTH*8;
|
|
|
+ scrpos += est->Draw2Width*8;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -218,11 +228,12 @@ static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
|
|
|
static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
|
|
|
struct PicoEState *est)
|
|
|
{
|
|
|
- struct PicoVideo *pvid=&Pico.video;
|
|
|
+ struct PicoVideo *pvid=&est->Pico->video;
|
|
|
static char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps
|
|
|
int width, height, ymask, htab;
|
|
|
int nametab, hscroll=0, vscroll, cells;
|
|
|
unsigned char *scrpos;
|
|
|
+ int scrstart = est->Draw2Start;
|
|
|
int blank=-1, xmask, nametab_row, trow;
|
|
|
|
|
|
// parse ranges
|
|
@@ -257,9 +268,9 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
|
|
|
else nametab=(pvid->reg[4]&0x07)<<12; // B
|
|
|
|
|
|
scrpos = est->Draw2FB;
|
|
|
- if (!(pvid->reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))
|
|
|
+ if (est->rendstatus & PDRAW_BORDER_32)
|
|
|
scrpos += 32;
|
|
|
- scrpos+=8*LINE_WIDTH*(planestart-START_ROW);
|
|
|
+ scrpos+=8*est->Draw2Width*(planestart-scrstart);
|
|
|
|
|
|
if((pvid->reg[11]&4)||(PicoMem.vsram[plane]&7))
|
|
|
planeend++; // we (may) have vertically clipped tiles due to vscroll, so we need 1 more row
|
|
@@ -273,7 +284,8 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
|
|
|
vscroll=PicoMem.vsram[plane+0x20];//&0x1ff;
|
|
|
#endif
|
|
|
#if INTERLACE
|
|
|
- if ((pvid->reg[12]&6) == 6) vscroll >>= 1;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE)
|
|
|
+ vscroll >>= 1;
|
|
|
#endif
|
|
|
nametab_row = nametab + (((trow+(vscroll>>3))&ymask)<<shift[width]); // pointer to nametable entries for this row
|
|
|
|
|
@@ -303,7 +315,8 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
|
|
|
if ((pvid->reg[11]&4) && !(vsidx&1)) { // 2-cell mode
|
|
|
vscroll=PicoMem.vsram[vsidx+plane];//&0x1ff;
|
|
|
#if INTERLACE
|
|
|
- if ((pvid->reg[12]&6) == 6) vscroll >>= 1;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE)
|
|
|
+ vscroll >>= 1;
|
|
|
#endif
|
|
|
nametab_row = nametab + (((trow+(vscroll>>3))&ymask)<<shift[width]); // pointer to nametable entries for this row
|
|
|
}
|
|
@@ -321,26 +334,26 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
|
|
|
|
|
|
// Get tile address/2:
|
|
|
#if INTERLACE
|
|
|
- if ((pvid->reg[12]&6) == 6)
|
|
|
- addr=(code&0x3ff)<<5;
|
|
|
- else
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE)
|
|
|
+ addr=(code&0x3ff)<<5;
|
|
|
+ else
|
|
|
#endif
|
|
|
- addr=(code&0x7ff)<<4;
|
|
|
+ addr=(code&0x7ff)<<4;
|
|
|
|
|
|
// pal=PicoCramHigh+((code>>9)&0x30);
|
|
|
pal=(unsigned char)((code>>9)&0x30);
|
|
|
|
|
|
- scroff=(8-(vscroll&7))*LINE_WIDTH;
|
|
|
+ scroff=(8-(vscroll&7))*est->Draw2Width;
|
|
|
switch((code>>11)&3) {
|
|
|
- case 0: zero=TileXnormYnorm(scrpos+scroff+dx,addr,pal,pvid); break;
|
|
|
- case 1: zero=TileXflipYnorm(scrpos+scroff+dx,addr,pal,pvid); break;
|
|
|
- case 2: zero=TileXnormYflip(scrpos+scroff+dx,addr,pal,pvid); break;
|
|
|
- case 3: zero=TileXflipYflip(scrpos+scroff+dx,addr,pal,pvid); break;
|
|
|
+ case 0: zero=TileXnormYnorm(scrpos+scroff+dx,addr,pal,est); break;
|
|
|
+ case 1: zero=TileXflipYnorm(scrpos+scroff+dx,addr,pal,est); break;
|
|
|
+ case 2: zero=TileXnormYflip(scrpos+scroff+dx,addr,pal,est); break;
|
|
|
+ case 3: zero=TileXflipYflip(scrpos+scroff+dx,addr,pal,est); break;
|
|
|
}
|
|
|
if(zero) blank=code; // We know this tile is blank now
|
|
|
}
|
|
|
|
|
|
- scrpos += LINE_WIDTH*8;
|
|
|
+ scrpos += est->Draw2Width*8;
|
|
|
}
|
|
|
|
|
|
*hcache = 0; // terminate cache
|
|
@@ -356,35 +369,36 @@ static void DrawTilesFromCacheF(u32 *hc, struct PicoEState *est)
|
|
|
unsigned char pal;
|
|
|
short blank=-1; // The tile we know is blank
|
|
|
unsigned char *scrpos = est->Draw2FB, *pd = 0;
|
|
|
+ int scrstart = est->Draw2Start;
|
|
|
|
|
|
- if (!(Pico.video.reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))
|
|
|
+ if (est->rendstatus & PDRAW_BORDER_32)
|
|
|
scrpos += 32;
|
|
|
|
|
|
while((code=*hc++)) {
|
|
|
- vscroll=(*hc++)*LINE_WIDTH - START_ROW*LINE_WIDTH*8;
|
|
|
+ vscroll=(*hc++ - START_ROW*8)*est->Draw2Width;
|
|
|
if((short)code == blank) continue;
|
|
|
|
|
|
// y pos
|
|
|
if(((unsigned)code>>27) != prevy) {
|
|
|
prevy = (unsigned)code>>27;
|
|
|
- pd = scrpos + prevy*LINE_WIDTH*8;
|
|
|
+ pd = scrpos + (prevy-scrstart)*est->Draw2Width*8;
|
|
|
}
|
|
|
|
|
|
// Get tile address/2:
|
|
|
#if INTERLACE
|
|
|
- if ((Pico.video.reg[12]&6) == 6)
|
|
|
- addr=(code&0x3ff)<<5;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE)
|
|
|
+ addr=(code&0x3ff)<<5;
|
|
|
else
|
|
|
#endif
|
|
|
- addr=(code&0x7ff)<<4;
|
|
|
+ addr=(code&0x7ff)<<4;
|
|
|
// pal=PicoCramHigh+((code>>9)&0x30);
|
|
|
pal=(unsigned char)((code>>9)&0x30);
|
|
|
|
|
|
switch((code>>11)&3) {
|
|
|
- case 0: zero=TileXnormYnorm(pd+vscroll+((code>>16)&0x1ff),addr,pal,&Pico.video); break;
|
|
|
- case 1: zero=TileXflipYnorm(pd+vscroll+((code>>16)&0x1ff),addr,pal,&Pico.video); break;
|
|
|
- case 2: zero=TileXnormYflip(pd+vscroll+((code>>16)&0x1ff),addr,pal,&Pico.video); break;
|
|
|
- case 3: zero=TileXflipYflip(pd+vscroll+((code>>16)&0x1ff),addr,pal,&Pico.video); break;
|
|
|
+ case 0: zero=TileXnormYnorm(pd+vscroll+((code>>16)&0x1ff),addr,pal,est); break;
|
|
|
+ case 1: zero=TileXflipYnorm(pd+vscroll+((code>>16)&0x1ff),addr,pal,est); break;
|
|
|
+ case 2: zero=TileXnormYflip(pd+vscroll+((code>>16)&0x1ff),addr,pal,est); break;
|
|
|
+ case 3: zero=TileXflipYflip(pd+vscroll+((code>>16)&0x1ff),addr,pal,est); break;
|
|
|
}
|
|
|
|
|
|
if(zero) blank=(short)code;
|
|
@@ -400,16 +414,17 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
|
|
|
unsigned char pal;
|
|
|
int tile,code,tdeltax,tdeltay;
|
|
|
unsigned char *scrpos;
|
|
|
+ int scrstart = est->Draw2Start;
|
|
|
int sx, sy;
|
|
|
|
|
|
sy=sprite[0];
|
|
|
height=sy>>24;
|
|
|
#if INTERLACE
|
|
|
- if ((Pico.video.reg[12]&6) == 6)
|
|
|
- sy = ((sy>>1)&0x1ff)-0x78;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE)
|
|
|
+ sy = ((sy>>1)&0x1ff)-0x78;
|
|
|
else
|
|
|
#endif
|
|
|
- sy=(sy&0x1ff)-0x78; // Y
|
|
|
+ sy=(sy&0x1ff)-0x78; // Y
|
|
|
width=(height>>2)&3; height&=3;
|
|
|
width++; height++; // Width and height in tiles
|
|
|
|
|
@@ -427,19 +442,18 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
|
|
|
pal=(unsigned char)((code>>9)&0x30);
|
|
|
|
|
|
// goto first vertically visible tile
|
|
|
- while(sy <= START_ROW*8) { sy+=8; tile+=tdeltay; height--; }
|
|
|
+ while(sy <= scrstart*8) { sy+=8; tile+=tdeltay; height--; }
|
|
|
|
|
|
scrpos = est->Draw2FB;
|
|
|
- if (!(Pico.video.reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))
|
|
|
+ if (est->rendstatus&PDRAW_BORDER_32)
|
|
|
scrpos += 32;
|
|
|
- scrpos+=(sy-START_ROW*8)*LINE_WIDTH;
|
|
|
+ scrpos+=(sy-scrstart*8)*est->Draw2Width;
|
|
|
|
|
|
for (; height > 0; height--, sy+=8, tile+=tdeltay)
|
|
|
{
|
|
|
- int w = width, x=sx, t=tile;
|
|
|
- int s=4;
|
|
|
+ int w = width, x=sx, t=tile, s;
|
|
|
|
|
|
- if(sy >= END_ROW*8+8) return; // offscreen
|
|
|
+ if((sy-scrstart*8) >= END_ROW*8+8) return; // offscreen
|
|
|
|
|
|
for (; w; w--,x+=8,t+=tdeltax)
|
|
|
{
|
|
@@ -448,30 +462,36 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
|
|
|
|
|
|
t&=0x7fff; // Clip tile address
|
|
|
#if INTERLACE
|
|
|
- if ((Pico.video.reg[12]&6) == 6) s=5;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE)
|
|
|
+ s=5;
|
|
|
+ else
|
|
|
#endif
|
|
|
+ s=4;
|
|
|
switch((code>>11)&3) {
|
|
|
- case 0: TileXnormYnorm(scrpos+x,t<<s,pal,&Pico.video); break;
|
|
|
- case 1: TileXflipYnorm(scrpos+x,t<<s,pal,&Pico.video); break;
|
|
|
- case 2: TileXnormYflip(scrpos+x,t<<s,pal,&Pico.video); break;
|
|
|
- case 3: TileXflipYflip(scrpos+x,t<<s,pal,&Pico.video); break;
|
|
|
+ case 0: TileXnormYnorm(scrpos+x,t<<s,pal,est); break;
|
|
|
+ case 1: TileXflipYnorm(scrpos+x,t<<s,pal,est); break;
|
|
|
+ case 2: TileXnormYflip(scrpos+x,t<<s,pal,est); break;
|
|
|
+ case 3: TileXflipYflip(scrpos+x,t<<s,pal,est); break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- scrpos+=8*LINE_WIDTH;
|
|
|
+ scrpos+=8*est->Draw2Width;
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
|
|
|
-static void DrawAllSpritesFull(int prio, int maxwidth)
|
|
|
+static void DrawAllSpritesFull(int prio, int maxwidth, struct PicoEState *est)
|
|
|
{
|
|
|
- struct PicoVideo *pvid=&Pico.video;
|
|
|
+ struct PicoVideo *pvid=&est->Pico->video;
|
|
|
int table=0,maskrange=0;
|
|
|
int i,u,link=0;
|
|
|
unsigned int *sprites[80]; // Sprites
|
|
|
int y_min=START_ROW*8, y_max=END_ROW*8; // for a simple sprite masking
|
|
|
- int max_sprites = Pico.video.reg[12]&1 ? 80 : 64;
|
|
|
+ int max_sprites = pvid->reg[12]&1 ? 80 : 64;
|
|
|
+
|
|
|
+ if (est->rendstatus & PDRAW_30_ROWS)
|
|
|
+ y_min += 8, y_max += 8;
|
|
|
|
|
|
table=pvid->reg[5]&0x7f;
|
|
|
if (pvid->reg[12]&1) table&=0x7e; // Lowest bit 0 in 40-cell mode
|
|
@@ -489,11 +509,11 @@ static void DrawAllSpritesFull(int prio, int maxwidth)
|
|
|
|
|
|
// check if it is not hidden vertically
|
|
|
#if INTERLACE
|
|
|
- if ((pvid->reg[12]&6) == 6)
|
|
|
- sy = ((code>>1)&0x1ff)-0x80;
|
|
|
+ if (est->rendstatus & PDRAW_INTERLACE)
|
|
|
+ sy = ((code>>1)&0x1ff)-0x80;
|
|
|
else
|
|
|
#endif
|
|
|
- sy = (code&0x1ff)-0x80;
|
|
|
+ sy = (code&0x1ff)-0x80;
|
|
|
height = (((code>>24)&3)+1)<<3;
|
|
|
if(sy+height <= y_min || sy > y_max) goto nextsprite;
|
|
|
|
|
@@ -534,7 +554,7 @@ static void DrawAllSpritesFull(int prio, int maxwidth)
|
|
|
// Go through sprites backwards:
|
|
|
for (i--; i >= 0; i--)
|
|
|
{
|
|
|
- DrawSpriteFull(sprites[i], &Pico.est);
|
|
|
+ DrawSpriteFull(sprites[i], est);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -548,24 +568,34 @@ static void BackFillFull(void *dst, int reg7)
|
|
|
back|=back<<8;
|
|
|
back|=back<<16;
|
|
|
|
|
|
- memset32(dst, back, LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/4);
|
|
|
+ memset32(dst, back, Pico.est.Draw2Width*(8+(END_ROW-START_ROW)*8)/4);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
static void DrawDisplayFull(void)
|
|
|
{
|
|
|
struct PicoEState *est = &Pico.est;
|
|
|
- struct PicoVideo *pvid=&Pico.video;
|
|
|
+ struct PicoVideo *pvid=&est->Pico->video;
|
|
|
int win, edge=0, hvwin=0; // LSb->MSb: hwin&plane, vwin&plane, full
|
|
|
- int planestart=START_ROW, planeend=END_ROW; // plane A start/end when window shares display with plane A (in tile rows or columns)
|
|
|
- int winstart=START_ROW, winend=END_ROW; // same for window
|
|
|
+ int scrstart=START_ROW, scrend = END_ROW; // our render area
|
|
|
+ int planestart, planeend; // plane A start/end when window shares display with plane A (in tile rows or columns)
|
|
|
+ int winstart, winend; // same for window
|
|
|
int maxw, maxcolc; // max width and col cells
|
|
|
|
|
|
- if(pvid->reg[12]&1) {
|
|
|
- maxw = 328; maxcolc = 40;
|
|
|
- } else {
|
|
|
+ if(est->rendstatus & PDRAW_32_COLS) {
|
|
|
maxw = 264; maxcolc = 32;
|
|
|
+ } else {
|
|
|
+ maxw = 328; maxcolc = 40;
|
|
|
+ }
|
|
|
+ if(est->rendstatus & PDRAW_30_ROWS) {
|
|
|
+ // In 240 line mode, the top and bottom 8 lines are omitted
|
|
|
+ // since this renderer always renderers 224 lines
|
|
|
+ scrstart ++, scrend ++;
|
|
|
}
|
|
|
+ est->Draw2Start = scrstart;
|
|
|
+
|
|
|
+ planestart = scrstart, planeend = scrend;
|
|
|
+ winstart = scrstart, winend = scrend;
|
|
|
|
|
|
// 32C border for centering? (for asm)
|
|
|
est->rendstatus &= ~PDRAW_BORDER_32;
|
|
@@ -582,12 +612,12 @@ static void DrawDisplayFull(void)
|
|
|
hvwin=4;
|
|
|
} else if(win < 0x80) {
|
|
|
// window on the top
|
|
|
- if(edge <= START_ROW) hvwin=0; // window not visible in our drawing region
|
|
|
- else if(edge >= END_ROW) hvwin=4;
|
|
|
+ if(edge <= scrstart) hvwin=0; // window not visible in our drawing region
|
|
|
+ else if(edge >= scrend) hvwin=4;
|
|
|
else planestart = winend = edge;
|
|
|
} else if(win > 0x80) {
|
|
|
// window at the bottom
|
|
|
- if(edge >= END_ROW) hvwin=0;
|
|
|
+ if(edge >= scrend) hvwin=0;
|
|
|
else planeend = winstart = edge;
|
|
|
}
|
|
|
}
|
|
@@ -622,19 +652,19 @@ static void DrawDisplayFull(void)
|
|
|
|
|
|
HighCache2A[0] = HighCache2B[0] = 0;
|
|
|
if (!(pvid->debug_p & PVD_KILL_B))
|
|
|
- DrawLayerFull(1, HighCache2B, START_ROW, (maxcolc<<16)|END_ROW, est);
|
|
|
+ DrawLayerFull(1, HighCache2B, scrstart, (maxcolc<<16)|scrend, est);
|
|
|
if (!(pvid->debug_p & PVD_KILL_A)) switch (hvwin)
|
|
|
{
|
|
|
case 4:
|
|
|
// fullscreen window
|
|
|
- DrawWindowFull(START_ROW, (maxcolc<<16)|END_ROW, 0, est);
|
|
|
+ DrawWindowFull(scrstart, (maxcolc<<16)|scrend, 0, est);
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
// we have plane A and both v and h windows
|
|
|
DrawLayerFull(0, HighCache2A, planestart, planeend, est);
|
|
|
DrawWindowFull( winstart&~0xff0000, (winend&~0xff0000)|(maxcolc<<16), 0, est); // h
|
|
|
- DrawWindowFull((winstart&~0xff)|START_ROW, (winend&~0xff)|END_ROW, 0, est); // v
|
|
|
+ DrawWindowFull((winstart&~0xff)|scrstart, (winend&~0xff)|scrend, 0, est); // v
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
@@ -646,11 +676,11 @@ static void DrawDisplayFull(void)
|
|
|
|
|
|
default:
|
|
|
// fullscreen plane A
|
|
|
- DrawLayerFull(0, HighCache2A, START_ROW, (maxcolc<<16)|END_ROW, est);
|
|
|
+ DrawLayerFull(0, HighCache2A, scrstart, (maxcolc<<16)|scrend, est);
|
|
|
break;
|
|
|
}
|
|
|
if (!(pvid->debug_p & PVD_KILL_S_LO))
|
|
|
- DrawAllSpritesFull(0, maxw);
|
|
|
+ DrawAllSpritesFull(0, maxw, est);
|
|
|
|
|
|
if (HighCache2B[0]) DrawTilesFromCacheF(HighCache2B, est);
|
|
|
if (HighCache2A[0]) DrawTilesFromCacheF(HighCache2A, est);
|
|
@@ -658,13 +688,13 @@ static void DrawDisplayFull(void)
|
|
|
{
|
|
|
case 4:
|
|
|
// fullscreen window
|
|
|
- DrawWindowFull(START_ROW, (maxcolc<<16)|END_ROW, 1, est);
|
|
|
+ DrawWindowFull(scrstart, (maxcolc<<16)|scrend, 1, est);
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
// we have plane A and both v and h windows
|
|
|
DrawWindowFull( winstart&~0xff0000, (winend&~0xff0000)|(maxcolc<<16), 1, est); // h
|
|
|
- DrawWindowFull((winstart&~0xff)|START_ROW, (winend&~0xff)|END_ROW, 1, est); // v
|
|
|
+ DrawWindowFull((winstart&~0xff)|scrstart, (winend&~0xff)|scrend, 1, est); // v
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
@@ -674,7 +704,7 @@ static void DrawDisplayFull(void)
|
|
|
break;
|
|
|
}
|
|
|
if (!(pvid->debug_p & PVD_KILL_S_HI))
|
|
|
- DrawAllSpritesFull(1, maxw);
|
|
|
+ DrawAllSpritesFull(1, maxw, est);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -690,18 +720,33 @@ PICO_INTERNAL void PicoFrameFull()
|
|
|
if (Pico.video.reg[1] & 0x40)
|
|
|
DrawDisplayFull();
|
|
|
|
|
|
+ // clear top and bottom 8 lines in 240 mode, since draw2 only does 224
|
|
|
+ if (Pico.est.rendstatus & PDRAW_30_ROWS) {
|
|
|
+ unsigned char *pd = Pico.est.Draw2FB;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 8; i > 0; i--, pd += Pico.est.Draw2Width)
|
|
|
+ memset32((int *)pd, 0xe0e0e0e0, 328/4);
|
|
|
+ pd += Pico.est.Draw2Width*(END_ROW-START_ROW)*8;
|
|
|
+ for (i = 8; i > 0; i--, pd += Pico.est.Draw2Width)
|
|
|
+ memset32((int *)pd, 0xe0e0e0e0, 328/4);
|
|
|
+ }
|
|
|
+
|
|
|
pprof_end(draw);
|
|
|
}
|
|
|
|
|
|
-void PicoDraw2SetOutBuf(void *dest)
|
|
|
+void PicoDraw2SetOutBuf(void *dest, int incr)
|
|
|
{
|
|
|
- if (dest)
|
|
|
+ if (dest) {
|
|
|
Pico.est.Draw2FB = dest;
|
|
|
- else
|
|
|
+ Pico.est.Draw2Width = incr;
|
|
|
+ } else {
|
|
|
Pico.est.Draw2FB = PicoDraw2FB_;
|
|
|
+ Pico.est.Draw2Width = LINE_WIDTH;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void PicoDraw2Init(void)
|
|
|
{
|
|
|
- PicoDraw2SetOutBuf(NULL);
|
|
|
+ PicoDraw2SetOutBuf(NULL, 0);
|
|
|
}
|