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] 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;