PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
draw.c
1#include <dma_tags.h>
2#include <gif_tags.h>
3
4#include <gs_privileged.h>
5#include <gs_gp.h>
6#include <gs_psm.h>
7
8#include <draw.h>
9#include <draw2d.h>
10
11qword_t *draw_setup_environment(qword_t *q, int context, framebuffer_t *frame, zbuffer_t *z)
12{
13
14 // Change this if modifying the gif packet after the giftag.
15 int qword_count = 15;
16
17 atest_t atest;
18 dtest_t dtest;
19 ztest_t ztest;
20 blend_t blend;
21 texwrap_t wrap;
22
23 atest.enable = DRAW_ENABLE;
24 atest.method = ATEST_METHOD_NOTEQUAL;
25 atest.compval = 0x00;
26 atest.keep = ATEST_KEEP_FRAMEBUFFER;
27
28 dtest.enable = DRAW_DISABLE;
29 dtest.pass = DRAW_DISABLE;
30
31 // Enable or Disable ZBuffer
32 if (z->enable)
33 {
34 ztest.enable = DRAW_ENABLE;
35 ztest.method = z->method;
36 }
37 else
38 {
39 z->mask = 1;
40 ztest.enable = DRAW_ENABLE;
41 ztest.method = ZTEST_METHOD_ALLPASS;
42 }
43
44 // Setup alpha blending
45 blend.color1 = BLEND_COLOR_SOURCE;
46 blend.color2 = BLEND_COLOR_DEST;
47 blend.alpha = BLEND_ALPHA_SOURCE;
48 blend.color3 = BLEND_COLOR_DEST;
49 blend.fixed_alpha = 0x80;
50
51 // Setup whole texture clamping
52 wrap.horizontal = WRAP_CLAMP;
53 wrap.vertical = WRAP_CLAMP;
54 wrap.minu = wrap.maxu = 0;
55 wrap.minv = wrap.maxv = 0;
56
57 // Begin packed gif data packet with another qword.
58 PACK_GIFTAG(q,GIF_SET_TAG(qword_count,0,0,0,GIF_FLG_PACKED,1),GIF_REG_AD);
59 q++;
60 // Framebuffer setting
61 PACK_GIFTAG(q, GS_SET_FRAME(frame->address>>11,frame->width>>6,frame->psm,frame->mask), GS_REG_FRAME + context);
62 q++;
63 // ZBuffer setting
64 PACK_GIFTAG(q, GS_SET_ZBUF(z->address>>11,z->zsm,z->mask), GS_REG_ZBUF + context);
65 q++;
66 // Override Primitive Control
67 PACK_GIFTAG(q, GS_SET_PRMODECONT(PRIM_OVERRIDE_DISABLE),GS_REG_PRMODECONT);
68 q++;
69 // Primitive coordinate offsets
70 PACK_GIFTAG(q, GS_SET_XYOFFSET(ftoi4(2048.0f),ftoi4(2048.0f)), GS_REG_XYOFFSET + context);
71 q++;
72 // Scissoring area
73 PACK_GIFTAG(q, GS_SET_SCISSOR(0,frame->width-1,0,frame->height-1), GS_REG_SCISSOR + context);
74 q++;
75 // Pixel testing
76 PACK_GIFTAG(q, GS_SET_TEST(atest.enable,atest.method,atest.compval,atest.keep,
77 dtest.enable,dtest.pass,
78 ztest.enable,ztest.method), GS_REG_TEST + context);
79 q++;
80 // Fog Color
81 PACK_GIFTAG(q, GS_SET_FOGCOL(0,0,0), GS_REG_FOGCOL);
82 q++;
83 // Per-pixel Alpha Blending (Blends if MSB of ALPHA is true)
84 PACK_GIFTAG(q, GS_SET_PABE(DRAW_DISABLE), GS_REG_PABE);
85 q++;
86 // Alpha Blending
87 PACK_GIFTAG(q, GS_SET_ALPHA(blend.color1,blend.color2,blend.alpha,
88 blend.color3,blend.fixed_alpha), GS_REG_ALPHA + context);
89 q++;
90 // Dithering
91 PACK_GIFTAG(q, GS_SET_DTHE(GS_DISABLE), GS_REG_DTHE);
92 q++;
93 PACK_GIFTAG(q, GS_SET_DIMX(4,2,5,3,0,6,1,7,5,3,4,2,1,7,0,6), GS_REG_DIMX);
94 q++;
95 // Color Clamp
96 PACK_GIFTAG(q,GS_SET_COLCLAMP(GS_ENABLE),GS_REG_COLCLAMP);
97 q++;
98 // Alpha Correction
99 if ((frame->psm == GS_PSM_16) || (frame->psm == GS_PSM_16S))
100 {
101 PACK_GIFTAG(q,GS_SET_FBA(ALPHA_CORRECT_RGBA16),GS_REG_FBA + context);
102 q++;
103 }
104 else
105 {
106 PACK_GIFTAG(q,GS_SET_FBA(ALPHA_CORRECT_RGBA32),GS_REG_FBA + context);
107 q++;
108 }
109 // Texture wrapping/clamping
110 PACK_GIFTAG(q, GS_SET_CLAMP(wrap.horizontal,wrap.vertical,wrap.minu,
111 wrap.maxu,wrap.minv,wrap.maxv), GS_REG_CLAMP + context);
112 q++;
113 PACK_GIFTAG(q, GS_SET_TEXA(0x80,ALPHA_EXPAND_NORMAL,0x80),GS_REG_TEXA);
114 q++;
115
116 return q;
117
118}
119
120qword_t *draw_disable_tests(qword_t *q, int context, zbuffer_t *z)
121{
122 (void)z;
123
124 PACK_GIFTAG(q,GIF_SET_TAG(1,0,0,0,GIF_FLG_PACKED,1), GIF_REG_AD);
125 q++;
126 PACK_GIFTAG(q, GS_SET_TEST(DRAW_ENABLE,ATEST_METHOD_NOTEQUAL,0x00,ATEST_KEEP_FRAMEBUFFER,
127 DRAW_DISABLE,DRAW_DISABLE,
128 DRAW_ENABLE,ZTEST_METHOD_ALLPASS), GS_REG_TEST + context);
129 q++;
130
131 return q;
132
133}
134
135qword_t *draw_enable_tests(qword_t *q, int context, zbuffer_t *z)
136{
137
138 PACK_GIFTAG(q,GIF_SET_TAG(1,0,0,0,GIF_FLG_PACKED,1), GIF_REG_AD);
139 q++;
140 PACK_GIFTAG(q, GS_SET_TEST(DRAW_ENABLE,ATEST_METHOD_NOTEQUAL,0x00,ATEST_KEEP_FRAMEBUFFER,
141 DRAW_DISABLE,DRAW_DISABLE,
142 DRAW_ENABLE,z->method), GS_REG_TEST + context);
143 q++;
144
145 return q;
146
147}
148
149qword_t *draw_clear(qword_t *q, int context, float x, float y, float width, float height, int r, int g, int b)
150{
151
152 rect_t rect;
153
154 union{
155 float fvalue;
156 u32 ivalue;
157 } q0 = {
158 1.0f
159 };
160
161 rect.v0.x = x;
162 rect.v0.y = y;
163 rect.v0.z = 0x00000000;
164
165 rect.color.rgbaq = GS_SET_RGBAQ(r,g,b,0x80,q0.ivalue);
166
167 rect.v1.x = x + width - 0.9375f;
168 rect.v1.y = y + height - 0.9375f;
169 rect.v1.z = 0x00000000;
170
171 PACK_GIFTAG(q, GIF_SET_TAG(2,0,0,0,0,1), GIF_REG_AD);
172 q++;
173 PACK_GIFTAG(q, GS_SET_PRMODECONT(PRIM_OVERRIDE_ENABLE),GS_REG_PRMODECONT);
174 q++;
175 PACK_GIFTAG(q, GS_SET_PRMODE(0,0,0,0,0,0,context,1), GS_REG_PRMODE);
176 q++;
177
178 q = draw_rect_filled_strips(q, context, &rect);
179
180 PACK_GIFTAG(q, GIF_SET_TAG(1,0,0,0,0,1), GIF_REG_AD);
181 q++;
182 PACK_GIFTAG(q, GS_SET_PRMODECONT(PRIM_OVERRIDE_DISABLE),GS_REG_PRMODECONT);
183 q++;
184
185 return q;
186
187}
188
189qword_t *draw_finish(qword_t *q)
190{
191
192 PACK_GIFTAG(q,GIF_SET_TAG(1,1,0,0,GIF_FLG_PACKED,1),GIF_REG_AD);
193 q++;
194 PACK_GIFTAG(q,1,GS_REG_FINISH);
195 q++;
196
197 return q;
198
199}
200
202{
203
204 while(!(*GS_REG_CSR & 2));
205 *GS_REG_CSR |= 2;
206
207}
208
209qword_t *draw_texture_flush(qword_t *q)
210{
211
212 // Flush texture buffer
213 DMATAG_END(q,2,0,0,0);
214 q++;
215 PACK_GIFTAG(q,GIF_SET_TAG(1,1,0,0,GIF_FLG_PACKED,1),GIF_REG_AD);
216 q++;
217 PACK_GIFTAG(q,1,GS_REG_TEXFLUSH);
218 q++;
219
220 return q;
221
222}
223
224qword_t *draw_texture_transfer(qword_t *q, void *src, int width, int height, int psm, int dest, int dest_width)
225{
226
227 int i;
228 int remaining;
229 int qwords = 0;
230
231 switch (psm)
232 {
233 case GS_PSM_8:
234 {
235 qwords = (width*height)>>4;
236 break;
237 }
238
239 case GS_PSM_32:
240 case GS_PSM_24:
241 {
242 qwords = (width*height)>>2;
243 break;
244 }
245
246 case GS_PSM_4:
247 {
248 qwords = (width*height)>>5;
249 break;
250 }
251
252 case GS_PSM_16:
253 case GS_PSM_16S:
254 {
255 qwords = (width*height)>>3;
256 break;
257 }
258
259 default:
260 {
261 switch (psm)
262 {
263 case GS_PSM_8H:
264 {
265 qwords = (width*height)>>4;
266 break;
267 }
268
269 case GS_PSMZ_32:
270 case GS_PSMZ_24:
271 {
272 qwords = (width*height)>>2;
273 break;
274 }
275
276 case GS_PSMZ_16:
277 case GS_PSMZ_16S:
278 {
279 qwords = (width*height)>>3;
280 break;
281 }
282
283 case GS_PSM_4HL:
284 case GS_PSM_4HH:
285 {
286 qwords = (width*height)>>5;
287 break;
288 }
289 }
290 break;
291 }
292 }
293
294 // Determine number of iterations based on the number of qwords
295 // that can be handled per dmatag
296 i = qwords / GIF_BLOCK_SIZE;
297
298 // Now calculate the remaining image data left over
299 remaining = qwords % GIF_BLOCK_SIZE;
300
301 // Setup the transfer
302 DMATAG_CNT(q,5,0,0,0);
303 q++;
304 PACK_GIFTAG(q,GIF_SET_TAG(4,0,0,0,GIF_FLG_PACKED,1),GIF_REG_AD);
305 q++;
306 PACK_GIFTAG(q,GS_SET_BITBLTBUF(0,0,0,dest>>6,dest_width>>6,psm),GS_REG_BITBLTBUF);
307 q++;
308 PACK_GIFTAG(q,GS_SET_TRXPOS(0,0,0,0,0),GS_REG_TRXPOS);
309 q++;
310 PACK_GIFTAG(q,GS_SET_TRXREG(width,height),GS_REG_TRXREG);
311 q++;
312 PACK_GIFTAG(q,GS_SET_TRXDIR(0),GS_REG_TRXDIR);
313 q++;
314
315
316 while(i-- > 0)
317 {
318
319 // Setup image data dma chain
320 DMATAG_CNT(q,1,0,0,0);
321 q++;
322 PACK_GIFTAG(q,GIF_SET_TAG(GIF_BLOCK_SIZE,0,0,0,2,0),0);
323 q++;
324 DMATAG_REF(q,GIF_BLOCK_SIZE,(unsigned int)src,0,0,0);
325 q++;
326
327 //Now increment the address by the number of qwords in bytes
328 src = (void *)((u8 *)src + (GIF_BLOCK_SIZE*16));
329
330 }
331
332 if(remaining)
333 {
334
335 // Setup remaining image data dma chain
336 DMATAG_CNT(q,1,0,0,0);
337 q++;
338 PACK_GIFTAG(q,GIF_SET_TAG(remaining,0,0,0,2,0),0);
339 q++;
340 DMATAG_REF(q,remaining,(unsigned int)src,0,0,0);
341 q++;
342
343 }
344
345 return q;
346
347}
348
349unsigned char draw_log2(unsigned int x)
350{
351
352 unsigned char res;
353
354 __asm__ __volatile__ ("plzcw %0, %1\n\t" : "=r" (res) : "r" (x));
355
356 res = 31 - (res + 1);
357 res += (x > (unsigned int)(1<<res) ? 1 : 0);
358
359 return res;
360}
#define DMATAG_REF(Q, QWC, ADDR, SPR, W2, W3)
Definition dma_tags.h:93
#define DMATAG_END(Q, QWC, SPR, W2, W3)
Definition dma_tags.h:75
#define DMATAG_CNT(Q, QWC, SPR, W2, W3)
Definition dma_tags.h:57
qword_t * draw_rect_filled_strips(qword_t *q, int context, rect_t *rect)
Definition draw2d.c:248
void draw_wait_finish(void)
Definition draw.c:201
qword_t * draw_finish(qword_t *q)
Definition draw.c:189
qword_t * draw_clear(qword_t *q, int context, float x, float y, float width, float height, int r, int g, int b)
Definition draw.c:149
qword_t * draw_setup_environment(qword_t *q, int context, framebuffer_t *frame, zbuffer_t *z)
Definition draw.c:11
qword_t * draw_texture_flush(qword_t *q)
Definition draw.c:209
qword_t * draw_texture_transfer(qword_t *q, void *src, int width, int height, int psm, int dest, int dest_width)
Definition draw.c:224
#define ALPHA_CORRECT_RGBA32
#define BLEND_COLOR_SOURCE
unsigned char draw_log2(unsigned int x)
Definition draw.c:349
#define PRIM_OVERRIDE_ENABLE
#define ALPHA_EXPAND_NORMAL
qword_t * draw_enable_tests(qword_t *q, int context, zbuffer_t *z)
Definition draw.c:135
qword_t * draw_disable_tests(qword_t *q, int context, zbuffer_t *z)
Definition draw.c:120
#define GIF_REG_AD
Definition gif_tags.h:72
#define GIF_FLG_PACKED
Definition gif_tags.h:35
#define GIF_BLOCK_SIZE
Definition gif_tags.h:12
#define GS_REG_TRXREG
Definition gs_gp.h:135
#define GS_REG_SCISSOR
Definition gs_gp.h:87
#define GS_REG_DTHE
Definition gs_gp.h:101
#define GS_REG_ZBUF
Definition gs_gp.h:125
#define GS_REG_PRMODECONT
Definition gs_gp.h:61
#define GS_REG_TEXFLUSH
Definition gs_gp.h:85
#define GS_REG_FBA
Definition gs_gp.h:113
#define GS_REG_TEXA
Definition gs_gp.h:81
#define GS_REG_CLAMP
Definition gs_gp.h:31
#define GS_REG_TEST
Definition gs_gp.h:105
#define GS_REG_DIMX
Definition gs_gp.h:99
#define GS_REG_FOGCOL
Definition gs_gp.h:83
#define GS_REG_XYOFFSET
Definition gs_gp.h:55
#define GS_REG_PABE
Definition gs_gp.h:111
#define GS_REG_TRXPOS
Definition gs_gp.h:133
#define GS_REG_COLCLAMP
Definition gs_gp.h:103
#define GS_REG_BITBLTBUF
Definition gs_gp.h:131
#define GS_REG_PRMODE
Definition gs_gp.h:63
#define GS_REG_FRAME
Definition gs_gp.h:119
#define GS_REG_FINISH
Definition gs_gp.h:143
#define GS_REG_TRXDIR
Definition gs_gp.h:137
#define GS_REG_ALPHA
Definition gs_gp.h:93
#define GS_REG_CSR
#define GS_PSM_4HH
Definition gs_psm.h:29
#define GS_PSM_4
Definition gs_psm.h:23
#define GS_PSM_16S
Definition gs_psm.h:17
#define GS_PSMZ_16S
Definition gs_psm.h:37
#define GS_PSMZ_24
Definition gs_psm.h:33
#define GS_PSMZ_32
Definition gs_psm.h:31
#define GS_PSM_4HL
Definition gs_psm.h:27
#define GS_PSM_8H
Definition gs_psm.h:25
#define GS_PSM_32
Definition gs_psm.h:11
#define GS_PSMZ_16
Definition gs_psm.h:35
#define GS_PSM_24
Definition gs_psm.h:13
#define GS_PSM_8
Definition gs_psm.h:21
#define GS_PSM_16
Definition gs_psm.h:15