view src/gba/Mode2.cpp @ 316:d263df762c59

greatly speed up scroll-text by using binary-search.
author Robert McIntyre <rlm@mit.edu>
date Mon, 02 Apr 2012 21:20:54 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 #include "GBAGfx.h"
2 #include "GBAGlobals.h"
4 void mode2RenderLine()
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 & 0x0400)
19 {
20 int changed = gfxBG2Changed;
21 if (gfxLastVCOUNT > VCOUNT)
22 changed = 3;
24 gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
25 BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
26 changed, line2);
27 }
29 if (layerEnable & 0x0800)
30 {
31 int changed = gfxBG3Changed;
32 if (gfxLastVCOUNT > VCOUNT)
33 changed = 3;
35 gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
36 BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
37 changed, line3);
38 }
40 gfxDrawSprites(lineOBJ);
42 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
44 for (int x = 0; x < 240; x++)
45 {
46 u32 color = backdrop;
47 u8 top = 0x20;
49 if ((u8)(line2[x]>>24) < (u8)(color >> 24))
50 {
51 color = line2[x];
52 top = 0x04;
53 }
55 if ((u8)(line3[x]>>24) < (u8)(color >> 24))
56 {
57 color = line3[x];
58 top = 0x08;
59 }
61 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
62 {
63 color = lineOBJ[x];
64 top = 0x10;
65 }
67 if ((top & 0x10) && (color & 0x00010000))
68 {
69 // semi-transparent OBJ
70 u32 back = backdrop;
71 u8 top2 = 0x20;
73 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
74 {
75 back = line2[x];
76 top2 = 0x04;
77 }
79 if ((u8)(line3[x]>>24) < (u8)(back >> 24))
80 {
81 back = line3[x];
82 top2 = 0x08;
83 }
85 if (top2 & (BLDMOD>>8))
86 color = gfxAlphaBlend(color, back,
87 coeff[COLEV & 0x1F],
88 coeff[(COLEV >> 8) & 0x1F]);
89 else
90 {
91 switch ((BLDMOD >> 6) & 3)
92 {
93 case 2:
94 if (BLDMOD & top)
95 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
96 break;
97 case 3:
98 if (BLDMOD & top)
99 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
100 break;
101 }
102 }
103 }
105 lineMix[x] = color;
106 }
107 gfxBG2Changed = 0;
108 gfxBG3Changed = 0;
109 gfxLastVCOUNT = VCOUNT;
110 }
112 void mode2RenderLineNoWindow()
113 {
114 u16 *palette = (u16 *)paletteRAM;
116 if (DISPCNT & 0x80)
117 {
118 for (int x = 0; x < 240; x++)
119 {
120 lineMix[x] = 0x7fff;
121 }
122 gfxLastVCOUNT = VCOUNT;
123 return;
124 }
126 if (layerEnable & 0x0400)
127 {
128 int changed = gfxBG2Changed;
129 if (gfxLastVCOUNT > VCOUNT)
130 changed = 3;
132 gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
133 BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
134 changed, line2);
135 }
137 if (layerEnable & 0x0800)
138 {
139 int changed = gfxBG3Changed;
140 if (gfxLastVCOUNT > VCOUNT)
141 changed = 3;
143 gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
144 BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
145 changed, line3);
146 }
148 gfxDrawSprites(lineOBJ);
150 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
152 for (int x = 0; x < 240; x++)
153 {
154 u32 color = backdrop;
155 u8 top = 0x20;
157 if ((u8)(line2[x]>>24) < (u8)(color >> 24))
158 {
159 color = line2[x];
160 top = 0x04;
161 }
163 if ((u8)(line3[x]>>24) < (u8)(color >> 24))
164 {
165 color = line3[x];
166 top = 0x08;
167 }
169 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
170 {
171 color = lineOBJ[x];
172 top = 0x10;
173 }
175 if (!(color & 0x00010000))
176 {
177 switch ((BLDMOD >> 6) & 3)
178 {
179 case 0:
180 break;
181 case 1:
182 {
183 if (top & BLDMOD)
184 {
185 u32 back = backdrop;
186 u8 top2 = 0x20;
188 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
189 {
190 if (top != 0x04)
191 {
192 back = line2[x];
193 top2 = 0x04;
194 }
195 }
197 if ((u8)(line3[x]>>24) < (u8)(back >> 24))
198 {
199 if (top != 0x08)
200 {
201 back = line3[x];
202 top2 = 0x08;
203 }
204 }
206 if ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
207 {
208 if (top != 0x10)
209 {
210 back = lineOBJ[x];
211 top2 = 0x10;
212 }
213 }
215 if (top2 & (BLDMOD>>8))
216 color = gfxAlphaBlend(color, back,
217 coeff[COLEV & 0x1F],
218 coeff[(COLEV >> 8) & 0x1F]);
219 }
220 break;
221 }
222 case 2:
223 if (BLDMOD & top)
224 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
225 break;
226 case 3:
227 if (BLDMOD & top)
228 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
229 break;
230 }
231 }
232 else
233 {
234 // semi-transparent OBJ
235 u32 back = backdrop;
236 u8 top2 = 0x20;
238 if ((u8)(line2[x]>>24) < (u8)(back >> 24))
239 {
240 back = line2[x];
241 top2 = 0x04;
242 }
244 if ((u8)(line3[x]>>24) < (u8)(back >> 24))
245 {
246 back = line3[x];
247 top2 = 0x08;
248 }
250 if (top2 & (BLDMOD>>8))
251 color = gfxAlphaBlend(color, back,
252 coeff[COLEV & 0x1F],
253 coeff[(COLEV >> 8) & 0x1F]);
254 else
255 {
256 switch ((BLDMOD >> 6) & 3)
257 {
258 case 2:
259 if (BLDMOD & top)
260 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
261 break;
262 case 3:
263 if (BLDMOD & top)
264 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
265 break;
266 }
267 }
268 }
270 lineMix[x] = color;
271 }
272 gfxBG2Changed = 0;
273 gfxBG3Changed = 0;
274 gfxLastVCOUNT = VCOUNT;
275 }
277 void mode2RenderLineAll()
278 {
279 u16 *palette = (u16 *)paletteRAM;
281 if (DISPCNT & 0x80)
282 {
283 for (int x = 0; x < 240; x++)
284 {
285 lineMix[x] = 0x7fff;
286 }
287 gfxLastVCOUNT = VCOUNT;
288 return;
289 }
291 bool inWindow0 = false;
292 bool inWindow1 = false;
294 if (layerEnable & 0x2000)
295 {
296 u8 v0 = WIN0V >> 8;
297 u8 v1 = WIN0V & 255;
298 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
299 if (v1 >= v0)
300 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
301 else
302 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
303 }
304 if (layerEnable & 0x4000)
305 {
306 u8 v0 = WIN1V >> 8;
307 u8 v1 = WIN1V & 255;
308 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
309 if (v1 >= v0)
310 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
311 else
312 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
313 }
315 if (layerEnable & 0x0400)
316 {
317 int changed = gfxBG2Changed;
318 if (gfxLastVCOUNT > VCOUNT)
319 changed = 3;
321 gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
322 BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
323 changed, line2);
324 }
326 if (layerEnable & 0x0800)
327 {
328 int changed = gfxBG3Changed;
329 if (gfxLastVCOUNT > VCOUNT)
330 changed = 3;
332 gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
333 BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
334 changed, line3);
335 }
337 gfxDrawSprites(lineOBJ);
338 gfxDrawOBJWin(lineOBJWin);
340 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
342 u8 inWin0Mask = WININ & 0xFF;
343 u8 inWin1Mask = WININ >> 8;
344 u8 outMask = WINOUT & 0xFF;
346 for (int x = 0; x < 240; x++)
347 {
348 u32 color = backdrop;
349 u8 top = 0x20;
350 u8 mask = outMask;
352 if (!(lineOBJWin[x] & 0x80000000))
353 {
354 mask = WINOUT >> 8;
355 }
357 if (inWindow1)
358 {
359 if (gfxInWin1[x])
360 mask = inWin1Mask;
361 }
363 if (inWindow0)
364 {
365 if (gfxInWin0[x])
366 {
367 mask = inWin0Mask;
368 }
369 }
371 if (line2[x] < color && (mask & 4))
372 {
373 color = line2[x];
374 top = 0x04;
375 }
377 if ((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8))
378 {
379 color = line3[x];
380 top = 0x08;
381 }
383 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16))
384 {
385 color = lineOBJ[x];
386 top = 0x10;
387 }
389 if (mask & 32)
390 {
391 if (!(color & 0x00010000))
392 {
393 switch ((BLDMOD >> 6) & 3)
394 {
395 case 0:
396 break;
397 case 1:
398 {
399 if (top & BLDMOD)
400 {
401 u32 back = backdrop;
402 u8 top2 = 0x20;
404 if ((mask & 4) && line2[x] < back)
405 {
406 if (top != 0x04)
407 {
408 back = line2[x];
409 top2 = 0x04;
410 }
411 }
413 if ((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
414 {
415 if (top != 0x08)
416 {
417 back = line3[x];
418 top2 = 0x08;
419 }
420 }
422 if ((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
423 {
424 if (top != 0x10)
425 {
426 back = lineOBJ[x];
427 top2 = 0x10;
428 }
429 }
431 if (top2 & (BLDMOD>>8))
432 color = gfxAlphaBlend(color, back,
433 coeff[COLEV & 0x1F],
434 coeff[(COLEV >> 8) & 0x1F]);
435 }
436 break;
437 }
438 case 2:
439 if (BLDMOD & top)
440 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
441 break;
442 case 3:
443 if (BLDMOD & top)
444 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
445 break;
446 }
447 }
448 else
449 {
450 // semi-transparent OBJ
451 u32 back = backdrop;
452 u8 top2 = 0x20;
454 if ((mask & 4) && line2[x] < back)
455 {
456 back = line2[x];
457 top2 = 0x04;
458 }
460 if ((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
461 {
462 back = line3[x];
463 top2 = 0x08;
464 }
466 if (top2 & (BLDMOD>>8))
467 color = gfxAlphaBlend(color, back,
468 coeff[COLEV & 0x1F],
469 coeff[(COLEV >> 8) & 0x1F]);
470 else
471 {
472 switch ((BLDMOD >> 6) & 3)
473 {
474 case 2:
475 if (BLDMOD & top)
476 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
477 break;
478 case 3:
479 if (BLDMOD & top)
480 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
481 break;
482 }
483 }
484 }
485 }
486 else if (color & 0x00010000)
487 {
488 // semi-transparent OBJ
489 u32 back = backdrop;
490 u8 top2 = 0x20;
492 if ((mask & 4) && line2[x] < back)
493 {
494 back = line2[x];
495 top2 = 0x04;
496 }
498 if ((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
499 {
500 back = line3[x];
501 top2 = 0x08;
502 }
504 if (top2 & (BLDMOD>>8))
505 color = gfxAlphaBlend(color, back,
506 coeff[COLEV & 0x1F],
507 coeff[(COLEV >> 8) & 0x1F]);
508 else
509 {
510 switch ((BLDMOD >> 6) & 3)
511 {
512 case 2:
513 if (BLDMOD & top)
514 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
515 break;
516 case 3:
517 if (BLDMOD & top)
518 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
519 break;
520 }
521 }
522 }
524 lineMix[x] = color;
525 }
526 gfxBG2Changed = 0;
527 gfxBG3Changed = 0;
528 gfxLastVCOUNT = VCOUNT;
529 }