XDG followup work #94
* Apply save order for save states and batteries. The order for save state/battery: 1. StateDir / BatteryDir; 2. The path of the current loaded game; 3. XDG Base Dir fallback. * Use XDG Base Dir fallback to save screenshots and recordings. * Apply search order for all dirs except recording (not implemented yet) of SDL port. The order for battery/save state/screenshot is: 1. StateDir/BatteryDir/ScreenshotDir; 2. The path of the current loaded game; 3. XDG Base Dir (or equivalent) fallback. * Refactor code. * Fix freeing and setting pointer to NULL of SDL port.
This commit is contained in:
parent
2142a46dd5
commit
a1f0c34ace
180
src/sdl/SDL.cpp
180
src/sdl/SDL.cpp
|
@ -64,14 +64,22 @@
|
|||
#include "inputSDL.h"
|
||||
#include "text.h"
|
||||
|
||||
// from: https://stackoverflow.com/questions/7608714/why-is-my-pointer-not-null-after-free
|
||||
#define freeSafe(ptr) free(ptr); ptr = NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#define GETCWD getcwd
|
||||
#else // _WIN32
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#define GETCWD _getcwd
|
||||
#define snprintf sprintf
|
||||
#define stat _stat
|
||||
#define access _access
|
||||
#ifndef W_OK
|
||||
#define W_OK 2
|
||||
#endif
|
||||
#define mkdir(X,Y) (_mkdir(X))
|
||||
// from: https://www.linuxquestions.org/questions/programming-9/porting-to-win32-429334/
|
||||
#ifndef S_ISDIR
|
||||
|
@ -208,7 +216,8 @@ int sdlMirroringEnable = 1;
|
|||
void systemConsoleMessage(const char*);
|
||||
|
||||
char* home;
|
||||
char homeDataDir[2048];
|
||||
char homeConfigDir[1024];
|
||||
char homeDataDir[1024];
|
||||
|
||||
char screenMessageBuffer[21];
|
||||
uint32_t screenMessageTime = 0;
|
||||
|
@ -253,7 +262,7 @@ void StartLirc(void)
|
|||
fprintf(stdout, "Success\n");
|
||||
//read the config file
|
||||
char LIRCConfigLoc[2048];
|
||||
sprintf(LIRCConfigLoc, "%s/%s", homeDataDir, "lircrc");
|
||||
sprintf(LIRCConfigLoc, "%s%c%s", homeConfigDir, FILE_SEP, "lircrc");
|
||||
fprintf(stdout, "LIRC Config file:");
|
||||
if (lirc_readconfig(LIRCConfigLoc, &LIRCConfigInfo, NULL) == 0) {
|
||||
//check vbam dir for lircrc
|
||||
|
@ -291,59 +300,47 @@ void StopLirc(void)
|
|||
|
||||
bool sdlCheckDirectory(const char* dir)
|
||||
{
|
||||
bool res = false;
|
||||
|
||||
if (!dir || !dir[0]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat buf;
|
||||
|
||||
int len = strlen(dir);
|
||||
if (!dir || !dir[0])
|
||||
return false;
|
||||
|
||||
char* p = (char*)dir + len - 1;
|
||||
|
||||
while (p != dir && (*p == '/' || *p == '\\')) {
|
||||
*p = 0;
|
||||
p--;
|
||||
if (stat(dir, &buf) == 0)
|
||||
{
|
||||
if (!(buf.st_mode & S_IFDIR))
|
||||
{
|
||||
fprintf(stderr, "Error: %s is not a directory\n", dir);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (stat(dir, &buf) == 0) {
|
||||
if (!(buf.st_mode & S_IFDIR)) {
|
||||
fprintf(stderr, "Error: %s is not a directory\n", dir);
|
||||
}
|
||||
res = true;
|
||||
} else {
|
||||
fprintf(stderr, "Error: %s does not exist\n", dir);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Error: %s does not exist\n", dir);
|
||||
return false;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
char* sdlGetFilename(char* name)
|
||||
{
|
||||
static char filebuffer[2048];
|
||||
|
||||
int len = strlen(name);
|
||||
|
||||
char* p = name + len - 1;
|
||||
|
||||
while (true) {
|
||||
if (*p == '/' || *p == '\\') {
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
len--;
|
||||
p--;
|
||||
if (len == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
strcpy(filebuffer, name);
|
||||
char path[1024] = ""; // avoid warning about uninitialised value
|
||||
char *filename = strrchr(name, FILE_SEP);
|
||||
if (filename)
|
||||
strncpy(path, filename + 1, strlen(filename));
|
||||
else
|
||||
strcpy(filebuffer, p);
|
||||
return filebuffer;
|
||||
sprintf(path, "%s", name);
|
||||
return strdup(path);
|
||||
}
|
||||
|
||||
char* sdlGetFilePath(char* name)
|
||||
{
|
||||
char path[1024] = ""; // avoid warning about uninitialised value
|
||||
char *filename = strrchr(name, FILE_SEP);
|
||||
if (filename)
|
||||
strncpy(path, name, strlen(name) - strlen(filename));
|
||||
else
|
||||
sprintf(path, "%c%c", '.', FILE_SEP);
|
||||
return strdup(path);
|
||||
}
|
||||
|
||||
FILE* sdlFindFile(const char* name)
|
||||
|
@ -661,15 +658,18 @@ static int sdlCalculateShift(uint32_t mask)
|
|||
static char* sdlStateName(int num)
|
||||
{
|
||||
static char stateName[2048];
|
||||
char *gameDir = sdlGetFilePath(filename);
|
||||
char *gameFile = sdlGetFilename(filename);
|
||||
|
||||
if (saveDir)
|
||||
sprintf(stateName, "%s/%s%d.sgm", saveDir, sdlGetFilename(filename),
|
||||
num + 1);
|
||||
else if (homeDir)
|
||||
sprintf(stateName, "%s/%s%d.sgm", homeDataDir, sdlGetFilename(filename), num + 1);
|
||||
sprintf(stateName, "%s%c%s%d.sgm", saveDir, FILE_SEP, gameFile, num + 1);
|
||||
else if (access(gameDir, W_OK) == 0)
|
||||
sprintf(stateName, "%s%c%s%d.sgm", gameDir, FILE_SEP, gameFile, num + 1);
|
||||
else
|
||||
sprintf(stateName, "%s%d.sgm", filename, num + 1);
|
||||
sprintf(stateName, "%s%c%s%d.sgm", homeDataDir, FILE_SEP, gameFile, num + 1);
|
||||
|
||||
freeSafe(gameDir);
|
||||
freeSafe(gameFile);
|
||||
return stateName;
|
||||
}
|
||||
|
||||
|
@ -760,37 +760,46 @@ void sdlWriteBackupStateExchange(int from, int to, int backup)
|
|||
|
||||
void sdlWriteBattery()
|
||||
{
|
||||
char buffer[1048];
|
||||
char buffer[2048];
|
||||
char *gameDir = sdlGetFilePath(filename);
|
||||
char *gameFile = sdlGetFilename(filename);
|
||||
|
||||
if (batteryDir)
|
||||
sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename));
|
||||
else if (homeDir)
|
||||
sprintf(buffer, "%s/%s.sav", homeDataDir, sdlGetFilename(filename));
|
||||
sprintf(buffer, "%s%c%s.sav", batteryDir, FILE_SEP, gameFile);
|
||||
else if (access(gameDir, W_OK) == 0)
|
||||
sprintf(buffer, "%s%c%s.sav", gameDir, FILE_SEP, gameFile);
|
||||
else
|
||||
sprintf(buffer, "%s.sav", filename);
|
||||
sprintf(buffer, "%s%c%s.sav", homeDataDir, FILE_SEP, gameFile);
|
||||
|
||||
emulator.emuWriteBattery(buffer);
|
||||
bool result = emulator.emuWriteBattery(buffer);
|
||||
|
||||
systemScreenMessage("Wrote battery");
|
||||
if (result)
|
||||
systemMessage(0, "Wrote battery '%s'", buffer);
|
||||
|
||||
freeSafe(gameFile);
|
||||
freeSafe(gameDir);
|
||||
}
|
||||
|
||||
void sdlReadBattery()
|
||||
{
|
||||
char buffer[1048];
|
||||
char buffer[2048];
|
||||
char *gameDir = sdlGetFilePath(filename);
|
||||
char *gameFile = sdlGetFilename(filename);
|
||||
|
||||
if (batteryDir)
|
||||
sprintf(buffer, "%s/%s.sav", batteryDir, sdlGetFilename(filename));
|
||||
else if (homeDir)
|
||||
sprintf(buffer, "%s/%s.sav", homeDataDir, sdlGetFilename(filename));
|
||||
sprintf(buffer, "%s%c%s.sav", batteryDir, FILE_SEP, gameFile);
|
||||
else if (access(gameDir, W_OK) == 0)
|
||||
sprintf(buffer, "%s%c%s.sav", gameDir, FILE_SEP, gameFile);
|
||||
else
|
||||
sprintf(buffer, "%s.sav", filename);
|
||||
sprintf(buffer, "%s%c%s.sav", homeDataDir, FILE_SEP, gameFile);
|
||||
|
||||
bool res = false;
|
||||
bool result = emulator.emuReadBattery(buffer);
|
||||
|
||||
res = emulator.emuReadBattery(buffer);
|
||||
if (result)
|
||||
systemMessage(0, "Loaded battery '%s'", buffer);
|
||||
|
||||
if (res)
|
||||
systemScreenMessage("Loaded battery");
|
||||
freeSafe(gameFile);
|
||||
freeSafe(gameDir);
|
||||
}
|
||||
|
||||
void sdlReadDesktopVideoMode()
|
||||
|
@ -1644,6 +1653,14 @@ void handleRewinds()
|
|||
}
|
||||
}
|
||||
|
||||
void SetHomeConfigDir()
|
||||
{
|
||||
sprintf(homeConfigDir, "%s%s", get_xdg_user_config_home().c_str(), DOT_DIR);
|
||||
struct stat s;
|
||||
if (stat(homeDataDir, &s) == -1 || !S_ISDIR(s.st_mode))
|
||||
mkdir(homeDataDir, 0755);
|
||||
}
|
||||
|
||||
void SetHomeDataDir()
|
||||
{
|
||||
sprintf(homeDataDir, "%s%s", get_xdg_user_data_home().c_str(), DOT_DIR);
|
||||
|
@ -1658,6 +1675,7 @@ int main(int argc, char** argv)
|
|||
|
||||
home = argv[0];
|
||||
SetHome(home);
|
||||
SetHomeConfigDir();
|
||||
SetHomeDataDir();
|
||||
|
||||
frameSkip = 2;
|
||||
|
@ -2224,27 +2242,35 @@ void system10Frames(int rate)
|
|||
void systemScreenCapture(int a)
|
||||
{
|
||||
char buffer[2048];
|
||||
bool result = false;
|
||||
char *gameDir = sdlGetFilePath(filename);
|
||||
char *gameFile = sdlGetFilename(filename);
|
||||
|
||||
if (captureFormat) {
|
||||
if (screenShotDir)
|
||||
sprintf(buffer, "%s/%s%02d.bmp", screenShotDir, sdlGetFilename(filename), a);
|
||||
else if (homeDir)
|
||||
sprintf(buffer, "%s/%s%02d.bmp", homeDataDir, sdlGetFilename(filename), a);
|
||||
sprintf(buffer, "%s%c%s%02d.bmp", screenShotDir, FILE_SEP, gameFile, a);
|
||||
else if (access(gameDir, W_OK) == 0)
|
||||
sprintf(buffer, "%s%c%s%02d.bmp", gameDir, FILE_SEP, gameFile, a);
|
||||
else
|
||||
sprintf(buffer, "%s%02d.bmp", filename, a);
|
||||
sprintf(buffer, "%s%c%s%02d.bmp", homeDataDir, FILE_SEP, gameFile, a);
|
||||
|
||||
emulator.emuWriteBMP(buffer);
|
||||
result = emulator.emuWriteBMP(buffer);
|
||||
} else {
|
||||
if (screenShotDir)
|
||||
sprintf(buffer, "%s/%s%02d.png", screenShotDir, sdlGetFilename(filename), a);
|
||||
else if (homeDir)
|
||||
sprintf(buffer, "%s/%s%02d.png", homeDataDir, sdlGetFilename(filename), a);
|
||||
sprintf(buffer, "%s%c%s%02d.png", screenShotDir, FILE_SEP, gameFile, a);
|
||||
else if (access(gameDir, W_OK) == 0)
|
||||
sprintf(buffer, "%s%c%s%02d.png", gameDir, FILE_SEP, gameFile, a);
|
||||
else
|
||||
sprintf(buffer, "%s%02d.png", filename, a);
|
||||
emulator.emuWritePNG(buffer);
|
||||
sprintf(buffer, "%s%c%s%02d.png", homeDataDir, FILE_SEP, gameFile, a);
|
||||
|
||||
result = emulator.emuWritePNG(buffer);
|
||||
}
|
||||
|
||||
systemScreenMessage("Screen capture");
|
||||
if (result)
|
||||
systemScreenMessage("Screen capture");
|
||||
|
||||
freeSafe(gameFile);
|
||||
freeSafe(gameDir);
|
||||
}
|
||||
|
||||
void systemSaveOldest()
|
||||
|
|
|
@ -461,6 +461,10 @@ void GameArea::recompute_dirs()
|
|||
batdir = wxGetApp().GetAbsolutePath(gopts.battery_dir);
|
||||
}
|
||||
|
||||
if (!wxIsWritable(batdir)) {
|
||||
batdir = wxGetApp().GetDataDir();
|
||||
}
|
||||
|
||||
statedir = gopts.state_dir;
|
||||
|
||||
if (!statedir.size()) {
|
||||
|
@ -469,11 +473,9 @@ void GameArea::recompute_dirs()
|
|||
statedir = wxGetApp().GetAbsolutePath(gopts.state_dir);
|
||||
}
|
||||
|
||||
if (!wxIsWritable(batdir))
|
||||
batdir = wxGetApp().GetConfigurationPath();
|
||||
|
||||
if (!wxIsWritable(statedir))
|
||||
statedir = wxGetApp().GetConfigurationPath();
|
||||
if (!wxIsWritable(statedir)) {
|
||||
statedir = wxGetApp().GetDataDir();
|
||||
}
|
||||
}
|
||||
|
||||
void GameArea::UnloadGame(bool destruct)
|
||||
|
|
|
@ -636,6 +636,16 @@ bool wxvbamApp::OnCmdLineParsed(wxCmdLineParser& cl)
|
|||
return true;
|
||||
}
|
||||
|
||||
wxString wxvbamApp::GetConfigDir()
|
||||
{
|
||||
return GetAbsolutePath(get_xdg_user_config_home() + DOT_DIR);
|
||||
}
|
||||
|
||||
wxString wxvbamApp::GetDataDir()
|
||||
{
|
||||
return GetAbsolutePath(get_xdg_user_data_home() + DOT_DIR);
|
||||
}
|
||||
|
||||
wxvbamApp::~wxvbamApp() {
|
||||
if (home != NULL)
|
||||
{
|
||||
|
@ -774,7 +784,10 @@ wxString MainFrame::GetGamePath(wxString path)
|
|||
game_path = wxFileName::GetCwd();
|
||||
|
||||
if (!wxIsWritable(game_path))
|
||||
game_path = wxGetApp().GetConfigurationPath();
|
||||
{
|
||||
game_path = wxGetApp().GetAbsolutePath(get_xdg_user_data_home() + DOT_DIR);
|
||||
wxFileName::Mkdir(game_path, 0777, wxPATH_MKDIR_FULL);
|
||||
}
|
||||
|
||||
return game_path;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,8 @@ public:
|
|||
virtual bool UsingWayland() { return using_wayland; }
|
||||
virtual void OnInitCmdLine(wxCmdLineParser&);
|
||||
virtual bool OnCmdLineParsed(wxCmdLineParser&);
|
||||
virtual wxString GetConfigDir();
|
||||
virtual wxString GetDataDir();
|
||||
wxString GetConfigurationPath();
|
||||
const wxString GetPluginsDir();
|
||||
wxString GetAbsolutePath(wxString path);
|
||||
|
|
Loading…
Reference in New Issue