rename expr.cpp.h to expr.c.h
[rofl0r-VisualBoyAdvance.git] / src / Mode0.c
blob5d30d7fc34dce7f2e3e83bdaa6d612f1f1516447
1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #include "GBA.h"
20 #include "Globals.h"
21 #include "Gfx.h"
23 void mode0RenderLine()
25 u16 *palette = (u16 *)paletteRAM;
27 if(DISPCNT & 0x80) {
28 for(int x = 0; x < 240; x++) {
29 lineMix[x] = 0x7fff;
31 return;
34 if(layerEnable & 0x0100) {
35 gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
38 if(layerEnable & 0x0200) {
39 gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
42 if(layerEnable & 0x0400) {
43 gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
46 if(layerEnable & 0x0800) {
47 gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
50 gfxDrawSprites(lineOBJ);
52 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
54 for(int x = 0; x < 240; x++) {
55 u32 color = backdrop;
56 u8 top = 0x20;
58 if(line0[x] < color) {
59 color = line0[x];
60 top = 0x01;
63 if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
64 color = line1[x];
65 top = 0x02;
68 if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
69 color = line2[x];
70 top = 0x04;
73 if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
74 color = line3[x];
75 top = 0x08;
78 if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
79 color = lineOBJ[x];
80 top = 0x10;
83 if((top & 0x10) && (color & 0x00010000)) {
84 // semi-transparent OBJ
85 u32 back = backdrop;
86 u8 top2 = 0x20;
88 if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
89 back = line0[x];
90 top2 = 0x01;
93 if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
94 back = line1[x];
95 top2 = 0x02;
98 if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
99 back = line2[x];
100 top2 = 0x04;
103 if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
104 back = line3[x];
105 top2 = 0x08;
108 if(top2 & (BLDMOD>>8))
109 color = gfxAlphaBlend(color, back,
110 coeff[COLEV & 0x1F],
111 coeff[(COLEV >> 8) & 0x1F]);
112 else {
113 switch((BLDMOD >> 6) & 3) {
114 case 2:
115 if(BLDMOD & top)
116 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
117 break;
118 case 3:
119 if(BLDMOD & top)
120 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
121 break;
126 lineMix[x] = color;
130 void mode0RenderLineNoWindow()
132 u16 *palette = (u16 *)paletteRAM;
134 if(DISPCNT & 0x80) {
135 for(int x = 0; x < 240; x++) {
136 lineMix[x] = 0x7fff;
138 return;
141 if(layerEnable & 0x0100) {
142 gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
145 if(layerEnable & 0x0200) {
146 gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
149 if(layerEnable & 0x0400) {
150 gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
153 if(layerEnable & 0x0800) {
154 gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
157 gfxDrawSprites(lineOBJ);
159 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
161 int effect = (BLDMOD >> 6) & 3;
163 for(int x = 0; x < 240; x++) {
164 u32 color = backdrop;
165 u8 top = 0x20;
167 if(line0[x] < color) {
168 color = line0[x];
169 top = 0x01;
172 if(line1[x] < (color & 0xFF000000)) {
173 color = line1[x];
174 top = 0x02;
177 if(line2[x] < (color & 0xFF000000)) {
178 color = line2[x];
179 top = 0x04;
182 if(line3[x] < (color & 0xFF000000)) {
183 color = line3[x];
184 top = 0x08;
187 if(lineOBJ[x] < (color & 0xFF000000)) {
188 color = lineOBJ[x];
189 top = 0x10;
192 if(!(color & 0x00010000)) {
193 switch(effect) {
194 case 0:
195 break;
196 case 1:
198 if(top & BLDMOD) {
199 u32 back = backdrop;
200 u8 top2 = 0x20;
201 if(line0[x] < back) {
202 if(top != 0x01) {
203 back = line0[x];
204 top2 = 0x01;
208 if(line1[x] < (back & 0xFF000000)) {
209 if(top != 0x02) {
210 back = line1[x];
211 top2 = 0x02;
215 if(line2[x] < (back & 0xFF000000)) {
216 if(top != 0x04) {
217 back = line2[x];
218 top2 = 0x04;
222 if(line3[x] < (back & 0xFF000000)) {
223 if(top != 0x08) {
224 back = line3[x];
225 top2 = 0x08;
229 if(lineOBJ[x] < (back & 0xFF000000)) {
230 if(top != 0x10) {
231 back = lineOBJ[x];
232 top2 = 0x10;
236 if(top2 & (BLDMOD>>8))
237 color = gfxAlphaBlend(color, back,
238 coeff[COLEV & 0x1F],
239 coeff[(COLEV >> 8) & 0x1F]);
243 break;
244 case 2:
245 if(BLDMOD & top)
246 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
247 break;
248 case 3:
249 if(BLDMOD & top)
250 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
251 break;
253 } else {
254 // semi-transparent OBJ
255 u32 back = backdrop;
256 u8 top2 = 0x20;
258 if(line0[x] < back) {
259 back = line0[x];
260 top2 = 0x01;
263 if(line1[x] < (back & 0xFF000000)) {
264 back = line1[x];
265 top2 = 0x02;
268 if(line2[x] < (back & 0xFF000000)) {
269 back = line2[x];
270 top2 = 0x04;
273 if(line3[x] < (back & 0xFF000000)) {
274 back = line3[x];
275 top2 = 0x08;
278 if(top2 & (BLDMOD>>8))
279 color = gfxAlphaBlend(color, back,
280 coeff[COLEV & 0x1F],
281 coeff[(COLEV >> 8) & 0x1F]);
282 else {
283 switch((BLDMOD >> 6) & 3) {
284 case 2:
285 if(BLDMOD & top)
286 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
287 break;
288 case 3:
289 if(BLDMOD & top)
290 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
291 break;
296 lineMix[x] = color;
300 void mode0RenderLineAll()
302 u16 *palette = (u16 *)paletteRAM;
304 if(DISPCNT & 0x80) {
305 for(int x = 0; x < 240; x++) {
306 lineMix[x] = 0x7fff;
308 return;
311 bool inWindow0 = false;
312 bool inWindow1 = false;
314 if(layerEnable & 0x2000) {
315 u8 v0 = WIN0V >> 8;
316 u8 v1 = WIN0V & 255;
317 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
318 if(v1 >= v0)
319 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
320 else
321 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
323 if(layerEnable & 0x4000) {
324 u8 v0 = WIN1V >> 8;
325 u8 v1 = WIN1V & 255;
326 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
327 if(v1 >= v0)
328 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
329 else
330 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
333 if((layerEnable & 0x0100)) {
334 gfxDrawTextScreen(BG0CNT, BG0HOFS, BG0VOFS, line0);
337 if((layerEnable & 0x0200)) {
338 gfxDrawTextScreen(BG1CNT, BG1HOFS, BG1VOFS, line1);
341 if((layerEnable & 0x0400)) {
342 gfxDrawTextScreen(BG2CNT, BG2HOFS, BG2VOFS, line2);
345 if((layerEnable & 0x0800)) {
346 gfxDrawTextScreen(BG3CNT, BG3HOFS, BG3VOFS, line3);
349 gfxDrawSprites(lineOBJ);
350 gfxDrawOBJWin(lineOBJWin);
352 u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
354 u8 inWin0Mask = WININ & 0xFF;
355 u8 inWin1Mask = WININ >> 8;
356 u8 outMask = WINOUT & 0xFF;
358 for(int x = 0; x < 240; x++) {
359 u32 color = backdrop;
360 u8 top = 0x20;
361 u8 mask = outMask;
363 if(!(lineOBJWin[x] & 0x80000000)) {
364 mask = WINOUT >> 8;
367 if(inWindow1) {
368 if(gfxInWin1[x])
369 mask = inWin1Mask;
372 if(inWindow0) {
373 if(gfxInWin0[x]) {
374 mask = inWin0Mask;
378 if((mask & 1) && (line0[x] < color)) {
379 color = line0[x];
380 top = 0x01;
383 if((mask & 2) && ((u8)(line1[x]>>24) < (u8)(color >> 24))) {
384 color = line1[x];
385 top = 0x02;
388 if((mask & 4) && ((u8)(line2[x]>>24) < (u8)(color >> 24))) {
389 color = line2[x];
390 top = 0x04;
393 if((mask & 8) && ((u8)(line3[x]>>24) < (u8)(color >> 24))) {
394 color = line3[x];
395 top = 0x08;
398 if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >> 24))) {
399 color = lineOBJ[x];
400 top = 0x10;
403 // special FX on in the window
404 if(mask & 32) {
405 if(!(color & 0x00010000)) {
406 switch((BLDMOD >> 6) & 3) {
407 case 0:
408 break;
409 case 1:
411 if(top & BLDMOD) {
412 u32 back = backdrop;
413 u8 top2 = 0x20;
414 if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
415 if(top != 0x01) {
416 back = line0[x];
417 top2 = 0x01;
421 if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
422 if(top != 0x02) {
423 back = line1[x];
424 top2 = 0x02;
428 if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
429 if(top != 0x04) {
430 back = line2[x];
431 top2 = 0x04;
435 if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
436 if(top != 0x08) {
437 back = line3[x];
438 top2 = 0x08;
442 if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
443 if(top != 0x10) {
444 back = lineOBJ[x];
445 top2 = 0x10;
449 if(top2 & (BLDMOD>>8))
450 color = gfxAlphaBlend(color, back,
451 coeff[COLEV & 0x1F],
452 coeff[(COLEV >> 8) & 0x1F]);
455 break;
456 case 2:
457 if(BLDMOD & top)
458 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
459 break;
460 case 3:
461 if(BLDMOD & top)
462 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
463 break;
465 } else {
466 // semi-transparent OBJ
467 u32 back = backdrop;
468 u8 top2 = 0x20;
470 if((mask & 1) && ((u8)(line0[x]>>24) < (u8)(back >> 24))) {
471 back = line0[x];
472 top2 = 0x01;
475 if((mask & 2) && ((u8)(line1[x]>>24) < (u8)(back >> 24))) {
476 back = line1[x];
477 top2 = 0x02;
480 if((mask & 4) && ((u8)(line2[x]>>24) < (u8)(back >> 24))) {
481 back = line2[x];
482 top2 = 0x04;
485 if((mask & 8) && ((u8)(line3[x]>>24) < (u8)(back >> 24))) {
486 back = line3[x];
487 top2 = 0x08;
490 if(top2 & (BLDMOD>>8))
491 color = gfxAlphaBlend(color, back,
492 coeff[COLEV & 0x1F],
493 coeff[(COLEV >> 8) & 0x1F]);
494 else {
495 switch((BLDMOD >> 6) & 3) {
496 case 2:
497 if(BLDMOD & top)
498 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
499 break;
500 case 3:
501 if(BLDMOD & top)
502 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
503 break;
507 } else if(color & 0x00010000) {
508 // semi-transparent OBJ
509 u32 back = backdrop;
510 u8 top2 = 0x20;
512 if((mask & 1) && ((u8)(line0[x]>>24) < (u8)(back >> 24))) {
513 back = line0[x];
514 top2 = 0x01;
517 if((mask & 2) && ((u8)(line1[x]>>24) < (u8)(back >> 24))) {
518 back = line1[x];
519 top2 = 0x02;
522 if((mask & 4) && ((u8)(line2[x]>>24) < (u8)(back >> 24))) {
523 back = line2[x];
524 top2 = 0x04;
527 if((mask & 8) && ((u8)(line3[x]>>24) < (u8)(back >> 24))) {
528 back = line3[x];
529 top2 = 0x08;
532 if(top2 & (BLDMOD>>8))
533 color = gfxAlphaBlend(color, back,
534 coeff[COLEV & 0x1F],
535 coeff[(COLEV >> 8) & 0x1F]);
536 else {
537 switch((BLDMOD >> 6) & 3) {
538 case 2:
539 if(BLDMOD & top)
540 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
541 break;
542 case 3:
543 if(BLDMOD & top)
544 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
545 break;
550 lineMix[x] = color;