Skip to content

Commit

Permalink
move config-file seeking code to its own thing.
Browse files Browse the repository at this point in the history
look also into the same directory as melonDS. make it the preferred place for storing melonDS.ini.
rewrite WinMain() wrapper.
  • Loading branch information
Arisotura committed Dec 11, 2018
1 parent 9a0bf91 commit 40f3f91
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 143 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ SET(SOURCES
src/GPU2D.cpp
src/GPU3D.cpp
src/GPU3D_Soft.cpp
src/melon_fopen.cpp
src/NDS.cpp
src/NDSCart.cpp
src/RTC.cpp
Expand Down
1 change: 1 addition & 0 deletions melonDS.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@
<Unit filename="src/libui_sdl/libui/windows/winpublic.cpp" />
<Unit filename="src/libui_sdl/libui/windows/winutil.cpp" />
<Unit filename="src/libui_sdl/main.cpp" />
<Unit filename="src/melon_fopen.cpp" />
<Unit filename="src/melon_fopen.h" />
<Unit filename="src/pcap/bluetooth.h" />
<Unit filename="src/pcap/bpf.h" />
Expand Down
106 changes: 27 additions & 79 deletions src/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,17 @@
#include <string.h>
#include <stdlib.h>
#include "Config.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
#include "melon_fopen.h"


bool LocalFileExists(const char* name);
extern char* EmuDirectory;

namespace Config
{

const char* kConfigFile = "melonDS.ini";

int KeyMapping[12];
int JoyMapping[12];

Expand Down Expand Up @@ -114,72 +110,6 @@ ConfigEntry ConfigFile[] =
{"", -1, NULL, 0, NULL, 0}
};

FILE* GetConfigFile(const char* fileName, const char* permissions)
{
// Locations are application directory, and XDG_CONFIG_HOME/melonds or AppData/MelonDS on windows

FILE* f;

// First check application directory
f = fopen(fileName, permissions);
if (f) return f;
#ifdef _WIN32
// Now check AppData
PWSTR appDataPath = NULL;
SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appDataPath);
if (!appDataPath)
return NULL;

const WCHAR* appdir = L"\\melonDS\\";

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?

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

// this will be more than enough
WCHAR fatperm[4];
fatperm[0] = permissions[0];
fatperm[1] = permissions[1];
fatperm[2] = permissions[2];
fatperm[3] = 0;

f = _wfopen(appDataPath, fatperm);
CoTaskMemFree(appDataPath);
delete[] wfileName;
if (f) return f;
#else
// 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;
#endif

return NULL;

}

bool HasConfigFile(const char* fileName)
{
FILE* f = GetConfigFile(fileName, "rb");
if (f)
{
fclose(f);
return true;
}
else
return false;
}

void Load()
{
Expand All @@ -196,7 +126,7 @@ void Load()
entry++;
}

FILE* f = Config::GetConfigFile("melonDS.ini", "r");
FILE* f = melon_fopen_local(kConfigFile, "r");
if (!f) return;

char linebuf[1024];
Expand Down Expand Up @@ -232,8 +162,26 @@ void Load()

