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:
+102
-3
@@ -28,6 +28,7 @@ struct options {
|
|||||||
char list;
|
char list;
|
||||||
char print;
|
char print;
|
||||||
char verbose;
|
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 parse_arguments(int argc, char *argv[], struct options *opts);
|
||||||
void listEntries(const index_header *h, const uint8 *buf, FILE *out);
|
void listEntries(const index_header *h, const uint8 *buf, FILE *out);
|
||||||
void writeEntries(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
|
int
|
||||||
main(int argc, char *argv[]) {
|
main(int argc, char *argv[]) {
|
||||||
@@ -47,6 +56,7 @@ main(int argc, char *argv[]) {
|
|||||||
uint8 *buf;
|
uint8 *buf;
|
||||||
index_header *h;
|
index_header *h;
|
||||||
struct options opts;
|
struct options opts;
|
||||||
|
char outnbuf[512];
|
||||||
|
|
||||||
parse_arguments(argc, argv, &opts);
|
parse_arguments(argc, argv, &opts);
|
||||||
|
|
||||||
@@ -69,6 +79,15 @@ main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
close(in);
|
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);
|
h = readIndex(buf);
|
||||||
if (opts.print)
|
if (opts.print)
|
||||||
printIndex(h, buf, stdout);
|
printIndex(h, buf, stdout);
|
||||||
@@ -77,7 +96,10 @@ main(int argc, char *argv[]) {
|
|||||||
listEntries(h, buf, stdout);
|
listEntries(h, buf, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.outfile) {
|
if (opts.sound && opts.outfile) {
|
||||||
|
writeSoundEntries(h, buf, opts.outfile);
|
||||||
|
|
||||||
|
} else if (opts.outfile) {
|
||||||
FILE *out;
|
FILE *out;
|
||||||
out = fopen(opts.outfile, "wb+");
|
out = fopen(opts.outfile, "wb+");
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
@@ -99,7 +121,8 @@ usage() {
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"unstr -a <infile>\n"
|
"unstr -a <infile>\n"
|
||||||
"unstr -p <infile>\n"
|
"unstr -p <infile>\n"
|
||||||
"unstr [-o <outfile>] <infile>\n");
|
"unstr [-o <outfile>] <infile>\n"
|
||||||
|
"unstr -s [-o <outfile>] <infile-sndtab>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -108,7 +131,7 @@ parse_arguments(int argc, char *argv[], struct options *opts) {
|
|||||||
|
|
||||||
memset(opts, '\0', sizeof (struct options));
|
memset(opts, '\0', sizeof (struct options));
|
||||||
while (1) {
|
while (1) {
|
||||||
ch = getopt(argc, argv, "ahlo:pv");
|
ch = getopt(argc, argv, "ahlo:psv");
|
||||||
if (ch == -1)
|
if (ch == -1)
|
||||||
break;
|
break;
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
@@ -124,6 +147,9 @@ parse_arguments(int argc, char *argv[], struct options *opts) {
|
|||||||
case 'v':
|
case 'v':
|
||||||
opts->verbose = 1;
|
opts->verbose = 1;
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
opts->sound = 1;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user