Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Filename: readVCC.c
- Author: Jeremy L. Crabtree <JeremyLC@GMail.com>
- Date: 20 July, 2014
- Purpose: This will read and extract the VOC/ACMP files embedded in
- the VCC container files used in Interplay's
- "Star Trek: Judgement Rites". Decompressing the ACMP audio
- is a job for someone less lazy than me.
- Notes: Output files are dumped in pwd because I'm lazy. Run this from
- where you want the output.
- License: If you re-use this code (pity you!) give me credit, thanks! :)
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- /* The master record is in the same format as the individual file records */
- typedef struct vccRecord
- {
- unsigned char header[9];
- unsigned int offset, size;
- } vccRecord;
- int read4byteint(FILE * inFile)
- {
- /* Read a 4 byte int that is stored LSB..MSB */
- unsigned char value[4];
- fread(value, 1, 4, inFile);
- return value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] << 24);
- }
- void readRecord(FILE * inFile, vccRecord *rec)
- {
- /*
- Read a 16 byte record.
- The first 8 bytes are text.
- The next 8 bytes are two 4-byte little-endian ints
- */
- rec->header[8] = '\x0'; //8 byte headers aren't null-terminated.
- fread(rec->header, 1, 8, inFile);
- rec->offset = read4byteint(inFile);
- rec->size = read4byteint(inFile);
- }
- void extractFile(vccRecord newFile, FILE *inFile)
- {
- /* Extract a VOC/ACMP from the main VCC file */
- unsigned int savedPos;
- unsigned char *fBuf;
- FILE *outFile;
- if(outFile = fopen(newFile.header, "wb"))
- {
- savedPos = ftell(inFile);
- fseek(inFile, newFile.offset, SEEK_SET);
- fBuf = malloc(newFile.size);
- fread(fBuf, 1, newFile.size, inFile);
- fwrite(fBuf, 1, newFile.size, outFile);
- free(fBuf);
- fclose(outFile);
- fseek(inFile, savedPos, SEEK_SET);
- }
- else
- {
- printf("Error %d opening %s for output\n", errno, newFile.header);
- exit(errno);
- }
- }
- int main(argc, argv)
- int argc;
- char **argv;
- {
- /* The rest of this should be self explanatory */
- unsigned int fileNum;
- vccRecord vccHead , fileRec;
- FILE *vccFile;
- if (2 == argc)
- if (vccFile = fopen(argv[1], "rb"))
- {
- readRecord(vccFile, &vccHead);
- if (strcmp(vccHead.header, "VOCFILES"))
- {
- fclose(vccFile);
- printf("Error %s is not a VCC file.\n", argv[1]);
- exit(1);
- }
- fseek(vccFile, vccHead.offset, SEEK_SET);
- for (fileNum = 0; fileNum < vccHead.size; fileNum++)
- {
- readRecord(vccFile, &fileRec);
- extractFile(fileRec, vccFile);
- }
- fclose(vccFile);
- }
- else
- {
- printf("Error %d opening %s\n", errno, argv[1]);
- exit(errno);
- }
- else
- printf("Usage %s <filename.vcc>\n", argv[0]);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement