rename expr.cpp.h to expr.c.h
[rofl0r-VisualBoyAdvance.git] / src / Mode3.c
blob8a87308d9a3fd059a4fb51e62b3e5da0f7e633b3
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 mode3RenderLine()
25 u16 *palette = (u16 *)paletteRAM;
27 if(DISPCNT & 0x80) {
28 for(int x = 0; x < 240; x++) {
29 lineMix[x] = 0x7fff;
31 gfxLastVCOUNT = VCOUNT;
32 return;
35 if(layerEnable & 0x0400) {
36 int changed = gfxBG2Changed;
38 if(gfxLastVCOUNT > VCOUNT)
39 changed = 3;
41 gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
42 BG2Y_L, BG2Y_H, BG2PA, BG2PB,
43 BG2PC, BG2PD,
44 gfxBG2X, gfxBG2Y, changed,
45 line2);
48 gfxDrawSprites(lineOBJ);
50 u32 background = (READ16LE(&palette[0]) | 0x30000000);
52 for(int x = 0; x < 240; x++) {
53 u32 color = background;
54 u8 top = 0x20;
56 if(line2[x] < color) {
57 color = line2[x];
58 top = 0x04;
61 if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
62 color = lineOBJ[x];
63 top = 0x10;
66 if((top & 0x10) && (color & 0x00010000)) {
67 // semi-transparent OBJ
68 u32 back = background;
69 u8 top2 = 0x20;
71 if(line2[x] < back) {
72 back = line2[x];
73 top2 = 0x04;
76 if(top2 & (BLDMOD>>8))
77 color = gfxAlphaBlend(color, back,
78 coeff[COLEV & 0x1F],
79 coeff[(COLEV >> 8) & 0x1F]);
80 else {
81 switch((BLDMOD >> 6) & 3) {
82 case 2:
83 if(BLDMOD & top)
84 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
85 break;
86 case 3:
87 if(BLDMOD & top)
88 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
89 break;
94 lineMix[x] = color;
96 gfxBG2Changed = 0;
97 gfxLastVCOUNT = VCOUNT;
100 void mode3RenderLineNoWindow()
102 u16 *palette = (u16 *)paletteRAM;
104 if(DISPCNT & 0x80) {
105 for(int x = 0; x < 240; x++) {
106 lineMix[x] = 0x7fff;
108 gfxLastVCOUNT = VCOUNT;
109 return;
112 if(layerEnable & 0x0400) {
113 int changed = gfxBG2Changed;
115 if(gfxLastVCOUNT > VCOUNT)
116 changed = 3;
118 gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
119 BG2Y_L, BG2Y_H, BG2PA, BG2PB,
120 BG2PC, BG2PD,
121 gfxBG2X, gfxBG2Y, changed,
122 line2);
125 gfxDrawSprites(lineOBJ);
127 u32 background = (READ16LE(&palette[0]) | 0x30000000);
129 for(int x = 0; x < 240; x++) {
130 u32 color = background;
131 u8 top = 0x20;
133 if(line2[x] < color) {
134 color = line2[x];
135 top = 0x04;
138 if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
139 color = lineOBJ[x];
140 top = 0x10;
143 if(!(color & 0x00010000)) {
144 switch((BLDMOD >> 6) & 3) {
145 case 0:
146 break;
147 case 1:
149 if(top & BLDMOD) {
150 u32 back = background;
151 u8 top2 = 0x20;
153 if(line2[x] < back) {
154 if(top != 0x04) {
155 back = line2[x];
156 top2 = 0x04;
160 if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
161 if(top != 0x10) {
162 back = lineOBJ[x];
163 top2 = 0x10;
167 if(top2 & (BLDMOD>>8))
168 color = gfxAlphaBlend(color, back,
169 coeff[COLEV & 0x1F],
170 coeff[(COLEV >> 8) & 0x1F]);
174 break;
175 case 2:
176 if(BLDMOD & top)
177 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
178 break;
179 case 3:
180 if(BLDMOD & top)
181 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
182 break;
184 } else {
185 // semi-transparent OBJ
186 u32 back = background;
187 u8 top2 = 0x20;
189 if(line2[x] < back) {
190 back = line2[x];
191 top2 = 0x04;
194 if(top2 & (BLDMOD>>8))
195 color = gfxAlphaBlend(color, back,
196 coeff[COLEV & 0x1F],
197 coeff[(COLEV >> 8) & 0x1F]);
198 else {
199 switch((BLDMOD >> 6) & 3) {
200 case 2:
201 if(BLDMOD & top)
202 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
203 break;
204 case 3:
205 if(BLDMOD & top)
206 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
207 break;
212 lineMix[x] = color;
214 gfxBG2Changed = 0;
215 gfxLastVCOUNT = VCOUNT;
218 void mode3RenderLineAll()
220 u16 *palette = (u16 *)paletteRAM;
222 if(DISPCNT & 0x80) {
223 for(int x = 0; x < 240; x++) {
224 lineMix[x] = 0x7fff;
226 gfxLastVCOUNT = VCOUNT;
227 return;
230 bool inWindow0 = false;
231 bool inWindow1 = false;
233 if(layerEnable & 0x2000) {
234 u8 v0 = WIN0V >> 8;
235 u8 v1 = WIN0V & 255;
236 inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
237 if(v1 >= v0)
238 inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
239 else
240 inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
242 if(layerEnable & 0x4000) {
243 u8 v0 = WIN1V >> 8;
244 u8 v1 = WIN1V & 255;
245 inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
246 if(v1 >= v0)
247 inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
248 else
249 inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
252 if(layerEnable & 0x0400) {
253 int changed = gfxBG2Changed;
255 if(gfxLastVCOUNT > VCOUNT)
256 changed = 3;
258 gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
259 BG2Y_L, BG2Y_H, BG2PA, BG2PB,
260 BG2PC, BG2PD,
261 gfxBG2X, gfxBG2Y, changed,
262 line2);
265 gfxDrawSprites(lineOBJ);
266 gfxDrawOBJWin(lineOBJWin);
268 u8 inWin0Mask = WININ & 0xFF;
269 u8 inWin1Mask = WININ >> 8;
270 u8 outMask = WINOUT & 0xFF;
272 u32 background = (READ16LE(&palette[0]) | 0x30000000);
274 for(int x = 0; x < 240; x++) {
275 u32 color = background;
276 u8 top = 0x20;
277 u8 mask = outMask;
279 if(!(lineOBJWin[x] & 0x80000000)) {
280 mask = WINOUT >> 8;
283 if(inWindow1) {
284 if(gfxInWin1[x])
285 mask = inWin1Mask;
288 if(inWindow0) {
289 if(gfxInWin0[x]) {
290 mask = inWin0Mask;
294 if((mask & 4) && (line2[x] < color)) {
295 color = line2[x];
296 top = 0x04;
299 if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
300 color = lineOBJ[x];
301 top = 0x10;
304 if(mask & 32) {
305 if(!(color & 0x00010000)) {
306 switch((BLDMOD >> 6) & 3) {
307 case 0:
308 break;
309 case 1:
311 if(top & BLDMOD) {
312 u32 back = background;
313 u8 top2 = 0x20;
315 if((mask & 4) && line2[x] < back) {
316 if(top != 0x04) {
317 back = line2[x];
318 top2 = 0x04;
322 if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
323 if(top != 0x10) {
324 back = lineOBJ[x];
325 top2 = 0x10;
329 if(top2 & (BLDMOD>>8))
330 color = gfxAlphaBlend(color, back,
331 coeff[COLEV & 0x1F],
332 coeff[(COLEV >> 8) & 0x1F]);
336 break;
337 case 2:
338 if(BLDMOD & top)
339 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
340 break;
341 case 3:
342 if(BLDMOD & top)
343 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
344 break;
346 } else {
347 // semi-transparent OBJ
348 u32 back = background;
349 u8 top2 = 0x20;
351 if((mask & 4) && line2[x] < back) {
352 back = line2[x];
353 top2 = 0x04;
356 if(top2 & (BLDMOD>>8))
357 color = gfxAlphaBlend(color, back,
358 coeff[COLEV & 0x1F],
359 coeff[(COLEV >> 8) & 0x1F]);
360 else {
361 switch((BLDMOD >> 6) & 3) {
362 case 2:
363 if(BLDMOD & top)
364 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
365 break;
366 case 3:
367 if(BLDMOD & top)
368 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
369 break;
373 } else if(color & 0x00010000) {
374 // semi-transparent OBJ
375 u32 back = background;
376 u8 top2 = 0x20;
378 if((mask & 4) && line2[x] < back) {
379 back = line2[x];
380 top2 = 0x04;
383 if(top2 & (BLDMOD>>8))
384 color = gfxAlphaBlend(color, back,
385 coeff[COLEV & 0x1F],
386 coeff[(COLEV >> 8) & 0x1F]);
387 else {
388 switch((BLDMOD >> 6) & 3) {
389 case 2:
390 if(BLDMOD & top)
391 color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
392 break;
393 case 3:
394 if(BLDMOD & top)
395 color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
396 break;
401 lineMix[x] = color;
403 gfxBG2Changed = 0;
404 gfxLastVCOUNT = VCOUNT;