1 /* ResidualVM - A 3D game interpreter
2 *
3 * ResidualVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the AUTHORS
5 * file distributed with this source distribution.
6 *
7 * Additional copyright for this file:
8 * Copyright (C) 1999-2000 Revolution Software Ltd.
9 * This code is based on source code created by Revolution Software,
10 * used with permission.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 *
26 */
27
28 #include "engines/icb/gfx/psx_pcdefines.h"
29 #include "engines/icb/gfx/psx_pcgpu.h"
30 #include "engines/icb/gfx/psx_poly.h"
31 #include "engines/icb/gfx/gfxstub.h"
32
33 #include "common/textconsole.h"
34
35 namespace ICB {
36
37 // Defaults for the OT list
38 #define UNLINKED_ADDR (void *)(0xDEADBEAF)
39 #define UNLINKED_LEN (0x6666)
40
41 // For storing user data in the OT entry e.g. texture pointer
42 void *OTusrData;
43
44 // No ABR support : at the moment
45 uint16 psxTP;
46
47 // The emulation of VRAM : 16-bit pixels 1024x512 big
48 uint16 psxVRAM[VRAM_WIDTH * VRAM_HEIGHT];
49
50 // Set VRAM to a certain colour
ClearImage(RECT16 * rect,uint8 r,uint8 g,uint8 b)51 int32 ClearImage(RECT16 *rect, uint8 r, uint8 g, uint8 b) {
52 uint16 colour;
53 int32 x, y;
54 int32 i;
55
56 // Convert 24-bit colour to 15-bit
57 colour = (uint16)((r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10));
58
59 for (y = rect->y; y < rect->y + rect->h; y++) {
60 for (x = rect->x; x < rect->x + rect->w; x++) {
61 i = x + y * VRAM_WIDTH;
62 psxVRAM[i] = colour;
63 }
64 }
65 return 1;
66 }
67
68 // Fill VRAM with data
LoadClut(uint32 * clut,int32 x,int32 y)69 uint16 LoadClut(uint32 *clut, int32 x, int32 y) {
70 RECT16 rect;
71 setRECT(&rect, (int16)x, (int16)y, 256, 1);
72 LoadImage(&rect, clut);
73 return (uint16)getClut(x, y);
74 }
75
76 // Fill VRAM with data
LoadImage(RECT16 * rect,uint32 * p)77 int32 LoadImage(RECT16 *rect, uint32 *p) {
78 int32 x, y, i;
79 uint16 *p16 = (uint16 *)p;
80
81 for (y = rect->y; y < rect->y + rect->h; y++) {
82 for (x = rect->x; x < rect->x + rect->w; x++) {
83 i = x + y * VRAM_WIDTH;
84 psxVRAM[i] = *p16;
85 p16++;
86 }
87 }
88 return 1;
89 }
90
91 // Move data around within VRAM
MoveImage(RECT16 * rect,int32 x,int32 y)92 int32 MoveImage(RECT16 *rect, int32 x, int32 y) {
93 int32 x0, y0, i0;
94 int32 x1, y1, i1;
95
96 y1 = y;
97 for (y0 = rect->y; y0 < rect->y + rect->h; y0++) {
98 x1 = x;
99 for (x0 = rect->x; x0 < rect->x + rect->w; x0++) {
100 i0 = x0 + y0 * VRAM_WIDTH;
101 i1 = x1 + y1 * VRAM_WIDTH;
102 psxVRAM[i1] = psxVRAM[i0];
103 x1++;
104 }
105 y1++;
106 }
107 return 1;
108 }
109
110 // Setup the linked list for the OT tags from back to the front
ClearOTagR(OT_tag * ot,uint32 size)111 OT_tag *ClearOTagR(OT_tag *ot, uint32 size) {
112 int32 i = size - 1;
113 while (i > 0) {
114 ot[i].addr = (void *)&ot[i - 1];
115 ot[i].len = UNLINKED_LEN;
116 i--;
117 }
118 ot[0].addr = UNLINKED_ADDR;
119 ot[0].len = UNLINKED_LEN;
120 return ot;
121 }
122
123 // Setup the linked list for the OT tags from front to back
ClearOTag(OT_tag * ot,uint32 size)124 OT_tag *ClearOTag(OT_tag *ot, uint32 size) {
125 uint32 i = 0;
126 while (i < (size - 1)) {
127 ot[i].addr = (void *)&ot[i + 1];
128 ot[i].len = UNLINKED_LEN;
129 }
130 ot[size - 1].addr = UNLINKED_ADDR;
131 ot[size - 1].len = UNLINKED_LEN;
132 return ot;
133 }
134
135 int32 nPrims;
136
137 // Draw the damm things
DrawOTag(OT_tag * ot)138 void DrawOTag(OT_tag *ot) {
139 OT_tag *prim = ot;
140 nPrims = 0;
141
142 while (prim->addr != UNLINKED_ADDR) {
143 if (prim->len != UNLINKED_LEN) {
144 DrawPrim((void *)prim);
145 }
146 // Move to the next link in the chain
147 prim = (OT_tag *)(prim->addr);
148 }
149 }
150
151 // Draw the base primitive
152
153 // Should also be checking the lengths to make sure we haven't
154 // got corrupt data
DrawPrim(void * prim)155 void DrawPrim(void *prim) {
156 P_TAG *p = (P_TAG *)prim;
157 uint32 code = p->code;
158 uint32 len = p->len;
159 uint16 z0 = p->z0;
160 void *usr = p->usr;
161 uint8 alpha = 0x00;
162
163 // Catch special primitives
164 // DR_TPAGE
165 if ((code & 0xe1) == 0xe1) {
166 psxTP = (uint16)(*((uint32 *)&(p->r0)) & 0xFFFF);
167 len -= GPUSIZE_DR_TPAGE; // we have used one word of data up
168 // Move the pointer onto the correct place
169 p++; // move past the P_TAG
170
171 // handle multiple primitives in one block
172 code = p->code;
173 if (len > 0) {
174 len -= GPUSIZE_TAG;
175 }
176
177 // Get the base alpha value
178 alpha = ((P_HEADER *)(p))->code;
179 // Modify that based on tbe ABR value
180 uint8 abr = (uint8)((psxTP >> 5) & 0x3);
181 if (abr == 0) {
182 // alpha is 0-64, so 32 is average
183 alpha = 0xC0 | 0x20; // average of background + foreground
184 } else if (abr == 1)
185 alpha = 0x40; // additive
186 else if (abr == 2)
187 alpha = 0x80; // subtractive
188 else if (abr == 3)
189 // alpha is 0-64 : no error checking
190 alpha |= 0xC0; // alpha blend
191 else
192 alpha = 0x00; // ignore any other modes
193 }
194
195 nPrims++;
196 // Decode the primitive type and then respond appropiately
197 // Mask off the primitive modifiers (bottom two bits)
198 // bit 0 = shade text
199 // bit 1 = semi-trans
200 switch (code & 0xFC) {
201 // Flat Coloured Rectangle
202 // TILE: code:0x60 length:4
203 case GPUCODE_TILE: {
204 TILE *pr = (TILE *)p;
205 if (len != GPUSIZE_TILE) {
206 warning("Primitive %p length %d != TILE length %d\n", prim, (uint32)len, GPUSIZE_TILE);
207 return;
208 }
209 DrawTile(pr->x0, pr->y0, pr->w, pr->h, pr->r0, pr->g0, pr->b0, alpha, z0);
210 break;
211 }
212 // Flat Coloured Rectangle 1 pixel width & height
213 // TILE_1: code:0x68 length:3
214 case GPUCODE_TILE_1: {
215 TILE_1 *pr = (TILE_1 *)p;
216 if (len != GPUSIZE_TILE_1) {
217 warning("Primitive %p length %d != TILE_1 length %d\n", prim, (uint32)len, GPUSIZE_TILE_1);
218 return;
219 }
220 DrawTile(pr->x0, pr->y0, 1, 1, pr->r0, pr->g0, pr->b0, alpha, z0);
221 break;
222 }
223 // Flat Coloured Rectangle 8 pixel width & height
224 // TILE_8: code:0x70 length:3
225 case GPUCODE_TILE_8: {
226 TILE_8 *pr = (TILE_8 *)p;
227 if (len != GPUSIZE_TILE_8) {
228 warning("Primitive %p length %d != TILE_8 length %d\n", prim, (uint32)len, GPUSIZE_TILE_8);
229 return;
230 }
231 DrawTile(pr->x0, pr->y0, 8, 8, pr->r0, pr->g0, pr->b0, alpha, z0);
232 break;
233 }
234 // Flat Coloured Rectangle 16 pixel width & height
235 // TILE_16: code:0x78 length:3
236 case GPUCODE_TILE_16: {
237 TILE_16 *pr = (TILE_16 *)p;
238 if (len != GPUSIZE_TILE_16) {
239 warning("Primitive %p length %d != TILE_16 length %d\n", prim, (uint32)len, GPUSIZE_TILE_16);
240 return;
241 }
242 DrawTile(pr->x0, pr->y0, 16, 16, pr->r0, pr->g0, pr->b0, alpha, z0);
243 break;
244 }
245 // Flat Coloured single line
246 // LineF2 = code: 0x40 length:4
247 case GPUCODE_LINE_F2: {
248 LINE_F2 *pr = (LINE_F2 *)p;
249 if (len != GPUSIZE_LINE_F2) {
250 warning("Primitive %p length %d != LineF2 length %d\n", prim, (uint32)len, GPUSIZE_LINE_F2);
251 return;
252 }
253 /*
254 printf( "LineF2: (%d,%d) (%d,%d) RGB0:%d %d %d\n",
255 pr->x0, pr->y0, pr->x1, pr->y1, pr->r0, pr->g0, pr->b0 );
256 */
257 DrawLineF2(pr->x0, pr->y0, pr->x1, pr->y1, pr->r0, pr->g0, pr->b0, alpha, z0);
258 break;
259 }
260 // Flat Coloured double line (not closed)
261 // LineF3 = code: 0x48 length:6
262 case GPUCODE_LINE_F3: {
263 LINE_F3 *pr = (LINE_F3 *)p;
264 if (len != GPUSIZE_LINE_F3) {
265 warning("Primitive %p length %d != LineF3 length %d\n", prim, (uint32)len, GPUSIZE_LINE_F3);
266 return;
267 }
268 /*
269 printf( "LineF3: (%d,%d) (%d,%d) (%d,%d) RGB0:%d %d %d\n",
270 pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2,
271 pr->r0, pr->g0, pr->b0 );
272 */
273 DrawLineF3(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->r0, pr->g0, pr->b0, alpha, z0);
274 break;
275 }
276 // Flat Coloured triple line (not closed)
277 // LineF4 = code: 0x4c length:7
278 case GPUCODE_LINE_F4: {
279 LINE_F4 *pr = (LINE_F4 *)p;
280 if (len != GPUSIZE_LINE_F4) {
281 warning("Primitive %p length %d != LineF4 length %d\n", prim, (uint32)len, GPUSIZE_LINE_F4);
282 return;
283 }
284 /*
285 printf( "LineF4: (%d,%d) (%d,%d) (%d,%d) (%d %d) RGB0:%d %d %d\n",
286 pr->x0, pr->y0, pr->x1, pr->y1,
287 pr->x2, pr->y2, pr->x3, pr->y3,
288 pr->r0, pr->g0, pr->b0 );
289 */
290 DrawLineF4(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->x3, pr->y3, pr->r0, pr->g0, pr->b0, alpha, z0);
291 break;
292 }
293
294 // Gouraud Coloured single line
295 // LineG2 = code: 0x50 length:5
296 case GPUCODE_LINE_G2: {
297 LINE_G2 *pr = (LINE_G2 *)p;
298 if (len != GPUSIZE_LINE_G2) {
299 warning("Primitive %p length %d != LineG2 length %d\n", prim, (uint32)len, GPUSIZE_LINE_G2);
300 return;
301 }
302 /*
303 printf( "LineG2: (%d,%d) (%d,%d) RGB0:%d %d %d RGB1:%d %d %d\n",
304 pr->x0, pr->y0, pr->x1, pr->y1,
305 pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1 );
306 */
307 DrawLineG2(pr->x0, pr->y0, pr->x1, pr->y1, pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1, alpha, z0);
308 break;
309 }
310 // Gouraud Coloured double line (not closed)
311 // LineG3 = code: 0x58 length:8
312 case GPUCODE_LINE_G3: {
313 LINE_G3 *pr = (LINE_G3 *)p;
314 if (len != GPUSIZE_LINE_G3) {
315 warning("Primitive %p length %d != LineG3 length %d\n", prim, (uint32)len, GPUSIZE_LINE_G3);
316 return;
317 }
318 /*
319 printf( "LineG3: (%d,%d) (%d,%d) (%d,%d) RGB0:%d %d %d RGB1:%d %d %d\n",
320 pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2,
321 pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1 );
322 */
323 DrawLineG3(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1, pr->r2, pr->g2, pr->b2, alpha, z0);
324 break;
325 }
326 // Gouraud Coloured triple line (not closed)
327 // LineG4 = code: 0x5c length:10
328 case GPUCODE_LINE_G4: {
329 LINE_G4 *pr = (LINE_G4 *)p;
330 if (len != GPUSIZE_LINE_G4) {
331 warning("Primitive %p length %d != LineG4 length %d\n", prim, (uint32)len, GPUSIZE_LINE_G4);
332 return;
333 }
334 /*
335 printf( "LineG4: (%d,%d) (%d,%d) (%d,%d) (%d %d) \
336 RGB0:%d %d %d RGB1:%d %d %d RGB2:%d %d %d RGB3:%d %d %d\n",
337 pr->x0, pr->y0, pr->x1, pr->y1,
338 pr->x2, pr->y2, pr->x3, pr->y3,
339 pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1,
340 pr->r2, pr->g2, pr->b2, pr->r3, pr->g3, pr->b3 );
341 */
342 DrawLineG4(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->x3, pr->y3, pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1, pr->r2, pr->g2, pr->b2, pr->r3, pr->g3,
343 pr->b3, alpha, z0);
344 break;
345 }
346
347 // Flat Coloured Non-textured triangle
348 // PolyF3 = code:0x20 length:5
349 case GPUCODE_POLY_F3: {
350 POLY_F3 *pr = (POLY_F3 *)p;
351 if (len != GPUSIZE_POLY_F3) {
352 warning("Primitive %p length %d != PolyF3 length %d\n", prim, (uint32)len, GPUSIZE_POLY_F3);
353 return;
354 }
355 /*
356 printf( "PolyF3: (%d,%d) (%d,%d) (%d,%d) RGB0:%d %d %d\n",
357 pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2,
358 pr->r0, pr->g0, pr->b0 );
359 */
360 DrawFlatTriangle(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->r0, pr->g0, pr->b0, alpha, z0);
361 break;
362 }
363
364 // Flat Coloured Non-textured quad
365 // PolyF4 = code:0x28 length:6
366 case GPUCODE_POLY_F4: {
367 POLY_F4 *pr = (POLY_F4 *)p;
368 if (len != GPUSIZE_POLY_F4) {
369 warning("Primitive %p length %d != PolyF4 length %d\n", prim, (uint32)len, GPUSIZE_POLY_F4);
370 return;
371 }
372 /*
373 printf( "PolyF4: (%d,%d) (%d,%d) (%d,%d) (%d %d) RGB0:%d %d %d\n",
374 pr->x0, pr->y0, pr->x1, pr->y1,
375 pr->x2, pr->y2, pr->x3, pr->y3,
376 pr->r0, pr->g0, pr->b0 );
377 */
378 DrawFlatQuad(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->x3, pr->y3, pr->r0, pr->g0, pr->b0, alpha, z0);
379 break;
380 }
381
382 // Gouraud Coloured Non-textured triangle
383 // PolyG3 = code:0x30 length:7
384 case GPUCODE_POLY_G3: {
385 POLY_G3 *pr = (POLY_G3 *)p;
386 if (len != GPUSIZE_POLY_G3) {
387 warning("Primitive %p length %d != PolyG3 length %d\n", prim, (uint32)len, GPUSIZE_POLY_G3);
388 return;
389 }
390 /*
391 printf( "PolyG3: (%d,%d) (%d,%d) (%d,%d) \
392 RGB0:%d %d %d RGB1:%d %d %d RGB2:%d %d %d\n",
393 pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2,
394 pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1,
395 pr->r2, pr->g2, pr->b2 );
396 */
397 DrawGouraudTriangle(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1, pr->r2, pr->g2, pr->b2, alpha, z0);
398 break;
399 }
400 // Gouraud Coloured Non-textured quad
401 // PolyG4 = code:0x38 length:9
402 case GPUCODE_POLY_G4: {
403 POLY_G4 *pr = (POLY_G4 *)p;
404 if (len != GPUSIZE_POLY_G4) {
405 warning("Primitive %p length %d != PolyG4 length %d\n", prim, (uint32)len, GPUSIZE_POLY_G4);
406 return;
407 }
408 /*
409 printf( "PolyG4: (%d,%d) (%d,%d) (%d,%d) (%d %d) \
410 RGB0:%d %d %d RGB1:%d %d %d RGB2:%d %d %d RGB3:%d %d %d\n",
411 pr->x0, pr->y0, pr->x1, pr->y1,
412 pr->x2, pr->y2, pr->x3, pr->y3,
413 pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1,
414 pr->r2, pr->g2, pr->b2, pr->r3, pr->g3, pr->b3 );
415 */
416 DrawGouraudQuad(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->x3, pr->y3, pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1, pr->r2, pr->g2, pr->b2, pr->r3,
417 pr->g3, pr->b3, alpha, z0);
418 break;
419 }
420 // Flat Coloured Textured triangle
421 // PolyFT3 = code:0x24 length:8
422 case GPUCODE_POLY_FT3: {
423 POLY_FT3 *pr = (POLY_FT3 *)p;
424 if (len != GPUSIZE_POLY_FT3) {
425 warning("Primitive %p length %d != PolyFT3 length %d\n", prim, (uint32)len, GPUSIZE_POLY_FT3);
426 return;
427 }
428 /*
429 printf( "PolyFT3: (%d,%d) (%d,%d) (%d,%d)\n(%d,%d) (%d,%d) (%d,%d)\nRGB0:%d %d %d\n",
430 pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2,
431 pr->u0, pr->v0, pr->u1, pr->v1, pr->u2, pr->v2,
432 pr->r0, pr->g0, pr->b0 );
433 */
434 DrawFlatTriangleTextured(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->r0, pr->g0, pr->b0, pr->u0, pr->v0, pr->u1, pr->v1, pr->u2, pr->v2, alpha, z0, usr);
435 break;
436 }
437 // Flat Coloured Textured quad
438 // PolyFT4 = code:0x2c length:10
439 case GPUCODE_POLY_FT4: {
440 POLY_FT4 *pr = (POLY_FT4 *)p;
441 if (len != GPUSIZE_POLY_FT4) {
442 warning("Primitive %p length %d != PolyFT4 length %d\n", prim, (uint32)len, GPUSIZE_POLY_FT4);
443 return;
444 }
445 /*
446 printf( "PolyFT4: (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n(%d,%d) (%d,%d) (%d,%d) (%d,%d)\nRGB0:%d %d %d\n",
447 pr->x0, pr->y0, pr->x1, pr->y1,
448 pr->x2, pr->y2, pr->x3, pr->y3,
449 pr->u0, pr->v0, pr->u1, pr->v1,
450 pr->u2, pr->u2, pr->u3, pr->u3,
451 pr->r0, pr->g0, pr->b0 );
452 */
453
454 DrawFlatQuadTextured(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->x3, pr->y3, pr->r0, pr->g0, pr->b0, pr->u0, pr->v0, pr->u1, pr->v1, pr->u2, pr->v2, pr->u3,
455 pr->v3, alpha, z0, usr);
456 break;
457 }
458 // Gouraud Coloured Textured triangle
459 // PolyGT3 = code:0x34 length:10
460 case GPUCODE_POLY_GT3: {
461 POLY_GT3 *pr = (POLY_GT3 *)p;
462 if (len != GPUSIZE_POLY_GT3) {
463 warning("Primitive %p length %d != PolyGT3 length %d\n", prim, (uint32)len, GPUSIZE_POLY_GT3);
464 return;
465 }
466 /*
467 printf( "PolyGT3: (%d,%d) (%d,%d) (%d,%d)\n(%d,%d) (%d,%d) (%d,%d)\nRGB0:%d %d %d RGB1:%d %d %d RGB2:%d %d %d\n",
468 pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2,
469 pr->u0, pr->v0, pr->u1, pr->v1, pr->u2, pr->v2,
470 pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1,
471 pr->r2, pr->g2, pr->b2 );
472 */
473
474 DrawGouraudTriangleTextured(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1, pr->r2, pr->g2, pr->b2, pr->u0, pr->v0,
475 pr->u1, pr->v1, pr->u2, pr->v2, alpha, z0, usr);
476 break;
477 }
478 // Gouraud Coloured Textured quad
479 // PolyGT4 = code:0x3c length:13
480 case GPUCODE_POLY_GT4: {
481 POLY_GT4 *pr = (POLY_GT4 *)p;
482 if (len != GPUSIZE_POLY_GT4) {
483 warning("Primitive %p length %d != PolyGT4 length %d\n", prim, (uint32)len, GPUSIZE_POLY_GT4);
484 return;
485 }
486 /*
487 printf( "PolyGT4: (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n(%d,%d) (%d,%d) (%d,%d) (%d,%d)\nRGB0:%d %d %d RGB1:%d %d %d RGB2:%d %d $d RGB3:%d %d %d\n",
488 pr->x0, pr->y0, pr->x1, pr->y1,
489 pr->x2, pr->y2, pr->x3, pr->y3,
490 pr->u0, pr->v0, pr->u1, pr->v1,
491 pr->u2, pr->u2, pr->u3, pr->u3,
492 pr->r0, pr->g0, pr->b0,
493 pr->r1, pr->g1, pr->b1,
494 pr->r2, pr->g2, pr->b2,
495 pr->r3, pr->g3, pr->b3 );
496 */
497 DrawGouraudQuadTextured(pr->x0, pr->y0, pr->x1, pr->y1, pr->x2, pr->y2, pr->x3, pr->y3, pr->r0, pr->g0, pr->b0, pr->r1, pr->g1, pr->b1, pr->r2, pr->g2, pr->b2,
498 pr->r3, pr->g3, pr->b3, pr->u0, pr->v0, pr->u1, pr->v1, pr->u2, pr->v2, pr->u3, pr->v3, alpha, z0, usr);
499 break;
500 }
501 // Flat Coloured Textured Tile
502 // SPRT = code:0x64 length:5
503 case GPUCODE_SPRT: {
504 SPRT *pr = (SPRT *)p;
505 if (len != GPUSIZE_SPRT) {
506 warning("Primitive %p length %d != SPRT length %d\n", prim, (uint32)len, GPUSIZE_SPRT);
507 return;
508 }
509 DrawSprite(pr->x0, pr->y0, pr->w, pr->h, pr->r0, pr->g0, pr->b0, pr->u0, pr->v0, alpha, z0, usr);
510 break;
511 }
512 // Flat Coloured Textured Tile 8 pixels x 8 pixels
513 // SPRT_8 = code:0x74 length:4
514 case GPUCODE_SPRT_8: {
515 SPRT_8 *pr = (SPRT_8 *)p;
516 if (len != GPUSIZE_SPRT_8) {
517 warning("Primitive %p length %d != SPRT_8 length %d\n", prim, (uint32)len, GPUSIZE_SPRT_8);
518 return;
519 }
520 DrawSprite(pr->x0, pr->y0, 8, 8, pr->r0, pr->g0, pr->b0, pr->u0, pr->v0, alpha, z0, usr);
521 break;
522 }
523 // Flat Coloured Textured Tile 16 pixels x 16 pixels
524 // SPRT_16 = code:0x7c length:4
525 case GPUCODE_SPRT_16: {
526 SPRT_16 *pr = (SPRT_16 *)p;
527 if (len != GPUSIZE_SPRT_16) {
528 warning("Primitive %p length %d != SPRT_16 length %d\n", prim, (uint32)len, GPUSIZE_SPRT_16);
529 return;
530 }
531 DrawSprite(pr->x0, pr->y0, 16, 16, pr->r0, pr->g0, pr->b0, pr->u0, pr->v0, alpha, z0, usr);
532 break;
533 }
534 default: {
535 warning("Unknown Primitive\n");
536 break;
537 }
538 }
539 }
540
541 } // End of namespace ICB
542