Support for SC1 format.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2727 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
+286
-114
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
@@ -37,12 +38,18 @@ struct options {
|
||||
char list;
|
||||
char print;
|
||||
char verbose;
|
||||
enum {
|
||||
Type_sc1, // PC version of SC1
|
||||
Type_pc, // PC version of SC2
|
||||
Type_3do, // 3DO version of SC2
|
||||
} type;
|
||||
};
|
||||
|
||||
|
||||
index_header *readIndex(const uint8 *buf);
|
||||
void printIndex(const index_header *h, const uint8 *buf, FILE *out);
|
||||
char *get_file_name(const uint8 *buf, const index_header *h,
|
||||
index_header *readIndex(const struct options *opts, const uint8 *buf);
|
||||
void printIndex(const struct options *opts, const index_header *h,
|
||||
const uint8 *buf, FILE *out);
|
||||
char *getFileName(const uint8 *buf, const index_header *h,
|
||||
uint16 file_index);
|
||||
void writeFiles(const index_header *h, const uint8 *data, const char *path);
|
||||
void parse_arguments(int argc, char *argv[], struct options *opts);
|
||||
@@ -78,9 +85,9 @@ main(int argc, char *argv[]) {
|
||||
}
|
||||
close(in);
|
||||
|
||||
h = readIndex(buf);
|
||||
h = readIndex(&opts, buf);
|
||||
if (opts.print)
|
||||
printIndex(h, buf, stdout);
|
||||
printIndex(&opts, h, buf, stdout);
|
||||
|
||||
if (opts.list)
|
||||
listResources(h, buf, stdout);
|
||||
@@ -89,8 +96,8 @@ main(int argc, char *argv[]) {
|
||||
size_t len;
|
||||
struct stat sb;
|
||||
|
||||
if (!h->res_flags) {
|
||||
fprintf(stderr, "Error: Cannot unpack data from unpackaged "
|
||||
if (!h->packaged) {
|
||||
fprintf(stderr, "Error: Cannot unpack data from non-packaged "
|
||||
"file.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -125,7 +132,12 @@ main(int argc, char *argv[]) {
|
||||
|
||||
void
|
||||
usage() {
|
||||
fprintf(stderr, "unpkg [-o outputdir] [-v] [-l listfile] <infile>\n");
|
||||
fprintf(stderr, "unpkg [-o <outputdir>] [-l] [-p] [-v] <infile>\n"
|
||||
"\t-o unpack to 'outputdir'\n"
|
||||
"\t-l list the resources\n"
|
||||
"\t-p print the index\n"
|
||||
"\t-t package file type; one of \"sc1\", \"pc\", or \"3do\"\n"
|
||||
"\t-v verbose mode\n");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -133,8 +145,9 @@ parse_arguments(int argc, char *argv[], struct options *opts) {
|
||||
char ch;
|
||||
|
||||
memset(opts, '\0', sizeof (struct options));
|
||||
opts->type = Type_3do;
|
||||
while (1) {
|
||||
ch = getopt(argc, argv, "hlo:pv");
|
||||
ch = getopt(argc, argv, "hlo:pt:v");
|
||||
if (ch == -1)
|
||||
break;
|
||||
switch(ch) {
|
||||
@@ -147,6 +160,25 @@ parse_arguments(int argc, char *argv[], struct options *opts) {
|
||||
case 'p':
|
||||
opts->print = 1;
|
||||
break;
|
||||
case 't':
|
||||
if (strcmp(optarg, "sc1") == 0 ||
|
||||
strcmp(optarg, "SC1") == 0) {
|
||||
opts->type = Type_sc1;
|
||||
} else if (strcmp(optarg, "pc") == 0 ||
|
||||
strcmp(optarg, "PC") == 0) {
|
||||
opts->type = Type_pc;
|
||||
} else if (strcmp(optarg, "3do") == 0 ||
|
||||
strcmp(optarg, "3DO") == 0) {
|
||||
opts->type = Type_3do;
|
||||
fprintf(stderr, "3DO package files are not yet "
|
||||
"supported.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
fprintf(stderr, "Invalid package file type.\n");
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
opts->verbose = 1;
|
||||
break;
|
||||
@@ -167,12 +199,30 @@ parse_arguments(int argc, char *argv[], struct options *opts) {
|
||||
}
|
||||
|
||||
index_header *
|
||||
readIndex(const uint8 *buf) {
|
||||
readIndex(const struct options *opts, const uint8 *buf) {
|
||||
index_header *h;
|
||||
uint16 res_flags;
|
||||
const uint8 *bufptr;
|
||||
|
||||
h = malloc(sizeof (index_header));
|
||||
h->res_flags = MAKE_WORD(buf[0x00], buf[0x01]) ? 1 : 0;
|
||||
res_flags = MAKE_WORD(buf[0x00], buf[0x01]);
|
||||
h->packaged = ((res_flags & 0x1) == 0x1) ? true : false;
|
||||
switch (opts->type) {
|
||||
case Type_sc1:
|
||||
h->path_list_offs =
|
||||
MAKE_DWORD(buf[0x02], buf[0x03], buf[0x04], buf[0x05]);
|
||||
h->file_list_offs =
|
||||
MAKE_DWORD(buf[0x06], buf[0x07], buf[0x08], buf[0x09]);
|
||||
h->packmem_list_offs =
|
||||
MAKE_DWORD(buf[0x0a], buf[0x0b], buf[0x0c], buf[0x0d]);
|
||||
h->num_types = MAKE_WORD(buf[0x0e], buf[0x0f]);
|
||||
h->num_packages = MAKE_WORD(buf[0x12], buf[0x13]);
|
||||
h->header_len = 0;
|
||||
break;
|
||||
case Type_pc:
|
||||
abort(); // Not supported
|
||||
break;
|
||||
case Type_3do:
|
||||
h->packmem_list_offs =
|
||||
MAKE_DWORD(buf[0x02], buf[0x03], buf[0x04], buf[0x05]);
|
||||
h->path_list_offs =
|
||||
@@ -181,7 +231,10 @@ readIndex(const uint8 *buf) {
|
||||
MAKE_DWORD(buf[0x0a], buf[0x0b], buf[0x0c], buf[0x0d]);
|
||||
h->num_packages = MAKE_WORD(buf[0x0e], buf[0x0f]);
|
||||
h->num_types = MAKE_WORD(buf[0x10], buf[0x11]);
|
||||
h->header_len = MAKE_DWORD(buf[0x12], buf[0x13], buf[0x14], buf[0x15]);
|
||||
h->header_len = MAKE_DWORD(
|
||||
buf[0x12], buf[0x13], buf[0x14], buf[0x15]);
|
||||
break;
|
||||
}
|
||||
|
||||
bufptr = buf + 0x16;
|
||||
h->package_list = malloc(h->num_packages * sizeof (package_desc));
|
||||
@@ -221,65 +274,72 @@ readIndex(const uint8 *buf) {
|
||||
{
|
||||
int i, j;
|
||||
int num_types, num_instances;
|
||||
uint32 temp;
|
||||
|
||||
for (i = 0; i < h->num_packages; i++) {
|
||||
package_desc *package = &h->package_list[i];
|
||||
|
||||
uint32 next_offset;
|
||||
if (h->res_flags) {
|
||||
// packaged
|
||||
if (h->packaged) {
|
||||
// One file name per package
|
||||
char *temp;
|
||||
temp = get_file_name(buf, h, h->package_list[i].file_index);
|
||||
h->package_list[i].filename =
|
||||
(temp == NULL) ? NULL : strdup(temp);
|
||||
temp = getFileName(buf, h, package->file_index);
|
||||
package->filename = (temp == NULL) ? NULL : strdup(temp);
|
||||
} else {
|
||||
// not packaged
|
||||
h->package_list[i].filename = NULL;
|
||||
// File name is specified per resource instance.
|
||||
package->filename = NULL;
|
||||
}
|
||||
|
||||
num_types = h->package_list[i].num_types;
|
||||
h->package_list[i].type_list =
|
||||
malloc(num_types * sizeof (packtype_desc));
|
||||
num_types = package->num_types;
|
||||
package->type_list = malloc(num_types * sizeof (packtype_desc));
|
||||
for (j = 0; j < num_types; j++) {
|
||||
packtype_desc *type = &package->type_list[j];
|
||||
uint32 temp;
|
||||
|
||||
temp = MAKE_DWORD(bufptr[0], bufptr[1], bufptr[2], bufptr[3]);
|
||||
h->package_list[i].type_list[j].type = GET_TYPE(temp);
|
||||
h->package_list[i].type_list[j].first_instance =
|
||||
GET_INSTANCE(temp);
|
||||
h->package_list[i].type_list[j].num_instances =
|
||||
GET_PACKAGE(temp);
|
||||
type->type = GET_TYPE(temp);
|
||||
type->first_instance = GET_INSTANCE(temp);
|
||||
type->num_instances = GET_PACKAGE(temp);
|
||||
bufptr += 4;
|
||||
}
|
||||
|
||||
if (h->res_flags) {
|
||||
// packaged
|
||||
next_offset = h->package_list[i].data_loc;
|
||||
}
|
||||
next_offset = package->data_loc;
|
||||
for (j = 0; j < num_types; j++) {
|
||||
packtype_desc *type = &package->type_list[j];
|
||||
int k;
|
||||
|
||||
num_instances = h->package_list[i].type_list[j].num_instances;
|
||||
h->package_list[i].type_list[j].instances =
|
||||
num_instances = type->num_instances;
|
||||
type->instances =
|
||||
malloc(sizeof (packdef_instance) * num_instances);
|
||||
for (k = 0; k < num_instances; k++) {
|
||||
if (h->res_flags) {
|
||||
// packaged
|
||||
h->package_list[i].type_list[j].instances[k].size =
|
||||
packdef_instance *instance = &type->instances[k];
|
||||
|
||||
if (h->packaged) {
|
||||
switch (opts->type) {
|
||||
case Type_sc1:
|
||||
instance->size =
|
||||
MAKE_WORD(bufptr[0], bufptr[1]);
|
||||
break;
|
||||
case Type_pc:
|
||||
abort(); // Not yet supported.
|
||||
break;
|
||||
case Type_3do:
|
||||
instance->size =
|
||||
4 * MAKE_WORD(bufptr[0], bufptr[1]);
|
||||
h->package_list[i].type_list[j].instances[k].offset =
|
||||
next_offset;
|
||||
h->package_list[i].type_list[j].instances[k].
|
||||
filename = NULL;
|
||||
next_offset += h->package_list[i].type_list[j].
|
||||
instances[k].size;
|
||||
break;
|
||||
}
|
||||
instance->offset = next_offset;
|
||||
next_offset += instance->size;
|
||||
instance->filename = NULL;
|
||||
// File name is specified per package.
|
||||
} else {
|
||||
char *temp;
|
||||
h->package_list[i].type_list[j].instances[k].size = 0;
|
||||
h->package_list[i].type_list[j].instances[k].offset =
|
||||
0;
|
||||
temp = get_file_name(buf, h,
|
||||
instance->size = 0;
|
||||
instance->offset = 0;
|
||||
temp = getFileName(buf, h,
|
||||
MAKE_WORD(bufptr[0], bufptr[1]));
|
||||
h->package_list[i].type_list[j].instances[k].
|
||||
filename = (temp == NULL) ?
|
||||
instance->filename = (temp == NULL) ?
|
||||
NULL : strdup(temp);
|
||||
|
||||
}
|
||||
bufptr += 2;
|
||||
} // for k
|
||||
@@ -290,11 +350,33 @@ readIndex(const uint8 *buf) {
|
||||
}
|
||||
|
||||
void
|
||||
printIndex(const index_header *h, const uint8 *buf, FILE *out) {
|
||||
printIndex(const struct options *opts, const index_header *h,
|
||||
const uint8 *buf, FILE *out) {
|
||||
const uint8 *bufptr;
|
||||
|
||||
fprintf(out, "0x00000000 File type: %s\n",
|
||||
h->res_flags ? "packaged" : "not packaged");
|
||||
h->packaged ? "packaged" : "not packaged");
|
||||
switch (opts->type) {
|
||||
case Type_sc1:
|
||||
fprintf(out, "0x00000002 path_list_offs: 0x%08x\n",
|
||||
h->path_list_offs);
|
||||
fprintf(out, "0x00000006 file_list_offs: 0x%08x\n",
|
||||
h->file_list_offs);
|
||||
fprintf(out, "0x0000000a packmem_list_offs: 0x%08x\n",
|
||||
h->packmem_list_offs);
|
||||
fprintf(out, "0x0000000e Number of package types: %d\n",
|
||||
h->num_types);
|
||||
fprintf(out, "0x00000010 Unknown: 0x%04x\n",
|
||||
MAKE_WORD(buf[0x10], buf[0x11]));
|
||||
fprintf(out, "0x00000012 Number of packages: %d\n",
|
||||
h->num_packages);
|
||||
fprintf(out, "0x00000013 Unknown: 0x%04x\n",
|
||||
MAKE_WORD(buf[0x13], buf[0x14]));
|
||||
break;
|
||||
case Type_pc:
|
||||
abort(); // Not supported
|
||||
break;
|
||||
case Type_3do:
|
||||
fprintf(out, "0x00000002 packmem_list_offs: 0x%08x\n",
|
||||
h->packmem_list_offs);
|
||||
fprintf(out, "0x00000006 path_list_offs: 0x%08x\n",
|
||||
@@ -307,6 +389,8 @@ printIndex(const index_header *h, const uint8 *buf, FILE *out) {
|
||||
h->num_types);
|
||||
fprintf(out, "0x00000012 Header length: 0x%08x\n",
|
||||
h->header_len);
|
||||
break;
|
||||
}
|
||||
|
||||
bufptr = buf + 0x16;
|
||||
fprintf(out, "0x00000016 package info:\n");
|
||||
@@ -353,19 +437,18 @@ printIndex(const index_header *h, const uint8 *buf, FILE *out) {
|
||||
int num_types, num_instances;
|
||||
|
||||
for (i = 0; i < h->num_packages; i++) {
|
||||
if (h->res_flags) {
|
||||
// packaged
|
||||
package_desc *package = &h->package_list[i];
|
||||
|
||||
if (h->packaged) {
|
||||
fprintf(out, "0x%08x Package #%d (%s):\n",
|
||||
bufptr - buf, i + 1,
|
||||
(h->package_list[i].filename == NULL) ?
|
||||
"<<UNNAMED>>" : h->package_list[i].filename);
|
||||
bufptr - buf, i + 1, (package->filename == NULL) ?
|
||||
"<<INTERNAL>>" : package->filename);
|
||||
} else {
|
||||
// not packaged
|
||||
fprintf(out, "0x%08x Package #%d:\n",
|
||||
bufptr - buf, i + 1);
|
||||
}
|
||||
|
||||
num_types = h->package_list[i].num_types;
|
||||
num_types = package->num_types;
|
||||
for (j = 0; j < num_types; j++) {
|
||||
fprintf(out, "0x%08x Type #%d: type %d, "
|
||||
"%d instances starting with #%d\n",
|
||||
@@ -377,30 +460,28 @@ printIndex(const index_header *h, const uint8 *buf, FILE *out) {
|
||||
}
|
||||
|
||||
for (j = 0; j < num_types; j++) {
|
||||
packtype_desc *type = &package->type_list[j];
|
||||
int k;
|
||||
|
||||
num_instances = h->package_list[i].type_list[j].num_instances;
|
||||
num_instances = type->num_instances;
|
||||
for (k = 0; k < num_instances; k++) {
|
||||
if (h->res_flags) {
|
||||
// packaged
|
||||
packdef_instance *instance = &type->instances[k];
|
||||
|
||||
if (h->packaged) {
|
||||
fprintf(out, "0x%08x Instance #%d of "
|
||||
"type %d: size %d bytes\n", bufptr - buf,
|
||||
k + h->package_list[i].type_list[j].
|
||||
first_instance,
|
||||
h->package_list[i].type_list[j].type,
|
||||
h->package_list[i].type_list[j].instances[k].
|
||||
size);
|
||||
k + type->first_instance, type->type,
|
||||
instance->size);
|
||||
} else {
|
||||
fprintf(out, "0x%08x Instance #%d of "
|
||||
"type %d: %s\n", bufptr - buf,
|
||||
k + h->package_list[i].type_list[j].
|
||||
first_instance,
|
||||
h->package_list[i].type_list[j].type,
|
||||
(h->package_list[i].type_list[j].instances[k].
|
||||
filename == NULL) ? "<<UNNAMED>>" :
|
||||
h->package_list[i].type_list[j].instances[k].
|
||||
filename);
|
||||
k + type->first_instance, type->type,
|
||||
(instance->filename == NULL) ?
|
||||
"<<UNNAMED>>" : instance->filename);
|
||||
// NB. NULL filenames should not occur for
|
||||
// non-packaged files.
|
||||
}
|
||||
|
||||
bufptr += 2;
|
||||
} // for k
|
||||
} // for j
|
||||
@@ -415,29 +496,27 @@ listResources(const index_header *h, const uint8 *buf, FILE *out) {
|
||||
char *filename;
|
||||
|
||||
for (i = 0; i < h->num_packages; i++) {
|
||||
if (h->res_flags) {
|
||||
// packaged
|
||||
filename = (h->package_list[i].filename == NULL) ?
|
||||
"<<UNNAMED>>" : h->package_list[i].filename;
|
||||
package_desc *package = &h->package_list[i];
|
||||
|
||||
if (h->packaged) {
|
||||
// One filename for all resources in a package.
|
||||
filename = (package->filename == NULL) ?
|
||||
"<<INTERNAL>>" : package->filename;
|
||||
}
|
||||
|
||||
num_types = h->package_list[i].num_types;
|
||||
num_types = package->num_types;
|
||||
for (j = 0; j < num_types; j++) {
|
||||
packtype_desc *type = &package->type_list[j];
|
||||
int k;
|
||||
|
||||
num_instances = h->package_list[i].type_list[j].num_instances;
|
||||
num_instances = type->num_instances;
|
||||
for (k = 0; k < num_instances; k++) {
|
||||
if (!h->res_flags) {
|
||||
filename = (h->package_list[i].type_list[j].instances[k].
|
||||
filename == NULL) ? "<<UNNAMED>>" :
|
||||
h->package_list[i].type_list[j].instances[k].
|
||||
filename;
|
||||
}
|
||||
fprintf(out, "0x%08x %s\n",
|
||||
MAKE_RESOURCE(i + 1,
|
||||
h->package_list[i].type_list[j].type,
|
||||
h->package_list[i].type_list[j].first_instance + k),
|
||||
filename);
|
||||
packdef_instance *instance = &type->instances[k];
|
||||
if (!h->packaged)
|
||||
filename = (instance->filename == NULL) ?
|
||||
"<<UNNAMED>>" : instance->filename;
|
||||
fprintf(out, "0x%08x %s\n", MAKE_RESOURCE(i + 1, type->type,
|
||||
type->first_instance + k), filename);
|
||||
} // for k
|
||||
} // for j
|
||||
} // for i
|
||||
@@ -445,8 +524,8 @@ listResources(const index_header *h, const uint8 *buf, FILE *out) {
|
||||
}
|
||||
|
||||
char *
|
||||
get_file_name(const uint8 *buf, const index_header *h, uint16 file_index) {
|
||||
static char result[MAXPATHLEN];
|
||||
getFileName(const uint8 *buf, const index_header *h, uint16 file_index) {
|
||||
static char result[PATH_MAX];
|
||||
char *ptr;
|
||||
file_info *fi;
|
||||
uint16 path_offset;
|
||||
@@ -484,7 +563,7 @@ writeFile(const char *file, const uint8 *data, size_t len) {
|
||||
// check if all the path components exist
|
||||
{
|
||||
const char *ptr;
|
||||
char path[MAXPATHLEN];
|
||||
char path[PATH_MAX];
|
||||
|
||||
ptr = file;
|
||||
if (ptr[0] == '/')
|
||||
@@ -515,10 +594,10 @@ writeFile(const char *file, const uint8 *data, size_t len) {
|
||||
ssize_t written;
|
||||
written = write(fd, data, len);
|
||||
if (written < 0) {
|
||||
if (errno != EINTR) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
perror("write failed");
|
||||
exit(1);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
len -= written;
|
||||
data += written;
|
||||
@@ -526,43 +605,136 @@ writeFile(const char *file, const uint8 *data, size_t len) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
// If everything is ok, 0 is returned.
|
||||
// Returns -1 on error, in which case errno is set.
|
||||
int
|
||||
copyFileSegment(const char *src, FILE *inFile, size_t offset,
|
||||
const char *dest, size_t size) {
|
||||
FILE *outFile;
|
||||
#define BUFSIZE 4096
|
||||
uint8 buf[BUFSIZE];
|
||||
|
||||
if (fseek(inFile, offset, SEEK_SET) == -1) {
|
||||
int savedErrno = errno;
|
||||
fprintf(stderr, "Seeking in input file %s (to %ld) failed: %s.\n",
|
||||
src, (long int) offset, strerror(errno));
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
outFile = fopen(dest, "wb");
|
||||
if (outFile == NULL) {
|
||||
int savedErrno = errno;
|
||||
fprintf(stderr, "Opening output file %s failed: %s.\n",
|
||||
dest, strerror(errno));
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
size_t toRead;
|
||||
size_t numRead;
|
||||
size_t numWritten;
|
||||
|
||||
toRead = sizeof buf;
|
||||
if (toRead > size)
|
||||
toRead = size;
|
||||
|
||||
do {
|
||||
numRead = fread(buf, 1, toRead, inFile);
|
||||
} while (ferror(inFile) && errno == EINTR);
|
||||
if (numRead != toRead) {
|
||||
if (ferror(inFile)) {
|
||||
int savedErrno = errno;
|
||||
fprintf(stderr, "Error reading file %s: %s.\n", src,
|
||||
strerror(errno));
|
||||
fclose(outFile);
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
} else {
|
||||
// EOF
|
||||
assert(feof(inFile));
|
||||
fprintf(stderr, "Unexpected end-of-file while reading "
|
||||
"file %s.\n", src);
|
||||
fclose(outFile);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
numWritten = fwrite(buf, 1, numRead, outFile);
|
||||
} while (ferror(outFile) && errno == EINTR);
|
||||
if (numWritten != numRead) {
|
||||
int savedErrno = errno;
|
||||
fprintf(stderr, "Error writing to file %s: %s.\n", dest,
|
||||
strerror(errno));
|
||||
fclose(outFile);
|
||||
errno = savedErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
size -= numWritten;
|
||||
}
|
||||
|
||||
fclose(outFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Only for packaged files.
|
||||
void
|
||||
writeFiles(const index_header *h, const uint8 *data, const char *path) {
|
||||
int i;
|
||||
char filename[MAXPATHLEN];
|
||||
char filename[PATH_MAX];
|
||||
int num_types, num_instances;
|
||||
|
||||
for (i = 0; i < h->num_packages; i++) {
|
||||
package_desc *package = &h->package_list[i];
|
||||
int j;
|
||||
FILE *inFile = NULL;
|
||||
|
||||
if (package->filename != NULL) {
|
||||
inFile = fopen(package->filename, "rb");
|
||||
if (inFile == NULL) {
|
||||
fprintf(stderr, "Error: Could not open input file %s.\n",
|
||||
package->filename);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
num_types = h->package_list[i].num_types;
|
||||
for (j = 0; j < num_types; j++) {
|
||||
packtype_desc *type = &package->type_list[j];
|
||||
int k;
|
||||
|
||||
num_instances = h->package_list[i].type_list[j].num_instances;
|
||||
num_instances = type->num_instances;
|
||||
for (k = 0; k < num_instances; k++) {
|
||||
sprintf(filename, "%s/%08x",
|
||||
path,
|
||||
MAKE_RESOURCE(i + 1,
|
||||
h->package_list[i].type_list[j].type,
|
||||
h->package_list[i].type_list[j].first_instance + k));
|
||||
packdef_instance *instance = &type->instances[k];
|
||||
sprintf(filename, "%s/%08x", path,
|
||||
MAKE_RESOURCE(i + 1, type->type,
|
||||
type->first_instance + k));
|
||||
#if 0
|
||||
sprintf(filename, "%s/%08x=%03x-%02x-%03x",
|
||||
path,
|
||||
MAKE_RESOURCE(i + 1,
|
||||
h->package_list[i].type_list[j].type,
|
||||
h->package_list[i].type_list[j].first_instance + k),
|
||||
i + 1,
|
||||
h->package_list[i].type_list[j].type,
|
||||
h->package_list[i].type_list[j].first_instance + k);
|
||||
MAKE_RESOURCE(i + 1, type->type,
|
||||
type->first_instance + k), i + 1, type->type,
|
||||
type->first_instance + k);
|
||||
#endif
|
||||
writeFile(filename,
|
||||
&data[h->package_list[i].type_list[j].instances[k].
|
||||
offset],
|
||||
h->package_list[i].type_list[j].instances[k].size);
|
||||
}
|
||||
if (package->filename != NULL) {
|
||||
// Resource is contained in a different file.
|
||||
copyFileSegment(instance->filename, inFile,
|
||||
instance->offset, filename, instance->size);
|
||||
} else {
|
||||
// Resource is contained in this package file itself.
|
||||
writeFile(filename, &data[instance->offset],
|
||||
instance->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inFile != NULL)
|
||||
fclose(inFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -13,6 +13,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char uint8;
|
||||
@@ -73,7 +74,7 @@ typedef struct {
|
||||
} package_desc;
|
||||
|
||||
typedef struct {
|
||||
uint8 res_flags;
|
||||
bool packaged;
|
||||
uint32 packmem_list_offs;
|
||||
uint32 path_list_offs;
|
||||
uint32 file_list_offs;
|
||||
|
||||
Reference in New Issue
Block a user