diff options
Diffstat (limited to 'src')
24 files changed, 258 insertions, 187 deletions
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 7a1360d34..b19b367e1 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp | |||
| @@ -19,8 +19,8 @@ | |||
| 19 | #include "core/settings.h" | 19 | #include "core/settings.h" |
| 20 | #include "core/system.h" | 20 | #include "core/system.h" |
| 21 | 21 | ||
| 22 | #include "video_core/video_core.h" | ||
| 23 | #include "video_core/debug_utils/debug_utils.h" | 22 | #include "video_core/debug_utils/debug_utils.h" |
| 23 | #include "video_core/video_core.h" | ||
| 24 | 24 | ||
| 25 | #define APP_NAME "citra" | 25 | #define APP_NAME "citra" |
| 26 | #define APP_VERSION "0.1-" VERSION | 26 | #define APP_VERSION "0.1-" VERSION |
| @@ -86,6 +86,9 @@ public: | |||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | void paintEvent(QPaintEvent* ev) override { | 88 | void paintEvent(QPaintEvent* ev) override { |
| 89 | if (do_painting) { | ||
| 90 | QPainter painter(this); | ||
| 91 | } | ||
| 89 | } | 92 | } |
| 90 | 93 | ||
| 91 | void resizeEvent(QResizeEvent* ev) override { | 94 | void resizeEvent(QResizeEvent* ev) override { |
| @@ -93,8 +96,12 @@ public: | |||
| 93 | parent->OnFramebufferSizeChanged(); | 96 | parent->OnFramebufferSizeChanged(); |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 99 | void DisablePainting() { do_painting = false; } | ||
| 100 | void EnablePainting() { do_painting = true; } | ||
| 101 | |||
| 96 | private: | 102 | private: |
| 97 | GRenderWindow* parent; | 103 | GRenderWindow* parent; |
| 104 | bool do_painting; | ||
| 98 | }; | 105 | }; |
| 99 | 106 | ||
| 100 | GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) : | 107 | GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) : |
| @@ -128,9 +135,6 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) : | |||
| 128 | 135 | ||
| 129 | BackupGeometry(); | 136 | BackupGeometry(); |
| 130 | 137 | ||
| 131 | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) | ||
| 132 | connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(OnFramebufferSizeChanged())); | ||
| 133 | #endif | ||
| 134 | } | 138 | } |
| 135 | 139 | ||
| 136 | void GRenderWindow::moveContext() | 140 | void GRenderWindow::moveContext() |
| @@ -273,8 +277,19 @@ void GRenderWindow::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,un | |||
| 273 | 277 | ||
| 274 | void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread) { | 278 | void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread) { |
| 275 | this->emu_thread = emu_thread; | 279 | this->emu_thread = emu_thread; |
| 280 | child->DisablePainting(); | ||
| 276 | } | 281 | } |
| 277 | 282 | ||
| 278 | void GRenderWindow::OnEmulationStopping() { | 283 | void GRenderWindow::OnEmulationStopping() { |
| 279 | emu_thread = nullptr; | 284 | emu_thread = nullptr; |
| 285 | child->EnablePainting(); | ||
| 286 | } | ||
| 287 | |||
| 288 | void GRenderWindow::showEvent(QShowEvent * event) { | ||
| 289 | QWidget::showEvent(event); | ||
| 290 | |||
| 291 | // windowHandle() is not initialized until the Window is shown, so we connect it here. | ||
| 292 | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) | ||
| 293 | connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(OnFramebufferSizeChanged()), Qt::UniqueConnection); | ||
| 294 | #endif | ||
| 280 | } | 295 | } |
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h index dc422358e..0a9d263b8 100644 --- a/src/citra_qt/bootmanager.h +++ b/src/citra_qt/bootmanager.h | |||
| @@ -12,11 +12,12 @@ | |||
| 12 | #include "common/emu_window.h" | 12 | #include "common/emu_window.h" |
| 13 | #include "common/thread.h" | 13 | #include "common/thread.h" |
| 14 | 14 | ||
| 15 | class QScreen; | ||
| 16 | class QKeyEvent; | 15 | class QKeyEvent; |
| 16 | class QScreen; | ||
| 17 | 17 | ||
| 18 | class GRenderWindow; | 18 | class GGLWidgetInternal; |
| 19 | class GMainWindow; | 19 | class GMainWindow; |
| 20 | class GRenderWindow; | ||
| 20 | 21 | ||
| 21 | class EmuThread : public QThread | 22 | class EmuThread : public QThread |
| 22 | { | 23 | { |
| @@ -123,13 +124,12 @@ public: | |||
| 123 | 124 | ||
| 124 | void OnClientAreaResized(unsigned width, unsigned height); | 125 | void OnClientAreaResized(unsigned width, unsigned height); |
| 125 | 126 | ||
| 126 | void OnFramebufferSizeChanged(); | ||
| 127 | |||
| 128 | public slots: | 127 | public slots: |
| 129 | void moveContext(); // overridden | 128 | void moveContext(); // overridden |
| 130 | 129 | ||
| 131 | void OnEmulationStarting(EmuThread* emu_thread); | 130 | void OnEmulationStarting(EmuThread* emu_thread); |
| 132 | void OnEmulationStopping(); | 131 | void OnEmulationStopping(); |
| 132 | void OnFramebufferSizeChanged(); | ||
| 133 | 133 | ||
| 134 | signals: | 134 | signals: |
| 135 | /// Emitted when the window is closed | 135 | /// Emitted when the window is closed |
| @@ -138,7 +138,7 @@ signals: | |||
| 138 | private: | 138 | private: |
| 139 | void OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) override; | 139 | void OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) override; |
| 140 | 140 | ||
| 141 | QGLWidget* child; | 141 | GGLWidgetInternal* child; |
| 142 | 142 | ||
| 143 | QByteArray geometry; | 143 | QByteArray geometry; |
| 144 | 144 | ||
| @@ -146,4 +146,7 @@ private: | |||
| 146 | int keyboard_id; | 146 | int keyboard_id; |
| 147 | 147 | ||
| 148 | EmuThread* emu_thread; | 148 | EmuThread* emu_thread; |
| 149 | |||
| 150 | protected: | ||
| 151 | void showEvent(QShowEvent* event) override; | ||
| 149 | }; | 152 | }; |
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 2fbb0f260..1e0d33313 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp | |||
| @@ -821,8 +821,8 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam | |||
| 821 | const std::string forbidden_characters = ".\"/\\[]:;=, "; | 821 | const std::string forbidden_characters = ".\"/\\[]:;=, "; |
| 822 | 822 | ||
| 823 | // On a FAT32 partition, 8.3 names are stored as a 11 bytes array, filled with spaces. | 823 | // On a FAT32 partition, 8.3 names are stored as a 11 bytes array, filled with spaces. |
| 824 | short_name = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'}; | 824 | short_name = {{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'}}; |
| 825 | extension = {' ', ' ', ' ', '\0'}; | 825 | extension = {{' ', ' ', ' ', '\0'}}; |
| 826 | 826 | ||
| 827 | std::string::size_type point = filename.rfind('.'); | 827 | std::string::size_type point = filename.rfind('.'); |
| 828 | if (point == filename.size() - 1) | 828 | if (point == filename.size() - 1) |
diff --git a/src/common/hash.cpp b/src/common/hash.cpp index 413e9c6f1..c49c2f60e 100644 --- a/src/common/hash.cpp +++ b/src/common/hash.cpp | |||
| @@ -17,27 +17,11 @@ namespace Common { | |||
| 17 | 17 | ||
| 18 | // Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do | 18 | // Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do |
| 19 | // the conversion here | 19 | // the conversion here |
| 20 | |||
| 21 | static FORCE_INLINE u32 getblock32(const u32* p, int i) { | ||
| 22 | return p[i]; | ||
| 23 | } | ||
| 24 | |||
| 25 | static FORCE_INLINE u64 getblock64(const u64* p, int i) { | 20 | static FORCE_INLINE u64 getblock64(const u64* p, int i) { |
| 26 | return p[i]; | 21 | return p[i]; |
| 27 | } | 22 | } |
| 28 | 23 | ||
| 29 | // Finalization mix - force all bits of a hash block to avalanche | 24 | // Finalization mix - force all bits of a hash block to avalanche |
| 30 | |||
| 31 | static FORCE_INLINE u32 fmix32(u32 h) { | ||
| 32 | h ^= h >> 16; | ||
| 33 | h *= 0x85ebca6b; | ||
| 34 | h ^= h >> 13; | ||
| 35 | h *= 0xc2b2ae35; | ||
| 36 | h ^= h >> 16; | ||
| 37 | |||
| 38 | return h; | ||
| 39 | } | ||
| 40 | |||
| 41 | static FORCE_INLINE u64 fmix64(u64 k) { | 25 | static FORCE_INLINE u64 fmix64(u64 k) { |
| 42 | k ^= k >> 33; | 26 | k ^= k >> 33; |
| 43 | k *= 0xff51afd7ed558ccdllu; | 27 | k *= 0xff51afd7ed558ccdllu; |
diff --git a/src/common/symbols.cpp b/src/common/symbols.cpp index f23e51c9d..db8340043 100644 --- a/src/common/symbols.cpp +++ b/src/common/symbols.cpp | |||
| @@ -8,46 +8,43 @@ TSymbolsMap g_symbols; | |||
| 8 | 8 | ||
| 9 | namespace Symbols | 9 | namespace Symbols |
| 10 | { | 10 | { |
| 11 | bool HasSymbol(u32 _address) | 11 | bool HasSymbol(u32 address) |
| 12 | { | 12 | { |
| 13 | return g_symbols.find(_address) != g_symbols.end(); | 13 | return g_symbols.find(address) != g_symbols.end(); |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | void Add(u32 _address, const std::string& _name, u32 _size, u32 _type) | 16 | void Add(u32 address, const std::string& name, u32 size, u32 type) |
| 17 | { | 17 | { |
| 18 | if (!HasSymbol(_address)) | 18 | if (!HasSymbol(address)) |
| 19 | { | 19 | { |
| 20 | TSymbol symbol; | 20 | TSymbol symbol; |
| 21 | symbol.address = _address; | 21 | symbol.address = address; |
| 22 | symbol.name = _name; | 22 | symbol.name = name; |
| 23 | symbol.size = _size; | 23 | symbol.size = size; |
| 24 | symbol.type = _type; | 24 | symbol.type = type; |
| 25 | 25 | ||
| 26 | g_symbols.insert(TSymbolsPair(_address, symbol)); | 26 | g_symbols.emplace(address, symbol); |
| 27 | } | 27 | } |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | TSymbol GetSymbol(u32 _address) | 30 | TSymbol GetSymbol(u32 address) |
| 31 | { | 31 | { |
| 32 | TSymbolsMap::iterator foundSymbolItr; | 32 | const auto iter = g_symbols.find(address); |
| 33 | TSymbol symbol; | ||
| 34 | 33 | ||
| 35 | foundSymbolItr = g_symbols.find(_address); | 34 | if (iter != g_symbols.end()) |
| 36 | if (foundSymbolItr != g_symbols.end()) | 35 | return iter->second; |
| 37 | { | ||
| 38 | symbol = (*foundSymbolItr).second; | ||
| 39 | } | ||
| 40 | 36 | ||
| 41 | return symbol; | 37 | return {}; |
| 42 | } | 38 | } |
| 43 | const std::string GetName(u32 _address) | 39 | |
| 40 | const std::string GetName(u32 address) | ||
| 44 | { | 41 | { |
| 45 | return GetSymbol(_address).name; | 42 | return GetSymbol(address).name; |
| 46 | } | 43 | } |
| 47 | 44 | ||
| 48 | void Remove(u32 _address) | 45 | void Remove(u32 address) |
| 49 | { | 46 | { |
| 50 | g_symbols.erase(_address); | 47 | g_symbols.erase(address); |
| 51 | } | 48 | } |
| 52 | 49 | ||
| 53 | void Clear() | 50 | void Clear() |
diff --git a/src/common/symbols.h b/src/common/symbols.h index 6b62b011e..5ed16009c 100644 --- a/src/common/symbols.h +++ b/src/common/symbols.h | |||
| @@ -12,15 +12,10 @@ | |||
| 12 | 12 | ||
| 13 | struct TSymbol | 13 | struct TSymbol |
| 14 | { | 14 | { |
| 15 | TSymbol() : | 15 | u32 address = 0; |
| 16 | address(0), | ||
| 17 | size(0), | ||
| 18 | type(0) | ||
| 19 | {} | ||
| 20 | u32 address; | ||
| 21 | std::string name; | 16 | std::string name; |
| 22 | u32 size; | 17 | u32 size = 0; |
| 23 | u32 type; | 18 | u32 type = 0; |
| 24 | }; | 19 | }; |
| 25 | 20 | ||
| 26 | typedef std::map<u32, TSymbol> TSymbolsMap; | 21 | typedef std::map<u32, TSymbol> TSymbolsMap; |
| @@ -28,12 +23,12 @@ typedef std::pair<u32, TSymbol> TSymbolsPair; | |||
| 28 | 23 | ||
| 29 | namespace Symbols | 24 | namespace Symbols |
| 30 | { | 25 | { |
| 31 | bool HasSymbol(u32 _address); | 26 | bool HasSymbol(u32 address); |
| 32 | 27 | ||
| 33 | void Add(u32 _address, const std::string& _name, u32 _size, u32 _type); | 28 | void Add(u32 address, const std::string& name, u32 size, u32 type); |
| 34 | TSymbol GetSymbol(u32 _address); | 29 | TSymbol GetSymbol(u32 address); |
| 35 | const std::string GetName(u32 _address); | 30 | const std::string GetName(u32 address); |
| 36 | void Remove(u32 _address); | 31 | void Remove(u32 address); |
| 37 | void Clear(); | 32 | void Clear(); |
| 38 | } | 33 | } |
| 39 | 34 | ||
diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h index b364e2621..ceb159d14 100644 --- a/src/core/arm/skyeye_common/armstate.h +++ b/src/core/arm/skyeye_common/armstate.h | |||
| @@ -247,6 +247,5 @@ private: | |||
| 247 | static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8; | 247 | static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8; |
| 248 | 248 | ||
| 249 | u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode | 249 | u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode |
| 250 | u32 exclusive_result; | ||
| 251 | bool exclusive_state; | 250 | bool exclusive_state; |
| 252 | }; | 251 | }; |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 56615502c..aba22cdd1 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <atomic> | 5 | #include <atomic> |
| 6 | #include <cinttypes> | ||
| 6 | #include <mutex> | 7 | #include <mutex> |
| 7 | #include <vector> | 8 | #include <vector> |
| 8 | 9 | ||
| @@ -530,7 +531,7 @@ void Idle(int max_idle) { | |||
| 530 | } | 531 | } |
| 531 | } | 532 | } |
| 532 | 533 | ||
| 533 | LOG_TRACE(Core_Timing, "Idle for %i cycles! (%f ms)", cycles_down, cycles_down / (float)(g_clock_rate_arm11 * 0.001f)); | 534 | LOG_TRACE(Core_Timing, "Idle for %" PRId64 " cycles! (%f ms)", cycles_down, cycles_down / (float)(g_clock_rate_arm11 * 0.001f)); |
| 534 | 535 | ||
| 535 | idled_cycles += cycles_down; | 536 | idled_cycles += cycles_down; |
| 536 | Core::g_app_core->down_count -= cycles_down; | 537 | Core::g_app_core->down_count -= cycles_down; |
diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index e16aa1491..441ca9b53 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp | |||
| @@ -62,7 +62,7 @@ std::unique_ptr<DirectoryBackend> IVFCArchive::OpenDirectory(const Path& path) c | |||
| 62 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 62 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 63 | 63 | ||
| 64 | size_t IVFCFile::Read(const u64 offset, const size_t length, u8* buffer) const { | 64 | size_t IVFCFile::Read(const u64 offset, const size_t length, u8* buffer) const { |
| 65 | LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); | 65 | LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length); |
| 66 | romfs_file->Seek(data_offset + offset, SEEK_SET); | 66 | romfs_file->Seek(data_offset + offset, SEEK_SET); |
| 67 | size_t read_length = (size_t)std::min((u64)length, data_size - offset); | 67 | size_t read_length = (size_t)std::min((u64)length, data_size - offset); |
| 68 | 68 | ||
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 8aa4110a6..08b3ea8c0 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cinttypes> | ||
| 6 | |||
| 5 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 6 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 7 | 9 | ||
| @@ -71,11 +73,11 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |||
| 71 | SharedPtr<Timer> timer = timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle)); | 73 | SharedPtr<Timer> timer = timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle)); |
| 72 | 74 | ||
| 73 | if (timer == nullptr) { | 75 | if (timer == nullptr) { |
| 74 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08lX", timer_handle); | 76 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08" PRIx64, timer_handle); |
| 75 | return; | 77 | return; |
| 76 | } | 78 | } |
| 77 | 79 | ||
| 78 | LOG_TRACE(Kernel, "Timer %u fired", timer_handle); | 80 | LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle); |
| 79 | 81 | ||
| 80 | timer->signaled = true; | 82 | timer->signaled = true; |
| 81 | 83 | ||
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 62ad90fdc..56986a49e 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp | |||
| @@ -21,28 +21,67 @@ | |||
| 21 | namespace Service { | 21 | namespace Service { |
| 22 | namespace CFG { | 22 | namespace CFG { |
| 23 | 23 | ||
| 24 | const u64 CFG_SAVE_ID = 0x00010017; | 24 | /// The maximum number of block entries that can exist in the config file |
| 25 | const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE; | 25 | static const u32 CONFIG_FILE_MAX_BLOCK_ENTRIES = 1479; |
| 26 | const ConsoleModelInfo CONSOLE_MODEL = { NINTENDO_3DS_XL, { 0, 0, 0 } }; | 26 | |
| 27 | const u8 CONSOLE_LANGUAGE = LANGUAGE_EN; | 27 | namespace { |
| 28 | const char CONSOLE_USERNAME[0x14] = "CITRA"; | 28 | |
| 29 | /** | ||
| 30 | * The header of the config savedata file, | ||
| 31 | * contains information about the blocks in the file | ||
| 32 | */ | ||
| 33 | struct SaveFileConfig { | ||
| 34 | u16 total_entries; ///< The total number of set entries in the config file | ||
| 35 | u16 data_entries_offset; ///< The offset where the data for the blocks start, this is hardcoded to 0x455C as per hardware | ||
| 36 | SaveConfigBlockEntry block_entries[CONFIG_FILE_MAX_BLOCK_ENTRIES]; ///< The block headers, the maximum possible value is 1479 as per hardware | ||
| 37 | u32 unknown; ///< This field is unknown, possibly padding, 0 has been observed in hardware | ||
| 38 | }; | ||
| 39 | static_assert(sizeof(SaveFileConfig) == 0x455C, "SaveFileConfig header must be exactly 0x455C bytes"); | ||
| 40 | |||
| 41 | struct UsernameBlock { | ||
| 42 | char16_t username[10]; ///< Exactly 20 bytes long, padded with zeros at the end if necessary | ||
| 43 | u32 zero; | ||
| 44 | u32 ng_word; | ||
| 45 | }; | ||
| 46 | static_assert(sizeof(UsernameBlock) == 0x1C, "UsernameBlock must be exactly 0x1C bytes"); | ||
| 47 | |||
| 48 | struct ConsoleModelInfo { | ||
| 49 | u8 model; ///< The console model (3DS, 2DS, etc) | ||
| 50 | u8 unknown[3]; ///< Unknown data | ||
| 51 | }; | ||
| 52 | static_assert(sizeof(ConsoleModelInfo) == 4, "ConsoleModelInfo must be exactly 4 bytes"); | ||
| 53 | |||
| 54 | struct ConsoleCountryInfo { | ||
| 55 | u8 unknown[3]; ///< Unknown data | ||
| 56 | u8 country_code; ///< The country code of the console | ||
| 57 | }; | ||
| 58 | static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes"); | ||
| 59 | |||
| 60 | } | ||
| 61 | |||
| 62 | static const u64 CFG_SAVE_ID = 0x00010017; | ||
| 63 | static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE; | ||
| 64 | static const ConsoleModelInfo CONSOLE_MODEL = { NINTENDO_3DS_XL, { 0, 0, 0 } }; | ||
| 65 | static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN; | ||
| 66 | static const char CONSOLE_USERNAME[0x14] = "CITRA"; | ||
| 29 | /// This will be initialized in Init, and will be used when creating the block | 67 | /// This will be initialized in Init, and will be used when creating the block |
| 30 | UsernameBlock CONSOLE_USERNAME_BLOCK; | 68 | static UsernameBlock CONSOLE_USERNAME_BLOCK; |
| 31 | /// TODO(Subv): Find out what this actually is | 69 | /// TODO(Subv): Find out what this actually is |
| 32 | const u8 SOUND_OUTPUT_MODE = 2; | 70 | static const u8 SOUND_OUTPUT_MODE = 2; |
| 33 | const u8 UNITED_STATES_COUNTRY_ID = 49; | 71 | static const u8 UNITED_STATES_COUNTRY_ID = 49; |
| 34 | /// TODO(Subv): Find what the other bytes are | 72 | /// TODO(Subv): Find what the other bytes are |
| 35 | const ConsoleCountryInfo COUNTRY_INFO = { { 0, 0, 0 }, UNITED_STATES_COUNTRY_ID }; | 73 | static const ConsoleCountryInfo COUNTRY_INFO = { { 0, 0, 0 }, UNITED_STATES_COUNTRY_ID }; |
| 36 | 74 | ||
| 37 | /** | 75 | /** |
| 38 | * TODO(Subv): Find out what this actually is, these values fix some NaN uniforms in some games, | 76 | * TODO(Subv): Find out what this actually is, these values fix some NaN uniforms in some games, |
| 39 | * for example Nintendo Zone | 77 | * for example Nintendo Zone |
| 40 | * Thanks Normmatt for providing this information | 78 | * Thanks Normmatt for providing this information |
| 41 | */ | 79 | */ |
| 42 | const std::array<float, 8> STEREO_CAMERA_SETTINGS = { | 80 | static const std::array<float, 8> STEREO_CAMERA_SETTINGS = {{ |
| 43 | 62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f, | 81 | 62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f, |
| 44 | 10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f | 82 | 10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f |
| 45 | }; | 83 | }}; |
| 84 | static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes"); | ||
| 46 | 85 | ||
| 47 | static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; | 86 | static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; |
| 48 | static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; | 87 | static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; |
| @@ -212,7 +251,7 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { | |||
| 212 | return RESULT_SUCCESS; | 251 | return RESULT_SUCCESS; |
| 213 | } | 252 | } |
| 214 | 253 | ||
| 215 | ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const u8* data) { | 254 | ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* data) { |
| 216 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | 255 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); |
| 217 | if (config->total_entries >= CONFIG_FILE_MAX_BLOCK_ENTRIES) | 256 | if (config->total_entries >= CONFIG_FILE_MAX_BLOCK_ENTRIES) |
| 218 | return ResultCode(-1); // TODO(Subv): Find the right error code | 257 | return ResultCode(-1); // TODO(Subv): Find the right error code |
| @@ -277,33 +316,63 @@ ResultCode FormatConfig() { | |||
| 277 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | 316 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); |
| 278 | // This value is hardcoded, taken from 3dbrew, verified by hardware, it's always the same value | 317 | // This value is hardcoded, taken from 3dbrew, verified by hardware, it's always the same value |
| 279 | config->data_entries_offset = 0x455C; | 318 | config->data_entries_offset = 0x455C; |
| 319 | |||
| 280 | // Insert the default blocks | 320 | // Insert the default blocks |
| 281 | res = CreateConfigInfoBlk(0x00050005, sizeof(STEREO_CAMERA_SETTINGS), 0xE, | 321 | u8 zero_buffer[0xC0] = {}; |
| 282 | reinterpret_cast<const u8*>(STEREO_CAMERA_SETTINGS.data())); | 322 | |
| 283 | if (!res.IsSuccess()) | 323 | // 0x00030001 - Unknown |
| 284 | return res; | 324 | res = CreateConfigInfoBlk(0x00030001, 0x8, 0xE, zero_buffer); |
| 285 | res = CreateConfigInfoBlk(0x00090001, sizeof(CONSOLE_UNIQUE_ID), 0xE, | 325 | if (!res.IsSuccess()) return res; |
| 286 | reinterpret_cast<const u8*>(&CONSOLE_UNIQUE_ID)); | 326 | |
| 287 | if (!res.IsSuccess()) | 327 | res = CreateConfigInfoBlk(0x00050005, sizeof(STEREO_CAMERA_SETTINGS), 0xE, STEREO_CAMERA_SETTINGS.data()); |
| 288 | return res; | 328 | if (!res.IsSuccess()) return res; |
| 289 | res = CreateConfigInfoBlk(0x000F0004, sizeof(CONSOLE_MODEL), 0x8, | ||
| 290 | reinterpret_cast<const u8*>(&CONSOLE_MODEL)); | ||
| 291 | if (!res.IsSuccess()) | ||
| 292 | return res; | ||
| 293 | res = CreateConfigInfoBlk(0x000A0002, sizeof(CONSOLE_LANGUAGE), 0xA, &CONSOLE_LANGUAGE); | ||
| 294 | if (!res.IsSuccess()) | ||
| 295 | return res; | ||
| 296 | res = CreateConfigInfoBlk(0x00070001, sizeof(SOUND_OUTPUT_MODE), 0xE, &SOUND_OUTPUT_MODE); | 329 | res = CreateConfigInfoBlk(0x00070001, sizeof(SOUND_OUTPUT_MODE), 0xE, &SOUND_OUTPUT_MODE); |
| 297 | if (!res.IsSuccess()) | 330 | if (!res.IsSuccess()) return res; |
| 298 | return res; | 331 | res = CreateConfigInfoBlk(0x00090001, sizeof(CONSOLE_UNIQUE_ID), 0xE, &CONSOLE_UNIQUE_ID); |
| 299 | res = CreateConfigInfoBlk(0x000B0000, sizeof(COUNTRY_INFO), 0xE, | 332 | if (!res.IsSuccess()) return res; |
| 300 | reinterpret_cast<const u8*>(&COUNTRY_INFO)); | 333 | res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, &CONSOLE_USERNAME_BLOCK); |
| 301 | if (!res.IsSuccess()) | 334 | if (!res.IsSuccess()) return res; |
| 302 | return res; | 335 | |
| 303 | res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, | 336 | // 0x000A0001 - Profile birthday |
| 304 | reinterpret_cast<const u8*>(&CONSOLE_USERNAME_BLOCK)); | 337 | const u8 profile_birthday[2] = {3, 25}; // March 25th, 2014 |
| 305 | if (!res.IsSuccess()) | 338 | res = CreateConfigInfoBlk(0x000A0001, sizeof(profile_birthday), 0xE, profile_birthday); |
| 306 | return res; | 339 | if (!res.IsSuccess()) return res; |
| 340 | |||
| 341 | res = CreateConfigInfoBlk(0x000A0002, sizeof(CONSOLE_LANGUAGE), 0xE, &CONSOLE_LANGUAGE); | ||
| 342 | if (!res.IsSuccess()) return res; | ||
| 343 | res = CreateConfigInfoBlk(0x000B0000, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO); | ||
| 344 | if (!res.IsSuccess()) return res; | ||
| 345 | |||
| 346 | char16_t country_name_buffer[16][0x40] = {}; | ||
| 347 | for (size_t i = 0; i < 16; ++i) { | ||
| 348 | Common::UTF8ToUTF16("Gensokyo").copy(country_name_buffer[i], 0x40); | ||
| 349 | } | ||
| 350 | // 0x000B0001 - Localized names for the profile Country | ||
| 351 | res = CreateConfigInfoBlk(0x000B0001, sizeof(country_name_buffer), 0xE, country_name_buffer); | ||
| 352 | if (!res.IsSuccess()) return res; | ||
| 353 | // 0x000B0002 - Localized names for the profile State/Province | ||
| 354 | res = CreateConfigInfoBlk(0x000B0002, sizeof(country_name_buffer), 0xE, country_name_buffer); | ||
| 355 | if (!res.IsSuccess()) return res; | ||
| 356 | |||
| 357 | // 0x000B0003 - Unknown, related to country/address (zip code?) | ||
| 358 | res = CreateConfigInfoBlk(0x000B0003, 0x4, 0xE, zero_buffer); | ||
| 359 | if (!res.IsSuccess()) return res; | ||
| 360 | |||
| 361 | // 0x000C0000 - Unknown | ||
| 362 | res = CreateConfigInfoBlk(0x000C0000, 0xC0, 0xE, zero_buffer); | ||
| 363 | if (!res.IsSuccess()) return res; | ||
| 364 | |||
| 365 | // 0x000C0001 - Unknown | ||
| 366 | res = CreateConfigInfoBlk(0x000C0001, 0x14, 0xE, zero_buffer); | ||
| 367 | if (!res.IsSuccess()) return res; | ||
| 368 | |||
| 369 | // 0x000D0000 - Accepted EULA version | ||
| 370 | res = CreateConfigInfoBlk(0x000D0000, 0x4, 0xE, zero_buffer); | ||
| 371 | if (!res.IsSuccess()) return res; | ||
| 372 | |||
| 373 | res = CreateConfigInfoBlk(0x000F0004, sizeof(CONSOLE_MODEL), 0xC, &CONSOLE_MODEL); | ||
| 374 | if (!res.IsSuccess()) return res; | ||
| 375 | |||
| 307 | // Save the buffer to the file | 376 | // Save the buffer to the file |
| 308 | res = UpdateConfigNANDSavegame(); | 377 | res = UpdateConfigNANDSavegame(); |
| 309 | if (!res.IsSuccess()) | 378 | if (!res.IsSuccess()) |
diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h index ff76dc9dc..fc2a16a04 100644 --- a/src/core/hle/service/cfg/cfg.h +++ b/src/core/hle/service/cfg/cfg.h | |||
| @@ -41,10 +41,11 @@ struct SaveConfigBlockEntry { | |||
| 41 | u16 flags; ///< The flags of the block, possibly used for access control | 41 | u16 flags; ///< The flags of the block, possibly used for access control |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | // TODO(Link Mauve): use a constexpr once MSVC starts supporting it. | 44 | static constexpr u16 C(const char code[2]) { |
| 45 | #define C(code) ((code)[0] | ((code)[1] << 8)) | 45 | return code[0] | (code[1] << 8); |
| 46 | } | ||
| 46 | 47 | ||
| 47 | static const std::array<u16, 187> country_codes = { | 48 | static const std::array<u16, 187> country_codes = {{ |
| 48 | 0, C("JP"), 0, 0, 0, 0, 0, 0, // 0-7 | 49 | 0, C("JP"), 0, 0, 0, 0, 0, 0, // 0-7 |
| 49 | C("AI"), C("AG"), C("AR"), C("AW"), C("BS"), C("BB"), C("BZ"), C("BO"), // 8-15 | 50 | C("AI"), C("AG"), C("AR"), C("AW"), C("BS"), C("BB"), C("BZ"), C("BO"), // 8-15 |
| 50 | C("BR"), C("VG"), C("CA"), C("KY"), C("CL"), C("CO"), C("CR"), C("DM"), // 16-23 | 51 | C("BR"), C("VG"), C("CA"), C("KY"), C("CL"), C("CO"), C("CR"), C("DM"), // 16-23 |
| @@ -69,9 +70,7 @@ static const std::array<u16, 187> country_codes = { | |||
| 69 | C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175 | 70 | C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175 |
| 70 | C("BH"), C("JO"), 0, 0, 0, 0, 0, 0, // 176-183 | 71 | C("BH"), C("JO"), 0, 0, 0, 0, 0, 0, // 176-183 |
| 71 | C("SM"), C("VA"), C("BM") // 184-186 | 72 | C("SM"), C("VA"), C("BM") // 184-186 |
| 72 | }; | 73 | }}; |
| 73 | |||
| 74 | #undef C | ||
| 75 | 74 | ||
| 76 | /** | 75 | /** |
| 77 | * CFG::GetCountryCodeString service function | 76 | * CFG::GetCountryCodeString service function |
| @@ -204,59 +203,6 @@ void UpdateConfigNANDSavegame(Service::Interface* self); | |||
| 204 | */ | 203 | */ |
| 205 | void FormatConfig(Service::Interface* self); | 204 | void FormatConfig(Service::Interface* self); |
| 206 | 205 | ||
| 207 | /// The maximum number of block entries that can exist in the config file | ||
| 208 | static const u32 CONFIG_FILE_MAX_BLOCK_ENTRIES = 1479; | ||
| 209 | |||
| 210 | /** | ||
| 211 | * The header of the config savedata file, | ||
| 212 | * contains information about the blocks in the file | ||
| 213 | */ | ||
| 214 | struct SaveFileConfig { | ||
| 215 | u16 total_entries; ///< The total number of set entries in the config file | ||
| 216 | u16 data_entries_offset; ///< The offset where the data for the blocks start, this is hardcoded to 0x455C as per hardware | ||
| 217 | SaveConfigBlockEntry block_entries[CONFIG_FILE_MAX_BLOCK_ENTRIES]; ///< The block headers, the maximum possible value is 1479 as per hardware | ||
| 218 | u32 unknown; ///< This field is unknown, possibly padding, 0 has been observed in hardware | ||
| 219 | }; | ||
| 220 | static_assert(sizeof(SaveFileConfig) == 0x455C, "The SaveFileConfig header must be exactly 0x455C bytes"); | ||
| 221 | |||
| 222 | struct UsernameBlock { | ||
| 223 | char16_t username[10]; ///< Exactly 20 bytes long, padded with zeros at the end if necessary | ||
| 224 | u32 zero; | ||
| 225 | u32 ng_word; | ||
| 226 | }; | ||
| 227 | static_assert(sizeof(UsernameBlock) == 0x1C, "Size of UsernameBlock must be 0x1C"); | ||
| 228 | |||
| 229 | struct ConsoleModelInfo { | ||
| 230 | u8 model; ///< The console model (3DS, 2DS, etc) | ||
| 231 | u8 unknown[3]; ///< Unknown data | ||
| 232 | }; | ||
| 233 | static_assert(sizeof(ConsoleModelInfo) == 4, "ConsoleModelInfo must be exactly 4 bytes"); | ||
| 234 | |||
| 235 | struct ConsoleCountryInfo { | ||
| 236 | u8 unknown[3]; ///< Unknown data | ||
| 237 | u8 country_code; ///< The country code of the console | ||
| 238 | }; | ||
| 239 | static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes"); | ||
| 240 | |||
| 241 | extern const u64 CFG_SAVE_ID; | ||
| 242 | extern const u64 CONSOLE_UNIQUE_ID; | ||
| 243 | extern const ConsoleModelInfo CONSOLE_MODEL; | ||
| 244 | extern const u8 CONSOLE_LANGUAGE; | ||
| 245 | extern const char CONSOLE_USERNAME[0x14]; | ||
| 246 | /// This will be initialized in the Interface constructor, and will be used when creating the block | ||
| 247 | extern UsernameBlock CONSOLE_USERNAME_BLOCK; | ||
| 248 | /// TODO(Subv): Find out what this actually is | ||
| 249 | extern const u8 SOUND_OUTPUT_MODE; | ||
| 250 | extern const u8 UNITED_STATES_COUNTRY_ID; | ||
| 251 | /// TODO(Subv): Find what the other bytes are | ||
| 252 | extern const ConsoleCountryInfo COUNTRY_INFO; | ||
| 253 | extern const std::array<float, 8> STEREO_CAMERA_SETTINGS; | ||
| 254 | |||
| 255 | static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes"); | ||
| 256 | static_assert(sizeof(CONSOLE_UNIQUE_ID) == 8, "CONSOLE_UNIQUE_ID must be exactly 8 bytes"); | ||
| 257 | static_assert(sizeof(CONSOLE_LANGUAGE) == 1, "CONSOLE_LANGUAGE must be exactly 1 byte"); | ||
| 258 | static_assert(sizeof(SOUND_OUTPUT_MODE) == 1, "SOUND_OUTPUT_MODE must be exactly 1 byte"); | ||
| 259 | |||
| 260 | /** | 206 | /** |
| 261 | * Reads a block with the specified id and flag from the Config savegame buffer | 207 | * Reads a block with the specified id and flag from the Config savegame buffer |
| 262 | * and writes the output to output. | 208 | * and writes the output to output. |
| @@ -278,7 +224,7 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output); | |||
| 278 | * @param data A pointer containing the data we will write to the new block | 224 | * @param data A pointer containing the data we will write to the new block |
| 279 | * @returns ResultCode indicating the result of the operation, 0 on success | 225 | * @returns ResultCode indicating the result of the operation, 0 on success |
| 280 | */ | 226 | */ |
| 281 | ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const u8* data); | 227 | ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* data); |
| 282 | 228 | ||
| 283 | /** | 229 | /** |
| 284 | * Deletes the config savegame file from the filesystem, the buffer in memory is not affected | 230 | * Deletes the config savegame file from the filesystem, the buffer in memory is not affected |
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index a8cb15d60..ce5619069 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp | |||
| @@ -212,10 +212,10 @@ static void ReadPipeIfPossible(Service::Interface* self) { | |||
| 212 | 212 | ||
| 213 | // Canned DSP responses that games expect. These were taken from HW by 3dmoo team. | 213 | // Canned DSP responses that games expect. These were taken from HW by 3dmoo team. |
| 214 | // TODO: Remove this hack :) | 214 | // TODO: Remove this hack :) |
| 215 | static const std::array<u16, 16> canned_read_pipe = { | 215 | static const std::array<u16, 16> canned_read_pipe = {{ |
| 216 | 0x000F, 0xBFFF, 0x9E8E, 0x8680, 0xA78E, 0x9430, 0x8400, 0x8540, | 216 | 0x000F, 0xBFFF, 0x9E8E, 0x8680, 0xA78E, 0x9430, 0x8400, 0x8540, |
| 217 | 0x948E, 0x8710, 0x8410, 0xA90E, 0xAA0E, 0xAACE, 0xAC4E, 0xAC58 | 217 | 0x948E, 0x8710, 0x8410, 0xA90E, 0xAA0E, 0xAACE, 0xAC4E, 0xAC58 |
| 218 | }; | 218 | }}; |
| 219 | 219 | ||
| 220 | u32 initial_size = read_pipe_count; | 220 | u32 initial_size = read_pipe_count; |
| 221 | 221 | ||
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index c35b13b25..2e1e5c3e9 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -35,14 +35,14 @@ static Kernel::SharedPtr<Kernel::Event> event_debug_pad; | |||
| 35 | static u32 next_pad_index; | 35 | static u32 next_pad_index; |
| 36 | static u32 next_touch_index; | 36 | static u32 next_touch_index; |
| 37 | 37 | ||
| 38 | const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping = { | 38 | const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping = {{ |
| 39 | Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y, | 39 | Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y, |
| 40 | Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR, | 40 | Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR, |
| 41 | Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE, | 41 | Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE, |
| 42 | Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT, | 42 | Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT, |
| 43 | Service::HID::PAD_CIRCLE_UP, Service::HID::PAD_CIRCLE_DOWN, Service::HID::PAD_CIRCLE_LEFT, Service::HID::PAD_CIRCLE_RIGHT, | 43 | Service::HID::PAD_CIRCLE_UP, Service::HID::PAD_CIRCLE_DOWN, Service::HID::PAD_CIRCLE_LEFT, Service::HID::PAD_CIRCLE_RIGHT, |
| 44 | Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT | 44 | Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT |
| 45 | }; | 45 | }}; |
| 46 | 46 | ||
| 47 | 47 | ||
| 48 | // TODO(peachum): | 48 | // TODO(peachum): |
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 530837d08..111b6a409 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -62,6 +62,10 @@ struct THREEDSX_Header | |||
| 62 | // Sizes of the code, rodata and data segments + | 62 | // Sizes of the code, rodata and data segments + |
| 63 | // size of the BSS section (uninitialized latter half of the data segment) | 63 | // size of the BSS section (uninitialized latter half of the data segment) |
| 64 | u32 code_seg_size, rodata_seg_size, data_seg_size, bss_size; | 64 | u32 code_seg_size, rodata_seg_size, data_seg_size, bss_size; |
| 65 | // offset and size of smdh | ||
| 66 | u32 smdh_offset, smdh_size; | ||
| 67 | // offset to filesystem | ||
| 68 | u32 fs_offset; | ||
| 65 | }; | 69 | }; |
| 66 | 70 | ||
| 67 | // Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts. | 71 | // Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts. |
| @@ -267,4 +271,40 @@ ResultStatus AppLoader_THREEDSX::Load() { | |||
| 267 | return ResultStatus::Success; | 271 | return ResultStatus::Success; |
| 268 | } | 272 | } |
| 269 | 273 | ||
| 274 | ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { | ||
| 275 | if (!file.IsOpen()) | ||
| 276 | return ResultStatus::Error; | ||
| 277 | |||
| 278 | // Reset read pointer in case this file has been read before. | ||
| 279 | file.Seek(0, SEEK_SET); | ||
| 280 | |||
| 281 | THREEDSX_Header hdr; | ||
| 282 | if (file.ReadBytes(&hdr, sizeof(THREEDSX_Header)) != sizeof(THREEDSX_Header)) | ||
| 283 | return ResultStatus::Error; | ||
| 284 | |||
| 285 | if (hdr.header_size != sizeof(THREEDSX_Header)) | ||
| 286 | return ResultStatus::Error; | ||
| 287 | |||
| 288 | // Check if the 3DSX has a RomFS... | ||
| 289 | if (hdr.fs_offset != 0) { | ||
| 290 | u32 romfs_offset = hdr.fs_offset; | ||
| 291 | u32 romfs_size = file.GetSize() - hdr.fs_offset; | ||
| 292 | |||
| 293 | LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset); | ||
| 294 | LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size); | ||
| 295 | |||
| 296 | // We reopen the file, to allow its position to be independent from file's | ||
| 297 | romfs_file = std::make_shared<FileUtil::IOFile>(filepath, "rb"); | ||
| 298 | if (!romfs_file->IsOpen()) | ||
| 299 | return ResultStatus::Error; | ||
| 300 | |||
| 301 | offset = romfs_offset; | ||
| 302 | size = romfs_size; | ||
| 303 | |||
| 304 | return ResultStatus::Success; | ||
| 305 | } | ||
| 306 | LOG_DEBUG(Loader, "3DSX has no RomFS"); | ||
| 307 | return ResultStatus::ErrorNotUsed; | ||
| 308 | } | ||
| 309 | |||
| 270 | } // namespace Loader | 310 | } // namespace Loader |
diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h index a0aa0c533..365ddb7a5 100644 --- a/src/core/loader/3dsx.h +++ b/src/core/loader/3dsx.h | |||
| @@ -17,8 +17,8 @@ namespace Loader { | |||
| 17 | /// Loads an 3DSX file | 17 | /// Loads an 3DSX file |
| 18 | class AppLoader_THREEDSX final : public AppLoader { | 18 | class AppLoader_THREEDSX final : public AppLoader { |
| 19 | public: | 19 | public: |
| 20 | AppLoader_THREEDSX(FileUtil::IOFile&& file, std::string filename) | 20 | AppLoader_THREEDSX(FileUtil::IOFile&& file, std::string filename, const std::string& filepath) |
| 21 | : AppLoader(std::move(file)), filename(std::move(filename)) {} | 21 | : AppLoader(std::move(file)), filename(std::move(filename)), filepath(filepath) {} |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * Returns the type of the file | 24 | * Returns the type of the file |
| @@ -33,8 +33,18 @@ public: | |||
| 33 | */ | 33 | */ |
| 34 | ResultStatus Load() override; | 34 | ResultStatus Load() override; |
| 35 | 35 | ||
| 36 | /** | ||
| 37 | * Get the RomFS of the application | ||
| 38 | * @param romfs_file Reference to buffer to store data | ||
| 39 | * @param offset Offset in the file to the RomFS | ||
| 40 | * @param size Size of the RomFS in bytes | ||
| 41 | * @return ResultStatus result of function | ||
| 42 | */ | ||
| 43 | ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override; | ||
| 44 | |||
| 36 | private: | 45 | private: |
| 37 | std::string filename; | 46 | std::string filename; |
| 47 | std::string filepath; | ||
| 38 | }; | 48 | }; |
| 39 | 49 | ||
| 40 | } // namespace Loader | 50 | } // namespace Loader |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index b1902dcca..6b88169e1 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -116,7 +116,15 @@ ResultStatus LoadFile(const std::string& filename) { | |||
| 116 | 116 | ||
| 117 | //3DSX file format... | 117 | //3DSX file format... |
| 118 | case FileType::THREEDSX: | 118 | case FileType::THREEDSX: |
| 119 | return AppLoader_THREEDSX(std::move(file), filename_filename).Load(); | 119 | { |
| 120 | AppLoader_THREEDSX app_loader(std::move(file), filename_filename, filename); | ||
| 121 | // Load application and RomFS | ||
| 122 | if (ResultStatus::Success == app_loader.Load()) { | ||
| 123 | Service::FS::RegisterArchiveType(Common::make_unique<FileSys::ArchiveFactory_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS); | ||
| 124 | return ResultStatus::Success; | ||
| 125 | } | ||
| 126 | break; | ||
| 127 | } | ||
| 120 | 128 | ||
| 121 | // Standard ELF file format... | 129 | // Standard ELF file format... |
| 122 | case FileType::ELF: | 130 | case FileType::ELF: |
diff --git a/src/core/settings.h b/src/core/settings.h index 6ca0e1afc..0b05e5bee 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -19,22 +19,22 @@ enum Values { | |||
| 19 | CUP, CDOWN, CLEFT, CRIGHT, | 19 | CUP, CDOWN, CLEFT, CRIGHT, |
| 20 | NUM_INPUTS | 20 | NUM_INPUTS |
| 21 | }; | 21 | }; |
| 22 | static const std::array<const char*, NUM_INPUTS> Mapping = { | 22 | static const std::array<const char*, NUM_INPUTS> Mapping = {{ |
| 23 | "pad_a", "pad_b", "pad_x", "pad_y", | 23 | "pad_a", "pad_b", "pad_x", "pad_y", |
| 24 | "pad_l", "pad_r", "pad_zl", "pad_zr", | 24 | "pad_l", "pad_r", "pad_zl", "pad_zr", |
| 25 | "pad_start", "pad_select", "pad_home", | 25 | "pad_start", "pad_select", "pad_home", |
| 26 | "pad_dup", "pad_ddown", "pad_dleft", "pad_dright", | 26 | "pad_dup", "pad_ddown", "pad_dleft", "pad_dright", |
| 27 | "pad_sup", "pad_sdown", "pad_sleft", "pad_sright", | 27 | "pad_sup", "pad_sdown", "pad_sleft", "pad_sright", |
| 28 | "pad_cup", "pad_cdown", "pad_cleft", "pad_cright" | 28 | "pad_cup", "pad_cdown", "pad_cleft", "pad_cright" |
| 29 | }; | 29 | }}; |
| 30 | static const std::array<Values, NUM_INPUTS> All = { | 30 | static const std::array<Values, NUM_INPUTS> All = {{ |
| 31 | A, B, X, Y, | 31 | A, B, X, Y, |
| 32 | L, R, ZL, ZR, | 32 | L, R, ZL, ZR, |
| 33 | START, SELECT, HOME, | 33 | START, SELECT, HOME, |
| 34 | DUP, DDOWN, DLEFT, DRIGHT, | 34 | DUP, DDOWN, DLEFT, DRIGHT, |
| 35 | SUP, SDOWN, SLEFT, SRIGHT, | 35 | SUP, SDOWN, SLEFT, SRIGHT, |
| 36 | CUP, CDOWN, CLEFT, CRIGHT | 36 | CUP, CDOWN, CLEFT, CRIGHT |
| 37 | }; | 37 | }}; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | 40 | ||
diff --git a/src/core/tracer/recorder.cpp b/src/core/tracer/recorder.cpp index 656706c0c..c6dc35c83 100644 --- a/src/core/tracer/recorder.cpp +++ b/src/core/tracer/recorder.cpp | |||
| @@ -143,11 +143,11 @@ void Recorder::Finish(const std::string& filename) { | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | void Recorder::FrameFinished() { | 145 | void Recorder::FrameFinished() { |
| 146 | stream.push_back( { FrameMarker } ); | 146 | stream.push_back( { { FrameMarker } } ); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) { | 149 | void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) { |
| 150 | StreamElement element = { MemoryLoad }; | 150 | StreamElement element = { { MemoryLoad } }; |
| 151 | element.data.memory_load.size = size; | 151 | element.data.memory_load.size = size; |
| 152 | element.data.memory_load.physical_address = physical_address; | 152 | element.data.memory_load.physical_address = physical_address; |
| 153 | 153 | ||
| @@ -168,7 +168,7 @@ void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) { | |||
| 168 | 168 | ||
| 169 | template<typename T> | 169 | template<typename T> |
| 170 | void Recorder::RegisterWritten(u32 physical_address, T value) { | 170 | void Recorder::RegisterWritten(u32 physical_address, T value) { |
| 171 | StreamElement element = { RegisterWrite }; | 171 | StreamElement element = { { RegisterWrite } }; |
| 172 | element.data.register_write.size = (sizeof(T) == 1) ? CTRegisterWrite::SIZE_8 | 172 | element.data.register_write.size = (sizeof(T) == 1) ? CTRegisterWrite::SIZE_8 |
| 173 | : (sizeof(T) == 2) ? CTRegisterWrite::SIZE_16 | 173 | : (sizeof(T) == 2) ? CTRegisterWrite::SIZE_16 |
| 174 | : (sizeof(T) == 4) ? CTRegisterWrite::SIZE_32 | 174 | : (sizeof(T) == 4) ? CTRegisterWrite::SIZE_32 |
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 77a4fe272..aa1f1484c 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp | |||
| @@ -92,7 +92,7 @@ void GeometryDumper::AddTriangle(Vertex& v0, Vertex& v1, Vertex& v2) { | |||
| 92 | vertices.push_back(v2); | 92 | vertices.push_back(v2); |
| 93 | 93 | ||
| 94 | int num_vertices = (int)vertices.size(); | 94 | int num_vertices = (int)vertices.size(); |
| 95 | faces.push_back({ num_vertices-3, num_vertices-2, num_vertices-1 }); | 95 | faces.push_back({{ num_vertices-3, num_vertices-2, num_vertices-1 }}); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | void GeometryDumper::Dump() { | 98 | void GeometryDumper::Dump() { |
| @@ -576,8 +576,8 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture | |||
| 576 | unsigned table_index = static_cast<int>((x < 2) ? table_index_1.Value() : table_index_2.Value()); | 576 | unsigned table_index = static_cast<int>((x < 2) ? table_index_1.Value() : table_index_2.Value()); |
| 577 | 577 | ||
| 578 | static const std::array<std::array<u8, 2>, 8> etc1_modifier_table = {{ | 578 | static const std::array<std::array<u8, 2>, 8> etc1_modifier_table = {{ |
| 579 | { 2, 8 }, { 5, 17 }, { 9, 29 }, { 13, 42 }, | 579 | {{ 2, 8 }}, {{ 5, 17 }}, {{ 9, 29 }}, {{ 13, 42 }}, |
| 580 | { 18, 60 }, { 24, 80 }, { 33, 106 }, { 47, 183 } | 580 | {{ 18, 60 }}, {{ 24, 80 }}, {{ 33, 106 }}, {{ 47, 183 }} |
| 581 | }}; | 581 | }}; |
| 582 | 582 | ||
| 583 | int modifier = etc1_modifier_table.at(table_index).at(GetTableSubIndex(texel)); | 583 | int modifier = etc1_modifier_table.at(table_index).at(GetTableSubIndex(texel)); |
diff --git a/src/video_core/gpu_debugger.h b/src/video_core/gpu_debugger.h index fae5de7d1..a3aab216c 100644 --- a/src/video_core/gpu_debugger.h +++ b/src/video_core/gpu_debugger.h | |||
| @@ -45,7 +45,6 @@ public: | |||
| 45 | 45 | ||
| 46 | private: | 46 | private: |
| 47 | GraphicsDebugger* observed; | 47 | GraphicsDebugger* observed; |
| 48 | bool in_destruction; | ||
| 49 | 48 | ||
| 50 | friend class GraphicsDebugger; | 49 | friend class GraphicsDebugger; |
| 51 | }; | 50 | }; |
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index a90ff5fef..7abf60292 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -735,11 +735,11 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, | |||
| 735 | auto color_output = ColorCombine(tev_stage.color_op, color_result); | 735 | auto color_output = ColorCombine(tev_stage.color_op, color_result); |
| 736 | 736 | ||
| 737 | // alpha combiner | 737 | // alpha combiner |
| 738 | std::array<u8,3> alpha_result = { | 738 | std::array<u8,3> alpha_result = {{ |
| 739 | GetAlphaModifier(tev_stage.alpha_modifier1, GetSource(tev_stage.alpha_source1)), | 739 | GetAlphaModifier(tev_stage.alpha_modifier1, GetSource(tev_stage.alpha_source1)), |
| 740 | GetAlphaModifier(tev_stage.alpha_modifier2, GetSource(tev_stage.alpha_source2)), | 740 | GetAlphaModifier(tev_stage.alpha_modifier2, GetSource(tev_stage.alpha_source2)), |
| 741 | GetAlphaModifier(tev_stage.alpha_modifier3, GetSource(tev_stage.alpha_source3)) | 741 | GetAlphaModifier(tev_stage.alpha_modifier3, GetSource(tev_stage.alpha_source3)) |
| 742 | }; | 742 | }}; |
| 743 | auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); | 743 | auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); |
| 744 | 744 | ||
| 745 | combiner_output[0] = std::min((unsigned)255, color_output.r() * tev_stage.GetColorMultiplier()); | 745 | combiner_output[0] = std::min((unsigned)255, color_output.r() * tev_stage.GetColorMultiplier()); |
| @@ -967,6 +967,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, | |||
| 967 | UNIMPLEMENTED(); | 967 | UNIMPLEMENTED(); |
| 968 | break; | 968 | break; |
| 969 | } | 969 | } |
| 970 | |||
| 971 | return {}; | ||
| 970 | }; | 972 | }; |
| 971 | 973 | ||
| 972 | auto LookupFactorA = [&](Regs::BlendFactor factor) -> u8 { | 974 | auto LookupFactorA = [&](Regs::BlendFactor factor) -> u8 { |
| @@ -1000,6 +1002,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, | |||
| 1000 | UNIMPLEMENTED(); | 1002 | UNIMPLEMENTED(); |
| 1001 | break; | 1003 | break; |
| 1002 | } | 1004 | } |
| 1005 | |||
| 1006 | return {}; | ||
| 1003 | }; | 1007 | }; |
| 1004 | 1008 | ||
| 1005 | static auto EvaluateBlendEquation = [](const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor, | 1009 | static auto EvaluateBlendEquation = [](const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor, |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 22f261c68..f1313b54f 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -314,12 +314,12 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | |||
| 314 | * Draws a single texture to the emulator window, rotating the texture to correct for the 3DS's LCD rotation. | 314 | * Draws a single texture to the emulator window, rotating the texture to correct for the 3DS's LCD rotation. |
| 315 | */ | 315 | */ |
| 316 | void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x, float y, float w, float h) { | 316 | void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x, float y, float w, float h) { |
| 317 | std::array<ScreenRectVertex, 4> vertices = { | 317 | std::array<ScreenRectVertex, 4> vertices = {{ |
| 318 | ScreenRectVertex(x, y, 1.f, 0.f), | 318 | ScreenRectVertex(x, y, 1.f, 0.f), |
| 319 | ScreenRectVertex(x+w, y, 1.f, 1.f), | 319 | ScreenRectVertex(x+w, y, 1.f, 1.f), |
| 320 | ScreenRectVertex(x, y+h, 0.f, 0.f), | 320 | ScreenRectVertex(x, y+h, 0.f, 0.f), |
| 321 | ScreenRectVertex(x+w, y+h, 0.f, 1.f), | 321 | ScreenRectVertex(x+w, y+h, 0.f, 1.f), |
| 322 | }; | 322 | }}; |
| 323 | 323 | ||
| 324 | state.texture_units[0].texture_2d = texture.handle; | 324 | state.texture_units[0].texture_2d = texture.handle; |
| 325 | state.Apply(); | 325 | state.Apply(); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 5677e538b..b42df7654 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -62,7 +62,6 @@ private: | |||
| 62 | const TextureInfo& texture); | 62 | const TextureInfo& texture); |
| 63 | 63 | ||
| 64 | EmuWindow* render_window; ///< Handle to render window | 64 | EmuWindow* render_window; ///< Handle to render window |
| 65 | u32 last_mode; ///< Last render mode | ||
| 66 | 65 | ||
| 67 | int resolution_width; ///< Current resolution width | 66 | int resolution_width; ///< Current resolution width |
| 68 | int resolution_height; ///< Current resolution height | 67 | int resolution_height; ///< Current resolution height |