From 0783498f570e7d5c00174cd10a3c1ff105d1eae6 Mon Sep 17 00:00:00 2001
From: archshift <admin@archshift.com>
Date: Sat, 25 Oct 2014 12:54:44 -0700
Subject: [PATCH 1/2] Use configuration files to enable or disable the new
 dyncom interpreter.

---
 src/citra/config.cpp    |  6 ++++++
 src/citra/config.h      |  1 +
 src/citra/default_ini.h |  3 +++
 src/citra_qt/config.cpp | 15 +++++++++++++++
 src/citra_qt/config.h   |  3 ++-
 src/core/core.cpp       | 17 ++++++++++++++---
 src/core/core.h         |  5 +++++
 src/core/hw/gpu.cpp     | 16 ++++++++++++++++
 src/core/hw/gpu.h       |  3 ---
 src/core/settings.h     |  5 +++++
 10 files changed, 67 insertions(+), 7 deletions(-)

diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 03a0ce6063..3e5e986c29 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -7,6 +7,7 @@
 #include "citra/default_ini.h"
 #include "common/file_util.h"
 #include "core/settings.h"
+#include "core/core.h"
 
 #include "config.h"
 
@@ -55,6 +56,10 @@ void Config::ReadControls() {
     Settings::values.pad_sright_key = glfw_config->GetInteger("Controls", "pad_sright", GLFW_KEY_RIGHT);
 }
 
+void Config::ReadCore() {
+    Settings::values.cpu_core = glfw_config->GetInteger("Core", "cpu_core", Core::CPU_Interpreter);
+}
+
 void Config::ReadData() {
     Settings::values.use_virtual_sd = glfw_config->GetBoolean("Data Storage", "use_virtual_sd", true);
 }
