diff options
| -rw-r--r-- | src/citra/config.cpp | 36 | ||||
| -rw-r--r-- | src/citra/emu_window/emu_window_glfw.cpp | 29 | ||||
| -rw-r--r-- | src/citra_qt/bootmanager.cpp | 29 | ||||
| -rw-r--r-- | src/citra_qt/config.cpp | 63 | ||||
| -rw-r--r-- | src/citra_qt/main.cpp | 3 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_dec.cpp | 25 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_dec.h | 16 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 133 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_thumb.cpp | 28 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_thumb.h | 28 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armstate.h | 25 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/soc_u.cpp | 10 | ||||
| -rw-r--r-- | src/core/settings.h | 54 |
15 files changed, 216 insertions, 278 deletions
diff --git a/src/citra/config.cpp b/src/citra/config.cpp index 506cb7939..2c1407a6f 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp | |||
| @@ -40,31 +40,21 @@ bool Config::LoadINI(INIReader* config, const char* location, const std::string& | |||
| 40 | return true; | 40 | return true; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = { | ||
| 44 | GLFW_KEY_A, GLFW_KEY_S, GLFW_KEY_Z, GLFW_KEY_X, | ||
| 45 | GLFW_KEY_Q, GLFW_KEY_W, GLFW_KEY_1, GLFW_KEY_2, | ||
| 46 | GLFW_KEY_M, GLFW_KEY_N, GLFW_KEY_B, | ||
| 47 | GLFW_KEY_T, GLFW_KEY_G, GLFW_KEY_F, GLFW_KEY_H, | ||
| 48 | GLFW_KEY_UP, GLFW_KEY_DOWN, GLFW_KEY_LEFT, GLFW_KEY_RIGHT, | ||
| 49 | GLFW_KEY_I, GLFW_KEY_K, GLFW_KEY_J, GLFW_KEY_L | ||
| 50 | }; | ||
| 51 | |||
| 43 | void Config::ReadValues() { | 52 | void Config::ReadValues() { |
| 44 | // Controls | 53 | // Controls |
| 45 | Settings::values.pad_a_key = glfw_config->GetInteger("Controls", "pad_a", GLFW_KEY_A); | 54 | for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { |
| 46 | Settings::values.pad_b_key = glfw_config->GetInteger("Controls", "pad_b", GLFW_KEY_S); | 55 | Settings::values.input_mappings[Settings::NativeInput::All[i]] = |
| 47 | Settings::values.pad_x_key = glfw_config->GetInteger("Controls", "pad_x", GLFW_KEY_Z); | 56 | glfw_config->GetInteger("Controls", Settings::NativeInput::Mapping[i], defaults[i]); |
| 48 | Settings::values.pad_y_key = glfw_config->GetInteger("Controls", "pad_y", GLFW_KEY_X); | 57 | } |
| 49 | Settings::values.pad_l_key = glfw_config->GetInteger("Controls", "pad_l", GLFW_KEY_Q); | ||
| 50 | Settings::values.pad_r_key = glfw_config->GetInteger("Controls", "pad_r", GLFW_KEY_W); | ||
| 51 | Settings::values.pad_zl_key = glfw_config->GetInteger("Controls", "pad_zl", GLFW_KEY_1); | ||
| 52 | Settings::values.pad_zr_key = glfw_config->GetInteger("Controls", "pad_zr", GLFW_KEY_2); | ||
| 53 | Settings::values.pad_start_key = glfw_config->GetInteger("Controls", "pad_start", GLFW_KEY_M); | ||
| 54 | Settings::values.pad_select_key = glfw_config->GetInteger("Controls", "pad_select", GLFW_KEY_N); | ||
| 55 | Settings::values.pad_home_key = glfw_config->GetInteger("Controls", "pad_home", GLFW_KEY_B); | ||
| 56 | Settings::values.pad_dup_key = glfw_config->GetInteger("Controls", "pad_dup", GLFW_KEY_T); | ||
| 57 | Settings::values.pad_ddown_key = glfw_config->GetInteger("Controls", "pad_ddown", GLFW_KEY_G); | ||
| 58 | Settings::values.pad_dleft_key = glfw_config->GetInteger("Controls", "pad_dleft", GLFW_KEY_F); | ||
| 59 | Settings::values.pad_dright_key = glfw_config->GetInteger("Controls", "pad_dright", GLFW_KEY_H); | ||
| 60 | Settings::values.pad_sup_key = glfw_config->GetInteger("Controls", "pad_sup", GLFW_KEY_UP); | ||
| 61 | Settings::values.pad_sdown_key = glfw_config->GetInteger("Controls", "pad_sdown", GLFW_KEY_DOWN); | ||
| 62 | Settings::values.pad_sleft_key = glfw_config->GetInteger("Controls", "pad_sleft", GLFW_KEY_LEFT); | ||
| 63 | Settings::values.pad_sright_key = glfw_config->GetInteger("Controls", "pad_sright", GLFW_KEY_RIGHT); | ||
| 64 | Settings::values.pad_cup_key = glfw_config->GetInteger("Controls", "pad_cup", GLFW_KEY_I); | ||
| 65 | Settings::values.pad_cdown_key = glfw_config->GetInteger("Controls", "pad_cdown", GLFW_KEY_K); | ||
| 66 | Settings::values.pad_cleft_key = glfw_config->GetInteger("Controls", "pad_cleft", GLFW_KEY_J); | ||
| 67 | Settings::values.pad_cright_key = glfw_config->GetInteger("Controls", "pad_cright", GLFW_KEY_L); | ||
| 68 | 58 | ||
| 69 | // Core | 59 | // Core |
| 70 | Settings::values.frame_skip = glfw_config->GetInteger("Core", "frame_skip", 0); | 60 | Settings::values.frame_skip = glfw_config->GetInteger("Core", "frame_skip", 0); |
diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp index 42fb683a9..6d6656b5a 100644 --- a/src/citra/emu_window/emu_window_glfw.cpp +++ b/src/citra/emu_window/emu_window_glfw.cpp | |||
| @@ -150,32 +150,9 @@ void EmuWindow_GLFW::DoneCurrent() { | |||
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | void EmuWindow_GLFW::ReloadSetKeymaps() { | 152 | void EmuWindow_GLFW::ReloadSetKeymaps() { |
| 153 | KeyMap::SetKeyMapping({Settings::values.pad_a_key, keyboard_id}, Service::HID::PAD_A); | 153 | for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { |
| 154 | KeyMap::SetKeyMapping({Settings::values.pad_b_key, keyboard_id}, Service::HID::PAD_B); | 154 | KeyMap::SetKeyMapping({Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, Service::HID::pad_mapping[i]); |
| 155 | KeyMap::SetKeyMapping({Settings::values.pad_select_key, keyboard_id}, Service::HID::PAD_SELECT); | 155 | } |
| 156 | KeyMap::SetKeyMapping({Settings::values.pad_start_key, keyboard_id}, Service::HID::PAD_START); | ||
| 157 | KeyMap::SetKeyMapping({Settings::values.pad_dright_key, keyboard_id}, Service::HID::PAD_RIGHT); | ||
| 158 | KeyMap::SetKeyMapping({Settings::values.pad_dleft_key, keyboard_id}, Service::HID::PAD_LEFT); | ||
| 159 | KeyMap::SetKeyMapping({Settings::values.pad_dup_key, keyboard_id}, Service::HID::PAD_UP); | ||
| 160 | KeyMap::SetKeyMapping({Settings::values.pad_ddown_key, keyboard_id}, Service::HID::PAD_DOWN); | ||
| 161 | KeyMap::SetKeyMapping({Settings::values.pad_r_key, keyboard_id}, Service::HID::PAD_R); | ||
| 162 | KeyMap::SetKeyMapping({Settings::values.pad_l_key, keyboard_id}, Service::HID::PAD_L); | ||
| 163 | KeyMap::SetKeyMapping({Settings::values.pad_x_key, keyboard_id}, Service::HID::PAD_X); | ||
| 164 | KeyMap::SetKeyMapping({Settings::values.pad_y_key, keyboard_id}, Service::HID::PAD_Y); | ||
| 165 | |||
| 166 | KeyMap::SetKeyMapping({Settings::values.pad_zl_key, keyboard_id}, Service::HID::PAD_ZL); | ||
| 167 | KeyMap::SetKeyMapping({Settings::values.pad_zr_key, keyboard_id}, Service::HID::PAD_ZR); | ||
| 168 | |||
| 169 | // KeyMap::SetKeyMapping({Settings::values.pad_touch_key, keyboard_id}, Service::HID::PAD_TOUCH); | ||
| 170 | |||
| 171 | KeyMap::SetKeyMapping({Settings::values.pad_cright_key, keyboard_id}, Service::HID::PAD_C_RIGHT); | ||
| 172 | KeyMap::SetKeyMapping({Settings::values.pad_cleft_key, keyboard_id}, Service::HID::PAD_C_LEFT); | ||
| 173 | KeyMap::SetKeyMapping({Settings::values.pad_cup_key, keyboard_id}, Service::HID::PAD_C_UP); | ||
| 174 | KeyMap::SetKeyMapping({Settings::values.pad_cdown_key, keyboard_id}, Service::HID::PAD_C_DOWN); | ||
| 175 | KeyMap::SetKeyMapping({Settings::values.pad_sright_key, keyboard_id}, Service::HID::PAD_CIRCLE_RIGHT); | ||
| 176 | KeyMap::SetKeyMapping({Settings::values.pad_sleft_key, keyboard_id}, Service::HID::PAD_CIRCLE_LEFT); | ||
| 177 | KeyMap::SetKeyMapping({Settings::values.pad_sup_key, keyboard_id}, Service::HID::PAD_CIRCLE_UP); | ||
| 178 | KeyMap::SetKeyMapping({Settings::values.pad_sdown_key, keyboard_id}, Service::HID::PAD_CIRCLE_DOWN); | ||
| 179 | } | 156 | } |
| 180 | 157 | ||
| 181 | void EmuWindow_GLFW::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) { | 158 | void EmuWindow_GLFW::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) { |
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index fa7bce466..b12bd858b 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp | |||
| @@ -248,32 +248,9 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent *event) | |||
| 248 | 248 | ||
| 249 | void GRenderWindow::ReloadSetKeymaps() | 249 | void GRenderWindow::ReloadSetKeymaps() |
| 250 | { | 250 | { |
| 251 | KeyMap::SetKeyMapping({Settings::values.pad_a_key, keyboard_id}, Service::HID::PAD_A); | 251 | for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { |
| 252 | KeyMap::SetKeyMapping({Settings::values.pad_b_key, keyboard_id}, Service::HID::PAD_B); | 252 | KeyMap::SetKeyMapping({Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, Service::HID::pad_mapping[i]); |
| 253 | KeyMap::SetKeyMapping({Settings::values.pad_select_key, keyboard_id}, Service::HID::PAD_SELECT); | 253 | } |
| 254 | KeyMap::SetKeyMapping({Settings::values.pad_start_key, keyboard_id}, Service::HID::PAD_START); | ||
| 255 | KeyMap::SetKeyMapping({Settings::values.pad_dright_key, keyboard_id}, Service::HID::PAD_RIGHT); | ||
| 256 | KeyMap::SetKeyMapping({Settings::values.pad_dleft_key, keyboard_id}, Service::HID::PAD_LEFT); | ||
| 257 | KeyMap::SetKeyMapping({Settings::values.pad_dup_key, keyboard_id}, Service::HID::PAD_UP); | ||
| 258 | KeyMap::SetKeyMapping({Settings::values.pad_ddown_key, keyboard_id}, Service::HID::PAD_DOWN); | ||
| 259 | KeyMap::SetKeyMapping({Settings::values.pad_r_key, keyboard_id}, Service::HID::PAD_R); | ||
| 260 | KeyMap::SetKeyMapping({Settings::values.pad_l_key, keyboard_id}, Service::HID::PAD_L); | ||
| 261 | KeyMap::SetKeyMapping({Settings::values.pad_x_key, keyboard_id}, Service::HID::PAD_X); | ||
| 262 | KeyMap::SetKeyMapping({Settings::values.pad_y_key, keyboard_id}, Service::HID::PAD_Y); | ||
| 263 | |||
| 264 | KeyMap::SetKeyMapping({Settings::values.pad_zl_key, keyboard_id}, Service::HID::PAD_ZL); | ||
| 265 | KeyMap::SetKeyMapping({Settings::values.pad_zr_key, keyboard_id}, Service::HID::PAD_ZR); | ||
| 266 | |||
| 267 | // KeyMap::SetKeyMapping({Settings::values.pad_touch_key, keyboard_id}, Service::HID::PAD_TOUCH); | ||
| 268 | |||
| 269 | KeyMap::SetKeyMapping({Settings::values.pad_cright_key, keyboard_id}, Service::HID::PAD_C_RIGHT); | ||
| 270 | KeyMap::SetKeyMapping({Settings::values.pad_cleft_key, keyboard_id}, Service::HID::PAD_C_LEFT); | ||
| 271 | KeyMap::SetKeyMapping({Settings::values.pad_cup_key, keyboard_id}, Service::HID::PAD_C_UP); | ||
| 272 | KeyMap::SetKeyMapping({Settings::values.pad_cdown_key, keyboard_id}, Service::HID::PAD_C_DOWN); | ||
| 273 | KeyMap::SetKeyMapping({Settings::values.pad_sright_key, keyboard_id}, Service::HID::PAD_CIRCLE_RIGHT); | ||
| 274 | KeyMap::SetKeyMapping({Settings::values.pad_sleft_key, keyboard_id}, Service::HID::PAD_CIRCLE_LEFT); | ||
| 275 | KeyMap::SetKeyMapping({Settings::values.pad_sup_key, keyboard_id}, Service::HID::PAD_CIRCLE_UP); | ||
| 276 | KeyMap::SetKeyMapping({Settings::values.pad_sdown_key, keyboard_id}, Service::HID::PAD_CIRCLE_DOWN); | ||
| 277 | } | 254 | } |
| 278 | 255 | ||
| 279 | void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) | 256 | void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) |
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp index 5c056446e..5716634ee 100644 --- a/src/citra_qt/config.cpp +++ b/src/citra_qt/config.cpp | |||
| @@ -21,31 +21,21 @@ Config::Config() { | |||
| 21 | Reload(); | 21 | Reload(); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | static const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> defaults = { | ||
| 25 | Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, | ||
| 26 | Qt::Key_Q, Qt::Key_W, Qt::Key_1, Qt::Key_2, | ||
| 27 | Qt::Key_M, Qt::Key_N, Qt::Key_B, | ||
| 28 | Qt::Key_T, Qt::Key_G, Qt::Key_F, Qt::Key_H, | ||
| 29 | Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right, | ||
| 30 | Qt::Key_I, Qt::Key_K, Qt::Key_J, Qt::Key_L | ||
| 31 | }; | ||
| 32 | |||
| 24 | void Config::ReadValues() { | 33 | void Config::ReadValues() { |
| 25 | qt_config->beginGroup("Controls"); | 34 | qt_config->beginGroup("Controls"); |
| 26 | Settings::values.pad_a_key = qt_config->value("pad_a", Qt::Key_A).toInt(); | 35 | for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { |
| 27 | Settings::values.pad_b_key = qt_config->value("pad_b", Qt::Key_S).toInt(); | 36 | Settings::values.input_mappings[Settings::NativeInput::All[i]] = |
| 28 | Settings::values.pad_x_key = qt_config->value("pad_x", Qt::Key_Z).toInt(); | 37 | qt_config->value(QString::fromStdString(Settings::NativeInput::Mapping[i]), defaults[i]).toInt(); |
| 29 | Settings::values.pad_y_key = qt_config->value("pad_y", Qt::Key_X).toInt(); | 38 | } |
| 30 | Settings::values.pad_l_key = qt_config->value("pad_l", Qt::Key_Q).toInt(); | ||
| 31 | Settings::values.pad_r_key = qt_config->value("pad_r", Qt::Key_W).toInt(); | ||
| 32 | Settings::values.pad_zl_key = qt_config->value("pad_zl", Qt::Key_1).toInt(); | ||
| 33 | Settings::values.pad_zr_key = qt_config->value("pad_zr", Qt::Key_2).toInt(); | ||
| 34 | Settings::values.pad_start_key = qt_config->value("pad_start", Qt::Key_M).toInt(); | ||
| 35 | Settings::values.pad_select_key = qt_config->value("pad_select", Qt::Key_N).toInt(); | ||
| 36 | Settings::values.pad_home_key = qt_config->value("pad_home", Qt::Key_B).toInt(); | ||
| 37 | Settings::values.pad_dup_key = qt_config->value("pad_dup", Qt::Key_T).toInt(); | ||
| 38 | Settings::values.pad_ddown_key = qt_config->value("pad_ddown", Qt::Key_G).toInt(); | ||
| 39 | Settings::values.pad_dleft_key = qt_config->value("pad_dleft", Qt::Key_F).toInt(); | ||
| 40 | Settings::values.pad_dright_key = qt_config->value("pad_dright", Qt::Key_H).toInt(); | ||
| 41 | Settings::values.pad_sup_key = qt_config->value("pad_sup", Qt::Key_Up).toInt(); | ||
| 42 | Settings::values.pad_sdown_key = qt_config->value("pad_sdown", Qt::Key_Down).toInt(); | ||
| 43 | Settings::values.pad_sleft_key = qt_config->value("pad_sleft", Qt::Key_Left).toInt(); | ||
| 44 | Settings::values.pad_sright_key = qt_config->value("pad_sright", Qt::Key_Right).toInt(); | ||
| 45 | Settings::values.pad_cup_key = qt_config->value("pad_cup", Qt::Key_I).toInt(); | ||
| 46 | Settings::values.pad_cdown_key = qt_config->value("pad_cdown", Qt::Key_K).toInt(); | ||
| 47 | Settings::values.pad_cleft_key = qt_config->value("pad_cleft", Qt::Key_J).toInt(); | ||
| 48 | Settings::values.pad_cright_key = qt_config->value("pad_cright", Qt::Key_L).toInt(); | ||
| 49 | qt_config->endGroup(); | 39 | qt_config->endGroup(); |
| 50 | 40 | ||
| 51 | qt_config->beginGroup("Core"); | 41 | qt_config->beginGroup("Core"); |
| @@ -75,29 +65,10 @@ void Config::ReadValues() { | |||
| 75 | 65 | ||
| 76 | void Config::SaveValues() { | 66 | void Config::SaveValues() { |
| 77 | qt_config->beginGroup("Controls"); | 67 | qt_config->beginGroup("Controls"); |
| 78 | qt_config->setValue("pad_a", Settings::values.pad_a_key); | 68 | for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { |
| 79 | qt_config->setValue("pad_b", Settings::values.pad_b_key); | 69 | qt_config->setValue(QString::fromStdString(Settings::NativeInput::Mapping[i]), |
| 80 | qt_config->setValue("pad_x", Settings::values.pad_x_key); | 70 | Settings::values.input_mappings[Settings::NativeInput::All[i]]); |
| 81 | qt_config->setValue("pad_y", Settings::values.pad_y_key); | 71 | } |
| 82 | qt_config->setValue("pad_l", Settings::values.pad_l_key); | ||
| 83 | qt_config->setValue("pad_r", Settings::values.pad_r_key); | ||
| 84 | qt_config->setValue("pad_zl", Settings::values.pad_zl_key); | ||
| 85 | qt_config->setValue("pad_zr", Settings::values.pad_zr_key); | ||
| 86 | qt_config->setValue("pad_start", Settings::values.pad_start_key); | ||
| 87 | qt_config->setValue("pad_select", Settings::values.pad_select_key); | ||
| 88 | qt_config->setValue("pad_home", Settings::values.pad_home_key); | ||
| 89 | qt_config->setValue("pad_dup", Settings::values.pad_dup_key); | ||
| 90 | qt_config->setValue("pad_ddown", Settings::values.pad_ddown_key); | ||
| 91 | qt_config->setValue("pad_dleft", Settings::values.pad_dleft_key); | ||
| 92 | qt_config->setValue("pad_dright", Settings::values.pad_dright_key); | ||
| 93 | qt_config->setValue("pad_sup", Settings::values.pad_sup_key); | ||
| 94 | qt_config->setValue("pad_sdown", Settings::values.pad_sdown_key); | ||
| 95 | qt_config->setValue("pad_sleft", Settings::values.pad_sleft_key); | ||
| 96 | qt_config->setValue("pad_sright", Settings::values.pad_sright_key); | ||
| 97 | qt_config->setValue("pad_cup", Settings::values.pad_cup_key); | ||
| 98 | qt_config->setValue("pad_cdown", Settings::values.pad_cdown_key); | ||
| 99 | qt_config->setValue("pad_cleft", Settings::values.pad_cleft_key); | ||
| 100 | qt_config->setValue("pad_cright", Settings::values.pad_cright_key); | ||
| 101 | qt_config->endGroup(); | 72 | qt_config->endGroup(); |
| 102 | 73 | ||
| 103 | qt_config->beginGroup("Core"); | 74 | qt_config->beginGroup("Core"); |
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 2746de779..34831f2ec 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp | |||
| @@ -263,6 +263,7 @@ void GMainWindow::ShutdownGame() { | |||
| 263 | 263 | ||
| 264 | // Update the GUI | 264 | // Update the GUI |
| 265 | ui.action_Start->setEnabled(false); | 265 | ui.action_Start->setEnabled(false); |
| 266 | ui.action_Start->setText(tr("Start")); | ||
| 266 | ui.action_Pause->setEnabled(false); | 267 | ui.action_Pause->setEnabled(false); |
| 267 | ui.action_Stop->setEnabled(false); | 268 | ui.action_Stop->setEnabled(false); |
| 268 | render_window->hide(); | 269 | render_window->hide(); |
| @@ -291,6 +292,8 @@ void GMainWindow::OnStartGame() | |||
| 291 | emu_thread->SetRunning(true); | 292 | emu_thread->SetRunning(true); |
| 292 | 293 | ||
| 293 | ui.action_Start->setEnabled(false); | 294 | ui.action_Start->setEnabled(false); |
| 295 | ui.action_Start->setText(tr("Continue")); | ||
| 296 | |||
| 294 | ui.action_Pause->setEnabled(true); | 297 | ui.action_Pause->setEnabled(true); |
| 295 | ui.action_Stop->setEnabled(true); | 298 | ui.action_Stop->setEnabled(true); |
| 296 | } | 299 | } |
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp index 3ab9f2c17..ee4288314 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.cpp +++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #include "core/arm/dyncom/arm_dyncom_dec.h" | 5 | #include "core/arm/dyncom/arm_dyncom_dec.h" |
| 6 | #include "core/arm/skyeye_common/armsupp.h" | 6 | #include "core/arm/skyeye_common/armsupp.h" |
| 7 | 7 | ||
| 8 | const ISEITEM arm_instruction[] = { | 8 | const InstructionSetEncodingItem arm_instruction[] = { |
| 9 | { "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }}, | 9 | { "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }}, |
| 10 | { "vmls", 7, ARMVFP2, { 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }}, | 10 | { "vmls", 7, ARMVFP2, { 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }}, |
| 11 | { "vnmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }}, | 11 | { "vnmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }}, |
| @@ -207,7 +207,7 @@ const ISEITEM arm_instruction[] = { | |||
| 207 | { "bbl", 1, 0, { 25, 27, 0x00000005 }}, | 207 | { "bbl", 1, 0, { 25, 27, 0x00000005 }}, |
| 208 | }; | 208 | }; |
| 209 | 209 | ||
| 210 | const ISEITEM arm_exclusion_code[] = { | 210 | const InstructionSetEncodingItem arm_exclusion_code[] = { |
| 211 | { "vmla", 0, ARMVFP2, { 0 }}, | 211 | { "vmla", 0, ARMVFP2, { 0 }}, |
| 212 | { "vmls", 0, ARMVFP2, { 0 }}, | 212 | { "vmls", 0, ARMVFP2, { 0 }}, |
| 213 | { "vnmla", 0, ARMVFP2, { 0 }}, | 213 | { "vnmla", 0, ARMVFP2, { 0 }}, |
| @@ -414,14 +414,13 @@ const ISEITEM arm_exclusion_code[] = { | |||
| 414 | { "invalid", 0, INVALID, { 0 }} | 414 | { "invalid", 0, INVALID, { 0 }} |
| 415 | }; | 415 | }; |
| 416 | 416 | ||
| 417 | int decode_arm_instr(u32 instr, s32* idx) { | 417 | ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) { |
| 418 | int n = 0; | 418 | int n = 0; |
| 419 | int base = 0; | 419 | int base = 0; |
| 420 | int ret = DECODE_FAILURE; | 420 | int instr_slots = sizeof(arm_instruction) / sizeof(InstructionSetEncodingItem); |
| 421 | int i = 0; | 421 | ARMDecodeStatus ret = ARMDecodeStatus::FAILURE; |
| 422 | int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); | ||
| 423 | 422 | ||
| 424 | for (i = 0; i < instr_slots; i++) { | 423 | for (int i = 0; i < instr_slots; i++) { |
| 425 | n = arm_instruction[i].attribute_value; | 424 | n = arm_instruction[i].attribute_value; |
| 426 | base = 0; | 425 | base = 0; |
| 427 | 426 | ||
| @@ -438,11 +437,11 @@ int decode_arm_instr(u32 instr, s32* idx) { | |||
| 438 | n--; | 437 | n--; |
| 439 | } | 438 | } |
| 440 | 439 | ||
| 441 | // All conditions is satisfied. | 440 | // All conditions are satisfied. |
| 442 | if (n == 0) | 441 | if (n == 0) |
| 443 | ret = DECODE_SUCCESS; | 442 | ret = ARMDecodeStatus::SUCCESS; |
| 444 | 443 | ||
| 445 | if (ret == DECODE_SUCCESS) { | 444 | if (ret == ARMDecodeStatus::SUCCESS) { |
| 446 | n = arm_exclusion_code[i].attribute_value; | 445 | n = arm_exclusion_code[i].attribute_value; |
| 447 | if (n != 0) { | 446 | if (n != 0) { |
| 448 | base = 0; | 447 | base = 0; |
| @@ -454,13 +453,13 @@ int decode_arm_instr(u32 instr, s32* idx) { | |||
| 454 | n--; | 453 | n--; |
| 455 | } | 454 | } |
| 456 | 455 | ||
| 457 | // All conditions is satisfied. | 456 | // All conditions are satisfied. |
| 458 | if (n == 0) | 457 | if (n == 0) |
| 459 | ret = DECODE_FAILURE; | 458 | ret = ARMDecodeStatus::FAILURE; |
| 460 | } | 459 | } |
| 461 | } | 460 | } |
| 462 | 461 | ||
| 463 | if (ret == DECODE_SUCCESS) { | 462 | if (ret == ARMDecodeStatus::SUCCESS) { |
| 464 | *idx = i; | 463 | *idx = i; |
| 465 | return ret; | 464 | return ret; |
| 466 | } | 465 | } |
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h index 5f6279627..d7170e0fc 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.h +++ b/src/core/arm/dyncom/arm_dyncom_dec.h | |||
| @@ -6,22 +6,20 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | 8 | ||
| 9 | int decode_arm_instr(u32 instr, s32* idx); | 9 | enum class ARMDecodeStatus { |
| 10 | 10 | SUCCESS, | |
| 11 | enum DECODE_STATUS { | 11 | FAILURE |
| 12 | DECODE_SUCCESS, | ||
| 13 | DECODE_FAILURE | ||
| 14 | }; | 12 | }; |
| 15 | 13 | ||
| 16 | struct instruction_set_encoding_item { | 14 | ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx); |
| 15 | |||
| 16 | struct InstructionSetEncodingItem { | ||
| 17 | const char *name; | 17 | const char *name; |
| 18 | int attribute_value; | 18 | int attribute_value; |
| 19 | int version; | 19 | int version; |
| 20 | u32 content[21]; | 20 | u32 content[21]; |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | typedef struct instruction_set_encoding_item ISEITEM; | ||
| 24 | |||
| 25 | // ARM versions | 23 | // ARM versions |
| 26 | enum { | 24 | enum { |
| 27 | INVALID = 0, | 25 | INVALID = 0, |
| @@ -38,4 +36,4 @@ enum { | |||
| 38 | ARMV6K, | 36 | ARMV6K, |
| 39 | }; | 37 | }; |
| 40 | 38 | ||
| 41 | extern const ISEITEM arm_instruction[]; | 39 | extern const InstructionSetEncodingItem arm_instruction[]; |
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index cf09acb4e..0c20c2bc3 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -47,27 +47,6 @@ enum { | |||
| 47 | 47 | ||
| 48 | typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper); | 48 | typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper); |
| 49 | 49 | ||
| 50 | // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. | ||
| 51 | // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to | ||
| 52 | // support LDR/STREXD. | ||
| 53 | static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8; | ||
| 54 | |||
| 55 | // Exclusive memory access | ||
| 56 | static int exclusive_detect(ARMul_State* state, u32 addr) { | ||
| 57 | if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK)) | ||
| 58 | return 0; | ||
| 59 | else | ||
| 60 | return -1; | ||
| 61 | } | ||
| 62 | |||
| 63 | static void add_exclusive_addr(ARMul_State* state, u32 addr){ | ||
| 64 | state->exclusive_tag = addr & RESERVATION_GRANULE_MASK; | ||
| 65 | } | ||
| 66 | |||
| 67 | static void remove_exclusive(ARMul_State* state, u32 addr){ | ||
| 68 | state->exclusive_tag = 0xFFFFFFFF; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int CondPassed(ARMul_State* cpu, unsigned int cond) { | 50 | static int CondPassed(ARMul_State* cpu, unsigned int cond) { |
| 72 | const u32 NFLAG = cpu->NFlag; | 51 | const u32 NFLAG = cpu->NFlag; |
| 73 | const u32 ZFLAG = cpu->ZFlag; | 52 | const u32 ZFLAG = cpu->ZFlag; |
| @@ -3489,21 +3468,15 @@ enum { | |||
| 3489 | FETCH_FAILURE | 3468 | FETCH_FAILURE |
| 3490 | }; | 3469 | }; |
| 3491 | 3470 | ||
| 3492 | static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) { | 3471 | static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) { |
| 3493 | // Check if in Thumb mode | 3472 | // Check if in Thumb mode |
| 3494 | tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); | 3473 | ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size); |
| 3495 | if(ret == t_branch){ | 3474 | if (ret == ThumbDecodeStatus::BRANCH) { |
| 3496 | // TODO: FIXME, endian should be judged | ||
| 3497 | u32 tinstr; | ||
| 3498 | if((addr & 0x3) != 0) | ||
| 3499 | tinstr = inst >> 16; | ||
| 3500 | else | ||
| 3501 | tinstr = inst & 0xFFFF; | ||
| 3502 | |||
| 3503 | int inst_index; | 3475 | int inst_index; |
| 3504 | int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); | 3476 | int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); |
| 3477 | u32 tinstr = GetThumbInstruction(inst, addr); | ||
| 3505 | 3478 | ||
| 3506 | switch((tinstr & 0xF800) >> 11){ | 3479 | switch ((tinstr & 0xF800) >> 11) { |
| 3507 | case 26: | 3480 | case 26: |
| 3508 | case 27: | 3481 | case 27: |
| 3509 | if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ | 3482 | if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ |
| @@ -3536,7 +3509,7 @@ static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_s | |||
| 3536 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3509 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3537 | break; | 3510 | break; |
| 3538 | default: | 3511 | default: |
| 3539 | ret = t_undefined; | 3512 | ret = ThumbDecodeStatus::UNDEFINED; |
| 3540 | break; | 3513 | break; |
| 3541 | } | 3514 | } |
| 3542 | } | 3515 | } |
| @@ -3548,10 +3521,6 @@ enum { | |||
| 3548 | FETCH_EXCEPTION | 3521 | FETCH_EXCEPTION |
| 3549 | }; | 3522 | }; |
| 3550 | 3523 | ||
| 3551 | typedef struct instruction_set_encoding_item ISEITEM; | ||
| 3552 | |||
| 3553 | extern const ISEITEM arm_instruction[]; | ||
| 3554 | |||
| 3555 | static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { | 3524 | static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { |
| 3556 | Common::Profiling::ScopeTimer timer_decode(profile_decode); | 3525 | Common::Profiling::ScopeTimer timer_decode(profile_decode); |
| 3557 | 3526 | ||
| @@ -3573,20 +3542,19 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { | |||
| 3573 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC); | 3542 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC); |
| 3574 | 3543 | ||
| 3575 | size++; | 3544 | size++; |
| 3576 | // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction | 3545 | // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction |
| 3577 | if (cpu->TFlag) { | 3546 | if (cpu->TFlag) { |
| 3578 | uint32_t arm_inst; | 3547 | uint32_t arm_inst; |
| 3579 | tdstate state = decode_thumb_instr(inst, phys_addr, &arm_inst, &inst_size, &inst_base); | 3548 | ThumbDecodeStatus state = DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base); |
| 3580 | 3549 | ||
| 3581 | // We have translated the branch instruction of thumb in thumb decoder | 3550 | // We have translated the Thumb branch instruction in the Thumb decoder |
| 3582 | if(state == t_branch){ | 3551 | if (state == ThumbDecodeStatus::BRANCH) { |
| 3583 | goto translated; | 3552 | goto translated; |
| 3584 | } | 3553 | } |
| 3585 | inst = arm_inst; | 3554 | inst = arm_inst; |
| 3586 | } | 3555 | } |
| 3587 | 3556 | ||
| 3588 | ret = decode_arm_instr(inst, &idx); | 3557 | if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) { |
| 3589 | if (ret == DECODE_FAILURE) { | ||
| 3590 | std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); | 3558 | std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); |
| 3591 | LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst); | 3559 | LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst); |
| 3592 | LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); | 3560 | LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); |
| @@ -3956,9 +3924,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3956 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 3924 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 3957 | adc_inst* const inst_cream = (adc_inst*)inst_base->component; | 3925 | adc_inst* const inst_cream = (adc_inst*)inst_base->component; |
| 3958 | 3926 | ||
| 3927 | u32 rn_val = RN; | ||
| 3928 | if (inst_cream->Rn == 15) | ||
| 3929 | rn_val += 2 * cpu->GetInstructionSize(); | ||
| 3930 | |||
| 3959 | bool carry; | 3931 | bool carry; |
| 3960 | bool overflow; | 3932 | bool overflow; |
| 3961 | RD = AddWithCarry(RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); | 3933 | RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); |
| 3962 | 3934 | ||
| 3963 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 3935 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 3964 | if (CurrentModeHasSPSR) { | 3936 | if (CurrentModeHasSPSR) { |
| @@ -4019,11 +3991,17 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4019 | } | 3991 | } |
| 4020 | AND_INST: | 3992 | AND_INST: |
| 4021 | { | 3993 | { |
| 4022 | and_inst *inst_cream = (and_inst *)inst_base->component; | 3994 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 4023 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3995 | and_inst* const inst_cream = (and_inst*)inst_base->component; |
| 3996 | |||
| 4024 | u32 lop = RN; | 3997 | u32 lop = RN; |
| 4025 | u32 rop = SHIFTER_OPERAND; | 3998 | u32 rop = SHIFTER_OPERAND; |
| 3999 | |||
| 4000 | if (inst_cream->Rn == 15) | ||
| 4001 | lop += 2 * cpu->GetInstructionSize(); | ||
| 4002 | |||
| 4026 | RD = lop & rop; | 4003 | RD = lop & rop; |
| 4004 | |||
| 4027 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4005 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4028 | if (CurrentModeHasSPSR) { | 4006 | if (CurrentModeHasSPSR) { |
| 4029 | cpu->Cpsr = cpu->Spsr_copy; | 4007 | cpu->Cpsr = cpu->Spsr_copy; |
| @@ -4174,9 +4152,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4174 | 4152 | ||
| 4175 | CLREX_INST: | 4153 | CLREX_INST: |
| 4176 | { | 4154 | { |
| 4177 | remove_exclusive(cpu, 0); | 4155 | cpu->UnsetExclusiveMemoryAddress(); |
| 4178 | cpu->exclusive_state = 0; | ||
| 4179 | |||
| 4180 | cpu->Reg[15] += cpu->GetInstructionSize(); | 4156 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4181 | INC_PC(sizeof(clrex_inst)); | 4157 | INC_PC(sizeof(clrex_inst)); |
| 4182 | FETCH_INST; | 4158 | FETCH_INST; |
| @@ -4198,9 +4174,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4198 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 4174 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 4199 | cmn_inst* const inst_cream = (cmn_inst*)inst_base->component; | 4175 | cmn_inst* const inst_cream = (cmn_inst*)inst_base->component; |
| 4200 | 4176 | ||
| 4177 | u32 rn_val = RN; | ||
| 4178 | if (inst_cream->Rn == 15) | ||
| 4179 | rn_val += 2 * cpu->GetInstructionSize(); | ||
| 4180 | |||
| 4201 | bool carry; | 4181 | bool carry; |
| 4202 | bool overflow; | 4182 | bool overflow; |
| 4203 | u32 result = AddWithCarry(RN, SHIFTER_OPERAND, 0, &carry, &overflow); | 4183 | u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow); |
| 4204 | 4184 | ||
| 4205 | UPDATE_NFLAG(result); | 4185 | UPDATE_NFLAG(result); |
| 4206 | UPDATE_ZFLAG(result); | 4186 | UPDATE_ZFLAG(result); |
| @@ -4543,8 +4523,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4543 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4523 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4544 | unsigned int read_addr = RN; | 4524 | unsigned int read_addr = RN; |
| 4545 | 4525 | ||
| 4546 | add_exclusive_addr(cpu, read_addr); | 4526 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4547 | cpu->exclusive_state = 1; | ||
| 4548 | 4527 | ||
| 4549 | RD = cpu->ReadMemory32(read_addr); | 4528 | RD = cpu->ReadMemory32(read_addr); |
| 4550 | if (inst_cream->Rd == 15) { | 4529 | if (inst_cream->Rd == 15) { |
| @@ -4563,8 +4542,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4563 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4542 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4564 | unsigned int read_addr = RN; | 4543 | unsigned int read_addr = RN; |
| 4565 | 4544 | ||
| 4566 | add_exclusive_addr(cpu, read_addr); | 4545 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4567 | cpu->exclusive_state = 1; | ||
| 4568 | 4546 | ||
| 4569 | RD = Memory::Read8(read_addr); | 4547 | RD = Memory::Read8(read_addr); |
| 4570 | if (inst_cream->Rd == 15) { | 4548 | if (inst_cream->Rd == 15) { |
| @@ -4583,8 +4561,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4583 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4561 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4584 | unsigned int read_addr = RN; | 4562 | unsigned int read_addr = RN; |
| 4585 | 4563 | ||
| 4586 | add_exclusive_addr(cpu, read_addr); | 4564 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4587 | cpu->exclusive_state = 1; | ||
| 4588 | 4565 | ||
| 4589 | RD = cpu->ReadMemory16(read_addr); | 4566 | RD = cpu->ReadMemory16(read_addr); |
| 4590 | if (inst_cream->Rd == 15) { | 4567 | if (inst_cream->Rd == 15) { |
| @@ -4603,8 +4580,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4603 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4580 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4604 | unsigned int read_addr = RN; | 4581 | unsigned int read_addr = RN; |
| 4605 | 4582 | ||
| 4606 | add_exclusive_addr(cpu, read_addr); | 4583 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4607 | cpu->exclusive_state = 1; | ||
| 4608 | 4584 | ||
| 4609 | RD = cpu->ReadMemory32(read_addr); | 4585 | RD = cpu->ReadMemory32(read_addr); |
| 4610 | RD2 = cpu->ReadMemory32(read_addr + 4); | 4586 | RD2 = cpu->ReadMemory32(read_addr + 4); |
| @@ -4943,6 +4919,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4943 | 4919 | ||
| 4944 | u32 lop = RN; | 4920 | u32 lop = RN; |
| 4945 | u32 rop = SHIFTER_OPERAND; | 4921 | u32 rop = SHIFTER_OPERAND; |
| 4922 | |||
| 4923 | if (inst_cream->Rn == 15) | ||
| 4924 | lop += 2 * cpu->GetInstructionSize(); | ||
| 4925 | |||
| 4946 | RD = lop | rop; | 4926 | RD = lop | rop; |
| 4947 | 4927 | ||
| 4948 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4928 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| @@ -5233,9 +5213,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5233 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 5213 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5234 | rsc_inst* const inst_cream = (rsc_inst*)inst_base->component; | 5214 | rsc_inst* const inst_cream = (rsc_inst*)inst_base->component; |
| 5235 | 5215 | ||
| 5216 | u32 rn_val = RN; | ||
| 5217 | if (inst_cream->Rn == 15) | ||
| 5218 | rn_val += 2 * cpu->GetInstructionSize(); | ||
| 5219 | |||
| 5236 | bool carry; | 5220 | bool carry; |
| 5237 | bool overflow; | 5221 | bool overflow; |
| 5238 | RD = AddWithCarry(~RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); | 5222 | RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); |
| 5239 | 5223 | ||
| 5240 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5224 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5241 | if (CurrentModeHasSPSR) { | 5225 | if (CurrentModeHasSPSR) { |
| @@ -5373,9 +5357,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5373 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 5357 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5374 | sbc_inst* const inst_cream = (sbc_inst*)inst_base->component; | 5358 | sbc_inst* const inst_cream = (sbc_inst*)inst_base->component; |
| 5375 | 5359 | ||
| 5360 | u32 rn_val = RN; | ||
| 5361 | if (inst_cream->Rn == 15) | ||
| 5362 | rn_val += 2 * cpu->GetInstructionSize(); | ||
| 5363 | |||
| 5376 | bool carry; | 5364 | bool carry; |
| 5377 | bool overflow; | 5365 | bool overflow; |
| 5378 | RD = AddWithCarry(RN, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); | 5366 | RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); |
| 5379 | 5367 | ||
| 5380 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5368 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5381 | if (CurrentModeHasSPSR) { | 5369 | if (CurrentModeHasSPSR) { |
| @@ -6089,10 +6077,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6089 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6077 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6090 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6078 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6091 | 6079 | ||
| 6092 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6080 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6093 | remove_exclusive(cpu, write_addr); | 6081 | cpu->UnsetExclusiveMemoryAddress(); |
| 6094 | cpu->exclusive_state = 0; | ||
| 6095 | |||
| 6096 | cpu->WriteMemory32(write_addr, RM); | 6082 | cpu->WriteMemory32(write_addr, RM); |
| 6097 | RD = 0; | 6083 | RD = 0; |
| 6098 | } else { | 6084 | } else { |
| @@ -6111,10 +6097,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6111 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6097 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6112 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6098 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6113 | 6099 | ||
| 6114 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6100 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6115 | remove_exclusive(cpu, write_addr); | 6101 | cpu->UnsetExclusiveMemoryAddress(); |
| 6116 | cpu->exclusive_state = 0; | ||
| 6117 | |||
| 6118 | Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]); | 6102 | Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]); |
| 6119 | RD = 0; | 6103 | RD = 0; |
| 6120 | } else { | 6104 | } else { |
| @@ -6133,9 +6117,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6133 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6117 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6134 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6118 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6135 | 6119 | ||
| 6136 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6120 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6137 | remove_exclusive(cpu, write_addr); | 6121 | cpu->UnsetExclusiveMemoryAddress(); |
| 6138 | cpu->exclusive_state = 0; | ||
| 6139 | 6122 | ||
| 6140 | const u32 rt = cpu->Reg[inst_cream->Rm + 0]; | 6123 | const u32 rt = cpu->Reg[inst_cream->Rm + 0]; |
| 6141 | const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; | 6124 | const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; |
| @@ -6165,10 +6148,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6165 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6148 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6166 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6149 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6167 | 6150 | ||
| 6168 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6151 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6169 | remove_exclusive(cpu, write_addr); | 6152 | cpu->UnsetExclusiveMemoryAddress(); |
| 6170 | cpu->exclusive_state = 0; | ||
| 6171 | |||
| 6172 | cpu->WriteMemory16(write_addr, RM); | 6153 | cpu->WriteMemory16(write_addr, RM); |
| 6173 | RD = 0; | 6154 | RD = 0; |
| 6174 | } else { | 6155 | } else { |
| @@ -6216,7 +6197,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6216 | 6197 | ||
| 6217 | u32 rn_val = RN; | 6198 | u32 rn_val = RN; |
| 6218 | if (inst_cream->Rn == 15) | 6199 | if (inst_cream->Rn == 15) |
| 6219 | rn_val += 8; | 6200 | rn_val += 2 * cpu->GetInstructionSize(); |
| 6220 | 6201 | ||
| 6221 | bool carry; | 6202 | bool carry; |
| 6222 | bool overflow; | 6203 | bool overflow; |
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp index 2860af376..29272fd5d 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp +++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp | |||
| @@ -12,15 +12,9 @@ | |||
| 12 | // with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions | 12 | // with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions |
| 13 | // allows easier simulation of the special dual BL instruction. | 13 | // allows easier simulation of the special dual BL instruction. |
| 14 | 14 | ||
| 15 | tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | 15 | ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { |
| 16 | tdstate valid = t_uninitialized; | 16 | ThumbDecodeStatus valid = ThumbDecodeStatus::UNINITIALIZED; |
| 17 | u32 tinstr = instr; | 17 | u32 tinstr = GetThumbInstruction(instr, addr); |
| 18 | |||
| 19 | // The endian should be judge here | ||
| 20 | if((addr & 0x3) != 0) | ||
| 21 | tinstr = instr >> 16; | ||
| 22 | else | ||
| 23 | tinstr &= 0xFFFF; | ||
| 24 | 18 | ||
| 25 | *ainstr = 0xDEADC0DE; // Debugging to catch non updates | 19 | *ainstr = 0xDEADC0DE; // Debugging to catch non updates |
| 26 | 20 | ||
| @@ -357,21 +351,21 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 357 | else | 351 | else |
| 358 | *ainstr |= (tinstr & 0x00FF); | 352 | *ainstr |= (tinstr & 0x00FF); |
| 359 | } else if ((tinstr & 0x0F00) != 0x0E00) | 353 | } else if ((tinstr & 0x0F00) != 0x0E00) |
| 360 | valid = t_branch; | 354 | valid = ThumbDecodeStatus::BRANCH; |
| 361 | else // UNDEFINED : cc=1110(AL) uses different format | 355 | else // UNDEFINED : cc=1110(AL) uses different format |
| 362 | valid = t_undefined; | 356 | valid = ThumbDecodeStatus::UNDEFINED; |
| 363 | 357 | ||
| 364 | break; | 358 | break; |
| 365 | 359 | ||
| 366 | case 28: // B | 360 | case 28: // B |
| 367 | valid = t_branch; | 361 | valid = ThumbDecodeStatus::BRANCH; |
| 368 | break; | 362 | break; |
| 369 | 363 | ||
| 370 | case 29: | 364 | case 29: |
| 371 | if(tinstr & 0x1) | 365 | if (tinstr & 0x1) |
| 372 | valid = t_undefined; | 366 | valid = ThumbDecodeStatus::UNDEFINED; |
| 373 | else | 367 | else |
| 374 | valid = t_branch; | 368 | valid = ThumbDecodeStatus::BRANCH; |
| 375 | break; | 369 | break; |
| 376 | 370 | ||
| 377 | case 30: // BL instruction 1 | 371 | case 30: // BL instruction 1 |
| @@ -380,7 +374,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 380 | // simulation simple (from the user perspective) we check if the following instruction is | 374 | // simulation simple (from the user perspective) we check if the following instruction is |
| 381 | // the second half of this BL, and if it is we simulate it immediately | 375 | // the second half of this BL, and if it is we simulate it immediately |
| 382 | 376 | ||
| 383 | valid = t_branch; | 377 | valid = ThumbDecodeStatus::BRANCH; |
| 384 | break; | 378 | break; |
| 385 | 379 | ||
| 386 | case 31: // BL instruction 2 | 380 | case 31: // BL instruction 2 |
| @@ -389,7 +383,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 389 | // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the | 383 | // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the |
| 390 | // simulation of it on its own, with undefined results if r14 is not suitably initialised. | 384 | // simulation of it on its own, with undefined results if r14 is not suitably initialised. |
| 391 | 385 | ||
| 392 | valid = t_branch; | 386 | valid = ThumbDecodeStatus::BRANCH; |
| 393 | break; | 387 | break; |
| 394 | } | 388 | } |
| 395 | 389 | ||
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h index c06f09580..447974363 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.h +++ b/src/core/arm/dyncom/arm_dyncom_thumb.h | |||
| @@ -28,20 +28,22 @@ | |||
| 28 | 28 | ||
| 29 | #include "common/common_types.h" | 29 | #include "common/common_types.h" |
| 30 | 30 | ||
| 31 | enum tdstate { | 31 | enum class ThumbDecodeStatus { |
| 32 | t_undefined, // Undefined Thumb instruction | 32 | UNDEFINED, // Undefined Thumb instruction |
| 33 | t_decoded, // Instruction decoded to ARM equivalent | 33 | DECODED, // Instruction decoded to ARM equivalent |
| 34 | t_branch, // Thumb branch (already processed) | 34 | BRANCH, // Thumb branch (already processed) |
| 35 | t_uninitialized, | 35 | UNINITIALIZED, |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size); | 38 | // Translates a Thumb mode instruction into its ARM equivalent. |
| 39 | ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size); | ||
| 39 | 40 | ||
| 40 | static inline u32 get_thumb_instr(u32 instr, u32 pc) { | 41 | static inline u32 GetThumbInstruction(u32 instr, u32 address) { |
| 41 | u32 tinstr; | 42 | // Normally you would need to handle instruction endianness, |
| 42 | if ((pc & 0x3) != 0) | 43 | // however, it is fixed to little-endian on the MPCore, so |
| 43 | tinstr = instr >> 16; | 44 | // there's no need to check for this beforehand. |
| 44 | else | 45 | if ((address & 0x3) != 0) |
| 45 | tinstr = instr & 0xFFFF; | 46 | return instr >> 16; |
| 46 | return tinstr; | 47 | |
| 48 | return instr & 0xFFFF; | ||
| 47 | } | 49 | } |
diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h index 88c1dab9d..b364e2621 100644 --- a/src/core/arm/skyeye_common/armstate.h +++ b/src/core/arm/skyeye_common/armstate.h | |||
| @@ -163,6 +163,19 @@ public: | |||
| 163 | u32 ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const; | 163 | u32 ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const; |
| 164 | void WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); | 164 | void WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); |
| 165 | 165 | ||
| 166 | // Exclusive memory access functions | ||
| 167 | bool IsExclusiveMemoryAccess(u32 address) const { | ||
| 168 | return exclusive_state && exclusive_tag == (address & RESERVATION_GRANULE_MASK); | ||
| 169 | } | ||
| 170 | void SetExclusiveMemoryAddress(u32 address) { | ||
| 171 | exclusive_tag = address & RESERVATION_GRANULE_MASK; | ||
| 172 | exclusive_state = true; | ||
| 173 | } | ||
| 174 | void UnsetExclusiveMemoryAddress() { | ||
| 175 | exclusive_tag = 0xFFFFFFFF; | ||
| 176 | exclusive_state = false; | ||
| 177 | } | ||
| 178 | |||
| 166 | // Whether or not the given CPU is in big endian mode (E bit is set) | 179 | // Whether or not the given CPU is in big endian mode (E bit is set) |
| 167 | bool InBigEndianMode() const { | 180 | bool InBigEndianMode() const { |
| 168 | return (Cpsr & (1 << 9)) != 0; | 181 | return (Cpsr & (1 << 9)) != 0; |
| @@ -203,9 +216,6 @@ public: | |||
| 203 | 216 | ||
| 204 | u32 Mode; // The current mode | 217 | u32 Mode; // The current mode |
| 205 | u32 Bank; // The current register bank | 218 | u32 Bank; // The current register bank |
| 206 | u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode | ||
| 207 | u32 exclusive_state; | ||
| 208 | u32 exclusive_result; | ||
| 209 | 219 | ||
| 210 | u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed | 220 | u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed |
| 211 | unsigned int shifter_carry_out; | 221 | unsigned int shifter_carry_out; |
| @@ -230,4 +240,13 @@ public: | |||
| 230 | 240 | ||
| 231 | private: | 241 | private: |
| 232 | void ResetMPCoreCP15Registers(); | 242 | void ResetMPCoreCP15Registers(); |
| 243 | |||
| 244 | // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. | ||
| 245 | // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to | ||
| 246 | // support LDR/STREXD. | ||
| 247 | static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8; | ||
| 248 | |||
| 249 | u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode | ||
| 250 | u32 exclusive_result; | ||
| 251 | bool exclusive_state; | ||
| 233 | }; | 252 | }; |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 70caa7d80..c35b13b25 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -35,6 +35,16 @@ static Kernel::SharedPtr<Kernel::Event> event_debug_pad; | |||
| 35 | static u32 next_pad_index; | 35 | static u32 next_pad_index; |
| 36 | static u32 next_touch_index; | 36 | static u32 next_touch_index; |
| 37 | 37 | ||
| 38 | const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping = { | ||
| 39 | Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y, | ||
| 40 | Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR, | ||
| 41 | Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE, | ||
| 42 | Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT, | ||
| 43 | Service::HID::PAD_CIRCLE_UP, Service::HID::PAD_CIRCLE_DOWN, Service::HID::PAD_CIRCLE_LEFT, Service::HID::PAD_CIRCLE_RIGHT, | ||
| 44 | Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT | ||
| 45 | }; | ||
| 46 | |||
| 47 | |||
| 38 | // TODO(peachum): | 48 | // TODO(peachum): |
| 39 | // Add a method for setting analog input from joystick device for the circle Pad. | 49 | // Add a method for setting analog input from joystick device for the circle Pad. |
| 40 | // | 50 | // |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index d50d479f8..517f4f2ae 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #ifndef _MSC_VER | 9 | #ifndef _MSC_VER |
| 10 | #include <cstddef> | 10 | #include <cstddef> |
| 11 | #endif | 11 | #endif |
| 12 | 12 | #include "core/settings.h" | |
| 13 | #include "common/bit_field.h" | 13 | #include "common/bit_field.h" |
| 14 | #include "common/common_funcs.h" | 14 | #include "common/common_funcs.h" |
| 15 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| @@ -157,6 +157,9 @@ const PadState PAD_CIRCLE_LEFT = {{1u << 29}}; | |||
| 157 | const PadState PAD_CIRCLE_UP = {{1u << 30}}; | 157 | const PadState PAD_CIRCLE_UP = {{1u << 30}}; |
| 158 | const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; | 158 | const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; |
| 159 | 159 | ||
| 160 | |||
| 161 | extern const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping; | ||
| 162 | |||
| 160 | /** | 163 | /** |
| 161 | * HID::GetIPCHandles service function | 164 | * HID::GetIPCHandles service function |
| 162 | * Inputs: | 165 | * Inputs: |
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index d0e166fdf..d768a3fc7 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp | |||
| @@ -481,11 +481,17 @@ static void GetHostId(Service::Interface* self) { | |||
| 481 | 481 | ||
| 482 | char name[128]; | 482 | char name[128]; |
| 483 | gethostname(name, sizeof(name)); | 483 | gethostname(name, sizeof(name)); |
| 484 | hostent* host = gethostbyname(name); | 484 | addrinfo hints = {}; |
| 485 | in_addr* addr = reinterpret_cast<in_addr*>(host->h_addr); | 485 | addrinfo* res; |
| 486 | |||
| 487 | hints.ai_family = AF_INET; | ||
| 488 | getaddrinfo(name, NULL, &hints, &res); | ||
| 489 | sockaddr_in* sock_addr = reinterpret_cast<sockaddr_in*>(res->ai_addr); | ||
| 490 | in_addr* addr = &sock_addr->sin_addr; | ||
| 486 | 491 | ||
| 487 | cmd_buffer[2] = addr->s_addr; | 492 | cmd_buffer[2] = addr->s_addr; |
| 488 | cmd_buffer[1] = 0; | 493 | cmd_buffer[1] = 0; |
| 494 | freeaddrinfo(res); | ||
| 489 | } | 495 | } |
| 490 | 496 | ||
| 491 | static void Close(Service::Interface* self) { | 497 | static void Close(Service::Interface* self) { |
diff --git a/src/core/settings.h b/src/core/settings.h index 5a70d157a..2775ee257 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -5,34 +5,42 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include <array> | ||
| 8 | 9 | ||
| 9 | namespace Settings { | 10 | namespace Settings { |
| 10 | 11 | ||
| 12 | namespace NativeInput { | ||
| 13 | enum Values { | ||
| 14 | A, B, X, Y, | ||
| 15 | L, R, ZL, ZR, | ||
| 16 | START, SELECT, HOME, | ||
| 17 | DUP, DDOWN, DLEFT, DRIGHT, | ||
| 18 | SUP, SDOWN, SLEFT, SRIGHT, | ||
| 19 | CUP, CDOWN, CLEFT, CRIGHT, | ||
| 20 | NUM_INPUTS | ||
| 21 | }; | ||
| 22 | static const std::array<const char*, NUM_INPUTS> Mapping = { | ||
| 23 | "pad_a", "pad_b", "pad_x", "pad_y", | ||
| 24 | "pad_l", "pad_r", "pad_zl", "pad_zr", | ||
| 25 | "pad_start", "pad_select", "pad_home", | ||
| 26 | "pad_dup", "pad_ddown", "pad_dleft", "pad_dright", | ||
| 27 | "pad_sup", "pad_sdown", "pad_sleft", "pad_sright", | ||
| 28 | "pad_cup", "pad_cdown", "pad_cleft", "pad_cright" | ||
| 29 | }; | ||
| 30 | static const std::array<Values, NUM_INPUTS> All = { | ||
| 31 | A, B, X, Y, | ||
| 32 | L, R, ZL, ZR, | ||
| 33 | START, SELECT, HOME, | ||
| 34 | DUP, DDOWN, DLEFT, DRIGHT, | ||
| 35 | SUP, SDOWN, SLEFT, SRIGHT, | ||
| 36 | CUP, CDOWN, CLEFT, CRIGHT | ||
| 37 | }; | ||
| 38 | } | ||
| 39 | |||
| 40 | |||
| 11 | struct Values { | 41 | struct Values { |
| 12 | // Controls | 42 | // Controls |
| 13 | int pad_a_key; | 43 | std::array<int, NativeInput::NUM_INPUTS> input_mappings; |
| 14 | int pad_b_key; | ||
| 15 | int pad_x_key; | ||
| 16 | int pad_y_key; | ||
| 17 | int pad_l_key; | ||
| 18 | int pad_r_key; | ||
| 19 | int pad_zl_key; | ||
| 20 | int pad_zr_key; | ||
| 21 | int pad_start_key; | ||
| 22 | int pad_select_key; | ||
| 23 | int pad_home_key; | ||
| 24 | int pad_dup_key; | ||
| 25 | int pad_ddown_key; | ||
| 26 | int pad_dleft_key; | ||
| 27 | int pad_dright_key; | ||
| 28 | int pad_sup_key; | ||
| 29 | int pad_sdown_key; | ||
| 30 | int pad_sleft_key; | ||
| 31 | int pad_sright_key; | ||
| 32 | int pad_cup_key; | ||
| 33 | int pad_cdown_key; | ||
| 34 | int pad_cleft_key; | ||
| 35 | int pad_cright_key; | ||
| 36 | 44 | ||
| 37 | // Core | 45 | // Core |
| 38 | int frame_skip; | 46 | int frame_skip; |