PS2SDK
PS2 Homebrew Libraries
draw.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # (c) 2009 Lion
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
11 #include <errno.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <sys/fcntl.h>
15 #include <sys/unistd.h>
16 #include <kernel.h>
17 #include <libgs.h>
18 
19 #include "internal.h"
20 
21 extern QWORD GsPrimWorkArea[];
22 
23 void GsSetDefaultDrawEnv(GS_DRAWENV *drawenv, u16 psm, u16 w, u16 h)
24 {
25  drawenv->offset_x = 2048-w/2;
26  drawenv->offset_y = 2048-h/2;
27  drawenv->clip.x = 0;
28  drawenv->clip.y = 0;
29  drawenv->clip.w = w;
30  drawenv->clip.h = h;
31  drawenv->draw_mask = 0;
32  drawenv->auto_clear = 1;
33 
34  drawenv->bg_color.r = 0x01;
35  drawenv->bg_color.g = 0x01;
36  drawenv->bg_color.b = 0x01;
37  drawenv->bg_color.a = 0x80;
38  drawenv->bg_color.q = 0.0f;
39 
40  drawenv->fbw = (w+63)/64;
41  drawenv->psm = psm;
42  drawenv->vram_addr = 0;
43  drawenv->vram_x = 0;
44  drawenv->vram_y = 0;
45 }
46 
47 void GsSetDefaultDrawEnvAddress(GS_DRAWENV *drawenv, u16 vram_addr)
48 {
49  drawenv->vram_addr=vram_addr;
50 }
51 
52 int checkModelVersion(void)
53 {
54  int fd, result;
55  char data[256];
56 
57  if((fd=open("rom0:ROMVER", O_RDONLY))>=0)
58  {
59  int i;
60  char *pData;
61  for(pData=data,i=0; (unsigned int)i<sizeof(data); i++)
62  {
63  read(fd, pData, 1);
64  if(*pData++=='\0') break;
65  }
66  close(fd);
67 
68  //ROMVER string format: VVVVRTYYYYMMDD\n
69  result=(20010608<atoi(data+i-9));
70  }
71  else result=-1;
72 
73  return result;
74 }
75 
76 void GsSetDefaultDisplayEnv(GS_DISPENV *dispenv, u16 psm, u16 w, u16 h, u16 dx, u16 dy)
77 {
78  GsGParam_t *pGParams;
79  int gs_DH, gs_DW, gs_DY, gs_DX;
80 
81  pGParams=GsGetGParam();
82  dispenv->disp.pad1=dispenv->disp.pad2=0;
83 
84  if(pGParams->omode >= GS_MODE_NTSC && pGParams->omode <= GS_MODE_PAL)
85  {
86  gs_DH=0;
87  gs_DW=0;
88  gs_DY=0;
89  gs_DX=0;
90  } else {
91  if(checkModelVersion())
92  _GetGsDxDyOffset(pGParams->omode, &gs_DX, &gs_DY, &gs_DW, &gs_DH);
93  else{
94  gs_DH=0;
95  gs_DW=0;
96  gs_DY=0;
97  gs_DX=0;
98  }
99  }
100 
101  dispenv->dispfb.pad1=dispenv->dispfb.pad2=0;
102  dispenv->dispfb.x=0;
103  dispenv->dispfb.y=0;
104  dispenv->dispfb.address=0;
105  dispenv->dispfb.fbw=(w+63)/64;
106  dispenv->dispfb.psm=psm;
107  switch(pGParams->omode)
108  {
109  case GS_MODE_NTSC:
110  if(pGParams->interlace)
111  {
112  dispenv->disp.display_y = dy+gs_DY+0x32;
113  dispenv->disp.display_x = (gs_DX+0x27C) + dx*((w+0x9FF)/w);
114  dispenv->disp.magnify_h = (w+0x9FF)/w - 1;
115  dispenv->disp.magnify_v = 0;
116  dispenv->disp.display_w = (w+0x9FF)/w*w - 1;
117 
118  if(pGParams->ffmode)
119  dispenv->disp.display_h = (h<<1) - 1;
120  else
121  dispenv->disp.display_h = h - 1;
122  } else {
123  dispenv->disp.display_h = h-1;
124  dispenv->disp.display_x = gs_DX+0x27C + dx*((w+0x9FF)/w);
125  dispenv->disp.display_y = gs_DY+dy+0x19;
126  dispenv->disp.magnify_h = (w+0x9FF)/w - 1;
127  dispenv->disp.magnify_v = 0;
128  dispenv->disp.display_w = (w+0x9FF)/w*w - 1;
129  }
130  break;
131  case GS_MODE_PAL:
132  if(pGParams->interlace)
133  {
134  dispenv->disp.display_y = gs_DY+dy+0x48;
135  dispenv->disp.display_x = gs_DX+0x290 + dx*((w+0x9FF)/w);
136  dispenv->disp.magnify_h = (w+0x9FF)/w - 1;
137  dispenv->disp.magnify_v = 0;
138  dispenv->disp.display_w = (w+0x9FF)/w*w - 1;
139 
140  if(pGParams->ffmode)
141  dispenv->disp.display_h = (h<<1) - 1;
142  else
143  dispenv->disp.display_h = h - 1;
144  } else {
145  dispenv->disp.display_h = h-1;
146  dispenv->disp.display_x = gs_DX+0x290 + dx*((w+0x9FF)/w);
147  dispenv->disp.display_y = dy+gs_DY+0x48;
148  dispenv->disp.magnify_h = (w+0x9FF)/w - 1;
149  dispenv->disp.magnify_v = 0;
150  dispenv->disp.display_w = (w+0x9FF)/w*w - 1;
151  }
152  break;
153  case GS_MODE_DTV_480P:
154  dispenv->disp.display_x = gs_DX+((0x2D0-w) + ((0x2D0-w)>>31))/2*2 + (dx<<1)+0xE8;
155  dispenv->disp.display_h = h-1;
156  dispenv->disp.display_w = (w<<1) - 1;
157  dispenv->disp.display_y = gs_DY+dy+0x23;
158  dispenv->disp.magnify_h = 1;
159  dispenv->disp.magnify_v = 0;
160  break;
161  default:
162  printf("GsSetDefaultDisplayEnv: Unsupported video mode: 0x%x\n", pGParams->omode);
163  }
164 }
165 
166 void GsSetDefaultDisplayEnvAddress(GS_DISPENV *dispenv, unsigned short vram_addr)
167 {
168  dispenv->dispfb.address=vram_addr;
169 }
170 
171 void GsPutDrawEnv1(GS_DRAWENV *drawenv)
172 {
173  GsSetXYOffset1(drawenv->offset_x<<4, drawenv->offset_y<<4);
174  GsSetScissor1(drawenv->clip.x, drawenv->clip.y, drawenv->clip.x+drawenv->clip.w, drawenv->clip.y+drawenv->clip.h);
175  GsSetFrame1(drawenv->vram_addr, drawenv->fbw, drawenv->psm, drawenv->draw_mask);
176 
177  //use a sprite to clear background
178  if(drawenv->auto_clear)
179  {
180  GsClearDrawEnv1(drawenv);
181  }
182 }
183 
185 {
186  unsigned char context;
187  QWORD *p;
188 
189  // use a sprite to clear background
190  context =0; // contex 1
191 
192  p=UNCACHED_SEG(GsPrimWorkArea);
193  gs_setGIF_TAG(((GS_GIF_TAG *)&p[0]), 4,1,0,0,GS_GIF_PACKED,1,gif_rd_ad);
194  gs_setR_PRIM(((GS_R_PRIM *)&p[1]), GS_PRIM_SPRITE,0, 0, 0, 1, 0, 1, context, 0);
195  gs_setR_RGBAQ(((GS_R_RGBAQ *)&p[2]), drawenv->bg_color.r, drawenv->bg_color.g, drawenv->bg_color.b, drawenv->bg_color.a, drawenv->bg_color.q);
196  gs_setR_XYZ2(((GS_R_XYZ *)&p[3]), (drawenv->offset_x+drawenv->clip.x)<<4, (drawenv->offset_y+drawenv->clip.y)<<4, 0x00000000);
197  gs_setR_XYZ2(((GS_R_XYZ *)&p[4]), (drawenv->offset_x+drawenv->clip.x+drawenv->clip.w)<<4, (drawenv->offset_y+drawenv->clip.y+drawenv->clip.h)<<4, 0x00000000);
198 
199  GsDmaSend(GsPrimWorkArea, 5);
200  GsDmaWait();
201 }
202 
203 void GsPutDisplayEnv1(GS_DISPENV *dispenv)
204 {
205  *((volatile GS_DISPLAY *)(gs_p_display1)) = dispenv->disp;
206  *((volatile GS_DISPFB *)(gs_p_dispfb1)) = dispenv->dispfb;
207 }
208 
209 void GsPutDrawEnv2(GS_DRAWENV *drawenv)
210 {
211  GsSetXYOffset2(drawenv->offset_x<<4, drawenv->offset_y<<4);
212  GsSetScissor2(drawenv->clip.x, drawenv->clip.y, drawenv->clip.x+drawenv->clip.w, drawenv->clip.y+drawenv->clip.h);
213  GsSetFrame2(drawenv->vram_addr, drawenv->fbw, drawenv->psm, drawenv->draw_mask);
214 
215  if(drawenv->auto_clear)
216  {
217  GsClearDrawEnv2(drawenv);
218  }
219 }
220 
222 {
223  unsigned char context;
224  QWORD *p;
225 
226  // use a sprite to clear background
227  context =1; // contex 2
228 
229  p=UNCACHED_SEG(GsPrimWorkArea);
230  gs_setGIF_TAG(((GS_GIF_TAG *)&p[0]), 4,1,0,0,GS_GIF_PACKED,1,gif_rd_ad);
231  gs_setR_PRIM(((GS_R_PRIM *)&p[1]), GS_PRIM_SPRITE,0, 0, 0, 1, 0, 1, context, 0);
232  gs_setR_RGBAQ(((GS_R_RGBAQ *)&p[2]), drawenv->bg_color.r, drawenv->bg_color.g, drawenv->bg_color.b, drawenv->bg_color.a, drawenv->bg_color.q);
233  gs_setR_XYZ2(((GS_R_XYZ *)&p[3]), (drawenv->offset_x+drawenv->clip.x)<<4, (drawenv->offset_y+drawenv->clip.y)<<4, 0x00000000);
234  gs_setR_XYZ2(((GS_R_XYZ *)&p[4]), (drawenv->offset_x+drawenv->clip.x+drawenv->clip.w)<<4, (drawenv->offset_y+drawenv->clip.y+drawenv->clip.h)<<4, 0x00000000);
235 
236  GsDmaSend(GsPrimWorkArea, 5);
237  GsDmaWait();
238 }
239 
240 void GsPutDisplayEnv2(GS_DISPENV *dispenv)
241 {
242  *((volatile GS_DISPLAY *)(gs_p_display2)) = dispenv->disp;
243  *((volatile GS_DISPFB *)(gs_p_dispfb2)) = dispenv->dispfb;
244 }
kernel.h
GS_DISPFB::pad2
u32 pad2
Definition: libgs.h:419
GS_DISPLAY::display_h
u32 display_h
Definition: libgs.h:436
GsGParam_t
Definition: libgs.h:21
GS_DISPLAY::display_y
u32 display_y
Definition: libgs.h:426
GS_DISPENV
Definition: libgs.h:1967
GsGParam_t::ffmode
u8 ffmode
Definition: libgs.h:27
GS_R_RGBAQ
Definition: libgs.h:945
GS_R_XYZ
Definition: libgs.h:965
GS_DISPFB::fbw
u32 fbw
Definition: libgs.h:409
GS_PRIM_SPRITE
#define GS_PRIM_SPRITE
Definition: gs_gp.h:163
GS_GIF_TAG
Definition: libgs.h:1859
gif_rd_ad
#define gif_rd_ad
Definition: libgs.h:326
GS_DISPLAY::pad1
u32 pad1
Definition: libgs.h:432
GS_DISPLAY::pad2
u32 pad2
Definition: libgs.h:438
GS_DISPFB::pad1
u32 pad1
Definition: libgs.h:413
gs_p_display2
#define gs_p_display2
Definition: libgs.h:202
GS_DISPFB
Definition: libgs.h:405
gs_p_display1
#define gs_p_display1
Definition: libgs.h:198
stdio.h
GsClearDrawEnv1
void GsClearDrawEnv1(GS_DRAWENV *drawenv)
Definition: draw.c:184
GS_DISPFB::psm
u32 psm
Definition: libgs.h:411
GS_DISPLAY
Definition: libgs.h:422
gs_p_dispfb2
#define gs_p_dispfb2
Definition: libgs.h:200
libgs.h
GS_DISPFB::x
u32 x
Definition: libgs.h:415
GsClearDrawEnv2
void GsClearDrawEnv2(GS_DRAWENV *drawenv)
Definition: draw.c:221
GS_DISPLAY::display_w
u32 display_w
Definition: libgs.h:434
GS_DISPLAY::display_x
u32 display_x
Definition: libgs.h:424
gs_p_dispfb1
#define gs_p_dispfb1
Definition: libgs.h:196
GS_DISPFB::address
u32 address
Definition: libgs.h:407
GS_DISPLAY::magnify_v
u32 magnify_v
Definition: libgs.h:430
stdlib.h
QWORD
Definition: libgs.h:333
GsGParam_t::omode
u8 omode
Definition: libgs.h:25
GS_DISPFB::y
u32 y
Definition: libgs.h:417
GS_DISPLAY::magnify_h
u32 magnify_h
Definition: libgs.h:428
errno.h
GsGParam_t::interlace
u8 interlace
Definition: libgs.h:23
GS_R_PRIM
Definition: libgs.h:940
GS_DRAWENV
Definition: libgs.h:1940