PS2SDK
PS2 Homebrew Libraries
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 
11 qword_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 
120 qword_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 
135 qword_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 
149 qword_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 
189 qword_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 
209 qword_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 
224 qword_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 
349 unsigned 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 }
GS_REG_TEXFLUSH
#define GS_REG_TEXFLUSH
Definition: gs_gp.h:85
gs_gp.h
GS_REG_TEST
#define GS_REG_TEST
Definition: gs_gp.h:105
draw_texture_flush
qword_t * draw_texture_flush(qword_t *q)
Definition: draw.c:209
draw_enable_tests
qword_t * draw_enable_tests(qword_t *q, int context, zbuffer_t *z)
Definition: draw.c:135
dma_tags.h
GS_REG_TRXPOS
#define GS_REG_TRXPOS
Definition: gs_gp.h:133
GS_REG_TRXDIR
#define GS_REG_TRXDIR
Definition: gs_gp.h:137
gs_privileged.h
GS_REG_CLAMP
#define GS_REG_CLAMP
Definition: gs_gp.h:31
GIF_REG_AD
#define GIF_REG_AD
Definition: gif_tags.h:72
GS_REG_CSR
#define GS_REG_CSR
Definition: gs_privileged.h:45
draw_finish
qword_t * draw_finish(qword_t *q)
Definition: draw.c:189
GS_PSMZ_16S
#define GS_PSMZ_16S
Definition: gs_psm.h:37
GS_REG_SCISSOR
#define GS_REG_SCISSOR
Definition: gs_gp.h:87
ALPHA_EXPAND_NORMAL
#define ALPHA_EXPAND_NORMAL
Definition: draw_sampling.h:36
BLEND_COLOR_SOURCE
#define BLEND_COLOR_SOURCE
Definition: draw_blending.h:14
GS_PSM_4HL
#define GS_PSM_4HL
Definition: gs_psm.h:27
GS_PSM_8
#define GS_PSM_8
Definition: gs_psm.h:21
GS_REG_DIMX
#define GS_REG_DIMX
Definition: gs_gp.h:99
GS_REG_BITBLTBUF
#define GS_REG_BITBLTBUF
Definition: gs_gp.h:131
DMATAG_END
#define DMATAG_END(Q, QWC, SPR, W2, W3)
Definition: dma_tags.h:75
DMATAG_CNT
#define DMATAG_CNT(Q, QWC, SPR, W2, W3)
Definition: dma_tags.h:57
GS_PSM_8H
#define GS_PSM_8H
Definition: gs_psm.h:25
dtest_t
Definition: draw_tests.h:44
atest_t
Definition: draw_tests.h:37
GS_PSM_16
#define GS_PSM_16
Definition: gs_psm.h:15
GS_REG_FBA
#define GS_REG_FBA
Definition: gs_gp.h:113
GS_REG_TEXA
#define GS_REG_TEXA
Definition: gs_gp.h:81
GS_REG_DTHE
#define GS_REG_DTHE
Definition: gs_gp.h:101
PRIM_OVERRIDE_ENABLE
#define PRIM_OVERRIDE_ENABLE
Definition: draw_primitives.h:33
draw_wait_finish
void draw_wait_finish(void)
Definition: draw.c:201
GS_REG_XYOFFSET
#define GS_REG_XYOFFSET
Definition: gs_gp.h:55
GS_REG_ALPHA
#define GS_REG_ALPHA
Definition: gs_gp.h:93
framebuffer_t
Definition: draw_buffers.h:40
GS_REG_FOGCOL
#define GS_REG_FOGCOL
Definition: gs_gp.h:83
GS_PSM_4
#define GS_PSM_4
Definition: gs_psm.h:23
GS_REG_ZBUF
#define GS_REG_ZBUF
Definition: gs_gp.h:125
DMATAG_REF
#define DMATAG_REF(Q, QWC, ADDR, SPR, W2, W3)
Definition: dma_tags.h:93
zbuffer_t
Definition: draw_buffers.h:48
GIF_FLG_PACKED
#define GIF_FLG_PACKED
Definition: gif_tags.h:35
GS_REG_PABE
#define GS_REG_PABE
Definition: gs_gp.h:111
draw_rect_filled_strips
qword_t * draw_rect_filled_strips(qword_t *q, int context, rect_t *rect)
Definition: draw2d.c:248
ztest_t
Definition: draw_tests.h:49
GS_PSM_32
#define GS_PSM_32
Definition: gs_psm.h:11
GS_PSMZ_24
#define GS_PSMZ_24
Definition: gs_psm.h:33
draw.h
draw_setup_environment
qword_t * draw_setup_environment(qword_t *q, int context, framebuffer_t *frame, zbuffer_t *z)
Definition: draw.c:11
GS_REG_TRXREG
#define GS_REG_TRXREG
Definition: gs_gp.h:135
GS_REG_COLCLAMP
#define GS_REG_COLCLAMP
Definition: gs_gp.h:103
draw_disable_tests
qword_t * draw_disable_tests(qword_t *q, int context, zbuffer_t *z)
Definition: draw.c:120
GS_PSMZ_16
#define GS_PSMZ_16
Definition: gs_psm.h:35
GS_PSMZ_32
#define GS_PSMZ_32
Definition: gs_psm.h:31
draw_texture_transfer
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
GIF_BLOCK_SIZE
#define GIF_BLOCK_SIZE
Definition: gif_tags.h:12
draw_clear
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
draw_log2
unsigned char draw_log2(unsigned int x)
Definition: draw.c:349
draw2d.h
ALPHA_CORRECT_RGBA32
#define ALPHA_CORRECT_RGBA32
Definition: draw_blending.h:23
GS_REG_FRAME
#define GS_REG_FRAME
Definition: gs_gp.h:119
gif_tags.h
blend_t
Definition: draw_blending.h:26
gs_psm.h
GS_REG_FINISH
#define GS_REG_FINISH
Definition: gs_gp.h:143
GS_PSM_4HH
#define GS_PSM_4HH
Definition: gs_psm.h:29
GS_REG_PRMODECONT
#define GS_REG_PRMODECONT
Definition: gs_gp.h:61
GS_REG_PRMODE
#define GS_REG_PRMODE
Definition: gs_gp.h:63
GS_PSM_24
#define GS_PSM_24
Definition: gs_psm.h:13
rect_t
Definition: draw2d.h:31
GS_PSM_16S
#define GS_PSM_16S
Definition: gs_psm.h:17
texwrap_t
Definition: draw_sampling.h:58