1 #include "GBA.h"
2 #include "Globals.h"
3 #include "GBAGfx.h"
4
mode5RenderLine()5 void mode5RenderLine()
6 {
7 if(DISPCNT & 0x0080) {
8 for(int x = 0; x < 240; x++) {
9 lineMix[x] = 0x7fff;
10 }
11 gfxLastVCOUNT = VCOUNT;
12 return;
13 }
14
15 u16 *palette = (u16 *)paletteRAM;
16
17 if(layerEnable & 0x0400) {
18 int changed = gfxBG2Changed;
19
20 if(gfxLastVCOUNT > VCOUNT)
21 changed = 3;
22
23 gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
24 BG2Y_L, BG2Y_H, BG2PA, BG2PB,
25 BG2PC, BG2PD,
26 gfxBG2X, gfxBG2Y, changed,
27 line2);
28 }
29
30 gfxDrawSprites(lineOBJ);
31
32 u32 background;
33 if(customBackdropColor == -1) {
34 background = (READ16LE(&palette[0]) | 0x30000000);
35 } else {
36 background = ((customBackdropColor & 0x7FFF) | 0x30000000);
37 }
38
39 for(int x = 0; x < 240; x++) {
40 u32 color = background;
41 u8 top = 0x20;
42
43 if(line2[x] < color) {
44 color = line2[x];
45 top = 0x04;
46 }
47
48 if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
49 color = lineOBJ[x];
50 top = 0x10;
51 }
52
53 if((top & 0x10) && (color & 0x00010000)) {
54 // semi-transparent OBJ
55 u32 back = background;
56 u8 top2 = 0x20;
57
58 if(line2[x] < back) {
59 back = line2[x];
60 top2 = 0x04;
61 }
62
63 if(top2 & (BLDMOD>>8))
64 color = gfxAlphaBlend(color, back,
65 coeff[COLEV & 0x1F],
66 coeff[(COLEV >> 8) & 0x1F]);
67 else {
68 switch((BLDMOD >> 6) & 3) {
69 case 2:
70 if(BLDMOD & top)
71 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
72 break;
73 case 3:
74 if(BLDMOD & top)
75 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
76 break;
77 }
78 }
79 }
80
81 lineMix[x] = color;
82 }
83 gfxBG2Changed = 0;
84 gfxLastVCOUNT = VCOUNT;
85 }
86
mode5RenderLineNoWindow()87 void mode5RenderLineNoWindow()
88 {
89 if(DISPCNT & 0x0080) {
90 for(int x = 0; x < 240; x++) {
91 lineMix[x] = 0x7fff;
92 }
93 gfxLastVCOUNT = VCOUNT;
94 return;
95 }
96
97 u16 *palette = (u16 *)paletteRAM;
98
99 if(layerEnable & 0x0400) {
100 int changed = gfxBG2Changed;
101
102 if(gfxLastVCOUNT > VCOUNT)
103 changed = 3;
104
105 gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
106 BG2Y_L, BG2Y_H, BG2PA, BG2PB,
107 BG2PC, BG2PD,
108 gfxBG2X, gfxBG2Y, changed,
109 line2);
110 }
111
112 gfxDrawSprites(lineOBJ);
113
114 u32 background;
115 if(customBackdropColor == -1) {
116 background = (READ16LE(&palette[0]) | 0x30000000);
117 } else {
118 background = ((customBackdropColor & 0x7FFF) | 0x30000000);
119 }
120
121 for(int x = 0; x < 240; x++) {
122 u32 color = background;
123 u8 top = 0x20;
124
125 if(line2[x] < color) {
126 color = line2[x];
127 top = 0x04;
128 }
129
130 if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
131 color = lineOBJ[x];
132 top = 0x10;
133 }
134
135 if(!(color & 0x00010000)) {
136 switch((BLDMOD >> 6) & 3) {
137 case 0:
138 break;
139 case 1:
140 {
141 if(top & BLDMOD) {
142 u32 back = background;
143 u8 top2 = 0x20;
144
145 if(line2[x] < back) {
146 if(top != 0x04) {
147 back = line2[x];
148 top2 = 0x04;
149 }
150 }
151
152 if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
153 if(top != 0x10) {
154 back = lineOBJ[x];
155 top2 = 0x10;
156 }
157 }
158
159 if(top2 & (BLDMOD>>8))
160 color = gfxAlphaBlend(color, back,
161 coeff[COLEV & 0x1F],
162 coeff[(COLEV >> 8) & 0x1F]);
163
164 }
165 }
166 break;
167 case 2:
168 if(BLDMOD & top)
169 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
170 break;
171 case 3:
172 if(BLDMOD & top)
173 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
174 break;
175 }
176 } else {
177 // semi-transparent OBJ
178 u32 back = background;
179 u8 top2 = 0x20;
180
181 if(line2[x] < back) {
182 back = line2[x];
183 top2 = 0x04;
184 }
185
186 if(top2 & (BLDMOD>>8))
187 color = gfxAlphaBlend(color, back,
188 coeff[COLEV & 0x1F],
189 coeff[(COLEV >> 8) & 0x1F]);
190 else {
191 switch((BLDMOD >> 6) & 3) {
192 case 2:
193 if(BLDMOD & top)
194 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
195 break;
196 case 3:
197 if(BLDMOD & top)
198 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
199 break;
200 }
201 }
202 }
203
204 lineMix[x] = color;
205 }
206 gfxBG2Changed = 0;
207 gfxLastVCOUNT = VCOUNT;
208 }
209
mode5RenderLineAll()210 void mode5RenderLineAll()
211 {
212 if(DISPCNT & 0x0080) {
213 for(int x = 0; x < 240; x++) {
214 lineMix[x] = 0x7fff;
215 }
216 gfxLastVCOUNT = VCOUNT;
217 return;
218 }
219
220 u16 *palette = (u16 *)paletteRAM;
221
222 if(layerEnable & 0x0400) {
223 int changed = gfxBG2Changed;
224
225 if(gfxLastVCOUNT > VCOUNT)
226 changed = 3;
227
228 gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
229 BG2Y_L, BG2Y_H, BG2PA, BG2PB,
230 BG2PC, BG2PD,
231 gfxBG2X, gfxBG2Y, changed,
232 line2);
233 }
234
235 gfxDrawSprites(lineOBJ);
236 gfxDrawOBJWin(lineOBJWin);
237
238 bool inWindow0 = false;
239 bool inWindow1 = false;
240
241 if(layerEnable & 0x2000) {
242 u8 v0 = WIN0V >> 8;
243 u8 v1 = WIN0V & 255;
244 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
245 if(v1 >= v0)
246 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
247 else
248 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
249 }
250 if(layerEnable & 0x4000) {
251 u8 v0 = WIN1V >> 8;
252 u8 v1 = WIN1V & 255;
253 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
254 if(v1 >= v0)
255 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
256 else
257 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
258 }
259
260 u8 inWin0Mask = WININ & 0xFF;
261 u8 inWin1Mask = WININ >> 8;
262 u8 outMask = WINOUT & 0xFF;
263
264 u32 background;
265 if(customBackdropColor == -1) {
266 background = (READ16LE(&palette[0]) | 0x30000000);
267 } else {
268 background = ((customBackdropColor & 0x7FFF) | 0x30000000);
269 }
270
271 for(int x = 0; x < 240; x++) {
272 u32 color = background;
273 u8 top = 0x20;
274 u8 mask = outMask;
275
276 if(!(lineOBJWin[x] & 0x80000000)) {
277 mask = WINOUT >> 8;
278 }
279
280 if(inWindow1) {
281 if(gfxInWin1[x])
282 mask = inWin1Mask;
283 }
284
285 if(inWindow0) {
286 if(gfxInWin0[x]) {
287 mask = inWin0Mask;
288 }
289 }
290
291 if((mask & 4) && (line2[x] < color)) {
292 color = line2[x];
293 top = 0x04;
294 }
295
296 if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
297 color = lineOBJ[x];
298 top = 0x10;
299 }
300
301 if(color & 0x00010000) {
302 // semi-transparent OBJ
303 u32 back = background;
304 u8 top2 = 0x20;
305
306 if((mask & 4) && line2[x] < back) {
307 back = line2[x];
308 top2 = 0x04;
309 }
310
311 if(top2 & (BLDMOD>>8))
312 color = gfxAlphaBlend(color, back,
313 coeff[COLEV & 0x1F],
314 coeff[(COLEV >> 8) & 0x1F]);
315 else {
316 switch((BLDMOD >> 6) & 3) {
317 case 2:
318 if(BLDMOD & top)
319 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
320 break;
321 case 3:
322 if(BLDMOD & top)
323 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
324 break;
325 }
326 }
327 } else if(mask & 32) {
328 switch((BLDMOD >> 6) & 3) {
329 case 0:
330 break;
331 case 1:
332 {
333 if(top & BLDMOD) {
334 u32 back = background;
335 u8 top2 = 0x20;
336
337 if((mask & 4) && line2[x] < back) {
338 if(top != 0x04) {
339 back = line2[x];
340 top2 = 0x04;
341 }
342 }
343
344 if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
345 if(top != 0x10) {
346 back = lineOBJ[x];
347 top2 = 0x10;
348 }
349 }
350
351 if(top2 & (BLDMOD>>8))
352 color = gfxAlphaBlend(color, back,
353 coeff[COLEV & 0x1F],
354 coeff[(COLEV >> 8) & 0x1F]);
355
356 }
357 }
358 break;
359 case 2:
360 if(BLDMOD & top)
361 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
362 break;
363 case 3:
364 if(BLDMOD & top)
365 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
366 break;
367 }
368 }
369
370 lineMix[x] = color;
371 }
372 gfxBG2Changed = 0;
373 gfxLastVCOUNT = VCOUNT;
374 }
375