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 | |
9115e7d2 |
39 | static uint8 sprlinebuf[256+8]; |
98733207 |
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 { |
9115e7d2 |
59 | // uint8 ca[2],atr,x; |
60 | uint8 ca[2],atr,x; |
98733207 |
61 | // union { int z; } |
9115e7d2 |
62 | |
98733207 |
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 | |
9115e7d2 |
123 | |
98733207 |
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]; |
ea80a45b |
179 | if(nosprites<8) |
180 | { |
181 | PPU_hook(0x2000); |
182 | PPU_hook(vadr); |
183 | } |
98733207 |
184 | dst.ca[1]=C[8]; |
98733207 |
185 | dst.x=spr->x; |
186 | dst.atr=spr->atr; |
187 | |
188 | |
189 | *(uint32 *)&SPRBUF[nosprites<<2]=*(uint32 *)&dst; |
190 | } |
191 | |
192 | nosprites++; |
193 | } |
194 | else |
195 | { |
196 | PPU_status|=0x20; |
197 | break; |
198 | } |
199 | } |
ea80a45b |
200 | |
201 | if(nosprites>8) PPU_status|=0x20; /* Handle case when >8 sprites per |
202 | scanline option is enabled. */ |
203 | else if(PPU_hook) |
204 | { |
205 | for(n=0;n<(8-nosprites);n++) |
206 | { |
207 | PPU_hook(0x2000); |
208 | PPU_hook(vofs); |
209 | } |
210 | } |
211 | |
98733207 |
212 | } |
213 | |
214 | #ifdef FRAMESKIP |
215 | extern int FSkip; |
216 | #endif |
217 | |
218 | void RefreshSprite(uint8 *target) |
219 | { |
9115e7d2 |
220 | int n, minx=256; |
98733207 |
221 | SPRB *spr; |
98733207 |
222 | |
223 | if(!nosprites) return; |
224 | #ifdef FRAMESKIP |
225 | if(FSkip) |
226 | { |
227 | if(!SpriteBlurp) |
228 | { |
229 | nosprites=0; |
230 | return; |
231 | } |
232 | else |
233 | nosprites=1; |
234 | } |
235 | #endif |
236 | |
98733207 |
237 | nosprites--; |
238 | spr = (SPRB*)SPRBUF+nosprites; |
239 | |
240 | for(n=nosprites;n>=0;n--,spr--) |
241 | { |
9115e7d2 |
242 | register uint32 J; |
98733207 |
243 | |
244 | J=spr->ca[0]|spr->ca[1]; |
98733207 |
245 | |
9115e7d2 |
246 | if (J) |
247 | { |
248 | register uint8 atr,c1,c2; |
249 | uint8 *C; |
250 | uint8 *VB; |
251 | int x=spr->x; |
252 | atr=spr->atr; |
253 | |
254 | if (x < minx) |
255 | { |
256 | if (minx == 256) FCEU_dwmemset(sprlinebuf,0x80808080,256); // only clear sprite buff when we encounter first sprite |
257 | minx = x; |
258 | } |
98733207 |
259 | if(n==0 && SpriteBlurp && !(PPU_status&0x40)) |
9115e7d2 |
260 | { |
98733207 |
261 | int z,ze=x+8; |
262 | if(ze>256) {ze=256;} |
263 | if(ScreenON && (scanline<FSettings.FirstSLine || scanline>FSettings.LastSLine |
264 | #ifdef FRAMESKIP |
265 | || FSkip |
266 | #endif |
267 | )) |
268 | BGRender(target); |
269 | |
270 | if(!(atr&H_FLIP)) |
271 | { |
272 | for(z=x;z<ze;z++) |
273 | { |
274 | if(J&(0x80>>(z-x))) |
275 | { |
276 | if(!(target[z]&64)) |
277 | tosprite=z; |
278 | } |
279 | } |
280 | } |
281 | else |
282 | { |
283 | for(z=x;z<ze;z++) |
284 | { |
285 | if(J&(1<<(z-x))) |
286 | { |
287 | if(!(target[z]&64)) |
288 | tosprite=z; |
289 | } |
290 | } |
291 | } |
292 | //FCEU_DispMessage("%d, %d:%d",scanline,x,tosprite); |
293 | } |
294 | |
9115e7d2 |
295 | c1=((spr->ca[0]>>1)&0x55)|(spr->ca[1]&0xAA); |
296 | c2=(spr->ca[0]&0x55)|((spr->ca[1]<<1)&0xAA); |
297 | |
98733207 |
298 | C = sprlinebuf+x; |
299 | VB = (PALRAM+0x10)+((atr&3)<<2); |
300 | |
98733207 |
301 | { |
9115e7d2 |
302 | J &= 0xff; |
303 | if(atr&SP_BACK) J |= 0x4000; |
98733207 |
304 | if (atr&H_FLIP) |
305 | { |
9115e7d2 |
306 | if (J&0x02) C[1]=VB[c1&3]|(J>>8); |
307 | if (J&0x01) *C=VB[c2&3]|(J>>8); |
98733207 |
308 | c1>>=2;c2>>=2; |
9115e7d2 |
309 | if (J&0x08) C[3]=VB[c1&3]|(J>>8); |
310 | if (J&0x04) C[2]=VB[c2&3]|(J>>8); |
98733207 |
311 | c1>>=2;c2>>=2; |
9115e7d2 |
312 | if (J&0x20) C[5]=VB[c1&3]|(J>>8); |
313 | if (J&0x10) C[4]=VB[c2&3]|(J>>8); |
98733207 |
314 | c1>>=2;c2>>=2; |
9115e7d2 |
315 | if (J&0x80) C[7]=VB[c1]|(J>>8); |
316 | if (J&0x40) C[6]=VB[c2]|(J>>8); |
98733207 |
317 | } else { |
9115e7d2 |
318 | if (J&0x02) C[6]=VB[c1&3]|(J>>8); |
319 | if (J&0x01) C[7]=VB[c2&3]|(J>>8); |
98733207 |
320 | c1>>=2;c2>>=2; |
9115e7d2 |
321 | if (J&0x08) C[4]=VB[c1&3]|(J>>8); |
322 | if (J&0x04) C[5]=VB[c2&3]|(J>>8); |
98733207 |
323 | c1>>=2;c2>>=2; |
9115e7d2 |
324 | if (J&0x20) C[2]=VB[c1&3]|(J>>8); |
325 | if (J&0x10) C[3]=VB[c2&3]|(J>>8); |
98733207 |
326 | c1>>=2;c2>>=2; |
9115e7d2 |
327 | if (J&0x80) *C=VB[c1]|(J>>8); |
328 | if (J&0x40) C[1]=VB[c2]|(J>>8); |
98733207 |
329 | } |
98733207 |
330 | } |
98733207 |
331 | } |
9115e7d2 |
332 | } |
98733207 |
333 | |
334 | nosprites=0; |
335 | #ifdef FRAMESKIP |
336 | if(FSkip) return; |
337 | #endif |
9115e7d2 |
338 | if (minx == 256) return; // no visible sprites |
98733207 |
339 | |
340 | { |
341 | uint8 n=((PPU[1]&4)^4)<<1; |
9115e7d2 |
342 | if ((int)n < minx) n = minx & 0xfc; |
98733207 |
343 | loopskie: |
344 | { |
345 | uint32 t=*(uint32 *)(sprlinebuf+n); |
346 | if(t!=0x80808080) |
347 | { |
348 | #ifdef LSB_FIRST |
9115e7d2 |
349 | uint32 tb=*(uint32 *)(target+n); |
350 | if(!(t&0x00000080) && (!(t&0x00000040) || (tb&0x00000040))) { // have sprite pixel AND (normal sprite OR behind bg with no bg) |
351 | tb &= ~0x000000ff; tb |= t & 0x000000ff; |
98733207 |
352 | } |
353 | |
9115e7d2 |
354 | if(!(t&0x00008000) && (!(t&0x00004000) || (tb&0x00004000))) { |
355 | tb &= ~0x0000ff00; tb |= t & 0x0000ff00; |
98733207 |
356 | } |
357 | |
9115e7d2 |
358 | if(!(t&0x00800000) && (!(t&0x00400000) || (tb&0x00400000))) { |
359 | tb &= ~0x00ff0000; tb |= t & 0x00ff0000; |
98733207 |
360 | } |
361 | |
9115e7d2 |
362 | if(!(t&0x80000000) && (!(t&0x40000000) || (tb&0x40000000))) { |
363 | tb &= ~0xff000000; tb |= t & 0xff000000; |
98733207 |
364 | } |
9115e7d2 |
365 | *(uint32 *)(target+n)=tb; |
98733207 |
366 | #else |
367 | if(!(t&0x80000000)) |
368 | { |
369 | if(!(t&0x40)) // Normal sprite |
370 | P[n]=sprlinebuf[n]; |
371 | else if(P[n]&64) // behind bg sprite |
372 | P[n]=sprlinebuf[n]; |
373 | } |
374 | |
375 | if(!(t&0x800000)) |
376 | { |
377 | if(!(t&0x4000)) // Normal sprite |
378 | P[n+1]=(sprlinebuf+1)[n]; |
379 | else if(P[n+1]&64) // behind bg sprite |
380 | P[n+1]=(sprlinebuf+1)[n]; |
381 | } |
382 | |
383 | if(!(t&0x8000)) |
384 | { |
385 | if(!(t&0x400000)) // Normal sprite |
386 | P[n+2]=(sprlinebuf+2)[n]; |
387 | else if(P[n+2]&64) // behind bg sprite |
388 | P[n+2]=(sprlinebuf+2)[n]; |
389 | } |
390 | |
391 | if(!(t&0x80)) |
392 | { |
393 | if(!(t&0x40000000)) // Normal sprite |
394 | P[n+3]=(sprlinebuf+3)[n]; |
395 | else if(P[n+3]&64) // behind bg sprite |
396 | P[n+3]=(sprlinebuf+3)[n]; |
397 | } |
398 | #endif |
399 | } |
400 | } |
401 | n+=4; |
402 | if(n) goto loopskie; |
403 | } |
404 | } |
405 | |
406 | |
407 | |
408 | |
409 | |
410 | /* |
411 | void FetchSpriteData(void) |
412 | { |
413 | uint8 ns,sb; |
414 | SPR *spr; |
415 | uint8 H; |
416 | int n; |
417 | int vofs; |
418 | uint8 P0=PPU[0]; |
419 | |
9115e7d2 |
420 | |
98733207 |
421 | spr=(SPR *)SPRAM; |
422 | H=8; |
423 | |
424 | ns=sb=0; |
425 | |
426 | vofs=(unsigned int)(P0&0x8&(((P0&0x20)^0x20)>>2))<<9; |
427 | H+=(P0&0x20)>>2; |
428 | |
429 | if(!PPU_hook) |
430 | for(n=63;n>=0;n--,spr++) |
431 | { |
432 | if((unsigned int)(scanline-spr->y)>=H) continue; |
433 | //printf("%d, %u\n",scanline,(unsigned int)(scanline-spr->y)); |
434 | if(ns<maxsprites) |
435 | { |
436 | if(n==63) sb=1; |
437 | |
438 | { |
439 | SPRB dst; |
440 | uint8 *C; |
441 | int t; |
442 | unsigned int vadr; |
443 | |
444 | t = (int)scanline-(spr->y); |
445 | |
446 | if (Sprite16) |
447 | vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4); |
448 | else |
449 | vadr = (spr->no<<4)+vofs; |
450 | |
451 | if (spr->atr&V_FLIP) |
452 | { |
453 | vadr+=7; |
454 | vadr-=t; |
455 | vadr+=(P0&0x20)>>1; |
456 | vadr-=t&8; |
457 | } |
458 | else |
459 | { |
460 | vadr+=t; |
461 | vadr+=t&8; |
462 | } |
463 | |
9115e7d2 |
464 | // Fix this geniestage hack |
98733207 |
465 | if(MMC5Hack && geniestage!=1) C = MMC5SPRVRAMADR(vadr); |
466 | else C = VRAMADR(vadr); |
467 | |
9115e7d2 |
468 | |
98733207 |
469 | dst.ca[0]=C[0]; |
470 | dst.ca[1]=C[8]; |
471 | dst.x=spr->x; |
472 | dst.atr=spr->atr; |
473 | |
474 | *(uint32 *)&SPRBUF[ns<<2]=*(uint32 *)&dst; |
475 | } |
476 | |
477 | ns++; |
478 | } |
479 | else |
480 | { |
481 | PPU_status|=0x20; |
482 | break; |
483 | } |
484 | } |
485 | else |
486 | for(n=63;n>=0;n--,spr++) |
487 | { |
488 | if((unsigned int)(scanline-spr->y)>=H) continue; |
489 | |
490 | if(ns<maxsprites) |
491 | { |
492 | if(n==63) sb=1; |
493 | |
494 | { |
495 | SPRB dst; |
496 | uint8 *C; |
497 | int t; |
498 | unsigned int vadr; |
499 | |
500 | t = (int)scanline-(spr->y); |
501 | |
502 | if (Sprite16) |
503 | vadr = ((spr->no&1)<<12) + ((spr->no&0xFE)<<4); |
504 | else |
505 | vadr = (spr->no<<4)+vofs; |
506 | |
507 | if (spr->atr&V_FLIP) |
508 | { |
509 | vadr+=7; |
510 | vadr-=t; |
511 | vadr+=(P0&0x20)>>1; |
512 | vadr-=t&8; |
513 | } |
514 | else |
515 | { |
516 | vadr+=t; |
517 | vadr+=t&8; |
518 | } |
519 | |
520 | if(MMC5Hack) C = MMC5SPRVRAMADR(vadr); |
521 | else C = VRAMADR(vadr); |
522 | dst.ca[0]=C[0]; |
523 | if(ns<8) |
524 | { |
525 | PPU_hook(0x2000); |
526 | PPU_hook(vadr); |
527 | } |
528 | dst.ca[1]=C[8]; |
529 | dst.x=spr->x; |
530 | dst.atr=spr->atr; |
531 | |
532 | |
533 | *(uint32 *)&SPRBUF[ns<<2]=*(uint32 *)&dst; |
534 | } |
535 | |
536 | ns++; |
537 | } |
538 | else |
539 | { |
540 | PPU_status|=0x20; |
541 | break; |
542 | } |
543 | } |
544 | //if(ns>=7) |
545 | //printf("%d %d\n",scanline,ns); |
546 | if(ns>8) PPU_status|=0x20; // Handle case when >8 sprites per |
9115e7d2 |
547 | // scanline option is enabled. |
98733207 |
548 | else if(PPU_hook) |
549 | { |
550 | for(n=0;n<(8-ns);n++) |
551 | { |
552 | PPU_hook(0x2000); |
553 | PPU_hook(vofs); |
554 | } |
555 | } |
556 | numsprites=ns; |
557 | SpriteBlurp=sb; |
558 | } |
559 | |
560 | |
561 | |
562 | void RefreshSprite(uint8 *target) |
563 | { |
9115e7d2 |
564 | |
98733207 |
565 | int n,sprindex; |
566 | SPRB *spr; |
567 | uint8 *P=target; |
568 | |
569 | //if (printed) { printf("SPRB: %d SPR: %d\n", sizeof(SPRB), sizeof(SPR)); printed=0; } |
570 | if(!numsprites) return; |
571 | |
572 | FCEU_dwmemset(sprlinebuf,0x80808080,256); |
573 | |
574 | numsprites--; |
575 | sprindex=numsprites; |
576 | spr = (SPRB*)SPRBUF; |
577 | |
578 | // for(n=nosprites;n>=0;n--,spr--) |
579 | for(n=numsprites;n>=0;n--,sprindex--) |
580 | { |
581 | uint8 J,atr,c1,c2; |
582 | int x=spr[sprindex].x; |
583 | uint8 *C; |
584 | uint8 *VB; |
9115e7d2 |
585 | |
98733207 |
586 | P+=x; |
587 | |
588 | c1=((spr[sprindex].ca[0]>>1)&0x55)|(spr[sprindex].ca[1]&0xAA); |
589 | c2=(spr[sprindex].ca[0]&0x55)|((spr[sprindex].ca[1]<<1)&0xAA); |
590 | |
591 | J=spr[sprindex].ca[0]|spr[sprindex].ca[1]; |
592 | atr=spr[sprindex].atr; |
593 | |
594 | if(J) |
9115e7d2 |
595 | { |
98733207 |
596 | if(n==0 && SpriteBlurp && !(PPU_status&0x40)) |
9115e7d2 |
597 | { |
98733207 |
598 | int z,ze=x+8; |
599 | if(ze>256) {ze=256;} |
600 | if(ScreenON && (scanline<FSettings.FirstSLine || scanline>FSettings.LastSLine |
601 | #ifdef FRAMESKIP |
602 | || FSkip |
603 | #endif |
604 | )) |
605 | // nothing wrong with this |
606 | BGRender(target); |
607 | |
608 | if(!(atr&H_FLIP)) |
609 | { |
610 | for(z=x;z<ze;z++) |
611 | { |
612 | if(J&(0x80>>(z-x))) |
613 | { |
614 | if(!(target[z]&64)) |
615 | tosprite=z; |
616 | } |
617 | } |
618 | } |
619 | else |
620 | { |
621 | for(z=x;z<ze;z++) |
622 | { |
623 | if(J&(1<<(z-x))) |
624 | { |
625 | if(!(target[z]&64)) |
626 | tosprite=z; |
627 | } |
628 | } |
629 | } |
630 | //FCEU_DispMessage("%d, %d:%d",scanline,x,tosprite); |
631 | } |
632 | |
633 | //C = sprlinebuf+(uint8)x; |
634 | C = &(sprlinebuf[(uint8)x]); |
635 | VB = (PALRAM+0x10)+((atr&3)<<2); |
636 | |
9115e7d2 |
637 | if(atr&SP_BACK) |
98733207 |
638 | { |
639 | if (atr&H_FLIP) |
640 | { |
641 | if (J&0x02) C[1]=VB[c1&3]|0x40; |
642 | if (J&0x01) *C=VB[c2&3]|0x40; |
643 | c1>>=2;c2>>=2; |
644 | if (J&0x08) C[3]=VB[c1&3]|0x40; |
645 | if (J&0x04) C[2]=VB[c2&3]|0x40; |
646 | c1>>=2;c2>>=2; |
647 | if (J&0x20) C[5]=VB[c1&3]|0x40; |
648 | if (J&0x10) C[4]=VB[c2&3]|0x40; |
649 | c1>>=2;c2>>=2; |
650 | if (J&0x80) C[7]=VB[c1]|0x40; |
651 | if (J&0x40) C[6]=VB[c2]|0x40; |
652 | } else { |
653 | if (J&0x02) C[6]=VB[c1&3]|0x40; |
654 | if (J&0x01) C[7]=VB[c2&3]|0x40; |
655 | c1>>=2;c2>>=2; |
656 | if (J&0x08) C[4]=VB[c1&3]|0x40; |
657 | if (J&0x04) C[5]=VB[c2&3]|0x40; |
658 | c1>>=2;c2>>=2; |
659 | if (J&0x20) C[2]=VB[c1&3]|0x40; |
660 | if (J&0x10) C[3]=VB[c2&3]|0x40; |
661 | c1>>=2;c2>>=2; |
662 | if (J&0x80) *C=VB[c1]|0x40; |
663 | if (J&0x40) C[1]=VB[c2]|0x40; |
664 | } |
665 | } else { |
666 | if (atr&H_FLIP) |
667 | { |
668 | if (J&0x02) C[1]=VB[(c1&3)]; |
669 | if (J&0x01) *C=VB[(c2&3)]; |
670 | c1>>=2;c2>>=2; |
671 | if (J&0x08) C[3]=VB[(c1&3)]; |
672 | if (J&0x04) C[2]=VB[(c2&3)]; |
673 | c1>>=2;c2>>=2; |
674 | if (J&0x20) C[5]=VB[(c1&3)]; |
675 | if (J&0x10) C[4]=VB[(c2&3)]; |
676 | c1>>=2;c2>>=2; |
677 | if (J&0x80) C[7]=VB[c1]; |
678 | if (J&0x40) C[6]=VB[c2]; |
9115e7d2 |
679 | }else{ |
98733207 |
680 | if (J&0x02) C[6]=VB[(c1&3)]; |
681 | if (J&0x01) C[7]=VB[(c2&3)]; |
682 | c1>>=2;c2>>=2; |
683 | if (J&0x08) C[4]=VB[(c1&3)]; |
684 | if (J&0x04) C[5]=VB[(c2&3)]; |
685 | c1>>=2;c2>>=2; |
686 | if (J&0x20) C[2]=VB[(c1&3)]; |
687 | if (J&0x10) C[3]=VB[(c2&3)]; |
688 | c1>>=2;c2>>=2; |
689 | if (J&0x80) *C=VB[c1]; |
690 | if (J&0x40) C[1]=VB[c2]; |
691 | } |
692 | } |
693 | } |
694 | P-=x; |
695 | } |
696 | |
697 | numsprites=0; |
698 | #ifdef FRAMESKIP |
699 | if(FSkip) return; |
700 | #endif |
701 | |
702 | { |
703 | uint8 n=((PPU[1]&4)^4)<<1; |
704 | loopskie: |
705 | { |
706 | uint32 t=*((uint32 *)(&(sprlinebuf[n]))); |
707 | if(t!=0x80808080) |
708 | { |
709 | #ifdef LSB_FIRST |
710 | if(!(t&0x80)) |
711 | { |
712 | if(!(t&0x40)) // Normal sprite |
713 | P[n]=sprlinebuf[n]; |
714 | else if(P[n]&64) // behind bg sprite |
715 | P[n]=sprlinebuf[n]; |
716 | } |
717 | |
718 | if(!(t&0x8000)) |
719 | { |
720 | if(!(t&0x4000)) // Normal sprite |
721 | P[n+1]=(sprlinebuf+1)[n]; |
722 | else if(P[n+1]&64) // behind bg sprite |
723 | P[n+1]=(sprlinebuf+1)[n]; |
724 | } |
725 | |
726 | if(!(t&0x800000)) |
727 | { |
728 | if(!(t&0x400000)) // Normal sprite |
729 | P[n+2]=(sprlinebuf+2)[n]; |
730 | else if(P[n+2]&64) // behind bg sprite |
731 | P[n+2]=(sprlinebuf+2)[n]; |
732 | } |
733 | |
734 | if(!(t&0x80000000)) |
735 | { |
736 | if(!(t&0x40000000)) // Normal sprite |
737 | P[n+3]=(sprlinebuf+3)[n]; |
738 | else if(P[n+3]&64) // behind bg sprite |
739 | P[n+3]=(sprlinebuf+3)[n]; |
740 | } |
741 | #else |
742 | if(!(t&0x80000000)) |
743 | { |
744 | if(!(t&0x40)) // Normal sprite |
745 | P[n]=sprlinebuf[n]; |
746 | else if(P[n]&64) // behind bg sprite |
747 | P[n]=sprlinebuf[n]; |
748 | } |
749 | |
750 | if(!(t&0x800000)) |
751 | { |
752 | if(!(t&0x4000)) // Normal sprite |
753 | P[n+1]=(sprlinebuf+1)[n]; |
754 | else if(P[n+1]&64) // behind bg sprite |
755 | P[n+1]=(sprlinebuf+1)[n]; |
756 | } |
757 | |
758 | if(!(t&0x8000)) |
759 | { |
760 | if(!(t&0x400000)) // Normal sprite |
761 | P[n+2]=(sprlinebuf+2)[n]; |
762 | else if(P[n+2]&64) // behind bg sprite |
763 | P[n+2]=(sprlinebuf+2)[n]; |
764 | } |
765 | |
766 | if(!(t&0x80)) |
767 | { |
768 | if(!(t&0x40000000)) // Normal sprite |
769 | P[n+3]=(sprlinebuf+3)[n]; |
770 | else if(P[n+3]&64) // behind bg sprite |
771 | P[n+3]=(sprlinebuf+3)[n]; |
772 | } |
773 | #endif |
774 | } |
775 | } |
776 | n+=4; |
777 | if(n) goto loopskie; |
778 | } |
779 | } |
780 | |
781 | |
782 | */ |