2 * For whatever reason, breaking this out of fce.c made sprites not corrupt
28 #define MMC5SPRVRAMADR(V) &MMC5SPRVPage[(V)>>10][(V)]
29 //#define MMC5BGVRAMADR(V) &MMC5BGVPage[(V)>>10][(V)]
30 #define VRAMADR(V) &VPage[(V)>>10][(V)]
37 static uint8 SPRBUF[0x100];
39 uint8 sprlinebuf[256+8];
43 int spork=0; /* spork the world. Any sprites on this line?
44 Then this will be set to 1. Needed for zapper
45 emulation and *gasp* sprite emulation.
49 extern void BGRender(uint8 *target);
52 static int maxsprites=8;
53 static int sprlinebuf_empty=0;
56 void FCEUI_DisableSpriteLimitation(int a)
65 } SPR __attribute__((aligned(1)));
73 } SPRB __attribute__((aligned(1)));
77 static uint8 nosprites,SpriteBlurp;
79 void FetchSpriteData(void)
88 nosprites=SpriteBlurp=0;
90 vofs=(unsigned int)(PPU[0]&0x8&(((PPU[0]&0x20)^0x20)>>2))<<9;
94 for(n=63;n>=0;n--,spr++)
96 if((unsigned int)(scanline-spr->y)>=H) continue;
98 if(nosprites<maxsprites)
100 if(n==63) SpriteBlurp=1;
108 t = (int)scanline-(spr->y);
111 vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4);
113 vadr = (spr->no<<4)+vofs;
119 vadr+=(PPU[0]&0x20)>>1;
128 /* Fix this geniestage hack */
129 if(MMC5Hack && geniestage!=1) C = MMC5SPRVRAMADR(vadr);
130 else C = VRAMADR(vadr);
139 *(uint32 *)&SPRBUF[nosprites<<2]=*(uint32 *)&dst;
151 for(n=63;n>=0;n--,spr++)
153 if((unsigned int)(scanline-spr->y)>=H) continue;
155 if(nosprites<maxsprites)
157 if(n==63) SpriteBlurp=1;
165 t = (int)scanline-(spr->y);
168 vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4);
170 vadr = (spr->no<<4)+vofs;
176 vadr+=(PPU[0]&0x20)>>1;
185 if(MMC5Hack) C = MMC5SPRVRAMADR(vadr);
186 else C = VRAMADR(vadr);
198 *(uint32 *)&SPRBUF[nosprites<<2]=*(uint32 *)&dst;
210 if(nosprites>8) PPU_status|=0x20; /* Handle case when >8 sprites per
211 scanline option is enabled. */
214 for(n=0;n<(8-nosprites);n++)
227 void RefreshSprites(void)
233 if(!nosprites) return;
248 spr = (SPRB*)SPRBUF+nosprites;
250 if (!sprlinebuf_empty)
252 FCEU_dwmemset(sprlinebuf,0x80808080,256);
253 sprlinebuf_empty = 1;
256 for(n=nosprites;n>=0;n--,spr--)
260 J=spr->ca[0]|spr->ca[1];
264 register uint8 atr,c1,c2;
270 if(n==0 && SpriteBlurp && !(PPU_status&0x40))
275 sphitdata= ((J<<7)&0x80) |
286 c1=((spr->ca[0]>>1)&0x55)|(spr->ca[1]&0xAA);
287 c2=(spr->ca[0]&0x55)|((spr->ca[1]<<1)&0xAA);
290 VB = (PALRAM+0x10)+((atr&3)<<2);
294 if(atr&SP_BACK) J |= 0x4000;
297 if (J&0x02) C[1]=VB[c1&3]|(J>>8);
298 if (J&0x01) *C=VB[c2&3]|(J>>8);
300 if (J&0x08) C[3]=VB[c1&3]|(J>>8);
301 if (J&0x04) C[2]=VB[c2&3]|(J>>8);
303 if (J&0x20) C[5]=VB[c1&3]|(J>>8);
304 if (J&0x10) C[4]=VB[c2&3]|(J>>8);
306 if (J&0x80) C[7]=VB[c1]|(J>>8);
307 if (J&0x40) C[6]=VB[c2]|(J>>8);
309 if (J&0x02) C[6]=VB[c1&3]|(J>>8);
310 if (J&0x01) C[7]=VB[c2&3]|(J>>8);
312 if (J&0x08) C[4]=VB[c1&3]|(J>>8);
313 if (J&0x04) C[5]=VB[c2&3]|(J>>8);
315 if (J&0x20) C[2]=VB[c1&3]|(J>>8);
316 if (J&0x10) C[3]=VB[c2&3]|(J>>8);
318 if (J&0x80) *C=VB[c1]|(J>>8);
319 if (J&0x40) C[1]=VB[c2]|(J>>8);
322 sprlinebuf_empty = 0;
331 void CopySprites(uint8 *target)
333 uint8 n=((PPU[1]&4)^4)<<1;
334 //if ((int)n < minx) n = minx & 0xfc;
337 uint32 t=*(uint32 *)(sprlinebuf+n);
341 uint32 tb=*(uint32 *)(target+n);
342 if(!(t&0x00000080) && (!(t&0x00000040) || (tb&0x00000040))) { // have sprite pixel AND (normal sprite OR behind bg with no bg)
343 tb &= ~0x000000ff; tb |= t & 0x000000ff;
346 if(!(t&0x00008000) && (!(t&0x00004000) || (tb&0x00004000))) {
347 tb &= ~0x0000ff00; tb |= t & 0x0000ff00;
350 if(!(t&0x00800000) && (!(t&0x00400000) || (tb&0x00400000))) {
351 tb &= ~0x00ff0000; tb |= t & 0x00ff0000;
354 if(!(t&0x80000000) && (!(t&0x40000000) || (tb&0x40000000))) {
355 tb &= ~0xff000000; tb |= t & 0xff000000;
357 *(uint32 *)(target+n)=tb;
359 #error not implemented