1 #ifdef FONTEDITOR
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <math.h>
7 #include <SDL/SDL.h>
8
9 #define CELLW 12
10 #define CELLH 12
11
12 #define XRES 800
13 #define YRES 600
14 //#define SCALE 1
15 //#define EXTENDED_FONT 1
16
17 char font[256][CELLH][CELLW];
18 char width[256];
19 unsigned char flags[256];
20 unsigned int color[256];
21 signed char top[256];
22 signed char left[256];
23
blendpixel(unsigned * vid,int x,int y,int r,int g,int b,int a)24 void blendpixel(unsigned *vid, int x, int y, int r, int g, int b, int a)
25 {
26 if (x<0 || y<0 || x>=XRES || y>=YRES)
27 return;
28 if (a != 255)
29 {
30 int t = vid[y*XRES+x];
31 r = (a*r + (255-a)*((t>>16)&255)) >> 8;
32 g = (a*g + (255-a)*((t>>8)&255)) >> 8;
33 b = (a*b + (255-a)*(t&255)) >> 8;
34 }
35 vid[y*XRES+x] = (r<<16)|(g<<8)|b;
36 }
37
drawchar(unsigned * vid,int x,int y,unsigned char c,int r,int g,int b)38 int drawchar(unsigned *vid, int x, int y, unsigned char c, int r, int g, int b)
39 {
40 int i, j;
41 if (color[c])
42 {
43 r = (color[c] >> 16) & 0xFF;
44 g = (color[c] >> 8) & 0xFF;
45 b = color[c] & 0xFF;
46 }
47 for (j = 0; j < CELLH; j++)
48 for (i = 0; i < width[c] && i < CELLW; i++)
49 blendpixel(vid, x+i+left[c], y+j+top[c], r, g, b, (font[c][j][i]*255)/3);
50 return x + width[c];
51 }
52
drawtext(unsigned * vid,int x,int y,const char * s,int r,int g,int b)53 int drawtext(unsigned *vid, int x, int y, const char *s, int r, int g, int b)
54 {
55 for (; *s; s++)
56 x = drawchar(vid, x, y, *s, r, g, b);
57 return x;
58 }
59
drawline(unsigned * vid,int x1,int y1,int x2,int y2,int r,int g,int b,int a)60 void drawline(unsigned *vid, int x1, int y1, int x2, int y2, int r, int g, int b, int a)
61 {
62 int cp = abs(y2-y1) > abs(x2-x1), x, y, dx, dy, sy;
63 float e, de;
64 if (cp)
65 {
66 y = x1;
67 x1 = y1;
68 y1 = y;
69 y = x2;
70 x2 = y2;
71 y2 = y;
72 }
73 if (x1 > x2)
74 {
75 y = x1;
76 x1 = x2;
77 x2 = y;
78 y = y1;
79 y1 = y2;
80 y2 = y;
81 }
82 dx = x2 - x1;
83 dy = abs(y2 - y1);
84 e = 0.0f;
85 de = dy/(float)dx;
86 y = y1;
87 sy = (y1<y2) ? 1 : -1;
88 for (x=x1; x<=x2; x++)
89 {
90 if (cp)
91 blendpixel(vid, y, x, r, g, b, a);
92 else
93 blendpixel(vid, x, y, r, g, b, a);
94 e += de;
95 if (e >= 0.5f)
96 {
97 y += sy;
98 e -= 1.0f;
99 }
100 }
101 }
102
drawcell(unsigned * vid,int i,int j,int c,int m)103 void drawcell(unsigned *vid, int i, int j, int c, int m)
104 {
105 int x, y, x0=i*32+64, y0=j*32+64;
106 for (y = 1;y < 32;y++)
107 for (x = 1; x < 32; x++)
108 blendpixel(vid, x0+x, y0+y, 127*m, 127*m, 127*m, c);
109 for (x = 0; x <32; x+=2)
110 {
111 if (!j)
112 blendpixel(vid, x0+x, y0, 64*m, 64*m, 64*m, 255);
113 if (!i)
114 blendpixel(vid, x0, y0+x, 64*m, 64*m, 64*m, 255);
115 blendpixel(vid, x0+x, y0+32, 64*m, 64*m, 64*m, 255);
116 blendpixel(vid, x0+32, y0+x, 64*m, 64*m, 64*m, 255);
117 }
118 }
119
120 /***********************************************************
121 * SDL OUTPUT *
122 ***********************************************************/
123
124 SDL_Surface *sdl_scrn;
125 int sdl_key;
sdl_open(void)126 void sdl_open(void)
127 {
128 if (SDL_Init(SDL_INIT_VIDEO)<0)
129 {
130 fprintf(stderr, "Initializing SDL: %s\n", SDL_GetError());
131 exit(1);
132 }
133 atexit(SDL_Quit);
134 sdl_scrn = SDL_SetVideoMode(XRES*SCALE, YRES*SCALE + 40*SCALE, 32, SDL_SWSURFACE);
135 if (!sdl_scrn)
136 {
137 fprintf(stderr, "Creating window: %s\n", SDL_GetError());
138 exit(1);
139 }
140 }
141
sdl_blit(int x,int y,int w,int h,unsigned int * src,int pitch)142 void sdl_blit(int x, int y, int w, int h, unsigned int *src, int pitch)
143 {
144 unsigned *dst,i,j,k;
145 if (SDL_MUSTLOCK(sdl_scrn))
146 if (SDL_LockSurface(sdl_scrn)<0)
147 return;
148 dst = (unsigned *)sdl_scrn->pixels+y*sdl_scrn->pitch/4+x;
149 for (j = 0;j < h; j++)
150 {
151 for (k = 0; k < SCALE; k++)
152 {
153 for (i = 0; i < w*SCALE; i++)
154 dst[i] = src[i/SCALE];
155 dst += sdl_scrn->pitch/4;
156 }
157 src += pitch/4;
158 }
159 if (SDL_MUSTLOCK(sdl_scrn))
160 SDL_UnlockSurface(sdl_scrn);
161 SDL_UpdateRect(sdl_scrn,0,0,0,0);
162 }
163
164 int frame_idx = 0;
dump_frame(unsigned int * src,int w,int h,int pitch)165 void dump_frame(unsigned int *src, int w, int h, int pitch)
166 {
167 char frame_name[32];
168 unsigned j,i,c;
169 FILE *f;
170 sprintf(frame_name,"frame%04d.ppm",frame_idx);
171 f=fopen(frame_name,"w");
172 fprintf(f,"P6\n%d %d\n255\n",w,h);
173 for (j = 0; j < h; j++)
174 {
175 for (i = 0; i < w; i++)
176 {
177 c = ((src[i]&0xFF0000)>>16) | (src[i]&0x00FF00) | ((src[i]&0x0000FF)<<16);
178 fwrite(&c,3,1,f);
179 }
180 src += pitch/4;
181 }
182 fclose(f);
183 frame_idx++;
184 }
185
sdl_poll()186 int sdl_poll()
187 {
188 SDL_Event event;
189 sdl_key=0;
190 while (SDL_PollEvent(&event))
191 {
192 switch (event.type)
193 {
194 case SDL_KEYDOWN:
195 sdl_key = event.key.keysym.sym;
196 break;
197 case SDL_QUIT:
198 return 1;
199 }
200 }
201 return 0;
202 }
203
204 /***********************************************************
205 * MAIN PROGRAM *
206 ***********************************************************/
207
208 const char *tag = "(c) 2008 Stanislaw Skowronek";
209
main(int argc,char * argv[])210 int main(int argc, char *argv[])
211 {
212 unsigned *vid_buf = (unsigned*)calloc(XRES*YRES, sizeof(unsigned));
213 int x, y, b = 0, lb, c = 0xA0, i, j, dc = 0;
214 int mode = 0;
215 char hex[18] = "";
216 char inputColor = 0;
217 FILE *f;
218
219 f = fopen("font.bin", "rb");
220 if(f)
221 {
222 fread(width, 1, 256, f);
223 #ifdef EXTENDED_FONT
224 fread(flags, 1, 256, f);
225 fread(color, 4, 256, f);
226 fread(top, 1, 256, f);
227 fread(left, 1, 256, f);
228 #endif
229 fread(font, CELLW*CELLH, 256, f);
230 fclose(f);
231 }
232
233 sdl_open();
234 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
235 while (!sdl_poll())
236 {
237 if (sdl_key=='q' || sdl_key==SDLK_ESCAPE)
238 break;
239 else if ((sdl_key==' ' || sdl_key=='=') && c < 255)
240 {
241 if (inputColor)
242 {
243 inputColor = 0;
244 color[c] = 0;
245 flags[c] &= ~0x2;
246 }
247 c++;
248 }
249 else if ((sdl_key=='\b' || sdl_key=='-') && c > 0)
250 {
251 if (inputColor)
252 {
253 inputColor = 0;
254 color[c] = 0;
255 flags[c] &= ~0x2;
256 }
257 c--;
258 }
259 #ifdef EXTENDED_FONT
260 else if (sdl_key == 'w')
261 flags[c] ^= 0x1;
262 else if (sdl_key == 'c')
263 {
264 if (!(flags[c] & 0x2))
265 {
266 flags[c] |= 0x2;
267 color[c] = 255<<24;
268 inputColor = 1;
269 }
270 else
271 {
272 flags[c] &= ~0x2;
273 color[c] = 0;
274 inputColor = 0;
275 }
276 }
277 else if (sdl_key == SDLK_RETURN)
278 {
279 int val = (x > 255) ? 255 : x;
280 switch (inputColor)
281 {
282 case 1:
283 color[c] |= (val<<16);
284 inputColor = 2;
285 break;
286 case 2:
287 color[c] |= (val<<8);
288 inputColor = 3;
289 break;
290 case 3:
291 color[c] |= (val<<0);
292 inputColor = 0;
293 break;
294 }
295 }
296 #endif
297
298 lb = b;
299 b = SDL_GetMouseState(&x, &y);
300 if (b)
301 {
302 x /= SCALE;
303 y /= SCALE;
304 }
305
306 i = x/32-2;
307 j = y/32-2;
308 if (!lb && b && (j<0 || j>=CELLH || i<0 || i>=CELLW))
309 {
310 int leftDistance = abs(i-left[c]);
311 int widthDistance = abs(i-width[c]);
312 int topDistance = abs(j-top[c]);
313 if (widthDistance <= leftDistance && widthDistance <= topDistance)
314 mode = 3; // WIDTH
315 else if (leftDistance <= topDistance)
316 mode = 4; // LEFT
317 else
318 mode = 2; // TOP
319 }
320 else if (!lb && b)
321 {
322 mode = 1; // DRAW
323 if (b == 1)
324 dc = (font[c][j][i]+3)%4;
325 else
326 dc = (font[c][j][i]+1)%4;
327 }
328
329 if (b)
330 switch(mode)
331 {
332 case 1:
333 if (i>=0 && j>=0 && i<CELLW && j<CELLH)
334 font[c][j][i] = dc;
335 break;
336 #ifdef EXTENDED_FONT
337 case 2:
338 top[c] = j;
339 break;
340 #endif
341 case 3:
342 width[c] = i;
343 break;
344 #ifdef EXTENDED_FONT
345 case 4:
346 left[c] = i;
347 break;
348 #endif
349 }
350
351 memset(vid_buf, 0, XRES*YRES*4);
352 for (j = 0; j < CELLH; j++)
353 for (i = 0; i < CELLW; i++)
354 drawcell(vid_buf, i, j, (font[c][j][i]*255)/3, i>=width[c]?1:2);
355 drawline(vid_buf, 32, 64+top[c]*32, 128+32*CELLW, 64+top[c]*32, 128, 128, 255, 255);
356 drawline(vid_buf, 64+width[c]*32, 32, 64+width[c]*32, 128+32*CELLH, 255, 128, 128, 255);
357 drawline(vid_buf, 64+left[c]*32, 32, 64+left[c]*32, 128+32*CELLH, 128, 255, 128, 255);
358
359 drawtext(vid_buf, 64, 192+32*CELLH, "A quick brown fox jumps over the lazy dog.", 255, 255, 255);
360 drawtext(vid_buf, 64, 192+33*CELLH, "A QUICK BROWN FOX JUMPS OVER THE LAZY DOG.", 255, 255, 255);
361 drawtext(vid_buf, 64, 192+34*CELLH, "0123456789 ~`!@#$%^&*()-=_+[]{}\\|;:'\",./<>?", 255, 255, 255);
362
363 drawtext(vid_buf, 64, 192+37*CELLH, "Use '+' (= key) and '-' to switch between characters", 255, 255, 255);
364 #ifdef EXTENDED_FONT
365 drawtext(vid_buf, 64, 192+38*CELLH, "Click near a line to modify top/left offset, or character width", 255, 255, 255);
366 drawtext(vid_buf, 64, 192+39*CELLH, "Use 'w' to toggle ignore width & auto draw next character flag, and 'c' to add / turn off font color", 255, 255, 255);
367 if (inputColor)
368 {
369 char temptext[64];
370 //drawtext(vid_buf, 64, 192+40*CELLH, "Due to extreme laziness, you must move the mouse and press enter to set the color of this icon", 255, 255, 255);
371 sprintf(temptext, "Press enter to set %s color to: %i", inputColor == 1 ? "red" : (inputColor == 2 ? "green" : "blue"), (x > 255) ? 255 : x);
372 drawtext(vid_buf, 64, 192+40*CELLH, temptext, 255, 255, 255);
373 }
374 #endif
375
376 drawchar(vid_buf, 32, 192+32*CELLH, c, 255, 255, 255);
377
378 sprintf(hex, "%02X", c);
379 drawtext(vid_buf, 32, 192+34*CELLH, hex, 255, 255, 255);
380 #ifdef EXTENDED_FONT
381 sprintf(hex, "flags: 0x%02X", flags[c]);
382 drawtext(vid_buf, 32, 192+35*CELLH, hex, 255, 255, 255);
383 sprintf(hex, "color: 0x%08X", color[c]);
384 drawtext(vid_buf, 32, 192+36*CELLH, hex, 255, 255, 255);
385 #endif
386
387 sdl_blit(0, 0, XRES, YRES, vid_buf, XRES*4);
388 }
389
390 f = fopen("font.bin", "wb");
391 fwrite(width, 1, 256, f);
392 #ifdef EXTENDED_FONT
393 fwrite(flags, 1, 256, f);
394 fwrite(color, 4, 256, f);
395 fwrite(top, 1, 256, f);
396 fwrite(left, 1, 256, f);
397 #endif
398 fwrite(font, CELLW*CELLH, 256, f);
399 fclose(f);
400 free(vid_buf);
401
402 return 0;
403 }
404
405 #endif
406