diff --git a/docs/changelog.txt b/docs/changelog.txt index 0fe8c6e9f4..1726e6b9a6 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -56,6 +56,7 @@ Template for new versions: ## New Features ## Fixes +- Honor the "portable mode" preference setting for locating save folders. Fixes DFHack cosaves not working. ## Misc Improvements diff --git a/library/include/modules/DFSDL.h b/library/include/modules/DFSDL.h index 0fcd17b322..8d12de1918 100644 --- a/library/include/modules/DFSDL.h +++ b/library/include/modules/DFSDL.h @@ -21,6 +21,7 @@ namespace DFHack SDL_Rect* rect; // from which coords (NULL to draw whole surface) SDL_Rect* dstResize; // if not NULL dst rect will be resized (x/y/w/h will be added to original dst) }; +} /** * The DFSDL module - provides access to SDL functions without actually @@ -28,47 +29,52 @@ namespace DFHack * \ingroup grp_modules * \ingroup grp_dfsdl */ -namespace DFSDL +namespace DFHack::DFSDL { + /** + * Call this on DFHack init so we can load the SDL functions. Returns false on + * failure. + */ + bool init(DFHack::color_ostream& out); -/** - * Call this on DFHack init so we can load the SDL functions. Returns false on - * failure. - */ -bool init(DFHack::color_ostream &out); + /** + * Call this when DFHack is being unloaded. + */ + void cleanup(); -/** - * Call this when DFHack is being unloaded. - */ -void cleanup(); + DFHACK_EXPORT SDL_Surface* DFIMG_Load(const char* file); + DFHACK_EXPORT SDL_Surface* DFSDL_CreateRGBSurface(uint32_t flags, int width, int height, int depth, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask); + DFHACK_EXPORT SDL_Surface* DFSDL_CreateRGBSurfaceFrom(void* pixels, int width, int height, int depth, int pitch, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask); + DFHACK_EXPORT int DFSDL_UpperBlit(SDL_Surface* src, const SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect); + DFHACK_EXPORT SDL_Surface* DFSDL_ConvertSurface(SDL_Surface* src, const SDL_PixelFormat* fmt, uint32_t flags); + DFHACK_EXPORT void DFSDL_FreeSurface(SDL_Surface* surface); + // DFHACK_EXPORT int DFSDL_SemWait(SDL_sem *sem); + // DFHACK_EXPORT int DFSDL_SemPost(SDL_sem *sem); + DFHACK_EXPORT int DFSDL_PushEvent(SDL_Event* event); + DFHACK_EXPORT void DFSDL_free(void* ptr); + DFHACK_EXPORT SDL_PixelFormat* DFSDL_AllocFormat(uint32_t pixel_format); + DFHACK_EXPORT SDL_Surface* DFSDL_CreateRGBSurfaceWithFormat(uint32_t flags, int width, int height, int depth, uint32_t format); + DFHACK_EXPORT int DFSDL_ShowSimpleMessageBox(uint32_t flags, const char* title, const char* message, SDL_Window* window); -DFHACK_EXPORT SDL_Surface * DFIMG_Load(const char *file); -DFHACK_EXPORT SDL_Surface * DFSDL_CreateRGBSurface(uint32_t flags, int width, int height, int depth, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask); -DFHACK_EXPORT SDL_Surface * DFSDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask); -DFHACK_EXPORT int DFSDL_UpperBlit(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect); -DFHACK_EXPORT SDL_Surface * DFSDL_ConvertSurface(SDL_Surface *src, const SDL_PixelFormat *fmt, uint32_t flags); -DFHACK_EXPORT void DFSDL_FreeSurface(SDL_Surface *surface); -// DFHACK_EXPORT int DFSDL_SemWait(SDL_sem *sem); -// DFHACK_EXPORT int DFSDL_SemPost(SDL_sem *sem); -DFHACK_EXPORT int DFSDL_PushEvent(SDL_Event *event); -DFHACK_EXPORT void DFSDL_free(void *ptr); -DFHACK_EXPORT SDL_PixelFormat* DFSDL_AllocFormat(uint32_t pixel_format); -DFHACK_EXPORT SDL_Surface* DFSDL_CreateRGBSurfaceWithFormat(uint32_t flags, int width, int height, int depth, uint32_t format); -DFHACK_EXPORT int DFSDL_ShowSimpleMessageBox(uint32_t flags, const char *title, const char *message, SDL_Window *window); + // submitted and returned text is UTF-8 + // see wrapper functions below for cp-437 variants + DFHACK_EXPORT char* DFSDL_GetClipboardText(); + DFHACK_EXPORT int DFSDL_SetClipboardText(const char* text); -// submitted and returned text is UTF-8 -// see wrapper functions below for cp-437 variants -DFHACK_EXPORT char * DFSDL_GetClipboardText(); -DFHACK_EXPORT int DFSDL_SetClipboardText(const char *text); + DFHACK_EXPORT char* DFSDL_GetPrefPath(const char* org, const char* app); + DFHACK_EXPORT char* DFSDL_GetBasePath(); } -// System clipboard -- submitted and returned text must be in CP437 -DFHACK_EXPORT std::string getClipboardTextCp437(); -DFHACK_EXPORT bool setClipboardTextCp437(std::string text); +namespace DFHack +{ + + // System clipboard -- submitted and returned text must be in CP437 + DFHACK_EXPORT std::string getClipboardTextCp437(); + DFHACK_EXPORT bool setClipboardTextCp437(std::string text); -// interprets 0xa as newline instead of usual CP437 char -DFHACK_EXPORT bool getClipboardTextCp437Multiline(std::vector * lines); -DFHACK_EXPORT bool setClipboardTextCp437Multiline(std::string text); + // interprets 0xa as newline instead of usual CP437 char + DFHACK_EXPORT bool getClipboardTextCp437Multiline(std::vector * lines); + DFHACK_EXPORT bool setClipboardTextCp437Multiline(std::string text); } diff --git a/library/modules/DFSDL.cpp b/library/modules/DFSDL.cpp index 832ffeb0be..536d1a5881 100644 --- a/library/modules/DFSDL.cpp +++ b/library/modules/DFSDL.cpp @@ -58,6 +58,8 @@ void (*g_SDL_free)(void *); SDL_PixelFormat* (*g_SDL_AllocFormat)(uint32_t pixel_format) = nullptr; SDL_Surface* (*g_SDL_CreateRGBSurfaceWithFormat)(uint32_t flags, int width, int height, int depth, uint32_t format) = nullptr; int (*g_SDL_ShowSimpleMessageBox)(uint32_t flags, const char *title, const char *message, SDL_Window *window) = nullptr; +char* (*g_SDL_GetPrefPath)(const char* org, const char* app) = nullptr; +char* (*g_SDL_GetBasePath)() = nullptr; bool DFSDL::init(color_ostream &out) { for (auto &lib_str : SDL_LIBS) { @@ -101,6 +103,8 @@ bool DFSDL::init(color_ostream &out) { bind(g_sdl_handle, SDL_AllocFormat); bind(g_sdl_handle, SDL_CreateRGBSurfaceWithFormat); bind(g_sdl_handle, SDL_ShowSimpleMessageBox); + bind(g_sdl_handle, SDL_GetPrefPath); + bind(g_sdl_handle, SDL_GetBasePath); #undef bind DEBUG(dfsdl,out).print("sdl successfully loaded\n"); @@ -175,6 +179,16 @@ SDL_Surface* DFSDL::DFSDL_CreateRGBSurfaceWithFormat(uint32_t flags, int width, return g_SDL_CreateRGBSurfaceWithFormat(flags, width, height, depth, format); } +char* DFSDL::DFSDL_GetPrefPath(const char* org, const char* app) +{ + return g_SDL_GetPrefPath(org, app); +} + +char* DFSDL::DFSDL_GetBasePath() +{ + return g_SDL_GetBasePath(); +} + int DFSDL::DFSDL_ShowSimpleMessageBox(uint32_t flags, const char *title, const char *message, SDL_Window *window) { if (!g_SDL_ShowSimpleMessageBox) return -1; diff --git a/library/modules/Persistence.cpp b/library/modules/Persistence.cpp index 9e1dd4d018..e2db24d5fd 100644 --- a/library/modules/Persistence.cpp +++ b/library/modules/Persistence.cpp @@ -29,12 +29,14 @@ distribution. #include "LuaTools.h" #include "MemAccess.h" +#include "modules/DFSDL.h" #include "modules/Filesystem.h" #include "modules/Gui.h" #include "modules/Persistence.h" #include "modules/World.h" #include "df/world.h" +#include "df/init.h" #include @@ -184,7 +186,14 @@ static std::string filterSaveFileName(std::string s) { } static std::filesystem::path getSavePath(const std::string &world) { - return std::filesystem::path{} / "save" / world; + auto getsavebase = []() { + if (df::global::init->media.flag.is_set(df::enums::init_media_flags::PORTABLE_MODE)) + return DFSDL::DFSDL_GetPrefPath("Bay 12 Games", "Dwarf Fortress"); + else + return DFSDL::DFSDL_GetBasePath(); + }; + std::filesystem::path base{ getsavebase() }; + return base / "save" / world; } static std::filesystem::path getSaveFilePath(const std::string &world, const std::string &name) {