view src/gba/Mode0.cpp @ 38:b374503a5b31

video does not appear to de-sync after 3 minutes of playing and several random battles.
author Robert McIntyre <rlm@mit.edu>
date Mon, 05 Mar 2012 15:06:22 -0600
parents f9f4f1b99eed
children
line wrap: on
line source
1 #include "GBAGfx.h"
2 #include "GBAGlobals.h"
4 void mode0RenderLine()
5 {
6 u16 *palette = (u16 *)paletteRAM;
8 if (DISPCNT & 0x80)
9 {
10 for (int x = 0; x < 240; x++)
11 {
12 lineMix[x] = 0x7fff;
13 }
14 return;
15 }
17 if (layerEnable & 0x0100)
18 {
19 gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
20 }
22 if (layerEnable & 0x0200)
23 {
24 gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
25 }
27 if (layerEnable & 0x0400)
28 {
29 gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
30 }
32 if (layerEnable & 0x0800)
33 {
34 gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
35 }
37 gfxDrawSprites(lineOBJ);
39 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
41 for (int x = 0; x < 240; x++)
42 {
43 u32 color = backdrop;
44 u8 top = 0x20;
46 if (line0[x] < color)
47 {
48 color = line0[x];
49 top = 0x01;
50 }
52 if ((u8)(line1[x]>>24) < (u8)(color >> 24))
53 {
54 color = line1[x];
55 top = 0x02;
56 }
58 if ((u8)(line2[x]>>24) < (u8)(color >> 24))
59 {
60 color = line2[x];
61 top = 0x04;
62 }
64 if ((u8)(line3[x]>>24) < (u8)(color >> 24))
65 {
66 color = line3[x];
67 top = 0x08;
68 }
70 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
71 {
72 color = lineOBJ[x];
73 top = 0x10;
74 }
76 if ((top & 0x10) && (color & 0x00010000))
77 {
78 // semi-transparent OBJ
79 u32 back = backdrop;
80 u8 top2 = 0x20;
82 if ((u8)(line0[x]>>24) < (u8)(back >> 24))
83 {
84 back = line0[x];
85 top2 = 0x01;
86 }
88 if ((u8)(line1[x]>>24) < (u8)(back >> 24))
89 {
90 back = line1[x];
91 top2 = 0x02;
92 }
94 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
95 {
96 back = line2[x];
97 top2 = 0x04;
98 }
100 if ((u8)(line3[x]>>24) < (u8)(back >> 24))
101 {
102 back = line3[x];
103 top2 = 0x08;
104 }
106 if (top2 & (BLDMOD>>8))
107 color = gfxAlphaBlend(color, back,
108 coeff[COLEV & 0x1F],
109 coeff[(COLEV >> 8) & 0x1F]);
110 else
111 {
112 switch ((BLDMOD >> 6) & 3)
113 {
114 case 2:
115 if (BLDMOD & top)
116 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
117 break;
118 case 3:
119 if (BLDMOD & top)
120 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
121 break;
122 }
123 }
124 }
126 lineMix[x] = color;
127 }
128 }
130 void mode0RenderLineNoWindow()
131 {
132 u16 *palette = (u16 *)paletteRAM;
134 if (DISPCNT & 0x80)
135 {
136 for (int x = 0; x < 240; x++)
137 {
138 lineMix[x] = 0x7fff;
139 }
140 return;
141 }
143 if (layerEnable & 0x0100)
144 {
145 gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
146 }
148 if (layerEnable & 0x0200)
149 {
150 gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
151 }
153 if (layerEnable & 0x0400)
154 {
155 gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
156 }
158 if (layerEnable & 0x0800)
159 {
160 gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
161 }
163 gfxDrawSprites(lineOBJ);
165 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
167 int effect = (BLDMOD >> 6) & 3;
169 for (int x = 0; x < 240; x++)
170 {
171 u32 color = backdrop;
172 u8 top = 0x20;
174 if (line0[x] < color)
175 {
176 color = line0[x];
177 top = 0x01;
178 }
180 if (line1[x] < (color & 0xFF000000))
181 {
182 color = line1[x];
183 top = 0x02;
184 }
186 if (line2[x] < (color & 0xFF000000))
187 {
188 color = line2[x];
189 top = 0x04;
190 }
192 if (line3[x] < (color & 0xFF000000))
193 {
194 color = line3[x];
195 top = 0x08;
196 }
198 if (lineOBJ[x] < (color & 0xFF000000))
199 {
200 color = lineOBJ[x];
201 top = 0x10;
202 }
204 if (!(color & 0x00010000))
205 {
206 switch (effect)
207 {
208 case 0:
209 break;
210 case 1:
211 {
212 if (top & BLDMOD)
213 {
214 u32 back = backdrop;
215 u8 top2 = 0x20;
216 if (line0[x] < back)
217 {
218 if (top != 0x01)
219 {
220 back = line0[x];
221 top2 = 0x01;
222 }
223 }
225 if (line1[x] < (back & 0xFF000000))
226 {
227 if (top != 0x02)
228 {
229 back = line1[x];
230 top2 = 0x02;
231 }
232 }
234 if (line2[x] < (back & 0xFF000000))
235 {
236 if (top != 0x04)
237 {
238 back = line2[x];
239 top2 = 0x04;
240 }
241 }
243 if (line3[x] < (back & 0xFF000000))
244 {
245 if (top != 0x08)
246 {
247 back = line3[x];
248 top2 = 0x08;
249 }
250 }
252 if (lineOBJ[x] < (back & 0xFF000000))
253 {
254 if (top != 0x10)
255 {
256 back = lineOBJ[x];
257 top2 = 0x10;
258 }
259 }
261 if (top2 & (BLDMOD>>8))
262 color = gfxAlphaBlend(color, back,
263 coeff[COLEV & 0x1F],
264 coeff[(COLEV >> 8) & 0x1F]);
265 }
266 break;
267 }
268 case 2:
269 if (BLDMOD & top)
270 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
271 break;
272 case 3:
273 if (BLDMOD & top)
274 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
275 break;
276 }
277 }
278 else
279 {
280 // semi-transparent OBJ
281 u32 back = backdrop;
282 u8 top2 = 0x20;
284 if (line0[x] < back)
285 {
286 back = line0[x];
287 top2 = 0x01;
288 }
290 if (line1[x] < (back & 0xFF000000))
291 {
292 back = line1[x];
293 top2 = 0x02;
294 }
296 if (line2[x] < (back & 0xFF000000))
297 {
298 back = line2[x];
299 top2 = 0x04;
300 }
302 if (line3[x] < (back & 0xFF000000))
303 {
304 back = line3[x];
305 top2 = 0x08;
306 }
308 if (top2 & (BLDMOD>>8))
309 color = gfxAlphaBlend(color, back,
310 coeff[COLEV & 0x1F],
311 coeff[(COLEV >> 8) & 0x1F]);
312 else
313 {
314 switch ((BLDMOD >> 6) & 3)
315 {
316 case 2:
317 if (BLDMOD & top)
318 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
319 break;
320 case 3:
321 if (BLDMOD & top)
322 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
323 break;
324 }
325 }
326 }
328 lineMix[x] = color;
329 }
330 }
332 void mode0RenderLineAll()
333 {
334 u16 *palette = (u16 *)paletteRAM;
336 if (DISPCNT & 0x80)
337 {
338 for (int x = 0; x < 240; x++)
339 {
340 lineMix[x] = 0x7fff;
341 }
342 return;
343 }
345 bool inWindow0 = false;
346 bool inWindow1 = false;
348 if (layerEnable & 0x2000)
349 {
350 u8 v0 = WIN0V >> 8;
351 u8 v1 = WIN0V & 255;
352 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
353 if (v1 >= v0)
354 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
355 else
356 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
357 }
358 if (layerEnable & 0x4000)
359 {
360 u8 v0 = WIN1V >> 8;
361 u8 v1 = WIN1V & 255;
362 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
363 if (v1 >= v0)
364 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
365 else
366 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
367 }
369 if ((layerEnable & 0x0100))
370 {
371 gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
372 }
374 if ((layerEnable & 0x0200))
375 {
376 gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
377 }
379 if ((layerEnable & 0x0400))
380 {
381 gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
382 }
384 if ((layerEnable & 0x0800))
385 {
386 gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
387 }
389 gfxDrawSprites(lineOBJ);
390 gfxDrawOBJWin(lineOBJWin);
392 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
394 u8 inWin0Mask = WININ & 0xFF;
395 u8 inWin1Mask = WININ >> 8;
396 u8 outMask = WINOUT & 0xFF;
398 for (int x = 0; x < 240; x++)
399 {
400 u32 color = backdrop;
401 u8 top = 0x20;
402 u8 mask = outMask;
404 if (!(lineOBJWin[x] & 0x80000000))
405 {
406 mask = WINOUT >> 8;
407 }
409 if (inWindow1)
410 {
411 if (gfxInWin1[x])
412 mask = inWin1Mask;
413 }
415 if (inWindow0)
416 {
417 if (gfxInWin0[x])
418 {
419 mask = inWin0Mask;
420 }
421 }
423 if ((mask & 1) && (line0[x] < color))
424 {
425 color = line0[x];
426 top = 0x01;
427 }
429 if ((mask & 2) && ((u8)(line1[x]>>24) < (u8)(color >> 24)))
430 {
431 color = line1[x];
432 top = 0x02;
433 }
435 if ((mask & 4) && ((u8)(line2[x]>>24) < (u8)(color >> 24)))
436 {
437 color = line2[x];
438 top = 0x04;
439 }
441 if ((mask & 8) && ((u8)(line3[x]>>24) < (u8)(color >> 24)))
442 {
443 color = line3[x];
444 top = 0x08;
445 }
447 if ((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)))
448 {
449 color = lineOBJ[x];
450 top = 0x10;
451 }
453 // special FX on in the window
454 if (mask & 32)
455 {
456 if (!(color & 0x00010000))
457 {
458 switch ((BLDMOD >> 6) & 3)
459 {
460 case 0:
461 break;
462 case 1:
463 {
464 if (top & BLDMOD)
465 {
466 u32 back = backdrop;
467 u8 top2 = 0x20;
468 if ((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24))
469 {
470 if (top != 0x01)
471 {
472 back = line0[x];
473 top2 = 0x01;
474 }
475 }
477 if ((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24))
478 {
479 if (top != 0x02)
480 {
481 back = line1[x];
482 top2 = 0x02;
483 }
484 }
486 if ((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24))
487 {
488 if (top != 0x04)
489 {
490 back = line2[x];
491 top2 = 0x04;
492 }
493 }
495 if ((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
496 {
497 if (top != 0x08)
498 {
499 back = line3[x];
500 top2 = 0x08;
501 }
502 }
504 if ((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
505 {
506 if (top != 0x10)
507 {
508 back = lineOBJ[x];
509 top2 = 0x10;
510 }
511 }
513 if (top2 & (BLDMOD>>8))
514 color = gfxAlphaBlend(color, back,
515 coeff[COLEV & 0x1F],
516 coeff[(COLEV >> 8) & 0x1F]);
517 }
518 break;
519 }
520 case 2:
521 if (BLDMOD & top)
522 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
523 break;
524 case 3:
525 if (BLDMOD & top)
526 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
527 break;
528 }
529 }
530 else
531 {
532 // semi-transparent OBJ
533 u32 back = backdrop;
534 u8 top2 = 0x20;
536 if ((mask & 1) && ((u8)(line0[x]>>24) < (u8)(back >> 24)))
537 {
538 back = line0[x];
539 top2 = 0x01;
540 }
542 if ((mask & 2) && ((u8)(line1[x]>>24) < (u8)(back >> 24)))
543 {
544 back = line1[x];
545 top2 = 0x02;
546 }
548 if ((mask & 4) && ((u8)(line2[x]>>24) < (u8)(back >> 24)))
549 {
550 back = line2[x];
551 top2 = 0x04;
552 }
554 if ((mask & 8) && ((u8)(line3[x]>>24) < (u8)(back >> 24)))
555 {
556 back = line3[x];
557 top2 = 0x08;
558 }
560 if (top2 & (BLDMOD>>8))
561 color = gfxAlphaBlend(color, back,
562 coeff[COLEV & 0x1F],
563 coeff[(COLEV >> 8) & 0x1F]);
564 else
565 {
566 switch ((BLDMOD >> 6) & 3)
567 {
568 case 2:
569 if (BLDMOD & top)
570 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
571 break;
572 case 3:
573 if (BLDMOD & top)
574 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
575 break;
576 }
577 }
578 }
579 }
580 else if (color & 0x00010000)
581 {
582 // semi-transparent OBJ
583 u32 back = backdrop;
584 u8 top2 = 0x20;
586 if ((mask & 1) && ((u8)(line0[x]>>24) < (u8)(back >> 24)))
587 {
588 back = line0[x];
589 top2 = 0x01;
590 }
592 if ((mask & 2) && ((u8)(line1[x]>>24) < (u8)(back >> 24)))
593 {
594 back = line1[x];
595 top2 = 0x02;
596 }
598 if ((mask & 4) && ((u8)(line2[x]>>24) < (u8)(back >> 24)))
599 {
600 back = line2[x];
601 top2 = 0x04;
602 }
604 if ((mask & 8) && ((u8)(line3[x]>>24) < (u8)(back >> 24)))
605 {
606 back = line3[x];
607 top2 = 0x08;
608 }
610 if (top2 & (BLDMOD>>8))
611 color = gfxAlphaBlend(color, back,
612 coeff[COLEV & 0x1F],
613 coeff[(COLEV >> 8) & 0x1F]);
614 else
615 {
616 switch ((BLDMOD >> 6) & 3)
617 {
618 case 2:
619 if (BLDMOD & top)
620 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
621 break;
622 case 3:
623 if (BLDMOD & top)
624 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
625 break;
626 }
627 }
628 }
630 lineMix[x] = color;
631 }
632 }