void Save()
{
FILE* f = Config::GetConfigFile("melonDS.ini", "w");
if (!f) return;
FILE* f;
if (LocalFileExists(kConfigFile))
{
f = melon_fopen_local(kConfigFile, "w");
if (!f) return;
}
else
{
int dirlen = strlen(EmuDirectory);
int filelen = strlen(kConfigFile);
char* path = new char[dirlen + 1 + filelen + 1];
strncpy(&path[0], EmuDirectory, dirlen);
path[dirlen] = '/';
strncpy(&path[dirlen+1], kConfigFile, filelen);
path[dirlen+1+filelen] = '\0';

f = melon_fopen(path, "w");
delete[] path;
if (!f) return;
}

ConfigEntry* entry = &ConfigFile[0];
for (;;)
Expand Down
5 changes: 3 additions & 2 deletions src/NDS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "RTC.h"
#include "Wifi.h"
#include "Platform.h"
#include "melon_fopen.h"


namespace NDS
Expand Down Expand Up @@ -386,7 +387,7 @@ void Reset()
dbg_CyclesTimer7 = 0;
#endif // DEBUG_CHECK_DESYNC

f = Config::GetConfigFile("bios9.bin", "rb");
f = melon_fopen_local("bios9.bin", "rb");
if (!f)
{
printf("ARM9 BIOS not found\n");
Expand All @@ -403,7 +404,7 @@ void Reset()
fclose(f);
}

f = Config::GetConfigFile("bios7.bin", "rb");
f = melon_fopen_local("bios7.bin", "rb");
if (!f)
{
printf("ARM7 BIOS not found\n");
Expand Down
7 changes: 4 additions & 3 deletions src/SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "Config.h"
#include "NDS.h"
#include "SPI.h"
#include "melon_fopen.h"


namespace SPI_Firmware
Expand Down Expand Up @@ -89,7 +90,7 @@ void Reset()
if (Firmware) delete[] Firmware;
Firmware = NULL;

FILE* f = Config::GetConfigFile("firmware.bin", "rb");
FILE* f = melon_fopen_local("firmware.bin", "rb");
if (!f)
{
printf("firmware.bin not found\n");
Expand Down Expand Up @@ -129,7 +130,7 @@ void Reset()

// take a backup
char* firmbkp = "firmware.bin.bak";
f = Config::GetConfigFile(firmbkp, "rb");
f = melon_fopen_local(firmbkp, "rb");
if (f) fclose(f);
else
{
Expand Down Expand Up @@ -324,7 +325,7 @@ void Write(u8 val, u32 hold)

if (!hold && (CurCmd == 0x02 || CurCmd == 0x0A))
{
FILE* f = Config::GetConfigFile("firmware.bin", "r+b");
FILE* f = melon_fopen_local("firmware.bin", "r+b");
if (f)
{
u32 cutoff = 0x7FA00 & FirmwareMask;
Expand Down
74 changes: 42 additions & 32 deletions src/libui_sdl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ const int kScreenLayout[3] = {0, 1, 2};
const int kScreenSizing[4] = {0, 1, 2, 3};


char* EmuDirectory;


uiWindow* MainWindow;
uiArea* MainDrawArea;

Expand Down Expand Up @@ -116,14 +119,22 @@ void GetSavestateName(int slot, char* filename, int len);



bool FileExists(char* name)
bool FileExists(const char* name)
{
FILE* f = melon_fopen(name, "rb");
if (!f) return false;
fclose(f);
return true;
}

bool LocalFileExists(const char* name)
{
FILE* f = melon_fopen_local(name, "rb");
if (!f) return false;
fclose(f);
return true;
}


void UpdateWindowTitle(void* data)
{
Expand Down Expand Up @@ -1308,6 +1319,19 @@ int main(int argc, char** argv)
printf("melonDS " MELONDS_VERSION "\n");
printf(MELONDS_URL "\n");

{
int len = strlen(argv[0]);
while (len > 0)
{
if (argv[0][len] == '/') break;
if (argv[0][len] == '\\') break;
len--;
}
EmuDirectory = new char[len];
strncpy(EmuDirectory, argv[0], len);
EmuDirectory[len] = '\0';
}

// http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");

Expand Down Expand Up @@ -1335,7 +1359,7 @@ int main(int argc, char** argv)

Config::Load();

if (!Config::HasConfigFile("bios7.bin") || !Config::HasConfigFile("bios9.bin") || !Config::HasConfigFile("firmware.bin"))
if (!LocalFileExists("bios7.bin") || !LocalFileExists("bios9.bin") || !LocalFileExists("firmware.bin"))
{
uiMsgBoxError(
NULL,
Expand Down Expand Up @@ -1618,6 +1642,7 @@ int main(int argc, char** argv)

uiUninit();
SDL_Quit();
delete[] EmuDirectory;
return 0;
}

Expand All @@ -1627,41 +1652,26 @@ int main(int argc, char** argv)

int CALLBACK WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdshow)
{
char cmdargs[16][256];
int arg = 1;
int j = 0;
bool inquote = false;
int len = strlen(cmdline);
for (int i = 0; i < len; i++)
int argc = 0;
wchar_t** argv_w = CommandLineToArgvW(GetCommandLineW(), &argc);
char* nullarg = "";

char** argv = new char*[argc];
for (int i = 0; i < argc; i++)
{
char c = cmdline[i];
if (c == '\0') break;
if (c == '"') inquote = !inquote;
if (!inquote && c==' ')
{
if (j > 255) j = 255;
if (arg < 16) cmdargs[arg][j] = '\0';
arg++;
j = 0;
}
else
{
if (arg < 16 && j < 255) cmdargs[arg][j] = c;
j++;
}
int len = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1, NULL, 0, NULL, NULL);
if (len < 1) return NULL;
argv[i] = new char[len];
int res = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1, argv[i], len, NULL, NULL);
if (res != len) { delete[] argv[i]; argv[i] = nullarg; }
}
if (j > 255) j = 255;
if (arg < 16) cmdargs[arg][j] = '\0';
if (len > 0) arg++;

// FIXME!!
strncpy(cmdargs[0], "melonDS.exe", 256);
int ret = main(argc, argv);

char* cmdargptr[16];
for (int i = 0; i < 16; i++)
cmdargptr[i] = &cmdargs[i][0];
for (int i = 0; i < argc; i++) if (argv[i] != nullarg) delete[] argv[i];
delete[] argv;

return main(arg, cmdargptr);
return ret;
}

#endif
Loading

0 comments on commit 40f3f91

Please sign in to comment.