view src/gba/GBAGfx.h @ 395:6ab872c5a7e7

set H for real
author Robert McIntyre <rlm@mit.edu>
date Fri, 13 Apr 2012 04:37:12 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 #ifndef VBA_GBA_GFX_H
2 #define VBA_GBA_GFX_H
4 #if _MSC_VER > 1000
5 #pragma once
6 #endif // _MSC_VER > 1000
8 #include "../Port.h"
9 #include "GBA.h"
10 #include "GBAGlobals.h"
12 //#define SPRITE_DEBUG
14 void gfxDrawTextScreen(u16, u16, u16, u32 *);
15 void gfxDrawRotScreen(u16,
16 u16, u16,
17 u16, u16,
18 u16, u16,
19 u16, u16,
20 int&, int&,
21 int,
22 u32 *);
23 void gfxDrawRotScreen16Bit(u16,
24 u16, u16,
25 u16, u16,
26 u16, u16,
27 u16, u16,
28 int&, int&,
29 int,
30 u32 *);
31 void gfxDrawRotScreen256(u16,
32 u16, u16,
33 u16, u16,
34 u16, u16,
35 u16, u16,
36 int&, int&,
37 int,
38 u32 *);
39 void gfxDrawRotScreen16Bit160(u16,
40 u16, u16,
41 u16, u16,
42 u16, u16,
43 u16, u16,
44 int&, int&,
45 int,
46 u32 *);
47 void gfxDrawSprites(u32 *);
48 void gfxIncreaseBrightness(u32 *line, int coeff);
49 void gfxDecreaseBrightness(u32 *line, int coeff);
50 void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb);
52 void mode0RenderLine();
53 void mode0RenderLineNoWindow();
54 void mode0RenderLineAll();
56 void mode1RenderLine();
57 void mode1RenderLineNoWindow();
58 void mode1RenderLineAll();
60 void mode2RenderLine();
61 void mode2RenderLineNoWindow();
62 void mode2RenderLineAll();
64 void mode3RenderLine();
65 void mode3RenderLineNoWindow();
66 void mode3RenderLineAll();
68 void mode4RenderLine();
69 void mode4RenderLineNoWindow();
70 void mode4RenderLineAll();
72 void mode5RenderLine();
73 void mode5RenderLineNoWindow();
74 void mode5RenderLineAll();
76 extern int coeff[32];
78 #define LINE_BUFFER_OVERFLOW_LEEWAY (512-240)
80 extern u32 line0[240+LINE_BUFFER_OVERFLOW_LEEWAY];
81 extern u32 line1[240+LINE_BUFFER_OVERFLOW_LEEWAY];
82 extern u32 line2[240+LINE_BUFFER_OVERFLOW_LEEWAY];
83 extern u32 line3[240+LINE_BUFFER_OVERFLOW_LEEWAY];
84 extern u32 lineOBJ[240+LINE_BUFFER_OVERFLOW_LEEWAY];
85 extern u32 lineOBJWin[240+LINE_BUFFER_OVERFLOW_LEEWAY];
86 extern u32 lineMix[240+LINE_BUFFER_OVERFLOW_LEEWAY];
87 extern bool gfxInWin0[240+LINE_BUFFER_OVERFLOW_LEEWAY];
88 extern bool gfxInWin1[240+LINE_BUFFER_OVERFLOW_LEEWAY];
90 extern int gfxBG2Changed;
91 extern int gfxBG3Changed;
93 extern int gfxBG2X;
94 extern int gfxBG2Y;
95 extern int gfxBG2LastX;
96 extern int gfxBG2LastY;
97 extern int gfxBG3X;
98 extern int gfxBG3Y;
99 extern int gfxBG3LastX;
100 extern int gfxBG3LastY;
101 extern int gfxLastVCOUNT;
103 inline void gfxClearArray(u32 *array)
104 {
105 for (int i = 0; i < 240; i++)
106 {
107 *array++ = 0x80000000;
108 }
109 }
111 inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
112 u32 *line)
113 {
114 u16 *palette = (u16 *)paletteRAM;
115 u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000];
116 u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800];
117 u32 prio = ((control & 3)<<25) + 0x1000000;
118 int sizeX = 256;
119 int sizeY = 256;
120 switch ((control >> 14) & 3)
121 {
122 case 0:
123 break;
124 case 1:
125 sizeX = 512;
126 break;
127 case 2:
128 sizeY = 512;
129 break;
130 case 3:
131 sizeX = 512;
132 sizeY = 512;
133 break;
134 }
136 int maskX = sizeX-1;
137 int maskY = sizeY-1;
139 bool mosaicOn = (control & 0x40) ? true : false;
141 int xxx = hofs & maskX;
142 int yyy = (vofs + VCOUNT) & maskY;
143 int mosaicX = (MOSAIC & 0x000F)+1;
144 int mosaicY = ((MOSAIC & 0x00F0)>>4)+1;
146 if (mosaicOn)
147 {
148 if ((VCOUNT % mosaicY) != 0)
149 {
150 mosaicY = (VCOUNT / mosaicY) * mosaicY;
151 yyy = (vofs + mosaicY) & maskY;
152 }
153 }
155 if (yyy > 255 && sizeY > 256)
156 {
157 yyy &= 255;
158 screenBase += 0x400;
159 if (sizeX > 256)
160 screenBase += 0x400;
161 }
163 int yshift = ((yyy>>3)<<5);
164 if ((control) & 0x80)
165 {
166 u16 *screenSource = screenBase + 0x400 * (xxx>>8) + ((xxx & 255)>>3) + yshift;
167 for (int x = 0; x < 240; x++)
168 {
169 u16 data = READ16LE(screenSource);
171 int tile = data & 0x3FF;
172 int tileX = (xxx & 7);
173 int tileY = yyy & 7;
175 if (data & 0x0400)
176 tileX = 7 - tileX;
177 if (data & 0x0800)
178 tileY = 7 - tileY;
180 u8 color = charBase[tile * 64 + tileY * 8 + tileX];
182 line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000;
184 if (data & 0x0400)
185 {
186 if (tileX == 0)
187 screenSource++;
188 }
189 else if (tileX == 7)
190 screenSource++;
191 xxx++;
192 if (xxx == 256)
193 {
194 if (sizeX > 256)
195 screenSource = screenBase + 0x400 + yshift;
196 else
197 {
198 screenSource = screenBase + yshift;
199 xxx = 0;
200 }
201 }
202 else if (xxx >= sizeX)
203 {
204 xxx = 0;
205 screenSource = screenBase + yshift;
206 }
207 }
208 }
209 else
210 {
211 u16 *screenSource = screenBase + 0x400*(xxx>>8)+((xxx&255)>>3) +
212 yshift;
213 for (int x = 0; x < 240; x++)
214 {
215 u16 data = READ16LE(screenSource);
217 int tile = data & 0x3FF;
218 int tileX = (xxx & 7);
219 int tileY = yyy & 7;
221 if (data & 0x0400)
222 tileX = 7 - tileX;
223 if (data & 0x0800)
224 tileY = 7 - tileY;
226 u8 color = charBase[(tile<<5) + (tileY<<2) + (tileX>>1)];
228 if (tileX & 1)
229 {
230 color = (color >> 4);
231 }
232 else
233 {
234 color &= 0x0F;
235 }
237 int pal = (READ16LE(screenSource)>>8) & 0xF0;
238 line[x] = color ? (READ16LE(&palette[pal + color])|prio) : 0x80000000;
240 if (data & 0x0400)
241 {
242 if (tileX == 0)
243 screenSource++;
244 }
245 else if (tileX == 7)
246 screenSource++;
247 xxx++;
248 if (xxx == 256)
249 {
250 if (sizeX > 256)
251 screenSource = screenBase + 0x400 + yshift;
252 else
253 {
254 screenSource = screenBase + yshift;
255 xxx = 0;
256 }
257 }
258 else if (xxx >= sizeX)
259 {
260 xxx = 0;
261 screenSource = screenBase + yshift;
262 }
263 }
264 }
265 if (mosaicOn)
266 {
267 if (mosaicX > 1)
268 {
269 int m = 1;
270 for (int i = 0; i < 239; i++)
271 {
272 line[i+1] = line[i];
273 m++;
274 if (m == mosaicX)
275 {
276 m = 1;
277 i++;
278 }
279 }
280 }
281 }
282 }
284 inline void gfxDrawRotScreen(u16 control,
285 u16 x_l, u16 x_h,
286 u16 y_l, u16 y_h,
287 u16 pa, u16 pb,
288 u16 pc, u16 pd,
289 int& currentX, int& currentY,
290 int changed,
291 u32 *line)
292 {
293 u16 *palette = (u16 *)paletteRAM;
294 u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000];
295 u8 * screenBase = (u8 *)&vram[((control >> 8) & 0x1f) * 0x800];
296 int prio = ((control & 3) << 25) + 0x1000000;
298 int sizeX = 128;
299 int sizeY = 128;
300 switch ((control >> 14) & 3)
301 {
302 case 0:
303 break;
304 case 1:
305 sizeX = sizeY = 256;
306 break;
307 case 2:
308 sizeX = sizeY = 512;
309 break;
310 case 3:
311 sizeX = sizeY = 1024;
312 break;
313 }
315 int dx = pa & 0x7FFF;
316 if (pa & 0x8000)
317 dx |= 0xFFFF8000;
318 int dmx = pb & 0x7FFF;
319 if (pb & 0x8000)
320 dmx |= 0xFFFF8000;
321 int dy = pc & 0x7FFF;
322 if (pc & 0x8000)
323 dy |= 0xFFFF8000;
324 int dmy = pd & 0x7FFFF;
325 if (pd & 0x8000)
326 dmy |= 0xFFFF8000;
328 if (VCOUNT == 0)
329 changed = 3;
331 if (changed & 1)
332 {
333 currentX = (x_l) | ((x_h & 0x07FF)<<16);
334 if (x_h & 0x0800)
335 currentX |= 0xF8000000;
336 }
337 else
338 {
339 currentX += dmx;
340 }
342 if (changed & 2)
343 {
344 currentY = (y_l) | ((y_h & 0x07FF)<<16);
345 if (y_h & 0x0800)
346 currentY |= 0xF8000000;
347 }
348 else
349 {
350 currentY += dmy;
351 }
353 int realX = currentX;
354 int realY = currentY;
356 if (control & 0x40)
357 {
358 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
359 int y = (VCOUNT % mosaicY);
360 realX -= y*dmx;
361 realY -= y*dmy;
362 }
364 int xxx = (realX >> 8);
365 int yyy = (realY >> 8);
367 if (control & 0x2000)
368 {
369 xxx %= sizeX;
370 yyy %= sizeY;
371 if (xxx < 0)
372 xxx += sizeX;
373 if (yyy < 0)
374 yyy += sizeY;
375 }
377 if (control & 0x80)
378 {
379 for (int x = 0; x < 240; x++)
380 {
381 if (xxx < 0 ||
382 yyy < 0 ||
383 xxx >= sizeX ||
384 yyy >= sizeY)
385 {
386 line[x] = 0x80000000;
387 }
388 else
389 {
390 int tile = screenBase[(xxx>>3) + (yyy>>3)*(sizeX>>3)];
392 int tileX = (xxx & 7);
393 int tileY = yyy & 7;
395 u8 color = charBase[(tile<<6) + (tileY<<3) + tileX];
397 line[x] = color ? (READ16LE(&palette[color])|prio) : 0x80000000;
398 }
399 realX += dx;
400 realY += dy;
402 xxx = (realX >> 8);
403 yyy = (realY >> 8);
405 if (control & 0x2000)
406 {
407 xxx %= sizeX;
408 yyy %= sizeY;
409 if (xxx < 0)
410 xxx += sizeX;
411 if (yyy < 0)
412 yyy += sizeY;
413 }
414 }
415 }
416 else
417 {
418 for (int x = 0; x < 240; x++)
419 {
420 if (xxx < 0 ||
421 yyy < 0 ||
422 xxx >= sizeX ||
423 yyy >= sizeY)
424 {
425 line[x] = 0x80000000;
426 }
427 else
428 {
429 int tile = screenBase[(xxx>>3) + (yyy>>3)*(sizeX>>3)];
431 int tileX = (xxx & 7);
432 int tileY = yyy & 7;
434 u8 color = charBase[(tile<<6) + (tileY<<3) + tileX];
436 line[x] = color ? (READ16LE(&palette[color])|prio) : 0x80000000;
437 }
438 realX += dx;
439 realY += dy;
441 xxx = (realX >> 8);
442 yyy = (realY >> 8);
444 if (control & 0x2000)
445 {
446 xxx %= sizeX;
447 yyy %= sizeY;
448 if (xxx < 0)
449 xxx += sizeX;
450 if (yyy < 0)
451 yyy += sizeY;
452 }
453 }
454 }
456 if (control & 0x40)
457 {
458 int mosaicX = (MOSAIC & 0xF) + 1;
459 if (mosaicX > 1)
460 {
461 int m = 1;
462 for (int i = 0; i < 239; i++)
463 {
464 line[i+1] = line[i];
465 m++;
466 if (m == mosaicX)
467 {
468 m = 1;
469 i++;
470 }
471 }
472 }
473 }
474 }
476 inline void gfxDrawRotScreen16Bit(u16 control,
477 u16 x_l, u16 x_h,
478 u16 y_l, u16 y_h,
479 u16 pa, u16 pb,
480 u16 pc, u16 pd,
481 int& currentX, int& currentY,
482 int changed,
483 u32 *line)
484 {
485 u16 *screenBase = (u16 *)&vram[0];
486 int prio = ((control & 3) << 25) + 0x1000000;
487 int sizeX = 240;
488 int sizeY = 160;
490 int startX = (x_l) | ((x_h & 0x07FF)<<16);
491 if (x_h & 0x0800)
492 startX |= 0xF8000000;
493 int startY = (y_l) | ((y_h & 0x07FF)<<16);
494 if (y_h & 0x0800)
495 startY |= 0xF8000000;
497 int dx = pa & 0x7FFF;
498 if (pa & 0x8000)
499 dx |= 0xFFFF8000;
500 int dmx = pb & 0x7FFF;
501 if (pb & 0x8000)
502 dmx |= 0xFFFF8000;
503 int dy = pc & 0x7FFF;
504 if (pc & 0x8000)
505 dy |= 0xFFFF8000;
506 int dmy = pd & 0x7FFFF;
507 if (pd & 0x8000)
508 dmy |= 0xFFFF8000;
510 if (VCOUNT == 0)
511 changed = 3;
513 if (changed & 1)
514 {
515 currentX = (x_l) | ((x_h & 0x07FF)<<16);
516 if (x_h & 0x0800)
517 currentX |= 0xF8000000;
518 }
519 else
520 currentX += dmx;
522 if (changed & 2)
523 {
524 currentY = (y_l) | ((y_h & 0x07FF)<<16);
525 if (y_h & 0x0800)
526 currentY |= 0xF8000000;
527 }
528 else
529 {
530 currentY += dmy;
531 }
533 int realX = currentX;
534 int realY = currentY;
536 if (control & 0x40)
537 {
538 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
539 int y = (VCOUNT % mosaicY);
540 realX -= y*dmx;
541 realY -= y*dmy;
542 }
544 int xxx = (realX >> 8);
545 int yyy = (realY >> 8);
547 for (int x = 0; x < 240; x++)
548 {
549 if (xxx < 0 ||
550 yyy < 0 ||
551 xxx >= sizeX ||
552 yyy >= sizeY)
553 {
554 line[x] = 0x80000000;
555 }
556 else
557 {
558 line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
559 }
560 realX += dx;
561 realY += dy;
563 xxx = (realX >> 8);
564 yyy = (realY >> 8);
565 }
567 if (control & 0x40)
568 {
569 int mosaicX = (MOSAIC & 0xF) + 1;
570 if (mosaicX > 1)
571 {
572 int m = 1;
573 for (int i = 0; i < 239; i++)
574 {
575 line[i+1] = line[i];
576 m++;
577 if (m == mosaicX)
578 {
579 m = 1;
580 i++;
581 }
582 }
583 }
584 }
585 }
587 inline void gfxDrawRotScreen256(u16 control,
588 u16 x_l, u16 x_h,
589 u16 y_l, u16 y_h,
590 u16 pa, u16 pb,
591 u16 pc, u16 pd,
592 int &currentX, int& currentY,
593 int changed,
594 u32 *line)
595 {
596 u16 *palette = (u16 *)paletteRAM;
597 u8 * screenBase = (DISPCNT & 0x0010) ? &vram[0xA000] : &vram[0x0000];
598 int prio = ((control & 3) << 25) + 0x1000000;
599 int sizeX = 240;
600 int sizeY = 160;
602 int startX = (x_l) | ((x_h & 0x07FF)<<16);
603 if (x_h & 0x0800)
604 startX |= 0xF8000000;
605 int startY = (y_l) | ((y_h & 0x07FF)<<16);
606 if (y_h & 0x0800)
607 startY |= 0xF8000000;
609 int dx = pa & 0x7FFF;
610 if (pa & 0x8000)
611 dx |= 0xFFFF8000;
612 int dmx = pb & 0x7FFF;
613 if (pb & 0x8000)
614 dmx |= 0xFFFF8000;
615 int dy = pc & 0x7FFF;
616 if (pc & 0x8000)
617 dy |= 0xFFFF8000;
618 int dmy = pd & 0x7FFFF;
619 if (pd & 0x8000)
620 dmy |= 0xFFFF8000;
622 if (VCOUNT == 0)
623 changed = 3;
625 if (changed & 1)
626 {
627 currentX = (x_l) | ((x_h & 0x07FF)<<16);
628 if (x_h & 0x0800)
629 currentX |= 0xF8000000;
630 }
631 else
632 {
633 currentX += dmx;
634 }
636 if (changed & 2)
637 {
638 currentY = (y_l) | ((y_h & 0x07FF)<<16);
639 if (y_h & 0x0800)
640 currentY |= 0xF8000000;
641 }
642 else
643 {
644 currentY += dmy;
645 }
647 int realX = currentX;
648 int realY = currentY;
650 if (control & 0x40)
651 {
652 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
653 int y = (VCOUNT / mosaicY) * mosaicY;
654 realX = startX + y*dmx;
655 realY = startY + y*dmy;
656 }
658 int xxx = (realX >> 8);
659 int yyy = (realY >> 8);
661 for (int x = 0; x < 240; x++)
662 {
663 if (xxx < 0 ||
664 yyy < 0 ||
665 xxx >= sizeX ||
666 yyy >= sizeY)
667 {
668 line[x] = 0x80000000;
669 }
670 else
671 {
672 u8 color = screenBase[yyy * 240 + xxx];
674 line[x] = color ? (READ16LE(&palette[color])|prio) : 0x80000000;
675 }
676 realX += dx;
677 realY += dy;
679 xxx = (realX >> 8);
680 yyy = (realY >> 8);
681 }
683 if (control & 0x40)
684 {
685 int mosaicX = (MOSAIC & 0xF) + 1;
686 if (mosaicX > 1)
687 {
688 int m = 1;
689 for (int i = 0; i < 239; i++)
690 {
691 line[i+1] = line[i];
692 m++;
693 if (m == mosaicX)
694 {
695 m = 1;
696 i++;
697 }
698 }
699 }
700 }
701 }
703 inline void gfxDrawRotScreen16Bit160(u16 control,
704 u16 x_l, u16 x_h,
705 u16 y_l, u16 y_h,
706 u16 pa, u16 pb,
707 u16 pc, u16 pd,
708 int& currentX, int& currentY,
709 int changed,
710 u32 *line)
711 {
712 u16 *screenBase = (DISPCNT & 0x0010) ? (u16 *)&vram[0xa000] :
713 (u16 *)&vram[0];
714 int prio = ((control & 3) << 25) + 0x1000000;
715 int sizeX = 160;
716 int sizeY = 128;
718 int startX = (x_l) | ((x_h & 0x07FF)<<16);
719 if (x_h & 0x0800)
720 startX |= 0xF8000000;
721 int startY = (y_l) | ((y_h & 0x07FF)<<16);
722 if (y_h & 0x0800)
723 startY |= 0xF8000000;
725 int dx = pa & 0x7FFF;
726 if (pa & 0x8000)
727 dx |= 0xFFFF8000;
728 int dmx = pb & 0x7FFF;
729 if (pb & 0x8000)
730 dmx |= 0xFFFF8000;
731 int dy = pc & 0x7FFF;
732 if (pc & 0x8000)
733 dy |= 0xFFFF8000;
734 int dmy = pd & 0x7FFFF;
735 if (pd & 0x8000)
736 dmy |= 0xFFFF8000;
738 if (VCOUNT == 0)
739 changed = 3;
741 if (changed & 1)
742 {
743 currentX = (x_l) | ((x_h & 0x07FF)<<16);
744 if (x_h & 0x0800)
745 currentX |= 0xF8000000;
746 }
747 else
748 {
749 currentX += dmx;
750 }
752 if (changed & 2)
753 {
754 currentY = (y_l) | ((y_h & 0x07FF)<<16);
755 if (y_h & 0x0800)
756 currentY |= 0xF8000000;
757 }
758 else
759 {
760 currentY += dmy;
761 }
763 int realX = currentX;
764 int realY = currentY;
766 if (control & 0x40)
767 {
768 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
769 int y = (VCOUNT / mosaicY) * mosaicY;
770 realX = startX + y*dmx;
771 realY = startY + y*dmy;
772 }
774 int xxx = (realX >> 8);
775 int yyy = (realY >> 8);
777 for (int x = 0; x < 240; x++)
778 {
779 if (xxx < 0 ||
780 yyy < 0 ||
781 xxx >= sizeX ||
782 yyy >= sizeY)
783 {
784 line[x] = 0x80000000;
785 }
786 else
787 {
788 line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
789 }
790 realX += dx;
791 realY += dy;
793 xxx = (realX >> 8);
794 yyy = (realY >> 8);
795 }
797 if (control & 0x40)
798 {
799 int mosaicX = (MOSAIC & 0xF) + 1;
800 if (mosaicX > 1)
801 {
802 int m = 1;
803 for (int i = 0; i < 239; i++)
804 {
805 line[i+1] = line[i];
806 m++;
807 if (m == mosaicX)
808 {
809 m = 1;
810 i++;
811 }
812 }
813 }
814 }
815 }
817 inline void gfxDrawSprites(u32 *lineOBJ)
818 {
819 int m = 0;
820 gfxClearArray(lineOBJ);
821 if (layerEnable & 0x1000)
822 {
823 u16 *sprites = (u16 *)oam;
824 u16 *spritePalette = &((u16 *)paletteRAM)[256];
825 int mosaicY = ((MOSAIC & 0xF000)>>12) + 1;
826 int mosaicX = ((MOSAIC & 0xF00)>>8) + 1;
827 for (int x = 0; x < 128; x++)
828 {
829 u16 a0 = READ16LE(sprites++);
830 u16 a1 = READ16LE(sprites++);
831 u16 a2 = READ16LE(sprites++);
832 sprites++;
834 // ignore OBJ-WIN
835 if ((a0 & 0x0c00) == 0x0800)
836 continue;
838 int sizeY = 8;
839 int sizeX = 8;
841 switch (((a0 >>12) & 0x0c)|(a1>>14))
842 {
843 case 0:
844 break;
845 case 1:
846 sizeX = sizeY = 16;
847 break;
848 case 2:
849 sizeX = sizeY = 32;
850 break;
851 case 3:
852 sizeX = sizeY = 64;
853 break;
854 case 4:
855 sizeX = 16;
856 break;
857 case 5:
858 sizeX = 32;
859 break;
860 case 6:
861 sizeX = 32;
862 sizeY = 16;
863 break;
864 case 7:
865 sizeX = 64;
866 sizeY = 32;
867 break;
868 case 8:
869 sizeY = 16;
870 break;
871 case 9:
872 sizeY = 32;
873 break;
874 case 10:
875 sizeX = 16;
876 sizeY = 32;
877 break;
878 case 11:
879 sizeX = 32;
880 sizeY = 64;
881 break;
882 default:
883 continue;
884 }
886 #ifdef SPRITE_DEBUG
887 int maskX = sizeX-1;
888 int maskY = sizeY-1;
889 #endif
891 int sy = (a0 & 255);
893 if (sy > 160)
894 sy -= 256;
896 if (a0 & 0x0100)
897 {
898 int fieldX = sizeX;
899 int fieldY = sizeY;
900 if (a0 & 0x0200)
901 {
902 fieldX <<= 1;
903 fieldY <<= 1;
904 }
906 int t = VCOUNT - sy;
907 if ((t >= 0) && (t < fieldY))
908 {
909 int sx = (a1 & 0x1FF);
910 if ((sx < 240) || (((sx + fieldX) & 511) < 240))
911 {
912 // int t2 = t - (fieldY >> 1);
913 int rot = (a1 >> 9) & 0x1F;
914 u16 *OAM = (u16 *)oam;
915 int dx = READ16LE(&OAM[3 + (rot << 4)]);
916 if (dx & 0x8000)
917 dx |= 0xFFFF8000;
918 int dmx = READ16LE(&OAM[7 + (rot << 4)]);
919 if (dmx & 0x8000)
920 dmx |= 0xFFFF8000;
921 int dy = READ16LE(&OAM[11 + (rot << 4)]);
922 if (dy & 0x8000)
923 dy |= 0xFFFF8000;
924 int dmy = READ16LE(&OAM[15 + (rot << 4)]);
925 if (dmy & 0x8000)
926 dmy |= 0xFFFF8000;
928 if (a0 & 0x1000)
929 {
930 t -= (t % mosaicY);
931 }
933 int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx
934 + t * dmx;
935 int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
936 + t * dmy;
938 u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
940 if (a0 & 0x2000)
941 {
942 int c = (a2 & 0x3FF);
943 if ((DISPCNT & 7) > 2 && (c < 512))
944 continue;
945 int inc = 32;
946 if (DISPCNT & 0x40)
947 inc = sizeX >> 2;
948 else
949 c &= 0x3FE;
950 for (int x = 0; x < fieldX; x++)
951 {
952 int xxx = realX >> 8;
953 int yyy = realY >> 8;
955 if (xxx < 0 || xxx >= sizeX ||
956 yyy < 0 || yyy >= sizeY ||
957 sx >= 240)
958 ;
959 else
960 {
961 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
962 + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
963 (xxx & 7))&0x7FFF)];
964 if ((color == 0) && (((prio >> 25)&3) <
965 ((lineOBJ[sx]>>25)&3)))
966 {
967 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
968 if ((a0 & 0x1000) && m)
969 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
970 }
971 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
972 {
973 lineOBJ[sx] = READ16LE(&spritePalette[color]) | prio;
974 if ((a0 & 0x1000) && m)
975 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
976 }
978 if (a0 & 0x1000)
979 {
980 m++;
981 if (m == mosaicX)
982 m = 0;
983 }
984 #ifdef SPRITE_DEBUG
985 if (t == 0 || t == maskY || x == 0 || x == maskX)
986 lineOBJ[sx] = 0x001F;
987 #endif
988 }
989 sx = (sx+1)&511;;
990 realX += dx;
991 realY += dy;
992 }
993 }
994 else
995 {
996 int c = (a2 & 0x3FF);
997 if ((DISPCNT & 7) > 2 && (c < 512))
998 continue;
1000 int inc = 32;
1001 if (DISPCNT & 0x40)
1002 inc = sizeX >> 3;
1003 int palette = (a2 >> 8) & 0xF0;
1004 for (int x = 0; x < fieldX; x++)
1006 int xxx = realX >> 8;
1007 int yyy = realY >> 8;
1008 if (xxx < 0 || xxx >= sizeX ||
1009 yyy < 0 || yyy >= sizeY ||
1010 sx >= 240)
1012 else
1014 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
1015 + ((yyy & 7)<<2) + ((xxx >> 3)<<5) +
1016 ((xxx & 7)>>1))&0x7FFF)];
1017 if (xxx & 1)
1018 color >>= 4;
1019 else
1020 color &= 0x0F;
1022 if ((color == 0) && (((prio >> 25)&3) <
1023 ((lineOBJ[sx]>>25)&3)))
1025 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
1026 if ((a0 & 0x1000) && m)
1027 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
1029 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
1031 lineOBJ[sx] = READ16LE(&spritePalette[palette+color]) | prio;
1032 if ((a0 & 0x1000) && m)
1033 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
1036 if ((a0 & 0x1000) && m)
1038 m++;
1039 if (m == mosaicX)
1040 m = 0;
1043 #ifdef SPRITE_DEBUG
1044 if (t == 0 || t == maskY || x == 0 || x == maskX)
1045 lineOBJ[sx] = 0x001F;
1046 #endif
1047 sx = (sx+1)&511;;
1048 realX += dx;
1049 realY += dy;
1055 else
1057 int t = VCOUNT - sy;
1058 if ((t >= 0) && (t < sizeY))
1060 int sx = (a1 & 0x1FF);
1061 if (((sx < 240) || (((sx+sizeX)&511) < 240)) && !(a0 & 0x0200))
1063 if (a0 & 0x2000)
1065 if (a1 & 0x2000)
1066 t = sizeY - t - 1;
1067 int c = (a2 & 0x3FF);
1068 if ((DISPCNT & 7) > 2 && (c < 512))
1069 continue;
1071 int inc = 32;
1072 if (DISPCNT & 0x40)
1074 inc = sizeX >> 2;
1076 else
1078 c &= 0x3FE;
1080 int xxx = 0;
1081 if (a1 & 0x1000)
1082 xxx = sizeX-1;
1084 if (a0 & 0x1000)
1086 t -= (t % mosaicY);
1089 int address = 0x10000 + ((((c+ (t>>3) * inc) << 5)
1090 + ((t & 7) << 3) + ((xxx>>3)<<6) + (xxx & 7)) & 0x7FFF);
1092 if (a1 & 0x1000)
1093 xxx = 7;
1094 u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
1096 for (int xx = 0; xx < sizeX; xx++)
1098 if (sx < 240)
1100 u8 color = vram[address];
1101 if ((color == 0) && (((prio >> 25)&3) <
1102 ((lineOBJ[sx]>>25)&3)))
1104 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
1105 if ((a0 & 0x1000) && m)
1106 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
1108 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
1110 lineOBJ[sx] = READ16LE(&spritePalette[color]) | prio;
1111 if ((a0 & 0x1000) && m)
1112 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
1115 if (a0 & 0x1000)
1117 m++;
1118 if (m == mosaicX)
1119 m = 0;
1122 #ifdef SPRITE_DEBUG
1123 if (t == 0 || t == maskY || xx == 0 || xx == maskX)
1124 lineOBJ[sx] = 0x001F;
1125 #endif
1128 sx = (sx+1) & 511;
1129 if (a1 & 0x1000)
1131 xxx--;
1132 address--;
1133 if (xxx == -1)
1135 address -= 56;
1136 xxx = 7;
1138 if (address < 0x10000)
1139 address += 0x8000;
1141 else
1143 xxx++;
1144 address++;
1145 if (xxx == 8)
1147 address += 56;
1148 xxx = 0;
1150 if (address > 0x17fff)
1151 address -= 0x8000;
1155 else
1157 if (a1 & 0x2000)
1158 t = sizeY - t - 1;
1159 int c = (a2 & 0x3FF);
1160 if ((DISPCNT & 7) > 2 && (c < 512))
1161 continue;
1163 int inc = 32;
1164 if (DISPCNT & 0x40)
1166 inc = sizeX >> 3;
1168 int xxx = 0;
1169 if (a1 & 0x1000)
1170 xxx = sizeX - 1;
1172 if (a0 & 0x1000)
1174 t -= (t % mosaicY);
1177 int address = 0x10000 + ((((c + (t>>3) * inc)<<5)
1178 + ((t & 7)<<2) + ((xxx>>3)<<5) + ((xxx & 7) >> 1))&0x7FFF);
1179 u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
1180 int palette = (a2 >> 8) & 0xF0;
1181 if (a1 & 0x1000)
1183 xxx = 7;
1184 for (int xx = sizeX - 1; xx >= 0; xx--)
1186 if (sx < 240)
1188 u8 color = vram[address];
1189 if (xx & 1)
1191 color = (color >> 4);
1193 else
1194 color &= 0x0F;
1196 if ((color == 0) && (((prio >> 25)&3) <
1197 ((lineOBJ[sx]>>25)&3)))
1199 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
1200 if ((a0 & 0x1000) && m)
1201 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
1203 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
1205 lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;
1206 if ((a0 & 0x1000) && m)
1207 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
1210 if (a0 & 0x1000)
1212 m++;
1213 if (m == mosaicX)
1214 m = 0;
1216 #ifdef SPRITE_DEBUG
1217 if (t == 0 || t == maskY || xx == 0 || xx == maskX)
1218 lineOBJ[sx] = 0x001F;
1219 #endif
1220 sx = (sx+1) & 511;
1221 xxx--;
1222 if (!(xx & 1))
1223 address--;
1224 if (xxx == -1)
1226 xxx = 7;
1227 address -= 28;
1229 if (address < 0x10000)
1230 address += 0x8000;
1233 else
1235 for (int xx = 0; xx < sizeX; xx++)
1237 if (sx < 240)
1239 u8 color = vram[address];
1240 if (xx & 1)
1242 color = (color >> 4);
1244 else
1245 color &= 0x0F;
1247 if ((color == 0) && (((prio >> 25)&3) <
1248 ((lineOBJ[sx]>>25)&3)))
1250 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
1251 if ((a0 & 0x1000) && m)
1252 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
1254 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
1256 lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;
1257 if ((a0 & 0x1000) && m)
1258 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
1261 if (a0 & 0x1000)
1263 m++;
1264 if (m == mosaicX)
1265 m = 0;
1267 #ifdef SPRITE_DEBUG
1268 if (t == 0 || t == maskY || xx == 0 || xx == maskX)
1269 lineOBJ[sx] = 0x001F;
1270 #endif
1271 sx = (sx+1) & 511;
1272 xxx++;
1273 if (xx & 1)
1274 address++;
1275 if (xxx == 8)
1277 address += 28;
1278 xxx = 0;
1280 if (address > 0x17fff)
1281 address -= 0x8000;
1292 inline void gfxDrawOBJWin(u32 *lineOBJWin)
1294 gfxClearArray(lineOBJWin);
1295 if (layerEnable & 0x8000)
1297 u16 *sprites = (u16 *)oam;
1298 // u16 *spritePalette = &((u16 *)paletteRAM)[256];
1299 for (int x = 0; x < 128; x++)
1301 u16 a0 = READ16LE(sprites++);
1302 u16 a1 = READ16LE(sprites++);
1303 u16 a2 = READ16LE(sprites++);
1304 sprites++;
1306 // ignore non OBJ-WIN
1307 if ((a0 & 0x0c00) != 0x0800)
1308 continue;
1310 int sizeY = 8;
1311 int sizeX = 8;
1313 switch (((a0 >>12) & 0x0c)|(a1>>14))
1315 case 0:
1316 break;
1317 case 1:
1318 sizeX = sizeY = 16;
1319 break;
1320 case 2:
1321 sizeX = sizeY = 32;
1322 break;
1323 case 3:
1324 sizeX = sizeY = 64;
1325 break;
1326 case 4:
1327 sizeX = 16;
1328 break;
1329 case 5:
1330 sizeX = 32;
1331 break;
1332 case 6:
1333 sizeX = 32;
1334 sizeY = 16;
1335 break;
1336 case 7:
1337 sizeX = 64;
1338 sizeY = 32;
1339 break;
1340 case 8:
1341 sizeY = 16;
1342 break;
1343 case 9:
1344 sizeY = 32;
1345 break;
1346 case 10:
1347 sizeX = 16;
1348 sizeY = 32;
1349 break;
1350 case 11:
1351 sizeX = 32;
1352 sizeY = 64;
1353 break;
1354 default:
1355 continue;
1358 int sy = (a0 & 255);
1360 if (sy > 160)
1361 sy -= 256;
1363 if (a0 & 0x0100)
1365 int fieldX = sizeX;
1366 int fieldY = sizeY;
1367 if (a0 & 0x0200)
1369 fieldX <<= 1;
1370 fieldY <<= 1;
1373 int t = VCOUNT - sy;
1374 if ((t >= 0) && (t < fieldY))
1376 int sx = (a1 & 0x1FF);
1377 if ((sx < 240) || (((sx + fieldX) & 511) < 240))
1379 // int t2 = t - (fieldY >> 1);
1380 int rot = (a1 >> 9) & 0x1F;
1381 u16 *OAM = (u16 *)oam;
1382 int dx = READ16LE(&OAM[3 + (rot << 4)]);
1383 if (dx & 0x8000)
1384 dx |= 0xFFFF8000;
1385 int dmx = READ16LE(&OAM[7 + (rot << 4)]);
1386 if (dmx & 0x8000)
1387 dmx |= 0xFFFF8000;
1388 int dy = READ16LE(&OAM[11 + (rot << 4)]);
1389 if (dy & 0x8000)
1390 dy |= 0xFFFF8000;
1391 int dmy = READ16LE(&OAM[15 + (rot << 4)]);
1392 if (dmy & 0x8000)
1393 dmy |= 0xFFFF8000;
1395 int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx
1396 + t * dmx;
1397 int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
1398 + t * dmy;
1400 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
1402 if (a0 & 0x2000)
1404 int c = (a2 & 0x3FF);
1405 if ((DISPCNT & 7) > 2 && (c < 512))
1406 continue;
1407 int inc = 32;
1408 if (DISPCNT & 0x40)
1409 inc = sizeX >> 2;
1410 else
1411 c &= 0x3FE;
1412 for (int x = 0; x < fieldX; x++)
1414 int xxx = realX >> 8;
1415 int yyy = realY >> 8;
1417 if (xxx < 0 || xxx >= sizeX ||
1418 yyy < 0 || yyy >= sizeY)
1419 {}
1420 else
1422 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
1423 + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
1424 (xxx & 7))&0x7fff)];
1425 if (color)
1427 lineOBJWin[sx] = 1;
1430 sx = (sx+1)&511;;
1431 realX += dx;
1432 realY += dy;
1435 else
1437 int c = (a2 & 0x3FF);
1438 if ((DISPCNT & 7) > 2 && (c < 512))
1439 continue;
1441 int inc = 32;
1442 if (DISPCNT & 0x40)
1443 inc = sizeX >> 3;
1444 // int palette = (a2 >> 8) & 0xF0;
1445 for (int x = 0; x < fieldX; x++)
1447 int xxx = realX >> 8;
1448 int yyy = realY >> 8;
1450 // if(x == 0 || x == (sizeX-1) ||
1451 // t == 0 || t == (sizeY-1)) {
1452 // lineOBJ[sx] = 0x001F | prio;
1453 // } else {
1454 if (xxx < 0 || xxx >= sizeX ||
1455 yyy < 0 || yyy >= sizeY)
1456 {}
1457 else
1459 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
1460 + ((yyy & 7)<<2) + ((xxx >> 3)<<5) +
1461 ((xxx & 7)>>1))&0x7fff)];
1462 if (xxx & 1)
1463 color >>= 4;
1464 else
1465 color &= 0x0F;
1467 if (color)
1469 lineOBJWin[sx] = 1;
1472 // }
1473 sx = (sx+1)&511;;
1474 realX += dx;
1475 realY += dy;
1481 else
1483 int t = VCOUNT - sy;
1484 if ((t >= 0) && (t < sizeY))
1486 int sx = (a1 & 0x1FF);
1487 if (((sx < 240) || (((sx+sizeX)&511) < 240)) && !(a0 & 0x0200))
1489 if (a0 & 0x2000)
1491 if (a1 & 0x2000)
1492 t = sizeY - t - 1;
1493 int c = (a2 & 0x3FF);
1494 if ((DISPCNT & 7) > 2 && (c < 512))
1495 continue;
1497 int inc = 32;
1498 if (DISPCNT & 0x40)
1500 inc = sizeX >> 2;
1502 else
1504 c &= 0x3FE;
1506 int xxx = 0;
1507 if (a1 & 0x1000)
1508 xxx = sizeX-1;
1509 int address = 0x10000 + ((((c+ (t>>3) * inc) << 5)
1510 + ((t & 7) << 3) + ((xxx>>3)<<6) + (xxx & 7))&0x7fff);
1511 if (a1 & 0x1000)
1512 xxx = 7;
1513 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
1514 for (int xx = 0; xx < sizeX; xx++)
1516 if (sx < 240)
1518 u8 color = vram[address];
1519 if (color)
1521 lineOBJWin[sx] = 1;
1525 sx = (sx+1) & 511;
1526 if (a1 & 0x1000)
1528 xxx--;
1529 address--;
1530 if (xxx == -1)
1532 address -= 56;
1533 xxx = 7;
1535 if (address < 0x10000)
1536 address += 0x8000;
1538 else
1540 xxx++;
1541 address++;
1542 if (xxx == 8)
1544 address += 56;
1545 xxx = 0;
1547 if (address > 0x17fff)
1548 address -= 0x8000;
1552 else
1554 if (a1 & 0x2000)
1555 t = sizeY - t - 1;
1556 int c = (a2 & 0x3FF);
1557 if ((DISPCNT & 7) > 2 && (c < 512))
1558 continue;
1560 int inc = 32;
1561 if (DISPCNT & 0x40)
1563 inc = sizeX >> 3;
1565 int xxx = 0;
1566 if (a1 & 0x1000)
1567 xxx = sizeX - 1;
1568 int address = 0x10000 + ((((c + (t>>3) * inc)<<5)
1569 + ((t & 7)<<2) + ((xxx>>3)<<5) + ((xxx & 7) >> 1))&0x7fff);
1570 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
1571 // int palette = (a2 >> 8) & 0xF0;
1572 if (a1 & 0x1000)
1574 xxx = 7;
1575 for (int xx = sizeX - 1; xx >= 0; xx--)
1577 if (sx < 240)
1579 u8 color = vram[address];
1580 if (xx & 1)
1582 color = (color >> 4);
1584 else
1585 color &= 0x0F;
1587 if (color)
1589 lineOBJWin[sx] = 1;
1592 sx = (sx+1) & 511;
1593 xxx--;
1594 if (!(xx & 1))
1595 address--;
1596 if (xxx == -1)
1598 xxx = 7;
1599 address -= 28;
1601 if (address < 0x10000)
1602 address += 0x8000;
1605 else
1607 for (int xx = 0; xx < sizeX; xx++)
1609 if (sx < 240)
1611 u8 color = vram[address];
1612 if (xx & 1)
1614 color = (color >> 4);
1616 else
1617 color &= 0x0F;
1619 if (color)
1621 lineOBJWin[sx] = 1;
1624 sx = (sx+1) & 511;
1625 xxx++;
1626 if (xx & 1)
1627 address++;
1628 if (xxx == 8)
1630 address += 28;
1631 xxx = 0;
1633 if (address > 0x17fff)
1634 address -= 0x8000;
1645 inline u32 gfxIncreaseBrightness(u32 color, int coeff)
1647 int r = (color & 0x1F);
1648 int g = ((color >> 5) & 0x1F);
1649 int b = ((color >> 10) & 0x1F);
1651 r = r + (((31 - r) * coeff) >> 4);
1652 g = g + (((31 - g) * coeff) >> 4);
1653 b = b + (((31 - b) * coeff) >> 4);
1654 if (r > 31)
1655 r = 31;
1656 if (g > 31)
1657 g = 31;
1658 if (b > 31)
1659 b = 31;
1660 color = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
1661 return color;
1664 inline void gfxIncreaseBrightness(u32 *line, int coeff)
1666 for (int x = 0; x < 240; x++)
1668 u32 color = *line;
1669 int r = (color & 0x1F);
1670 int g = ((color >> 5) & 0x1F);
1671 int b = ((color >> 10) & 0x1F);
1673 r = r + (((31 - r) * coeff) >> 4);
1674 g = g + (((31 - g) * coeff) >> 4);
1675 b = b + (((31 - b) * coeff) >> 4);
1676 if (r > 31)
1677 r = 31;
1678 if (g > 31)
1679 g = 31;
1680 if (b > 31)
1681 b = 31;
1682 *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
1686 inline u32 gfxDecreaseBrightness(u32 color, int coeff)
1688 int r = (color & 0x1F);
1689 int g = ((color >> 5) & 0x1F);
1690 int b = ((color >> 10) & 0x1F);
1692 r = r - ((r * coeff) >> 4);
1693 g = g - ((g * coeff) >> 4);
1694 b = b - ((b * coeff) >> 4);
1695 if (r < 0)
1696 r = 0;
1697 if (g < 0)
1698 g = 0;
1699 if (b < 0)
1700 b = 0;
1701 color = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
1703 return color;
1706 inline void gfxDecreaseBrightness(u32 *line, int coeff)
1708 for (int x = 0; x < 240; x++)
1710 u32 color = *line;
1711 int r = (color & 0x1F);
1712 int g = ((color >> 5) & 0x1F);
1713 int b = ((color >> 10) & 0x1F);
1715 r = r - ((r * coeff) >> 4);
1716 g = g - ((g * coeff) >> 4);
1717 b = b - ((b * coeff) >> 4);
1718 if (r < 0)
1719 r = 0;
1720 if (g < 0)
1721 g = 0;
1722 if (b < 0)
1723 b = 0;
1724 *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
1728 inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)
1730 if (color < 0x80000000)
1732 int r = (color & 0x1F);
1733 int g = ((color >> 5) & 0x1F);
1734 int b = ((color >> 10) & 0x1F);
1735 int r0 = (color2 & 0x1F);
1736 int g0 = ((color2 >> 5) & 0x1F);
1737 int b0 = ((color2 >> 10) & 0x1F);
1739 r = ((r * ca) >> 4) + ((r0 * cb) >> 4);
1740 g = ((g * ca) >> 4) + ((g0 * cb) >> 4);
1741 b = ((b * ca) >> 4) + ((b0 * cb) >> 4);
1743 if (r > 31)
1744 r = 31;
1745 if (g > 31)
1746 g = 31;
1747 if (b > 31)
1748 b = 31;
1750 return (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
1752 return color;
1755 inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)
1757 for (int x = 0; x < 240; x++)
1759 u32 color = *ta;
1760 if (color < 0x80000000)
1762 int r = (color & 0x1F);
1763 int g = ((color >> 5) & 0x1F);
1764 int b = ((color >> 10) & 0x1F);
1765 u32 color2 = (*tb++);
1766 int r0 = (color2 & 0x1F);
1767 int g0 = ((color2 >> 5) & 0x1F);
1768 int b0 = ((color2 >> 10) & 0x1F);
1770 r = ((r * ca) >> 4) + ((r0 * cb) >> 4);
1771 g = ((g * ca) >> 4) + ((g0 * cb) >> 4);
1772 b = ((b * ca) >> 4) + ((b0 * cb) >> 4);
1774 if (r > 31)
1775 r = 31;
1776 if (g > 31)
1777 g = 31;
1778 if (b > 31)
1779 b = 31;
1781 *ta++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
1783 else
1785 ta++;
1786 tb++;
1791 #endif // VBA_GBA_GFX_H