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 static uint8 sprlinebuf[256+8];
40 extern void BGRender(uint8 *target);
44 static int maxsprites=8;
47 void FCEUI_DisableSpriteLimitation(int a)
56 } SPR __attribute__((aligned(1)));
64 } SPRB __attribute__((aligned(1)));
68 static uint8 nosprites,SpriteBlurp;
70 void FetchSpriteData(void)
79 nosprites=SpriteBlurp=0;
81 vofs=(unsigned int)(PPU[0]&0x8&(((PPU[0]&0x20)^0x20)>>2))<<9;
85 for(n=63;n>=0;n--,spr++)
87 if((unsigned int)(scanline-spr->y)>=H) continue;
89 if(nosprites<maxsprites)
91 if(n==63) SpriteBlurp=1;
99 t = (int)scanline-(spr->y);
102 vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4);
104 vadr = (spr->no<<4)+vofs;
110 vadr+=(PPU[0]&0x20)>>1;
119 /* Fix this geniestage hack */
120 if(MMC5Hack && geniestage!=1) C = MMC5SPRVRAMADR(vadr);
121 else C = VRAMADR(vadr);
130 *(uint32 *)&SPRBUF[nosprites<<2]=*(uint32 *)&dst;
142 for(n=63;n>=0;n--,spr++)
144 if((unsigned int)(scanline-spr->y)>=H) continue;
146 if(nosprites<maxsprites)
148 if(n==63) SpriteBlurp=1;
156 t = (int)scanline-(spr->y);
159 vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4);
161 vadr = (spr->no<<4)+vofs;
167 vadr+=(PPU[0]&0x20)>>1;
176 if(MMC5Hack) C = MMC5SPRVRAMADR(vadr);
177 else C = VRAMADR(vadr);
186 *(uint32 *)&SPRBUF[nosprites<<2]=*(uint32 *)&dst;
203 void RefreshSprite(uint8 *target)
209 if(!nosprites) return;
223 FCEU_dwmemset(sprlinebuf,0x80808080,256);
225 spr = (SPRB*)SPRBUF+nosprites;
227 for(n=nosprites;n>=0;n--,spr--)
229 register uint8 J,atr,c1,c2;
236 c1=((spr->ca[0]>>1)&0x55)|(spr->ca[1]&0xAA);
237 c2=(spr->ca[0]&0x55)|((spr->ca[1]<<1)&0xAA);
239 J=spr->ca[0]|spr->ca[1];
244 if(n==0 && SpriteBlurp && !(PPU_status&0x40))
248 if(ScreenON && (scanline<FSettings.FirstSLine || scanline>FSettings.LastSLine
277 //FCEU_DispMessage("%d, %d:%d",scanline,x,tosprite);
281 VB = (PALRAM+0x10)+((atr&3)<<2);
287 if (J&0x02) C[1]=VB[c1&3]|0x40;
288 if (J&0x01) *C=VB[c2&3]|0x40;
290 if (J&0x08) C[3]=VB[c1&3]|0x40;;
291 if (J&0x04) C[2]=VB[c2&3]|0x40;;
293 if (J&0x20) C[5]=VB[c1&3]|0x40;;
294 if (J&0x10) C[4]=VB[c2&3]|0x40;;
296 if (J&0x80) C[7]=VB[c1]|0x40;;
297 if (J&0x40) C[6]=VB[c2]|0x40;;
299 if (J&0x02) C[6]=VB[c1&3]|0x40;
300 if (J&0x01) C[7]=VB[c2&3]|0x40;
302 if (J&0x08) C[4]=VB[c1&3]|0x40;
303 if (J&0x04) C[5]=VB[c2&3]|0x40;
305 if (J&0x20) C[2]=VB[c1&3]|0x40;
306 if (J&0x10) C[3]=VB[c2&3]|0x40;
308 if (J&0x80) *C=VB[c1]|0x40;
309 if (J&0x40) C[1]=VB[c2]|0x40;
314 if (J&0x02) C[1]=VB[(c1&3)];
315 if (J&0x01) *C=VB[(c2&3)];
317 if (J&0x08) C[3]=VB[(c1&3)];
318 if (J&0x04) C[2]=VB[(c2&3)];
320 if (J&0x20) C[5]=VB[(c1&3)];
321 if (J&0x10) C[4]=VB[(c2&3)];
323 if (J&0x80) C[7]=VB[c1];
324 if (J&0x40) C[6]=VB[c2];
326 if (J&0x02) C[6]=VB[(c1&3)];
327 if (J&0x01) C[7]=VB[(c2&3)];
329 if (J&0x08) C[4]=VB[(c1&3)];
330 if (J&0x04) C[5]=VB[(c2&3)];
332 if (J&0x20) C[2]=VB[(c1&3)];
333 if (J&0x10) C[3]=VB[(c2&3)];
335 if (J&0x80) *C=VB[c1];
336 if (J&0x40) C[1]=VB[c2];
349 uint8 n=((PPU[1]&4)^4)<<1;
352 uint32 t=*(uint32 *)(sprlinebuf+n);
358 if(!(t&0x40)) // Normal sprite
360 else if(P[n]&64) // behind bg sprite
366 if(!(t&0x4000)) // Normal sprite
367 P[n+1]=(sprlinebuf+1)[n];
368 else if(P[n+1]&64) // behind bg sprite
369 P[n+1]=(sprlinebuf+1)[n];
374 if(!(t&0x400000)) // Normal sprite
375 P[n+2]=(sprlinebuf+2)[n];
376 else if(P[n+2]&64) // behind bg sprite
377 P[n+2]=(sprlinebuf+2)[n];
382 if(!(t&0x40000000)) // Normal sprite
383 P[n+3]=(sprlinebuf+3)[n];
384 else if(P[n+3]&64) // behind bg sprite
385 P[n+3]=(sprlinebuf+3)[n];
390 if(!(t&0x40)) // Normal sprite
392 else if(P[n]&64) // behind bg sprite
398 if(!(t&0x4000)) // Normal sprite
399 P[n+1]=(sprlinebuf+1)[n];
400 else if(P[n+1]&64) // behind bg sprite
401 P[n+1]=(sprlinebuf+1)[n];
406 if(!(t&0x400000)) // Normal sprite
407 P[n+2]=(sprlinebuf+2)[n];
408 else if(P[n+2]&64) // behind bg sprite
409 P[n+2]=(sprlinebuf+2)[n];
414 if(!(t&0x40000000)) // Normal sprite
415 P[n+3]=(sprlinebuf+3)[n];
416 else if(P[n+3]&64) // behind bg sprite
417 P[n+3]=(sprlinebuf+3)[n];
432 void FetchSpriteData(void)
447 vofs=(unsigned int)(P0&0x8&(((P0&0x20)^0x20)>>2))<<9;
451 for(n=63;n>=0;n--,spr++)
453 if((unsigned int)(scanline-spr->y)>=H) continue;
454 //printf("%d, %u\n",scanline,(unsigned int)(scanline-spr->y));
465 t = (int)scanline-(spr->y);
468 vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4);
470 vadr = (spr->no<<4)+vofs;
485 // Fix this geniestage hack
486 if(MMC5Hack && geniestage!=1) C = MMC5SPRVRAMADR(vadr);
487 else C = VRAMADR(vadr);
495 *(uint32 *)&SPRBUF[ns<<2]=*(uint32 *)&dst;
507 for(n=63;n>=0;n--,spr++)
509 if((unsigned int)(scanline-spr->y)>=H) continue;
521 t = (int)scanline-(spr->y);
524 vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4);
526 vadr = (spr->no<<4)+vofs;
541 if(MMC5Hack) C = MMC5SPRVRAMADR(vadr);
542 else C = VRAMADR(vadr);
554 *(uint32 *)&SPRBUF[ns<<2]=*(uint32 *)&dst;
566 //printf("%d %d\n",scanline,ns);
567 if(ns>8) PPU_status|=0x20; // Handle case when >8 sprites per
568 // scanline option is enabled.
571 for(n=0;n<(8-ns);n++)
583 void RefreshSprite(uint8 *target)
590 //if (printed) { printf("SPRB: %d SPR: %d\n", sizeof(SPRB), sizeof(SPR)); printed=0; }
591 if(!numsprites) return;
593 FCEU_dwmemset(sprlinebuf,0x80808080,256);
599 // for(n=nosprites;n>=0;n--,spr--)
600 for(n=numsprites;n>=0;n--,sprindex--)
603 int x=spr[sprindex].x;
609 c1=((spr[sprindex].ca[0]>>1)&0x55)|(spr[sprindex].ca[1]&0xAA);
610 c2=(spr[sprindex].ca[0]&0x55)|((spr[sprindex].ca[1]<<1)&0xAA);
612 J=spr[sprindex].ca[0]|spr[sprindex].ca[1];
613 atr=spr[sprindex].atr;
617 if(n==0 && SpriteBlurp && !(PPU_status&0x40))
621 if(ScreenON && (scanline<FSettings.FirstSLine || scanline>FSettings.LastSLine
626 // nothing wrong with this
651 //FCEU_DispMessage("%d, %d:%d",scanline,x,tosprite);
654 //C = sprlinebuf+(uint8)x;
655 C = &(sprlinebuf[(uint8)x]);
656 VB = (PALRAM+0x10)+((atr&3)<<2);
662 if (J&0x02) C[1]=VB[c1&3]|0x40;
663 if (J&0x01) *C=VB[c2&3]|0x40;
665 if (J&0x08) C[3]=VB[c1&3]|0x40;
666 if (J&0x04) C[2]=VB[c2&3]|0x40;
668 if (J&0x20) C[5]=VB[c1&3]|0x40;
669 if (J&0x10) C[4]=VB[c2&3]|0x40;
671 if (J&0x80) C[7]=VB[c1]|0x40;
672 if (J&0x40) C[6]=VB[c2]|0x40;
674 if (J&0x02) C[6]=VB[c1&3]|0x40;
675 if (J&0x01) C[7]=VB[c2&3]|0x40;
677 if (J&0x08) C[4]=VB[c1&3]|0x40;
678 if (J&0x04) C[5]=VB[c2&3]|0x40;
680 if (J&0x20) C[2]=VB[c1&3]|0x40;
681 if (J&0x10) C[3]=VB[c2&3]|0x40;
683 if (J&0x80) *C=VB[c1]|0x40;
684 if (J&0x40) C[1]=VB[c2]|0x40;
689 if (J&0x02) C[1]=VB[(c1&3)];
690 if (J&0x01) *C=VB[(c2&3)];
692 if (J&0x08) C[3]=VB[(c1&3)];
693 if (J&0x04) C[2]=VB[(c2&3)];
695 if (J&0x20) C[5]=VB[(c1&3)];
696 if (J&0x10) C[4]=VB[(c2&3)];
698 if (J&0x80) C[7]=VB[c1];
699 if (J&0x40) C[6]=VB[c2];
701 if (J&0x02) C[6]=VB[(c1&3)];
702 if (J&0x01) C[7]=VB[(c2&3)];
704 if (J&0x08) C[4]=VB[(c1&3)];
705 if (J&0x04) C[5]=VB[(c2&3)];
707 if (J&0x20) C[2]=VB[(c1&3)];
708 if (J&0x10) C[3]=VB[(c2&3)];
710 if (J&0x80) *C=VB[c1];
711 if (J&0x40) C[1]=VB[c2];
724 uint8 n=((PPU[1]&4)^4)<<1;
727 uint32 t=*((uint32 *)(&(sprlinebuf[n])));
733 if(!(t&0x40)) // Normal sprite
735 else if(P[n]&64) // behind bg sprite
741 if(!(t&0x4000)) // Normal sprite
742 P[n+1]=(sprlinebuf+1)[n];
743 else if(P[n+1]&64) // behind bg sprite
744 P[n+1]=(sprlinebuf+1)[n];
749 if(!(t&0x400000)) // Normal sprite
750 P[n+2]=(sprlinebuf+2)[n];
751 else if(P[n+2]&64) // behind bg sprite
752 P[n+2]=(sprlinebuf+2)[n];
757 if(!(t&0x40000000)) // Normal sprite
758 P[n+3]=(sprlinebuf+3)[n];
759 else if(P[n+3]&64) // behind bg sprite
760 P[n+3]=(sprlinebuf+3)[n];
765 if(!(t&0x40)) // Normal sprite
767 else if(P[n]&64) // behind bg sprite
773 if(!(t&0x4000)) // Normal sprite
774 P[n+1]=(sprlinebuf+1)[n];
775 else if(P[n+1]&64) // behind bg sprite
776 P[n+1]=(sprlinebuf+1)[n];
781 if(!(t&0x400000)) // Normal sprite
782 P[n+2]=(sprlinebuf+2)[n];
783 else if(P[n+2]&64) // behind bg sprite
784 P[n+2]=(sprlinebuf+2)[n];
789 if(!(t&0x40000000)) // Normal sprite
790 P[n+3]=(sprlinebuf+3)[n];
791 else if(P[n+3]&64) // behind bg sprite
792 P[n+3]=(sprlinebuf+3)[n];