Skip to content
Permalink
Browse files

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.
  • Loading branch information
denisfa authored and rkitover committed Mar 18, 2019
1 parent 2142a46 commit a1f0c34acec3e0483570b927ee921b5a37c8fc9b
Showing with 125 additions and 82 deletions.
  1. +102 −76 src/sdl/SDL.cpp
  2. +7 −5 src/wx/panel.cpp
  3. +14 −1 src/wx/wxvbam.cpp
  4. +2 −0 src/wx/wxvbam.h
@@ -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);

char* p = (char*)dir + len - 1;
if (!dir || !dir[0])
return false;

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;
}
char path[1024] = ""; // avoid warning about uninitialised value
char *filename = strrchr(name, FILE_SEP);
if (filename)
strncpy(path, filename + 1, strlen(filename));
else
sprintf(path, "%s", name);
return strdup(path);
}

if (len == 0)
strcpy(filebuffer, name);
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
strcpy(filebuffer, p);
return filebuffer;
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);

bool result = emulator.emuWriteBattery(buffer);

emulator.emuWriteBattery(buffer);
if (result)
systemMessage(0, "Wrote battery '%s'", buffer);

systemScreenMessage("Wrote battery");
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 @@ class wxvbamApp : public wxApp {
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);

0 comments on commit a1f0c34

Please sign in to comment.
You can’t perform that action at this time.