mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
vdp renderer, improvements for 8bit fast
improved 240 lines support, add setting buffer width, structural improvements
This commit is contained in:
parent
4e0fca8142
commit
f55fb31463
6 changed files with 152 additions and 103 deletions
|
@ -224,7 +224,7 @@ static void p32x_start_blank(void)
|
|||
pprof_start(draw);
|
||||
|
||||
offs = 8; lines = 224;
|
||||
if ((Pico.video.reg[1] & 8) && !(PicoIn.opt & POPT_ALT_RENDERER)) {
|
||||
if (Pico.video.reg[1] & 8) {
|
||||
offs = 0;
|
||||
lines = 240;
|
||||
}
|
||||
|
|
|
@ -1840,6 +1840,7 @@ PICO_INTERNAL void PicoFrameStart(void)
|
|||
if (!(Pico.video.reg[12] & 1))
|
||||
Pico.est.rendstatus |= PDRAW_32_COLS;
|
||||
if (Pico.video.reg[1] & 8) {
|
||||
Pico.est.rendstatus |= PDRAW_30_ROWS;
|
||||
offs = 0;
|
||||
lines = 240;
|
||||
}
|
||||
|
@ -1984,7 +1985,7 @@ void PicoDrawSetOutFormat(pdso_t which, int use_32x_line_mode)
|
|||
{
|
||||
PicoDrawSetInternalBuf(NULL, 0);
|
||||
PicoDrawSetOutBufMD(NULL, 0);
|
||||
PicoDraw2SetOutBuf(NULL);
|
||||
PicoDraw2SetOutBuf(NULL, 0);
|
||||
switch (which)
|
||||
{
|
||||
case PDF_8BIT:
|
||||
|
@ -2016,7 +2017,7 @@ void PicoDrawSetOutBufMD(void *dest, int increment)
|
|||
// kludge for no-copy mode, using ALT_RENDERER layout
|
||||
PicoDrawSetInternalBuf(dest, increment);
|
||||
} else if (FinalizeLine == NULL) {
|
||||
PicoDraw2SetOutBuf(dest);
|
||||
PicoDraw2SetOutBuf(dest, increment);
|
||||
} else if (dest != NULL) {
|
||||
DrawLineDestBase = dest;
|
||||
DrawLineDestIncrement = increment;
|
||||
|
|
239
pico/draw2.c
239
pico/draw2.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -208,9 +208,10 @@ void PicoDoHighPal555(int sh, int line, struct PicoEState *est);
|
|||
#define PDRAW_SONIC_MODE (1<<5) // mid-frame palette changes for 8bit renderer
|
||||
#define PDRAW_PLANE_HI_PRIO (1<<6) // have layer with all hi prio tiles (mk3)
|
||||
#define PDRAW_SHHI_DONE (1<<7) // layer sh/hi already processed
|
||||
#define PDRAW_32_COLS (1<<8) // 32 column mode
|
||||
#define PDRAW_32_COLS (1<<8) // 32 columns mode
|
||||
#define PDRAW_BORDER_32 (1<<9) // center H32 in buffer (32 px border)
|
||||
#define PDRAW_SKIP_FRAME (1<<10) // frame is skipped
|
||||
#define PDRAW_30_ROWS (1<<11) // 30 rows mode (240 lines)
|
||||
extern int rendstatus_old;
|
||||
extern int rendlines;
|
||||
|
||||
|
|
|
@ -359,6 +359,8 @@ struct PicoEState
|
|||
void *PicoMem_cram;
|
||||
unsigned int *PicoOpt;
|
||||
unsigned char *Draw2FB;
|
||||
int Draw2Width;
|
||||
int Draw2Start;
|
||||
unsigned short HighPal[0x100];
|
||||
unsigned short SonicPal[0x100];
|
||||
int SonicPalCount;
|
||||
|
@ -673,7 +675,7 @@ extern int DrawLineDestIncrement;
|
|||
extern u32 VdpSATCache[128];
|
||||
|
||||
// draw2.c
|
||||
void PicoDraw2SetOutBuf(void *dest);
|
||||
void PicoDraw2SetOutBuf(void *dest, int incr);
|
||||
void PicoDraw2Init(void);
|
||||
PICO_INTERNAL void PicoFrameFull();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue