annotate src/gba/Mode5.cpp @ 43:629602cb5e8c

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