aboutsummaryrefslogtreecommitdiff
path: root/src/frontend
diff options
context:
space:
mode:
authorJesse Talavera-Greenberg <jesse@jesse.tg>2023-08-18 16:50:57 -0400
committerGitHub <noreply@github.com>2023-08-18 22:50:57 +0200
commitee5567708630441d8d3210e81d6e03d028fb7bbd (patch)
treeab92234123b16ec414d6c0da9bb0716c1b798229 /src/frontend
parentf454eba3c3243b095f0e6b9ddde3e68b095c5d8d (diff)
Assorted portability enhancements (#1800)
* Introduce some Platform calls for managing dynamic libraries * Add Platform::WriteFATSectors * Introduce some Platform calls for managing dynamic libraries * Add Platform::WriteFATSectors * Change includes of "../types.h" to "types.h" - Makes it easier to directly include these headers in downstream projects * Change an include of "../Wifi.h" to "Wifi.h" * Allow CommonFuncs.cpp to compile on Android * Tidy up some logging calls - Use Platform::Log in LAN_Socket.cpp - Soften some warnings to Debug logs (since they don't necessarily represent problems) * Add Platform::EnterGBAMode - Gracefully stop the emulator if trying to enter GBA mode * Soften some logs that most players won't care about * Soften some more logs * Introduce Platform wrappers for file operations * Fix pointer spacing * Fix more style nits * Log the errno when ftruncate fails * Fix FileSeek offset argument - With an s32 offset, we couldn't access files larger than 2GB * Revise Platform::StopEmu to address feedback - Remove Platform::EnterGBAMode in favor of adding a reason to Platform::StopEmu - Also rename Platform::StopEmu to Platform::SignalStop - Add an optional argument to NDS::Stop - Use the new argument everywhere that the console stops itself * Rename FileGetString to FileReadLine - It conveys the meaning better * Rename FileSeekOrigin::Set to Start - It conveys the meaning better * Change definition of FileGetString to FileReadLine - Oops, almost forgot it * Rename FlushFile to FileFlush - To remain consistent with the other File functions * Add a FileType usage * Fix line break in FileSeekOrigin * Document Platform::DeInit * Clarify that StopReason::Unknown doesn't always mean an error * Move and document FileType::HostFile * Remove Platform::OpenDataFile - Nothing currently uses it * Refactor Platform::OpenFile and Platform::OpenLocalFile to accept a FileMode enum instead of a string - The enum is converted to fopen flags under the hood - The file type is used to decide whether to add the "b" flag - Some helper functions are exposed for the benefit of consistent behavior among frontends - Equivalent behavior is maintained * Fix a tab that should be spaces * Use Windows' 64-bit implementations of fseek/ftell * Move Platform::IsBinaryFile to Platform.cpp - It could vary by frontend * Remove an unused FileType * Rename an enum constant * Document various Platform items * Use Platform::DynamicLibrary to load libandroid - And clean it up at the end * Fix a typo * Pass the correct filetype to FATStorage - Since it can be used for DSI NAND images or for SD cards * Remove Platform::FileType
Diffstat (limited to 'src/frontend')
-rw-r--r--src/frontend/qt_sdl/Config.cpp27
-rw-r--r--src/frontend/qt_sdl/Config.h1
-rw-r--r--src/frontend/qt_sdl/EmuSettingsDialog.cpp13
-rw-r--r--src/frontend/qt_sdl/LAN_PCap.cpp15
-rw-r--r--src/frontend/qt_sdl/LAN_PCap.h2
-rw-r--r--src/frontend/qt_sdl/LAN_Socket.cpp24
-rw-r--r--src/frontend/qt_sdl/LAN_Socket.h2
-rw-r--r--src/frontend/qt_sdl/Platform.cpp203
-rw-r--r--src/frontend/qt_sdl/ROMManager.cpp127
-rw-r--r--src/frontend/qt_sdl/SaveManager.cpp15
-rw-r--r--src/frontend/qt_sdl/TitleManagerDialog.cpp11
-rw-r--r--src/frontend/qt_sdl/main.cpp14
12 files changed, 297 insertions, 157 deletions
diff --git a/src/frontend/qt_sdl/Config.cpp b/src/frontend/qt_sdl/Config.cpp
index b4d78f7..898e4a1 100644
--- a/src/frontend/qt_sdl/Config.cpp
+++ b/src/frontend/qt_sdl/Config.cpp
@@ -106,6 +106,7 @@ int FirmwareBirthdayDay;
int FirmwareFavouriteColour;
std::string FirmwareMessage;
std::string FirmwareMAC;
+std::string WifiSettingsPath = "wfcsettings.bin"; // Should this be configurable?
int MPAudioMode;
int MPRecvTimeout;
@@ -353,24 +354,24 @@ ConfigEntry ConfigFile[] =
void LoadFile(int inst)
{
- FILE* f;
+ Platform::FileHandle* f;
if (inst > 0)
{
char name[100] = {0};
snprintf(name, 99, kUniqueConfigFile, inst+1);
- f = Platform::OpenLocalFile(name, "r");
+ f = Platform::OpenLocalFile(name, Platform::FileMode::ReadText);
}
else
- f = Platform::OpenLocalFile(kConfigFile, "r");
+ f = Platform::OpenLocalFile(kConfigFile, Platform::FileMode::ReadText);
if (!f) return;
char linebuf[1024];
char entryname[32];
char entryval[1024];
- while (!feof(f))
+ while (!Platform::IsEndOfFile(f))
{
- if (fgets(linebuf, 1024, f) == nullptr)
+ if (!Platform::FileReadLine(linebuf, 1024, f))
break;
int ret = sscanf(linebuf, "%31[A-Za-z_0-9]=%[^\t\r\n]", entryname, entryval);
@@ -396,7 +397,7 @@ void LoadFile(int inst)
}
}
- fclose(f);
+ CloseFile(f);
}
void Load()
@@ -423,15 +424,15 @@ void Save()
{
int inst = Platform::InstanceID();
- FILE* f;
+ Platform::FileHandle* f;
if (inst > 0)
{
char name[100] = {0};
snprintf(name, 99, kUniqueConfigFile, inst+1);
- f = Platform::OpenLocalFile(name, "w");
+ f = Platform::OpenLocalFile(name, Platform::FileMode::WriteText);
}
else
- f = Platform::OpenLocalFile(kConfigFile, "w");
+ f = Platform::OpenLocalFile(kConfigFile, Platform::FileMode::WriteText);
if (!f) return;
@@ -442,13 +443,13 @@ void Save()
switch (entry->Type)
{
- case 0: fprintf(f, "%s=%d\r\n", entry->Name, *(int*)entry->Value); break;
- case 1: fprintf(f, "%s=%d\r\n", entry->Name, *(bool*)entry->Value ? 1:0); break;
- case 2: fprintf(f, "%s=%s\r\n", entry->Name, (*(std::string*)entry->Value).c_str()); break;
+ case 0: Platform::FileWriteFormatted(f, "%s=%d\r\n", entry->Name, *(int*)entry->Value); break;
+ case 1: Platform::FileWriteFormatted(f, "%s=%d\r\n", entry->Name, *(bool*)entry->Value ? 1:0); break;
+ case 2: Platform::FileWriteFormatted(f, "%s=%s\r\n", entry->Name, (*(std::string*)entry->Value).c_str()); break;
}
}
- fclose(f);
+ CloseFile(f);
}
}
diff --git a/src/frontend/qt_sdl/Config.h b/src/frontend/qt_sdl/Config.h
index 1cd0e56..504c068 100644
--- a/src/frontend/qt_sdl/Config.h
+++ b/src/frontend/qt_sdl/Config.h
@@ -152,6 +152,7 @@ extern int FirmwareBirthdayDay;
extern int FirmwareFavouriteColour;
extern std::string FirmwareMessage;
extern std::string FirmwareMAC;
+extern std::string WifiSettingsPath;
extern int MPAudioMode;
extern int MPRecvTimeout;
diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp
index b984e05..0bdbb5c 100644
--- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp
+++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp
@@ -29,6 +29,7 @@
#include "EmuSettingsDialog.h"
#include "ui_EmuSettingsDialog.h"
+using namespace Platform;
EmuSettingsDialog* EmuSettingsDialog::currentDlg = nullptr;
@@ -156,19 +157,19 @@ void EmuSettingsDialog::verifyFirmware()
// bytes 0x0C-0x14 are different.
std::string filename = ui->txtFirmwarePath->text().toStdString();
- FILE* f = Platform::OpenLocalFile(filename, "rb");
+ FileHandle* f = Platform::OpenLocalFile(filename, FileMode::Read);
if (!f) return;
u8 chk1[0x180], chk2[0x180];
- fseek(f, 0, SEEK_SET);
- fread(chk1, 1, 0x180, f);
- fseek(f, -0x380, SEEK_END);
- fread(chk2, 1, 0x180, f);
+ FileRewind(f);
+ FileRead(chk1, 1, 0x180, f);
+ FileSeek(f, -0x380, FileSeekOrigin::End);
+ FileRead(chk2, 1, 0x180, f);
memset(&chk1[0x0C], 0, 8);
memset(&chk2[0x0C], 0, 8);
- fclose(f);
+ CloseFile(f);
if (!memcmp(chk1, chk2, 0x180))
{
diff --git a/src/frontend/qt_sdl/LAN_PCap.cpp b/src/frontend/qt_sdl/LAN_PCap.cpp
index 2a04e70..f5bf436 100644
--- a/src/frontend/qt_sdl/LAN_PCap.cpp
+++ b/src/frontend/qt_sdl/LAN_PCap.cpp
@@ -21,9 +21,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <SDL2/SDL.h>
#include <pcap/pcap.h>
-#include "../Wifi.h"
+#include "Wifi.h"
#include "LAN_PCap.h"
#include "Config.h"
#include "Platform.h"
@@ -88,7 +87,7 @@ const char* PCapLibNames[] =
AdapterData* Adapters = NULL;
int NumAdapters = 0;
-void* PCapLib = NULL;
+Platform::DynamicLibrary* PCapLib = NULL;
pcap_t* PCapAdapter = NULL;
AdapterData* PCapAdapterData;
@@ -98,10 +97,10 @@ volatile int RXNum;
#define LOAD_PCAP_FUNC(sym) \
- ptr_##sym = (type_##sym)SDL_LoadFunction(lib, #sym); \
+ ptr_##sym = (type_##sym)DynamicLibrary_LoadFunction(lib, #sym); \
if (!ptr_##sym) return false;
-bool TryLoadPCap(void* lib)
+bool TryLoadPCap(Platform::DynamicLibrary *lib)
{
LOAD_PCAP_FUNC(pcap_findalldevs)
LOAD_PCAP_FUNC(pcap_freealldevs)
@@ -130,12 +129,12 @@ bool Init(bool open_adapter)
for (int i = 0; PCapLibNames[i]; i++)
{
- void* lib = SDL_LoadObject(PCapLibNames[i]);
+ Platform::DynamicLibrary* lib = Platform::DynamicLibrary_Load(PCapLibNames[i]);
if (!lib) continue;
if (!TryLoadPCap(lib))
{
- SDL_UnloadObject(lib);
+ Platform::DynamicLibrary_Unload(lib);
continue;
}
@@ -355,7 +354,7 @@ void DeInit()
PCapAdapter = NULL;
}
- SDL_UnloadObject(PCapLib);
+ Platform::DynamicLibrary_Unload(PCapLib);
PCapLib = NULL;
}
}
diff --git a/src/frontend/qt_sdl/LAN_PCap.h b/src/frontend/qt_sdl/LAN_PCap.h
index 610c0ae..2f4663f 100644
--- a/src/frontend/qt_sdl/LAN_PCap.h
+++ b/src/frontend/qt_sdl/LAN_PCap.h
@@ -19,7 +19,7 @@
#ifndef LAN_PCAP_H
#define LAN_PCAP_H
-#include "../types.h"
+#include "types.h"
namespace LAN_PCap
{
diff --git a/src/frontend/qt_sdl/LAN_Socket.cpp b/src/frontend/qt_sdl/LAN_Socket.cpp
index 6c00b58..6753bb8 100644
--- a/src/frontend/qt_sdl/LAN_Socket.cpp
+++ b/src/frontend/qt_sdl/LAN_Socket.cpp
@@ -24,6 +24,7 @@
#include "Wifi.h"
#include "LAN_Socket.h"
#include "FIFO.h"
+#include "Platform.h"
#include <slirp/libslirp.h>
@@ -40,6 +41,9 @@
namespace LAN_Socket
{
+using Platform::Log;
+using Platform::LogLevel;
+
const u32 kSubnet = 0x0A400000;
const u32 kServerIP = kSubnet | 0x01;
const u32 kDNSIP = kSubnet | 0x02;
@@ -87,7 +91,7 @@ void RXEnqueue(const void* buf, int len)
if (!RXBuffer.CanFit(totallen >> 2))
{
- printf("slirp: !! NOT ENOUGH SPACE IN RX BUFFER\n");
+ Log(LogLevel::Warn, "slirp: !! NOT ENOUGH SPACE IN RX BUFFER\n");
return;
}
@@ -101,11 +105,11 @@ ssize_t SlirpCbSendPacket(const void* buf, size_t len, void* opaque)
{
if (len > 2048)
{
- printf("slirp: packet too big (%zu)\n", len);
+ Log(LogLevel::Warn, "slirp: packet too big (%zu)\n", len);
return 0;
}
- printf("slirp: response packet of %zu bytes, type %04X\n", len, ntohs(((u16*)buf)[6]));
+ Log(LogLevel::Debug, "slirp: response packet of %zu bytes, type %04X\n", len, ntohs(((u16*)buf)[6]));
RXEnqueue(buf, len);
@@ -114,7 +118,7 @@ ssize_t SlirpCbSendPacket(const void* buf, size_t len, void* opaque)
void SlirpCbGuestError(const char* msg, void* opaque)
{
- printf("SLIRP: error: %s\n", msg);
+ Log(LogLevel::Error, "SLIRP: error: %s\n", msg);
}
int64_t SlirpCbClockGetNS(void* opaque)
@@ -139,7 +143,7 @@ void SlirpCbTimerMod(void* timer, int64_t expire_time, void* opaque)
void SlirpCbRegisterPollFD(int fd, void* opaque)
{
- printf("Slirp: register poll FD %d\n", fd);
+ Log(LogLevel::Debug, "Slirp: register poll FD %d\n", fd);
/*if (FDListSize >= FDListMax)
{
@@ -158,7 +162,7 @@ void SlirpCbRegisterPollFD(int fd, void* opaque)
void SlirpCbUnregisterPollFD(int fd, void* opaque)
{
- printf("Slirp: unregister poll FD %d\n", fd);
+ Log(LogLevel::Debug, "Slirp: unregister poll FD %d\n", fd);
/*if (FDListSize < 1)
{
@@ -178,7 +182,7 @@ void SlirpCbUnregisterPollFD(int fd, void* opaque)
void SlirpCbNotify(void* opaque)
{
- printf("Slirp: notify???\n");
+ Log(LogLevel::Debug, "Slirp: notify???\n");
}
SlirpCb cb =
@@ -283,7 +287,7 @@ void HandleDNSFrame(u8* data, int len)
u16 numauth = ntohs(*(u16*)&dnsbody[8]);
u16 numadd = ntohs(*(u16*)&dnsbody[10]);
- printf("DNS: ID=%04X, flags=%04X, Q=%d, A=%d, auth=%d, add=%d\n",
+ Log(LogLevel::Debug, "DNS: ID=%04X, flags=%04X, Q=%d, A=%d, auth=%d, add=%d\n",
id, flags, numquestions, numanswers, numauth, numadd);
// for now we only take 'simple' DNS requests
@@ -429,7 +433,7 @@ int SendPacket(u8* data, int len)
if (len > 2048)
{
- printf("LAN_SendPacket: error: packet too long (%d)\n", len);
+ Log(LogLevel::Error, "LAN_SendPacket: error: packet too long (%d)\n", len);
return 0;
}
@@ -461,7 +465,7 @@ int SlirpCbAddPoll(int fd, int events, void* opaque)
{
if (PollListSize >= PollListMax)
{
- printf("slirp: POLL LIST FULL\n");
+ Log(LogLevel::Error, "slirp: POLL LIST FULL\n");
return -1;
}
diff --git a/src/frontend/qt_sdl/LAN_Socket.h b/src/frontend/qt_sdl/LAN_Socket.h
index 2073d1b..f2c7ed4 100644
--- a/src/frontend/qt_sdl/LAN_Socket.h
+++ b/src/frontend/qt_sdl/LAN_Socket.h
@@ -19,7 +19,7 @@
#ifndef LAN_SOCKET_H
#define LAN_SOCKET_H
-#include "../types.h"
+#include "types.h"
namespace LAN_Socket
{
diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp
index eef9934..5263377 100644
--- a/src/frontend/qt_sdl/Platform.cpp
+++ b/src/frontend/qt_sdl/Platform.cpp
@@ -29,6 +29,7 @@
#include <QMutex>
#include <QOpenGLContext>
#include <QSharedMemory>
+#include <SDL_loadso.h>
#include "Platform.h"
#include "Config.h"
@@ -37,7 +38,12 @@
#include "LAN_Socket.h"
#include "LAN_PCap.h"
#include "LocalMP.h"
+#include "OSD.h"
+#ifdef __WIN32__
+#define fseek _fseeki64
+#define ftell _ftelli64
+#endif // __WIN32__
std::string EmuDirectory;
@@ -149,10 +155,24 @@ void DeInit()
IPCDeInit();
}
-
-void StopEmu()
+void SignalStop(StopReason reason)
{
emuStop();
+ switch (reason)
+ {
+ case StopReason::GBAModeNotSupported:
+ Log(LogLevel::Error, "!! GBA MODE NOT SUPPORTED\n");
+ OSD::AddMessage(0xFFA0A0, "GBA mode not supported.");
+ break;
+ case StopReason::BadExceptionRegion:
+ OSD::AddMessage(0xFFA0A0, "Internal error.");
+ break;
+ case StopReason::PowerOff:
+ case StopReason::External:
+ OSD::AddMessage(0xFFC040, "Shutdown");
+ default:
+ break;
+ }
}
@@ -246,6 +266,7 @@ std::string GetConfigString(ConfigEntry entry)
case Firm_Username: return Config::FirmwareUsername;
case Firm_Message: return Config::FirmwareMessage;
+ case WifiSettingsPath: return Config::WifiSettingsPath;
}
return "";
@@ -288,45 +309,72 @@ bool GetConfigArray(ConfigEntry entry, void* data)
return false;
}
+constexpr char AccessMode(FileMode mode, bool file_exists)
+{
+ if (!(mode & FileMode::Write))
+ // If we're only opening the file for reading...
+ return 'r';
+
+ if (mode & (FileMode::NoCreate))
+ // If we're not allowed to create a new file...
+ return 'r'; // Open in "r+" mode (IsExtended will add the "+")
+
+ if ((mode & FileMode::Preserve) && file_exists)
+ // If we're not allowed to overwrite a file that already exists...
+ return 'r'; // Open in "r+" mode (IsExtended will add the "+")
+
+ return 'w';
+}
-FILE* OpenFile(const std::string& path, const std::string& mode, bool mustexist)
+constexpr bool IsExtended(FileMode mode)
{
- QFile f(QString::fromStdString(path));
+ // fopen's "+" flag always opens the file for read/write
+ return (mode & FileMode::ReadWrite) == FileMode::ReadWrite;
+}
- if (mustexist && !f.exists())
- {
+static std::string GetModeString(FileMode mode, bool file_exists)
+{
+ std::string modeString;
+
+ modeString += AccessMode(mode, file_exists);
+
+ if (IsExtended(mode))
+ modeString += '+';
+
+ if (!(mode & FileMode::Text))
+ modeString += 'b';
+
+ return modeString;
+}
+
+FileHandle* OpenFile(const std::string& path, FileMode mode)
+{
+ if ((mode & FileMode::ReadWrite) == FileMode::None)
+ { // If we aren't reading or writing, then we can't open the file
+ Log(LogLevel::Error, "Attempted to open \"%s\" in neither read nor write mode (FileMode 0x%x)\n", path.c_str(), mode);
return nullptr;
}
- QIODevice::OpenMode qmode;
- if (mode.length() > 1 && mode[0] == 'r' && mode[1] == '+')
- {
- qmode = QIODevice::OpenModeFlag::ReadWrite;
- }
- else if (mode.length() > 1 && mode[0] == 'w' && mode[1] == '+')
- {
- qmode = QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::ReadWrite;
- }
- else if (mode[0] == 'w')
+ bool file_exists = QFile::exists(QString::fromStdString(path));
+ std::string modeString = GetModeString(mode, file_exists);
+
+ FILE* file = fopen(path.c_str(), modeString.c_str());
+ if (file)
{
- qmode = QIODevice::OpenModeFlag::Truncate | QIODevice::OpenModeFlag::WriteOnly;
+ Log(LogLevel::Debug, "Opened \"%s\" with FileMode 0x%x (effective mode \"%s\")\n", path.c_str(), mode, modeString.c_str());
+ return reinterpret_cast<FileHandle *>(file);
}
else
{
- qmode = QIODevice::OpenModeFlag::ReadOnly;
+ Log(LogLevel::Warn, "Failed to open \"%s\" with FileMode 0x%x (effective mode \"%s\")\n", path.c_str(), mode, modeString.c_str());
+ return nullptr;
}
-
- f.open(qmode);
- FILE* file = fdopen(dup(f.handle()), mode.c_str());
- f.close();
-
- return file;
}
-FILE* OpenLocalFile(const std::string& path, const std::string& mode)
+FileHandle* OpenLocalFile(const std::string& path, FileMode mode)
{
QString qpath = QString::fromStdString(path);
- QDir dir(qpath);
+ QDir dir(qpath);
QString fullpath;
if (dir.isAbsolute())
@@ -347,7 +395,93 @@ FILE* OpenLocalFile(const std::string& path, const std::string& mode)
#endif
}
- return OpenFile(fullpath.toStdString(), mode, mode[0] != 'w');
+ return OpenFile(fullpath.toStdString(), mode);
+}
+
+bool CloseFile(FileHandle* file)
+{
+ return fclose(reinterpret_cast<FILE *>(file)) == 0;
+}
+
+bool IsEndOfFile(FileHandle* file)
+{
+ return feof(reinterpret_cast<FILE *>(file)) != 0;
+}
+
+bool FileReadLine(char* str, int count, FileHandle* file)
+{
+ return fgets(str, count, reinterpret_cast<FILE *>(file)) != nullptr;
+}
+
+bool FileExists(const std::string& name)
+{
+ FileHandle* f = OpenFile(name, FileMode::Read);
+ if (!f) return false;
+ CloseFile(f);
+ return true;
+}
+
+bool LocalFileExists(const std::string& name)
+{
+ FileHandle* f = OpenLocalFile(name, FileMode::Read);
+ if (!f) return false;
+ CloseFile(f);
+ return true;
+}
+
+bool FileSeek(FileHandle* file, s64 offset, FileSeekOrigin origin)
+{
+ int stdorigin;
+ switch (origin)
+ {
+ case FileSeekOrigin::Start: stdorigin = SEEK_SET; break;
+ case FileSeekOrigin::Current: stdorigin = SEEK_CUR; break;
+ case FileSeekOrigin::End: stdorigin = SEEK_END; break;
+ }
+
+ return fseek(reinterpret_cast<FILE *>(file), offset, stdorigin) == 0;
+}
+
+void FileRewind(FileHandle* file)
+{
+ rewind(reinterpret_cast<FILE *>(file));
+}
+
+u64 FileRead(void* data, u64 size, u64 count, FileHandle* file)
+{
+ return fread(data, size, count, reinterpret_cast<FILE *>(file));
+}
+
+bool FileFlush(FileHandle* file)
+{
+ return fflush(reinterpret_cast<FILE *>(file)) == 0;
+}
+
+u64 FileWrite(const void* data, u64 size, u64 count, FileHandle* file)
+{
+ return fwrite(data, size, count, reinterpret_cast<FILE *>(file));
+}
+
+u64 FileWriteFormatted(FileHandle* file, const char* fmt, ...)
+{
+ if (fmt == nullptr)
+ return 0;
+
+ va_list args;
+ va_start(args, fmt);
+ u64 ret = vfprintf(reinterpret_cast<FILE *>(file), fmt, args);
+ va_end(args);
+ return ret;
+}
+
+u64 FileLength(FileHandle* file)
+{
+ FILE* stdfile = reinterpret_cast<FILE *>(file);
+ long pos = ftell(stdfile);
+ fseek(stdfile, 0, SEEK_END);
+ long len = ftell(stdfile);
+ fseek(stdfile, pos, SEEK_SET);
+ return len;
}
void Log(LogLevel level, const char* fmt, ...)
@@ -566,4 +700,19 @@ void Camera_CaptureFrame(int num, u32* frame, int width, int height, bool yuv)
return camManager[num]->captureFrame(frame, width, height, yuv);
}
+DynamicLibrary* DynamicLibrary_Load(const char* lib)
+{
+ return (DynamicLibrary*) SDL_LoadObject(lib);
+}
+
+void DynamicLibrary_Unload(DynamicLibrary* lib)
+{
+ SDL_UnloadObject(lib);
+}
+
+void* DynamicLibrary_LoadFunction(DynamicLibrary* lib, const char* name)
+{
+ return SDL_LoadFunction(lib, name);
+}
+
}
diff --git a/src/frontend/qt_sdl/ROMManager.cpp b/src/frontend/qt_sdl/ROMManager.cpp
index 3b2b72b..a2a5fca 100644
--- a/src/frontend/qt_sdl/ROMManager.cpp
+++ b/src/frontend/qt_sdl/ROMManager.cpp
@@ -36,6 +36,7 @@
#include "SPI.h"
#include "DSi_I2C.h"
+using namespace Platform;
namespace ROMManager
{
@@ -119,137 +120,131 @@ std::string GetAssetPath(bool gba, const std::string& configpath, const std::str
QString VerifyDSBIOS()
{
- FILE* f;
+ FileHandle* f;
long len;
- f = Platform::OpenLocalFile(Config::BIOS9Path, "rb");
+ f = Platform::OpenLocalFile(Config::BIOS9Path, FileMode::Read);
if (!f) return "DS ARM9 BIOS was not found or could not be accessed. Check your emu settings.";
- fseek(f, 0, SEEK_END);
- len = ftell(f);
+ len = FileLength(f);
if (len != 0x1000)
{
- fclose(f);
+ CloseFile(f);
return "DS ARM9 BIOS is not a valid BIOS dump.";
}
- fclose(f);
+ CloseFile(f);
- f = Platform::OpenLocalFile(Config::BIOS7Path, "rb");
+ f = Platform::OpenLocalFile(Config::BIOS7Path, FileMode::Read);
if (!f) return "DS ARM7 BIOS was not found or could not be accessed. Check your emu settings.";
- fseek(f, 0, SEEK_END);
- len = ftell(f);
+ len = FileLength(f);
if (len != 0x4000)
{
- fclose(f);
+ CloseFile(f);
return "DS ARM7 BIOS is not a valid BIOS dump.";
}
- fclose(f);
+ CloseFile(f);
return "";
}
QString VerifyDSiBIOS()
{
- FILE* f;
+ FileHandle* f;
long len;
// TODO: check the first 32 bytes
- f = Platform::OpenLocalFile(Config::DSiBIOS9Path, "rb");
+ f = Platform::OpenLocalFile(Config::DSiBIOS9Path, FileMode::Read);
if (!f) return "DSi ARM9 BIOS was not found or could not be accessed. Check your emu settings.";
- fseek(f, 0, SEEK_END);
- len = ftell(f);
+ len = FileLength(f);
if (len != 0x10000)
{
- fclose(f);
+ CloseFile(f);
return "DSi ARM9 BIOS is not a valid BIOS dump.";
}
- fclose(f);
+ CloseFile(f);
- f = Platform::OpenLocalFile(Config::DSiBIOS7Path, "rb");
+ f = Platform::OpenLocalFile(Config::DSiBIOS7Path, FileMode::Read);
if (!f) return "DSi ARM7 BIOS was not found or could not be accessed. Check your emu settings.";
- fseek(f, 0, SEEK_END);
- len = ftell(f);
+ len = FileLength(f);
if (len != 0x10000)
{
- fclose(f);
+ CloseFile(f);
return "DSi ARM7 BIOS is not a valid BIOS dump.";
}
- fclose(f);
+ CloseFile(f);
return "";
}
QString VerifyDSFirmware()
{
- FILE* f;
+ FileHandle* f;
long len;
- f = Platform::OpenLocalFile(Config::FirmwarePath, "rb");
+ f = Platform::OpenLocalFile(Config::FirmwarePath, FileMode::Read);
if (!f) return "DS firmware was not found or could not be accessed. Check your emu settings.";
- fseek(f, 0, SEEK_END);
- len = ftell(f);
+ len = FileLength(f);
if (len == 0x20000)
{
// 128KB firmware, not bootable
- fclose(f);
+ CloseFile(f);
// TODO report it somehow? detect in core?
return "";
}
else if (len != 0x40000 && len != 0x80000)
{
- fclose(f);
+ CloseFile(f);
return "DS firmware is not a valid firmware dump.";
}
- fclose(f);
+ CloseFile(f);
return "";
}
QString VerifyDSiFirmware()
{
- FILE* f;
+ FileHandle* f;
long len;
- f = Platform::OpenLocalFile(Config::DSiFirmwarePath, "rb");
+ f = Platform::OpenLocalFile(Config::DSiFirmwarePath, FileMode::Read);
if (!f) return "DSi firmware was not found or could not be accessed. Check your emu settings.";
- fseek(f, 0, SEEK_END);
- len = ftell(f);
+ len = FileLength(f);
if (len != 0x20000)
{
// not 128KB
// TODO: check whether those work
- fclose(f);
+ CloseFile(f);
return "DSi firmware is not a valid firmware dump.";
}
- fclose(f);
+ CloseFile(f);
return "";
}
QString VerifyDSiNAND()
{
- FILE* f;
+ FileHandle* f;
long len;
- f = Platform::OpenLocalFile(Config::DSiNANDPath, "r+b");
+ f = Platform::OpenLocalFile(Config::DSiNANDPath, FileMode::ReadWriteExisting);
if (!f) return "DSi NAND was not found or could not be accessed. Check your emu settings.";
// TODO: some basic checks
// check that it has the nocash footer, and all
- fclose(f);
+ CloseFile(f);
return "";
}
@@ -659,29 +654,28 @@ bool LoadROM(QStringList filepath, bool reset)
// regular file
std::string filename = filepath.at(0).toStdString();
- FILE* f = Platform::OpenFile(filename, "rb", true);
+ Platform::FileHandle* f = Platform::OpenFile(filename, FileMode::Read);
if (!f) return false;
- fseek(f, 0, SEEK_END);
- long len = ftell(f);
+ long len = Platform::FileLength(f);
if (len > 0x40000000)
{
- fclose(f);
+ Platform::CloseFile(f);
delete[] filedata;
return false;
}
- fseek(f, 0, SEEK_SET);
+ Platform::FileRewind(f);
filedata = new u8[len];
- size_t nread = fread(filedata, (size_t)len, 1, f);
+ size_t nread = Platform::FileRead(filedata, (size_t)len, 1, f);
if (nread != 1)
{
- fclose(f);
+ Platform::CloseFile(f);
delete[] filedata;
return false;
}
- fclose(f);
+ Platform::CloseFile(f);
filelen = (u32)len;
if (filename.length() > 4 && filename.substr(filename.length() - 4) == ".zst")
@@ -754,17 +748,16 @@ bool LoadROM(QStringList filepath, bool reset)
std::string origsav = savname;
savname += Platform::InstanceFileSuffix();
- FILE* sav = Platform::OpenFile(savname, "rb", true);
- if (!sav) sav = Platform::OpenFile(origsav, "rb", true);
+ FileHandle* sav = Platform::OpenFile(savname, FileMode::Read);
+ if (!sav) sav = Platform::OpenFile(origsav, FileMode::Read);
if (sav)
{
- fseek(sav, 0, SEEK_END);
- savelen = (u32)ftell(sav);
+ savelen = (u32)Platform::FileLength(sav);
- fseek(sav, 0, SEEK_SET);
+ FileRewind(sav);
savedata = new u8[savelen];
- fread(savedata, savelen, 1, sav);
- fclose(sav);
+ FileRead(savedata, savelen, 1, sav);
+ CloseFile(sav);
}
bool res = NDS::LoadCart(filedata, filelen, savedata, savelen);
@@ -841,28 +834,27 @@ bool LoadGBAROM(QStringList filepath)
// regular file
std::string filename = filepath.at(0).toStdString();
- FILE* f = Platform::OpenFile(filename, "rb", true);
+ FileHandle* f = Platform::OpenFile(filename, FileMode::Read);
if (!f) return false;
- fseek(f, 0, SEEK_END);
- long len = ftell(f);
+ long len = FileLength(f);
if (len > 0x40000000)
{
- fclose(f);
+ CloseFile(f);
return false;
}
- fseek(f, 0, SEEK_SET);
+ FileRewind(f);
filedata = new u8[len];
- size_t nread = fread(filedata, (size_t)len, 1, f);
+ size_t nread = FileRead(filedata, (size_t)len, 1, f);
if (nread != 1)
{
- fclose(f);
+ CloseFile(f);
delete[] filedata;
return false;
}
- fclose(f);
+ CloseFile(f);
filelen = (u32)len;
if (filename.length() > 4 && filename.substr(filename.length() - 4) == ".zst")
@@ -926,17 +918,16 @@ bool LoadGBAROM(QStringList filepath)
std::string origsav = savname;
savname += Platform::InstanceFileSuffix();
- FILE* sav = Platform::OpenFile(savname, "rb", true);
- if (!sav) sav = Platform::OpenFile(origsav, "rb", true);
+ FileHandle* sav = Platform::OpenFile(savname, FileMode::Read);
+ if (!sav) sav = Platform::OpenFile(origsav, FileMode::Read);
if (sav)
{
- fseek(sav, 0, SEEK_END);
- savelen = (u32)ftell(sav);
+ savelen = (u32)FileLength(sav);
- fseek(sav, 0, SEEK_SET);
+ FileRewind(sav);
savedata = new u8[savelen];
- fread(savedata, savelen, 1, sav);
- fclose(sav);
+ FileRead(savedata, savelen, 1, sav);
+ CloseFile(sav);
}
bool res = NDS::LoadGBACart(filedata, filelen, savedata, savelen);
diff --git a/src/frontend/qt_sdl/SaveManager.cpp b/src/frontend/qt_sdl/SaveManager.cpp
index 005219b..034b48f 100644
--- a/src/frontend/qt_sdl/SaveManager.cpp
+++ b/src/frontend/qt_sdl/SaveManager.cpp
@@ -22,8 +22,7 @@
#include "SaveManager.h"
#include "Platform.h"
-using Platform::Log;
-using Platform::LogLevel;
+using namespace Platform;
SaveManager::SaveManager(const std::string& path) : QThread()
{
@@ -77,11 +76,11 @@ void SaveManager::SetPath(const std::string& path, bool reload)
if (reload)
{
- FILE* f = Platform::OpenFile(Path, "rb", true);
+ FileHandle* f = Platform::OpenFile(Path, FileMode::Read);
if (f)
{
- fread(Buffer, 1, Length, f);
- fclose(f);
+ FileRead(Buffer, 1, Length, f);
+ CloseFile(f);
}
}
else
@@ -177,12 +176,12 @@ void SaveManager::FlushSecondaryBuffer(u8* dst, u32 dstLength)
}
else
{
- FILE* f = Platform::OpenFile(Path, "wb");
+ FileHandle* f = Platform::OpenFile(Path, FileMode::Write);
if (f)
{
Log(LogLevel::Info, "SaveManager: Written\n");
- fwrite(SecondaryBuffer, SecondaryBufferLength, 1, f);
- fclose(f);
+ FileWrite(SecondaryBuffer, SecondaryBufferLength, 1, f);
+ CloseFile(f);
}
}
PreviousFlushVersion = FlushVersion;
diff --git a/src/frontend/qt_sdl/TitleManagerDialog.cpp b/src/frontend/qt_sdl/TitleManagerDialog.cpp
index 3d52bdd..d5147fc 100644
--- a/src/frontend/qt_sdl/TitleManagerDialog.cpp
+++ b/src/frontend/qt_sdl/TitleManagerDialog.cpp
@@ -30,8 +30,7 @@
#include "ui_TitleManagerDialog.h"
#include "ui_TitleImportDialog.h"
-using Platform::Log;
-using Platform::LogLevel;
+using namespace Platform;
bool TitleManagerDialog::NANDInited = false;
TitleManagerDialog* TitleManagerDialog::currentDlg = nullptr;
@@ -140,14 +139,14 @@ bool TitleManagerDialog::openNAND()
{
NANDInited = false;
- FILE* bios7i = Platform::OpenLocalFile(Config::DSiBIOS7Path, "rb");
+ FileHandle* bios7i = Platform::OpenLocalFile(Config::DSiBIOS7Path, FileMode::Read);
if (!bios7i)
return false;
u8 es_keyY[16];
- fseek(bios7i, 0x8308, SEEK_SET);
- fread(es_keyY, 16, 1, bios7i);
- fclose(bios7i);
+ FileSeek(bios7i, 0x8308, FileSeekOrigin::Start);
+ FileRead(es_keyY, 16, 1, bios7i);
+ CloseFile(bios7i);
if (!DSi_NAND::Init(es_keyY))
{
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index e5e1977..de4c09a 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -2639,7 +2639,7 @@ void MainWindow::onImportSavefile()
return;
}
- FILE* f = Platform::OpenFile(path.toStdString(), "rb", true);
+ Platform::FileHandle* f = Platform::OpenFile(path.toStdString(), Platform::FileMode::Read);
if (!f)
{
QMessageBox::critical(this, "melonDS", "Could not open the given savefile.");
@@ -2661,18 +2661,16 @@ void MainWindow::onImportSavefile()
ROMManager::Reset();
}
- u32 len;
- fseek(f, 0, SEEK_END);
- len = (u32)ftell(f);
+ u32 len = FileLength(f);
u8* data = new u8[len];
- fseek(f, 0, SEEK_SET);
- fread(data, len, 1, f);
+ Platform::FileRewind(f);
+ Platform::FileRead(data, len, 1, f);
NDS::LoadSave(data, len);
delete[] data;
- fclose(f);
+ CloseFile(f);
emuThread->emuUnpause();
}
@@ -3196,8 +3194,6 @@ void emuStop()
RunningSomething = false;
emit emuThread->windowEmuStop();
-
- OSD::AddMessage(0xFFC040, "Shutdown");
}
MelonApplication::MelonApplication(int& argc, char** argv)