Separate Frame from Resource folder to support native MacOS port.

Fixes https://github.com/audetto/AppleWin/issues/55

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2022-01-03 17:01:22 +00:00
parent 1f1a0f0c3f
commit f03c09db76
12 changed files with 138 additions and 97 deletions

View file

@ -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

View file

@ -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 <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <libgen.h>
#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<std::string> 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/";
}
}

View file

@ -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<BYTE> myResource;
};

View file

@ -0,0 +1,99 @@
#include "StdAfx.h"
#include "frontends/common2/gnuframe.h"
#include "frontends/common2/fileregistry.h"
#include <sys/stat.h>
#include <unistd.h>
#include <libgen.h>
#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<std::string> 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/";
}
}

View file

@ -0,0 +1,22 @@
#pragma once
#include "frontends/common2/commonframe.h"
#include <string>
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;
};
}

View file

@ -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<char> buffer;
readFileToBuffer(path, buffer);

View file

@ -1,6 +1,7 @@
#pragma once
#include "frontends/common2/commonframe.h"
#include "frontends/common2/gnuframe.h"
#include <memory>
#include <vector>
@ -8,7 +9,7 @@
namespace ra2
{
class RetroFrame : public common2::CommonFrame
class RetroFrame : public virtual common2::CommonFrame, public common2::GNUFrame
{
public:
RetroFrame();

View file

@ -1,6 +1,7 @@
#pragma once
#include "frontends/common2/commonframe.h"
#include "frontends/common2/gnuframe.h"
#include <memory>
#include <string>
@ -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<EvDevPaddle> & paddle);

View file

@ -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);

View file

@ -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);

View file

@ -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<SDL_Surface> 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<SDL_Surface> surface(SDL_LoadBMP(path.c_str()), SDL_FreeSurface);
if (surface)

View file

@ -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);