move config-file seeking code to its own thing.

look also into the same directory as melonDS. make it the preferred place for storing melonDS.ini.
rewrite WinMain() wrapper.
This commit is contained in:
StapleButter
2018-12-11 21:34:05 +01:00
parent 9a0bf912d9
commit 40f3f91368
8 changed files with 256 additions and 143 deletions

176
src/melon_fopen.cpp Normal file
View File

@ -0,0 +1,176 @@
/*
Copyright 2016-2019 StapleButter
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK
#include <windows.h>
//#include <knownfolders.h> // FUCK THAT SHIT
extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_RoamingAppData = {0x3eb685db, 0x65f9, 0x4cf6, {0xa0, 0x3a, 0xe3, 0xef, 0x65, 0x72, 0x9f, 0x3d}};
#include <shlobj.h>
#else
#include <glib.h>
#endif
extern char* EmuDirectory;
#ifdef __WIN32__
FILE* melon_fopen(const char* path, const char* mode)
{
int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
if (len < 1) return NULL;
WCHAR* fatass = new WCHAR[len];
int res = MultiByteToWideChar(CP_UTF8, 0, path, -1, fatass, len);
if (res != len) { delete[] fatass; return NULL; } // checkme?
// this will be more than enough
WCHAR fatmode[4];
fatmode[0] = mode[0];
fatmode[1] = mode[1];
fatmode[2] = mode[2];
fatmode[3] = 0;
FILE* ret = _wfopen(fatass, fatmode);
delete[] fatass;
return ret;
}
FILE* melon_fopen_local(const char* fileName, const char* permissions)
{
// Locations are application directory, and AppData/melonDS on windows
FILE* f;
// First check current working directory
f = fopen(fileName, permissions);
if (f) return f;
// then emu directory
{
int dirlen = strlen(EmuDirectory);
if (dirlen)
{
int filelen = strlen(fileName);
int len = dirlen + 1 + filelen + 1;
char* tmp = new char[len];
strncpy(&tmp[0], EmuDirectory, dirlen);
tmp[dirlen] = '\\';
strncpy(&tmp[dirlen+1], fileName, filelen);
tmp[dirlen+1+filelen] = '\0';
f = melon_fopen(tmp, permissions);
delete[] tmp;
if (f) return f;
}
}
// Now check AppData
PWSTR appDataPath = NULL;
SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appDataPath);
if (!appDataPath)
return NULL;
// this will be more than enough
WCHAR fatperm[4];
fatperm[0] = permissions[0];
fatperm[1] = permissions[1];
fatperm[2] = permissions[2];
fatperm[3] = 0;
int fnlen = MultiByteToWideChar(CP_UTF8, 0, fileName, -1, NULL, 0);
if (fnlen < 1) return NULL;
WCHAR* wfileName = new WCHAR[fnlen];
int res = MultiByteToWideChar(CP_UTF8, 0, fileName, -1, wfileName, fnlen);
if (res != fnlen) { delete[] wfileName; return NULL; } // checkme?
const WCHAR* appdir = L"\\melonDS\\";
int pos = wcslen(appDataPath);
void* ptr = CoTaskMemRealloc(appDataPath, (pos+wcslen(appdir)+fnlen+1)*sizeof(WCHAR));
if (!ptr) { delete[] wfileName; return NULL; } // oh well
appDataPath = (PWSTR)ptr;
wcscpy(&appDataPath[pos], appdir); pos += wcslen(appdir);
wcscpy(&appDataPath[pos], wfileName);
f = _wfopen(appDataPath, fatperm);
CoTaskMemFree(appDataPath);
delete[] wfileName;
if (f) return f;
return NULL;
}
#else
FILE* melon_fopen(const char* filename, const char* perm) { return fopen(filename, perm); }
FILE* GetConfigFile(const char* fileName, const char* permissions)
{
// Locations are application directory, and XDG_CONFIG_HOME/melonds
FILE* f;
// First check current working directory
f = fopen(fileName, permissions);
if (f) return f;
// then emu directory
{
int dirlen = strlen(EmuDirectory);
if (dirlen)
{
int filelen = strlen(fileName);
int len = dirlen + 1 + filelen + 1;
char* tmp = new char[len];
strncpy(&tmp[0], EmuDirectory, dirlen);
tmp[dirlen] = '\\';
strncpy(&tmp[dirlen+1], fileName, filelen);
tmp[dirlen+1+filelen] = '\0';
f = fopen(tmp, permissions);
delete[] tmp;
if (f) return f;
}
}
// Now check XDG_CONFIG_HOME
// TODO: check for memory leak there
std::string path = std::string(g_get_user_config_dir()) + "/melonds/" + fileName;
f = fopen(path.c_str(), permissions);
if (f) return f;
return NULL;
}
#endif