view src/gba/Mode4.cpp @ 331:6ec288064d49

improved do-save-corruption
author Robert McIntyre <rlm@mit.edu>
date Fri, 06 Apr 2012 12:18:58 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 #include "GBAGfx.h"
2 #include "GBAGlobals.h"
4 void mode4RenderLine()
5 {
6 u16 *palette = (u16 *)paletteRAM;
8 if (DISPCNT & 0x0080)
9 {
10 for (int x = 0; x < 240; x++)
11 {
12 lineMix[x] = 0x7fff;
13 }
14 gfxLastVCOUNT = VCOUNT;
15 return;
16 }
18 if (layerEnable & 0x400)
19 {
20 int changed = gfxBG2Changed;
22 if (gfxLastVCOUNT > VCOUNT)
23 changed = 3;
25 gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
26 BG2PA, BG2PB, BG2PC, BG2PD,
27 gfxBG2X, gfxBG2Y, changed,
28 line2);
29 }
31 gfxDrawSprites(lineOBJ);
33 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
35 for (int x = 0; x < 240; x++)
36 {
37 u32 color = backdrop;
38 u8 top = 0x20;
40 if (line2[x] < color)
41 {
42 color = line2[x];
43 top = 0x04;
44 }
46 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
47 {
48 color = lineOBJ[x];
49 top = 0x10;
50 }
52 if ((top & 0x10) && (color & 0x00010000))
53 {
54 // semi-transparent OBJ
55 u32 back = backdrop;
56 u8 top2 = 0x20;
58 if (line2[x] < back)
59 {
60 back = line2[x];
61 top2 = 0x04;
62 }
64 if (top2 & (BLDMOD>>8))
65 color = gfxAlphaBlend(color, back,
66 coeff[COLEV & 0x1F],
67 coeff[(COLEV >> 8) & 0x1F]);
68 else
69 {
70 switch ((BLDMOD >> 6) & 3)
71 {
72 case 2:
73 if (BLDMOD & top)
74 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
75 break;
76 case 3:
77 if (BLDMOD & top)
78 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
79 break;
80 }
81 }
82 }
84 lineMix[x] = color;
85 }
86 gfxBG2Changed = 0;
87 gfxLastVCOUNT = VCOUNT;
88 }
90 void mode4RenderLineNoWindow()
91 {
92 u16 *palette = (u16 *)paletteRAM;
94 if (DISPCNT & 0x0080)
95 {
96 for (int x = 0; x < 240; x++)
97 {
98 lineMix[x] = 0x7fff;
99 }
100 gfxLastVCOUNT = VCOUNT;
101 return;
102 }
104 if (layerEnable & 0x400)
105 {
106 int changed = gfxBG2Changed;
108 if (gfxLastVCOUNT > VCOUNT)
109 changed = 3;
111 gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
112 BG2PA, BG2PB, BG2PC, BG2PD,
113 gfxBG2X, gfxBG2Y, changed,
114 line2);
115 }
117 gfxDrawSprites(lineOBJ);
119 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
121 for (int x = 0; x < 240; x++)
122 {
123 u32 color = backdrop;
124 u8 top = 0x20;
126 if (line2[x] < color)
127 {
128 color = line2[x];
129 top = 0x04;
130 }
132 if ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))
133 {
134 color = lineOBJ[x];
135 top = 0x10;
136 }
138 if (!(color & 0x00010000))
139 {
140 switch ((BLDMOD >> 6) & 3)
141 {
142 case 0:
143 break;
144 case 1:
145 {
146 if (top & BLDMOD)
147 {
148 u32 back = backdrop;
149 u8 top2 = 0x20;
151 if (line2[x] < back)
152 {
153 if (top != 0x04)
154 {
155 back = line2[x];
156 top2 = 0x04;
157 }
158 }
160 if ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
161 {
162 if (top != 0x10)
163 {
164 back = lineOBJ[x];
165 top2 = 0x10;
166 }
167 }
169 if (top2 & (BLDMOD>>8))
170 color = gfxAlphaBlend(color, back,
171 coeff[COLEV & 0x1F],
172 coeff[(COLEV >> 8) & 0x1F]);
173 }
174 break;
175 }
176 case 2:
177 if (BLDMOD & top)
178 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
179 break;
180 case 3:
181 if (BLDMOD & top)
182 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
183 break;
184 }
185 }
186 else
187 {
188 // semi-transparent OBJ
189 u32 back = backdrop;
190 u8 top2 = 0x20;
192 if (line2[x] < back)
193 {
194 back = line2[x];
195 top2 = 0x04;
196 }
198 if (top2 & (BLDMOD>>8))
199 color = gfxAlphaBlend(color, back,
200 coeff[COLEV & 0x1F],
201 coeff[(COLEV >> 8) & 0x1F]);
202 else
203 {
204 switch ((BLDMOD >> 6) & 3)
205 {
206 case 2:
207 if (BLDMOD & top)
208 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
209 break;
210 case 3:
211 if (BLDMOD & top)
212 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
213 break;
214 }
215 }
216 }
218 lineMix[x] = color;
219 }
220 gfxBG2Changed = 0;
221 gfxLastVCOUNT = VCOUNT;
222 }
224 void mode4RenderLineAll()
225 {
226 u16 *palette = (u16 *)paletteRAM;
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 bool inWindow0 = false;
239 bool inWindow1 = false;
241 if (layerEnable & 0x2000)
242 {
243 u8 v0 = WIN0V >> 8;
244 u8 v1 = WIN0V & 255;
245 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
246 if (v1 >= v0)
247 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
248 else
249 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
250 }
251 if (layerEnable & 0x4000)
252 {
253 u8 v0 = WIN1V >> 8;
254 u8 v1 = WIN1V & 255;
255 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
256 if (v1 >= v0)
257 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
258 else
259 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
260 }
262 if (layerEnable & 0x400)
263 {
264 int changed = gfxBG2Changed;
266 if (gfxLastVCOUNT > VCOUNT)
267 changed = 3;
269 gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
270 BG2PA, BG2PB, BG2PC, BG2PD,
271 gfxBG2X, gfxBG2Y, changed,
272 line2);
273 }
275 gfxDrawSprites(lineOBJ);
276 gfxDrawOBJWin(lineOBJWin);
278 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
280 u8 inWin0Mask = WININ & 0xFF;
281 u8 inWin1Mask = WININ >> 8;
282 u8 outMask = WINOUT & 0xFF;
284 for (int x = 0; x < 240; x++)
285 {
286 u32 color = backdrop;
287 u8 top = 0x20;
288 u8 mask = outMask;
290 if (!(lineOBJWin[x] & 0x80000000))
291 {
292 mask = WINOUT >> 8;
293 }
295 if (inWindow1)
296 {
297 if (gfxInWin1[x])
298 mask = inWin1Mask;
299 }
301 if (inWindow0)
302 {
303 if (gfxInWin0[x])
304 {
305 mask = inWin0Mask;
306 }
307 }
309 if ((mask & 4) && (line2[x] < color))
310 {
311 color = line2[x];
312 top = 0x04;
313 }
315 if ((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24)))
316 {
317 color = lineOBJ[x];
318 top = 0x10;
319 }
321 if (mask & 32)
322 {
323 if (!(color & 0x00010000))
324 {
325 switch ((BLDMOD >> 6) & 3)
326 {
327 case 0:
328 break;
329 case 1:
330 {
331 if (top & BLDMOD)
332 {
333 u32 back = backdrop;
334 u8 top2 = 0x20;
336 if ((mask & 4) && line2[x] < back)
337 {
338 if (top != 0x04)
339 {
340 back = line2[x];
341 top2 = 0x04;
342 }
343 }
345 if ((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24))
346 {
347 if (top != 0x10)
348 {
349 back = lineOBJ[x];
350 top2 = 0x10;
351 }
352 }
354 if (top2 & (BLDMOD>>8))
355 color = gfxAlphaBlend(color, back,
356 coeff[COLEV & 0x1F],
357 coeff[(COLEV >> 8) & 0x1F]);
358 }
359 break;
360 }
361 case 2:
362 if (BLDMOD & top)
363 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
364 break;
365 case 3:
366 if (BLDMOD & top)
367 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
368 break;
369 }
370 }
371 else
372 {
373 // semi-transparent OBJ
374 u32 back = backdrop;
375 u8 top2 = 0x20;
377 if ((mask & 4) && line2[x] < back)
378 {
379 back = line2[x];
380 top2 = 0x04;
381 }
383 if (top2 & (BLDMOD>>8))
384 color = gfxAlphaBlend(color, back,
385 coeff[COLEV & 0x1F],
386 coeff[(COLEV >> 8) & 0x1F]);
387 else
388 {
389 switch ((BLDMOD >> 6) & 3)
390 {
391 case 2:
392 if (BLDMOD & top)
393 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
394 break;
395 case 3:
396 if (BLDMOD & top)
397 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
398 break;
399 }
400 }
401 }
402 }
403 else if (color & 0x00010000)
404 {
405 // semi-transparent OBJ
406 u32 back = backdrop;
407 u8 top2 = 0x20;
409 if ((mask & 4) && line2[x] < back)
410 {
411 back = line2[x];
412 top2 = 0x04;
413 }
415 if (top2 & (BLDMOD>>8))
416 color = gfxAlphaBlend(color, back,
417 coeff[COLEV & 0x1F],
418 coeff[(COLEV >> 8) & 0x1F]);
419 else
420 {
421 switch ((BLDMOD >> 6) & 3)
422 {
423 case 2:
424 if (BLDMOD & top)
425 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
426 break;
427 case 3:
428 if (BLDMOD & top)
429 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
430 break;
431 }
432 }
433 }
435 lineMix[x] = color;
436 }
437 gfxBG2Changed = 0;
438 gfxLastVCOUNT = VCOUNT;
439 }