Mercurial > hg > dmlib
annotate vview.c @ 62:daeb5d4f6bad
Do include "dmtext.h" where necessary.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 01 Oct 2012 09:50:43 +0300 |
parents | 32250b436bca |
children |
rev | line source |
---|---|
0 | 1 #include "dmlib.h" |
2 #include "dmargs.h" | |
62
daeb5d4f6bad
Do include "dmtext.h" where necessary.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
3 #include "dmtext.h" |
0 | 4 |
5 #define DM_COLORS (256) | |
6 | |
7 char *optFilename = NULL, *optFontFile = "font.ttf"; | |
8 int optVFlags = SDL_SWSURFACE | SDL_HWPALETTE; | |
9 int optScrWidth = 640, optScrHeight = 480, optFontSize = 20, optScrDepth = 32; | |
10 BOOL optShowSurfaceInfo = FALSE; | |
11 | |
12 DMOptArg optList[] = { | |
13 { 0, '?', "help", "Show this help", OPT_NONE }, | |
14 { 2, 'v', "verbose", "Be more verbose", OPT_NONE }, | |
15 { 3, 'f', "full", "Fullscreen", OPT_NONE }, | |
16 { 4, 'h', "hw", "Use SDL hardware surface", OPT_NONE }, | |
17 { 5, 's', "size", "Initial window size/resolution -s 640x480", OPT_ARGREQ }, | |
18 { 6, 'd', "depth", "Color depth of mode/window in bits (8/15/16/32)", OPT_ARGREQ }, | |
19 { 7, 'i', "info", "Print out extra information on used SDL surfaces", OPT_NONE } | |
20 }; | |
21 | |
22 const int optListN = sizeof(optList) / sizeof(optList[0]); | |
23 | |
24 | |
25 void argShowHelp() | |
26 { | |
27 dmPrintBanner(stdout, dmProgName, "[options] <datafile>"); | |
28 dmArgsPrintHelp(stdout, optList, optListN); | |
29 } | |
30 | |
31 | |
32 BOOL argHandleOpt(const int optN, char *optArg, char *currArg) | |
33 { | |
34 switch (optN) { | |
35 case 0: | |
36 argShowHelp(); | |
37 exit(0); | |
38 break; | |
39 | |
40 case 2: | |
41 dmVerbosity++; | |
42 break; | |
43 | |
44 case 3: | |
45 optVFlags |= SDL_FULLSCREEN; | |
46 break; | |
47 | |
48 case 6: | |
49 if (optArg) | |
50 optScrDepth = atoi(optArg); | |
51 break; | |
52 | |
53 case 7: | |
54 optShowSurfaceInfo = TRUE; | |
55 break; | |
56 | |
57 case 5: | |
58 { | |
59 int w, h; | |
60 if (sscanf(optArg, "%dx%d", &w, &h) == 2) | |
61 { | |
62 if (w < 320 || h < 200 || w > 3200 || h > 3200) | |
63 { | |
64 dmError("Invalid width or height: %d x %d\n", w, h); | |
65 return FALSE; | |
66 } | |
67 optScrWidth = w; | |
68 optScrHeight = h; | |
69 } | |
70 else | |
71 { | |
72 dmError("Invalid size argument '%s'.\n", optArg); | |
73 return FALSE; | |
74 } | |
75 } | |
76 break; | |
77 | |
78 default: | |
79 dmError("Unknown option '%s'.\n", currArg); | |
80 return FALSE; | |
81 } | |
82 | |
83 return TRUE; | |
84 } | |
85 | |
86 | |
87 BOOL argHandleFile(char *filename) | |
88 { | |
89 if (optFilename == NULL) | |
90 { | |
91 optFilename = dm_strdup(filename); | |
92 return TRUE; | |
93 } | |
94 else | |
95 { | |
96 dmError("Too many filenames specified ('%s')\n", filename); | |
97 return FALSE; | |
98 } | |
99 } | |
100 | |
101 void DM_MakePalette(SDL_Color *pal) | |
102 { | |
103 int n; | |
104 | |
105 for (n = 0; n < 64; n++) | |
106 { | |
107 pal[n].r = n * 2; | |
108 pal[n].g = 0; | |
109 pal[n].b = 0; | |
110 } | |
111 | |
112 for (n = 64; n < 128; n++) | |
113 { | |
114 pal[n].r = n * 2; | |
115 pal[n].g = (n - 64) * 4; | |
116 pal[n].b = (n - 64) * 4; | |
117 } | |
118 | |
119 for (n = 128; n < 192; n++) | |
120 { | |
121 pal[n].r = (255 - n) * 4; | |
122 pal[n].g = (255 - n) * 2; | |
123 pal[n].b = (255 - n) * 2; | |
124 } | |
125 | |
126 for (n = 192; n < 256; n++) | |
127 { | |
128 pal[n].r = 0; | |
129 pal[n].g = (255 - n) * 2; | |
130 pal[n].b = (255 - n) * 2; | |
131 } | |
132 } | |
133 | |
134 | |
135 void DM_CreatePaletteFrom(SDL_Color *pal, Uint8 *buf) | |
136 { | |
137 int n, offs; | |
138 for (offs = n = 0; n < DM_COLORS; n++) | |
139 { | |
140 pal[n].r = buf[offs++]; | |
141 pal[n].g = buf[offs++]; | |
142 pal[n].b = buf[offs++]; | |
143 } | |
144 } | |
145 | |
146 void printSurface(FILE *f, SDL_Surface *s, const char *name) | |
147 { | |
148 if (!optShowSurfaceInfo || s == NULL) return; | |
149 | |
150 fprintf(f, "\nSDL_Surface[%p]: %s:\n" | |
151 " flags : 0x%08x\n" | |
152 " format : %p\n", s, name, s->flags, s->format); | |
153 if (s->format != NULL) | |
154 { | |
155 SDL_PixelFormat *pf = s->format; | |
156 fprintf(f, | |
157 " palette : %p\n" | |
158 " BitsPerPixel : %d\n" | |
159 " BytesPerPixel : %d\n" | |
160 " colorkey : %d (%08x)\n" | |
161 " alpha : %d\n", | |
162 pf->palette, | |
163 pf->BitsPerPixel, | |
164 pf->BytesPerPixel, | |
165 pf->colorkey, pf->colorkey, | |
166 pf->alpha); | |
167 | |
168 fprintf(f, | |
169 " R/G/B/A loss : %d / %d / %d / %d\n" | |
170 " R/G/B/A shift : %d / %d / %d / %d\n" | |
171 " R/G/B/A mask : %08x / %08x / %08x / %08x\n", | |
172 pf->Rloss , pf->Gloss , pf->Bloss , pf->Aloss, | |
173 pf->Rshift , pf->Gshift , pf->Bshift , pf->Ashift, | |
174 pf->Rmask , pf->Gmask , pf->Bmask , pf->Amask | |
175 ); | |
176 } | |
177 fprintf(f, | |
178 " W x H : %d x %d\n" | |
179 " pitch : %d bytes\n" | |
180 " pixels : %p\n\n", | |
181 s->w, s->h, | |
182 s->pitch, | |
183 s->pixels); | |
184 } | |
185 | |
186 BOOL DM_InitializeVideo(SDL_Surface **screen) | |
187 { | |
188 *screen = SDL_SetVideoMode(optScrWidth, optScrHeight, optScrDepth, optVFlags | SDL_RESIZABLE); | |
189 if (*screen == NULL) | |
190 { | |
191 dmError("Can't SDL_SetVideoMode(): %s\n", SDL_GetError()); | |
192 return FALSE; | |
193 } | |
194 printSurface(stdout, *screen, "screen"); | |
195 return TRUE; | |
196 } | |
197 | |
198 void DM_UnRLE(Uint8 *dst, Uint8 **udata, const Uint8 *dp, const int rleMarker, const Uint8 *de) | |
199 { | |
200 Uint8 *data = *udata; | |
201 | |
202 while (data < dp && dst < de) | |
203 { | |
204 int c = *data++; | |
205 if ((c & rleMarker) == rleMarker) | |
206 { | |
207 int cnt = c & (0xff ^ rleMarker); | |
208 c = *data++; | |
209 while (cnt-- && dst < de) | |
210 *dst++ = c; | |
211 } | |
212 else | |
213 *dst++ = c; | |
214 } | |
215 | |
216 *udata = data; | |
217 } | |
218 | |
219 void DM_Redraw(SDL_Surface *screen, Uint8 *data, int skip, int useRLE, int rleMarker) | |
220 { | |
221 Uint8 *pix = screen->pixels; | |
222 | |
223 if (useRLE) | |
224 { | |
225 const int tmpmax = screen->w * 64; | |
226 Uint8 *tmp = dmMalloc(tmpmax); | |
227 const Uint8 *dp = data + (screen->w * screen->h); | |
228 | |
229 if (skip > tmpmax) | |
230 skip = tmpmax; | |
231 | |
232 if (useRLE == 1) | |
233 { | |
234 int yc; | |
235 for (yc = 0; yc < screen->h; yc++) | |
236 { | |
237 memset(tmp, 0xff, tmpmax); | |
238 DM_UnRLE(tmp, &data, dp, rleMarker, tmp + tmpmax); | |
239 memcpy(pix, tmp, screen->w); | |
240 pix += screen->pitch; | |
241 } | |
242 } | |
243 else | |
244 if (useRLE == 2) | |
245 { | |
246 int yc; | |
247 for (yc = 0; yc < screen->h; yc++) | |
248 { | |
249 memset(tmp, 0xff, tmpmax); | |
250 DM_UnRLE(tmp, &data, dp, rleMarker, tmp + skip); | |
251 memcpy(pix, tmp, screen->w); | |
252 pix += screen->pitch; | |
253 } | |
254 } | |
255 else | |
256 { | |
257 printf("useRLE=%d\n", useRLE); | |
258 } | |
259 | |
260 dmFree(tmp); | |
261 } | |
262 else | |
263 { | |
264 int yc; | |
265 for (yc = 0; yc < screen->h; yc++) | |
266 { | |
267 int xc; | |
268 for (xc = 0; xc < screen->w; xc++) | |
269 pix[xc] = *data++; | |
270 pix += screen->pitch; | |
271 } | |
272 } | |
273 } | |
274 | |
275 void DM_Random(SDL_Surface *screen, int q) | |
276 { | |
277 Uint8 *pix = screen->pixels; | |
278 int xc, yc; | |
279 | |
280 for (yc = 0; yc < screen->h; yc++) | |
281 { | |
282 Uint8 *dp = pix; | |
283 | |
284 for (xc = 0; xc < screen->w; xc++) | |
285 *dp++ = (xc * q + yc * q); | |
286 | |
287 pix += screen->pitch; | |
288 } | |
289 } | |
290 | |
291 void adjustValue(int *val, int min, int max, int delta) | |
292 { | |
293 *val += delta; | |
294 if (*val < min) *val = min; | |
295 else if (*val > max) *val = max; | |
296 } | |
297 | |
298 int main(int argc, char *argv[]) | |
299 { | |
300 SDL_Color pal[256]; | |
301 SDL_Surface *screen = NULL, *bmap = NULL; | |
302 TTF_Font *font = NULL; | |
303 SDL_Color fontcol={255,255,255,0}; | |
304 SDL_Event event; | |
305 Uint8 *scrData = NULL; | |
306 size_t scrSize = 0; | |
307 int scrWidth = 128, scrHeight = 128, scrPalOffs = 0, scrOffs = 0, scrSkip = 0; | |
308 BOOL initSDL = FALSE, initTTF = FALSE, | |
309 exitFlag, needRedraw, palChanged = FALSE, showTest = FALSE, useRLE = FALSE, | |
310 showHex = FALSE, scrPalette = FALSE, scrChanged; | |
311 | |
312 // Initialize | |
313 dmInitProg("vtest", "vtester", "0.1", NULL, NULL); | |
314 | |
315 // Parse arguments | |
316 if (!dmArgsProcess(argc, argv, optList, optListN, | |
317 argHandleOpt, argHandleFile, FALSE)) | |
318 exit(1); | |
319 | |
320 | |
321 if (optFilename == NULL) | |
322 { | |
323 dmError("No input file specified.\n"); | |
324 goto error_exit; | |
325 } | |
326 else | |
327 { | |
328 FILE *f = fopen(optFilename, "rb"); | |
329 if (f == NULL) | |
330 { | |
331 dmError("Could not open input file '%s'\n"); | |
332 goto error_exit; | |
333 } | |
334 fseek(f, 0L, SEEK_END); | |
335 scrSize = ftell(f); | |
336 fseek(f, 0L, SEEK_SET); | |
337 | |
338 if ((scrData = malloc(scrSize)) == NULL) | |
339 { | |
340 fclose(f); | |
341 dmError("Error allocating memory for data, %d bytes.\n", scrSize); | |
342 goto error_exit; | |
343 } | |
344 | |
345 fread(scrData, 1, scrSize, f); | |
346 fclose(f); | |
347 } | |
348 | |
349 | |
350 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) | |
351 { | |
352 dmError("Could not initialize SDL: %s\n", SDL_GetError()); | |
353 goto error_exit; | |
354 } | |
355 initSDL = TRUE; | |
356 | |
357 if (TTF_Init() < 0) | |
358 { | |
359 dmError("Could not initialize FreeType/TTF: %s\n", SDL_GetError()); | |
360 goto error_exit; | |
361 } | |
362 initTTF = TRUE; | |
363 | |
364 font = TTF_OpenFont(optFontFile, optFontSize); | |
365 if (font == NULL) | |
366 { | |
367 dmError("Could not load TTF font '%s' (%d): %s\n", | |
368 optFontFile, optFontSize, SDL_GetError()); | |
369 goto error_exit; | |
370 } | |
371 TTF_SetFontStyle(font, TTF_STYLE_NORMAL); | |
372 | |
373 if (!DM_InitializeVideo(&screen)) | |
374 goto error_exit; | |
375 | |
376 SDL_WM_SetCaption("Halleluja", "DMT"); | |
377 | |
378 exitFlag = FALSE; | |
379 scrChanged = palChanged = TRUE; | |
380 | |
381 while (!exitFlag) | |
382 { | |
383 while (SDL_PollEvent(&event)) | |
384 switch (event.type) | |
385 { | |
386 case SDL_KEYDOWN: | |
387 { | |
388 int amount = 10; | |
389 | |
390 if ((event.key.keysym.mod & KMOD_CTRL)) | |
391 amount = 50; | |
392 | |
393 if ((event.key.keysym.mod & KMOD_SHIFT)) | |
394 amount = 1; | |
395 | |
396 switch (event.key.keysym.sym) | |
397 { | |
398 case SDLK_ESCAPE: exitFlag = TRUE; break; | |
399 case SDLK_LEFT: adjustValue(&scrWidth, 0, 1024, -amount); scrChanged = TRUE; break; | |
400 case SDLK_RIGHT: adjustValue(&scrWidth, 0, 1024, amount); scrChanged = TRUE; break; | |
401 case SDLK_UP: adjustValue(&scrHeight, 0, 1024, -amount); scrChanged = TRUE; break; | |
402 case SDLK_DOWN: adjustValue(&scrHeight, 0, 1024, amount); scrChanged = TRUE; break; | |
403 | |
404 case SDLK_F1: | |
405 scrPalette = !scrPalette; | |
406 palChanged = TRUE; | |
407 break; | |
408 | |
409 case SDLK_F2: | |
410 showTest = !showTest; | |
411 break; | |
412 | |
413 case SDLK_F3: adjustValue(&scrPalOffs, 0, scrSize - 256 * 3, -amount); palChanged = TRUE; break; | |
414 case SDLK_F4: adjustValue(&scrPalOffs, 0, scrSize - 256 * 3, amount); palChanged = TRUE; break; | |
415 | |
416 case SDLK_F5: adjustValue(&scrOffs, 0, scrSize, -amount); break; | |
417 case SDLK_F6: adjustValue(&scrOffs, 0, scrSize, amount); break; | |
418 | |
419 case SDLK_F7: adjustValue(&scrSkip, 0, scrSize, -amount); break; | |
420 case SDLK_F8: adjustValue(&scrSkip, 0, scrSize, amount); break; | |
421 | |
422 case SDLK_F9: | |
423 showHex = !showHex; | |
424 break; | |
425 | |
426 case SDLK_r: | |
427 useRLE = (useRLE + 1) % 3; | |
428 break; | |
429 | |
430 default: | |
431 break; | |
432 } | |
433 } | |
434 | |
435 needRedraw = TRUE; | |
436 break; | |
437 | |
438 case SDL_VIDEORESIZE: | |
439 optScrWidth = event.resize.w; | |
440 optScrHeight = event.resize.h; | |
441 | |
442 if (!DM_InitializeVideo(&screen)) | |
443 goto error_exit; | |
444 | |
445 needRedraw = TRUE; | |
446 break; | |
447 | |
448 case SDL_VIDEOEXPOSE: | |
449 needRedraw = TRUE; | |
450 break; | |
451 | |
452 case SDL_QUIT: | |
453 exit(0); | |
454 } | |
455 | |
456 if (scrChanged) | |
457 { | |
458 SDL_FreeSurface(bmap); | |
459 bmap = SDL_CreateRGBSurface(SDL_SWSURFACE, scrWidth, scrHeight, 8, 0, 0, 0, 0); | |
460 printSurface(stdout, bmap, "bmap"); | |
461 needRedraw = TRUE; | |
462 scrChanged = FALSE; | |
463 palChanged = TRUE; | |
464 } | |
465 | |
466 if (palChanged) | |
467 { | |
468 if (scrPalette) | |
469 DM_CreatePaletteFrom(pal, scrData + scrPalOffs); | |
470 else | |
471 DM_MakePalette(pal); | |
472 | |
473 SDL_SetColors(bmap, pal, 0, DM_COLORS); | |
474 palChanged = FALSE; | |
475 } | |
476 | |
477 if (needRedraw) | |
478 { | |
479 if (SDL_MUSTLOCK(screen) != 0 && SDL_LockSurface(screen) != 0) | |
480 { | |
481 dmError("Can't lock surface.\n"); | |
482 goto error_exit; | |
483 } | |
484 | |
485 dmClearSurface(screen, dmMapRGB(screen, 255, 255, 150)); | |
486 dmFillRect(screen, 0, 0, screen->w, TTF_FontHeight(font) + 10, dmMapRGB(screen, 50, 50, 150)); | |
487 dmDrawTTFText(screen, font, fontcol, 5, 5, "%3d x %3d @ 0x%08x, skip=%d/0x%x", | |
488 scrWidth, scrHeight, scrOffs, scrSkip, scrSkip); | |
489 | |
490 dmFillRect(screen, 0, screen->h - TTF_FontHeight(font) - 10, screen->w, screen->h, dmMapRGB(screen, 150, 50, 50)); | |
491 if (scrPalette) | |
492 { | |
493 dmDrawTTFText(screen, font, fontcol, 5, screen->h - TTF_FontHeight(font) - 5, | |
494 "Palette offset 0x%08x/%08x", scrPalOffs, scrSize); | |
495 } | |
496 else | |
497 { | |
498 dmDrawTTFText(screen, font, fontcol, 5, screen->h - TTF_FontHeight(font) - 5, | |
499 "Generated palette."); | |
500 } | |
501 dmDrawTTFText(screen, font, fontcol, 450, screen->h - TTF_FontHeight(font) - 5, | |
502 "useRLE=%d", useRLE); | |
503 | |
504 | |
505 if (showTest) | |
506 DM_Random(bmap, SDL_GetTicks() / 100); | |
507 else | |
508 DM_Redraw(bmap, scrData + scrOffs, scrSkip, useRLE, 0xc0); | |
509 | |
510 // float f = SDL_GetTicks() / 200.0f; | |
511 // dmScaledBlitSurfaceAny(bmap, sin(f) * 50, 40, screen->w + 100 * cos(f), screen->h - 80, screen, DMD_NONE); | |
512 dmScaledBlitSurfaceAny(bmap, 5, 40, screen->w - 10, screen->h - 80, screen, DMD_NONE); | |
513 | |
514 if (showHex) | |
515 { | |
516 int w = 350, h = screen->h - 50; | |
517 int i, x = screen->w - w, y = 25; | |
518 int fh = TTF_FontHeight(font); | |
519 | |
520 dmFillRect(screen, screen->w - 350, - 5, w, h, dmMapRGB(screen, 50, 50, 50)); | |
521 | |
522 dmDrawTTFText(screen, font, fontcol, x, y, "Palette hexdump"); | |
523 y += fh + 5; | |
524 for (i = 0; i < 16; i++) | |
525 { | |
526 int offs = scrPalOffs + i * 3; | |
527 dmDrawTTFText(screen, font, fontcol, x, y + fh * i, "%04x: %02x %02x %02x | '%c' '%c' '%c'", | |
528 offs, scrData[offs], scrData[offs+1], scrData[offs+2], | |
529 scrData[offs], scrData[offs+1], scrData[offs+2]); | |
530 } | |
531 } | |
532 | |
533 if (SDL_MUSTLOCK(screen) != 0) | |
534 SDL_UnlockSurface(screen); | |
535 | |
536 SDL_Flip(screen); | |
537 needRedraw = FALSE; | |
538 } | |
539 | |
540 SDL_Delay(10); | |
541 } | |
542 | |
543 | |
544 error_exit: | |
545 if (screen) | |
546 SDL_FreeSurface(screen); | |
547 | |
548 if (font) | |
549 TTF_CloseFont(font); | |
550 | |
551 if (initSDL) | |
552 SDL_Quit(); | |
553 | |
554 if (initTTF) | |
555 TTF_Quit(); | |
556 | |
557 return 0; | |
558 } |