Allowed Drag & Drop importing of mods and DynOS packs

This commit is contained in:
MysterD 2023-04-03 19:15:52 -07:00
parent 0d21c66037
commit 9c6fef9ecd
25 changed files with 9624 additions and 30 deletions

View file

@ -534,7 +534,7 @@ SRC_DIRS := src src/engine src/game src/audio src/bass_audio src/menu src/buffer
BIN_DIRS := bin bin/$(VERSION) BIN_DIRS := bin bin/$(VERSION)
# PC files # PC files
SRC_DIRS += src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes src/pc/mods src/pc/network src/pc/network/packets src/pc/network/socket src/pc/utils src/pc/djui src/pc/lua src/pc/lua/utils SRC_DIRS += src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes src/pc/mods src/pc/network src/pc/network/packets src/pc/network/socket src/pc/utils src/pc/utils/miniz src/pc/djui src/pc/lua src/pc/lua/utils
#ifeq ($(DISCORDRPC),1) #ifeq ($(DISCORDRPC),1)
# SRC_DIRS += src/pc/discord # SRC_DIRS += src/pc/discord

View file

@ -26,6 +26,7 @@ bool dynos_warp_exit_level(s32 aDelay);
bool dynos_warp_to_castle(s32 aLevel); bool dynos_warp_to_castle(s32 aLevel);
// -- dynos packs -- // // -- dynos packs -- //
void dynos_packs_init(void);
int dynos_pack_get_count(void); int dynos_pack_get_count(void);
const char* dynos_pack_get_name(s32 index); const char* dynos_pack_get_name(s32 index);
bool dynos_pack_get_enabled(s32 index); bool dynos_pack_get_enabled(s32 index);

View file

