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:
+103
-4
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user