X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=fceu.git;a=blobdiff_plain;f=ppu.c;h=d2ea4494001db36bbda109c3cc82a8de51f88eee;hp=0f2a47fea9a6bb41aa7755a787a8c7fc7b99ba4b;hb=9115e7d2b5e5b8dc00774fe92db97f1d02b2fee1;hpb=4a1bf31bcd80812fe491d3255646e43c304116b9 diff --git a/ppu.c b/ppu.c index 0f2a47f..d2ea449 100644 --- a/ppu.c +++ b/ppu.c @@ -36,7 +36,7 @@ uint8 SPRAM[0x100]; static uint8 SPRBUF[0x100]; -static uint8 sprlinebuf[256+8]; +static uint8 sprlinebuf[256+8]; extern void BGRender(uint8 *target); extern int tosprite; @@ -56,10 +56,10 @@ typedef struct { } SPR __attribute__((aligned(1))); typedef struct { - // uint8 ca[2],atr,x; - uint8 ca[2],atr,x; + // uint8 ca[2],atr,x; + uint8 ca[2],atr,x; // union { int z; } - + } SPRB __attribute__((aligned(1))); @@ -120,7 +120,7 @@ void FetchSpriteData(void) if(MMC5Hack && geniestage!=1) C = MMC5SPRVRAMADR(vadr); else C = VRAMADR(vadr); - + dst.ca[0]=C[0]; dst.ca[1]=C[8]; dst.x=spr->x; @@ -202,9 +202,8 @@ extern int FSkip; void RefreshSprite(uint8 *target) { - int n; + int n, minx=256; SPRB *spr; - uint8 *P=target; if(!nosprites) return; #ifdef FRAMESKIP @@ -220,29 +219,30 @@ void RefreshSprite(uint8 *target) } #endif - FCEU_dwmemset(sprlinebuf,0x80808080,256); nosprites--; spr = (SPRB*)SPRBUF+nosprites; for(n=nosprites;n>=0;n--,spr--) { - register uint8 J,atr,c1,c2; - int x=spr->x; - uint8 *C; - uint8 *VB; - - P+=x; - - c1=((spr->ca[0]>>1)&0x55)|(spr->ca[1]&0xAA); - c2=(spr->ca[0]&0x55)|((spr->ca[1]<<1)&0xAA); + register uint32 J; J=spr->ca[0]|spr->ca[1]; - atr=spr->atr; - if(J) - { + if (J) + { + register uint8 atr,c1,c2; + uint8 *C; + uint8 *VB; + int x=spr->x; + atr=spr->atr; + + if (x < minx) + { + if (minx == 256) FCEU_dwmemset(sprlinebuf,0x80808080,256); // only clear sprite buff when we encounter first sprite + minx = x; + } if(n==0 && SpriteBlurp && !(PPU_status&0x40)) - { + { int z,ze=x+8; if(ze>256) {ze=256;} if(ScreenON && (scanlineFSettings.LastSLine @@ -277,113 +277,77 @@ void RefreshSprite(uint8 *target) //FCEU_DispMessage("%d, %d:%d",scanline,x,tosprite); } + c1=((spr->ca[0]>>1)&0x55)|(spr->ca[1]&0xAA); + c2=(spr->ca[0]&0x55)|((spr->ca[1]<<1)&0xAA); + C = sprlinebuf+x; VB = (PALRAM+0x10)+((atr&3)<<2); - if(atr&SP_BACK) { + J &= 0xff; + if(atr&SP_BACK) J |= 0x4000; if (atr&H_FLIP) { - if (J&0x02) C[1]=VB[c1&3]|0x40; - if (J&0x01) *C=VB[c2&3]|0x40; + if (J&0x02) C[1]=VB[c1&3]|(J>>8); + if (J&0x01) *C=VB[c2&3]|(J>>8); c1>>=2;c2>>=2; - if (J&0x08) C[3]=VB[c1&3]|0x40;; - if (J&0x04) C[2]=VB[c2&3]|0x40;; + if (J&0x08) C[3]=VB[c1&3]|(J>>8); + if (J&0x04) C[2]=VB[c2&3]|(J>>8); c1>>=2;c2>>=2; - if (J&0x20) C[5]=VB[c1&3]|0x40;; - if (J&0x10) C[4]=VB[c2&3]|0x40;; + if (J&0x20) C[5]=VB[c1&3]|(J>>8); + if (J&0x10) C[4]=VB[c2&3]|(J>>8); c1>>=2;c2>>=2; - if (J&0x80) C[7]=VB[c1]|0x40;; - if (J&0x40) C[6]=VB[c2]|0x40;; + if (J&0x80) C[7]=VB[c1]|(J>>8); + if (J&0x40) C[6]=VB[c2]|(J>>8); } else { - if (J&0x02) C[6]=VB[c1&3]|0x40; - if (J&0x01) C[7]=VB[c2&3]|0x40; + if (J&0x02) C[6]=VB[c1&3]|(J>>8); + if (J&0x01) C[7]=VB[c2&3]|(J>>8); c1>>=2;c2>>=2; - if (J&0x08) C[4]=VB[c1&3]|0x40; - if (J&0x04) C[5]=VB[c2&3]|0x40; + if (J&0x08) C[4]=VB[c1&3]|(J>>8); + if (J&0x04) C[5]=VB[c2&3]|(J>>8); c1>>=2;c2>>=2; - if (J&0x20) C[2]=VB[c1&3]|0x40; - if (J&0x10) C[3]=VB[c2&3]|0x40; + if (J&0x20) C[2]=VB[c1&3]|(J>>8); + if (J&0x10) C[3]=VB[c2&3]|(J>>8); c1>>=2;c2>>=2; - if (J&0x80) *C=VB[c1]|0x40; - if (J&0x40) C[1]=VB[c2]|0x40; + if (J&0x80) *C=VB[c1]|(J>>8); + if (J&0x40) C[1]=VB[c2]|(J>>8); } - } else { - if (atr&H_FLIP) - { - if (J&0x02) C[1]=VB[(c1&3)]; - if (J&0x01) *C=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x08) C[3]=VB[(c1&3)]; - if (J&0x04) C[2]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x20) C[5]=VB[(c1&3)]; - if (J&0x10) C[4]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x80) C[7]=VB[c1]; - if (J&0x40) C[6]=VB[c2]; - }else{ - if (J&0x02) C[6]=VB[(c1&3)]; - if (J&0x01) C[7]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x08) C[4]=VB[(c1&3)]; - if (J&0x04) C[5]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x20) C[2]=VB[(c1&3)]; - if (J&0x10) C[3]=VB[(c2&3)]; - c1>>=2;c2>>=2; - if (J&0x80) *C=VB[c1]; - if (J&0x40) C[1]=VB[c2]; - } } - } - P-=x; } + } nosprites=0; #ifdef FRAMESKIP if(FSkip) return; #endif + if (minx == 256) return; // no visible sprites { uint8 n=((PPU[1]&4)^4)<<1; + if ((int)n < minx) n = minx & 0xfc; loopskie: { uint32 t=*(uint32 *)(sprlinebuf+n); if(t!=0x80808080) { #ifdef LSB_FIRST - if(!(t&0x80)) - { - if(!(t&0x40)) // Normal sprite - P[n]=sprlinebuf[n]; - else if(P[n]&64) // behind bg sprite - P[n]=sprlinebuf[n]; + uint32 tb=*(uint32 *)(target+n); + if(!(t&0x00000080) && (!(t&0x00000040) || (tb&0x00000040))) { // have sprite pixel AND (normal sprite OR behind bg with no bg) + tb &= ~0x000000ff; tb |= t & 0x000000ff; } - if(!(t&0x8000)) - { - if(!(t&0x4000)) // Normal sprite - P[n+1]=(sprlinebuf+1)[n]; - else if(P[n+1]&64) // behind bg sprite - P[n+1]=(sprlinebuf+1)[n]; + if(!(t&0x00008000) && (!(t&0x00004000) || (tb&0x00004000))) { + tb &= ~0x0000ff00; tb |= t & 0x0000ff00; } - if(!(t&0x800000)) - { - if(!(t&0x400000)) // Normal sprite - P[n+2]=(sprlinebuf+2)[n]; - else if(P[n+2]&64) // behind bg sprite - P[n+2]=(sprlinebuf+2)[n]; + if(!(t&0x00800000) && (!(t&0x00400000) || (tb&0x00400000))) { + tb &= ~0x00ff0000; tb |= t & 0x00ff0000; } - if(!(t&0x80000000)) - { - if(!(t&0x40000000)) // Normal sprite - P[n+3]=(sprlinebuf+3)[n]; - else if(P[n+3]&64) // behind bg sprite - P[n+3]=(sprlinebuf+3)[n]; + if(!(t&0x80000000) && (!(t&0x40000000) || (tb&0x40000000))) { + tb &= ~0xff000000; tb |= t & 0xff000000; } + *(uint32 *)(target+n)=tb; #else if(!(t&0x80000000)) { @@ -438,7 +402,7 @@ void FetchSpriteData(void) int vofs; uint8 P0=PPU[0]; - + spr=(SPR *)SPRAM; H=8; @@ -482,11 +446,11 @@ void FetchSpriteData(void) vadr+=t&8; } - // Fix this geniestage hack + // Fix this geniestage hack if(MMC5Hack && geniestage!=1) C = MMC5SPRVRAMADR(vadr); else C = VRAMADR(vadr); - + dst.ca[0]=C[0]; dst.ca[1]=C[8]; dst.x=spr->x; @@ -565,7 +529,7 @@ void FetchSpriteData(void) //if(ns>=7) //printf("%d %d\n",scanline,ns); if(ns>8) PPU_status|=0x20; // Handle case when >8 sprites per -// scanline option is enabled. +// scanline option is enabled. else if(PPU_hook) { for(n=0;n<(8-ns);n++) @@ -582,7 +546,7 @@ void FetchSpriteData(void) void RefreshSprite(uint8 *target) { - + int n,sprindex; SPRB *spr; uint8 *P=target; @@ -603,7 +567,7 @@ void RefreshSprite(uint8 *target) int x=spr[sprindex].x; uint8 *C; uint8 *VB; - + P+=x; c1=((spr[sprindex].ca[0]>>1)&0x55)|(spr[sprindex].ca[1]&0xAA); @@ -613,9 +577,9 @@ void RefreshSprite(uint8 *target) atr=spr[sprindex].atr; if(J) - { + { if(n==0 && SpriteBlurp && !(PPU_status&0x40)) - { + { int z,ze=x+8; if(ze>256) {ze=256;} if(ScreenON && (scanlineFSettings.LastSLine @@ -655,7 +619,7 @@ void RefreshSprite(uint8 *target) C = &(sprlinebuf[(uint8)x]); VB = (PALRAM+0x10)+((atr&3)<<2); - if(atr&SP_BACK) + if(atr&SP_BACK) { if (atr&H_FLIP) { @@ -697,7 +661,7 @@ void RefreshSprite(uint8 *target) c1>>=2;c2>>=2; if (J&0x80) C[7]=VB[c1]; if (J&0x40) C[6]=VB[c2]; - }else{ + }else{ if (J&0x02) C[6]=VB[(c1&3)]; if (J&0x01) C[7]=VB[(c2&3)]; c1>>=2;c2>>=2;