sdk-world v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Loading...
Searching...
No Matches
gsTexture.c
1// ____ ___ | / _____ _____
2// | __ | |___/ | |
3// |___| ___| | \ __|__ | gsKit Open Source Project.
4// ----------------------------------------------------------------------
5// Copyright 2004 - Chris "Neovanglist" Gilbert <Neovanglist@LainOS.org>
6// Licenced under Academic Free License version 2.0
7// Review gsKit README & LICENSE files for further details.
8//
9// gsTexture.c - Texture loading, handling, and manipulation.
10//
11// lzw() implimentation from jbit! Thanks jbit!
12//
13
14#include <stdio.h>
15#include <string.h>
16#include <malloc.h>
17#include <kernel.h>
18
19#include "gsKit.h"
20#include "gsInline.h"
21
22static inline u32 lzw(u32 val)
23{
24 u32 res;
25 __asm__ __volatile__ (" plzcw %0, %1 " : "=r" (res) : "r" (val));
26 return(res);
27}
28
29
30u32 gsKit_texture_size_ee(int width, int height, int psm)
31{
32
33#ifdef DEBUG
34 printf("Width: %d - Height: %d\n", width, height);
35#endif
36
37 switch (psm) {
38 case GS_PSM_CT32: return (width*height*4);
39 case GS_PSM_CT24: return (width*height*4);
40 case GS_PSM_CT16: return (width*height*2);
41 case GS_PSM_CT16S: return (width*height*2);
42 case GS_PSM_T8: return (width*height );
43 case GS_PSM_T4: return (width*height/2);
44 default: printf("gsKit: unsupported PSM %d\n", psm);
45 }
46
47 return -1;
48}
49
50u32 gsKit_texture_size(int width, int height, int psm)
51{
52 int widthBlocks, heightBlocks;
53 int widthAlign, heightAlign;
54
55 // Calculate the number of blocks width and height
56 // A block is 256 bytes in size
57 switch (psm) {
58 case GS_PSM_CT32:
59 case GS_PSM_CT24:
60 // 1 block = 8x8 pixels
61 widthBlocks = (width + 7) / 8;
62 heightBlocks = (height + 7) / 8;
63 break;
64 case GS_PSM_CT16:
65 case GS_PSM_CT16S:
66 // 1 block = 16x8 pixels
67 widthBlocks = (width + 15) / 16;
68 heightBlocks = (height + 7) / 8;
69 break;
70 case GS_PSM_T8:
71 // 1 block = 16x16 pixels
72 widthBlocks = (width + 15) / 16;
73 heightBlocks = (height + 15) / 16;
74 break;
75 case GS_PSM_T4:
76 // 1 block = 32x16 pixels
77 widthBlocks = (width + 31) / 32;
78 heightBlocks = (height + 15) / 16;
79 break;
80 default:
81 printf("gsKit: unsupported PSM %d\n", psm);
82 return -1;
83 }
84
85 // Calculate the minimum block alignment
86 if(psm == GS_PSM_CT32 || psm == GS_PSM_CT24 || psm == GS_PSM_T8) {
87 // 8x4 blocks in a page.
88 // block traversing order:
89 // 0145....
90 // 2367....
91 // ........
92 // ........
93 if(widthBlocks <= 2 && heightBlocks <= 1) {
94 widthAlign = 1;
95 heightAlign = 1;
96 }
97 else if(widthBlocks <= 4 && heightBlocks <= 2) {
98 widthAlign = 2;
99 heightAlign = 2;
100 }
101 else if(widthBlocks <= 8 && heightBlocks <= 4) {
102 widthAlign = 4;
103 heightAlign = 4;
104 }
105 else {
106 widthAlign = 8;
107 heightAlign = 4;
108 }
109 }
110 else if(psm == GS_PSM_CT16 || psm == GS_PSM_T4) {
111 // 4x8 blocks in a page.
112 // block traversing order:
113 // 02..
114 // 13..
115 // 46..
116 // 57..
117 // ....
118 // ....
119 // ....
120 // ....
121 if(widthBlocks <= 1 && heightBlocks <= 2) {
122 widthAlign = 1;
123 heightAlign = 1;
124 }
125 else if(widthBlocks <= 2 && heightBlocks <= 4) {
126 widthAlign = 2;
127 heightAlign = 2;
128 }
129 else if(widthBlocks <= 4 && heightBlocks <= 8) {
130 widthAlign = 4;
131 heightAlign = 4;
132 }
133 else {
134 widthAlign = 4;
135 heightAlign = 8;
136 }
137 }
138 else /* if(psm == GS_PSM_CT16S) */ {
139 // 4x8 blocks in a page.
140 // block traversing order:
141 // 02..
142 // 13..
143 // ....
144 // ....
145 // 46..
146 // 57..
147 // ....
148 // ....
149 if(widthBlocks <= 1 && heightBlocks <= 2) {
150 widthAlign = 1;
151 heightAlign = 1;
152 }
153 else if(widthBlocks <= 2 && heightBlocks <= 2) {
154 widthAlign = 2;
155 heightAlign = 2;
156 }
157 else if(widthBlocks <= 2 && heightBlocks <= 8) {
158 widthAlign = 2;
159 heightAlign = 8;
160 }
161 else {
162 widthAlign = 4;
163 heightAlign = 8;
164 }
165 }
166
167 widthBlocks = (-widthAlign) & (widthBlocks + widthAlign - 1);
168 heightBlocks = (-heightAlign) & (heightBlocks + heightAlign - 1);
169
170 return widthBlocks * heightBlocks * 256;
171}
172
173static inline u8
174from8to5(u8 c, const s8 dither)
175{
176 if((c+dither) > 255)
177 return 255>>3;
178 else if((c+dither) < 0)
179 return 0;
180 else
181 return (c+dither)>>3;
182}
183
184static inline u16
185fromRGBto16(const s8 dither, u8 r, u8 g, u8 b)
186{
187 // A1 B5 G5 R5
188 return 0x8000 | (from8to5(b, dither)<<10) | (from8to5(g, dither)<<5) | from8to5(r, dither);
189}
190
191static inline u16
192from24to16(const s8 dither, u8 *c)
193{
194 return fromRGBto16(dither, c[0], c[1], c[2]);
195}
196
197void gsKit_texture_to_psm16(GSTEXTURE *Texture)
198{
199 int x, y;
200 const s8 dither_matrix[16] = {-4,2,-3,3,0,-2,1,-1,-3,3,-4,2,1,-1,0,-2};
201 size_t size;
202 u16 *pixels16;
203 u8 *pixels24;
204
205 // Only 24bit to 16bit supported
206 if (Texture->PSM != GS_PSM_CT24)
207 return;
208
209 size = Texture->Width * Texture->Height * 2;
210 pixels16 = (u16*)memalign(128, size);
211 pixels24 = (u8 *)Texture->Mem;
212
213 for(y=0; y < Texture->Height; y++) {
214 for(x=0; x < Texture->Width; x++) {
215 int i = y * Texture->Width + x;
216 s8 dither = dither_matrix[(y&3)*4+(x&3)];
217 pixels16[i] = from24to16(dither, &pixels24[i*3]);
218 }
219 }
220
221 free(Texture->Mem);
222 Texture->Mem = (void*)pixels16;
223 Texture->PSM = GS_PSM_CT16S;
224}
225
226void gsKit_texture_send(u32 *mem, int width, int height, u32 tbp, u32 psm, u32 tbw, u8 clut)
227{
228 u64* p_store;
229 u64* p_data;
230 u32* p_mem;
231 int packets;
232 int remain;
233 int qwc;
234 int p_size;
235
236 qwc = gsKit_texture_size_ee(width, height, psm) / 16;
237 if( gsKit_texture_size_ee(width, height, psm) % 16 )
238 {
239#ifdef GSKIT_DEBUG
240 printf("Uneven division of quad word count from VRAM alloc. Rounding up QWC.\n");
241#endif
242 qwc++;
243 }
244
245 packets = qwc / GS_GIF_BLOCKSIZE;
246 remain = qwc % GS_GIF_BLOCKSIZE;
247 p_mem = (u32*)mem;
248
249 if(clut == GS_CLUT_TEXTURE)
250 p_size = (7+(packets * 3)+remain);
251 else
252 p_size = (9+(packets * 3)+remain);
253
254 if(remain > 0)
255 p_size += 2;
256
257 p_store = p_data = memalign(64, (p_size * 16));
258
259 FlushCache(0);
260
261 // DMA DATA
262 *p_data++ = DMA_TAG( 5, 0, DMA_CNT, 0, 0, 0 );
263 *p_data++ = 0;
264
265 *p_data++ = GIF_TAG( 4, 0, 0, 0, GSKIT_GIF_FLG_PACKED, 1 );
266 *p_data++ = GIF_AD;
267
268#ifdef GSKIT_DEBUG
269 if(tbp % 256)
270 printf("ERROR: Texture base pointer not on 256 byte alignment - Modulo = %d\n", tbp % 256);
271#endif
272
273 *p_data++ = GS_SETREG_BITBLTBUF(0, 0, 0, tbp/256, tbw, psm);
274 *p_data++ = GS_BITBLTBUF;
275
276 *p_data++ = GS_SETREG_TRXPOS(0, 0, 0, 0, 0);
277 *p_data++ = GS_TRXPOS;
278
279 *p_data++ = GS_SETREG_TRXREG(width, height);
280 *p_data++ = GS_TRXREG;
281
282 *p_data++ = GS_SETREG_TRXDIR(0);
283 *p_data++ = GS_TRXDIR;
284
285 while (packets-- > 0)
286 {
287 *p_data++ = DMA_TAG( 1, 0, DMA_CNT, 0, 0, 0);
288 *p_data++ = 0;
289 *p_data++ = GIF_TAG( GS_GIF_BLOCKSIZE, 0, 0, 0, GSKIT_GIF_FLG_IMAGE, 0 );
290 *p_data++ = 0;
291 *p_data++ = DMA_TAG( GS_GIF_BLOCKSIZE, 1, DMA_REF, 0, (u32)p_mem, 0 );
292 *p_data++ = 0;
293 p_mem+= (GS_GIF_BLOCKSIZE * 4);
294 }
295
296 if (remain > 0) {
297 *p_data++ = DMA_TAG( 1, 0, DMA_CNT, 0, 0, 0);
298 *p_data++ = 0;
299 *p_data++ = GIF_TAG( remain, 0, 0, 0, GSKIT_GIF_FLG_IMAGE, 0 );
300 *p_data++ = 0;
301 *p_data++ = DMA_TAG( remain, 1, DMA_REF, 0, (u32)p_mem, 0 );
302 *p_data++ = 0;
303 }
304
305 if(clut == GS_CLUT_TEXTURE)
306 {
307 *p_data++ = DMA_TAG( 0, 0, DMA_END, 0, 0, 0 );
308 *p_data++ = 0;
309 }
310 else
311 {
312 *p_data++ = DMA_TAG( 2, 0, DMA_END, 0, 0, 0 );
313 *p_data++ = 0;
314
315 *p_data++ = GIF_TAG( 1, 1, 0, 0, GSKIT_GIF_FLG_PACKED, 1 );
316 *p_data++ = GIF_AD;
317
318 *p_data++ = 0;
319 *p_data++ = GS_TEXFLUSH;
320 }
321
322 // Need to wait first to make sure that if our doublebuffered drawbuffer is still
323 // chugging away we have a safe time to start our transfer.
325 dmaKit_send_chain(DMA_CHANNEL_GIF, p_store, p_size);
326 dmaKit_wait_fast(); //Wait for the DMA transfer to complete, before freeing the GIF packet buffer.
327 free(p_store);
328}
329
330void gsKit_texture_send_inline(GSGLOBAL *gsGlobal, u32 *mem, int width, int height, u32 tbp, u32 psm, u32 tbw, u8 clut)
331{
332 u64* p_data;
333 u32* p_mem;
334 int packets;
335 int remain;
336 int qwc;
337 int dmasize;
338
339 qwc = gsKit_texture_size_ee(width, height, psm) / 16;
340 if( gsKit_texture_size_ee(width, height, psm) % 16 )
341 {
342#ifdef GSKIT_DEBUG
343 printf("Uneven division of quad word count from VRAM alloc. Rounding up QWC.\n");
344#endif
345 qwc++;
346 }
347
348 packets = qwc / GS_GIF_BLOCKSIZE;
349 remain = qwc % GS_GIF_BLOCKSIZE;
350 p_mem = (u32*)mem;
351
352 p_data = gsKit_heap_alloc(gsGlobal, 4, 64, GIF_AD);
353
354 *p_data++ = GIF_TAG_AD(4);
355 *p_data++ = GIF_AD;
356
357#ifdef GSKIT_DEBUG
358 if(tbp % 256)
359 printf("ERROR: Texture base pointer not on 256 byte alignment - Modulo = %d\n", tbp % 256);
360#endif
361
362 *p_data++ = GS_SETREG_BITBLTBUF(0, 0, 0, tbp/256, tbw, psm);
363 *p_data++ = GS_BITBLTBUF;
364
365 *p_data++ = GS_SETREG_TRXPOS(0, 0, 0, 0, 0);
366 *p_data++ = GS_TRXPOS;
367
368 *p_data++ = GS_SETREG_TRXREG(width, height);
369 *p_data++ = GS_TRXREG;
370
371 *p_data++ = GS_SETREG_TRXDIR(0);
372 *p_data++ = GS_TRXDIR;
373
374 dmasize = (packets * 3);
375 if(remain)
376 dmasize += 3;
377
378 p_data = gsKit_heap_alloc_dma(gsGlobal, dmasize, dmasize * 16);
379
380 while (packets-- > 0)
381 {
382 *p_data++ = DMA_TAG( 1, 0, DMA_CNT, 0, 0, 0);
383 *p_data++ = 0;
384 *p_data++ = GIF_TAG( GS_GIF_BLOCKSIZE, 0, 0, 0, GSKIT_GIF_FLG_IMAGE, 0 );
385 *p_data++ = 0;
386 *p_data++ = DMA_TAG( GS_GIF_BLOCKSIZE, 0, DMA_REF, 0, (u32)p_mem, 0 );
387 *p_data++ = 0;
388 p_mem+= (GS_GIF_BLOCKSIZE * 4);
389 }
390
391 if (remain > 0) {
392 *p_data++ = DMA_TAG( 1, 0, DMA_CNT, 0, 0, 0);
393 *p_data++ = 0;
394 *p_data++ = GIF_TAG( remain, 0, 0, 0, GSKIT_GIF_FLG_IMAGE, 0 );
395 *p_data++ = 0;
396 *p_data++ = DMA_TAG( remain, 0, DMA_REF, 0, (u32)p_mem, 0 );
397 *p_data++ = 0;
398 }
399
400 if(clut != GS_CLUT_TEXTURE)
401 {
402 p_data = gsKit_heap_alloc(gsGlobal, 1, 16, GIF_AD);
403
404 *p_data++ = GIF_TAG_AD(1);
405 *p_data++ = GIF_AD;
406
407 *p_data++ = 0;
408 *p_data++ = GS_TEXFLUSH;
409 }
410}
411
412void gsKit_texture_upload(GSGLOBAL *gsGlobal, GSTEXTURE *Texture)
413{
414 gsKit_setup_tbw(Texture);
415
416 if (Texture->PSM == GS_PSM_T8)
417 {
418 gsKit_texture_send(Texture->Mem, Texture->Width, Texture->Height, Texture->Vram, Texture->PSM, Texture->TBW, GS_CLUT_TEXTURE);
419 gsKit_texture_send(Texture->Clut, 16, 16, Texture->VramClut, Texture->ClutPSM, 1, GS_CLUT_PALLETE);
420
421 }
422 else if (Texture->PSM == GS_PSM_T4)
423 {
424 gsKit_texture_send(Texture->Mem, Texture->Width, Texture->Height, Texture->Vram, Texture->PSM, Texture->TBW, GS_CLUT_TEXTURE);
425 gsKit_texture_send(Texture->Clut, 8, 2, Texture->VramClut, Texture->ClutPSM, 1, GS_CLUT_PALLETE);
426 }
427 else
428 {
429 gsKit_texture_send(Texture->Mem, Texture->Width, Texture->Height, Texture->Vram, Texture->PSM, Texture->TBW, GS_CLUT_NONE);
430 }
431}
432
433static inline void gsKit_set_tw_th(const GSTEXTURE *Texture, int *tw, int *th)
434{
435 *tw = 31 - (lzw(Texture->Width) + 1);
436 if(Texture->Width > (1<<*tw))
437 (*tw)++;
438
439 *th = 31 - (lzw(Texture->Height) + 1);
440 if(Texture->Height > (1<<*th))
441 (*th)++;
442}
443void gsKit_prim_sprite_texture_3d(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture,
444 float x1, float y1, int iz1, float u1, float v1,
445 float x2, float y2, int iz2, float u2, float v2, u64 color)
446{
447 u64* p_data;
448 int qsize;
449 int bsize;
450
451 int tw, th;
452
453 int ix1;
454 int ix2;
455 int iy1;
456 int iy2;
457
458 int iu1;
459 int iu2;
460 int iv1;
461 int iv2;
462
464
465 qsize = 4;
466 bsize = 64;
467
468 gsKit_set_tw_th(Texture, &tw, &th);
469
470 ix1 = gsKit_float_to_int_x(gsGlobal, x1);
471 ix2 = gsKit_float_to_int_x(gsGlobal, x2);
472 iy1 = gsKit_float_to_int_y(gsGlobal, y1);
473 iy2 = gsKit_float_to_int_y(gsGlobal, y2);
474
475 iu1 = gsKit_float_to_int_u(Texture, u1);
476 iu2 = gsKit_float_to_int_u(Texture, u2);
477 iv1 = gsKit_float_to_int_v(Texture, v1);
478 iv2 = gsKit_float_to_int_v(Texture, v2);
479
480 p_data = gsKit_heap_alloc(gsGlobal, qsize, bsize, GSKIT_GIF_PRIM_SPRITE_TEXTURED);
481
482 *p_data++ = GIF_TAG_SPRITE_TEXTURED(0);
484
485 if(Texture->VramClut == 0)
486 {
487 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
488 tw, th, gsGlobal->PrimAlphaEnable, 0,
489 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
490 }
491 else
492 {
493 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
494 tw, th, gsGlobal->PrimAlphaEnable, 0,
495 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
496 }
497
498 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 0, 1, gsGlobal->PrimFogEnable,
500 1, gsGlobal->PrimContext, 0);
501
502 *p_data++ = color;
503
504 *p_data++ = GS_SETREG_UV( iu1, iv1 );
505 *p_data++ = GS_SETREG_XYZ2( ix1, iy1, iz1 );
506
507 *p_data++ = GS_SETREG_UV( iu2, iv2 );
508 *p_data++ = GS_SETREG_XYZ2( ix2, iy2, iz2 );
509}
510
511void gsKit_prim_sprite_striped_texture_3d(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture,
512 float x1, float y1, int iz1, float u1, float v1,
513 float x2, float y2, int iz2, float u2, float v2, u64 color)
514{
515 u64* p_data;
516 int qsize;
517 int bsize;
518 int ix1;
519 int ix2;
520 int iy1;
521 int iy2;
522
523 int iv1;
524 int iv2;
525
526 int tw, th;
527
528 u64 Tex0;
529
530 u64 Prim;
531
532 int extracount;
533
534 int stripcount;
535
536 float leftwidth;
537 float rightwidth;
538 float ustripwidth;
539 float leftuwidth;
540 float rightuwidth;
541 float fu1;
542
543 // If you do bilinear on this the results will be a disaster because of bleeding.
545
546 qsize = 4;
547 bsize = 64;
548
549 ix1 = x1;
550 ix2 = x2;
551 iy1 = gsKit_float_to_int_y(gsGlobal, y1);
552 iy2 = gsKit_float_to_int_y(gsGlobal, y2);
553
554 iv1 = gsKit_float_to_int_v(Texture, v1);
555 iv2 = gsKit_float_to_int_v(Texture, v2);
556
557 gsKit_set_tw_th(Texture, &tw, &th);
558
559 if(Texture->VramClut == 0)
560 {
561 Tex0 = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
562 tw, th, gsGlobal->PrimAlphaEnable, 0,
563 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
564 }
565 else
566 {
567 Tex0 = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
568 tw, th, gsGlobal->PrimAlphaEnable, 0,
569 Texture->VramClut/256, Texture->ClutPSM, 0, 0, GS_CLUT_STOREMODE_LOAD);
570 }
571
572 Prim = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 0, 1, gsGlobal->PrimFogEnable,
574 1, gsGlobal->PrimContext, 0);
575
576 ix1 = ((ix1 >> 6) << 6);
577 ix2 = ((ix2 >> 6) << 6);
578
579 extracount = 0;
580 if(((int)x1) % 64)
581 {
582 ix1 += 64;
583 extracount++;
584 }
585 if(((int)x2) % 64)
586 {
587 extracount++;
588 }
589
590 stripcount = ((ix2 - ix1) / 64);
591
592 if(!(stripcount + extracount))
593 {
594 return;
595 }
596
597 leftwidth = ix1 - (float)x1;
598 rightwidth = (float)x2 - ix2;
599
600 leftuwidth = ((leftwidth / (x2-x1)) * (u2 - u1));
601
602 rightuwidth = ((rightwidth / (x2-x1)) * (u2 - u1));
603
604 ustripwidth = ((((u2 - u1) - leftuwidth) - rightuwidth) / stripcount);
605
606 fu1 = 0.0f;
607
608 // This is a lie btw... it's not really A+D mode, but I lie to my allocator so it doesn't screw up the NLOOP arg of the GIFTAG.
609 p_data = gsKit_heap_alloc(gsGlobal, qsize * (stripcount + extracount), bsize * (stripcount + extracount), GIF_AD);
610
611 *p_data++ = GIF_TAG_SPRITE_TEXTURED((stripcount + extracount));
613
614 //printf("stripcount = %d | extracount = %d | ustripwidth = %f | rightwidth = %f\n", stripcount, extracount, ustripwidth, rightwidth);
615
616 if(leftwidth >= 1.0f)
617 {
618 *p_data++ = Tex0;
619 *p_data++ = Prim;
620
621 *p_data++ = color;
622
623 *p_data++ = GS_SETREG_UV( gsKit_float_to_int_u(Texture, u1), iv1 );
624 *p_data++ = GS_SETREG_XYZ2( gsKit_float_to_int_x(gsGlobal, x1), iy1, iz1 );
625
626 fu1 = leftuwidth;
627
628 *p_data++ = GS_SETREG_UV( gsKit_float_to_int_u(Texture, fu1), iv2 );
629 *p_data++ = GS_SETREG_XYZ2( (ix1 << 4) + gsGlobal->OffsetX, iy2, iz2 );
630
631 *p_data++ = 0;
632 }
633
634 while(stripcount--)
635 {
636 *p_data++ = Tex0;
637 *p_data++ = Prim;
638
639 *p_data++ = color;
640
641 *p_data++ = GS_SETREG_UV( gsKit_float_to_int_u(Texture, fu1), iv1 );
642 *p_data++ = GS_SETREG_XYZ2( (ix1 << 4) + gsGlobal->OffsetX, iy1, iz1 );
643
644 fu1 += ustripwidth;
645 ix1 += 64;
646
647 *p_data++ = GS_SETREG_UV( gsKit_float_to_int_u(Texture, fu1), iv2 );
648 *p_data++ = GS_SETREG_XYZ2( (ix1 << 4) + gsGlobal->OffsetX, iy2, iz2 );
649
650 *p_data++ = 0;
651 }
652
653
654 if(rightwidth > 0.0f)
655 {
656
657 *p_data++ = Tex0;
658 *p_data++ = Prim;
659
660 *p_data++ = color;
661
662 *p_data++ = GS_SETREG_UV( gsKit_float_to_int_u(Texture, fu1), iv1 );
663 *p_data++ = GS_SETREG_XYZ2( (ix1 << 4) + gsGlobal->OffsetX, iy1, iz1 );
664
665 fu1 += rightuwidth;
666 rightwidth += ix1;
667
668 *p_data++ = GS_SETREG_UV( gsKit_float_to_int_u(Texture, fu1), iv2 );
669 *p_data++ = GS_SETREG_XYZ2( gsKit_float_to_int_x(gsGlobal, rightwidth), iy2, iz2 );
670
671 *p_data++ = 0;
672
673 }
674}
675
676void gskit_prim_list_sprite_texture_uv_3d(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture, int count, const GSPRIMUVPOINT *vertices)
677{
678 u64* p_data;
679 u64* p_store;
680 int tw, th;
681
682 int qsize = (count*3) + 2;
683 int bytes = count * sizeof(GSPRIMUVPOINT);
684
686 gsKit_set_tw_th(Texture, &tw, &th);
687
688 p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD);
689
690 if(p_store == gsGlobal->CurQueue->last_tag)
691 {
692 *p_data++ = GIF_TAG_AD(qsize);
693 *p_data++ = GIF_AD;
694 }
695
696 if(Texture->VramClut == 0)
697 {
698 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
699 tw, th, gsGlobal->PrimAlphaEnable, 0,
700 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
701 }
702 else
703 {
704 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
705 tw, th, gsGlobal->PrimAlphaEnable, 0,
706 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
707 }
708 *p_data++ = GS_TEX0_1 + gsGlobal->PrimContext;
709
710 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 1, 1, gsGlobal->PrimFogEnable,
712 1, gsGlobal->PrimContext, 0);
713
714 *p_data++ = GS_PRIM;
715
716 memcpy(p_data, vertices, bytes);
717}
718
719void gskit_prim_list_sprite_texture_uv_flat(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture, int count, const u128 *flatContent)
720{
721 u64* p_data;
722 u64* p_store;
723 int tw, th;
724
725 int qsize = (count) + 2;
726 int bytes = count * sizeof(u128);
727
729 gsKit_set_tw_th(Texture, &tw, &th);
730
731 p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD);
732
733 if(p_store == gsGlobal->CurQueue->last_tag)
734 {
735 *p_data++ = GIF_TAG_AD(qsize);
736 *p_data++ = GIF_AD;
737 }
738
739 if(Texture->VramClut == 0)
740 {
741 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
742 tw, th, gsGlobal->PrimAlphaEnable, 0,
743 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
744 }
745 else
746 {
747 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
748 tw, th, gsGlobal->PrimAlphaEnable, 0,
749 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
750 }
751 *p_data++ = GS_TEX0_1 + gsGlobal->PrimContext;
752
753 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 0, 1, gsGlobal->PrimFogEnable,
755 1, gsGlobal->PrimContext, 0);
756
757 *p_data++ = GS_PRIM;
758
759 memcpy(p_data, flatContent, bytes);
760}
761
762void gskit_prim_list_sprite_texture_uv_flat_color(GSGLOBAL *gsGlobal, const GSTEXTURE *Texture, gs_rgbaq color, int count, const GSPRIMUVPOINTFLAT *vertices)
763{
764 u64* p_data;
765 u64* p_store;
766 int tw, th;
767
768 int qsize = (count * 2) + 3;
769 int bytes = count * sizeof(GSPRIMUVPOINTFLAT);
770
772 gsKit_set_tw_th(Texture, &tw, &th);
773
774 p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD);
775
776 if(p_store == gsGlobal->CurQueue->last_tag)
777 {
778 *p_data++ = GIF_TAG_AD(qsize);
779 *p_data++ = GIF_AD;
780 }
781
782 if(Texture->VramClut == 0)
783 {
784 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
785 tw, th, gsGlobal->PrimAlphaEnable, 0,
786 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
787 }
788 else
789 {
790 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
791 tw, th, gsGlobal->PrimAlphaEnable, 0,
792 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
793 }
794 *p_data++ = GS_TEX0_1 + gsGlobal->PrimContext;
795
796 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_SPRITE, 0, 1, gsGlobal->PrimFogEnable,
798 1, gsGlobal->PrimContext, 0);
799
800 *p_data++ = GS_PRIM;
801
802 // Copy color
803 memcpy(p_data, &color, sizeof(gs_rgbaq));
804 p_data += 2; // Advance 2 u64, which is 16 bytes the gs_rgbaq struct size
805 // Copy vertices
806 memcpy(p_data, vertices, bytes);
807}
808
809
810void gsKit_prim_triangle_texture_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture,
811 float x1, float y1, int iz1, float u1, float v1,
812 float x2, float y2, int iz2, float u2, float v2,
813 float x3, float y3, int iz3, float u3, float v3, u64 color)
814{
815 u64* p_data;
816
817 int qsize;
818 int bsize;
819
820 int tw, th;
821
822 int ix1;
823 int ix2;
824 int ix3;
825 int iy1;
826 int iy2;
827 int iy3;
828
829 int iu1;
830 int iu2;
831 int iu3;
832 int iv1;
833 int iv2;
834 int iv3;
835
837 qsize = 5;
838 bsize = 80;
839
840 gsKit_set_tw_th(Texture, &tw, &th);
841
842 ix1 = gsKit_float_to_int_x(gsGlobal, x1);
843 ix2 = gsKit_float_to_int_x(gsGlobal, x2);
844 ix3 = gsKit_float_to_int_x(gsGlobal, x3);
845 iy1 = gsKit_float_to_int_y(gsGlobal, y1);
846 iy2 = gsKit_float_to_int_y(gsGlobal, y2);
847 iy3 = gsKit_float_to_int_y(gsGlobal, y3);
848
849 iu1 = gsKit_float_to_int_u(Texture, u1);
850 iu2 = gsKit_float_to_int_u(Texture, u2);
851 iu3 = gsKit_float_to_int_u(Texture, u3);
852 iv1 = gsKit_float_to_int_v(Texture, v1);
853 iv2 = gsKit_float_to_int_v(Texture, v2);
854 iv3 = gsKit_float_to_int_v(Texture, v3);
855
856 p_data = gsKit_heap_alloc(gsGlobal, qsize, bsize, GSKIT_GIF_PRIM_TRIANGLE_TEXTURED);
857
858 *p_data++ = GIF_TAG_TRIANGLE_TEXTURED(0);
860
861 if(Texture->VramClut == 0)
862 {
863 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
864 tw, th, gsGlobal->PrimAlphaEnable, 0,
865 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
866 }
867 else
868 {
869 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
870 tw, th, gsGlobal->PrimAlphaEnable, 0,
871 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
872 }
873
874 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRIANGLE, 0, 1, gsGlobal->PrimFogEnable,
876 1, gsGlobal->PrimContext, 0);
877
878
879 *p_data++ = color;
880
881 *p_data++ = GS_SETREG_UV( iu1, iv1 );
882 *p_data++ = GS_SETREG_XYZ2( ix1, iy1, iz1 );
883
884 *p_data++ = GS_SETREG_UV( iu2, iv2 );
885 *p_data++ = GS_SETREG_XYZ2( ix2, iy2, iz2 );
886
887 *p_data++ = GS_SETREG_UV( iu3, iv3 );
888 *p_data++ = GS_SETREG_XYZ2( ix3, iy3, iz3 );
889}
890
891void gsKit_prim_triangle_goraud_texture_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture,
892 float x1, float y1, int iz1, float u1, float v1,
893 float x2, float y2, int iz2, float u2, float v2,
894 float x3, float y3, int iz3, float u3, float v3,
895 u64 color1, u64 color2, u64 color3)
896{
897 u64* p_data;
898
899 int qsize;
900 int bsize;
901
902 int tw, th;
903
904 int ix1;
905 int ix2;
906 int ix3;
907 int iy1;
908 int iy2;
909 int iy3;
910
911 int iu1;
912 int iu2;
913 int iu3;
914 int iv1;
915 int iv2;
916 int iv3;
917
919 qsize = 6;
920 bsize = 96;
921
922 gsKit_set_tw_th(Texture, &tw, &th);
923
924 ix1 = gsKit_float_to_int_x(gsGlobal, x1);
925 ix2 = gsKit_float_to_int_x(gsGlobal, x2);
926 ix3 = gsKit_float_to_int_x(gsGlobal, x3);
927 iy1 = gsKit_float_to_int_y(gsGlobal, y1);
928 iy2 = gsKit_float_to_int_y(gsGlobal, y2);
929 iy3 = gsKit_float_to_int_y(gsGlobal, y3);
930
931 iu1 = gsKit_float_to_int_u(Texture, u1);
932 iu2 = gsKit_float_to_int_u(Texture, u2);
933 iu3 = gsKit_float_to_int_u(Texture, u3);
934 iv1 = gsKit_float_to_int_v(Texture, v1);
935 iv2 = gsKit_float_to_int_v(Texture, v2);
936 iv3 = gsKit_float_to_int_v(Texture, v3);
937
938 p_data = gsKit_heap_alloc(gsGlobal, qsize, bsize, GSKIT_GIF_PRIM_TRIANGLE_TEXTURED);
939
942
943 if(Texture->VramClut == 0)
944 {
945 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
946 tw, th, gsGlobal->PrimAlphaEnable, 0,
947 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
948 }
949 else
950 {
951 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
952 tw, th, gsGlobal->PrimAlphaEnable, 0,
953 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
954 }
955
956 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRIANGLE, 1, 1, gsGlobal->PrimFogEnable,
958 1, gsGlobal->PrimContext, 0);
959
960
961 *p_data++ = color1;
962 *p_data++ = GS_SETREG_UV( iu1, iv1 );
963 *p_data++ = GS_SETREG_XYZ2( ix1, iy1, iz1 );
964
965 *p_data++ = color2;
966 *p_data++ = GS_SETREG_UV( iu2, iv2 );
967 *p_data++ = GS_SETREG_XYZ2( ix2, iy2, iz2 );
968
969 *p_data++ = color3;
970 *p_data++ = GS_SETREG_UV( iu3, iv3 );
971 *p_data++ = GS_SETREG_XYZ2( ix3, iy3, iz3 );
972}
973
974void gsKit_prim_list_triangle_goraud_texture_uv_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture, int count, const GSPRIMUVPOINT *vertices)
975{
976 u64* p_data;
977 u64* p_store;
978 int tw, th;
979
980 int qsize = (count*3) + 2;
981 int bytes = count * sizeof(GSPRIMUVPOINT);
982
984 gsKit_set_tw_th(Texture, &tw, &th);
985
986 p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD);
987
988 if(p_store == gsGlobal->CurQueue->last_tag)
989 {
990 *p_data++ = GIF_TAG_AD(qsize);
991 *p_data++ = GIF_AD;
992 }
993
994 if(Texture->VramClut == 0)
995 {
996 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
997 tw, th, gsGlobal->PrimAlphaEnable, 0,
998 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
999 }
1000 else
1001 {
1002 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1003 tw, th, gsGlobal->PrimAlphaEnable, 0,
1004 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
1005 }
1006 *p_data++ = GS_TEX0_1 + gsGlobal->PrimContext;
1007
1008 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRIANGLE, 1, 1, gsGlobal->PrimFogEnable,
1010 1, gsGlobal->PrimContext, 0);
1011
1012 *p_data++ = GS_PRIM;
1013
1014 memcpy(p_data, vertices, bytes);
1015}
1016
1017void gsKit_prim_list_triangle_goraud_texture_stq_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture, int count, const GSPRIMSTQPOINT *vertices)
1018{
1019 u64* p_data;
1020 u64* p_store;
1021 int tw, th;
1022
1023 int qsize = (count*3) + 2;
1024 int bytes = count * sizeof(GSPRIMSTQPOINT);
1025
1027 gsKit_set_tw_th(Texture, &tw, &th);
1028
1029 p_store = p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize*16), GIF_AD);
1030
1031 if(p_store == gsGlobal->CurQueue->last_tag)
1032 {
1033 *p_data++ = GIF_TAG_AD(qsize);
1034 *p_data++ = GIF_AD;
1035 }
1036
1037 if(Texture->VramClut == 0)
1038 {
1039 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1040 tw, th, gsGlobal->PrimAlphaEnable, 0,
1041 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
1042 }
1043 else
1044 {
1045 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1046 tw, th, gsGlobal->PrimAlphaEnable, 0,
1047 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
1048 }
1049 *p_data++ = GS_TEX0_1 + gsGlobal->PrimContext;
1050
1051 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRIANGLE, 1, 1, gsGlobal->PrimFogEnable,
1053 0, gsGlobal->PrimContext, 0);
1054
1055 *p_data++ = GS_PRIM;
1056
1057 memcpy(p_data, vertices, bytes);
1058}
1059
1060void gsKit_prim_triangle_strip_texture(GSGLOBAL *gsGlobal, GSTEXTURE *Texture,
1061 float *TriStrip, int segments, int iz, u64 color)
1062{
1063 u64* p_data;
1064
1065 int qsize;
1066 int count;
1067 int vertexdata[segments*4];
1068
1069 int tw, th;
1070
1072 qsize = 3 + (segments * 2);
1073
1074 gsKit_set_tw_th(Texture, &tw, &th);
1075
1076 for(count = 0; count < (segments * 4); count+=4)
1077 {
1078 vertexdata[count+0] = gsKit_float_to_int_x(gsGlobal, *TriStrip++);
1079 vertexdata[count+1] = gsKit_float_to_int_y(gsGlobal, *TriStrip++);
1080 vertexdata[count+2] = gsKit_float_to_int_u(Texture, *TriStrip++);
1081 vertexdata[count+3] = gsKit_float_to_int_v(Texture, *TriStrip++);
1082 }
1083
1084 p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize * 16), GIF_AD);
1085
1086 *p_data++ = GIF_TAG_AD(qsize);
1087 *p_data++ = GIF_AD;
1088
1089 if(Texture->VramClut == 0)
1090 {
1091 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1092 tw, th, gsGlobal->PrimAlphaEnable, 0,
1093 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
1094 }
1095 else
1096 {
1097 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1098 tw, th, gsGlobal->PrimAlphaEnable, 0,
1099 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
1100 }
1101 *p_data++ = GS_TEX0_1+gsGlobal->PrimContext;
1102
1103 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRISTRIP, 0, 1, gsGlobal->PrimFogEnable,
1105 1, gsGlobal->PrimContext, 0);
1106
1107 *p_data++ = GS_PRIM;
1108
1109 *p_data++ = color;
1110 *p_data++ = GS_RGBAQ;
1111
1112 for(count = 0; count < (segments * 4); count+=4)
1113 {
1114 *p_data++ = GS_SETREG_UV( vertexdata[count+2], vertexdata[count+3] );
1115 *p_data++ = GS_UV;
1116
1117 *p_data++ = GS_SETREG_XYZ2( vertexdata[count], vertexdata[count+1], iz );
1118 *p_data++ = GS_XYZ2;
1119 }
1120}
1121
1122void gsKit_prim_triangle_strip_texture_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture,
1123 float *TriStrip, int segments, u64 color)
1124{
1125 u64* p_data;
1126
1127 int qsize;
1128 int count;
1129 int vertexdata[segments*5];
1130
1131 int tw, th;
1132
1134 qsize = 3 + (segments * 2);
1135
1136 gsKit_set_tw_th(Texture, &tw, &th);
1137
1138 for(count = 0; count < (segments * 5); count+=5)
1139 {
1140 vertexdata[count+0] = gsKit_float_to_int_x(gsGlobal, *TriStrip++);
1141 vertexdata[count+1] = gsKit_float_to_int_y(gsGlobal, *TriStrip++);
1142 vertexdata[count+2] = (int)((*TriStrip++) * 16.0f); // z
1143 vertexdata[count+3] = gsKit_float_to_int_u(Texture, *TriStrip++);
1144 vertexdata[count+4] = gsKit_float_to_int_v(Texture, *TriStrip++);
1145 }
1146
1147 p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize * 16), GIF_AD);
1148
1149 *p_data++ = GIF_TAG_AD(qsize);
1150 *p_data++ = GIF_AD;
1151
1152 if(Texture->VramClut == 0)
1153 {
1154 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1155 tw, th, gsGlobal->PrimAlphaEnable, 0,
1156 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
1157 }
1158 else
1159 {
1160 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1161 tw, th, gsGlobal->PrimAlphaEnable, 0,
1162 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
1163 }
1164 *p_data++ = GS_TEX0_1+gsGlobal->PrimContext;
1165
1166 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRISTRIP, 0, 1, gsGlobal->PrimFogEnable,
1168 1, gsGlobal->PrimContext, 0);
1169
1170 *p_data++ = GS_PRIM;
1171
1172 *p_data++ = color;
1173 *p_data++ = GS_RGBAQ;
1174
1175 for(count = 0; count < (segments * 5); count+=5)
1176 {
1177 *p_data++ = GS_SETREG_UV( vertexdata[count+3], vertexdata[count+4] );
1178 *p_data++ = GS_UV;
1179
1180 *p_data++ = GS_SETREG_XYZ2( vertexdata[count], vertexdata[count+1], vertexdata[count+2] );
1181 *p_data++ = GS_XYZ2;
1182 }
1183}
1184
1185void gsKit_prim_triangle_fan_texture(GSGLOBAL *gsGlobal, GSTEXTURE *Texture,
1186 float *TriFan, int verticies, int iz, u64 color)
1187{
1188 u64* p_data;
1189
1190 int qsize;
1191 int count;
1192 int vertexdata[verticies*4];
1193
1194 int tw, th;
1195
1197 qsize = 3 + (verticies * 2);
1198
1199 gsKit_set_tw_th(Texture, &tw, &th);
1200
1201 for(count = 0; count < (verticies * 4); count+=4)
1202 {
1203 vertexdata[count+0] = gsKit_float_to_int_x(gsGlobal, *TriFan++);
1204 vertexdata[count+1] = gsKit_float_to_int_y(gsGlobal, *TriFan++);
1205 vertexdata[count+2] = gsKit_float_to_int_u(Texture, *TriFan++);
1206 vertexdata[count+3] = gsKit_float_to_int_v(Texture, *TriFan++);
1207 }
1208
1209 p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize * 16), GIF_AD);
1210
1211 *p_data++ = GIF_TAG_AD(qsize);
1212 *p_data++ = GIF_AD;
1213
1214 if(Texture->VramClut == 0)
1215 {
1216 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1217 tw, th, gsGlobal->PrimAlphaEnable, 0,
1218 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
1219 }
1220 else
1221 {
1222 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1223 tw, th, gsGlobal->PrimAlphaEnable, 0,
1224 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
1225 }
1226 *p_data++ = GS_TEX0_1+gsGlobal->PrimContext;
1227
1228 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRIFAN, 0, 1, gsGlobal->PrimFogEnable,
1230 1, gsGlobal->PrimContext, 0);
1231
1232 *p_data++ = GS_PRIM;
1233
1234 *p_data++ = color;
1235 *p_data++ = GS_RGBAQ;
1236
1237 for(count = 0; count < (verticies * 4); count+=4)
1238 {
1239 *p_data++ = GS_SETREG_UV( vertexdata[count+2], vertexdata[count+3] );
1240 *p_data++ = GS_UV;
1241
1242 *p_data++ = GS_SETREG_XYZ2( vertexdata[count], vertexdata[count+1], iz );
1243 *p_data++ = GS_XYZ2;
1244 }
1245}
1246
1247void gsKit_prim_triangle_fan_texture_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture,
1248 float *TriFan, int verticies, u64 color)
1249{
1250 u64* p_data;
1251 int qsize;
1252 int count;
1253 int vertexdata[verticies*5];
1254
1255 int tw, th;
1256
1258 qsize = 3 + (verticies * 2);
1259
1260 gsKit_set_tw_th(Texture, &tw, &th);
1261
1262 for(count = 0; count < (verticies * 5); count+=5)
1263 {
1264 vertexdata[count+0] = gsKit_float_to_int_x(gsGlobal, *TriFan++);
1265 vertexdata[count+1] = gsKit_float_to_int_y(gsGlobal, *TriFan++);
1266 vertexdata[count+2] = (int)((*TriFan++) * 16.0f); // z
1267 vertexdata[count+3] = gsKit_float_to_int_u(Texture, *TriFan++);
1268 vertexdata[count+4] = gsKit_float_to_int_v(Texture, *TriFan++);
1269 }
1270
1271 p_data = gsKit_heap_alloc(gsGlobal, qsize, (qsize * 16), GIF_AD);
1272
1273 *p_data++ = GIF_TAG_AD(qsize);
1274 *p_data++ = GIF_AD;
1275
1276 if(Texture->VramClut == 0)
1277 {
1278 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1279 tw, th, gsGlobal->PrimAlphaEnable, 0,
1280 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
1281 }
1282 else
1283 {
1284 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1285 tw, th, gsGlobal->PrimAlphaEnable, 0,
1286 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
1287 }
1288 *p_data++ = GS_TEX0_1+gsGlobal->PrimContext;
1289
1290 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRIFAN, 0, 1, gsGlobal->PrimFogEnable,
1292 1, gsGlobal->PrimContext, 0);
1293
1294 *p_data++ = GS_PRIM;
1295
1296 *p_data++ = color;
1297 *p_data++ = GS_RGBAQ;
1298
1299 for(count = 0; count < (verticies * 5); count+=5)
1300 {
1301 *p_data++ = GS_SETREG_UV( vertexdata[count+3], vertexdata[count+4] );
1302 *p_data++ = GS_UV;
1303
1304 *p_data++ = GS_SETREG_XYZ2( vertexdata[count], vertexdata[count+1], vertexdata[count+2] );
1305 *p_data++ = GS_XYZ2;
1306 }
1307}
1308
1309void gsKit_prim_quad_texture_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture,
1310 float x1, float y1, int iz1, float u1, float v1,
1311 float x2, float y2, int iz2, float u2, float v2,
1312 float x3, float y3, int iz3, float u3, float v3,
1313 float x4, float y4, int iz4, float u4, float v4, u64 color)
1314{
1315 u64* p_data;
1316
1317 int qsize;
1318 int bsize;
1319
1320 int tw, th;
1321
1322 int ix1;
1323 int ix2;
1324 int ix3;
1325 int ix4;
1326 int iy1;
1327 int iy2;
1328 int iy3;
1329 int iy4;
1330
1331 int iu1;
1332 int iu2;
1333 int iu3;
1334 int iu4;
1335 int iv1;
1336 int iv2;
1337 int iv3;
1338 int iv4;
1339
1341
1342 qsize = 6;
1343 bsize = 96;
1344
1345 gsKit_set_tw_th(Texture, &tw, &th);
1346
1347 ix1 = gsKit_float_to_int_x(gsGlobal, x1);
1348 ix2 = gsKit_float_to_int_x(gsGlobal, x2);
1349 ix3 = gsKit_float_to_int_x(gsGlobal, x3);
1350 ix4 = gsKit_float_to_int_x(gsGlobal, x4);
1351 iy1 = gsKit_float_to_int_y(gsGlobal, y1);
1352 iy2 = gsKit_float_to_int_y(gsGlobal, y2);
1353 iy3 = gsKit_float_to_int_y(gsGlobal, y3);
1354 iy4 = gsKit_float_to_int_y(gsGlobal, y4);
1355
1356 iu1 = gsKit_float_to_int_u(Texture, u1);
1357 iu2 = gsKit_float_to_int_u(Texture, u2);
1358 iu3 = gsKit_float_to_int_u(Texture, u3);
1359 iu4 = gsKit_float_to_int_u(Texture, u4);
1360 iv1 = gsKit_float_to_int_v(Texture, v1);
1361 iv2 = gsKit_float_to_int_v(Texture, v2);
1362 iv3 = gsKit_float_to_int_v(Texture, v3);
1363 iv4 = gsKit_float_to_int_v(Texture, v4);
1364
1365 p_data = gsKit_heap_alloc(gsGlobal, qsize, bsize, GSKIT_GIF_PRIM_QUAD_TEXTURED);
1366
1367 *p_data++ = GIF_TAG_QUAD_TEXTURED(0);
1369
1370 if(Texture->VramClut == 0)
1371 {
1372 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1373 tw, th, gsGlobal->PrimAlphaEnable, 0,
1374 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
1375 }
1376 else
1377 {
1378 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1379 tw, th, gsGlobal->PrimAlphaEnable, 0,
1380 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
1381 }
1382
1383 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRISTRIP, 0, 1, gsGlobal->PrimFogEnable,
1385 1, gsGlobal->PrimContext, 0);
1386
1387 *p_data++ = color;
1388
1389 *p_data++ = GS_SETREG_UV( iu1, iv1 );
1390 *p_data++ = GS_SETREG_XYZ2( ix1, iy1, iz1 );
1391
1392 *p_data++ = GS_SETREG_UV( iu2, iv2 );
1393 *p_data++ = GS_SETREG_XYZ2( ix2, iy2, iz2 );
1394
1395 *p_data++ = GS_SETREG_UV( iu3, iv3 );
1396 *p_data++ = GS_SETREG_XYZ2( ix3, iy3, iz3 );
1397
1398 *p_data++ = GS_SETREG_UV( iu4, iv4 );
1399 *p_data++ = GS_SETREG_XYZ2( ix4, iy4, iz4 );
1400}
1401
1402void gsKit_prim_quad_goraud_texture_3d(GSGLOBAL *gsGlobal, GSTEXTURE *Texture,
1403 float x1, float y1, int iz1, float u1, float v1,
1404 float x2, float y2, int iz2, float u2, float v2,
1405 float x3, float y3, int iz3, float u3, float v3,
1406 float x4, float y4, int iz4, float u4, float v4,
1407 u64 color1, u64 color2, u64 color3, u64 color4)
1408{
1409 u64* p_data;
1410 int qsize;
1411 int bsize;
1412
1413 int tw, th;
1414
1415 int ix1;
1416 int ix2;
1417 int ix3;
1418 int ix4;
1419 int iy1;
1420 int iy2;
1421 int iy3;
1422 int iy4;
1423
1424 int iu1;
1425 int iu2;
1426 int iu3;
1427 int iu4;
1428 int iv1;
1429 int iv2;
1430 int iv3;
1431 int iv4;
1432
1434
1435 qsize = 7;
1436 bsize = 112;
1437
1438 gsKit_set_tw_th(Texture, &tw, &th);
1439
1440 ix1 = gsKit_float_to_int_x(gsGlobal, x1);
1441 ix2 = gsKit_float_to_int_x(gsGlobal, x2);
1442 ix3 = gsKit_float_to_int_x(gsGlobal, x3);
1443 ix4 = gsKit_float_to_int_x(gsGlobal, x4);
1444 iy1 = gsKit_float_to_int_y(gsGlobal, y1);
1445 iy2 = gsKit_float_to_int_y(gsGlobal, y2);
1446 iy3 = gsKit_float_to_int_y(gsGlobal, y3);
1447 iy4 = gsKit_float_to_int_y(gsGlobal, y4);
1448
1449 iu1 = gsKit_float_to_int_u(Texture, u1);
1450 iu2 = gsKit_float_to_int_u(Texture, u2);
1451 iu3 = gsKit_float_to_int_u(Texture, u3);
1452 iu4 = gsKit_float_to_int_u(Texture, u4);
1453 iv1 = gsKit_float_to_int_v(Texture, v1);
1454 iv2 = gsKit_float_to_int_v(Texture, v2);
1455 iv3 = gsKit_float_to_int_v(Texture, v3);
1456 iv4 = gsKit_float_to_int_v(Texture, v4);
1457
1458 p_data = gsKit_heap_alloc(gsGlobal, qsize, bsize, GSKIT_GIF_PRIM_QUAD_TEXTURED);
1459
1460 *p_data++ = GIF_TAG_QUAD_GORAUD_TEXTURED(0);
1462
1463 if(Texture->VramClut == 0)
1464 {
1465 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1466 tw, th, gsGlobal->PrimAlphaEnable, 0,
1467 0, 0, 0, 0, GS_CLUT_STOREMODE_NOLOAD);
1468 }
1469 else
1470 {
1471 *p_data++ = GS_SETREG_TEX0(Texture->Vram/256, Texture->TBW, Texture->PSM,
1472 tw, th, gsGlobal->PrimAlphaEnable, 0,
1473 Texture->VramClut/256, Texture->ClutPSM, Texture->ClutStorageMode, 0, GS_CLUT_STOREMODE_LOAD);
1474 }
1475
1476 *p_data++ = GS_SETREG_PRIM( GS_PRIM_PRIM_TRISTRIP, 1, 1, gsGlobal->PrimFogEnable,
1478 1, gsGlobal->PrimContext, 0);
1479
1480 *p_data++ = color1;
1481 *p_data++ = GS_SETREG_UV( iu1, iv1 );
1482 *p_data++ = GS_SETREG_XYZ2( ix1, iy1, iz1 );
1483
1484 *p_data++ = color2;
1485 *p_data++ = GS_SETREG_UV( iu2, iv2 );
1486 *p_data++ = GS_SETREG_XYZ2( ix2, iy2, iz2 );
1487
1488 *p_data++ = color3;
1489 *p_data++ = GS_SETREG_UV( iu3, iv3 );
1490 *p_data++ = GS_SETREG_XYZ2( ix3, iy3, iz3 );
1491
1492 *p_data++ = color4;
1493 *p_data++ = GS_SETREG_UV( iu4, iv4 );
1494 *p_data++ = GS_SETREG_XYZ2( ix4, iy4, iz4 );
1495}
void dmaKit_wait_fast(void)
Definition dmaCore.c:45
void dmaKit_send_chain(u16 channel, void *data, u32 size)
Definition dmaCore.c:135
void gsKit_set_texfilter(GSGLOBAL *gsGlobal, u8 FilterMode)
Sets the Texture Filtering Parameters.
Definition gsCore.c:376
#define GS_FILTER_NEAREST
Use simple filtering (nearest neighbor).
Definition gsCore.h:71
#define GS_GIF_BLOCKSIZE
GS GIF Data Transfer Blocksize.
Definition gsCore.h:32
#define GIF_TAG_AD(NLOOP)
A+D GIFTAG.
Definition gsInit.h:308
#define GS_PRIM
GS Primitive.
Definition gsInit.h:156
#define GS_PSM_CT32
R8 G8 B8 A8 (RGBA32) Texture.
Definition gsInit.h:115
#define GS_PSM_T8
8 Bit Texture with CLUT
Definition gsInit.h:123
#define GS_TRXDIR
GS Activation for Transmission Between Buffers.
Definition gsInit.h:254
#define GIF_TAG_SPRITE_TEXTURED_REGS(ctx)
Textured Sprite Primitive REGLIST.
Definition gsInit.h:409
#define GS_PSM_CT16S
RGBA16 Texture ?
Definition gsInit.h:121
#define GIF_TAG_QUAD_GORAUD_TEXTURED(NLOOP)
Textured Quad Goraud Primitive GIFTAG.
Definition gsInit.h:473
#define GS_SETREG_XYZ2
GS Vertex Value Object Creation Macro.
Definition gsInit.h:590
#define GS_XYZ2
GS Vertex Coordinate Value.
Definition gsInit.h:166
#define GS_PSM_T4
4 Bit Texture with CLUT
Definition gsInit.h:127
#define GS_PRIM_PRIM_TRIANGLE
GS Triangle Primitive.
Definition gsInit.h:273
#define GS_RGBAQ
GS Color in RGBAQ Format.
Definition gsInit.h:158
#define GIF_TAG_TRIANGLE_GORAUD_TEXTURED(NLOOP)
Textured Triangle Goraud Primitive GIFTAG.
Definition gsInit.h:455
#define GS_TRXREG
GS Specificiation for Transmission Area in Buffers.
Definition gsInit.h:252
#define GIF_TAG(NLOOP, EOP, PRE, PRIM, FLG, NREG)
DMA Packet Header "GIF Tag" For Packets Sent To GIF.
Definition gsInit.h:570
#define GIF_TAG_TRIANGLE_TEXTURED(NLOOP)
Textured Triangle Primitive GIFTAG.
Definition gsInit.h:421
#define GS_PSM_CT24
R8 G8 B8 (RGB24) Texture.
Definition gsInit.h:117
#define GS_BITBLTBUF
GS Setting for Transmission Between Buffers.
Definition gsInit.h:248
#define GS_UV
GS Texture Coordinate Value in Texel Coordinates.
Definition gsInit.h:162
#define GS_TEX0_1
GS Texture Information Settings (Context 1).
Definition gsInit.h:168
#define GIF_TAG_TRIANGLE_GORAUD_TEXTURED_REGS(ctx)
Textured Triangle Goraud Primitive REGLIST.
Definition gsInit.h:457
#define GS_TRXPOS
GS Specificiation for Transmission Area in Buffers.
Definition gsInit.h:250
#define GIF_AD
GIF_TAG Address+Data Setting. (Used after GIF_TAG).
Definition gsInit.h:494
#define GS_TEXFLUSH
GS Texture Page Buffer.
Definition gsInit.h:214
#define GIF_TAG_SPRITE_TEXTURED(NLOOP)
Textured Sprite Primitive GIFTAG.
Definition gsInit.h:407
#define GIF_TAG_TRIANGLE_TEXTURED_REGS(ctx)
Textured Triangle Primitive REGLIST.
Definition gsInit.h:423
#define GIF_TAG_QUAD_GORAUD_TEXTURED_REGS(ctx)
Textured Quad Goraud Primitive REGLIST.
Definition gsInit.h:475
#define GIF_TAG_QUAD_TEXTURED_REGS(ctx)
Textured Quad Primitive REGLIST.
Definition gsInit.h:439
#define GS_PRIM_PRIM_SPRITE
GS Sprite Primitive.
Definition gsInit.h:279
#define GIF_TAG_QUAD_TEXTURED(NLOOP)
Textured Quad Primitive GIFTAG.
Definition gsInit.h:437
#define GS_PRIM_PRIM_TRIFAN
GS Triangle Fan Primitive.
Definition gsInit.h:277
#define GS_PRIM_PRIM_TRISTRIP
GS Triangle Strip Primitive.
Definition gsInit.h:275
#define GS_PSM_CT16
RGBA16 Texture.
Definition gsInit.h:119
#define GSKIT_GIF_FLG_PACKED
gsKit GIFTAG data format "FLG"
Definition gsInit.h:299
int PrimAlphaEnable
Primitive Alpha Blending Enable.
Definition gsInit.h:945
int PrimContext
Primitive Context.
Definition gsInit.h:942
GSQUEUE * CurQueue
Draw Queue (Current).
Definition gsInit.h:934
int OffsetX
X Window Offset.
Definition gsInit.h:921
int PrimFogEnable
Primitive Fog Enable.
Definition gsInit.h:943
int PrimAAEnable
Primitive AntiAlaising Enable.
Definition gsInit.h:944
void * last_tag
Pointer to the GIF_TAG of the last object in this draw queue.
Definition gsInit.h:863
u32 * Clut
EE CLUT Memory Pointer.
Definition gsInit.h:962
u32 TBW
Texture Base Width.
Definition gsInit.h:960
u32 * Mem
EE Memory Pointer.
Definition gsInit.h:961
u8 ClutStorageMode
CLUT Storage Mode.
Definition gsInit.h:966
u32 Vram
GS VRAM Memory Pointer.
Definition gsInit.h:963
u32 VramClut
GS VRAM CLUT Memory Pointer.
Definition gsInit.h:964
u8 ClutPSM
CLUT Pixel Storage Method (Color Format).
Definition gsInit.h:959
u8 PSM
Pixel Storage Method (Color Format).
Definition gsInit.h:958
u32 Height
Height of the Texture.
Definition gsInit.h:957
u32 Width
Width of the Texture.
Definition gsInit.h:956
u32 Filter
NEAREST or LINEAR.
Definition gsInit.h:965