annotate src/gba/Mode2.cpp @ 124:f8dadd9478a5

fixed problem with mode transitions
author Robert McIntyre <rlm@mit.edu>
date Sat, 17 Mar 2012 01:23:47 -0500 (2012-03-17)
parents f9f4f1b99eed
children
rev   line source
rlm@1 1 #include "GBAGfx.h"
rlm@1 2 #include "GBAGlobals.h"
rlm@1 3
rlm@1 4 void mode2RenderLine()
rlm@1 5 {
rlm@1 6 u16 *palette = (u16 *)paletteRAM;
rlm@1 7
rlm@1 8 if (DISPCNT & 0x80)
rlm@1 9 {
rlm@1 10 for (int x = 0; x < 240; x++)
rlm@1 11 {
rlm@1 12 lineMix[x] = 0x7fff;
rlm@1 13 }
rlm@1 14 gfxLastVCOUNT = VCOUNT;
rlm@1 15 return;
rlm@1 16 }
rlm@1 17
rlm@1 18 if (layerEnable & 0x0400)
rlm@1 19 {
rlm@1 20 int changed = gfxBG2Changed;
rlm@1 21 if (gfxLastVCOUNT > VCOUNT)
rlm@1 22 changed = 3;
rlm@1 23
rlm@1 24 gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
rlm@1 25 BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
rlm@1 26 changed, line2);
rlm@1 27 }
rlm@1 28
rlm@1 29 if (layerEnable & 0x0800)
rlm@1 30 {
rlm@1 31 int changed = gfxBG3Changed;
rlm@1 32 if (gfxLastVCOUNT > VCOUNT)
rlm@1 33 changed = 3;
rlm@1 34
rlm@1 35 gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
rlm@1 36 BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
rlm@1 37 changed, line3);
rlm@1 38 }
rlm@1 39
rlm@1 40 gfxDrawSprites(lineOBJ);
rlm@1 41
rlm@1 42 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
rlm@1 43
rlm@1 44 for (int x = 0; x < 240; x++)
rlm@1 45 {
rlm@1 46 u32 color = backdrop;
rlm@1 47 u8 top = 0x20;
rlm@1 48
rlm@1 49 if ((u8)(line2[x]>>24) < (u8)(color >> 24))
rlm@1 50 {
rlm@1 51 color = line2[x];
rlm@1 52 top = 0x04;
rlm@1 53 }
rlm@1 54
rlm@1 55 if ((u8)(line3[x]>>24) < (u8)(color >> 24))
rlm@1 56 {
rlm@1 57 color = line3[x];
rlm@1 58 top = 0x08;
rlm@1 59 }
rlm@1 60
rlm@1 61 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
rlm@1 62 {
rlm@1 63 color = lineOBJ[x];
rlm@1 64 top = 0x10;
rlm@1 65 }
rlm@1 66
rlm@1 67 if ((top & 0x10) && (color & 0x00010000))
rlm@1 68 {
rlm@1 69 // semi-transparent OBJ
rlm@1 70 u32 back = backdrop;
rlm@1 71 u8 top2 = 0x20;
rlm@1 72
rlm@1 73 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
rlm@1 74 {
rlm@1 75 back = line2[x];
rlm@1 76 top2 = 0x04;
rlm@1 77 }
rlm@1 78
rlm@1 79 if ((u8)(line3[x]>>24) < (u8)(back >> 24))
rlm@1 80 {
rlm@1 81 back = line3[x];
rlm@1 82 top2 = 0x08;
rlm@1 83 }
rlm@1 84
rlm@1 85 if (top2 & (BLDMOD>>8))
rlm@1 86 color = gfxAlphaBlend(color, back,
rlm@1 87 coeff[COLEV & 0x1F],
rlm@1 88 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 89 else
rlm@1 90 {
rlm@1 91 switch ((BLDMOD >> 6) & 3)
rlm@1 92 {
rlm@1 93 case 2:
rlm@1 94 if (BLDMOD & top)
rlm@1 95 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 96 break;
rlm@1 97 case 3:
rlm@1 98 if (BLDMOD & top)
rlm@1 99 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 100 break;
rlm@1 101 }
rlm@1 102 }
rlm@1 103 }
rlm@1 104
rlm@1 105 lineMix[x] = color;
rlm@1 106 }
rlm@1 107 gfxBG2Changed = 0;
rlm@1 108 gfxBG3Changed = 0;
rlm@1 109 gfxLastVCOUNT = VCOUNT;
rlm@1 110 }
rlm@1 111
rlm@1 112 void mode2RenderLineNoWindow()
rlm@1 113 {
rlm@1 114 u16 *palette = (u16 *)paletteRAM;
rlm@1 115
rlm@1 116 if (DISPCNT & 0x80)
rlm@1 117 {
rlm@1 118 for (int x = 0; x < 240; x++)
rlm@1 119 {
rlm@1 120 lineMix[x] = 0x7fff;
rlm@1 121 }
rlm@1 122 gfxLastVCOUNT = VCOUNT;
rlm@1 123 return;
rlm@1 124 }
rlm@1 125
rlm@1 126 if (layerEnable & 0x0400)
rlm@1 127 {
rlm@1 128 int changed = gfxBG2Changed;
rlm@1 129 if (gfxLastVCOUNT > VCOUNT)
rlm@1 130 changed = 3;
rlm@1 131
rlm@1 132 gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
rlm@1 133 BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
rlm@1 134 changed, line2);
rlm@1 135 }
rlm@1 136
rlm@1 137 if (layerEnable & 0x0800)
rlm@1 138 {
rlm@1 139 int changed = gfxBG3Changed;
rlm@1 140 if (gfxLastVCOUNT > VCOUNT)
rlm@1 141 changed = 3;
rlm@1 142
rlm@1 143 gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
rlm@1 144 BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
rlm@1 145 changed, line3);
rlm@1 146 }
rlm@1 147
rlm@1 148 gfxDrawSprites(lineOBJ);
rlm@1 149
rlm@1 150 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
rlm@1 151
rlm@1 152 for (int x = 0; x < 240; x++)
rlm@1 153 {
rlm@1 154 u32 color = backdrop;
rlm@1 155 u8 top = 0x20;
rlm@1 156
rlm@1 157 if ((u8)(line2[x]>>24) < (u8)(color >> 24))
rlm@1 158 {
rlm@1 159 color = line2[x];
rlm@1 160 top = 0x04;
rlm@1 161 }
rlm@1 162
rlm@1 163 if ((u8)(line3[x]>>24) < (u8)(color >> 24))
rlm@1 164 {
rlm@1 165 color = line3[x];
rlm@1 166 top = 0x08;
rlm@1 167 }
rlm@1 168
rlm@1 169 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
rlm@1 170 {
rlm@1 171 color = lineOBJ[x];
rlm@1 172 top = 0x10;
rlm@1 173 }
rlm@1 174
rlm@1 175 if (!(color & 0x00010000))
rlm@1 176 {
rlm@1 177 switch ((BLDMOD >> 6) & 3)
rlm@1 178 {
rlm@1 179 case 0:
rlm@1 180 break;
rlm@1 181 case 1:
rlm@1 182 {
rlm@1 183 if (top & BLDMOD)
rlm@1 184 {
rlm@1 185 u32 back = backdrop;
rlm@1 186 u8 top2 = 0x20;
rlm@1 187
rlm@1 188 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
rlm@1 189 {
rlm@1 190 if (top != 0x04)
rlm@1 191 {
rlm@1 192 back = line2[x];
rlm@1 193 top2 = 0x04;
rlm@1 194 }
rlm@1 195 }
rlm@1 196
rlm@1 197 if ((u8)(line3[x]>>24) < (u8)(back >> 24))
rlm@1 198 {
rlm@1 199 if (top != 0x08)
rlm@1 200 {
rlm@1 201 back = line3[x];
rlm@1 202 top2 = 0x08;
rlm@1 203 }
rlm@1 204 }
rlm@1 205
rlm@1 206 if ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
rlm@1 207 {
rlm@1 208 if (top != 0x10)
rlm@1 209 {
rlm@1 210 back = lineOBJ[x];
rlm@1 211 top2 = 0x10;
rlm@1 212 }
rlm@1 213 }
rlm@1 214
rlm@1 215 if (top2 & (BLDMOD>>8))
rlm@1 216 color = gfxAlphaBlend(color, back,
rlm@1 217 coeff[COLEV & 0x1F],
rlm@1 218 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 219 }
rlm@1 220 break;
rlm@1 221 }
rlm@1 222 case 2:
rlm@1 223 if (BLDMOD & top)
rlm@1 224 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 225 break;
rlm@1 226 case 3:
rlm@1 227 if (BLDMOD & top)
rlm@1 228 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 229 break;
rlm@1 230 }
rlm@1 231 }
rlm@1 232 else
rlm@1 233 {
rlm@1 234 // semi-transparent OBJ
rlm@1 235 u32 back = backdrop;
rlm@1 236 u8 top2 = 0x20;
rlm@1 237
rlm@1 238 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
rlm@1 239 {
rlm@1 240 back = line2[x];
rlm@1 241 top2 = 0x04;
rlm@1 242 }
rlm@1 243
rlm@1 244 if ((u8)(line3[x]>>24) < (u8)(back >> 24))
rlm@1 245 {
rlm@1 246 back = line3[x];
rlm@1 247 top2 = 0x08;
rlm@1 248 }
rlm@1 249
rlm@1 250 if (top2 & (BLDMOD>>8))
rlm@1 251 color = gfxAlphaBlend(color, back,
rlm@1 252 coeff[COLEV & 0x1F],
rlm@1 253 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 254 else
rlm@1 255 {
rlm@1 256 switch ((BLDMOD >> 6) & 3)
rlm@1 257 {
rlm@1 258 case 2:
rlm@1 259 if (BLDMOD & top)
rlm@1 260 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 261 break;
rlm@1 262 case 3:
rlm@1 263 if (BLDMOD & top)
rlm@1 264 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 265 break;
rlm@1 266 }
rlm@1 267 }
rlm@1 268 }
rlm@1 269
rlm@1 270 lineMix[x] = color;
rlm@1 271 }
rlm@1 272 gfxBG2Changed = 0;
rlm@1 273 gfxBG3Changed = 0;
rlm@1 274 gfxLastVCOUNT = VCOUNT;
rlm@1 275 }
rlm@1 276
rlm@1 277 void mode2RenderLineAll()
rlm@1 278 {
rlm@1 279 u16 *palette = (u16 *)paletteRAM;
rlm@1 280
rlm@1 281 if (DISPCNT & 0x80)
rlm@1 282 {
rlm@1 283 for (int x = 0; x < 240; x++)
rlm@1 284 {
rlm@1 285 lineMix[x] = 0x7fff;
rlm@1 286 }
rlm@1 287 gfxLastVCOUNT = VCOUNT;
rlm@1 288 return;
rlm@1 289 }
rlm@1 290
rlm@1 291 bool inWindow0 = false;
rlm@1 292 bool inWindow1 = false;
rlm@1 293
rlm@1 294 if (layerEnable & 0x2000)
rlm@1 295 {
rlm@1 296 u8 v0 = WIN0V >> 8;
rlm@1 297 u8 v1 = WIN0V & 255;
rlm@1 298 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
rlm@1 299 if (v1 >= v0)
rlm@1 300 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
rlm@1 301 else
rlm@1 302 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
rlm@1 303 }
rlm@1 304 if (layerEnable & 0x4000)
rlm@1 305 {
rlm@1 306 u8 v0 = WIN1V >> 8;
rlm@1 307 u8 v1 = WIN1V & 255;
rlm@1 308 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
rlm@1 309 if (v1 >= v0)
rlm@1 310 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
rlm@1 311 else
rlm@1 312 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
rlm@1 313 }
rlm@1 314
rlm@1 315 if (layerEnable & 0x0400)
rlm@1 316 {
rlm@1 317 int changed = gfxBG2Changed;
rlm@1 318 if (gfxLastVCOUNT > VCOUNT)
rlm@1 319 changed = 3;
rlm@1 320
rlm@1 321 gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
rlm@1 322 BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
rlm@1 323 changed, line2);
rlm@1 324 }
rlm@1 325
rlm@1 326 if (layerEnable & 0x0800)
rlm@1 327 {
rlm@1 328 int changed = gfxBG3Changed;
rlm@1 329 if (gfxLastVCOUNT > VCOUNT)
rlm@1 330 changed = 3;
rlm@1 331
rlm@1 332 gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
rlm@1 333 BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
rlm@1 334 changed, line3);
rlm@1 335 }
rlm@1 336
rlm@1 337 gfxDrawSprites(lineOBJ);
rlm@1 338 gfxDrawOBJWin(lineOBJWin);
rlm@1 339
rlm@1 340 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
rlm@1 341
rlm@1 342 u8 inWin0Mask = WININ & 0xFF;
rlm@1 343 u8 inWin1Mask = WININ >> 8;
rlm@1 344 u8 outMask = WINOUT & 0xFF;
rlm@1 345
rlm@1 346 for (int x = 0; x < 240; x++)
rlm@1 347 {
rlm@1 348 u32 color = backdrop;
rlm@1 349 u8 top = 0x20;
rlm@1 350 u8 mask = outMask;
rlm@1 351
rlm@1 352 if (!(lineOBJWin[x] & 0x80000000))
rlm@1 353 {
rlm@1 354 mask = WINOUT >> 8;
rlm@1 355 }
rlm@1 356
rlm@1 357 if (inWindow1)
rlm@1 358 {
rlm@1 359 if (gfxInWin1[x])
rlm@1 360 mask = inWin1Mask;
rlm@1 361 }
rlm@1 362
rlm@1 363 if (inWindow0)
rlm@1 364 {
rlm@1 365 if (gfxInWin0[x])
rlm@1 366 {
rlm@1 367 mask = inWin0Mask;
rlm@1 368 }
rlm@1 369 }
rlm@1 370
rlm@1 371 if (line2[x] < color && (mask & 4))
rlm@1 372 {
rlm@1 373 color = line2[x];
rlm@1 374 top = 0x04;
rlm@1 375 }
rlm@1 376
rlm@1 377 if ((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8))
rlm@1 378 {
rlm@1 379 color = line3[x];
rlm@1 380 top = 0x08;
rlm@1 381 }
rlm@1 382
rlm@1 383 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16))
rlm@1 384 {
rlm@1 385 color = lineOBJ[x];
rlm@1 386 top = 0x10;
rlm@1 387 }
rlm@1 388
rlm@1 389 if (mask & 32)
rlm@1 390 {
rlm@1 391 if (!(color & 0x00010000))
rlm@1 392 {
rlm@1 393 switch ((BLDMOD >> 6) & 3)
rlm@1 394 {
rlm@1 395 case 0:
rlm@1 396 break;
rlm@1 397 case 1:
rlm@1 398 {
rlm@1 399 if (top & BLDMOD)
rlm@1 400 {
rlm@1 401 u32 back = backdrop;
rlm@1 402 u8 top2 = 0x20;
rlm@1 403
rlm@1 404 if ((mask & 4) && line2[x] < back)
rlm@1 405 {
rlm@1 406 if (top != 0x04)
rlm@1 407 {
rlm@1 408 back = line2[x];
rlm@1 409 top2 = 0x04;
rlm@1 410 }
rlm@1 411 }
rlm@1 412
rlm@1 413 if ((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
rlm@1 414 {
rlm@1 415 if (top != 0x08)
rlm@1 416 {
rlm@1 417 back = line3[x];
rlm@1 418 top2 = 0x08;
rlm@1 419 }
rlm@1 420 }
rlm@1 421
rlm@1 422 if ((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
rlm@1 423 {
rlm@1 424 if (top != 0x10)
rlm@1 425 {
rlm@1 426 back = lineOBJ[x];
rlm@1 427 top2 = 0x10;
rlm@1 428 }
rlm@1 429 }
rlm@1 430
rlm@1 431 if (top2 & (BLDMOD>>8))
rlm@1 432 color = gfxAlphaBlend(color, back,
rlm@1 433 coeff[COLEV & 0x1F],
rlm@1 434 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 435 }
rlm@1 436 break;
rlm@1 437 }
rlm@1 438 case 2:
rlm@1 439 if (BLDMOD & top)
rlm@1 440 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 441 break;
rlm@1 442 case 3:
rlm@1 443 if (BLDMOD & top)
rlm@1 444 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 445 break;
rlm@1 446 }
rlm@1 447 }
rlm@1 448 else
rlm@1 449 {
rlm@1 450 // semi-transparent OBJ
rlm@1 451 u32 back = backdrop;
rlm@1 452 u8 top2 = 0x20;
rlm@1 453
rlm@1 454 if ((mask & 4) && line2[x] < back)
rlm@1 455 {
rlm@1 456 back = line2[x];
rlm@1 457 top2 = 0x04;
rlm@1 458 }
rlm@1 459
rlm@1 460 if ((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
rlm@1 461 {
rlm@1 462 back = line3[x];
rlm@1 463 top2 = 0x08;
rlm@1 464 }
rlm@1 465
rlm@1 466 if (top2 & (BLDMOD>>8))
rlm@1 467 color = gfxAlphaBlend(color, back,
rlm@1 468 coeff[COLEV & 0x1F],
rlm@1 469 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 470 else
rlm@1 471 {
rlm@1 472 switch ((BLDMOD >> 6) & 3)
rlm@1 473 {
rlm@1 474 case 2:
rlm@1 475 if (BLDMOD & top)
rlm@1 476 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 477 break;
rlm@1 478 case 3:
rlm@1 479 if (BLDMOD & top)
rlm@1 480 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 481 break;
rlm@1 482 }
rlm@1 483 }
rlm@1 484 }
rlm@1 485 }
rlm@1 486 else if (color & 0x00010000)
rlm@1 487 {
rlm@1 488 // semi-transparent OBJ
rlm@1 489 u32 back = backdrop;
rlm@1 490 u8 top2 = 0x20;
rlm@1 491
rlm@1 492 if ((mask & 4) && line2[x] < back)
rlm@1 493 {
rlm@1 494 back = line2[x];
rlm@1 495 top2 = 0x04;
rlm@1 496 }
rlm@1 497
rlm@1 498 if ((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
rlm@1 499 {
rlm@1 500 back = line3[x];
rlm@1 501 top2 = 0x08;
rlm@1 502 }
rlm@1 503
rlm@1 504 if (top2 & (BLDMOD>>8))
rlm@1 505 color = gfxAlphaBlend(color, back,
rlm@1 506 coeff[COLEV & 0x1F],
rlm@1 507 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 508 else
rlm@1 509 {
rlm@1 510 switch ((BLDMOD >> 6) & 3)
rlm@1 511 {
rlm@1 512 case 2:
rlm@1 513 if (BLDMOD & top)
rlm@1 514 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 515 break;
rlm@1 516 case 3:
rlm@1 517 if (BLDMOD & top)
rlm@1 518 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 519 break;
rlm@1 520 }
rlm@1 521 }
rlm@1 522 }
rlm@1 523
rlm@1 524 lineMix[x] = color;
rlm@1 525 }
rlm@1 526 gfxBG2Changed = 0;
rlm@1 527 gfxBG3Changed = 0;
rlm@1 528 gfxLastVCOUNT = VCOUNT;
rlm@1 529 }
rlm@1 530