From 1b9f270b193e965ddff55ed8b464a008a2fafdae Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Mon, 19 Jun 2023 19:37:05 -0700 Subject: [PATCH 1/2] Migrate `IOFile` implementation to `io_file.cpp` Makes the implementation of `IOFile` private, allowing inclusions and defines such as `#define fseeko` and `#include ` to not poison client-code or the global namespace. --- CMakeLists.txt | 2 +- include/io_file.hpp | 135 ++++++++------------------------------------ src/io_file.cpp | 115 +++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 114 deletions(-) create mode 100644 src/io_file.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 34542f84..ff02efb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,7 @@ else() message(FATAL_ERROR "Currently unsupported CPU architecture") endif() -set(SOURCE_FILES src/main.cpp src/emulator.cpp src/core/CPU/cpu_dynarmic.cpp src/core/CPU/dynarmic_cycles.cpp +set(SOURCE_FILES src/main.cpp src/emulator.cpp src/io_file.cpp src/core/CPU/cpu_dynarmic.cpp src/core/CPU/dynarmic_cycles.cpp src/core/memory.cpp ) set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limits.cpp diff --git a/include/io_file.hpp b/include/io_file.hpp index 41e2285c..dc014079 100644 --- a/include/io_file.hpp +++ b/include/io_file.hpp @@ -1,136 +1,45 @@ #pragma once #include -#include #include #include -#include - -#ifdef _MSC_VER -// 64 bit offsets for MSVC -#define fseeko _fseeki64 -#define ftello _ftelli64 -#define fileno _fileno - -#pragma warning(disable : 4996) -#endif - -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS -#endif - -#ifdef WIN32 -#include // For _chsize_s -#else -#include // For ftruncate -#endif class IOFile { - FILE* handle = nullptr; - static inline std::filesystem::path appData = ""; // Directory for holding app data. AppData on Windows + FILE* handle = nullptr; + static inline std::filesystem::path appData = ""; // Directory for holding app data. AppData on Windows -public: - IOFile() {} - IOFile(FILE* handle) : handle(handle) {} - IOFile(const std::filesystem::path& path, const char* permissions = "rb") { - open(path, permissions); - } + public: + IOFile(); + IOFile(FILE* handle); + IOFile(const std::filesystem::path& path, const char* permissions = "rb"); - bool isOpen() { - return handle != nullptr; - } + bool isOpen(); - bool open(const std::filesystem::path& path, const char* permissions = "rb") { - const auto str = path.string(); // For some reason converting paths directly with c_str() doesn't work - return open(str.c_str(), permissions); - } + bool open(const std::filesystem::path& path, const char* permissions = "rb"); - bool open(const char* filename, const char* permissions = "rb") { - handle = std::fopen(filename, permissions); - return isOpen(); - } + bool open(const char* filename, const char* permissions = "rb"); - void close() { - if (isOpen()) { - fclose(handle); - handle = nullptr; - } - } + void close(); - std::pair read(void* data, std::size_t length, std::size_t dataSize) { - if (!isOpen()) { - return { false, std::numeric_limits::max() }; - } + std::pair read(void* data, std::size_t length, std::size_t dataSize); - if (length == 0) return { true, 0 }; - return { true, std::fread(data, dataSize, length, handle) }; - } + std::pair readBytes(void* data, std::size_t count); - auto readBytes(void* data, std::size_t count) { - return read(data, count, sizeof(std::uint8_t)); - } + std::pair write(const void* data, std::size_t length, std::size_t dataSize); - std::pair write(const void* data, std::size_t length, std::size_t dataSize) { - if (!isOpen()) { - return { false, std::numeric_limits::max() }; - } + std::pair writeBytes(const void* data, std::size_t count); - if (length == 0) return { true, 0 }; - return { true, std::fwrite(data, dataSize, length, handle) }; - } + std::optional size(); - auto writeBytes(const void* data, std::size_t count) { - return write(data, count, sizeof(std::uint8_t)); - } + bool seek(std::int64_t offset, int origin = SEEK_SET); - std::optional size() { - if (!isOpen()) return {}; + bool rewind(); - std::uint64_t pos = ftello(handle); - if (fseeko(handle, 0, SEEK_END) != 0) { - return {}; - } + FILE* getHandle(); - std::uint64_t size = ftello(handle); - if ((size != pos) && (fseeko(handle, pos, SEEK_SET) != 0)) { - return {}; - } + static void setAppDataDir(const std::filesystem::path& dir); - return size; - } + // Sets the size of the file to "size" and returns whether it succeeded or not + bool setSize(std::uint64_t size); - bool seek(std::int64_t offset, int origin = SEEK_SET) { - if (!isOpen() || fseeko(handle, offset, origin) != 0) - return false; - - return true; - } - - bool rewind() { - return seek(0, SEEK_SET); - } - - FILE* getHandle() { - return handle; - } - - static void setAppDataDir(const std::filesystem::path& dir) { - if (dir == "") Helpers::panic("Failed to set app data directory"); - appData = dir; - } - - // Sets the size of the file to "size" and returns whether it succeeded or not - bool setSize(std::uint64_t size) { - if (!isOpen()) return false; - bool success; - -#ifdef WIN32 - success = _chsize_s(_fileno(handle), size) == 0; -#else - success = ftruncate(fileno(handle), size) == 0; -#endif - fflush(handle); - return success; - } - - static std::filesystem::path getAppData() { return IOFile::appData; } + static std::filesystem::path getAppData(); }; \ No newline at end of file diff --git a/src/io_file.cpp b/src/io_file.cpp new file mode 100644 index 00000000..ec29de40 --- /dev/null +++ b/src/io_file.cpp @@ -0,0 +1,115 @@ +#include "io_file.hpp" + +#include "helpers.hpp" + +#ifdef _MSC_VER +// 64 bit offsets for MSVC +#define fseeko _fseeki64 +#define ftello _ftelli64 +#define fileno _fileno + +#pragma warning(disable : 4996) +#endif + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#ifdef WIN32 +#include // For _chsize_s +#else +#include // For ftruncate +#endif + +IOFile::IOFile() {} + +IOFile::IOFile(FILE* handle) : handle(handle) {} + +IOFile::IOFile(const std::filesystem::path& path, const char* permissions) { open(path, permissions); } + +bool IOFile::isOpen() { return handle != nullptr; } + +bool IOFile::open(const std::filesystem::path& path, const char* permissions) { + const auto str = path.string(); // For some reason converting paths directly with c_str() doesn't work + return open(str.c_str(), permissions); +} + +bool IOFile::open(const char* filename, const char* permissions) { + handle = std::fopen(filename, permissions); + return isOpen(); +} + +void IOFile::close() { + if (isOpen()) { + fclose(handle); + handle = nullptr; + } +} + +std::pair IOFile::read(void* data, std::size_t length, std::size_t dataSize) { + if (!isOpen()) { + return {false, std::numeric_limits::max()}; + } + + if (length == 0) return {true, 0}; + return {true, std::fread(data, dataSize, length, handle)}; +} + +std::pair IOFile::readBytes(void* data, std::size_t count) { return read(data, count, sizeof(std::uint8_t)); } + +std::pair IOFile::write(const void* data, std::size_t length, std::size_t dataSize) { + if (!isOpen()) { + return {false, std::numeric_limits::max()}; + } + + if (length == 0) return {true, 0}; + return {true, std::fwrite(data, dataSize, length, handle)}; +} + +std::pair IOFile::writeBytes(const void* data, std::size_t count) { return write(data, count, sizeof(std::uint8_t)); } + +std::optional IOFile::size() { + if (!isOpen()) return {}; + + std::uint64_t pos = ftello(handle); + if (fseeko(handle, 0, SEEK_END) != 0) { + return {}; + } + + std::uint64_t size = ftello(handle); + if ((size != pos) && (fseeko(handle, pos, SEEK_SET) != 0)) { + return {}; + } + + return size; +} + +bool IOFile::seek(std::int64_t offset, int origin) { + if (!isOpen() || fseeko(handle, offset, origin) != 0) return false; + + return true; +} + +bool IOFile::rewind() { return seek(0, SEEK_SET); } + +FILE* IOFile::getHandle() { return handle; } + +void IOFile::setAppDataDir(const std::filesystem::path& dir) { + if (dir == "") Helpers::panic("Failed to set app data directory"); + appData = dir; +} + +bool IOFile::setSize(std::uint64_t size) { + if (!isOpen()) return false; + bool success; + +#ifdef WIN32 + success = _chsize_s(_fileno(handle), size) == 0; +#else + success = ftruncate(fileno(handle), size) == 0; +#endif + fflush(handle); + return success; +} + +std::filesystem::path IOFile::getAppData() { return IOFile::appData; } From d028c1cb64b2a6a13e3559aa2fbe14a498e13521 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 28 Jun 2023 03:39:04 +0300 Subject: [PATCH 2/2] Bonk headers --- include/emulator.hpp | 43 +------------------------------------------ include/io_file.hpp | 17 ++++------------- src/emulator.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ src/io_file.cpp | 21 +++++++-------------- src/main.cpp | 2 +- 5 files changed, 56 insertions(+), 70 deletions(-) diff --git a/include/emulator.hpp b/include/emulator.hpp index 59a7a293..10279443 100644 --- a/include/emulator.hpp +++ b/include/emulator.hpp @@ -44,48 +44,7 @@ class Emulator { NCSD loadedNCSD; public: - Emulator() : kernel(cpu, memory, gpu), cpu(memory, kernel), gpu(memory), memory(cpu.getTicksRef()) { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) { - Helpers::panic("Failed to initialize SDL2"); - } - - // Make SDL use consistent positional button mapping - SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0"); - if (SDL_Init(SDL_INIT_GAMECONTROLLER) < 0) { - Helpers::warn("Failed to initialize SDL2 GameController: %s", SDL_GetError()); - } - - // Request OpenGL 4.1 Core (Max available on MacOS) - // MacOS gets mad if we don't explicitly demand a core profile - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL); - - if (window == nullptr) { - Helpers::panic("Window creation failed: %s", SDL_GetError()); - } - - glContext = SDL_GL_CreateContext(window); - if (glContext == nullptr) { - Helpers::panic("OpenGL context creation failed: %s", SDL_GetError()); - } - - if (!gladLoadGL(reinterpret_cast(SDL_GL_GetProcAddress))) { - Helpers::panic("OpenGL init failed: %s", SDL_GetError()); - } - - if (SDL_WasInit(SDL_INIT_GAMECONTROLLER)) { - gameController = SDL_GameControllerOpen(0); - - if (gameController != nullptr) { - SDL_Joystick* stick = SDL_GameControllerGetJoystick(gameController); - gameControllerID = SDL_JoystickInstanceID(stick); - } - } - - reset(); - } + Emulator(); void step(); void render(); diff --git a/include/io_file.hpp b/include/io_file.hpp index dc014079..0e5d7c53 100644 --- a/include/io_file.hpp +++ b/include/io_file.hpp @@ -8,38 +8,29 @@ class IOFile { static inline std::filesystem::path appData = ""; // Directory for holding app data. AppData on Windows public: - IOFile(); - IOFile(FILE* handle); + IOFile() {} + IOFile(FILE* handle) : handle(handle) {} IOFile(const std::filesystem::path& path, const char* permissions = "rb"); - bool isOpen(); - + bool isOpen() { return handle != nullptr; } bool open(const std::filesystem::path& path, const char* permissions = "rb"); - bool open(const char* filename, const char* permissions = "rb"); - void close(); std::pair read(void* data, std::size_t length, std::size_t dataSize); - std::pair readBytes(void* data, std::size_t count); std::pair write(const void* data, std::size_t length, std::size_t dataSize); - std::pair writeBytes(const void* data, std::size_t count); std::optional size(); bool seek(std::int64_t offset, int origin = SEEK_SET); - bool rewind(); - FILE* getHandle(); - static void setAppDataDir(const std::filesystem::path& dir); + static std::filesystem::path getAppData() { return appData; } // Sets the size of the file to "size" and returns whether it succeeded or not bool setSize(std::uint64_t size); - - static std::filesystem::path getAppData(); }; \ No newline at end of file diff --git a/src/emulator.cpp b/src/emulator.cpp index 3a862231..2c8fadc8 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -1,5 +1,48 @@ #include "emulator.hpp" +Emulator::Emulator() : kernel(cpu, memory, gpu), cpu(memory, kernel), gpu(memory), memory(cpu.getTicksRef()) { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) { + Helpers::panic("Failed to initialize SDL2"); + } + + // Make SDL use consistent positional button mapping + SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0"); + if (SDL_Init(SDL_INIT_GAMECONTROLLER) < 0) { + Helpers::warn("Failed to initialize SDL2 GameController: %s", SDL_GetError()); + } + + // Request OpenGL 4.1 Core (Max available on MacOS) + // MacOS gets mad if we don't explicitly demand a core profile + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL); + + if (window == nullptr) { + Helpers::panic("Window creation failed: %s", SDL_GetError()); + } + + glContext = SDL_GL_CreateContext(window); + if (glContext == nullptr) { + Helpers::panic("OpenGL context creation failed: %s", SDL_GetError()); + } + + if (!gladLoadGL(reinterpret_cast(SDL_GL_GetProcAddress))) { + Helpers::panic("OpenGL init failed: %s", SDL_GetError()); + } + + if (SDL_WasInit(SDL_INIT_GAMECONTROLLER)) { + gameController = SDL_GameControllerOpen(0); + + if (gameController != nullptr) { + SDL_Joystick* stick = SDL_GameControllerGetJoystick(gameController); + gameControllerID = SDL_JoystickInstanceID(stick); + } + } + + reset(); +} + void Emulator::reset() { cpu.reset(); gpu.reset(); diff --git a/src/io_file.cpp b/src/io_file.cpp index ec29de40..e3f04dc0 100644 --- a/src/io_file.cpp +++ b/src/io_file.cpp @@ -21,14 +21,8 @@ #include // For ftruncate #endif -IOFile::IOFile() {} - -IOFile::IOFile(FILE* handle) : handle(handle) {} - IOFile::IOFile(const std::filesystem::path& path, const char* permissions) { open(path, permissions); } -bool IOFile::isOpen() { return handle != nullptr; } - bool IOFile::open(const std::filesystem::path& path, const char* permissions) { const auto str = path.string(); // For some reason converting paths directly with c_str() doesn't work return open(str.c_str(), permissions); @@ -55,17 +49,19 @@ std::pair IOFile::read(void* data, std::size_t length, std::s return {true, std::fread(data, dataSize, length, handle)}; } -std::pair IOFile::readBytes(void* data, std::size_t count) { return read(data, count, sizeof(std::uint8_t)); } - std::pair IOFile::write(const void* data, std::size_t length, std::size_t dataSize) { if (!isOpen()) { return {false, std::numeric_limits::max()}; } - if (length == 0) return {true, 0}; - return {true, std::fwrite(data, dataSize, length, handle)}; + if (length == 0) { + return {true, 0}; + } else { + return {true, std::fwrite(data, dataSize, length, handle)}; + } } +std::pair IOFile::readBytes(void* data, std::size_t count) { return read(data, count, sizeof(std::uint8_t)); } std::pair IOFile::writeBytes(const void* data, std::size_t count) { return write(data, count, sizeof(std::uint8_t)); } std::optional IOFile::size() { @@ -91,7 +87,6 @@ bool IOFile::seek(std::int64_t offset, int origin) { } bool IOFile::rewind() { return seek(0, SEEK_SET); } - FILE* IOFile::getHandle() { return handle; } void IOFile::setAppDataDir(const std::filesystem::path& dir) { @@ -110,6 +105,4 @@ bool IOFile::setSize(std::uint64_t size) { #endif fflush(handle); return success; -} - -std::filesystem::path IOFile::getAppData() { return IOFile::appData; } +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d78dc407..9637e83f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,7 +5,7 @@ int main (int argc, char *argv[]) { emu.initGraphicsContext(); - auto romPath = std::filesystem::current_path() / (argc > 1 ? argv[1] : "OoT Demo Encrypted.3ds"); + auto romPath = std::filesystem::current_path() / (argc > 1 ? argv[1] : "teapot.elf"); if (!emu.loadROM(romPath)) { // For some reason just .c_str() doesn't show the proper path Helpers::panic("Failed to load ROM file: %s", romPath.string().c_str());