view src/gba/Mode5.cpp @ 124:f8dadd9478a5

fixed problem with mode transitions
author Robert McIntyre <rlm@mit.edu>
date Sat, 17 Mar 2012 01:23:47 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 #include "GBAGfx.h"
2 #include "GBAGlobals.h"
4 void mode5RenderLine()
5 {
6 if (DISPCNT & 0x0080)
7 {
8 for (int x = 0; x < 240; x++)
9 {
10 lineMix[x] = 0x7fff;
11 }
12 gfxLastVCOUNT = VCOUNT;
13 return;
14 }
16 u16 *palette = (u16 *)paletteRAM;
18 if (layerEnable & 0x0400)
19 {
20 int changed = gfxBG2Changed;
22 if (gfxLastVCOUNT > VCOUNT)
23 changed = 3;
25 gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
26 BG2Y_L, BG2Y_H, BG2PA, BG2PB,
27 BG2PC, BG2PD,
28 gfxBG2X, gfxBG2Y, changed,
29 line2);
30 }
32 gfxDrawSprites(lineOBJ);
34 u32 background = (READ16LE(&palette[0]) | 0x30000000);
36 for (int x = 0; x < 240; x++)
37 {
38 u32 color = background;
39 u8 top = 0x20;
41 if (line2[x] < color)
42 {
43 color = line2[x];
44 top = 0x04;
45 }
47 if ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
48 {
49 color = lineOBJ[x];
50 top = 0x10;
51 }
53 if ((top & 0x10) && (color & 0x00010000))
54 {
55 // semi-transparent OBJ
56 u32 back = background;
57 u8 top2 = 0x20;
59 if (line2[x] < back)
60 {
61 back = line2[x];
62 top2 = 0x04;
63 }
65 if (top2 & (BLDMOD>>8))
66 color = gfxAlphaBlend(color, back,
67 coeff[COLEV & 0x1F],
68 coeff[(COLEV >> 8) & 0x1F]);
69 else
70 {
71 switch ((BLDMOD >> 6) & 3)
72 {
73 case 2:
74 if (BLDMOD & top)
75 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
76 break;
77 case 3:
78 if (BLDMOD & top)
79 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
80 break;
81 }
82 }
83 }
85 lineMix[x] = color;
86 }
87 gfxBG2Changed = 0;
88 gfxLastVCOUNT = VCOUNT;
89 }
91 void mode5RenderLineNoWindow()
92 {
93 if (DISPCNT & 0x0080)
94 {
95 for (int x = 0; x < 240; x++)
96 {
97 lineMix[x] = 0x7fff;
98 }
99 gfxLastVCOUNT = VCOUNT;
100 return;
101 }
103 u16 *palette = (u16 *)paletteRAM;
105 if (layerEnable & 0x0400)
106 {
107 int changed = gfxBG2Changed;
109 if (gfxLastVCOUNT > VCOUNT)
110 changed = 3;
112 gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
113 BG2Y_L, BG2Y_H, BG2PA, BG2PB,
114 BG2PC, BG2PD,
115 gfxBG2X, gfxBG2Y, changed,
116 line2);
117 }
119 gfxDrawSprites(lineOBJ);
121 u32 background = (READ16LE(&palette[0]) | 0x30000000);
123 for (int x = 0; x < 240; x++)
124 {
125 u32 color = background;
126 u8 top = 0x20;
128 if (line2[x] < color)
129 {
130 color = line2[x];
131 top = 0x04;
132 }
134 if ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))
135 {
136 color = lineOBJ[x];
137 top = 0x10;
138 }
140 if (!(color & 0x00010000))
141 {
142 switch ((BLDMOD >> 6) & 3)
143 {
144 case 0:
145 break;
146 case 1:
147 {
148 if (top & BLDMOD)
149 {
150 u32 back = background;
151 u8 top2 = 0x20;
153 if (line2[x] < back)
154 {
155 if (top != 0x04)
156 {
157 back = line2[x];
158 top2 = 0x04;
159 }
160 }
162 if ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
163 {
164 if (top != 0x10)
165 {
166 back = lineOBJ[x];
167 top2 = 0x10;
168 }
169 }
171 if (top2 & (BLDMOD>>8))
172 color = gfxAlphaBlend(color, back,
173 coeff[COLEV & 0x1F],
174 coeff[(COLEV >> 8) & 0x1F]);
175 }
176 break;
177 }
178 case 2:
179 if (BLDMOD & top)
180 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
181 break;
182 case 3:
183 if (BLDMOD & top)
184 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
185 break;
186 }
187 }
188 else
189 {
190 // semi-transparent OBJ
191 u32 back = background;
192 u8 top2 = 0x20;
194 if (line2[x] < back)
195 {
196 back = line2[x];
197 top2 = 0x04;
198 }
200 if (top2 & (BLDMOD>>8))
201 color = gfxAlphaBlend(color, back,
202 coeff[COLEV & 0x1F],
203 coeff[(COLEV >> 8) & 0x1F]);
204 else
205 {
206 switch ((BLDMOD >> 6) & 3)
207 {
208 case 2:
209 if (BLDMOD & top)
210 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
211 break;
212 case 3:
213 if (BLDMOD & top)
214 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
215 break;
216 }
217 }
218 }
220 lineMix[x] = color;
221 }
222 gfxBG2Changed = 0;
223 gfxLastVCOUNT = VCOUNT;
224 }
226 void mode5RenderLineAll()
227 {
228 if (DISPCNT & 0x0080)
229 {
230 for (int x = 0; x < 240; x++)
231 {
232 lineMix[x] = 0x7fff;
233 }
234 gfxLastVCOUNT = VCOUNT;
235 return;
236 }
238 u16 *palette = (u16 *)paletteRAM;
240 if (layerEnable & 0x0400)
241 {
242 int changed = gfxBG2Changed;
244 if (gfxLastVCOUNT > VCOUNT)
245 changed = 3;
247 gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
248 BG2Y_L, BG2Y_H, BG2PA, BG2PB,
249 BG2PC, BG2PD,
250 gfxBG2X, gfxBG2Y, changed,
251 line2);
252 }
254 gfxDrawSprites(lineOBJ);
255 gfxDrawOBJWin(lineOBJWin);
257 bool inWindow0 = false;
258 bool inWindow1 = false;
260 if (layerEnable & 0x2000)
261 {
262 u8 v0 = WIN0V >> 8;
263 u8 v1 = WIN0V & 255;
264 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
265 if (v1 >= v0)
266 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
267 else
268 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
269 }
270 if (layerEnable & 0x4000)
271 {
272 u8 v0 = WIN1V >> 8;
273 u8 v1 = WIN1V & 255;
274 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
275 if (v1 >= v0)
276 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
277 else
278 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
279 }
281 u8 inWin0Mask = WININ & 0xFF;
282 u8 inWin1Mask = WININ >> 8;
283 u8 outMask = WINOUT & 0xFF;
285 u32 background = (READ16LE(&palette[0]) | 0x30000000);
287 for (int x = 0; x < 240; x++)
288 {
289 u32 color = background;
290 u8 top = 0x20;
291 u8 mask = outMask;
293 if (!(lineOBJWin[x] & 0x80000000))
294 {
295 mask = WINOUT >> 8;
296 }
298 if (inWindow1)
299 {
300 if (gfxInWin1[x])
301 mask = inWin1Mask;
302 }
304 if (inWindow0)
305 {
306 if (gfxInWin0[x])
307 {
308 mask = inWin0Mask;
309 }
310 }
312 if ((mask & 4) && (line2[x] < color))
313 {
314 color = line2[x];
315 top = 0x04;
316 }
318 if ((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
319 {
320 color = lineOBJ[x];
321 top = 0x10;
322 }
324 if (mask & 32)
325 {
326 if (!(color & 0x00010000))
327 {
328 switch ((BLDMOD >> 6) & 3)
329 {
330 case 0:
331 break;
332 case 1:
333 {
334 if (top & BLDMOD)
335 {
336 u32 back = background;
337 u8 top2 = 0x20;
339 if ((mask & 4) && line2[x] < back)
340 {
341 if (top != 0x04)
342 {
343 back = line2[x];
344 top2 = 0x04;
345 }
346 }
348 if ((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
349 {
350 if (top != 0x10)
351 {
352 back = lineOBJ[x];
353 top2 = 0x10;
354 }
355 }
357 if (top2 & (BLDMOD>>8))
358 color = gfxAlphaBlend(color, back,
359 coeff[COLEV & 0x1F],
360 coeff[(COLEV >> 8) & 0x1F]);
361 }
362 break;
363 }
364 case 2:
365 if (BLDMOD & top)
366 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
367 break;
368 case 3:
369 if (BLDMOD & top)
370 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
371 break;
372 }
373 }
374 else
375 {
376 // semi-transparent OBJ
377 u32 back = background;
378 u8 top2 = 0x20;
380 if ((mask & 4) && line2[x] < back)
381 {
382 back = line2[x];
383 top2 = 0x04;
384 }
386 if (top2 & (BLDMOD>>8))
387 color = gfxAlphaBlend(color, back,
388 coeff[COLEV & 0x1F],
389 coeff[(COLEV >> 8) & 0x1F]);
390 else
391 {
392 switch ((BLDMOD >> 6) & 3)
393 {
394 case 2:
395 if (BLDMOD & top)
396 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
397 break;
398 case 3:
399 if (BLDMOD & top)
400 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
401 break;
402 }
403 }
404 }
405 }
406 else if (color & 0x00010000)
407 {
408 // semi-transparent OBJ
409 u32 back = background;
410 u8 top2 = 0x20;
412 if ((mask & 4) && line2[x] < back)
413 {
414 back = line2[x];
415 top2 = 0x04;
416 }
418 if (top2 & (BLDMOD>>8))
419 color = gfxAlphaBlend(color, back,
420 coeff[COLEV & 0x1F],
421 coeff[(COLEV >> 8) & 0x1F]);
422 else
423 {
424 switch ((BLDMOD >> 6) & 3)
425 {
426 case 2:
427 if (BLDMOD & top)
428 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
429 break;
430 case 3:
431 if (BLDMOD & top)
432 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
433 break;
434 }
435 }
436 }
438 lineMix[x] = color;
439 }
440 gfxBG2Changed = 0;
441 gfxLastVCOUNT = VCOUNT;
442 }