aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2020-01-28 21:37:36 +0100
committerGitHub <noreply@github.com>2020-01-28 21:37:36 +0100
commit2c51a495274106bc39b04f3ef99b217f5df21a21 (patch)
tree11f98cf0e8c087964943acdbac00ed618a559824
parent8b9eef352c9ea00f1dc8fbe37ecab79cd8630b3c (diff)
parentc5623c4dcd122278e45a363b655be67d845ecf63 (diff)
Merge pull request #546 from nadiaholmquist/feature/unix-xdg
Make melonDS properly installable systemwide on UNIX systems
-rw-r--r--flatpak/net.kuribo64.melonDS.yml (renamed from flatpak/net.kuribo64.melonds.yml)12
-rw-r--r--flatpak/net.kuribo64.melonds.desktop8
-rw-r--r--net.kuribo64.melonDS.desktop11
-rw-r--r--src/NDSCart.cpp2
-rw-r--r--src/Platform.h8
-rw-r--r--src/libui_sdl/CMakeLists.txt8
-rw-r--r--src/libui_sdl/Platform.cpp71
-rw-r--r--src/libui_sdl/main.cpp53
8 files changed, 140 insertions, 33 deletions
diff --git a/flatpak/net.kuribo64.melonds.yml b/flatpak/net.kuribo64.melonDS.yml
index dcc97b5..e336990 100644
--- a/flatpak/net.kuribo64.melonds.yml
+++ b/flatpak/net.kuribo64.melonDS.yml
@@ -1,5 +1,5 @@
---
-app-id: net.kuribo64.melonds
+app-id: net.kuribo64.melonDS
runtime: org.freedesktop.Platform
runtime-version: '18.08'
sdk: org.freedesktop.Sdk
@@ -22,10 +22,8 @@ modules:
buildsystem: cmake-ninja
sources:
- type: git
- url: https://github.com/StapleButter/melonDS.git
- commit: d4d4965b2fffc69958685a25a9d9fc0c78b54567
- - type: file
- path: net.kuribo64.melonds.desktop
+ url: https://github.com/Arisotura/melonDS.git
+ branch: master
post-install:
- - "desktop-file-install --dir=/app/share/applications net.kuribo64.melonds.desktop"
- - "install -D icon/melon_256x256.png /app/share/icons/hicolor/256x256/apps/net.kuribo64.melonds.png"
+ - "desktop-file-install --dir=/app/share/applications net.kuribo64.melonDS.desktop"
+ - "install -D icon/melon_256x256.png /app/share/icons/hicolor/256x256/apps/net.kuribo64.melonDS.png"
diff --git a/flatpak/net.kuribo64.melonds.desktop b/flatpak/net.kuribo64.melonds.desktop
deleted file mode 100644
index e91f10d..0000000
--- a/flatpak/net.kuribo64.melonds.desktop
+++ /dev/null
@@ -1,8 +0,0 @@
-[Desktop Entry]
-Name=melonDS
-Comment=Nintendo DS emulator
-Exec=melonDS
-Type=Application
-Categories=Game;
-Terminal=false
-Icon=net.kuribo64.melonds
diff --git a/net.kuribo64.melonDS.desktop b/net.kuribo64.melonDS.desktop
new file mode 100644
index 0000000..c0dafe2
--- /dev/null
+++ b/net.kuribo64.melonDS.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Name=melonDS
+GenericName=Nintendo DS Emulator
+Comment=A fast and accurate Nintendo DS emulator.
+Exec=melonDS
+Type=Application
+Categories=Game;Emulator;
+Terminal=false
+Icon=net.kuribo64.melonDS
+MimeType=application/x-nintendo-ds-rom;
+Keywords=emulator;Nintendo;DS;NDS;Nintendo DS;
diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp
index 014ae5a..c313011 100644
--- a/src/NDSCart.cpp
+++ b/src/NDSCart.cpp
@@ -814,7 +814,7 @@ bool ReadROMParams(u32 gamecode, u32* params)
// [gamecode] [ROM size] [save type] [reserved]
// list must be sorted by gamecode
- FILE* f = Platform::OpenLocalFile("romlist.bin", "rb");
+ FILE* f = Platform::OpenDataFile("romlist.bin");
if (!f) return false;
fseek(f, 0, SEEK_END);
diff --git a/src/Platform.h b/src/Platform.h
index ca6971e..dfe83d0 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -32,15 +32,21 @@ void StopEmu();
// can be optionally restricted to only opening a file that already exists.
// * OpenLocalFile():
// opens files local to the emulator (melonDS.ini, BIOS, firmware, ...)
-// checks, by order of priority:
+// For Windows builds, or portable UNIX builds it checks, by order of priority:
// * current working directory
// * emulator directory (essentially where the melonDS executable is) if supported
// * any platform-specific application data directories
// in create mode, if the file doesn't exist, it will be created in the emulator
// directory if supported, or in the current directory otherwise
+// For regular UNIX builds, the user's configuration directory is always used.
+// * OpenDataFile():
+// Opens a file that was installed alongside melonDS on UNIX systems in /usr/share, etc.
+// Looks in the user's data directory first, then the system's.
+// If on Windows or a portable UNIX build, this simply calls OpenLocalFile().
FILE* OpenFile(const char* path, const char* mode, bool mustexist=false);
FILE* OpenLocalFile(const char* path, const char* mode);
+FILE* OpenDataFile(const char* path);
inline bool FileExists(const char* name)
{
diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt
index 64206bf..2d384e4 100644
--- a/src/libui_sdl/CMakeLists.txt
+++ b/src/libui_sdl/CMakeLists.txt
@@ -31,6 +31,11 @@ target_link_libraries(melonDS
core ${SDL2_LIBRARIES} libui)
if (UNIX)
+ option(UNIX_PORTABLE "Make a portable build that looks for its configuration in the current directory" OFF)
+ if (UNIX_PORTABLE)
+ add_definitions(-DUNIX_PORTABLE)
+ endif()
+
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
pkg_check_modules(SDL2 REQUIRED sdl2)
@@ -61,4 +66,7 @@ elseif (WIN32)
target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi)
endif ()
+install(FILES ../../net.kuribo64.melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
+install(FILES ../../icon/melon_256x256.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME net.kuribo64.melonDS.png)
+install(FILES ../../romlist.bin DESTINATION ${CMAKE_INSTALL_PREFIX}/share/melonDS)
install(TARGETS melonDS RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
diff --git a/src/libui_sdl/Platform.cpp b/src/libui_sdl/Platform.cpp
index 94b3791..cc1b734 100644
--- a/src/libui_sdl/Platform.cpp
+++ b/src/libui_sdl/Platform.cpp
@@ -135,6 +135,66 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist)
return ret;
}
+#if !defined(UNIX_PORTABLE) && !defined(__WIN32__)
+
+FILE* OpenLocalFile(const char* path, const char* mode)
+{
+ std::string fullpath;
+ if (path[0] == '/')
+ {
+ // If it's an absolute path, just open that.
+ fullpath = std::string(path);
+ }
+ else
+ {
+ // Check user configuration directory
+ std::string confpath = std::string(g_get_user_config_dir()) + "/melonDS/";
+ g_mkdir_with_parents(confpath.c_str(), 0755);
+ fullpath = confpath + path;
+ }
+
+ return OpenFile(fullpath.c_str(), mode, mode[0] != 'w');
+}
+
+FILE* OpenDataFile(const char* path)
+{
+ const char* melondir = "melonDS";
+ const char* const* sys_dirs = g_get_system_data_dirs();
+ const char* user_dir = g_get_user_data_dir();
+
+ // First check the user's data directory
+ char* fullpath = g_build_path("/", user_dir, melondir, path, NULL);
+ if (access(fullpath, R_OK) == 0)
+ {
+ FILE* f = fopen(fullpath, "r");
+ g_free(fullpath);
+ return f;
+ }
+ free(fullpath);
+
+ // Then check the system data directories
+ for (size_t i = 0; sys_dirs[i] != NULL; i++)
+ {
+ const char* dir = sys_dirs[i];
+ char* fullpath = g_build_path("/", dir, melondir, path, NULL);
+
+ if (access(fullpath, R_OK) == 0)
+ {
+ FILE* f = fopen(fullpath, "r");
+ g_free(fullpath);
+ return f;
+ }
+ free(fullpath);
+ }
+
+ FILE* f = fopen(path, "rb");
+ if (f) return f;
+
+ return NULL;
+}
+
+#else
+
FILE* OpenLocalFile(const char* path, const char* mode)
{
bool relpath = false;
@@ -178,7 +238,7 @@ FILE* OpenLocalFile(const char* path, const char* mode)
emudirpath[pathlen] = '\0';
}
- // Locations are application directory, and AppData/melonDS on Windows or XDG_CONFIG_HOME/melonds on Linux
+ // Locations are application directory, and AppData/melonDS on Windows or XDG_CONFIG_HOME/melonDS on Linux
FILE* f;
@@ -240,7 +300,7 @@ FILE* OpenLocalFile(const char* path, const char* mode)
{
// Now check XDG_CONFIG_HOME
// TODO: check for memory leak there
- std::string fullpath = std::string(g_get_user_config_dir()) + "/melonds/" + path;
+ std::string fullpath = std::string(g_get_user_config_dir()) + "/melonDS/" + path;
f = OpenFile(fullpath.c_str(), mode, true);
if (f) { delete[] emudirpath; return f; }
}
@@ -257,6 +317,13 @@ FILE* OpenLocalFile(const char* path, const char* mode)
return NULL;
}
+FILE* OpenDataFile(const char* path)
+{
+ return OpenLocalFile(path, "rb");
+}
+
+#endif
+
void* Thread_Create(void (*func)())
{
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 4c0d6dd..130c8f9 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -21,6 +21,10 @@
#include <stdio.h>
#include <string.h>
+#ifndef __WIN32__
+#include <glib.h>
+#endif
+
#include <SDL2/SDL.h>
#include "libui/ui.h"
@@ -2681,6 +2685,7 @@ int main(int argc, char** argv)
printf("melonDS " MELONDS_VERSION "\n");
printf(MELONDS_URL "\n");
+#if defined(__WIN32__) || defined(UNIX_PORTABLE)
if (argc > 0 && strlen(argv[0]) > 0)
{
int len = strlen(argv[0]);
@@ -2707,6 +2712,13 @@ int main(int argc, char** argv)
EmuDirectory = new char[2];
strcpy(EmuDirectory, ".");
}
+#else
+ const char* confdir = g_get_user_config_dir();
+ const char* confname = "/melonds";
+ EmuDirectory = new char[strlen(confdir) + strlen(confname) + 1];
+ strcat(EmuDirectory, confdir);
+ strcat(EmuDirectory, confname);
+#endif
// http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
@@ -2742,15 +2754,23 @@ int main(int argc, char** argv)
!Platform::LocalFileExists("bios9.bin") ||
!Platform::LocalFileExists("firmware.bin"))
{
- uiMsgBoxError(
- NULL,
- "BIOS/Firmware not found",
+#if defined(__WIN32__) || defined(UNIX_PORTABLE)
+ const char* locationName = "the directory you run melonDS from";
+#else
+ char* locationName = EmuDirectory;
+#endif
+ char msgboxtext[512];
+ sprintf(msgboxtext,
"One or more of the following required files don't exist or couldn't be accessed:\n\n"
"bios7.bin -- ARM7 BIOS\n"
"bios9.bin -- ARM9 BIOS\n"
"firmware.bin -- firmware image\n\n"
- "Dump the files from your DS and place them in the directory you run melonDS from.\n"
- "Make sure that the files can be accessed.");
+ "Dump the files from your DS and place them in %s.\n"
+ "Make sure that the files can be accessed.",
+ locationName
+ );
+
+ uiMsgBoxError(NULL, "BIOS/Firmware not found", msgboxtext);
uiUninit();
SDL_Quit();
@@ -2796,7 +2816,18 @@ int main(int argc, char** argv)
}
}
{
- FILE* f = Platform::OpenLocalFile("romlist.bin", "rb");
+ const char* romlist_missing = "Save memory type detection will not work correctly.\n\n"
+ "You should use the latest version of romlist.bin (provided in melonDS release packages).";
+#if !defined(UNIX_PORTABLE) && !defined(__WIN32__)
+ std::string missingstr = std::string(romlist_missing) +
+ "\n\nThe ROM list should be placed in " + g_get_user_data_dir() + "/melonds/, otherwise "
+ "melonDS will search for it in the current working directory.";
+ const char* romlist_missing_text = missingstr.c_str();
+#else
+ const char* romlist_missing_text = romlist_missing;
+#endif
+
+ FILE* f = Platform::OpenDataFile("romlist.bin");
if (f)
{
u32 data;
@@ -2805,18 +2836,12 @@ int main(int argc, char** argv)
if ((data >> 24) == 0) // old CRC-based list
{
- uiMsgBoxError(NULL,
- "Your version of romlist.bin is outdated.",
- "Save memory type detection will not work correctly.\n\n"
- "You should use the latest version of romlist.bin (provided in melonDS release packages).");
+ uiMsgBoxError(NULL, "Your version of romlist.bin is outdated.", romlist_missing_text);
}
}
else
{
- uiMsgBoxError(NULL,
- "romlist.bin not found.",
- "Save memory type detection will not work correctly.\n\n"
- "You should use the latest version of romlist.bin (provided in melonDS release packages).");
+ uiMsgBoxError(NULL, "romlist.bin not found.", romlist_missing_text);
}
}