summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/bootmanager.cpp23
-rw-r--r--src/citra_qt/bootmanager.h13
-rw-r--r--src/common/file_util.cpp4
-rw-r--r--src/common/hash.cpp16
-rw-r--r--src/common/symbols.cpp41
-rw-r--r--src/common/symbols.h21
-rw-r--r--src/core/arm/skyeye_common/armstate.h1
-rw-r--r--src/core/core_timing.cpp3
-rw-r--r--src/core/file_sys/ivfc_archive.cpp2
-rw-r--r--src/core/hle/kernel/timer.cpp6
-rw-r--r--src/core/hle/service/cfg/cfg.cpp143
-rw-r--r--src/core/hle/service/cfg/cfg.h66
-rw-r--r--src/core/hle/service/dsp_dsp.cpp4
-rw-r--r--src/core/hle/service/hid/hid.cpp4
-rw-r--r--src/core/loader/3dsx.cpp40
-rw-r--r--src/core/loader/3dsx.h14
-rw-r--r--src/core/loader/loader.cpp10
-rw-r--r--src/core/settings.h8
-rw-r--r--src/core/tracer/recorder.cpp6
-rw-r--r--src/video_core/debug_utils/debug_utils.cpp6
-rw-r--r--src/video_core/gpu_debugger.h1
-rw-r--r--src/video_core/rasterizer.cpp8
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp4
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h1
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 @@
#include "core/settings.h"
#include "core/system.h"
-#include "video_core/video_core.h"
#include "video_core/debug_utils/debug_utils.h"
+#include "video_core/video_core.h"
#define APP_NAME "citra"
#define APP_VERSION "0.1-" VERSION
@@ -86,6 +86,9 @@ public:
}
void paintEvent(QPaintEvent* ev) override {
+ if (do_painting) {
+ QPainter painter(this);
+ }
}
void resizeEvent(QResizeEvent* ev) override {
@@ -93,8 +96,12 @@ public:
parent->OnFramebufferSizeChanged();
}
+ void DisablePainting() { do_painting = false; }
+ void EnablePainting() { do_painting = true; }
+
private:
GRenderWindow* parent;
+ bool do_painting;
};
GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) :
@@ -128,9 +135,6 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) :
BackupGeometry();
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(OnFramebufferSizeChanged()));
-#endif
}
void GRenderWindow::moveContext()
@@ -273,8 +277,19 @@ void GRenderWindow::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,un
void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread) {
this->emu_thread = emu_thread;
+ child->DisablePainting();
}
void GRenderWindow::OnEmulationStopping() {
emu_thread = nullptr;
+ child->EnablePainting();
+}
+
+void GRenderWindow::showEvent(QShowEvent * event) {
+ QWidget::showEvent(event);
+
+ // windowHandle() is not initialized until the Window is shown, so we connect it here.
+ #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(OnFramebufferSizeChanged()), Qt::UniqueConnection);
+ #endif
}
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 @@
#include "common/emu_window.h"
#include "common/thread.h"
-class QScreen;
class QKeyEvent;
+class QScreen;
-class GRenderWindow;
+class GGLWidgetInternal;
class GMainWindow;
+class GRenderWindow;
class EmuThread : public QThread
{
@@ -123,13 +124,12 @@ public:
void OnClientAreaResized(unsigned width, unsigned height);
- void OnFramebufferSizeChanged();
-
public slots:
void moveContext(); // overridden
void OnEmulationStarting(EmuThread* emu_thread);
void OnEmulationStopping();
+ void OnFramebufferSizeChanged();
signals:
/// Emitted when the window is closed
@@ -138,7 +138,7 @@ signals:
private:
void OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) override;
- QGLWidget* child;
+ GGLWidgetInternal* child;
QByteArray geometry;
@@ -146,4 +146,7 @@ private:
int keyboard_id;
EmuThread* emu_thread;
+
+protected:
+ void showEvent(QShowEvent* event) override;
};
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
const std::string forbidden_characters = ".\"/\\[]:;=, ";
// On a FAT32 partition, 8.3 names are stored as a 11 bytes array, filled with spaces.
- short_name = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'};
- extension = {' ', ' ', ' ', '\0'};
+ short_name = {{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'}};
+ extension = {{' ', ' ', ' ', '\0'}};
std::string::size_type point = filename.rfind('.');
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 {
// Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do
// the conversion here
-
-static FORCE_INLINE u32 getblock32(const u32* p, int i) {
- return p[i];
-}
-
static FORCE_INLINE u64 getblock64(const u64* p, int i) {
return p[i];
}
// Finalization mix - force all bits of a hash block to avalanche
-
-static FORCE_INLINE u32 fmix32(u32 h) {
- h ^= h >> 16;
- h *= 0x85ebca6b;
- h ^= h >> 13;
- h *= 0xc2b2ae35;
- h ^= h >> 16;
-
- return h;
-}
-
static FORCE_INLINE u64 fmix64(u64 k) {
k ^= k >> 33;
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;
namespace Symbols
{
- bool HasSymbol(u32 _address)
+ bool HasSymbol(u32 address)
{
- return g_symbols.find(_address) != g_symbols.end();
+ return g_symbols.find(address) != g_symbols.end();
}
- void Add(u32 _address, const std::string& _name, u32 _size, u32 _type)
+ void Add(u32 address, const std::string& name, u32 size, u32 type)
{
- if (!HasSymbol(_address))
+ if (!HasSymbol(address))
{
TSymbol symbol;
- symbol.address = _address;
- symbol.name = _name;
- symbol.size = _size;
- symbol.type = _type;
+ symbol.address = address;
+ symbol.name = name;
+ symbol.size = size;
+ symbol.type = type;
- g_symbols.insert(TSymbolsPair(_address, symbol));
+ g_symbols.emplace(address, symbol);
}
}
- TSymbol GetSymbol(u32 _address)
+ TSymbol GetSymbol(u32 address)
{
- TSymbolsMap::iterator foundSymbolItr;
- TSymbol symbol;
+ const auto iter = g_symbols.find(address);
- foundSymbolItr = g_symbols.find(_address);
- if (foundSymbolItr != g_symbols.end())
- {
- symbol = (*foundSymbolItr).second;
- }
+ if (iter != g_symbols.end())
+ return iter->second;
- return symbol;
+ return {};
}
- const std::string GetName(u32 _address)
+
+ const std::string GetName(u32 address)
{
- return GetSymbol(_address).name;
+ return GetSymbol(address).name;
}
- void Remove(u32 _address)
+ void Remove(u32 address)
{
- g_symbols.erase(_address);
+ g_symbols.erase(address);
}
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 @@
struct TSymbol
{
- TSymbol() :
- address(0),
- size(0),
- type(0)
- {}
- u32 address;
+ u32 address = 0;
std::string name;
- u32 size;
- u32 type;
+ u32 size = 0;
+ u32 type = 0;
};
typedef std::map<u32, TSymbol> TSymbolsMap;
@@ -28,12 +23,12 @@ typedef std::pair<u32, TSymbol> TSymbolsPair;
namespace Symbols
{
- bool HasSymbol(u32 _address);
+ bool HasSymbol(u32 address);
- void Add(u32 _address, const std::string& _name, u32 _size, u32 _type);
- TSymbol GetSymbol(u32 _address);
- const std::string GetName(u32 _address);
- void Remove(u32 _address);
+ void Add(u32 address, const std::string& name, u32 size, u32 type);
+ TSymbol GetSymbol(u32 address);
+ const std::string GetName(u32 address);
+ void Remove(u32 address);
void Clear();
}
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:
static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode
- u32 exclusive_result;
bool exclusive_state;
};
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 @@
// Refer to the license.txt file included.
#include <atomic>
+#include <cinttypes>
#include <mutex>
#include <vector>
@@ -530,7 +531,7 @@ void Idle(int max_idle) {
}
}
- LOG_TRACE(Core_Timing, "Idle for %i cycles! (%f ms)", cycles_down, cycles_down / (float)(g_clock_rate_arm11 * 0.001f));
+ LOG_TRACE(Core_Timing, "Idle for %" PRId64 " cycles! (%f ms)", cycles_down, cycles_down / (float)(g_clock_rate_arm11 * 0.001f));
idled_cycles += cycles_down;
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
////////////////////////////////////////////////////////////////////////////////////////////////////
size_t IVFCFile::Read(const u64 offset, const size_t length, u8* buffer) const {
- LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
+ LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length);
romfs_file->Seek(data_offset + offset, SEEK_SET);
size_t read_length = (size_t)std::min((u64)length, data_size - offset);
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 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cinttypes>
+
#include "common/assert.h"
#include "common/logging/log.h"
@@ -71,11 +73,11 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
SharedPtr<Timer> timer = timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle));
if (timer == nullptr) {
- LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08lX", timer_handle);
+ LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08" PRIx64, timer_handle);
return;
}
- LOG_TRACE(Kernel, "Timer %u fired", timer_handle);
+ LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle);
timer->signaled = true;
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 @@
namespace Service {
namespace CFG {
-const u64 CFG_SAVE_ID = 0x00010017;
-const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE;
-const ConsoleModelInfo CONSOLE_MODEL = { NINTENDO_3DS_XL, { 0, 0, 0 } };
-const u8 CONSOLE_LANGUAGE = LANGUAGE_EN;
-const char CONSOLE_USERNAME[0x14] = "CITRA";
+/// The maximum number of block entries that can exist in the config file
+static const u32 CONFIG_FILE_MAX_BLOCK_ENTRIES = 1479;
+
+namespace {
+
+/**
+ * The header of the config savedata file,
+ * contains information about the blocks in the file
+ */
+struct SaveFileConfig {
+ u16 total_entries; ///< The total number of set entries in the config file
+ u16 data_entries_offset; ///< The offset where the data for the blocks start, this is hardcoded to 0x455C as per hardware
+ SaveConfigBlockEntry block_entries[CONFIG_FILE_MAX_BLOCK_ENTRIES]; ///< The block headers, the maximum possible value is 1479 as per hardware
+ u32 unknown; ///< This field is unknown, possibly padding, 0 has been observed in hardware
+};
+static_assert(sizeof(SaveFileConfig) == 0x455C, "SaveFileConfig header must be exactly 0x455C bytes");
+
+struct UsernameBlock {
+ char16_t username[10]; ///< Exactly 20 bytes long, padded with zeros at the end if necessary
+ u32 zero;
+ u32 ng_word;
+};
+static_assert(sizeof(UsernameBlock) == 0x1C, "UsernameBlock must be exactly 0x1C bytes");
+
+struct ConsoleModelInfo {
+ u8 model; ///< The console model (3DS, 2DS, etc)
+ u8 unknown[3]; ///< Unknown data
+};
+static_assert(sizeof(ConsoleModelInfo) == 4, "ConsoleModelInfo must be exactly 4 bytes");
+
+struct ConsoleCountryInfo {
+ u8 unknown[3]; ///< Unknown data
+ u8 country_code; ///< The country code of the console
+};
+static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes");
+
+}
+
+static const u64 CFG_SAVE_ID = 0x00010017;
+static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE;
+static const ConsoleModelInfo CONSOLE_MODEL = { NINTENDO_3DS_XL, { 0, 0, 0 } };
+static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN;
+static const char CONSOLE_USERNAME[0x14] = "CITRA";
/// This will be initialized in Init, and will be used when creating the block
-UsernameBlock CONSOLE_USERNAME_BLOCK;
+static UsernameBlock CONSOLE_USERNAME_BLOCK;
/// TODO(Subv): Find out what this actually is
-const u8 SOUND_OUTPUT_MODE = 2;
-const u8 UNITED_STATES_COUNTRY_ID = 49;
+static const u8 SOUND_OUTPUT_MODE = 2;
+static const u8 UNITED_STATES_COUNTRY_ID = 49;
/// TODO(Subv): Find what the other bytes are
-const ConsoleCountryInfo COUNTRY_INFO = { { 0, 0, 0 }, UNITED_STATES_COUNTRY_ID };
+static const ConsoleCountryInfo COUNTRY_INFO = { { 0, 0, 0 }, UNITED_STATES_COUNTRY_ID };
/**
* TODO(Subv): Find out what this actually is, these values fix some NaN uniforms in some games,
* for example Nintendo Zone
* Thanks Normmatt for providing this information
*/
-const std::array<float, 8> STEREO_CAMERA_SETTINGS = {
+static const std::array<float, 8> STEREO_CAMERA_SETTINGS = {{
62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f,
10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f
-};
+}};
+static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes");
static const u32 CONFIG_SAVEFILE_SIZE = 0x8000;
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) {
return RESULT_SUCCESS;
}
-ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const u8* data) {
+ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* data) {
SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data());
if (config->total_entries >= CONFIG_FILE_MAX_BLOCK_ENTRIES)
return ResultCode(-1); // TODO(Subv): Find the right error code
@@ -277,33 +316,63 @@ ResultCode FormatConfig() {
SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data());
// This value is hardcoded, taken from 3dbrew, verified by hardware, it's always the same value
config->data_entries_offset = 0x455C;
+
// Insert the default blocks
- res = CreateConfigInfoBlk(0x00050005, sizeof(STEREO_CAMERA_SETTINGS), 0xE,
- reinterpret_cast<const u8*>(STEREO_CAMERA_SETTINGS.data()));
- if (!res.IsSuccess())
- return res;
- res = CreateConfigInfoBlk(0x00090001, sizeof(CONSOLE_UNIQUE_ID), 0xE,
- reinterpret_cast<const u8*>(&CONSOLE_UNIQUE_ID));
- if (!res.IsSuccess())
- return res;
- res = CreateConfigInfoBlk(0x000F0004, sizeof(CONSOLE_MODEL), 0x8,
- reinterpret_cast<const u8*>(&CONSOLE_MODEL));
- if (!res.IsSuccess())
- return res;
- res = CreateConfigInfoBlk(0x000A0002, sizeof(CONSOLE_LANGUAGE), 0xA, &CONSOLE_LANGUAGE);
- if (!res.IsSuccess())
- return res;
+ u8 zero_buffer[0xC0] = {};
+
+ // 0x00030001 - Unknown
+ res = CreateConfigInfoBlk(0x00030001, 0x8, 0xE, zero_buffer);
+ if (!res.IsSuccess()) return res;
+
+ res = CreateConfigInfoBlk(0x00050005, sizeof(STEREO_CAMERA_SETTINGS), 0xE, STEREO_CAMERA_SETTINGS.data());
+ if (!res.IsSuccess()) return res;
res = CreateConfigInfoBlk(0x00070001, sizeof(SOUND_OUTPUT_MODE), 0xE, &SOUND_OUTPUT_MODE);
- if (!res.IsSuccess())
- return res;
- res = CreateConfigInfoBlk(0x000B0000, sizeof(COUNTRY_INFO), 0xE,
- reinterpret_cast<const u8*>(&COUNTRY_INFO));
- if (!res.IsSuccess())
- return res;
- res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE,
- reinterpret_cast<const u8*>(&CONSOLE_USERNAME_BLOCK));
- if (!res.IsSuccess())
- return res;
+ if (!res.IsSuccess()) return res;
+ res = CreateConfigInfoBlk(0x00090001, sizeof(CONSOLE_UNIQUE_ID), 0xE, &CONSOLE_UNIQUE_ID);
+ if (!res.IsSuccess()) return res;
+ res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, &CONSOLE_USERNAME_BLOCK);
+ if (!res.IsSuccess()) return res;
+
+ // 0x000A0001 - Profile birthday
+ const u8 profile_birthday[2] = {3, 25}; // March 25th, 2014
+ res = CreateConfigInfoBlk(0x000A0001, sizeof(profile_birthday), 0xE, profile_birthday);
+ if (!res.IsSuccess()) return res;
+
+ res = CreateConfigInfoBlk(0x000A0002, sizeof(CONSOLE_LANGUAGE), 0xE, &CONSOLE_LANGUAGE);
+ if (!res.IsSuccess()) return res;
+ res = CreateConfigInfoBlk(0x000B0000, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO);
+ if (!res.IsSuccess()) return res;
+
+ char16_t country_name_buffer[16][0x40] = {};
+ for (size_t i = 0; i < 16; ++i) {
+ Common::UTF8ToUTF16("Gensokyo").copy(country_name_buffer[i], 0x40);
+ }
+ // 0x000B0001 - Localized names for the profile Country
+ res = CreateConfigInfoBlk(0x000B0001, sizeof(country_name_buffer), 0xE, country_name_buffer);
+ if (!res.IsSuccess()) return res;
+ // 0x000B0002 - Localized names for the profile State/Province
+ res = CreateConfigInfoBlk(0x000B0002, sizeof(country_name_buffer), 0xE, country_name_buffer);
+ if (!res.IsSuccess()) return res;
+
+ // 0x000B0003 - Unknown, related to country/address (zip code?)
+ res = CreateConfigInfoBlk(0x000B0003, 0x4, 0xE, zero_buffer);
+ if (!res.IsSuccess()) return res;
+
+ // 0x000C0000 - Unknown
+ res = CreateConfigInfoBlk(0x000C0000, 0xC0, 0xE, zero_buffer);
+ if (!res.IsSuccess()) return res;
+
+ // 0x000C0001 - Unknown
+ res = CreateConfigInfoBlk(0x000C0001, 0x14, 0xE, zero_buffer);
+ if (!res.IsSuccess()) return res;
+
+ // 0x000D0000 - Accepted EULA version
+ res = CreateConfigInfoBlk(0x000D0000, 0x4, 0xE, zero_buffer);
+ if (!res.IsSuccess()) return res;
+
+ res = CreateConfigInfoBlk(0x000F0004, sizeof(CONSOLE_MODEL), 0xC, &CONSOLE_MODEL);
+ if (!res.IsSuccess()) return res;
+
// Save the buffer to the file
res = UpdateConfigNANDSavegame();
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 {
u16 flags; ///< The flags of the block, possibly used for access control
};
-// TODO(Link Mauve): use a constexpr once MSVC starts supporting it.
-#define C(code) ((code)[0] | ((code)[1] << 8))
+static constexpr u16 C(const char code[2]) {
+ return code[0] | (code[1] << 8);
+}
-static const std::array<u16, 187> country_codes = {
+static const std::array<u16, 187> country_codes = {{
0, C("JP"), 0, 0, 0, 0, 0, 0, // 0-7
C("AI"), C("AG"), C("AR"), C("AW"), C("BS"), C("BB"), C("BZ"), C("BO"), // 8-15
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 = {
C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175
C("BH"), C("JO"), 0, 0, 0, 0, 0, 0, // 176-183
C("SM"), C("VA"), C("BM") // 184-186
-};
-
-#undef C
+}};
/**
* CFG::GetCountryCodeString service function
@@ -204,59 +203,6 @@ void UpdateConfigNANDSavegame(Service::Interface* self);
*/
void FormatConfig(Service::Interface* self);
-/// The maximum number of block entries that can exist in the config file
-static const u32 CONFIG_FILE_MAX_BLOCK_ENTRIES = 1479;
-
-/**
-* The header of the config savedata file,
-* contains information about the blocks in the file
-*/
-struct SaveFileConfig {
- u16 total_entries; ///< The total number of set entries in the config file
- u16 data_entries_offset; ///< The offset where the data for the blocks start, this is hardcoded to 0x455C as per hardware
- SaveConfigBlockEntry block_entries[CONFIG_FILE_MAX_BLOCK_ENTRIES]; ///< The block headers, the maximum possible value is 1479 as per hardware
- u32 unknown; ///< This field is unknown, possibly padding, 0 has been observed in hardware
-};
-static_assert(sizeof(SaveFileConfig) == 0x455C, "The SaveFileConfig header must be exactly 0x455C bytes");
-
-struct UsernameBlock {
- char16_t username[10]; ///< Exactly 20 bytes long, padded with zeros at the end if necessary
- u32 zero;
- u32 ng_word;
-};
-static_assert(sizeof(UsernameBlock) == 0x1C, "Size of UsernameBlock must be 0x1C");
-
-struct ConsoleModelInfo {
- u8 model; ///< The console model (3DS, 2DS, etc)
- u8 unknown[3]; ///< Unknown data
-};
-static_assert(sizeof(ConsoleModelInfo) == 4, "ConsoleModelInfo must be exactly 4 bytes");
-
-struct ConsoleCountryInfo {
- u8 unknown[3]; ///< Unknown data
- u8 country_code; ///< The country code of the console
-};
-static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes");
-
-extern const u64 CFG_SAVE_ID;
-extern const u64 CONSOLE_UNIQUE_ID;
-extern const ConsoleModelInfo CONSOLE_MODEL;
-extern const u8 CONSOLE_LANGUAGE;
-extern const char CONSOLE_USERNAME[0x14];
-/// This will be initialized in the Interface constructor, and will be used when creating the block
-extern UsernameBlock CONSOLE_USERNAME_BLOCK;
-/// TODO(Subv): Find out what this actually is
-extern const u8 SOUND_OUTPUT_MODE;
-extern const u8 UNITED_STATES_COUNTRY_ID;
-/// TODO(Subv): Find what the other bytes are
-extern const ConsoleCountryInfo COUNTRY_INFO;
-extern const std::array<float, 8> STEREO_CAMERA_SETTINGS;
-
-static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes");
-static_assert(sizeof(CONSOLE_UNIQUE_ID) == 8, "CONSOLE_UNIQUE_ID must be exactly 8 bytes");
-static_assert(sizeof(CONSOLE_LANGUAGE) == 1, "CONSOLE_LANGUAGE must be exactly 1 byte");
-static_assert(sizeof(SOUND_OUTPUT_MODE) == 1, "SOUND_OUTPUT_MODE must be exactly 1 byte");
-
/**
* Reads a block with the specified id and flag from the Config savegame buffer
* and writes the output to output.
@@ -278,7 +224,7 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output);
* @param data A pointer containing the data we will write to the new block
* @returns ResultCode indicating the result of the operation, 0 on success
*/
-ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const u8* data);
+ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* data);
/**
* 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) {
// Canned DSP responses that games expect. These were taken from HW by 3dmoo team.
// TODO: Remove this hack :)
- static const std::array<u16, 16> canned_read_pipe = {
+ static const std::array<u16, 16> canned_read_pipe = {{
0x000F, 0xBFFF, 0x9E8E, 0x8680, 0xA78E, 0x9430, 0x8400, 0x8540,
0x948E, 0x8710, 0x8410, 0xA90E, 0xAA0E, 0xAACE, 0xAC4E, 0xAC58
- };
+ }};
u32 initial_size = read_pipe_count;
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;
static u32 next_pad_index;
static u32 next_touch_index;
-const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping = {
+const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping = {{
Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y,
Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR,
Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE,
Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT,
Service::HID::PAD_CIRCLE_UP, Service::HID::PAD_CIRCLE_DOWN, Service::HID::PAD_CIRCLE_LEFT, Service::HID::PAD_CIRCLE_RIGHT,
Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT
-};
+}};
// 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
// Sizes of the code, rodata and data segments +
// size of the BSS section (uninitialized latter half of the data segment)
u32 code_seg_size, rodata_seg_size, data_seg_size, bss_size;
+ // offset and size of smdh
+ u32 smdh_offset, smdh_size;
+ // offset to filesystem
+ u32 fs_offset;
};
// Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts.
@@ -267,4 +271,40 @@ ResultStatus AppLoader_THREEDSX::Load() {
return ResultStatus::Success;
}
+ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) {
+ if (!file.IsOpen())
+ return ResultStatus::Error;
+
+ // Reset read pointer in case this file has been read before.
+ file.Seek(0, SEEK_SET);
+
+ THREEDSX_Header hdr;
+ if (file.ReadBytes(&hdr, sizeof(THREEDSX_Header)) != sizeof(THREEDSX_Header))
+ return ResultStatus::Error;
+
+ if (hdr.header_size != sizeof(THREEDSX_Header))
+ return ResultStatus::Error;
+
+ // Check if the 3DSX has a RomFS...
+ if (hdr.fs_offset != 0) {
+ u32 romfs_offset = hdr.fs_offset;
+ u32 romfs_size = file.GetSize() - hdr.fs_offset;
+
+ LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset);
+ LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size);
+
+ // We reopen the file, to allow its position to be independent from file's
+ romfs_file = std::make_shared<FileUtil::IOFile>(filepath, "rb");
+ if (!romfs_file->IsOpen())
+ return ResultStatus::Error;
+
+ offset = romfs_offset;
+ size = romfs_size;
+
+ return ResultStatus::Success;
+ }
+ LOG_DEBUG(Loader, "3DSX has no RomFS");
+ return ResultStatus::ErrorNotUsed;
+}
+
} // 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 {
/// Loads an 3DSX file
class AppLoader_THREEDSX final : public AppLoader {
public:
- AppLoader_THREEDSX(FileUtil::IOFile&& file, std::string filename)
- : AppLoader(std::move(file)), filename(std::move(filename)) {}
+ AppLoader_THREEDSX(FileUtil::IOFile&& file, std::string filename, const std::string& filepath)
+ : AppLoader(std::move(file)), filename(std::move(filename)), filepath(filepath) {}
/**
* Returns the type of the file
@@ -33,8 +33,18 @@ public:
*/
ResultStatus Load() override;
+ /**
+ * Get the RomFS of the application
+ * @param romfs_file Reference to buffer to store data
+ * @param offset Offset in the file to the RomFS
+ * @param size Size of the RomFS in bytes
+ * @return ResultStatus result of function
+ */
+ ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override;
+
private:
std::string filename;
+ std::string filepath;
};
} // 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) {
//3DSX file format...
case FileType::THREEDSX:
- return AppLoader_THREEDSX(std::move(file), filename_filename).Load();
+ {
+ AppLoader_THREEDSX app_loader(std::move(file), filename_filename, filename);
+ // Load application and RomFS
+ if (ResultStatus::Success == app_loader.Load()) {
+ Service::FS::RegisterArchiveType(Common::make_unique<FileSys::ArchiveFactory_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS);
+ return ResultStatus::Success;
+ }
+ break;
+ }
// Standard ELF file format...
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 {
CUP, CDOWN, CLEFT, CRIGHT,
NUM_INPUTS
};
-static const std::array<const char*, NUM_INPUTS> Mapping = {
+static const std::array<const char*, NUM_INPUTS> Mapping = {{
"pad_a", "pad_b", "pad_x", "pad_y",
"pad_l", "pad_r", "pad_zl", "pad_zr",
"pad_start", "pad_select", "pad_home",
"pad_dup", "pad_ddown", "pad_dleft", "pad_dright",
"pad_sup", "pad_sdown", "pad_sleft", "pad_sright",
"pad_cup", "pad_cdown", "pad_cleft", "pad_cright"
-};
-static const std::array<Values, NUM_INPUTS> All = {
+}};
+static const std::array<Values, NUM_INPUTS> All = {{
A, B, X, Y,
L, R, ZL, ZR,
START, SELECT, HOME,
DUP, DDOWN, DLEFT, DRIGHT,
SUP, SDOWN, SLEFT, SRIGHT,
CUP, CDOWN, CLEFT, CRIGHT
-};
+}};
}
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) {
}
void Recorder::FrameFinished() {
- stream.push_back( { FrameMarker } );
+ stream.push_back( { { FrameMarker } } );
}
void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) {
- StreamElement element = { MemoryLoad };
+ StreamElement element = { { MemoryLoad } };
element.data.memory_load.size = size;
element.data.memory_load.physical_address = physical_address;
@@ -168,7 +168,7 @@ void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) {
template<typename T>
void Recorder::RegisterWritten(u32 physical_address, T value) {
- StreamElement element = { RegisterWrite };
+ StreamElement element = { { RegisterWrite } };
element.data.register_write.size = (sizeof(T) == 1) ? CTRegisterWrite::SIZE_8
: (sizeof(T) == 2) ? CTRegisterWrite::SIZE_16
: (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) {
vertices.push_back(v2);
int num_vertices = (int)vertices.size();
- faces.push_back({ num_vertices-3, num_vertices-2, num_vertices-1 });
+ faces.push_back({{ num_vertices-3, num_vertices-2, num_vertices-1 }});
}
void GeometryDumper::Dump() {
@@ -576,8 +576,8 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture
unsigned table_index = static_cast<int>((x < 2) ? table_index_1.Value() : table_index_2.Value());
static const std::array<std::array<u8, 2>, 8> etc1_modifier_table = {{
- { 2, 8 }, { 5, 17 }, { 9, 29 }, { 13, 42 },
- { 18, 60 }, { 24, 80 }, { 33, 106 }, { 47, 183 }
+ {{ 2, 8 }}, {{ 5, 17 }}, {{ 9, 29 }}, {{ 13, 42 }},
+ {{ 18, 60 }}, {{ 24, 80 }}, {{ 33, 106 }}, {{ 47, 183 }}
}};
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:
private:
GraphicsDebugger* observed;
- bool in_destruction;
friend class GraphicsDebugger;
};
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,
auto color_output = ColorCombine(tev_stage.color_op, color_result);
// alpha combiner
- std::array<u8,3> alpha_result = {
+ std::array<u8,3> alpha_result = {{
GetAlphaModifier(tev_stage.alpha_modifier1, GetSource(tev_stage.alpha_source1)),
GetAlphaModifier(tev_stage.alpha_modifier2, GetSource(tev_stage.alpha_source2)),
GetAlphaModifier(tev_stage.alpha_modifier3, GetSource(tev_stage.alpha_source3))
- };
+ }};
auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result);
combiner_output[0] = std::min((unsigned)255, color_output.r() * tev_stage.GetColorMultiplier());
@@ -967,6 +967,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
UNIMPLEMENTED();
break;
}
+
+ return {};
};
auto LookupFactorA = [&](Regs::BlendFactor factor) -> u8 {
@@ -1000,6 +1002,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
UNIMPLEMENTED();
break;
}
+
+ return {};
};
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,
* Draws a single texture to the emulator window, rotating the texture to correct for the 3DS's LCD rotation.
*/
void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x, float y, float w, float h) {
- std::array<ScreenRectVertex, 4> vertices = {
+ std::array<ScreenRectVertex, 4> vertices = {{
ScreenRectVertex(x, y, 1.f, 0.f),
ScreenRectVertex(x+w, y, 1.f, 1.f),
ScreenRectVertex(x, y+h, 0.f, 0.f),
ScreenRectVertex(x+w, y+h, 0.f, 1.f),
- };
+ }};
state.texture_units[0].texture_2d = texture.handle;
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:
const TextureInfo& texture);
EmuWindow* render_window; ///< Handle to render window
- u32 last_mode; ///< Last render mode
int resolution_width; ///< Current resolution width
int resolution_height; ///< Current resolution height