~ubuntu-branches/debian/jessie/scummvm/jessie

« back to all changes in this revision

Viewing changes to tools/sci/sciunpack.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Moritz Muehlenhoff
  • Date: 2011-05-25 19:02:23 UTC
  • mto: This revision was merged to the branch mainline in revision 23.
  • Revision ID: james.westby@ubuntu.com-20110525190223-fiqm0oaec714xk31
Tags: upstream-1.3.0
ImportĀ upstreamĀ versionĀ 1.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ScummVM - Graphic Adventure Engine
2
 
 *
3
 
 * ScummVM is the legal property of its developers, whose names
4
 
 * are too numerous to list here. Please refer to the COPYRIGHT
5
 
 * file distributed with this source distribution.
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or
8
 
 * modify it under the terms of the GNU General Public License
9
 
 * as published by the Free Software Foundation; either version 2
10
 
 * of the License, or (at your option) any later version.
11
 
 
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
 
 *
21
 
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-2-1/tools/sci/sciunpack.cpp $
22
 
 * $Id: sciunpack.cpp 38423 2009-02-17 15:59:52Z sev $
23
 
 *
24
 
 */
25
 
 
26
 
#ifdef HAVE_CONFIG_H
27
 
#include <config.h>
28
 
#endif /* HAVE_CONFIG_H */
29
 
 
30
 
#include "sciunpack.h"
31
 
 
32
 
#include <sciresource.h>
33
 
#include <engine.h>
34
 
#include <console.h>
35
 
 
36
 
/* #define DRAW_GRAPHICS */
37
 
 
38
 
#undef HAVE_OBSTACK_H
39
 
 
40
 
#ifdef _MSC_VER
41
 
#  include <direct.h>
42
 
#  define extern __declspec(dllimport) extern
43
 
#endif
44
 
 
45
 
#ifdef HAVE_GETOPT_H
46
 
#       ifndef WIN32
47
 
#               include <getopt.h>
48
 
#       else
49
 
#               include <win32/getopt.h>
50
 
#       endif
51
 
#endif /* HAVE_GETOPT_H */
52
 
 
53
 
#ifdef DRAW_GRAPHICS
54
 
#  ifdef HAVE_LIBPNG
55
 
#    include "graphics_png.h"
56
 
#  endif /* HAVE_LIBPNG */
57
 
#endif /* DRAW_GRAPHICS */
58
 
 
59
 
#if defined (_MSC_VER) || defined (__BEOS__) || defined(__amigaos4__)
60
 
/* [DJ] fchmod is not in Visual C++ RTL - and probably not needed,anyway */
61
 
/* [RS] (see comment above, but read MS-DOS instead of Visual C++ RTL) */
62
 
#  define fchmod(file,mode)
63
 
#  define CREAT_OPTIONS O_BINARY
64
 
#endif
65
 
 
66
 
#ifndef CREAT_OPTIONS
67
 
#  define CREAT_OPTIONS 0x640
68
 
#endif
69
 
 
70
 
 
71
 
#define ACT_UNPACK 0
72
 
#define ACT_WORDS 1
73
 
#define ACT_LIST 2
74
 
#define ACT_SCRIPTDUMP 3
75
 
#define ACT_VOCABDUMP 4
76
 
 
77
 
#define ACT_DEFAULT ACT_UNPACK
78
 
 
79
 
static int conversion = 0;
80
 
static int list = 0;
81
 
static int verbose = 0;
82
 
static int with_header = 1;
83
 
static int color_mode = 0;
84
 
static int action = ACT_DEFAULT;
85
 
static guint8 midimask = 0x01;  /* MT-32 */
86
 
 
87
 
resource_mgr_t *resmgr;
88
 
 
89
 
#ifdef WIN32
90
 
#define fchmod(arg1, arg2)
91
 
#endif
92
 
 
93
 
void
94
 
print_resource_filename(FILE* file, int type, int number) {
95
 
        if (resmgr->sci_version < SCI_VERSION_1)
96
 
                fprintf(file, "%s.%03d", sci_resource_types[type], number);
97
 
        else
98
 
                fprintf(file, "%d.%s", number, sci_resource_type_suffixes[type]);
99
 
}
100
 
 
101
 
void
102
 
sprint_resource_filename(char* buf, int type, int number) {
103
 
        if (resmgr->sci_version < SCI_VERSION_1)
104
 
                sprintf(buf, "%s.%03d", sci_resource_types[type], number);
105
 
        else
106
 
                sprintf(buf, "%d.%s", number, sci_resource_type_suffixes[type]);
107
 
}
108
 
 
109
 
#ifdef HAVE_GETOPT_LONG
110
 
static struct option options[] = {
111
 
        {"conversion", no_argument, &conversion, 1},
112
 
        {"version", no_argument, 0, 256},
113
 
        {"verbose", no_argument, &verbose, 1},
114
 
        {"help", no_argument, 0, 'h'},
115
 
        {"output-file", required_argument, 0, 'o'},
116
 
        {"unpack", no_argument, &action, ACT_UNPACK},
117
 
        {"list", no_argument, &action, ACT_LIST},
118
 
        {"words", no_argument, &action, ACT_WORDS},
119
 
        {"vocab", no_argument, &action, ACT_VOCABDUMP},
120
 
        {"objects", no_argument, &action, ACT_SCRIPTDUMP},
121
 
        {"with-header", no_argument, &with_header, 1},
122
 
        {"without-header", no_argument, &with_header, 0},
123
 
        {"sort-alpha", no_argument, &vocab_sort, SORT_METHOD_ALPHA},
124
 
        {"sort-group", no_argument, &vocab_sort, SORT_METHOD_GROUP},
125
 
#ifdef DRAW_GRAPHICS
126
 
        {"palette-dither", no_argument, &color_mode, SCI_COLOR_DITHER},
127
 
        {"palette-interpolate", no_argument, &color_mode, SCI_COLOR_INTERPOLATE},
128
 
        {"palette-dither256", no_argument, &color_mode, SCI_COLOR_DITHER256},
129
 
#endif /* DRAW_GRAPHICS */
130
 
        {"gamedir", required_argument, 0, 'd'},
131
 
        {"midimask", required_argument, 0, 'M'},
132
 
        {0, 0, 0, 0}
133
 
};
134
 
 
135
 
#endif /* HAVE_GETOPT_LONG */
136
 
 
137
 
 
138
 
void unpack_resource(int stype, int snr, char *outfilename);
139
 
 
140
 
 
141
 
int main(int argc, char** argv) {
142
 
        int retval = 0;
143
 
        int i;
144
 
        int stype = -1;
145
 
        int snr;
146
 
        char *resourcenumber_string = 0;
147
 
        char *outfilename = 0;
148
 
        int optindex = 0;
149
 
        int c;
150
 
        char *gamedir = sci_getcwd();
151
 
        int res_version = SCI_VERSION_AUTODETECT;
152
 
 
153
 
#ifdef HAVE_GETOPT_LONG
154
 
        while ((c = getopt_long(argc, argv, "WOVUvhLcr:o:d:M:", options, &optindex)) > -1) {
155
 
#else /* !HAVE_GETOPT_LONG */
156
 
        while ((c = getopt(argc, argv, "WOVUvhLcr:o:d:M:")) > -1) {
157
 
#endif /* !HAVE_GETOPT_LONG */
158
 
 
159
 
                switch (c) {
160
 
                case 256:
161
 
                        printf("sciunpack ("PACKAGE") "VERSION"\n");
162
 
                        printf("This program is copyright (C) 1999, 2000, 2001 Christoph Reichenbach,\n"
163
 
                               " Lars Skovlund, Magnus Reftel\n"
164
 
                               "It comes WITHOUT WARRANTY of any kind.\n"
165
 
                               "This is free software, released under the GNU General Public License.\n");
166
 
                        exit(0);
167
 
 
168
 
                case 'h': {
169
 
                        char *gcc_3_0_can_kiss_my_ass =
170
 
                            "Usage: sciunpack [options] [-U] <resource.number>\n"
171
 
                            "       sciunpack [options] [-U] <resource> <number>\n"
172
 
                            "Unpacks resource data\n"
173
 
                            "If * is specified instead of <number>, \n"
174
 
                            "all resources of given type will be unpacked.\n\n"
175
 
                            "       sciunpack [options] -W\n"
176
 
                            "Lists vocabulary words\n\n"
177
 
                            "       sciunpack [options] -O\n"
178
 
                            "Dumps the complete object hierarchy\n\n"
179
 
                            "       sciunpack [options] -V\n"
180
 
                            "Prints selector names, opcodes, kernel names, and classes\n\n"
181
 
                            "\nAvalable operations:\n"
182
 
                            " --unpack      -U       Decompress resource\n"
183
 
                            " --list        -L       List all resources\n"
184
 
                            " --words       -W       List all vocabulary words\n"
185
 
                            " --objects     -O       Print all objects\n"
186
 
                            " --vocab       -V       Lists the complete vocabulary\n"
187
 
                            "\nAvailable options:\n"
188
 
                            "General:\n"
189
 
                            " --version              Prints the version number\n"
190
 
                            " --verbose     -v       Enables additional output\n"
191
 
                            " --help        -h       Displays this help message\n"
192
 
                            " --midimask    -M       What 'play mask' to use.  Defaults to MT-32 (0x01)\n"
193
 
 
194
 
                            "Listing words:\n"
195
 
                            " --sort-alpha              sort in alphabetical order\n"
196
 
                            " --sort-group              sort in group order\n"
197
 
                            "Unpacking:\n"
198
 
                            " --convert     -c       Converts selected resources\n"
199
 
                            " --output-file -o       Selects output file\n"
200
 
                            " --gamedir     -d       Read game resources from dir\n"
201
 
                            " --with-header          Forces the SCI header to be written (default)\n"
202
 
                            " --without-header       Prevents the two SCI header bytes from being written\n"
203
 
#ifdef DRAW_GRAPHICS
204
 
                            " --palette-dither       Forces colors in 16 color games to be dithered\n"
205
 
                            " --palette-interpolate  Does color interpolation when drawing picture resources\n"
206
 
                            " --palette-dither256    Does dithering in 256 colors\n"
207
 
#endif /* DRAW_GRAPHICS */
208
 
                            "\nAs a default, 'resource.number' is the output filename.\n"
209
 
                            "If conversion is enabled, the following resources will be treated specially:\n"
210
 
                            "  sound resources:   Will be converted to MIDI, stored in <number>.midi\n"
211
 
                            "  script resources:  Will be dissected and  stored in <number>.script\n"
212
 
#ifdef DRAW_GRAPHICS
213
 
                            "  picture resources: Will be converted to PNG, stored in <number>.png\n"
214
 
 
215
 
#endif /* DRAW_GRAPHICS */
216
 
                            ;
217
 
 
218
 
                        printf(gcc_3_0_can_kiss_my_ass);
219
 
                        exit(0);
220
 
                }
221
 
 
222
 
                case 'v':
223
 
                        verbose = 1;
224
 
                        break;
225
 
 
226
 
                case 'L':
227
 
                        action = ACT_LIST;
228
 
                        break;
229
 
 
230
 
                case 'W':
231
 
                        action = ACT_WORDS;
232
 
                        break;
233
 
 
234
 
                case 'V':
235
 
                        action = ACT_VOCABDUMP;
236
 
                        break;
237
 
 
238
 
                case 'O':
239
 
                        action = ACT_SCRIPTDUMP;
240
 
                        break;
241
 
 
242
 
                case 'o':
243
 
                        outfilename = optarg;
244
 
                        break;
245
 
 
246
 
                case 'd':
247
 
                        if (gamedir) sci_free(gamedir);
248
 
                        gamedir = sci_strdup(optarg);
249
 
                        break;
250
 
 
251
 
                case 'r':
252
 
                        res_version = atoi(optarg);
253
 
                        break;
254
 
 
255
 
                case 'c':
256
 
                        conversion = 1;
257
 
                        break;
258
 
 
259
 
                case 'M':
260
 
                        midimask = (guint8) strtol(optarg, NULL, 0);
261
 
                        break;
262
 
 
263
 
                case 0: /* getopt_long already did this for us */
264
 
                case '?':
265
 
                        /* getopt_long already printed an error message. */
266
 
                        break;
267
 
 
268
 
                default:
269
 
                        return -1;
270
 
                }
271
 
        }
272
 
 
273
 
        if (action == ACT_UNPACK) {
274
 
                char *resstring = argv[optind];
275
 
 
276
 
                if (optind == argc) {
277
 
                        fprintf(stderr, "Resource identifier required\n");
278
 
                        return 1;
279
 
                }
280
 
 
281
 
                if ((resourcenumber_string = (char *) strchr(resstring, '.'))) {
282
 
                        *resourcenumber_string++ = 0;
283
 
                } else if (optind + 1 == argc) {
284
 
                        fprintf(stderr, "Resource number required\n");
285
 
                        return 1;
286
 
                } else resourcenumber_string = argv[optind+1];
287
 
 
288
 
                for (i = 0; i < 18; i++)
289
 
                        if ((strcmp(sci_resource_types[i], resstring) == 0)) stype = i;
290
 
                if (stype == -1) {
291
 
                        printf("Could not find the resource type '%s'.\n", resstring);
292
 
                        return 1;
293
 
                }
294
 
        } /* ACT_UNPACK */
295
 
 
296
 
        if (gamedir)
297
 
                if (chdir(gamedir)) {
298
 
                        printf("Error changing to game directory '%s'\n", gamedir);
299
 
                        exit(1);
300
 
                }
301
 
 
302
 
        if (!(resmgr = scir_new_resource_manager(gamedir, res_version,
303
 
                       0, 1024 * 128))) {
304
 
                fprintf(stderr, "Could not find any resources; quitting.\n");
305
 
                exit(1);
306
 
        }
307
 
 
308
 
        if (verbose) printf("Autodetect determined: %s\n",
309
 
                                    sci_version_types[resmgr->sci_version]);
310
 
 
311
 
 
312
 
        switch (action) {
313
 
 
314
 
        case ACT_LIST: {
315
 
                int i;
316
 
 
317
 
                if (verbose) {
318
 
                        for (i = 0; i < resmgr->resources_nr; i++) {
319
 
                                printf("%i: ", i);
320
 
                                print_resource_filename(stdout,
321
 
                                                        resmgr->resources[i].type,
322
 
                                                        resmgr->resources[i].number);
323
 
                                printf("   has size %i\n", resmgr->resources[i].size);
324
 
                        }
325
 
 
326
 
                        fprintf(stderr, " Reading complete. Actual resource count is %i\n",
327
 
                                resmgr->resources_nr);
328
 
                } else {
329
 
                        for (i = 0; i < resmgr->resources_nr; i++) {
330
 
                                print_resource_filename(stdout,
331
 
                                                        resmgr->resources[i].type,
332
 
                                                        resmgr->resources[i].number);
333
 
                                printf("\n");
334
 
                        }
335
 
                }
336
 
                break;
337
 
        }
338
 
 
339
 
        case ACT_UNPACK: {
340
 
 
341
 
                if (!strcmp(resourcenumber_string, "*")) {
342
 
                        int i;
343
 
                        for (i = 0; i < resmgr->resources_nr; i++)
344
 
                                if (resmgr->resources[i].type == stype)
345
 
                                        unpack_resource(stype, resmgr->resources[i].number, NULL);
346
 
                } else {
347
 
                        snr = atoi(resourcenumber_string);
348
 
                        unpack_resource(stype, snr, outfilename);
349
 
                }
350
 
                break;
351
 
        }
352
 
 
353
 
        case ACT_WORDS:
354
 
                retval = vocab_print();
355
 
                break;
356
 
 
357
 
        case ACT_SCRIPTDUMP:
358
 
                retval = script_dump();
359
 
                break;
360
 
 
361
 
        case ACT_VOCABDUMP:
362
 
                retval = vocab_dump();
363
 
                break;
364
 
 
365
 
        default:
366
 
                fprintf(stderr, "Invalid action %d- internal error!\n", action);
367
 
                return 1;
368
 
        }
369
 
 
370
 
 
371
 
        scir_free_resource_manager(resmgr);
372
 
        return retval;
373
 
}
374
 
 
375
 
 
376
 
void unpack_resource(int stype, int snr, char *outfilename) {
377
 
        char fnamebuffer[12]; /* stores default file name */
378
 
        resource_t *found;
379
 
 
380
 
        if ((stype == sci_sound) && conversion && (resmgr->sci_version > SCI_VERSION_0)) {
381
 
                fprintf(stderr, "MIDI conversion is only supported for SCI version 0\n");
382
 
                conversion = 0;
383
 
        }
384
 
 
385
 
        if (!outfilename) {
386
 
                outfilename = fnamebuffer;
387
 
                if ((stype == sci_sound) && conversion) {
388
 
#ifdef HAVE_OBSTACK_H
389
 
                        map_MIDI_instruments(resmgr);
390
 
#endif
391
 
                        sprintf(outfilename, "%03d.midi", snr);
392
 
                }
393
 
#ifdef DRAW_GRAPHICS
394
 
                else if ((stype == sci_pic) && conversion)
395
 
                        sprintf(outfilename, "%03d.png", snr);
396
 
#endif /* DRAW_GRAPHICS */
397
 
                else
398
 
                        sprint_resource_filename(outfilename, stype, snr);
399
 
        }
400
 
 
401
 
        if (verbose) {
402
 
                printf("seeking ");
403
 
                print_resource_filename(stdout, stype, snr);
404
 
                printf("...\n");
405
 
        }
406
 
 
407
 
        if ((found = scir_find_resource(resmgr, stype, snr, 0))) {
408
 
 
409
 
#ifdef DRAW_GRAPHICS
410
 
                if ((stype == sci_pic) && conversion) {
411
 
                        int i;
412
 
                        picture_t pic = alloc_empty_picture(SCI_RESOLUTION_320X200, SCI_COLORDEPTH_8BPP);
413
 
                        draw_pic0(pic, 1, 0, found->data);
414
 
                        if ((i = write_pic_png(outfilename, pic->maps[0]))) {
415
 
                                fprintf(stderr, "Writing the png failed (%d)\n", i);
416
 
                        } else if (verbose) printf("Done.\n");
417
 
                        free_picture(pic);
418
 
                } else
419
 
#endif /* DRAW_GRAPHICS */
420
 
                        if ((stype == sci_script) && conversion) {
421
 
                                sprintf(outfilename, "%03d.script", snr);
422
 
                                open_console_file(outfilename);
423
 
                                script_dissect(resmgr, snr, NULL, 0);
424
 
                                close_console_file();
425
 
                        } else {
426
 
 
427
 
                                /* Visual C++ doesn't allow to specify O_BINARY with creat() */
428
 
#ifdef _MSC_VER
429
 
                                int outf = open(outfilename, _O_CREAT | _O_BINARY | _O_RDWR);
430
 
#else
431
 
                                int outf = creat(outfilename, CREAT_OPTIONS);
432
 
#endif
433
 
 
434
 
#ifdef HAVE_OBSTACK_H
435
 
                                if ((stype == sci_sound) && conversion) {
436
 
                                        int midilength;
437
 
                                        guint8 *outdata = makeMIDI0(found->data, &midilength, midimask);
438
 
                                        if (!outdata) {
439
 
                                                fprintf(stderr, "MIDI conversion failed. Aborting...\n");
440
 
                                                return;
441
 
                                        }
442
 
                                        if (verbose) printf("MIDI conversion from %d bytes of sound resource"
443
 
                                                                    " to a %d bytes MIDI file.\n",
444
 
                                                                    found->size, midilength);
445
 
                                        write(outf, outdata, midilength);
446
 
                                        free(outdata);
447
 
                                } else {
448
 
#endif /* HAVE_OBSTACK_H */
449
 
                                        guint8 header = 0x80 | found->type;
450
 
 
451
 
                                        if (with_header) {
452
 
                                                write(outf, &header, 1);
453
 
                                                header = 0x00;
454
 
                                                write(outf, &header, 1);
455
 
                                        }
456
 
 
457
 
                                        write(outf,  found->data, found->size);
458
 
#ifdef HAVE_OBSTACK_H
459
 
                                }
460
 
#endif /* HAVE_OBSTACK_H */
461
 
 
462
 
                                fchmod(outf, 0644);
463
 
                                close(outf);
464
 
                                fchmod(outf, 0644);
465
 
 
466
 
                                if (verbose) printf("Done.\n");
467
 
                        }
468
 
 
469
 
        } else printf("Resource not found.\n");
470
 
}
471
 
 
472
 
 
473