From 9a040e1cde73f0438fc247c9b5d4e83740458acd Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Sat, 1 Oct 2022 03:28:12 +0300 Subject: [PATCH] Add IOFile and headers for NCSD/NCCH --- CMakeLists.txt | 2 +- include/io_file.hpp | 82 +++++++++++++++++++++++++++++++++++++++++ include/loader/ncch.hpp | 15 ++++++++ include/loader/ncsd.hpp | 18 +++++++++ 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 include/io_file.hpp create mode 100644 include/loader/ncch.hpp create mode 100644 include/loader/ncsd.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e0fb021b..7deabaef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/opengl.hpp inc include/services/gsp_gpu.hpp include/services/gsp_lcd.hpp include/arm_defs.hpp include/PICA/gpu.hpp include/PICA/regs.hpp include/services/ndm.hpp include/PICA/shader.hpp include/PICA/shader_unit.hpp include/PICA/float_types.hpp - include/logger.hpp + include/logger.hpp include/loader/ncch.hpp include/loader/ncsd.hpp include/io_file.hpp ) set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp diff --git a/include/io_file.hpp b/include/io_file.hpp new file mode 100644 index 00000000..3dea5737 --- /dev/null +++ b/include/io_file.hpp @@ -0,0 +1,82 @@ +#pragma once +#include +#include +#include +#include + +#ifdef _MSC_VER +// 64 bit offsets for MSVC +#define fseeko _fseeki64 +#define ftello _ftelli64 +#define fileno _fileno +#endif + +#ifdef _CRT_SECURE_NO_WARNINGS +#undef _CRT_SECURE_NO_WARNINGS +#endif + +class IOFile { + FILE* handle = nullptr; + +public: + bool isOpen() { + return handle != nullptr; + } + + 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 char* filename, const char* permissions = "rb") { + handle = std::fopen(filename, permissions); + return isOpen(); + } + + void close() { + if (isOpen()) { + fclose(handle); + handle = nullptr; + } + } + + std::pair 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) }; + } + + auto readBytes(void* data, std::size_t count) { + return read(data, count, sizeof(std::uint8_t)); + } + + std::uint64_t size() { + if (!isOpen()) return 0; + + std::uint64_t pos = ftello(handle); + if (fseeko(handle, 0, SEEK_END) != 0) { + return 0; + } + + std::uint64_t size = ftello(handle); + if ((size != pos) && (fseeko(handle, pos, SEEK_SET) != 0)) { + return 0; + } + + return size; + } + + bool seek(std::int64_t offset, int origin = 0) { + if (!isOpen() || fseeko(handle, offset, origin) != 0) + return false; + + return true; + } + + bool rewind() { + return seek(0, 0); + } +}; \ No newline at end of file diff --git a/include/loader/ncch.hpp b/include/loader/ncch.hpp new file mode 100644 index 00000000..993c29ce --- /dev/null +++ b/include/loader/ncch.hpp @@ -0,0 +1,15 @@ +#include "helpers.hpp" + +struct NCCH { + bool isNew3DS = false; + bool initialized = false; + bool mountRomFS = false; + bool encrypted = false; + + static constexpr u64 mediaUnit = 0x200; + u64 size = 0; // Size of NCCH converted to bytes + + // Header: 0x200 byte NCCH header + // Returns true on success, false on failure + bool loadFromHeader(u8* header); +}; \ No newline at end of file diff --git a/include/loader/ncsd.hpp b/include/loader/ncsd.hpp new file mode 100644 index 00000000..2a8eddba --- /dev/null +++ b/include/loader/ncsd.hpp @@ -0,0 +1,18 @@ +#include +#include "helpers.hpp" +#include "io_file.hpp" +#include "loader/ncch.hpp" + +struct NCSD { + static constexpr u64 mediaUnit = 0x200; + + struct Partition { + u64 offset = 0; // Offset of partition converted to bytes + u64 length = 0; // Length of partition converted to bytes + NCCH ncch; + }; + + IOFile file; + u64 size = 0; // Image size according to the header converted to bytes + std::array partitions; // NCCH partitions +};