From cad9c1bbc9226a3d15321696c49eac2d3536782c Mon Sep 17 00:00:00 2001 From: Kyle K Date: Mon, 20 Apr 2015 16:14:32 -0500 Subject: add logic to detect game archive, test Wangan Midnight audio extraction --- TXRExtractor.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++------- TXRExtractor.h | 4 +++- TXRExtractor.vcxproj | 1 + wmn.cpp | 9 +++++++++ wmn.h | 1 + 5 files changed, 61 insertions(+), 8 deletions(-) diff --git a/TXRExtractor.cpp b/TXRExtractor.cpp index f52d7b4..0961018 100644 --- a/TXRExtractor.cpp +++ b/TXRExtractor.cpp @@ -2,7 +2,7 @@ * Tokyo Xtreme Racer Extractor * * currently supported archives: - * - Wangan Midnight 2007 PS3..............: WMN.DAT (done), AUDIO_PS3.DAT (work in progress...) + * - Wangan Midnight 2007 PS3..............: WMN.DAT (done), AUDIO_PS3.DAT (DONE) * - Import Tuner Challenge 2006 XBOX360...: work in progress... * * @@ -16,8 +16,42 @@ #include #include +// detects supported Tokyo Xtreme Racer archive +int txre_detect_archive(archive_unpack_f *f, FILE *fd_archive, FILE *fd_toc) { + int ret1, ret2; + char toc_heading[48] = { 0 }; + char dat_heading[60] = { 0 }; + + // read first 60 bytes of archive and 48 bytes of table of content + ret1 = fread(toc_heading, 48, 1, fd_toc); + ret2 = fread(dat_heading, 60, 1, fd_archive); + + if (ret1 & ret2) { + struct WMN_TOC_HEADER *toc_header = (struct WMN_TOC_HEADER *) toc_heading; + struct WMN_DAT_CHUNK *dat_header = (struct WMN_DAT_CHUNK *) dat_heading; + + // detect Wangan Midnight + if ((strncmp(toc_header->fourcc, "BLDh", 4) == 0) && (strncmp(toc_header->def_section, "def ", 4) == 0)) { + if ((strncmp(dat_header->fourcc, "GARC", 4) == 0) && (strncmp(dat_header->file_zlib_magic, "zlib", 4) == 0)) { + *f = wmn_extract; + return 0; + } else { + *f = wmn_extract_audio; + return 0; + } + } + } else { + fprintf(stderr, "failed to prefetch first 60 bytes of archive and first 48 bytes of toc: %s\n", strerror(errno)); + } + + return 1; +} + int main(int argc, char* argv[]) { + archive_unpack_f archive_unpack = NULL; + int ret; + /* avoid end-of-line conversions */ _setmode(_fileno(stdin), O_BINARY); _setmode(_fileno(stdout), O_BINARY); @@ -35,13 +69,19 @@ int main(int argc, char* argv[]) exit(2); } - // cd to output dir - if (_chdir(argv[3])) { - fprintf(stderr, "couldn't cd into %s: %s\n", argv[3], strerror(errno)); - exit(12); - } + ret = txre_detect_archive(&archive_unpack, fd_archive, fd_toc); + if (ret == 0) { + // cd to output dir + if (_chdir(argv[3])) { + fprintf(stderr, "couldn't cd into %s: %s\n", argv[3], strerror(errno)); + exit(12); + } - wmn_extract(fd_archive, fd_toc); + // unpack archive + ret = archive_unpack(fd_archive, fd_toc); + } else { + fprintf(stdout, "unsupported archive\n"); + } fclose(fd_archive); fclose(fd_toc); diff --git a/TXRExtractor.h b/TXRExtractor.h index 67c0a80..ede16e3 100644 --- a/TXRExtractor.h +++ b/TXRExtractor.h @@ -1,7 +1,9 @@ #ifndef TXREXTRACTOR_HEADER #define TXREXTRACTOR_HEADER -// function prototypes +typedef int(*archive_unpack_f)(FILE *, FILE *); +// function prototypes +int txre_detect_archive(archive_unpack_f *, FILE *, FILE *); #endif diff --git a/TXRExtractor.vcxproj b/TXRExtractor.vcxproj index fa817b8..dbf337c 100644 --- a/TXRExtractor.vcxproj +++ b/TXRExtractor.vcxproj @@ -72,6 +72,7 @@ true WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true + include Console diff --git a/wmn.cpp b/wmn.cpp index 5e57e22..6789317 100644 --- a/wmn.cpp +++ b/wmn.cpp @@ -266,6 +266,9 @@ int wmn_extract(FILE *fd_archive, FILE *fd_toc) { char **filenames; int i, ret; + rewind(fd_archive); + rewind(fd_toc); + // parse toc header and check for validity ret = fread((void *) &toc_header, sizeof(struct WMN_TOC_HEADER), 1, fd_toc); if ( ret != 1 || !(strncmp(toc_header.fourcc, "BLDh", 4) == 0) || !(strncmp(toc_header.def_section, "def ", 4) == 0) ) { @@ -295,3 +298,9 @@ int wmn_extract(FILE *fd_archive, FILE *fd_toc) { return 0; } + +int wmn_extract_audio(FILE *fd_archive, FILE *fd_toc) { + // audio files are stored uncompressed, since wmn_dat_inflate_file already can handle non zlib deflated files + // we can call wmn_extract directly + return wmn_extract(fd_archive, fd_toc); +} diff --git a/wmn.h b/wmn.h index 7f81695..e30756e 100644 --- a/wmn.h +++ b/wmn.h @@ -85,5 +85,6 @@ int wmn_dat_inflate_file(FILE *, struct WMN_DAT_CHUNK, struct WMN_TOC_DIR_ENTRY, int wmn_toc_parse_filenames(FILE *, struct WMN_TOC_HEADER, char **); int wmn_toc_parse_dir_entries(FILE *, FILE *, struct WMN_TOC_HEADER, char **); int wmn_extract(FILE *, FILE *); +int wmn_extract_audio(FILE *, FILE *); #endif -- cgit v1.2.3