Mercurial > hg > dmlib
comparison gfxconv.c @ 473:73bfe73553eb
Implement palette remapping option for image outputs.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 07 Nov 2012 00:55:43 +0200 |
parents | 3f5163208ef6 |
children | 95d1facfdb77 |
comparison
equal
deleted
inserted
replaced
472:0359697eeb46 | 473:73bfe73553eb |
---|---|
13 #include "libgfx.h" | 13 #include "libgfx.h" |
14 #include "lib64gfx.h" | 14 #include "lib64gfx.h" |
15 | 15 |
16 //#define UNFINISHED 1 | 16 //#define UNFINISHED 1 |
17 | 17 |
18 #define DM_MAX_COLORS 256 | |
19 | |
20 #define ASC_NBITS 8 | |
21 #define ASC_NCOLORS 4 | |
22 static const char dmASCIIPalette[ASC_NCOLORS] = ".:X#"; | |
23 | |
18 enum | 24 enum |
19 { | 25 { |
20 FFMT_AUTO = 0, | 26 FFMT_AUTO = 0, |
21 | 27 |
22 FFMT_ASCII, | 28 FFMT_ASCII, |
89 }; | 95 }; |
90 | 96 |
91 static const int nconvFormatList = sizeof(convFormatList) / sizeof(convFormatList[0]); | 97 static const int nconvFormatList = sizeof(convFormatList) / sizeof(convFormatList[0]); |
92 | 98 |
93 | 99 |
94 #define ASC_NBITS 8 | 100 typedef struct |
95 #define ASC_NCOLORS 4 | 101 { |
96 static const char dmASCIIPalette[ASC_NCOLORS] = ".:X#"; | 102 BOOL triplet; |
103 DMColor color; | |
104 int from, to; | |
105 } DMMapValue; | |
106 | |
97 | 107 |
98 | 108 |
99 char *optInFilename = NULL, | 109 char *optInFilename = NULL, |
100 *optOutFilename = NULL; | 110 *optOutFilename = NULL; |
101 int optInFormat = FFMT_AUTO, | 111 int optInFormat = FFMT_AUTO, |
105 optItemCount = -1, | 115 optItemCount = -1, |
106 optPlanedWidth = 1, | 116 optPlanedWidth = 1, |
107 optForcedFormat = -1; | 117 optForcedFormat = -1; |
108 int optInSkip = 0; | 118 int optInSkip = 0; |
109 BOOL optInMulticolor = FALSE, | 119 BOOL optInMulticolor = FALSE, |
110 optSequential = FALSE; | 120 optSequential = FALSE, |
121 optRemapColors = FALSE; | |
122 int optNRemapTable = 0; | |
123 DMMapValue optRemapTable[DM_MAX_COLORS]; | |
111 int optColors[C64_MAX_COLORS]; | 124 int optColors[C64_MAX_COLORS]; |
112 | 125 |
113 DMImageSpec optSpec = | 126 DMImageSpec optSpec = |
114 { | 127 { |
115 .scale = 1, | 128 .scale = 1, |
125 { 15, 'v', "verbose", "Increase verbosity", OPT_NONE }, | 138 { 15, 'v', "verbose", "Increase verbosity", OPT_NONE }, |
126 { 3, 'o', "output", "Output filename", OPT_ARGREQ }, | 139 { 3, 'o', "output", "Output filename", OPT_ARGREQ }, |
127 { 1, 'i', "informat", "Set input format ([s]prite, [c]har, [b]itmap, [i]mage)", OPT_ARGREQ }, | 140 { 1, 'i', "informat", "Set input format ([s]prite, [c]har, [b]itmap, [i]mage)", OPT_ARGREQ }, |
128 { 2, 'm', "multicolor", "Input is multicolor", OPT_NONE }, | 141 { 2, 'm', "multicolor", "Input is multicolor", OPT_NONE }, |
129 { 4, 's', "skip", "Skip bytes in input", OPT_ARGREQ }, | 142 { 4, 's', "skip", "Skip bytes in input", OPT_ARGREQ }, |
130 { 5, 'f', "format", "Output format (see list below)", OPT_ARGREQ }, | 143 { 5, 'f', "format", "Output format (see --formats)", OPT_ARGREQ }, |
144 { 17, 'F', "formats", "Output format (see list below)", OPT_NONE }, | |
131 { 8, 'q', "sequential", "Output sequential files (image output only)", OPT_NONE }, | 145 { 8, 'q', "sequential", "Output sequential files (image output only)", OPT_NONE }, |
132 { 6, 'c', "colormap", "Color mappings (see below for information)", OPT_ARGREQ }, | 146 { 6, 'c', "colormap", "Color mappings (see below for information)", OPT_ARGREQ }, |
133 { 7, 'n', "numitems", "How many 'items' to view (default: all)", OPT_ARGREQ }, | 147 { 7, 'n', "numitems", "How many 'items' to view (default: all)", OPT_ARGREQ }, |
134 { 9, 'S', "scale", "Scale output by x (image output only)", OPT_ARGREQ }, | 148 { 9, 'S', "scale", "Scale output by x (image output only)", OPT_ARGREQ }, |
135 { 10, 'b', "bformat", "Force input bitmap format (see below)", OPT_ARGREQ }, | 149 { 10, 'b', "bformat", "Force input bitmap format (see below)", OPT_ARGREQ }, |
136 { 11, 'w', "width", "Item width (number of items per row, min 1)", OPT_ARGREQ }, | 150 { 11, 'w', "width", "Item width (number of items per row, min 1)", OPT_ARGREQ }, |
137 { 12, 'P', "paletted", "Use indexed/paletted output (png, pcx output only)", OPT_NONE }, | 151 { 12, 'P', "paletted", "Use indexed/paletted output (png, pcx output only)", OPT_NONE }, |
138 { 13, 'B', "bplanes", "Bits per pixel OR # of bitplanes (certain output formats)", OPT_ARGREQ }, | 152 { 13, 'B', "bplanes", "Bits per pixel OR # of bitplanes (certain output formats)", OPT_ARGREQ }, |
139 { 14, 'I', "interleave", "Interleave scanlines (default: output whole planes)", OPT_NONE }, | 153 { 14, 'I', "interleave", "Interleave scanlines (default: output whole planes)", OPT_NONE }, |
154 { 16, 'R', "remap", "Remap output image colors (-R <(#RRGGBB|index):index>[,<..>] | -R @map.txt)", OPT_ARGREQ }, | |
140 }; | 155 }; |
141 | 156 |
142 static const int optListN = sizeof(optList) / sizeof(optList[0]); | 157 static const int optListN = sizeof(optList) / sizeof(optList[0]); |
143 | 158 |
144 | 159 |
145 void argShowHelp() | 160 void argShowFormats() |
146 { | 161 { |
147 int i; | 162 int i; |
148 | |
149 dmPrintBanner(stdout, dmProgName, "[options] <input file>"); | |
150 dmArgsPrintHelp(stdout, optList, optListN); | |
151 | 163 |
152 printf("\n" | 164 printf("\n" |
153 "Available input/output formats:\n" | 165 "Available input/output formats:\n" |
154 " EXT | I | O | Description\n" | 166 " EXT | I | O | Description\n" |
155 "------+---+---+--------------------------------\n" | 167 "------+---+---+--------------------------------\n" |
172 printf("%3d | %-5s | %-15s | %s\n", | 184 printf("%3d | %-5s | %-15s | %s\n", |
173 i, fmt->extension, | 185 i, fmt->extension, |
174 dmC64ImageTypeNames[fmt->type], | 186 dmC64ImageTypeNames[fmt->type], |
175 fmt->name); | 187 fmt->name); |
176 } | 188 } |
189 } | |
190 | |
191 | |
192 void argShowHelp() | |
193 { | |
194 dmPrintBanner(stdout, dmProgName, "[options] <input file>"); | |
195 dmArgsPrintHelp(stdout, optList, optListN); | |
177 | 196 |
178 printf( | 197 printf( |
179 "\n" | 198 "\n" |
180 "Color map definitions are used for ANSI and image output, to declare what\n" | 199 "Color map definitions are used for ANSI and image output, to declare what\n" |
181 "output colors of the C64 palette are used for each single color/multi color\n" | 200 "output colors of the C64 palette are used for each single color/multi color\n" |
182 "bit-combination. For example, if the input is multi color sprite or char,\n" | 201 "bit-combination. For example, if the input is multi color sprite or char,\n" |
183 "you can define colors like: -c 0:8:3:15 .. for single color: -c 0:1\n" | 202 "you can define colors like: -c 0,8,3,15 .. for single color: -c 0,1\n" |
184 "The numbers are palette indexes, and the order is for bit(pair)-values\n" | 203 "The numbers are palette indexes, and the order is for bit(pair)-values\n" |
185 "00, 01, 10, 11 (multi color) and 0, 1 (single color). NOTICE! 255 is the\n" | 204 "00, 01, 10, 11 (multi color) and 0, 1 (single color). NOTICE! 255 is the\n" |
186 "special color that can be used for transparency.\n" | 205 "special color that can be used for transparency.\n" |
187 ); | 206 ); |
188 } | 207 } |
221 } | 240 } |
222 return FALSE; | 241 return FALSE; |
223 } | 242 } |
224 | 243 |
225 | 244 |
245 static BOOL dmParseMapOptionMapItem(char *opt, DMMapValue *value, const int nmax, const char *msg) | |
246 { | |
247 char *split = strchr(opt, ':'); | |
248 | |
249 if (split == NULL) | |
250 { | |
251 dmError("Invalid %s value '%s', expected <(#|%)RRGGBB|[$|0x]index>:<[$|0x]index>.\n", msg, opt); | |
252 return FALSE; | |
253 } | |
254 | |
255 *split = 0; | |
256 | |
257 if (*opt == '#' || *opt == '%') | |
258 { | |
259 int colR, colG, colB, colA; | |
260 | |
261 if (sscanf(opt + 1, "%2x%2x%2x%2x", &colR, &colG, &colB, &colA) != 4 && | |
262 sscanf(opt + 1, "%2X%2X%2X%2X", &colR, &colG, &colB, &colA) != 4) | |
263 { | |
264 colA = 0; | |
265 if (sscanf(opt + 1, "%2x%2x%2x", &colR, &colG, &colB) != 3 && | |
266 sscanf(opt + 1, "%2X%2X%2X", &colR, &colG, &colB) != 3) | |
267 { | |
268 dmError("Invalid %s value '%s', expected a hex triplet after #.\n", msg, opt); | |
269 return FALSE; | |
270 } | |
271 } | |
272 value->color.r = colR; | |
273 value->color.g = colG; | |
274 value->color.b = colB; | |
275 value->color.a = colA; | |
276 value->triplet = TRUE; | |
277 } | |
278 else | |
279 { | |
280 if (!dmGetIntVal(opt, &value->from)) | |
281 { | |
282 dmError("Invalid %s value '%s', could not parse.\n", msg, opt); | |
283 return FALSE; | |
284 } | |
285 value->triplet = FALSE; | |
286 } | |
287 | |
288 if (!dmGetIntVal(split + 1, &value->to)) | |
289 { | |
290 dmError("Invalid %s value '%s', could not parse.\n", msg, opt); | |
291 return FALSE; | |
292 } | |
293 | |
294 if (!value->triplet && (value->from < 0 || value->from > 255)) | |
295 { | |
296 dmError("Invalid %s map source color index value %d.\n", msg, value->from); | |
297 return FALSE; | |
298 } | |
299 | |
300 if (value->to < 0 || value->to > nmax) | |
301 { | |
302 dmError("Invalid %s map destination color index value %d.\n", msg, value->to); | |
303 return FALSE; | |
304 } | |
305 | |
306 return TRUE; | |
307 } | |
308 | |
309 | |
310 static BOOL dmParseMapOptionItem(char *opt, char *end, void *pvalue, const int index, const int nmax, const BOOL requireIndex, const char *msg) | |
311 { | |
312 // Trim whitespace | |
313 if (end != NULL) | |
314 { | |
315 *end = 0; | |
316 for (end--; end > opt && *end && isspace(*end); end--) | |
317 *end = 0; | |
318 } | |
319 while (*opt && isspace(*opt)) opt++; | |
320 | |
321 // Parse item based on mode | |
322 if (requireIndex) | |
323 { | |
324 DMMapValue *value = (DMMapValue *) pvalue; | |
325 if (!dmParseMapOptionMapItem(opt, value, nmax, msg)) | |
326 return FALSE; | |
327 } | |
328 else | |
329 { | |
330 int *value = (int *) pvalue; | |
331 char *split = strchr(opt, ':'); | |
332 if (split != NULL) | |
333 { | |
334 dmError("Unexpected ':' in indexed %s '%s'.\n", msg, opt); | |
335 return FALSE; | |
336 } | |
337 | |
338 if (!dmGetIntVal(opt, &value[index])) | |
339 { | |
340 dmError("Invalid %s value '%s', could not parse.\n", msg, opt); | |
341 return FALSE; | |
342 } | |
343 } | |
344 | |
345 return TRUE; | |
346 } | |
347 | |
348 | |
349 BOOL dmParseMapOptionString(char *opt, void *values, int *nvalues, const int nmax, const BOOL requireIndex, const char *msg) | |
350 { | |
351 char *end, *start = opt; | |
352 | |
353 *nvalues = 0; | |
354 while (*nvalues < nmax && *start && (end = strchr(start, ',')) != NULL) | |
355 { | |
356 if (!dmParseMapOptionItem(start, end, values, *nvalues, nmax, requireIndex, msg)) | |
357 return FALSE; | |
358 | |
359 start = end + 1; | |
360 (*nvalues)++; | |
361 } | |
362 | |
363 if (*start && *nvalues < nmax) | |
364 { | |
365 if (!dmParseMapOptionItem(start, NULL, values, *nvalues, nmax, requireIndex, msg)) | |
366 return FALSE; | |
367 | |
368 (*nvalues)++; | |
369 } | |
370 | |
371 return TRUE; | |
372 } | |
373 | |
374 | |
375 int dmParseColorRemapFile(const char *filename, DMMapValue *values, int *nvalue, const int nmax) | |
376 { | |
377 FILE *fp; | |
378 char line[512]; | |
379 int res = DMERR_OK; | |
380 | |
381 if ((fp = fopen(filename, "r")) == NULL) | |
382 { | |
383 res = dmGetErrno(); | |
384 dmError("Could not open color remap file '%s' for reading, %d: %s\n", | |
385 res, dmErrorStr(res)); | |
386 return res; | |
387 } | |
388 | |
389 while (fgets(line, sizeof(line), fp)) | |
390 { | |
391 char *start = line; | |
392 while (*start && isspace(*start)) start++; | |
393 | |
394 if (*start != 0 && *start != ';') | |
395 { | |
396 if (!dmParseMapOptionMapItem(line, &values[*nvalue], nmax, "mapping file")) | |
397 goto error; | |
398 else | |
399 { | |
400 (*nvalue)++; | |
401 if (*nvalue >= nmax) | |
402 { | |
403 dmError("Too many mapping pairs in '%s', maximum is %d.\n", | |
404 filename, nmax); | |
405 goto error; | |
406 } | |
407 } | |
408 } | |
409 } | |
410 | |
411 error: | |
412 fclose(fp); | |
413 return res; | |
414 } | |
415 | |
416 | |
226 BOOL argHandleOpt(const int optN, char *optArg, char *currArg) | 417 BOOL argHandleOpt(const int optN, char *optArg, char *currArg) |
227 { | 418 { |
228 switch (optN) | 419 switch (optN) |
229 { | 420 { |
230 case 0: | 421 case 0: |
231 argShowHelp(); | 422 argShowHelp(); |
423 exit(0); | |
424 break; | |
425 | |
426 case 17: | |
427 argShowFormats(); | |
232 exit(0); | 428 exit(0); |
233 break; | 429 break; |
234 | 430 |
235 case 15: | 431 case 15: |
236 dmVerbosity++; | 432 dmVerbosity++; |
281 } | 477 } |
282 break; | 478 break; |
283 | 479 |
284 case 6: | 480 case 6: |
285 { | 481 { |
286 int index = 0, tmp; | 482 int index, ncolors; |
287 char *s, *p = optArg; | 483 if (!dmParseMapOptionString(optArg, optColors, |
288 | 484 &ncolors, C64_MAX_COLORS, FALSE, "color table option")) |
289 while (index < C64_MAX_COLORS && *p != 0 && (s = strchr(p, ':')) != NULL) | 485 return FALSE; |
290 { | 486 |
291 *s = 0; | |
292 if (sscanf(p, "%d", &tmp) == 1) | |
293 optColors[index++] = tmp; | |
294 p = s + 1; | |
295 } | |
296 | |
297 if (*p && index < C64_MAX_COLORS) | |
298 { | |
299 if (sscanf(p, "%d", &tmp) == 1) | |
300 optColors[index++] = tmp; | |
301 } | |
302 | |
303 dmMsg(1, "Set color table: "); | 487 dmMsg(1, "Set color table: "); |
304 for (tmp = 0; tmp < index; tmp++) | 488 for (index = 0; index < ncolors; index++) |
305 { | 489 { |
306 dmPrint(1, "[%d:%d]%s", | 490 dmPrint(1, "[%d:%d]%s", |
307 tmp, optColors[tmp], | 491 index, optColors[index], |
308 (tmp < index - 1) ? ", " : ""); | 492 (index < ncolors) ? ", " : ""); |
309 } | 493 } |
310 dmPrint(1, "\n"); | 494 dmPrint(1, "\n"); |
311 } | 495 } |
312 break; | 496 break; |
313 | 497 |
363 } | 547 } |
364 break; | 548 break; |
365 | 549 |
366 case 14: | 550 case 14: |
367 optSpec.interleave = TRUE; | 551 optSpec.interleave = TRUE; |
552 break; | |
553 | |
554 | |
555 case 16: | |
556 if (optArg[0] == '@') | |
557 { | |
558 if (optArg[1] != 0) | |
559 { | |
560 int res; | |
561 if ((res = dmParseColorRemapFile(optArg + 1, | |
562 optRemapTable, &optNRemapTable, DM_MAX_COLORS)) != DMERR_OK) | |
563 return FALSE; | |
564 } | |
565 else | |
566 { | |
567 dmError("No remap filename given.\n"); | |
568 return FALSE; | |
569 } | |
570 } | |
571 else | |
572 { | |
573 if (!dmParseMapOptionString(optArg, optRemapTable, | |
574 &optNRemapTable, DM_MAX_COLORS, TRUE, "color remap option")) | |
575 return FALSE; | |
576 } | |
577 | |
578 optRemapColors = TRUE; | |
368 break; | 579 break; |
369 | 580 |
370 default: | 581 default: |
371 dmError("Unknown option '%s'.\n", currArg); | 582 dmError("Unknown option '%s'.\n", currArg); |
372 return FALSE; | 583 return FALSE; |
516 return 0; | 727 return 0; |
517 } | 728 } |
518 #endif | 729 #endif |
519 | 730 |
520 | 731 |
732 int dmRemapImageColors(DMImage *image) | |
733 { | |
734 dmMsg(1, "Remapping %d output image colors.\n", optNRemapTable); | |
735 DMColor *npal = dmCalloc(image->ncolors, sizeof(DMColor)); | |
736 int *dpal = dmMalloc(image->ncolors * sizeof(int)); | |
737 BOOL *spal = dmCalloc(image->ncolors, sizeof(BOOL)); | |
738 int index, xc, yc; | |
739 | |
740 if (npal == NULL || spal == NULL || dpal == NULL) | |
741 { | |
742 dmError("Could not allocate memory for remapped palette.\n"); | |
743 return DMERR_MALLOC; | |
744 } | |
745 | |
746 for (index = 0; index < image->ncolors; index++) | |
747 dpal[index] = -1; | |
748 | |
749 // Find and mark mapped colors | |
750 for (index = 0; index < optNRemapTable; index++) | |
751 { | |
752 DMMapValue *map = &optRemapTable[index]; | |
753 if (map->triplet) | |
754 { | |
755 BOOL found = FALSE; | |
756 int n; | |
757 for (n = 0; n < image->ncolors; n++) | |
758 { | |
759 if (memcmp(&(image->pal[n]), &(map->color), sizeof(DMColor)) == 0) | |
760 { | |
761 dmMsg(3, "RGBA match #%02x%02x%02x%02x: %d -> %d\n", | |
762 map->color.r, map->color.g, map->color.b, map->color.a, | |
763 n, | |
764 map->to); | |
765 | |
766 dpal[map->to] = n; | |
767 spal[n] = TRUE; | |
768 found = TRUE; | |
769 } | |
770 } | |
771 | |
772 if (!found) | |
773 { | |
774 dmMsg(3, "No RGBA match found for map index %d, #%02x%02x%02x%02x\n", | |
775 index, | |
776 map->color.r, map->color.g, map->color.b, map->color.a); | |
777 } | |
778 } | |
779 else | |
780 { | |
781 dmMsg(3, "Map index %d: %d -> %d\n", | |
782 index, | |
783 map->from, map->to); | |
784 | |
785 dpal[map->to] = map->from; | |
786 spal[map->from] = TRUE; | |
787 } | |
788 } | |
789 | |
790 // Fill in the rest | |
791 dmMsg(3, "Placing non-mapped palette entries.\n"); | |
792 for (index = 0; index < image->ncolors; index++) | |
793 { | |
794 if (dpal[index] < 0) | |
795 { | |
796 int src; | |
797 for (src = 0; src < image->ncolors; src++) | |
798 { | |
799 if (!spal[src]) | |
800 { | |
801 dpal[index] = src; | |
802 spal[src] = TRUE; | |
803 break; | |
804 } | |
805 } | |
806 } | |
807 } | |
808 | |
809 // Copy palette entries | |
810 dmMsg(3, "Creating new palette.\n"); | |
811 for (index = 0; index < image->ncolors; index++) | |
812 { | |
813 if (dpal[index] >= 0 && dpal[index] < image->ncolors) | |
814 { | |
815 memcpy(&npal[index], &(image->pal[dpal[index]]), sizeof(DMColor)); | |
816 } | |
817 } | |
818 | |
819 // Remap image | |
820 dmMsg(3, "Remapping image.\n"); | |
821 for (yc = 0; yc < image->height; yc++) | |
822 { | |
823 Uint8 *dp = image->data + image->pitch * yc; | |
824 for (xc = 0; xc < image->width; xc++) | |
825 { | |
826 Uint8 col = dp[xc]; | |
827 if (col < image->ncolors && dpal[col] >= 0 && dpal[col] < image->ncolors) | |
828 { | |
829 dp[xc] = dpal[col]; | |
830 } | |
831 } | |
832 } | |
833 | |
834 // Set new palette, free memory | |
835 dmFree(image->pal); | |
836 image->pal = npal; | |
837 dmFree(spal); | |
838 dmFree(dpal); | |
839 return DMERR_OK; | |
840 } | |
841 | |
842 | |
521 int dmWriteImage(const char *filename, DMImage *image, DMImageSpec *spec, int iformat, BOOL info) | 843 int dmWriteImage(const char *filename, DMImage *image, DMImageSpec *spec, int iformat, BOOL info) |
522 { | 844 { |
523 if (info) | 845 if (info) |
524 { | 846 { |
525 dmMsg(1, "Outputting %s image %d x %d -> %d x %d [%d]\n", | 847 dmMsg(1, "Outputting %s image %d x %d -> %d x %d [%d]\n", |
526 dmImageFormatList[iformat].fext, | 848 dmImageFormatList[iformat].fext, |
527 image->width, image->height, | 849 image->width, image->height, |
528 image->width * spec->scale, image->height * spec->scale, | 850 image->width * spec->scale, image->height * spec->scale, |
529 spec->scale); | 851 spec->scale); |
852 } | |
853 | |
854 // Perform color remapping | |
855 if (optRemapColors) | |
856 { | |
857 int res; | |
858 if ((res = dmRemapImageColors(image)) != DMERR_OK) | |
859 return res; | |
530 } | 860 } |
531 | 861 |
532 switch (iformat) | 862 switch (iformat) |
533 { | 863 { |
534 #ifdef DM_USE_LIBPNG | 864 #ifdef DM_USE_LIBPNG |
606 if (info) dmMsg(2, "%d bitplanes, %s interleave.\n", spec->nplanes, spec->interleave ? "with" : "without"); | 936 if (info) dmMsg(2, "%d bitplanes, %s interleave.\n", spec->nplanes, spec->interleave ? "with" : "without"); |
607 return dmWriteIFFMasterRAWImage(filename, image, spec); | 937 return dmWriteIFFMasterRAWImage(filename, image, spec); |
608 } | 938 } |
609 | 939 |
610 default: | 940 default: |
611 return FALSE; | 941 return DMERR_INVALID_DATA; |
612 } | 942 } |
613 } | 943 } |
614 | 944 |
615 | 945 |
616 int dmDumpSpritesAndChars(FILE *inFile) | 946 int dmDumpSpritesAndChars(FILE *inFile) |
804 size_t dataSize; | 1134 size_t dataSize; |
805 int i; | 1135 int i; |
806 | 1136 |
807 // Default colors | 1137 // Default colors |
808 for (i = 0; i < C64_MAX_COLORS; i++) | 1138 for (i = 0; i < C64_MAX_COLORS; i++) |
809 optColors[i] = i + 1; | 1139 optColors[i] = i; |
810 | 1140 |
811 // Initialize and parse commandline | 1141 // Initialize and parse commandline |
812 dmInitProg("gfxconv", "Simple graphics converter", "0.5", NULL, NULL); | 1142 dmInitProg("gfxconv", "Simple graphics converter", "0.6", NULL, NULL); |
813 | 1143 |
814 if (!dmArgsProcess(argc, argv, optList, optListN, | 1144 if (!dmArgsProcess(argc, argv, optList, optListN, |
815 argHandleOpt, argHandleFile, TRUE)) | 1145 argHandleOpt, argHandleFile, TRUE)) |
816 exit(1); | 1146 exit(1); |
817 | 1147 |