1 /*         ______   ___    ___
2  *        /\  _  \ /\_ \  /\_ \
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *
11  *      Grabber datafile -> asm converter for the Allegro library.
12  *
13  *      By Shawn Hargreaves.
14  *
15  *      See readme.txt for copyright information.
16  */
17 
18 
19 #define ALLEGRO_USE_CONSOLE
20 
21 #include <stdio.h>
22 #include <string.h>
23 #include <time.h>
24 
25 #include "allegro.h"
26 #include "allegro/internal/aintern.h"
27 #include "datedit.h"
28 
29 
30 /* unused callbacks for datedit.c */
datedit_msg(AL_CONST char * fmt,...)31 void datedit_msg(AL_CONST char *fmt, ...) { }
datedit_startmsg(AL_CONST char * fmt,...)32 void datedit_startmsg(AL_CONST char *fmt, ...) { }
datedit_endmsg(AL_CONST char * fmt,...)33 void datedit_endmsg(AL_CONST char *fmt, ...) { }
datedit_error(AL_CONST char * fmt,...)34 void datedit_error(AL_CONST char *fmt, ...) { }
datedit_ask(AL_CONST char * fmt,...)35 int datedit_ask(AL_CONST char *fmt, ...) { return 0; }
datedit_select(AL_CONST char * (* list_getter)(int index,int * list_size),AL_CONST char * fmt,...)36 int datedit_select(AL_CONST char *(*list_getter)(int index, int *list_size), AL_CONST char *fmt, ...) { return 0; }
37 
38 
39 /* this program is not portable! */
40 #ifdef ALLEGRO_I386
41 
42 
43 #ifndef ALLEGRO_ASM_PREFIX
44    #define ALLEGRO_ASM_PREFIX    ""
45 #endif
46 
47 
48 static int err = 0;
49 static int truecolor = FALSE;
50 static int convert_compiled_sprites = FALSE;
51 
52 static char prefix[80] = "";
53 
54 static char *infilename = NULL;
55 static char *outfilename = NULL;
56 static char *outfilenameheader = NULL;
57 static char *dataname = NULL;
58 static char default_dataname[]="data";
59 static char *password = NULL;
60 
61 static DATAFILE *data = NULL;
62 
63 static FILE *outfile = NULL;
64 static FILE *outfileheader = NULL;
65 
66 static void output_object(DATAFILE *object, char *name);
67 
68 
69 
usage(void)70 static void usage(void)
71 {
72    printf("\nDatafile -> asm conversion utility for Allegro " ALLEGRO_VERSION_STR ", " ALLEGRO_PLATFORM_STR "\n");
73    printf("By Shawn Hargreaves, " ALLEGRO_DATE_STR "\n\n");
74    printf("Usage: dat2s [options] inputfile.dat\n\n");
75    printf("Options:\n");
76    printf("\t'-o outputfile.s' sets the output file (default stdout)\n");
77    printf("\t'-h outputfile.h' sets the output header file (default none)\n");
78    printf("\t'-p prefix' sets the object name prefix string (default none)\n");
79    printf("\t'-S' converts COMPILED_SPRITEs to BITMAPs (default abort)\n");
80    printf("\t'-n name' gives a name for the datafile (default 'data')\n");
81    printf("\t'-007 password' sets the datafile password\n");
82 }
83 
84 
85 
write_data(unsigned char * data,int size)86 static void write_data(unsigned char *data, int size)
87 {
88    int c;
89 
90    for (c=0; c<size; c++) {
91       if ((c & 7) == 0)
92 	 fprintf(outfile, "\t.byte ");
93 
94       fprintf(outfile, "0x%02X", data[c]);
95 
96       if ((c<size-1) && ((c & 7) != 7))
97 	 fprintf(outfile, ", ");
98       else
99 	 fprintf(outfile, "\n");
100    }
101 }
102 
103 
104 
output_data(unsigned char * data,int size,char * name,char * type,int global)105 static void output_data(unsigned char *data, int size, char *name, char *type, int global)
106 {
107    fprintf(outfile, "# %s (%d bytes)\n", type, size);
108 
109    if (global)
110       fprintf(outfile, ".globl " ALLEGRO_ASM_PREFIX "%s%s\n", prefix, name);
111 
112    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s:\n", prefix, name);
113 
114    write_data(data, size);
115 
116    fprintf(outfile, "\n");
117 }
118 
119 
120 
output_bitmap(BITMAP * bmp,char * name,int global)121 static void output_bitmap(BITMAP *bmp, char *name, int global)
122 {
123    int bpp = bitmap_color_depth(bmp);
124    int bypp = (bpp + 7) / 8;
125    char buf[160];
126    int c;
127 
128    if (bpp > 8)
129       truecolor = TRUE;
130 
131    strcpy(buf, name);
132    strcat(buf, "_data");
133 
134    output_data(bmp->line[0], bmp->w*bmp->h*bypp, buf, "bitmap data", FALSE);
135 
136    fprintf(outfile, "# bitmap\n");
137 
138    if (global)
139       fprintf(outfile, ".globl " ALLEGRO_ASM_PREFIX "%s%s\n", prefix, name);
140 
141    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s:\n", prefix, name);
142 
143    fprintf(outfile, "\t.long %-16d# w\n", bmp->w);
144    fprintf(outfile, "\t.long %-16d# h\n", bmp->h);
145    fprintf(outfile, "\t.long %-16d# clip\n", -1);
146    fprintf(outfile, "\t.long %-16d# cl\n", 0);
147    fprintf(outfile, "\t.long %-16d# cr\n", bmp->w);
148    fprintf(outfile, "\t.long %-16d# ct\n", 0);
149    fprintf(outfile, "\t.long %-16d# cb\n", bmp->h);
150    fprintf(outfile, "\t.long %-16d# bpp\n", bpp);
151    fprintf(outfile, "\t.long %-16d# write_bank\n", 0);
152    fprintf(outfile, "\t.long %-16d# read_bank\n", 0);
153    fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_data\n", prefix, name);
154    fprintf(outfile, "\t.long %-16d# bitmap_id\n", 0);
155    fprintf(outfile, "\t.long %-16d# extra\n", 0);
156    fprintf(outfile, "\t.long %-16d# x_ofs\n", 0);
157    fprintf(outfile, "\t.long %-16d# y_ofs\n", 0);
158    fprintf(outfile, "\t.long %-16d# seg\n", 0);
159 
160    for (c=0; c<bmp->h; c++)
161       fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_data + %d\n", prefix, name, bmp->w*c*bypp);
162 
163    fprintf(outfile, "\n");
164 }
165 
166 
167 
output_sample(SAMPLE * spl,char * name)168 static void output_sample(SAMPLE *spl, char *name)
169 {
170    char buf[160];
171 
172    strcpy(buf, name);
173    strcat(buf, "_data");
174 
175    output_data(spl->data, spl->len * ((spl->bits==8) ? 1 : sizeof(short)) * ((spl->stereo) ? 2 : 1), buf, "waveform data", FALSE);
176 
177    fprintf(outfile, "# sample\n.globl " ALLEGRO_ASM_PREFIX "%s%s\n", prefix, name);
178    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s:\n", prefix, name);
179    fprintf(outfile, "\t.long %-16d# bits\n", spl->bits);
180    fprintf(outfile, "\t.long %-16d# stereo\n", spl->stereo);
181    fprintf(outfile, "\t.long %-16d# freq\n", spl->freq);
182    fprintf(outfile, "\t.long %-16d# priority\n", spl->priority);
183    fprintf(outfile, "\t.long %-16ld# length\n", spl->len);
184    fprintf(outfile, "\t.long %-16ld# loop_start\n", spl->loop_start);
185    fprintf(outfile, "\t.long %-16ld# loop_end\n", spl->loop_end);
186    fprintf(outfile, "\t.long %-16ld# param\n", spl->param);
187    fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_data\n\n", prefix, name);
188 }
189 
190 
191 
output_midi(MIDI * midi,char * name)192 static void output_midi(MIDI *midi, char *name)
193 {
194    char buf[160];
195    int c;
196 
197    for (c=0; c<MIDI_TRACKS; c++) {
198       if (midi->track[c].data) {
199 	 sprintf(buf, "%s_track_%d", name, c);
200 	 output_data(midi->track[c].data, midi->track[c].len, buf, "midi track", FALSE);
201       }
202    }
203 
204    fprintf(outfile, "# midi file\n.globl " ALLEGRO_ASM_PREFIX "%s%s\n", prefix, name);
205    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s:\n", prefix, name);
206    fprintf(outfile, "\t.long %-16d# divisions\n", midi->divisions);
207 
208    for (c=0; c<MIDI_TRACKS; c++)
209       if (midi->track[c].data)
210 	 fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_track_%d, %d\n", prefix, name, c, midi->track[c].len);
211       else
212 	 fprintf(outfile, "\t.long 0, 0\n");
213 
214    fprintf(outfile, "\n");
215 }
216 
217 
218 
output_font_color(FONT_COLOR_DATA * cf,char * name,int depth)219 static void output_font_color(FONT_COLOR_DATA *cf, char *name, int depth)
220 {
221    char buf[1000], goodname[1000];
222    int ch;
223 
224    if (cf->next) output_font_color(cf->next, name, depth + 1);
225 
226    if (depth > 0)
227       sprintf(goodname, "%s_r%d", name, depth + 1);
228    else
229       strcpy(goodname, name);
230 
231    for (ch = cf->begin; ch < cf->end; ch++) {
232       sprintf(buf, "%s_char_%04X", goodname, ch);
233       output_bitmap(cf->bitmaps[ch - cf->begin], buf, FALSE);
234    }
235 
236    fprintf(outfile, "# glyph list\n");
237    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s_glyphs:\n", prefix, goodname);
238 
239    for (ch = cf->begin; ch < cf->end; ch++)
240       fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_char_%04X\n", prefix, goodname, ch);
241    fprintf(outfile, "\n# FONT_COLOR_DATA\n");
242 
243    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s_data:\n", prefix, goodname);
244    fprintf(outfile, "\t.long 0x%04X%10c# begin\n", cf->begin, ' ');
245    fprintf(outfile, "\t.long 0x%04X%10c# end\n", cf->end, ' ');
246    fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_glyphs\n", prefix, goodname);
247    if (cf->next)
248       fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_r%d_data\n", prefix, name, depth + 2);
249    else
250       fprintf(outfile, "\t.long %-16d#next\n", 0);
251    fprintf(outfile, "\n");
252 }
253 
254 
255 
output_font_mono(FONT_MONO_DATA * mf,char * name,int depth)256 static void output_font_mono(FONT_MONO_DATA *mf, char *name, int depth)
257 {
258    char buf[1000], goodname[1000];
259    int ch;
260 
261    if (mf->next) output_font_mono(mf->next, name, depth + 1);
262 
263    if (depth > 0)
264       sprintf(goodname, "%s_r%d", name, depth + 1);
265    else
266       strcpy(goodname, name);
267 
268    for (ch = mf->begin; ch < mf->end; ch++) {
269       FONT_GLYPH *g = mf->glyphs[ch - mf->begin];
270 
271       sprintf(buf, "%s_char_%04X", goodname, ch);
272       fprintf(outfile, "# glyph\n");
273       fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s:\n", prefix, buf);
274       fprintf(outfile, "\t.short %-15d# w\n", g->w);
275       fprintf(outfile, "\t.short %-15d# h\n", g->h);
276 
277       write_data(g->dat, ((g->w + 7) / 8) * g->h);
278       fprintf(outfile, "\n");
279    }
280 
281    fprintf(outfile, "# glyph list\n");
282    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s_glyphs:\n", prefix, goodname);
283 
284    for (ch = mf->begin; ch < mf->end; ch++)
285       fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_char_%04X\n", prefix, goodname, ch);
286    fprintf(outfile, "\n# FONT_COLOR_DATA\n");
287 
288    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s_data:\n", prefix, goodname);
289    fprintf(outfile, "\t.long 0x%04X%10c# begin\n", mf->begin, ' ');
290    fprintf(outfile, "\t.long 0x%04X%10c# end\n", mf->end, ' ');
291    fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_glyphs\n", prefix, goodname);
292    if (mf->next)
293       fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_r%d_data\n", prefix, name, depth + 2);
294    else
295       fprintf(outfile, "\t.long %-16d#next\n", 0);
296    fprintf(outfile, "\n");
297 }
298 
299 
300 
output_font(FONT * f,char * name,int depth)301 static void output_font(FONT *f, char *name, int depth)
302 {
303    int color_flag = (f->vtable == font_vtable_color ? 1 : 0);
304 
305    if (color_flag)
306       output_font_color(f->data, name, 0);
307    else
308       output_font_mono(f->data, name, 0);
309 
310    fprintf(outfile, "# font\n");
311    fprintf(outfile, ".globl " ALLEGRO_ASM_PREFIX "%s%s\n", prefix, name);
312    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s:\n", prefix, name);
313    fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s_data\n", prefix, name);
314    fprintf(outfile, "\t.long %-16d# height\n", f->height);
315    fprintf(outfile, "\t.long %-16d# color flag\n", color_flag);
316    fprintf(outfile, "\n");
317 }
318 
319 
320 
output_rle_sprite(RLE_SPRITE * sprite,char * name)321 static void output_rle_sprite(RLE_SPRITE *sprite, char *name)
322 {
323    int bpp = sprite->color_depth;
324 
325    if (bpp > 8)
326       truecolor = TRUE;
327 
328    fprintf(outfile, "# RLE sprite\n.globl " ALLEGRO_ASM_PREFIX "%s%s\n", prefix, name);
329    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s:\n", prefix, name);
330    fprintf(outfile, "\t.long %-16d# w\n", sprite->w);
331    fprintf(outfile, "\t.long %-16d# h\n", sprite->h);
332    fprintf(outfile, "\t.long %-16d# color depth\n", bpp);
333    fprintf(outfile, "\t.long %-16d# size\n", sprite->size);
334 
335    write_data((unsigned char *)sprite->dat, sprite->size);
336 
337    fprintf(outfile, "\n");
338 }
339 
340 
341 
get_object_name(char * buf,char * name,DATAFILE * dat,int root)342 static void get_object_name(char *buf, char *name, DATAFILE *dat, int root)
343 {
344    if (!root) {
345       strcpy(buf, name);
346       strcat(buf, "_");
347    }
348    else
349       buf[0] = 0;
350 
351    strcat(buf, get_datafile_property(dat, DAT_NAME));
352    strlwr(buf);
353 }
354 
355 
356 
output_datafile(DATAFILE * dat,char * name,int root)357 static void output_datafile(DATAFILE *dat, char *name, int root)
358 {
359    char buf[160];
360    int c;
361 
362    for (c=0; (dat[c].type != DAT_END) && (!err); c++) {
363       get_object_name(buf, name, dat+c, root);
364       output_object(dat+c, buf);
365    }
366 
367    fprintf(outfile, "# datafile\n.globl " ALLEGRO_ASM_PREFIX "%s%s\n", prefix, name);
368    fprintf(outfile, ".balign 4\n" ALLEGRO_ASM_PREFIX "%s%s:\n", prefix, name);
369 
370    if (outfileheader)
371       fprintf(outfileheader, "extern DATAFILE %s%s[];\n", prefix, name);
372 
373    for (c=0; dat[c].type != DAT_END; c++) {
374       get_object_name(buf, name, dat+c, root);
375       fprintf(outfile, "\t.long " ALLEGRO_ASM_PREFIX "%s%s\n", prefix, buf);
376       fprintf(outfile, "\t.long %-16d# %c%c%c%c\n", dat[c].type, (dat[c].type>>24) & 0xFF, (dat[c].type>>16) & 0xFF, (dat[c].type>>8) & 0xFF, dat[c].type & 0xFF);
377       fprintf(outfile, "\t.long %-16ld# size\n", dat[c].size);
378       fprintf(outfile, "\t.long %-16d# properties\n", 0);
379    }
380 
381    fprintf(outfile, "\t.long 0\n\t.long -1\n\t.long 0\n\t.long 0\n\n");
382 }
383 
384 
385 
output_object(DATAFILE * object,char * name)386 static void output_object(DATAFILE *object, char *name)
387 {
388    char buf[160];
389    int i;
390 
391    switch (object->type) {
392 
393       case DAT_FONT:
394 	 if (outfileheader)
395 	    fprintf(outfileheader, "extern FONT %s%s;\n", prefix, name);
396 
397 	 output_font((FONT *)object->dat, name, 0);
398 	 break;
399 
400       case DAT_BITMAP:
401 	 if (outfileheader)
402 	    fprintf(outfileheader, "extern BITMAP %s%s;\n", prefix, name);
403 
404 	 output_bitmap((BITMAP *)object->dat, name, TRUE);
405 	 break;
406 
407       case DAT_PALETTE:
408 	 if (outfileheader)
409 	    fprintf(outfileheader, "extern PALETTE %s%s;\n", prefix, name);
410 
411 	 output_data(object->dat, sizeof(PALETTE), name, "palette", TRUE);
412 	 break;
413 
414       case DAT_SAMPLE:
415 	 if (outfileheader)
416 	    fprintf(outfileheader, "extern SAMPLE %s%s;\n", prefix, name);
417 
418 	 output_sample((SAMPLE *)object->dat, name);
419 	 break;
420 
421       case DAT_MIDI:
422 	 if (outfileheader)
423 	    fprintf(outfileheader, "extern MIDI %s%s;\n", prefix, name);
424 
425 	 output_midi((MIDI *)object->dat, name);
426 	 break;
427 
428       case DAT_PATCH:
429 	 printf("Compiled GUS patch objects are not supported!\n");
430 	 break;
431 
432       case DAT_RLE_SPRITE:
433 	 if (outfileheader)
434 	    fprintf(outfileheader, "extern RLE_SPRITE %s%s;\n", prefix, name);
435 
436 	 output_rle_sprite((RLE_SPRITE *)object->dat, name);
437 	 break;
438 
439       case DAT_FLI:
440 	 if (outfileheader)
441 	    fprintf(outfileheader, "extern unsigned char %s%s[];\n", prefix, name);
442 
443 	 output_data(object->dat, object->size, name, "FLI/FLC animation", TRUE);
444 	 break;
445 
446       case DAT_C_SPRITE:
447       case DAT_XC_SPRITE:
448 	 if (convert_compiled_sprites) {
449 	    object->type = DAT_BITMAP;
450 	    output_object(object, name);
451 	 }
452 	 else {
453 	    fprintf(stderr, "Error: encountered a compiled sprite (%s). Please\n"
454 	                    "see documentation for more information.\n", name);
455 	    err = 1;
456 	 }
457 	 break;
458 
459       case DAT_FILE:
460 	 output_datafile((DATAFILE *)object->dat, name, FALSE);
461 	 break;
462 
463       default:
464 	 for (i=0; datedit_object_info[i]->type != DAT_END; i++) {
465 	    if ((datedit_object_info[i]->type == object->type) && (datedit_object_info[i]->dat2s)) {
466 	       strcpy(buf, prefix);
467 	       strcat(buf, name);
468 	       datedit_object_info[i]->dat2s(object, buf, outfile, outfileheader);
469 	       return;
470 	    }
471 	 }
472 
473 	 if (outfileheader)
474 	    fprintf(outfileheader, "extern unsigned char %s%s[];\n", prefix, name);
475 
476 	 output_data(object->dat, object->size, name, "binary data", TRUE);
477 	 break;
478    }
479 }
480 
481 
482 
main(int argc,char * argv[])483 int main(int argc, char *argv[])
484 {
485    int c;
486    char tm[80];
487    time_t now;
488 
489    if (install_allegro(SYSTEM_NONE, &errno, atexit) != 0)
490       return 1;
491    datedit_init();
492 
493    time(&now);
494    strcpy(tm, asctime(localtime(&now)));
495    for (c=0; tm[c]; c++)
496       if ((tm[c] == '\r') || (tm[c] == '\n'))
497 	 tm[c] = 0;
498 
499    for (c=1; c<argc; c++) {
500       if (stricmp(argv[c], "-o") == 0) {
501 	 if ((outfilename) || (c >= argc-1)) {
502 	    usage();
503 	    return 1;
504 	 }
505 	 outfilename = argv[++c];
506       }
507       else if (stricmp(argv[c], "-h") == 0) {
508 	 if ((outfilenameheader) || (c >= argc-1)) {
509 	    usage();
510 	    return 1;
511 	 }
512 	 outfilenameheader = argv[++c];
513       }
514       else if (stricmp(argv[c], "-p") == 0) {
515 	 if ((prefix[0]) || (c >= argc-1)) {
516 	    usage();
517 	    return 1;
518 	 }
519 	 strcpy(prefix, argv[++c]);
520       }
521       else if (stricmp(argv[c], "-n") == 0) {
522 	 if ((dataname) || (c >= argc-1)) {
523 	    usage();
524 	    return 1;
525 	 }
526 	 dataname = argv[++c];
527       }
528       else if (stricmp(argv[c], "-007") == 0) {
529 	 if ((password) || (c >= argc-1)) {
530 	    usage();
531 	    return 1;
532 	 }
533 	 password = argv[++c];
534       }
535       else if (stricmp(argv[c], "-S") == 0) {
536 	 if (convert_compiled_sprites) {
537 	    usage();
538 	    return 1;
539 	 }
540 	 convert_compiled_sprites = TRUE;
541       }
542       else {
543 	 if ((argv[c][0] == '-') || (infilename)) {
544 	    usage();
545 	    return 1;
546 	 }
547 	 infilename = argv[c];
548       }
549    }
550 
551    if (!infilename) {
552       usage();
553       return 1;
554    }
555 
556    if ((prefix[0]) && (prefix[strlen(prefix)-1] != '_'))
557       strcat(prefix, "_");
558 
559    if (!dataname)
560       dataname = default_dataname;
561 
562    set_color_conversion(COLORCONV_NONE);
563 
564    data = datedit_load_datafile(infilename, FALSE, password);
565    if (!data) {
566       fprintf(stderr, "Error reading %s\n", infilename);
567       err = 1;
568       goto ohshit;
569    }
570 
571    if (outfilename) {
572       outfile = fopen(outfilename, "w");
573       if (!outfile) {
574 	 fprintf(stderr, "Error writing %s\n", outfilename);
575 	 err = 1;
576 	 goto ohshit;
577       }
578    }
579    else
580       outfile = stdout;
581 
582    fprintf(outfile, "/* Compiled Allegro data file, produced by dat2s v" ALLEGRO_VERSION_STR ", " ALLEGRO_PLATFORM_STR " */\n");
583    fprintf(outfile, "/* Input file: %s */\n", infilename);
584    fprintf(outfile, "/* Date: %s */\n", tm);
585    fprintf(outfile, "/* Do not hand edit! */\n\n.data\n\n");
586 
587    if (outfilenameheader) {
588       outfileheader = fopen(outfilenameheader, "w");
589       if (!outfileheader) {
590 	 fprintf(stderr, "Error writing %s\n", outfilenameheader);
591 	 err = 1;
592 	 goto ohshit;
593       }
594       fprintf(outfileheader, "/* Allegro data file definitions, produced by dat2s v" ALLEGRO_VERSION_STR ", " ALLEGRO_PLATFORM_STR " */\n");
595       fprintf(outfileheader, "/* Input file: %s */\n", infilename);
596       fprintf(outfileheader, "/* Date: %s */\n", tm);
597       fprintf(outfileheader, "/* Do not hand edit! */\n\n");
598    }
599 
600    if (outfilename)
601       printf("Converting %s to %s...\n", infilename, outfilename);
602 
603    output_datafile(data, dataname, TRUE);
604 
605    #ifdef ALLEGRO_USE_CONSTRUCTOR
606 
607       fprintf(outfile, ".text\n");
608       fprintf(outfile, ".balign 4\n");
609       fprintf(outfile, "construct_me:\n");
610       fprintf(outfile, "\tpushl %%ebp\n");
611       fprintf(outfile, "\tmovl %%esp, %%ebp\n");
612       fprintf(outfile, "\tpushl $" ALLEGRO_ASM_PREFIX "%s%s\n", prefix, dataname);
613       fprintf(outfile, "\tcall " ALLEGRO_ASM_PREFIX "_construct_datafile\n");
614       fprintf(outfile, "\taddl $4, %%esp\n");
615       fprintf(outfile, "\tleave\n");
616       fprintf(outfile, "\tret\n\n");
617       #ifdef ALLEGRO_DJGPP
618       fprintf(outfile, ".section .ctor\n");
619       #else
620       fprintf(outfile, ".section .ctors\n");
621       #endif
622       fprintf(outfile, "\t.long construct_me\n");
623 
624    #endif
625 
626    if ((outfile && ferror(outfile)) || (outfileheader && ferror(outfileheader)))
627       err = 1;
628 
629    ohshit:
630 
631    if ((outfile) && (outfile != stdout))
632       fclose(outfile);
633 
634    if (outfileheader)
635       fclose(outfileheader);
636 
637    if (data)
638       unload_datafile(data);
639 
640    if (err) {
641       if (outfilename)
642 	 delete_file(outfilename);
643 
644       if (outfilenameheader)
645 	 delete_file(outfilenameheader);
646    }
647    else {
648       #ifdef ALLEGRO_USE_CONSTRUCTOR
649 
650 	 if (truecolor) {
651 	    printf("\nI noticed some truecolor images, so you must call fixup_datafile()\n");
652 	    printf("before using this data! (after setting a video mode).\n");
653 	 }
654 
655       #else
656 
657 	 printf("\nI don't know how to do constructor functions on this platform, so you must\n");
658 	 printf("call fixup_datafile() before using this data! (after setting a video mode).\n");
659 
660       #endif
661    }
662 
663    return err;
664 }
665 
666 
667 #else       /* ifdef ALLEGRO_I386 */
668 
669 
main(void)670 int main(void)
671 {
672    allegro_init();
673    allegro_message("Sorry, the DAT2S program only works on x86 processors.\n");
674    return 1;
675 }
676 
677 
678 #endif
679 
680 END_OF_MAIN()
681