diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui
index b340149d5..5667b14b6 100644
--- a/src/citra_qt/configuration/configure_graphics.ui
+++ b/src/citra_qt/configuration/configure_graphics.ui
@@ -63,57 +63,57 @@
-
- Auto (Window Size)
+ Auto (Window Size)
-
- Native (400x240)
+ Native (400x240)
-
- 2x Native (800x480)
+ 2x Native (800x480)
-
- 3x Native (1200x720)
+ 3x Native (1200x720)
-
- 4x Native (1600x960)
+ 4x Native (1600x960)
-
- 5x Native (2000x1200)
+ 5x Native (2000x1200)
-
- 6x Native (2400x1440)
+ 6x Native (2400x1440)
-
- 7x Native (2800x1680)
+ 7x Native (2800x1680)
-
- 8x Native (3200x1920)
+ 8x Native (3200x1920)
-
- 9x Native (3600x2160)
+ 9x Native (3600x2160)
-
- 10x Native (4000x2400)
+ 10x Native (4000x2400)
diff --git a/src/citra_qt/configuration/configure_system.cpp b/src/citra_qt/configuration/configure_system.cpp
index 9b1e6711d..88a067c12 100644
--- a/src/citra_qt/configuration/configure_system.cpp
+++ b/src/citra_qt/configuration/configure_system.cpp
@@ -78,7 +78,8 @@ void ConfigureSystem::ReadSystemSettings() {
// set the console id
u64 console_id = Service::CFG::GetConsoleUniqueId();
- ui->label_console_id->setText("Console ID: 0x" + QString::number(console_id, 16).toUpper());
+ ui->label_console_id->setText(
+ tr("Console ID: 0x%1").arg(QString::number(console_id, 16).toUpper()));
}
void ConfigureSystem::applyConfiguration() {
diff --git a/src/citra_qt/configuration/configure_web.cpp b/src/citra_qt/configuration/configure_web.cpp
index 38ce19c0f..bf8c21ac7 100644
--- a/src/citra_qt/configuration/configure_web.cpp
+++ b/src/citra_qt/configuration/configure_web.cpp
@@ -24,15 +24,15 @@ ConfigureWeb::~ConfigureWeb() {}
void ConfigureWeb::setConfiguration() {
ui->web_credentials_disclaimer->setWordWrap(true);
ui->telemetry_learn_more->setOpenExternalLinks(true);
- ui->telemetry_learn_more->setText("Learn more");
+ ui->telemetry_learn_more->setText(tr("Learn more"));
ui->web_signup_link->setOpenExternalLinks(true);
- ui->web_signup_link->setText("Sign up");
+ ui->web_signup_link->setText(tr("Sign up"));
ui->web_token_info_link->setOpenExternalLinks(true);
ui->web_token_info_link->setText(
- "What is my token?");
+ tr("What is my token?"));
ui->toggle_telemetry->setChecked(Settings::values.enable_telemetry);
ui->edit_username->setText(QString::fromStdString(Settings::values.citra_username));
@@ -40,8 +40,8 @@ void ConfigureWeb::setConfiguration() {
// Connect after setting the values, to avoid calling OnLoginChanged now
connect(ui->edit_token, &QLineEdit::textChanged, this, &ConfigureWeb::OnLoginChanged);
connect(ui->edit_username, &QLineEdit::textChanged, this, &ConfigureWeb::OnLoginChanged);
- ui->label_telemetry_id->setText("Telemetry ID: 0x" +
- QString::number(Core::GetTelemetryId(), 16).toUpper());
+ ui->label_telemetry_id->setText(
+ tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
user_verified = true;
}
@@ -60,8 +60,8 @@ void ConfigureWeb::applyConfiguration() {
void ConfigureWeb::RefreshTelemetryID() {
const u64 new_telemetry_id{Core::RegenerateTelemetryId()};
- ui->label_telemetry_id->setText("Telemetry ID: 0x" +
- QString::number(new_telemetry_id, 16).toUpper());
+ ui->label_telemetry_id->setText(
+ tr("Telemetry ID: 0x%1").arg(QString::number(new_telemetry_id, 16).toUpper()));
}
void ConfigureWeb::OnLoginChanged() {
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index cd1a8de2d..3ed619991 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -26,6 +26,7 @@ set(SRCS
file_sys/archive_systemsavedata.cpp
file_sys/disk_archive.cpp
file_sys/ivfc_archive.cpp
+ file_sys/ncch_container.cpp
file_sys/path_parser.cpp
file_sys/savedata_archive.cpp
frontend/camera/blank_camera.cpp
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index ccd43f431..2aa017a54 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -41,6 +41,9 @@ public:
/// Clear all instruction cache
virtual void ClearInstructionCache() = 0;
+ /// Notify CPU emulation that page tables have changed
+ virtual void PageTableChanged() = 0;
+
/**
* Set the Program Counter to an address
* @param addr Address to set PC to
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 34c5aa381..42ae93ae8 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -41,7 +41,7 @@ static bool IsReadOnlyMemory(u32 vaddr) {
}
static Dynarmic::UserCallbacks GetUserCallbacks(
- const std::shared_ptr& interpeter_state) {
+ const std::shared_ptr& interpeter_state, Memory::PageTable* current_page_table) {
Dynarmic::UserCallbacks user_callbacks{};
user_callbacks.InterpreterFallback = &InterpreterFallback;
user_callbacks.user_arg = static_cast(interpeter_state.get());
@@ -56,16 +56,14 @@ static Dynarmic::UserCallbacks GetUserCallbacks(
user_callbacks.memory.Write16 = &Memory::Write16;
user_callbacks.memory.Write32 = &Memory::Write32;
user_callbacks.memory.Write64 = &Memory::Write64;
- // TODO(Subv): Re-add the page table pointers once dynarmic supports switching page tables at
- // runtime.
- user_callbacks.page_table = nullptr;
+ user_callbacks.page_table = ¤t_page_table->pointers;
user_callbacks.coprocessors[15] = std::make_shared(interpeter_state);
return user_callbacks;
}
ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) {
interpreter_state = std::make_shared(initial_mode);
- jit = std::make_unique(GetUserCallbacks(interpreter_state));
+ PageTableChanged();
}
void ARM_Dynarmic::SetPC(u32 pc) {
@@ -136,6 +134,7 @@ void ARM_Dynarmic::AddTicks(u64 ticks) {
MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
+ ASSERT(Memory::GetCurrentPageTable() == current_page_table);
MICROPROFILE_SCOPE(ARM_Jit);
std::size_t ticks_executed = jit->Run(static_cast(num_instructions));
@@ -178,3 +177,16 @@ void ARM_Dynarmic::PrepareReschedule() {
void ARM_Dynarmic::ClearInstructionCache() {
jit->ClearCache();
}
+
+void ARM_Dynarmic::PageTableChanged() {
+ current_page_table = Memory::GetCurrentPageTable();
+
+ auto iter = jits.find(current_page_table);
+ if (iter != jits.end()) {
+ jit = iter->second.get();
+ return;
+ }
+
+ jit = new Dynarmic::Jit(GetUserCallbacks(interpreter_state, current_page_table));
+ jits.emplace(current_page_table, std::unique_ptr(jit));
+}
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index 834dc989e..96148a1a5 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -4,12 +4,17 @@
#pragma once
+#include