From ffe20c1236d4f8140d25c7548ab452e7b35064bd Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Thu, 30 Apr 2020 03:20:18 +0200 Subject: Use Qt abstractions instead of glib's for paths on Linux --- src/frontend/qt_sdl/Platform.cpp | 53 +++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 30 deletions(-) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 31b5277..de8db93 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -37,7 +37,8 @@ #define socket_t SOCKET #define sockaddr_t SOCKADDR #else - #include + #include + #include #include #include #include @@ -139,6 +140,7 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist) FILE* OpenLocalFile(const char* path, const char* mode) { std::string fullpath; + if (path[0] == '/') { // If it's an absolute path, just open that. @@ -147,9 +149,10 @@ FILE* OpenLocalFile(const char* path, const char* mode) 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; + QString confpath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/melonDS/"; + confpath.append(path); + + fullpath = confpath.toStdString(); } return OpenFile(fullpath.c_str(), mode, mode[0] != 'w'); @@ -157,37 +160,27 @@ FILE* OpenLocalFile(const char* path, const char* mode) 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(); + QString melondir = "melonDS"; + QStringList sys_dirs = QStandardPaths::standardLocations(QStandardPaths::DataLocation); + QString sep = QDir::separator(); - // 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); + const char* found = NULL; - // 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); + for (int i = 0; i < sys_dirs.size(); i++) { + QString f = sys_dirs.at(i) + sep + melondir + sep + QString(path); - if (access(fullpath, R_OK) == 0) - { - FILE* f = fopen(fullpath, "r"); - g_free(fullpath); - return f; + if (QFile::exists(f)) { + found = f.toStdString().c_str(); + break; } - free(fullpath); } - FILE* f = fopen(path, "rb"); - if (f) return f; + if (found == NULL) + return NULL; + + FILE* f = fopen(found, "rb"); + if (f) + return f; return NULL; } @@ -299,7 +292,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 = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation).toStdString() + "/melonDS/" + path; f = OpenFile(fullpath.c_str(), mode, true); if (f) { delete[] emudirpath; return f; } } -- cgit v1.2.3 From 6cfe4faa56f4c7c34bf42cd600c66a2ed7966062 Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 6 May 2020 02:36:47 +0200 Subject: Use Qt abstractions for file I/O and threading on both Windows and Linux. --- src/frontend/qt_sdl/CMakeLists.txt | 13 +- src/frontend/qt_sdl/Platform.cpp | 537 +++++++++++++------------------------ 2 files changed, 191 insertions(+), 359 deletions(-) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index f03cad2..0b39a1c 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -17,6 +17,7 @@ endif() find_package(Qt5 COMPONENTS Core REQUIRED) find_package(Qt5 COMPONENTS Gui REQUIRED) find_package(Qt5 COMPONENTS Widgets REQUIRED) +find_package(Threads REQUIRED) set(CMAKE_AUTOMOC ON) @@ -27,22 +28,24 @@ add_executable(melonDS ${SOURCES_QT_SDL}) target_include_directories(melonDS PRIVATE ${SDL2_INCLUDE_DIRS}) target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..") target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..") -target_link_libraries(melonDS core ${SDL2_LIBRARIES}) +target_link_libraries(melonDS core ${SDL2_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) 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() + option(PORTABLE "Make a portable build that looks for its configuration in the current directory" OFF) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") target_link_libraries(melonDS dl Qt5::Core Qt5::Gui Qt5::Widgets) endif () elseif (WIN32) + option(PORTABLE "Make a portable build that looks for its configuration in the current directory" ON) target_sources(melonDS PUBLIC "${CMAKE_SOURCE_DIR}/melon.rc") target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32 Qt5::Core Qt5::Gui Qt5::Widgets) endif () +if (PORTABLE) + add_definitions(-DPORTABLE) +endif() + install(FILES ../../net.kuribo64.melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) install(FILES ../../icon/melon_16x16.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/16x16/apps RENAME net.kuribo64.melonDS.png) install(FILES ../../icon/melon_32x32.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/32x32/apps RENAME net.kuribo64.melonDS.png) diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index de8db93..ddf48e9 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -19,34 +19,36 @@ #include #include #include -#include +#include +#include +#include +#include +#include + #include "Platform.h" #include "PlatformConfig.h" //#include "LAN_Socket.h" //#include "LAN_PCap.h" -#include #ifdef __WIN32__ - #define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK - #include - //#include // FUCK THAT SHIT - extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_RoamingAppData = {0x3eb685db, 0x65f9, 0x4cf6, {0xa0, 0x3a, 0xe3, 0xef, 0x65, 0x72, 0x9f, 0x3d}}; - #include - #include - #include - #define socket_t SOCKET - #define sockaddr_t SOCKADDR +#define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK +#include +//#include // FUCK THAT SHIT +#include +#include +#include +#define socket_t SOCKET +#define sockaddr_t SOCKADDR #else - #include - #include - #include - #include - #include - #include - #include - #define socket_t int - #define sockaddr_t struct sockaddr - #define closesocket close + +#include +#include +#include +#include + +#define socket_t int +#define sockaddr_t struct sockaddr +#define closesocket close #endif #ifndef INVALID_SOCKET @@ -62,22 +64,6 @@ void Stop(bool internal); namespace Platform { - -typedef struct -{ - SDL_Thread* ID; - void (*Func)(); - -} ThreadData; - -int ThreadEntry(void* data) -{ - ThreadData* thread = (ThreadData*)data; - thread->Func(); - return 0; -} - - socket_t MPSocket; sockaddr_t MPSendAddr; u8 PacketBuffer[2048]; @@ -87,307 +73,151 @@ u8 PacketBuffer[2048]; void StopEmu() { - //Stop(true); + //Stop(true); } - FILE* OpenFile(const char* path, const char* mode, bool mustexist) { - FILE* ret; - -#ifdef __WIN32__ + QFile f(path); - int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); - if (len < 1) return NULL; - WCHAR* fatpath = new WCHAR[len]; - int res = MultiByteToWideChar(CP_UTF8, 0, path, -1, fatpath, len); - if (res != len) { delete[] fatpath; 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; - - if (mustexist) - { - ret = _wfopen(fatpath, L"rb"); - if (ret) ret = _wfreopen(fatpath, fatmode, ret); - } - else - ret = _wfopen(fatpath, fatmode); - - delete[] fatpath; + if (!mustexist && !f.exists()) + return nullptr; -#else - - if (mustexist) - { - ret = fopen(path, "rb"); - if (ret) ret = freopen(path, mode, ret); - } - else - ret = fopen(path, mode); + f.open(QIODevice::ReadOnly); + FILE* file = fdopen(dup(f.handle()), mode); + f.close(); -#endif - - return ret; + return file; } -#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 - QString confpath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/melonDS/"; - confpath.append(path); - - fullpath = confpath.toStdString(); - } - - return OpenFile(fullpath.c_str(), mode, mode[0] != 'w'); -} - -FILE* OpenDataFile(const char* path) -{ - QString melondir = "melonDS"; - QStringList sys_dirs = QStandardPaths::standardLocations(QStandardPaths::DataLocation); - QString sep = QDir::separator(); - - const char* found = NULL; - - for (int i = 0; i < sys_dirs.size(); i++) { - QString f = sys_dirs.at(i) + sep + melondir + sep + QString(path); + QString fullpath; - if (QFile::exists(f)) { - found = f.toStdString().c_str(); - break; - } - } - - if (found == NULL) - return NULL; - - FILE* f = fopen(found, "rb"); - if (f) - return f; + if (path[0] == '/') + { + // If it's an absolute path, just open that. + fullpath = path; + } + else + { +#ifdef PORTABLE + fullpath = QString("./") + path; +#else + // Check user configuration directory + fullpath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/melonDS/"; + fullpath.append(path); +#endif + } - return NULL; + return OpenFile(fullpath.toUtf8(), mode, mode[0] != 'w'); } -#else - -FILE* OpenLocalFile(const char* path, const char* mode) +FILE* OpenDataFile(const char* path) { - bool relpath = false; - int pathlen = strlen(path); - -#ifdef __WIN32__ - if (pathlen > 3) - { - if (path[1] == ':' && path[2] == '\\') - return OpenFile(path, mode); - } +#ifdef PORTABLE + return OpenLocalFile(path); #else - if (pathlen > 1) - { - if (path[0] == '/') - return OpenFile(path, mode); - } -#endif + QString melondir = "/melonDS/"; + QStringList sys_dirs = QStandardPaths::standardLocations(QStandardPaths::DataLocation); + QString found = nullptr; - if (pathlen >= 3) - { - if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || path[2] == '\\')) - relpath = true; - } - - int emudirlen = strlen(EmuDirectory); - char* emudirpath; - if (emudirlen) - { - int len = emudirlen + 1 + pathlen + 1; - emudirpath = new char[len]; - strncpy(&emudirpath[0], EmuDirectory, emudirlen); - emudirpath[emudirlen] = '/'; - strncpy(&emudirpath[emudirlen+1], path, pathlen); - emudirpath[emudirlen+1+pathlen] = '\0'; - } - else - { - emudirpath = new char[pathlen+1]; - strncpy(&emudirpath[0], path, pathlen); - emudirpath[pathlen] = '\0'; - } - - // Locations are application directory, and AppData/melonDS on Windows or XDG_CONFIG_HOME/melonDS on Linux - - FILE* f; - - // First check current working directory - f = OpenFile(path, mode, true); - if (f) { delete[] emudirpath; return f; } - - // then emu directory - f = OpenFile(emudirpath, mode, true); - if (f) { delete[] emudirpath; return f; } + for (int i = 0; i < sys_dirs.size(); i++) + { + QString f = sys_dirs.at(i) + melondir + path; -#ifdef __WIN32__ + if (QFile::exists(f)) + { + found = f; + break; + } + } - // a path relative to AppData wouldn't make much sense - if (!relpath) - { - // Now check AppData - PWSTR appDataPath = NULL; - SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appDataPath); - if (!appDataPath) - { - delete[] emudirpath; - return NULL; - } - - // this will be more than enough - WCHAR fatperm[4]; - fatperm[0] = mode[0]; - fatperm[1] = mode[1]; - fatperm[2] = mode[2]; - fatperm[3] = 0; - - int fnlen = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); - if (fnlen < 1) { delete[] emudirpath; return NULL; } - WCHAR* wfileName = new WCHAR[fnlen]; - int res = MultiByteToWideChar(CP_UTF8, 0, path, -1, wfileName, fnlen); - if (res != fnlen) { delete[] wfileName; delete[] emudirpath; 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; delete[] emudirpath; return NULL; } // oh well - appDataPath = (PWSTR)ptr; - - wcscpy(&appDataPath[pos], appdir); pos += wcslen(appdir); - wcscpy(&appDataPath[pos], wfileName); - - f = _wfopen(appDataPath, L"rb"); - if (f) f = _wfreopen(appDataPath, fatperm, f); - CoTaskMemFree(appDataPath); - delete[] wfileName; - if (f) { delete[] emudirpath; return f; } - } + if (found == nullptr) + return nullptr; -#else - - if (!relpath) - { - // Now check XDG_CONFIG_HOME - // TODO: check for memory leak there - std::string fullpath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation).toStdString() + "/melonDS/" + path; - f = OpenFile(fullpath.c_str(), mode, true); - if (f) { delete[] emudirpath; return f; } - } + FILE* f = OpenFile(found.toUtf8(), "rb", false); + if (f) + return f; + return nullptr; #endif - - if (mode[0] != 'r') - { - f = OpenFile(emudirpath, mode); - if (f) { delete[] emudirpath; return f; } - } - - delete[] emudirpath; - return NULL; } -FILE* OpenDataFile(const char* path) +void* Thread_Create(void (* func)()) { - return OpenLocalFile(path, "rb"); -} - -#endif - - -void* Thread_Create(void (*func)()) -{ - ThreadData* data = new ThreadData; - data->Func = func; - data->ID = SDL_CreateThread(ThreadEntry, "melonDS core thread", data); - return data; + QThread* t = QThread::create(func); + t->start(); + return (void*) t; } void Thread_Free(void* thread) { - delete (ThreadData*)thread; + QThread* t = (QThread*) thread; + t->terminate(); + delete t; } void Thread_Wait(void* thread) { - SDL_WaitThread((SDL_Thread*)((ThreadData*)thread)->ID, NULL); + ((QThread*) thread)->wait(); } void* Semaphore_Create() { - return SDL_CreateSemaphore(0); + return new QSemaphore(); } void Semaphore_Free(void* sema) { - SDL_DestroySemaphore((SDL_sem*)sema); + delete (QSemaphore*) sema; } void Semaphore_Reset(void* sema) { - while (SDL_SemTryWait((SDL_sem*)sema) == 0); + QSemaphore* s = (QSemaphore*) sema; + + s->acquire(s->available()); } void Semaphore_Wait(void* sema) { - SDL_SemWait((SDL_sem*)sema); + ((QSemaphore*) sema)->acquire(); } void Semaphore_Post(void* sema) { - SDL_SemPost((SDL_sem*)sema); + ((QSemaphore*) sema)->release(); } void* GL_GetProcAddress(const char* proc) { - return NULL;//uiGLGetProcAddress(proc); + return (void*) QOpenGLContext::globalShareContext()->getProcAddress(proc); } bool MP_Init() { - int opt_true = 1; - int res; + int opt_true = 1; + int res; #ifdef __WIN32__ - WSADATA wsadata; - if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) - { - return false; - } + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) + { + return false; + } #endif // __WIN32__ - MPSocket = socket(AF_INET, SOCK_DGRAM, 0); + MPSocket = socket(AF_INET, SOCK_DGRAM, 0); if (MPSocket < 0) { return false; } - res = setsockopt(MPSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_true, sizeof(int)); + res = setsockopt(MPSocket, SOL_SOCKET, SO_REUSEADDR, (const char*) &opt_true, sizeof(int)); if (res < 0) { closesocket(MPSocket); @@ -397,8 +227,8 @@ bool MP_Init() sockaddr_t saddr; saddr.sa_family = AF_INET; - *(u32*)&saddr.sa_data[2] = htonl(Config::SocketBindAnyAddr ? INADDR_ANY : INADDR_LOOPBACK); - *(u16*)&saddr.sa_data[0] = htons(7064); + *(u32*) &saddr.sa_data[2] = htonl(Config::SocketBindAnyAddr ? INADDR_ANY : INADDR_LOOPBACK); + *(u16*) &saddr.sa_data[0] = htons(7064); res = bind(MPSocket, &saddr, sizeof(sockaddr_t)); if (res < 0) { @@ -407,7 +237,7 @@ bool MP_Init() return false; } - res = setsockopt(MPSocket, SOL_SOCKET, SO_BROADCAST, (const char*)&opt_true, sizeof(int)); + res = setsockopt(MPSocket, SOL_SOCKET, SO_BROADCAST, (const char*) &opt_true, sizeof(int)); if (res < 0) { closesocket(MPSocket); @@ -416,50 +246,50 @@ bool MP_Init() } MPSendAddr.sa_family = AF_INET; - *(u32*)&MPSendAddr.sa_data[2] = htonl(INADDR_BROADCAST); - *(u16*)&MPSendAddr.sa_data[0] = htons(7064); + *(u32*) &MPSendAddr.sa_data[2] = htonl(INADDR_BROADCAST); + *(u16*) &MPSendAddr.sa_data[0] = htons(7064); return true; } void MP_DeInit() { - if (MPSocket >= 0) - closesocket(MPSocket); + if (MPSocket >= 0) + closesocket(MPSocket); #ifdef __WIN32__ - WSACleanup(); + WSACleanup(); #endif // __WIN32__ } int MP_SendPacket(u8* data, int len) { - if (MPSocket < 0) - return 0; - - if (len > 2048-8) - { - printf("MP_SendPacket: error: packet too long (%d)\n", len); - return 0; - } - - *(u32*)&PacketBuffer[0] = htonl(0x4946494E); // NIFI - PacketBuffer[4] = NIFI_VER; - PacketBuffer[5] = 0; - *(u16*)&PacketBuffer[6] = htons(len); - memcpy(&PacketBuffer[8], data, len); - - int slen = sendto(MPSocket, (const char*)PacketBuffer, len+8, 0, &MPSendAddr, sizeof(sockaddr_t)); - if (slen < 8) return 0; - return slen - 8; + if (MPSocket < 0) + return 0; + + if (len > 2048 - 8) + { + printf("MP_SendPacket: error: packet too long (%d)\n", len); + return 0; + } + + *(u32*) &PacketBuffer[0] = htonl(0x4946494E); // NIFI + PacketBuffer[4] = NIFI_VER; + PacketBuffer[5] = 0; + *(u16*) &PacketBuffer[6] = htons(len); + memcpy(&PacketBuffer[8], data, len); + + int slen = sendto(MPSocket, (const char*) PacketBuffer, len + 8, 0, &MPSendAddr, sizeof(sockaddr_t)); + if (slen < 8) return 0; + return slen - 8; } int MP_RecvPacket(u8* data, bool block) { - if (MPSocket < 0) - return 0; + if (MPSocket < 0) + return 0; - fd_set fd; + fd_set fd; struct timeval tv; FD_ZERO(&fd); @@ -467,84 +297,83 @@ int MP_RecvPacket(u8* data, bool block) tv.tv_sec = 0; tv.tv_usec = block ? 5000 : 0; - if (!select(MPSocket+1, &fd, 0, 0, &tv)) - { - return 0; - } - - sockaddr_t fromAddr; - socklen_t fromLen = sizeof(sockaddr_t); - int rlen = recvfrom(MPSocket, (char*)PacketBuffer, 2048, 0, &fromAddr, &fromLen); - if (rlen < 8+24) - { - return 0; - } - rlen -= 8; - - if (ntohl(*(u32*)&PacketBuffer[0]) != 0x4946494E) - { - return 0; - } - - if (PacketBuffer[4] != NIFI_VER) - { - return 0; - } - - if (ntohs(*(u16*)&PacketBuffer[6]) != rlen) - { - return 0; - } - - memcpy(data, &PacketBuffer[8], rlen); - return rlen; -} + if (!select(MPSocket + 1, &fd, 0, 0, &tv)) + { + return 0; + } + sockaddr_t fromAddr; + socklen_t fromLen = sizeof(sockaddr_t); + int rlen = recvfrom(MPSocket, (char*) PacketBuffer, 2048, 0, &fromAddr, &fromLen); + if (rlen < 8 + 24) + { + return 0; + } + rlen -= 8; + + if (ntohl(*(u32*) &PacketBuffer[0]) != 0x4946494E) + { + return 0; + } + + if (PacketBuffer[4] != NIFI_VER) + { + return 0; + } + + if (ntohs(*(u16*) &PacketBuffer[6]) != rlen) + { + return 0; + } + + memcpy(data, &PacketBuffer[8], rlen); + return rlen; +} bool LAN_Init() { - /*if (Config::DirectLAN) - { - if (!LAN_PCap::Init(true)) - return false; - } - else - { - if (!LAN_Socket::Init()) - return false; - }*/ - - return true; + /*if (Config::DirectLAN) + { + if (!LAN_PCap::Init(true)) + return false; + } + else + { + if (!LAN_Socket::Init()) + return false; + }*/ + + return true; } void LAN_DeInit() { - // checkme. blarg - //if (Config::DirectLAN) - // LAN_PCap::DeInit(); - //else - // LAN_Socket::DeInit(); - /*LAN_PCap::DeInit(); - LAN_Socket::DeInit();*/ + // checkme. blarg + //if (Config::DirectLAN) + // LAN_PCap::DeInit(); + //else + // LAN_Socket::DeInit(); + /*LAN_PCap::DeInit(); + LAN_Socket::DeInit();*/ } int LAN_SendPacket(u8* data, int len) { - /*if (Config::DirectLAN) - return LAN_PCap::SendPacket(data, len); - else - return LAN_Socket::SendPacket(data, len);*/ - return 0; + /*if (Config::DirectLAN) + return LAN_PCap::SendPacket(data, len); + else + return LAN_Socket::SendPacket(data, len);*/ + return 0; } int LAN_RecvPacket(u8* data) { - /*if (Config::DirectLAN) - return LAN_PCap::RecvPacket(data); - else - return LAN_Socket::RecvPacket(data);*/ - return 0; + /*if (Config::DirectLAN) + return LAN_PCap::RecvPacket(data); + else + return LAN_Socket::RecvPacket(data);*/ + return 0; } -- cgit v1.2.3 From beb3b20d5e85f9d58017684dc0abc39a0352f2f4 Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 6 May 2020 03:49:20 +0200 Subject: Fix crash with nonexistent config directory or writable files. --- src/frontend/qt_sdl/Platform.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index ddf48e9..7ce70ab 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -80,10 +80,12 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist) { QFile f(path); - if (!mustexist && !f.exists()) + if (mustexist && !f.exists()) + { return nullptr; + } - f.open(QIODevice::ReadOnly); + f.open(QIODevice::ReadWrite); FILE* file = fdopen(dup(f.handle()), mode); f.close(); @@ -105,7 +107,9 @@ FILE* OpenLocalFile(const char* path, const char* mode) fullpath = QString("./") + path; #else // Check user configuration directory - fullpath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/melonDS/"; + QDir config(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + config.mkdir("melonDS"); + fullpath = config.absolutePath() + "/melonDS/"; fullpath.append(path); #endif } -- cgit v1.2.3 From b746c0b7279d1f5b4bcfd02c115b09d583e9df4f Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 6 May 2020 03:53:05 +0200 Subject: Only initially open files as writable if they actually should be. --- src/frontend/qt_sdl/Platform.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 7ce70ab..125e7ea 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -85,7 +85,9 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist) return nullptr; } - f.open(QIODevice::ReadWrite); + QIODevice::OpenMode qmode = mode[0] == 'w' ? QIODevice::ReadWrite : QIODevice::ReadOnly; + + f.open(qmode); FILE* file = fdopen(dup(f.handle()), mode); f.close(); -- cgit v1.2.3 From 7829070b7ff2bb86e2bc47065a57147757510b76 Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 3 Jun 2020 14:41:07 +0200 Subject: Handle r+ file mode --- src/frontend/qt_sdl/Platform.cpp | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 47befb0..e56e527 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -133,7 +133,14 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist) return nullptr; } - QIODevice::OpenMode qmode = mode[0] == 'w' ? QIODevice::ReadWrite : QIODevice::ReadOnly; + QIODevice::OpenMode qmode; + if (strlen(mode) > 1 && mode[0] == 'r' && mode[1] == '+') { + qmode = QIODevice::OpenModeFlag::ReadWrite; + } else if (mode[0] == 'w') { + qmode = QIODevice::OpenModeFlag::Truncate; + } else { + qmode = QIODevice::OpenModeFlag::ReadOnly; + } f.open(qmode); FILE* file = fdopen(dup(f.handle()), mode); @@ -167,37 +174,6 @@ FILE* OpenLocalFile(const char* path, const char* mode) return OpenFile(fullpath.toUtf8(), mode, mode[0] != 'w'); } -FILE* OpenDataFile(const char* path) -{ -#ifdef PORTABLE - return OpenLocalFile(path); -#else - QString melondir = "/melonDS/"; - QStringList sys_dirs = QStandardPaths::standardLocations(QStandardPaths::DataLocation); - QString found = nullptr; - - for (int i = 0; i < sys_dirs.size(); i++) - { - QString f = sys_dirs.at(i) + melondir + path; - - if (QFile::exists(f)) - { - found = f; - break; - } - } - - if (found == nullptr) - return nullptr; - - FILE* f = OpenFile(found.toUtf8(), "rb", false); - if (f) - return f; - - return nullptr; -#endif -} - void* Thread_Create(void (* func)()) { QThread* t = QThread::create(func); -- cgit v1.2.3 From 21f1856da2cd218b6b6b10634f11f053ac1adfdf Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 3 Jun 2020 14:54:36 +0200 Subject: Fix indentation --- src/frontend/qt_sdl/CMakeLists.txt | 90 ++++++++--------- src/frontend/qt_sdl/Platform.cpp | 202 ++++++++++++++++++------------------- 2 files changed, 146 insertions(+), 146 deletions(-) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 2ebef96..ea7849f 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -1,41 +1,41 @@ project(qt_sdl) SET(SOURCES_QT_SDL - main.cpp - main_shaders.h - EmuSettingsDialog.cpp - InputConfigDialog.cpp - VideoSettingsDialog.cpp - AudioSettingsDialog.cpp - WifiSettingsDialog.cpp - Input.cpp - LAN_PCap.cpp - LAN_Socket.cpp - OSD.cpp - OSD_shaders.h - font.h - Platform.cpp - PlatformConfig.cpp - - ../Util_ROM.cpp - ../Util_Video.cpp - ../Util_Audio.cpp - ../FrontendUtil.h - ../mic_blow.h - - ../../../melon.qrc + main.cpp + main_shaders.h + EmuSettingsDialog.cpp + InputConfigDialog.cpp + VideoSettingsDialog.cpp + AudioSettingsDialog.cpp + WifiSettingsDialog.cpp + Input.cpp + LAN_PCap.cpp + LAN_Socket.cpp + OSD.cpp + OSD_shaders.h + font.h + Platform.cpp + PlatformConfig.cpp + + ../Util_ROM.cpp + ../Util_Video.cpp + ../Util_Audio.cpp + ../FrontendUtil.h + ../mic_blow.h + + ../../../melon.qrc ) if (WIN32) - set(CMAKE_RC_COMPILE_OBJECT " -i -o ") + set(CMAKE_RC_COMPILE_OBJECT " -i -o ") endif() if (BUILD_STATIC AND QT5_STATIC_DIR) - set(QT5_STATIC_BASE ${QT5_STATIC_DIR}/lib/cmake/Qt5) - set(Qt5_DIR ${QT5_STATIC_BASE}) - set(Qt5Core_DIR ${QT5_STATIC_BASE}Core) - set(Qt5Gui_DIR ${QT5_STATIC_BASE}Gui) - set(Qt5Widgets_DIR ${QT5_STATIC_BASE}Widgets) + set(QT5_STATIC_BASE ${QT5_STATIC_DIR}/lib/cmake/Qt5) + set(Qt5_DIR ${QT5_STATIC_BASE}) + set(Qt5Core_DIR ${QT5_STATIC_BASE}Core) + set(Qt5Gui_DIR ${QT5_STATIC_BASE}Gui) + set(Qt5Widgets_DIR ${QT5_STATIC_BASE}Widgets) endif() find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED) @@ -49,9 +49,9 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(SDL2 REQUIRED sdl2) if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL Release)) - add_executable(melonDS WIN32 ${SOURCES_QT_SDL}) + add_executable(melonDS WIN32 ${SOURCES_QT_SDL}) else() - add_executable(melonDS ${SOURCES_QT_SDL}) + add_executable(melonDS ${SOURCES_QT_SDL}) endif() target_link_libraries(melonDS ${CMAKE_THREAD_LIBS_INIT}) @@ -63,28 +63,28 @@ target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..") target_link_libraries(melonDS core) if (BUILD_STATIC) - target_link_libraries(melonDS -static ${SDL2_LIBRARIES}) + target_link_libraries(melonDS -static ${SDL2_LIBRARIES}) else() - target_link_libraries(melonDS ${SDL2_LIBRARIES}) + target_link_libraries(melonDS ${SDL2_LIBRARIES}) endif() if (UNIX) - option(PORTABLE "Make a portable build that looks for its configuration in the current directory" OFF) - target_link_libraries(melonDS dl Qt5::Core Qt5::Gui Qt5::Widgets) + option(PORTABLE "Make a portable build that looks for its configuration in the current directory" OFF) + target_link_libraries(melonDS dl Qt5::Core Qt5::Gui Qt5::Widgets) elseif (WIN32) - option(PORTABLE "Make a portable build that looks for its configuration in the current directory" ON) - target_sources(melonDS PUBLIC "${CMAKE_SOURCE_DIR}/melon.rc") - - target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32) - if (BUILD_STATIC) - target_link_libraries(melonDS imm32 winmm version setupapi -static Qt5::Core Qt5::Gui Qt5::Widgets z zstd) - else() - target_link_libraries(melonDS Qt5::Core Qt5::Gui Qt5::Widgets) - endif() + option(PORTABLE "Make a portable build that looks for its configuration in the current directory" ON) + target_sources(melonDS PUBLIC "${CMAKE_SOURCE_DIR}/melon.rc") + + target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32) + if (BUILD_STATIC) + target_link_libraries(melonDS imm32 winmm version setupapi -static Qt5::Core Qt5::Gui Qt5::Widgets z zstd) + else() + target_link_libraries(melonDS Qt5::Core Qt5::Gui Qt5::Widgets) + endif() endif() if (PORTABLE) - add_definitions(-DPORTABLE) + add_definitions(-DPORTABLE) endif() install(FILES ../../../net.kuribo64.melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index e56e527..fdb7d6d 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -32,7 +32,7 @@ #include #ifdef __WIN32__ -#define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK +#define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK #include //#include // FUCK THAT SHIT #include @@ -104,11 +104,11 @@ void Init(int argc, char** argv) } #else QString confdir; - QDir config(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); - config.mkdir("melonDS"); - confdir = config.absolutePath() + "/melonDS/"; - EmuDirectory = new char[confdir.length() + 1]; - memcpy(EmuDirectory, confdir.toUtf8().data(), confdir.length()); + QDir config(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + config.mkdir("melonDS"); + confdir = config.absolutePath() + "/melonDS/"; + EmuDirectory = new char[confdir.length() + 1]; + memcpy(EmuDirectory, confdir.toUtf8().data(), confdir.length()); #endif } @@ -126,99 +126,99 @@ void StopEmu() FILE* OpenFile(const char* path, const char* mode, bool mustexist) { - QFile f(path); - - if (mustexist && !f.exists()) - { - return nullptr; - } - - QIODevice::OpenMode qmode; - if (strlen(mode) > 1 && mode[0] == 'r' && mode[1] == '+') { - qmode = QIODevice::OpenModeFlag::ReadWrite; - } else if (mode[0] == 'w') { - qmode = QIODevice::OpenModeFlag::Truncate; - } else { - qmode = QIODevice::OpenModeFlag::ReadOnly; - } - - f.open(qmode); - FILE* file = fdopen(dup(f.handle()), mode); - f.close(); - - return file; + QFile f(path); + + if (mustexist && !f.exists()) + { + return nullptr; + } + + QIODevice::OpenMode qmode; + if (strlen(mode) > 1 && mode[0] == 'r' && mode[1] == '+') { + qmode = QIODevice::OpenModeFlag::ReadWrite; + } else if (mode[0] == 'w') { + qmode = QIODevice::OpenModeFlag::Truncate; + } else { + qmode = QIODevice::OpenModeFlag::ReadOnly; + } + + f.open(qmode); + FILE* file = fdopen(dup(f.handle()), mode); + f.close(); + + return file; } FILE* OpenLocalFile(const char* path, const char* mode) { - QString fullpath; - - if (path[0] == '/') - { - // If it's an absolute path, just open that. - fullpath = path; - } - else - { + QString fullpath; + + if (path[0] == '/') + { + // If it's an absolute path, just open that. + fullpath = path; + } + else + { #ifdef PORTABLE - fullpath = QString("./") + path; + fullpath = QString("./") + path; #else - // Check user configuration directory - QDir config(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); - config.mkdir("melonDS"); - fullpath = config.absolutePath() + "/melonDS/"; - fullpath.append(path); + // Check user configuration directory + QDir config(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + config.mkdir("melonDS"); + fullpath = config.absolutePath() + "/melonDS/"; + fullpath.append(path); #endif - } + } - return OpenFile(fullpath.toUtf8(), mode, mode[0] != 'w'); + return OpenFile(fullpath.toUtf8(), mode, mode[0] != 'w'); } void* Thread_Create(void (* func)()) { - QThread* t = QThread::create(func); - t->start(); - return (void*) t; + QThread* t = QThread::create(func); + t->start(); + return (void*) t; } void Thread_Free(void* thread) { - QThread* t = (QThread*) thread; - t->terminate(); - delete t; + QThread* t = (QThread*) thread; + t->terminate(); + delete t; } void Thread_Wait(void* thread) { - ((QThread*) thread)->wait(); + ((QThread*) thread)->wait(); } void* Semaphore_Create() { - return new QSemaphore(); + return new QSemaphore(); } void Semaphore_Free(void* sema) { - delete (QSemaphore*) sema; + delete (QSemaphore*) sema; } void Semaphore_Reset(void* sema) { - QSemaphore* s = (QSemaphore*) sema; + QSemaphore* s = (QSemaphore*) sema; - s->acquire(s->available()); + s->acquire(s->available()); } void Semaphore_Wait(void* sema) { - ((QSemaphore*) sema)->acquire(); + ((QSemaphore*) sema)->acquire(); } void Semaphore_Post(void* sema) { - ((QSemaphore*) sema)->release(); + ((QSemaphore*) sema)->release(); } @@ -242,44 +242,44 @@ bool MP_Init() #endif // __WIN32__ MPSocket = socket(AF_INET, SOCK_DGRAM, 0); - if (MPSocket < 0) - { - return false; - } - - res = setsockopt(MPSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_true, sizeof(int)); - if (res < 0) - { - closesocket(MPSocket); - MPSocket = INVALID_SOCKET; - return false; - } - - sockaddr_t saddr; - saddr.sa_family = AF_INET; - *(u32*)&saddr.sa_data[2] = htonl(Config::SocketBindAnyAddr ? INADDR_ANY : INADDR_LOOPBACK); - *(u16*)&saddr.sa_data[0] = htons(7064); - res = bind(MPSocket, &saddr, sizeof(sockaddr_t)); - if (res < 0) - { - closesocket(MPSocket); - MPSocket = INVALID_SOCKET; - return false; - } - - res = setsockopt(MPSocket, SOL_SOCKET, SO_BROADCAST, (const char*)&opt_true, sizeof(int)); - if (res < 0) - { - closesocket(MPSocket); - MPSocket = INVALID_SOCKET; - return false; - } - - MPSendAddr.sa_family = AF_INET; - *(u32*)&MPSendAddr.sa_data[2] = htonl(INADDR_BROADCAST); - *(u16*)&MPSendAddr.sa_data[0] = htons(7064); - - return true; + if (MPSocket < 0) + { + return false; + } + + res = setsockopt(MPSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_true, sizeof(int)); + if (res < 0) + { + closesocket(MPSocket); + MPSocket = INVALID_SOCKET; + return false; + } + + sockaddr_t saddr; + saddr.sa_family = AF_INET; + *(u32*)&saddr.sa_data[2] = htonl(Config::SocketBindAnyAddr ? INADDR_ANY : INADDR_LOOPBACK); + *(u16*)&saddr.sa_data[0] = htons(7064); + res = bind(MPSocket, &saddr, sizeof(sockaddr_t)); + if (res < 0) + { + closesocket(MPSocket); + MPSocket = INVALID_SOCKET; + return false; + } + + res = setsockopt(MPSocket, SOL_SOCKET, SO_BROADCAST, (const char*)&opt_true, sizeof(int)); + if (res < 0) + { + closesocket(MPSocket); + MPSocket = INVALID_SOCKET; + return false; + } + + MPSendAddr.sa_family = AF_INET; + *(u32*)&MPSendAddr.sa_data[2] = htonl(INADDR_BROADCAST); + *(u16*)&MPSendAddr.sa_data[0] = htons(7064); + + return true; } void MP_DeInit() @@ -320,14 +320,14 @@ int MP_RecvPacket(u8* data, bool block) return 0; fd_set fd; - struct timeval tv; + struct timeval tv; - FD_ZERO(&fd); - FD_SET(MPSocket, &fd); - tv.tv_sec = 0; - tv.tv_usec = block ? 5000 : 0; + FD_ZERO(&fd); + FD_SET(MPSocket, &fd); + tv.tv_sec = 0; + tv.tv_usec = block ? 5000 : 0; - if (!select(MPSocket+1, &fd, 0, 0, &tv)) + if (!select(MPSocket+1, &fd, 0, 0, &tv)) { return 0; } -- cgit v1.2.3 From 23aeb5fb72069634ff3c926f778511bf4f6b1578 Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 3 Jun 2020 16:38:26 +0200 Subject: Fix _dup on windows --- src/frontend/qt_sdl/Platform.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index fdb7d6d..7621931 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -38,6 +38,8 @@ #include #include #include +#include +#define dup _dup #define socket_t SOCKET #define sockaddr_t SOCKADDR #else -- cgit v1.2.3 From f9644abb67035efefcc31a894ccdd5253fd4311c Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 3 Jun 2020 16:41:34 +0200 Subject: Handle open flags more correctly --- src/frontend/qt_sdl/Platform.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 7621931..5199254 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -137,9 +137,11 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist) QIODevice::OpenMode qmode; if (strlen(mode) > 1 && mode[0] == 'r' && mode[1] == '+') { - qmode = QIODevice::OpenModeFlag::ReadWrite; - } else if (mode[0] == 'w') { - qmode = QIODevice::OpenModeFlag::Truncate; + qmode = QIODevice::OpenModeFlag::ReadWrite; + } else if (strlen(mode) > 1 && mode[0] == 'w' && mode[1] == '+') { + qmode = QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::ReadWrite; + } else if (mode[0] == 'w') { + qmode = QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::WriteOnly; } else { qmode = QIODevice::OpenModeFlag::ReadOnly; } -- cgit v1.2.3 From a4b88f0294c1d051dba55887d70835a518fa16b4 Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 3 Jun 2020 16:49:58 +0200 Subject: Fix paths on Windows --- src/frontend/qt_sdl/Platform.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 5199254..671fdee 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -155,9 +155,10 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist) FILE* OpenLocalFile(const char* path, const char* mode) { + QDir dir(path); QString fullpath; - if (path[0] == '/') + if (dir.isAbsolute()) { // If it's an absolute path, just open that. fullpath = path; @@ -165,7 +166,7 @@ FILE* OpenLocalFile(const char* path, const char* mode) else { #ifdef PORTABLE - fullpath = QString("./") + path; + fullpath = path; #else // Check user configuration directory QDir config(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); -- cgit v1.2.3 From 924975f6db7acc419f3ed1758fc5705ea1b13aea Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 3 Jun 2020 17:01:10 +0200 Subject: Use GenericConfigLocation so files will be placed correctly in non-portable Windows builds --- src/frontend/qt_sdl/Platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/frontend/qt_sdl/Platform.cpp') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 671fdee..43f358f 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -169,7 +169,7 @@ FILE* OpenLocalFile(const char* path, const char* mode) fullpath = path; #else // Check user configuration directory - QDir config(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + QDir config(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); config.mkdir("melonDS"); fullpath = config.absolutePath() + "/melonDS/"; fullpath.append(path); -- cgit v1.2.3