Mercurial > vba-clojure
view src/gba/GBAGfx.h @ 232:e1dd3624d295
preliminary map data region in cart.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 24 Mar 2012 15:21:24 -0500 |
parents | f9f4f1b99eed |
children |
line wrap: on
line source
1 #ifndef VBA_GBA_GFX_H2 #define VBA_GBA_GFX_H4 #if _MSC_VER > 10005 #pragma once6 #endif // _MSC_VER > 10008 #include "../Port.h"9 #include "GBA.h"10 #include "GBAGlobals.h"12 //#define SPRITE_DEBUG14 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 else197 {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 else210 {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 else233 {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 else253 {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 else338 {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 else349 {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 else389 {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 else417 {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 else428 {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 else520 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 else529 {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 else557 {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 ¤tX, 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 else632 {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 else643 {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 else671 {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 else748 {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 else759 {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 else787 {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-WIN835 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_DEBUG887 int maskX = sizeX-1;888 int maskY = sizeY-1;889 #endif891 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)*dmx934 + t * dmx;935 int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy936 + 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 else949 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 else960 {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_DEBUG985 if (t == 0 || t == maskY || x == 0 || x == maskX)986 lineOBJ[sx] = 0x001F;987 #endif988 }989 sx = (sx+1)&511;;990 realX += dx;991 realY += dy;992 }993 }994 else995 {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++)1005 {1006 int xxx = realX >> 8;1007 int yyy = realY >> 8;1008 if (xxx < 0 || xxx >= sizeX ||1009 yyy < 0 || yyy >= sizeY ||1010 sx >= 240)1011 ;1012 else1013 {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 else1020 color &= 0x0F;1022 if ((color == 0) && (((prio >> 25)&3) <1023 ((lineOBJ[sx]>>25)&3)))1024 {1025 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;1026 if ((a0 & 0x1000) && m)1027 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;1028 }1029 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))1030 {1031 lineOBJ[sx] = READ16LE(&spritePalette[palette+color]) | prio;1032 if ((a0 & 0x1000) && m)1033 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;1034 }1035 }1036 if ((a0 & 0x1000) && m)1037 {1038 m++;1039 if (m == mosaicX)1040 m = 0;1041 }1043 #ifdef SPRITE_DEBUG1044 if (t == 0 || t == maskY || x == 0 || x == maskX)1045 lineOBJ[sx] = 0x001F;1046 #endif1047 sx = (sx+1)&511;;1048 realX += dx;1049 realY += dy;1050 }1051 }1052 }1053 }1054 }1055 else1056 {1057 int t = VCOUNT - sy;1058 if ((t >= 0) && (t < sizeY))1059 {1060 int sx = (a1 & 0x1FF);1061 if (((sx < 240) || (((sx+sizeX)&511) < 240)) && !(a0 & 0x0200))1062 {1063 if (a0 & 0x2000)1064 {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)1073 {1074 inc = sizeX >> 2;1075 }1076 else1077 {1078 c &= 0x3FE;1079 }1080 int xxx = 0;1081 if (a1 & 0x1000)1082 xxx = sizeX-1;1084 if (a0 & 0x1000)1085 {1086 t -= (t % mosaicY);1087 }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++)1097 {1098 if (sx < 240)1099 {1100 u8 color = vram[address];1101 if ((color == 0) && (((prio >> 25)&3) <1102 ((lineOBJ[sx]>>25)&3)))1103 {1104 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;1105 if ((a0 & 0x1000) && m)1106 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;1107 }1108 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))1109 {1110 lineOBJ[sx] = READ16LE(&spritePalette[color]) | prio;1111 if ((a0 & 0x1000) && m)1112 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;1113 }1115 if (a0 & 0x1000)1116 {1117 m++;1118 if (m == mosaicX)1119 m = 0;1120 }1122 #ifdef SPRITE_DEBUG1123 if (t == 0 || t == maskY || xx == 0 || xx == maskX)1124 lineOBJ[sx] = 0x001F;1125 #endif1126 }1128 sx = (sx+1) & 511;1129 if (a1 & 0x1000)1130 {1131 xxx--;1132 address--;1133 if (xxx == -1)1134 {1135 address -= 56;1136 xxx = 7;1137 }1138 if (address < 0x10000)1139 address += 0x8000;1140 }1141 else1142 {1143 xxx++;1144 address++;1145 if (xxx == 8)1146 {1147 address += 56;1148 xxx = 0;1149 }1150 if (address > 0x17fff)1151 address -= 0x8000;1152 }1153 }1154 }1155 else1156 {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)1165 {1166 inc = sizeX >> 3;1167 }1168 int xxx = 0;1169 if (a1 & 0x1000)1170 xxx = sizeX - 1;1172 if (a0 & 0x1000)1173 {1174 t -= (t % mosaicY);1175 }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)1182 {1183 xxx = 7;1184 for (int xx = sizeX - 1; xx >= 0; xx--)1185 {1186 if (sx < 240)1187 {1188 u8 color = vram[address];1189 if (xx & 1)1190 {1191 color = (color >> 4);1192 }1193 else1194 color &= 0x0F;1196 if ((color == 0) && (((prio >> 25)&3) <1197 ((lineOBJ[sx]>>25)&3)))1198 {1199 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;1200 if ((a0 & 0x1000) && m)1201 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;1202 }1203 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))1204 {1205 lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;1206 if ((a0 & 0x1000) && m)1207 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;1208 }1209 }1210 if (a0 & 0x1000)1211 {1212 m++;1213 if (m == mosaicX)1214 m = 0;1215 }1216 #ifdef SPRITE_DEBUG1217 if (t == 0 || t == maskY || xx == 0 || xx == maskX)1218 lineOBJ[sx] = 0x001F;1219 #endif1220 sx = (sx+1) & 511;1221 xxx--;1222 if (!(xx & 1))1223 address--;1224 if (xxx == -1)1225 {1226 xxx = 7;1227 address -= 28;1228 }1229 if (address < 0x10000)1230 address += 0x8000;1231 }1232 }1233 else1234 {1235 for (int xx = 0; xx < sizeX; xx++)1236 {1237 if (sx < 240)1238 {1239 u8 color = vram[address];1240 if (xx & 1)1241 {1242 color = (color >> 4);1243 }1244 else1245 color &= 0x0F;1247 if ((color == 0) && (((prio >> 25)&3) <1248 ((lineOBJ[sx]>>25)&3)))1249 {1250 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;1251 if ((a0 & 0x1000) && m)1252 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;1253 }1254 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))1255 {1256 lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;1257 if ((a0 & 0x1000) && m)1258 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;1259 }1260 }1261 if (a0 & 0x1000)1262 {1263 m++;1264 if (m == mosaicX)1265 m = 0;1266 }1267 #ifdef SPRITE_DEBUG1268 if (t == 0 || t == maskY || xx == 0 || xx == maskX)1269 lineOBJ[sx] = 0x001F;1270 #endif1271 sx = (sx+1) & 511;1272 xxx++;1273 if (xx & 1)1274 address++;1275 if (xxx == 8)1276 {1277 address += 28;1278 xxx = 0;1279 }1280 if (address > 0x17fff)1281 address -= 0x8000;1282 }1283 }1284 }1285 }1286 }1287 }1288 }1289 }1290 }1292 inline void gfxDrawOBJWin(u32 *lineOBJWin)1293 {1294 gfxClearArray(lineOBJWin);1295 if (layerEnable & 0x8000)1296 {1297 u16 *sprites = (u16 *)oam;1298 // u16 *spritePalette = &((u16 *)paletteRAM)[256];1299 for (int x = 0; x < 128; x++)1300 {1301 u16 a0 = READ16LE(sprites++);1302 u16 a1 = READ16LE(sprites++);1303 u16 a2 = READ16LE(sprites++);1304 sprites++;1306 // ignore non OBJ-WIN1307 if ((a0 & 0x0c00) != 0x0800)1308 continue;1310 int sizeY = 8;1311 int sizeX = 8;1313 switch (((a0 >>12) & 0x0c)|(a1>>14))1314 {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;1356 }1358 int sy = (a0 & 255);1360 if (sy > 160)1361 sy -= 256;1363 if (a0 & 0x0100)1364 {1365 int fieldX = sizeX;1366 int fieldY = sizeY;1367 if (a0 & 0x0200)1368 {1369 fieldX <<= 1;1370 fieldY <<= 1;1371 }1373 int t = VCOUNT - sy;1374 if ((t >= 0) && (t < fieldY))1375 {1376 int sx = (a1 & 0x1FF);1377 if ((sx < 240) || (((sx + fieldX) & 511) < 240))1378 {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)*dmx1396 + t * dmx;1397 int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy1398 + t * dmy;1400 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);1402 if (a0 & 0x2000)1403 {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 else1411 c &= 0x3FE;1412 for (int x = 0; x < fieldX; x++)1413 {1414 int xxx = realX >> 8;1415 int yyy = realY >> 8;1417 if (xxx < 0 || xxx >= sizeX ||1418 yyy < 0 || yyy >= sizeY)1419 {}1420 else1421 {1422 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)1423 + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +1424 (xxx & 7))&0x7fff)];1425 if (color)1426 {1427 lineOBJWin[sx] = 1;1428 }1429 }1430 sx = (sx+1)&511;;1431 realX += dx;1432 realY += dy;1433 }1434 }1435 else1436 {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++)1446 {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 else1458 {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 else1465 color &= 0x0F;1467 if (color)1468 {1469 lineOBJWin[sx] = 1;1470 }1471 }1472 // }1473 sx = (sx+1)&511;;1474 realX += dx;1475 realY += dy;1476 }1477 }1478 }1479 }1480 }1481 else1482 {1483 int t = VCOUNT - sy;1484 if ((t >= 0) && (t < sizeY))1485 {1486 int sx = (a1 & 0x1FF);1487 if (((sx < 240) || (((sx+sizeX)&511) < 240)) && !(a0 & 0x0200))1488 {1489 if (a0 & 0x2000)1490 {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)1499 {1500 inc = sizeX >> 2;1501 }1502 else1503 {1504 c &= 0x3FE;1505 }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++)1515 {1516 if (sx < 240)1517 {1518 u8 color = vram[address];1519 if (color)1520 {1521 lineOBJWin[sx] = 1;1522 }1523 }1525 sx = (sx+1) & 511;1526 if (a1 & 0x1000)1527 {1528 xxx--;1529 address--;1530 if (xxx == -1)1531 {1532 address -= 56;1533 xxx = 7;1534 }1535 if (address < 0x10000)1536 address += 0x8000;1537 }1538 else1539 {1540 xxx++;1541 address++;1542 if (xxx == 8)1543 {1544 address += 56;1545 xxx = 0;1546 }1547 if (address > 0x17fff)1548 address -= 0x8000;1549 }1550 }1551 }1552 else1553 {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)1562 {1563 inc = sizeX >> 3;1564 }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)1573 {1574 xxx = 7;1575 for (int xx = sizeX - 1; xx >= 0; xx--)1576 {1577 if (sx < 240)1578 {1579 u8 color = vram[address];1580 if (xx & 1)1581 {1582 color = (color >> 4);1583 }1584 else1585 color &= 0x0F;1587 if (color)1588 {1589 lineOBJWin[sx] = 1;1590 }1591 }1592 sx = (sx+1) & 511;1593 xxx--;1594 if (!(xx & 1))1595 address--;1596 if (xxx == -1)1597 {1598 xxx = 7;1599 address -= 28;1600 }1601 if (address < 0x10000)1602 address += 0x8000;1603 }1604 }1605 else1606 {1607 for (int xx = 0; xx < sizeX; xx++)1608 {1609 if (sx < 240)1610 {1611 u8 color = vram[address];1612 if (xx & 1)1613 {1614 color = (color >> 4);1615 }1616 else1617 color &= 0x0F;1619 if (color)1620 {1621 lineOBJWin[sx] = 1;1622 }1623 }1624 sx = (sx+1) & 511;1625 xxx++;1626 if (xx & 1)1627 address++;1628 if (xxx == 8)1629 {1630 address += 28;1631 xxx = 0;1632 }1633 if (address > 0x17fff)1634 address -= 0x8000;1635 }1636 }1637 }1638 }1639 }1640 }1641 }1642 }1643 }1645 inline u32 gfxIncreaseBrightness(u32 color, int coeff)1646 {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;1662 }1664 inline void gfxIncreaseBrightness(u32 *line, int coeff)1665 {1666 for (int x = 0; x < 240; x++)1667 {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;1683 }1684 }1686 inline u32 gfxDecreaseBrightness(u32 color, int coeff)1687 {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;1704 }1706 inline void gfxDecreaseBrightness(u32 *line, int coeff)1707 {1708 for (int x = 0; x < 240; x++)1709 {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;1725 }1726 }1728 inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)1729 {1730 if (color < 0x80000000)1731 {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;1751 }1752 return color;1753 }1755 inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)1756 {1757 for (int x = 0; x < 240; x++)1758 {1759 u32 color = *ta;1760 if (color < 0x80000000)1761 {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;1782 }1783 else1784 {1785 ta++;1786 tb++;1787 }1788 }1789 }1791 #endif // VBA_GBA_GFX_H