From f03c09db764578329e736f141e51b25626e7f35f Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Mon, 3 Jan 2022 17:01:22 +0000 Subject: [PATCH] Separate Frame from Resource folder to support native MacOS port. Fixes https://github.com/audetto/AppleWin/issues/55 Signed-off-by: Andrea Odetti --- source/frontends/common2/CMakeLists.txt | 2 + source/frontends/common2/commonframe.cpp | 85 +--------------- source/frontends/common2/commonframe.h | 7 +- source/frontends/common2/gnuframe.cpp | 99 +++++++++++++++++++ source/frontends/common2/gnuframe.h | 22 +++++ source/frontends/libretro/retroframe.cpp | 2 +- source/frontends/libretro/retroframe.h | 3 +- source/frontends/ncurses/nframe.h | 3 +- source/frontends/sdl/imgui/sdlimguiframe.h | 3 +- .../frontends/sdl/renderer/sdlrendererframe.h | 3 +- source/frontends/sdl/sdlframe.cpp | 4 +- source/frontends/sdl/sdlframe.h | 2 +- 12 files changed, 138 insertions(+), 97 deletions(-) create mode 100644 source/frontends/common2/gnuframe.cpp create mode 100644 source/frontends/common2/gnuframe.h diff --git a/source/frontends/common2/CMakeLists.txt b/source/frontends/common2/CMakeLists.txt index a4e080539..49869f975 100644 --- a/source/frontends/common2/CMakeLists.txt +++ b/source/frontends/common2/CMakeLists.txt @@ -2,6 +2,7 @@ include(GNUInstallDirs) set(SOURCE_FILES commonframe.cpp + gnuframe.cpp fileregistry.cpp ptreeregistry.cpp programoptions.cpp @@ -12,6 +13,7 @@ set(SOURCE_FILES set(HEADER_FILES commonframe.h + gnuframe.h fileregistry.h ptreeregistry.h programoptions.h diff --git a/source/frontends/common2/commonframe.cpp b/source/frontends/common2/commonframe.cpp index bf6774ebb..a3ab55ff9 100644 --- a/source/frontends/common2/commonframe.cpp +++ b/source/frontends/common2/commonframe.cpp @@ -1,101 +1,23 @@ #include "StdAfx.h" #include "frontends/common2/commonframe.h" #include "frontends/common2/utils.h" -#include "frontends/common2/fileregistry.h" #include "linux/resources.h" -#include "linux/context.h" #include #include #include -#include - -#ifdef __APPLE__ -#include "mach-o/dyld.h" -#endif #include "Log.h" -#include "Core.h" -#include "config.h" - -namespace -{ - - bool dirExists(const std::string & folder) - { - struct stat stdbuf; - - if (stat(folder.c_str(), &stdbuf) == 0 && S_ISDIR(stdbuf.st_mode)) - { - return true; - } - else - { - return false; - } - } - - std::string getResourcePath(const std::string & target) - { - std::vector paths; - - char self[1024] = {0}; - -#ifdef __APPLE__ - uint32_t size = sizeof(self); - const int ch = _NSGetExecutablePath(self, &size); -#else - const int ch = readlink("/proc/self/exe", self, sizeof(self)); -#endif - - if (ch != -1) - { - const char * path = dirname(self); - - // case 1: run from the build folder - paths.emplace_back(std::string(path) + '/'+ ROOT_PATH); - // case 2: run from the installation folder - paths.emplace_back(std::string(path) + '/'+ SHARE_PATH); - } - - // case 3: use the source folder - paths.emplace_back(CMAKE_SOURCE_DIR); - - for (const std::string & path : paths) - { - char * real = realpath(path.c_str(), nullptr); - if (real) - { - const std::string resourcePath = std::string(real) + target; - free(real); - if (dirExists(resourcePath)) - { - return resourcePath; - } - } - } - - throw std::runtime_error("Cannot found the resource path: " + target); - } - -} namespace common2 { - CommonFrame::CommonFrame() - : myResourcePath(getResourcePath("/resource/")) - { - // should this go down to LinuxFrame (maybe Initialisation?) - g_sProgramDir = getResourcePath("/bin/"); - } - BYTE* CommonFrame::GetResource(WORD id, LPCSTR lpType, DWORD expectedSize) { myResource.clear(); const std::string & filename = getResourceName(id); - const std::string path = myResourcePath + filename; + const std::string path = getResourcePath(filename); const int fd = open(path.c_str(), O_RDONLY); @@ -133,9 +55,4 @@ namespace common2 return resource; } - std::string CommonFrame::Video_GetScreenShotFolder() - { - return GetHomeDir() + "/Pictures/"; - } - } diff --git a/source/frontends/common2/commonframe.h b/source/frontends/common2/commonframe.h index d51fba6e4..d59c34531 100644 --- a/source/frontends/common2/commonframe.h +++ b/source/frontends/common2/commonframe.h @@ -10,16 +10,13 @@ namespace common2 class CommonFrame : public LinuxFrame { public: - CommonFrame(); - BYTE* GetResource(WORD id, LPCSTR lpType, DWORD expectedSize) override; - std::string Video_GetScreenShotFolder() override; - protected: + virtual std::string getResourcePath(const std::string & filename) = 0; + static std::string getBitmapFilename(const std::string & resource); - const std::string myResourcePath; std::vector myResource; }; diff --git a/source/frontends/common2/gnuframe.cpp b/source/frontends/common2/gnuframe.cpp new file mode 100644 index 000000000..dead08364 --- /dev/null +++ b/source/frontends/common2/gnuframe.cpp @@ -0,0 +1,99 @@ +#include "StdAfx.h" +#include "frontends/common2/gnuframe.h" +#include "frontends/common2/fileregistry.h" + +#include +#include +#include + +#ifdef __APPLE__ +#include "mach-o/dyld.h" +#endif + +#include "Core.h" +#include "config.h" + +namespace +{ + + bool dirExists(const std::string & folder) + { + struct stat stdbuf; + + if (stat(folder.c_str(), &stdbuf) == 0 && S_ISDIR(stdbuf.st_mode)) + { + return true; + } + else + { + return false; + } + } + + std::string getResourceFolder(const std::string & target) + { + std::vector paths; + + char self[1024] = {0}; + +#ifdef __APPLE__ + uint32_t size = sizeof(self); + const int ch = _NSGetExecutablePath(self, &size); +#else + const int ch = readlink("/proc/self/exe", self, sizeof(self)); +#endif + + if (ch != -1) + { + const char * path = dirname(self); + + // case 1: run from the build folder + paths.emplace_back(std::string(path) + '/'+ ROOT_PATH); + // case 2: run from the installation folder + paths.emplace_back(std::string(path) + '/'+ SHARE_PATH); + } + + // case 3: use the source folder + paths.emplace_back(CMAKE_SOURCE_DIR); + + for (const std::string & path : paths) + { + char * real = realpath(path.c_str(), nullptr); + if (real) + { + const std::string resourcePath = std::string(real) + target; + free(real); + if (dirExists(resourcePath)) + { + return resourcePath; + } + } + } + + throw std::runtime_error("Cannot found the resource path: " + target); + } + +} + +namespace common2 +{ + + GNUFrame::GNUFrame() + : myHomeDir(GetHomeDir()) + , myResourceFolder(getResourceFolder("/resource/")) + { + // should this go down to LinuxFrame (maybe Initialisation?) + g_sProgramDir = getResourceFolder("/bin/"); + } + + std::string GNUFrame::getResourcePath(const std::string & filename) + { + return myResourceFolder + filename; + } + + std::string GNUFrame::Video_GetScreenShotFolder() + { + return myHomeDir + "/Pictures/"; + } + +} diff --git a/source/frontends/common2/gnuframe.h b/source/frontends/common2/gnuframe.h new file mode 100644 index 000000000..3d64640a7 --- /dev/null +++ b/source/frontends/common2/gnuframe.h @@ -0,0 +1,22 @@ +#pragma once + +#include "frontends/common2/commonframe.h" +#include + +namespace common2 +{ + + class GNUFrame : public virtual CommonFrame + { + public: + GNUFrame(); + + std::string Video_GetScreenShotFolder() override; + std::string getResourcePath(const std::string & filename) override; + + private: + const std::string myHomeDir; + const std::string myResourceFolder; + }; + +} diff --git a/source/frontends/libretro/retroframe.cpp b/source/frontends/libretro/retroframe.cpp index 9c9c4c3c2..02ea04d8a 100644 --- a/source/frontends/libretro/retroframe.cpp +++ b/source/frontends/libretro/retroframe.cpp @@ -139,7 +139,7 @@ namespace ra2 void RetroFrame::GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) { const std::string filename = getBitmapFilename(lpBitmapName); - const std::string path = myResourcePath + filename; + const std::string path = getResourcePath(filename); std::vector buffer; readFileToBuffer(path, buffer); diff --git a/source/frontends/libretro/retroframe.h b/source/frontends/libretro/retroframe.h index 7df2f3a81..a77985dcb 100644 --- a/source/frontends/libretro/retroframe.h +++ b/source/frontends/libretro/retroframe.h @@ -1,6 +1,7 @@ #pragma once #include "frontends/common2/commonframe.h" +#include "frontends/common2/gnuframe.h" #include #include @@ -8,7 +9,7 @@ namespace ra2 { - class RetroFrame : public common2::CommonFrame + class RetroFrame : public virtual common2::CommonFrame, public common2::GNUFrame { public: RetroFrame(); diff --git a/source/frontends/ncurses/nframe.h b/source/frontends/ncurses/nframe.h index e6c6d283e..1a96546cf 100644 --- a/source/frontends/ncurses/nframe.h +++ b/source/frontends/ncurses/nframe.h @@ -1,6 +1,7 @@ #pragma once #include "frontends/common2/commonframe.h" +#include "frontends/common2/gnuframe.h" #include #include @@ -13,7 +14,7 @@ namespace na2 class EvDevPaddle; struct NCurses; - class NFrame : public common2::CommonFrame + class NFrame : public virtual common2::CommonFrame, public common2::GNUFrame { public: NFrame(const std::shared_ptr & paddle); diff --git a/source/frontends/sdl/imgui/sdlimguiframe.h b/source/frontends/sdl/imgui/sdlimguiframe.h index 41bc6a920..7dc32631a 100644 --- a/source/frontends/sdl/imgui/sdlimguiframe.h +++ b/source/frontends/sdl/imgui/sdlimguiframe.h @@ -3,6 +3,7 @@ #include "frontends/sdl/sdlframe.h" #include "frontends/sdl/imgui/sdlsettings.h" #include "frontends/sdl/imgui/glselector.h" +#include "frontends/common2/gnuframe.h" namespace common2 { @@ -12,7 +13,7 @@ namespace common2 namespace sa2 { - class SDLImGuiFrame : public SDLFrame + class SDLImGuiFrame : public SDLFrame, public common2::GNUFrame { public: SDLImGuiFrame(const common2::EmulatorOptions & options); diff --git a/source/frontends/sdl/renderer/sdlrendererframe.h b/source/frontends/sdl/renderer/sdlrendererframe.h index 775e5fd60..3a5857ad4 100644 --- a/source/frontends/sdl/renderer/sdlrendererframe.h +++ b/source/frontends/sdl/renderer/sdlrendererframe.h @@ -1,6 +1,7 @@ #pragma once #include "frontends/sdl/sdlframe.h" +#include "frontends/common2/gnuframe.h" namespace common2 { @@ -10,7 +11,7 @@ namespace common2 namespace sa2 { - class SDLRendererFrame : public SDLFrame + class SDLRendererFrame : public SDLFrame, public common2::GNUFrame { public: SDLRendererFrame(const common2::EmulatorOptions & options); diff --git a/source/frontends/sdl/sdlframe.cpp b/source/frontends/sdl/sdlframe.cpp index 7a868a91d..3b7241026 100644 --- a/source/frontends/sdl/sdlframe.cpp +++ b/source/frontends/sdl/sdlframe.cpp @@ -178,7 +178,7 @@ namespace sa2 void SDLFrame::SetApplicationIcon() { - const std::string path = myResourcePath + "APPLEWIN.ICO"; + const std::string path = getResourcePath("APPLEWIN.ICO"); std::shared_ptr icon(IMG_Load(path.c_str()), SDL_FreeSurface); if (icon) { @@ -194,7 +194,7 @@ namespace sa2 void SDLFrame::GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) { const std::string filename = getBitmapFilename(lpBitmapName); - const std::string path = myResourcePath + filename; + const std::string path = getResourcePath(filename); std::shared_ptr surface(SDL_LoadBMP(path.c_str()), SDL_FreeSurface); if (surface) diff --git a/source/frontends/sdl/sdlframe.h b/source/frontends/sdl/sdlframe.h index e6304ea38..a262b3928 100644 --- a/source/frontends/sdl/sdlframe.h +++ b/source/frontends/sdl/sdlframe.h @@ -14,7 +14,7 @@ namespace common2 namespace sa2 { - class SDLFrame : public common2::CommonFrame + class SDLFrame : public virtual common2::CommonFrame { public: SDLFrame(const common2::EmulatorOptions & options);