mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-26 07:39:56 -06:00
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:

committed by
GitHub

parent
f454eba3c3
commit
ee55677086
257
src/Platform.h
257
src/Platform.h
@ -28,12 +28,64 @@ namespace Platform
|
||||
{
|
||||
|
||||
void Init(int argc, char** argv);
|
||||
|
||||
/**
|
||||
* Frees all resources that were allocated in \c Init
|
||||
* or by any other \c Platform function.
|
||||
*/
|
||||
void DeInit();
|
||||
|
||||
void StopEmu();
|
||||
enum StopReason {
|
||||
/**
|
||||
* The emulator stopped for some unspecified reason.
|
||||
* Not necessarily an error.
|
||||
*/
|
||||
Unknown,
|
||||
|
||||
// instance ID, for local multiplayer
|
||||
/**
|
||||
* The emulator stopped due to an external call to \c NDS::Stop,
|
||||
* most likely because the user stopped the game manually.
|
||||
*/
|
||||
External,
|
||||
|
||||
/**
|
||||
* The emulator stopped because it tried to enter GBA mode,
|
||||
* which melonDS does not support.
|
||||
*/
|
||||
GBAModeNotSupported,
|
||||
|
||||
/**
|
||||
* The emulator stopped because of an error in the emulated console,
|
||||
* not necessarily because of an error in melonDS.
|
||||
*/
|
||||
BadExceptionRegion,
|
||||
|
||||
/**
|
||||
* The emulated console shut itself down normally,
|
||||
* likely because its system settings were adjusted
|
||||
* or its "battery" ran out.
|
||||
*/
|
||||
PowerOff,
|
||||
};
|
||||
|
||||
/**
|
||||
* Signals to the frontend that no more frames should be requested.
|
||||
* Frontends should not call this directly;
|
||||
* use \c NDS::Stop instead.
|
||||
*/
|
||||
void SignalStop(StopReason reason);
|
||||
|
||||
/**
|
||||
* @returns The ID of the running melonDS instance if running in local multiplayer mode,
|
||||
* or 0 if not.
|
||||
*/
|
||||
int InstanceID();
|
||||
|
||||
/**
|
||||
* @returns A suffix that should be appended to all instance-specific paths
|
||||
* if running in local multiplayer mode,
|
||||
* or the empty string if not.
|
||||
*/
|
||||
std::string InstanceFileSuffix();
|
||||
|
||||
// configuration values
|
||||
@ -82,6 +134,8 @@ enum ConfigEntry
|
||||
Firm_Message,
|
||||
Firm_MAC,
|
||||
|
||||
WifiSettingsPath,
|
||||
|
||||
AudioBitDepth,
|
||||
|
||||
DSi_FullBIOSBoot
|
||||
@ -92,43 +146,154 @@ bool GetConfigBool(ConfigEntry entry);
|
||||
std::string GetConfigString(ConfigEntry entry);
|
||||
bool GetConfigArray(ConfigEntry entry, void* data);
|
||||
|
||||
// fopen() wrappers
|
||||
// * OpenFile():
|
||||
// simple fopen() wrapper that supports UTF8.
|
||||
// can be optionally restricted to only opening a file that already exists.
|
||||
// * OpenLocalFile():
|
||||
// opens files local to the emulator (melonDS.ini, BIOS, firmware, ...)
|
||||
// For Windows builds, or portable UNIX builds it checks, by order of priority:
|
||||
// * current working directory
|
||||
// * emulator directory (essentially where the melonDS executable is) if supported
|
||||
// * any platform-specific application data directories
|
||||
// in create mode, if the file doesn't exist, it will be created in the emulator
|
||||
// directory if supported, or in the current directory otherwise
|
||||
// For regular UNIX builds, the user's configuration directory is always used.
|
||||
// * OpenDataFile():
|
||||
// Opens a file that was installed alongside melonDS on UNIX systems in /usr/share, etc.
|
||||
// Looks in the user's data directory first, then the system's.
|
||||
// If on Windows or a portable UNIX build, this simply calls OpenLocalFile().
|
||||
/**
|
||||
* Denotes how a file will be opened and accessed.
|
||||
* Flags may or may not correspond to the operating system's file API.
|
||||
*/
|
||||
enum FileMode : unsigned {
|
||||
None = 0,
|
||||
|
||||
FILE* OpenFile(const std::string& path, const std::string& mode, bool mustexist=false);
|
||||
FILE* OpenLocalFile(const std::string& path, const std::string& mode);
|
||||
FILE* OpenDataFile(const std::string& path);
|
||||
/**
|
||||
* Opens a file for reading.
|
||||
* Either this or \c Write must be set.
|
||||
* Similar to \c "r" in \c fopen.
|
||||
*/
|
||||
Read = 0b00'00'01,
|
||||
|
||||
inline bool FileExists(const std::string& name)
|
||||
/**
|
||||
* Opens a file for writing, creating it if it doesn't exist.
|
||||
* Will truncate existing files unless \c Preserve is set.
|
||||
* Either this or \c Read must be set.
|
||||
* Similar to <tt>fopen</tt>'s \c "w" flag.
|
||||
*/
|
||||
Write = 0b00'00'10,
|
||||
|
||||
/**
|
||||
* Opens an existing file as-is without truncating it.
|
||||
* The file may still be created unless \c NoCreate is set.
|
||||
* @note This flag has no effect if \c Write is not set.
|
||||
*/
|
||||
Preserve = 0b00'01'00,
|
||||
|
||||
/**
|
||||
* Do not create the file if it doesn't exist.
|
||||
* @note This flag has no effect if \c Write is not set.
|
||||
*/
|
||||
NoCreate = 0b00'10'00,
|
||||
|
||||
/**
|
||||
* Opens a file in text mode,
|
||||
* rather than the default binary mode.
|
||||
* Text-mode files may have their line endings converted
|
||||
* to match the operating system,
|
||||
* and may also be line-buffered.
|
||||
*/
|
||||
Text = 0b01'00'00,
|
||||
|
||||
/**
|
||||
* Opens a file for reading and writing.
|
||||
* Equivalent to <tt>Read | Write</tt>.
|
||||
*/
|
||||
ReadWrite = Read | Write,
|
||||
|
||||
/**
|
||||
* Opens a file for reading and writing
|
||||
* without truncating it or creating a new one.
|
||||
* Equivalent to <tt>Read | Write | Preserve | NoCreate</tt>.
|
||||
*/
|
||||
ReadWriteExisting = Read | Write | Preserve | NoCreate,
|
||||
|
||||
/**
|
||||
* Opens a file for reading in text mode.
|
||||
* Equivalent to <tt>Read | Text</tt>.
|
||||
*/
|
||||
ReadText = Read | Text,
|
||||
|
||||
/**
|
||||
* Opens a file for writing in text mode,
|
||||
* creating it if it doesn't exist.
|
||||
* Equivalent to <tt>Write | Text</tt>.
|
||||
*/
|
||||
WriteText = Write | Text,
|
||||
};
|
||||
|
||||
/**
|
||||
* Denotes the origin of a seek operation.
|
||||
* Similar to \c fseek's \c SEEK_* constants.
|
||||
*/
|
||||
enum class FileSeekOrigin
|
||||
{
|
||||
FILE* f = OpenFile(name, "rb");
|
||||
if (!f) return false;
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
Start,
|
||||
Current,
|
||||
End,
|
||||
};
|
||||
|
||||
inline bool LocalFileExists(const std::string& name)
|
||||
{
|
||||
FILE* f = OpenLocalFile(name, "rb");
|
||||
if (!f) return false;
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Opaque handle for a file object.
|
||||
* This can be implemented as a struct defined by the frontend,
|
||||
* or as a simple pointer cast.
|
||||
* The core will never look inside this struct,
|
||||
* but frontends may do so freely.
|
||||
*/
|
||||
struct FileHandle;
|
||||
|
||||
// Simple fopen() wrapper that supports UTF8.
|
||||
// Can be optionally restricted to only opening a file that already exists.
|
||||
FileHandle* OpenFile(const std::string& path, FileMode mode);
|
||||
|
||||
// opens files local to the emulator (melonDS.ini, BIOS, firmware, ...)
|
||||
// For Windows builds, or portable UNIX builds it checks, by order of priority:
|
||||
// * current working directory
|
||||
// * emulator directory (essentially where the melonDS executable is) if supported
|
||||
// * any platform-specific application data directories
|
||||
// in create mode, if the file doesn't exist, it will be created in the emulator
|
||||
// directory if supported, or in the current directory otherwise
|
||||
// For regular UNIX builds, the user's configuration directory is always used.
|
||||
FileHandle* OpenLocalFile(const std::string& path, FileMode mode);
|
||||
|
||||
/// Returns true if the given file exists.
|
||||
bool FileExists(const std::string& name);
|
||||
bool LocalFileExists(const std::string& name);
|
||||
|
||||
/** Close a file opened with \c OpenFile.
|
||||
* @returns \c true if the file was closed successfully, false otherwise.
|
||||
* @post \c file is no longer valid and should not be used.
|
||||
* The underlying object may still be allocated (e.g. if the frontend refcounts files),
|
||||
* but that's an implementation detail.
|
||||
* @see fclose
|
||||
*/
|
||||
bool CloseFile(FileHandle* file);
|
||||
|
||||
/// @returns \c true if there is no more data left to read in this file,
|
||||
/// \c false if there is still data left to read or if there was an error.
|
||||
/// @see feof
|
||||
bool IsEndOfFile(FileHandle* file);
|
||||
|
||||
/// @see fgets
|
||||
bool FileReadLine(char* str, int count, FileHandle* file);
|
||||
|
||||
/// @see fseek
|
||||
bool FileSeek(FileHandle* file, s64 offset, FileSeekOrigin origin);
|
||||
|
||||
/// @see rewind
|
||||
void FileRewind(FileHandle* file);
|
||||
|
||||
/// @see fread
|
||||
u64 FileRead(void* data, u64 size, u64 count, FileHandle* file);
|
||||
|
||||
/// @see fflush
|
||||
bool FileFlush(FileHandle* file);
|
||||
|
||||
/// @see fwrite
|
||||
u64 FileWrite(const void* data, u64 size, u64 count, FileHandle* file);
|
||||
|
||||
/// @see fprintf
|
||||
u64 FileWriteFormatted(FileHandle* file, const char* fmt, ...);
|
||||
|
||||
/// @returns The length of the file in bytes, or 0 if there was an error.
|
||||
/// @note If this function checks the length by using \c fseek and \c ftell
|
||||
/// (or local equivalents), it must leave the stream position as it was found.
|
||||
u64 FileLength(FileHandle* file);
|
||||
|
||||
enum LogLevel
|
||||
{
|
||||
@ -201,6 +366,28 @@ void Camera_Start(int num);
|
||||
void Camera_Stop(int num);
|
||||
void Camera_CaptureFrame(int num, u32* frame, int width, int height, bool yuv);
|
||||
|
||||
struct DynamicLibrary;
|
||||
|
||||
/**
|
||||
* @param lib The name of the library to load.
|
||||
* @return A handle to the loaded library, or \c nullptr if the library could not be loaded.
|
||||
*/
|
||||
DynamicLibrary* DynamicLibrary_Load(const char* lib);
|
||||
|
||||
/**
|
||||
* Releases a loaded library.
|
||||
* Pointers to functions in the library will be invalidated.
|
||||
* @param lib The library to unload.
|
||||
*/
|
||||
void DynamicLibrary_Unload(DynamicLibrary* lib);
|
||||
|
||||
/**
|
||||
* Loads a function from a library.
|
||||
* @param lib The library to load the function from.
|
||||
* @param name The name of the function to load.
|
||||
* @return A pointer to the loaded function, or \c nullptr if the function could not be loaded.
|
||||
*/
|
||||
void* DynamicLibrary_LoadFunction(DynamicLibrary* lib, const char* name);
|
||||
}
|
||||
|
||||
#endif // PLATFORM_H
|
||||
|
Reference in New Issue
Block a user