rlm@1
|
1 #ifndef VBA_GBA_GFX_H
|
rlm@1
|
2 #define VBA_GBA_GFX_H
|
rlm@1
|
3
|
rlm@1
|
4 #if _MSC_VER > 1000
|
rlm@1
|
5 #pragma once
|
rlm@1
|
6 #endif // _MSC_VER > 1000
|
rlm@1
|
7
|
rlm@1
|
8 #include "../Port.h"
|
rlm@1
|
9 #include "GBA.h"
|
rlm@1
|
10 #include "GBAGlobals.h"
|
rlm@1
|
11
|
rlm@1
|
12 //#define SPRITE_DEBUG
|
rlm@1
|
13
|
rlm@1
|
14 void gfxDrawTextScreen(u16, u16, u16, u32 *);
|
rlm@1
|
15 void gfxDrawRotScreen(u16,
|
rlm@1
|
16 u16, u16,
|
rlm@1
|
17 u16, u16,
|
rlm@1
|
18 u16, u16,
|
rlm@1
|
19 u16, u16,
|
rlm@1
|
20 int&, int&,
|
rlm@1
|
21 int,
|
rlm@1
|
22 u32 *);
|
rlm@1
|
23 void gfxDrawRotScreen16Bit(u16,
|
rlm@1
|
24 u16, u16,
|
rlm@1
|
25 u16, u16,
|
rlm@1
|
26 u16, u16,
|
rlm@1
|
27 u16, u16,
|
rlm@1
|
28 int&, int&,
|
rlm@1
|
29 int,
|
rlm@1
|
30 u32 *);
|
rlm@1
|
31 void gfxDrawRotScreen256(u16,
|
rlm@1
|
32 u16, u16,
|
rlm@1
|
33 u16, u16,
|
rlm@1
|
34 u16, u16,
|
rlm@1
|
35 u16, u16,
|
rlm@1
|
36 int&, int&,
|
rlm@1
|
37 int,
|
rlm@1
|
38 u32 *);
|
rlm@1
|
39 void gfxDrawRotScreen16Bit160(u16,
|
rlm@1
|
40 u16, u16,
|
rlm@1
|
41 u16, u16,
|
rlm@1
|
42 u16, u16,
|
rlm@1
|
43 u16, u16,
|
rlm@1
|
44 int&, int&,
|
rlm@1
|
45 int,
|
rlm@1
|
46 u32 *);
|
rlm@1
|
47 void gfxDrawSprites(u32 *);
|
rlm@1
|
48 void gfxIncreaseBrightness(u32 *line, int coeff);
|
rlm@1
|
49 void gfxDecreaseBrightness(u32 *line, int coeff);
|
rlm@1
|
50 void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb);
|
rlm@1
|
51
|
rlm@1
|
52 void mode0RenderLine();
|
rlm@1
|
53 void mode0RenderLineNoWindow();
|
rlm@1
|
54 void mode0RenderLineAll();
|
rlm@1
|
55
|
rlm@1
|
56 void mode1RenderLine();
|
rlm@1
|
57 void mode1RenderLineNoWindow();
|
rlm@1
|
58 void mode1RenderLineAll();
|
rlm@1
|
59
|
rlm@1
|
60 void mode2RenderLine();
|
rlm@1
|
61 void mode2RenderLineNoWindow();
|
rlm@1
|
62 void mode2RenderLineAll();
|
rlm@1
|
63
|
rlm@1
|
64 void mode3RenderLine();
|
rlm@1
|
65 void mode3RenderLineNoWindow();
|
rlm@1
|
66 void mode3RenderLineAll();
|
rlm@1
|
67
|
rlm@1
|
68 void mode4RenderLine();
|
rlm@1
|
69 void mode4RenderLineNoWindow();
|
rlm@1
|
70 void mode4RenderLineAll();
|
rlm@1
|
71
|
rlm@1
|
72 void mode5RenderLine();
|
rlm@1
|
73 void mode5RenderLineNoWindow();
|
rlm@1
|
74 void mode5RenderLineAll();
|
rlm@1
|
75
|
rlm@1
|
76 extern int coeff[32];
|
rlm@1
|
77
|
rlm@1
|
78 #define LINE_BUFFER_OVERFLOW_LEEWAY (512-240)
|
rlm@1
|
79
|
rlm@1
|
80 extern u32 line0[240+LINE_BUFFER_OVERFLOW_LEEWAY];
|
rlm@1
|
81 extern u32 line1[240+LINE_BUFFER_OVERFLOW_LEEWAY];
|
rlm@1
|
82 extern u32 line2[240+LINE_BUFFER_OVERFLOW_LEEWAY];
|
rlm@1
|
83 extern u32 line3[240+LINE_BUFFER_OVERFLOW_LEEWAY];
|
rlm@1
|
84 extern u32 lineOBJ[240+LINE_BUFFER_OVERFLOW_LEEWAY];
|
rlm@1
|
85 extern u32 lineOBJWin[240+LINE_BUFFER_OVERFLOW_LEEWAY];
|
rlm@1
|
86 extern u32 lineMix[240+LINE_BUFFER_OVERFLOW_LEEWAY];
|
rlm@1
|
87 extern bool gfxInWin0[240+LINE_BUFFER_OVERFLOW_LEEWAY];
|
rlm@1
|
88 extern bool gfxInWin1[240+LINE_BUFFER_OVERFLOW_LEEWAY];
|
rlm@1
|
89
|
rlm@1
|
90 extern int gfxBG2Changed;
|
rlm@1
|
91 extern int gfxBG3Changed;
|
rlm@1
|
92
|
rlm@1
|
93 extern int gfxBG2X;
|
rlm@1
|
94 extern int gfxBG2Y;
|
rlm@1
|
95 extern int gfxBG2LastX;
|
rlm@1
|
96 extern int gfxBG2LastY;
|
rlm@1
|
97 extern int gfxBG3X;
|
rlm@1
|
98 extern int gfxBG3Y;
|
rlm@1
|
99 extern int gfxBG3LastX;
|
rlm@1
|
100 extern int gfxBG3LastY;
|
rlm@1
|
101 extern int gfxLastVCOUNT;
|
rlm@1
|
102
|
rlm@1
|
103 inline void gfxClearArray(u32 *array)
|
rlm@1
|
104 {
|
rlm@1
|
105 for (int i = 0; i < 240; i++)
|
rlm@1
|
106 {
|
rlm@1
|
107 *array++ = 0x80000000;
|
rlm@1
|
108 }
|
rlm@1
|
109 }
|
rlm@1
|
110
|
rlm@1
|
111 inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
|
rlm@1
|
112 u32 *line)
|
rlm@1
|
113 {
|
rlm@1
|
114 u16 *palette = (u16 *)paletteRAM;
|
rlm@1
|
115 u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000];
|
rlm@1
|
116 u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800];
|
rlm@1
|
117 u32 prio = ((control & 3)<<25) + 0x1000000;
|
rlm@1
|
118 int sizeX = 256;
|
rlm@1
|
119 int sizeY = 256;
|
rlm@1
|
120 switch ((control >> 14) & 3)
|
rlm@1
|
121 {
|
rlm@1
|
122 case 0:
|
rlm@1
|
123 break;
|
rlm@1
|
124 case 1:
|
rlm@1
|
125 sizeX = 512;
|
rlm@1
|
126 break;
|
rlm@1
|
127 case 2:
|
rlm@1
|
128 sizeY = 512;
|
rlm@1
|
129 break;
|
rlm@1
|
130 case 3:
|
rlm@1
|
131 sizeX = 512;
|
rlm@1
|
132 sizeY = 512;
|
rlm@1
|
133 break;
|
rlm@1
|
134 }
|
rlm@1
|
135
|
rlm@1
|
136 int maskX = sizeX-1;
|
rlm@1
|
137 int maskY = sizeY-1;
|
rlm@1
|
138
|
rlm@1
|
139 bool mosaicOn = (control & 0x40) ? true : false;
|
rlm@1
|
140
|
rlm@1
|
141 int xxx = hofs & maskX;
|
rlm@1
|
142 int yyy = (vofs + VCOUNT) & maskY;
|
rlm@1
|
143 int mosaicX = (MOSAIC & 0x000F)+1;
|
rlm@1
|
144 int mosaicY = ((MOSAIC & 0x00F0)>>4)+1;
|
rlm@1
|
145
|
rlm@1
|
146 if (mosaicOn)
|
rlm@1
|
147 {
|
rlm@1
|
148 if ((VCOUNT % mosaicY) != 0)
|
rlm@1
|
149 {
|
rlm@1
|
150 mosaicY = (VCOUNT / mosaicY) * mosaicY;
|
rlm@1
|
151 yyy = (vofs + mosaicY) & maskY;
|
rlm@1
|
152 }
|
rlm@1
|
153 }
|
rlm@1
|
154
|
rlm@1
|
155 if (yyy > 255 && sizeY > 256)
|
rlm@1
|
156 {
|
rlm@1
|
157 yyy &= 255;
|
rlm@1
|
158 screenBase += 0x400;
|
rlm@1
|
159 if (sizeX > 256)
|
rlm@1
|
160 screenBase += 0x400;
|
rlm@1
|
161 }
|
rlm@1
|
162
|
rlm@1
|
163 int yshift = ((yyy>>3)<<5);
|
rlm@1
|
164 if ((control) & 0x80)
|
rlm@1
|
165 {
|
rlm@1
|
166 u16 *screenSource = screenBase + 0x400 * (xxx>>8) + ((xxx & 255)>>3) + yshift;
|
rlm@1
|
167 for (int x = 0; x < 240; x++)
|
rlm@1
|
168 {
|
rlm@1
|
169 u16 data = READ16LE(screenSource);
|
rlm@1
|
170
|
rlm@1
|
171 int tile = data & 0x3FF;
|
rlm@1
|
172 int tileX = (xxx & 7);
|
rlm@1
|
173 int tileY = yyy & 7;
|
rlm@1
|
174
|
rlm@1
|
175 if (data & 0x0400)
|
rlm@1
|
176 tileX = 7 - tileX;
|
rlm@1
|
177 if (data & 0x0800)
|
rlm@1
|
178 tileY = 7 - tileY;
|
rlm@1
|
179
|
rlm@1
|
180 u8 color = charBase[tile * 64 + tileY * 8 + tileX];
|
rlm@1
|
181
|
rlm@1
|
182 line[x] = color ? (READ16LE(&palette[color]) | prio) : 0x80000000;
|
rlm@1
|
183
|
rlm@1
|
184 if (data & 0x0400)
|
rlm@1
|
185 {
|
rlm@1
|
186 if (tileX == 0)
|
rlm@1
|
187 screenSource++;
|
rlm@1
|
188 }
|
rlm@1
|
189 else if (tileX == 7)
|
rlm@1
|
190 screenSource++;
|
rlm@1
|
191 xxx++;
|
rlm@1
|
192 if (xxx == 256)
|
rlm@1
|
193 {
|
rlm@1
|
194 if (sizeX > 256)
|
rlm@1
|
195 screenSource = screenBase + 0x400 + yshift;
|
rlm@1
|
196 else
|
rlm@1
|
197 {
|
rlm@1
|
198 screenSource = screenBase + yshift;
|
rlm@1
|
199 xxx = 0;
|
rlm@1
|
200 }
|
rlm@1
|
201 }
|
rlm@1
|
202 else if (xxx >= sizeX)
|
rlm@1
|
203 {
|
rlm@1
|
204 xxx = 0;
|
rlm@1
|
205 screenSource = screenBase + yshift;
|
rlm@1
|
206 }
|
rlm@1
|
207 }
|
rlm@1
|
208 }
|
rlm@1
|
209 else
|
rlm@1
|
210 {
|
rlm@1
|
211 u16 *screenSource = screenBase + 0x400*(xxx>>8)+((xxx&255)>>3) +
|
rlm@1
|
212 yshift;
|
rlm@1
|
213 for (int x = 0; x < 240; x++)
|
rlm@1
|
214 {
|
rlm@1
|
215 u16 data = READ16LE(screenSource);
|
rlm@1
|
216
|
rlm@1
|
217 int tile = data & 0x3FF;
|
rlm@1
|
218 int tileX = (xxx & 7);
|
rlm@1
|
219 int tileY = yyy & 7;
|
rlm@1
|
220
|
rlm@1
|
221 if (data & 0x0400)
|
rlm@1
|
222 tileX = 7 - tileX;
|
rlm@1
|
223 if (data & 0x0800)
|
rlm@1
|
224 tileY = 7 - tileY;
|
rlm@1
|
225
|
rlm@1
|
226 u8 color = charBase[(tile<<5) + (tileY<<2) + (tileX>>1)];
|
rlm@1
|
227
|
rlm@1
|
228 if (tileX & 1)
|
rlm@1
|
229 {
|
rlm@1
|
230 color = (color >> 4);
|
rlm@1
|
231 }
|
rlm@1
|
232 else
|
rlm@1
|
233 {
|
rlm@1
|
234 color &= 0x0F;
|
rlm@1
|
235 }
|
rlm@1
|
236
|
rlm@1
|
237 int pal = (READ16LE(screenSource)>>8) & 0xF0;
|
rlm@1
|
238 line[x] = color ? (READ16LE(&palette[pal + color])|prio) : 0x80000000;
|
rlm@1
|
239
|
rlm@1
|
240 if (data & 0x0400)
|
rlm@1
|
241 {
|
rlm@1
|
242 if (tileX == 0)
|
rlm@1
|
243 screenSource++;
|
rlm@1
|
244 }
|
rlm@1
|
245 else if (tileX == 7)
|
rlm@1
|
246 screenSource++;
|
rlm@1
|
247 xxx++;
|
rlm@1
|
248 if (xxx == 256)
|
rlm@1
|
249 {
|
rlm@1
|
250 if (sizeX > 256)
|
rlm@1
|
251 screenSource = screenBase + 0x400 + yshift;
|
rlm@1
|
252 else
|
rlm@1
|
253 {
|
rlm@1
|
254 screenSource = screenBase + yshift;
|
rlm@1
|
255 xxx = 0;
|
rlm@1
|
256 }
|
rlm@1
|
257 }
|
rlm@1
|
258 else if (xxx >= sizeX)
|
rlm@1
|
259 {
|
rlm@1
|
260 xxx = 0;
|
rlm@1
|
261 screenSource = screenBase + yshift;
|
rlm@1
|
262 }
|
rlm@1
|
263 }
|
rlm@1
|
264 }
|
rlm@1
|
265 if (mosaicOn)
|
rlm@1
|
266 {
|
rlm@1
|
267 if (mosaicX > 1)
|
rlm@1
|
268 {
|
rlm@1
|
269 int m = 1;
|
rlm@1
|
270 for (int i = 0; i < 239; i++)
|
rlm@1
|
271 {
|
rlm@1
|
272 line[i+1] = line[i];
|
rlm@1
|
273 m++;
|
rlm@1
|
274 if (m == mosaicX)
|
rlm@1
|
275 {
|
rlm@1
|
276 m = 1;
|
rlm@1
|
277 i++;
|
rlm@1
|
278 }
|
rlm@1
|
279 }
|
rlm@1
|
280 }
|
rlm@1
|
281 }
|
rlm@1
|
282 }
|
rlm@1
|
283
|
rlm@1
|
284 inline void gfxDrawRotScreen(u16 control,
|
rlm@1
|
285 u16 x_l, u16 x_h,
|
rlm@1
|
286 u16 y_l, u16 y_h,
|
rlm@1
|
287 u16 pa, u16 pb,
|
rlm@1
|
288 u16 pc, u16 pd,
|
rlm@1
|
289 int& currentX, int& currentY,
|
rlm@1
|
290 int changed,
|
rlm@1
|
291 u32 *line)
|
rlm@1
|
292 {
|
rlm@1
|
293 u16 *palette = (u16 *)paletteRAM;
|
rlm@1
|
294 u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000];
|
rlm@1
|
295 u8 * screenBase = (u8 *)&vram[((control >> 8) & 0x1f) * 0x800];
|
rlm@1
|
296 int prio = ((control & 3) << 25) + 0x1000000;
|
rlm@1
|
297
|
rlm@1
|
298 int sizeX = 128;
|
rlm@1
|
299 int sizeY = 128;
|
rlm@1
|
300 switch ((control >> 14) & 3)
|
rlm@1
|
301 {
|
rlm@1
|
302 case 0:
|
rlm@1
|
303 break;
|
rlm@1
|
304 case 1:
|
rlm@1
|
305 sizeX = sizeY = 256;
|
rlm@1
|
306 break;
|
rlm@1
|
307 case 2:
|
rlm@1
|
308 sizeX = sizeY = 512;
|
rlm@1
|
309 break;
|
rlm@1
|
310 case 3:
|
rlm@1
|
311 sizeX = sizeY = 1024;
|
rlm@1
|
312 break;
|
rlm@1
|
313 }
|
rlm@1
|
314
|
rlm@1
|
315 int dx = pa & 0x7FFF;
|
rlm@1
|
316 if (pa & 0x8000)
|
rlm@1
|
317 dx |= 0xFFFF8000;
|
rlm@1
|
318 int dmx = pb & 0x7FFF;
|
rlm@1
|
319 if (pb & 0x8000)
|
rlm@1
|
320 dmx |= 0xFFFF8000;
|
rlm@1
|
321 int dy = pc & 0x7FFF;
|
rlm@1
|
322 if (pc & 0x8000)
|
rlm@1
|
323 dy |= 0xFFFF8000;
|
rlm@1
|
324 int dmy = pd & 0x7FFFF;
|
rlm@1
|
325 if (pd & 0x8000)
|
rlm@1
|
326 dmy |= 0xFFFF8000;
|
rlm@1
|
327
|
rlm@1
|
328 if (VCOUNT == 0)
|
rlm@1
|
329 changed = 3;
|
rlm@1
|
330
|
rlm@1
|
331 if (changed & 1)
|
rlm@1
|
332 {
|
rlm@1
|
333 currentX = (x_l) | ((x_h & 0x07FF)<<16);
|
rlm@1
|
334 if (x_h & 0x0800)
|
rlm@1
|
335 currentX |= 0xF8000000;
|
rlm@1
|
336 }
|
rlm@1
|
337 else
|
rlm@1
|
338 {
|
rlm@1
|
339 currentX += dmx;
|
rlm@1
|
340 }
|
rlm@1
|
341
|
rlm@1
|
342 if (changed & 2)
|
rlm@1
|
343 {
|
rlm@1
|
344 currentY = (y_l) | ((y_h & 0x07FF)<<16);
|
rlm@1
|
345 if (y_h & 0x0800)
|
rlm@1
|
346 currentY |= 0xF8000000;
|
rlm@1
|
347 }
|
rlm@1
|
348 else
|
rlm@1
|
349 {
|
rlm@1
|
350 currentY += dmy;
|
rlm@1
|
351 }
|
rlm@1
|
352
|
rlm@1
|
353 int realX = currentX;
|
rlm@1
|
354 int realY = currentY;
|
rlm@1
|
355
|
rlm@1
|
356 if (control & 0x40)
|
rlm@1
|
357 {
|
rlm@1
|
358 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
|
rlm@1
|
359 int y = (VCOUNT % mosaicY);
|
rlm@1
|
360 realX -= y*dmx;
|
rlm@1
|
361 realY -= y*dmy;
|
rlm@1
|
362 }
|
rlm@1
|
363
|
rlm@1
|
364 int xxx = (realX >> 8);
|
rlm@1
|
365 int yyy = (realY >> 8);
|
rlm@1
|
366
|
rlm@1
|
367 if (control & 0x2000)
|
rlm@1
|
368 {
|
rlm@1
|
369 xxx %= sizeX;
|
rlm@1
|
370 yyy %= sizeY;
|
rlm@1
|
371 if (xxx < 0)
|
rlm@1
|
372 xxx += sizeX;
|
rlm@1
|
373 if (yyy < 0)
|
rlm@1
|
374 yyy += sizeY;
|
rlm@1
|
375 }
|
rlm@1
|
376
|
rlm@1
|
377 if (control & 0x80)
|
rlm@1
|
378 {
|
rlm@1
|
379 for (int x = 0; x < 240; x++)
|
rlm@1
|
380 {
|
rlm@1
|
381 if (xxx < 0 ||
|
rlm@1
|
382 yyy < 0 ||
|
rlm@1
|
383 xxx >= sizeX ||
|
rlm@1
|
384 yyy >= sizeY)
|
rlm@1
|
385 {
|
rlm@1
|
386 line[x] = 0x80000000;
|
rlm@1
|
387 }
|
rlm@1
|
388 else
|
rlm@1
|
389 {
|
rlm@1
|
390 int tile = screenBase[(xxx>>3) + (yyy>>3)*(sizeX>>3)];
|
rlm@1
|
391
|
rlm@1
|
392 int tileX = (xxx & 7);
|
rlm@1
|
393 int tileY = yyy & 7;
|
rlm@1
|
394
|
rlm@1
|
395 u8 color = charBase[(tile<<6) + (tileY<<3) + tileX];
|
rlm@1
|
396
|
rlm@1
|
397 line[x] = color ? (READ16LE(&palette[color])|prio) : 0x80000000;
|
rlm@1
|
398 }
|
rlm@1
|
399 realX += dx;
|
rlm@1
|
400 realY += dy;
|
rlm@1
|
401
|
rlm@1
|
402 xxx = (realX >> 8);
|
rlm@1
|
403 yyy = (realY >> 8);
|
rlm@1
|
404
|
rlm@1
|
405 if (control & 0x2000)
|
rlm@1
|
406 {
|
rlm@1
|
407 xxx %= sizeX;
|
rlm@1
|
408 yyy %= sizeY;
|
rlm@1
|
409 if (xxx < 0)
|
rlm@1
|
410 xxx += sizeX;
|
rlm@1
|
411 if (yyy < 0)
|
rlm@1
|
412 yyy += sizeY;
|
rlm@1
|
413 }
|
rlm@1
|
414 }
|
rlm@1
|
415 }
|
rlm@1
|
416 else
|
rlm@1
|
417 {
|
rlm@1
|
418 for (int x = 0; x < 240; x++)
|
rlm@1
|
419 {
|
rlm@1
|
420 if (xxx < 0 ||
|
rlm@1
|
421 yyy < 0 ||
|
rlm@1
|
422 xxx >= sizeX ||
|
rlm@1
|
423 yyy >= sizeY)
|
rlm@1
|
424 {
|
rlm@1
|
425 line[x] = 0x80000000;
|
rlm@1
|
426 }
|
rlm@1
|
427 else
|
rlm@1
|
428 {
|
rlm@1
|
429 int tile = screenBase[(xxx>>3) + (yyy>>3)*(sizeX>>3)];
|
rlm@1
|
430
|
rlm@1
|
431 int tileX = (xxx & 7);
|
rlm@1
|
432 int tileY = yyy & 7;
|
rlm@1
|
433
|
rlm@1
|
434 u8 color = charBase[(tile<<6) + (tileY<<3) + tileX];
|
rlm@1
|
435
|
rlm@1
|
436 line[x] = color ? (READ16LE(&palette[color])|prio) : 0x80000000;
|
rlm@1
|
437 }
|
rlm@1
|
438 realX += dx;
|
rlm@1
|
439 realY += dy;
|
rlm@1
|
440
|
rlm@1
|
441 xxx = (realX >> 8);
|
rlm@1
|
442 yyy = (realY >> 8);
|
rlm@1
|
443
|
rlm@1
|
444 if (control & 0x2000)
|
rlm@1
|
445 {
|
rlm@1
|
446 xxx %= sizeX;
|
rlm@1
|
447 yyy %= sizeY;
|
rlm@1
|
448 if (xxx < 0)
|
rlm@1
|
449 xxx += sizeX;
|
rlm@1
|
450 if (yyy < 0)
|
rlm@1
|
451 yyy += sizeY;
|
rlm@1
|
452 }
|
rlm@1
|
453 }
|
rlm@1
|
454 }
|
rlm@1
|
455
|
rlm@1
|
456 if (control & 0x40)
|
rlm@1
|
457 {
|
rlm@1
|
458 int mosaicX = (MOSAIC & 0xF) + 1;
|
rlm@1
|
459 if (mosaicX > 1)
|
rlm@1
|
460 {
|
rlm@1
|
461 int m = 1;
|
rlm@1
|
462 for (int i = 0; i < 239; i++)
|
rlm@1
|
463 {
|
rlm@1
|
464 line[i+1] = line[i];
|
rlm@1
|
465 m++;
|
rlm@1
|
466 if (m == mosaicX)
|
rlm@1
|
467 {
|
rlm@1
|
468 m = 1;
|
rlm@1
|
469 i++;
|
rlm@1
|
470 }
|
rlm@1
|
471 }
|
rlm@1
|
472 }
|
rlm@1
|
473 }
|
rlm@1
|
474 }
|
rlm@1
|
475
|
rlm@1
|
476 inline void gfxDrawRotScreen16Bit(u16 control,
|
rlm@1
|
477 u16 x_l, u16 x_h,
|
rlm@1
|
478 u16 y_l, u16 y_h,
|
rlm@1
|
479 u16 pa, u16 pb,
|
rlm@1
|
480 u16 pc, u16 pd,
|
rlm@1
|
481 int& currentX, int& currentY,
|
rlm@1
|
482 int changed,
|
rlm@1
|
483 u32 *line)
|
rlm@1
|
484 {
|
rlm@1
|
485 u16 *screenBase = (u16 *)&vram[0];
|
rlm@1
|
486 int prio = ((control & 3) << 25) + 0x1000000;
|
rlm@1
|
487 int sizeX = 240;
|
rlm@1
|
488 int sizeY = 160;
|
rlm@1
|
489
|
rlm@1
|
490 int startX = (x_l) | ((x_h & 0x07FF)<<16);
|
rlm@1
|
491 if (x_h & 0x0800)
|
rlm@1
|
492 startX |= 0xF8000000;
|
rlm@1
|
493 int startY = (y_l) | ((y_h & 0x07FF)<<16);
|
rlm@1
|
494 if (y_h & 0x0800)
|
rlm@1
|
495 startY |= 0xF8000000;
|
rlm@1
|
496
|
rlm@1
|
497 int dx = pa & 0x7FFF;
|
rlm@1
|
498 if (pa & 0x8000)
|
rlm@1
|
499 dx |= 0xFFFF8000;
|
rlm@1
|
500 int dmx = pb & 0x7FFF;
|
rlm@1
|
501 if (pb & 0x8000)
|
rlm@1
|
502 dmx |= 0xFFFF8000;
|
rlm@1
|
503 int dy = pc & 0x7FFF;
|
rlm@1
|
504 if (pc & 0x8000)
|
rlm@1
|
505 dy |= 0xFFFF8000;
|
rlm@1
|
506 int dmy = pd & 0x7FFFF;
|
rlm@1
|
507 if (pd & 0x8000)
|
rlm@1
|
508 dmy |= 0xFFFF8000;
|
rlm@1
|
509
|
rlm@1
|
510 if (VCOUNT == 0)
|
rlm@1
|
511 changed = 3;
|
rlm@1
|
512
|
rlm@1
|
513 if (changed & 1)
|
rlm@1
|
514 {
|
rlm@1
|
515 currentX = (x_l) | ((x_h & 0x07FF)<<16);
|
rlm@1
|
516 if (x_h & 0x0800)
|
rlm@1
|
517 currentX |= 0xF8000000;
|
rlm@1
|
518 }
|
rlm@1
|
519 else
|
rlm@1
|
520 currentX += dmx;
|
rlm@1
|
521
|
rlm@1
|
522 if (changed & 2)
|
rlm@1
|
523 {
|
rlm@1
|
524 currentY = (y_l) | ((y_h & 0x07FF)<<16);
|
rlm@1
|
525 if (y_h & 0x0800)
|
rlm@1
|
526 currentY |= 0xF8000000;
|
rlm@1
|
527 }
|
rlm@1
|
528 else
|
rlm@1
|
529 {
|
rlm@1
|
530 currentY += dmy;
|
rlm@1
|
531 }
|
rlm@1
|
532
|
rlm@1
|
533 int realX = currentX;
|
rlm@1
|
534 int realY = currentY;
|
rlm@1
|
535
|
rlm@1
|
536 if (control & 0x40)
|
rlm@1
|
537 {
|
rlm@1
|
538 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
|
rlm@1
|
539 int y = (VCOUNT % mosaicY);
|
rlm@1
|
540 realX -= y*dmx;
|
rlm@1
|
541 realY -= y*dmy;
|
rlm@1
|
542 }
|
rlm@1
|
543
|
rlm@1
|
544 int xxx = (realX >> 8);
|
rlm@1
|
545 int yyy = (realY >> 8);
|
rlm@1
|
546
|
rlm@1
|
547 for (int x = 0; x < 240; x++)
|
rlm@1
|
548 {
|
rlm@1
|
549 if (xxx < 0 ||
|
rlm@1
|
550 yyy < 0 ||
|
rlm@1
|
551 xxx >= sizeX ||
|
rlm@1
|
552 yyy >= sizeY)
|
rlm@1
|
553 {
|
rlm@1
|
554 line[x] = 0x80000000;
|
rlm@1
|
555 }
|
rlm@1
|
556 else
|
rlm@1
|
557 {
|
rlm@1
|
558 line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
|
rlm@1
|
559 }
|
rlm@1
|
560 realX += dx;
|
rlm@1
|
561 realY += dy;
|
rlm@1
|
562
|
rlm@1
|
563 xxx = (realX >> 8);
|
rlm@1
|
564 yyy = (realY >> 8);
|
rlm@1
|
565 }
|
rlm@1
|
566
|
rlm@1
|
567 if (control & 0x40)
|
rlm@1
|
568 {
|
rlm@1
|
569 int mosaicX = (MOSAIC & 0xF) + 1;
|
rlm@1
|
570 if (mosaicX > 1)
|
rlm@1
|
571 {
|
rlm@1
|
572 int m = 1;
|
rlm@1
|
573 for (int i = 0; i < 239; i++)
|
rlm@1
|
574 {
|
rlm@1
|
575 line[i+1] = line[i];
|
rlm@1
|
576 m++;
|
rlm@1
|
577 if (m == mosaicX)
|
rlm@1
|
578 {
|
rlm@1
|
579 m = 1;
|
rlm@1
|
580 i++;
|
rlm@1
|
581 }
|
rlm@1
|
582 }
|
rlm@1
|
583 }
|
rlm@1
|
584 }
|
rlm@1
|
585 }
|
rlm@1
|
586
|
rlm@1
|
587 inline void gfxDrawRotScreen256(u16 control,
|
rlm@1
|
588 u16 x_l, u16 x_h,
|
rlm@1
|
589 u16 y_l, u16 y_h,
|
rlm@1
|
590 u16 pa, u16 pb,
|
rlm@1
|
591 u16 pc, u16 pd,
|
rlm@1
|
592 int ¤tX, int& currentY,
|
rlm@1
|
593 int changed,
|
rlm@1
|
594 u32 *line)
|
rlm@1
|
595 {
|
rlm@1
|
596 u16 *palette = (u16 *)paletteRAM;
|
rlm@1
|
597 u8 * screenBase = (DISPCNT & 0x0010) ? &vram[0xA000] : &vram[0x0000];
|
rlm@1
|
598 int prio = ((control & 3) << 25) + 0x1000000;
|
rlm@1
|
599 int sizeX = 240;
|
rlm@1
|
600 int sizeY = 160;
|
rlm@1
|
601
|
rlm@1
|
602 int startX = (x_l) | ((x_h & 0x07FF)<<16);
|
rlm@1
|
603 if (x_h & 0x0800)
|
rlm@1
|
604 startX |= 0xF8000000;
|
rlm@1
|
605 int startY = (y_l) | ((y_h & 0x07FF)<<16);
|
rlm@1
|
606 if (y_h & 0x0800)
|
rlm@1
|
607 startY |= 0xF8000000;
|
rlm@1
|
608
|
rlm@1
|
609 int dx = pa & 0x7FFF;
|
rlm@1
|
610 if (pa & 0x8000)
|
rlm@1
|
611 dx |= 0xFFFF8000;
|
rlm@1
|
612 int dmx = pb & 0x7FFF;
|
rlm@1
|
613 if (pb & 0x8000)
|
rlm@1
|
614 dmx |= 0xFFFF8000;
|
rlm@1
|
615 int dy = pc & 0x7FFF;
|
rlm@1
|
616 if (pc & 0x8000)
|
rlm@1
|
617 dy |= 0xFFFF8000;
|
rlm@1
|
618 int dmy = pd & 0x7FFFF;
|
rlm@1
|
619 if (pd & 0x8000)
|
rlm@1
|
620 dmy |= 0xFFFF8000;
|
rlm@1
|
621
|
rlm@1
|
622 if (VCOUNT == 0)
|
rlm@1
|
623 changed = 3;
|
rlm@1
|
624
|
rlm@1
|
625 if (changed & 1)
|
rlm@1
|
626 {
|
rlm@1
|
627 currentX = (x_l) | ((x_h & 0x07FF)<<16);
|
rlm@1
|
628 if (x_h & 0x0800)
|
rlm@1
|
629 currentX |= 0xF8000000;
|
rlm@1
|
630 }
|
rlm@1
|
631 else
|
rlm@1
|
632 {
|
rlm@1
|
633 currentX += dmx;
|
rlm@1
|
634 }
|
rlm@1
|
635
|
rlm@1
|
636 if (changed & 2)
|
rlm@1
|
637 {
|
rlm@1
|
638 currentY = (y_l) | ((y_h & 0x07FF)<<16);
|
rlm@1
|
639 if (y_h & 0x0800)
|
rlm@1
|
640 currentY |= 0xF8000000;
|
rlm@1
|
641 }
|
rlm@1
|
642 else
|
rlm@1
|
643 {
|
rlm@1
|
644 currentY += dmy;
|
rlm@1
|
645 }
|
rlm@1
|
646
|
rlm@1
|
647 int realX = currentX;
|
rlm@1
|
648 int realY = currentY;
|
rlm@1
|
649
|
rlm@1
|
650 if (control & 0x40)
|
rlm@1
|
651 {
|
rlm@1
|
652 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
|
rlm@1
|
653 int y = (VCOUNT / mosaicY) * mosaicY;
|
rlm@1
|
654 realX = startX + y*dmx;
|
rlm@1
|
655 realY = startY + y*dmy;
|
rlm@1
|
656 }
|
rlm@1
|
657
|
rlm@1
|
658 int xxx = (realX >> 8);
|
rlm@1
|
659 int yyy = (realY >> 8);
|
rlm@1
|
660
|
rlm@1
|
661 for (int x = 0; x < 240; x++)
|
rlm@1
|
662 {
|
rlm@1
|
663 if (xxx < 0 ||
|
rlm@1
|
664 yyy < 0 ||
|
rlm@1
|
665 xxx >= sizeX ||
|
rlm@1
|
666 yyy >= sizeY)
|
rlm@1
|
667 {
|
rlm@1
|
668 line[x] = 0x80000000;
|
rlm@1
|
669 }
|
rlm@1
|
670 else
|
rlm@1
|
671 {
|
rlm@1
|
672 u8 color = screenBase[yyy * 240 + xxx];
|
rlm@1
|
673
|
rlm@1
|
674 line[x] = color ? (READ16LE(&palette[color])|prio) : 0x80000000;
|
rlm@1
|
675 }
|
rlm@1
|
676 realX += dx;
|
rlm@1
|
677 realY += dy;
|
rlm@1
|
678
|
rlm@1
|
679 xxx = (realX >> 8);
|
rlm@1
|
680 yyy = (realY >> 8);
|
rlm@1
|
681 }
|
rlm@1
|
682
|
rlm@1
|
683 if (control & 0x40)
|
rlm@1
|
684 {
|
rlm@1
|
685 int mosaicX = (MOSAIC & 0xF) + 1;
|
rlm@1
|
686 if (mosaicX > 1)
|
rlm@1
|
687 {
|
rlm@1
|
688 int m = 1;
|
rlm@1
|
689 for (int i = 0; i < 239; i++)
|
rlm@1
|
690 {
|
rlm@1
|
691 line[i+1] = line[i];
|
rlm@1
|
692 m++;
|
rlm@1
|
693 if (m == mosaicX)
|
rlm@1
|
694 {
|
rlm@1
|
695 m = 1;
|
rlm@1
|
696 i++;
|
rlm@1
|
697 }
|
rlm@1
|
698 }
|
rlm@1
|
699 }
|
rlm@1
|
700 }
|
rlm@1
|
701 }
|
rlm@1
|
702
|
rlm@1
|
703 inline void gfxDrawRotScreen16Bit160(u16 control,
|
rlm@1
|
704 u16 x_l, u16 x_h,
|
rlm@1
|
705 u16 y_l, u16 y_h,
|
rlm@1
|
706 u16 pa, u16 pb,
|
rlm@1
|
707 u16 pc, u16 pd,
|
rlm@1
|
708 int& currentX, int& currentY,
|
rlm@1
|
709 int changed,
|
rlm@1
|
710 u32 *line)
|
rlm@1
|
711 {
|
rlm@1
|
712 u16 *screenBase = (DISPCNT & 0x0010) ? (u16 *)&vram[0xa000] :
|
rlm@1
|
713 (u16 *)&vram[0];
|
rlm@1
|
714 int prio = ((control & 3) << 25) + 0x1000000;
|
rlm@1
|
715 int sizeX = 160;
|
rlm@1
|
716 int sizeY = 128;
|
rlm@1
|
717
|
rlm@1
|
718 int startX = (x_l) | ((x_h & 0x07FF)<<16);
|
rlm@1
|
719 if (x_h & 0x0800)
|
rlm@1
|
720 startX |= 0xF8000000;
|
rlm@1
|
721 int startY = (y_l) | ((y_h & 0x07FF)<<16);
|
rlm@1
|
722 if (y_h & 0x0800)
|
rlm@1
|
723 startY |= 0xF8000000;
|
rlm@1
|
724
|
rlm@1
|
725 int dx = pa & 0x7FFF;
|
rlm@1
|
726 if (pa & 0x8000)
|
rlm@1
|
727 dx |= 0xFFFF8000;
|
rlm@1
|
728 int dmx = pb & 0x7FFF;
|
rlm@1
|
729 if (pb & 0x8000)
|
rlm@1
|
730 dmx |= 0xFFFF8000;
|
rlm@1
|
731 int dy = pc & 0x7FFF;
|
rlm@1
|
732 if (pc & 0x8000)
|
rlm@1
|
733 dy |= 0xFFFF8000;
|
rlm@1
|
734 int dmy = pd & 0x7FFFF;
|
rlm@1
|
735 if (pd & 0x8000)
|
rlm@1
|
736 dmy |= 0xFFFF8000;
|
rlm@1
|
737
|
rlm@1
|
738 if (VCOUNT == 0)
|
rlm@1
|
739 changed = 3;
|
rlm@1
|
740
|
rlm@1
|
741 if (changed & 1)
|
rlm@1
|
742 {
|
rlm@1
|
743 currentX = (x_l) | ((x_h & 0x07FF)<<16);
|
rlm@1
|
744 if (x_h & 0x0800)
|
rlm@1
|
745 currentX |= 0xF8000000;
|
rlm@1
|
746 }
|
rlm@1
|
747 else
|
rlm@1
|
748 {
|
rlm@1
|
749 currentX += dmx;
|
rlm@1
|
750 }
|
rlm@1
|
751
|
rlm@1
|
752 if (changed & 2)
|
rlm@1
|
753 {
|
rlm@1
|
754 currentY = (y_l) | ((y_h & 0x07FF)<<16);
|
rlm@1
|
755 if (y_h & 0x0800)
|
rlm@1
|
756 currentY |= 0xF8000000;
|
rlm@1
|
757 }
|
rlm@1
|
758 else
|
rlm@1
|
759 {
|
rlm@1
|
760 currentY += dmy;
|
rlm@1
|
761 }
|
rlm@1
|
762
|
rlm@1
|
763 int realX = currentX;
|
rlm@1
|
764 int realY = currentY;
|
rlm@1
|
765
|
rlm@1
|
766 if (control & 0x40)
|
rlm@1
|
767 {
|
rlm@1
|
768 int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
|
rlm@1
|
769 int y = (VCOUNT / mosaicY) * mosaicY;
|
rlm@1
|
770 realX = startX + y*dmx;
|
rlm@1
|
771 realY = startY + y*dmy;
|
rlm@1
|
772 }
|
rlm@1
|
773
|
rlm@1
|
774 int xxx = (realX >> 8);
|
rlm@1
|
775 int yyy = (realY >> 8);
|
rlm@1
|
776
|
rlm@1
|
777 for (int x = 0; x < 240; x++)
|
rlm@1
|
778 {
|
rlm@1
|
779 if (xxx < 0 ||
|
rlm@1
|
780 yyy < 0 ||
|
rlm@1
|
781 xxx >= sizeX ||
|
rlm@1
|
782 yyy >= sizeY)
|
rlm@1
|
783 {
|
rlm@1
|
784 line[x] = 0x80000000;
|
rlm@1
|
785 }
|
rlm@1
|
786 else
|
rlm@1
|
787 {
|
rlm@1
|
788 line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
|
rlm@1
|
789 }
|
rlm@1
|
790 realX += dx;
|
rlm@1
|
791 realY += dy;
|
rlm@1
|
792
|
rlm@1
|
793 xxx = (realX >> 8);
|
rlm@1
|
794 yyy = (realY >> 8);
|
rlm@1
|
795 }
|
rlm@1
|
796
|
rlm@1
|
797 if (control & 0x40)
|
rlm@1
|
798 {
|
rlm@1
|
799 int mosaicX = (MOSAIC & 0xF) + 1;
|
rlm@1
|
800 if (mosaicX > 1)
|
rlm@1
|
801 {
|
rlm@1
|
802 int m = 1;
|
rlm@1
|
803 for (int i = 0; i < 239; i++)
|
rlm@1
|
804 {
|
rlm@1
|
805 line[i+1] = line[i];
|
rlm@1
|
806 m++;
|
rlm@1
|
807 if (m == mosaicX)
|
rlm@1
|
808 {
|
rlm@1
|
809 m = 1;
|
rlm@1
|
810 i++;
|
rlm@1
|
811 }
|
rlm@1
|
812 }
|
rlm@1
|
813 }
|
rlm@1
|
814 }
|
rlm@1
|
815 }
|
rlm@1
|
816
|
rlm@1
|
817 inline void gfxDrawSprites(u32 *lineOBJ)
|
rlm@1
|
818 {
|
rlm@1
|
819 int m = 0;
|
rlm@1
|
820 gfxClearArray(lineOBJ);
|
rlm@1
|
821 if (layerEnable & 0x1000)
|
rlm@1
|
822 {
|
rlm@1
|
823 u16 *sprites = (u16 *)oam;
|
rlm@1
|
824 u16 *spritePalette = &((u16 *)paletteRAM)[256];
|
rlm@1
|
825 int mosaicY = ((MOSAIC & 0xF000)>>12) + 1;
|
rlm@1
|
826 int mosaicX = ((MOSAIC & 0xF00)>>8) + 1;
|
rlm@1
|
827 for (int x = 0; x < 128; x++)
|
rlm@1
|
828 {
|
rlm@1
|
829 u16 a0 = READ16LE(sprites++);
|
rlm@1
|
830 u16 a1 = READ16LE(sprites++);
|
rlm@1
|
831 u16 a2 = READ16LE(sprites++);
|
rlm@1
|
832 sprites++;
|
rlm@1
|
833
|
rlm@1
|
834 // ignore OBJ-WIN
|
rlm@1
|
835 if ((a0 & 0x0c00) == 0x0800)
|
rlm@1
|
836 continue;
|
rlm@1
|
837
|
rlm@1
|
838 int sizeY = 8;
|
rlm@1
|
839 int sizeX = 8;
|
rlm@1
|
840
|
rlm@1
|
841 switch (((a0 >>12) & 0x0c)|(a1>>14))
|
rlm@1
|
842 {
|
rlm@1
|
843 case 0:
|
rlm@1
|
844 break;
|
rlm@1
|
845 case 1:
|
rlm@1
|
846 sizeX = sizeY = 16;
|
rlm@1
|
847 break;
|
rlm@1
|
848 case 2:
|
rlm@1
|
849 sizeX = sizeY = 32;
|
rlm@1
|
850 break;
|
rlm@1
|
851 case 3:
|
rlm@1
|
852 sizeX = sizeY = 64;
|
rlm@1
|
853 break;
|
rlm@1
|
854 case 4:
|
rlm@1
|
855 sizeX = 16;
|
rlm@1
|
856 break;
|
rlm@1
|
857 case 5:
|
rlm@1
|
858 sizeX = 32;
|
rlm@1
|
859 break;
|
rlm@1
|
860 case 6:
|
rlm@1
|
861 sizeX = 32;
|
rlm@1
|
862 sizeY = 16;
|
rlm@1
|
863 break;
|
rlm@1
|
864 case 7:
|
rlm@1
|
865 sizeX = 64;
|
rlm@1
|
866 sizeY = 32;
|
rlm@1
|
867 break;
|
rlm@1
|
868 case 8:
|
rlm@1
|
869 sizeY = 16;
|
rlm@1
|
870 break;
|
rlm@1
|
871 case 9:
|
rlm@1
|
872 sizeY = 32;
|
rlm@1
|
873 break;
|
rlm@1
|
874 case 10:
|
rlm@1
|
875 sizeX = 16;
|
rlm@1
|
876 sizeY = 32;
|
rlm@1
|
877 break;
|
rlm@1
|
878 case 11:
|
rlm@1
|
879 sizeX = 32;
|
rlm@1
|
880 sizeY = 64;
|
rlm@1
|
881 break;
|
rlm@1
|
882 default:
|
rlm@1
|
883 continue;
|
rlm@1
|
884 }
|
rlm@1
|
885
|
rlm@1
|
886 #ifdef SPRITE_DEBUG
|
rlm@1
|
887 int maskX = sizeX-1;
|
rlm@1
|
888 int maskY = sizeY-1;
|
rlm@1
|
889 #endif
|
rlm@1
|
890
|
rlm@1
|
891 int sy = (a0 & 255);
|
rlm@1
|
892
|
rlm@1
|
893 if (sy > 160)
|
rlm@1
|
894 sy -= 256;
|
rlm@1
|
895
|
rlm@1
|
896 if (a0 & 0x0100)
|
rlm@1
|
897 {
|
rlm@1
|
898 int fieldX = sizeX;
|
rlm@1
|
899 int fieldY = sizeY;
|
rlm@1
|
900 if (a0 & 0x0200)
|
rlm@1
|
901 {
|
rlm@1
|
902 fieldX <<= 1;
|
rlm@1
|
903 fieldY <<= 1;
|
rlm@1
|
904 }
|
rlm@1
|
905
|
rlm@1
|
906 int t = VCOUNT - sy;
|
rlm@1
|
907 if ((t >= 0) && (t < fieldY))
|
rlm@1
|
908 {
|
rlm@1
|
909 int sx = (a1 & 0x1FF);
|
rlm@1
|
910 if ((sx < 240) || (((sx + fieldX) & 511) < 240))
|
rlm@1
|
911 {
|
rlm@1
|
912 // int t2 = t - (fieldY >> 1);
|
rlm@1
|
913 int rot = (a1 >> 9) & 0x1F;
|
rlm@1
|
914 u16 *OAM = (u16 *)oam;
|
rlm@1
|
915 int dx = READ16LE(&OAM[3 + (rot << 4)]);
|
rlm@1
|
916 if (dx & 0x8000)
|
rlm@1
|
917 dx |= 0xFFFF8000;
|
rlm@1
|
918 int dmx = READ16LE(&OAM[7 + (rot << 4)]);
|
rlm@1
|
919 if (dmx & 0x8000)
|
rlm@1
|
920 dmx |= 0xFFFF8000;
|
rlm@1
|
921 int dy = READ16LE(&OAM[11 + (rot << 4)]);
|
rlm@1
|
922 if (dy & 0x8000)
|
rlm@1
|
923 dy |= 0xFFFF8000;
|
rlm@1
|
924 int dmy = READ16LE(&OAM[15 + (rot << 4)]);
|
rlm@1
|
925 if (dmy & 0x8000)
|
rlm@1
|
926 dmy |= 0xFFFF8000;
|
rlm@1
|
927
|
rlm@1
|
928 if (a0 & 0x1000)
|
rlm@1
|
929 {
|
rlm@1
|
930 t -= (t % mosaicY);
|
rlm@1
|
931 }
|
rlm@1
|
932
|
rlm@1
|
933 int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx
|
rlm@1
|
934 + t * dmx;
|
rlm@1
|
935 int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
|
rlm@1
|
936 + t * dmy;
|
rlm@1
|
937
|
rlm@1
|
938 u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
|
rlm@1
|
939
|
rlm@1
|
940 if (a0 & 0x2000)
|
rlm@1
|
941 {
|
rlm@1
|
942 int c = (a2 & 0x3FF);
|
rlm@1
|
943 if ((DISPCNT & 7) > 2 && (c < 512))
|
rlm@1
|
944 continue;
|
rlm@1
|
945 int inc = 32;
|
rlm@1
|
946 if (DISPCNT & 0x40)
|
rlm@1
|
947 inc = sizeX >> 2;
|
rlm@1
|
948 else
|
rlm@1
|
949 c &= 0x3FE;
|
rlm@1
|
950 for (int x = 0; x < fieldX; x++)
|
rlm@1
|
951 {
|
rlm@1
|
952 int xxx = realX >> 8;
|
rlm@1
|
953 int yyy = realY >> 8;
|
rlm@1
|
954
|
rlm@1
|
955 if (xxx < 0 || xxx >= sizeX ||
|
rlm@1
|
956 yyy < 0 || yyy >= sizeY ||
|
rlm@1
|
957 sx >= 240)
|
rlm@1
|
958 ;
|
rlm@1
|
959 else
|
rlm@1
|
960 {
|
rlm@1
|
961 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
|
rlm@1
|
962 + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
|
rlm@1
|
963 (xxx & 7))&0x7FFF)];
|
rlm@1
|
964 if ((color == 0) && (((prio >> 25)&3) <
|
rlm@1
|
965 ((lineOBJ[sx]>>25)&3)))
|
rlm@1
|
966 {
|
rlm@1
|
967 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
|
rlm@1
|
968 if ((a0 & 0x1000) && m)
|
rlm@1
|
969 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
970 }
|
rlm@1
|
971 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
|
rlm@1
|
972 {
|
rlm@1
|
973 lineOBJ[sx] = READ16LE(&spritePalette[color]) | prio;
|
rlm@1
|
974 if ((a0 & 0x1000) && m)
|
rlm@1
|
975 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
976 }
|
rlm@1
|
977
|
rlm@1
|
978 if (a0 & 0x1000)
|
rlm@1
|
979 {
|
rlm@1
|
980 m++;
|
rlm@1
|
981 if (m == mosaicX)
|
rlm@1
|
982 m = 0;
|
rlm@1
|
983 }
|
rlm@1
|
984 #ifdef SPRITE_DEBUG
|
rlm@1
|
985 if (t == 0 || t == maskY || x == 0 || x == maskX)
|
rlm@1
|
986 lineOBJ[sx] = 0x001F;
|
rlm@1
|
987 #endif
|
rlm@1
|
988 }
|
rlm@1
|
989 sx = (sx+1)&511;;
|
rlm@1
|
990 realX += dx;
|
rlm@1
|
991 realY += dy;
|
rlm@1
|
992 }
|
rlm@1
|
993 }
|
rlm@1
|
994 else
|
rlm@1
|
995 {
|
rlm@1
|
996 int c = (a2 & 0x3FF);
|
rlm@1
|
997 if ((DISPCNT & 7) > 2 && (c < 512))
|
rlm@1
|
998 continue;
|
rlm@1
|
999
|
rlm@1
|
1000 int inc = 32;
|
rlm@1
|
1001 if (DISPCNT & 0x40)
|
rlm@1
|
1002 inc = sizeX >> 3;
|
rlm@1
|
1003 int palette = (a2 >> 8) & 0xF0;
|
rlm@1
|
1004 for (int x = 0; x < fieldX; x++)
|
rlm@1
|
1005 {
|
rlm@1
|
1006 int xxx = realX >> 8;
|
rlm@1
|
1007 int yyy = realY >> 8;
|
rlm@1
|
1008 if (xxx < 0 || xxx >= sizeX ||
|
rlm@1
|
1009 yyy < 0 || yyy >= sizeY ||
|
rlm@1
|
1010 sx >= 240)
|
rlm@1
|
1011 ;
|
rlm@1
|
1012 else
|
rlm@1
|
1013 {
|
rlm@1
|
1014 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
|
rlm@1
|
1015 + ((yyy & 7)<<2) + ((xxx >> 3)<<5) +
|
rlm@1
|
1016 ((xxx & 7)>>1))&0x7FFF)];
|
rlm@1
|
1017 if (xxx & 1)
|
rlm@1
|
1018 color >>= 4;
|
rlm@1
|
1019 else
|
rlm@1
|
1020 color &= 0x0F;
|
rlm@1
|
1021
|
rlm@1
|
1022 if ((color == 0) && (((prio >> 25)&3) <
|
rlm@1
|
1023 ((lineOBJ[sx]>>25)&3)))
|
rlm@1
|
1024 {
|
rlm@1
|
1025 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1026 if ((a0 & 0x1000) && m)
|
rlm@1
|
1027 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1028 }
|
rlm@1
|
1029 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
|
rlm@1
|
1030 {
|
rlm@1
|
1031 lineOBJ[sx] = READ16LE(&spritePalette[palette+color]) | prio;
|
rlm@1
|
1032 if ((a0 & 0x1000) && m)
|
rlm@1
|
1033 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1034 }
|
rlm@1
|
1035 }
|
rlm@1
|
1036 if ((a0 & 0x1000) && m)
|
rlm@1
|
1037 {
|
rlm@1
|
1038 m++;
|
rlm@1
|
1039 if (m == mosaicX)
|
rlm@1
|
1040 m = 0;
|
rlm@1
|
1041 }
|
rlm@1
|
1042
|
rlm@1
|
1043 #ifdef SPRITE_DEBUG
|
rlm@1
|
1044 if (t == 0 || t == maskY || x == 0 || x == maskX)
|
rlm@1
|
1045 lineOBJ[sx] = 0x001F;
|
rlm@1
|
1046 #endif
|
rlm@1
|
1047 sx = (sx+1)&511;;
|
rlm@1
|
1048 realX += dx;
|
rlm@1
|
1049 realY += dy;
|
rlm@1
|
1050 }
|
rlm@1
|
1051 }
|
rlm@1
|
1052 }
|
rlm@1
|
1053 }
|
rlm@1
|
1054 }
|
rlm@1
|
1055 else
|
rlm@1
|
1056 {
|
rlm@1
|
1057 int t = VCOUNT - sy;
|
rlm@1
|
1058 if ((t >= 0) && (t < sizeY))
|
rlm@1
|
1059 {
|
rlm@1
|
1060 int sx = (a1 & 0x1FF);
|
rlm@1
|
1061 if (((sx < 240) || (((sx+sizeX)&511) < 240)) && !(a0 & 0x0200))
|
rlm@1
|
1062 {
|
rlm@1
|
1063 if (a0 & 0x2000)
|
rlm@1
|
1064 {
|
rlm@1
|
1065 if (a1 & 0x2000)
|
rlm@1
|
1066 t = sizeY - t - 1;
|
rlm@1
|
1067 int c = (a2 & 0x3FF);
|
rlm@1
|
1068 if ((DISPCNT & 7) > 2 && (c < 512))
|
rlm@1
|
1069 continue;
|
rlm@1
|
1070
|
rlm@1
|
1071 int inc = 32;
|
rlm@1
|
1072 if (DISPCNT & 0x40)
|
rlm@1
|
1073 {
|
rlm@1
|
1074 inc = sizeX >> 2;
|
rlm@1
|
1075 }
|
rlm@1
|
1076 else
|
rlm@1
|
1077 {
|
rlm@1
|
1078 c &= 0x3FE;
|
rlm@1
|
1079 }
|
rlm@1
|
1080 int xxx = 0;
|
rlm@1
|
1081 if (a1 & 0x1000)
|
rlm@1
|
1082 xxx = sizeX-1;
|
rlm@1
|
1083
|
rlm@1
|
1084 if (a0 & 0x1000)
|
rlm@1
|
1085 {
|
rlm@1
|
1086 t -= (t % mosaicY);
|
rlm@1
|
1087 }
|
rlm@1
|
1088
|
rlm@1
|
1089 int address = 0x10000 + ((((c+ (t>>3) * inc) << 5)
|
rlm@1
|
1090 + ((t & 7) << 3) + ((xxx>>3)<<6) + (xxx & 7)) & 0x7FFF);
|
rlm@1
|
1091
|
rlm@1
|
1092 if (a1 & 0x1000)
|
rlm@1
|
1093 xxx = 7;
|
rlm@1
|
1094 u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
|
rlm@1
|
1095
|
rlm@1
|
1096 for (int xx = 0; xx < sizeX; xx++)
|
rlm@1
|
1097 {
|
rlm@1
|
1098 if (sx < 240)
|
rlm@1
|
1099 {
|
rlm@1
|
1100 u8 color = vram[address];
|
rlm@1
|
1101 if ((color == 0) && (((prio >> 25)&3) <
|
rlm@1
|
1102 ((lineOBJ[sx]>>25)&3)))
|
rlm@1
|
1103 {
|
rlm@1
|
1104 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1105 if ((a0 & 0x1000) && m)
|
rlm@1
|
1106 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1107 }
|
rlm@1
|
1108 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
|
rlm@1
|
1109 {
|
rlm@1
|
1110 lineOBJ[sx] = READ16LE(&spritePalette[color]) | prio;
|
rlm@1
|
1111 if ((a0 & 0x1000) && m)
|
rlm@1
|
1112 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1113 }
|
rlm@1
|
1114
|
rlm@1
|
1115 if (a0 & 0x1000)
|
rlm@1
|
1116 {
|
rlm@1
|
1117 m++;
|
rlm@1
|
1118 if (m == mosaicX)
|
rlm@1
|
1119 m = 0;
|
rlm@1
|
1120 }
|
rlm@1
|
1121
|
rlm@1
|
1122 #ifdef SPRITE_DEBUG
|
rlm@1
|
1123 if (t == 0 || t == maskY || xx == 0 || xx == maskX)
|
rlm@1
|
1124 lineOBJ[sx] = 0x001F;
|
rlm@1
|
1125 #endif
|
rlm@1
|
1126 }
|
rlm@1
|
1127
|
rlm@1
|
1128 sx = (sx+1) & 511;
|
rlm@1
|
1129 if (a1 & 0x1000)
|
rlm@1
|
1130 {
|
rlm@1
|
1131 xxx--;
|
rlm@1
|
1132 address--;
|
rlm@1
|
1133 if (xxx == -1)
|
rlm@1
|
1134 {
|
rlm@1
|
1135 address -= 56;
|
rlm@1
|
1136 xxx = 7;
|
rlm@1
|
1137 }
|
rlm@1
|
1138 if (address < 0x10000)
|
rlm@1
|
1139 address += 0x8000;
|
rlm@1
|
1140 }
|
rlm@1
|
1141 else
|
rlm@1
|
1142 {
|
rlm@1
|
1143 xxx++;
|
rlm@1
|
1144 address++;
|
rlm@1
|
1145 if (xxx == 8)
|
rlm@1
|
1146 {
|
rlm@1
|
1147 address += 56;
|
rlm@1
|
1148 xxx = 0;
|
rlm@1
|
1149 }
|
rlm@1
|
1150 if (address > 0x17fff)
|
rlm@1
|
1151 address -= 0x8000;
|
rlm@1
|
1152 }
|
rlm@1
|
1153 }
|
rlm@1
|
1154 }
|
rlm@1
|
1155 else
|
rlm@1
|
1156 {
|
rlm@1
|
1157 if (a1 & 0x2000)
|
rlm@1
|
1158 t = sizeY - t - 1;
|
rlm@1
|
1159 int c = (a2 & 0x3FF);
|
rlm@1
|
1160 if ((DISPCNT & 7) > 2 && (c < 512))
|
rlm@1
|
1161 continue;
|
rlm@1
|
1162
|
rlm@1
|
1163 int inc = 32;
|
rlm@1
|
1164 if (DISPCNT & 0x40)
|
rlm@1
|
1165 {
|
rlm@1
|
1166 inc = sizeX >> 3;
|
rlm@1
|
1167 }
|
rlm@1
|
1168 int xxx = 0;
|
rlm@1
|
1169 if (a1 & 0x1000)
|
rlm@1
|
1170 xxx = sizeX - 1;
|
rlm@1
|
1171
|
rlm@1
|
1172 if (a0 & 0x1000)
|
rlm@1
|
1173 {
|
rlm@1
|
1174 t -= (t % mosaicY);
|
rlm@1
|
1175 }
|
rlm@1
|
1176
|
rlm@1
|
1177 int address = 0x10000 + ((((c + (t>>3) * inc)<<5)
|
rlm@1
|
1178 + ((t & 7)<<2) + ((xxx>>3)<<5) + ((xxx & 7) >> 1))&0x7FFF);
|
rlm@1
|
1179 u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
|
rlm@1
|
1180 int palette = (a2 >> 8) & 0xF0;
|
rlm@1
|
1181 if (a1 & 0x1000)
|
rlm@1
|
1182 {
|
rlm@1
|
1183 xxx = 7;
|
rlm@1
|
1184 for (int xx = sizeX - 1; xx >= 0; xx--)
|
rlm@1
|
1185 {
|
rlm@1
|
1186 if (sx < 240)
|
rlm@1
|
1187 {
|
rlm@1
|
1188 u8 color = vram[address];
|
rlm@1
|
1189 if (xx & 1)
|
rlm@1
|
1190 {
|
rlm@1
|
1191 color = (color >> 4);
|
rlm@1
|
1192 }
|
rlm@1
|
1193 else
|
rlm@1
|
1194 color &= 0x0F;
|
rlm@1
|
1195
|
rlm@1
|
1196 if ((color == 0) && (((prio >> 25)&3) <
|
rlm@1
|
1197 ((lineOBJ[sx]>>25)&3)))
|
rlm@1
|
1198 {
|
rlm@1
|
1199 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1200 if ((a0 & 0x1000) && m)
|
rlm@1
|
1201 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1202 }
|
rlm@1
|
1203 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
|
rlm@1
|
1204 {
|
rlm@1
|
1205 lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;
|
rlm@1
|
1206 if ((a0 & 0x1000) && m)
|
rlm@1
|
1207 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1208 }
|
rlm@1
|
1209 }
|
rlm@1
|
1210 if (a0 & 0x1000)
|
rlm@1
|
1211 {
|
rlm@1
|
1212 m++;
|
rlm@1
|
1213 if (m == mosaicX)
|
rlm@1
|
1214 m = 0;
|
rlm@1
|
1215 }
|
rlm@1
|
1216 #ifdef SPRITE_DEBUG
|
rlm@1
|
1217 if (t == 0 || t == maskY || xx == 0 || xx == maskX)
|
rlm@1
|
1218 lineOBJ[sx] = 0x001F;
|
rlm@1
|
1219 #endif
|
rlm@1
|
1220 sx = (sx+1) & 511;
|
rlm@1
|
1221 xxx--;
|
rlm@1
|
1222 if (!(xx & 1))
|
rlm@1
|
1223 address--;
|
rlm@1
|
1224 if (xxx == -1)
|
rlm@1
|
1225 {
|
rlm@1
|
1226 xxx = 7;
|
rlm@1
|
1227 address -= 28;
|
rlm@1
|
1228 }
|
rlm@1
|
1229 if (address < 0x10000)
|
rlm@1
|
1230 address += 0x8000;
|
rlm@1
|
1231 }
|
rlm@1
|
1232 }
|
rlm@1
|
1233 else
|
rlm@1
|
1234 {
|
rlm@1
|
1235 for (int xx = 0; xx < sizeX; xx++)
|
rlm@1
|
1236 {
|
rlm@1
|
1237 if (sx < 240)
|
rlm@1
|
1238 {
|
rlm@1
|
1239 u8 color = vram[address];
|
rlm@1
|
1240 if (xx & 1)
|
rlm@1
|
1241 {
|
rlm@1
|
1242 color = (color >> 4);
|
rlm@1
|
1243 }
|
rlm@1
|
1244 else
|
rlm@1
|
1245 color &= 0x0F;
|
rlm@1
|
1246
|
rlm@1
|
1247 if ((color == 0) && (((prio >> 25)&3) <
|
rlm@1
|
1248 ((lineOBJ[sx]>>25)&3)))
|
rlm@1
|
1249 {
|
rlm@1
|
1250 lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1251 if ((a0 & 0x1000) && m)
|
rlm@1
|
1252 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1253 }
|
rlm@1
|
1254 else if ((color) && (prio < (lineOBJ[sx]&0xFF000000)))
|
rlm@1
|
1255 {
|
rlm@1
|
1256 lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;
|
rlm@1
|
1257 if ((a0 & 0x1000) && m)
|
rlm@1
|
1258 lineOBJ[sx] = (lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
|
rlm@1
|
1259 }
|
rlm@1
|
1260 }
|
rlm@1
|
1261 if (a0 & 0x1000)
|
rlm@1
|
1262 {
|
rlm@1
|
1263 m++;
|
rlm@1
|
1264 if (m == mosaicX)
|
rlm@1
|
1265 m = 0;
|
rlm@1
|
1266 }
|
rlm@1
|
1267 #ifdef SPRITE_DEBUG
|
rlm@1
|
1268 if (t == 0 || t == maskY || xx == 0 || xx == maskX)
|
rlm@1
|
1269 lineOBJ[sx] = 0x001F;
|
rlm@1
|
1270 #endif
|
rlm@1
|
1271 sx = (sx+1) & 511;
|
rlm@1
|
1272 xxx++;
|
rlm@1
|
1273 if (xx & 1)
|
rlm@1
|
1274 address++;
|
rlm@1
|
1275 if (xxx == 8)
|
rlm@1
|
1276 {
|
rlm@1
|
1277 address += 28;
|
rlm@1
|
1278 xxx = 0;
|
rlm@1
|
1279 }
|
rlm@1
|
1280 if (address > 0x17fff)
|
rlm@1
|
1281 address -= 0x8000;
|
rlm@1
|
1282 }
|
rlm@1
|
1283 }
|
rlm@1
|
1284 }
|
rlm@1
|
1285 }
|
rlm@1
|
1286 }
|
rlm@1
|
1287 }
|
rlm@1
|
1288 }
|
rlm@1
|
1289 }
|
rlm@1
|
1290 }
|
rlm@1
|
1291
|
rlm@1
|
1292 inline void gfxDrawOBJWin(u32 *lineOBJWin)
|
rlm@1
|
1293 {
|
rlm@1
|
1294 gfxClearArray(lineOBJWin);
|
rlm@1
|
1295 if (layerEnable & 0x8000)
|
rlm@1
|
1296 {
|
rlm@1
|
1297 u16 *sprites = (u16 *)oam;
|
rlm@1
|
1298 // u16 *spritePalette = &((u16 *)paletteRAM)[256];
|
rlm@1
|
1299 for (int x = 0; x < 128; x++)
|
rlm@1
|
1300 {
|
rlm@1
|
1301 u16 a0 = READ16LE(sprites++);
|
rlm@1
|
1302 u16 a1 = READ16LE(sprites++);
|
rlm@1
|
1303 u16 a2 = READ16LE(sprites++);
|
rlm@1
|
1304 sprites++;
|
rlm@1
|
1305
|
rlm@1
|
1306 // ignore non OBJ-WIN
|
rlm@1
|
1307 if ((a0 & 0x0c00) != 0x0800)
|
rlm@1
|
1308 continue;
|
rlm@1
|
1309
|
rlm@1
|
1310 int sizeY = 8;
|
rlm@1
|
1311 int sizeX = 8;
|
rlm@1
|
1312
|
rlm@1
|
1313 switch (((a0 >>12) & 0x0c)|(a1>>14))
|
rlm@1
|
1314 {
|
rlm@1
|
1315 case 0:
|
rlm@1
|
1316 break;
|
rlm@1
|
1317 case 1:
|
rlm@1
|
1318 sizeX = sizeY = 16;
|
rlm@1
|
1319 break;
|
rlm@1
|
1320 case 2:
|
rlm@1
|
1321 sizeX = sizeY = 32;
|
rlm@1
|
1322 break;
|
rlm@1
|
1323 case 3:
|
rlm@1
|
1324 sizeX = sizeY = 64;
|
rlm@1
|
1325 break;
|
rlm@1
|
1326 case 4:
|
rlm@1
|
1327 sizeX = 16;
|
rlm@1
|
1328 break;
|
rlm@1
|
1329 case 5:
|
rlm@1
|
1330 sizeX = 32;
|
rlm@1
|
1331 break;
|
rlm@1
|
1332 case 6:
|
rlm@1
|
1333 sizeX = 32;
|
rlm@1
|
1334 sizeY = 16;
|
rlm@1
|
1335 break;
|
rlm@1
|
1336 case 7:
|
rlm@1
|
1337 sizeX = 64;
|
rlm@1
|
1338 sizeY = 32;
|
rlm@1
|
1339 break;
|
rlm@1
|
1340 case 8:
|
rlm@1
|
1341 sizeY = 16;
|
rlm@1
|
1342 break;
|
rlm@1
|
1343 case 9:
|
rlm@1
|
1344 sizeY = 32;
|
rlm@1
|
1345 break;
|
rlm@1
|
1346 case 10:
|
rlm@1
|
1347 sizeX = 16;
|
rlm@1
|
1348 sizeY = 32;
|
rlm@1
|
1349 break;
|
rlm@1
|
1350 case 11:
|
rlm@1
|
1351 sizeX = 32;
|
rlm@1
|
1352 sizeY = 64;
|
rlm@1
|
1353 break;
|
rlm@1
|
1354 default:
|
rlm@1
|
1355 continue;
|
rlm@1
|
1356 }
|
rlm@1
|
1357
|
rlm@1
|
1358 int sy = (a0 & 255);
|
rlm@1
|
1359
|
rlm@1
|
1360 if (sy > 160)
|
rlm@1
|
1361 sy -= 256;
|
rlm@1
|
1362
|
rlm@1
|
1363 if (a0 & 0x0100)
|
rlm@1
|
1364 {
|
rlm@1
|
1365 int fieldX = sizeX;
|
rlm@1
|
1366 int fieldY = sizeY;
|
rlm@1
|
1367 if (a0 & 0x0200)
|
rlm@1
|
1368 {
|
rlm@1
|
1369 fieldX <<= 1;
|
rlm@1
|
1370 fieldY <<= 1;
|
rlm@1
|
1371 }
|
rlm@1
|
1372
|
rlm@1
|
1373 int t = VCOUNT - sy;
|
rlm@1
|
1374 if ((t >= 0) && (t < fieldY))
|
rlm@1
|
1375 {
|
rlm@1
|
1376 int sx = (a1 & 0x1FF);
|
rlm@1
|
1377 if ((sx < 240) || (((sx + fieldX) & 511) < 240))
|
rlm@1
|
1378 {
|
rlm@1
|
1379 // int t2 = t - (fieldY >> 1);
|
rlm@1
|
1380 int rot = (a1 >> 9) & 0x1F;
|
rlm@1
|
1381 u16 *OAM = (u16 *)oam;
|
rlm@1
|
1382 int dx = READ16LE(&OAM[3 + (rot << 4)]);
|
rlm@1
|
1383 if (dx & 0x8000)
|
rlm@1
|
1384 dx |= 0xFFFF8000;
|
rlm@1
|
1385 int dmx = READ16LE(&OAM[7 + (rot << 4)]);
|
rlm@1
|
1386 if (dmx & 0x8000)
|
rlm@1
|
1387 dmx |= 0xFFFF8000;
|
rlm@1
|
1388 int dy = READ16LE(&OAM[11 + (rot << 4)]);
|
rlm@1
|
1389 if (dy & 0x8000)
|
rlm@1
|
1390 dy |= 0xFFFF8000;
|
rlm@1
|
1391 int dmy = READ16LE(&OAM[15 + (rot << 4)]);
|
rlm@1
|
1392 if (dmy & 0x8000)
|
rlm@1
|
1393 dmy |= 0xFFFF8000;
|
rlm@1
|
1394
|
rlm@1
|
1395 int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx
|
rlm@1
|
1396 + t * dmx;
|
rlm@1
|
1397 int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
|
rlm@1
|
1398 + t * dmy;
|
rlm@1
|
1399
|
rlm@1
|
1400 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
|
rlm@1
|
1401
|
rlm@1
|
1402 if (a0 & 0x2000)
|
rlm@1
|
1403 {
|
rlm@1
|
1404 int c = (a2 & 0x3FF);
|
rlm@1
|
1405 if ((DISPCNT & 7) > 2 && (c < 512))
|
rlm@1
|
1406 continue;
|
rlm@1
|
1407 int inc = 32;
|
rlm@1
|
1408 if (DISPCNT & 0x40)
|
rlm@1
|
1409 inc = sizeX >> 2;
|
rlm@1
|
1410 else
|
rlm@1
|
1411 c &= 0x3FE;
|
rlm@1
|
1412 for (int x = 0; x < fieldX; x++)
|
rlm@1
|
1413 {
|
rlm@1
|
1414 int xxx = realX >> 8;
|
rlm@1
|
1415 int yyy = realY >> 8;
|
rlm@1
|
1416
|
rlm@1
|
1417 if (xxx < 0 || xxx >= sizeX ||
|
rlm@1
|
1418 yyy < 0 || yyy >= sizeY)
|
rlm@1
|
1419 {}
|
rlm@1
|
1420 else
|
rlm@1
|
1421 {
|
rlm@1
|
1422 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
|
rlm@1
|
1423 + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
|
rlm@1
|
1424 (xxx & 7))&0x7fff)];
|
rlm@1
|
1425 if (color)
|
rlm@1
|
1426 {
|
rlm@1
|
1427 lineOBJWin[sx] = 1;
|
rlm@1
|
1428 }
|
rlm@1
|
1429 }
|
rlm@1
|
1430 sx = (sx+1)&511;;
|
rlm@1
|
1431 realX += dx;
|
rlm@1
|
1432 realY += dy;
|
rlm@1
|
1433 }
|
rlm@1
|
1434 }
|
rlm@1
|
1435 else
|
rlm@1
|
1436 {
|
rlm@1
|
1437 int c = (a2 & 0x3FF);
|
rlm@1
|
1438 if ((DISPCNT & 7) > 2 && (c < 512))
|
rlm@1
|
1439 continue;
|
rlm@1
|
1440
|
rlm@1
|
1441 int inc = 32;
|
rlm@1
|
1442 if (DISPCNT & 0x40)
|
rlm@1
|
1443 inc = sizeX >> 3;
|
rlm@1
|
1444 // int palette = (a2 >> 8) & 0xF0;
|
rlm@1
|
1445 for (int x = 0; x < fieldX; x++)
|
rlm@1
|
1446 {
|
rlm@1
|
1447 int xxx = realX >> 8;
|
rlm@1
|
1448 int yyy = realY >> 8;
|
rlm@1
|
1449
|
rlm@1
|
1450 // if(x == 0 || x == (sizeX-1) ||
|
rlm@1
|
1451 // t == 0 || t == (sizeY-1)) {
|
rlm@1
|
1452 // lineOBJ[sx] = 0x001F | prio;
|
rlm@1
|
1453 // } else {
|
rlm@1
|
1454 if (xxx < 0 || xxx >= sizeX ||
|
rlm@1
|
1455 yyy < 0 || yyy >= sizeY)
|
rlm@1
|
1456 {}
|
rlm@1
|
1457 else
|
rlm@1
|
1458 {
|
rlm@1
|
1459 u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
|
rlm@1
|
1460 + ((yyy & 7)<<2) + ((xxx >> 3)<<5) +
|
rlm@1
|
1461 ((xxx & 7)>>1))&0x7fff)];
|
rlm@1
|
1462 if (xxx & 1)
|
rlm@1
|
1463 color >>= 4;
|
rlm@1
|
1464 else
|
rlm@1
|
1465 color &= 0x0F;
|
rlm@1
|
1466
|
rlm@1
|
1467 if (color)
|
rlm@1
|
1468 {
|
rlm@1
|
1469 lineOBJWin[sx] = 1;
|
rlm@1
|
1470 }
|
rlm@1
|
1471 }
|
rlm@1
|
1472 // }
|
rlm@1
|
1473 sx = (sx+1)&511;;
|
rlm@1
|
1474 realX += dx;
|
rlm@1
|
1475 realY += dy;
|
rlm@1
|
1476 }
|
rlm@1
|
1477 }
|
rlm@1
|
1478 }
|
rlm@1
|
1479 }
|
rlm@1
|
1480 }
|
rlm@1
|
1481 else
|
rlm@1
|
1482 {
|
rlm@1
|
1483 int t = VCOUNT - sy;
|
rlm@1
|
1484 if ((t >= 0) && (t < sizeY))
|
rlm@1
|
1485 {
|
rlm@1
|
1486 int sx = (a1 & 0x1FF);
|
rlm@1
|
1487 if (((sx < 240) || (((sx+sizeX)&511) < 240)) && !(a0 & 0x0200))
|
rlm@1
|
1488 {
|
rlm@1
|
1489 if (a0 & 0x2000)
|
rlm@1
|
1490 {
|
rlm@1
|
1491 if (a1 & 0x2000)
|
rlm@1
|
1492 t = sizeY - t - 1;
|
rlm@1
|
1493 int c = (a2 & 0x3FF);
|
rlm@1
|
1494 if ((DISPCNT & 7) > 2 && (c < 512))
|
rlm@1
|
1495 continue;
|
rlm@1
|
1496
|
rlm@1
|
1497 int inc = 32;
|
rlm@1
|
1498 if (DISPCNT & 0x40)
|
rlm@1
|
1499 {
|
rlm@1
|
1500 inc = sizeX >> 2;
|
rlm@1
|
1501 }
|
rlm@1
|
1502 else
|
rlm@1
|
1503 {
|
rlm@1
|
1504 c &= 0x3FE;
|
rlm@1
|
1505 }
|
rlm@1
|
1506 int xxx = 0;
|
rlm@1
|
1507 if (a1 & 0x1000)
|
rlm@1
|
1508 xxx = sizeX-1;
|
rlm@1
|
1509 int address = 0x10000 + ((((c+ (t>>3) * inc) << 5)
|
rlm@1
|
1510 + ((t & 7) << 3) + ((xxx>>3)<<6) + (xxx & 7))&0x7fff);
|
rlm@1
|
1511 if (a1 & 0x1000)
|
rlm@1
|
1512 xxx = 7;
|
rlm@1
|
1513 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
|
rlm@1
|
1514 for (int xx = 0; xx < sizeX; xx++)
|
rlm@1
|
1515 {
|
rlm@1
|
1516 if (sx < 240)
|
rlm@1
|
1517 {
|
rlm@1
|
1518 u8 color = vram[address];
|
rlm@1
|
1519 if (color)
|
rlm@1
|
1520 {
|
rlm@1
|
1521 lineOBJWin[sx] = 1;
|
rlm@1
|
1522 }
|
rlm@1
|
1523 }
|
rlm@1
|
1524
|
rlm@1
|
1525 sx = (sx+1) & 511;
|
rlm@1
|
1526 if (a1 & 0x1000)
|
rlm@1
|
1527 {
|
rlm@1
|
1528 xxx--;
|
rlm@1
|
1529 address--;
|
rlm@1
|
1530 if (xxx == -1)
|
rlm@1
|
1531 {
|
rlm@1
|
1532 address -= 56;
|
rlm@1
|
1533 xxx = 7;
|
rlm@1
|
1534 }
|
rlm@1
|
1535 if (address < 0x10000)
|
rlm@1
|
1536 address += 0x8000;
|
rlm@1
|
1537 }
|
rlm@1
|
1538 else
|
rlm@1
|
1539 {
|
rlm@1
|
1540 xxx++;
|
rlm@1
|
1541 address++;
|
rlm@1
|
1542 if (xxx == 8)
|
rlm@1
|
1543 {
|
rlm@1
|
1544 address += 56;
|
rlm@1
|
1545 xxx = 0;
|
rlm@1
|
1546 }
|
rlm@1
|
1547 if (address > 0x17fff)
|
rlm@1
|
1548 address -= 0x8000;
|
rlm@1
|
1549 }
|
rlm@1
|
1550 }
|
rlm@1
|
1551 }
|
rlm@1
|
1552 else
|
rlm@1
|
1553 {
|
rlm@1
|
1554 if (a1 & 0x2000)
|
rlm@1
|
1555 t = sizeY - t - 1;
|
rlm@1
|
1556 int c = (a2 & 0x3FF);
|
rlm@1
|
1557 if ((DISPCNT & 7) > 2 && (c < 512))
|
rlm@1
|
1558 continue;
|
rlm@1
|
1559
|
rlm@1
|
1560 int inc = 32;
|
rlm@1
|
1561 if (DISPCNT & 0x40)
|
rlm@1
|
1562 {
|
rlm@1
|
1563 inc = sizeX >> 3;
|
rlm@1
|
1564 }
|
rlm@1
|
1565 int xxx = 0;
|
rlm@1
|
1566 if (a1 & 0x1000)
|
rlm@1
|
1567 xxx = sizeX - 1;
|
rlm@1
|
1568 int address = 0x10000 + ((((c + (t>>3) * inc)<<5)
|
rlm@1
|
1569 + ((t & 7)<<2) + ((xxx>>3)<<5) + ((xxx & 7) >> 1))&0x7fff);
|
rlm@1
|
1570 // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
|
rlm@1
|
1571 // int palette = (a2 >> 8) & 0xF0;
|
rlm@1
|
1572 if (a1 & 0x1000)
|
rlm@1
|
1573 {
|
rlm@1
|
1574 xxx = 7;
|
rlm@1
|
1575 for (int xx = sizeX - 1; xx >= 0; xx--)
|
rlm@1
|
1576 {
|
rlm@1
|
1577 if (sx < 240)
|
rlm@1
|
1578 {
|
rlm@1
|
1579 u8 color = vram[address];
|
rlm@1
|
1580 if (xx & 1)
|
rlm@1
|
1581 {
|
rlm@1
|
1582 color = (color >> 4);
|
rlm@1
|
1583 }
|
rlm@1
|
1584 else
|
rlm@1
|
1585 color &= 0x0F;
|
rlm@1
|
1586
|
rlm@1
|
1587 if (color)
|
rlm@1
|
1588 {
|
rlm@1
|
1589 lineOBJWin[sx] = 1;
|
rlm@1
|
1590 }
|
rlm@1
|
1591 }
|
rlm@1
|
1592 sx = (sx+1) & 511;
|
rlm@1
|
1593 xxx--;
|
rlm@1
|
1594 if (!(xx & 1))
|
rlm@1
|
1595 address--;
|
rlm@1
|
1596 if (xxx == -1)
|
rlm@1
|
1597 {
|
rlm@1
|
1598 xxx = 7;
|
rlm@1
|
1599 address -= 28;
|
rlm@1
|
1600 }
|
rlm@1
|
1601 if (address < 0x10000)
|
rlm@1
|
1602 address += 0x8000;
|
rlm@1
|
1603 }
|
rlm@1
|
1604 }
|
rlm@1
|
1605 else
|
rlm@1
|
1606 {
|
rlm@1
|
1607 for (int xx = 0; xx < sizeX; xx++)
|
rlm@1
|
1608 {
|
rlm@1
|
1609 if (sx < 240)
|
rlm@1
|
1610 {
|
rlm@1
|
1611 u8 color = vram[address];
|
rlm@1
|
1612 if (xx & 1)
|
rlm@1
|
1613 {
|
rlm@1
|
1614 color = (color >> 4);
|
rlm@1
|
1615 }
|
rlm@1
|
1616 else
|
rlm@1
|
1617 color &= 0x0F;
|
rlm@1
|
1618
|
rlm@1
|
1619 if (color)
|
rlm@1
|
1620 {
|
rlm@1
|
1621 lineOBJWin[sx] = 1;
|
rlm@1
|
1622 }
|
rlm@1
|
1623 }
|
rlm@1
|
1624 sx = (sx+1) & 511;
|
rlm@1
|
1625 xxx++;
|
rlm@1
|
1626 if (xx & 1)
|
rlm@1
|
1627 address++;
|
rlm@1
|
1628 if (xxx == 8)
|
rlm@1
|
1629 {
|
rlm@1
|
1630 address += 28;
|
rlm@1
|
1631 xxx = 0;
|
rlm@1
|
1632 }
|
rlm@1
|
1633 if (address > 0x17fff)
|
rlm@1
|
1634 address -= 0x8000;
|
rlm@1
|
1635 }
|
rlm@1
|
1636 }
|
rlm@1
|
1637 }
|
rlm@1
|
1638 }
|
rlm@1
|
1639 }
|
rlm@1
|
1640 }
|
rlm@1
|
1641 }
|
rlm@1
|
1642 }
|
rlm@1
|
1643 }
|
rlm@1
|
1644
|
rlm@1
|
1645 inline u32 gfxIncreaseBrightness(u32 color, int coeff)
|
rlm@1
|
1646 {
|
rlm@1
|
1647 int r = (color & 0x1F);
|
rlm@1
|
1648 int g = ((color >> 5) & 0x1F);
|
rlm@1
|
1649 int b = ((color >> 10) & 0x1F);
|
rlm@1
|
1650
|
rlm@1
|
1651 r = r + (((31 - r) * coeff) >> 4);
|
rlm@1
|
1652 g = g + (((31 - g) * coeff) >> 4);
|
rlm@1
|
1653 b = b + (((31 - b) * coeff) >> 4);
|
rlm@1
|
1654 if (r > 31)
|
rlm@1
|
1655 r = 31;
|
rlm@1
|
1656 if (g > 31)
|
rlm@1
|
1657 g = 31;
|
rlm@1
|
1658 if (b > 31)
|
rlm@1
|
1659 b = 31;
|
rlm@1
|
1660 color = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
|
rlm@1
|
1661 return color;
|
rlm@1
|
1662 }
|
rlm@1
|
1663
|
rlm@1
|
1664 inline void gfxIncreaseBrightness(u32 *line, int coeff)
|
rlm@1
|
1665 {
|
rlm@1
|
1666 for (int x = 0; x < 240; x++)
|
rlm@1
|
1667 {
|
rlm@1
|
1668 u32 color = *line;
|
rlm@1
|
1669 int r = (color & 0x1F);
|
rlm@1
|
1670 int g = ((color >> 5) & 0x1F);
|
rlm@1
|
1671 int b = ((color >> 10) & 0x1F);
|
rlm@1
|
1672
|
rlm@1
|
1673 r = r + (((31 - r) * coeff) >> 4);
|
rlm@1
|
1674 g = g + (((31 - g) * coeff) >> 4);
|
rlm@1
|
1675 b = b + (((31 - b) * coeff) >> 4);
|
rlm@1
|
1676 if (r > 31)
|
rlm@1
|
1677 r = 31;
|
rlm@1
|
1678 if (g > 31)
|
rlm@1
|
1679 g = 31;
|
rlm@1
|
1680 if (b > 31)
|
rlm@1
|
1681 b = 31;
|
rlm@1
|
1682 *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
|
rlm@1
|
1683 }
|
rlm@1
|
1684 }
|
rlm@1
|
1685
|
rlm@1
|
1686 inline u32 gfxDecreaseBrightness(u32 color, int coeff)
|
rlm@1
|
1687 {
|
rlm@1
|
1688 int r = (color & 0x1F);
|
rlm@1
|
1689 int g = ((color >> 5) & 0x1F);
|
rlm@1
|
1690 int b = ((color >> 10) & 0x1F);
|
rlm@1
|
1691
|
rlm@1
|
1692 r = r - ((r * coeff) >> 4);
|
rlm@1
|
1693 g = g - ((g * coeff) >> 4);
|
rlm@1
|
1694 b = b - ((b * coeff) >> 4);
|
rlm@1
|
1695 if (r < 0)
|
rlm@1
|
1696 r = 0;
|
rlm@1
|
1697 if (g < 0)
|
rlm@1
|
1698 g = 0;
|
rlm@1
|
1699 if (b < 0)
|
rlm@1
|
1700 b = 0;
|
rlm@1
|
1701 color = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
|
rlm@1
|
1702
|
rlm@1
|
1703 return color;
|
rlm@1
|
1704 }
|
rlm@1
|
1705
|
rlm@1
|
1706 inline void gfxDecreaseBrightness(u32 *line, int coeff)
|
rlm@1
|
1707 {
|
rlm@1
|
1708 for (int x = 0; x < 240; x++)
|
rlm@1
|
1709 {
|
rlm@1
|
1710 u32 color = *line;
|
rlm@1
|
1711 int r = (color & 0x1F);
|
rlm@1
|
1712 int g = ((color >> 5) & 0x1F);
|
rlm@1
|
1713 int b = ((color >> 10) & 0x1F);
|
rlm@1
|
1714
|
rlm@1
|
1715 r = r - ((r * coeff) >> 4);
|
rlm@1
|
1716 g = g - ((g * coeff) >> 4);
|
rlm@1
|
1717 b = b - ((b * coeff) >> 4);
|
rlm@1
|
1718 if (r < 0)
|
rlm@1
|
1719 r = 0;
|
rlm@1
|
1720 if (g < 0)
|
rlm@1
|
1721 g = 0;
|
rlm@1
|
1722 if (b < 0)
|
rlm@1
|
1723 b = 0;
|
rlm@1
|
1724 *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
|
rlm@1
|
1725 }
|
rlm@1
|
1726 }
|
rlm@1
|
1727
|
rlm@1
|
1728 inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)
|
rlm@1
|
1729 {
|
rlm@1
|
1730 if (color < 0x80000000)
|
rlm@1
|
1731 {
|
rlm@1
|
1732 int r = (color & 0x1F);
|
rlm@1
|
1733 int g = ((color >> 5) & 0x1F);
|
rlm@1
|
1734 int b = ((color >> 10) & 0x1F);
|
rlm@1
|
1735 int r0 = (color2 & 0x1F);
|
rlm@1
|
1736 int g0 = ((color2 >> 5) & 0x1F);
|
rlm@1
|
1737 int b0 = ((color2 >> 10) & 0x1F);
|
rlm@1
|
1738
|
rlm@1
|
1739 r = ((r * ca) >> 4) + ((r0 * cb) >> 4);
|
rlm@1
|
1740 g = ((g * ca) >> 4) + ((g0 * cb) >> 4);
|
rlm@1
|
1741 b = ((b * ca) >> 4) + ((b0 * cb) >> 4);
|
rlm@1
|
1742
|
rlm@1
|
1743 if (r > 31)
|
rlm@1
|
1744 r = 31;
|
rlm@1
|
1745 if (g > 31)
|
rlm@1
|
1746 g = 31;
|
rlm@1
|
1747 if (b > 31)
|
rlm@1
|
1748 b = 31;
|
rlm@1
|
1749
|
rlm@1
|
1750 return (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
|
rlm@1
|
1751 }
|
rlm@1
|
1752 return color;
|
rlm@1
|
1753 }
|
rlm@1
|
1754
|
rlm@1
|
1755 inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)
|
rlm@1
|
1756 {
|
rlm@1
|
1757 for (int x = 0; x < 240; x++)
|
rlm@1
|
1758 {
|
rlm@1
|
1759 u32 color = *ta;
|
rlm@1
|
1760 if (color < 0x80000000)
|
rlm@1
|
1761 {
|
rlm@1
|
1762 int r = (color & 0x1F);
|
rlm@1
|
1763 int g = ((color >> 5) & 0x1F);
|
rlm@1
|
1764 int b = ((color >> 10) & 0x1F);
|
rlm@1
|
1765 u32 color2 = (*tb++);
|
rlm@1
|
1766 int r0 = (color2 & 0x1F);
|
rlm@1
|
1767 int g0 = ((color2 >> 5) & 0x1F);
|
rlm@1
|
1768 int b0 = ((color2 >> 10) & 0x1F);
|
rlm@1
|
1769
|
rlm@1
|
1770 r = ((r * ca) >> 4) + ((r0 * cb) >> 4);
|
rlm@1
|
1771 g = ((g * ca) >> 4) + ((g0 * cb) >> 4);
|
rlm@1
|
1772 b = ((b * ca) >> 4) + ((b0 * cb) >> 4);
|
rlm@1
|
1773
|
rlm@1
|
1774 if (r > 31)
|
rlm@1
|
1775 r = 31;
|
rlm@1
|
1776 if (g > 31)
|
rlm@1
|
1777 g = 31;
|
rlm@1
|
1778 if (b > 31)
|
rlm@1
|
1779 b = 31;
|
rlm@1
|
1780
|
rlm@1
|
1781 *ta++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
|
rlm@1
|
1782 }
|
rlm@1
|
1783 else
|
rlm@1
|
1784 {
|
rlm@1
|
1785 ta++;
|
rlm@1
|
1786 tb++;
|
rlm@1
|
1787 }
|
rlm@1
|
1788 }
|
rlm@1
|
1789 }
|
rlm@1
|
1790
|
rlm@1
|
1791 #endif // VBA_GBA_GFX_H
|