Last active
March 27, 2021 06:35
-
-
Save Langerz82/7925a54e75685b1f4aad17782616f207 to your computer and use it in GitHub Desktop.
Flycast - Zip Support for CDI/GDI files - Some initial changes (7-zip not yet implemented).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/core/archive/7zArchive.cpp b/core/archive/7zArchive.cpp | |
index 8ae6bba3..28fd97a8 100644 | |
--- a/core/archive/7zArchive.cpp | |
+++ b/core/archive/7zArchive.cpp | |
@@ -105,6 +105,14 @@ ArchiveFile* SzArchive::OpenFileByCrc(u32 crc) | |
return NULL; | |
} | |
+ | |
+// TODO | |
+void SzArchive::Extract(const char *path, char* gamefile, | |
+ std::vector<string> &zipped_files) | |
+{ | |
+ return; | |
+} | |
+ | |
SzArchive::~SzArchive() | |
{ | |
if (lookStream.buf != NULL) | |
diff --git a/core/archive/7zArchive.h b/core/archive/7zArchive.h | |
index 7cdf3515..97fcc160 100644 | |
--- a/core/archive/7zArchive.h | |
+++ b/core/archive/7zArchive.h | |
@@ -38,6 +38,9 @@ public: | |
virtual ArchiveFile* OpenFile(const char* name) override; | |
virtual ArchiveFile *OpenFileByCrc(u32 crc) override; | |
+ virtual void Extract(const char *path, char* gamefile, | |
+ std::vector<string> &zipped_files) override; | |
+ | |
private: | |
virtual bool Open(const char* path) override; | |
diff --git a/core/archive/ZipArchive.cpp b/core/archive/ZipArchive.cpp | |
index aca16614..2a728d2f 100644 | |
--- a/core/archive/ZipArchive.cpp | |
+++ b/core/archive/ZipArchive.cpp | |
@@ -19,6 +19,7 @@ | |
along with reicast. If not, see <https://www.gnu.org/licenses/>. | |
*/ | |
#include "ZipArchive.h" | |
+#include "../log/LogManager.h" | |
ZipArchive::~ZipArchive() | |
{ | |
@@ -78,3 +79,45 @@ u32 ZipArchiveFile::Read(void* buffer, u32 length) | |
{ | |
return zip_fread(zip_file, buffer, length); | |
} | |
+ | |
+void ZipArchive::Extract(const char *path, char* gamefile, | |
+ std::vector<string> &zipped_files) | |
+{ | |
+ struct zip_stat sb; | |
+ struct zip_file *zf; | |
+ char buf[1024*8]; | |
+ FILE* fd; | |
+ u32 sum, len; | |
+ int num = zip_get_num_files(zip); | |
+ INFO_LOG(COMMON, "num: %d", num); | |
+ for (u32 i = 0; i < num; i++) { | |
+ if (zip_stat_index(zip, i, 0, &sb) == 0) { | |
+ INFO_LOG(COMMON, "sb.name: %s", sb.name); | |
+ INFO_LOG(COMMON, "sb.size: %d", (int) sb.size); | |
+ | |
+ zf = zip_fopen_index(zip, i, 0); | |
+ string z_file = (string) path + "/" + sb.name; | |
+ zipped_files.push_back(z_file); | |
+ fd = fopen(z_file.c_str(), "wb"); | |
+ INFO_LOG(COMMON, "filename: %s", z_file.c_str()); | |
+ sum = 0; | |
+ while (sum != sb.size) { | |
+ len = zip_fread(zf, buf, 1024*8); | |
+ if (len < 0) { | |
+ ERROR_LOG(COMMON, "zip_fread: %d ", len); | |
+ } | |
+ fwrite(buf, sizeof(char), len, fd); | |
+ sum += len; | |
+ } | |
+ char *ext = strrchr((char*)z_file.c_str(), '.'); | |
+ if (!strcmp(".cdi", ext) || !strcmp(".CDI", ext) || | |
+ !strcmp(".gdi", ext) || !strcmp(".GDI", ext)) | |
+ { | |
+ strncpy(gamefile, z_file.c_str(), strlen(gamefile)); | |
+ INFO_LOG(COMMON, "gamefile: %s", gamefile); | |
+ } | |
+ fclose(fd); | |
+ zip_fclose(zf); | |
+ } | |
+ } | |
+} | |
diff --git a/core/archive/ZipArchive.h b/core/archive/ZipArchive.h | |
index d63e5756..ab2eda2a 100644 | |
--- a/core/archive/ZipArchive.h | |
+++ b/core/archive/ZipArchive.h | |
@@ -32,6 +32,8 @@ public: | |
virtual ArchiveFile* OpenFile(const char* name) override; | |
virtual ArchiveFile* OpenFileByCrc(u32 crc) override; | |
+ virtual void Extract(const char *path, char* gamefile, | |
+ std::vector<string> &zipped_files) override; | |
private: | |
virtual bool Open(const char* path) override; | |
diff --git a/core/archive/archive.h b/core/archive/archive.h | |
index 54b84c56..8d413355 100644 | |
--- a/core/archive/archive.h | |
+++ b/core/archive/archive.h | |
@@ -39,6 +39,8 @@ public: | |
virtual ArchiveFile *OpenFileByCrc(u32 crc) = 0; | |
friend Archive *OpenArchive(const char *path); | |
+ virtual void Extract(const char *path, char* gamefile, | |
+ std::vector<string> &zipped_files) = 0; | |
private: | |
virtual bool Open(const char *name) = 0; | |
diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp | |
index 3eea93ce..56cf7524 100644 | |
--- a/core/hw/naomi/naomi_cart.cpp | |
+++ b/core/hw/naomi/naomi_cart.cpp | |
@@ -386,6 +386,26 @@ error: | |
return false; | |
} | |
+bool naomi_is_cart(const char* file) | |
+{ | |
+ const char *ext = path_get_extension(file); | |
+ | |
+ char game_name[128]; | |
+ strncpy(game_name, path_basename(file), sizeof(game_name) - 1); | |
+ game_name[sizeof(game_name) - 1] = '\0'; | |
+ path_remove_extension(game_name); | |
+ | |
+ int gameid = 0; | |
+ for (; Games[gameid].name != NULL; gameid++) | |
+ if (!stricmp(Games[gameid].name, game_name)) | |
+ break; | |
+ if (Games[gameid].name == NULL) | |
+ // Not found. Will fail later | |
+ return false; | |
+ | |
+ return true; | |
+} | |
+ | |
int naomi_cart_GetSystemType(const char* file) | |
{ | |
const char *ext = path_get_extension(file); | |
diff --git a/core/hw/naomi/naomi_cart.h b/core/hw/naomi/naomi_cart.h | |
index 8309c45c..0801061a 100644 | |
--- a/core/hw/naomi/naomi_cart.h | |
+++ b/core/hw/naomi/naomi_cart.h | |
@@ -86,6 +86,7 @@ private: | |
}; | |
bool naomi_cart_SelectFile(); | |
+bool naomi_is_cart(const char* file); | |
int naomi_cart_GetSystemType(const char* file); | |
int naomi_cart_GetRotation(); | |
void naomi_cart_Close(); | |
diff --git a/core/libretro-common/include/libretro.h b/core/libretro-common/include/libretro.h | |
index 4ddb6e89..67876f7b 100644 | |
--- a/core/libretro-common/include/libretro.h | |
+++ b/core/libretro-common/include/libretro.h | |
@@ -2681,7 +2681,7 @@ struct retro_core_options_intl | |
struct retro_game_info | |
{ | |
- const char *path; /* Path to game, UTF-8 encoded. | |
+ char *path; /* Path to game, UTF-8 encoded. | |
* Sometimes used as a reference for building other paths. | |
* May be NULL if game was loaded from stdin or similar, | |
* but in this case some cores will be unable to load `data`. | |
@@ -2854,7 +2854,7 @@ RETRO_API void retro_cheat_set(unsigned index, bool enabled, const char *code); | |
/* Loads a game. | |
* Return true to indicate successful loading and false to indicate load failure. | |
*/ | |
-RETRO_API bool retro_load_game(const struct retro_game_info *game); | |
+RETRO_API bool retro_load_game(struct retro_game_info *game); | |
/* Loads a "special" kind of game. Should not be used, | |
* except in extreme cases. */ | |
diff --git a/core/libretro/libretro.cpp b/core/libretro/libretro.cpp | |
index f5f41ac3..1828ec45 100644 | |
--- a/core/libretro/libretro.cpp | |
+++ b/core/libretro/libretro.cpp | |
@@ -53,6 +53,7 @@ char* strdup(const char *str) | |
#include "log/LogManager.h" | |
#include "cheats.h" | |
#include "rend/CustomTexture.h" | |
+#include "../archive/archive.h" | |
#if defined(_XBOX) || defined(_WIN32) | |
char slash = '\\'; | |
@@ -184,6 +185,9 @@ static void init_disk_control_interface(void); | |
static bool read_m3u(const char *file); | |
char *game_data; | |
+ | |
+std::vector<string> zipped_files; | |
+ | |
char g_base_name[128]; | |
char game_dir[1024]; | |
char game_dir_no_slash[1024]; | |
@@ -1826,8 +1830,22 @@ static bool set_opengl_hw_render(u32 preferred) | |
#endif | |
} | |
+ | |
+static void LoadZipFile(char* filename) | |
+{ | |
+ Archive *archive = OpenArchive(filename); | |
+ if (archive != NULL) | |
+ INFO_LOG(COMMON, "Opened Archive %s", filename); | |
+ | |
+ archive->Extract(game_dir, filename, zipped_files); | |
+ | |
+ if (archive != NULL) | |
+ delete archive; | |
+ | |
+} | |
+ | |
// Loading/unloading games | |
-bool retro_load_game(const struct retro_game_info *game) | |
+bool retro_load_game(struct retro_game_info *game) | |
{ | |
const char *dir = NULL; | |
const char *vmu_dir = NULL; | |
@@ -1840,6 +1858,15 @@ bool retro_load_game(const struct retro_game_info *game) | |
extract_basename(g_base_name, game->path, sizeof(g_base_name)); | |
extract_directory(game_dir, game->path, sizeof(game_dir)); | |
+ char *ext = strrchr(g_base_name, '.'); | |
+ if (!naomi_is_cart(game->path) && | |
+ (!strcmp(".zip", ext) || !strcmp(".ZIP", ext) || | |
+ !strcmp(".7z", ext) || !strcmp(".7Z", ext))) | |
+ { | |
+ LoadZipFile(game->path); | |
+ log_cb(RETRO_LOG_INFO, "LoadZipFile: %s\n", game->path); | |
+ } | |
+ | |
// Storing rom dir for later use | |
snprintf(g_roms_dir, sizeof(g_roms_dir), "%s%c", game_dir, slash); | |
@@ -1869,19 +1896,19 @@ bool retro_load_game(const struct retro_game_info *game) | |
settings.dreamcast.cable = 3; | |
update_variables(true); | |
- char *ext = strrchr(g_base_name, '.'); | |
- | |
+ settings.System = DC_PLATFORM_DREAMCAST; | |
{ | |
/* Check for extension .lst, .bin, .dat or .zip. If found, we will set the system type | |
* automatically to Naomi or AtomisWave. */ | |
if (ext) | |
{ | |
log_cb(RETRO_LOG_INFO, "File extension is: %s\n", ext); | |
- if (!strcmp(".lst", ext) | |
+ if ((!strcmp(".lst", ext) | |
|| !strcmp(".bin", ext) || !strcmp(".BIN", ext) | |
|| !strcmp(".dat", ext) || !strcmp(".DAT", ext) | |
|| !strcmp(".zip", ext) || !strcmp(".ZIP", ext) | |
|| !strcmp(".7z", ext) || !strcmp(".7Z", ext)) | |
+ && naomi_is_cart(game->path)) | |
{ | |
settings.System = naomi_cart_GetSystemType(game->path); | |
/* System may have changed - have to update | |
@@ -2048,6 +2075,14 @@ bool retro_load_game_special(unsigned game_type, const struct retro_game_info *i | |
void retro_unload_game(void) | |
{ | |
+ INFO_LOG(COMMON, "Flycast deleting tmp rom"); | |
+ for (std::vector<string>::iterator it = zipped_files.begin(); | |
+ it != zipped_files.end(); ++it) | |
+ { | |
+ remove(it->c_str()); | |
+ log_cb(RETRO_LOG_INFO, "removed: %s\n", it->c_str()); | |
+ } | |
+ | |
INFO_LOG(COMMON, "Flycast unloading game"); | |
if (game_data) | |
free(game_data); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment