diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/citra/config.cpp | 17 | ||||
| -rw-r--r-- | src/citra/config.h | 5 | ||||
| -rw-r--r-- | src/citra/emu_window/emu_window_glfw.cpp | 8 | ||||
| -rw-r--r-- | src/citra_qt/config.cpp | 52 | ||||
| -rw-r--r-- | src/citra_qt/config.h | 11 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 54 | ||||
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 15 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/ac_u.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/service/cfg_u.cpp | 88 | ||||
| -rw-r--r-- | src/core/hle/service/dsp_dsp.cpp | 131 | ||||
| -rw-r--r-- | src/core/hle/service/dsp_dsp.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/ptm_u.cpp | 19 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 4 |
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 | ||
| 39 | void Config::ReadControls() { | 39 | void 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 | ||
| 59 | void 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 | ||
| 64 | void 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 | ||
| 68 | void 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 | ||
| 72 | void Config::Reload() { | 70 | void 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 | ||
| 80 | Config::~Config() { | 75 | Config::~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(); | ||
| 22 | public: | 19 | public: |
| 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 | ||
| 24 | void Config::ReadControls() { | 24 | void 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 | ||
| 46 | void Config::SaveControls() { | 59 | void 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 | |||
| 68 | void 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 | ||
| 75 | void 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 | |||
| 82 | void 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 | ||
| 88 | void 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 | |||
| 94 | void 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 | ||
| 100 | void 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 | ||
| 106 | void Config::Reload() { | 94 | void Config::Reload() { |
| 107 | ReadControls(); | 95 | ReadValues(); |
| 108 | ReadCore(); | ||
| 109 | ReadData(); | ||
| 110 | ReadMiscellaneous(); | ||
| 111 | } | 96 | } |
| 112 | 97 | ||
| 113 | void Config::Save() { | 98 | void Config::Save() { |
| 114 | SaveControls(); | 99 | SaveValues(); |
| 115 | SaveCore(); | ||
| 116 | SaveData(); | ||
| 117 | SaveMiscellaneous(); | ||
| 118 | } | 100 | } |
| 119 | 101 | ||
| 120 | Config::~Config() { | 102 | Config::~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(); | ||
| 24 | public: | 17 | public: |
| 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 */ |
| 96 | static int exclusive_detect(ARMul_State* state, ARMword addr){ | 96 | static 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 | ||
| 110 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ | 109 | static 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 | ||
| 3312 | typedef map<unsigned int, int> bb_map; | 3310 | typedef std::unordered_map<u32, int> bb_map; |
| 3313 | bb_map CreamCache[65536]; | 3311 | bb_map CreamCache; |
| 3314 | bb_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]; | |||
| 3319 | unsigned int DummyCache[0x100000]; | 3316 | unsigned int DummyCache[0x100000]; |
| 3320 | #endif | 3317 | #endif |
| 3321 | 3318 | ||
| 3322 | #define HASH(x) ((x + (x << 3) + (x >> 6)) % 65536) | ||
| 3323 | void insert_bb(unsigned int addr, int start) | 3319 | void 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 | ||
| 89 | bool ReleaseMutex(Mutex* mutex) { | 89 | bool 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 |
| 144 | inline bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle) { | 144 | inline 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 | ||
| 12 | namespace AC_U { | 12 | namespace 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 | */ | ||
| 20 | void 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 | |||
| 14 | const Interface::FunctionInfo FunctionTable[] = { | 32 | const 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 | ||
| 12 | namespace CFG_U { | 12 | namespace CFG_U { |
| 13 | 13 | ||
| 14 | static 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 | */ | ||
| 49 | static 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 | */ | ||
| 77 | static 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 | |||
| 14 | const Interface::FunctionInfo FunctionTable[] = { | 98 | const 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 | ||
| 12 | namespace DSP_DSP { | 13 | namespace DSP_DSP { |
| 13 | 14 | ||
| 15 | static Handle semaphore_event; | ||
| 16 | static 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 | */ | ||
| 30 | void 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 | */ | ||
| 47 | void 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 | */ | ||
| 65 | void 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 | */ | ||
| 82 | void 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 | |||
| 14 | const Interface::FunctionInfo FunctionTable[] = { | 92 | const 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 | ||
| 45 | Interface::Interface() { | 123 | Interface::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 | ||
| 12 | namespace PTM_U { | 12 | namespace PTM_U { |
| 13 | 13 | ||
| 14 | static 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 | */ | ||
| 22 | static 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 | |||
| 14 | const Interface::FunctionInfo FunctionTable[] = { | 31 | const 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 |
| 191 | static Result ArbitrateAddress(Handle arbiter, u32 address, u32 type, u32 value, s64 nanoseconds) { | 191 | static 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 |
| 332 | static void SleepThread(s64 nanoseconds) { | 334 | static 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; |