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
This commit is contained in:
Jesse Talavera-Greenberg
2023-08-18 16:50:57 -04:00
committed by GitHub
parent f454eba3c3
commit ee55677086
36 changed files with 787 additions and 443 deletions

View File

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

View File

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

View File

@ -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))
{

View File

@ -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;
}
}

View File

@ -19,7 +19,7 @@
#ifndef LAN_PCAP_H
#define LAN_PCAP_H
#include "../types.h"
#include "types.h"
namespace LAN_PCap
{

View File

@ -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;
}

View File

@ -19,7 +19,7 @@
#ifndef LAN_SOCKET_H
#define LAN_SOCKET_H
#include "../types.h"
#include "types.h"
namespace LAN_Socket
{

View File

@ -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;
}
FILE* OpenFile(const std::string& path, const std::string& mode, bool mustexist)
constexpr char AccessMode(FileMode mode, bool file_exists)
{
QFile f(QString::fromStdString(path));
if (!(mode & FileMode::Write))
// If we're only opening the file for reading...
return 'r';
if (mustexist && !f.exists())
{
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';
}
constexpr bool IsExtended(FileMode mode)
{
// fopen's "+" flag always opens the file for read/write
return (mode & FileMode::ReadWrite) == FileMode::ReadWrite;
}
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] == '+')
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::ReadWrite;
}
else if (mode.length() > 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;
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);
}
}

View File

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

View File

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

View File

@ -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))
{

View File

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