annotate src/gba/GBAGfx.h @ 328:35960b03693f

improved delayed-difference with memoization
author Robert McIntyre <rlm@mit.edu>
date Thu, 05 Apr 2012 15:05:08 -0500
parents f9f4f1b99eed
children
rev   line source
rlm@1 1 #ifndef VBA_GBA_GFX_H
rlm@1 2 #define VBA_GBA_GFX_H
rlm@1 3
rlm@1 4 #if _MSC_VER > 1000
rlm@1 5 #pragma once
rlm@1 6 #endif // _MSC_VER > 1000
rlm@1 7
rlm@1 8 #include "../Port.h"
rlm@1 9 #include "GBA.h"
rlm@1 10 #include "GBAGlobals.h"
rlm@1 11
rlm@1 12 //#define SPRITE_DEBUG
rlm@1 13
rlm@1 14 void gfxDrawTextScreen(u16, u16, u16, u32 *);
rlm@1 15 void gfxDrawRotScreen(u16,
rlm@1 16 u16, u16,
rlm@1 17 u16, u16,
rlm@1 18 u16, u16,
rlm@1 19 u16, u16,
rlm@1 20 int&, int&,
rlm@1 21 int,
rlm@1 22 u32 *);
rlm@1 23 void gfxDrawRotScreen16Bit(u16,
rlm@1 24 u16, u16,
rlm@1 25 u16, u16,
rlm@1 26 u16, u16,
rlm@1 27 u16, u16,
rlm@1 28 int&, int&,
rlm@1 29 int,
rlm@1 30 u32 *);
rlm@1 31 void gfxDrawRotScreen256(u16,
rlm@1 32 u16, u16,
rlm@1 33 u16, u16,
rlm@1 34 u16, u16,
rlm@1 35 u16, u16,
rlm@1 36 int&, int&,
rlm@1 37 int,
rlm@1 38 u32 *);
rlm@1 39 void gfxDrawRotScreen16Bit160(u16,
rlm@1 40 u16, u16,
rlm@1 41 u16, u16,
rlm@1 42 u16, u16,
rlm@1 43 u16, u16,
rlm@1 44 int&, int&,
rlm@1 45 int,
rlm@1 46 u32 *);
rlm@1 47 void gfxDrawSprites(u32 *);
rlm@1 48 void gfxIncreaseBrightness(u32 *line, int coeff);
rlm@1 49 void gfxDecreaseBrightness(u32 *line, int coeff);
rlm@1 50 void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb);
rlm@1 51
rlm@1 52 void mode0RenderLine();
rlm@1 53 void mode0RenderLineNoWindow();
rlm@1 54 void mode0RenderLineAll();
rlm@1 55
rlm@1 56 void mode1RenderLine();
rlm@1 57 void mode1RenderLineNoWindow();
rlm@1 58 void mode1RenderLineAll();
rlm@1 59
rlm@1 60 void mode2RenderLine();
rlm@1 61 void mode2RenderLineNoWindow();
rlm@1 62 void mode2RenderLineAll();
rlm@1 63
rlm@1 64 void mode3RenderLine();
rlm@1 65 void mode3RenderLineNoWindow();
rlm@1 66 void mode3RenderLineAll();
rlm@1 67
rlm@1 68 void mode4RenderLine();
rlm@1 69 void mode4RenderLineNoWindow();
rlm@1 70 void mode4RenderLineAll();
rlm@1 71
rlm@1 72 void mode5RenderLine();
rlm@1 73 void mode5RenderLineNoWindow();
rlm@1 74 void mode5RenderLineAll();
rlm@1 75
rlm@1 76 extern int coeff[32];
rlm@1 77
rlm@1 78 #define LINE_BUFFER_OVERFLOW_LEEWAY (512-240)
rlm@1 79
rlm@1 80 extern u32 line0[240+LINE_BUFFER_OVERFLOW_LEEWAY];
rlm@1 81 extern u32 line1[240+LINE_BUFFER_OVERFLOW_LEEWAY];
rlm@1 82 extern u32 line2[240+LINE_BUFFER_OVERFLOW_LEEWAY];
rlm@1 83 extern u32 line3[240+LINE_BUFFER_OVERFLOW_LEEWAY];
rlm@1 84 extern u32 lineOBJ[240+LINE_BUFFER_OVERFLOW_LEEWAY];
rlm@1 85 extern u32 lineOBJWin[240+LINE_BUFFER_OVERFLOW_LEEWAY];
rlm@1 86 extern u32 lineMix[240+LINE_BUFFER_OVERFLOW_LEEWAY];
rlm@1 87 extern bool gfxInWin0[240+LINE_BUFFER_OVERFLOW_LEEWAY];
rlm@1 88 extern bool gfxInWin1[240+LINE_BUFFER_OVERFLOW_LEEWAY];
rlm@1 89
rlm@1 90 extern int gfxBG2Changed;
rlm@1 91 extern int gfxBG3Changed;
rlm@1 92
rlm@1 93 extern int gfxBG2X;
rlm@1 94 extern int gfxBG2Y;
rlm@1 95 extern int gfxBG2LastX;
rlm@1 96 extern int gfxBG2LastY;
rlm@1 97 extern int gfxBG3X;
rlm@1 98 extern int gfxBG3Y;
rlm@1 99 extern int gfxBG3LastX;
rlm@1 100 extern int gfxBG3LastY;
rlm@1 101 extern int gfxLastVCOUNT;
rlm@1 102
rlm@1 103 inline void gfxClearArray(u32 *array)
rlm@1 104 {
rlm@1 105 for (int i = 0; i < 240; i++)
rlm@1 106 {
rlm@1 107 *array++ = 0x80000000;
rlm@1 108 }
rlm@1 109 }
rlm@1 110
rlm@1 111 inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
rlm@1 112 u32 *line)
rlm@1 113 {
rlm@1 114 u16 *palette = (u16 *)paletteRAM;
rlm@1 115 u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000];
rlm@1 116 u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800];
rlm@1 117 u32 prio = ((control & 3)<<25) + 0x1000000;
rlm@1 118 int sizeX = 256;
rlm@1 119 int sizeY = 256;
rlm@1 120 switch ((control >> 14) & 3)
rlm@1 121 {
rlm@1 122 case 0:
rlm@1 123 break;
rlm@1 124 case 1:
rlm@1 125 sizeX = 512;
rlm@1 126 break;
rlm@1 127 case 2:
rlm@1 128 sizeY = 512;
rlm@1 129 break;
rlm@1 130 case 3:
rlm@1 131 sizeX = 512;
rlm@1 132 sizeY = 512;
rlm@1 133 break;
rlm@1 134 }
rlm@1 135
rlm@1 136 int maskX = sizeX-1;
rlm@1 137 int maskY = sizeY-1;
rlm@1 138
rlm@1 139 bool mosaicOn = (control & 0x40) ? true : false;
rlm@1 140
rlm@1 141 int xxx = hofs & maskX;
rlm@1 142 int yyy = (vofs + VCOUNT) & maskY;
rlm@1 143 int mosaicX = (MOSAIC & 0x000F)+1;
rlm@1 144 int mosaicY = ((MOSAIC & 0x00F0)>>4)+1;
rlm@1 145
rlm@1 146 if (mosaicOn)
rlm@1 147 {
rlm@1 148 if ((VCOUNT % mosaicY) != 0)
rlm@1 149 {
rlm@1 150 mosaicY = (VCOUNT / mosaicY) * mosaicY;
rlm@1 151 yyy = (vofs + mosaicY) & maskY;
rlm@1 152 }
rlm@1 153 }
rlm@1 154
rlm@1 155 if (yyy > 255 && sizeY > 256)
rlm@1 156 {
rlm@1 157 yyy &= 255;
rlm@1 158 screenBase += 0x400;
rlm@1 159 if (sizeX > 256)
rlm@1 160 screenBase += 0x400;
rlm@1 161 }
rlm@1 162
rlm@1 163 int yshift = ((yyy>>3)<<5);
rlm@1 164 if ((control) & 0x80)
rlm@1 165 {
rlm@1 166 u16 *screenSource = screenBase + 0x400 * (xxx>>8) + ((xxx & 255)>>3) + yshift;
rlm@1 167 for (int x = 0; x < 240; x++)
rlm@1 168 {
rlm@1 169 u16 data = READ16LE(screenSource);
rlm@1 170
rlm@1 171 int tile = data & 0x3FF;
rlm@1 172 int tileX = (xxx & 7);
rlm@1 173 int tileY = yyy & 7;
rlm@1 174
rlm@1 175 if (data & 0x0400)
rlm@1 176 tileX = 7 - tileX;
rlm@1 177 if (data & 0x0800)
rlm@1 178 tileY = 7 - tileY;
rlm@1 179
rlm@1 180 u8 color = charBase[tile * 64 + tileY * 8 + tileX];
rlm@1 181
rlm@1 182 line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000;
rlm@1 183
rlm@1 184 if (data & 0x0400)
rlm@1 185 {
rlm@1 186 if (tileX == 0)
rlm@1 187 screenSource++;
rlm@1 188 }
rlm@1 189 else if (tileX == 7)
rlm@1 190 screenSource++;
rlm@1 191 xxx++;
rlm@1 192 if (xxx == 256)
rlm@1 193 {
rlm@1 194 if (sizeX > 256)
rlm@1 195 screenSource = screenBase + 0x400 + yshift;
rlm@1 196 else
rlm@1 197 {
rlm@1 198 screenSource = screenBase + yshift;
rlm@1 199 xxx = 0;
rlm@1 200 }
rlm@1 201 }
rlm@1 202 else if (xxx >= sizeX)
rlm@1 203 {
rlm@1 204 xxx = 0;
rlm@1 205 screenSource = screenBase + yshift;
rlm@1 206 }
rlm@1 207 }
rlm@1 208 }
rlm@1 209 else
rlm@1 210 {
rlm@1 211 u16 *screenSource = screenBase + 0x400*(xxx>>8)+((xxx&255)>>3) +
rlm@1 212 yshift;
rlm@1 213 for (int x = 0; x < 240; x++)
rlm@1 214 {
rlm@1 215 u16 data = READ16LE(screenSource);
rlm@1 216
rlm@1 217 int tile = data & 0x3FF;
rlm@1 218 int tileX = (xxx & 7);
rlm@1 219 int tileY = yyy & 7;
rlm@1 220
rlm@1 221 if (data & 0x0400)
rlm@1 222 tileX = 7 - tileX;
rlm@1 223 if (data & 0x0800)
rlm@1 224 tileY = 7 - tileY;
rlm@1 225
rlm@1 226 u8 color = charBase[(tile<<5) + (tileY<<2) + (tileX>>1)];
rlm@1 227
rlm@1 228 if (tileX & 1)
rlm@1 229 {
rlm@1 230 color = (color >> 4);
rlm@1 231 }
rlm@1 232 else
rlm@1 233 {
rlm@1 234 color &= 0x0F;
rlm@1 235 }
rlm@1 236
rlm@1 237 int pal = (READ16LE(screenSource)>>8) & 0xF0;
rlm@1 238 line[x] = color ? (READ16LE(&palette[pal + color])|prio) : 0x80000000;
rlm@1 239
rlm@1 240 if (data & 0x0400)
rlm@1 241 {
rlm@1 242 if (tileX == 0)
rlm@1 243 screenSource++;
rlm@1 244 }
rlm@1 245 else if (tileX == 7)
rlm@1 246 screenSource++;
rlm@1 247 xxx++;
rlm@1 248 if (xxx == 256)
rlm@1 249 {
rlm@1 250 if (sizeX > 256)
rlm@1 251 screenSource = screenBase + 0x400 + yshift;
rlm@1 252 else
rlm@1 253 {
rlm@1 254 screenSource = screenBase + yshift;
rlm@1 255 xxx = 0;
rlm@1 256 }
rlm@1 257 }
rlm@1 258 else if (xxx >= sizeX)
rlm@1 259 {
rlm@1 260 xxx = 0;
rlm@1 261 screenSource = screenBase + yshift;
rlm@1 262 }
rlm@1 263 }
rlm@1 264 }
rlm@1 265 if (mosaicOn)
rlm@1 266 {
rlm@1 267 if (mosaicX > 1)
rlm@1 268 {
rlm@1 269 int m = 1;
rlm@1 270 for (int i = 0; i < 239; i++)
rlm@1 271 {
rlm@1 272 line[i+1] = line[i];
rlm@1 273 m++;
rlm@1 274 if (m == mosaicX)
rlm@1 275 {
rlm@1 276 m = 1;
rlm@1 277 i++;
rlm@1 278 }
rlm@1 279 }
rlm@1 280 }
rlm@1 281 }
rlm@1 282 }
rlm@1 283
rlm@1 284 inline void gfxDrawRotScreen(u16 control,
rlm@1 285 u16 x_l, u16 x_h,
rlm@1 286 u16 y_l, u16 y_h,
rlm@1 287 u16 pa, u16 pb,
rlm@1 288 u16 pc, u16 pd,
rlm@1 289 int& currentX, int& currentY,
rlm@1 290 int changed,
rlm@1 291 u32 *line)
rlm@1 292 {
rlm@1 293 u16 *palette = (u16 *)paletteRAM;
rlm@1 294 u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000];
rlm@1 295 u8 * screenBase = (u8 *)&vram[((control >> 8) & 0x1f) * 0x800];
rlm@1 296 int prio = ((control & 3) << 25) + 0x1000000;
rlm@1 297
rlm@1 298 int sizeX = 128;
rlm@1 299 int sizeY = 128;
rlm@1 300 switch ((control >> 14) & 3)
rlm@1 301 {
rlm@1 302 case 0:
rlm@1 303 break;
rlm@1 304 case 1:
rlm@1 305 sizeX = sizeY = 256;
rlm@1 306 break;
rlm@1 307 case 2:
rlm@1 308 sizeX = sizeY = 512;
rlm@1 309 break;
rlm@1 310 case 3:
rlm@1 311 sizeX = sizeY = 1024;
rlm@1 312 break;
rlm@1 313 }
rlm@1 314
rlm@1 315 int dx = pa & 0x7FFF;
rlm@1 316 if (pa & 0x8000)
rlm@1 317 dx |= 0xFFFF8000;
rlm@1 318 int dmx = pb & 0x7FFF;
rlm@1 319 if (pb & 0x8000)
rlm@1 320 dmx |= 0xFFFF8000;
rlm@1 321 int dy = pc & 0x7FFF;
rlm@1 322 if (pc & 0x8000)
rlm@1 323 dy |= 0xFFFF8000;
rlm@1 324 int dmy = pd & 0x7FFFF;
rlm@1 325 if (pd & 0x8000)
rlm@1 326 dmy |= 0xFFFF8000;
rlm@1 327
rlm@1 328 if (VCOUNT == 0)
rlm@1 329 changed = 3;
rlm@1 330
rlm@1 331 if (changed & 1)
rlm@1 332 {
rlm@1 333 currentX = (x_l) | ((x_h & 0x07FF)<<16);
rlm@1 334 if (x_h & 0x0800)
rlm@1 335 currentX |= 0xF8000000;
rlm@1 336 }
rlm@1 337 else
rlm@1 338 {
rlm@1 339 currentX += dmx;
rlm@1 340 }
rlm@1 341
rlm@1 342 if (changed & 2)
rlm@1 343 {
rlm@1 344 currentY = (y_l) | ((y_h & 0x07FF)<<16);
rlm@1 345 if (y_h & 0x0800)
rlm@1 346 currentY |= 0xF8000000;
rlm@1 347 }
rlm@1 348 else
rlm@1 349 {
rlm@1 350 currentY += dmy;
rlm@1 351 }
rlm@1 352
rlm@1 353 int realX = currentX;
rlm@1 354 int realY = currentY;
rlm@1 355
rlm@1 356 if (control & 0x40)
rlm@1 357 {
rlm@1 358 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
rlm@1 359 int y = (VCOUNT % mosaicY);
rlm@1 360 realX -= y*dmx;
rlm@1 361 realY -= y*dmy;
rlm@1 362 }
rlm@1 363
rlm@1 364 int xxx = (realX >> 8);
rlm@1 365 int yyy = (realY >> 8);
rlm@1 366
rlm@1 367 if (control & 0x2000)
rlm@1 368 {
rlm@1 369 xxx %= sizeX;
rlm@1 370 yyy %= sizeY;
rlm@1 371 if (xxx < 0)
rlm@1 372 xxx += sizeX;
rlm@1 373 if (yyy < 0)
rlm@1 374 yyy += sizeY;
rlm@1 375 }
rlm@1 376
rlm@1 377 if (control & 0x80)
rlm@1 378 {
rlm@1 379 for (int x = 0; x < 240; x++)
rlm@1 380 {
rlm@1 381 if (xxx < 0 ||
rlm@1 382 yyy < 0 ||
rlm@1 383 xxx >= sizeX ||
rlm@1 384 yyy >= sizeY)
rlm@1 385 {
rlm@1 386 line[x] = 0x80000000;
rlm@1 387 }
rlm@1 388 else
rlm@1 389 {
rlm@1 390 int tile = screenBase[(xxx>>3) + (yyy>>3)*(sizeX>>3)];
rlm@1 391
rlm@1 392 int tileX = (xxx & 7);
rlm@1 393 int tileY = yyy & 7;
rlm@1 394
rlm@1 395 u8 color = charBase[(tile<<6) + (tileY<<3) + tileX];
rlm@1 396
rlm@1 397 line[x] = color ? (READ16LE(&palette[color])|prio) : 0x80000000;
rlm@1 398 }
rlm@1 399 realX += dx;
rlm@1 400 realY += dy;
rlm@1 401
rlm@1 402 xxx = (realX >> 8);
rlm@1 403 yyy = (realY >> 8);
rlm@1 404
rlm@1 405 if (control & 0x2000)
rlm@1 406 {
rlm@1 407 xxx %= sizeX;
rlm@1 408 yyy %= sizeY;
rlm@1 409 if (xxx < 0)
rlm@1 410 xxx += sizeX;
rlm@1 411 if (yyy < 0)
rlm@1 412 yyy += sizeY;
rlm@1 413 }
rlm@1 414 }
rlm@1 415 }
rlm@1 416 else
rlm@1 417 {
rlm@1 418 for (int x = 0; x < 240; x++)
rlm@1 419 {
rlm@1 420 if (xxx < 0 ||
rlm@1 421 yyy < 0 ||
rlm@1 422 xxx >= sizeX ||
rlm@1 423 yyy >= sizeY)
rlm@1 424 {
rlm@1 425 line[x] = 0x80000000;
rlm@1 426 }
rlm@1 427 else
rlm@1 428 {
rlm@1 429 int tile = screenBase[(xxx>>3) + (yyy>>3)*(sizeX>>3)];
rlm@1 430
rlm@1 431 int tileX = (xxx & 7);
rlm@1 432 int tileY = yyy & 7;
rlm@1 433
rlm@1 434 u8 color = charBase[(tile<<6) + (tileY<<3) + tileX];
rlm@1 435
rlm@1 436 line[x] = color ? (READ16LE(&palette[color])|prio) : 0x80000000;
rlm@1 437 }
rlm@1 438 realX += dx;
rlm@1 439 realY += dy;
rlm@1 440
rlm@1 441 xxx = (realX >> 8);
rlm@1 442 yyy = (realY >> 8);
rlm@1 443
rlm@1 444 if (control & 0x2000)
rlm@1 445 {
rlm@1 446 xxx %= sizeX;
rlm@1 447 yyy %= sizeY;
rlm@1 448 if (xxx < 0)
rlm@1 449 xxx += sizeX;
rlm@1 450 if (yyy < 0)
rlm@1 451 yyy += sizeY;
rlm@1 452 }
rlm@1 453 }
rlm@1 454 }
rlm@1 455
rlm@1 456 if (control & 0x40)
rlm@1 457 {
rlm@1 458 int mosaicX = (MOSAIC & 0xF) + 1;
rlm@1 459 if (mosaicX > 1)
rlm@1 460 {
rlm@1 461 int m = 1;
rlm@1 462 for (int i = 0; i < 239; i++)
rlm@1 463 {
rlm@1 464 line[i+1] = line[i];
rlm@1 465 m++;
rlm@1 466 if (m == mosaicX)
rlm@1 467 {
rlm@1 468 m = 1;
rlm@1 469 i++;
rlm@1 470 }
rlm@1 471 }
rlm@1 472 }
rlm@1 473 }
rlm@1 474 }
rlm@1 475
rlm@1 476 inline void gfxDrawRotScreen16Bit(u16 control,
rlm@1 477 u16 x_l, u16 x_h,
rlm@1 478 u16 y_l, u16 y_h,
rlm@1 479 u16 pa, u16 pb,
rlm@1 480 u16 pc, u16 pd,
rlm@1 481 int& currentX, int& currentY,
rlm@1 482 int changed,
rlm@1 483 u32 *line)
rlm@1 484 {
rlm@1 485 u16 *screenBase = (u16 *)&vram[0];
rlm@1 486 int prio = ((control & 3) << 25) + 0x1000000;
rlm@1 487 int sizeX = 240;
rlm@1 488 int sizeY = 160;
rlm@1 489
rlm@1 490 int startX = (x_l) | ((x_h & 0x07FF)<<16);
rlm@1 491 if (x_h & 0x0800)
rlm@1 492 startX |= 0xF8000000;
rlm@1 493 int startY = (y_l) | ((y_h & 0x07FF)<<16);
rlm@1 494 if (y_h & 0x0800)
rlm@1 495 startY |= 0xF8000000;
rlm@1 496
rlm@1 497 int dx = pa & 0x7FFF;
rlm@1 498 if (pa & 0x8000)
rlm@1 499 dx |= 0xFFFF8000;
rlm@1 500 int dmx = pb & 0x7FFF;
rlm@1 501 if (pb & 0x8000)
rlm@1 502 dmx |= 0xFFFF8000;
rlm@1 503 int dy = pc & 0x7FFF;
rlm@1 504 if (pc & 0x8000)
rlm@1 505 dy |= 0xFFFF8000;
rlm@1 506 int dmy = pd & 0x7FFFF;
rlm@1 507 if (pd & 0x8000)
rlm@1 508 dmy |= 0xFFFF8000;
rlm@1 509
rlm@1 510 if (VCOUNT == 0)
rlm@1 511 changed = 3;
rlm@1 512
rlm@1 513 if (changed & 1)
rlm@1 514 {
rlm@1 515 currentX = (x_l) | ((x_h & 0x07FF)<<16);
rlm@1 516 if (x_h & 0x0800)
rlm@1 517 currentX |= 0xF8000000;
rlm@1 518 }
rlm@1 519 else
rlm@1 520 currentX += dmx;
rlm@1 521
rlm@1 522 if (changed & 2)
rlm@1 523 {
rlm@1 524 currentY = (y_l) | ((y_h & 0x07FF)<<16);
rlm@1 525 if (y_h & 0x0800)
rlm@1 526 currentY |= 0xF8000000;
rlm@1 527 }
rlm@1 528 else
rlm@1 529 {
rlm@1 530 currentY += dmy;
rlm@1 531 }
rlm@1 532
rlm@1 533 int realX = currentX;
rlm@1 534 int realY = currentY;
rlm@1 535
rlm@1 536 if (control & 0x40)
rlm@1 537 {
rlm@1 538 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
rlm@1 539 int y = (VCOUNT % mosaicY);
rlm@1 540 realX -= y*dmx;
rlm@1 541 realY -= y*dmy;
rlm@1 542 }
rlm@1 543
rlm@1 544 int xxx = (realX >> 8);
rlm@1 545 int yyy = (realY >> 8);
rlm@1 546
rlm@1 547 for (int x = 0; x < 240; x++)
rlm@1 548 {
rlm@1 549 if (xxx < 0 ||
rlm@1 550 yyy < 0 ||
rlm@1 551 xxx >= sizeX ||
rlm@1 552 yyy >= sizeY)
rlm@1 553 {
rlm@1 554 line[x] = 0x80000000;
rlm@1 555 }
rlm@1 556 else
rlm@1 557 {
rlm@1 558 line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
rlm@1 559 }
rlm@1 560 realX += dx;
rlm@1 561 realY += dy;
rlm@1 562
rlm@1 563 xxx = (realX >> 8);
rlm@1 564 yyy = (realY >> 8);
rlm@1 565 }
rlm@1 566
rlm@1 567 if (control & 0x40)
rlm@1 568 {
rlm@1 569 int mosaicX = (MOSAIC & 0xF) + 1;
rlm@1 570 if (mosaicX > 1)
rlm@1 571 {
rlm@1 572 int m = 1;
rlm@1 573 for (int i = 0; i < 239; i++)
rlm@1 574 {
rlm@1 575 line[i+1] = line[i];
rlm@1 576 m++;
rlm@1 577 if (m == mosaicX)
rlm@1 578 {
rlm@1 579 m = 1;
rlm@1 580 i++;
rlm@1 581 }
rlm@1 582 }
rlm@1 583 }
rlm@1 584 }
rlm@1 585 }
rlm@1 586
rlm@1 587 inline void gfxDrawRotScreen256(u16 control,
rlm@1 588 u16 x_l, u16 x_h,
rlm@1 589 u16 y_l, u16 y_h,
rlm@1 590 u16 pa, u16 pb,
rlm@1 591 u16 pc, u16 pd,
rlm@1 592 int &currentX, int& currentY,
rlm@1 593 int changed,
rlm@1 594 u32 *line)
rlm@1 595 {
rlm@1 596 u16 *palette = (u16 *)paletteRAM;
rlm@1 597 u8 * screenBase = (DISPCNT & 0x0010) ? &vram[0xA000] : &vram[0x0000];
rlm@1 598 int prio = ((control & 3) << 25) + 0x1000000;
rlm@1 599 int sizeX = 240;
rlm@1 600 int sizeY = 160;
rlm@1 601
rlm@1 602 int startX = (x_l) | ((x_h & 0x07FF)<<16);
rlm@1 603 if (x_h & 0x0800)
rlm@1 604 startX |= 0xF8000000;
rlm@1 605 int startY = (y_l) | ((y_h & 0x07FF)<<16);
rlm@1 606 if (y_h & 0x0800)
rlm@1 607 startY |= 0xF8000000;
rlm@1 608
rlm@1 609 int dx = pa & 0x7FFF;
rlm@1 610 if (pa & 0x8000)
rlm@1 611 dx |= 0xFFFF8000;
rlm@1 612 int dmx = pb & 0x7FFF;
rlm@1 613 if (pb & 0x8000)
rlm@1 614 dmx |= 0xFFFF8000;
rlm@1 615 int dy = pc & 0x7FFF;
rlm@1 616 if (pc & 0x8000)
rlm@1 617 dy |= 0xFFFF8000;
rlm@1 618 int dmy = pd & 0x7FFFF;
rlm@1 619 if (pd & 0x8000)
rlm@1 620 dmy |= 0xFFFF8000;
rlm@1 621
rlm@1 622 if (VCOUNT == 0)
rlm@1 623 changed = 3;
rlm@1 624
rlm@1 625 if (changed & 1)
rlm@1 626 {
rlm@1 627 currentX = (x_l) | ((x_h & 0x07FF)<<16);
rlm@1 628 if (x_h & 0x0800)
rlm@1 629 currentX |= 0xF8000000;
rlm@1 630 }
rlm@1 631 else
rlm@1 632 {
rlm@1 633 currentX += dmx;
rlm@1 634 }
rlm@1 635
rlm@1 636 if (changed & 2)
rlm@1 637 {
rlm@1 638 currentY = (y_l) | ((y_h & 0x07FF)<<16);
rlm@1 639 if (y_h & 0x0800)
rlm@1 640 currentY |= 0xF8000000;
rlm@1 641 }
rlm@1 642 else
rlm@1 643 {
rlm@1 644 currentY += dmy;
rlm@1 645 }
rlm@1 646
rlm@1 647 int realX = currentX;
rlm@1 648 int realY = currentY;
rlm@1 649
rlm@1 650 if (control & 0x40)
rlm@1 651 {
rlm@1 652 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
rlm@1 653 int y = (VCOUNT / mosaicY) * mosaicY;
rlm@1 654 realX = startX + y*dmx;
rlm@1 655 realY = startY + y*dmy;
rlm@1 656 }
rlm@1 657
rlm@1 658 int xxx = (realX >> 8);
rlm@1 659 int yyy = (realY >> 8);
rlm@1 660
rlm@1 661 for (int x = 0; x < 240; x++)
rlm@1 662 {
rlm@1 663 if (xxx < 0 ||
rlm@1 664 yyy < 0 ||
rlm@1 665 xxx >= sizeX ||
rlm@1 666 yyy >= sizeY)
rlm@1 667 {
rlm@1 668 line[x] = 0x80000000;
rlm@1 669 }
rlm@1 670 else
rlm@1 671 {
rlm@1 672 u8 color = screenBase[yyy * 240 + xxx];
rlm@1 673
rlm@1 674 line[x] = color ? (READ16LE(&palette[color])|prio) : 0x80000000;
rlm@1 675 }
rlm@1 676 realX += dx;
rlm@1 677 realY += dy;
rlm@1 678
rlm@1 679 xxx = (realX >> 8);
rlm@1 680 yyy = (realY >> 8);
rlm@1 681 }
rlm@1 682
rlm@1 683 if (control & 0x40)
rlm@1 684 {
rlm@1 685 int mosaicX = (MOSAIC & 0xF) + 1;
rlm@1 686 if (mosaicX > 1)
rlm@1 687 {
rlm@1 688 int m = 1;
rlm@1 689 for (int i = 0; i < 239; i++)
rlm@1 690 {
rlm@1 691 line[i+1] = line[i];
rlm@1 692 m++;
rlm@1 693 if (m == mosaicX)
rlm@1 694 {
rlm@1 695 m = 1;
rlm@1 696 i++;
rlm@1 697 }
rlm@1 698 }
rlm@1 699 }
rlm@1 700 }
rlm@1 701 }
rlm@1 702
rlm@1 703 inline void gfxDrawRotScreen16Bit160(u16 control,
rlm@1 704 u16 x_l, u16 x_h,
rlm@1 705 u16 y_l, u16 y_h,
rlm@1 706 u16 pa, u16 pb,
rlm@1 707 u16 pc, u16 pd,
rlm@1 708 int& currentX, int& currentY,
rlm@1 709 int changed,
rlm@1 710 u32 *line)
rlm@1 711 {
rlm@1 712 u16 *screenBase = (DISPCNT & 0x0010) ? (u16 *)&vram[0xa000] :
rlm@1 713 (u16 *)&vram[0];
rlm@1 714 int prio = ((control & 3) << 25) + 0x1000000;
rlm@1 715 int sizeX = 160;
rlm@1 716 int sizeY = 128;
rlm@1 717
rlm@1 718 int startX = (x_l) | ((x_h & 0x07FF)<<16);
rlm@1 719 if (x_h & 0x0800)
rlm@1 720 startX |= 0xF8000000;
rlm@1 721 int startY = (y_l) | ((y_h & 0x07FF)<<16);
rlm@1 722 if (y_h & 0x0800)
rlm@1 723 startY |= 0xF8000000;
rlm@1 724
rlm@1 725 int dx = pa & 0x7FFF;
rlm@1 726 if (pa & 0x8000)
rlm@1 727 dx |= 0xFFFF8000;
rlm@1 728 int dmx = pb & 0x7FFF;
rlm@1 729 if (pb & 0x8000)
rlm@1 730 dmx |= 0xFFFF8000;
rlm@1 731 int dy = pc & 0x7FFF;
rlm@1 732 if (pc & 0x8000)
rlm@1 733 dy |= 0xFFFF8000;
rlm@1 734 int dmy = pd & 0x7FFFF;
rlm@1 735 if (pd & 0x8000)
rlm@1 736 dmy |= 0xFFFF8000;
rlm@1 737
rlm@1 738 if (VCOUNT == 0)
rlm@1 739 changed = 3;
rlm@1 740
rlm@1 741 if (changed & 1)
rlm@1 742 {
rlm@1 743 currentX = (x_l) | ((x_h & 0x07FF)<<16);
rlm@1 744 if (x_h & 0x0800)
rlm@1 745 currentX |= 0xF8000000;
rlm@1 746 }
rlm@1 747 else
rlm@1 748 {
rlm@1 749 currentX += dmx;
rlm@1 750 }
rlm@1 751
rlm@1 752 if (changed & 2)
rlm@1 753 {
rlm@1 754 currentY = (y_l) | ((y_h & 0x07FF)<<16);
rlm@1 755 if (y_h & 0x0800)
rlm@1 756 currentY |= 0xF8000000;
rlm@1 757 }
rlm@1 758 else
rlm@1 759 {
rlm@1 760 currentY += dmy;
rlm@1 761 }
rlm@1 762
rlm@1 763 int realX = currentX;
rlm@1 764 int realY = currentY;
rlm@1 765
rlm@1 766 if (control & 0x40)
rlm@1 767 {
rlm@1 768 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
rlm@1 769 int y = (VCOUNT / mosaicY) * mosaicY;
rlm@1 770 realX = startX + y*dmx;
rlm@1 771 realY = startY + y*dmy;
rlm@1 772 }
rlm@1 773
rlm@1 774 int xxx = (realX >> 8);
rlm@1 775 int yyy = (realY >> 8);
rlm@1 776
rlm@1 777 for (int x = 0; x < 240; x++)
rlm@1 778 {
rlm@1 779 if (xxx < 0 ||
rlm@1 780 yyy < 0 ||
rlm@1 781 xxx >= sizeX ||
rlm@1 782 yyy >= sizeY)
rlm@1 783 {
rlm@1 784 line[x] = 0x80000000;
rlm@1 785 }
rlm@1 786 else
rlm@1 787 {
rlm@1 788 line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
rlm@1 789 }
rlm@1 790 realX += dx;
rlm@1 791 realY += dy;
rlm@1 792
rlm@1 793 xxx = (realX >> 8);
rlm@1 794 yyy = (realY >> 8);
rlm@1 795 }
rlm@1 796
rlm@1 797 if (control & 0x40)
rlm@1 798 {
rlm@1 799 int mosaicX = (MOSAIC & 0xF) + 1;
rlm@1 800 if (mosaicX > 1)
rlm@1 801 {
rlm@1 802 int m = 1;
rlm@1 803 for (int i = 0; i < 239; i++)
rlm@1 804 {
rlm@1 805 line[i+1] = line[i];
rlm@1 806 m++;
rlm@1 807 if (m == mosaicX)
rlm@1 808 {
rlm@1 809 m = 1;
rlm@1 810 i++;
rlm@1 811 }
rlm@1 812 }
rlm@1 813 }
rlm@1 814 }
rlm@1 815 }
rlm@1 816
rlm@1 817 inline void gfxDrawSprites(u32 *lineOBJ)
rlm@1 818 {
rlm@1 819 int m = 0;
rlm@1 820 gfxClearArray(lineOBJ);
rlm@1 821 if (layerEnable & 0x1000)
rlm@1 822 {
rlm@1 823 u16 *sprites = (u16 *)oam;
rlm@1 824 u16 *spritePalette = &((u16 *)paletteRAM)[256];
rlm@1 825 int mosaicY = ((MOSAIC & 0xF000)>>12) + 1;
rlm@1 826 int mosaicX = ((MOSAIC & 0xF00)>>8) + 1;
rlm@1 827 for (int x = 0; x < 128; x++)
rlm@1 828 {
rlm@1 829 u16 a0 = READ16LE(sprites++);
rlm@1 830 u16 a1 = READ16LE(sprites++);
rlm@1 831 u16 a2 = READ16LE(sprites++);
rlm@1 832 sprites++;
rlm@1 833
rlm@1 834 // ignore OBJ-WIN
rlm@1 835 if ((a0 & 0x0c00) == 0x0800)
rlm@1 836 continue;
rlm@1 837
rlm@1 838 int sizeY = 8;
rlm@1 839 int sizeX = 8;
rlm@1 840
rlm@1 841 switch (((a0 >>12) & 0x0c)|(a1>>14))
rlm@1 842 {
rlm@1 843 case 0:
rlm@1 844 break;
rlm@1 845 case 1:
rlm@1 846 sizeX = sizeY = 16;
rlm@1 847 break;
rlm@1 848 case 2:
rlm@1 849 sizeX = sizeY = 32;
rlm@1 850 break;
rlm@1 851 case 3:
rlm@1 852 sizeX = sizeY = 64;
rlm@1 853 break;
rlm@1 854 case 4:
rlm@1 855 sizeX = 16;
rlm@1 856 break;
rlm@1 857 case 5:
rlm@1 858 sizeX = 32;
rlm@1 859 break;
rlm@1 860 case 6:
rlm@1 861 sizeX = 32;
rlm@1 862 sizeY = 16;
rlm@1 863 break;
rlm@1 864 case 7:
rlm@1 865 sizeX = 64;
rlm@1 866 sizeY = 32;
rlm@1 867 break;
rlm@1 868 case 8:
rlm@1 869 sizeY = 16;
rlm@1 870 break;
rlm@1 871 case 9:
rlm@1 872 sizeY = 32;
rlm@1 873 break;
rlm@1 874 case 10:
rlm@1 875 sizeX = 16;
rlm@1 876 sizeY = 32;
rlm@1 877 break;
rlm@1 878 case 11:
rlm@1 879 sizeX = 32;
rlm@1 880 sizeY = 64;
rlm@1 881 break;
rlm@1 882 default:
rlm@1 883 continue;
rlm@1 884 }
rlm@1 885
rlm@1 886 #ifdef SPRITE_DEBUG
rlm@1 887 int maskX = sizeX-1;
rlm@1 888 int maskY = sizeY-1;
rlm@1 889 #endif
rlm@1 890
rlm@1 891 int sy = (a0 & 255);
rlm@1 892
rlm@1 893 if (sy > 160)
rlm@1 894 sy -= 256;
rlm@1 895
rlm@1 896 if (a0 & 0x0100)
rlm@1 897 {
rlm@1 898 int fieldX = sizeX;
rlm@1 899 int fieldY = sizeY;
rlm@1 900 if (a0 & 0x0200)
rlm@1 901 {
rlm@1 902 fieldX <<= 1;
rlm@1 903 fieldY <<= 1;
rlm@1 904 }
rlm@1 905
rlm@1 906 int t = VCOUNT - sy;
rlm@1 907 if ((t >= 0) && (t < fieldY))
rlm@1 908 {
rlm@1 909 int sx = (a1 & 0x1FF);
rlm@1 910 if ((sx < 240) || (((sx + fieldX) & 511) < 240))
rlm@1 911 {
rlm@1 912 // int t2 = t - (fieldY >> 1);
rlm@1 913 int rot = (a1 >> 9) & 0x1F;
rlm@1 914 u16 *OAM = (u16 *)oam;
rlm@1 915 int dx = READ16LE(&OAM[3 + (rot << 4)]);
rlm@1 916 if (dx & 0x8000)
rlm@1 917 dx |= 0xFFFF8000;
rlm@1 918 int dmx = READ16LE(&OAM[7 + (rot << 4)]);
rlm@1 919 if (dmx & 0x8000)
rlm@1 920 dmx |= 0xFFFF8000;
rlm@1 921 int dy = READ16LE(&OAM[11 + (rot << 4)]);
rlm@1 922 if (dy & 0x8000)
rlm@1 923 dy |= 0xFFFF8000;
rlm@1 924 int dmy = READ16LE(&OAM[15 + (rot << 4)]);
rlm@1 925 if (dmy & 0x8000)
rlm@1 926 dmy |= 0xFFFF8000;
rlm@1 927
rlm@1 928 if (a0 & 0x1000)
rlm@1 929 {
rlm@1 930 t -= (t % mosaicY);
rlm@1 931 }
rlm@1 932
rlm@1 933 int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx
rlm@1 934 + t * dmx;
rlm@1 935 int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
rlm@1 936 + t * dmy;
rlm@1 937
rlm@1 938 u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
rlm@1 939
rlm@1 940 if (a0 & 0x2000)
rlm@1 941 {
rlm@1 942 int c = (a2 & 0x3FF);
rlm@1 943 if ((DISPCNT & 7) > 2 && (c < 512))
rlm@1 944 continue;
rlm@1 945 int inc = 32;
rlm@1 946 if (DISPCNT & 0x40)
rlm@1 947 inc = sizeX >> 2;
rlm@1 948 else
rlm@1 949 c &= 0x3FE;
rlm@1 950 for (int x = 0; x < fieldX; x++)
rlm@1 951 {
rlm@1 952 int xxx = realX >> 8;
rlm@1 953 int yyy = realY >> 8;
rlm@1 954
rlm@1 955 if (xxx < 0 || xxx >= sizeX ||
rlm@1 956 yyy < 0 || yyy >= sizeY ||
rlm@1 957 sx >= 240)
rlm@1 958 ;
rlm@1 959 else
rlm@1 960 {
rlm@1 961 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
rlm@1 962 + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
rlm@1 963 (xxx & 7))&0x7FFF)];
rlm@1 964 if ((color == 0) && (((prio >> 25)&3) <
rlm@1 965 ((lineOBJ[sx]>>25)&3)))
rlm@1 966 {
rlm@1 967 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
rlm@1 968 if ((a0 & 0x1000) && m)
rlm@1 969 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 970 }
rlm@1 971 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
rlm@1 972 {
rlm@1 973 lineOBJ[sx] = READ16LE(&spritePalette[color]) | prio;
rlm@1 974 if ((a0 & 0x1000) && m)
rlm@1 975 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 976 }
rlm@1 977
rlm@1 978 if (a0 & 0x1000)
rlm@1 979 {
rlm@1 980 m++;
rlm@1 981 if (m == mosaicX)
rlm@1 982 m = 0;
rlm@1 983 }
rlm@1 984 #ifdef SPRITE_DEBUG
rlm@1 985 if (t == 0 || t == maskY || x == 0 || x == maskX)
rlm@1 986 lineOBJ[sx] = 0x001F;
rlm@1 987 #endif
rlm@1 988 }
rlm@1 989 sx = (sx+1)&511;;
rlm@1 990 realX += dx;
rlm@1 991 realY += dy;
rlm@1 992 }
rlm@1 993 }
rlm@1 994 else
rlm@1 995 {
rlm@1 996 int c = (a2 & 0x3FF);
rlm@1 997 if ((DISPCNT & 7) > 2 && (c < 512))
rlm@1 998 continue;
rlm@1 999
rlm@1 1000 int inc = 32;
rlm@1 1001 if (DISPCNT & 0x40)
rlm@1 1002 inc = sizeX >> 3;
rlm@1 1003 int palette = (a2 >> 8) & 0xF0;
rlm@1 1004 for (int x = 0; x < fieldX; x++)
rlm@1 1005 {
rlm@1 1006 int xxx = realX >> 8;
rlm@1 1007 int yyy = realY >> 8;
rlm@1 1008 if (xxx < 0 || xxx >= sizeX ||
rlm@1 1009 yyy < 0 || yyy >= sizeY ||
rlm@1 1010 sx >= 240)
rlm@1 1011 ;
rlm@1 1012 else
rlm@1 1013 {
rlm@1 1014 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
rlm@1 1015 + ((yyy & 7)<<2) + ((xxx >> 3)<<5) +
rlm@1 1016 ((xxx & 7)>>1))&0x7FFF)];
rlm@1 1017 if (xxx & 1)
rlm@1 1018 color >>= 4;
rlm@1 1019 else
rlm@1 1020 color &= 0x0F;
rlm@1 1021
rlm@1 1022 if ((color == 0) && (((prio >> 25)&3) <
rlm@1 1023 ((lineOBJ[sx]>>25)&3)))
rlm@1 1024 {
rlm@1 1025 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
rlm@1 1026 if ((a0 & 0x1000) && m)
rlm@1 1027 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 1028 }
rlm@1 1029 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
rlm@1 1030 {
rlm@1 1031 lineOBJ[sx] = READ16LE(&spritePalette[palette+color]) | prio;
rlm@1 1032 if ((a0 & 0x1000) && m)
rlm@1 1033 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 1034 }
rlm@1 1035 }
rlm@1 1036 if ((a0 & 0x1000) && m)
rlm@1 1037 {
rlm@1 1038 m++;
rlm@1 1039 if (m == mosaicX)
rlm@1 1040 m = 0;
rlm@1 1041 }
rlm@1 1042
rlm@1 1043 #ifdef SPRITE_DEBUG
rlm@1 1044 if (t == 0 || t == maskY || x == 0 || x == maskX)
rlm@1 1045 lineOBJ[sx] = 0x001F;
rlm@1 1046 #endif
rlm@1 1047 sx = (sx+1)&511;;
rlm@1 1048 realX += dx;
rlm@1 1049 realY += dy;
rlm@1 1050 }
rlm@1 1051 }
rlm@1 1052 }
rlm@1 1053 }
rlm@1 1054 }
rlm@1 1055 else
rlm@1 1056 {
rlm@1 1057 int t = VCOUNT - sy;
rlm@1 1058 if ((t >= 0) && (t < sizeY))
rlm@1 1059 {
rlm@1 1060 int sx = (a1 & 0x1FF);
rlm@1 1061 if (((sx < 240) || (((sx+sizeX)&511) < 240)) && !(a0 & 0x0200))
rlm@1 1062 {
rlm@1 1063 if (a0 & 0x2000)
rlm@1 1064 {
rlm@1 1065 if (a1 & 0x2000)
rlm@1 1066 t = sizeY - t - 1;
rlm@1 1067 int c = (a2 & 0x3FF);
rlm@1 1068 if ((DISPCNT & 7) > 2 && (c < 512))
rlm@1 1069 continue;
rlm@1 1070
rlm@1 1071 int inc = 32;
rlm@1 1072 if (DISPCNT & 0x40)
rlm@1 1073 {
rlm@1 1074 inc = sizeX >> 2;
rlm@1 1075 }
rlm@1 1076 else
rlm@1 1077 {
rlm@1 1078 c &= 0x3FE;
rlm@1 1079 }
rlm@1 1080 int xxx = 0;
rlm@1 1081 if (a1 & 0x1000)
rlm@1 1082 xxx = sizeX-1;
rlm@1 1083
rlm@1 1084 if (a0 & 0x1000)
rlm@1 1085 {
rlm@1 1086 t -= (t % mosaicY);
rlm@1 1087 }
rlm@1 1088
rlm@1 1089 int address = 0x10000 + ((((c+ (t>>3) * inc) << 5)
rlm@1 1090 + ((t & 7) << 3) + ((xxx>>3)<<6) + (xxx & 7)) & 0x7FFF);
rlm@1 1091
rlm@1 1092 if (a1 & 0x1000)
rlm@1 1093 xxx = 7;
rlm@1 1094 u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
rlm@1 1095
rlm@1 1096 for (int xx = 0; xx < sizeX; xx++)
rlm@1 1097 {
rlm@1 1098 if (sx < 240)
rlm@1 1099 {
rlm@1 1100 u8 color = vram[address];
rlm@1 1101 if ((color == 0) && (((prio >> 25)&3) <
rlm@1 1102 ((lineOBJ[sx]>>25)&3)))
rlm@1 1103 {
rlm@1 1104 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
rlm@1 1105 if ((a0 & 0x1000) && m)
rlm@1 1106 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 1107 }
rlm@1 1108 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
rlm@1 1109 {
rlm@1 1110 lineOBJ[sx] = READ16LE(&spritePalette[color]) | prio;
rlm@1 1111 if ((a0 & 0x1000) && m)
rlm@1 1112 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 1113 }
rlm@1 1114
rlm@1 1115 if (a0 & 0x1000)
rlm@1 1116 {
rlm@1 1117 m++;
rlm@1 1118 if (m == mosaicX)
rlm@1 1119 m = 0;
rlm@1 1120 }
rlm@1 1121
rlm@1 1122 #ifdef SPRITE_DEBUG
rlm@1 1123 if (t == 0 || t == maskY || xx == 0 || xx == maskX)
rlm@1 1124 lineOBJ[sx] = 0x001F;
rlm@1 1125 #endif
rlm@1 1126 }
rlm@1 1127
rlm@1 1128 sx = (sx+1) & 511;
rlm@1 1129 if (a1 & 0x1000)
rlm@1 1130 {
rlm@1 1131 xxx--;
rlm@1 1132 address--;
rlm@1 1133 if (xxx == -1)
rlm@1 1134 {
rlm@1 1135 address -= 56;
rlm@1 1136 xxx = 7;
rlm@1 1137 }
rlm@1 1138 if (address < 0x10000)
rlm@1 1139 address += 0x8000;
rlm@1 1140 }
rlm@1 1141 else
rlm@1 1142 {
rlm@1 1143 xxx++;
rlm@1 1144 address++;
rlm@1 1145 if (xxx == 8)
rlm@1 1146 {
rlm@1 1147 address += 56;
rlm@1 1148 xxx = 0;
rlm@1 1149 }
rlm@1 1150 if (address > 0x17fff)
rlm@1 1151 address -= 0x8000;
rlm@1 1152 }
rlm@1 1153 }
rlm@1 1154 }
rlm@1 1155 else
rlm@1 1156 {
rlm@1 1157 if (a1 & 0x2000)
rlm@1 1158 t = sizeY - t - 1;
rlm@1 1159 int c = (a2 & 0x3FF);
rlm@1 1160 if ((DISPCNT & 7) > 2 && (c < 512))
rlm@1 1161 continue;
rlm@1 1162
rlm@1 1163 int inc = 32;
rlm@1 1164 if (DISPCNT & 0x40)
rlm@1 1165 {
rlm@1 1166 inc = sizeX >> 3;
rlm@1 1167 }
rlm@1 1168 int xxx = 0;
rlm@1 1169 if (a1 & 0x1000)
rlm@1 1170 xxx = sizeX - 1;
rlm@1 1171
rlm@1 1172 if (a0 & 0x1000)
rlm@1 1173 {
rlm@1 1174 t -= (t % mosaicY);
rlm@1 1175 }
rlm@1 1176
rlm@1 1177 int address = 0x10000 + ((((c + (t>>3) * inc)<<5)
rlm@1 1178 + ((t & 7)<<2) + ((xxx>>3)<<5) + ((xxx & 7) >> 1))&0x7FFF);
rlm@1 1179 u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
rlm@1 1180 int palette = (a2 >> 8) & 0xF0;
rlm@1 1181 if (a1 & 0x1000)
rlm@1 1182 {
rlm@1 1183 xxx = 7;
rlm@1 1184 for (int xx = sizeX - 1; xx >= 0; xx--)
rlm@1 1185 {
rlm@1 1186 if (sx < 240)
rlm@1 1187 {
rlm@1 1188 u8 color = vram[address];
rlm@1 1189 if (xx & 1)
rlm@1 1190 {
rlm@1 1191 color = (color >> 4);
rlm@1 1192 }
rlm@1 1193 else
rlm@1 1194 color &= 0x0F;
rlm@1 1195
rlm@1 1196 if ((color == 0) && (((prio >> 25)&3) <
rlm@1 1197 ((lineOBJ[sx]>>25)&3)))
rlm@1 1198 {
rlm@1 1199 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
rlm@1 1200 if ((a0 & 0x1000) && m)
rlm@1 1201 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 1202 }
rlm@1 1203 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
rlm@1 1204 {
rlm@1 1205 lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;
rlm@1 1206 if ((a0 & 0x1000) && m)
rlm@1 1207 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 1208 }
rlm@1 1209 }
rlm@1 1210 if (a0 & 0x1000)
rlm@1 1211 {
rlm@1 1212 m++;
rlm@1 1213 if (m == mosaicX)
rlm@1 1214 m = 0;
rlm@1 1215 }
rlm@1 1216 #ifdef SPRITE_DEBUG
rlm@1 1217 if (t == 0 || t == maskY || xx == 0 || xx == maskX)
rlm@1 1218 lineOBJ[sx] = 0x001F;
rlm@1 1219 #endif
rlm@1 1220 sx = (sx+1) & 511;
rlm@1 1221 xxx--;
rlm@1 1222 if (!(xx & 1))
rlm@1 1223 address--;
rlm@1 1224 if (xxx == -1)
rlm@1 1225 {
rlm@1 1226 xxx = 7;
rlm@1 1227 address -= 28;
rlm@1 1228 }
rlm@1 1229 if (address < 0x10000)
rlm@1 1230 address += 0x8000;
rlm@1 1231 }
rlm@1 1232 }
rlm@1 1233 else
rlm@1 1234 {
rlm@1 1235 for (int xx = 0; xx < sizeX; xx++)
rlm@1 1236 {
rlm@1 1237 if (sx < 240)
rlm@1 1238 {
rlm@1 1239 u8 color = vram[address];
rlm@1 1240 if (xx & 1)
rlm@1 1241 {
rlm@1 1242 color = (color >> 4);
rlm@1 1243 }
rlm@1 1244 else
rlm@1 1245 color &= 0x0F;
rlm@1 1246
rlm@1 1247 if ((color == 0) && (((prio >> 25)&3) <
rlm@1 1248 ((lineOBJ[sx]>>25)&3)))
rlm@1 1249 {
rlm@1 1250 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
rlm@1 1251 if ((a0 & 0x1000) && m)
rlm@1 1252 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 1253 }
rlm@1 1254 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
rlm@1 1255 {
rlm@1 1256 lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;
rlm@1 1257 if ((a0 & 0x1000) && m)
rlm@1 1258 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
rlm@1 1259 }
rlm@1 1260 }
rlm@1 1261 if (a0 & 0x1000)
rlm@1 1262 {
rlm@1 1263 m++;
rlm@1 1264 if (m == mosaicX)
rlm@1 1265 m = 0;
rlm@1 1266 }
rlm@1 1267 #ifdef SPRITE_DEBUG
rlm@1 1268 if (t == 0 || t == maskY || xx == 0 || xx == maskX)
rlm@1 1269 lineOBJ[sx] = 0x001F;
rlm@1 1270 #endif
rlm@1 1271 sx = (sx+1) & 511;
rlm@1 1272 xxx++;
rlm@1 1273 if (xx & 1)
rlm@1 1274 address++;
rlm@1 1275 if (xxx == 8)
rlm@1 1276 {
rlm@1 1277 address += 28;
rlm@1 1278 xxx = 0;
rlm@1 1279 }
rlm@1 1280 if (address > 0x17fff)
rlm@1 1281 address -= 0x8000;
rlm@1 1282 }
rlm@1 1283 }
rlm@1 1284 }
rlm@1 1285 }
rlm@1 1286 }
rlm@1 1287 }
rlm@1 1288 }
rlm@1 1289 }
rlm@1 1290 }
rlm@1 1291
rlm@1 1292 inline void gfxDrawOBJWin(u32 *lineOBJWin)
rlm@1 1293 {
rlm@1 1294 gfxClearArray(lineOBJWin);
rlm@1 1295 if (layerEnable & 0x8000)
rlm@1 1296 {
rlm@1 1297 u16 *sprites = (u16 *)oam;
rlm@1 1298 // u16 *spritePalette = &((u16 *)paletteRAM)[256];
rlm@1 1299 for (int x = 0; x < 128; x++)
rlm@1 1300 {
rlm@1 1301 u16 a0 = READ16LE(sprites++);
rlm@1 1302 u16 a1 = READ16LE(sprites++);
rlm@1 1303 u16 a2 = READ16LE(sprites++);
rlm@1 1304 sprites++;
rlm@1 1305
rlm@1 1306 // ignore non OBJ-WIN
rlm@1 1307 if ((a0 & 0x0c00) != 0x0800)
rlm@1 1308 continue;
rlm@1 1309
rlm@1 1310 int sizeY = 8;
rlm@1 1311 int sizeX = 8;
rlm@1 1312
rlm@1 1313 switch (((a0 >>12) & 0x0c)|(a1>>14))
rlm@1 1314 {
rlm@1 1315 case 0:
rlm@1 1316 break;
rlm@1 1317 case 1:
rlm@1 1318 sizeX = sizeY = 16;
rlm@1 1319 break;
rlm@1 1320 case 2:
rlm@1 1321 sizeX = sizeY = 32;
rlm@1 1322 break;
rlm@1 1323 case 3:
rlm@1 1324 sizeX = sizeY = 64;
rlm@1 1325 break;
rlm@1 1326 case 4:
rlm@1 1327 sizeX = 16;
rlm@1 1328 break;
rlm@1 1329 case 5:
rlm@1 1330 sizeX = 32;
rlm@1 1331 break;
rlm@1 1332 case 6:
rlm@1 1333 sizeX = 32;
rlm@1 1334 sizeY = 16;
rlm@1 1335 break;
rlm@1 1336 case 7:
rlm@1 1337 sizeX = 64;
rlm@1 1338 sizeY = 32;
rlm@1 1339 break;
rlm@1 1340 case 8:
rlm@1 1341 sizeY = 16;
rlm@1 1342 break;
rlm@1 1343 case 9:
rlm@1 1344 sizeY = 32;
rlm@1 1345 break;
rlm@1 1346 case 10:
rlm@1 1347 sizeX = 16;
rlm@1 1348 sizeY = 32;
rlm@1 1349 break;
rlm@1 1350 case 11:
rlm@1 1351 sizeX = 32;
rlm@1 1352 sizeY = 64;
rlm@1 1353 break;
rlm@1 1354 default:
rlm@1 1355 continue;
rlm@1 1356 }
rlm@1 1357
rlm@1 1358 int sy = (a0 & 255);
rlm@1 1359
rlm@1 1360 if (sy > 160)
rlm@1 1361 sy -= 256;
rlm@1 1362
rlm@1 1363 if (a0 & 0x0100)
rlm@1 1364 {
rlm@1 1365 int fieldX = sizeX;
rlm@1 1366 int fieldY = sizeY;
rlm@1 1367 if (a0 & 0x0200)
rlm@1 1368 {
rlm@1 1369 fieldX <<= 1;
rlm@1 1370 fieldY <<= 1;
rlm@1 1371 }
rlm@1 1372
rlm@1 1373 int t = VCOUNT - sy;
rlm@1 1374 if ((t >= 0) && (t < fieldY))
rlm@1 1375 {
rlm@1 1376 int sx = (a1 & 0x1FF);
rlm@1 1377 if ((sx < 240) || (((sx + fieldX) & 511) < 240))
rlm@1 1378 {
rlm@1 1379 // int t2 = t - (fieldY >> 1);
rlm@1 1380 int rot = (a1 >> 9) & 0x1F;
rlm@1 1381 u16 *OAM = (u16 *)oam;
rlm@1 1382 int dx = READ16LE(&OAM[3 + (rot << 4)]);
rlm@1 1383 if (dx & 0x8000)
rlm@1 1384 dx |= 0xFFFF8000;
rlm@1 1385 int dmx = READ16LE(&OAM[7 + (rot << 4)]);
rlm@1 1386 if (dmx & 0x8000)
rlm@1 1387 dmx |= 0xFFFF8000;
rlm@1 1388 int dy = READ16LE(&OAM[11 + (rot << 4)]);
rlm@1 1389 if (dy & 0x8000)
rlm@1 1390 dy |= 0xFFFF8000;
rlm@1 1391 int dmy = READ16LE(&OAM[15 + (rot << 4)]);
rlm@1 1392 if (dmy & 0x8000)
rlm@1 1393 dmy |= 0xFFFF8000;
rlm@1 1394
rlm@1 1395 int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx
rlm@1 1396 + t * dmx;
rlm@1 1397 int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
rlm@1 1398 + t * dmy;
rlm@1 1399
rlm@1 1400 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
rlm@1 1401
rlm@1 1402 if (a0 & 0x2000)
rlm@1 1403 {
rlm@1 1404 int c = (a2 & 0x3FF);
rlm@1 1405 if ((DISPCNT & 7) > 2 && (c < 512))
rlm@1 1406 continue;
rlm@1 1407 int inc = 32;
rlm@1 1408 if (DISPCNT & 0x40)
rlm@1 1409 inc = sizeX >> 2;
rlm@1 1410 else
rlm@1 1411 c &= 0x3FE;
rlm@1 1412 for (int x = 0; x < fieldX; x++)
rlm@1 1413 {
rlm@1 1414 int xxx = realX >> 8;
rlm@1 1415 int yyy = realY >> 8;
rlm@1 1416
rlm@1 1417 if (xxx < 0 || xxx >= sizeX ||
rlm@1 1418 yyy < 0 || yyy >= sizeY)
rlm@1 1419 {}
rlm@1 1420 else
rlm@1 1421 {
rlm@1 1422 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
rlm@1 1423 + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
rlm@1 1424 (xxx & 7))&0x7fff)];
rlm@1 1425 if (color)
rlm@1 1426 {
rlm@1 1427 lineOBJWin[sx] = 1;
rlm@1 1428 }
rlm@1 1429 }
rlm@1 1430 sx = (sx+1)&511;;
rlm@1 1431 realX += dx;
rlm@1 1432 realY += dy;
rlm@1 1433 }
rlm@1 1434 }
rlm@1 1435 else
rlm@1 1436 {
rlm@1 1437 int c = (a2 & 0x3FF);
rlm@1 1438 if ((DISPCNT & 7) > 2 && (c < 512))
rlm@1 1439 continue;
rlm@1 1440
rlm@1 1441 int inc = 32;
rlm@1 1442 if (DISPCNT & 0x40)
rlm@1 1443 inc = sizeX >> 3;
rlm@1 1444 // int palette = (a2 >> 8) & 0xF0;
rlm@1 1445 for (int x = 0; x < fieldX; x++)
rlm@1 1446 {
rlm@1 1447 int xxx = realX >> 8;
rlm@1 1448 int yyy = realY >> 8;
rlm@1 1449
rlm@1 1450 // if(x == 0 || x == (sizeX-1) ||
rlm@1 1451 // t == 0 || t == (sizeY-1)) {
rlm@1 1452 // lineOBJ[sx] = 0x001F | prio;
rlm@1 1453 // } else {
rlm@1 1454 if (xxx < 0 || xxx >= sizeX ||
rlm@1 1455 yyy < 0 || yyy >= sizeY)
rlm@1 1456 {}
rlm@1 1457 else
rlm@1 1458 {
rlm@1 1459 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
rlm@1 1460 + ((yyy & 7)<<2) + ((xxx >> 3)<<5) +
rlm@1 1461 ((xxx & 7)>>1))&0x7fff)];
rlm@1 1462 if (xxx & 1)
rlm@1 1463 color >>= 4;
rlm@1 1464 else
rlm@1 1465 color &= 0x0F;
rlm@1 1466
rlm@1 1467 if (color)
rlm@1 1468 {
rlm@1 1469 lineOBJWin[sx] = 1;
rlm@1 1470 }
rlm@1 1471 }
rlm@1 1472 // }
rlm@1 1473 sx = (sx+1)&511;;
rlm@1 1474 realX += dx;
rlm@1 1475 realY += dy;
rlm@1 1476 }
rlm@1 1477 }
rlm@1 1478 }
rlm@1 1479 }
rlm@1 1480 }
rlm@1 1481 else
rlm@1 1482 {
rlm@1 1483 int t = VCOUNT - sy;
rlm@1 1484 if ((t >= 0) && (t < sizeY))
rlm@1 1485 {
rlm@1 1486 int sx = (a1 & 0x1FF);
rlm@1 1487 if (((sx < 240) || (((sx+sizeX)&511) < 240)) && !(a0 & 0x0200))
rlm@1 1488 {
rlm@1 1489 if (a0 & 0x2000)
rlm@1 1490 {
rlm@1 1491 if (a1 & 0x2000)
rlm@1 1492 t = sizeY - t - 1;
rlm@1 1493 int c = (a2 & 0x3FF);
rlm@1 1494 if ((DISPCNT & 7) > 2 && (c < 512))
rlm@1 1495 continue;
rlm@1 1496
rlm@1 1497 int inc = 32;
rlm@1 1498 if (DISPCNT & 0x40)
rlm@1 1499 {
rlm@1 1500 inc = sizeX >> 2;
rlm@1 1501 }
rlm@1 1502 else
rlm@1 1503 {
rlm@1 1504 c &= 0x3FE;
rlm@1 1505 }
rlm@1 1506 int xxx = 0;
rlm@1 1507 if (a1 & 0x1000)
rlm@1 1508 xxx = sizeX-1;
rlm@1 1509 int address = 0x10000 + ((((c+ (t>>3) * inc) << 5)
rlm@1 1510 + ((t & 7) << 3) + ((xxx>>3)<<6) + (xxx & 7))&0x7fff);
rlm@1 1511 if (a1 & 0x1000)
rlm@1 1512 xxx = 7;
rlm@1 1513 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
rlm@1 1514 for (int xx = 0; xx < sizeX; xx++)
rlm@1 1515 {
rlm@1 1516 if (sx < 240)
rlm@1 1517 {
rlm@1 1518 u8 color = vram[address];
rlm@1 1519 if (color)
rlm@1 1520 {
rlm@1 1521 lineOBJWin[sx] = 1;
rlm@1 1522 }
rlm@1 1523 }
rlm@1 1524
rlm@1 1525 sx = (sx+1) & 511;
rlm@1 1526 if (a1 & 0x1000)
rlm@1 1527 {
rlm@1 1528 xxx--;
rlm@1 1529 address--;
rlm@1 1530 if (xxx == -1)
rlm@1 1531 {
rlm@1 1532 address -= 56;
rlm@1 1533 xxx = 7;
rlm@1 1534 }
rlm@1 1535 if (address < 0x10000)
rlm@1 1536 address += 0x8000;
rlm@1 1537 }
rlm@1 1538 else
rlm@1 1539 {
rlm@1 1540 xxx++;
rlm@1 1541 address++;
rlm@1 1542 if (xxx == 8)
rlm@1 1543 {
rlm@1 1544 address += 56;
rlm@1 1545 xxx = 0;
rlm@1 1546 }
rlm@1 1547 if (address > 0x17fff)
rlm@1 1548 address -= 0x8000;
rlm@1 1549 }
rlm@1 1550 }
rlm@1 1551 }
rlm@1 1552 else
rlm@1 1553 {
rlm@1 1554 if (a1 & 0x2000)
rlm@1 1555 t = sizeY - t - 1;
rlm@1 1556 int c = (a2 & 0x3FF);
rlm@1 1557 if ((DISPCNT & 7) > 2 && (c < 512))
rlm@1 1558 continue;
rlm@1 1559
rlm@1 1560 int inc = 32;
rlm@1 1561 if (DISPCNT & 0x40)
rlm@1 1562 {
rlm@1 1563 inc = sizeX >> 3;
rlm@1 1564 }
rlm@1 1565 int xxx = 0;
rlm@1 1566 if (a1 & 0x1000)
rlm@1 1567 xxx = sizeX - 1;
rlm@1 1568 int address = 0x10000 + ((((c + (t>>3) * inc)<<5)
rlm@1 1569 + ((t & 7)<<2) + ((xxx>>3)<<5) + ((xxx & 7) >> 1))&0x7fff);
rlm@1 1570 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
rlm@1 1571 // int palette = (a2 >> 8) & 0xF0;
rlm@1 1572 if (a1 & 0x1000)
rlm@1 1573 {
rlm@1 1574 xxx = 7;
rlm@1 1575 for (int xx = sizeX - 1; xx >= 0; xx--)
rlm@1 1576 {
rlm@1 1577 if (sx < 240)
rlm@1 1578 {
rlm@1 1579 u8 color = vram[address];
rlm@1 1580 if (xx & 1)
rlm@1 1581 {
rlm@1 1582 color = (color >> 4);
rlm@1 1583 }
rlm@1 1584 else
rlm@1 1585 color &= 0x0F;
rlm@1 1586
rlm@1 1587 if (color)
rlm@1 1588 {
rlm@1 1589 lineOBJWin[sx] = 1;
rlm@1 1590 }
rlm@1 1591 }
rlm@1 1592 sx = (sx+1) & 511;
rlm@1 1593 xxx--;
rlm@1 1594 if (!(xx & 1))
rlm@1 1595 address--;
rlm@1 1596 if (xxx == -1)
rlm@1 1597 {
rlm@1 1598 xxx = 7;
rlm@1 1599 address -= 28;
rlm@1 1600 }
rlm@1 1601 if (address < 0x10000)
rlm@1 1602 address += 0x8000;
rlm@1 1603 }
rlm@1 1604 }
rlm@1 1605 else
rlm@1 1606 {
rlm@1 1607 for (int xx = 0; xx < sizeX; xx++)
rlm@1 1608 {
rlm@1 1609 if (sx < 240)
rlm@1 1610 {
rlm@1 1611 u8 color = vram[address];
rlm@1 1612 if (xx & 1)
rlm@1 1613 {
rlm@1 1614 color = (color >> 4);
rlm@1 1615 }
rlm@1 1616 else
rlm@1 1617 color &= 0x0F;
rlm@1 1618
rlm@1 1619 if (color)
rlm@1 1620 {
rlm@1 1621 lineOBJWin[sx] = 1;
rlm@1 1622 }
rlm@1 1623 }
rlm@1 1624 sx = (sx+1) & 511;
rlm@1 1625 xxx++;
rlm@1 1626 if (xx & 1)
rlm@1 1627 address++;
rlm@1 1628 if (xxx == 8)
rlm@1 1629 {
rlm@1 1630 address += 28;
rlm@1 1631 xxx = 0;
rlm@1 1632 }
rlm@1 1633 if (address > 0x17fff)
rlm@1 1634 address -= 0x8000;
rlm@1 1635 }
rlm@1 1636 }
rlm@1 1637 }
rlm@1 1638 }
rlm@1 1639 }
rlm@1 1640 }
rlm@1 1641 }
rlm@1 1642 }
rlm@1 1643 }
rlm@1 1644
rlm@1 1645 inline u32 gfxIncreaseBrightness(u32 color, int coeff)
rlm@1 1646 {
rlm@1 1647 int r = (color & 0x1F);
rlm@1 1648 int g = ((color >> 5) & 0x1F);
rlm@1 1649 int b = ((color >> 10) & 0x1F);
rlm@1 1650
rlm@1 1651 r = r + (((31 - r) * coeff) >> 4);
rlm@1 1652 g = g + (((31 - g) * coeff) >> 4);
rlm@1 1653 b = b + (((31 - b) * coeff) >> 4);
rlm@1 1654 if (r > 31)
rlm@1 1655 r = 31;
rlm@1 1656 if (g > 31)
rlm@1 1657 g = 31;
rlm@1 1658 if (b > 31)
rlm@1 1659 b = 31;
rlm@1 1660 color = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
rlm@1 1661 return color;
rlm@1 1662 }
rlm@1 1663
rlm@1 1664 inline void gfxIncreaseBrightness(u32 *line, int coeff)
rlm@1 1665 {
rlm@1 1666 for (int x = 0; x < 240; x++)
rlm@1 1667 {
rlm@1 1668 u32 color = *line;
rlm@1 1669 int r = (color & 0x1F);
rlm@1 1670 int g = ((color >> 5) & 0x1F);
rlm@1 1671 int b = ((color >> 10) & 0x1F);
rlm@1 1672
rlm@1 1673 r = r + (((31 - r) * coeff) >> 4);
rlm@1 1674 g = g + (((31 - g) * coeff) >> 4);
rlm@1 1675 b = b + (((31 - b) * coeff) >> 4);
rlm@1 1676 if (r > 31)
rlm@1 1677 r = 31;
rlm@1 1678 if (g > 31)
rlm@1 1679 g = 31;
rlm@1 1680 if (b > 31)
rlm@1 1681 b = 31;
rlm@1 1682 *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
rlm@1 1683 }
rlm@1 1684 }
rlm@1 1685
rlm@1 1686 inline u32 gfxDecreaseBrightness(u32 color, int coeff)
rlm@1 1687 {
rlm@1 1688 int r = (color & 0x1F);
rlm@1 1689 int g = ((color >> 5) & 0x1F);
rlm@1 1690 int b = ((color >> 10) & 0x1F);
rlm@1 1691
rlm@1 1692 r = r - ((r * coeff) >> 4);
rlm@1 1693 g = g - ((g * coeff) >> 4);
rlm@1 1694 b = b - ((b * coeff) >> 4);
rlm@1 1695 if (r < 0)
rlm@1 1696 r = 0;
rlm@1 1697 if (g < 0)
rlm@1 1698 g = 0;
rlm@1 1699 if (b < 0)
rlm@1 1700 b = 0;
rlm@1 1701 color = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
rlm@1 1702
rlm@1 1703 return color;
rlm@1 1704 }
rlm@1 1705
rlm@1 1706 inline void gfxDecreaseBrightness(u32 *line, int coeff)
rlm@1 1707 {
rlm@1 1708 for (int x = 0; x < 240; x++)
rlm@1 1709 {
rlm@1 1710 u32 color = *line;
rlm@1 1711 int r = (color & 0x1F);
rlm@1 1712 int g = ((color >> 5) & 0x1F);
rlm@1 1713 int b = ((color >> 10) & 0x1F);
rlm@1 1714
rlm@1 1715 r = r - ((r * coeff) >> 4);
rlm@1 1716 g = g - ((g * coeff) >> 4);
rlm@1 1717 b = b - ((b * coeff) >> 4);
rlm@1 1718 if (r < 0)
rlm@1 1719 r = 0;
rlm@1 1720 if (g < 0)
rlm@1 1721 g = 0;
rlm@1 1722 if (b < 0)
rlm@1 1723 b = 0;
rlm@1 1724 *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
rlm@1 1725 }
rlm@1 1726 }
rlm@1 1727
rlm@1 1728 inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)
rlm@1 1729 {
rlm@1 1730 if (color < 0x80000000)
rlm@1 1731 {
rlm@1 1732 int r = (color & 0x1F);
rlm@1 1733 int g = ((color >> 5) & 0x1F);
rlm@1 1734 int b = ((color >> 10) & 0x1F);
rlm@1 1735 int r0 = (color2 & 0x1F);
rlm@1 1736 int g0 = ((color2 >> 5) & 0x1F);
rlm@1 1737 int b0 = ((color2 >> 10) & 0x1F);
rlm@1 1738
rlm@1 1739 r = ((r * ca) >> 4) + ((r0 * cb) >> 4);
rlm@1 1740 g = ((g * ca) >> 4) + ((g0 * cb) >> 4);
rlm@1 1741 b = ((b * ca) >> 4) + ((b0 * cb) >> 4);
rlm@1 1742
rlm@1 1743 if (r > 31)
rlm@1 1744 r = 31;
rlm@1 1745 if (g > 31)
rlm@1 1746 g = 31;
rlm@1 1747 if (b > 31)
rlm@1 1748 b = 31;
rlm@1 1749
rlm@1 1750 return (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
rlm@1 1751 }
rlm@1 1752 return color;
rlm@1 1753 }
rlm@1 1754
rlm@1 1755 inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)
rlm@1 1756 {
rlm@1 1757 for (int x = 0; x < 240; x++)
rlm@1 1758 {
rlm@1 1759 u32 color = *ta;
rlm@1 1760 if (color < 0x80000000)
rlm@1 1761 {
rlm@1 1762 int r = (color & 0x1F);
rlm@1 1763 int g = ((color >> 5) & 0x1F);
rlm@1 1764 int b = ((color >> 10) & 0x1F);
rlm@1 1765 u32 color2 = (*tb++);
rlm@1 1766 int r0 = (color2 & 0x1F);
rlm@1 1767 int g0 = ((color2 >> 5) & 0x1F);
rlm@1 1768 int b0 = ((color2 >> 10) & 0x1F);
rlm@1 1769
rlm@1 1770 r = ((r * ca) >> 4) + ((r0 * cb) >> 4);
rlm@1 1771 g = ((g * ca) >> 4) + ((g0 * cb) >> 4);
rlm@1 1772 b = ((b * ca) >> 4) + ((b0 * cb) >> 4);
rlm@1 1773
rlm@1 1774 if (r > 31)
rlm@1 1775 r = 31;
rlm@1 1776 if (g > 31)
rlm@1 1777 g = 31;
rlm@1 1778 if (b > 31)
rlm@1 1779 b = 31;
rlm@1 1780
rlm@1 1781 *ta++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
rlm@1 1782 }
rlm@1 1783 else
rlm@1 1784 {
rlm@1 1785 ta++;
rlm@1 1786 tb++;
rlm@1 1787 }
rlm@1 1788 }
rlm@1 1789 }
rlm@1 1790
rlm@1 1791 #endif // VBA_GBA_GFX_H