vdp, test code for 8 bit fast renderer
authorkub <derkub@gmail.com>
Thu, 17 Sep 2020 22:02:45 +0000 (00:02 +0200)
committerkub <derkub@gmail.com>
Thu, 17 Sep 2020 22:27:41 +0000 (00:27 +0200)
pico/32x/draw.c
pico/draw2.c
platform/linux/emu.c

index 45c2726..991abae 100644 (file)
@@ -330,7 +330,7 @@ void PicoDrawSetOutFormat32x(pdso_t which, int use_32x_line_mode)
   } else {
     // use the same layout as alt renderer
     PicoDrawSetInternalBuf(NULL, 0);
-    PicoDrawSetOutBufMD(Pico.est.Draw2FB + 8, 328);
+    PicoDrawSetOutBufMD(Pico.est.Draw2FB, 328);
   }
 
   if (use_32x_line_mode)
index 9106977..e254952 100644 (file)
@@ -11,6 +11,9 @@
 #define START_ROW  0 // which row of tiles to start rendering at?\r
 #define END_ROW   28 // ..end\r
 \r
+#define VSRAM      0 // 2-cell vscroll (broken for line based hscroll)\r
+#define INTERLACE  0 // interlace mode 2\r
+\r
 #define TILE_ROWS END_ROW-START_ROW\r
 \r
 // note: this is not implemented in ARM asm\r
@@ -22,8 +25,8 @@
 \r
 static unsigned char PicoDraw2FB_[(8+320) * (8+240+8) + 8];\r
 \r
-static int HighCache2A[41*(TILE_ROWS+1)+1+1]; // caches for high layers\r
-static int HighCache2B[41*(TILE_ROWS+1)+1+1];\r
+static int HighCache2A[2*41*(TILE_ROWS+1)+1+1]; // caches for high layers\r
+static int HighCache2B[2*41*(TILE_ROWS+1)+1+1];\r
 \r
 unsigned short *PicoCramHigh=PicoMem.cram; // pointer to CRAM buff (0x40 shorts), converted to native device color (works only with 16bit for now)\r
 void (*PicoPrepareCram)()=0;            // prepares PicoCramHigh for renderer to use\r
@@ -40,12 +43,15 @@ void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est);
 #else\r
 \r
 \r
-static int TileXnormYnorm(unsigned char *pd,int addr,unsigned char pal)\r
+static int TileXnormYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)\r
 {\r
        unsigned int pack=0; unsigned int t=0, blank = 1;\r
-       int i;\r
+       int i, inc=2;\r
 \r
-       for(i=8; i; i--, addr+=2, pd += LINE_WIDTH) {\r
+#if INTERLACE\r
+       if ((pvid->reg[12]&6) == 6) inc = 4;\r
+#endif\r
+       for(i=8; i; i--, addr+=inc, pd += LINE_WIDTH) {\r
                pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
                if(!pack) continue;\r
 \r
@@ -63,12 +69,15 @@ static int TileXnormYnorm(unsigned char *pd,int addr,unsigned char pal)
        return blank; // Tile blank?\r
 }\r
 \r
-static int TileXflipYnorm(unsigned char *pd,int addr,unsigned char pal)\r
+static int TileXflipYnorm(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)\r
 {\r
        unsigned int pack=0; unsigned int t=0, blank = 1;\r
-       int i;\r
+       int i, inc=2;\r
 \r
-       for(i=8; i; i--, addr+=2, pd += LINE_WIDTH) {\r
+#if INTERLACE\r
+       if ((pvid->reg[12]&6) == 6) inc = 4;\r
+#endif\r
+       for(i=8; i; i--, addr+=inc, pd += LINE_WIDTH) {\r
                pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
                if(!pack) continue;\r
 \r
@@ -85,13 +94,16 @@ static int TileXflipYnorm(unsigned char *pd,int addr,unsigned char pal)
        return blank; // Tile blank?\r
 }\r
 \r
-static int TileXnormYflip(unsigned char *pd,int addr,unsigned char pal)\r
+static int TileXnormYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)\r
 {\r
        unsigned int pack=0; unsigned int t=0, blank = 1;\r
-       int i;\r
+       int i, inc=2;\r
 \r
+#if INTERLACE\r
+       if ((pvid->reg[12]&6) == 6) inc = 4, addr += 16;\r
+#endif\r
        addr+=14;\r
-       for(i=8; i; i--, addr-=2, pd += LINE_WIDTH) {\r
+       for(i=8; i; i--, addr-=inc, pd += LINE_WIDTH) {\r
                pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
                if(!pack) continue;\r
 \r
@@ -109,13 +121,16 @@ static int TileXnormYflip(unsigned char *pd,int addr,unsigned char pal)
        return blank; // Tile blank?\r
 }\r
 \r
-static int TileXflipYflip(unsigned char *pd,int addr,unsigned char pal)\r
+static int TileXflipYflip(unsigned char *pd,int addr,unsigned char pal, struct PicoVideo *pvid)\r
 {\r
        unsigned int pack=0; unsigned int t=0, blank = 1;\r
-       int i;\r
+       int i, inc=2;\r
 \r
+#if INTERLACE\r
+       if ((pvid->reg[12]&6) == 6) inc = 4, addr += 16;\r
+#endif\r
        addr+=14;\r
-       for(i=8; i; i--, addr-=2, pd += LINE_WIDTH) {\r
+       for(i=8; i; i--, addr-=inc, pd += LINE_WIDTH) {\r
                pack=*(unsigned int *)(PicoMem.vram+addr); // Get 8 pixels\r
                if(!pack) continue;\r
 \r
@@ -187,10 +202,10 @@ static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
                        pal=(unsigned char)((code>>9)&0x30);\r
 \r
                        switch((code>>11)&3) {\r
-                               case 0: zero=TileXnormYnorm(scrpos+(tilex<<3),addr,pal); break;\r
-                               case 1: zero=TileXflipYnorm(scrpos+(tilex<<3),addr,pal); break;\r
-                               case 2: zero=TileXnormYflip(scrpos+(tilex<<3),addr,pal); break;\r
-                               case 3: zero=TileXflipYflip(scrpos+(tilex<<3),addr,pal); break;\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
                        }\r
                        if(zero) blank=code; // We know this tile is blank now\r
                }\r
@@ -204,7 +219,7 @@ static void DrawLayerFull(int plane, int *hcache, int planestart, int planeend,
                          struct PicoEState *est)\r
 {\r
        struct PicoVideo *pvid=&Pico.video;\r
-       static char shift[4]={5,6,6,7}; // 32,64 or 128 sized tilemaps\r
+       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
@@ -246,21 +261,25 @@ static void DrawLayerFull(int plane, int *hcache, int planestart, int planeend,
                scrpos += 32;\r
        scrpos+=8*LINE_WIDTH*(planestart-START_ROW);\r
 \r
-       // Get vertical scroll value:\r
-       vscroll=PicoMem.vsram[plane]&0x1ff;\r
-       scrpos+=(8-(vscroll&7))*LINE_WIDTH;\r
-       if(vscroll&7) planeend++; // we have vertically clipped tiles due to vscroll, so we need 1 more row\r
-\r
-       *hcache++ = 8-(vscroll&7); // push y-offset to tilecache\r
-\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
        for(trow = planestart; trow < planeend; trow++) { // current tile row\r
-               int cellc=cells,tilex,dx;\r
+               int cellc=cells,tilex,dx,vsidx=0;\r
+\r
+               // Get vertical scroll value:\r
+               vscroll=PicoMem.vsram[plane];//&0x1ff;\r
+#if VSRAM\r
+               if (!(pvid->reg[12]&1) && (pvid->reg[11]&4)) // H32 + 2-cell mode\r
+                       vscroll=PicoMem.vsram[plane+0x20];//&0x1ff;\r
+#endif\r
+#if INTERLACE\r
+               if ((pvid->reg[12]&6) == 6) vscroll >>= 1;\r
+#endif\r
+               nametab_row = nametab + (((trow+(vscroll>>3))&ymask)<<shift[width]); // pointer to nametable entries for this row\r
 \r
                // Find the tile row in the name table\r
                //ts.line=(vscroll+Scanline)&ymask;\r
                //ts.nametab+=(ts.line>>3)<<shift[width];\r
-               nametab_row = nametab + (((trow+(vscroll>>3))&ymask)<<shift[width]); // pointer to nametable entries for this row\r
 \r
                // update hscroll if needed\r
                if(htab) {\r
@@ -272,33 +291,51 @@ static void DrawLayerFull(int plane, int *hcache, int planestart, int planeend,
                // Draw tiles across screen:\r
                tilex=(-hscroll)>>3;\r
                dx=((hscroll-1)&7)+1;\r
-               if(dx != 8) cellc++; // have hscroll, do more cells\r
+               if(dx != 8) cellc++, vsidx--; // have hscroll, do more cells\r
 \r
                for (; cellc; dx+=8,tilex++,cellc--)\r
                {\r
-                       int code=0,addr=0,zero=0;\r
+                       int code=0,addr=0,zero=0,scroff;\r
 //                     unsigned short *pal=NULL;\r
                        unsigned char pal;\r
 \r
+#if VSRAM\r
+                       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
+#endif\r
+                               nametab_row = nametab + (((trow+(vscroll>>3))&ymask)<<shift[width]); // pointer to nametable entries for this row\r
+                       }\r
+#endif\r
+                       vsidx++;\r
+\r
                        code=PicoMem.vram[nametab_row+(tilex&xmask)];\r
                        if (code==blank) continue;\r
 \r
                        if (code>>15) { // high priority tile\r
                                *hcache++ = code|(dx<<16)|(trow<<27); // cache it\r
+                               *hcache++ = 8-(vscroll&7); // push y-offset to tilecache\r
                                continue;\r
                        }\r
 \r
                        // Get tile address/2:\r
+#if INTERLACE\r
+               if ((pvid->reg[12]&6) == 6)\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
+                       scroff=(8-(vscroll&7))*LINE_WIDTH;\r
                        switch((code>>11)&3) {\r
-                               case 0: zero=TileXnormYnorm(scrpos+dx,addr,pal); break;\r
-                               case 1: zero=TileXflipYnorm(scrpos+dx,addr,pal); break;\r
-                               case 2: zero=TileXnormYflip(scrpos+dx,addr,pal); break;\r
-                               case 3: zero=TileXflipYflip(scrpos+dx,addr,pal); break;\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
                        }\r
                        if(zero) blank=code; // We know this tile is blank now\r
                }\r
@@ -312,7 +349,7 @@ static void DrawLayerFull(int plane, int *hcache, int planestart, int planeend,
 \r
 static void DrawTilesFromCacheF(int *hc, struct PicoEState *est)\r
 {\r
-       int code, addr, zero = 0;\r
+       int code, addr, zero = 0, vscroll;\r
        unsigned int prevy=0xFFFFFFFF;\r
 //     unsigned short *pal;\r
        unsigned char pal;\r
@@ -321,10 +358,9 @@ static void DrawTilesFromCacheF(int *hc, struct PicoEState *est)
 \r
        if (!(Pico.video.reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
                scrpos += 32;\r
-       // *hcache++ = code|(dx<<16)|(trow<<27); // cache it\r
-       scrpos+=(*hc++)*LINE_WIDTH - START_ROW*LINE_WIDTH*8;\r
 \r
        while((code=*hc++)) {\r
+               vscroll=(*hc++)*LINE_WIDTH - START_ROW*LINE_WIDTH*8;\r
                if((short)code == blank) continue;\r
 \r
                // y pos\r
@@ -334,15 +370,20 @@ static void DrawTilesFromCacheF(int *hc, struct PicoEState *est)
                }\r
 \r
                // Get tile address/2:\r
+#if INTERLACE\r
+               if ((Pico.video.reg[12]&6) == 6)\r
+               addr=(code&0x3ff)<<5;\r
+               else\r
+#endif\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+((code>>16)&0x1ff),addr,pal); break;\r
-                       case 1: zero=TileXflipYnorm(pd+((code>>16)&0x1ff),addr,pal); break;\r
-                       case 2: zero=TileXnormYflip(pd+((code>>16)&0x1ff),addr,pal); break;\r
-                       case 3: zero=TileXflipYflip(pd+((code>>16)&0x1ff),addr,pal); break;\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
                }\r
 \r
                if(zero) blank=(short)code;\r
@@ -362,6 +403,11 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
 \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
+       else\r
+#endif\r
        sy=(sy&0x1ff)-0x78; // Y\r
        width=(height>>2)&3; height&=3;\r
        width++; height++; // Width and height in tiles\r
@@ -372,8 +418,8 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
        tile=code&0x7ff; // Tile number\r
        tdeltax=height; // Delta to increase tile by going right\r
        tdeltay=1;      // Delta to increase tile by going down\r
-       if (code&0x0800) { tdeltax=-tdeltax; tile+=height*(width-1); } // Flip X\r
-       if (code&0x1000) { tdeltay=-tdeltay; tile+=height-1; } // Flip Y\r
+       if (code&0x1000) { tile+=tdeltax-1; tdeltay=-tdeltay; } // Flip Y\r
+       if (code&0x0800) { tile+=tdeltax*(width-1); tdeltax=-tdeltax; } // Flip X\r
 \r
        //delta<<=4; // Delta of address\r
 //     pal=PicoCramHigh+((code>>9)&0x30); // Get palette pointer\r
@@ -390,6 +436,7 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
        for (; height > 0; height--, sy+=8, tile+=tdeltay)\r
        {\r
                int w = width, x=sx, t=tile;\r
+               int s=4;\r
 \r
                if(sy >= END_ROW*8+8) return; // offscreen\r
 \r
@@ -399,11 +446,14 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
                        if(x>=328) break; // Offscreen\r
 \r
                        t&=0x7fff; // Clip tile address\r
+#if INTERLACE\r
+       if ((Pico.video.reg[12]&6) == 6) s=5;\r
+#endif\r
                        switch((code>>11)&3) {\r
-                               case 0: TileXnormYnorm(scrpos+x,t<<4,pal); break;\r
-                               case 1: TileXflipYnorm(scrpos+x,t<<4,pal); break;\r
-                               case 2: TileXnormYflip(scrpos+x,t<<4,pal); break;\r
-                               case 3: TileXflipYflip(scrpos+x,t<<4,pal); break;\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
                        }\r
                }\r
 \r
@@ -437,6 +487,11 @@ static void DrawAllSpritesFull(int prio, int maxwidth)
                code = sprite[0];\r
 \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
+               else\r
+#endif\r
                sy = (code&0x1ff)-0x80;\r
                height = (((code>>24)&3)+1)<<3;\r
                if(sy+height <= y_min || sy > y_max) goto nextsprite;\r
@@ -564,7 +619,7 @@ static void DrawDisplayFull(void)
 \r
        if (hvwin==1) { winend|=maxcolc<<16; planeend|=maxcolc<<16; }\r
 \r
-       HighCache2A[1] = HighCache2B[1] = 0;\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
        if (!(pvid->debug_p & PVD_KILL_A)) switch (hvwin)\r
@@ -596,8 +651,8 @@ static void DrawDisplayFull(void)
        if (!(pvid->debug_p & PVD_KILL_S_LO))\r
                DrawAllSpritesFull(0, maxw);\r
 \r
-       if (HighCache2B[1]) DrawTilesFromCacheF(HighCache2B, est);\r
-       if (HighCache2A[1]) DrawTilesFromCacheF(HighCache2A, est);\r
+       if (HighCache2B[0]) DrawTilesFromCacheF(HighCache2B, est);\r
+       if (HighCache2A[0]) DrawTilesFromCacheF(HighCache2A, est);\r
        if (!(pvid->debug_p & PVD_KILL_A)) switch (hvwin)\r
        {\r
                case 4:\r
index 8c86471..beeab37 100644 (file)
@@ -73,7 +73,7 @@ void pemu_finalize_frame(const char *fps, const char *notice)
 {\r
        if (currentConfig.renderer != RT_16BIT && !(PicoIn.AHW & PAHW_32X)) {\r
                unsigned short *pd = (unsigned short *)g_screen_ptr + out_y * g_screen_ppitch + out_x;\r
-               unsigned char *ps = Pico.est.Draw2FB + 328*out_y + out_x + 8;\r
+               unsigned char *ps = Pico.est.Draw2FB + 328*out_y + 8; //+ out_x;\r
                unsigned short *pal = Pico.est.HighPal;\r
                int i, x;\r
 \r
@@ -101,16 +101,19 @@ static void apply_renderer(void)
        switch (currentConfig.renderer) {\r
        case RT_16BIT:\r
                PicoIn.opt &= ~POPT_ALT_RENDERER;\r
+               PicoIn.opt &= ~POPT_DIS_32C_BORDER;\r
                PicoDrawSetOutFormat(PDF_RGB555, 0);\r
                PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch * 2);\r
                break;\r
        case RT_8BIT_ACC:\r
                PicoIn.opt &= ~POPT_ALT_RENDERER;\r
+               PicoIn.opt |=  POPT_DIS_32C_BORDER;\r
                PicoDrawSetOutFormat(PDF_8BIT, 0);\r
                PicoDrawSetOutBuf(Pico.est.Draw2FB, 328);\r
                break;\r
        case RT_8BIT_FAST:\r
                PicoIn.opt |=  POPT_ALT_RENDERER;\r
+               PicoIn.opt |=  POPT_DIS_32C_BORDER;\r
                PicoDrawSetOutFormat(PDF_NONE, 0);\r
                break;\r
        }\r
@@ -163,6 +166,7 @@ void plat_update_volume(int has_changed, int is_up)
 \r
 void pemu_forced_frame(int no_scale, int do_emu)\r
 {\r
+       PicoIn.opt &= ~POPT_DIS_32C_BORDER;\r
        PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch * 2);\r
        PicoDrawSetCallbacks(NULL, NULL);\r
        Pico.m.dirtyPal = 1;\r