From 0c4c749f81443979abda62984a95e1bc791f997c Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Tue, 2 Sep 2014 17:05:15 +0200 Subject: [PATCH] Added commandline 7z support --- file.c | 22 +++++++++++++++++++++- file_path.c | 15 +++++++++++++++ file_path.h | 4 ++++ general.h | 8 ++++++++ retroarch.c | 21 +++++++++++++++++++-- 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/file.c b/file.c index ee9b015625..46cde11290 100644 --- a/file.c +++ b/file.c @@ -132,7 +132,27 @@ error: static ssize_t read_content_file(const char *path, void **buf) { uint8_t *ret_buf = NULL; - ssize_t ret = read_file(path, (void**)&ret_buf); + ssize_t ret = -1; + /* Here we check, whether the file, we are about to read is inside an archive, or not. + We determine, whether a file is inside a compressed archive, by checking, if the archive string is a substring of the + complete path + For example: fullpath: /home/user/game.7z/mygame.rom + carchive_path: /home/user/game.7z */ +#ifdef HAVE_COMPRESSION + char const* archive_found = strstr(path,g_extern.carchive_path); + if (g_extern.is_carchive) + { + if(archive_found) + { + char rel_path[PATH_MAX]; + snprintf(rel_path, sizeof(rel_path), archive_found+strlen(g_extern.carchive_path)+1); + ret = read_compressed_file(g_extern.carchive_path, rel_path, (void**)&ret_buf); + } + } + else +#endif + ret = read_file(path, (void**)&ret_buf); + if (ret <= 0) return ret; diff --git a/file_path.c b/file_path.c index e7c9e078a7..8fe81e687f 100644 --- a/file_path.c +++ b/file_path.c @@ -60,6 +60,10 @@ #include #endif +#ifdef HAVE_7ZIP +#include "decompress/7zip_support.h" +#endif + /* Dump to file. */ bool write_file(const char *path, const void *data, size_t size) { @@ -73,6 +77,17 @@ bool write_file(const char *path, const void *data, size_t size) return ret; } +/* Generic compressed file loader. */ +#ifdef HAVE_COMPRESSION +long read_compressed_file(const char * archive_path, const char *relative_path, void **buf) +{ +#ifdef HAVE_7ZIP + return read_7zip_file(archive_path,relative_path,buf); +#endif + return -1; +} +#endif + /* Generic file loader. */ long read_file(const char *path, void **buf) { diff --git a/file_path.h b/file_path.h index 8dc8438881..c7beb2d366 100644 --- a/file_path.h +++ b/file_path.h @@ -26,6 +26,10 @@ extern "C" { #endif +#ifdef HAVE_COMPRESSION +long read_compressed_file(const char * archive_path, const char *relative_path, void **buf); +#endif + long read_file(const char *path, void **buf); bool read_file_string(const char *path, char **buf); bool write_file(const char *path, const void *buf, size_t size); diff --git a/general.h b/general.h index 45237ca16b..7b6caa3821 100644 --- a/general.h +++ b/general.h @@ -442,6 +442,14 @@ struct global char basename[PATH_MAX]; char fullpath[PATH_MAX]; +#ifdef HAVE_COMPRESSION + // In case of a compressed archive, this is the path to the archive. Fullpath contains everything + char carchive_path[PATH_MAX]; + + // True, in case of a compressed archive containing the rom. + bool is_carchive; +#endif + // A list of save types and associated paths for all content. struct string_list *savefiles; diff --git a/retroarch.c b/retroarch.c index 40809113a2..2f7b736f10 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1008,6 +1008,9 @@ static void print_help(void) puts("\t\tAvailable commands are listed if command is invalid."); #endif +#ifdef HAVE_COMPRESSION + puts("\t-z/--carchive: Path to a compressed container containing the main content file.\n\t\tThe main content file has to be specified as a subfile, for example like this:\n\t\t ./retroarch -Lmylib.so -z myfile.7z myfile.7z/myrom.rom ."); +#endif puts("\t-r/--record: Path to record video file.\n\t\tUsing .mkv extension is recommended."); puts("\t--recordconfig: Path to settings used during recording."); puts("\t--size: Overrides output video size when recording (format: WIDTHxHEIGHT)."); @@ -1175,6 +1178,9 @@ static void parse_input(int argc, char *argv[]) { "detach", 0, NULL, 'D' }, { "features", 0, &val, 'f' }, { "subsystem", 1, NULL, 'Z' }, +#ifdef HAVE_COMPRESSION + { "carchive", 0, NULL, 'z' }, +#endif { NULL, 0, NULL, 0 } }; @@ -1192,9 +1198,15 @@ static void parse_input(int argc, char *argv[]) #define NETPLAY_ARG #endif +#ifdef HAVE_COMPRESSION +#define COMPRESS_ARG "z:" +#else +#define COMPRESS_ARG +#endif + #define BSV_MOVIE_ARG "P:R:M:" - const char *optstring = "hs:fvS:A:c:U:DN:d:" BSV_MOVIE_ARG NETPLAY_ARG DYNAMIC_ARG FFMPEG_RECORD_ARG; + const char *optstring = "hs:fvS:A:c:U:DN:d:" BSV_MOVIE_ARG NETPLAY_ARG DYNAMIC_ARG FFMPEG_RECORD_ARG COMPRESS_ARG; for (;;) { @@ -1313,7 +1325,12 @@ static void parse_input(int argc, char *argv[]) } break; #endif - +#ifdef HAVE_COMPRESSION + case 'z': + strlcpy(g_extern.carchive_path, optarg, sizeof(g_extern.carchive_path)); + g_extern.is_carchive = true; + break; +#endif case 'P': case 'R': strlcpy(g_extern.bsv.movie_start_path, optarg,