Unpacks sound strtabs into waves now (with -s)

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@732 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2003-02-12 01:04:44 +00:00
parent 6938c61ed6
commit 1e08fd27de
+103 -4
View File
@@ -28,6 +28,7 @@ struct options {
char list;
char print;
char verbose;
char sound;
};
@@ -38,7 +39,15 @@ void writeFiles(const index_header *h, const uint8 *data, const char *path,
void parse_arguments(int argc, char *argv[], struct options *opts);
void listEntries(const index_header *h, const uint8 *buf, FILE *out);
void writeEntries(const index_header *h, const uint8 *buf, FILE *out);
void writeSoundEntries(const index_header *h, const uint8 *buf, const char* outmask);
const char *riffHdr = "RIFF";
const char *waveType = "WAVE";
const char *fmtHdr = "fmt ";
const char *dataHdr = "data";
#define FMTHDR_SIZE 0x10
#define DATAHDR_SIZE 0x08
#define WAVEHDR_SIZE (4 + 4 + 4 + FMTHDR_SIZE + DATAHDR_SIZE)
int
main(int argc, char *argv[]) {
@@ -47,6 +56,7 @@ main(int argc, char *argv[]) {
uint8 *buf;
index_header *h;
struct options opts;
char outnbuf[512];
parse_arguments(argc, argv, &opts);
@@ -69,6 +79,15 @@ main(int argc, char *argv[]) {
}
close(in);
if (opts.sound && !opts.outfile) {
char *pdot = strrchr(opts.infile, '.');
opts.outfile = outnbuf;
strcpy(outnbuf, opts.infile);
if (pdot)
outnbuf[pdot - opts.infile] = 0;
}
h = readIndex(buf);
if (opts.print)
printIndex(h, buf, stdout);
@@ -76,8 +95,11 @@ main(int argc, char *argv[]) {
if (opts.list) {
listEntries(h, buf, stdout);
}
if (opts.outfile) {
if (opts.sound && opts.outfile) {
writeSoundEntries(h, buf, opts.outfile);
} else if (opts.outfile) {
FILE *out;
out = fopen(opts.outfile, "wb+");
if (out == NULL) {
@@ -99,7 +121,8 @@ usage() {
fprintf(stderr,
"unstr -a <infile>\n"
"unstr -p <infile>\n"
"unstr [-o <outfile>] <infile>\n");
"unstr [-o <outfile>] <infile>\n"
"unstr -s [-o <outfile>] <infile-sndtab>\n");
}
void
@@ -108,7 +131,7 @@ parse_arguments(int argc, char *argv[], struct options *opts) {
memset(opts, '\0', sizeof (struct options));
while (1) {
ch = getopt(argc, argv, "ahlo:pv");
ch = getopt(argc, argv, "ahlo:psv");
if (ch == -1)
break;
switch(ch) {
@@ -124,6 +147,9 @@ parse_arguments(int argc, char *argv[], struct options *opts) {
case 'v':
opts->verbose = 1;
break;
case 's':
opts->sound = 1;
break;
case '?':
case 'h':
default:
@@ -209,4 +235,77 @@ writeEntries(const index_header *h, const uint8 *buf, FILE *out) {
}
}
void
signSoundBuf(uint8 *buf, uint32 len)
{
for (; len; ++buf, --len)
*buf ^= 0x80;
}
void
writeFile_Int16_LE(FILE *f, uint16 val)
{
fputc(val & 0xff, f);
fputc((val >> 8) & 0xff, f);
}
void
writeFile_Int32_LE(FILE *f, uint32 val)
{
writeFile_Int16_LE(f, val & 0xffff);
writeFile_Int16_LE(f, (val >> 16) & 0xffff);
}
void
writeSoundEntries(const index_header *h, const uint8 *buf, const char* outmask) {
FILE *out;
uint32 i;
char namebuf[512];
const uint8 *start;
uint8 *data;
const uint8 *orgdata;
uint32 datalen;
uint32 wavelen;
uint32 freq;
start = buf + 8 + (h->num_entries + 1) * 4;
data = NULL;
for (i = 0; i < h->num_entries; i++) {
sprintf(namebuf, "%s.%u.wav", outmask, i);
out = fopen(namebuf, "wb");
if (out == NULL) {
fprintf(stderr, "Could not open output file '%s': %s\n",
namebuf, strerror(errno));
exit(EXIT_FAILURE);
}
datalen = h->entries[i].size - 2;
data = realloc(data, datalen);
orgdata = start + h->entries[i].offset;
memcpy(data, orgdata, datalen);
signSoundBuf(data, datalen);
freq = MAKE_WORD(orgdata[datalen], orgdata[datalen + 1]);
wavelen = datalen + WAVEHDR_SIZE;
fputs(riffHdr, out);
writeFile_Int32_LE(out, wavelen);
fputs(waveType, out);
fputs(fmtHdr, out);
writeFile_Int32_LE(out, FMTHDR_SIZE);
writeFile_Int16_LE(out, 1); // format
writeFile_Int16_LE(out, 1); // channels
writeFile_Int32_LE(out, freq); // samples/sec
writeFile_Int32_LE(out, freq); // bytes/sec
writeFile_Int16_LE(out, 1); // block align
writeFile_Int16_LE(out, 8); // bits/sample
fputs(dataHdr, out);
writeFile_Int32_LE(out, datalen);
fwrite(data, 1, datalen, out);
fclose(out);
}
free(data);
}