vdp renderer, improvements for 8bit fast

improved 240 lines support, add setting buffer width, structural improvements
This commit is contained in:
kub 2021-01-20 20:49:04 +01:00
parent 4e0fca8142
commit f55fb31463
6 changed files with 152 additions and 103 deletions

View file

@ -167,7 +167,7 @@ PLATFORM_MP3 = 1
PLATFORM_ZLIB = 1
endif
ifeq "$(PLATFORM)" "psp"
CFLAGS += -DUSE_BGR565 -DDRAW2_OVERRIDE_LINE_WIDTH=512 -G8 # -DLPRINTF_STDIO -DFW15
CFLAGS += -DUSE_BGR565 -G8 # -DLPRINTF_STDIO -DFW15
LDFLAGS := $(filter-out -lpsp%, $(LDFLAGS)) # collides with PSP image generation
LDLIBS += -lpspnet_inet -lpspgu -lpspge -lpsppower -lpspaudio -lpspdisplay
LDLIBS += -lpspaudiocodec -lpsprtc -lpspctrl -lpspsdk -lpspuser -lpspkernel

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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;

View file

@ -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();