@@ -62,6 +67,7 @@ void Config::ReadData() {
 void Config::Reload() {
     LoadINI(glfw_config, glfw_config_loc.c_str(), DefaultINI::glfw_config_file);
     ReadControls();
+    ReadCore();
     ReadData();
 }
 
diff --git a/src/citra/config.h b/src/citra/config.h
index c4fac2459c..4f65518765 100644
--- a/src/citra/config.h
+++ b/src/citra/config.h
@@ -16,6 +16,7 @@ class Config {
 
     bool LoadINI(INIReader* config, const char* location, const std::string& default_contents="", bool retry=true);
     void ReadControls();
+    void ReadCore();
     void ReadData();
 public:
     Config();
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index e7e45f4a96..4a016d4838 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -26,6 +26,9 @@ pad_sdown =
 pad_sleft =
 pad_sright =
 
+[Core]
+cpu_core = ## 0: Interpreter (default), 1: DynCom Interpreter
+
 [Data Storage]
 use_virtual_sd =
 )";
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index 0c4f75a96d..ded44ea8db 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -6,6 +6,7 @@
 #include <QStringList>
 
 #include "core/settings.h"
+#include "core/core.h"
 #include "common/file_util.h"
 
 #include "config.h"
@@ -64,6 +65,18 @@ void Config::SaveControls() {
     qt_config->endGroup();
 }
 
+void Config::ReadCore() {
+    qt_config->beginGroup("Core");
+    Settings::values.cpu_core = qt_config->value("cpu_core", Core::CPU_Interpreter).toInt();
+    qt_config->endGroup();
+}
+
+void Config::SaveCore() {
+    qt_config->beginGroup("Core");
+    qt_config->setValue("cpu_core", Settings::values.cpu_core);
+    qt_config->endGroup();
+}
+
 void Config::ReadData() {
     qt_config->beginGroup("Data Storage");
     Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
@@ -78,11 +91,13 @@ void Config::SaveData() {
 
 void Config::Reload() {
     ReadControls();
+    ReadCore();
     ReadData();
 }
 
 void Config::Save() {
     SaveControls();
+    SaveCore();
     SaveData();
 }
 
diff --git a/src/citra_qt/config.h b/src/citra_qt/config.h
index 74c9ff11dd..782c262876 100644
--- a/src/citra_qt/config.h
+++ b/src/citra_qt/config.h
@@ -14,7 +14,8 @@ class Config {
 
     void ReadControls();
     void SaveControls();
-
+    void ReadCore();
+    void SaveCore();
     void ReadData();
     void SaveData();
 public:
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 01d4f0afaa..25c78d33cd 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -5,12 +5,14 @@
 #include "common/common_types.h"
 
 #include "core/core.h"
-#include "core/hw/hw.h"
+
+#include "core/settings.h"
 #include "core/arm/disassembler/arm_disasm.h"
 #include "core/arm/interpreter/arm_interpreter.h"
-
+#include "core/arm/dyncom/arm_dyncom.h"
 #include "core/hle/hle.h"
 #include "core/hle/kernel/thread.h"
+#include "core/hw/hw.h"
 
 namespace Core {
 
@@ -48,9 +50,18 @@ int Init() {
     NOTICE_LOG(MASTER_LOG, "initialized OK");
 
     g_disasm = new ARM_Disasm();
-    g_app_core = new ARM_Interpreter();
     g_sys_core = new ARM_Interpreter();
 
+    switch (Settings::values.cpu_core) {
+        case CPU_FastInterpreter:
+            g_app_core = new ARM_DynCom();
+            break;
+        case CPU_Interpreter:
+        default:
+            g_app_core = new ARM_Interpreter();
+            break;
+    }
+
     g_last_ticks = Core::g_app_core->GetTicks();
 
     return 0;
diff --git a/src/core/core.h b/src/core/core.h
index 87da252b83..872dc0cd1d 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -11,6 +11,11 @@
 
 namespace Core {
 
+enum CPUCore {
+    CPU_Interpreter,
+    CPU_FastInterpreter
+};
+
 extern ARM_Interface*   g_app_core;     ///< ARM11 application core
 extern ARM_Interface*   g_sys_core;     ///< ARM11 system (OS) core
 
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 33a0e0fe7c..94768b1012 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -4,6 +4,7 @@
 
 #include "common/common_types.h"
 
+#include "core/settings.h"
 #include "core/core.h"
 #include "core/mem_map.h"
 
@@ -24,6 +25,9 @@ u32 g_cur_line = 0;         ///< Current vertical screen line
 u64 g_last_line_ticks = 0;  ///< CPU tick count from last vertical screen line
 u64 g_last_frame_ticks = 0; ///< CPU tick count from last frame
 
+static u32 kFrameCycles = 0; ///< 268MHz / 60 frames per second
+static u32 kFrameTicks  = 0; ///< Approximate number of instructions/frame
+
 template <typename T>
 inline void Read(T &var, const u32 raw_addr) {
     u32 addr = raw_addr - 0x1EF00000;
@@ -214,6 +218,18 @@ void Update() {
 
 /// Initialize hardware
 void Init() {
+    switch (Settings::values.cpu_core) {
+        case Core::CPU_FastInterpreter:
+            kFrameCycles = 268123480 / 2048;
+            break;
+        case Core::CPU_Interpreter:
+        default:
+            kFrameCycles = 268123480 / 60;
+            break;
+    }
+    
+    kFrameTicks  = kFrameCycles / 3;
+
     g_cur_line = 0;
     g_last_frame_ticks = g_last_line_ticks = Core::g_app_core->GetTicks();
 
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index 92097d182d..3fa7b9ccfc 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -11,9 +11,6 @@
 
 namespace GPU {
 
-static const u32 kFrameCycles   = 268123480 / 60;   ///< 268MHz / 60 frames per second
-static const u32 kFrameTicks    = kFrameCycles / 3; ///< Approximate number of instructions/frame
-
 // Returns index corresponding to the Regs member labeled by field_name
 // TODO: Due to Visual studio bug 209229, offsetof does not return constant expressions
 //       when used with array elements (e.g. GPU_REG_INDEX(memory_fill_config[0])).
diff --git a/src/core/settings.h b/src/core/settings.h
index d586e2ef4f..3e47818843 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -7,6 +7,7 @@
 namespace Settings {
 
 struct Values {
+    // Controls
     int pad_a_key;
     int pad_b_key;
     int pad_x_key;
@@ -25,6 +26,10 @@ struct Values {
     int pad_sleft_key;
     int pad_sright_key;
 
+    // Core
+    int cpu_core;
+
+    // Data Storage
     bool use_virtual_sd;
 } extern values;
 

From 09e19f9f1ee2e965a581e70b30cbc357f4b5ad21 Mon Sep 17 00:00:00 2001
From: archshift <admin@archshift.com>
Date: Mon, 27 Oct 2014 18:56:08 -0700
Subject: [PATCH 2/2] Added `gpu_refresh_rate` config setting for the new
 interpreter speed hack.

---
 src/citra/config.cpp    |  1 +
 src/citra/default_ini.h |  3 ++-
 src/citra_qt/config.cpp |  2 ++
 src/core/hw/gpu.cpp     | 11 +----------
 src/core/settings.h     |  1 +
 5 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 3e5e986c29..c5ce8a1647 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -58,6 +58,7 @@ void Config::ReadControls() {
 
 void Config::ReadCore() {
     Settings::values.cpu_core = glfw_config->GetInteger("Core", "cpu_core", Core::CPU_Interpreter);
+    Settings::values.gpu_refresh_rate = glfw_config->GetInteger("Core", "gpu_refresh_rate", 60);
 }
 
 void Config::ReadData() {
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index 4a016d4838..7352c70c24 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -27,7 +27,8 @@ pad_sleft =
 pad_sright =
 
 [Core]
-cpu_core = ## 0: Interpreter (default), 1: DynCom Interpreter
+cpu_core = ## 0: Interpreter (default), 1: FastInterpreter (experimental)
+gpu_refresh_rate = ## 60 (default), 1024 or 2048 may work better on the FastInterpreter
 
 [Data Storage]
 use_virtual_sd =
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index ded44ea8db..63d3964394 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -68,12 +68,14 @@ void Config::SaveControls() {
 void Config::ReadCore() {
     qt_config->beginGroup("Core");
     Settings::values.cpu_core = qt_config->value("cpu_core", Core::CPU_Interpreter).toInt();
+    Settings::values.gpu_refresh_rate = qt_config->value("gpu_refresh_rate", 60).toInt();
     qt_config->endGroup();
 }
 
 void Config::SaveCore() {
     qt_config->beginGroup("Core");
     qt_config->setValue("cpu_core", Settings::values.cpu_core);
+    qt_config->setValue("gpu_refresh_rate", Settings::values.gpu_refresh_rate);
     qt_config->endGroup();
 }
 
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 94768b1012..76dbe3fdcb 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -218,16 +218,7 @@ void Update() {
 
 /// Initialize hardware
 void Init() {
-    switch (Settings::values.cpu_core) {
-        case Core::CPU_FastInterpreter:
-            kFrameCycles = 268123480 / 2048;
-            break;
-        case Core::CPU_Interpreter:
-        default:
-            kFrameCycles = 268123480 / 60;
-            break;
-    }
-    
+    kFrameCycles = 268123480 / Settings::values.gpu_refresh_rate;
     kFrameTicks  = kFrameCycles / 3;
 
     g_cur_line = 0;
diff --git a/src/core/settings.h b/src/core/settings.h
index 3e47818843..6a6265e186 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -28,6 +28,7 @@ struct Values {
 
     // Core
     int cpu_core;
+    int gpu_refresh_rate;
 
     // Data Storage
     bool use_virtual_sd;