Mercurial > vba-clojure
view src/gba/Mode3.cpp @ 124:f8dadd9478a5
fixed problem with mode transitions
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 17 Mar 2012 01:23:47 -0500 |
parents | f9f4f1b99eed |
children |
line wrap: on
line source
1 #include "GBAGfx.h"2 #include "GBAGlobals.h"4 void mode3RenderLine()5 {6 u16 *palette = (u16 *)paletteRAM;8 if (DISPCNT & 0x80)9 {10 for (int x = 0; x < 240; x++)11 {12 lineMix[x] = 0x7fff;13 }14 gfxLastVCOUNT = VCOUNT;15 return;16 }18 if (layerEnable & 0x0400)19 {20 int changed = gfxBG2Changed;22 if (gfxLastVCOUNT > VCOUNT)23 changed = 3;25 gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,26 BG2Y_L, BG2Y_H, BG2PA, BG2PB,27 BG2PC, BG2PD,28 gfxBG2X, gfxBG2Y, changed,29 line2);30 }32 gfxDrawSprites(lineOBJ);34 u32 background = (READ16LE(&palette[0]) | 0x30000000);36 for (int x = 0; x < 240; x++)37 {38 u32 color = background;39 u8 top = 0x20;41 if (line2[x] < color)42 {43 color = line2[x];44 top = 0x04;45 }47 if ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))48 {49 color = lineOBJ[x];50 top = 0x10;51 }53 if ((top & 0x10) && (color & 0x00010000))54 {55 // semi-transparent OBJ56 u32 back = background;57 u8 top2 = 0x20;59 if (line2[x] < back)60 {61 back = line2[x];62 top2 = 0x04;63 }65 if (top2 & (BLDMOD>>8))66 color = gfxAlphaBlend(color, back,67 coeff[COLEV & 0x1F],68 coeff[(COLEV >> 8) & 0x1F]);69 else70 {71 switch ((BLDMOD >> 6) & 3)72 {73 case 2:74 if (BLDMOD & top)75 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);76 break;77 case 3:78 if (BLDMOD & top)79 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);80 break;81 }82 }83 }85 lineMix[x] = color;86 }87 gfxBG2Changed = 0;88 gfxLastVCOUNT = VCOUNT;89 }91 void mode3RenderLineNoWindow()92 {93 u16 *palette = (u16 *)paletteRAM;95 if (DISPCNT & 0x80)96 {97 for (int x = 0; x < 240; x++)98 {99 lineMix[x] = 0x7fff;100 }101 gfxLastVCOUNT = VCOUNT;102 return;103 }105 if (layerEnable & 0x0400)106 {107 int changed = gfxBG2Changed;109 if (gfxLastVCOUNT > VCOUNT)110 changed = 3;112 gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,113 BG2Y_L, BG2Y_H, BG2PA, BG2PB,114 BG2PC, BG2PD,115 gfxBG2X, gfxBG2Y, changed,116 line2);117 }119 gfxDrawSprites(lineOBJ);121 u32 background = (READ16LE(&palette[0]) | 0x30000000);123 for (int x = 0; x < 240; x++)124 {125 u32 color = background;126 u8 top = 0x20;128 if (line2[x] < color)129 {130 color = line2[x];131 top = 0x04;132 }134 if ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))135 {136 color = lineOBJ[x];137 top = 0x10;138 }140 if (!(color & 0x00010000))141 {142 switch ((BLDMOD >> 6) & 3)143 {144 case 0:145 break;146 case 1:147 {148 if (top & BLDMOD)149 {150 u32 back = background;151 u8 top2 = 0x20;153 if (line2[x] < back)154 {155 if (top != 0x04)156 {157 back = line2[x];158 top2 = 0x04;159 }160 }162 if ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))163 {164 if (top != 0x10)165 {166 back = lineOBJ[x];167 top2 = 0x10;168 }169 }171 if (top2 & (BLDMOD>>8))172 color = gfxAlphaBlend(color, back,173 coeff[COLEV & 0x1F],174 coeff[(COLEV >> 8) & 0x1F]);175 }176 break;177 }178 case 2:179 if (BLDMOD & top)180 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);181 break;182 case 3:183 if (BLDMOD & top)184 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);185 break;186 }187 }188 else189 {190 // semi-transparent OBJ191 u32 back = background;192 u8 top2 = 0x20;194 if (line2[x] < back)195 {196 back = line2[x];197 top2 = 0x04;198 }200 if (top2 & (BLDMOD>>8))201 color = gfxAlphaBlend(color, back,202 coeff[COLEV & 0x1F],203 coeff[(COLEV >> 8) & 0x1F]);204 else205 {206 switch ((BLDMOD >> 6) & 3)207 {208 case 2:209 if (BLDMOD & top)210 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);211 break;212 case 3:213 if (BLDMOD & top)214 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);215 break;216 }217 }218 }220 lineMix[x] = color;221 }222 gfxBG2Changed = 0;223 gfxLastVCOUNT = VCOUNT;224 }226 void mode3RenderLineAll()227 {228 u16 *palette = (u16 *)paletteRAM;230 if (DISPCNT & 0x80)231 {232 for (int x = 0; x < 240; x++)233 {234 lineMix[x] = 0x7fff;235 }236 gfxLastVCOUNT = VCOUNT;237 return;238 }240 bool inWindow0 = false;241 bool inWindow1 = false;243 if (layerEnable & 0x2000)244 {245 u8 v0 = WIN0V >> 8;246 u8 v1 = WIN0V & 255;247 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));248 if (v1 >= v0)249 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);250 else251 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);252 }253 if (layerEnable & 0x4000)254 {255 u8 v0 = WIN1V >> 8;256 u8 v1 = WIN1V & 255;257 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));258 if (v1 >= v0)259 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);260 else261 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);262 }264 if (layerEnable & 0x0400)265 {266 int changed = gfxBG2Changed;268 if (gfxLastVCOUNT > VCOUNT)269 changed = 3;271 gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,272 BG2Y_L, BG2Y_H, BG2PA, BG2PB,273 BG2PC, BG2PD,274 gfxBG2X, gfxBG2Y, changed,275 line2);276 }278 gfxDrawSprites(lineOBJ);279 gfxDrawOBJWin(lineOBJWin);281 u8 inWin0Mask = WININ & 0xFF;282 u8 inWin1Mask = WININ >> 8;283 u8 outMask = WINOUT & 0xFF;285 u32 background = (READ16LE(&palette[0]) | 0x30000000);287 for (int x = 0; x < 240; x++)288 {289 u32 color = background;290 u8 top = 0x20;291 u8 mask = outMask;293 if (!(lineOBJWin[x] & 0x80000000))294 {295 mask = WINOUT >> 8;296 }298 if (inWindow1)299 {300 if (gfxInWin1[x])301 mask = inWin1Mask;302 }304 if (inWindow0)305 {306 if (gfxInWin0[x])307 {308 mask = inWin0Mask;309 }310 }312 if ((mask & 4) && (line2[x] < color))313 {314 color = line2[x];315 top = 0x04;316 }318 if ((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))319 {320 color = lineOBJ[x];321 top = 0x10;322 }324 if (mask & 32)325 {326 if (!(color & 0x00010000))327 {328 switch ((BLDMOD >> 6) & 3)329 {330 case 0:331 break;332 case 1:333 {334 if (top & BLDMOD)335 {336 u32 back = background;337 u8 top2 = 0x20;339 if ((mask & 4) && line2[x] < back)340 {341 if (top != 0x04)342 {343 back = line2[x];344 top2 = 0x04;345 }346 }348 if ((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))349 {350 if (top != 0x10)351 {352 back = lineOBJ[x];353 top2 = 0x10;354 }355 }357 if (top2 & (BLDMOD>>8))358 color = gfxAlphaBlend(color, back,359 coeff[COLEV & 0x1F],360 coeff[(COLEV >> 8) & 0x1F]);361 }362 break;363 }364 case 2:365 if (BLDMOD & top)366 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);367 break;368 case 3:369 if (BLDMOD & top)370 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);371 break;372 }373 }374 else375 {376 // semi-transparent OBJ377 u32 back = background;378 u8 top2 = 0x20;380 if ((mask & 4) && line2[x] < back)381 {382 back = line2[x];383 top2 = 0x04;384 }386 if (top2 & (BLDMOD>>8))387 color = gfxAlphaBlend(color, back,388 coeff[COLEV & 0x1F],389 coeff[(COLEV >> 8) & 0x1F]);390 else391 {392 switch ((BLDMOD >> 6) & 3)393 {394 case 2:395 if (BLDMOD & top)396 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);397 break;398 case 3:399 if (BLDMOD & top)400 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);401 break;402 }403 }404 }405 }406 else if (color & 0x00010000)407 {408 // semi-transparent OBJ409 u32 back = background;410 u8 top2 = 0x20;412 if ((mask & 4) && line2[x] < back)413 {414 back = line2[x];415 top2 = 0x04;416 }418 if (top2 & (BLDMOD>>8))419 color = gfxAlphaBlend(color, back,420 coeff[COLEV & 0x1F],421 coeff[(COLEV >> 8) & 0x1F]);422 else423 {424 switch ((BLDMOD >> 6) & 3)425 {426 case 2:427 if (BLDMOD & top)428 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);429 break;430 case 3:431 if (BLDMOD & top)432 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);433 break;434 }435 }436 }438 lineMix[x] = color;439 }440 gfxBG2Changed = 0;441 gfxLastVCOUNT = VCOUNT;442 }