vdp renderer, improvements for 8bit fast
authorkub <derkub@gmail.com>
Wed, 20 Jan 2021 19:49:04 +0000 (20:49 +0100)
committerkub <derkub@gmail.com>
Wed, 20 Jan 2021 19:55:12 +0000 (20:55 +0100)
improved 240 lines support, add setting buffer width, structural improvements

Makefile
pico/32x/32x.c
pico/draw.c
pico/draw2.c
pico/pico.h
pico/pico_int.h

index 7dcb1ff..a88e897 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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
index f19dbd5..b91310a 100644 (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;
     }
index deb23f9..ce4fe1c 100644 (file)
@@ -1840,6 +1840,7 @@ PICO_INTERNAL void PicoFrameStart(void)
   if (!(Pico.video.reg[12] & 1))\r
     Pico.est.rendstatus |= PDRAW_32_COLS;\r
   if (Pico.video.reg[1] & 8) {\r
+    Pico.est.rendstatus |= PDRAW_30_ROWS;\r
     offs = 0;\r
     lines = 240;\r
   }\r
@@ -1984,7 +1985,7 @@ void PicoDrawSetOutFormat(pdso_t which, int use_32x_line_mode)
 {\r
   PicoDrawSetInternalBuf(NULL, 0);\r
   PicoDrawSetOutBufMD(NULL, 0);\r
-  PicoDraw2SetOutBuf(NULL);\r
+  PicoDraw2SetOutBuf(NULL, 0);\r
   switch (which)\r
   {\r
     case PDF_8BIT:\r
@@ -2016,7 +2017,7 @@ void PicoDrawSetOutBufMD(void *dest, int increment)
     // kludge for no-copy mode, using ALT_RENDERER layout\r
     PicoDrawSetInternalBuf(dest, increment);\r
   } else if (FinalizeLine == NULL) {\r
-    PicoDraw2SetOutBuf(dest);\r
+    PicoDraw2SetOutBuf(dest, increment);\r
   } else if (dest != NULL) {\r
     DrawLineDestBase = dest;\r
     DrawLineDestIncrement = increment;\r
index a1adaee..9d65ea5 100644 (file)
@@ -23,7 +23,7 @@
 #define LINE_WIDTH 328\r
 #endif\r
 \r
-static unsigned char PicoDraw2FB_[(8+320) * (8+240+8) + 8];\r
+static unsigned char PicoDraw2FB_[LINE_WIDTH * (8+240+8) + 8];\r
 \r
 static u32 HighCache2A[2*41*(TILE_ROWS+1)+1+1]; // caches for high layers\r
 static u32 HighCache2B[2*41*(TILE_ROWS+1)+1+1];\r
@@ -43,16 +43,17 @@ void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est);
 #else\r
 \r
 \r
-static int TileXnormYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)\r
+static int TileXnormYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoEState *est)\r
 {\r
        unsigned int pack=0; unsigned int t=0, blank = 1;\r
+       unsigned short *vram = est->PicoMem_vram;\r
        int i, inc=2;\r
 \r
 #if INTERLACE\r
-       if ((pvid->reg[12]&6) == 6) inc = 4;\r
+       if (est->rendstatus & PDRAW_INTERLACE) inc = 4;\r
 #endif\r
-       for(i=8; i; i--, addr+=inc, pd += LINE_WIDTH) {\r
-               pack=*(u32 *)(PicoMem.vram+addr); // Get 8 pixels\r
+       for(i=8; i; i--, addr+=inc, pd += est->Draw2Width) {\r
+               pack=*(u32 *)(vram+addr); // Get 8 pixels\r
                if(!pack) continue;\r
 \r
                t=pack&0x0000f000; if (t) pd[0]=(unsigned char)((t>>12)|pal);\r
@@ -69,16 +70,17 @@ static int TileXnormYnorm(unsigned char *pd,int addr,unsigned char pal, struct P
        return blank; // Tile blank?\r
 }\r
 \r
-static int TileXflipYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)\r
+static int TileXflipYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoEState *est)\r
 {\r
        unsigned int pack=0; unsigned int t=0, blank = 1;\r
+       unsigned short *vram = est->PicoMem_vram;\r
        int i, inc=2;\r
 \r
 #if INTERLACE\r
-       if ((pvid->reg[12]&6) == 6) inc = 4;\r
+       if (est->rendstatus & PDRAW_INTERLACE) inc = 4;\r
 #endif\r
-       for(i=8; i; i--, addr+=inc, pd += LINE_WIDTH) {\r
-               pack=*(u32 *)(PicoMem.vram+addr); // Get 8 pixels\r
+       for(i=8; i; i--, addr+=inc, pd += est->Draw2Width) {\r
+               pack=*(u32 *)(vram+addr); // Get 8 pixels\r
                if(!pack) continue;\r
 \r
                t=pack&0x000f0000; if (t) pd[0]=(unsigned char)((t>>16)|pal);\r
@@ -94,17 +96,18 @@ static int TileXflipYnorm(unsigned char *pd,int addr,unsigned char pal, struct P
        return blank; // Tile blank?\r
 }\r
 \r
-static int TileXnormYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)\r
+static int TileXnormYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoEState *est)\r
 {\r
        unsigned int pack=0; unsigned int t=0, blank = 1;\r
+       unsigned short *vram = est->PicoMem_vram;\r
        int i, inc=2;\r
 \r
 #if INTERLACE\r
-       if ((pvid->reg[12]&6) == 6) inc = 4, addr += 16;\r
+       if (est->rendstatus & PDRAW_INTERLACE) inc = 4, addr += 16;\r
 #endif\r
        addr+=14;\r
-       for(i=8; i; i--, addr-=inc, pd += LINE_WIDTH) {\r
-               pack=*(u32 *)(PicoMem.vram+addr); // Get 8 pixels\r
+       for(i=8; i; i--, addr-=inc, pd += est->Draw2Width) {\r
+               pack=*(u32 *)(vram+addr); // Get 8 pixels\r
                if(!pack) continue;\r
 \r
                t=pack&0x0000f000; if (t) pd[0]=(unsigned char)((t>>12)|pal);\r
@@ -121,17 +124,18 @@ static int TileXnormYflip(unsigned char *pd,int addr,unsigned char pal, struct P
        return blank; // Tile blank?\r
 }\r
 \r
-static int TileXflipYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)\r
+static int TileXflipYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoEState *est)\r
 {\r
        unsigned int pack=0; unsigned int t=0, blank = 1;\r
+       unsigned short *vram = est->PicoMem_vram;\r
        int i, inc=2;\r
 \r
 #if INTERLACE\r
-       if ((pvid->reg[12]&6) == 6) inc = 4, addr += 16;\r
+       if (est->rendstatus & PDRAW_INTERLACE) inc = 4, addr += 16;\r
 #endif\r
        addr+=14;\r
-       for(i=8; i; i--, addr-=inc, pd += LINE_WIDTH) {\r
-               pack=*(u32 *)(PicoMem.vram+addr); // Get 8 pixels\r
+       for(i=8; i; i--, addr-=inc, pd += est->Draw2Width) {\r
+               pack=*(u32 *)(vram+addr); // Get 8 pixels\r
                if(!pack) continue;\r
 \r
                t=pack&0x000f0000; if (t) pd[0]=(unsigned char)((t>>16)|pal);\r
@@ -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]\r
 static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)\r
 {\r
-       struct PicoVideo *pvid=&Pico.video;\r
+       struct PicoVideo *pvid=&est->Pico->video;\r
        int nametab, nametab_step, trow, tilex, blank=-1, code;\r
        unsigned char *scrpos = est->Draw2FB;\r
+       int scrstart = est->Draw2Start;\r
        int tile_start, tile_end; // in cells\r
 \r
        // parse ranges\r
@@ -172,17 +177,17 @@ static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
        {\r
                nametab=(pvid->reg[3]&0x3e)<<9; // 32-cell mode\r
                nametab_step = 1<<5;\r
-               if (!(PicoIn.opt&POPT_DIS_32C_BORDER))\r
+               if (est->rendstatus & PDRAW_BORDER_32)\r
                        scrpos += 32;\r
        }\r
-       nametab += nametab_step*start;\r
+       nametab += nametab_step*(start-scrstart);\r
 \r
        // check priority\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
-       scrpos+=8*LINE_WIDTH*(start-START_ROW);\r
+       scrpos+=8*est->Draw2Width+8;\r
+       scrpos+=8*est->Draw2Width*(start-scrstart);\r
 \r
        // do a window until we reach planestart row\r
        for(trow = start; trow < end; trow++, nametab+=nametab_step) { // current tile row\r
@@ -196,21 +201,26 @@ static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
                        if (code==blank) continue;\r
 \r
                        // Get tile address/2:\r
-                       addr=(code&0x7ff)<<4;\r
+#if INTERLACE\r
+                       if (est->rendstatus & PDRAW_INTERLACE)\r
+                               addr=(code&0x3ff)<<5;\r
+                       else\r
+#endif\r
+                               addr=(code&0x7ff)<<4;\r
 \r
 //                     pal=PicoCramHigh+((code>>9)&0x30);\r
                        pal=(unsigned char)((code>>9)&0x30);\r
 \r
                        switch((code>>11)&3) {\r
-                               case 0: zero=TileXnormYnorm(scrpos+(tilex<<3),addr,pal,pvid); break;\r
-                               case 1: zero=TileXflipYnorm(scrpos+(tilex<<3),addr,pal,pvid); break;\r
-                               case 2: zero=TileXnormYflip(scrpos+(tilex<<3),addr,pal,pvid); break;\r
-                               case 3: zero=TileXflipYflip(scrpos+(tilex<<3),addr,pal,pvid); break;\r
+                               case 0: zero=TileXnormYnorm(scrpos+(tilex<<3),addr,pal,est); break;\r
+                               case 1: zero=TileXflipYnorm(scrpos+(tilex<<3),addr,pal,est); break;\r
+                               case 2: zero=TileXnormYflip(scrpos+(tilex<<3),addr,pal,est); break;\r
+                               case 3: zero=TileXflipYflip(scrpos+(tilex<<3),addr,pal,est); break;\r
                        }\r
                        if(zero) blank=code; // We know this tile is blank now\r
                }\r
 \r
-               scrpos += LINE_WIDTH*8;\r
+               scrpos += est->Draw2Width*8;\r
        }\r
 }\r
 \r
@@ -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,\r
                          struct PicoEState *est)\r
 {\r
-       struct PicoVideo *pvid=&Pico.video;\r
+       struct PicoVideo *pvid=&est->Pico->video;\r
        static char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps\r
        int width, height, ymask, htab;\r
        int nametab, hscroll=0, vscroll, cells;\r
        unsigned char *scrpos;\r
+       int scrstart = est->Draw2Start;\r
        int blank=-1, xmask, nametab_row, trow;\r
 \r
        // parse ranges\r
@@ -257,9 +268,9 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
        else          nametab=(pvid->reg[4]&0x07)<<12; // B\r
 \r
        scrpos = est->Draw2FB;\r
-       if (!(pvid->reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
+       if (est->rendstatus & PDRAW_BORDER_32)\r
                scrpos += 32;\r
-       scrpos+=8*LINE_WIDTH*(planestart-START_ROW);\r
+       scrpos+=8*est->Draw2Width*(planestart-scrstart);\r
 \r
        if((pvid->reg[11]&4)||(PicoMem.vsram[plane]&7))\r
                planeend++; // we (may) have vertically clipped tiles due to vscroll, so we need 1 more row\r
@@ -273,7 +284,8 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
                        vscroll=PicoMem.vsram[plane+0x20];//&0x1ff;\r
 #endif\r
 #if INTERLACE\r
-               if ((pvid->reg[12]&6) == 6) vscroll >>= 1;\r
+               if (est->rendstatus & PDRAW_INTERLACE)\r
+                       vscroll >>= 1;\r
 #endif\r
                nametab_row = nametab + (((trow+(vscroll>>3))&ymask)<<shift[width]); // pointer to nametable entries for this row\r
 \r
@@ -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\r
                                vscroll=PicoMem.vsram[vsidx+plane];//&0x1ff;\r
 #if INTERLACE\r
-                               if ((pvid->reg[12]&6) == 6) vscroll >>= 1;\r
+                               if (est->rendstatus & PDRAW_INTERLACE)\r
+                                       vscroll >>= 1;\r
 #endif\r
                                nametab_row = nametab + (((trow+(vscroll>>3))&ymask)<<shift[width]); // pointer to nametable entries for this row\r
                        }\r
@@ -321,26 +334,26 @@ static void DrawLayerFull(int plane, u32 *hcache, int planestart, int planeend,
 \r
                        // Get tile address/2:\r
 #if INTERLACE\r
-               if ((pvid->reg[12]&6) == 6)\r
-                       addr=(code&0x3ff)<<5;\r
-               else\r
+                       if (est->rendstatus & PDRAW_INTERLACE)\r
+                               addr=(code&0x3ff)<<5;\r
+                       else\r
 #endif\r
-                       addr=(code&0x7ff)<<4;\r
+                               addr=(code&0x7ff)<<4;\r
 \r
 //                     pal=PicoCramHigh+((code>>9)&0x30);\r
                        pal=(unsigned char)((code>>9)&0x30);\r
 \r
-                       scroff=(8-(vscroll&7))*LINE_WIDTH;\r
+                       scroff=(8-(vscroll&7))*est->Draw2Width;\r
                        switch((code>>11)&3) {\r
-                               case 0: zero=TileXnormYnorm(scrpos+scroff+dx,addr,pal,pvid); break;\r
-                               case 1: zero=TileXflipYnorm(scrpos+scroff+dx,addr,pal,pvid); break;\r
-                               case 2: zero=TileXnormYflip(scrpos+scroff+dx,addr,pal,pvid); break;\r
-                               case 3: zero=TileXflipYflip(scrpos+scroff+dx,addr,pal,pvid); break;\r
+                               case 0: zero=TileXnormYnorm(scrpos+scroff+dx,addr,pal,est); break;\r
+                               case 1: zero=TileXflipYnorm(scrpos+scroff+dx,addr,pal,est); break;\r
+                               case 2: zero=TileXnormYflip(scrpos+scroff+dx,addr,pal,est); break;\r
+                               case 3: zero=TileXflipYflip(scrpos+scroff+dx,addr,pal,est); break;\r
                        }\r
                        if(zero) blank=code; // We know this tile is blank now\r
                }\r
 \r
-               scrpos += LINE_WIDTH*8;\r
+               scrpos += est->Draw2Width*8;\r
        }\r
 \r
        *hcache = 0; // terminate cache\r
@@ -356,35 +369,36 @@ static void DrawTilesFromCacheF(u32 *hc, struct PicoEState *est)
        unsigned char pal;\r
        short blank=-1; // The tile we know is blank\r
        unsigned char *scrpos = est->Draw2FB, *pd = 0;\r
+       int scrstart = est->Draw2Start;\r
 \r
-       if (!(Pico.video.reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
+       if (est->rendstatus & PDRAW_BORDER_32)\r
                scrpos += 32;\r
 \r
        while((code=*hc++)) {\r
-               vscroll=(*hc++)*LINE_WIDTH - START_ROW*LINE_WIDTH*8;\r
+               vscroll=(*hc++ - START_ROW*8)*est->Draw2Width;\r
                if((short)code == blank) continue;\r
 \r
                // y pos\r
                if(((unsigned)code>>27) != prevy) {\r
                        prevy = (unsigned)code>>27;\r
-                       pd = scrpos + prevy*LINE_WIDTH*8;\r
+                       pd = scrpos + (prevy-scrstart)*est->Draw2Width*8;\r
                }\r
 \r
                // Get tile address/2:\r
 #if INTERLACE\r
-               if ((Pico.video.reg[12]&6) == 6)\r
-               addr=(code&0x3ff)<<5;\r
+               if (est->rendstatus & PDRAW_INTERLACE)\r
+                       addr=(code&0x3ff)<<5;\r
                else\r
 #endif\r
-               addr=(code&0x7ff)<<4;\r
+                       addr=(code&0x7ff)<<4;\r
 //             pal=PicoCramHigh+((code>>9)&0x30);\r
                pal=(unsigned char)((code>>9)&0x30);\r
 \r
                switch((code>>11)&3) {\r
-                       case 0: zero=TileXnormYnorm(pd+vscroll+((code>>16)&0x1ff),addr,pal,&Pico.video); break;\r
-                       case 1: zero=TileXflipYnorm(pd+vscroll+((code>>16)&0x1ff),addr,pal,&Pico.video); break;\r
-                       case 2: zero=TileXnormYflip(pd+vscroll+((code>>16)&0x1ff),addr,pal,&Pico.video); break;\r
-                       case 3: zero=TileXflipYflip(pd+vscroll+((code>>16)&0x1ff),addr,pal,&Pico.video); break;\r
+                       case 0: zero=TileXnormYnorm(pd+vscroll+((code>>16)&0x1ff),addr,pal,est); break;\r
+                       case 1: zero=TileXflipYnorm(pd+vscroll+((code>>16)&0x1ff),addr,pal,est); break;\r
+                       case 2: zero=TileXnormYflip(pd+vscroll+((code>>16)&0x1ff),addr,pal,est); break;\r
+                       case 3: zero=TileXflipYflip(pd+vscroll+((code>>16)&0x1ff),addr,pal,est); break;\r
                }\r
 \r
                if(zero) blank=(short)code;\r
@@ -400,16 +414,17 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
        unsigned char pal;\r
        int tile,code,tdeltax,tdeltay;\r
        unsigned char *scrpos;\r
+       int scrstart = est->Draw2Start;\r
        int sx, sy;\r
 \r
        sy=sprite[0];\r
        height=sy>>24;\r
 #if INTERLACE\r
-       if ((Pico.video.reg[12]&6) == 6)\r
-       sy = ((sy>>1)&0x1ff)-0x78;\r
+       if (est->rendstatus & PDRAW_INTERLACE)\r
+               sy = ((sy>>1)&0x1ff)-0x78;\r
        else\r
 #endif\r
-       sy=(sy&0x1ff)-0x78; // Y\r
+               sy=(sy&0x1ff)-0x78; // Y\r
        width=(height>>2)&3; height&=3;\r
        width++; height++; // Width and height in tiles\r
 \r
@@ -427,19 +442,18 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
        pal=(unsigned char)((code>>9)&0x30);\r
 \r
        // goto first vertically visible tile\r
-       while(sy <= START_ROW*8) { sy+=8; tile+=tdeltay; height--; }\r
+       while(sy <= scrstart*8) { sy+=8; tile+=tdeltay; height--; }\r
 \r
        scrpos = est->Draw2FB;\r
-       if (!(Pico.video.reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
+       if (est->rendstatus&PDRAW_BORDER_32)\r
                scrpos += 32;\r
-       scrpos+=(sy-START_ROW*8)*LINE_WIDTH;\r
+       scrpos+=(sy-scrstart*8)*est->Draw2Width;\r
 \r
        for (; height > 0; height--, sy+=8, tile+=tdeltay)\r
        {\r
-               int w = width, x=sx, t=tile;\r
-               int s=4;\r
+               int w = width, x=sx, t=tile, s;\r
 \r
-               if(sy >= END_ROW*8+8) return; // offscreen\r
+               if((sy-scrstart*8) >= END_ROW*8+8) return; // offscreen\r
 \r
                for (; w; w--,x+=8,t+=tdeltax)\r
                {\r
@@ -448,30 +462,36 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
 \r
                        t&=0x7fff; // Clip tile address\r
 #if INTERLACE\r
-       if ((Pico.video.reg[12]&6) == 6) s=5;\r
+                       if (est->rendstatus & PDRAW_INTERLACE)\r
+                               s=5;\r
+                       else\r
 #endif\r
+                               s=4;\r
                        switch((code>>11)&3) {\r
-                               case 0: TileXnormYnorm(scrpos+x,t<<s,pal,&Pico.video); break;\r
-                               case 1: TileXflipYnorm(scrpos+x,t<<s,pal,&Pico.video); break;\r
-                               case 2: TileXnormYflip(scrpos+x,t<<s,pal,&Pico.video); break;\r
-                               case 3: TileXflipYflip(scrpos+x,t<<s,pal,&Pico.video); break;\r
+                               case 0: TileXnormYnorm(scrpos+x,t<<s,pal,est); break;\r
+                               case 1: TileXflipYnorm(scrpos+x,t<<s,pal,est); break;\r
+                               case 2: TileXnormYflip(scrpos+x,t<<s,pal,est); break;\r
+                               case 3: TileXflipYflip(scrpos+x,t<<s,pal,est); break;\r
                        }\r
                }\r
 \r
-               scrpos+=8*LINE_WIDTH;\r
+               scrpos+=8*est->Draw2Width;\r
        }\r
 }\r
 #endif\r
 \r
 \r
-static void DrawAllSpritesFull(int prio, int maxwidth)\r
+static void DrawAllSpritesFull(int prio, int maxwidth, struct PicoEState *est)\r
 {\r
-       struct PicoVideo *pvid=&Pico.video;\r
+       struct PicoVideo *pvid=&est->Pico->video;\r
        int table=0,maskrange=0;\r
        int i,u,link=0;\r
        unsigned int *sprites[80]; // Sprites\r
        int y_min=START_ROW*8, y_max=END_ROW*8; // for a simple sprite masking\r
-       int max_sprites = Pico.video.reg[12]&1 ? 80 : 64;\r
+       int max_sprites = pvid->reg[12]&1 ? 80 : 64;\r
+\r
+       if (est->rendstatus & PDRAW_30_ROWS)\r
+               y_min += 8, y_max += 8;\r
 \r
        table=pvid->reg[5]&0x7f;\r
        if (pvid->reg[12]&1) table&=0x7e; // Lowest bit 0 in 40-cell mode\r
@@ -489,11 +509,11 @@ static void DrawAllSpritesFull(int prio, int maxwidth)
 \r
                // check if it is not hidden vertically\r
 #if INTERLACE\r
-               if ((pvid->reg[12]&6) == 6)\r
-               sy = ((code>>1)&0x1ff)-0x80;\r
+               if (est->rendstatus & PDRAW_INTERLACE)\r
+                       sy = ((code>>1)&0x1ff)-0x80;\r
                else\r
 #endif\r
-               sy = (code&0x1ff)-0x80;\r
+                       sy = (code&0x1ff)-0x80;\r
                height = (((code>>24)&3)+1)<<3;\r
                if(sy+height <= y_min || sy > y_max) goto nextsprite;\r
 \r
@@ -534,7 +554,7 @@ static void DrawAllSpritesFull(int prio, int maxwidth)
        // Go through sprites backwards:\r
        for (i--; i >= 0; i--)\r
        {\r
-               DrawSpriteFull(sprites[i], &Pico.est);\r
+               DrawSpriteFull(sprites[i], est);\r
        }\r
 }\r
 \r
@@ -548,24 +568,34 @@ static void BackFillFull(void *dst, int reg7)
        back|=back<<8;\r
        back|=back<<16;\r
 \r
-       memset32(dst, back, LINE_WIDTH*(8+(END_ROW-START_ROW)*8)/4);\r
+       memset32(dst, back, Pico.est.Draw2Width*(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
+       struct PicoVideo *pvid=&est->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
-       int winstart=START_ROW, winend=END_ROW;     // same for window\r
+       int scrstart=START_ROW, scrend = END_ROW; // our render area\r
+       int planestart, planeend; // plane A start/end when window shares display with plane A (in tile rows or columns)\r
+       int winstart, winend;     // same for window\r
        int maxw, maxcolc; // max width and col cells\r
 \r
-       if(pvid->reg[12]&1) {\r
-               maxw = 328; maxcolc = 40;\r
-       } else {\r
+       if(est->rendstatus & PDRAW_32_COLS) {\r
                maxw = 264; maxcolc = 32;\r
+       } else {\r
+               maxw = 328; maxcolc = 40;\r
+       }\r
+       if(est->rendstatus & PDRAW_30_ROWS) {\r
+               // In 240 line mode, the top and bottom 8 lines are omitted\r
+               // since this renderer always renderers 224 lines\r
+               scrstart ++, scrend ++;\r
        }\r
+       est->Draw2Start = scrstart;\r
+\r
+       planestart = scrstart, planeend = scrend;\r
+       winstart = scrstart, winend = scrend;\r
 \r
        // 32C border for centering? (for asm)\r
        est->rendstatus &= ~PDRAW_BORDER_32;\r
@@ -582,12 +612,12 @@ static void DrawDisplayFull(void)
                        hvwin=4;\r
                } else if(win < 0x80) {\r
                        // window on the top\r
-                            if(edge <= START_ROW) hvwin=0; // window not visible in our drawing region\r
-                       else if(edge >= END_ROW)   hvwin=4;\r
+                            if(edge <= scrstart) hvwin=0; // window not visible in our drawing region\r
+                       else if(edge >= scrend)   hvwin=4;\r
                        else planestart = winend = edge;\r
                } else if(win > 0x80) {\r
                        // window at the bottom\r
-                       if(edge >= END_ROW) hvwin=0;\r
+                       if(edge >= scrend) hvwin=0;\r
                        else planeend = winstart = edge;\r
                }\r
        }\r
@@ -622,19 +652,19 @@ static void DrawDisplayFull(void)
 \r
        HighCache2A[0] = HighCache2B[0] = 0;\r
        if (!(pvid->debug_p & PVD_KILL_B))\r
-               DrawLayerFull(1, HighCache2B, START_ROW, (maxcolc<<16)|END_ROW, est);\r
+               DrawLayerFull(1, HighCache2B, scrstart, (maxcolc<<16)|scrend, 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, est);\r
+               DrawWindowFull(scrstart, (maxcolc<<16)|scrend, 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, 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
+               DrawWindowFull((winstart&~0xff)|scrstart, (winend&~0xff)|scrend, 0, est);    // v\r
                break;\r
 \r
                case 2:\r
@@ -646,11 +676,11 @@ static void DrawDisplayFull(void)
 \r
                default:\r
                // fullscreen plane A\r
-               DrawLayerFull(0, HighCache2A, START_ROW, (maxcolc<<16)|END_ROW, est);\r
+               DrawLayerFull(0, HighCache2A, scrstart, (maxcolc<<16)|scrend, est);\r
                break;\r
        }\r
        if (!(pvid->debug_p & PVD_KILL_S_LO))\r
-               DrawAllSpritesFull(0, maxw);\r
+               DrawAllSpritesFull(0, maxw, est);\r
 \r
        if (HighCache2B[0]) DrawTilesFromCacheF(HighCache2B, est);\r
        if (HighCache2A[0]) DrawTilesFromCacheF(HighCache2A, est);\r
@@ -658,13 +688,13 @@ static void DrawDisplayFull(void)
        {\r
                case 4:\r
                // fullscreen window\r
-               DrawWindowFull(START_ROW, (maxcolc<<16)|END_ROW, 1, est);\r
+               DrawWindowFull(scrstart, (maxcolc<<16)|scrend, 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, est); // h\r
-               DrawWindowFull((winstart&~0xff)|START_ROW, (winend&~0xff)|END_ROW, 1, est);    // v\r
+               DrawWindowFull((winstart&~0xff)|scrstart, (winend&~0xff)|scrend, 1, est);    // v\r
                break;\r
 \r
                case 2:\r
@@ -674,7 +704,7 @@ static void DrawDisplayFull(void)
                break;\r
        }\r
        if (!(pvid->debug_p & PVD_KILL_S_HI))\r
-               DrawAllSpritesFull(1, maxw);\r
+               DrawAllSpritesFull(1, maxw, est);\r
 }\r
 \r
 \r
@@ -690,18 +720,33 @@ PICO_INTERNAL void PicoFrameFull()
        if (Pico.video.reg[1] & 0x40)\r
                DrawDisplayFull();\r
 \r
+       // clear top and bottom 8 lines in 240 mode, since draw2 only does 224\r
+       if (Pico.est.rendstatus & PDRAW_30_ROWS) {\r
+               unsigned char *pd = Pico.est.Draw2FB;\r
+               int i;\r
+\r
+               for (i = 8; i > 0; i--, pd += Pico.est.Draw2Width)\r
+                       memset32((int *)pd, 0xe0e0e0e0, 328/4);\r
+               pd += Pico.est.Draw2Width*(END_ROW-START_ROW)*8;\r
+               for (i = 8; i > 0; i--, pd += Pico.est.Draw2Width)\r
+                       memset32((int *)pd, 0xe0e0e0e0, 328/4);\r
+       }\r
+\r
        pprof_end(draw);\r
 }\r
 \r
-void PicoDraw2SetOutBuf(void *dest)\r
+void PicoDraw2SetOutBuf(void *dest, int incr)\r
 {\r
-       if (dest)\r
+       if (dest) {\r
                Pico.est.Draw2FB = dest;\r
-       else\r
+               Pico.est.Draw2Width = incr;\r
+       } else {\r
                Pico.est.Draw2FB = PicoDraw2FB_;\r
+               Pico.est.Draw2Width = LINE_WIDTH;\r
+       }\r
 }\r
 \r
 void PicoDraw2Init(void)\r
 {\r
-       PicoDraw2SetOutBuf(NULL);\r
+       PicoDraw2SetOutBuf(NULL, 0);\r
 }\r
index 92d3397..b75a014 100644 (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\r
 #define PDRAW_PLANE_HI_PRIO (1<<6) // have layer with all hi prio tiles (mk3)\r
 #define PDRAW_SHHI_DONE     (1<<7) // layer sh/hi already processed\r
-#define PDRAW_32_COLS       (1<<8) // 32 column mode\r
+#define PDRAW_32_COLS       (1<<8) // 32 columns mode\r
 #define PDRAW_BORDER_32     (1<<9) // center H32 in buffer (32 px border)\r
 #define PDRAW_SKIP_FRAME   (1<<10) // frame is skipped\r
+#define PDRAW_30_ROWS      (1<<11) // 30 rows mode (240 lines)\r
 extern int rendstatus_old;\r
 extern int rendlines;\r
 \r
index ce20d1e..d66b67e 100644 (file)
@@ -359,6 +359,8 @@ struct PicoEState
   void *PicoMem_cram;\r
   unsigned int  *PicoOpt;\r
   unsigned char *Draw2FB;\r
+  int Draw2Width;\r
+  int Draw2Start;\r
   unsigned short HighPal[0x100];\r
   unsigned short SonicPal[0x100];\r
   int SonicPalCount;\r
@@ -673,7 +675,7 @@ extern int DrawLineDestIncrement;
 extern u32 VdpSATCache[128];\r
 \r
 // draw2.c\r
-void PicoDraw2SetOutBuf(void *dest);\r
+void PicoDraw2SetOutBuf(void *dest, int incr);\r
 void PicoDraw2Init(void);\r
 PICO_INTERNAL void PicoFrameFull();\r
 \r