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