annotate src/gba/Mode4.cpp @ 331:6ec288064d49

improved do-save-corruption
author Robert McIntyre <rlm@mit.edu>
date Fri, 06 Apr 2012 12:18:58 -0500
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 mode4RenderLine()
rlm@1 5 {
rlm@1 6 u16 *palette = (u16 *)paletteRAM;
rlm@1 7
rlm@1 8 if (DISPCNT & 0x0080)
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 & 0x400)
rlm@1 19 {
rlm@1 20 int changed = gfxBG2Changed;
rlm@1 21
rlm@1 22 if (gfxLastVCOUNT > VCOUNT)
rlm@1 23 changed = 3;
rlm@1 24
rlm@1 25 gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
rlm@1 26 BG2PA, BG2PB, BG2PC, BG2PD,
rlm@1 27 gfxBG2X, gfxBG2Y, changed,
rlm@1 28 line2);
rlm@1 29 }
rlm@1 30
rlm@1 31 gfxDrawSprites(lineOBJ);
rlm@1 32
rlm@1 33 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
rlm@1 34
rlm@1 35 for (int x = 0; x < 240; x++)
rlm@1 36 {
rlm@1 37 u32 color = backdrop;
rlm@1 38 u8 top = 0x20;
rlm@1 39
rlm@1 40 if (line2[x] < color)
rlm@1 41 {
rlm@1 42 color = line2[x];
rlm@1 43 top = 0x04;
rlm@1 44 }
rlm@1 45
rlm@1 46 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
rlm@1 47 {
rlm@1 48 color = lineOBJ[x];
rlm@1 49 top = 0x10;
rlm@1 50 }
rlm@1 51
rlm@1 52 if ((top & 0x10) && (color & 0x00010000))
rlm@1 53 {
rlm@1 54 // semi-transparent OBJ
rlm@1 55 u32 back = backdrop;
rlm@1 56 u8 top2 = 0x20;
rlm@1 57
rlm@1 58 if (line2[x] < back)
rlm@1 59 {
rlm@1 60 back = line2[x];
rlm@1 61 top2 = 0x04;
rlm@1 62 }
rlm@1 63
rlm@1 64 if (top2 & (BLDMOD>>8))
rlm@1 65 color = gfxAlphaBlend(color, back,
rlm@1 66 coeff[COLEV & 0x1F],
rlm@1 67 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 68 else
rlm@1 69 {
rlm@1 70 switch ((BLDMOD >> 6) & 3)
rlm@1 71 {
rlm@1 72 case 2:
rlm@1 73 if (BLDMOD & top)
rlm@1 74 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 75 break;
rlm@1 76 case 3:
rlm@1 77 if (BLDMOD & top)
rlm@1 78 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 79 break;
rlm@1 80 }
rlm@1 81 }
rlm@1 82 }
rlm@1 83
rlm@1 84 lineMix[x] = color;
rlm@1 85 }
rlm@1 86 gfxBG2Changed = 0;
rlm@1 87 gfxLastVCOUNT = VCOUNT;
rlm@1 88 }
rlm@1 89
rlm@1 90 void mode4RenderLineNoWindow()
rlm@1 91 {
rlm@1 92 u16 *palette = (u16 *)paletteRAM;
rlm@1 93
rlm@1 94 if (DISPCNT & 0x0080)
rlm@1 95 {
rlm@1 96 for (int x = 0; x < 240; x++)
rlm@1 97 {
rlm@1 98 lineMix[x] = 0x7fff;
rlm@1 99 }
rlm@1 100 gfxLastVCOUNT = VCOUNT;
rlm@1 101 return;
rlm@1 102 }
rlm@1 103
rlm@1 104 if (layerEnable & 0x400)
rlm@1 105 {
rlm@1 106 int changed = gfxBG2Changed;
rlm@1 107
rlm@1 108 if (gfxLastVCOUNT > VCOUNT)
rlm@1 109 changed = 3;
rlm@1 110
rlm@1 111 gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
rlm@1 112 BG2PA, BG2PB, BG2PC, BG2PD,
rlm@1 113 gfxBG2X, gfxBG2Y, changed,
rlm@1 114 line2);
rlm@1 115 }
rlm@1 116
rlm@1 117 gfxDrawSprites(lineOBJ);
rlm@1 118
rlm@1 119 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
rlm@1 120
rlm@1 121 for (int x = 0; x < 240; x++)
rlm@1 122 {
rlm@1 123 u32 color = backdrop;
rlm@1 124 u8 top = 0x20;
rlm@1 125
rlm@1 126 if (line2[x] < color)
rlm@1 127 {
rlm@1 128 color = line2[x];
rlm@1 129 top = 0x04;
rlm@1 130 }
rlm@1 131
rlm@1 132 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
rlm@1 133 {
rlm@1 134 color = lineOBJ[x];
rlm@1 135 top = 0x10;
rlm@1 136 }
rlm@1 137
rlm@1 138 if (!(color & 0x00010000))
rlm@1 139 {
rlm@1 140 switch ((BLDMOD >> 6) & 3)
rlm@1 141 {
rlm@1 142 case 0:
rlm@1 143 break;
rlm@1 144 case 1:
rlm@1 145 {
rlm@1 146 if (top & BLDMOD)
rlm@1 147 {
rlm@1 148 u32 back = backdrop;
rlm@1 149 u8 top2 = 0x20;
rlm@1 150
rlm@1 151 if (line2[x] < back)
rlm@1 152 {
rlm@1 153 if (top != 0x04)
rlm@1 154 {
rlm@1 155 back = line2[x];
rlm@1 156 top2 = 0x04;
rlm@1 157 }
rlm@1 158 }
rlm@1 159
rlm@1 160 if ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
rlm@1 161 {
rlm@1 162 if (top != 0x10)
rlm@1 163 {
rlm@1 164 back = lineOBJ[x];
rlm@1 165 top2 = 0x10;
rlm@1 166 }
rlm@1 167 }
rlm@1 168
rlm@1 169 if (top2 & (BLDMOD>>8))
rlm@1 170 color = gfxAlphaBlend(color, back,
rlm@1 171 coeff[COLEV & 0x1F],
rlm@1 172 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 173 }
rlm@1 174 break;
rlm@1 175 }
rlm@1 176 case 2:
rlm@1 177 if (BLDMOD & top)
rlm@1 178 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 179 break;
rlm@1 180 case 3:
rlm@1 181 if (BLDMOD & top)
rlm@1 182 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 183 break;
rlm@1 184 }
rlm@1 185 }
rlm@1 186 else
rlm@1 187 {
rlm@1 188 // semi-transparent OBJ
rlm@1 189 u32 back = backdrop;
rlm@1 190 u8 top2 = 0x20;
rlm@1 191
rlm@1 192 if (line2[x] < back)
rlm@1 193 {
rlm@1 194 back = line2[x];
rlm@1 195 top2 = 0x04;
rlm@1 196 }
rlm@1 197
rlm@1 198 if (top2 & (BLDMOD>>8))
rlm@1 199 color = gfxAlphaBlend(color, back,
rlm@1 200 coeff[COLEV & 0x1F],
rlm@1 201 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 202 else
rlm@1 203 {
rlm@1 204 switch ((BLDMOD >> 6) & 3)
rlm@1 205 {
rlm@1 206 case 2:
rlm@1 207 if (BLDMOD & top)
rlm@1 208 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 209 break;
rlm@1 210 case 3:
rlm@1 211 if (BLDMOD & top)
rlm@1 212 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 213 break;
rlm@1 214 }
rlm@1 215 }
rlm@1 216 }
rlm@1 217
rlm@1 218 lineMix[x] = color;
rlm@1 219 }
rlm@1 220 gfxBG2Changed = 0;
rlm@1 221 gfxLastVCOUNT = VCOUNT;
rlm@1 222 }
rlm@1 223
rlm@1 224 void mode4RenderLineAll()
rlm@1 225 {
rlm@1 226 u16 *palette = (u16 *)paletteRAM;
rlm@1 227
rlm@1 228 if (DISPCNT & 0x0080)
rlm@1 229 {
rlm@1 230 for (int x = 0; x < 240; x++)
rlm@1 231 {
rlm@1 232 lineMix[x] = 0x7fff;
rlm@1 233 }
rlm@1 234 gfxLastVCOUNT = VCOUNT;
rlm@1 235 return;
rlm@1 236 }
rlm@1 237
rlm@1 238 bool inWindow0 = false;
rlm@1 239 bool inWindow1 = false;
rlm@1 240
rlm@1 241 if (layerEnable & 0x2000)
rlm@1 242 {
rlm@1 243 u8 v0 = WIN0V >> 8;
rlm@1 244 u8 v1 = WIN0V & 255;
rlm@1 245 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
rlm@1 246 if (v1 >= v0)
rlm@1 247 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
rlm@1 248 else
rlm@1 249 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
rlm@1 250 }
rlm@1 251 if (layerEnable & 0x4000)
rlm@1 252 {
rlm@1 253 u8 v0 = WIN1V >> 8;
rlm@1 254 u8 v1 = WIN1V & 255;
rlm@1 255 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
rlm@1 256 if (v1 >= v0)
rlm@1 257 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
rlm@1 258 else
rlm@1 259 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
rlm@1 260 }
rlm@1 261
rlm@1 262 if (layerEnable & 0x400)
rlm@1 263 {
rlm@1 264 int changed = gfxBG2Changed;
rlm@1 265
rlm@1 266 if (gfxLastVCOUNT > VCOUNT)
rlm@1 267 changed = 3;
rlm@1 268
rlm@1 269 gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
rlm@1 270 BG2PA, BG2PB, BG2PC, BG2PD,
rlm@1 271 gfxBG2X, gfxBG2Y, changed,
rlm@1 272 line2);
rlm@1 273 }
rlm@1 274
rlm@1 275 gfxDrawSprites(lineOBJ);
rlm@1 276 gfxDrawOBJWin(lineOBJWin);
rlm@1 277
rlm@1 278 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
rlm@1 279
rlm@1 280 u8 inWin0Mask = WININ & 0xFF;
rlm@1 281 u8 inWin1Mask = WININ >> 8;
rlm@1 282 u8 outMask = WINOUT & 0xFF;
rlm@1 283
rlm@1 284 for (int x = 0; x < 240; x++)
rlm@1 285 {
rlm@1 286 u32 color = backdrop;
rlm@1 287 u8 top = 0x20;
rlm@1 288 u8 mask = outMask;
rlm@1 289
rlm@1 290 if (!(lineOBJWin[x] & 0x80000000))
rlm@1 291 {
rlm@1 292 mask = WINOUT >> 8;
rlm@1 293 }
rlm@1 294
rlm@1 295 if (inWindow1)
rlm@1 296 {
rlm@1 297 if (gfxInWin1[x])
rlm@1 298 mask = inWin1Mask;
rlm@1 299 }
rlm@1 300
rlm@1 301 if (inWindow0)
rlm@1 302 {
rlm@1 303 if (gfxInWin0[x])
rlm@1 304 {
rlm@1 305 mask = inWin0Mask;
rlm@1 306 }
rlm@1 307 }
rlm@1 308
rlm@1 309 if ((mask & 4) && (line2[x] < color))
rlm@1 310 {
rlm@1 311 color = line2[x];
rlm@1 312 top = 0x04;
rlm@1 313 }
rlm@1 314
rlm@1 315 if ((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
rlm@1 316 {
rlm@1 317 color = lineOBJ[x];
rlm@1 318 top = 0x10;
rlm@1 319 }
rlm@1 320
rlm@1 321 if (mask & 32)
rlm@1 322 {
rlm@1 323 if (!(color & 0x00010000))
rlm@1 324 {
rlm@1 325 switch ((BLDMOD >> 6) & 3)
rlm@1 326 {
rlm@1 327 case 0:
rlm@1 328 break;
rlm@1 329 case 1:
rlm@1 330 {
rlm@1 331 if (top & BLDMOD)
rlm@1 332 {
rlm@1 333 u32 back = backdrop;
rlm@1 334 u8 top2 = 0x20;
rlm@1 335
rlm@1 336 if ((mask & 4) && line2[x] < back)
rlm@1 337 {
rlm@1 338 if (top != 0x04)
rlm@1 339 {
rlm@1 340 back = line2[x];
rlm@1 341 top2 = 0x04;
rlm@1 342 }
rlm@1 343 }
rlm@1 344
rlm@1 345 if ((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
rlm@1 346 {
rlm@1 347 if (top != 0x10)
rlm@1 348 {
rlm@1 349 back = lineOBJ[x];
rlm@1 350 top2 = 0x10;
rlm@1 351 }
rlm@1 352 }
rlm@1 353
rlm@1 354 if (top2 & (BLDMOD>>8))
rlm@1 355 color = gfxAlphaBlend(color, back,
rlm@1 356 coeff[COLEV & 0x1F],
rlm@1 357 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 358 }
rlm@1 359 break;
rlm@1 360 }
rlm@1 361 case 2:
rlm@1 362 if (BLDMOD & top)
rlm@1 363 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 364 break;
rlm@1 365 case 3:
rlm@1 366 if (BLDMOD & top)
rlm@1 367 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 368 break;
rlm@1 369 }
rlm@1 370 }
rlm@1 371 else
rlm@1 372 {
rlm@1 373 // semi-transparent OBJ
rlm@1 374 u32 back = backdrop;
rlm@1 375 u8 top2 = 0x20;
rlm@1 376
rlm@1 377 if ((mask & 4) && line2[x] < back)
rlm@1 378 {
rlm@1 379 back = line2[x];
rlm@1 380 top2 = 0x04;
rlm@1 381 }
rlm@1 382
rlm@1 383 if (top2 & (BLDMOD>>8))
rlm@1 384 color = gfxAlphaBlend(color, back,
rlm@1 385 coeff[COLEV & 0x1F],
rlm@1 386 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 387 else
rlm@1 388 {
rlm@1 389 switch ((BLDMOD >> 6) & 3)
rlm@1 390 {
rlm@1 391 case 2:
rlm@1 392 if (BLDMOD & top)
rlm@1 393 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 394 break;
rlm@1 395 case 3:
rlm@1 396 if (BLDMOD & top)
rlm@1 397 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 398 break;
rlm@1 399 }
rlm@1 400 }
rlm@1 401 }
rlm@1 402 }
rlm@1 403 else if (color & 0x00010000)
rlm@1 404 {
rlm@1 405 // semi-transparent OBJ
rlm@1 406 u32 back = backdrop;
rlm@1 407 u8 top2 = 0x20;
rlm@1 408
rlm@1 409 if ((mask & 4) && line2[x] < back)
rlm@1 410 {
rlm@1 411 back = line2[x];
rlm@1 412 top2 = 0x04;
rlm@1 413 }
rlm@1 414
rlm@1 415 if (top2 & (BLDMOD>>8))
rlm@1 416 color = gfxAlphaBlend(color, back,
rlm@1 417 coeff[COLEV & 0x1F],
rlm@1 418 coeff[(COLEV >> 8) & 0x1F]);
rlm@1 419 else
rlm@1 420 {
rlm@1 421 switch ((BLDMOD >> 6) & 3)
rlm@1 422 {
rlm@1 423 case 2:
rlm@1 424 if (BLDMOD & top)
rlm@1 425 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 426 break;
rlm@1 427 case 3:
rlm@1 428 if (BLDMOD & top)
rlm@1 429 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
rlm@1 430 break;
rlm@1 431 }
rlm@1 432 }
rlm@1 433 }
rlm@1 434
rlm@1 435 lineMix[x] = color;
rlm@1 436 }
rlm@1 437 gfxBG2Changed = 0;
rlm@1 438 gfxLastVCOUNT = VCOUNT;
rlm@1 439 }
rlm@1 440