@ -67,6 +67,11 @@ bool dynos_warp_to_castle(s32 aLevel) {
// -- dynos packs -- // // -- dynos packs -- //
void dynos_packs_init(void) {
DynOS_Gfx_Init();
DynOS_Pack_Init();
}
int dynos_pack_get_count(void) { int dynos_pack_get_count(void) {
return DynOS_Pack_GetCount(); return DynOS_Pack_GetCount();
} }

View file

@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Disconnected:\\#c8c8c8\\ Host has closed the con
DISCONNECT_BIG_MOD = "Server had too large of a mod.\nQuitting." DISCONNECT_BIG_MOD = "Server had too large of a mod.\nQuitting."
DIED = "@ died" DIED = "@ died"
DEBUG_FLY = "@ entered the debug free fly state" DEBUG_FLY = "@ entered the debug free fly state"
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
[CHAT] [CHAT]
KICKING = "Kicking '@'!" KICKING = "Kicking '@'!"

View file

@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Déconnecté:\\#c8c8c8\\ L'hôte s'est déconnec
DISCONNECT_BIG_MOD = "Le mod utilisé est trop volumineux.\nDéconnexion." DISCONNECT_BIG_MOD = "Le mod utilisé est trop volumineux.\nDéconnexion."
DIED = "@ est mort" DIED = "@ est mort"
DEBUG_FLY = "@ a activé le mode vol (débug) " DEBUG_FLY = "@ a activé le mode vol (débug) "
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
[CHAT] [CHAT]
KICKING = "Vous avez expulsé '@' !" KICKING = "Vous avez expulsé '@' !"

View file

@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Verbindung getrennt:\\#c8c8c8\\ Der Servereigent
DISCONNECT_BIG_MOD = "Der Server besaß eine modifikation, die zu Groß war.\nDie Verbindung wird geschlossen." DISCONNECT_BIG_MOD = "Der Server besaß eine modifikation, die zu Groß war.\nDie Verbindung wird geschlossen."
DIED = "@ starb" DIED = "@ starb"
DEBUG_FLY = "@ trat in den Debug-Free-Fly-Zustand ein" DEBUG_FLY = "@ trat in den Debug-Free-Fly-Zustand ein"
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
[CHAT] [CHAT]
KICKING = "'@' wird rausgeschmissen!" KICKING = "'@' wird rausgeschmissen!"

View file

@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Disconnected:\\#c8c8c8\\ O host fechou a conexã
DISCONNECT_BIG_MOD = "o server tem um mod muito grande.\nQuitting." DISCONNECT_BIG_MOD = "o server tem um mod muito grande.\nQuitting."
DIED = "@ morreu" DIED = "@ morreu"
DEBUG_FLY = "@ entrou no estado de debug para voar" DEBUG_FLY = "@ entrou no estado de debug para voar"
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
[CHAT] [CHAT]
KICKING = "Expulso '@'!" KICKING = "Expulso '@'!"

View file

@ -15,6 +15,10 @@ DISCONNECT_CLOSED = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ El anfitrión ha cerrad
DISCONNECT_BIG_MOD = "El servidor tenía un mod demasiado pesado.\nSaliendo." DISCONNECT_BIG_MOD = "El servidor tenía un mod demasiado pesado.\nSaliendo."
DIED = "@ ha muerto" DIED = "@ ha muerto"
DEBUG_FLY = "@ está en estado de vuelo libre debug" DEBUG_FLY = "@ está en estado de vuelo libre debug"
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'"
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'"
IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'"
IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game"
[CHAT] [CHAT]
KICKING = "¡Expulsando a '@'!" KICKING = "¡Expulsando a '@'!"

View file

@ -275,13 +275,7 @@ static void enable_mod_read(char** tokens, UNUSED int numTokens) {
strncat(combined, tokens[i], 255); strncat(combined, tokens[i], 255);
} }
for (unsigned int i = 0; i < gLocalMods.entryCount; i++) { mods_enable(combined);
struct Mod* mod = gLocalMods.entries[i];
if (!strcmp(combined, mod->relativePath)) {
mod->enabled = true;
break;
}
}
} }
static void enable_mod_write(FILE* file) { static void enable_mod_write(FILE* file) {
@ -447,7 +441,7 @@ const char *configfile_backup_name(void) {
} }
// Loads the config file specified by 'filename' // Loads the config file specified by 'filename'
void configfile_load(const char *filename, bool* error) { static void configfile_load_internal(const char *filename, bool* error) {
fs_file_t *file; fs_file_t *file;
char *line; char *line;
unsigned int temp; unsigned int temp;
@ -563,6 +557,16 @@ NEXT_OPTION:
#endif #endif
} }
void configfile_load(void) {
bool configReadError = false;
configfile_load_internal(configfile_name(), &configReadError);
if (configReadError) {
configfile_load_internal(configfile_backup_name(), &configReadError);
} else {
configfile_save(configfile_backup_name());
}
}
// Writes the config file to 'filename' // Writes the config file to 'filename'
void configfile_save(const char *filename) { void configfile_save(const char *filename) {
FILE *file; FILE *file;

View file

@ -112,7 +112,7 @@ extern bool configDebugInfo;
extern bool configDebugError; extern bool configDebugError;
extern char configLanguage[]; extern char configLanguage[];
void configfile_load(const char *filename, bool* error); void configfile_load(void);
void configfile_save(const char *filename); void configfile_save(const char *filename);
const char *configfile_name(void); const char *configfile_name(void);
const char *configfile_backup_name(void); const char *configfile_backup_name(void);

View file

@ -42,8 +42,14 @@ static void _debuglog_print_log(char* logType, char* filename) {
_debuglog_print_short_filename(filename); _debuglog_print_short_filename(filename);
} }
#if defined(DISABLE_MODULE_LOG)
#define LOG_DEBUG(...)
#define LOG_INFO(...)
#define LOG_ERROR(...)
#else
#define LOG_DEBUG(...) (configDebugPrint ? ( _debuglog_print_log("DEBUG", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0) #define LOG_DEBUG(...) (configDebugPrint ? ( _debuglog_print_log("DEBUG", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0)
#define LOG_INFO(...) (configDebugInfo ? ( _debuglog_print_log("INFO", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0) #define LOG_INFO(...) (configDebugInfo ? ( _debuglog_print_log("INFO", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0)
#define LOG_ERROR(...) (configDebugError ? ( _debuglog_print_log("ERROR", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0) #define LOG_ERROR(...) (configDebugError ? ( _debuglog_print_log("ERROR", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0)
#endif
#endif #endif

View file

@ -10,6 +10,8 @@ static void djui_panel_dynos_apply(struct DjuiBase* caller) {
} }
void djui_panel_dynos_create(struct DjuiBase* caller) { void djui_panel_dynos_create(struct DjuiBase* caller) {
dynos_packs_init();
int packCount = dynos_pack_get_count(); int packCount = dynos_pack_get_count();
struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(DYNOS, DYNOS)); struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(DYNOS, DYNOS));
struct DjuiBase* body = djui_three_panel_get_body(panel); struct DjuiBase* body = djui_three_panel_get_body(panel);

View file

@ -90,6 +90,8 @@ static void djui_panel_host_mods_destroy(struct DjuiBase* base) {
void djui_panel_host_mods_create(struct DjuiBase* caller) { void djui_panel_host_mods_create(struct DjuiBase* caller) {
bool isRomHacks = (caller->tag == 1); bool isRomHacks = (caller->tag == 1);
mods_refresh_local();
mods_update_selectable(); mods_update_selectable();
struct DjuiThreePanel* panel = djui_panel_menu_create(isRomHacks struct DjuiThreePanel* panel = djui_panel_menu_create(isRomHacks

View file

@ -37,6 +37,7 @@
#include "src/pc/controller/controller_sdl.h" #include "src/pc/controller/controller_sdl.h"
#include "src/pc/controller/controller_bind_mapping.h" #include "src/pc/controller/controller_bind_mapping.h"
#include "pc/utils/misc.h" #include "pc/utils/misc.h"
#include "pc/mods/mod_import.h"
// TODO: figure out if this shit even works // TODO: figure out if this shit even works
#ifdef VERSION_EU #ifdef VERSION_EU
@ -163,6 +164,10 @@ static void gfx_sdl_onkeyup(int scancode) {
kb_key_up(translate_sdl_scancode(scancode)); kb_key_up(translate_sdl_scancode(scancode));
} }
static void gfx_sdl_ondropfile(char* path) {
mod_import_file(path);
}
static void gfx_sdl_handle_events(void) { static void gfx_sdl_handle_events(void) {
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
@ -192,6 +197,9 @@ static void gfx_sdl_handle_events(void) {
} }
} }
break; break;
case SDL_DROPFILE:
gfx_sdl_ondropfile(event.drop.file);
break;
case SDL_QUIT: case SDL_QUIT:
game_exit(); game_exit();
break; break;

View file

@ -60,9 +60,9 @@ static void _logfile_print_log(enum LogFileType logFileType, char* logType, char
} }
#if defined(DEBUG) && defined(DISABLE_MODULE_LOG) #if defined(DEBUG) && defined(DISABLE_MODULE_LOG)
#define LOGFILE_DEBUG(_LFT, ...) ( _logfile_print_log(_LFT, "DEBUG", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n")) #define LOGFILE_DEBUG(_LFT, ...)
#define LOGFILE_INFO(_LFT, ...) ( _logfile_print_log(_LFT, "INFO", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n")) #define LOGFILE_INFO(_LFT, ...)
#define LOGFILE_ERROR(_LFT, ...) ( _logfile_print_log(_LFT, "ERROR", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"), LOG_ERROR(__VA_ARGS__)) #define LOGFILE_ERROR(_LFT, ...)
#elif defined(DEBUG) && !defined(DISABLE_MODULE_LOG) #elif defined(DEBUG) && !defined(DISABLE_MODULE_LOG)
#define LOGFILE_DEBUG(_LFT, ...) ( _logfile_print_log(_LFT, "DEBUG", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"), LOG_DEBUG(__VA_ARGS__)) #define LOGFILE_DEBUG(_LFT, ...) ( _logfile_print_log(_LFT, "DEBUG", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"), LOG_DEBUG(__VA_ARGS__))
#define LOGFILE_INFO(_LFT, ...) ( _logfile_print_log(_LFT, "INFO", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"), LOG_INFO (__VA_ARGS__)) #define LOGFILE_INFO(_LFT, ...) ( _logfile_print_log(_LFT, "INFO", __FILE__, __LINE__), fprintf(gLogFiles[_LFT].file, __VA_ARGS__), fprintf(gLogFiles[_LFT].file, "\n"), LOG_INFO (__VA_ARGS__))

View file

@ -1,11 +1,11 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#define DISABLE_MODULE_LOG 1
#include "pc/debuglog.h"
#include "mod_cache.h" #include "mod_cache.h"
#include "mods.h" #include "mods.h"
#include "mod.h" #include "mod.h"
#include "mods_utils.h" #include "mods_utils.h"
#define DISABLE_MODULE_LOG 1
#include "pc/debuglog.h"
#include "pc/utils/md5.h" #include "pc/utils/md5.h"
#define MOD_CACHE_FILENAME "mod.cache" #define MOD_CACHE_FILENAME "mod.cache"

210
src/pc/mods/mod_import.c Normal file
View file

@ -0,0 +1,210 @@
#include "PR/ultratypes.h"
#include <types.h>
#include "pc/platform.h"
#include "pc/utils/miniz/miniz.h"
#include "pc/debuglog.h"
#include "data/dynos.c.h"
#include "pc/djui/djui_language.h"
#include "pc/djui/djui_popup.h"
#include "mods.h"
#include "mods_utils.h"
static bool mod_import_lua(char* src) {
char dst[SYS_MAX_PATH] = { 0 };
if (!concat_path(dst, (char*)fs_get_write_path(MOD_DIRECTORY), path_basename(src))) {
LOG_ERROR("Failed to concat path for lua mod import");
return false;
}
FILE* fin = fopen(src, "rb");
if (fin == NULL) {
LOG_ERROR("Failed to open src path for lua mod import");
return false;
}
FILE* fout = fopen(dst, "wb");
if (fout == NULL) {
LOG_ERROR("Failed to open dst path for lua mod import");
return false;
}
size_t rbytes;
size_t wbytes;
unsigned char buff[8192];
do {
rbytes = fread(buff, 1, sizeof(buff), fin);
if (rbytes > 0) {
wbytes = fwrite(buff, 1, rbytes, fout);
} else {
wbytes = 0;
}
} while ((rbytes > 0) && (rbytes == wbytes));
if (wbytes) {
LOG_ERROR("Write error on lua mod import");
return false;
}
fclose(fout);
fclose(fin);
LOG_INFO("Imported lua mod: '%s' -> '%s'", src, dst);
return true;
}
static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
LOG_INFO("Importing zip mod: %s", path);
mz_zip_archive zip_archive = { 0 };
mz_bool status = mz_zip_reader_init_file(&zip_archive, path, 0);
if (!status) {
LOG_ERROR("mz_zip_reader_init_file() failed!");
return false;
}
// Figure out if its a dynos pack or a mod
*isLua = false;
*isDynos = false;
for (int i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) {
mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
LOG_ERROR("mz_zip_reader_file_stat() failed!");
mz_zip_reader_end(&zip_archive);
return false;
}
if (str_ends_with(file_stat.m_filename, ".lua")) {
*isLua = true;
break;
} else if (str_ends_with(file_stat.m_filename, ".tex")) {
*isDynos = true;
} else if (str_ends_with(file_stat.m_filename, ".png")) {
*isDynos = true;
} else if (str_ends_with(file_stat.m_filename, ".bin")) {
*isDynos = true;
}
}
// Figure out dst directory
char dstDirectory[SYS_MAX_PATH] = { 0 };
char dst[SYS_MAX_PATH] = { 0 };
if (*isLua) {
snprintf(dstDirectory, SYS_MAX_PATH, "%s", (char*)fs_get_write_path(MOD_DIRECTORY));
} else if (*isDynos) {
snprintf(dstDirectory, SYS_MAX_PATH, "%s", (char*)fs_get_write_path(DYNOS_PACKS_FOLDER));
} else {
LOG_ERROR("Could not figure out what type of mod this is");
return false;
}
// Extract the archive
for (int i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) {
mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
LOG_ERROR("mz_zip_reader_file_stat() failed!");
mz_zip_reader_end(&zip_archive);
return false;
}
// Build dst path
if (!concat_path(dst, dstDirectory, file_stat.m_filename)) {
LOG_ERROR("Failed to concat path for zip mod import");
mz_zip_reader_end(&zip_archive);
return false;
}
LOG_INFO("Filename: \"%s\", Comment: \"%s\", Uncompressed size: %u, Compressed size: %u, Is Dir: %u", file_stat.m_filename, file_stat.m_comment, (u32)file_stat.m_uncomp_size, (u32)file_stat.m_comp_size, mz_zip_reader_is_file_a_directory(&zip_archive, i));
// If it's a directory, make it
if (mz_zip_reader_is_file_a_directory(&zip_archive, i)) {
// Remove the directory
if (fs_sys_dir_exists(dst)) {
mods_delete_folder(dst);
}
if (!fs_sys_mkdir(dst)) {
LOG_ERROR("Failed to mkdir for zip mod import");
mz_zip_reader_end(&zip_archive);
return false;
}
continue;
}
// Try to extract all the files to the heap.
size_t uncompSize;
const char* p = mz_zip_reader_extract_file_to_heap(&zip_archive, file_stat.m_filename, &uncompSize, 0);
if (!p) {
LOG_ERROR("mz_zip_reader_extract_file_to_heap() failed!");
mz_zip_reader_end(&zip_archive);
return EXIT_FAILURE;
}
// Make sure the extraction really succeeded.
if (uncompSize != file_stat.m_uncomp_size) {
LOG_ERROR("mz_zip_reader_extract_file_to_heap() failed to extract the proper data");
mz_free((void*)p);
mz_zip_reader_end(&zip_archive);
return EXIT_FAILURE;
}
// Write the data
FILE* fout = fopen(dst, "wb");
if (fout == NULL) {
LOG_ERROR("Failed to open dst path for zip mod import");
return false;
}
size_t wbytes = fwrite(p, 1, uncompSize, fout);
if (wbytes != uncompSize) {
LOG_ERROR("Write error on zip mod import");
}
fclose(fout);
LOG_INFO("Successfully extracted file \"%s\", size %u", file_stat.m_filename, (u32)uncompSize);
// We're done.
mz_free((void*)p);
}
// Close the archive, freeing any resources it was using
mz_zip_reader_end(&zip_archive);
return true;
}
bool mod_import_file(char* path) {
bool isLua = false;
bool isDynos = false;
bool ret = false;
if (gNetworkType != NT_NONE) {
djui_popup_create(DLANG(NOTIF, IMPORT_FAIL_INGAME), 1);
return false;
}
if (str_ends_with(path, ".lua")) {
isLua = true;
ret = mod_import_lua(path);
} else if (str_ends_with(path, ".zip")) {
ret = mod_import_zip(path, &isLua, &isDynos);
}
char msg[SYS_MAX_PATH] = { 0 };
char* basename = path_basename(path);
if (ret) {
if (isLua) {
djui_language_replace(DLANG(NOTIF, IMPORT_MOD_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
djui_popup_create(msg, 1);
} else if (isDynos) {
dynos_packs_init();
djui_language_replace(DLANG(NOTIF, IMPORT_DYNOS_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
djui_popup_create(msg, 1);
}
} else {
djui_language_replace(DLANG(NOTIF, IMPORT_FAIL), msg, SYS_MAX_PATH, '@', basename);
djui_popup_create(msg, 1);
}
return ret;
}

6
src/pc/mods/mod_import.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef MOD_IMPORT_H
#define MOD_IMPORT_H
bool mod_import_file(char* path);
#endif

View file

@ -5,7 +5,6 @@
#include "data/dynos.c.h" #include "data/dynos.c.h"
#include "pc/debuglog.h" #include "pc/debuglog.h"
#define MOD_DIRECTORY "mods"
#define MAX_SESSION_CHARS 7 #define MAX_SESSION_CHARS 7
struct Mods gLocalMods = { 0 }; struct Mods gLocalMods = { 0 };
@ -14,6 +13,43 @@ struct Mods gActiveMods = { 0 };
char gRemoteModsBasePath[SYS_MAX_PATH] = { 0 }; char gRemoteModsBasePath[SYS_MAX_PATH] = { 0 };
struct LocalEnabledPath {
char* relativePath;
struct LocalEnabledPath* next;
};
struct LocalEnabledPath* sLocalEnabledPaths = NULL;
static void mods_local_store_enabled(void) {
assert(sLocalEnabledPaths == NULL);
struct LocalEnabledPath* prev = NULL;
struct Mods* mods = &gLocalMods;
for (int i = 0; i < mods->entryCount; i ++) {
if (!mods->entries[i]->enabled) { continue; }
struct LocalEnabledPath* n = calloc(1, sizeof(struct LocalEnabledPath));
n->relativePath = sys_strdup(mods->entries[i]->relativePath);
if (!prev) {
sLocalEnabledPaths = n;
} else {
prev->next = n;
}
}
}
static void mods_local_restore_enabled(void) {
struct LocalEnabledPath* n = sLocalEnabledPaths;
while (n) {
struct LocalEnabledPath* next = n->next;
mods_enable(n->relativePath);
free(n->relativePath);
free(n);
n = next;
}
sLocalEnabledPaths = NULL;
}
bool mods_generate_remote_base_path(void) { bool mods_generate_remote_base_path(void) {
srand(time(0)); srand(time(0));
@ -137,9 +173,8 @@ static void mods_load(struct Mods* mods, char* modsBasePath) {
} }
void mods_init(void) { void mods_refresh_local(void) {
// load mod cache mods_local_store_enabled();
mod_cache_load();
// figure out user path // figure out user path
bool hasUserPath = true; bool hasUserPath = true;
@ -172,6 +207,26 @@ void mods_init(void) {
struct Mod* mod = gLocalMods.entries[i]; struct Mod* mod = gLocalMods.entries[i];
gLocalMods.size += mod->size; gLocalMods.size += mod->size;
} }
mods_local_restore_enabled();
}
void mods_enable(char* relativePath) {
if (!relativePath) { return; }
for (unsigned int i = 0; i < gLocalMods.entryCount; i++) {
struct Mod* mod = gLocalMods.entries[i];
if (!strcmp(relativePath, mod->relativePath)) {
mod->enabled = true;
break;
}
}
}
void mods_init(void) {
// load mod cache
mod_cache_load();
mods_refresh_local();
} }
void mods_clear(struct Mods* mods) { void mods_clear(struct Mods* mods) {

View file

@ -7,6 +7,7 @@
#include "mod.h" #include "mod.h"
#define MAX_MOD_SIZE (35 * 1048576) // 35MB #define MAX_MOD_SIZE (35 * 1048576) // 35MB
#define MOD_DIRECTORY "mods"
#define TMP_DIRECTORY "tmp" #define TMP_DIRECTORY "tmp"
struct Mods { struct Mods {
@ -24,6 +25,9 @@ extern char gRemoteModsBasePath[];
bool mods_generate_remote_base_path(void); bool mods_generate_remote_base_path(void);
void mods_activate(struct Mods* mods); void mods_activate(struct Mods* mods);
void mods_clear(struct Mods* mods); void mods_clear(struct Mods* mods);
void mods_delete_folder(char* path);
void mods_refresh_local(void);
void mods_enable(char* relativePath);
void mods_init(void); void mods_init(void);
void mods_shutdown(void); void mods_shutdown(void);

View file

@ -78,8 +78,8 @@ void mods_update_selectable(void) {
mods_size_enforce(&gLocalMods); mods_size_enforce(&gLocalMods);
} }
static void mods_delete_folder(char* path) { void mods_delete_folder(char* path) {
LOG_INFO("Deleting tmp folder '%s'", path); LOG_INFO("Deleting folder '%s'", path);
struct dirent* dir; struct dirent* dir;
DIR* d = opendir(path); DIR* d = opendir(path);
if (!d) { return; } if (!d) { return; }
@ -94,7 +94,7 @@ static void mods_delete_folder(char* path) {
mods_delete_folder(fullPath); mods_delete_folder(fullPath);
} else if (fs_sys_file_exists(fullPath)) { } else if (fs_sys_file_exists(fullPath)) {
if (unlink(fullPath) == -1) { if (unlink(fullPath) == -1) {
LOG_ERROR("Failed to remove tmp file '%s'", fullPath); LOG_ERROR("Failed to remove file '%s'", fullPath);
continue; continue;
} }
} }

View file

@ -280,17 +280,11 @@ void main_func(void) {
mods_init(); mods_init();
// load config // load config
bool configReadError = false; configfile_load();
configfile_load(configfile_name(), &configReadError);
if (configReadError) {
configfile_load(configfile_backup_name(), &configReadError);
} else {
configfile_save(configfile_backup_name());
}
if (!djui_language_init(configLanguage)) { if (!djui_language_init(configLanguage)) {
snprintf(configLanguage, MAX_CONFIG_STRING, "%s", ""); snprintf(configLanguage, MAX_CONFIG_STRING, "%s", "");
} }
dynos_pack_init(); dynos_pack_init();
// If coop_custom_palette_* values are not found in sm64config.txt, the custom palette config will use the default values (Mario's palette) // If coop_custom_palette_* values are not found in sm64config.txt, the custom palette config will use the default values (Mario's palette)

View file

@ -0,0 +1,22 @@
Copyright 2013-2014 RAD Game Tools and Valve Software
Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

7833
src/pc/utils/miniz/miniz.c Normal file

File diff suppressed because it is too large Load diff

1422
src/pc/utils/miniz/miniz.h Normal file

File diff suppressed because it is too large Load diff