X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=Pico%2FDraw.c;h=6f60a03a62ac45ae96ca1b9b0db708ec102a88ed;hb=dca310c413517d278898b967cfe610574310acd8;hp=9d7e9bc5f2ccd372e19538f0e5ae475459e4c120;hpb=83c093a48ab58670ea82d0ec81658daa9f9b950a;p=picodrive.git diff --git a/Pico/Draw.c b/Pico/Draw.c index 9d7e9bc..6f60a03 100644 --- a/Pico/Draw.c +++ b/Pico/Draw.c @@ -8,14 +8,18 @@ #include "PicoInt.h" -#ifndef __GNUC__ -#pragma warning (disable:4706) // Disable assignment within conditional -#endif int (*PicoScan)(unsigned int num, void *data)=NULL; -unsigned short DefOutBuff[320*2]; +#if OVERRIDE_HIGHCOL +static unsigned char DefHighCol[8+320+8]; +unsigned char *HighCol=DefHighCol; +#else unsigned char HighCol[8+320+8]; +#endif +unsigned short DefOutBuff[320*2]; +void *DrawLineDest=DefOutBuff; // pointer to dest buffer where to draw this line to + static int HighCacheA[41+1]; // caches for high layers static int HighCacheB[41+1]; static int HighCacheS[80+1]; // and sprites @@ -25,7 +29,6 @@ char HighSprZ[320+8+8]; // Z-buffer for accurate sprites and shadow/hilight mode // lsb->msb: moved sprites, not all window tiles use same priority, accurate sprites (copied from PicoOpt), interlace // dirty sprites, sonic mode, have layer with all hi prio tiles (mk3), layer sh/hi already processed int rendstatus; -void *DrawLineDest=DefOutBuff; // pointer to dest buffer where to draw this line to int Scanline=0; // Scanline static int SpriteBlocks; @@ -63,6 +66,10 @@ void blockcpy_or(void *dst, void *src, size_t n, int pat) #endif +#ifdef _ASM_DRAW_C_AMIPS +int TileNorm(int sx,int addr,int pal); +int TileFlip(int sx,int addr,int pal); +#else static int TileNorm(int sx,int addr,int pal) { unsigned char *pd = HighCol+sx; @@ -105,7 +112,7 @@ static int TileFlip(int sx,int addr,int pal) } return 1; // Tile blank } - +#endif // tile renderers for hacky operator sprite support #define sh_pix(x) \ @@ -528,22 +535,49 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache } // Draw tiles across screen: - for (; tilex < tend; tilex++) + if (!sh) { - int addr=0,zero=0; - int pal; + for (; tilex < tend; tilex++) + { + int addr=0,zero=0; + int pal; + + code=Pico.vram[nametab+tilex]; + if(code==blank) continue; + if((code>>15) != prio) { + rendstatus|=2; + continue; + } - code=Pico.vram[nametab+tilex]; - if(code==blank) continue; - if((code>>15) != prio) { - rendstatus|=2; - continue; + pal=((code>>9)&0x30); + + // Get tile address/2: + addr=(code&0x7ff)<<4; + if (code&0x1000) addr+=14-ty; else addr+=ty; // Y-flip + + if (code&0x0800) zero=TileFlip(8+(tilex<<3),addr,pal); + else zero=TileNorm(8+(tilex<<3),addr,pal); + + if (zero) blank=code; // We know this tile is blank now } + } + else + { + for (; tilex < tend; tilex++) + { + int addr=0,zero=0; + int pal, tmp, *zb; + + code=Pico.vram[nametab+tilex]; + if(code==blank) continue; + if((code>>15) != prio) { + rendstatus|=2; + continue; + } - pal=((code>>9)&0x30); + pal=((code>>9)&0x30); - if(sh) { - int tmp, *zb = (int *)(HighCol+8+(tilex<<3)); + zb = (int *)(HighCol+8+(tilex<<3)); if(prio) { tmp = *zb; if(!(tmp&0x00000080)) tmp&=~0x000000c0; if(!(tmp&0x00008000)) tmp&=~0x0000c000; @@ -555,24 +589,43 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache } else { pal |= 0x40; } - } - // Get tile address/2: - addr=(code&0x7ff)<<4; - if (code&0x1000) addr+=14-ty; else addr+=ty; // Y-flip + // Get tile address/2: + addr=(code&0x7ff)<<4; + if (code&0x1000) addr+=14-ty; else addr+=ty; // Y-flip - if (code&0x0800) zero=TileFlip(8+(tilex<<3),addr,pal); - else zero=TileNorm(8+(tilex<<3),addr,pal); + if (code&0x0800) zero=TileFlip(8+(tilex<<3),addr,pal); + else zero=TileNorm(8+(tilex<<3),addr,pal); - if (zero) blank=code; // We know this tile is blank now + if (zero) blank=code; // We know this tile is blank now + } } - - // terminate the cache list - //*hcache = 0; } // -------------------------------------------- +static void DrawTilesFromCacheShPrep(void) +{ + if (!(rendstatus&0x80)) + { + // as some layer has covered whole line with hi priority tiles, + // we can process whole line and then act as if sh/hi mode was off. + int c = 320/4, *zb = (int *)(HighCol+8); + rendstatus|=0x80; + while (c--) + { + int tmp = *zb; + if (!(tmp & 0x80808080)) *zb=tmp&0x3f3f3f3f; + else { + if(!(tmp&0x00000080)) tmp&=~0x000000c0; if(!(tmp&0x00008000)) tmp&=~0x0000c000; + if(!(tmp&0x00800000)) tmp&=~0x00c00000; if(!(tmp&0x80000000)) tmp&=~0xc0000000; + *zb=tmp; + } + zb++; + } + } +} + static void DrawTilesFromCache(int *hc, int sh, int rlim) { int code, addr, dx; @@ -582,66 +635,49 @@ static void DrawTilesFromCache(int *hc, int sh, int rlim) if (sh && (rendstatus&0xc0)) { - if (!(rendstatus&0x80)) - { - // as some layer has covered whole line with hi priority tiles, - // we can process whole line and then act as if sh/hi mode was off. - rendstatus|=0x80; - int c = 320/4, *zb = (int *)(HighCol+8); - while (c--) - { - int tmp = *zb; - if (!(tmp & 0x80808080)) *zb=tmp&0x3f3f3f3f; - else { - if(!(tmp&0x00000080)) tmp&=~0x000000c0; if(!(tmp&0x00008000)) tmp&=~0x0000c000; - if(!(tmp&0x00800000)) tmp&=~0x00c00000; if(!(tmp&0x80000000)) tmp&=~0xc0000000; - *zb=tmp; - } - zb++; - } - } + DrawTilesFromCacheShPrep(); sh = 0; } - if (sh) + if (!sh) { + short blank=-1; // The tile we know is blank while ((code=*hc++)) { - unsigned char *zb; + int zero; + if((short)code == blank) continue; // Get tile address/2: addr=(code&0x7ff)<<4; addr+=(unsigned int)code>>25; // y offset into tile dx=(code>>16)&0x1ff; - zb = HighCol+dx; - if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++; - if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++; - if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++; - if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++; pal=((code>>9)&0x30); if (rlim-dx < 0) goto last_cut_tile; - if (code&0x0800) TileFlip(dx,addr,pal); - else TileNorm(dx,addr,pal); + if (code&0x0800) zero=TileFlip(dx,addr,pal); + else zero=TileNorm(dx,addr,pal); + + if (zero) blank=(short)code; } } else { - short blank=-1; // The tile we know is blank while ((code=*hc++)) { - int zero; - if((short)code == blank) continue; + unsigned char *zb; // Get tile address/2: addr=(code&0x7ff)<<4; addr+=(unsigned int)code>>25; // y offset into tile dx=(code>>16)&0x1ff; + zb = HighCol+dx; + if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++; + if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++; + if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++; + if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++; pal=((code>>9)&0x30); if (rlim-dx < 0) goto last_cut_tile; - if (code&0x0800) zero=TileFlip(dx,addr,pal); - else zero=TileNorm(dx,addr,pal); - - if (zero) blank=(short)code; + if (code&0x0800) TileFlip(dx,addr,pal); + else TileNorm(dx,addr,pal); } } return; @@ -1120,8 +1156,7 @@ static void DrawAllSprites(int *hcache, int maxwidth, int prio, int sh) #ifndef _ASM_DRAW_C static void BackFill(int reg7, int sh) { - unsigned int back=0; - unsigned int *pd=NULL,*end=NULL; + unsigned int back; // Start with a blank scanline (background colour): back=reg7&0x3f; @@ -1129,10 +1164,7 @@ static void BackFill(int reg7, int sh) back|=back<<8; back|=back<<16; - pd= (unsigned int *)(HighCol+8); - end=(unsigned int *)(HighCol+8+320); - - do { pd[0]=pd[1]=pd[2]=pd[3]=back; pd+=4; } while (pd= 0; i--) - pal[i] = (unsigned short) (((ppal[i]&0x00f)<<12)|((ppal[i]&0x0f0)<<3)|((ppal[i]&0xf00)>>7)); + if (dirtyPal) + { + unsigned int *spal=(void *)Pico.cram; + unsigned int *dpal=(void *)HighPal; + for (i = 0x3f/2; i >= 0; i--) +#ifdef USE_BGR555 + dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4); +#else + dpal[i] = ((spal[i]&0x000f000f)<<12)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)>>7); +#endif Pico.m.dirtyPal = 0; } - if (Pico.video.reg[12]&1) { - len = 320; - } else { - if(!(PicoOpt&0x100)) pd+=32; - len = 256; - } - - if(sh) { - if(dirtyPal) { + if (sh) + { + if (dirtyPal) { // shadowed pixels - for(i = 0x3f; i >= 0; i--) + for (i = 0x3f; i >= 0; i--) pal[0x40|i] = pal[0xc0|i] = (unsigned short)((pal[i]>>1)&0x738e); // hilighted pixels - for(i = 0x3f; i >= 0; i--) { + for (i = 0x3f; i >= 0; i--) { t=pal[i]&0xe71c;t+=0x4208;if(t&0x20)t|=0x1c;if(t&0x800)t|=0x700;if(t&0x10000)t|=0xe000;t&=0xe71c; pal[0x80|i]=(unsigned short)t; } } } - for(i = 0; i < len; i++) + if (Pico.video.reg[12]&1) { + len = 320; + } else { + if (!(PicoOpt&0x100)) pd+=32; + len = 256; + } + +#ifndef PSP + for (i = 0; i < len; i++) pd[i] = pal[ps[i]]; +#else + { + extern void amips_clut(unsigned short *dst, unsigned char *src, unsigned short *pal, int count); + amips_clut(pd, ps, pal, len); + } +#endif } #endif @@ -1253,7 +1299,7 @@ static void FinalizeLine8bit(int sh) } } -void (*FinalizeLine)(int sh) = FinalizeLineBGR444; +static void (*FinalizeLine)(int sh) = FinalizeLineBGR444; // -------------------------------------------- @@ -1354,8 +1400,8 @@ PICO_INTERNAL int PicoLine(int scan) if (Pico.video.reg[1]&0x40) DrawDisplay(sh); - FinalizeLine(sh); - //if (SpriteBlocks & (1<<(scan>>3))) for (sh=0; sh < 30; sh++) DrawLineDest[sh] = 0xf; + if (FinalizeLine != NULL) + FinalizeLine(sh); Skip=PicoScan(Scanline,DrawLineDest); @@ -1365,9 +1411,15 @@ PICO_INTERNAL int PicoLine(int scan) void PicoDrawSetColorFormat(int which) { - if (which == 2) - FinalizeLine = FinalizeLine8bit; - else if (which == 1) - FinalizeLine = FinalizeLineRGB555; - else FinalizeLine = FinalizeLineBGR444; + switch (which) + { + case 2: FinalizeLine = FinalizeLine8bit; break; + case 1: FinalizeLine = FinalizeLineRGB555; break; + case 0: FinalizeLine = FinalizeLineBGR444; break; + default:FinalizeLine = NULL; break; + } +#if OVERRIDE_HIGHCOL + if (which) HighCol=DefHighCol; +#endif } +