view src/gba/Mode1.cpp @ 513:3dbb863eb801

accuracy of displayed image is much improved, but there the palettes are still messed up.
author Robert McIntyre <rlm@mit.edu>
date Fri, 22 Jun 2012 18:58:47 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 #include "GBAGfx.h"
2 #include "GBAGlobals.h"
4 void mode1RenderLine()
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 gfxLastVCOUNT = VCOUNT;
15 return;
16 }
18 if (layerEnable & 0x0100)
19 {
20 gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
21 }
23 if (layerEnable & 0x0200)
24 {
25 gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
26 }
28 if (layerEnable & 0x0400)
29 {
30 int changed = gfxBG2Changed;
31 if (gfxLastVCOUNT > VCOUNT)
32 changed = 3;
33 gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
34 BG2PA, BG2PB, BG2PC, BG2PD,
35 gfxBG2X, gfxBG2Y, changed, line2);
36 }
38 gfxDrawSprites(lineOBJ);
40 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
42 for (int x = 0; x < 240; x++)
43 {
44 u32 color = backdrop;
45 u8 top = 0x20;
47 if (line0[x] < color)
48 {
49 color = line0[x];
50 top = 0x01;
51 }
53 if ((u8)(line1[x]>>24) < (u8)(color >> 24))
54 {
55 color = line1[x];
56 top = 0x02;
57 }
59 if ((u8)(line2[x]>>24) < (u8)(color >> 24))
60 {
61 color = line2[x];
62 top = 0x04;
63 }
65 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
66 {
67 color = lineOBJ[x];
68 top = 0x10;
69 }
71 if ((top & 0x10) && (color & 0x00010000))
72 {
73 // semi-transparent OBJ
74 u32 back = backdrop;
75 u8 top2 = 0x20;
77 if ((u8)(line0[x]>>24) < (u8)(back >> 24))
78 {
79 back = line0[x];
80 top2 = 0x01;
81 }
83 if ((u8)(line1[x]>>24) < (u8)(back >> 24))
84 {
85 back = line1[x];
86 top2 = 0x02;
87 }
89 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
90 {
91 back = line2[x];
92 top2 = 0x04;
93 }
95 if (top2 & (BLDMOD>>8))
96 color = gfxAlphaBlend(color, back,
97 coeff[COLEV & 0x1F],
98 coeff[(COLEV >> 8) & 0x1F]);
99 else
100 {
101 switch ((BLDMOD >> 6) & 3)
102 {
103 case 2:
104 if (BLDMOD & top)
105 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
106 break;
107 case 3:
108 if (BLDMOD & top)
109 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
110 break;
111 }
112 }
113 }
115 lineMix[x] = color;
116 }
117 gfxBG2Changed = 0;
118 gfxLastVCOUNT = VCOUNT;
119 }
121 void mode1RenderLineNoWindow()
122 {
123 u16 *palette = (u16 *)paletteRAM;
125 if (DISPCNT & 0x80)
126 {
127 for (int x = 0; x < 240; x++)
128 {
129 lineMix[x] = 0x7fff;
130 }
131 gfxLastVCOUNT = VCOUNT;
132 return;
133 }
135 if (layerEnable & 0x0100)
136 {
137 gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
138 }
140 if (layerEnable & 0x0200)
141 {
142 gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
143 }
145 if (layerEnable & 0x0400)
146 {
147 int changed = gfxBG2Changed;
148 if (gfxLastVCOUNT > VCOUNT)
149 changed = 3;
150 gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
151 BG2PA, BG2PB, BG2PC, BG2PD,
152 gfxBG2X, gfxBG2Y, changed, line2);
153 }
155 gfxDrawSprites(lineOBJ);
157 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
159 for (int x = 0; x < 240; x++)
160 {
161 u32 color = backdrop;
162 u8 top = 0x20;
164 if (line0[x] < color)
165 {
166 color = line0[x];
167 top = 0x01;
168 }
170 if ((u8)(line1[x]>>24) < (u8)(color >> 24))
171 {
172 color = line1[x];
173 top = 0x02;
174 }
176 if ((u8)(line2[x]>>24) < (u8)(color >> 24))
177 {
178 color = line2[x];
179 top = 0x04;
180 }
182 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
183 {
184 color = lineOBJ[x];
185 top = 0x10;
186 }
188 if (!(color & 0x00010000))
189 {
190 switch ((BLDMOD >> 6) & 3)
191 {
192 case 0:
193 break;
194 case 1:
195 {
196 if (top & BLDMOD)
197 {
198 u32 back = backdrop;
199 u8 top2 = 0x20;
200 if ((u8)(line0[x]>>24) < (u8)(back >> 24))
201 {
202 if (top != 0x01)
203 {
204 back = line0[x];
205 top2 = 0x01;
206 }
207 }
209 if ((u8)(line1[x]>>24) < (u8)(back >> 24))
210 {
211 if (top != 0x02)
212 {
213 back = line1[x];
214 top2 = 0x02;
215 }
216 }
218 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
219 {
220 if (top != 0x04)
221 {
222 back = line2[x];
223 top2 = 0x04;
224 }
225 }
227 if ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
228 {
229 if (top != 0x10)
230 {
231 back = lineOBJ[x];
232 top2 = 0x10;
233 }
234 }
236 if (top2 & (BLDMOD>>8))
237 color = gfxAlphaBlend(color, back,
238 coeff[COLEV & 0x1F],
239 coeff[(COLEV >> 8) & 0x1F]);
240 }
241 break;
242 }
243 case 2:
244 if (BLDMOD & top)
245 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
246 break;
247 case 3:
248 if (BLDMOD & top)
249 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
250 break;
251 }
252 }
253 else
254 {
255 // semi-transparent OBJ
256 u32 back = backdrop;
257 u8 top2 = 0x20;
259 if ((u8)(line0[x]>>24) < (u8)(back >> 24))
260 {
261 back = line0[x];
262 top2 = 0x01;
263 }
265 if ((u8)(line1[x]>>24) < (u8)(back >> 24))
266 {
267 back = line1[x];
268 top2 = 0x02;
269 }
271 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
272 {
273 back = line2[x];
274 top2 = 0x04;
275 }
277 if (top2 & (BLDMOD>>8))
278 color = gfxAlphaBlend(color, back,
279 coeff[COLEV & 0x1F],
280 coeff[(COLEV >> 8) & 0x1F]);
281 else
282 {
283 switch ((BLDMOD >> 6) & 3)
284 {
285 case 2:
286 if (BLDMOD & top)
287 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
288 break;
289 case 3:
290 if (BLDMOD & top)
291 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
292 break;
293 }
294 }
295 }
297 lineMix[x] = color;
298 }
299 gfxBG2Changed = 0;
300 gfxLastVCOUNT = VCOUNT;
301 }
303 void mode1RenderLineAll()
304 {
305 u16 *palette = (u16 *)paletteRAM;
307 if (DISPCNT & 0x80)
308 {
309 for (int x = 0; x < 240; x++)
310 {
311 lineMix[x] = 0x7fff;
312 }
313 gfxLastVCOUNT = VCOUNT;
314 return;
315 }
317 bool inWindow0 = false;
318 bool inWindow1 = false;
320 if (layerEnable & 0x2000)
321 {
322 u8 v0 = WIN0V >> 8;
323 u8 v1 = WIN0V & 255;
324 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
325 if (v1 >= v0)
326 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
327 else
328 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
329 }
330 if (layerEnable & 0x4000)
331 {
332 u8 v0 = WIN1V >> 8;
333 u8 v1 = WIN1V & 255;
334 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
335 if (v1 >= v0)
336 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
337 else
338 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
339 }
341 if (layerEnable & 0x0100)
342 {
343 gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
344 }
346 if (layerEnable & 0x0200)
347 {
348 gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
349 }
351 if (layerEnable & 0x0400)
352 {
353 int changed = gfxBG2Changed;
354 if (gfxLastVCOUNT > VCOUNT)
355 changed = 3;
356 gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
357 BG2PA, BG2PB, BG2PC, BG2PD,
358 gfxBG2X, gfxBG2Y, changed, line2);
359 }
361 gfxDrawSprites(lineOBJ);
362 gfxDrawOBJWin(lineOBJWin);
364 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
366 u8 inWin0Mask = WININ & 0xFF;
367 u8 inWin1Mask = WININ >> 8;
368 u8 outMask = WINOUT & 0xFF;
370 for (int x = 0; x < 240; x++)
371 {
372 u32 color = backdrop;
373 u8 top = 0x20;
374 u8 mask = outMask;
376 if (!(lineOBJWin[x] & 0x80000000))
377 {
378 mask = WINOUT >> 8;
379 }
381 if (inWindow1)
382 {
383 if (gfxInWin1[x])
384 mask = inWin1Mask;
385 }
387 if (inWindow0)
388 {
389 if (gfxInWin0[x])
390 {
391 mask = inWin0Mask;
392 }
393 }
395 if (line0[x] < color && (mask & 1))
396 {
397 color = line0[x];
398 top = 0x01;
399 }
401 if ((u8)(line1[x]>>24) < (u8)(color >> 24) && (mask & 2))
402 {
403 color = line1[x];
404 top = 0x02;
405 }
407 if ((u8)(line2[x]>>24) < (u8)(color >> 24) && (mask & 4))
408 {
409 color = line2[x];
410 top = 0x04;
411 }
413 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16))
414 {
415 color = lineOBJ[x];
416 top = 0x10;
417 }
419 // special FX on the window
420 if (mask & 32)
421 {
422 if (!(color & 0x00010000))
423 {
424 switch ((BLDMOD >> 6) & 3)
425 {
426 case 0:
427 break;
428 case 1:
429 {
430 if (top & BLDMOD)
431 {
432 u32 back = backdrop;
433 u8 top2 = 0x20;
434 if ((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24))
435 {
436 if (top != 0x01)
437 {
438 back = line0[x];
439 top2 = 0x01;
440 }
441 }
443 if ((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24))
444 {
445 if (top != 0x02)
446 {
447 back = line1[x];
448 top2 = 0x02;
449 }
450 }
452 if ((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24))
453 {
454 if (top != 0x04)
455 {
456 back = line2[x];
457 top2 = 0x04;
458 }
459 }
461 if ((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
462 {
463 if (top != 0x10)
464 {
465 back = lineOBJ[x];
466 top2 = 0x10;
467 }
468 }
470 if (top2 & (BLDMOD>>8))
471 color = gfxAlphaBlend(color, back,
472 coeff[COLEV & 0x1F],
473 coeff[(COLEV >> 8) & 0x1F]);
474 }
475 break;
476 }
477 case 2:
478 if (BLDMOD & top)
479 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
480 break;
481 case 3:
482 if (BLDMOD & top)
483 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
484 break;
485 }
486 }
487 else
488 {
489 // semi-transparent OBJ
490 u32 back = backdrop;
491 u8 top2 = 0x20;
493 if ((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24))
494 {
495 back = line0[x];
496 top2 = 0x01;
497 }
499 if ((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24))
500 {
501 back = line1[x];
502 top2 = 0x02;
503 }
505 if ((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24))
506 {
507 back = line2[x];
508 top2 = 0x04;
509 }
511 if (top2 & (BLDMOD>>8))
512 color = gfxAlphaBlend(color, back,
513 coeff[COLEV & 0x1F],
514 coeff[(COLEV >> 8) & 0x1F]);
515 else
516 {
517 switch ((BLDMOD >> 6) & 3)
518 {
519 case 2:
520 if (BLDMOD & top)
521 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
522 break;
523 case 3:
524 if (BLDMOD & top)
525 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
526 break;
527 }
528 }
529 }
530 }
531 else if (color & 0x00010000)
532 {
533 // semi-transparent OBJ
534 u32 back = backdrop;
535 u8 top2 = 0x20;
537 if ((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24))
538 {
539 back = line0[x];
540 top2 = 0x01;
541 }
543 if ((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24))
544 {
545 back = line1[x];
546 top2 = 0x02;
547 }
549 if ((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24))
550 {
551 back = line2[x];
552 top2 = 0x04;
553 }
555 if (top2 & (BLDMOD>>8))
556 color = gfxAlphaBlend(color, back,
557 coeff[COLEV & 0x1F],
558 coeff[(COLEV >> 8) & 0x1F]);
559 else
560 {
561 switch ((BLDMOD >> 6) & 3)
562 {
563 case 2:
564 if (BLDMOD & top)
565 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
566 break;
567 case 3:
568 if (BLDMOD & top)
569 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
570 break;
571 }
572 }
573 }
575 lineMix[x] = color;
576 }
577 gfxBG2Changed = 0;
578 gfxLastVCOUNT = VCOUNT;
579 }