source: ps2launchargs/source/uLaunchELF/makeicon.c@ 1137

Last change on this file since 1137 was 1101, checked in by iritscen, 7 years ago

Added following to ps2launchargs:\n-Source code.\n-DLL needed to run ps2client.\n-Instructions for building uLaunchELF.

  • Property svn:executable set to *
File size: 12.8 KB
Line 
1//--------------------------------------------------------------
2//File name: makeicon.c
3//--------------------------------------------------------------
4#include "launchelf.h"
5#include "libmc.h"
6#include "math.h"
7extern u8 font_uLE[];
8
9u16* tex_buffer;
10
11#define ICON_WIDTH 128
12#define ICON_HEIGHT 128
13#define ICON_MARGIN 0
14#define FONT_WIDTH 8
15#define FONT_HEIGHT 16
16
17//f16 = s16/4096
18#define f16 s16
19#define f32 float
20//--------------------------------------------------------------
21struct icon_header
22{
23 u32 icon_id; // PS2 icon id = 0x010000
24 u32 anim_shapes; // number of animation shapes
25 u32 texture_type; // 0x07=uncompressed
26 u32 UNKNOWN; // always 0x3F800000
27 u32 num_vertices; // always multiple of 3
28};
29//--------------------------------------------------------------
30struct icon_vertex
31{
32 f16 xyz[3];
33 u16 w; //no idea what this is //RA: but it is required, though it may be zeroed
34};
35//--------------------------------------------------------------
36struct icon_texturedata
37{
38 f16 uv[2];
39 u8 rgba[4];
40};
41//--------------------------------------------------------------
42struct icon_animheader
43{
44 u32 id; //always 0x01
45 u32 frame_length;
46 f32 anim_speed;
47 u32 play_offset;
48 u32 num_frames;
49};
50//--------------------------------------------------------------
51struct icon_framedata
52{
53 u32 shapeid;
54 u32 num_keys;
55 u32 time;
56 u32 value;
57};
58//--------------------------------------------------------------
59// A few cheap defines for assigning vector and texture coordinates to vertices
60//Set vector coordinate value of a vertex
61#define set_vv(coord,x,y,z)\
62 coord.xyz[0]=4096*x;\
63 coord.xyz[1]=4096*y;\
64 coord.xyz[2]=4096*z;\
65 coord.w = 0;
66//--------------------------------------------------------------
67// Set texture coordinate value of a vertex
68#define set_tv(uv,u,v)\
69 uv[0]=u*4096;\
70 uv[1]=v*4096;
71//--------------------------------------------------------------
72// draw a char using the system font (16x16)
73void tex_drawChar(unsigned int c, int x, int y, u16 colour)
74{
75 int i, j, k, pixBase, pixMask;
76 u8 *cm;
77
78 u16 temp_image[16][32];
79 // blank out the memory(was causing issues before)
80 for (i=0;i<16;i++)
81 for(j=0;j<32;j++)
82 temp_image[i][j]=0x0000;
83
84 if(c >= 0x11A) c = '_';
85 cm = &font_uLE[c*16]; //cm points to the character definition in the font
86
87 pixMask = 0x80;
88 for(i=0; i<8; i++){ //for i == each pixel column
89 pixBase = -1;
90 for(j=0; j<16; j++){ //for j == each pixel row
91 if((pixBase < 0) && (cm[j] & pixMask)){ //if start of sequence
92 pixBase = j;
93 } else if((pixBase > -1) && !(cm[j] & pixMask)){ //if end of sequence
94 for(k=pixBase;k<j;k++)
95 temp_image[i*2][k*2]=0xFFFF;//every other pixel is blank
96 pixBase = -1;
97 }
98 }//ends for j == each pixel row
99 if(pixBase > -1) //if end of sequence including final row
100 {
101 for(k=pixBase;k<j;k++)
102 temp_image[i*2][k*2]=0xFFFF;
103 }
104 pixMask >>= 1;
105 }//ends for i == each pixel column
106
107 // OR's with the previous bit in the row to fill in the blank space
108 for (i=1;i<16;i+=2)
109 for(j=0;j<32;j++)
110 temp_image[i][j]=temp_image[i-1][j]|temp_image[i][j];
111
112 // OR's with the previous bit in the column to fill in the blank space
113 for(j=1;j<32;j+=2)
114 for (i=0;i<16;i++)
115 temp_image[i][j]=temp_image[i][j-1]|temp_image[i][j];
116
117 //store the temp image buffer into the real image buffer
118 for (i=0;i<16;i++)
119 for (j=0;j<32;j++)
120 tex_buffer[x+i + (y+j)*128]=temp_image[i][j];
121}
122//--------------------------------------------------------------
123// draw a string of characters to an icon texture, without shift-JIS support
124// NOTE: I added in the ability for \n to be part of the string, don't know if its
125// necessary though, although there are some cases where it doesnt work
126
127int tex_printXY(const unsigned char *s, int x, int y, u16 colour)
128{
129 unsigned int c1, c2;
130 int i;
131 int text_spacing=16;//we magnified font
132 int x_orig = x;
133 int x_max = x;
134 i=0;
135 while((c1=s[i++])!=0) {
136 if (c1 == '\t'){ //'Horizontal Tab' code ?
137 x += FONT_WIDTH; //use HT to step half a char space, for centering odd chars
138 continue; //loop back to try next character
139 }
140 if (c1 == '\v') //'Vertical Tab' code ?
141 goto force_halfrow; //use VT to step half a row down, for centering odd rows
142 if (c1 == '\r'){ //'Carriage Return' code ?
143force_newrow: //use CR to step a full row down, and restart a row
144 y += FONT_HEIGHT;
145force_halfrow: //This label is used to allow centering of odd rows
146 y += FONT_HEIGHT;
147 if(x > x_max)
148 x_max = x;
149 x = x_orig;
150 continue; //loop back to try next character
151 }
152 if(y > ICON_HEIGHT - 2*FONT_HEIGHT) //if insufficient room for current row
153 break; //then cut the string rendering here
154 if(x > ICON_WIDTH-ICON_MARGIN-2*FONT_WIDTH){ //if out of room on current row
155 i--; //back index to retry on next loop
156 goto force_newrow; //and cut this row here.
157 }
158 //Here we know there is room for at least one char on current row
159 if(c1 != 0xFF) { // Normal character
160norm_char:
161 tex_drawChar(c1, x, y, colour);
162 x += text_spacing;
163 continue;
164 } //End if for normal character
165 // Here we got a sequence starting with 0xFF ('ÿ')
166 if((c2=s[i++])==0){ //if that was the final character
167 i--; //back index to retry on next loop
168 goto norm_char; //and go display 'ÿ' as any other character
169 }
170 //Here we deal with any sequence prefixed by 'ÿ'
171 if((c2 < '0') || (c2 > '=')) //if the sequence is illegal
172 continue; //then just ignore it
173 c1=(c2-'0')*2+0x100; //generate adjusted char code > 0xFF
174 tex_drawChar(c1, x, y, colour); //render this base character to texture
175 x += text_spacing;
176 if((c2 > '4') && (c2 < ':')) //if this is a normal-width character
177 continue; //continue with the next loop
178 //compound sequence 'ÿ0'=Circle 'ÿ1'=Cross 'ÿ2'=Square 'ÿ3'=Triangle
179 //'ÿ4'=FilledBox 'ÿ:'=Pad_Rt 'ÿ;'=Pad_Dn 'ÿ<'=Pad_Lt 'ÿ='=Pad_Up
180 if(x > ICON_WIDTH-ICON_MARGIN-2*FONT_WIDTH) //if out of room for compound character ?
181 goto force_newrow; //then cut this row here.
182 tex_drawChar(c1+1, x, y, colour); //render 2nd half of compound character
183 x += text_spacing;
184 } // ends while(1)
185 if(x > x_max)
186 x_max = x;
187 return x_max; //Return max X position reached (not needed for anything though)
188}
189
190//--------------------------------------------------------------
191//This is a quick and dirty RLE compression algorithm that assumes
192//everything is part of a run, and treats everything as a run,
193//regardless as to how long that run is. It could be slightly
194//optimized, but the gains would be rather insignifigant.
195//NB: With the text magnification used, the assumption of each
196//sequence being a run longer than one pixel is always true.
197//--------------------------------------------------------------
198u32 tex_compresRLE()
199{
200 u16* new_tex=(u16*)malloc(128*128*2);
201 u16 outbufferpos=0, runcounter=0, currentposition=0;
202 while(currentposition<128*128)
203 {
204 runcounter = 1;
205 // 16384 is size of the uncompressed texture/2
206 while (currentposition+runcounter<16384 && tex_buffer[currentposition] == tex_buffer[currentposition+runcounter])
207 runcounter++;
208 new_tex[outbufferpos++] = runcounter;
209 new_tex[outbufferpos++] = tex_buffer[currentposition];
210 currentposition += runcounter;
211 }
212
213 u32 size = outbufferpos*2;
214 free(tex_buffer);
215 tex_buffer = (u16*)malloc(size);
216 memcpy(tex_buffer, new_tex, size);
217 free(new_tex);
218 return size;
219}
220//--------------------------------------------------------------
221//These defines multiplied like '4096*+xs' yield a standard sized flat icon
222#define xs 5/2
223#define ys 5/2
224#define zs 0
225//--------------------------------------------------------------
226/*
227 * Create an icon with the text 'icontext', and store in 'filename'
228 * returns 0 on success, -1 on failure
229 *
230 * The position of the text is hard coded in on line 260
231 */
232//--------------------------------------------------------------
233int make_icon(char* icontext,char* filename)
234{
235 int i;
236 struct icon_header icn_head;
237 icn_head.icon_id = 0x010000;
238 icn_head.anim_shapes = 0x01;
239 icn_head.texture_type = 0x0E; //uncompressed=0x07
240 icn_head.UNKNOWN = 0x3F800000;
241 icn_head.num_vertices = 12;
242
243 struct icon_vertex icn_vertices[12];
244 struct icon_texturedata texdata[12];
245 struct icon_vertex normals[4]; //numvertices/3, as 3 vertices share one normal
246 //Back face //Triangle Vertices //Texture coordinates of vertices
247 set_vv(normals[0], 0, 0, 1);
248 set_vv(icn_vertices[ 0],-xs, -ys, zs); set_tv(texdata[ 0].uv,1,0);
249 set_vv(icn_vertices[ 1], xs, -ys, zs); set_tv(texdata[ 1].uv,0,0);
250 set_vv(icn_vertices[ 2], xs, ys, zs); set_tv(texdata[ 2].uv,0,1);
251 set_vv(normals[1], 0, 0, 1);
252 set_vv(icn_vertices[ 3], xs, ys, zs); set_tv(texdata[ 3].uv,0,1);
253 set_vv(icn_vertices[ 4],-xs, ys, zs); set_tv(texdata[ 4].uv,1,1);
254 set_vv(icn_vertices[ 5],-xs, -ys, zs); set_tv(texdata[ 5].uv,1,0);
255 //Front face
256 set_vv(normals[2], 0, 0,-1);
257 set_vv(icn_vertices[ 6], xs, -ys, -zs); set_tv(texdata[ 6].uv,1,0);
258 set_vv(icn_vertices[ 7],-xs, -ys, -zs); set_tv(texdata[ 7].uv,0,0);
259 set_vv(icn_vertices[ 8],-xs, ys, -zs); set_tv(texdata[ 8].uv,0,1);
260 set_vv(normals[3], 0, 0,-1);
261 set_vv(icn_vertices[ 9],-xs, ys, -zs); set_tv(texdata[ 9].uv,0,1);
262 set_vv(icn_vertices[10], xs, ys, -zs); set_tv(texdata[10].uv,1,1);
263 set_vv(icn_vertices[11], xs, -ys, -zs); set_tv(texdata[11].uv,1,0);
264
265 for (i=0;i<icn_head.num_vertices;i++)
266 {
267 //the y values are generally too small, make them larger
268 icn_vertices[i].xyz[1]-=ys*4096;//subtract increases?
269 texdata[i].rgba[0]=0x80;
270 texdata[i].rgba[1]=0x80;
271 texdata[i].rgba[2]=0x80;
272 texdata[i].rgba[3]=0x80;
273 }
274
275 struct icon_animheader icn_anim_head;
276 icn_anim_head.id=0x01;
277 icn_anim_head.frame_length=1;
278 icn_anim_head.anim_speed=1;
279 icn_anim_head.play_offset=0;
280 icn_anim_head.num_frames=1;
281
282 struct icon_framedata framedata;
283 framedata.shapeid=0;
284 framedata.num_keys=1;
285 framedata.time=1;
286 framedata.value=1;
287
288 // allocates room for the texture and sets the background to black
289 tex_buffer=malloc(128*128*2); // the entire 128x128 pixel image(16bpp)
290 memset(tex_buffer,0x00,128*128*2); // black background
291 tex_printXY(icontext,0,0,0xFFFF); // (string,xpos,ypos,color)
292 u32 tex_size=tex_compresRLE(); // compress the texture, overwrites tex_buffer
293
294 int f=fioOpen(filename,O_WRONLY | O_CREAT);//open/create the file
295 if (f<0)return -1;
296 fioWrite(f,&icn_head, sizeof(icn_head));
297 for (i=0;i<icn_head.num_vertices;i++)
298 {
299 fioWrite(f,&icn_vertices[i], sizeof(icn_vertices[i]));
300 fioWrite(f,&normals[i/3], sizeof(normals[i/3]));
301 fioWrite(f,&texdata[i], sizeof(texdata[i]));
302 }
303 fioWrite(f,&icn_anim_head, sizeof(icn_anim_head));
304 fioWrite(f,&framedata, sizeof(framedata));
305 fioWrite(f,&tex_size,4);
306 fioWrite(f,tex_buffer,tex_size);
307 fioClose(f);
308 return 0;
309}
310//--------------------------------------------------------------
311/*
312 * This makes the icon.sys file that goes along with the icon itself
313 * text is the text that the browser shows (max of 32 characters)
314 * iconname is the icon file that it refers to(usually icon.icn/or icon.ico)
315 * filename is where to store the icon.sys file(eg: mc0:/FOLDER/icon.sys)
316 */
317//--------------------------------------------------------------
318int make_iconsys(char* title,char* iconname, char* filename)
319{
320 // mcIcon is defined as part of libmc
321 mcIcon icon_sys;
322
323 memset(((void *) &icon_sys), 0, sizeof(icon_sys));
324
325 strcpy(icon_sys.head,"PS2D");
326 icon_sys.nlOffset=0;//0=automagically wordwrap, otherwise newline position(multiple of 2)
327 strcpy_sjis((short *)&icon_sys.title, title);
328
329 icon_sys.trans=0x40;
330 // default values from mcIconSysGen
331 iconIVECTOR bgcolor[4]={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
332 iconFVECTOR ambientlight = {1,1,1,0};
333 iconFVECTOR lightdirection[3] = {
334 { 0.5, 0.5, 0.5, 0.0 },
335 { 0.0, 0.4,-0.1, 0.0 },
336 {-0.5,-0.5, 0.5, 0.0 },
337 };
338 iconFVECTOR lightcolors[3] = {
339 { 0.5, 0.5, 0.5, 0.00 },
340 { 0.7, 0.7, 0.7, 0.00 },
341 { 0.5, 0.5, 0.5, 0.00 },
342 };
343 memcpy(icon_sys.bgCol, bgcolor, sizeof(bgcolor));
344 memcpy(icon_sys.lightDir, lightdirection, sizeof(lightdirection));
345 memcpy(icon_sys.lightCol, lightcolors, sizeof(lightcolors));
346 memcpy(icon_sys.lightAmbient, ambientlight, sizeof(ambientlight));
347 strcpy(icon_sys.view, iconname);
348 strcpy(icon_sys.copy, iconname);
349 strcpy(icon_sys.del, iconname);
350
351 int f=fioOpen(filename,O_WRONLY | O_CREAT);// open/create the file
352 if(f<0)return -1;
353 fioWrite(f,&icon_sys,sizeof(icon_sys));
354 fioClose(f);
355
356 return 0;
357}
358//--------------------------------------------------------------
359//End of file: makeicon.c
360//--------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.