summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra/config.cpp17
-rw-r--r--src/citra/config.h5
-rw-r--r--src/citra/emu_window/emu_window_glfw.cpp8
-rw-r--r--src/citra_qt/config.cpp52
-rw-r--r--src/citra_qt/config.h11
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp54
-rw-r--r--src/core/hle/kernel/mutex.cpp15
-rw-r--r--src/core/hle/kernel/thread.cpp2
-rw-r--r--src/core/hle/service/ac_u.cpp20
-rw-r--r--src/core/hle/service/cfg_u.cpp88
-rw-r--r--src/core/hle/service/dsp_dsp.cpp131
-rw-r--r--src/core/hle/service/dsp_dsp.h2
-rw-r--r--src/core/hle/service/ptm_u.cpp19
-rw-r--r--src/core/hle/svc.cpp5
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp4
15 files changed, 294 insertions, 139 deletions
diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index f45d09fc2..1f8f5922b 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -36,7 +36,8 @@ bool Config::LoadINI(INIReader* config, const char* location, const std::string&
36 return true; 36 return true;
37} 37}
38 38
39void Config::ReadControls() { 39void Config::ReadValues() {
40 // Controls
40 Settings::values.pad_a_key = glfw_config->GetInteger("Controls", "pad_a", GLFW_KEY_A); 41 Settings::values.pad_a_key = glfw_config->GetInteger("Controls", "pad_a", GLFW_KEY_A);
41 Settings::values.pad_b_key = glfw_config->GetInteger("Controls", "pad_b", GLFW_KEY_S); 42 Settings::values.pad_b_key = glfw_config->GetInteger("Controls", "pad_b", GLFW_KEY_S);
42 Settings::values.pad_x_key = glfw_config->GetInteger("Controls", "pad_x", GLFW_KEY_Z); 43 Settings::values.pad_x_key = glfw_config->GetInteger("Controls", "pad_x", GLFW_KEY_Z);
@@ -54,27 +55,21 @@ void Config::ReadControls() {
54 Settings::values.pad_sdown_key = glfw_config->GetInteger("Controls", "pad_sdown", GLFW_KEY_DOWN); 55 Settings::values.pad_sdown_key = glfw_config->GetInteger("Controls", "pad_sdown", GLFW_KEY_DOWN);
55 Settings::values.pad_sleft_key = glfw_config->GetInteger("Controls", "pad_sleft", GLFW_KEY_LEFT); 56 Settings::values.pad_sleft_key = glfw_config->GetInteger("Controls", "pad_sleft", GLFW_KEY_LEFT);
56 Settings::values.pad_sright_key = glfw_config->GetInteger("Controls", "pad_sright", GLFW_KEY_RIGHT); 57 Settings::values.pad_sright_key = glfw_config->GetInteger("Controls", "pad_sright", GLFW_KEY_RIGHT);
57}
58 58
59void Config::ReadCore() { 59 // Core
60 Settings::values.cpu_core = glfw_config->GetInteger("Core", "cpu_core", Core::CPU_Interpreter); 60 Settings::values.cpu_core = glfw_config->GetInteger("Core", "cpu_core", Core::CPU_Interpreter);
61 Settings::values.gpu_refresh_rate = glfw_config->GetInteger("Core", "gpu_refresh_rate", 60); 61 Settings::values.gpu_refresh_rate = glfw_config->GetInteger("Core", "gpu_refresh_rate", 60);
62}
63 62
64void Config::ReadData() { 63 // Data Storage
65 Settings::values.use_virtual_sd = glfw_config->GetBoolean("Data Storage", "use_virtual_sd", true); 64 Settings::values.use_virtual_sd = glfw_config->GetBoolean("Data Storage", "use_virtual_sd", true);
66}
67 65
68void Config::ReadMiscellaneous() { 66 // Miscellaneous
69 Settings::values.enable_log = glfw_config->GetBoolean("Miscellaneous", "enable_log", true); 67 Settings::values.enable_log = glfw_config->GetBoolean("Miscellaneous", "enable_log", true);
70} 68}
71 69
72void Config::Reload() { 70void Config::Reload() {
73 LoadINI(glfw_config, glfw_config_loc.c_str(), DefaultINI::glfw_config_file); 71 LoadINI(glfw_config, glfw_config_loc.c_str(), DefaultINI::glfw_config_file);
74 ReadControls(); 72 ReadValues();
75 ReadCore();
76 ReadData();
77 ReadMiscellaneous();
78} 73}
79 74
80Config::~Config() { 75Config::~Config() {
diff --git a/src/citra/config.h b/src/citra/config.h
index 19bb83700..2b46fa8aa 100644
--- a/src/citra/config.h
+++ b/src/citra/config.h
@@ -15,10 +15,7 @@ class Config {
15 std::string glfw_config_loc; 15 std::string glfw_config_loc;
16 16
17 bool LoadINI(INIReader* config, const char* location, const std::string& default_contents="", bool retry=true); 17 bool LoadINI(INIReader* config, const char* location, const std::string& default_contents="", bool retry=true);
18 void ReadControls(); 18 void ReadValues();
19 void ReadCore();
20 void ReadData();
21 void ReadMiscellaneous();
22public: 19public:
23 Config(); 20 Config();
24 ~Config(); 21 ~Config();
diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp
index 8efb39e2e..697bf4693 100644
--- a/src/citra/emu_window/emu_window_glfw.cpp
+++ b/src/citra/emu_window/emu_window_glfw.cpp
@@ -58,9 +58,13 @@ EmuWindow_GLFW::EmuWindow_GLFW() {
58 58
59 ReloadSetKeymaps(); 59 ReloadSetKeymaps();
60 60
61 glfwSetErrorCallback([](int error, const char *desc){
62 ERROR_LOG(GUI, "GLFW 0x%08x: %s", error, desc);
63 });
64
61 // Initialize the window 65 // Initialize the window
62 if(glfwInit() != GL_TRUE) { 66 if(glfwInit() != GL_TRUE) {
63 printf("Failed to initialize GLFW! Exiting..."); 67 ERROR_LOG(GUI, "Failed to initialize GLFW! Exiting...");
64 exit(1); 68 exit(1);
65 } 69 }
66 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 70 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
@@ -75,7 +79,7 @@ EmuWindow_GLFW::EmuWindow_GLFW() {
75 window_title.c_str(), NULL, NULL); 79 window_title.c_str(), NULL, NULL);
76 80
77 if (m_render_window == NULL) { 81 if (m_render_window == NULL) {
78 printf("Failed to create GLFW window! Exiting..."); 82 ERROR_LOG(GUI, "Failed to create GLFW window! Exiting...");
79 exit(1); 83 exit(1);
80 } 84 }
81 85
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index 09fce4d6f..3209e5900 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -21,7 +21,7 @@ Config::Config() {
21 Reload(); 21 Reload();
22} 22}
23 23
24void Config::ReadControls() { 24void Config::ReadValues() {
25 qt_config->beginGroup("Controls"); 25 qt_config->beginGroup("Controls");
26 Settings::values.pad_a_key = qt_config->value("pad_a", Qt::Key_A).toInt(); 26 Settings::values.pad_a_key = qt_config->value("pad_a", Qt::Key_A).toInt();
27 Settings::values.pad_b_key = qt_config->value("pad_b", Qt::Key_S).toInt(); 27 Settings::values.pad_b_key = qt_config->value("pad_b", Qt::Key_S).toInt();
@@ -41,9 +41,22 @@ void Config::ReadControls() {
41 Settings::values.pad_sleft_key = qt_config->value("pad_sleft", Qt::Key_Left).toInt(); 41 Settings::values.pad_sleft_key = qt_config->value("pad_sleft", Qt::Key_Left).toInt();
42 Settings::values.pad_sright_key = qt_config->value("pad_sright", Qt::Key_Right).toInt(); 42 Settings::values.pad_sright_key = qt_config->value("pad_sright", Qt::Key_Right).toInt();
43 qt_config->endGroup(); 43 qt_config->endGroup();
44
45 qt_config->beginGroup("Core");
46 Settings::values.cpu_core = qt_config->value("cpu_core", Core::CPU_Interpreter).toInt();
47 Settings::values.gpu_refresh_rate = qt_config->value("gpu_refresh_rate", 60).toInt();
48 qt_config->endGroup();
49
50 qt_config->beginGroup("Data Storage");
51 Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
52 qt_config->endGroup();
53
54 qt_config->beginGroup("Miscellaneous");
55 Settings::values.enable_log = qt_config->value("enable_log", true).toBool();
56 qt_config->endGroup();
44} 57}
45 58
46void Config::SaveControls() { 59void Config::SaveValues() {
47 qt_config->beginGroup("Controls"); 60 qt_config->beginGroup("Controls");
48 qt_config->setValue("pad_a", Settings::values.pad_a_key); 61 qt_config->setValue("pad_a", Settings::values.pad_a_key);
49 qt_config->setValue("pad_b", Settings::values.pad_b_key); 62 qt_config->setValue("pad_b", Settings::values.pad_b_key);
@@ -63,58 +76,27 @@ void Config::SaveControls() {
63 qt_config->setValue("pad_sleft", Settings::values.pad_sleft_key); 76 qt_config->setValue("pad_sleft", Settings::values.pad_sleft_key);
64 qt_config->setValue("pad_sright", Settings::values.pad_sright_key); 77 qt_config->setValue("pad_sright", Settings::values.pad_sright_key);
65 qt_config->endGroup(); 78 qt_config->endGroup();
66}
67
68void Config::ReadCore() {
69 qt_config->beginGroup("Core");
70 Settings::values.cpu_core = qt_config->value("cpu_core", Core::CPU_Interpreter).toInt();
71 Settings::values.gpu_refresh_rate = qt_config->value("gpu_refresh_rate", 60).toInt();
72 qt_config->endGroup();
73}
74 79
75void Config::SaveCore() {
76 qt_config->beginGroup("Core"); 80 qt_config->beginGroup("Core");
77 qt_config->setValue("cpu_core", Settings::values.cpu_core); 81 qt_config->setValue("cpu_core", Settings::values.cpu_core);
78 qt_config->setValue("gpu_refresh_rate", Settings::values.gpu_refresh_rate); 82 qt_config->setValue("gpu_refresh_rate", Settings::values.gpu_refresh_rate);
79 qt_config->endGroup(); 83 qt_config->endGroup();
80}
81
82void Config::ReadData() {
83 qt_config->beginGroup("Data Storage");
84 Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
85 qt_config->endGroup();
86}
87 84
88void Config::SaveData() {
89 qt_config->beginGroup("Data Storage"); 85 qt_config->beginGroup("Data Storage");
90 qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd); 86 qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd);
91 qt_config->endGroup(); 87 qt_config->endGroup();
92}
93
94void Config::ReadMiscellaneous() {
95 qt_config->beginGroup("Miscellaneous");
96 Settings::values.enable_log = qt_config->value("enable_log", true).toBool();
97 qt_config->endGroup();
98}
99 88
100void Config::SaveMiscellaneous() {
101 qt_config->beginGroup("Miscellaneous"); 89 qt_config->beginGroup("Miscellaneous");
102 qt_config->setValue("enable_log", Settings::values.enable_log); 90 qt_config->setValue("enable_log", Settings::values.enable_log);
103 qt_config->endGroup(); 91 qt_config->endGroup();
104} 92}
105 93
106void Config::Reload() { 94void Config::Reload() {
107 ReadControls(); 95 ReadValues();
108 ReadCore();
109 ReadData();
110 ReadMiscellaneous();
111} 96}
112 97
113void Config::Save() { 98void Config::Save() {
114 SaveControls(); 99 SaveValues();
115 SaveCore();
116 SaveData();
117 SaveMiscellaneous();
118} 100}
119 101
120Config::~Config() { 102Config::~Config() {
diff --git a/src/citra_qt/config.h b/src/citra_qt/config.h
index 8c6568cb2..4c95d0cb9 100644
--- a/src/citra_qt/config.h
+++ b/src/citra_qt/config.h
@@ -12,15 +12,8 @@ class Config {
12 QSettings* qt_config; 12 QSettings* qt_config;
13 std::string qt_config_loc; 13 std::string qt_config_loc;
14 14
15 void ReadControls(); 15 void ReadValues();
16 void SaveControls(); 16 void SaveValues();
17 void ReadCore();
18 void SaveCore();
19 void ReadData();
20 void SaveData();
21
22 void ReadMiscellaneous();
23 void SaveMiscellaneous();
24public: 17public:
25 Config(); 18 Config();
26 ~Config(); 19 ~Config();
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index f899e2e8a..233cd3e3a 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -26,7 +26,7 @@
26#define CITRA_IGNORE_EXIT(x) 26#define CITRA_IGNORE_EXIT(x)
27 27
28#include <algorithm> 28#include <algorithm>
29#include <map> 29#include <unordered_map>
30#include <stdio.h> 30#include <stdio.h>
31#include <assert.h> 31#include <assert.h>
32#include <cstdio> 32#include <cstdio>
@@ -94,9 +94,8 @@ typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper);
94 94
95/* exclusive memory access */ 95/* exclusive memory access */
96static int exclusive_detect(ARMul_State* state, ARMword addr){ 96static int exclusive_detect(ARMul_State* state, ARMword addr){
97 int i;
98 #if 0 97 #if 0
99 for(i = 0; i < 128; i++){ 98 for(int i = 0; i < 128; i++){
100 if(state->exclusive_tag_array[i] == addr) 99 if(state->exclusive_tag_array[i] == addr)
101 return 0; 100 return 0;
102 } 101 }
@@ -108,9 +107,8 @@ static int exclusive_detect(ARMul_State* state, ARMword addr){
108} 107}
109 108
110static void add_exclusive_addr(ARMul_State* state, ARMword addr){ 109static void add_exclusive_addr(ARMul_State* state, ARMword addr){
111 int i;
112 #if 0 110 #if 0
113 for(i = 0; i < 128; i++){ 111 for(int i = 0; i < 128; i++){
114 if(state->exclusive_tag_array[i] == 0xffffffff){ 112 if(state->exclusive_tag_array[i] == 0xffffffff){
115 state->exclusive_tag_array[i] = addr; 113 state->exclusive_tag_array[i] = addr;
116 //DEBUG_LOG(ARM11, "In %s, add addr 0x%x\n", __func__, addr); 114 //DEBUG_LOG(ARM11, "In %s, add addr 0x%x\n", __func__, addr);
@@ -3309,9 +3307,8 @@ const transop_fp_t arm_instruction_trans[] = {
3309 INTERPRETER_TRANSLATE(blx_1_thumb) 3307 INTERPRETER_TRANSLATE(blx_1_thumb)
3310}; 3308};
3311 3309
3312typedef map<unsigned int, int> bb_map; 3310typedef std::unordered_map<u32, int> bb_map;
3313bb_map CreamCache[65536]; 3311bb_map CreamCache;
3314bb_map ProfileCache[65536];
3315 3312
3316//#define USE_DUMMY_CACHE 3313//#define USE_DUMMY_CACHE
3317 3314
@@ -3319,14 +3316,12 @@ bb_map ProfileCache[65536];
3319unsigned int DummyCache[0x100000]; 3316unsigned int DummyCache[0x100000];
3320#endif 3317#endif
3321 3318
3322#define HASH(x) ((x + (x << 3) + (x >> 6)) % 65536)
3323void insert_bb(unsigned int addr, int start) 3319void insert_bb(unsigned int addr, int start)
3324{ 3320{
3325#ifdef USE_DUMMY_CACHE 3321#ifdef USE_DUMMY_CACHE
3326 DummyCache[addr] = start; 3322 DummyCache[addr] = start;
3327#else 3323#else
3328// CreamCache[addr] = start; 3324 CreamCache[addr] = start;
3329 CreamCache[HASH(addr)][addr] = start;
3330#endif 3325#endif
3331} 3326}
3332 3327
@@ -3341,8 +3336,8 @@ int find_bb(unsigned int addr, int &start)
3341 } else 3336 } else
3342 ret = -1; 3337 ret = -1;
3343#else 3338#else
3344 bb_map::const_iterator it = CreamCache[HASH(addr)].find(addr); 3339 bb_map::const_iterator it = CreamCache.find(addr);
3345 if (it != CreamCache[HASH(addr)].end()) { 3340 if (it != CreamCache.end()) {
3346 start = static_cast<int>(it->second); 3341 start = static_cast<int>(it->second);
3347 ret = 0; 3342 ret = 0;
3348#if HYBRID_MODE 3343#if HYBRID_MODE
@@ -3473,30 +3468,15 @@ void flush_bb(uint32_t addr)
3473 uint32_t start; 3468 uint32_t start;
3474 3469
3475 addr &= 0xfffff000; 3470 addr &= 0xfffff000;
3476 for (int i = 0; i < 65536; i ++) { 3471 for (it = CreamCache.begin(); it != CreamCache.end(); ) {
3477 for (it = CreamCache[i].begin(); it != CreamCache[i].end(); ) { 3472 start = static_cast<uint32_t>(it->first);
3478 start = static_cast<uint32_t>(it->first); 3473 //start = (start >> 12) << 12;
3479 //start = (start >> 12) << 12; 3474 start &= 0xfffff000;
3480 start &= 0xfffff000; 3475 if (start == addr) {
3481 if (start == addr) { 3476 //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
3482 //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first)); 3477 CreamCache.erase(it++);
3483 CreamCache[i].erase(it ++); 3478 } else
3484 } else 3479 ++it;
3485 ++it;
3486 }
3487 }
3488
3489 for (int i = 0; i < 65536; i ++) {
3490 for (it = ProfileCache[i].begin(); it != ProfileCache[i].end(); ) {
3491 start = static_cast<uint32_t>(it->first);
3492 //start = (start >> 12) << 12;
3493 start &= 0xfffff000;
3494 if (start == addr) {
3495 //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
3496 ProfileCache[i].erase(it ++);
3497 } else
3498 ++it;
3499 }
3500 } 3480 }
3501 3481
3502 //DEBUG_LOG(ARM11, "flush bb @ %x\n", addr); 3482 //DEBUG_LOG(ARM11, "flush bb @ %x\n", addr);
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index b303ba128..d07e9761b 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -88,20 +88,19 @@ bool ReleaseMutexForThread(Mutex* mutex, Handle thread) {
88 88
89bool ReleaseMutex(Mutex* mutex) { 89bool ReleaseMutex(Mutex* mutex) {
90 MutexEraseLock(mutex); 90 MutexEraseLock(mutex);
91 bool woke_threads = false;
92 91
93 // Find the next waiting thread for the mutex... 92 // Find the next waiting thread for the mutex...
94 while (!woke_threads && !mutex->waiting_threads.empty()) { 93 while (!mutex->waiting_threads.empty()) {
95 std::vector<Handle>::iterator iter = mutex->waiting_threads.begin(); 94 std::vector<Handle>::iterator iter = mutex->waiting_threads.begin();
96 woke_threads |= ReleaseMutexForThread(mutex, *iter); 95 ReleaseMutexForThread(mutex, *iter);
97 mutex->waiting_threads.erase(iter); 96 mutex->waiting_threads.erase(iter);
98 } 97 }
98
99 // Reset mutex lock thread handle, nothing is waiting 99 // Reset mutex lock thread handle, nothing is waiting
100 if (!woke_threads) { 100 mutex->locked = false;
101 mutex->locked = false; 101 mutex->lock_thread = -1;
102 mutex->lock_thread = -1; 102
103 } 103 return true;
104 return woke_threads;
105} 104}
106 105
107/** 106/**
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index f3f54a4e9..f59795901 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -143,7 +143,7 @@ void ChangeReadyState(Thread* t, bool ready) {
143/// Verify that a thread has not been released from waiting 143/// Verify that a thread has not been released from waiting
144inline bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle) { 144inline bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle) {
145 _dbg_assert_(KERNEL, thread != nullptr); 145 _dbg_assert_(KERNEL, thread != nullptr);
146 return type == thread->wait_type && wait_handle == thread->wait_handle; 146 return (type == thread->wait_type) && (wait_handle == thread->wait_handle) && (thread->IsWaiting());
147} 147}
148 148
149/// Stops the current thread 149/// Stops the current thread
diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp
index 9af96f6b8..46aee40d6 100644
--- a/src/core/hle/service/ac_u.cpp
+++ b/src/core/hle/service/ac_u.cpp
@@ -11,6 +11,24 @@
11 11
12namespace AC_U { 12namespace AC_U {
13 13
14/**
15 * AC_U::GetWifiStatus service function
16 * Outputs:
17 * 1 : Result of function, 0 on success, otherwise error code
18 * 2 : Output connection type, 0 = none, 1 = Old3DS Internet, 2 = New3DS Internet.
19 */
20void GetWifiStatus(Service::Interface* self) {
21 u32* cmd_buff = Service::GetCommandBuffer();
22
23 // TODO(purpasmart96): This function is only a stub,
24 // it returns a valid result without implementing full functionality.
25
26 cmd_buff[1] = 0; // No error
27 cmd_buff[2] = 0; // Connection type set to none
28
29 WARN_LOG(KERNEL, "(STUBBED) called");
30}
31
14const Interface::FunctionInfo FunctionTable[] = { 32const Interface::FunctionInfo FunctionTable[] = {
15 {0x00010000, nullptr, "CreateDefaultConfig"}, 33 {0x00010000, nullptr, "CreateDefaultConfig"},
16 {0x00040006, nullptr, "ConnectAsync"}, 34 {0x00040006, nullptr, "ConnectAsync"},
@@ -18,7 +36,7 @@ const Interface::FunctionInfo FunctionTable[] = {
18 {0x00080004, nullptr, "CloseAsync"}, 36 {0x00080004, nullptr, "CloseAsync"},
19 {0x00090002, nullptr, "GetCloseResult"}, 37 {0x00090002, nullptr, "GetCloseResult"},
20 {0x000A0000, nullptr, "GetLastErrorCode"}, 38 {0x000A0000, nullptr, "GetLastErrorCode"},
21 {0x000D0000, nullptr, "GetWifiStatus"}, 39 {0x000D0000, GetWifiStatus, "GetWifiStatus"},
22 {0x000E0042, nullptr, "GetCurrentAPInfo"}, 40 {0x000E0042, nullptr, "GetCurrentAPInfo"},
23 {0x00100042, nullptr, "GetCurrentNZoneInfo"}, 41 {0x00100042, nullptr, "GetCurrentNZoneInfo"},
24 {0x00110042, nullptr, "GetNZoneApNumService"}, 42 {0x00110042, nullptr, "GetNZoneApNumService"},
diff --git a/src/core/hle/service/cfg_u.cpp b/src/core/hle/service/cfg_u.cpp
index 822b0e2b8..d6b586ea0 100644
--- a/src/core/hle/service/cfg_u.cpp
+++ b/src/core/hle/service/cfg_u.cpp
@@ -11,6 +11,90 @@
11 11
12namespace CFG_U { 12namespace CFG_U {
13 13
14static const std::array<const char*, 187> country_codes = {
15 nullptr, "JP", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // 0-7
16 "AI", "AG", "AR", "AW", "BS", "BB", "BZ", "BO", // 8-15
17 "BR", "VG", "CA", "KY", "CL", "CO", "CR", "DM", // 16-23
18 "DO", "EC", "SV", "GF", "GD", "GP", "GT", "GY", // 24-31
19 "HT", "HN", "JM", "MQ", "MX", "MS", "AN", "NI", // 32-39
20 "PA", "PY", "PE", "KN", "LC", "VC", "SR", "TT", // 40-47
21 "TC", "US", "UY", "VI", "VE", nullptr, nullptr, nullptr, // 48-55
22 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // 56-63
23 "AL", "AU", "AT", "BE", "BA", "BW", "BG", "HR", // 64-71
24 "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", // 72-79
25 "HU", "IS", "IE", "IT", "LV", "LS", "LI", "LT", // 80-87
26 "LU", "MK", "MT", "ME", "MZ", "NA", "NL", "NZ", // 88-95
27 "NO", "PL", "PT", "RO", "RU", "RS", "SK", "SI", // 96-103
28 "ZA", "ES", "SZ", "SE", "CH", "TR", "GB", "ZM", // 104-111
29 "ZW", "AZ", "MR", "ML", "NE", "TD", "SD", "ER", // 112-119
30 "DJ", "SO", "AD", "GI", "GG", "IM", "JE", "MC", // 120-127
31 "TW", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // 128-135
32 "KR", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // 136-143
33 "HK", "MO", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // 144-151
34 "ID", "SG", "TH", "PH", "MY", nullptr, nullptr, nullptr, // 152-159
35 "CN", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // 160-167
36 "AE", "IN", "EG", "OM", "QA", "KW", "SA", "SY", // 168-175
37 "BH", "JO", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // 176-183
38 "SM", "VA", "BM", // 184-186
39};
40
41/**
42 * CFG_User::GetCountryCodeString service function
43 * Inputs:
44 * 1 : Country Code ID
45 * Outputs:
46 * 1 : Result of function, 0 on success, otherwise error code
47 * 2 : Country's 2-char string
48 */
49static void GetCountryCodeString(Service::Interface* self) {
50 u32* cmd_buffer = Service::GetCommandBuffer();
51 u32 country_code_id = cmd_buffer[1];
52
53 if (country_code_id >= country_codes.size()) {
54 ERROR_LOG(KERNEL, "requested country code id=%d is invalid", country_code_id);
55 cmd_buffer[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw;
56 return;
57 }
58
59 const char* code = country_codes[country_code_id];
60 if (code != nullptr) {
61 cmd_buffer[1] = 0;
62 cmd_buffer[2] = code[0] | (code[1] << 8);
63 } else {
64 cmd_buffer[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw;
65 DEBUG_LOG(KERNEL, "requested country code id=%d is not set", country_code_id);
66 }
67}
68
69/**
70 * CFG_User::GetCountryCodeID service function
71 * Inputs:
72 * 1 : Country Code 2-char string
73 * Outputs:
74 * 1 : Result of function, 0 on success, otherwise error code
75 * 2 : Country Code ID
76 */
77static void GetCountryCodeID(Service::Interface* self) {
78 u32* cmd_buffer = Service::GetCommandBuffer();
79 u16 country_code = cmd_buffer[1];
80 u16 country_code_id = -1;
81
82 for (u32 i = 0; i < country_codes.size(); ++i) {
83 const char* code_string = country_codes[i];
84
85 if (code_string != nullptr) {
86 u16 code = code_string[0] | (code_string[1] << 8);
87 if (code == country_code) {
88 country_code_id = i;
89 break;
90 }
91 }
92 }
93
94 cmd_buffer[1] = 0;
95 cmd_buffer[2] = country_code_id;
96}
97
14const Interface::FunctionInfo FunctionTable[] = { 98const Interface::FunctionInfo FunctionTable[] = {
15 {0x00010082, nullptr, "GetConfigInfoBlk2"}, 99 {0x00010082, nullptr, "GetConfigInfoBlk2"},
16 {0x00020000, nullptr, "SecureInfoGetRegion"}, 100 {0x00020000, nullptr, "SecureInfoGetRegion"},
@@ -20,8 +104,8 @@ const Interface::FunctionInfo FunctionTable[] = {
20 {0x00060000, nullptr, "GetModelNintendo2DS"}, 104 {0x00060000, nullptr, "GetModelNintendo2DS"},
21 {0x00070040, nullptr, "unknown"}, 105 {0x00070040, nullptr, "unknown"},
22 {0x00080080, nullptr, "unknown"}, 106 {0x00080080, nullptr, "unknown"},
23 {0x00090080, nullptr, "GetCountryCodeString"}, 107 {0x00090040, GetCountryCodeString, "GetCountryCodeString"},
24 {0x000A0040, nullptr, "GetCountryCodeID"}, 108 {0x000A0040, GetCountryCodeID, "GetCountryCodeID"},
25}; 109};
26//////////////////////////////////////////////////////////////////////////////////////////////////// 110////////////////////////////////////////////////////////////////////////////////////////////////////
27// Interface class 111// Interface class
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index bbcf26f61..a2b68cac8 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -4,6 +4,7 @@
4 4
5#include "common/log.h" 5#include "common/log.h"
6#include "core/hle/hle.h" 6#include "core/hle/hle.h"
7#include "core/hle/kernel/event.h"
7#include "core/hle/service/dsp_dsp.h" 8#include "core/hle/service/dsp_dsp.h"
8 9
9//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -11,38 +12,118 @@
11 12
12namespace DSP_DSP { 13namespace DSP_DSP {
13 14
15static Handle semaphore_event;
16static Handle interrupt_event;
17
18/**
19 * DSP_DSP::LoadComponent service function
20 * Inputs:
21 * 1 : Size
22 * 2 : Unknown (observed only half word used)
23 * 3 : Unknown (observed only half word used)
24 * 4 : (size << 4) | 0xA
25 * 5 : Buffer address
26 * Outputs:
27 * 1 : Result of function, 0 on success, otherwise error code
28 * 2 : Component loaded, 0 on not loaded, 1 on loaded
29 */
30void LoadComponent(Service::Interface* self) {
31 u32* cmd_buff = Service::GetCommandBuffer();
32
33 cmd_buff[1] = 0; // No error
34 cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware
35
36 // TODO(bunnei): Implement real DSP firmware loading
37
38 DEBUG_LOG(KERNEL, "(STUBBED) called");
39}
40
41/**
42 * DSP_DSP::GetSemaphoreEventHandle service function
43 * Outputs:
44 * 1 : Result of function, 0 on success, otherwise error code
45 * 3 : Semaphore event handle
46 */
47void GetSemaphoreEventHandle(Service::Interface* self) {
48 u32* cmd_buff = Service::GetCommandBuffer();
49
50 cmd_buff[1] = 0; // No error
51 cmd_buff[3] = semaphore_event; // Event handle
52
53 DEBUG_LOG(KERNEL, "(STUBBED) called");
54}
55
56/**
57 * DSP_DSP::RegisterInterruptEvents service function
58 * Inputs:
59 * 1 : Parameter 0 (purpose unknown)
60 * 2 : Parameter 1 (purpose unknown)
61 * 4 : Interrupt event handle
62 * Outputs:
63 * 1 : Result of function, 0 on success, otherwise error code
64 */
65void RegisterInterruptEvents(Service::Interface* self) {
66 u32* cmd_buff = Service::GetCommandBuffer();
67
68 interrupt_event = static_cast<Handle>(cmd_buff[4]);
69
70 cmd_buff[1] = 0; // No error
71
72 DEBUG_LOG(KERNEL, "(STUBBED) called");
73}
74
75/**
76 * DSP_DSP::WriteReg0x10 service function
77 * Inputs:
78 * 1 : Unknown (observed only half word used)
79 * Outputs:
80 * 1 : Result of function, 0 on success, otherwise error code
81 */
82void WriteReg0x10(Service::Interface* self) {
83 u32* cmd_buff = Service::GetCommandBuffer();
84
85 Kernel::SignalEvent(interrupt_event);
86
87 cmd_buff[1] = 0; // No error
88
89 DEBUG_LOG(KERNEL, "(STUBBED) called");
90}
91
14const Interface::FunctionInfo FunctionTable[] = { 92const Interface::FunctionInfo FunctionTable[] = {
15 {0x00010040, nullptr, "RecvData"}, 93 {0x00010040, nullptr, "RecvData"},
16 {0x00020040, nullptr, "RecvDataIsReady"}, 94 {0x00020040, nullptr, "RecvDataIsReady"},
17 {0x00030080, nullptr, "SendData"}, 95 {0x00030080, nullptr, "SendData"},
18 {0x00040040, nullptr, "SendDataIsEmpty"}, 96 {0x00040040, nullptr, "SendDataIsEmpty"},
19 {0x00070040, nullptr, "WriteReg0x10"}, 97 {0x00070040, WriteReg0x10, "WriteReg0x10"},
20 {0x00080000, nullptr, "GetSemaphore"}, 98 {0x00080000, nullptr, "GetSemaphore"},
21 {0x00090040, nullptr, "ClearSemaphore"}, 99 {0x00090040, nullptr, "ClearSemaphore"},
22 {0x000B0000, nullptr, "CheckSemaphoreRequest"}, 100 {0x000B0000, nullptr, "CheckSemaphoreRequest"},
23 {0x000C0040, nullptr, "ConvertProcessAddressFromDspDram"}, 101 {0x000C0040, nullptr, "ConvertProcessAddressFromDspDram"},
24 {0x000D0082, nullptr, "WriteProcessPipe"}, 102 {0x000D0082, nullptr, "WriteProcessPipe"},
25 {0x001000C0, nullptr, "ReadPipeIfPossible"}, 103 {0x001000C0, nullptr, "ReadPipeIfPossible"},
26 {0x001100C2, nullptr, "LoadComponent"}, 104 {0x001100C2, LoadComponent, "LoadComponent"},
27 {0x00120000, nullptr, "UnloadComponent"}, 105 {0x00120000, nullptr, "UnloadComponent"},
28 {0x00130082, nullptr, "FlushDataCache"}, 106 {0x00130082, nullptr, "FlushDataCache"},
29 {0x00140082, nullptr, "InvalidateDCache"}, 107 {0x00140082, nullptr, "InvalidateDCache"},
30 {0x00150082, nullptr, "RegisterInterruptEvents"}, 108 {0x00150082, RegisterInterruptEvents, "RegisterInterruptEvents"},
31 {0x00160000, nullptr, "GetSemaphoreEventHandle"}, 109 {0x00160000, GetSemaphoreEventHandle, "GetSemaphoreEventHandle"},
32 {0x00170040, nullptr, "SetSemaphoreMask"}, 110 {0x00170040, nullptr, "SetSemaphoreMask"},
33 {0x00180040, nullptr, "GetPhysicalAddress"}, 111 {0x00180040, nullptr, "GetPhysicalAddress"},
34 {0x00190040, nullptr, "GetVirtualAddress"}, 112 {0x00190040, nullptr, "GetVirtualAddress"},
35 {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"}, 113 {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"},
36 {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"}, 114 {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"},
37 {0x001C0082, nullptr, "SetIirFilterEQ"}, 115 {0x001C0082, nullptr, "SetIirFilterEQ"},
38 {0x001F0000, nullptr, "GetHeadphoneStatus"}, 116 {0x001F0000, nullptr, "GetHeadphoneStatus"},
39 {0x00210000, nullptr, "GetIsDspOccupied"}, 117 {0x00210000, nullptr, "GetIsDspOccupied"},
40}; 118};
41 119
42//////////////////////////////////////////////////////////////////////////////////////////////////// 120////////////////////////////////////////////////////////////////////////////////////////////////////
43// Interface class 121// Interface class
44 122
45Interface::Interface() { 123Interface::Interface() {
124 semaphore_event = Kernel::CreateEvent(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event");
125 interrupt_event = 0;
126
46 Register(FunctionTable, ARRAY_SIZE(FunctionTable)); 127 Register(FunctionTable, ARRAY_SIZE(FunctionTable));
47} 128}
48 129
diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h
index c4ce44245..9431b62f6 100644
--- a/src/core/hle/service/dsp_dsp.h
+++ b/src/core/hle/service/dsp_dsp.h
@@ -20,7 +20,7 @@ public:
20 * @return Port name of service 20 * @return Port name of service
21 */ 21 */
22 std::string GetPortName() const override { 22 std::string GetPortName() const override {
23 return "dsp:DSP"; 23 return "dsp::DSP";
24 } 24 }
25}; 25};
26 26
diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp
index d9122dbbc..1ce32ee4a 100644
--- a/src/core/hle/service/ptm_u.cpp
+++ b/src/core/hle/service/ptm_u.cpp
@@ -11,13 +11,30 @@
11 11
12namespace PTM_U { 12namespace PTM_U {
13 13
14static bool shell_open = true;
15
16/*
17 * PTM_User::GetShellState service function.
18 * Outputs:
19 * 1 : Result of function, 0 on success, otherwise error code
20 * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0)
21 */
22static void GetShellState(Service::Interface* self) {
23 u32* cmd_buff = Service::GetCommandBuffer();
24
25 cmd_buff[1] = 0;
26 cmd_buff[2] = shell_open ? 1 : 0;
27
28 DEBUG_LOG(KERNEL, "PTM_U::GetShellState called");
29}
30
14const Interface::FunctionInfo FunctionTable[] = { 31const Interface::FunctionInfo FunctionTable[] = {
15 {0x00010002, nullptr, "RegisterAlarmClient"}, 32 {0x00010002, nullptr, "RegisterAlarmClient"},
16 {0x00020080, nullptr, "SetRtcAlarm"}, 33 {0x00020080, nullptr, "SetRtcAlarm"},
17 {0x00030000, nullptr, "GetRtcAlarm"}, 34 {0x00030000, nullptr, "GetRtcAlarm"},
18 {0x00040000, nullptr, "CancelRtcAlarm"}, 35 {0x00040000, nullptr, "CancelRtcAlarm"},
19 {0x00050000, nullptr, "GetAdapterState"}, 36 {0x00050000, nullptr, "GetAdapterState"},
20 {0x00060000, nullptr, "GetShellState"}, 37 {0x00060000, GetShellState, "GetShellState"},
21 {0x00070000, nullptr, "GetBatteryLevel"}, 38 {0x00070000, nullptr, "GetBatteryLevel"},
22 {0x00080000, nullptr, "GetBatteryChargeState"}, 39 {0x00080000, nullptr, "GetBatteryChargeState"},
23 {0x00090000, nullptr, "GetPedometerState"}, 40 {0x00090000, nullptr, "GetPedometerState"},
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 87d768856..43a3cbe03 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -189,6 +189,8 @@ static Result CreateAddressArbiter(u32* arbiter) {
189 189
190/// Arbitrate address 190/// Arbitrate address
191static Result ArbitrateAddress(Handle arbiter, u32 address, u32 type, u32 value, s64 nanoseconds) { 191static Result ArbitrateAddress(Handle arbiter, u32 address, u32 type, u32 value, s64 nanoseconds) {
192 DEBUG_LOG(SVC, "called handle=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X", arbiter,
193 address, type, value);
192 return Kernel::ArbitrateAddress(arbiter, static_cast<Kernel::ArbitrationType>(type), 194 return Kernel::ArbitrateAddress(arbiter, static_cast<Kernel::ArbitrationType>(type),
193 address, value).raw; 195 address, value).raw;
194} 196}
@@ -331,6 +333,9 @@ static Result ClearEvent(Handle evt) {
331/// Sleep the current thread 333/// Sleep the current thread
332static void SleepThread(s64 nanoseconds) { 334static void SleepThread(s64 nanoseconds) {
333 DEBUG_LOG(SVC, "called nanoseconds=%lld", nanoseconds); 335 DEBUG_LOG(SVC, "called nanoseconds=%lld", nanoseconds);
336
337 // Check for next thread to schedule
338 HLE::Reschedule(__func__);
334} 339}
335 340
336/// This returns the total CPU ticks elapsed since the CPU was powered-on 341/// This returns the total CPU ticks elapsed since the CPU was powered-on
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 2469d0b01..06de6afbd 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -240,14 +240,14 @@ MathUtil::Rectangle<unsigned> RendererOpenGL::GetViewportExtent() {
240 MathUtil::Rectangle<unsigned> viewport_extent; 240 MathUtil::Rectangle<unsigned> viewport_extent;
241 if (window_aspect_ratio > emulation_aspect_ratio) { 241 if (window_aspect_ratio > emulation_aspect_ratio) {
242 // Window is narrower than the emulation content => apply borders to the top and bottom 242 // Window is narrower than the emulation content => apply borders to the top and bottom
243 unsigned viewport_height = emulation_aspect_ratio * framebuffer_width; 243 unsigned viewport_height = std::round(emulation_aspect_ratio * framebuffer_width);
244 viewport_extent.left = 0; 244 viewport_extent.left = 0;
245 viewport_extent.top = (framebuffer_height - viewport_height) / 2; 245 viewport_extent.top = (framebuffer_height - viewport_height) / 2;
246 viewport_extent.right = viewport_extent.left + framebuffer_width; 246 viewport_extent.right = viewport_extent.left + framebuffer_width;
247 viewport_extent.bottom = viewport_extent.top + viewport_height; 247 viewport_extent.bottom = viewport_extent.top + viewport_height;
248 } else { 248 } else {
249 // Otherwise, apply borders to the left and right sides of the window. 249 // Otherwise, apply borders to the left and right sides of the window.
250 unsigned viewport_width = framebuffer_height / emulation_aspect_ratio; 250 unsigned viewport_width = std::round(framebuffer_height / emulation_aspect_ratio);
251 viewport_extent.left = (framebuffer_width - viewport_width) / 2; 251 viewport_extent.left = (framebuffer_width - viewport_width) / 2;
252 viewport_extent.top = 0; 252 viewport_extent.top = 0;
253 viewport_extent.right = viewport_extent.left + viewport_width; 253 viewport_extent.right = viewport_extent.left + viewport_width;