98733207 |
1 | /** |
2 | * For whatever reason, breaking this out of fce.c made sprites not corrupt |
3 | */ |
4 | |
5 | |
6 | #include <string.h> |
7 | #include <stdio.h> |
8 | #include <stdlib.h> |
9 | |
10 | #include "types.h" |
11 | #include "x6502.h" |
12 | #include "fce.h" |
13 | #include "sound.h" |
14 | #include "svga.h" |
15 | #include "netplay.h" |
16 | #include "general.h" |
17 | #include "endian.h" |
18 | #include "version.h" |
19 | #include "memory.h" |
20 | |
21 | #include "cart.h" |
22 | #include "nsf.h" |
23 | #include "fds.h" |
24 | #include "ines.h" |
25 | #include "unif.h" |
26 | #include "cheat.h" |
27 | |
28 | #define MMC5SPRVRAMADR(V) &MMC5SPRVPage[(V)>>10][(V)] |
29 | //#define MMC5BGVRAMADR(V) &MMC5BGVPage[(V)>>10][(V)] |
30 | #define VRAMADR(V) &VPage[(V)>>10][(V)] |
31 | |
32 | #define V_FLIP 0x80 |
33 | #define H_FLIP 0x40 |
34 | #define SP_BACK 0x20 |
35 | |
36 | uint8 SPRAM[0x100]; |
37 | static uint8 SPRBUF[0x100]; |
38 | |
39 | static uint8 sprlinebuf[256+8]; |
40 | extern void BGRender(uint8 *target); |
41 | extern int tosprite; |
42 | |
43 | |
44 | static int maxsprites=8; |
45 | |
46 | |
47 | void FCEUI_DisableSpriteLimitation(int a) |
48 | { |
49 | maxsprites=a?64:8; |
50 | } |
51 | |
52 | |
53 | //int printed=1; |
54 | typedef struct { |
55 | uint8 y,no,atr,x; |
56 | } SPR __attribute__((aligned(1))); |
57 | |
58 | typedef struct { |
59 | // uint8 ca[2],atr,x; |
60 | uint8 ca[2],atr,x; |
61 | // union { int z; } |
62 | |
63 | |
64 | } SPRB __attribute__((aligned(1))); |
65 | |
66 | |
67 | |
68 | static uint8 nosprites,SpriteBlurp; |
69 | |
70 | void FetchSpriteData(void) |
71 | { |
72 | SPR *spr; |
73 | uint8 H; |
74 | int n,vofs; |
75 | |
76 | spr=(SPR *)SPRAM; |
77 | H=8; |
78 | |
79 | nosprites=SpriteBlurp=0; |
80 | |
81 | vofs=(unsigned int)(PPU[0]&0x8&(((PPU[0]&0x20)^0x20)>>2))<<9; |
82 | H+=(PPU[0]&0x20)>>2; |
83 | |
84 | if(!PPU_hook) |
85 | for(n=63;n>=0;n--,spr++) |
86 | { |
87 | if((unsigned int)(scanline-spr->y)>=H) continue; |
88 | |
89 | if(nosprites<maxsprites) |
90 | { |
91 | if(n==63) SpriteBlurp=1; |
92 | |
93 | { |
94 | SPRB dst; |
95 | uint8 *C; |
96 | int t; |
97 | unsigned int vadr; |
98 | |
99 | t = (int)scanline-(spr->y); |
100 | |
101 | if (Sprite16) |
102 | vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4); |
103 | else |
104 | vadr = (spr->no<<4)+vofs; |
105 | |
106 | if (spr->atr&V_FLIP) |
107 | { |
108 | vadr+=7; |
109 | vadr-=t; |
110 | vadr+=(PPU[0]&0x20)>>1; |
111 | vadr-=t&8; |
112 | } |
113 | else |
114 | { |
115 | vadr+=t; |
116 | vadr+=t&8; |
117 | } |
118 | |
119 | /* Fix this geniestage hack */ |
120 | if(MMC5Hack && geniestage!=1) C = MMC5SPRVRAMADR(vadr); |
121 | else C = VRAMADR(vadr); |
122 | |
123 | |
124 | dst.ca[0]=C[0]; |
125 | dst.ca[1]=C[8]; |
126 | dst.x=spr->x; |
127 | dst.atr=spr->atr; |
128 | |
129 | |
130 | *(uint32 *)&SPRBUF[nosprites<<2]=*(uint32 *)&dst; |
131 | } |
132 | |
133 | nosprites++; |
134 | } |
135 | else |
136 | { |
137 | PPU_status|=0x20; |
138 | break; |
139 | } |
140 | } |
141 | else |
142 | for(n=63;n>=0;n--,spr++) |
143 | { |
144 | if((unsigned int)(scanline-spr->y)>=H) continue; |
145 | |
146 | if(nosprites<maxsprites) |
147 | { |
148 | if(n==63) SpriteBlurp=1; |
149 | |
150 | { |
151 | SPRB dst; |
152 | uint8 *C; |
153 | int t; |
154 | unsigned int vadr; |
155 | |
156 | t = (int)scanline-(spr->y); |
157 | |
158 | if (Sprite16) |
159 | vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4); |
160 | else |
161 | vadr = (spr->no<<4)+vofs; |
162 | |
163 | if (spr->atr&V_FLIP) |
164 | { |
165 | vadr+=7; |
166 | vadr-=t; |
167 | vadr+=(PPU[0]&0x20)>>1; |
168 | vadr-=t&8; |
169 | } |
170 | else |
171 | { |
172 | vadr+=t; |
173 | vadr+=t&8; |
174 | } |
175 | |
176 | if(MMC5Hack) C = MMC5SPRVRAMADR(vadr); |
177 | else C = VRAMADR(vadr); |
178 | dst.ca[0]=C[0]; |
179 | PPU_hook(vadr); |
180 | dst.ca[1]=C[8]; |
181 | PPU_hook(vadr|8); |
182 | dst.x=spr->x; |
183 | dst.atr=spr->atr; |
184 | |
185 | |
186 | *(uint32 *)&SPRBUF[nosprites<<2]=*(uint32 *)&dst; |
187 | } |
188 | |
189 | nosprites++; |
190 | } |
191 | else |
192 | { |
193 | PPU_status|=0x20; |
194 | break; |
195 | } |
196 | } |
197 | } |
198 | |
199 | #ifdef FRAMESKIP |
200 | extern int FSkip; |
201 | #endif |
202 | |
203 | void RefreshSprite(uint8 *target) |
204 | { |
205 | int n; |
206 | SPRB *spr; |
207 | uint8 *P=target; |
208 | |
209 | if(!nosprites) return; |
210 | #ifdef FRAMESKIP |
211 | if(FSkip) |
212 | { |
213 | if(!SpriteBlurp) |
214 | { |
215 | nosprites=0; |
216 | return; |
217 | } |
218 | else |
219 | nosprites=1; |
220 | } |
221 | #endif |
222 | |
223 | FCEU_dwmemset(sprlinebuf,0x80808080,256); |
224 | nosprites--; |
225 | spr = (SPRB*)SPRBUF+nosprites; |
226 | |
227 | for(n=nosprites;n>=0;n--,spr--) |
228 | { |
229 | register uint8 J,atr,c1,c2; |
230 | int x=spr->x; |
231 | uint8 *C; |
232 | uint8 *VB; |
233 | |
234 | P+=x; |
235 | |
236 | c1=((spr->ca[0]>>1)&0x55)|(spr->ca[1]&0xAA); |
237 | c2=(spr->ca[0]&0x55)|((spr->ca[1]<<1)&0xAA); |
238 | |
239 | J=spr->ca[0]|spr->ca[1]; |
240 | atr=spr->atr; |
241 | |
242 | if(J) |
243 | { |
244 | if(n==0 && SpriteBlurp && !(PPU_status&0x40)) |
245 | { |
246 | int z,ze=x+8; |
247 | if(ze>256) {ze=256;} |
248 | if(ScreenON && (scanline<FSettings.FirstSLine || scanline>FSettings.LastSLine |
249 | #ifdef FRAMESKIP |
250 | || FSkip |
251 | #endif |
252 | )) |
253 | BGRender(target); |
254 | |
255 | if(!(atr&H_FLIP)) |
256 | { |
257 | for(z=x;z<ze;z++) |
258 | { |
259 | if(J&(0x80>>(z-x))) |
260 | { |
261 | if(!(target[z]&64)) |
262 | tosprite=z; |
263 | } |
264 | } |
265 | } |
266 | else |
267 | { |
268 | for(z=x;z<ze;z++) |
269 | { |
270 | if(J&(1<<(z-x))) |
271 | { |
272 | if(!(target[z]&64)) |
273 | tosprite=z; |
274 | } |
275 | } |
276 | } |
277 | //FCEU_DispMessage("%d, %d:%d",scanline,x,tosprite); |
278 | } |
279 | |
280 | C = sprlinebuf+x; |
281 | VB = (PALRAM+0x10)+((atr&3)<<2); |
282 | |
283 | if(atr&SP_BACK) |
284 | { |
285 | if (atr&H_FLIP) |
286 | { |
287 | if (J&0x02) C[1]=VB[c1&3]|0x40; |
288 | if (J&0x01) *C=VB[c2&3]|0x40; |
289 | c1>>=2;c2>>=2; |
290 | if (J&0x08) C[3]=VB[c1&3]|0x40;; |
291 | if (J&0x04) C[2]=VB[c2&3]|0x40;; |
292 | c1>>=2;c2>>=2; |
293 | if (J&0x20) C[5]=VB[c1&3]|0x40;; |
294 | if (J&0x10) C[4]=VB[c2&3]|0x40;; |
295 | c1>>=2;c2>>=2; |
296 | if (J&0x80) C[7]=VB[c1]|0x40;; |
297 | if (J&0x40) C[6]=VB[c2]|0x40;; |
298 | } else { |
299 | if (J&0x02) C[6]=VB[c1&3]|0x40; |
300 | if (J&0x01) C[7]=VB[c2&3]|0x40; |
301 | c1>>=2;c2>>=2; |
302 | if (J&0x08) C[4]=VB[c1&3]|0x40; |
303 | if (J&0x04) C[5]=VB[c2&3]|0x40; |
304 | c1>>=2;c2>>=2; |
305 | if (J&0x20) C[2]=VB[c1&3]|0x40; |
306 | if (J&0x10) C[3]=VB[c2&3]|0x40; |
307 | c1>>=2;c2>>=2; |
308 | if (J&0x80) *C=VB[c1]|0x40; |
309 | if (J&0x40) C[1]=VB[c2]|0x40; |
310 | } |
311 | } else { |
312 | if (atr&H_FLIP) |
313 | { |
314 | if (J&0x02) C[1]=VB[(c1&3)]; |
315 | if (J&0x01) *C=VB[(c2&3)]; |
316 | c1>>=2;c2>>=2; |
317 | if (J&0x08) C[3]=VB[(c1&3)]; |
318 | if (J&0x04) C[2]=VB[(c2&3)]; |
319 | c1>>=2;c2>>=2; |
320 | if (J&0x20) C[5]=VB[(c1&3)]; |
321 | if (J&0x10) C[4]=VB[(c2&3)]; |
322 | c1>>=2;c2>>=2; |
323 | if (J&0x80) C[7]=VB[c1]; |
324 | if (J&0x40) C[6]=VB[c2]; |
325 | }else{ |
326 | if (J&0x02) C[6]=VB[(c1&3)]; |
327 | if (J&0x01) C[7]=VB[(c2&3)]; |
328 | c1>>=2;c2>>=2; |
329 | if (J&0x08) C[4]=VB[(c1&3)]; |
330 | if (J&0x04) C[5]=VB[(c2&3)]; |
331 | c1>>=2;c2>>=2; |
332 | if (J&0x20) C[2]=VB[(c1&3)]; |
333 | if (J&0x10) C[3]=VB[(c2&3)]; |
334 | c1>>=2;c2>>=2; |
335 | if (J&0x80) *C=VB[c1]; |
336 | if (J&0x40) C[1]=VB[c2]; |
337 | } |
338 | } |
339 | } |
340 | P-=x; |
341 | } |
342 | |
343 | nosprites=0; |
344 | #ifdef FRAMESKIP |
345 | if(FSkip) return; |
346 | #endif |
347 | |
348 | { |
349 | uint8 n=((PPU[1]&4)^4)<<1; |
350 | loopskie: |
351 | { |
352 | uint32 t=*(uint32 *)(sprlinebuf+n); |
353 | if(t!=0x80808080) |
354 | { |
355 | #ifdef LSB_FIRST |
356 | if(!(t&0x80)) |
357 | { |
358 | if(!(t&0x40)) // Normal sprite |
359 | P[n]=sprlinebuf[n]; |
360 | else if(P[n]&64) // behind bg sprite |
361 | P[n]=sprlinebuf[n]; |
362 | } |
363 | |
364 | if(!(t&0x8000)) |
365 | { |
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]; |
370 | } |
371 | |
372 | if(!(t&0x800000)) |
373 | { |
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]; |
378 | } |
379 | |
380 | if(!(t&0x80000000)) |
381 | { |
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]; |
386 | } |
387 | #else |
388 | if(!(t&0x80000000)) |
389 | { |
390 | if(!(t&0x40)) // Normal sprite |
391 | P[n]=sprlinebuf[n]; |
392 | else if(P[n]&64) // behind bg sprite |
393 | P[n]=sprlinebuf[n]; |
394 | } |
395 | |
396 | if(!(t&0x800000)) |
397 | { |
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]; |
402 | } |
403 | |
404 | if(!(t&0x8000)) |
405 | { |
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]; |
410 | } |
411 | |
412 | if(!(t&0x80)) |
413 | { |
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]; |
418 | } |
419 | #endif |
420 | } |
421 | } |
422 | n+=4; |
423 | if(n) goto loopskie; |
424 | } |
425 | } |
426 | |
427 | |
428 | |
429 | |
430 | |
431 | /* |
432 | void FetchSpriteData(void) |
433 | { |
434 | uint8 ns,sb; |
435 | SPR *spr; |
436 | uint8 H; |
437 | int n; |
438 | int vofs; |
439 | uint8 P0=PPU[0]; |
440 | |
441 | |
442 | spr=(SPR *)SPRAM; |
443 | H=8; |
444 | |
445 | ns=sb=0; |
446 | |
447 | vofs=(unsigned int)(P0&0x8&(((P0&0x20)^0x20)>>2))<<9; |
448 | H+=(P0&0x20)>>2; |
449 | |
450 | if(!PPU_hook) |
451 | for(n=63;n>=0;n--,spr++) |
452 | { |
453 | if((unsigned int)(scanline-spr->y)>=H) continue; |
454 | //printf("%d, %u\n",scanline,(unsigned int)(scanline-spr->y)); |
455 | if(ns<maxsprites) |
456 | { |
457 | if(n==63) sb=1; |
458 | |
459 | { |
460 | SPRB dst; |
461 | uint8 *C; |
462 | int t; |
463 | unsigned int vadr; |
464 | |
465 | t = (int)scanline-(spr->y); |
466 | |
467 | if (Sprite16) |
468 | vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4); |
469 | else |
470 | vadr = (spr->no<<4)+vofs; |
471 | |
472 | if (spr->atr&V_FLIP) |
473 | { |
474 | vadr+=7; |
475 | vadr-=t; |
476 | vadr+=(P0&0x20)>>1; |
477 | vadr-=t&8; |
478 | } |
479 | else |
480 | { |
481 | vadr+=t; |
482 | vadr+=t&8; |
483 | } |
484 | |
485 | // Fix this geniestage hack |
486 | if(MMC5Hack && geniestage!=1) C = MMC5SPRVRAMADR(vadr); |
487 | else C = VRAMADR(vadr); |
488 | |
489 | |
490 | dst.ca[0]=C[0]; |
491 | dst.ca[1]=C[8]; |
492 | dst.x=spr->x; |
493 | dst.atr=spr->atr; |
494 | |
495 | *(uint32 *)&SPRBUF[ns<<2]=*(uint32 *)&dst; |
496 | } |
497 | |
498 | ns++; |
499 | } |
500 | else |
501 | { |
502 | PPU_status|=0x20; |
503 | break; |
504 | } |
505 | } |
506 | else |
507 | for(n=63;n>=0;n--,spr++) |
508 | { |
509 | if((unsigned int)(scanline-spr->y)>=H) continue; |
510 | |
511 | if(ns<maxsprites) |
512 | { |
513 | if(n==63) sb=1; |
514 | |
515 | { |
516 | SPRB dst; |
517 | uint8 *C; |
518 | int t; |
519 | unsigned int vadr; |
520 | |
521 | t = (int)scanline-(spr->y); |
522 | |
523 | if (Sprite16) |
524 | vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4); |
525 | else |
526 | vadr = (spr->no<<4)+vofs; |
527 | |
528 | if (spr->atr&V_FLIP) |
529 | { |
530 | vadr+=7; |
531 | vadr-=t; |
532 | vadr+=(P0&0x20)>>1; |
533 | vadr-=t&8; |
534 | } |
535 | else |
536 | { |
537 | vadr+=t; |
538 | vadr+=t&8; |
539 | } |
540 | |
541 | if(MMC5Hack) C = MMC5SPRVRAMADR(vadr); |
542 | else C = VRAMADR(vadr); |
543 | dst.ca[0]=C[0]; |
544 | if(ns<8) |
545 | { |
546 | PPU_hook(0x2000); |
547 | PPU_hook(vadr); |
548 | } |
549 | dst.ca[1]=C[8]; |
550 | dst.x=spr->x; |
551 | dst.atr=spr->atr; |
552 | |
553 | |
554 | *(uint32 *)&SPRBUF[ns<<2]=*(uint32 *)&dst; |
555 | } |
556 | |
557 | ns++; |
558 | } |
559 | else |
560 | { |
561 | PPU_status|=0x20; |
562 | break; |
563 | } |
564 | } |
565 | //if(ns>=7) |
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. |
569 | else if(PPU_hook) |
570 | { |
571 | for(n=0;n<(8-ns);n++) |
572 | { |
573 | PPU_hook(0x2000); |
574 | PPU_hook(vofs); |
575 | } |
576 | } |
577 | numsprites=ns; |
578 | SpriteBlurp=sb; |
579 | } |
580 | |
581 | |
582 | |
583 | void RefreshSprite(uint8 *target) |
584 | { |
585 | |
586 | int n,sprindex; |
587 | SPRB *spr; |
588 | uint8 *P=target; |
589 | |
590 | //if (printed) { printf("SPRB: %d SPR: %d\n", sizeof(SPRB), sizeof(SPR)); printed=0; } |
591 | if(!numsprites) return; |
592 | |
593 | FCEU_dwmemset(sprlinebuf,0x80808080,256); |
594 | |
595 | numsprites--; |
596 | sprindex=numsprites; |
597 | spr = (SPRB*)SPRBUF; |
598 | |
599 | // for(n=nosprites;n>=0;n--,spr--) |
600 | for(n=numsprites;n>=0;n--,sprindex--) |
601 | { |
602 | uint8 J,atr,c1,c2; |
603 | int x=spr[sprindex].x; |
604 | uint8 *C; |
605 | uint8 *VB; |
606 | |
607 | P+=x; |
608 | |
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); |
611 | |
612 | J=spr[sprindex].ca[0]|spr[sprindex].ca[1]; |
613 | atr=spr[sprindex].atr; |
614 | |
615 | if(J) |
616 | { |
617 | if(n==0 && SpriteBlurp && !(PPU_status&0x40)) |
618 | { |
619 | int z,ze=x+8; |
620 | if(ze>256) {ze=256;} |
621 | if(ScreenON && (scanline<FSettings.FirstSLine || scanline>FSettings.LastSLine |
622 | #ifdef FRAMESKIP |
623 | || FSkip |
624 | #endif |
625 | )) |
626 | // nothing wrong with this |
627 | BGRender(target); |
628 | |
629 | if(!(atr&H_FLIP)) |
630 | { |
631 | for(z=x;z<ze;z++) |
632 | { |
633 | if(J&(0x80>>(z-x))) |
634 | { |
635 | if(!(target[z]&64)) |
636 | tosprite=z; |
637 | } |
638 | } |
639 | } |
640 | else |
641 | { |
642 | for(z=x;z<ze;z++) |
643 | { |
644 | if(J&(1<<(z-x))) |
645 | { |
646 | if(!(target[z]&64)) |
647 | tosprite=z; |
648 | } |
649 | } |
650 | } |
651 | //FCEU_DispMessage("%d, %d:%d",scanline,x,tosprite); |
652 | } |
653 | |
654 | //C = sprlinebuf+(uint8)x; |
655 | C = &(sprlinebuf[(uint8)x]); |
656 | VB = (PALRAM+0x10)+((atr&3)<<2); |
657 | |
658 | if(atr&SP_BACK) |
659 | { |
660 | if (atr&H_FLIP) |
661 | { |
662 | if (J&0x02) C[1]=VB[c1&3]|0x40; |
663 | if (J&0x01) *C=VB[c2&3]|0x40; |
664 | c1>>=2;c2>>=2; |
665 | if (J&0x08) C[3]=VB[c1&3]|0x40; |
666 | if (J&0x04) C[2]=VB[c2&3]|0x40; |
667 | c1>>=2;c2>>=2; |
668 | if (J&0x20) C[5]=VB[c1&3]|0x40; |
669 | if (J&0x10) C[4]=VB[c2&3]|0x40; |
670 | c1>>=2;c2>>=2; |
671 | if (J&0x80) C[7]=VB[c1]|0x40; |
672 | if (J&0x40) C[6]=VB[c2]|0x40; |
673 | } else { |
674 | if (J&0x02) C[6]=VB[c1&3]|0x40; |
675 | if (J&0x01) C[7]=VB[c2&3]|0x40; |
676 | c1>>=2;c2>>=2; |
677 | if (J&0x08) C[4]=VB[c1&3]|0x40; |
678 | if (J&0x04) C[5]=VB[c2&3]|0x40; |
679 | c1>>=2;c2>>=2; |
680 | if (J&0x20) C[2]=VB[c1&3]|0x40; |
681 | if (J&0x10) C[3]=VB[c2&3]|0x40; |
682 | c1>>=2;c2>>=2; |
683 | if (J&0x80) *C=VB[c1]|0x40; |
684 | if (J&0x40) C[1]=VB[c2]|0x40; |
685 | } |
686 | } else { |
687 | if (atr&H_FLIP) |
688 | { |
689 | if (J&0x02) C[1]=VB[(c1&3)]; |
690 | if (J&0x01) *C=VB[(c2&3)]; |
691 | c1>>=2;c2>>=2; |
692 | if (J&0x08) C[3]=VB[(c1&3)]; |
693 | if (J&0x04) C[2]=VB[(c2&3)]; |
694 | c1>>=2;c2>>=2; |
695 | if (J&0x20) C[5]=VB[(c1&3)]; |
696 | if (J&0x10) C[4]=VB[(c2&3)]; |
697 | c1>>=2;c2>>=2; |
698 | if (J&0x80) C[7]=VB[c1]; |
699 | if (J&0x40) C[6]=VB[c2]; |
700 | }else{ |
701 | if (J&0x02) C[6]=VB[(c1&3)]; |
702 | if (J&0x01) C[7]=VB[(c2&3)]; |
703 | c1>>=2;c2>>=2; |
704 | if (J&0x08) C[4]=VB[(c1&3)]; |
705 | if (J&0x04) C[5]=VB[(c2&3)]; |
706 | c1>>=2;c2>>=2; |
707 | if (J&0x20) C[2]=VB[(c1&3)]; |
708 | if (J&0x10) C[3]=VB[(c2&3)]; |
709 | c1>>=2;c2>>=2; |
710 | if (J&0x80) *C=VB[c1]; |
711 | if (J&0x40) C[1]=VB[c2]; |
712 | } |
713 | } |
714 | } |
715 | P-=x; |
716 | } |
717 | |
718 | numsprites=0; |
719 | #ifdef FRAMESKIP |
720 | if(FSkip) return; |
721 | #endif |
722 | |
723 | { |
724 | uint8 n=((PPU[1]&4)^4)<<1; |
725 | loopskie: |
726 | { |
727 | uint32 t=*((uint32 *)(&(sprlinebuf[n]))); |
728 | if(t!=0x80808080) |
729 | { |
730 | #ifdef LSB_FIRST |
731 | if(!(t&0x80)) |
732 | { |
733 | if(!(t&0x40)) // Normal sprite |
734 | P[n]=sprlinebuf[n]; |
735 | else if(P[n]&64) // behind bg sprite |
736 | P[n]=sprlinebuf[n]; |
737 | } |
738 | |
739 | if(!(t&0x8000)) |
740 | { |
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]; |
745 | } |
746 | |
747 | if(!(t&0x800000)) |
748 | { |
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]; |
753 | } |
754 | |
755 | if(!(t&0x80000000)) |
756 | { |
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]; |
761 | } |
762 | #else |
763 | if(!(t&0x80000000)) |
764 | { |
765 | if(!(t&0x40)) // Normal sprite |
766 | P[n]=sprlinebuf[n]; |
767 | else if(P[n]&64) // behind bg sprite |
768 | P[n]=sprlinebuf[n]; |
769 | } |
770 | |
771 | if(!(t&0x800000)) |
772 | { |
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]; |
777 | } |
778 | |
779 | if(!(t&0x8000)) |
780 | { |
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]; |
785 | } |
786 | |
787 | if(!(t&0x80)) |
788 | { |
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]; |
793 | } |
794 | #endif |
795 | } |
796 | } |
797 | n+=4; |
798 | if(n) goto loopskie; |
799 | } |
800 | } |
801 | |
802 | |
803 | */ |