diff options
112 files changed, 652 insertions, 510 deletions
diff --git a/externals/boost b/externals/boost -Subproject 728a4d7d1c8b28355544ae829df9c4b5f28373c +Subproject a1afc91d3aaa3da06bdbc13c78613e146665340 diff --git a/src/citra/config.cpp b/src/citra/config.cpp index 1ebe74941..f5b4069c7 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp @@ -63,6 +63,9 @@ void Config::ReadValues() { // Data Storage Settings::values.use_virtual_sd = glfw_config->GetBoolean("Data Storage", "use_virtual_sd", true); + // System Region + Settings::values.region_value = glfw_config->GetInteger("System Region", "region_value", 1); + // Miscellaneous Settings::values.log_filter = glfw_config->Get("Miscellaneous", "log_filter", "*:Info"); } diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h index 3f523857f..be4b289bd 100644 --- a/src/citra/default_ini.h +++ b/src/citra/default_ini.h @@ -33,6 +33,9 @@ frame_skip = ## 0: No frameskip (default), 1 : 2x frameskip, 2 : 4x frameskip, e [Data Storage] use_virtual_sd = +[System Region] +region_value = ## 0 : Japan, 1 : Usa (default), 2 : Europe, 3 : Australia, 4 : China, 5 : Korea, 6 : Taiwan. + [Miscellaneous] log_filter = *:Info ## Examples: *:Debug Kernel.SVC:Trace Service.*:Critical )"; diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp index 9d1adc2fa..8a3ee64a8 100644 --- a/src/citra/emu_window/emu_window_glfw.cpp +++ b/src/citra/emu_window/emu_window_glfw.cpp @@ -36,15 +36,15 @@ const bool EmuWindow_GLFW::IsOpen() { } void EmuWindow_GLFW::OnFramebufferResizeEvent(GLFWwindow* win, int width, int height) { - _dbg_assert_(Frontend, width > 0); - _dbg_assert_(Frontend, height > 0); + ASSERT(width > 0); + ASSERT(height > 0); GetEmuWindow(win)->NotifyFramebufferSizeChanged(std::pair<unsigned,unsigned>(width, height)); } void EmuWindow_GLFW::OnClientAreaResizeEvent(GLFWwindow* win, int width, int height) { - _dbg_assert_(Frontend, width > 0); - _dbg_assert_(Frontend, height > 0); + ASSERT(width > 0); + ASSERT(height > 0); // NOTE: GLFW provides no proper way to set a minimal window size. // Hence, we just ignore the corresponding EmuWindow hint. @@ -149,7 +149,7 @@ void EmuWindow_GLFW::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,u std::pair<int,int> current_size; glfwGetWindowSize(m_render_window, ¤t_size.first, ¤t_size.second); - _dbg_assert_(Frontend, (int)minimal_size.first > 0 && (int)minimal_size.second > 0); + DEBUG_ASSERT((int)minimal_size.first > 0 && (int)minimal_size.second > 0); int new_width = std::max(current_size.first, (int)minimal_size.first); int new_height = std::max(current_size.second, (int)minimal_size.second); diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp index 955c8a4e0..76aeaedd0 100644 --- a/src/citra_qt/config.cpp +++ b/src/citra_qt/config.cpp @@ -51,6 +51,10 @@ void Config::ReadValues() { Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool(); qt_config->endGroup(); + qt_config->beginGroup("System Region"); + Settings::values.region_value = qt_config->value("region_value", 1).toInt(); + qt_config->endGroup(); + qt_config->beginGroup("Miscellaneous"); Settings::values.log_filter = qt_config->value("log_filter", "*:Info").toString().toStdString(); qt_config->endGroup(); @@ -86,6 +90,10 @@ void Config::SaveValues() { qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd); qt_config->endGroup(); + qt_config->beginGroup("System Region"); + qt_config->setValue("region_value", Settings::values.region_value); + qt_config->endGroup(); + qt_config->beginGroup("Miscellaneous"); qt_config->setValue("log_filter", QString::fromStdString(Settings::values.log_filter)); qt_config->endGroup(); diff --git a/src/citra_qt/config/controller_config.cpp b/src/citra_qt/config/controller_config.cpp index 892995bb2..512879f1b 100644 --- a/src/citra_qt/config/controller_config.cpp +++ b/src/citra_qt/config/controller_config.cpp @@ -92,4 +92,4 @@ void GControllerConfigDialog::EnableChanges() } } -*/
\ No newline at end of file +*/ diff --git a/src/citra_qt/debugger/graphics_breakpoints.cpp b/src/citra_qt/debugger/graphics_breakpoints.cpp index 262e2e770..92348be34 100644 --- a/src/citra_qt/debugger/graphics_breakpoints.cpp +++ b/src/citra_qt/debugger/graphics_breakpoints.cpp @@ -47,7 +47,7 @@ QVariant BreakPointModel::data(const QModelIndex& index, int role) const { Pica::DebugContext::Event::VertexLoaded, tr("Vertex loaded") } }; - _dbg_assert_(Debug_GPU, map.size() == static_cast<size_t>(Pica::DebugContext::Event::NumEvents)); + DEBUG_ASSERT(map.size() == static_cast<size_t>(Pica::DebugContext::Event::NumEvents)); return (map.find(event) != map.end()) ? map.at(event) : QString(); } diff --git a/src/citra_qt/debugger/ramview.cpp b/src/citra_qt/debugger/ramview.cpp index 2b199bad1..88570f2cd 100644 --- a/src/citra_qt/debugger/ramview.cpp +++ b/src/citra_qt/debugger/ramview.cpp @@ -14,4 +14,4 @@ void GRamView::OnCPUStepped() { // TODO: QHexEdit doesn't show vertical scroll bars for > 10MB data streams... //setData(QByteArray((const char*)Mem_RAM,sizeof(Mem_RAM)/8)); -}
\ No newline at end of file +} diff --git a/src/citra_qt/util/spinbox.cpp b/src/citra_qt/util/spinbox.cpp index 1e3767c18..2e2076a27 100644 --- a/src/citra_qt/util/spinbox.cpp +++ b/src/citra_qt/util/spinbox.cpp @@ -32,8 +32,7 @@ #include <QLineEdit> #include <QRegExpValidator> -#include "common/log.h" - +#include "common/assert.h" #include "spinbox.h" CSpinBox::CSpinBox(QWidget* parent) : QAbstractSpinBox(parent), min_value(-100), max_value(100), value(0), base(10), num_digits(0) @@ -244,7 +243,7 @@ QValidator::State CSpinBox::validate(QString& input, int& pos) const if (strpos >= input.length() - HasSign() - suffix.length()) return QValidator::Intermediate; - _dbg_assert_(Frontend, base <= 10 || base == 16); + DEBUG_ASSERT(base <= 10 || base == 16); QString regexp; // Demand sign character for negative ranges diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 3c3419bbc..8c87deaa4 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -26,6 +26,7 @@ set(SRCS ) set(HEADERS + assert.h bit_field.h break_points.h chunk_file.h @@ -44,7 +45,6 @@ set(HEADERS hash.h key_map.h linear_disk_cache.h - log.h logging/text_formatter.h logging/filter.h logging/log.h diff --git a/src/common/assert.h b/src/common/assert.h new file mode 100644 index 000000000..3b2232a7e --- /dev/null +++ b/src/common/assert.h @@ -0,0 +1,36 @@ +// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/common_funcs.h" + +// TODO (yuriks) allow synchronous logging so we don't need printf +#define ASSERT(_a_) \ + do if (!(_a_)) {\ + fprintf(stderr, "Assertion Failed!\n\n Line: %d\n File: %s\n Time: %s\n", \ + __LINE__, __FILE__, __TIME__); \ + Crash(); \ + } while (0) + +#define ASSERT_MSG(_a_, ...) \ + do if (!(_a_)) {\ + fprintf(stderr, "Assertion Failed!\n\n Line: %d\n File: %s\n Time: %s\n", \ + __LINE__, __FILE__, __TIME__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + Crash(); \ + } while (0) + +#define UNREACHABLE() ASSERT_MSG(false, "Unreachable code!") + +#ifdef _DEBUG +#define DEBUG_ASSERT(_a_) ASSERT(_a_) +#define DEBUG_ASSERT_MSG(_a_, ...) ASSERT_MSG(_a_, __VA_ARGS__) +#else // not debug +#define DEBUG_ASSERT(_a_) +#define DEBUG_ASSERT_MSG(_a_, _desc_, ...) +#endif + +#define UNIMPLEMENTED() DEBUG_ASSERT_MSG(false, "Unimplemented code!") diff --git a/src/common/break_points.cpp b/src/common/break_points.cpp index 6696935fa..2655d3ce9 100644 --- a/src/common/break_points.cpp +++ b/src/common/break_points.cpp @@ -5,6 +5,7 @@ #include "common/common.h" #include "common/debug_interface.h" #include "common/break_points.h" +#include "common/logging/log.h" #include <sstream> #include <algorithm> diff --git a/src/common/chunk_file.h b/src/common/chunk_file.h index 39a14dc81..dc27da088 100644 --- a/src/common/chunk_file.h +++ b/src/common/chunk_file.h @@ -180,7 +180,7 @@ public: case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything case MODE_VERIFY: for (int i = 0; i < size; i++) { - _dbg_assert_msg_(Common, ((u8*)data)[i] == (*ptr)[i], + DEBUG_ASSERT_MSG(((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); @@ -200,7 +200,7 @@ public: case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything case MODE_VERIFY: for (int i = 0; i < size; i++) { - _dbg_assert_msg_(Common, ((u8*)data)[i] == (*ptr)[i], + DEBUG_ASSERT_MSG(((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); @@ -505,8 +505,7 @@ public: case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; case MODE_MEASURE: break; case MODE_VERIFY: - _dbg_assert_msg_(Common, - !strcmp(x.c_str(), (char*)*ptr), + DEBUG_ASSERT_MSG((x == (char*)*ptr), "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (char*)*ptr, ptr); break; @@ -524,7 +523,7 @@ public: case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; case MODE_MEASURE: break; case MODE_VERIFY: - _dbg_assert_msg_(Common, x == (wchar_t*)*ptr, + DEBUG_ASSERT_MSG((x == (wchar_t*)*ptr), "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; diff --git a/src/common/common.h b/src/common/common.h index 3246c7797..ad2de6f2e 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -25,7 +25,8 @@ private: NonCopyable& operator=(NonCopyable& other); }; -#include "common/log.h" +#include "common/assert.h" +#include "common/logging/log.h" #include "common/common_types.h" #include "common/msg_handler.h" #include "common/common_funcs.h" diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 229eb74c9..44d8ae11f 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h @@ -44,15 +44,14 @@ template<> struct CompileTimeAssert<true> {}; #include <sys/endian.h> #endif -// go to debugger mode - #ifdef GEKKO - #define Crash() - #elif defined _M_GENERIC - #define Crash() { exit(1); } - #else - #define Crash() {asm ("int $3");} - #endif - #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#if defined(__x86_64__) || defined(_M_X64) +#define Crash() __asm__ __volatile__("int $3") +#elif defined(_M_ARM) +#define Crash() __asm__ __volatile__("trap") +#else +#define Crash() exit(1) +#endif + // GCC 4.8 defines all the rotate functions now // Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit #ifndef _rotl @@ -97,10 +96,10 @@ inline u64 _rotr64(u64 x, unsigned int shift){ #define LC_GLOBAL_LOCALE ((locale_t)-1) #define LC_ALL_MASK LC_ALL #define LC_COLLATE_MASK LC_COLLATE - #define LC_CTYPE_MASK LC_CTYPE - #define LC_MONETARY_MASK LC_MONETARY + #define LC_CTYPE_MASK LC_CTYPE + #define LC_MONETARY_MASK LC_MONETARY #define LC_NUMERIC_MASK LC_NUMERIC - #define LC_TIME_MASK LC_TIME + #define LC_TIME_MASK LC_TIME inline locale_t uselocale(locale_t new_locale) { @@ -136,14 +135,10 @@ inline u64 _rotr64(u64 x, unsigned int shift){ #define fstat64 _fstat64 #define fileno _fileno - #if _M_IX86 - #define Crash() {__asm int 3} - #else -extern "C" { - __declspec(dllimport) void __stdcall DebugBreak(void); -} - #define Crash() {DebugBreak();} - #endif // M_IX86 + extern "C" { + __declspec(dllimport) void __stdcall DebugBreak(void); + } + #define Crash() {DebugBreak();} #endif // _MSC_VER ndef // Dolphin's min and max functions diff --git a/src/common/common_types.h b/src/common/common_types.h index 94e1406b1..1b453e7f5 100644 --- a/src/common/common_types.h +++ b/src/common/common_types.h @@ -28,6 +28,12 @@ #include <cstdint> #include <cstdlib> +#ifdef _MSC_VER +#ifndef __func__ +#define __func__ __FUNCTION__ +#endif +#endif + typedef std::uint8_t u8; ///< 8-bit unsigned byte typedef std::uint16_t u16; ///< 16-bit unsigned short typedef std::uint32_t u32; ///< 32-bit unsigned word diff --git a/src/common/concurrent_ring_buffer.h b/src/common/concurrent_ring_buffer.h index 311bb01f4..fc18e6c86 100644 --- a/src/common/concurrent_ring_buffer.h +++ b/src/common/concurrent_ring_buffer.h @@ -11,7 +11,6 @@ #include <thread> #include "common/common.h" // for NonCopyable -#include "common/log.h" // for _dbg_assert_ namespace Common { @@ -93,7 +92,7 @@ public: return QUEUE_CLOSED; } } - _dbg_assert_(Common, CanRead()); + DEBUG_ASSERT(CanRead()); return PopInternal(dest, dest_len); } @@ -119,7 +118,7 @@ private: size_t PopInternal(T* dest, size_t dest_len) { size_t output_count = 0; while (output_count < dest_len && CanRead()) { - _dbg_assert_(Common, CanRead()); + DEBUG_ASSERT(CanRead()); T* item = &Data()[reader_index]; T out_val = std::move(*item); diff --git a/src/common/log.h b/src/common/log.h deleted file mode 100644 index b397cf14d..000000000 --- a/src/common/log.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "common/common_funcs.h" -#include "common/msg_handler.h" -#include "common/logging/log.h" - -#ifdef _MSC_VER -#ifndef __func__ -#define __func__ __FUNCTION__ -#endif -#endif - -#ifdef _DEBUG -#define _dbg_assert_(_t_, _a_) \ - if (!(_a_)) {\ - LOG_CRITICAL(_t_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n\nIgnore and continue?", \ - __LINE__, __FILE__, __TIME__); \ - if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ - } -#define _dbg_assert_msg_(_t_, _a_, ...)\ - if (!(_a_)) {\ - LOG_CRITICAL(_t_, __VA_ARGS__); \ - if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ - } -#define _dbg_update_() Host_UpdateLogDisplay(); - -#else // not debug -#define _dbg_update_() ; - -#ifndef _dbg_assert_ -#define _dbg_assert_(_t_, _a_) {} -#define _dbg_assert_msg_(_t_, _a_, _desc_, ...) {} -#endif // dbg_assert -#endif - -#define _assert_(_a_) _dbg_assert_(MASTER_LOG, _a_) - -#ifndef GEKKO -#ifdef _MSC_VER -#define _assert_msg_(_t_, _a_, _fmt_, ...) \ - if (!(_a_)) {\ - if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ - } -#else // not msvc -#define _assert_msg_(_t_, _a_, _fmt_, ...) \ - if (!(_a_)) {\ - if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ - } -#endif // _WIN32 -#else // GEKKO -#define _assert_msg_(_t_, _a_, _fmt_, ...) -#endif
\ No newline at end of file diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 83ebb42d9..459b44135 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -4,7 +4,7 @@ #include <algorithm> -#include "common/log.h" // For _dbg_assert_ +#include "common/assert.h" #include "common/logging/backend.h" #include "common/logging/log.h" @@ -67,7 +67,7 @@ Logger::Logger() { #undef SUB // Ensures that ALL_LOG_CLASSES isn't missing any entries. - _dbg_assert_(Log, all_classes.size() == (size_t)Class::Count); + DEBUG_ASSERT(all_classes.size() == (size_t)Class::Count); } // GetClassName is a macro defined by Windows.h, grrr... diff --git a/src/common/logging/log.h b/src/common/logging/log.h index 897ef36b8..6c5ca3968 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -57,6 +57,7 @@ enum class Class : ClassType { Service_GSP, ///< The GSP (GPU control) service Service_AC, ///< The AC (WiFi status) service Service_PTM, ///< The PTM (Power status & misc.) service + Service_LDR, ///< The LDR (3ds dll loader) service Service_CFG, ///< The CFG (Configuration) service Service_DSP, ///< The DSP (DSP control) service Service_HID, ///< The HID (User input) service diff --git a/src/common/msg_handler.h b/src/common/msg_handler.h index 5a483ddb4..421f93e23 100644 --- a/src/common/msg_handler.h +++ b/src/common/msg_handler.h @@ -29,7 +29,6 @@ extern bool MsgAlert(bool yes_no, int Style, const char* format, ...) ; void SetEnableAlert(bool enable); -#ifndef GEKKO #ifdef _MSC_VER #define SuccessAlert(format, ...) MsgAlert(false, INFORMATION, format, __VA_ARGS__) #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) @@ -55,16 +54,3 @@ void SetEnableAlert(bool enable); #define AskYesNoT(format, ...) MsgAlert(true, QUESTION, format, ##__VA_ARGS__) #define CriticalAlertT(format, ...) MsgAlert(false, CRITICAL, format, ##__VA_ARGS__) #endif -#else -// GEKKO - #define SuccessAlert(format, ...) ; - #define PanicAlert(format, ...) ; - #define PanicYesNo(format, ...) ; - #define AskYesNo(format, ...) ; - #define CriticalAlert(format, ...) ; - #define SuccessAlertT(format, ...) ; - #define PanicAlertT(format, ...) ; - #define PanicYesNoT(format, ...) ; - #define AskYesNoT(format, ...) ; - #define CriticalAlertT(format, ...) ; -#endif diff --git a/src/common/scope_exit.h b/src/common/scope_exit.h index 77dcbaa22..08f09a8c8 100644 --- a/src/common/scope_exit.h +++ b/src/common/scope_exit.h @@ -5,6 +5,7 @@ #pragma once #include "common/common_funcs.h" +#include <utility> namespace detail { template <typename Func> diff --git a/src/common/symbols.cpp b/src/common/symbols.cpp index 9e4dccfb3..f23e51c9d 100644 --- a/src/common/symbols.cpp +++ b/src/common/symbols.cpp @@ -54,4 +54,4 @@ namespace Symbols { g_symbols.clear(); } -}
\ No newline at end of file +} diff --git a/src/common/utf8.cpp b/src/common/utf8.cpp index 66a2f6339..56609634c 100644 --- a/src/common/utf8.cpp +++ b/src/common/utf8.cpp @@ -456,4 +456,4 @@ std::wstring ConvertUTF8ToWString(const std::string &source) { return str; } -#endif
\ No newline at end of file +#endif diff --git a/src/common/utf8.h b/src/common/utf8.h index 6479ec5ad..a6e84913b 100644 --- a/src/common/utf8.h +++ b/src/common/utf8.h @@ -64,4 +64,4 @@ std::string ConvertWStringToUTF8(const wchar_t *wstr); void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source); std::wstring ConvertUTF8ToWString(const std::string &source); -#endif
\ No newline at end of file +#endif diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index 45c720e16..f7c7451e9 100644 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ b/src/core/arm/disassembler/arm_disasm.cpp @@ -963,4 +963,4 @@ Opcode ARM_Disasm::DecodeALU(uint32_t insn) { } // Unreachable return OP_INVALID; -}
\ No newline at end of file +} diff --git a/src/core/arm/dyncom/arm_dyncom_run.cpp b/src/core/arm/dyncom/arm_dyncom_run.cpp index d457d0ac5..15677da27 100644 --- a/src/core/arm/dyncom/arm_dyncom_run.cpp +++ b/src/core/arm/dyncom/arm_dyncom_run.cpp @@ -4,6 +4,7 @@ #include <assert.h> +#include "common/logging/log.h" #include "core/arm/skyeye_common/armdefs.h" void switch_mode(arm_core_t *core, uint32_t mode) { diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp index de70ca8ae..d5a698365 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp +++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp @@ -48,7 +48,7 @@ tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t case 3: // ADD/SUB { - ARMword subset[4] = { + static const ARMword subset[4] = { 0xE0900000, // ADDS Rd,Rs,Rn 0xE0500000, // SUBS Rd,Rs,Rn 0xE2900000, // ADDS Rd,Rs,#imm3 @@ -67,7 +67,7 @@ tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t case 6: // ADD case 7: // SUB { - ARMword subset[4] = { + static const ARMword subset[4] = { 0xE3B00000, // MOVS Rd,#imm8 0xE3500000, // CMP Rd,#imm8 0xE2900000, // ADDS Rd,Rd,#imm8 @@ -95,7 +95,7 @@ tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t t_mul }; - struct { + static const struct { ARMword opcode; otype type; } subset[16] = { @@ -205,7 +205,7 @@ tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t // merged into a single subset, saving on the following boolean: if ((tinstr & (1 << 9)) == 0) { - ARMword subset[4] = { + static const ARMword subset[4] = { 0xE7800000, // STR Rd,[Rb,Ro] 0xE7C00000, // STRB Rd,[Rb,Ro] 0xE7900000, // LDR Rd,[Rb,Ro] @@ -218,7 +218,7 @@ tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t |((tinstr & 0x01C0) >> 6); // Ro } else { - ARMword subset[4] = { + static const ARMword subset[4] = { 0xE18000B0, // STRH Rd,[Rb,Ro] 0xE19000D0, // LDRSB Rd,[Rb,Ro] 0xE19000B0, // LDRH Rd,[Rb,Ro] @@ -236,7 +236,7 @@ tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t case 14: // STRB Rd,[Rb,#imm5] case 15: // LDRB Rd,[Rb,#imm5] { - ARMword subset[4] = { + static const ARMword subset[4] = { 0xE5800000, // STR Rd,[Rb,#imm5] 0xE5900000, // LDR Rd,[Rb,#imm5] 0xE5C00000, // STRB Rd,[Rb,#imm5] @@ -300,7 +300,7 @@ tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t } else if ((tinstr & 0x0F00) == 0x0e00) *ainstr = 0xEF000000 | SWI_Breakpoint; else { - ARMword subset[4] = { + static const ARMword subset[4] = { 0xE92D0000, // STMDB sp!,{rlist} 0xE92D4000, // STMDB sp!,{rlist,lr} 0xE8BD0000, // LDMIA sp!,{rlist} diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 3aebd7e9d..d96d3fe16 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -7,8 +7,8 @@ #include <mutex> #include <vector> +#include "common/assert.h" #include "common/chunk_file.h" -#include "common/log.h" #include "core/arm/arm_interface.h" #include "core/core.h" diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 390178f67..43a106549 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -181,20 +181,6 @@ public: } /** - * Tries to open the archive of this type with the specified path - * @param path Path to the archive - * @return ResultCode of the operation - */ - virtual ResultCode Open(const Path& path) = 0; - - /** - * Deletes the archive contents and then re-creates the base folder - * @param path Path to the archive - * @return ResultCode of the operation, 0 on success - */ - virtual ResultCode Format(const Path& path) const = 0; - - /** * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) */ virtual std::string GetName() const = 0; @@ -260,4 +246,29 @@ public: virtual std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const = 0; }; +class ArchiveFactory : NonCopyable { +public: + virtual ~ArchiveFactory() { + } + + /** + * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) + */ + virtual std::string GetName() const = 0; + + /** + * Tries to open the archive of this type with the specified path + * @param path Path to the archive + * @return An ArchiveBackend corresponding operating specified archive path. + */ + virtual ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) = 0; + + /** + * Deletes the archive contents and then re-creates the base folder + * @param path Path to the archive + * @return ResultCode of the operation, 0 on success + */ + virtual ResultCode Format(const Path& path) = 0; +}; + } // namespace FileSys diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 33e4e76f8..0363c9771 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -6,6 +6,7 @@ #include "common/common_types.h" #include "common/file_util.h" +#include "common/make_unique.h" #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/disk_archive.h" @@ -33,12 +34,12 @@ std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) SYSTEM_ID.c_str(), SDCARD_ID.c_str()); } -Archive_ExtSaveData::Archive_ExtSaveData(const std::string& mount_location, bool shared) - : DiskArchive(GetExtDataContainerPath(mount_location, shared)) { +ArchiveFactory_ExtSaveData::ArchiveFactory_ExtSaveData(const std::string& mount_location, bool shared) + : mount_point(GetExtDataContainerPath(mount_location, shared)) { LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str()); } -bool Archive_ExtSaveData::Initialize() { +bool ArchiveFactory_ExtSaveData::Initialize() { if (!FileUtil::CreateFullPath(mount_point)) { LOG_ERROR(Service_FS, "Unable to create ExtSaveData base path."); return false; @@ -47,18 +48,18 @@ bool Archive_ExtSaveData::Initialize() { return true; } -ResultCode Archive_ExtSaveData::Open(const Path& path) { +ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path) { std::string fullpath = GetExtSaveDataPath(mount_point, path); if (!FileUtil::Exists(fullpath)) { // TODO(Subv): Check error code, this one is probably wrong return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, ErrorSummary::InvalidState, ErrorLevel::Status); } - concrete_mount_point = fullpath; - return RESULT_SUCCESS; + auto archive = Common::make_unique<DiskArchive>(fullpath); + return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode Archive_ExtSaveData::Format(const Path& path) const { +ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path) { std::string fullpath = GetExtSaveDataPath(mount_point, path); FileUtil::CreateFullPath(fullpath); return RESULT_SUCCESS; diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index 802a11b5f..83c6b0291 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -15,9 +15,9 @@ namespace FileSys { /// File system interface to the ExtSaveData archive -class Archive_ExtSaveData final : public DiskArchive { +class ArchiveFactory_ExtSaveData final : public ArchiveFactory { public: - Archive_ExtSaveData(const std::string& mount_point, bool shared); + ArchiveFactory_ExtSaveData(const std::string& mount_point, bool shared); /** * Initialize the archive. @@ -25,21 +25,20 @@ public: */ bool Initialize(); - ResultCode Open(const Path& path) override; - ResultCode Format(const Path& path) const override; std::string GetName() const override { return "ExtSaveData"; } - const std::string& GetMountPoint() const override { - return concrete_mount_point; - } + ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; + ResultCode Format(const Path& path) override; -protected: + const std::string& GetMountPoint() const { return mount_point; } + +private: /** - * This holds the full directory path for this archive, it is only set after a successful call to Open, - * this is formed as <base extsavedatapath>/<type>/<high>/<low>. + * This holds the full directory path for this archive, it is only set after a successful call + * to Open, this is formed as <base extsavedatapath>/<type>/<high>/<low>. * See GetExtSaveDataPath for the code that extracts this data from an archive path. */ - std::string concrete_mount_point; + std::string mount_point; }; /** diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index a30f73d0e..bf54a3866 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -15,11 +15,24 @@ namespace FileSys { -Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) { +ArchiveFactory_RomFS::ArchiveFactory_RomFS(const Loader::AppLoader& app_loader) + : romfs_data(std::make_shared<std::vector<u8>>()) { // Load the RomFS from the app - if (Loader::ResultStatus::Success != app_loader.ReadRomFS(raw_data)) { + if (Loader::ResultStatus::Success != app_loader.ReadRomFS(*romfs_data)) { LOG_ERROR(Service_FS, "Unable to read RomFS!"); } } +ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_RomFS::Open(const Path& path) { + auto archive = Common::make_unique<IVFCArchive>(romfs_data); + return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); +} + +ResultCode ArchiveFactory_RomFS::Format(const Path& path) { + LOG_ERROR(Service_FS, "Attempted to format a RomFS archive."); + // TODO: Verify error code + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, + ErrorSummary::NotSupported, ErrorLevel::Permanent); +} + } // namespace FileSys diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 5cb75e04d..409bc670a 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -4,6 +4,7 @@ #pragma once +#include <memory> #include <vector> #include "common/common_types.h" @@ -17,12 +18,16 @@ namespace FileSys { /// File system interface to the RomFS archive -class Archive_RomFS final : public IVFCArchive { +class ArchiveFactory_RomFS final : public ArchiveFactory { public: - Archive_RomFS(const Loader::AppLoader& app_loader); + ArchiveFactory_RomFS(const Loader::AppLoader& app_loader); std::string GetName() const override { return "RomFS"; } - ResultCode Open(const Path& path) override { return RESULT_SUCCESS; } + ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; + ResultCode Format(const Path& path) override; + +private: + std::shared_ptr<std::vector<u8>> romfs_data; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index 3baee5294..8496e06f3 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -6,6 +6,7 @@ #include "common/common_types.h" #include "common/file_util.h" +#include "common/make_unique.h" #include "core/file_sys/archive_savedata.h" #include "core/file_sys/disk_archive.h" @@ -28,26 +29,28 @@ static std::string GetSaveDataPath(const std::string& mount_location, u64 progra return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, low); } -Archive_SaveData::Archive_SaveData(const std::string& sdmc_directory) - : DiskArchive(GetSaveDataContainerPath(sdmc_directory)) { +ArchiveFactory_SaveData::ArchiveFactory_SaveData(const std::string& sdmc_directory) + : mount_point(GetSaveDataContainerPath(sdmc_directory)) { LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str()); } -ResultCode Archive_SaveData::Open(const Path& path) { - if (concrete_mount_point.empty()) - concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id); +ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) { + std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id); if (!FileUtil::Exists(concrete_mount_point)) { // When a SaveData archive is created for the first time, it is not yet formatted - // and the save file/directory structure expected by the game has not yet been initialized. - // Returning the NotFormatted error code will signal the game to provision the SaveData archive - // with the files and folders that it expects. + // and the save file/directory structure expected by the game has not yet been initialized. + // Returning the NotFormatted error code will signal the game to provision the SaveData archive + // with the files and folders that it expects. return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, ErrorSummary::InvalidState, ErrorLevel::Status); } - return RESULT_SUCCESS; + + auto archive = Common::make_unique<DiskArchive>(std::move(concrete_mount_point)); + return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode Archive_SaveData::Format(const Path& path) const { +ResultCode ArchiveFactory_SaveData::Format(const Path& path) { + std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_program_id); FileUtil::DeleteDirRecursively(concrete_mount_point); FileUtil::CreateFullPath(concrete_mount_point); return RESULT_SUCCESS; diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 07c7f7eff..db17afc92 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -15,22 +15,17 @@ namespace FileSys { /// File system interface to the SaveData archive -class Archive_SaveData final : public DiskArchive { +class ArchiveFactory_SaveData final : public ArchiveFactory { public: - Archive_SaveData(const std::string& mount_point); + ArchiveFactory_SaveData(const std::string& mount_point); std::string GetName() const override { return "SaveData"; } - ResultCode Open(const Path& path) override; + ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; + ResultCode Format(const Path& path) override; - ResultCode Format(const Path& path) const override; - - const std::string& GetMountPoint() const override { - return concrete_mount_point; - } - -protected: - std::string concrete_mount_point; +private: + std::string mount_point; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp index a7a507536..47d8a9d25 100644 --- a/src/core/file_sys/archive_savedatacheck.cpp +++ b/src/core/file_sys/archive_savedatacheck.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/file_util.h" +#include "common/make_unique.h" #include "core/file_sys/archive_savedatacheck.h" #include "core/hle/service/fs/archive.h" @@ -21,32 +22,33 @@ static std::string GetSaveDataCheckPath(const std::string& mount_point, u32 high mount_point.c_str(), high, low); } -Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& nand_directory) : +ArchiveFactory_SaveDataCheck::ArchiveFactory_SaveDataCheck(const std::string& nand_directory) : mount_point(GetSaveDataCheckContainerPath(nand_directory)) { } -ResultCode Archive_SaveDataCheck::Open(const Path& path) { - // TODO(Subv): We should not be overwriting raw_data everytime this function is called, - // but until we use factory classes to create the archives at runtime instead of creating them beforehand - // and allow multiple archives of the same type to be open at the same time without clobbering each other, - // we won't be able to maintain the state of each archive, hence we overwrite it every time it's needed. - // There are a number of problems with this, for example opening a file in this archive, then opening - // this archive again with a different path, will corrupt the previously open file. +ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveDataCheck::Open(const Path& path) { auto vec = path.AsBinary(); const u32* data = reinterpret_cast<u32*>(vec.data()); std::string file_path = GetSaveDataCheckPath(mount_point, data[1], data[0]); FileUtil::IOFile file(file_path, "rb"); - std::fill(raw_data.begin(), raw_data.end(), 0); - if (!file.IsOpen()) { return ResultCode(-1); // TODO(Subv): Find the right error code } auto size = file.GetSize(); - raw_data.resize(size); - file.ReadBytes(raw_data.data(), size); + auto raw_data = std::make_shared<std::vector<u8>>(size); + file.ReadBytes(raw_data->data(), size); file.Close(); - return RESULT_SUCCESS; + + auto archive = Common::make_unique<IVFCArchive>(std::move(raw_data)); + return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); +} + +ResultCode ArchiveFactory_SaveDataCheck::Format(const Path& path) { + LOG_ERROR(Service_FS, "Attempted to format a SaveDataCheck archive."); + // TODO: Verify error code + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, + ErrorSummary::NotSupported, ErrorLevel::Permanent); } } // namespace FileSys diff --git a/src/core/file_sys/archive_savedatacheck.h b/src/core/file_sys/archive_savedatacheck.h index f6e73e803..f78a6f02e 100644 --- a/src/core/file_sys/archive_savedatacheck.h +++ b/src/core/file_sys/archive_savedatacheck.h @@ -17,12 +17,14 @@ namespace FileSys { /// File system interface to the SaveDataCheck archive -class Archive_SaveDataCheck final : public IVFCArchive { +class ArchiveFactory_SaveDataCheck final : public ArchiveFactory { public: - Archive_SaveDataCheck(const std::string& mount_point); + ArchiveFactory_SaveDataCheck(const std::string& mount_point); std::string GetName() const override { return "SaveDataCheck"; } - ResultCode Open(const Path& path) override; + + ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; + ResultCode Format(const Path& path) override; private: std::string mount_point; diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 26b03e82f..92b20c7f6 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -6,6 +6,7 @@ #include "common/common_types.h" #include "common/file_util.h" +#include "common/make_unique.h" #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/disk_archive.h" @@ -16,17 +17,17 @@ namespace FileSys { -Archive_SDMC::Archive_SDMC(const std::string& sdmc_directory) : DiskArchive(sdmc_directory) { +ArchiveFactory_SDMC::ArchiveFactory_SDMC(const std::string& sdmc_directory) : sdmc_directory(sdmc_directory) { LOG_INFO(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str()); } -bool Archive_SDMC::Initialize() { +bool ArchiveFactory_SDMC::Initialize() { if (!Settings::values.use_virtual_sd) { LOG_WARNING(Service_FS, "SDMC disabled by config."); return false; } - if (!FileUtil::CreateFullPath(mount_point)) { + if (!FileUtil::CreateFullPath(sdmc_directory)) { LOG_ERROR(Service_FS, "Unable to create SDMC path."); return false; } @@ -34,4 +35,14 @@ bool Archive_SDMC::Initialize() { return true; } +ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& path) { + auto archive = Common::make_unique<DiskArchive>(sdmc_directory); + return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); +} + +ResultCode ArchiveFactory_SDMC::Format(const Path& path) { + // This is kind of an undesirable operation, so let's just ignore it. :) + return RESULT_SUCCESS; +} + } // namespace FileSys diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 1b801f217..1becf6c0f 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -15,9 +15,9 @@ namespace FileSys { /// File system interface to the SDMC archive -class Archive_SDMC final : public DiskArchive { +class ArchiveFactory_SDMC final : public ArchiveFactory { public: - Archive_SDMC(const std::string& mount_point); + ArchiveFactory_SDMC(const std::string& mount_point); /** * Initialize the archive. @@ -26,6 +26,12 @@ public: bool Initialize(); std::string GetName() const override { return "SDMC"; } + + ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; + ResultCode Format(const Path& path) override; + +private: + std::string sdmc_directory; }; } // namespace FileSys diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index c6e033fcd..f53fd57db 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -18,26 +18,26 @@ namespace FileSys { std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const { LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); - auto file = Common::make_unique<DiskFile>(this, path, mode); + auto file = Common::make_unique<DiskFile>(*this, path, mode); if (!file->Open()) return nullptr; return std::move(file); } bool DiskArchive::DeleteFile(const Path& path) const { - return FileUtil::Delete(GetMountPoint() + path.AsString()); + return FileUtil::Delete(mount_point + path.AsString()); } bool DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const { - return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString()); + return FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString()); } bool DiskArchive::DeleteDirectory(const Path& path) const { - return FileUtil::DeleteDir(GetMountPoint() + path.AsString()); + return FileUtil::DeleteDir(mount_point + path.AsString()); } ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u32 size) const { - std::string full_path = GetMountPoint() + path.AsString(); + std::string full_path = mount_point + path.AsString(); if (FileUtil::Exists(full_path)) return ResultCode(ErrorDescription::AlreadyExists, ErrorModule::FS, ErrorSummary::NothingHappened, ErrorLevel::Info); @@ -58,16 +58,16 @@ ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u32 size) const { bool DiskArchive::CreateDirectory(const Path& path) const { - return FileUtil::CreateDir(GetMountPoint() + path.AsString()); + return FileUtil::CreateDir(mount_point + path.AsString()); } bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { - return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString()); + return FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString()); } std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) const { LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str()); - auto directory = Common::make_unique<DiskDirectory>(this, path); + auto directory = Common::make_unique<DiskDirectory>(*this, path); if (!directory->Open()) return nullptr; return std::move(directory); @@ -75,13 +75,12 @@ std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) c //////////////////////////////////////////////////////////////////////////////////////////////////// -DiskFile::DiskFile(const DiskArchive* archive, const Path& path, const Mode mode) { +DiskFile::DiskFile(const DiskArchive& archive, const Path& path, const Mode mode) { // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass // the root directory we set while opening the archive. // For example, opening /../../etc/passwd can give the emulated program your users list. - this->path = archive->GetMountPoint() + path.AsString(); + this->path = archive.mount_point + path.AsString(); this->mode.hex = mode.hex; - this->archive = archive; } bool DiskFile::Open() { @@ -134,12 +133,11 @@ bool DiskFile::Close() const { //////////////////////////////////////////////////////////////////////////////////////////////////// -DiskDirectory::DiskDirectory(const DiskArchive* archive, const Path& path) { +DiskDirectory::DiskDirectory(const DiskArchive& archive, const Path& path) { // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass // the root directory we set while opening the archive. // For example, opening /../../usr/bin can give the emulated program your installed programs. - this->path = archive->GetMountPoint() + path.AsString(); - this->archive = archive; + this->path = archive.mount_point + path.AsString(); } bool DiskDirectory::Open() { diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h index 3472f6874..dbbdced74 100644 --- a/src/core/file_sys/disk_archive.h +++ b/src/core/file_sys/disk_archive.h @@ -24,8 +24,8 @@ class DiskArchive : public ArchiveBackend { public: DiskArchive(const std::string& mount_point_) : mount_point(mount_point_) {} - virtual std::string GetName() const = 0; - virtual ResultCode Format(const Path& path) const { return RESULT_SUCCESS; } + virtual std::string GetName() const { return "DiskArchive: " + mount_point; } + std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override; bool DeleteFile(const Path& path) const override; bool RenameFile(const Path& src_path, const Path& dest_path) const override; @@ -35,26 +35,17 @@ public: bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override; - virtual ResultCode Open(const Path& path) override { - return RESULT_SUCCESS; - } - - /** - * Getter for the path used for this Archive - * @return Mount point of that passthrough archive - */ - virtual const std::string& GetMountPoint() const { - return mount_point; - } - protected: + friend class DiskFile; + friend class DiskDirectory; + std::string mount_point; }; class DiskFile : public FileBackend { public: DiskFile(); - DiskFile(const DiskArchive* archive, const Path& path, const Mode mode); + DiskFile(const DiskArchive& archive, const Path& path, const Mode mode); bool Open() override; size_t Read(const u64 offset, const u32 length, u8* buffer) const override; @@ -68,7 +59,6 @@ public: } protected: - const DiskArchive* archive; std::string path; Mode mode; std::unique_ptr<FileUtil::IOFile> file; @@ -77,7 +67,7 @@ protected: class DiskDirectory : public DirectoryBackend { public: DiskDirectory(); - DiskDirectory(const DiskArchive* archive, const Path& path); + DiskDirectory(const DiskArchive& archive, const Path& path); ~DiskDirectory() override { Close(); @@ -91,7 +81,6 @@ public: } protected: - const DiskArchive* archive; std::string path; u32 total_entries_in_directory; FileUtil::FSTEntry directory; diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index 68c3c8b81..35aca54fa 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -15,11 +15,15 @@ namespace FileSys { -IVFCArchive::IVFCArchive() { +IVFCArchive::IVFCArchive(std::shared_ptr<const std::vector<u8>> data) : data(data) { +} + +std::string IVFCArchive::GetName() const { + return "IVFC"; } std::unique_ptr<FileBackend> IVFCArchive::OpenFile(const Path& path, const Mode mode) const { - return Common::make_unique<IVFCFile>(this); + return Common::make_unique<IVFCFile>(data); } bool IVFCArchive::DeleteFile(const Path& path) const { @@ -57,31 +61,25 @@ std::unique_ptr<DirectoryBackend> IVFCArchive::OpenDirectory(const Path& path) c return Common::make_unique<IVFCDirectory>(); } -ResultCode IVFCArchive::Format(const Path& path) const { - LOG_CRITICAL(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str()); - // TODO: Verify error code - return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); -} - //////////////////////////////////////////////////////////////////////////////////////////////////// size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const { LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); - memcpy(buffer, &archive->raw_data[(u32)offset], length); + memcpy(buffer, data->data() + offset, length); return length; } size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { - LOG_CRITICAL(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str()); + LOG_ERROR(Service_FS, "Attempted to write to IVFC file"); return 0; } size_t IVFCFile::GetSize() const { - return sizeof(u8) * archive->raw_data.size(); + return sizeof(u8) * data->size(); } bool IVFCFile::SetSize(const u64 size) const { - LOG_CRITICAL(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str()); + LOG_ERROR(Service_FS, "Attempted to set the size of an IVFC file"); return false; } diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index 6f4cc86df..1aff9e0a4 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -4,6 +4,7 @@ #pragma once +#include <memory> #include <vector> #include "common/common_types.h" @@ -23,7 +24,9 @@ namespace FileSys { */ class IVFCArchive : public ArchiveBackend { public: - IVFCArchive(); + IVFCArchive(std::shared_ptr<const std::vector<u8>> data); + + std::string GetName() const override; std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override; bool DeleteFile(const Path& path) const override; @@ -33,16 +36,14 @@ public: bool CreateDirectory(const Path& path) const override; bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override; - ResultCode Format(const Path& path) const override; protected: - friend class IVFCFile; - std::vector<u8> raw_data; + std::shared_ptr<const std::vector<u8>> data; }; class IVFCFile : public FileBackend { public: - IVFCFile(const IVFCArchive* archive) : archive(archive) {} + IVFCFile(std::shared_ptr<const std::vector<u8>> data) : data(data) {} bool Open() override { return true; } size_t Read(const u64 offset, const u32 length, u8* buffer) const override; @@ -53,7 +54,7 @@ public: void Flush() const override { } private: - const IVFCArchive* archive; + std::shared_ptr<const std::vector<u8>> data; }; class IVFCDirectory : public DirectoryBackend { diff --git a/src/core/hle/config_mem.cpp b/src/core/hle/config_mem.cpp index 721a600b5..68d3071f5 100644 --- a/src/core/hle/config_mem.cpp +++ b/src/core/hle/config_mem.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include "common/common_types.h" -#include "common/log.h" +#include "common/logging/log.h" #include "core/hle/config_mem.h" diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp index 5a2edeb4a..97d73781f 100644 --- a/src/core/hle/hle.cpp +++ b/src/core/hle/hle.cpp @@ -45,7 +45,7 @@ void CallSVC(u32 opcode) { } void Reschedule(const char *reason) { - _dbg_assert_msg_(Kernel, reason != 0 && strlen(reason) < 256, "Reschedule: Invalid or too long reason."); + DEBUG_ASSERT_MSG(reason != nullptr && strlen(reason) < 256, "Reschedule: Invalid or too long reason."); // TODO(bunnei): It seems that games depend on some CPU execution time elapsing during HLE // routines. This simulates that time by artificially advancing the number of CPU "ticks". diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 898e1c98f..420906ec0 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -32,7 +32,7 @@ bool Event::ShouldWait() { } void Event::Acquire() { - _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); + ASSERT_MSG(!ShouldWait(), "object unavailable!"); // Release the event if it's not sticky... if (reset_type != RESETTYPE_STICKY) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a2ffbcdb7..eb61d8ef3 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -52,7 +52,7 @@ void WaitObject::WakeupAllWaitingThreads() { for (auto thread : waiting_threads_copy) thread->ReleaseWaitObject(this); - _assert_msg_(Kernel, waiting_threads.empty(), "failed to awaken all waiting threads!"); + ASSERT_MSG(waiting_threads.empty(), "failed to awaken all waiting threads!"); } HandleTable::HandleTable() { @@ -61,7 +61,7 @@ HandleTable::HandleTable() { } ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { - _dbg_assert_(Kernel, obj != nullptr); + DEBUG_ASSERT(obj != nullptr); u16 slot = next_free_slot; if (slot >= generations.size()) { diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index a811db392..be2c49706 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -64,7 +64,7 @@ void Mutex::Acquire() { } void Mutex::Acquire(SharedPtr<Thread> thread) { - _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); + ASSERT_MSG(!ShouldWait(), "object unavailable!"); // Actually "acquire" the mutex only if we don't already have it... if (lock_count == 0) { diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index c8cf8b9a2..6aecc24aa 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -36,7 +36,7 @@ bool Semaphore::ShouldWait() { } void Semaphore::Acquire() { - _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); + ASSERT_MSG(!ShouldWait(), "object unavailable!"); --available_count; } diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index 7cc9332c9..9e9288e0f 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h @@ -66,7 +66,7 @@ public: } void Acquire() override { - _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); + ASSERT_MSG(!ShouldWait(), "object unavailable!"); } }; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 7f629c20e..f8c834a8d 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -29,7 +29,7 @@ bool Thread::ShouldWait() { } void Thread::Acquire() { - _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); + ASSERT_MSG(!ShouldWait(), "object unavailable!"); } // Lists all thread ids that aren't deleted/etc. @@ -144,7 +144,7 @@ void ArbitrateAllThreads(u32 address) { * @param new_thread The thread to switch to */ static void SwitchContext(Thread* new_thread) { - _dbg_assert_msg_(Kernel, new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running."); + DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running."); Thread* previous_thread = GetCurrentThread(); @@ -304,14 +304,12 @@ void Thread::ResumeFromWait() { break; case THREADSTATUS_RUNNING: case THREADSTATUS_READY: - LOG_ERROR(Kernel, "Thread with object id %u has already resumed.", GetObjectId()); - _dbg_assert_(Kernel, false); + DEBUG_ASSERT_MSG(false, "Thread with object id %u has already resumed.", GetObjectId()); return; case THREADSTATUS_DEAD: // This should never happen, as threads must complete before being stopped. - LOG_CRITICAL(Kernel, "Thread with object id %u cannot be resumed because it's DEAD.", + DEBUG_ASSERT_MSG(false, "Thread with object id %u cannot be resumed because it's DEAD.", GetObjectId()); - _dbg_assert_(Kernel, false); return; } @@ -387,7 +385,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, // TODO(peachum): Remove this. Range checking should be done, and an appropriate error should be returned. static void ClampPriority(const Thread* thread, s32* priority) { if (*priority < THREADPRIO_HIGHEST || *priority > THREADPRIO_LOWEST) { - _dbg_assert_msg_(Kernel, false, "Application passed an out of range priority. An error should be returned."); + DEBUG_ASSERT_MSG(false, "Application passed an out of range priority. An error should be returned."); s32 new_priority = CLAMP(*priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", @@ -425,7 +423,7 @@ SharedPtr<Thread> SetupIdleThread() { } SharedPtr<Thread> SetupMainThread(u32 stack_size, u32 entry_point, s32 priority) { - _dbg_assert_(Kernel, !GetCurrentThread()); + DEBUG_ASSERT(!GetCurrentThread()); // Initialize new "main" thread auto thread_res = Thread::Create("main", entry_point, priority, 0, diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 4352fc99c..aa0afb796 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -38,7 +38,7 @@ bool Timer::ShouldWait() { } void Timer::Acquire() { - _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); + ASSERT_MSG( !ShouldWait(), "object unavailable!"); } void Timer::Set(s64 initial, s64 interval) { diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 948b9e38e..9dbd5a914 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -307,14 +307,14 @@ public: } ResultVal& operator=(const ResultVal& o) { - if (*this) { - if (o) { + if (!empty()) { + if (!o.empty()) { *GetPointer() = *o.GetPointer(); } else { GetPointer()->~T(); } } else { - if (o) { + if (!o.empty()) { new (&storage) T(*o.GetPointer()); } } @@ -363,7 +363,7 @@ public: /// Asserts that the result succeeded and returns a reference to it. T& Unwrap() { // TODO(yuriks): Should be a release assert - _assert_msg_(Common, Succeeded(), "Tried to Unwrap empty ResultVal"); + ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal"); return **this; } diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index 53d920de1..50644816b 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" +#include "common/logging/log.h" #include "core/hle/hle.h" #include "core/hle/service/ac_u.h" diff --git a/src/core/hle/service/act_u.cpp b/src/core/hle/service/act_u.cpp index 4ea7a9fb2..57f49c91f 100644 --- a/src/core/hle/service/act_u.cpp +++ b/src/core/hle/service/act_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/act_u.h" diff --git a/src/core/hle/service/am_app.cpp b/src/core/hle/service/am_app.cpp index df10db87f..684b753f0 100644 --- a/src/core/hle/service/am_app.cpp +++ b/src/core/hle/service/am_app.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/am_app.h" diff --git a/src/core/hle/service/am_net.cpp b/src/core/hle/service/am_net.cpp index c74012d9d..ba2a499f1 100644 --- a/src/core/hle/service/am_net.cpp +++ b/src/core/hle/service/am_net.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/am_net.h" diff --git a/src/core/hle/service/am_sys.cpp b/src/core/hle/service/am_sys.cpp index c5df8abda..7ab89569f 100644 --- a/src/core/hle/service/am_sys.cpp +++ b/src/core/hle/service/am_sys.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/am_sys.h" diff --git a/src/core/hle/service/apt_a.cpp b/src/core/hle/service/apt_a.cpp index e1dd2a5fb..1c1d92572 100644 --- a/src/core/hle/service/apt_a.cpp +++ b/src/core/hle/service/apt_a.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/apt_a.h" diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp index ccfd04591..12af5e9f7 100644 --- a/src/core/hle/service/apt_u.cpp +++ b/src/core/hle/service/apt_u.cpp @@ -79,7 +79,7 @@ void Initialize(Service::Interface* self) { notification_event->Clear(); pause_event->Signal(); // Fire start event - _assert_msg_(KERNEL, (nullptr != lock), "Cannot initialize without lock"); + ASSERT_MSG((nullptr != lock), "Cannot initialize without lock"); lock->Release(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error diff --git a/src/core/hle/service/boss_p.cpp b/src/core/hle/service/boss_p.cpp index b3aa6acee..8280830e5 100644 --- a/src/core/hle/service/boss_p.cpp +++ b/src/core/hle/service/boss_p.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/boss_p.h" diff --git a/src/core/hle/service/boss_u.cpp b/src/core/hle/service/boss_u.cpp index 50bb5d426..2c322bdfd 100644 --- a/src/core/hle/service/boss_u.cpp +++ b/src/core/hle/service/boss_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/boss_u.h" diff --git a/src/core/hle/service/cam_u.cpp b/src/core/hle/service/cam_u.cpp index cf3b27664..fcfd87715 100644 --- a/src/core/hle/service/cam_u.cpp +++ b/src/core/hle/service/cam_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/cam_u.h" diff --git a/src/core/hle/service/cecd_s.cpp b/src/core/hle/service/cecd_s.cpp index 2c707baff..b298f151d 100644 --- a/src/core/hle/service/cecd_s.cpp +++ b/src/core/hle/service/cecd_s.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/cecd_s.h" diff --git a/src/core/hle/service/cecd_u.cpp b/src/core/hle/service/cecd_u.cpp index b7ea3a186..9125364bc 100644 --- a/src/core/hle/service/cecd_u.cpp +++ b/src/core/hle/service/cecd_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/cecd_u.h" diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 8812c49ef..1a2104b48 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include <algorithm> -#include "common/log.h" #include "common/make_unique.h" #include "core/file_sys/archive_systemsavedata.h" #include "core/hle/service/cfg/cfg.h" @@ -109,7 +108,7 @@ ResultCode UpdateConfigNANDSavegame() { mode.create_flag = 1; FileSys::Path path("config"); auto file = cfg_system_save_data->OpenFile(path, mode); - _assert_msg_(Service_CFG, file != nullptr, "could not open file"); + ASSERT_MSG(file != nullptr, "could not open file"); file->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data()); return RESULT_SUCCESS; } diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index 555b7884a..20b09a8cb 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_i.h" diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index 2170894d6..d80aeae8d 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_s.h" diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 1da9f59f6..4c5eac382 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -3,8 +3,8 @@ // Refer to the license.txt file included. #include "common/file_util.h" -#include "common/log.h" #include "common/string_util.h" +#include "core/settings.h" #include "core/file_sys/archive_systemsavedata.h" #include "core/hle/hle.h" #include "core/hle/service/cfg/cfg.h" @@ -83,7 +83,7 @@ static void GetCountryCodeID(Service::Interface* self) { u16 country_code_id = 0; // The following algorithm will fail if the first country code isn't 0. - _dbg_assert_(Service_CFG, country_codes[0] == 0); + DEBUG_ASSERT(country_codes[0] == 0); for (size_t id = 0; id < country_codes.size(); ++id) { if (country_codes[id] == country_code) { @@ -129,6 +129,65 @@ static void GetConfigInfoBlk2(Service::Interface* self) { } /** + * CFG_User::SecureInfoGetRegion service function + * Inputs: + * 1 : None + * Outputs: + * 0 : Result Header code + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Region value loaded from SecureInfo offset 0x100 + */ +static void SecureInfoGetRegion(Service::Interface* self) { + u32* cmd_buffer = Kernel::GetCommandBuffer(); + + cmd_buffer[1] = RESULT_SUCCESS.raw; // No Error + cmd_buffer[2] = Settings::values.region_value; +} + +/** + * CFG_User::GenHashConsoleUnique service function + * Inputs: + * 1 : 20 bit application ID salt + * Outputs: + * 0 : Result Header code + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Hash/"ID" lower word + * 3 : Hash/"ID" upper word + */ +static void GenHashConsoleUnique(Service::Interface* self) { + u32* cmd_buffer = Kernel::GetCommandBuffer(); + u32 app_id_salt = cmd_buffer[1]; + + cmd_buffer[1] = RESULT_SUCCESS.raw; // No Error + cmd_buffer[2] = 0x33646D6F ^ (app_id_salt & 0xFFFFF); // 3dmoo hash + cmd_buffer[3] = 0x6F534841 ^ (app_id_salt & 0xFFFFF); + + LOG_WARNING(Service_CFG, "(STUBBED) called app_id_salt=0x%08X", app_id_salt); +} + +/** + * CFG_User::GetRegionCanadaUSA service function + * Inputs: + * 1 : None + * Outputs: + * 0 : Result Header code + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Output value + */ +static void GetRegionCanadaUSA(Service::Interface* self) { + u32* cmd_buffer = Kernel::GetCommandBuffer(); + + cmd_buffer[1] = RESULT_SUCCESS.raw; // No Error + + u8 canada_or_usa = 1; + if (canada_or_usa == Settings::values.region_value) { + cmd_buffer[2] = 1; + } else { + cmd_buffer[2] = 0; + } +} + +/** * CFG_User::GetSystemModel service function * Inputs: * 0 : 0x00050000 @@ -171,9 +230,9 @@ static void GetModelNintendo2DS(Service::Interface* self) { const Interface::FunctionInfo FunctionTable[] = { {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, - {0x00020000, nullptr, "SecureInfoGetRegion"}, - {0x00030040, nullptr, "GenHashConsoleUnique"}, - {0x00040000, nullptr, "GetRegionCanadaUSA"}, + {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, + {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, + {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, {0x00050000, GetSystemModel, "GetSystemModel"}, {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp index 39b00982c..6a1d961ac 100644 --- a/src/core/hle/service/csnd_snd.cpp +++ b/src/core/hle/service/csnd_snd.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/csnd_snd.h" diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index 0f86894a6..db1e3b5fd 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/kernel/event.h" #include "core/hle/service/dsp_dsp.h" @@ -128,6 +127,31 @@ void WriteReg0x10(Service::Interface* self) { } /** + * DSP_DSP::WriteProcessPipe service function + * Inputs: + * 1 : Number + * 2 : Size + * 3 : (size <<14) | 0x402 + * 4 : Buffer + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ +void WriteProcessPipe(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 number = cmd_buff[1]; + u32 size = cmd_buff[2]; + u32 new_size = cmd_buff[3]; + u32 buffer = cmd_buff[4]; + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%08X, new_size=0x%08X, buffer=0x%08X", + number, size, new_size, buffer); +} + +/** * DSP_DSP::ReadPipeIfPossible service function * Inputs: * 1 : Unknown @@ -169,6 +193,41 @@ void ReadPipeIfPossible(Service::Interface* self) { LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%08X, buffer=0x%08X", size, addr); } +/** + * DSP_DSP::SetSemaphoreMask service function + * Inputs: + * 1 : Mask + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void SetSemaphoreMask(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 mask = cmd_buff[1]; + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_DSP, "(STUBBED) called mask=0x%08X", mask); +} + +/** + * DSP_DSP::GetHeadphoneStatus service function + * Inputs: + * 1 : None + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : The headphone status response, 0 = Not using headphones?, + * 1 = using headphones? + */ +void GetHeadphoneStatus(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[2] = 0; // Not using headphones? + + LOG_WARNING(Service_DSP, "(STUBBED) called"); +} + const Interface::FunctionInfo FunctionTable[] = { {0x00010040, nullptr, "RecvData"}, {0x00020040, nullptr, "RecvDataIsReady"}, @@ -179,7 +238,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00090040, nullptr, "ClearSemaphore"}, {0x000B0000, nullptr, "CheckSemaphoreRequest"}, {0x000C0040, ConvertProcessAddressFromDspDram, "ConvertProcessAddressFromDspDram"}, - {0x000D0082, nullptr, "WriteProcessPipe"}, + {0x000D0082, WriteProcessPipe, "WriteProcessPipe"}, {0x001000C0, ReadPipeIfPossible, "ReadPipeIfPossible"}, {0x001100C2, LoadComponent, "LoadComponent"}, {0x00120000, nullptr, "UnloadComponent"}, @@ -187,13 +246,13 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00140082, nullptr, "InvalidateDCache"}, {0x00150082, RegisterInterruptEvents, "RegisterInterruptEvents"}, {0x00160000, GetSemaphoreEventHandle, "GetSemaphoreEventHandle"}, - {0x00170040, nullptr, "SetSemaphoreMask"}, + {0x00170040, SetSemaphoreMask, "SetSemaphoreMask"}, {0x00180040, nullptr, "GetPhysicalAddress"}, {0x00190040, nullptr, "GetVirtualAddress"}, {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"}, {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"}, {0x001C0082, nullptr, "SetIirFilterEQ"}, - {0x001F0000, nullptr, "GetHeadphoneStatus"}, + {0x001F0000, GetHeadphoneStatus, "GetHeadphoneStatus"}, {0x00210000, nullptr, "GetIsDspOccupied"}, }; diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 962de2170..8d765acb5 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/err_f.h" diff --git a/src/core/hle/service/frd_a.cpp b/src/core/hle/service/frd_a.cpp index 79140a756..569979319 100644 --- a/src/core/hle/service/frd_a.cpp +++ b/src/core/hle/service/frd_a.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/frd_a.h" diff --git a/src/core/hle/service/frd_u.cpp b/src/core/hle/service/frd_u.cpp index 59faca77a..6d2ff1e21 100644 --- a/src/core/hle/service/frd_u.cpp +++ b/src/core/hle/service/frd_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/frd_u.h" diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index ccf132f31..37bcec219 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -5,6 +5,8 @@ #include <memory> #include <unordered_map> +#include <boost/container/flat_map.hpp> + #include "common/common_types.h" #include "common/file_util.h" #include "common/make_unique.h" @@ -18,7 +20,6 @@ #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/directory_backend.h" #include "core/hle/service/fs/archive.h" -#include "core/hle/kernel/session.h" #include "core/hle/result.h" // Specializes std::hash for ArchiveIdCode, so that we can use it in std::unordered_map. @@ -74,43 +75,19 @@ enum class DirectoryCommand : u32 { Close = 0x08020000, }; -class Archive { -public: - Archive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code) - : id_code(id_code), backend(std::move(backend)) { - } - - std::string GetName() const { return "Archive: " + backend->GetName(); } - - ArchiveIdCode id_code; ///< Id code of the archive - std::unique_ptr<FileSys::ArchiveBackend> backend; ///< Archive backend interface -}; - -class File : public Kernel::Session { -public: - File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) - : path(path), priority(0), backend(std::move(backend)) { - } - - std::string GetName() const override { return "Path: " + path.DebugStr(); } - - FileSys::Path path; ///< Path of the file - u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means - std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface - - ResultVal<bool> SyncRequest() override { - u32* cmd_buff = Kernel::GetCommandBuffer(); - FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); - switch (cmd) { +ResultVal<bool> File::SyncRequest() { + u32* cmd_buff = Kernel::GetCommandBuffer(); + FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); + switch (cmd) { // Read from file... case FileCommand::Read: { - u64 offset = cmd_buff[1] | ((u64) cmd_buff[2]) << 32; - u32 length = cmd_buff[3]; + u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; + u32 length = cmd_buff[3]; u32 address = cmd_buff[5]; LOG_TRACE(Service_FS, "Read %s %s: offset=0x%llx length=%d address=0x%x", - GetTypeName().c_str(), GetName().c_str(), offset, length, address); + GetTypeName().c_str(), GetName().c_str(), offset, length, address); cmd_buff[2] = backend->Read(offset, length, Memory::GetPointer(address)); break; } @@ -118,12 +95,12 @@ public: // Write to file... case FileCommand::Write: { - u64 offset = cmd_buff[1] | ((u64) cmd_buff[2]) << 32; - u32 length = cmd_buff[3]; - u32 flush = cmd_buff[4]; + u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; + u32 length = cmd_buff[3]; + u32 flush = cmd_buff[4]; u32 address = cmd_buff[6]; LOG_TRACE(Service_FS, "Write %s %s: offset=0x%llx length=%d address=0x%x, flush=0x%x", - GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush); + GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush); cmd_buff[2] = backend->Write(offset, length, flush, Memory::GetPointer(address)); break; } @@ -141,7 +118,7 @@ public: { u64 size = cmd_buff[1] | ((u64)cmd_buff[2] << 32); LOG_TRACE(Service_FS, "SetSize %s %s size=%llu", - GetTypeName().c_str(), GetName().c_str(), size); + GetTypeName().c_str(), GetName().c_str(), size); backend->SetSize(size); break; } @@ -187,27 +164,15 @@ public: ResultCode error = UnimplementedFunction(ErrorModule::FS); cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. return error; - } - cmd_buff[1] = 0; // No error - return MakeResult<bool>(false); } -}; - -class Directory : public Kernel::Session { -public: - Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path) - : path(path), backend(std::move(backend)) { - } - - std::string GetName() const override { return "Directory: " + path.DebugStr(); } - - FileSys::Path path; ///< Path of the directory - std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + return MakeResult<bool>(false); +} - ResultVal<bool> SyncRequest() override { - u32* cmd_buff = Kernel::GetCommandBuffer(); - DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); - switch (cmd) { +ResultVal<bool> Directory::SyncRequest() { + u32* cmd_buff = Kernel::GetCommandBuffer(); + DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); + switch (cmd) { // Read from directory... case DirectoryCommand::Read: @@ -216,7 +181,7 @@ public: u32 address = cmd_buff[3]; auto entries = reinterpret_cast<FileSys::Entry*>(Memory::GetPointer(address)); LOG_TRACE(Service_FS, "Read %s %s: count=%d", - GetTypeName().c_str(), GetName().c_str(), count); + GetTypeName().c_str(), GetName().c_str(), count); // Number of entries actually read cmd_buff[2] = backend->Read(count, entries); @@ -236,29 +201,31 @@ public: ResultCode error = UnimplementedFunction(ErrorModule::FS); cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. return MakeResult<bool>(false); - } - cmd_buff[1] = 0; // No error - return MakeResult<bool>(false); } -}; + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + return MakeResult<bool>(false); +} //////////////////////////////////////////////////////////////////////////////////////////////////// +using FileSys::ArchiveBackend; +using FileSys::ArchiveFactory; + /** * Map of registered archives, identified by id code. Once an archive is registered here, it is * never removed until the FS service is shut down. */ -static std::unordered_map<ArchiveIdCode, std::unique_ptr<Archive>> id_code_map; +static boost::container::flat_map<ArchiveIdCode, std::unique_ptr<ArchiveFactory>> id_code_map; /** * Map of active archive handles. Values are pointers to the archives in `idcode_map`. */ -static std::unordered_map<ArchiveHandle, Archive*> handle_map; +static std::unordered_map<ArchiveHandle, std::unique_ptr<ArchiveBackend>> handle_map; static ArchiveHandle next_handle; -static Archive* GetArchive(ArchiveHandle handle) { +static ArchiveBackend* GetArchive(ArchiveHandle handle) { auto itr = handle_map.find(handle); - return (itr == handle_map.end()) ? nullptr : itr->second; + return (itr == handle_map.end()) ? nullptr : itr->second.get(); } ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path) { @@ -271,15 +238,13 @@ ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi ErrorSummary::NotFound, ErrorLevel::Permanent); } - ResultCode res = itr->second->backend->Open(archive_path); - if (!res.IsSuccess()) - return res; + CASCADE_RESULT(std::unique_ptr<ArchiveBackend> res, itr->second->Open(archive_path)); // This should never even happen in the first place with 64-bit handles, while (handle_map.count(next_handle) != 0) { ++next_handle; } - handle_map.emplace(next_handle, itr->second.get()); + handle_map.emplace(next_handle, std::move(res)); return MakeResult<ArchiveHandle>(next_handle++); } @@ -292,39 +257,39 @@ ResultCode CloseArchive(ArchiveHandle handle) { // TODO(yuriks): This might be what the fs:REG service is for. See the Register/Unregister calls in // http://3dbrew.org/wiki/Filesystem_services#ProgramRegistry_service_.22fs:REG.22 -ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code) { - auto result = id_code_map.emplace(id_code, Common::make_unique<Archive>(std::move(backend), id_code)); +ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, ArchiveIdCode id_code) { + auto result = id_code_map.emplace(id_code, std::move(factory)); bool inserted = result.second; - _dbg_assert_msg_(Service_FS, inserted, "Tried to register more than one archive with same id code"); + ASSERT_MSG(inserted, "Tried to register more than one archive with same id code"); auto& archive = result.first->second; LOG_DEBUG(Service_FS, "Registered archive %s with id code 0x%08X", archive->GetName().c_str(), id_code); return RESULT_SUCCESS; } -ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenFileFromArchive(ArchiveHandle archive_handle, +ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - std::unique_ptr<FileSys::FileBackend> backend = archive->backend->OpenFile(path, mode); + std::unique_ptr<FileSys::FileBackend> backend = archive->OpenFile(path, mode); if (backend == nullptr) { return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); } auto file = Kernel::SharedPtr<File>(new File(std::move(backend), path)); - return MakeResult<Kernel::SharedPtr<Kernel::Session>>(std::move(file)); + return MakeResult<Kernel::SharedPtr<File>>(std::move(file)); } ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - if (archive->backend->DeleteFile(path)) + if (archive->DeleteFile(path)) return RESULT_SUCCESS; return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::Canceled, ErrorLevel::Status); @@ -332,13 +297,13 @@ ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Pa ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { - Archive* src_archive = GetArchive(src_archive_handle); - Archive* dest_archive = GetArchive(dest_archive_handle); + ArchiveBackend* src_archive = GetArchive(src_archive_handle); + ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); if (src_archive == nullptr || dest_archive == nullptr) return ERR_INVALID_HANDLE; if (src_archive == dest_archive) { - if (src_archive->backend->RenameFile(src_path, dest_path)) + if (src_archive->RenameFile(src_path, dest_path)) return RESULT_SUCCESS; } else { // TODO: Implement renaming across archives @@ -352,30 +317,30 @@ ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const Fil } ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - if (archive->backend->DeleteDirectory(path)) + if (archive->DeleteDirectory(path)) return RESULT_SUCCESS; return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::Canceled, ErrorLevel::Status); } ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - return archive->backend->CreateFile(path, file_size); + return archive->CreateFile(path, file_size); } ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - if (archive->backend->CreateDirectory(path)) + if (archive->CreateDirectory(path)) return RESULT_SUCCESS; return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::Canceled, ErrorLevel::Status); @@ -383,13 +348,13 @@ ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { - Archive* src_archive = GetArchive(src_archive_handle); - Archive* dest_archive = GetArchive(dest_archive_handle); + ArchiveBackend* src_archive = GetArchive(src_archive_handle); + ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); if (src_archive == nullptr || dest_archive == nullptr) return ERR_INVALID_HANDLE; if (src_archive == dest_archive) { - if (src_archive->backend->RenameDirectory(src_path, dest_path)) + if (src_archive->RenameDirectory(src_path, dest_path)) return RESULT_SUCCESS; } else { // TODO: Implement renaming across archives @@ -402,31 +367,29 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons ErrorSummary::NothingHappened, ErrorLevel::Status); } -ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, +ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - std::unique_ptr<FileSys::DirectoryBackend> backend = archive->backend->OpenDirectory(path); + std::unique_ptr<FileSys::DirectoryBackend> backend = archive->OpenDirectory(path); if (backend == nullptr) { return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Permanent); } auto directory = Kernel::SharedPtr<Directory>(new Directory(std::move(backend), path)); - return MakeResult<Kernel::SharedPtr<Kernel::Session>>(std::move(directory)); + return MakeResult<Kernel::SharedPtr<Directory>>(std::move(directory)); } -ResultCode FormatSaveData() { - // Do not create the archive again if it already exists - auto archive_itr = id_code_map.find(ArchiveIdCode::SaveData); +ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::Path& path) { + auto archive_itr = id_code_map.find(id_code); if (archive_itr == id_code_map.end()) { return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error } - // Use an empty path, we do not use it when formatting the savedata - return archive_itr->second->backend->Format(FileSys::Path()); + return archive_itr->second->Format(path); } ResultCode CreateExtSaveData(u32 high, u32 low) { @@ -460,32 +423,32 @@ void ArchiveInit() { std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX); std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); - auto sdmc_archive = Common::make_unique<FileSys::Archive_SDMC>(sdmc_directory); - if (sdmc_archive->Initialize()) - CreateArchive(std::move(sdmc_archive), ArchiveIdCode::SDMC); + auto sdmc_factory = Common::make_unique<FileSys::ArchiveFactory_SDMC>(sdmc_directory); + if (sdmc_factory->Initialize()) + RegisterArchiveType(std::move(sdmc_factory), ArchiveIdCode::SDMC); else LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); // Create the SaveData archive - auto savedata_archive = Common::make_unique<FileSys::Archive_SaveData>(sdmc_directory); - CreateArchive(std::move(savedata_archive), ArchiveIdCode::SaveData); + auto savedata_factory = Common::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory); + RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData); - auto extsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(sdmc_directory, false); - if (extsavedata_archive->Initialize()) - CreateArchive(std::move(extsavedata_archive), ArchiveIdCode::ExtSaveData); + auto extsavedata_factory = Common::make_unique<FileSys::ArchiveFactory_ExtSaveData>(sdmc_directory, false); + if (extsavedata_factory->Initialize()) + RegisterArchiveType(std::move(extsavedata_factory), ArchiveIdCode::ExtSaveData); else - LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_archive->GetMountPoint().c_str()); + LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_factory->GetMountPoint().c_str()); - auto sharedextsavedata_archive = Common::make_unique<FileSys::Archive_ExtSaveData>(nand_directory, true); - if (sharedextsavedata_archive->Initialize()) - CreateArchive(std::move(sharedextsavedata_archive), ArchiveIdCode::SharedExtSaveData); + auto sharedextsavedata_factory = Common::make_unique<FileSys::ArchiveFactory_ExtSaveData>(nand_directory, true); + if (sharedextsavedata_factory->Initialize()) + RegisterArchiveType(std::move(sharedextsavedata_factory), ArchiveIdCode::SharedExtSaveData); else LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", - sharedextsavedata_archive->GetMountPoint().c_str()); + sharedextsavedata_factory->GetMountPoint().c_str()); // Create the SaveDataCheck archive, basically a small variation of the RomFS archive - auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(nand_directory); - CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck); + auto savedatacheck_factory = Common::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory); + RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck); } /// Shutdown archives diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index ab5ea4da8..c490327d0 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -8,6 +8,7 @@ #include "core/file_sys/archive_backend.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/session.h" #include "core/hle/result.h" /// The unique system identifier hash, also known as ID0 @@ -36,6 +37,35 @@ enum class ArchiveIdCode : u32 { typedef u64 ArchiveHandle; +class File : public Kernel::Session { +public: + File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) + : path(path), priority(0), backend(std::move(backend)) { + } + + std::string GetName() const override { return "Path: " + path.DebugStr(); } + + FileSys::Path path; ///< Path of the file + u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means + std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface + + ResultVal<bool> SyncRequest() override; +}; + +class Directory : public Kernel::Session { +public: + Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path) + : path(path), backend(std::move(backend)) { + } + + std::string GetName() const override { return "Directory: " + path.DebugStr(); } + + FileSys::Path path; ///< Path of the directory + std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface + + ResultVal<bool> SyncRequest() override; +}; + /** * Opens an archive * @param id_code IdCode of the archive to open @@ -51,11 +81,11 @@ ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi ResultCode CloseArchive(ArchiveHandle handle); /** - * Creates an Archive + * Registers an Archive type, instances of which can later be opened using its IdCode. * @param backend File system backend interface to the archive * @param id_code Id code used to access this type of archive */ -ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code); +ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, ArchiveIdCode id_code); /** * Open a File from an Archive @@ -64,7 +94,7 @@ ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, Arc * @param mode Mode under which to open the File * @return The opened File object as a Session */ -ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenFileFromArchive(ArchiveHandle archive_handle, +ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode); /** @@ -128,14 +158,17 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons * @param path Path to the Directory inside of the Archive * @return The opened Directory object as a Session */ -ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, +ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); /** - * Creates a blank SaveData archive. + * Erases the contents of the physical folder that contains the archive + * identified by the specified id code and path + * @param id_code The id of the archive to format + * @param path The path to the archive, if relevant. * @return ResultCode 0 on success or the corresponding code on error */ -ResultCode FormatSaveData(); +ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::Path& path = FileSys::Path()); /** * Creates a blank SharedExtSaveData archive for the specified extdata ID diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 94a3a31c8..71ee4ff55 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -61,7 +61,7 @@ static void OpenFile(Service::Interface* self) { LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); - ResultVal<SharedPtr<Session>> file_res = OpenFileFromArchive(archive_handle, file_path, mode); + ResultVal<SharedPtr<File>> file_res = OpenFileFromArchive(archive_handle, file_path, mode); cmd_buff[1] = file_res.Code().raw; if (file_res.Succeeded()) { cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); @@ -117,7 +117,7 @@ static void OpenFileDirectly(Service::Interface* self) { } SCOPE_EXIT({ CloseArchive(*archive_handle); }); - ResultVal<SharedPtr<Session>> file_res = OpenFileFromArchive(*archive_handle, file_path, mode); + ResultVal<SharedPtr<File>> file_res = OpenFileFromArchive(*archive_handle, file_path, mode); cmd_buff[1] = file_res.Code().raw; if (file_res.Succeeded()) { cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); @@ -337,7 +337,7 @@ static void OpenDirectory(Service::Interface* self) { LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); - ResultVal<SharedPtr<Session>> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); + ResultVal<SharedPtr<Directory>> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); cmd_buff[1] = dir_res.Code().raw; if (dir_res.Succeeded()) { cmd_buff[3] = Kernel::g_handle_table.Create(*dir_res).MoveFrom(); @@ -468,7 +468,7 @@ static void FormatSaveData(Service::Interface* self) { return; } - cmd_buff[1] = FormatSaveData().raw; + cmd_buff[1] = FormatArchive(ArchiveIdCode::SaveData).raw; } /** @@ -484,7 +484,7 @@ static void FormatThisUserSaveData(Service::Interface* self) { // TODO(Subv): Find out what the inputs and outputs of this function are - cmd_buff[1] = FormatSaveData().raw; + cmd_buff[1] = FormatArchive(ArchiveIdCode::SaveData).raw; } static void CreateExtSaveData(Service::Interface* self) { diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 495c117ee..4c3ac845b 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - -#include "common/log.h" #include "common/bit_field.h" #include "core/mem_map.h" @@ -36,7 +34,7 @@ static inline u8* GetCommandBuffer(u32 thread_id) { } static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) { - _dbg_assert_msg_(Service_GSP, screen_index < 2, "Invalid screen index"); + DEBUG_ASSERT_MSG(screen_index < 2, "Invalid screen index"); // For each thread there are two FrameBufferUpdate fields u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate); @@ -186,7 +184,7 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) { u32 flags = cmd_buff[1]; g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]); - _assert_msg_(GSP, (g_interrupt_event != nullptr), "handle is not valid!"); + ASSERT_MSG((g_interrupt_event != nullptr), "handle is not valid!"); g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem"); Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); @@ -227,14 +225,13 @@ void SignalInterrupt(InterruptId interrupt_id) { // Update framebuffer information if requested // TODO(yuriks): Confirm where this code should be called. It is definitely updated without // executing any GSP commands, only waiting on the event. - for (int screen_id = 0; screen_id < 2; ++screen_id) { + int screen_id = (interrupt_id == InterruptId::PDC0) ? 0 : (interrupt_id == InterruptId::PDC1) ? 1 : -1; + if (screen_id != -1) { FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id); - if (info->is_dirty) { SetBufferSwap(screen_id, info->framebuffer_info[info->index]); + info->is_dirty = false; } - - info->is_dirty = false; } } g_interrupt_event->Signal(); diff --git a/src/core/hle/service/gsp_lcd.cpp b/src/core/hle/service/gsp_lcd.cpp index d63fa1ee2..9e36732b4 100644 --- a/src/core/hle/service/gsp_lcd.cpp +++ b/src/core/hle/service/gsp_lcd.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - -#include "common/log.h" #include "common/bit_field.h" #include "core/hle/service/gsp_lcd.h" diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp index 054aa8b59..8f06b224d 100644 --- a/src/core/hle/service/hid/hid_spvr.cpp +++ b/src/core/hle/service/hid/hid_spvr.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/hid/hid_spvr.h" diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp index 68edafebb..7f464705f 100644 --- a/src/core/hle/service/hid/hid_user.cpp +++ b/src/core/hle/service/hid/hid_user.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" - #include "core/hle/hle.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/shared_memory.h" diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index 6595ca572..0a3aba0a0 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/http_c.h" diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp index 31da8e160..4c26c2f03 100644 --- a/src/core/hle/service/ir_rst.cpp +++ b/src/core/hle/service/ir_rst.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/ir_rst.h" diff --git a/src/core/hle/service/ir_u.cpp b/src/core/hle/service/ir_u.cpp index 7fa233048..608ed3c06 100644 --- a/src/core/hle/service/ir_u.cpp +++ b/src/core/hle/service/ir_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/ir_u.h" diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp index 459717fff..c0c4a2344 100644 --- a/src/core/hle/service/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/ldr_ro.h" @@ -11,9 +10,69 @@ namespace LDR_RO { +/** + * LDR_RO::Initialize service function + * Inputs: + * 1 : CRS buffer pointer + * 2 : CRS Size + * 3 : Process memory address where the CRS will be mapped + * 4 : Value, must be zero + * 5 : KProcess handle + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ +static void Initialize(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 crs_buffer_ptr = cmd_buff[1]; + u32 crs_size = cmd_buff[2]; + u32 address = cmd_buff[3]; + u32 value = cmd_buff[4]; + u32 process = cmd_buff[5]; + + if (value != 0) { + LOG_ERROR(Service_LDR, "This value should be zero, but is actually %u!", value); + } + + // TODO(purpasmart96): Verify return header on HW + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_LDR, "(STUBBED) called"); +} + +/** + * LDR_RO::LoadCRR service function + * Inputs: + * 1 : CRS buffer pointer + * 2 : CRS Size + * 3 : Value, must be zero + * 4 : KProcess handle + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ +static void LoadCRR(Service::Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + u32 crs_buffer_ptr = cmd_buff[1]; + u32 crs_size = cmd_buff[2]; + u32 value = cmd_buff[3]; + u32 process = cmd_buff[4]; + + if (value != 0) { + LOG_ERROR(Service_LDR, "This value should be zero, but is actually %u!", value); + } + + // TODO(purpasmart96): Verify return header on HW + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_LDR, "(STUBBED) called"); +} + const Interface::FunctionInfo FunctionTable[] = { - {0x000100C2, nullptr, "Initialize"}, - {0x00020082, nullptr, "LoadCRR"}, + {0x000100C2, Initialize, "Initialize"}, + {0x00020082, LoadCRR, "LoadCRR"}, {0x00030042, nullptr, "UnloadCCR"}, {0x000402C2, nullptr, "LoadExeCRO"}, {0x000500C2, nullptr, "LoadCROSymbols"}, diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index af967b5b6..25e70d321 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/mic_u.h" diff --git a/src/core/hle/service/news_s.cpp b/src/core/hle/service/news_s.cpp index d7537875b..302d588c7 100644 --- a/src/core/hle/service/news_s.cpp +++ b/src/core/hle/service/news_s.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/news_s.h" diff --git a/src/core/hle/service/news_u.cpp b/src/core/hle/service/news_u.cpp index a9e161c23..7d835aa30 100644 --- a/src/core/hle/service/news_u.cpp +++ b/src/core/hle/service/news_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/news_u.h" diff --git a/src/core/hle/service/nim_aoc.cpp b/src/core/hle/service/nim_aoc.cpp index ab2ef4429..7a6aea91a 100644 --- a/src/core/hle/service/nim_aoc.cpp +++ b/src/core/hle/service/nim_aoc.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/nim_aoc.h" diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp index 61fcb54ce..88be6c8d9 100644 --- a/src/core/hle/service/nwm_uds.cpp +++ b/src/core/hle/service/nwm_uds.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/nwm_uds.h" diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp index d61eaf80f..7420a62f4 100644 --- a/src/core/hle/service/pm_app.cpp +++ b/src/core/hle/service/pm_app.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/pm_app.h" diff --git a/src/core/hle/service/ptm_play.cpp b/src/core/hle/service/ptm_play.cpp index b357057fd..f21d9088e 100644 --- a/src/core/hle/service/ptm_play.cpp +++ b/src/core/hle/service/ptm_play.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/ptm_play.h" diff --git a/src/core/hle/service/ptm_sysm.cpp b/src/core/hle/service/ptm_sysm.cpp index b6f688de3..96ef2dce0 100644 --- a/src/core/hle/service/ptm_sysm.cpp +++ b/src/core/hle/service/ptm_sysm.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "common/make_unique.h" #include "core/file_sys/archive_extsavedata.h" #include "core/hle/hle.h" diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index 7b465a348..7121d837c 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "common/make_unique.h" -#include "core/file_sys/archive_extsavedata.h" + #include "core/hle/hle.h" +#include "core/hle/service/fs/archive.h" #include "core/hle/service/ptm_u.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -28,7 +28,6 @@ struct GameCoin { u8 day; }; static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 }; -static std::unique_ptr<FileSys::Archive_ExtSaveData> ptm_shared_extsavedata; static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0}; /// Charge levels used by PTM functions @@ -138,31 +137,28 @@ const Interface::FunctionInfo FunctionTable[] = { Interface::Interface() { Register(FunctionTable); - // Create the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file - // TODO(Subv): In the future we should use the FS service to query this archive - std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); - ptm_shared_extsavedata = Common::make_unique<FileSys::Archive_ExtSaveData>(nand_directory, true); - if (!ptm_shared_extsavedata->Initialize()) { - LOG_CRITICAL(Service_PTM, "Could not initialize SharedExtSaveData archive for the PTM:U service"); - return; - } + + // Open the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file FileSys::Path archive_path(ptm_shared_extdata_id); - ResultCode result = ptm_shared_extsavedata->Open(archive_path); + auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); // If the archive didn't exist, create the files inside - if (result.description == ErrorDescription::FS_NotFormatted) { - // Format the archive to clear the directories - ptm_shared_extsavedata->Format(archive_path); + if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) { + // Format the archive to create the directories + Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); // Open it again to get a valid archive now that the folder exists - ptm_shared_extsavedata->Open(archive_path); + archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); + ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!"); + FileSys::Path gamecoin_path("gamecoin.dat"); FileSys::Mode open_mode = {}; open_mode.write_flag = 1; open_mode.create_flag = 1; // Open the file and write the default gamecoin information - auto gamecoin = ptm_shared_extsavedata->OpenFile(gamecoin_path, open_mode); - if (gamecoin != nullptr) { - gamecoin->Write(0, sizeof(GameCoin), 1, reinterpret_cast<const u8*>(&default_game_coin)); - gamecoin->Close(); + auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); + if (gamecoin_result.Succeeded()) { + auto gamecoin = gamecoin_result.MoveFrom(); + gamecoin->backend->Write(0, sizeof(GameCoin), 1, reinterpret_cast<const u8*>(&default_game_coin)); + gamecoin->backend->Close(); } } } diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 414c53c54..231ead185 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -29,7 +29,6 @@ #include <poll.h> #endif -#include "common/log.h" #include "common/scope_exit.h" #include "core/hle/hle.h" #include "core/hle/service/soc_u.h" @@ -259,7 +258,7 @@ union CTRSockAddr { break; } default: - _dbg_assert_msg_(Service_SOC, false, "Unhandled address family (sa_family) in CTRSockAddr::ToPlatform"); + ASSERT_MSG(false, "Unhandled address family (sa_family) in CTRSockAddr::ToPlatform"); break; } return result; @@ -280,7 +279,7 @@ union CTRSockAddr { break; } default: - _dbg_assert_msg_(Service_SOC, false, "Unhandled address family (sa_family) in CTRSockAddr::ToPlatform"); + ASSERT_MSG(false, "Unhandled address family (sa_family) in CTRSockAddr::ToPlatform"); break; } return result; diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp index 3f49c1c97..e634276fc 100644 --- a/src/core/hle/service/ssl_c.cpp +++ b/src/core/hle/service/ssl_c.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/service/ssl_c.h" diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index fc76d2721..a58e04d6d 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/log.h" #include "core/hle/hle.h" #include "core/hle/kernel/event.h" #include "core/hle/service/y2r_u.h" diff --git a/src/core/hle/shared_page.cpp b/src/core/hle/shared_page.cpp index 6033a53b4..f5f2a6858 100644 --- a/src/core/hle/shared_page.cpp +++ b/src/core/hle/shared_page.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "common/common_types.h" -#include "common/log.h" #include "core/core.h" #include "core/mem_map.h" diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 96da29923..17385f9b2 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -175,7 +175,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If // this happens, the running application will crash. - _assert_msg_(Kernel, out != nullptr, "invalid output pointer specified!"); + ASSERT_MSG(out != nullptr, "invalid output pointer specified!"); // Check if 'handle_count' is invalid if (handle_count < 0) diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp index 503200629..a63ba6eeb 100644 --- a/src/core/hw/hw.cpp +++ b/src/core/hw/hw.cpp @@ -88,4 +88,4 @@ void Shutdown() { LOG_DEBUG(HW, "shutdown OK"); } -}
\ No newline at end of file +} diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 52730a7b4..94dcc50f9 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -127,7 +127,7 @@ ResultStatus LoadFile(const std::string& filename) { // Load application and RomFS if (ResultStatus::Success == app_loader.Load()) { Kernel::g_program_id = app_loader.GetProgramId(); - Service::FS::CreateArchive(Common::make_unique<FileSys::Archive_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS); + Service::FS::RegisterArchiveType(Common::make_unique<FileSys::ArchiveFactory_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } break; diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp index 0e3b81b28..4f93c0e64 100644 --- a/src/core/mem_map_funcs.cpp +++ b/src/core/mem_map_funcs.cpp @@ -136,9 +136,9 @@ inline void Write(const VAddr vaddr, const T data) { *(T*)&g_dsp_mem[vaddr - DSP_MEMORY_VADDR] = data; //} else if ((vaddr & 0xFFFF0000) == 0x1FF80000) { - // _assert_msg_(MEMMAP, false, "umimplemented write to Configuration Memory"); + // ASSERT_MSG(MEMMAP, false, "umimplemented write to Configuration Memory"); //} else if ((vaddr & 0xFFFFF000) == 0x1FF81000) { - // _assert_msg_(MEMMAP, false, "umimplemented write to shared page"); + // ASSERT_MSG(MEMMAP, false, "umimplemented write to shared page"); // Error out... } else { diff --git a/src/core/settings.h b/src/core/settings.h index cedba3a98..e62dd4358 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -35,6 +35,9 @@ struct Values { // Data Storage bool use_virtual_sd; + // System Region + int region_value; + std::string log_filter; } extern values; diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 12f0009bd..8c4ec1044 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -16,7 +16,7 @@ #include <nihstro/shader_binary.h> -#include "common/log.h" +#include "common/assert.h" #include "common/file_util.h" #include "common/math_util.h" @@ -197,7 +197,7 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data it->component_mask = it->component_mask | component_mask; } } catch (const std::out_of_range& ) { - _dbg_assert_msg_(HW_GPU, 0, "Unknown output attribute mapping"); + DEBUG_ASSERT_MSG(false, "Unknown output attribute mapping"); LOG_ERROR(HW_GPU, "Unknown output attribute mapping: %03x, %03x, %03x, %03x", (int)output_attributes[i].map_x.Value(), (int)output_attributes[i].map_y.Value(), @@ -571,7 +571,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture default: LOG_ERROR(HW_GPU, "Unknown texture format: %x", (u32)info.format); - _dbg_assert_(HW_GPU, 0); + DEBUG_ASSERT(false); return {}; } } diff --git a/src/video_core/gpu_debugger.h b/src/video_core/gpu_debugger.h index a51d49c92..c2c898992 100644 --- a/src/video_core/gpu_debugger.h +++ b/src/video_core/gpu_debugger.h @@ -8,8 +8,6 @@ #include <functional> #include <vector> -#include "common/log.h" - #include "core/hle/service/gsp_gpu.h" #include "command_processor.h" diff --git a/src/video_core/primitive_assembly.cpp b/src/video_core/primitive_assembly.cpp index 242a07e26..1776a1925 100644 --- a/src/video_core/primitive_assembly.cpp +++ b/src/video_core/primitive_assembly.cpp @@ -6,6 +6,7 @@ #include "primitive_assembly.h" #include "vertex_shader.h" +#include "common/logging/log.h" #include "video_core/debug_utils/debug_utils.h" namespace Pica { diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 06fd8d140..617c767e7 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -216,7 +216,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, if (!texture.enabled) continue; - _dbg_assert_(HW_GPU, 0 != texture.config.address); + DEBUG_ASSERT(0 != texture.config.address); int s = (int)(uv[i].u() * float24::FromFloat32(static_cast<float>(texture.config.width))).ToFloat32(); int t = (int)(uv[i].v() * float24::FromFloat32(static_cast<float>(texture.config.height))).ToFloat32(); @@ -232,7 +232,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, default: LOG_ERROR(HW_GPU, "Unknown texture coordinate wrapping mode %x\n", (int)mode); - _dbg_assert_(HW_GPU, 0); + UNIMPLEMENTED(); return 0; } }; @@ -282,7 +282,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, default: LOG_ERROR(HW_GPU, "Unknown color combiner source %d\n", (int)source); - _dbg_assert_(HW_GPU, 0); + UNIMPLEMENTED(); return {}; } }; @@ -380,7 +380,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, default: LOG_ERROR(HW_GPU, "Unknown color combiner operation %d\n", (int)op); - _dbg_assert_(HW_GPU, 0); + UNIMPLEMENTED(); return {}; } }; @@ -404,7 +404,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, default: LOG_ERROR(HW_GPU, "Unknown alpha combiner operation %d\n", (int)op); - _dbg_assert_(HW_GPU, 0); + UNIMPLEMENTED(); return 0; } }; diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index e982e3746..42d0e597c 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include "gl_shader_util.h" -#include "common/log.h" +#include "common/logging/log.h" #include <vector> #include <algorithm> diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index aa47bd616..735c0cf45 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -99,15 +99,15 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& const u8* framebuffer_data = Memory::GetPointer(framebuffer_vaddr); // TODO: Handle other pixel formats - _dbg_assert_msg_(Render_OpenGL, framebuffer.color_format == GPU::Regs::PixelFormat::RGB8, + ASSERT_MSG(framebuffer.color_format == GPU::Regs::PixelFormat::RGB8, "Unsupported 3DS pixel format."); size_t pixel_stride = framebuffer.stride / 3; // OpenGL only supports specifying a stride in units of pixels, not bytes, unfortunately - _dbg_assert_(Render_OpenGL, pixel_stride * 3 == framebuffer.stride); + ASSERT(pixel_stride * 3 == framebuffer.stride); // Ensure no bad interactions with GL_UNPACK_ALIGNMENT, which by default // only allows rows to have a memory alignement of 4. - _dbg_assert_(Render_OpenGL, pixel_stride % 4 == 0); + ASSERT(pixel_stride % 4 == 0); glBindTexture(GL_TEXTURE_2D, texture.handle); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride); diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp index 48977380e..0bd52231b 100644 --- a/src/video_core/vertex_shader.cpp +++ b/src/video_core/vertex_shader.cpp @@ -146,13 +146,10 @@ static void ProcessShaderCode(VertexShaderState& state) { case Instruction::OpCodeType::Arithmetic: { bool is_inverted = 0 != (instr.opcode.GetInfo().subtype & Instruction::OpCodeInfo::SrcInversed); - if (is_inverted) { - // TODO: We don't really support this properly: For instance, the address register - // offset needs to be applied to SRC2 instead, etc. - // For now, we just abort in this situation. - LOG_CRITICAL(HW_GPU, "Bad condition..."); - exit(0); - } + // TODO: We don't really support this properly: For instance, the address register + // offset needs to be applied to SRC2 instead, etc. + // For now, we just abort in this situation. + ASSERT_MSG(!is_inverted, "Bad condition..."); const int address_offset = (instr.common.address_register_index == 0) ? 0 : state.address_registers[instr.common.address_register_index - 1]; @@ -342,7 +339,7 @@ static void ProcessShaderCode(VertexShaderState& state) { default: LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x", (int)instr.opcode.Value(), instr.opcode.GetInfo().name, instr.hex); - _dbg_assert_(HW_GPU, 0); + DEBUG_ASSERT(false); break; } diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index c9707e5f1..0a236595c 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -4,7 +4,6 @@ #include "common/common.h" #include "common/emu_window.h" -#include "common/log.h" #include "core/core.h" |