diff options
74 files changed, 1178 insertions, 388 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index bbe9f76cd..05a560404 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -9,6 +9,8 @@ if (NOT MSVC) | |||
| 9 | else() | 9 | else() |
| 10 | # Silence deprecation warnings | 10 | # Silence deprecation warnings |
| 11 | add_definitions(/D_CRT_SECURE_NO_WARNINGS) | 11 | add_definitions(/D_CRT_SECURE_NO_WARNINGS) |
| 12 | # set up output paths for executable binaries (.exe-files, and .dll-files on DLL-capable platforms) | ||
| 13 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) | ||
| 12 | endif() | 14 | endif() |
| 13 | add_definitions(-DSINGLETHREADED) | 15 | add_definitions(-DSINGLETHREADED) |
| 14 | 16 | ||
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 82b66be75..c8c8e3884 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md | |||
| @@ -27,6 +27,7 @@ Follow the indentation/whitespace style shown below. Do not use tabs, use 4-spac | |||
| 27 | ### Comments | 27 | ### Comments |
| 28 | * For regular comments, use C++ style (`//`) comments, even for multi-line ones. | 28 | * For regular comments, use C++ style (`//`) comments, even for multi-line ones. |
| 29 | * For doc-comments (Doxygen comments), use `/// ` if it's a single line, else use the `/**` `*/` style featured in the example. Start the text on the second line, not the first containing `/**`. | 29 | * For doc-comments (Doxygen comments), use `/// ` if it's a single line, else use the `/**` `*/` style featured in the example. Start the text on the second line, not the first containing `/**`. |
| 30 | * For items that are both defined and declared in two separate files, put the doc-comment only next to the associated declaration. (In a header file, usually.) Otherwise, put it next to the implementation. Never duplicate doc-comments in both places. | ||
| 30 | 31 | ||
| 31 | ```cpp | 32 | ```cpp |
| 32 | namespace Example { | 33 | namespace Example { |
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..982619126 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); |
| @@ -72,10 +76,10 @@ EmuWindow_GLFW::EmuWindow_GLFW() { | |||
| 72 | std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); | 76 | std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); |
| 73 | m_render_window = glfwCreateWindow(VideoCore::kScreenTopWidth, | 77 | m_render_window = glfwCreateWindow(VideoCore::kScreenTopWidth, |
| 74 | (VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight), | 78 | (VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight), |
| 75 | window_title.c_str(), NULL, NULL); | 79 | window_title.c_str(), nullptr, nullptr); |
| 76 | 80 | ||
| 77 | if (m_render_window == NULL) { | 81 | if (m_render_window == nullptr) { |
| 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 | ||
| @@ -119,7 +123,7 @@ void EmuWindow_GLFW::MakeCurrent() { | |||
| 119 | 123 | ||
| 120 | /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread | 124 | /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread |
| 121 | void EmuWindow_GLFW::DoneCurrent() { | 125 | void EmuWindow_GLFW::DoneCurrent() { |
| 122 | glfwMakeContextCurrent(NULL); | 126 | glfwMakeContextCurrent(nullptr); |
| 123 | } | 127 | } |
| 124 | 128 | ||
| 125 | void EmuWindow_GLFW::ReloadSetKeymaps() { | 129 | void EmuWindow_GLFW::ReloadSetKeymaps() { |
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 9bf079919..9a29f974b 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp | |||
| @@ -230,7 +230,7 @@ QByteArray GRenderWindow::saveGeometry() | |||
| 230 | { | 230 | { |
| 231 | // If we are a top-level widget, store the current geometry | 231 | // If we are a top-level widget, store the current geometry |
| 232 | // otherwise, store the last backup | 232 | // otherwise, store the last backup |
| 233 | if (parent() == NULL) | 233 | if (parent() == nullptr) |
| 234 | return ((QGLWidget*)this)->saveGeometry(); | 234 | return ((QGLWidget*)this)->saveGeometry(); |
| 235 | else | 235 | else |
| 236 | return geometry; | 236 | return geometry; |
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/citra_qt/hotkeys.cpp b/src/citra_qt/hotkeys.cpp index bbaa4a8dc..5d0b52e4f 100644 --- a/src/citra_qt/hotkeys.cpp +++ b/src/citra_qt/hotkeys.cpp | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | struct Hotkey | 6 | struct Hotkey |
| 7 | { | 7 | { |
| 8 | Hotkey() : shortcut(NULL), context(Qt::WindowShortcut) {} | 8 | Hotkey() : shortcut(nullptr), context(Qt::WindowShortcut) {} |
| 9 | 9 | ||
| 10 | QKeySequence keyseq; | 10 | QKeySequence keyseq; |
| 11 | QShortcut* shortcut; | 11 | QShortcut* shortcut; |
| @@ -81,7 +81,7 @@ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widge | |||
| 81 | Hotkey& hk = hotkey_groups[group][action]; | 81 | Hotkey& hk = hotkey_groups[group][action]; |
| 82 | 82 | ||
| 83 | if (!hk.shortcut) | 83 | if (!hk.shortcut) |
| 84 | hk.shortcut = new QShortcut(hk.keyseq, widget, NULL, NULL, hk.context); | 84 | hk.shortcut = new QShortcut(hk.keyseq, widget, nullptr, nullptr, hk.context); |
| 85 | 85 | ||
| 86 | return hk.shortcut; | 86 | return hk.shortcut; |
| 87 | } | 87 | } |
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index d5554d917..0701decef 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp | |||
| @@ -131,7 +131,7 @@ GMainWindow::GMainWindow() | |||
| 131 | GMainWindow::~GMainWindow() | 131 | GMainWindow::~GMainWindow() |
| 132 | { | 132 | { |
| 133 | // will get automatically deleted otherwise | 133 | // will get automatically deleted otherwise |
| 134 | if (render_window->parent() == NULL) | 134 | if (render_window->parent() == nullptr) |
| 135 | delete render_window; | 135 | delete render_window; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| @@ -164,7 +164,7 @@ void GMainWindow::BootGame(std::string filename) | |||
| 164 | 164 | ||
| 165 | void GMainWindow::OnMenuLoadFile() | 165 | void GMainWindow::OnMenuLoadFile() |
| 166 | { | 166 | { |
| 167 | QString filename = QFileDialog::getOpenFileName(this, tr("Load file"), QString(), tr("3DS executable (*.elf *.axf *.bin *.cci *.cxi)")); | 167 | QString filename = QFileDialog::getOpenFileName(this, tr("Load file"), QString(), tr("3DS executable (*.3dsx *.elf *.axf *.bin *.cci *.cxi)")); |
| 168 | if (filename.size()) | 168 | if (filename.size()) |
| 169 | BootGame(filename.toLatin1().data()); | 169 | BootGame(filename.toLatin1().data()); |
| 170 | } | 170 | } |
| @@ -213,14 +213,14 @@ void GMainWindow::OnOpenHotkeysDialog() | |||
| 213 | void GMainWindow::ToggleWindowMode() | 213 | void GMainWindow::ToggleWindowMode() |
| 214 | { | 214 | { |
| 215 | bool enable = ui.action_Popout_Window_Mode->isChecked(); | 215 | bool enable = ui.action_Popout_Window_Mode->isChecked(); |
| 216 | if (enable && render_window->parent() != NULL) | 216 | if (enable && render_window->parent() != nullptr) |
| 217 | { | 217 | { |
| 218 | ui.horizontalLayout->removeWidget(render_window); | 218 | ui.horizontalLayout->removeWidget(render_window); |
| 219 | render_window->setParent(NULL); | 219 | render_window->setParent(nullptr); |
| 220 | render_window->setVisible(true); | 220 | render_window->setVisible(true); |
| 221 | render_window->RestoreGeometry(); | 221 | render_window->RestoreGeometry(); |
| 222 | } | 222 | } |
| 223 | else if (!enable && render_window->parent() == NULL) | 223 | else if (!enable && render_window->parent() == nullptr) |
| 224 | { | 224 | { |
| 225 | render_window->BackupGeometry(); | 225 | render_window->BackupGeometry(); |
| 226 | ui.horizontalLayout->addWidget(render_window); | 226 | ui.horizontalLayout->addWidget(render_window); |
diff --git a/src/common/chunk_file.h b/src/common/chunk_file.h index 609784076..32af74594 100644 --- a/src/common/chunk_file.h +++ b/src/common/chunk_file.h | |||
| @@ -204,11 +204,11 @@ public: | |||
| 204 | { | 204 | { |
| 205 | for (auto it = x.begin(), end = x.end(); it != end; ++it) | 205 | for (auto it = x.begin(), end = x.end(); it != end; ++it) |
| 206 | { | 206 | { |
| 207 | if (it->second != NULL) | 207 | if (it->second != nullptr) |
| 208 | delete it->second; | 208 | delete it->second; |
| 209 | } | 209 | } |
| 210 | } | 210 | } |
| 211 | T *dv = NULL; | 211 | T *dv = nullptr; |
| 212 | DoMap(x, dv); | 212 | DoMap(x, dv); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| @@ -264,11 +264,11 @@ public: | |||
| 264 | { | 264 | { |
| 265 | for (auto it = x.begin(), end = x.end(); it != end; ++it) | 265 | for (auto it = x.begin(), end = x.end(); it != end; ++it) |
| 266 | { | 266 | { |
| 267 | if (it->second != NULL) | 267 | if (it->second != nullptr) |
| 268 | delete it->second; | 268 | delete it->second; |
| 269 | } | 269 | } |
| 270 | } | 270 | } |
| 271 | T *dv = NULL; | 271 | T *dv = nullptr; |
| 272 | DoMultimap(x, dv); | 272 | DoMultimap(x, dv); |
| 273 | } | 273 | } |
| 274 | 274 | ||
| @@ -320,7 +320,7 @@ public: | |||
| 320 | template<class T> | 320 | template<class T> |
| 321 | void Do(std::vector<T *> &x) | 321 | void Do(std::vector<T *> &x) |
| 322 | { | 322 | { |
| 323 | T *dv = NULL; | 323 | T *dv = nullptr; |
| 324 | DoVector(x, dv); | 324 | DoVector(x, dv); |
| 325 | } | 325 | } |
| 326 | 326 | ||
| @@ -369,7 +369,7 @@ public: | |||
| 369 | template<class T> | 369 | template<class T> |
| 370 | void Do(std::deque<T *> &x) | 370 | void Do(std::deque<T *> &x) |
| 371 | { | 371 | { |
| 372 | T *dv = NULL; | 372 | T *dv = nullptr; |
| 373 | DoDeque(x, dv); | 373 | DoDeque(x, dv); |
| 374 | } | 374 | } |
| 375 | 375 | ||
| @@ -395,7 +395,7 @@ public: | |||
| 395 | template<class T> | 395 | template<class T> |
| 396 | void Do(std::list<T *> &x) | 396 | void Do(std::list<T *> &x) |
| 397 | { | 397 | { |
| 398 | T *dv = NULL; | 398 | T *dv = nullptr; |
| 399 | Do(x, dv); | 399 | Do(x, dv); |
| 400 | } | 400 | } |
| 401 | 401 | ||
| @@ -433,7 +433,7 @@ public: | |||
| 433 | { | 433 | { |
| 434 | for (auto it = x.begin(), end = x.end(); it != end; ++it) | 434 | for (auto it = x.begin(), end = x.end(); it != end; ++it) |
| 435 | { | 435 | { |
| 436 | if (*it != NULL) | 436 | if (*it != nullptr) |
| 437 | delete *it; | 437 | delete *it; |
| 438 | } | 438 | } |
| 439 | } | 439 | } |
| @@ -518,7 +518,7 @@ public: | |||
| 518 | void DoClass(T *&x) { | 518 | void DoClass(T *&x) { |
| 519 | if (mode == MODE_READ) | 519 | if (mode == MODE_READ) |
| 520 | { | 520 | { |
| 521 | if (x != NULL) | 521 | if (x != nullptr) |
| 522 | delete x; | 522 | delete x; |
| 523 | x = new T(); | 523 | x = new T(); |
| 524 | } | 524 | } |
| @@ -567,7 +567,7 @@ public: | |||
| 567 | { | 567 | { |
| 568 | if (mode == MODE_READ) | 568 | if (mode == MODE_READ) |
| 569 | { | 569 | { |
| 570 | cur->next = 0; | 570 | cur->next = nullptr; |
| 571 | list_cur = cur; | 571 | list_cur = cur; |
| 572 | if (prev) | 572 | if (prev) |
| 573 | prev->next = cur; | 573 | prev->next = cur; |
| @@ -586,13 +586,13 @@ public: | |||
| 586 | if (mode == MODE_READ) | 586 | if (mode == MODE_READ) |
| 587 | { | 587 | { |
| 588 | if (prev) | 588 | if (prev) |
| 589 | prev->next = 0; | 589 | prev->next = nullptr; |
| 590 | if (list_end) | 590 | if (list_end) |
| 591 | *list_end = prev; | 591 | *list_end = prev; |
| 592 | if (list_cur) | 592 | if (list_cur) |
| 593 | { | 593 | { |
| 594 | if (list_start == list_cur) | 594 | if (list_start == list_cur) |
| 595 | list_start = 0; | 595 | list_start = nullptr; |
| 596 | do | 596 | do |
| 597 | { | 597 | { |
| 598 | LinkedListItem<T>* next = list_cur->next; | 598 | LinkedListItem<T>* next = list_cur->next; |
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index d84ec4c42..1139dc3b8 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h | |||
| @@ -106,7 +106,7 @@ inline u64 _rotr64(u64 x, unsigned int shift){ | |||
| 106 | // Restore the global locale | 106 | // Restore the global locale |
| 107 | _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); | 107 | _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); |
| 108 | } | 108 | } |
| 109 | else if(new_locale != NULL) | 109 | else if(new_locale != nullptr) |
| 110 | { | 110 | { |
| 111 | // Configure the thread to set the locale only for this thread | 111 | // Configure the thread to set the locale only for this thread |
| 112 | _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); | 112 | _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); |
diff --git a/src/common/console_listener.cpp b/src/common/console_listener.cpp index d7f27c358..b6042796d 100644 --- a/src/common/console_listener.cpp +++ b/src/common/console_listener.cpp | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | ConsoleListener::ConsoleListener() | 16 | ConsoleListener::ConsoleListener() |
| 17 | { | 17 | { |
| 18 | #ifdef _WIN32 | 18 | #ifdef _WIN32 |
| 19 | hConsole = NULL; | 19 | hConsole = nullptr; |
| 20 | bUseColor = true; | 20 | bUseColor = true; |
| 21 | #else | 21 | #else |
| 22 | bUseColor = isatty(fileno(stdout)); | 22 | bUseColor = isatty(fileno(stdout)); |
| @@ -66,19 +66,19 @@ void ConsoleListener::UpdateHandle() | |||
| 66 | void ConsoleListener::Close() | 66 | void ConsoleListener::Close() |
| 67 | { | 67 | { |
| 68 | #ifdef _WIN32 | 68 | #ifdef _WIN32 |
| 69 | if (hConsole == NULL) | 69 | if (hConsole == nullptr) |
| 70 | return; | 70 | return; |
| 71 | FreeConsole(); | 71 | FreeConsole(); |
| 72 | hConsole = NULL; | 72 | hConsole = nullptr; |
| 73 | #else | 73 | #else |
| 74 | fflush(NULL); | 74 | fflush(nullptr); |
| 75 | #endif | 75 | #endif |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | bool ConsoleListener::IsOpen() | 78 | bool ConsoleListener::IsOpen() |
| 79 | { | 79 | { |
| 80 | #ifdef _WIN32 | 80 | #ifdef _WIN32 |
| 81 | return (hConsole != NULL); | 81 | return (hConsole != nullptr); |
| 82 | #else | 82 | #else |
| 83 | return true; | 83 | return true; |
| 84 | #endif | 84 | #endif |
diff --git a/src/common/extended_trace.cpp b/src/common/extended_trace.cpp index bf61ac1d1..cf7c346d4 100644 --- a/src/common/extended_trace.cpp +++ b/src/common/extended_trace.cpp | |||
| @@ -82,7 +82,7 @@ static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath ) | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | // Add user defined path | 84 | // Add user defined path |
| 85 | if ( lpszIniPath != NULL ) | 85 | if ( lpszIniPath != nullptr ) |
| 86 | if ( lpszIniPath[0] != '\0' ) | 86 | if ( lpszIniPath[0] != '\0' ) |
| 87 | { | 87 | { |
| 88 | strcat( lpszSymbolPath, ";" ); | 88 | strcat( lpszSymbolPath, ";" ); |
| @@ -138,7 +138,7 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L | |||
| 138 | DWORD dwSymSize = 10000; | 138 | DWORD dwSymSize = 10000; |
| 139 | TCHAR lpszUnDSymbol[BUFFERSIZE]=_T("?"); | 139 | TCHAR lpszUnDSymbol[BUFFERSIZE]=_T("?"); |
| 140 | CHAR lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; | 140 | CHAR lpszNonUnicodeUnDSymbol[BUFFERSIZE]="?"; |
| 141 | LPTSTR lpszParamSep = NULL; | 141 | LPTSTR lpszParamSep = nullptr; |
| 142 | LPTSTR lpszParsed = lpszUnDSymbol; | 142 | LPTSTR lpszParsed = lpszUnDSymbol; |
| 143 | PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); | 143 | PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc( GMEM_FIXED, dwSymSize ); |
| 144 | 144 | ||
| @@ -187,13 +187,13 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L | |||
| 187 | 187 | ||
| 188 | // Let's go through the stack, and modify the function prototype, and insert the actual | 188 | // Let's go through the stack, and modify the function prototype, and insert the actual |
| 189 | // parameter values from the stack | 189 | // parameter values from the stack |
| 190 | if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == NULL && _tcsstr( lpszUnDSymbol, _T("()") ) == NULL) | 190 | if ( _tcsstr( lpszUnDSymbol, _T("(void)") ) == nullptr && _tcsstr( lpszUnDSymbol, _T("()") ) == nullptr) |
| 191 | { | 191 | { |
| 192 | ULONG index = 0; | 192 | ULONG index = 0; |
| 193 | for( ; ; index++ ) | 193 | for( ; ; index++ ) |
| 194 | { | 194 | { |
| 195 | lpszParamSep = _tcschr( lpszParsed, _T(',') ); | 195 | lpszParamSep = _tcschr( lpszParsed, _T(',') ); |
| 196 | if ( lpszParamSep == NULL ) | 196 | if ( lpszParamSep == nullptr ) |
| 197 | break; | 197 | break; |
| 198 | 198 | ||
| 199 | *lpszParamSep = _T('\0'); | 199 | *lpszParamSep = _T('\0'); |
| @@ -205,7 +205,7 @@ static BOOL GetFunctionInfoFromAddresses( ULONG fnAddress, ULONG stackAddress, L | |||
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | lpszParamSep = _tcschr( lpszParsed, _T(')') ); | 207 | lpszParamSep = _tcschr( lpszParsed, _T(')') ); |
| 208 | if ( lpszParamSep != NULL ) | 208 | if ( lpszParamSep != nullptr ) |
| 209 | { | 209 | { |
| 210 | *lpszParamSep = _T('\0'); | 210 | *lpszParamSep = _T('\0'); |
| 211 | 211 | ||
| @@ -248,7 +248,7 @@ static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo ) | |||
| 248 | PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); | 248 | PCSTR2LPTSTR( lineInfo.FileName, lpszFileName ); |
| 249 | TCHAR fname[_MAX_FNAME]; | 249 | TCHAR fname[_MAX_FNAME]; |
| 250 | TCHAR ext[_MAX_EXT]; | 250 | TCHAR ext[_MAX_EXT]; |
| 251 | _tsplitpath(lpszFileName, NULL, NULL, fname, ext); | 251 | _tsplitpath(lpszFileName, nullptr, nullptr, fname, ext); |
| 252 | _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); | 252 | _stprintf( lpszSourceInfo, _T("%s%s(%d)"), fname, ext, lineInfo.LineNumber ); |
| 253 | ret = TRUE; | 253 | ret = TRUE; |
| 254 | } | 254 | } |
| @@ -332,11 +332,11 @@ void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file ) | |||
| 332 | hProcess, | 332 | hProcess, |
| 333 | hThread, | 333 | hThread, |
| 334 | &callStack, | 334 | &callStack, |
| 335 | NULL, | 335 | nullptr, |
| 336 | NULL, | 336 | nullptr, |
| 337 | SymFunctionTableAccess, | 337 | SymFunctionTableAccess, |
| 338 | SymGetModuleBase, | 338 | SymGetModuleBase, |
| 339 | NULL); | 339 | nullptr); |
| 340 | 340 | ||
| 341 | if ( index == 0 ) | 341 | if ( index == 0 ) |
| 342 | continue; | 342 | continue; |
| @@ -389,11 +389,11 @@ void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, | |||
| 389 | hProcess, | 389 | hProcess, |
| 390 | hThread, | 390 | hThread, |
| 391 | &callStack, | 391 | &callStack, |
| 392 | NULL, | 392 | nullptr, |
| 393 | NULL, | 393 | nullptr, |
| 394 | SymFunctionTableAccess, | 394 | SymFunctionTableAccess, |
| 395 | SymGetModuleBase, | 395 | SymGetModuleBase, |
| 396 | NULL); | 396 | nullptr); |
| 397 | 397 | ||
| 398 | if ( index == 0 ) | 398 | if ( index == 0 ) |
| 399 | continue; | 399 | continue; |
diff --git a/src/common/fifo_queue.h b/src/common/fifo_queue.h index 2c18285d4..b426e6596 100644 --- a/src/common/fifo_queue.h +++ b/src/common/fifo_queue.h | |||
| @@ -57,7 +57,7 @@ public: | |||
| 57 | // advance the read pointer | 57 | // advance the read pointer |
| 58 | m_read_ptr = m_read_ptr->next; | 58 | m_read_ptr = m_read_ptr->next; |
| 59 | // set the next element to NULL to stop the recursive deletion | 59 | // set the next element to NULL to stop the recursive deletion |
| 60 | tmpptr->next = NULL; | 60 | tmpptr->next = nullptr; |
| 61 | delete tmpptr; // this also deletes the element | 61 | delete tmpptr; // this also deletes the element |
| 62 | } | 62 | } |
| 63 | 63 | ||
| @@ -86,7 +86,7 @@ private: | |||
| 86 | class ElementPtr | 86 | class ElementPtr |
| 87 | { | 87 | { |
| 88 | public: | 88 | public: |
| 89 | ElementPtr() : current(NULL), next(NULL) {} | 89 | ElementPtr() : current(nullptr), next(nullptr) {} |
| 90 | 90 | ||
| 91 | ~ElementPtr() | 91 | ~ElementPtr() |
| 92 | { | 92 | { |
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index b6dec838c..6c4860503 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp | |||
| @@ -140,7 +140,7 @@ bool CreateDir(const std::string &path) | |||
| 140 | { | 140 | { |
| 141 | INFO_LOG(COMMON, "CreateDir: directory %s", path.c_str()); | 141 | INFO_LOG(COMMON, "CreateDir: directory %s", path.c_str()); |
| 142 | #ifdef _WIN32 | 142 | #ifdef _WIN32 |
| 143 | if (::CreateDirectory(Common::UTF8ToTStr(path).c_str(), NULL)) | 143 | if (::CreateDirectory(Common::UTF8ToTStr(path).c_str(), nullptr)) |
| 144 | return true; | 144 | return true; |
| 145 | DWORD error = GetLastError(); | 145 | DWORD error = GetLastError(); |
| 146 | if (error == ERROR_ALREADY_EXISTS) | 146 | if (error == ERROR_ALREADY_EXISTS) |
| @@ -423,7 +423,7 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) | |||
| 423 | FSTEntry entry; | 423 | FSTEntry entry; |
| 424 | const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); | 424 | const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); |
| 425 | #else | 425 | #else |
| 426 | struct dirent dirent, *result = NULL; | 426 | struct dirent dirent, *result = nullptr; |
| 427 | 427 | ||
| 428 | DIR *dirp = opendir(directory.c_str()); | 428 | DIR *dirp = opendir(directory.c_str()); |
| 429 | if (!dirp) | 429 | if (!dirp) |
| @@ -491,7 +491,7 @@ bool DeleteDirRecursively(const std::string &directory) | |||
| 491 | { | 491 | { |
| 492 | const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); | 492 | const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); |
| 493 | #else | 493 | #else |
| 494 | struct dirent dirent, *result = NULL; | 494 | struct dirent dirent, *result = nullptr; |
| 495 | DIR *dirp = opendir(directory.c_str()); | 495 | DIR *dirp = opendir(directory.c_str()); |
| 496 | if (!dirp) | 496 | if (!dirp) |
| 497 | return false; | 497 | return false; |
| @@ -552,7 +552,7 @@ void CopyDir(const std::string &source_path, const std::string &dest_path) | |||
| 552 | if (!FileUtil::Exists(source_path)) return; | 552 | if (!FileUtil::Exists(source_path)) return; |
| 553 | if (!FileUtil::Exists(dest_path)) FileUtil::CreateFullPath(dest_path); | 553 | if (!FileUtil::Exists(dest_path)) FileUtil::CreateFullPath(dest_path); |
| 554 | 554 | ||
| 555 | struct dirent dirent, *result = NULL; | 555 | struct dirent dirent, *result = nullptr; |
| 556 | DIR *dirp = opendir(source_path.c_str()); | 556 | DIR *dirp = opendir(source_path.c_str()); |
| 557 | if (!dirp) return; | 557 | if (!dirp) return; |
| 558 | 558 | ||
| @@ -586,11 +586,11 @@ std::string GetCurrentDir() | |||
| 586 | { | 586 | { |
| 587 | char *dir; | 587 | char *dir; |
| 588 | // Get the current working directory (getcwd uses malloc) | 588 | // Get the current working directory (getcwd uses malloc) |
| 589 | if (!(dir = __getcwd(NULL, 0))) { | 589 | if (!(dir = __getcwd(nullptr, 0))) { |
| 590 | 590 | ||
| 591 | ERROR_LOG(COMMON, "GetCurrentDirectory failed: %s", | 591 | ERROR_LOG(COMMON, "GetCurrentDirectory failed: %s", |
| 592 | GetLastErrorMsg()); | 592 | GetLastErrorMsg()); |
| 593 | return NULL; | 593 | return nullptr; |
| 594 | } | 594 | } |
| 595 | std::string strDir = dir; | 595 | std::string strDir = dir; |
| 596 | free(dir); | 596 | free(dir); |
| @@ -626,7 +626,7 @@ std::string& GetExeDirectory() | |||
| 626 | if (DolphinPath.empty()) | 626 | if (DolphinPath.empty()) |
| 627 | { | 627 | { |
| 628 | TCHAR Dolphin_exe_Path[2048]; | 628 | TCHAR Dolphin_exe_Path[2048]; |
| 629 | GetModuleFileName(NULL, Dolphin_exe_Path, 2048); | 629 | GetModuleFileName(nullptr, Dolphin_exe_Path, 2048); |
| 630 | DolphinPath = Common::TStrToUTF8(Dolphin_exe_Path); | 630 | DolphinPath = Common::TStrToUTF8(Dolphin_exe_Path); |
| 631 | DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\')); | 631 | DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\')); |
| 632 | } | 632 | } |
| @@ -826,7 +826,7 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam | |||
| 826 | } | 826 | } |
| 827 | 827 | ||
| 828 | IOFile::IOFile() | 828 | IOFile::IOFile() |
| 829 | : m_file(NULL), m_good(true) | 829 | : m_file(nullptr), m_good(true) |
| 830 | {} | 830 | {} |
| 831 | 831 | ||
| 832 | IOFile::IOFile(std::FILE* file) | 832 | IOFile::IOFile(std::FILE* file) |
| @@ -834,7 +834,7 @@ IOFile::IOFile(std::FILE* file) | |||
| 834 | {} | 834 | {} |
| 835 | 835 | ||
| 836 | IOFile::IOFile(const std::string& filename, const char openmode[]) | 836 | IOFile::IOFile(const std::string& filename, const char openmode[]) |
| 837 | : m_file(NULL), m_good(true) | 837 | : m_file(nullptr), m_good(true) |
| 838 | { | 838 | { |
| 839 | Open(filename, openmode); | 839 | Open(filename, openmode); |
| 840 | } | 840 | } |
| @@ -845,7 +845,7 @@ IOFile::~IOFile() | |||
| 845 | } | 845 | } |
| 846 | 846 | ||
| 847 | IOFile::IOFile(IOFile&& other) | 847 | IOFile::IOFile(IOFile&& other) |
| 848 | : m_file(NULL), m_good(true) | 848 | : m_file(nullptr), m_good(true) |
| 849 | { | 849 | { |
| 850 | Swap(other); | 850 | Swap(other); |
| 851 | } | 851 | } |
| @@ -880,14 +880,14 @@ bool IOFile::Close() | |||
| 880 | if (!IsOpen() || 0 != std::fclose(m_file)) | 880 | if (!IsOpen() || 0 != std::fclose(m_file)) |
| 881 | m_good = false; | 881 | m_good = false; |
| 882 | 882 | ||
| 883 | m_file = NULL; | 883 | m_file = nullptr; |
| 884 | return m_good; | 884 | return m_good; |
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | std::FILE* IOFile::ReleaseHandle() | 887 | std::FILE* IOFile::ReleaseHandle() |
| 888 | { | 888 | { |
| 889 | std::FILE* const ret = m_file; | 889 | std::FILE* const ret = m_file; |
| 890 | m_file = NULL; | 890 | m_file = nullptr; |
| 891 | return ret; | 891 | return ret; |
| 892 | } | 892 | } |
| 893 | 893 | ||
diff --git a/src/common/file_util.h b/src/common/file_util.h index 72b80be8a..beaf7174a 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h | |||
| @@ -202,11 +202,11 @@ public: | |||
| 202 | return WriteArray(reinterpret_cast<const char*>(data), length); | 202 | return WriteArray(reinterpret_cast<const char*>(data), length); |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | bool IsOpen() { return NULL != m_file; } | 205 | bool IsOpen() { return nullptr != m_file; } |
| 206 | 206 | ||
| 207 | // m_good is set to false when a read, write or other function fails | 207 | // m_good is set to false when a read, write or other function fails |
| 208 | bool IsGood() { return m_good; } | 208 | bool IsGood() { return m_good; } |
| 209 | operator void*() { return m_good ? m_file : NULL; } | 209 | operator void*() { return m_good ? m_file : nullptr; } |
| 210 | 210 | ||
| 211 | std::FILE* ReleaseHandle(); | 211 | std::FILE* ReleaseHandle(); |
| 212 | 212 | ||
diff --git a/src/common/linear_disk_cache.h b/src/common/linear_disk_cache.h index f4263f72a..bb1b5174f 100644 --- a/src/common/linear_disk_cache.h +++ b/src/common/linear_disk_cache.h | |||
| @@ -70,7 +70,7 @@ public: | |||
| 70 | // good header, read some key/value pairs | 70 | // good header, read some key/value pairs |
| 71 | K key; | 71 | K key; |
| 72 | 72 | ||
| 73 | V *value = NULL; | 73 | V *value = nullptr; |
| 74 | u32 value_size; | 74 | u32 value_size; |
| 75 | u32 entry_number; | 75 | u32 entry_number; |
| 76 | 76 | ||
diff --git a/src/common/log_manager.cpp b/src/common/log_manager.cpp index 38c681ee0..39b1924c7 100644 --- a/src/common/log_manager.cpp +++ b/src/common/log_manager.cpp | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | #include "common/log_manager.h" | 7 | #include "common/log_manager.h" |
| 8 | #include "common/console_listener.h" | 8 | #include "common/console_listener.h" |
| 9 | #include "common/timer.h" | 9 | #include "common/timer.h" |
| 10 | #include "common/thread.h" | ||
| 11 | 10 | ||
| 12 | void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line, | 11 | void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line, |
| 13 | const char* function, const char* fmt, ...) | 12 | const char* function, const char* fmt, ...) |
| @@ -22,7 +21,7 @@ void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* | |||
| 22 | va_end(args); | 21 | va_end(args); |
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | LogManager *LogManager::m_logManager = NULL; | 24 | LogManager *LogManager::m_logManager = nullptr; |
| 26 | 25 | ||
| 27 | LogManager::LogManager() | 26 | LogManager::LogManager() |
| 28 | { | 27 | { |
| @@ -142,7 +141,7 @@ void LogManager::Init() | |||
| 142 | void LogManager::Shutdown() | 141 | void LogManager::Shutdown() |
| 143 | { | 142 | { |
| 144 | delete m_logManager; | 143 | delete m_logManager; |
| 145 | m_logManager = NULL; | 144 | m_logManager = nullptr; |
| 146 | } | 145 | } |
| 147 | 146 | ||
| 148 | LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable) | 147 | LogContainer::LogContainer(const char* shortName, const char* fullName, bool enable) |
diff --git a/src/common/mem_arena.cpp b/src/common/mem_arena.cpp index 67dbaf509..7d4fda0e2 100644 --- a/src/common/mem_arena.cpp +++ b/src/common/mem_arena.cpp | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #ifdef IOS | 32 | #ifdef IOS |
| 33 | void* globalbase = NULL; | 33 | void* globalbase = nullptr; |
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| 36 | #ifdef ANDROID | 36 | #ifdef ANDROID |
| @@ -121,7 +121,7 @@ void MemArena::GrabLowMemSpace(size_t size) | |||
| 121 | { | 121 | { |
| 122 | #ifdef _WIN32 | 122 | #ifdef _WIN32 |
| 123 | #ifndef _XBOX | 123 | #ifndef _XBOX |
| 124 | hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)(size), NULL); | 124 | hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, (DWORD)(size), nullptr); |
| 125 | GetSystemInfo(&sysInfo); | 125 | GetSystemInfo(&sysInfo); |
| 126 | #endif | 126 | #endif |
| 127 | #elif defined(ANDROID) | 127 | #elif defined(ANDROID) |
| @@ -178,7 +178,7 @@ void *MemArena::CreateView(s64 offset, size_t size, void *base) | |||
| 178 | #ifdef _XBOX | 178 | #ifdef _XBOX |
| 179 | size = roundup(size); | 179 | size = roundup(size); |
| 180 | // use 64kb pages | 180 | // use 64kb pages |
| 181 | void * ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); | 181 | void * ptr = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); |
| 182 | return ptr; | 182 | return ptr; |
| 183 | #else | 183 | #else |
| 184 | size = roundup(size); | 184 | size = roundup(size); |
| @@ -243,8 +243,8 @@ u8* MemArena::Find4GBBase() | |||
| 243 | return base; | 243 | return base; |
| 244 | #else | 244 | #else |
| 245 | #ifdef IOS | 245 | #ifdef IOS |
| 246 | void* base = NULL; | 246 | void* base = nullptr; |
| 247 | if (globalbase == NULL){ | 247 | if (globalbase == nullptr){ |
| 248 | base = mmap(0, 0x08000000, PROT_READ | PROT_WRITE, | 248 | base = mmap(0, 0x08000000, PROT_READ | PROT_WRITE, |
| 249 | MAP_ANON | MAP_SHARED, -1, 0); | 249 | MAP_ANON | MAP_SHARED, -1, 0); |
| 250 | if (base == MAP_FAILED) { | 250 | if (base == MAP_FAILED) { |
| @@ -357,7 +357,7 @@ bail: | |||
| 357 | if (views[j].out_ptr_low && *views[j].out_ptr_low) | 357 | if (views[j].out_ptr_low && *views[j].out_ptr_low) |
| 358 | { | 358 | { |
| 359 | arena->ReleaseView(*views[j].out_ptr_low, views[j].size); | 359 | arena->ReleaseView(*views[j].out_ptr_low, views[j].size); |
| 360 | *views[j].out_ptr_low = NULL; | 360 | *views[j].out_ptr_low = nullptr; |
| 361 | } | 361 | } |
| 362 | if (*views[j].out_ptr) | 362 | if (*views[j].out_ptr) |
| 363 | { | 363 | { |
| @@ -369,7 +369,7 @@ bail: | |||
| 369 | arena->ReleaseView(*views[j].out_ptr, views[j].size); | 369 | arena->ReleaseView(*views[j].out_ptr, views[j].size); |
| 370 | } | 370 | } |
| 371 | #endif | 371 | #endif |
| 372 | *views[j].out_ptr = NULL; | 372 | *views[j].out_ptr = nullptr; |
| 373 | } | 373 | } |
| 374 | } | 374 | } |
| 375 | return false; | 375 | return false; |
| @@ -415,7 +415,7 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena | |||
| 415 | #elif defined(_WIN32) | 415 | #elif defined(_WIN32) |
| 416 | // Try a whole range of possible bases. Return once we got a valid one. | 416 | // Try a whole range of possible bases. Return once we got a valid one. |
| 417 | u32 max_base_addr = 0x7FFF0000 - 0x10000000; | 417 | u32 max_base_addr = 0x7FFF0000 - 0x10000000; |
| 418 | u8 *base = NULL; | 418 | u8 *base = nullptr; |
| 419 | 419 | ||
| 420 | for (u32 base_addr = 0x01000000; base_addr < max_base_addr; base_addr += 0x400000) | 420 | for (u32 base_addr = 0x01000000; base_addr < max_base_addr; base_addr += 0x400000) |
| 421 | { | 421 | { |
| @@ -463,8 +463,8 @@ void MemoryMap_Shutdown(const MemoryView *views, int num_views, u32 flags, MemAr | |||
| 463 | arena->ReleaseView(*views[i].out_ptr_low, views[i].size); | 463 | arena->ReleaseView(*views[i].out_ptr_low, views[i].size); |
| 464 | if (*views[i].out_ptr && (views[i].out_ptr_low && *views[i].out_ptr != *views[i].out_ptr_low)) | 464 | if (*views[i].out_ptr && (views[i].out_ptr_low && *views[i].out_ptr != *views[i].out_ptr_low)) |
| 465 | arena->ReleaseView(*views[i].out_ptr, views[i].size); | 465 | arena->ReleaseView(*views[i].out_ptr, views[i].size); |
| 466 | *views[i].out_ptr = NULL; | 466 | *views[i].out_ptr = nullptr; |
| 467 | if (views[i].out_ptr_low) | 467 | if (views[i].out_ptr_low) |
| 468 | *views[i].out_ptr_low = NULL; | 468 | *views[i].out_ptr_low = nullptr; |
| 469 | } | 469 | } |
| 470 | } | 470 | } |
diff --git a/src/common/memory_util.cpp b/src/common/memory_util.cpp index b6f66e4e1..93da5500b 100644 --- a/src/common/memory_util.cpp +++ b/src/common/memory_util.cpp | |||
| @@ -93,7 +93,7 @@ void* AllocateMemoryPages(size_t size) | |||
| 93 | // printf("Mapped memory at %p (size %ld)\n", ptr, | 93 | // printf("Mapped memory at %p (size %ld)\n", ptr, |
| 94 | // (unsigned long)size); | 94 | // (unsigned long)size); |
| 95 | 95 | ||
| 96 | if (ptr == NULL) | 96 | if (ptr == nullptr) |
| 97 | PanicAlert("Failed to allocate raw memory"); | 97 | PanicAlert("Failed to allocate raw memory"); |
| 98 | 98 | ||
| 99 | return ptr; | 99 | return ptr; |
| @@ -104,7 +104,7 @@ void* AllocateAlignedMemory(size_t size,size_t alignment) | |||
| 104 | #ifdef _WIN32 | 104 | #ifdef _WIN32 |
| 105 | void* ptr = _aligned_malloc(size,alignment); | 105 | void* ptr = _aligned_malloc(size,alignment); |
| 106 | #else | 106 | #else |
| 107 | void* ptr = NULL; | 107 | void* ptr = nullptr; |
| 108 | #ifdef ANDROID | 108 | #ifdef ANDROID |
| 109 | ptr = memalign(alignment, size); | 109 | ptr = memalign(alignment, size); |
| 110 | #else | 110 | #else |
| @@ -116,7 +116,7 @@ void* AllocateAlignedMemory(size_t size,size_t alignment) | |||
| 116 | // printf("Mapped memory at %p (size %ld)\n", ptr, | 116 | // printf("Mapped memory at %p (size %ld)\n", ptr, |
| 117 | // (unsigned long)size); | 117 | // (unsigned long)size); |
| 118 | 118 | ||
| 119 | if (ptr == NULL) | 119 | if (ptr == nullptr) |
| 120 | PanicAlert("Failed to allocate aligned memory"); | 120 | PanicAlert("Failed to allocate aligned memory"); |
| 121 | 121 | ||
| 122 | return ptr; | 122 | return ptr; |
| @@ -130,7 +130,7 @@ void FreeMemoryPages(void* ptr, size_t size) | |||
| 130 | 130 | ||
| 131 | if (!VirtualFree(ptr, 0, MEM_RELEASE)) | 131 | if (!VirtualFree(ptr, 0, MEM_RELEASE)) |
| 132 | PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); | 132 | PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); |
| 133 | ptr = NULL; // Is this our responsibility? | 133 | ptr = nullptr; // Is this our responsibility? |
| 134 | 134 | ||
| 135 | #else | 135 | #else |
| 136 | munmap(ptr, size); | 136 | munmap(ptr, size); |
| @@ -184,7 +184,7 @@ std::string MemUsage() | |||
| 184 | // Print information about the memory usage of the process. | 184 | // Print information about the memory usage of the process. |
| 185 | 185 | ||
| 186 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); | 186 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); |
| 187 | if (NULL == hProcess) return "MemUsage Error"; | 187 | if (nullptr == hProcess) return "MemUsage Error"; |
| 188 | 188 | ||
| 189 | if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) | 189 | if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) |
| 190 | Ret = Common::StringFromFormat("%s K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); | 190 | Ret = Common::StringFromFormat("%s K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); |
diff --git a/src/common/misc.cpp b/src/common/misc.cpp index cf6df44e8..bc9d26188 100644 --- a/src/common/misc.cpp +++ b/src/common/misc.cpp | |||
| @@ -23,9 +23,9 @@ const char* GetLastErrorMsg() | |||
| 23 | #ifdef _WIN32 | 23 | #ifdef _WIN32 |
| 24 | static __declspec(thread) char err_str[buff_size] = {}; | 24 | static __declspec(thread) char err_str[buff_size] = {}; |
| 25 | 25 | ||
| 26 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), | 26 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(), |
| 27 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | 27 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| 28 | err_str, buff_size, NULL); | 28 | err_str, buff_size, nullptr); |
| 29 | #else | 29 | #else |
| 30 | static __thread char err_str[buff_size] = {}; | 30 | static __thread char err_str[buff_size] = {}; |
| 31 | 31 | ||
diff --git a/src/common/platform.h b/src/common/platform.h index d9f095433..53d98fe74 100644 --- a/src/common/platform.h +++ b/src/common/platform.h | |||
| @@ -77,7 +77,7 @@ | |||
| 77 | inline struct tm* localtime_r(const time_t *clock, struct tm *result) { | 77 | inline struct tm* localtime_r(const time_t *clock, struct tm *result) { |
| 78 | if (localtime_s(result, clock) == 0) | 78 | if (localtime_s(result, clock) == 0) |
| 79 | return result; | 79 | return result; |
| 80 | return NULL; | 80 | return nullptr; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | #else | 83 | #else |
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index dcec9275f..7fb7ede5e 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp | |||
| @@ -31,7 +31,7 @@ std::string ToUpper(std::string str) { | |||
| 31 | // faster than sscanf | 31 | // faster than sscanf |
| 32 | bool AsciiToHex(const char* _szValue, u32& result) | 32 | bool AsciiToHex(const char* _szValue, u32& result) |
| 33 | { | 33 | { |
| 34 | char *endptr = NULL; | 34 | char *endptr = nullptr; |
| 35 | const u32 value = strtoul(_szValue, &endptr, 16); | 35 | const u32 value = strtoul(_szValue, &endptr, 16); |
| 36 | 36 | ||
| 37 | if (!endptr || *endptr) | 37 | if (!endptr || *endptr) |
| @@ -69,7 +69,7 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar | |||
| 69 | // will be present in the middle of a multibyte sequence. | 69 | // will be present in the middle of a multibyte sequence. |
| 70 | // | 70 | // |
| 71 | // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l. | 71 | // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l. |
| 72 | static locale_t c_locale = NULL; | 72 | static locale_t c_locale = nullptr; |
| 73 | if (!c_locale) | 73 | if (!c_locale) |
| 74 | c_locale = _create_locale(LC_ALL, ".1252"); | 74 | c_locale = _create_locale(LC_ALL, ".1252"); |
| 75 | writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); | 75 | writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); |
| @@ -92,7 +92,7 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar | |||
| 92 | std::string StringFromFormat(const char* format, ...) | 92 | std::string StringFromFormat(const char* format, ...) |
| 93 | { | 93 | { |
| 94 | va_list args; | 94 | va_list args; |
| 95 | char *buf = NULL; | 95 | char *buf = nullptr; |
| 96 | #ifdef _WIN32 | 96 | #ifdef _WIN32 |
| 97 | int required = 0; | 97 | int required = 0; |
| 98 | 98 | ||
| @@ -162,7 +162,7 @@ std::string StripQuotes(const std::string& s) | |||
| 162 | 162 | ||
| 163 | bool TryParse(const std::string &str, u32 *const output) | 163 | bool TryParse(const std::string &str, u32 *const output) |
| 164 | { | 164 | { |
| 165 | char *endptr = NULL; | 165 | char *endptr = nullptr; |
| 166 | 166 | ||
| 167 | // Reset errno to a value other than ERANGE | 167 | // Reset errno to a value other than ERANGE |
| 168 | errno = 0; | 168 | errno = 0; |
diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 59efbce4c..7e3b620c7 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h | |||
| @@ -37,7 +37,7 @@ struct ThreadQueueList { | |||
| 37 | ~ThreadQueueList() { | 37 | ~ThreadQueueList() { |
| 38 | for (int i = 0; i < NUM_QUEUES; ++i) | 38 | for (int i = 0; i < NUM_QUEUES; ++i) |
| 39 | { | 39 | { |
| 40 | if (queues[i].data != NULL) | 40 | if (queues[i].data != nullptr) |
| 41 | free(queues[i].data); | 41 | free(queues[i].data); |
| 42 | } | 42 | } |
| 43 | } | 43 | } |
| @@ -46,7 +46,7 @@ struct ThreadQueueList { | |||
| 46 | int contains(const IdType uid) { | 46 | int contains(const IdType uid) { |
| 47 | for (int i = 0; i < NUM_QUEUES; ++i) | 47 | for (int i = 0; i < NUM_QUEUES; ++i) |
| 48 | { | 48 | { |
| 49 | if (queues[i].data == NULL) | 49 | if (queues[i].data == nullptr) |
| 50 | continue; | 50 | continue; |
| 51 | 51 | ||
| 52 | Queue *cur = &queues[i]; | 52 | Queue *cur = &queues[i]; |
| @@ -133,7 +133,7 @@ struct ThreadQueueList { | |||
| 133 | inline void clear() { | 133 | inline void clear() { |
| 134 | for (int i = 0; i < NUM_QUEUES; ++i) | 134 | for (int i = 0; i < NUM_QUEUES; ++i) |
| 135 | { | 135 | { |
| 136 | if (queues[i].data != NULL) | 136 | if (queues[i].data != nullptr) |
| 137 | free(queues[i].data); | 137 | free(queues[i].data); |
| 138 | } | 138 | } |
| 139 | memset(queues, 0, sizeof(queues)); | 139 | memset(queues, 0, sizeof(queues)); |
| @@ -147,7 +147,7 @@ struct ThreadQueueList { | |||
| 147 | 147 | ||
| 148 | inline void prepare(u32 priority) { | 148 | inline void prepare(u32 priority) { |
| 149 | Queue *cur = &queues[priority]; | 149 | Queue *cur = &queues[priority]; |
| 150 | if (cur->next == NULL) | 150 | if (cur->next == nullptr) |
| 151 | link(priority, INITIAL_CAPACITY); | 151 | link(priority, INITIAL_CAPACITY); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| @@ -176,7 +176,7 @@ private: | |||
| 176 | 176 | ||
| 177 | for (int i = (int) priority - 1; i >= 0; --i) | 177 | for (int i = (int) priority - 1; i >= 0; --i) |
| 178 | { | 178 | { |
| 179 | if (queues[i].next != NULL) | 179 | if (queues[i].next != nullptr) |
| 180 | { | 180 | { |
| 181 | cur->next = queues[i].next; | 181 | cur->next = queues[i].next; |
| 182 | queues[i].next = cur; | 182 | queues[i].next = cur; |
| @@ -193,7 +193,7 @@ private: | |||
| 193 | int size = cur->end - cur->first; | 193 | int size = cur->end - cur->first; |
| 194 | if (size >= cur->capacity - 2) { | 194 | if (size >= cur->capacity - 2) { |
| 195 | IdType *new_data = (IdType *)realloc(cur->data, cur->capacity * 2 * sizeof(IdType)); | 195 | IdType *new_data = (IdType *)realloc(cur->data, cur->capacity * 2 * sizeof(IdType)); |
| 196 | if (new_data != NULL) { | 196 | if (new_data != nullptr) { |
| 197 | cur->capacity *= 2; | 197 | cur->capacity *= 2; |
| 198 | cur->data = new_data; | 198 | cur->data = new_data; |
| 199 | } | 199 | } |
diff --git a/src/common/timer.cpp b/src/common/timer.cpp index ded4a344e..4a797f751 100644 --- a/src/common/timer.cpp +++ b/src/common/timer.cpp | |||
| @@ -25,7 +25,7 @@ u32 Timer::GetTimeMs() | |||
| 25 | return timeGetTime(); | 25 | return timeGetTime(); |
| 26 | #else | 26 | #else |
| 27 | struct timeval t; | 27 | struct timeval t; |
| 28 | (void)gettimeofday(&t, NULL); | 28 | (void)gettimeofday(&t, nullptr); |
| 29 | return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); | 29 | return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); |
| 30 | #endif | 30 | #endif |
| 31 | } | 31 | } |
| @@ -183,7 +183,7 @@ std::string Timer::GetTimeFormatted() | |||
| 183 | return StringFromFormat("%s:%03i", tmp, tp.millitm); | 183 | return StringFromFormat("%s:%03i", tmp, tp.millitm); |
| 184 | #else | 184 | #else |
| 185 | struct timeval t; | 185 | struct timeval t; |
| 186 | (void)gettimeofday(&t, NULL); | 186 | (void)gettimeofday(&t, nullptr); |
| 187 | return StringFromFormat("%s:%03d", tmp, (int)(t.tv_usec / 1000)); | 187 | return StringFromFormat("%s:%03d", tmp, (int)(t.tv_usec / 1000)); |
| 188 | #endif | 188 | #endif |
| 189 | } | 189 | } |
| @@ -197,7 +197,7 @@ double Timer::GetDoubleTime() | |||
| 197 | (void)::ftime(&tp); | 197 | (void)::ftime(&tp); |
| 198 | #else | 198 | #else |
| 199 | struct timeval t; | 199 | struct timeval t; |
| 200 | (void)gettimeofday(&t, NULL); | 200 | (void)gettimeofday(&t, nullptr); |
| 201 | #endif | 201 | #endif |
| 202 | // Get continuous timestamp | 202 | // Get continuous timestamp |
| 203 | u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); | 203 | u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); |
diff --git a/src/common/utf8.cpp b/src/common/utf8.cpp index be4ebc855..66a2f6339 100644 --- a/src/common/utf8.cpp +++ b/src/common/utf8.cpp | |||
| @@ -281,28 +281,28 @@ int u8_read_escape_sequence(const char *str, u32 *dest) | |||
| 281 | do { | 281 | do { |
| 282 | digs[dno++] = str[i++]; | 282 | digs[dno++] = str[i++]; |
| 283 | } while (octal_digit(str[i]) && dno < 3); | 283 | } while (octal_digit(str[i]) && dno < 3); |
| 284 | ch = strtol(digs, NULL, 8); | 284 | ch = strtol(digs, nullptr, 8); |
| 285 | } | 285 | } |
| 286 | else if (str[0] == 'x') { | 286 | else if (str[0] == 'x') { |
| 287 | while (hex_digit(str[i]) && dno < 2) { | 287 | while (hex_digit(str[i]) && dno < 2) { |
| 288 | digs[dno++] = str[i++]; | 288 | digs[dno++] = str[i++]; |
| 289 | } | 289 | } |
| 290 | if (dno > 0) | 290 | if (dno > 0) |
| 291 | ch = strtol(digs, NULL, 16); | 291 | ch = strtol(digs, nullptr, 16); |
| 292 | } | 292 | } |
| 293 | else if (str[0] == 'u') { | 293 | else if (str[0] == 'u') { |
| 294 | while (hex_digit(str[i]) && dno < 4) { | 294 | while (hex_digit(str[i]) && dno < 4) { |
| 295 | digs[dno++] = str[i++]; | 295 | digs[dno++] = str[i++]; |
| 296 | } | 296 | } |
| 297 | if (dno > 0) | 297 | if (dno > 0) |
| 298 | ch = strtol(digs, NULL, 16); | 298 | ch = strtol(digs, nullptr, 16); |
| 299 | } | 299 | } |
| 300 | else if (str[0] == 'U') { | 300 | else if (str[0] == 'U') { |
| 301 | while (hex_digit(str[i]) && dno < 8) { | 301 | while (hex_digit(str[i]) && dno < 8) { |
| 302 | digs[dno++] = str[i++]; | 302 | digs[dno++] = str[i++]; |
| 303 | } | 303 | } |
| 304 | if (dno > 0) | 304 | if (dno > 0) |
| 305 | ch = strtol(digs, NULL, 16); | 305 | ch = strtol(digs, nullptr, 16); |
| 306 | } | 306 | } |
| 307 | *dest = ch; | 307 | *dest = ch; |
| 308 | 308 | ||
| @@ -353,7 +353,7 @@ const char *u8_strchr(const char *s, u32 ch, int *charn) | |||
| 353 | lasti = i; | 353 | lasti = i; |
| 354 | (*charn)++; | 354 | (*charn)++; |
| 355 | } | 355 | } |
| 356 | return NULL; | 356 | return nullptr; |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | const char *u8_memchr(const char *s, u32 ch, size_t sz, int *charn) | 359 | const char *u8_memchr(const char *s, u32 ch, size_t sz, int *charn) |
| @@ -378,7 +378,7 @@ const char *u8_memchr(const char *s, u32 ch, size_t sz, int *charn) | |||
| 378 | lasti = i; | 378 | lasti = i; |
| 379 | (*charn)++; | 379 | (*charn)++; |
| 380 | } | 380 | } |
| 381 | return NULL; | 381 | return nullptr; |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | int u8_is_locale_utf8(const char *locale) | 384 | int u8_is_locale_utf8(const char *locale) |
| @@ -419,35 +419,35 @@ bool UTF8StringHasNonASCII(const char *utf8string) { | |||
| 419 | 419 | ||
| 420 | std::string ConvertWStringToUTF8(const wchar_t *wstr) { | 420 | std::string ConvertWStringToUTF8(const wchar_t *wstr) { |
| 421 | int len = (int)wcslen(wstr); | 421 | int len = (int)wcslen(wstr); |
| 422 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, NULL, NULL); | 422 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr, len, 0, 0, nullptr, nullptr); |
| 423 | std::string s; | 423 | std::string s; |
| 424 | s.resize(size); | 424 | s.resize(size); |
| 425 | if (size > 0) { | 425 | if (size > 0) { |
| 426 | WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, NULL, NULL); | 426 | WideCharToMultiByte(CP_UTF8, 0, wstr, len, &s[0], size, nullptr, nullptr); |
| 427 | } | 427 | } |
| 428 | return s; | 428 | return s; |
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | std::string ConvertWStringToUTF8(const std::wstring &wstr) { | 431 | std::string ConvertWStringToUTF8(const std::wstring &wstr) { |
| 432 | int len = (int)wstr.size(); | 432 | int len = (int)wstr.size(); |
| 433 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, NULL, NULL); | 433 | int size = (int)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, 0, 0, nullptr, nullptr); |
| 434 | std::string s; | 434 | std::string s; |
| 435 | s.resize(size); | 435 | s.resize(size); |
| 436 | if (size > 0) { | 436 | if (size > 0) { |
| 437 | WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, NULL, NULL); | 437 | WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), len, &s[0], size, nullptr, nullptr); |
| 438 | } | 438 | } |
| 439 | return s; | 439 | return s; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { | 442 | void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { |
| 443 | int len = (int)source.size(); | 443 | int len = (int)source.size(); |
| 444 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | 444 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, nullptr, 0); |
| 445 | MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); | 445 | MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, dest, std::min((int)destSize, size)); |
| 446 | } | 446 | } |
| 447 | 447 | ||
| 448 | std::wstring ConvertUTF8ToWString(const std::string &source) { | 448 | std::wstring ConvertUTF8ToWString(const std::string &source) { |
| 449 | int len = (int)source.size(); | 449 | int len = (int)source.size(); |
| 450 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); | 450 | int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, nullptr, 0); |
| 451 | std::wstring str; | 451 | std::wstring str; |
| 452 | str.resize(size); | 452 | str.resize(size); |
| 453 | if (size > 0) { | 453 | if (size > 0) { |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 48241c3d4..f3d7dca9e 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -63,6 +63,7 @@ set(SRCS | |||
| 63 | loader/elf.cpp | 63 | loader/elf.cpp |
| 64 | loader/loader.cpp | 64 | loader/loader.cpp |
| 65 | loader/ncch.cpp | 65 | loader/ncch.cpp |
| 66 | loader/3dsx.cpp | ||
| 66 | core.cpp | 67 | core.cpp |
| 67 | core_timing.cpp | 68 | core_timing.cpp |
| 68 | mem_map.cpp | 69 | mem_map.cpp |
| @@ -143,6 +144,7 @@ set(HEADERS | |||
| 143 | loader/elf.h | 144 | loader/elf.h |
| 144 | loader/loader.h | 145 | loader/loader.h |
| 145 | loader/ncch.h | 146 | loader/ncch.h |
| 147 | loader/3dsx.h | ||
| 146 | core.h | 148 | core.h |
| 147 | core_timing.h | 149 | core_timing.h |
| 148 | mem_map.h | 150 | mem_map.h |
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/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index 73223874e..d717bd2c8 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp | |||
| @@ -5724,7 +5724,7 @@ L_stm_s_takeabort: | |||
| 5724 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | 5724 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |
| 5725 | s16 b1 = (state->Reg[src2] & 0xFFFF); | 5725 | s16 b1 = (state->Reg[src2] & 0xFFFF); |
| 5726 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | 5726 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5727 | state->Reg[tar] = (a1 - a2)&0xFFFF | (((b1 - b2)&0xFFFF)<< 0x10); | 5727 | state->Reg[tar] = ((a1 - a2) & 0xFFFF) | (((b1 - b2)&0xFFFF)<< 0x10); |
| 5728 | return 1; | 5728 | return 1; |
| 5729 | } | 5729 | } |
| 5730 | else if ((instr & 0xFF0) == 0xf10)//sadd16 | 5730 | else if ((instr & 0xFF0) == 0xf10)//sadd16 |
| @@ -5736,7 +5736,7 @@ L_stm_s_takeabort: | |||
| 5736 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | 5736 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |
| 5737 | s16 b1 = (state->Reg[src2] & 0xFFFF); | 5737 | s16 b1 = (state->Reg[src2] & 0xFFFF); |
| 5738 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | 5738 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5739 | state->Reg[tar] = (a1 + a2)&0xFFFF | (((b1 + b2)&0xFFFF)<< 0x10); | 5739 | state->Reg[tar] = ((a1 + a2) & 0xFFFF) | (((b1 + b2)&0xFFFF)<< 0x10); |
| 5740 | return 1; | 5740 | return 1; |
| 5741 | } | 5741 | } |
| 5742 | else if ((instr & 0xFF0) == 0xf50)//ssax | 5742 | else if ((instr & 0xFF0) == 0xf50)//ssax |
| @@ -5748,7 +5748,7 @@ L_stm_s_takeabort: | |||
| 5748 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | 5748 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |
| 5749 | s16 b1 = (state->Reg[src2] & 0xFFFF); | 5749 | s16 b1 = (state->Reg[src2] & 0xFFFF); |
| 5750 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | 5750 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5751 | state->Reg[tar] = (a1 - b2) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10); | 5751 | state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10); |
| 5752 | return 1; | 5752 | return 1; |
| 5753 | } | 5753 | } |
| 5754 | else if ((instr & 0xFF0) == 0xf30)//sasx | 5754 | else if ((instr & 0xFF0) == 0xf30)//sasx |
| @@ -5760,7 +5760,7 @@ L_stm_s_takeabort: | |||
| 5760 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | 5760 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |
| 5761 | s16 b1 = (state->Reg[src2] & 0xFFFF); | 5761 | s16 b1 = (state->Reg[src2] & 0xFFFF); |
| 5762 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | 5762 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5763 | state->Reg[tar] = (a2 - b1) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10); | 5763 | state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10); |
| 5764 | return 1; | 5764 | return 1; |
| 5765 | } | 5765 | } |
| 5766 | else printf ("Unhandled v6 insn: sadd/ssub\n"); | 5766 | else printf ("Unhandled v6 insn: sadd/ssub\n"); |
diff --git a/src/core/arm/skyeye_common/armcpu.h b/src/core/arm/skyeye_common/armcpu.h index 3a029f0e7..2b756c5bc 100644 --- a/src/core/arm/skyeye_common/armcpu.h +++ b/src/core/arm/skyeye_common/armcpu.h | |||
| @@ -24,8 +24,6 @@ | |||
| 24 | #include <stddef.h> | 24 | #include <stddef.h> |
| 25 | #include <stdio.h> | 25 | #include <stdio.h> |
| 26 | 26 | ||
| 27 | #include "common/thread.h" | ||
| 28 | |||
| 29 | #include "core/arm/skyeye_common/armdefs.h" | 27 | #include "core/arm/skyeye_common/armdefs.h" |
| 30 | 28 | ||
| 31 | typedef struct ARM_CPU_State_s { | 29 | typedef struct ARM_CPU_State_s { |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 558c6cbf7..bf8acf41f 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -67,7 +67,7 @@ s64 idledCycles; | |||
| 67 | static std::recursive_mutex externalEventSection; | 67 | static std::recursive_mutex externalEventSection; |
| 68 | 68 | ||
| 69 | // Warning: not included in save state. | 69 | // Warning: not included in save state. |
| 70 | void(*advanceCallback)(int cyclesExecuted) = NULL; | 70 | void(*advanceCallback)(int cyclesExecuted) = nullptr; |
| 71 | 71 | ||
| 72 | void SetClockFrequencyMHz(int cpuMhz) | 72 | void SetClockFrequencyMHz(int cpuMhz) |
| 73 | { | 73 | { |
| @@ -231,7 +231,7 @@ void ClearPendingEvents() | |||
| 231 | 231 | ||
| 232 | void AddEventToQueue(Event* ne) | 232 | void AddEventToQueue(Event* ne) |
| 233 | { | 233 | { |
| 234 | Event* prev = NULL; | 234 | Event* prev = nullptr; |
| 235 | Event** pNext = &first; | 235 | Event** pNext = &first; |
| 236 | for (;;) | 236 | for (;;) |
| 237 | { | 237 | { |
| @@ -327,7 +327,7 @@ s64 UnscheduleThreadsafeEvent(int event_type, u64 userdata) | |||
| 327 | } | 327 | } |
| 328 | if (!tsFirst) | 328 | if (!tsFirst) |
| 329 | { | 329 | { |
| 330 | tsLast = NULL; | 330 | tsLast = nullptr; |
| 331 | return result; | 331 | return result; |
| 332 | } | 332 | } |
| 333 | 333 | ||
| @@ -433,7 +433,7 @@ void RemoveThreadsafeEvent(int event_type) | |||
| 433 | } | 433 | } |
| 434 | if (!tsFirst) | 434 | if (!tsFirst) |
| 435 | { | 435 | { |
| 436 | tsLast = NULL; | 436 | tsLast = nullptr; |
| 437 | return; | 437 | return; |
| 438 | } | 438 | } |
| 439 | Event *prev = tsFirst; | 439 | Event *prev = tsFirst; |
| @@ -495,7 +495,7 @@ void MoveEvents() | |||
| 495 | AddEventToQueue(tsFirst); | 495 | AddEventToQueue(tsFirst); |
| 496 | tsFirst = next; | 496 | tsFirst = next; |
| 497 | } | 497 | } |
| 498 | tsLast = NULL; | 498 | tsLast = nullptr; |
| 499 | 499 | ||
| 500 | // Move free events to threadsafe pool | 500 | // Move free events to threadsafe pool |
| 501 | while (allocatedTsEvents > 0 && eventPool) | 501 | while (allocatedTsEvents > 0 && eventPool) |
| @@ -614,7 +614,7 @@ void DoState(PointerWrap &p) | |||
| 614 | // These (should) be filled in later by the modules. | 614 | // These (should) be filled in later by the modules. |
| 615 | event_types.resize(n, EventType(AntiCrashCallback, "INVALID EVENT")); | 615 | event_types.resize(n, EventType(AntiCrashCallback, "INVALID EVENT")); |
| 616 | 616 | ||
| 617 | p.DoLinkedList<BaseEvent, GetNewEvent, FreeEvent, Event_DoState>(first, (Event **)NULL); | 617 | p.DoLinkedList<BaseEvent, GetNewEvent, FreeEvent, Event_DoState>(first, (Event **)nullptr); |
| 618 | p.DoLinkedList<BaseEvent, GetNewTsEvent, FreeTsEvent, Event_DoState>(tsFirst, &tsLast); | 618 | p.DoLinkedList<BaseEvent, GetNewTsEvent, FreeTsEvent, Event_DoState>(tsFirst, &tsLast); |
| 619 | 619 | ||
| 620 | p.Do(g_clock_rate_arm11); | 620 | p.Do(g_clock_rate_arm11); |
diff --git a/src/core/file_sys/archive.h b/src/core/file_sys/archive.h index 2e79bb883..f3cb11133 100644 --- a/src/core/file_sys/archive.h +++ b/src/core/file_sys/archive.h | |||
| @@ -67,6 +67,8 @@ public: | |||
| 67 | u16str = std::u16string(data, size/2 - 1); // Data is always null-terminated. | 67 | u16str = std::u16string(data, size/2 - 1); // Data is always null-terminated. |
| 68 | break; | 68 | break; |
| 69 | } | 69 | } |
| 70 | default: | ||
| 71 | break; | ||
| 70 | } | 72 | } |
| 71 | } | 73 | } |
| 72 | 74 | ||
| @@ -192,6 +194,14 @@ public: | |||
| 192 | virtual bool DeleteFile(const FileSys::Path& path) const = 0; | 194 | virtual bool DeleteFile(const FileSys::Path& path) const = 0; |
| 193 | 195 | ||
| 194 | /** | 196 | /** |
| 197 | * Rename a File specified by its path | ||
| 198 | * @param src_path Source path relative to the archive | ||
| 199 | * @param dest_path Destination path relative to the archive | ||
| 200 | * @return Whether rename succeeded | ||
| 201 | */ | ||
| 202 | virtual bool RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const = 0; | ||
| 203 | |||
| 204 | /** | ||
| 195 | * Delete a directory specified by its path | 205 | * Delete a directory specified by its path |
| 196 | * @param path Path relative to the archive | 206 | * @param path Path relative to the archive |
| 197 | * @return Whether the directory could be deleted | 207 | * @return Whether the directory could be deleted |
| @@ -206,6 +216,14 @@ public: | |||
| 206 | virtual bool CreateDirectory(const Path& path) const = 0; | 216 | virtual bool CreateDirectory(const Path& path) const = 0; |
| 207 | 217 | ||
| 208 | /** | 218 | /** |
| 219 | * Rename a Directory specified by its path | ||
| 220 | * @param src_path Source path relative to the archive | ||
| 221 | * @param dest_path Destination path relative to the archive | ||
| 222 | * @return Whether rename succeeded | ||
| 223 | */ | ||
| 224 | virtual bool RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const = 0; | ||
| 225 | |||
| 226 | /** | ||
| 209 | * Open a directory specified by its path | 227 | * Open a directory specified by its path |
| 210 | * @param path Path relative to the archive | 228 | * @param path Path relative to the archive |
| 211 | * @return Opened directory, or nullptr | 229 | * @return Opened directory, or nullptr |
diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index 53dc57954..8c2dbeda5 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp | |||
| @@ -43,6 +43,11 @@ bool Archive_RomFS::DeleteFile(const FileSys::Path& path) const { | |||
| 43 | return false; | 43 | return false; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | bool Archive_RomFS::RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const { | ||
| 47 | ERROR_LOG(FILESYS, "Attempted to rename a file within ROMFS."); | ||
| 48 | return false; | ||
| 49 | } | ||
| 50 | |||
| 46 | /** | 51 | /** |
| 47 | * Delete a directory specified by its path | 52 | * Delete a directory specified by its path |
| 48 | * @param path Path relative to the archive | 53 | * @param path Path relative to the archive |
| @@ -63,6 +68,11 @@ bool Archive_RomFS::CreateDirectory(const Path& path) const { | |||
| 63 | return false; | 68 | return false; |
| 64 | } | 69 | } |
| 65 | 70 | ||
| 71 | bool Archive_RomFS::RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const { | ||
| 72 | ERROR_LOG(FILESYS, "Attempted to rename a file within ROMFS."); | ||
| 73 | return false; | ||
| 74 | } | ||
| 75 | |||
| 66 | /** | 76 | /** |
| 67 | * Open a directory specified by its path | 77 | * Open a directory specified by its path |
| 68 | * @param path Path relative to the archive | 78 | * @param path Path relative to the archive |
diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 0649dde99..222bdc356 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h | |||
| @@ -44,6 +44,14 @@ public: | |||
| 44 | bool DeleteFile(const FileSys::Path& path) const override; | 44 | bool DeleteFile(const FileSys::Path& path) const override; |
| 45 | 45 | ||
| 46 | /** | 46 | /** |
| 47 | * Rename a File specified by its path | ||
| 48 | * @param src_path Source path relative to the archive | ||
| 49 | * @param dest_path Destination path relative to the archive | ||
| 50 | * @return Whether rename succeeded | ||
| 51 | */ | ||
| 52 | bool RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const override; | ||
| 53 | |||
| 54 | /** | ||
| 47 | * Delete a directory specified by its path | 55 | * Delete a directory specified by its path |
| 48 | * @param path Path relative to the archive | 56 | * @param path Path relative to the archive |
| 49 | * @return Whether the directory could be deleted | 57 | * @return Whether the directory could be deleted |
| @@ -58,6 +66,14 @@ public: | |||
| 58 | bool CreateDirectory(const Path& path) const override; | 66 | bool CreateDirectory(const Path& path) const override; |
| 59 | 67 | ||
| 60 | /** | 68 | /** |
| 69 | * Rename a Directory specified by its path | ||
| 70 | * @param src_path Source path relative to the archive | ||
| 71 | * @param dest_path Destination path relative to the archive | ||
| 72 | * @return Whether rename succeeded | ||
| 73 | */ | ||
| 74 | bool RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const override; | ||
| 75 | |||
| 76 | /** | ||
| 61 | * Open a directory specified by its path | 77 | * Open a directory specified by its path |
| 62 | * @param path Path relative to the archive | 78 | * @param path Path relative to the archive |
| 63 | * @return Opened directory, or nullptr | 79 | * @return Opened directory, or nullptr |
diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index c2ffcd40d..fc0b9b72d 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp | |||
| @@ -50,7 +50,7 @@ bool Archive_SDMC::Initialize() { | |||
| 50 | * @return Opened file, or nullptr | 50 | * @return Opened file, or nullptr |
| 51 | */ | 51 | */ |
| 52 | std::unique_ptr<File> Archive_SDMC::OpenFile(const Path& path, const Mode mode) const { | 52 | std::unique_ptr<File> Archive_SDMC::OpenFile(const Path& path, const Mode mode) const { |
| 53 | DEBUG_LOG(FILESYS, "called path=%s mode=%d", path.DebugStr().c_str(), mode); | 53 | DEBUG_LOG(FILESYS, "called path=%s mode=%u", path.DebugStr().c_str(), mode.hex); |
| 54 | File_SDMC* file = new File_SDMC(this, path, mode); | 54 | File_SDMC* file = new File_SDMC(this, path, mode); |
| 55 | if (!file->Open()) | 55 | if (!file->Open()) |
| 56 | return nullptr; | 56 | return nullptr; |
| @@ -66,6 +66,10 @@ bool Archive_SDMC::DeleteFile(const FileSys::Path& path) const { | |||
| 66 | return FileUtil::Delete(GetMountPoint() + path.AsString()); | 66 | return FileUtil::Delete(GetMountPoint() + path.AsString()); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | bool Archive_SDMC::RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const { | ||
| 70 | return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString()); | ||
| 71 | } | ||
| 72 | |||
| 69 | /** | 73 | /** |
| 70 | * Delete a directory specified by its path | 74 | * Delete a directory specified by its path |
| 71 | * @param path Path relative to the archive | 75 | * @param path Path relative to the archive |
| @@ -84,6 +88,10 @@ bool Archive_SDMC::CreateDirectory(const Path& path) const { | |||
| 84 | return FileUtil::CreateDir(GetMountPoint() + path.AsString()); | 88 | return FileUtil::CreateDir(GetMountPoint() + path.AsString()); |
| 85 | } | 89 | } |
| 86 | 90 | ||
| 91 | bool Archive_SDMC::RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const { | ||
| 92 | return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString()); | ||
| 93 | } | ||
| 94 | |||
| 87 | /** | 95 | /** |
| 88 | * Open a directory specified by its path | 96 | * Open a directory specified by its path |
| 89 | * @param path Path relative to the archive | 97 | * @param path Path relative to the archive |
| @@ -92,6 +100,8 @@ bool Archive_SDMC::CreateDirectory(const Path& path) const { | |||
| 92 | std::unique_ptr<Directory> Archive_SDMC::OpenDirectory(const Path& path) const { | 100 | std::unique_ptr<Directory> Archive_SDMC::OpenDirectory(const Path& path) const { |
| 93 | DEBUG_LOG(FILESYS, "called path=%s", path.DebugStr().c_str()); | 101 | DEBUG_LOG(FILESYS, "called path=%s", path.DebugStr().c_str()); |
| 94 | Directory_SDMC* directory = new Directory_SDMC(this, path); | 102 | Directory_SDMC* directory = new Directory_SDMC(this, path); |
| 103 | if (!directory->Open()) | ||
| 104 | return nullptr; | ||
| 95 | return std::unique_ptr<Directory>(directory); | 105 | return std::unique_ptr<Directory>(directory); |
| 96 | } | 106 | } |
| 97 | 107 | ||
diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 74ce29c0d..19f563a62 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h | |||
| @@ -48,6 +48,14 @@ public: | |||
| 48 | bool DeleteFile(const FileSys::Path& path) const override; | 48 | bool DeleteFile(const FileSys::Path& path) const override; |
| 49 | 49 | ||
| 50 | /** | 50 | /** |
| 51 | * Rename a File specified by its path | ||
| 52 | * @param src_path Source path relative to the archive | ||
| 53 | * @param dest_path Destination path relative to the archive | ||
| 54 | * @return Whether rename succeeded | ||
| 55 | */ | ||
| 56 | bool RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const override; | ||
| 57 | |||
| 58 | /** | ||
| 51 | * Delete a directory specified by its path | 59 | * Delete a directory specified by its path |
| 52 | * @param path Path relative to the archive | 60 | * @param path Path relative to the archive |
| 53 | * @return Whether the directory could be deleted | 61 | * @return Whether the directory could be deleted |
| @@ -62,6 +70,14 @@ public: | |||
| 62 | bool CreateDirectory(const Path& path) const override; | 70 | bool CreateDirectory(const Path& path) const override; |
| 63 | 71 | ||
| 64 | /** | 72 | /** |
| 73 | * Rename a Directory specified by its path | ||
| 74 | * @param src_path Source path relative to the archive | ||
| 75 | * @param dest_path Destination path relative to the archive | ||
| 76 | * @return Whether rename succeeded | ||
| 77 | */ | ||
| 78 | bool RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const override; | ||
| 79 | |||
| 80 | /** | ||
| 65 | * Open a directory specified by its path | 81 | * Open a directory specified by its path |
| 66 | * @param path Path relative to the archive | 82 | * @param path Path relative to the archive |
| 67 | * @return Opened directory, or nullptr | 83 | * @return Opened directory, or nullptr |
diff --git a/src/core/file_sys/directory.h b/src/core/file_sys/directory.h index e10431337..1bb4101d6 100644 --- a/src/core/file_sys/directory.h +++ b/src/core/file_sys/directory.h | |||
| @@ -42,6 +42,12 @@ public: | |||
| 42 | virtual ~Directory() { } | 42 | virtual ~Directory() { } |
| 43 | 43 | ||
| 44 | /** | 44 | /** |
| 45 | * Open the directory | ||
| 46 | * @return true if the directory opened correctly | ||
| 47 | */ | ||
| 48 | virtual bool Open() = 0; | ||
| 49 | |||
| 50 | /** | ||
| 45 | * List files contained in the directory | 51 | * List files contained in the directory |
| 46 | * @param count Number of entries to return at once in entries | 52 | * @param count Number of entries to return at once in entries |
| 47 | * @param entries Buffer to read data into | 53 | * @param entries Buffer to read data into |
diff --git a/src/core/file_sys/directory_romfs.cpp b/src/core/file_sys/directory_romfs.cpp index 4e8f4c04d..e6d571391 100644 --- a/src/core/file_sys/directory_romfs.cpp +++ b/src/core/file_sys/directory_romfs.cpp | |||
| @@ -17,6 +17,10 @@ Directory_RomFS::Directory_RomFS() { | |||
| 17 | Directory_RomFS::~Directory_RomFS() { | 17 | Directory_RomFS::~Directory_RomFS() { |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | bool Directory_RomFS::Open() { | ||
| 21 | return false; | ||
| 22 | } | ||
| 23 | |||
| 20 | /** | 24 | /** |
| 21 | * List files contained in the directory | 25 | * List files contained in the directory |
| 22 | * @param count Number of entries to return at once in entries | 26 | * @param count Number of entries to return at once in entries |
diff --git a/src/core/file_sys/directory_romfs.h b/src/core/file_sys/directory_romfs.h index 4b71c4b13..e2944099e 100644 --- a/src/core/file_sys/directory_romfs.h +++ b/src/core/file_sys/directory_romfs.h | |||
| @@ -20,6 +20,12 @@ public: | |||
| 20 | ~Directory_RomFS() override; | 20 | ~Directory_RomFS() override; |
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | * Open the directory | ||
| 24 | * @return true if the directory opened correctly | ||
| 25 | */ | ||
| 26 | bool Open() override; | ||
| 27 | |||
| 28 | /** | ||
| 23 | * List files contained in the directory | 29 | * List files contained in the directory |
| 24 | * @param count Number of entries to return at once in entries | 30 | * @param count Number of entries to return at once in entries |
| 25 | * @param entries Buffer to read data into | 31 | * @param entries Buffer to read data into |
diff --git a/src/core/file_sys/directory_sdmc.cpp b/src/core/file_sys/directory_sdmc.cpp index 60a197ce9..0f156a127 100644 --- a/src/core/file_sys/directory_sdmc.cpp +++ b/src/core/file_sys/directory_sdmc.cpp | |||
| @@ -19,15 +19,22 @@ Directory_SDMC::Directory_SDMC(const Archive_SDMC* archive, const Path& path) { | |||
| 19 | // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass | 19 | // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass |
| 20 | // the root directory we set while opening the archive. | 20 | // the root directory we set while opening the archive. |
| 21 | // For example, opening /../../usr/bin can give the emulated program your installed programs. | 21 | // For example, opening /../../usr/bin can give the emulated program your installed programs. |
| 22 | std::string absolute_path = archive->GetMountPoint() + path.AsString(); | 22 | this->path = archive->GetMountPoint() + path.AsString(); |
| 23 | FileUtil::ScanDirectoryTree(absolute_path, directory); | 23 | |
| 24 | children_iterator = directory.children.begin(); | ||
| 25 | } | 24 | } |
| 26 | 25 | ||
| 27 | Directory_SDMC::~Directory_SDMC() { | 26 | Directory_SDMC::~Directory_SDMC() { |
| 28 | Close(); | 27 | Close(); |
| 29 | } | 28 | } |
| 30 | 29 | ||
| 30 | bool Directory_SDMC::Open() { | ||
| 31 | if (!FileUtil::IsDirectory(path)) | ||
| 32 | return false; | ||
| 33 | FileUtil::ScanDirectoryTree(path, directory); | ||
| 34 | children_iterator = directory.children.begin(); | ||
| 35 | return true; | ||
| 36 | } | ||
| 37 | |||
| 31 | /** | 38 | /** |
| 32 | * List files contained in the directory | 39 | * List files contained in the directory |
| 33 | * @param count Number of entries to return at once in entries | 40 | * @param count Number of entries to return at once in entries |
diff --git a/src/core/file_sys/directory_sdmc.h b/src/core/file_sys/directory_sdmc.h index 4520d0401..4c08b0d61 100644 --- a/src/core/file_sys/directory_sdmc.h +++ b/src/core/file_sys/directory_sdmc.h | |||
| @@ -23,6 +23,12 @@ public: | |||
| 23 | ~Directory_SDMC() override; | 23 | ~Directory_SDMC() override; |
| 24 | 24 | ||
| 25 | /** | 25 | /** |
| 26 | * Open the directory | ||
| 27 | * @return true if the directory opened correctly | ||
| 28 | */ | ||
| 29 | bool Open() override; | ||
| 30 | |||
| 31 | /** | ||
| 26 | * List files contained in the directory | 32 | * List files contained in the directory |
| 27 | * @param count Number of entries to return at once in entries | 33 | * @param count Number of entries to return at once in entries |
| 28 | * @param entries Buffer to read data into | 34 | * @param entries Buffer to read data into |
| @@ -37,6 +43,7 @@ public: | |||
| 37 | bool Close() const override; | 43 | bool Close() const override; |
| 38 | 44 | ||
| 39 | private: | 45 | private: |
| 46 | std::string path; | ||
| 40 | u32 total_entries_in_directory; | 47 | u32 total_entries_in_directory; |
| 41 | FileUtil::FSTEntry directory; | 48 | FileUtil::FSTEntry directory; |
| 42 | 49 | ||
diff --git a/src/core/file_sys/file_sdmc.cpp b/src/core/file_sys/file_sdmc.cpp index a4b90670a..b01d96e3d 100644 --- a/src/core/file_sys/file_sdmc.cpp +++ b/src/core/file_sys/file_sdmc.cpp | |||
| @@ -38,12 +38,15 @@ bool File_SDMC::Open() { | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | std::string mode_string; | 40 | std::string mode_string; |
| 41 | if (mode.read_flag && mode.write_flag) | 41 | if (mode.create_flag) |
| 42 | mode_string = "w+"; | 42 | mode_string = "w+"; |
| 43 | else if (mode.write_flag) | ||
| 44 | mode_string = "r+"; // Files opened with Write access can be read from | ||
| 43 | else if (mode.read_flag) | 45 | else if (mode.read_flag) |
| 44 | mode_string = "r"; | 46 | mode_string = "r"; |
| 45 | else if (mode.write_flag) | 47 | |
| 46 | mode_string = "w"; | 48 | // Open the file in binary mode, to avoid problems with CR/LF on Windows systems |
| 49 | mode_string += "b"; | ||
| 47 | 50 | ||
| 48 | file = new FileUtil::IOFile(path, mode_string.c_str()); | 51 | file = new FileUtil::IOFile(path, mode_string.c_str()); |
| 49 | return true; | 52 | return true; |
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index db571b895..ce4f3c854 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -53,7 +53,7 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3 | |||
| 53 | // Wait current thread (acquire the arbiter)... | 53 | // Wait current thread (acquire the arbiter)... |
| 54 | case ArbitrationType::WaitIfLessThan: | 54 | case ArbitrationType::WaitIfLessThan: |
| 55 | if ((s32)Memory::Read32(address) <= value) { | 55 | if ((s32)Memory::Read32(address) <= value) { |
| 56 | Kernel::WaitCurrentThread(WAITTYPE_ARB, handle); | 56 | Kernel::WaitCurrentThread(WAITTYPE_ARB, handle, address); |
| 57 | HLE::Reschedule(__func__); | 57 | HLE::Reschedule(__func__); |
| 58 | } | 58 | } |
| 59 | break; | 59 | break; |
diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp index e273444c9..a875fa7ff 100644 --- a/src/core/hle/kernel/archive.cpp +++ b/src/core/hle/kernel/archive.cpp | |||
| @@ -340,49 +340,68 @@ ResultVal<Handle> OpenFileFromArchive(Handle archive_handle, const FileSys::Path | |||
| 340 | return MakeResult<Handle>(handle); | 340 | return MakeResult<Handle>(handle); |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | /** | 343 | ResultCode DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path) { |
| 344 | * Delete a File from an Archive | ||
| 345 | * @param archive_handle Handle to an open Archive object | ||
| 346 | * @param path Path to the File inside of the Archive | ||
| 347 | * @return Whether deletion succeeded | ||
| 348 | */ | ||
| 349 | Result DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path) { | ||
| 350 | Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); | 344 | Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); |
| 351 | if (archive == nullptr) | 345 | if (archive == nullptr) |
| 352 | return -1; | 346 | return InvalidHandle(ErrorModule::FS); |
| 353 | if (archive->backend->DeleteFile(path)) | 347 | if (archive->backend->DeleteFile(path)) |
| 354 | return 0; | 348 | return RESULT_SUCCESS; |
| 355 | return -1; | 349 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description |
| 350 | ErrorSummary::Canceled, ErrorLevel::Status); | ||
| 356 | } | 351 | } |
| 357 | 352 | ||
| 358 | /** | 353 | ResultCode RenameFileBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path, |
| 359 | * Delete a Directory from an Archive | 354 | Handle dest_archive_handle, const FileSys::Path& dest_path) { |
| 360 | * @param archive_handle Handle to an open Archive object | 355 | Archive* src_archive = Kernel::g_object_pool.GetFast<Archive>(src_archive_handle); |
| 361 | * @param path Path to the Directory inside of the Archive | 356 | Archive* dest_archive = Kernel::g_object_pool.GetFast<Archive>(dest_archive_handle); |
| 362 | * @return Whether deletion succeeded | 357 | if (src_archive == nullptr || dest_archive == nullptr) |
| 363 | */ | 358 | return InvalidHandle(ErrorModule::FS); |
| 364 | Result DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { | 359 | if (src_archive == dest_archive) { |
| 360 | if (src_archive->backend->RenameFile(src_path, dest_path)) | ||
| 361 | return RESULT_SUCCESS; | ||
| 362 | } else { | ||
| 363 | // TODO: Implement renaming across archives | ||
| 364 | return UnimplementedFunction(ErrorModule::FS); | ||
| 365 | } | ||
| 366 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description | ||
| 367 | ErrorSummary::NothingHappened, ErrorLevel::Status); | ||
| 368 | } | ||
| 369 | |||
| 370 | ResultCode DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { | ||
| 365 | Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); | 371 | Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); |
| 366 | if (archive == nullptr) | 372 | if (archive == nullptr) |
| 367 | return -1; | 373 | return InvalidHandle(ErrorModule::FS); |
| 368 | if (archive->backend->DeleteDirectory(path)) | 374 | if (archive->backend->DeleteDirectory(path)) |
| 369 | return 0; | 375 | return RESULT_SUCCESS; |
| 370 | return -1; | 376 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description |
| 377 | ErrorSummary::Canceled, ErrorLevel::Status); | ||
| 371 | } | 378 | } |
| 372 | 379 | ||
| 373 | /** | 380 | ResultCode CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { |
| 374 | * Create a Directory from an Archive | ||
| 375 | * @param archive_handle Handle to an open Archive object | ||
| 376 | * @param path Path to the Directory inside of the Archive | ||
| 377 | * @return Whether creation succeeded | ||
| 378 | */ | ||
| 379 | Result CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path) { | ||
| 380 | Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); | 381 | Archive* archive = Kernel::g_object_pool.GetFast<Archive>(archive_handle); |
| 381 | if (archive == nullptr) | 382 | if (archive == nullptr) |
| 382 | return -1; | 383 | return InvalidHandle(ErrorModule::FS); |
| 383 | if (archive->backend->CreateDirectory(path)) | 384 | if (archive->backend->CreateDirectory(path)) |
| 384 | return 0; | 385 | return RESULT_SUCCESS; |
| 385 | return -1; | 386 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description |
| 387 | ErrorSummary::Canceled, ErrorLevel::Status); | ||
| 388 | } | ||
| 389 | |||
| 390 | ResultCode RenameDirectoryBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path, | ||
| 391 | Handle dest_archive_handle, const FileSys::Path& dest_path) { | ||
| 392 | Archive* src_archive = Kernel::g_object_pool.GetFast<Archive>(src_archive_handle); | ||
| 393 | Archive* dest_archive = Kernel::g_object_pool.GetFast<Archive>(dest_archive_handle); | ||
| 394 | if (src_archive == nullptr || dest_archive == nullptr) | ||
| 395 | return InvalidHandle(ErrorModule::FS); | ||
| 396 | if (src_archive == dest_archive) { | ||
| 397 | if (src_archive->backend->RenameDirectory(src_path, dest_path)) | ||
| 398 | return RESULT_SUCCESS; | ||
| 399 | } else { | ||
| 400 | // TODO: Implement renaming across archives | ||
| 401 | return UnimplementedFunction(ErrorModule::FS); | ||
| 402 | } | ||
| 403 | return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description | ||
| 404 | ErrorSummary::NothingHappened, ErrorLevel::Status); | ||
| 386 | } | 405 | } |
| 387 | 406 | ||
| 388 | /** | 407 | /** |
| @@ -402,6 +421,11 @@ ResultVal<Handle> OpenDirectoryFromArchive(Handle archive_handle, const FileSys: | |||
| 402 | directory->path = path; | 421 | directory->path = path; |
| 403 | directory->backend = archive->backend->OpenDirectory(path); | 422 | directory->backend = archive->backend->OpenDirectory(path); |
| 404 | 423 | ||
| 424 | if (!directory->backend) { | ||
| 425 | return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, | ||
| 426 | ErrorSummary::NotFound, ErrorLevel::Permanent); | ||
| 427 | } | ||
| 428 | |||
| 405 | return MakeResult<Handle>(handle); | 429 | return MakeResult<Handle>(handle); |
| 406 | } | 430 | } |
| 407 | 431 | ||
diff --git a/src/core/hle/kernel/archive.h b/src/core/hle/kernel/archive.h index 6fc4f0f25..b50833a2b 100644 --- a/src/core/hle/kernel/archive.h +++ b/src/core/hle/kernel/archive.h | |||
| @@ -50,7 +50,18 @@ ResultVal<Handle> OpenFileFromArchive(Handle archive_handle, const FileSys::Path | |||
| 50 | * @param path Path to the File inside of the Archive | 50 | * @param path Path to the File inside of the Archive |
| 51 | * @return Whether deletion succeeded | 51 | * @return Whether deletion succeeded |
| 52 | */ | 52 | */ |
| 53 | Result DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path); | 53 | ResultCode DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path); |
| 54 | |||
| 55 | /** | ||
| 56 | * Rename a File between two Archives | ||
| 57 | * @param src_archive_handle Handle to the source Archive object | ||
| 58 | * @param src_path Path to the File inside of the source Archive | ||
| 59 | * @param dest_archive_handle Handle to the destination Archive object | ||
| 60 | * @param dest_path Path to the File inside of the destination Archive | ||
| 61 | * @return Whether rename succeeded | ||
| 62 | */ | ||
| 63 | ResultCode RenameFileBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path, | ||
| 64 | Handle dest_archive_handle, const FileSys::Path& dest_path); | ||
| 54 | 65 | ||
| 55 | /** | 66 | /** |
| 56 | * Delete a Directory from an Archive | 67 | * Delete a Directory from an Archive |
| @@ -58,7 +69,7 @@ Result DeleteFileFromArchive(Handle archive_handle, const FileSys::Path& path); | |||
| 58 | * @param path Path to the Directory inside of the Archive | 69 | * @param path Path to the Directory inside of the Archive |
| 59 | * @return Whether deletion succeeded | 70 | * @return Whether deletion succeeded |
| 60 | */ | 71 | */ |
| 61 | Result DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); | 72 | ResultCode DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); |
| 62 | 73 | ||
| 63 | /** | 74 | /** |
| 64 | * Create a Directory from an Archive | 75 | * Create a Directory from an Archive |
| @@ -66,7 +77,18 @@ Result DeleteDirectoryFromArchive(Handle archive_handle, const FileSys::Path& pa | |||
| 66 | * @param path Path to the Directory inside of the Archive | 77 | * @param path Path to the Directory inside of the Archive |
| 67 | * @return Whether creation of directory succeeded | 78 | * @return Whether creation of directory succeeded |
| 68 | */ | 79 | */ |
| 69 | Result CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); | 80 | ResultCode CreateDirectoryFromArchive(Handle archive_handle, const FileSys::Path& path); |
| 81 | |||
| 82 | /** | ||
| 83 | * Rename a Directory between two Archives | ||
| 84 | * @param src_archive_handle Handle to the source Archive object | ||
| 85 | * @param src_path Path to the Directory inside of the source Archive | ||
| 86 | * @param dest_archive_handle Handle to the destination Archive object | ||
| 87 | * @param dest_path Path to the Directory inside of the destination Archive | ||
| 88 | * @return Whether rename succeeded | ||
| 89 | */ | ||
| 90 | ResultCode RenameDirectoryBetweenArchives(Handle src_archive_handle, const FileSys::Path& src_path, | ||
| 91 | Handle dest_archive_handle, const FileSys::Path& dest_path); | ||
| 70 | 92 | ||
| 71 | /** | 93 | /** |
| 72 | * Open a Directory from an Archive | 94 | * Open a Directory from an Archive |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 018000abd..80a34c2d5 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 6 | |||
| 5 | #include "common/common.h" | 7 | #include "common/common.h" |
| 6 | 8 | ||
| 7 | #include "core/core.h" | 9 | #include "core/core.h" |
| @@ -37,7 +39,7 @@ Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) { | |||
| 37 | return 0; | 39 | return 0; |
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | bool ObjectPool::IsValid(Handle handle) { | 42 | bool ObjectPool::IsValid(Handle handle) const { |
| 41 | int index = handle - HANDLE_OFFSET; | 43 | int index = handle - HANDLE_OFFSET; |
| 42 | if (index < 0) | 44 | if (index < 0) |
| 43 | return false; | 45 | return false; |
| @@ -75,13 +77,8 @@ void ObjectPool::List() { | |||
| 75 | } | 77 | } |
| 76 | } | 78 | } |
| 77 | 79 | ||
| 78 | int ObjectPool::GetCount() { | 80 | int ObjectPool::GetCount() const { |
| 79 | int count = 0; | 81 | return std::count(occupied.begin(), occupied.end(), true); |
| 80 | for (int i = 0; i < MAX_COUNT; i++) { | ||
| 81 | if (occupied[i]) | ||
| 82 | count++; | ||
| 83 | } | ||
| 84 | return count; | ||
| 85 | } | 82 | } |
| 86 | 83 | ||
| 87 | Object* ObjectPool::CreateByIDType(int type) { | 84 | Object* ObjectPool::CreateByIDType(int type) { |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 8d3937ce8..00a2228bf 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -86,7 +86,7 @@ public: | |||
| 86 | } | 86 | } |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | bool IsValid(Handle handle); | 89 | bool IsValid(Handle handle) const; |
| 90 | 90 | ||
| 91 | template <class T> | 91 | template <class T> |
| 92 | T* Get(Handle handle) { | 92 | T* Get(Handle handle) { |
| @@ -142,7 +142,7 @@ public: | |||
| 142 | Object* &operator [](Handle handle); | 142 | Object* &operator [](Handle handle); |
| 143 | void List(); | 143 | void List(); |
| 144 | void Clear(); | 144 | void Clear(); |
| 145 | int GetCount(); | 145 | int GetCount() const; |
| 146 | 146 | ||
| 147 | private: | 147 | private: |
| 148 | 148 | ||
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..1e879b45a 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -49,6 +49,8 @@ public: | |||
| 49 | 49 | ||
| 50 | ThreadContext context; | 50 | ThreadContext context; |
| 51 | 51 | ||
| 52 | u32 thread_id; | ||
| 53 | |||
| 52 | u32 status; | 54 | u32 status; |
| 53 | u32 entry_point; | 55 | u32 entry_point; |
| 54 | u32 stack_top; | 56 | u32 stack_top; |
| @@ -61,6 +63,7 @@ public: | |||
| 61 | 63 | ||
| 62 | WaitType wait_type; | 64 | WaitType wait_type; |
| 63 | Handle wait_handle; | 65 | Handle wait_handle; |
| 66 | VAddr wait_address; | ||
| 64 | 67 | ||
| 65 | std::vector<Handle> waiting_threads; | 68 | std::vector<Handle> waiting_threads; |
| 66 | 69 | ||
| @@ -76,6 +79,9 @@ static Common::ThreadQueueList<Handle> thread_ready_queue; | |||
| 76 | static Handle current_thread_handle; | 79 | static Handle current_thread_handle; |
| 77 | static Thread* current_thread; | 80 | static Thread* current_thread; |
| 78 | 81 | ||
| 82 | static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup | ||
| 83 | static u32 next_thread_id; ///< The next available thread id | ||
| 84 | |||
| 79 | /// Gets the current thread | 85 | /// Gets the current thread |
| 80 | inline Thread* GetCurrentThread() { | 86 | inline Thread* GetCurrentThread() { |
| 81 | return current_thread; | 87 | return current_thread; |
| @@ -121,6 +127,7 @@ void ResetThread(Thread* t, u32 arg, s32 lowest_priority) { | |||
| 121 | } | 127 | } |
| 122 | t->wait_type = WAITTYPE_NONE; | 128 | t->wait_type = WAITTYPE_NONE; |
| 123 | t->wait_handle = 0; | 129 | t->wait_handle = 0; |
| 130 | t->wait_address = 0; | ||
| 124 | } | 131 | } |
| 125 | 132 | ||
| 126 | /// Change a thread to "ready" state | 133 | /// Change a thread to "ready" state |
| @@ -141,9 +148,15 @@ void ChangeReadyState(Thread* t, bool ready) { | |||
| 141 | } | 148 | } |
| 142 | 149 | ||
| 143 | /// Verify that a thread has not been released from waiting | 150 | /// Verify that a thread has not been released from waiting |
| 144 | inline bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle) { | 151 | static bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle) { |
| 145 | _dbg_assert_(KERNEL, thread != nullptr); | 152 | _dbg_assert_(KERNEL, thread != nullptr); |
| 146 | return type == thread->wait_type && wait_handle == thread->wait_handle; | 153 | return (type == thread->wait_type) && (wait_handle == thread->wait_handle) && (thread->IsWaiting()); |
| 154 | } | ||
| 155 | |||
| 156 | /// Verify that a thread has not been released from waiting (with wait address) | ||
| 157 | static bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle, VAddr wait_address) { | ||
| 158 | _dbg_assert_(KERNEL, thread != nullptr); | ||
| 159 | return VerifyWait(thread, type, wait_handle) && (wait_address == thread->wait_address); | ||
| 147 | } | 160 | } |
| 148 | 161 | ||
| 149 | /// Stops the current thread | 162 | /// Stops the current thread |
| @@ -164,6 +177,7 @@ ResultCode StopThread(Handle handle, const char* reason) { | |||
| 164 | // Stopped threads are never waiting. | 177 | // Stopped threads are never waiting. |
| 165 | thread->wait_type = WAITTYPE_NONE; | 178 | thread->wait_type = WAITTYPE_NONE; |
| 166 | thread->wait_handle = 0; | 179 | thread->wait_handle = 0; |
| 180 | thread->wait_address = 0; | ||
| 167 | 181 | ||
| 168 | return RESULT_SUCCESS; | 182 | return RESULT_SUCCESS; |
| 169 | } | 183 | } |
| @@ -192,12 +206,12 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) { | |||
| 192 | for (Handle handle : thread_queue) { | 206 | for (Handle handle : thread_queue) { |
| 193 | Thread* thread = g_object_pool.Get<Thread>(handle); | 207 | Thread* thread = g_object_pool.Get<Thread>(handle); |
| 194 | 208 | ||
| 195 | // TODO(bunnei): Verify arbiter address... | 209 | if (!VerifyWait(thread, WAITTYPE_ARB, arbiter, address)) |
| 196 | if (!VerifyWait(thread, WAITTYPE_ARB, arbiter)) | ||
| 197 | continue; | 210 | continue; |
| 198 | 211 | ||
| 199 | if (thread == nullptr) | 212 | if (thread == nullptr) |
| 200 | continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up. | 213 | continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up. |
| 214 | |||
| 201 | if(thread->current_priority <= priority) { | 215 | if(thread->current_priority <= priority) { |
| 202 | highest_priority_thread = handle; | 216 | highest_priority_thread = handle; |
| 203 | priority = thread->current_priority; | 217 | priority = thread->current_priority; |
| @@ -217,8 +231,7 @@ void ArbitrateAllThreads(u32 arbiter, u32 address) { | |||
| 217 | for (Handle handle : thread_queue) { | 231 | for (Handle handle : thread_queue) { |
| 218 | Thread* thread = g_object_pool.Get<Thread>(handle); | 232 | Thread* thread = g_object_pool.Get<Thread>(handle); |
| 219 | 233 | ||
| 220 | // TODO(bunnei): Verify arbiter address... | 234 | if (VerifyWait(thread, WAITTYPE_ARB, arbiter, address)) |
| 221 | if (VerifyWait(thread, WAITTYPE_ARB, arbiter)) | ||
| 222 | ResumeThreadFromWait(handle); | 235 | ResumeThreadFromWait(handle); |
| 223 | } | 236 | } |
| 224 | } | 237 | } |
| @@ -272,11 +285,6 @@ Thread* NextThread() { | |||
| 272 | return Kernel::g_object_pool.Get<Thread>(next); | 285 | return Kernel::g_object_pool.Get<Thread>(next); |
| 273 | } | 286 | } |
| 274 | 287 | ||
| 275 | /** | ||
| 276 | * Puts the current thread in the wait state for the given type | ||
| 277 | * @param wait_type Type of wait | ||
| 278 | * @param wait_handle Handle of Kernel object that we are waiting on, defaults to current thread | ||
| 279 | */ | ||
| 280 | void WaitCurrentThread(WaitType wait_type, Handle wait_handle) { | 288 | void WaitCurrentThread(WaitType wait_type, Handle wait_handle) { |
| 281 | Thread* thread = GetCurrentThread(); | 289 | Thread* thread = GetCurrentThread(); |
| 282 | thread->wait_type = wait_type; | 290 | thread->wait_type = wait_type; |
| @@ -284,6 +292,11 @@ void WaitCurrentThread(WaitType wait_type, Handle wait_handle) { | |||
| 284 | ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); | 292 | ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); |
| 285 | } | 293 | } |
| 286 | 294 | ||
| 295 | void WaitCurrentThread(WaitType wait_type, Handle wait_handle, VAddr wait_address) { | ||
| 296 | WaitCurrentThread(wait_type, wait_handle); | ||
| 297 | GetCurrentThread()->wait_address = wait_address; | ||
| 298 | } | ||
| 299 | |||
| 287 | /// Resumes a thread from waiting by marking it as "ready" | 300 | /// Resumes a thread from waiting by marking it as "ready" |
| 288 | void ResumeThreadFromWait(Handle handle) { | 301 | void ResumeThreadFromWait(Handle handle) { |
| 289 | Thread* thread = Kernel::g_object_pool.Get<Thread>(handle); | 302 | Thread* thread = Kernel::g_object_pool.Get<Thread>(handle); |
| @@ -325,6 +338,7 @@ Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 prio | |||
| 325 | thread_queue.push_back(handle); | 338 | thread_queue.push_back(handle); |
| 326 | thread_ready_queue.prepare(priority); | 339 | thread_ready_queue.prepare(priority); |
| 327 | 340 | ||
| 341 | thread->thread_id = next_thread_id++; | ||
| 328 | thread->status = THREADSTATUS_DORMANT; | 342 | thread->status = THREADSTATUS_DORMANT; |
| 329 | thread->entry_point = entry_point; | 343 | thread->entry_point = entry_point; |
| 330 | thread->stack_top = stack_top; | 344 | thread->stack_top = stack_top; |
| @@ -333,6 +347,7 @@ Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 prio | |||
| 333 | thread->processor_id = processor_id; | 347 | thread->processor_id = processor_id; |
| 334 | thread->wait_type = WAITTYPE_NONE; | 348 | thread->wait_type = WAITTYPE_NONE; |
| 335 | thread->wait_handle = 0; | 349 | thread->wait_handle = 0; |
| 350 | thread->wait_address = 0; | ||
| 336 | thread->name = name; | 351 | thread->name = name; |
| 337 | 352 | ||
| 338 | return thread; | 353 | return thread; |
| @@ -465,9 +480,21 @@ void Reschedule() { | |||
| 465 | } | 480 | } |
| 466 | } | 481 | } |
| 467 | 482 | ||
| 483 | ResultCode GetThreadId(u32* thread_id, Handle handle) { | ||
| 484 | Thread* thread = g_object_pool.Get<Thread>(handle); | ||
| 485 | if (thread == nullptr) | ||
| 486 | return ResultCode(ErrorDescription::InvalidHandle, ErrorModule::OS, | ||
| 487 | ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||
| 488 | |||
| 489 | *thread_id = thread->thread_id; | ||
| 490 | |||
| 491 | return RESULT_SUCCESS; | ||
| 492 | } | ||
| 493 | |||
| 468 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 494 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 469 | 495 | ||
| 470 | void ThreadingInit() { | 496 | void ThreadingInit() { |
| 497 | next_thread_id = INITIAL_THREAD_ID; | ||
| 471 | } | 498 | } |
| 472 | 499 | ||
| 473 | void ThreadingShutdown() { | 500 | void ThreadingShutdown() { |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index ce63a70d3..be7adface 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -5,6 +5,9 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | |||
| 9 | #include "core/mem_map.h" | ||
| 10 | |||
| 8 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/kernel.h" |
| 9 | #include "core/hle/result.h" | 12 | #include "core/hle/result.h" |
| 10 | 13 | ||
| @@ -58,6 +61,14 @@ void Reschedule(); | |||
| 58 | /// Stops the current thread | 61 | /// Stops the current thread |
| 59 | ResultCode StopThread(Handle thread, const char* reason); | 62 | ResultCode StopThread(Handle thread, const char* reason); |
| 60 | 63 | ||
| 64 | /** | ||
| 65 | * Retrieves the ID of the specified thread handle | ||
| 66 | * @param thread_id Will contain the output thread id | ||
| 67 | * @param handle Handle to the thread we want | ||
| 68 | * @return Whether the function was successful or not | ||
| 69 | */ | ||
| 70 | ResultCode GetThreadId(u32* thread_id, Handle handle); | ||
| 71 | |||
| 61 | /// Resumes a thread from waiting by marking it as "ready" | 72 | /// Resumes a thread from waiting by marking it as "ready" |
| 62 | void ResumeThreadFromWait(Handle handle); | 73 | void ResumeThreadFromWait(Handle handle); |
| 63 | 74 | ||
| @@ -77,6 +88,14 @@ Handle GetCurrentThreadHandle(); | |||
| 77 | */ | 88 | */ |
| 78 | void WaitCurrentThread(WaitType wait_type, Handle wait_handle=GetCurrentThreadHandle()); | 89 | void WaitCurrentThread(WaitType wait_type, Handle wait_handle=GetCurrentThreadHandle()); |
| 79 | 90 | ||
| 91 | /** | ||
| 92 | * Puts the current thread in the wait state for the given type | ||
| 93 | * @param wait_type Type of wait | ||
| 94 | * @param wait_handle Handle of Kernel object that we are waiting on, defaults to current thread | ||
| 95 | * @param wait_address Arbitration address used to resume from wait | ||
| 96 | */ | ||
| 97 | void WaitCurrentThread(WaitType wait_type, Handle wait_handle, VAddr wait_address); | ||
| 98 | |||
| 80 | /// Put current thread in a wait state - on WaitSynchronization | 99 | /// Put current thread in a wait state - on WaitSynchronization |
| 81 | void WaitThread_Synchronization(); | 100 | void WaitThread_Synchronization(); |
| 82 | 101 | ||
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..72be4c817 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,137 @@ | |||
| 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::ConvertProcessAddressFromDspDram service function | ||
| 20 | * Inputs: | ||
| 21 | * 1 : Address | ||
| 22 | * Outputs: | ||
| 23 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 24 | * 2 : (inaddr << 1) + 0x1FF40000 (where 0x1FF00000 is the DSP RAM address) | ||
| 25 | */ | ||
| 26 | void ConvertProcessAddressFromDspDram(Service::Interface* self) { | ||
| 27 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 28 | |||
| 29 | u32 addr = cmd_buff[1]; | ||
| 30 | |||
| 31 | cmd_buff[1] = 0; // No error | ||
| 32 | cmd_buff[2] = (addr << 1) + (Memory::DSP_MEMORY_VADDR + 0x40000); | ||
| 33 | |||
| 34 | DEBUG_LOG(KERNEL, "(STUBBED) called with address %u", addr); | ||
| 35 | } | ||
| 36 | |||
| 37 | /** | ||
| 38 | * DSP_DSP::LoadComponent service function | ||
| 39 | * Inputs: | ||
| 40 | * 1 : Size | ||
| 41 | * 2 : Unknown (observed only half word used) | ||
| 42 | * 3 : Unknown (observed only half word used) | ||
| 43 | * 4 : (size << 4) | 0xA | ||
| 44 | * 5 : Buffer address | ||
| 45 | * Outputs: | ||
| 46 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 47 | * 2 : Component loaded, 0 on not loaded, 1 on loaded | ||
| 48 | */ | ||
| 49 | void LoadComponent(Service::Interface* self) { | ||
| 50 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 51 | |||
| 52 | cmd_buff[1] = 0; // No error | ||
| 53 | cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware | ||
| 54 | |||
| 55 | // TODO(bunnei): Implement real DSP firmware loading | ||
| 56 | |||
| 57 | DEBUG_LOG(KERNEL, "(STUBBED) called"); | ||
| 58 | } | ||
| 59 | |||
| 60 | /** | ||
| 61 | * DSP_DSP::GetSemaphoreEventHandle service function | ||
| 62 | * Outputs: | ||
| 63 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 64 | * 3 : Semaphore event handle | ||
| 65 | */ | ||
| 66 | void GetSemaphoreEventHandle(Service::Interface* self) { | ||
| 67 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 68 | |||
| 69 | cmd_buff[1] = 0; // No error | ||
| 70 | cmd_buff[3] = semaphore_event; // Event handle | ||
| 71 | |||
| 72 | DEBUG_LOG(KERNEL, "(STUBBED) called"); | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 76 | * DSP_DSP::RegisterInterruptEvents service function | ||
| 77 | * Inputs: | ||
| 78 | * 1 : Parameter 0 (purpose unknown) | ||
| 79 | * 2 : Parameter 1 (purpose unknown) | ||
| 80 | * 4 : Interrupt event handle | ||
| 81 | * Outputs: | ||
| 82 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 83 | */ | ||
| 84 | void RegisterInterruptEvents(Service::Interface* self) { | ||
| 85 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 86 | |||
| 87 | interrupt_event = static_cast<Handle>(cmd_buff[4]); | ||
| 88 | |||
| 89 | cmd_buff[1] = 0; // No error | ||
| 90 | |||
| 91 | DEBUG_LOG(KERNEL, "(STUBBED) called"); | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * DSP_DSP::WriteReg0x10 service function | ||
| 96 | * Inputs: | ||
| 97 | * 1 : Unknown (observed only half word used) | ||
| 98 | * Outputs: | ||
| 99 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 100 | */ | ||
| 101 | void WriteReg0x10(Service::Interface* self) { | ||
| 102 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 103 | |||
| 104 | Kernel::SignalEvent(interrupt_event); | ||
| 105 | |||
| 106 | cmd_buff[1] = 0; // No error | ||
| 107 | |||
| 108 | DEBUG_LOG(KERNEL, "(STUBBED) called"); | ||
| 109 | } | ||
| 110 | |||
| 14 | const Interface::FunctionInfo FunctionTable[] = { | 111 | const Interface::FunctionInfo FunctionTable[] = { |
| 15 | {0x00010040, nullptr, "RecvData"}, | 112 | {0x00010040, nullptr, "RecvData"}, |
| 16 | {0x00020040, nullptr, "RecvDataIsReady"}, | 113 | {0x00020040, nullptr, "RecvDataIsReady"}, |
| 17 | {0x00030080, nullptr, "SendData"}, | 114 | {0x00030080, nullptr, "SendData"}, |
| 18 | {0x00040040, nullptr, "SendDataIsEmpty"}, | 115 | {0x00040040, nullptr, "SendDataIsEmpty"}, |
| 19 | {0x00070040, nullptr, "WriteReg0x10"}, | 116 | {0x00070040, WriteReg0x10, "WriteReg0x10"}, |
| 20 | {0x00080000, nullptr, "GetSemaphore"}, | 117 | {0x00080000, nullptr, "GetSemaphore"}, |
| 21 | {0x00090040, nullptr, "ClearSemaphore"}, | 118 | {0x00090040, nullptr, "ClearSemaphore"}, |
| 22 | {0x000B0000, nullptr, "CheckSemaphoreRequest"}, | 119 | {0x000B0000, nullptr, "CheckSemaphoreRequest"}, |
| 23 | {0x000C0040, nullptr, "ConvertProcessAddressFromDspDram"}, | 120 | {0x000C0040, ConvertProcessAddressFromDspDram, "ConvertProcessAddressFromDspDram"}, |
| 24 | {0x000D0082, nullptr, "WriteProcessPipe"}, | 121 | {0x000D0082, nullptr, "WriteProcessPipe"}, |
| 25 | {0x001000C0, nullptr, "ReadPipeIfPossible"}, | 122 | {0x001000C0, nullptr, "ReadPipeIfPossible"}, |
| 26 | {0x001100C2, nullptr, "LoadComponent"}, | 123 | {0x001100C2, LoadComponent, "LoadComponent"}, |
| 27 | {0x00120000, nullptr, "UnloadComponent"}, | 124 | {0x00120000, nullptr, "UnloadComponent"}, |
| 28 | {0x00130082, nullptr, "FlushDataCache"}, | 125 | {0x00130082, nullptr, "FlushDataCache"}, |
| 29 | {0x00140082, nullptr, "InvalidateDCache"}, | 126 | {0x00140082, nullptr, "InvalidateDCache"}, |
| 30 | {0x00150082, nullptr, "RegisterInterruptEvents"}, | 127 | {0x00150082, RegisterInterruptEvents, "RegisterInterruptEvents"}, |
| 31 | {0x00160000, nullptr, "GetSemaphoreEventHandle"}, | 128 | {0x00160000, GetSemaphoreEventHandle, "GetSemaphoreEventHandle"}, |
| 32 | {0x00170040, nullptr, "SetSemaphoreMask"}, | 129 | {0x00170040, nullptr, "SetSemaphoreMask"}, |
| 33 | {0x00180040, nullptr, "GetPhysicalAddress"}, | 130 | {0x00180040, nullptr, "GetPhysicalAddress"}, |
| 34 | {0x00190040, nullptr, "GetVirtualAddress"}, | 131 | {0x00190040, nullptr, "GetVirtualAddress"}, |
| 35 | {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"}, | 132 | {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"}, |
| 36 | {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"}, | 133 | {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"}, |
| 37 | {0x001C0082, nullptr, "SetIirFilterEQ"}, | 134 | {0x001C0082, nullptr, "SetIirFilterEQ"}, |
| 38 | {0x001F0000, nullptr, "GetHeadphoneStatus"}, | 135 | {0x001F0000, nullptr, "GetHeadphoneStatus"}, |
| 39 | {0x00210000, nullptr, "GetIsDspOccupied"}, | 136 | {0x00210000, nullptr, "GetIsDspOccupied"}, |
| 40 | }; | 137 | }; |
| 41 | 138 | ||
| 42 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 139 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 43 | // Interface class | 140 | // Interface class |
| 44 | 141 | ||
| 45 | Interface::Interface() { | 142 | Interface::Interface() { |
| 143 | semaphore_event = Kernel::CreateEvent(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event"); | ||
| 144 | interrupt_event = 0; | ||
| 145 | |||
| 46 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 146 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); |
| 47 | } | 147 | } |
| 48 | 148 | ||
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/fs_user.cpp b/src/core/hle/service/fs_user.cpp index 435be5b5d..51e8b579e 100644 --- a/src/core/hle/service/fs_user.cpp +++ b/src/core/hle/service/fs_user.cpp | |||
| @@ -55,7 +55,7 @@ static void OpenFile(Service::Interface* self) { | |||
| 55 | u32 filename_ptr = cmd_buff[9]; | 55 | u32 filename_ptr = cmd_buff[9]; |
| 56 | FileSys::Path file_path(filename_type, filename_size, filename_ptr); | 56 | FileSys::Path file_path(filename_type, filename_size, filename_ptr); |
| 57 | 57 | ||
| 58 | DEBUG_LOG(KERNEL, "path=%s, mode=%d attrs=%d", file_path.DebugStr().c_str(), mode, attributes); | 58 | DEBUG_LOG(KERNEL, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); |
| 59 | 59 | ||
| 60 | ResultVal<Handle> handle = Kernel::OpenFileFromArchive(archive_handle, file_path, mode); | 60 | ResultVal<Handle> handle = Kernel::OpenFileFromArchive(archive_handle, file_path, mode); |
| 61 | cmd_buff[1] = handle.Code().raw; | 61 | cmd_buff[1] = handle.Code().raw; |
| @@ -102,8 +102,8 @@ static void OpenFileDirectly(Service::Interface* self) { | |||
| 102 | FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); | 102 | FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); |
| 103 | FileSys::Path file_path(filename_type, filename_size, filename_ptr); | 103 | FileSys::Path file_path(filename_type, filename_size, filename_ptr); |
| 104 | 104 | ||
| 105 | DEBUG_LOG(KERNEL, "archive_path=%s file_path=%s, mode=%d attributes=%d", | 105 | DEBUG_LOG(KERNEL, "archive_path=%s file_path=%s, mode=%u attributes=%d", |
| 106 | archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode, attributes); | 106 | archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex, attributes); |
| 107 | 107 | ||
| 108 | if (archive_path.GetType() != FileSys::Empty) { | 108 | if (archive_path.GetType() != FileSys::Empty) { |
| 109 | ERROR_LOG(KERNEL, "archive LowPath type other than empty is currently unsupported"); | 109 | ERROR_LOG(KERNEL, "archive LowPath type other than empty is currently unsupported"); |
| @@ -159,7 +159,49 @@ void DeleteFile(Service::Interface* self) { | |||
| 159 | DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", | 159 | DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", |
| 160 | filename_type, filename_size, file_path.DebugStr().c_str()); | 160 | filename_type, filename_size, file_path.DebugStr().c_str()); |
| 161 | 161 | ||
| 162 | cmd_buff[1] = Kernel::DeleteFileFromArchive(archive_handle, file_path); | 162 | cmd_buff[1] = Kernel::DeleteFileFromArchive(archive_handle, file_path).raw; |
| 163 | |||
| 164 | DEBUG_LOG(KERNEL, "called"); | ||
| 165 | } | ||
| 166 | |||
| 167 | /* | ||
| 168 | * FS_User::RenameFile service function | ||
| 169 | * Inputs: | ||
| 170 | * 2 : Source archive handle lower word | ||
| 171 | * 3 : Source archive handle upper word | ||
| 172 | * 4 : Source file path type | ||
| 173 | * 5 : Source file path size | ||
| 174 | * 6 : Dest archive handle lower word | ||
| 175 | * 7 : Dest archive handle upper word | ||
| 176 | * 8 : Dest file path type | ||
| 177 | * 9 : Dest file path size | ||
| 178 | * 11: Source file path string data | ||
| 179 | * 13: Dest file path string | ||
| 180 | * Outputs: | ||
| 181 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 182 | */ | ||
| 183 | void RenameFile(Service::Interface* self) { | ||
| 184 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 185 | |||
| 186 | // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to | ||
| 187 | // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. | ||
| 188 | Handle src_archive_handle = static_cast<Handle>(cmd_buff[3]); | ||
| 189 | auto src_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); | ||
| 190 | u32 src_filename_size = cmd_buff[5]; | ||
| 191 | Handle dest_archive_handle = static_cast<Handle>(cmd_buff[7]); | ||
| 192 | auto dest_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[8]); | ||
| 193 | u32 dest_filename_size = cmd_buff[9]; | ||
| 194 | u32 src_filename_ptr = cmd_buff[11]; | ||
| 195 | u32 dest_filename_ptr = cmd_buff[13]; | ||
| 196 | |||
| 197 | FileSys::Path src_file_path(src_filename_type, src_filename_size, src_filename_ptr); | ||
| 198 | FileSys::Path dest_file_path(dest_filename_type, dest_filename_size, dest_filename_ptr); | ||
| 199 | |||
| 200 | DEBUG_LOG(KERNEL, "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s", | ||
| 201 | src_filename_type, src_filename_size, src_file_path.DebugStr().c_str(), | ||
| 202 | dest_filename_type, dest_filename_size, dest_file_path.DebugStr().c_str()); | ||
| 203 | |||
| 204 | cmd_buff[1] = Kernel::RenameFileBetweenArchives(src_archive_handle, src_file_path, dest_archive_handle, dest_file_path).raw; | ||
| 163 | 205 | ||
| 164 | DEBUG_LOG(KERNEL, "called"); | 206 | DEBUG_LOG(KERNEL, "called"); |
| 165 | } | 207 | } |
| @@ -190,7 +232,7 @@ void DeleteDirectory(Service::Interface* self) { | |||
| 190 | DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", | 232 | DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", |
| 191 | dirname_type, dirname_size, dir_path.DebugStr().c_str()); | 233 | dirname_type, dirname_size, dir_path.DebugStr().c_str()); |
| 192 | 234 | ||
| 193 | cmd_buff[1] = Kernel::DeleteDirectoryFromArchive(archive_handle, dir_path); | 235 | cmd_buff[1] = Kernel::DeleteDirectoryFromArchive(archive_handle, dir_path).raw; |
| 194 | 236 | ||
| 195 | DEBUG_LOG(KERNEL, "called"); | 237 | DEBUG_LOG(KERNEL, "called"); |
| 196 | } | 238 | } |
| @@ -220,11 +262,53 @@ static void CreateDirectory(Service::Interface* self) { | |||
| 220 | 262 | ||
| 221 | DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); | 263 | DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); |
| 222 | 264 | ||
| 223 | cmd_buff[1] = Kernel::CreateDirectoryFromArchive(archive_handle, dir_path); | 265 | cmd_buff[1] = Kernel::CreateDirectoryFromArchive(archive_handle, dir_path).raw; |
| 224 | 266 | ||
| 225 | DEBUG_LOG(KERNEL, "called"); | 267 | DEBUG_LOG(KERNEL, "called"); |
| 226 | } | 268 | } |
| 227 | 269 | ||
| 270 | /* | ||
| 271 | * FS_User::RenameDirectory service function | ||
| 272 | * Inputs: | ||
| 273 | * 2 : Source archive handle lower word | ||
| 274 | * 3 : Source archive handle upper word | ||
| 275 | * 4 : Source dir path type | ||
| 276 | * 5 : Source dir path size | ||
| 277 | * 6 : Dest archive handle lower word | ||
| 278 | * 7 : Dest archive handle upper word | ||
| 279 | * 8 : Dest dir path type | ||
| 280 | * 9 : Dest dir path size | ||
| 281 | * 11: Source dir path string data | ||
| 282 | * 13: Dest dir path string | ||
| 283 | * Outputs: | ||
| 284 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 285 | */ | ||
| 286 | void RenameDirectory(Service::Interface* self) { | ||
| 287 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 288 | |||
| 289 | // TODO(Link Mauve): cmd_buff[2] and cmd_buff[6], aka archive handle lower word, aren't used according to | ||
| 290 | // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. | ||
| 291 | Handle src_archive_handle = static_cast<Handle>(cmd_buff[3]); | ||
| 292 | auto src_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); | ||
| 293 | u32 src_dirname_size = cmd_buff[5]; | ||
| 294 | Handle dest_archive_handle = static_cast<Handle>(cmd_buff[7]); | ||
| 295 | auto dest_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[8]); | ||
| 296 | u32 dest_dirname_size = cmd_buff[9]; | ||
| 297 | u32 src_dirname_ptr = cmd_buff[11]; | ||
| 298 | u32 dest_dirname_ptr = cmd_buff[13]; | ||
| 299 | |||
| 300 | FileSys::Path src_dir_path(src_dirname_type, src_dirname_size, src_dirname_ptr); | ||
| 301 | FileSys::Path dest_dir_path(dest_dirname_type, dest_dirname_size, dest_dirname_ptr); | ||
| 302 | |||
| 303 | DEBUG_LOG(KERNEL, "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s", | ||
| 304 | src_dirname_type, src_dirname_size, src_dir_path.DebugStr().c_str(), | ||
| 305 | dest_dirname_type, dest_dirname_size, dest_dir_path.DebugStr().c_str()); | ||
| 306 | |||
| 307 | cmd_buff[1] = Kernel::RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, dest_archive_handle, dest_dir_path).raw; | ||
| 308 | |||
| 309 | DEBUG_LOG(KERNEL, "called"); | ||
| 310 | } | ||
| 311 | |||
| 228 | static void OpenDirectory(Service::Interface* self) { | 312 | static void OpenDirectory(Service::Interface* self) { |
| 229 | u32* cmd_buff = Service::GetCommandBuffer(); | 313 | u32* cmd_buff = Service::GetCommandBuffer(); |
| 230 | 314 | ||
| @@ -314,12 +398,12 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 314 | {0x080201C2, OpenFile, "OpenFile"}, | 398 | {0x080201C2, OpenFile, "OpenFile"}, |
| 315 | {0x08030204, OpenFileDirectly, "OpenFileDirectly"}, | 399 | {0x08030204, OpenFileDirectly, "OpenFileDirectly"}, |
| 316 | {0x08040142, DeleteFile, "DeleteFile"}, | 400 | {0x08040142, DeleteFile, "DeleteFile"}, |
| 317 | {0x08050244, nullptr, "RenameFile"}, | 401 | {0x08050244, RenameFile, "RenameFile"}, |
| 318 | {0x08060142, DeleteDirectory, "DeleteDirectory"}, | 402 | {0x08060142, DeleteDirectory, "DeleteDirectory"}, |
| 319 | {0x08070142, nullptr, "DeleteDirectoryRecursively"}, | 403 | {0x08070142, nullptr, "DeleteDirectoryRecursively"}, |
| 320 | {0x08080202, nullptr, "CreateFile"}, | 404 | {0x08080202, nullptr, "CreateFile"}, |
| 321 | {0x08090182, CreateDirectory, "CreateDirectory"}, | 405 | {0x08090182, CreateDirectory, "CreateDirectory"}, |
| 322 | {0x080A0244, nullptr, "RenameDirectory"}, | 406 | {0x080A0244, RenameDirectory, "RenameDirectory"}, |
| 323 | {0x080B0102, OpenDirectory, "OpenDirectory"}, | 407 | {0x080B0102, OpenDirectory, "OpenDirectory"}, |
| 324 | {0x080C00C2, OpenArchive, "OpenArchive"}, | 408 | {0x080C00C2, OpenArchive, "OpenArchive"}, |
| 325 | {0x080D0144, nullptr, "ControlArchive"}, | 409 | {0x080D0144, nullptr, "ControlArchive"}, |
diff --git a/src/core/hle/service/hid_user.cpp b/src/core/hle/service/hid_user.cpp index d29de1a52..2abaf0f2f 100644 --- a/src/core/hle/service/hid_user.cpp +++ b/src/core/hle/service/hid_user.cpp | |||
| @@ -55,7 +55,7 @@ static void UpdateNextCirclePadState() { | |||
| 55 | /** | 55 | /** |
| 56 | * Sets a Pad state (button or button combo) as pressed | 56 | * Sets a Pad state (button or button combo) as pressed |
| 57 | */ | 57 | */ |
| 58 | void PadButtonPress(PadState pad_state) { | 58 | void PadButtonPress(const PadState& pad_state) { |
| 59 | next_state.hex |= pad_state.hex; | 59 | next_state.hex |= pad_state.hex; |
| 60 | UpdateNextCirclePadState(); | 60 | UpdateNextCirclePadState(); |
| 61 | } | 61 | } |
| @@ -63,7 +63,7 @@ void PadButtonPress(PadState pad_state) { | |||
| 63 | /** | 63 | /** |
| 64 | * Sets a Pad state (button or button combo) as released | 64 | * Sets a Pad state (button or button combo) as released |
| 65 | */ | 65 | */ |
| 66 | void PadButtonRelease(PadState pad_state) { | 66 | void PadButtonRelease(const PadState& pad_state) { |
| 67 | next_state.hex &= ~pad_state.hex; | 67 | next_state.hex &= ~pad_state.hex; |
| 68 | UpdateNextCirclePadState(); | 68 | UpdateNextCirclePadState(); |
| 69 | } | 69 | } |
diff --git a/src/core/hle/service/hid_user.h b/src/core/hle/service/hid_user.h index 5ed97085d..8f53befdb 100644 --- a/src/core/hle/service/hid_user.h +++ b/src/core/hle/service/hid_user.h | |||
| @@ -93,8 +93,8 @@ const PadState PAD_CIRCLE_UP = {{1u << 30}}; | |||
| 93 | const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; | 93 | const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; |
| 94 | 94 | ||
| 95 | // Methods for updating the HID module's state | 95 | // Methods for updating the HID module's state |
| 96 | void PadButtonPress(PadState pad_state); | 96 | void PadButtonPress(const PadState& pad_state); |
| 97 | void PadButtonRelease(PadState pad_state); | 97 | void PadButtonRelease(const PadState& pad_state); |
| 98 | void PadUpdateComplete(); | 98 | void PadUpdateComplete(); |
| 99 | 99 | ||
| 100 | /** | 100 | /** |
diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index d9122dbbc..941df467b 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp | |||
| @@ -11,15 +11,101 @@ | |||
| 11 | 11 | ||
| 12 | namespace PTM_U { | 12 | namespace PTM_U { |
| 13 | 13 | ||
| 14 | /// Charge levels used by PTM functions | ||
| 15 | enum class ChargeLevels : u32 { | ||
| 16 | CriticalBattery = 1, | ||
| 17 | LowBattery = 2, | ||
| 18 | HalfFull = 3, | ||
| 19 | MostlyFull = 4, | ||
| 20 | CompletelyFull = 5, | ||
| 21 | }; | ||
| 22 | |||
| 23 | static bool shell_open = true; | ||
| 24 | |||
| 25 | static bool battery_is_charging = true; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * It is unknown if GetAdapterState is the same as GetBatteryChargeState, | ||
| 29 | * it is likely to just be a duplicate function of GetBatteryChargeState | ||
| 30 | * that controls another part of the HW. | ||
| 31 | * PTM_U::GetAdapterState service function | ||
| 32 | * Outputs: | ||
| 33 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 34 | * 2 : Output of function, 0 = not charging, 1 = charging. | ||
| 35 | */ | ||
| 36 | static void GetAdapterState(Service::Interface* self) { | ||
| 37 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 38 | |||
| 39 | // TODO(purpasmart96): This function is only a stub, | ||
| 40 | // it returns a valid result without implementing full functionality. | ||
| 41 | |||
| 42 | cmd_buff[1] = 0; // No error | ||
| 43 | cmd_buff[2] = battery_is_charging ? 1 : 0; | ||
| 44 | |||
| 45 | WARN_LOG(KERNEL, "(STUBBED) called"); | ||
| 46 | } | ||
| 47 | |||
| 48 | /* | ||
| 49 | * PTM_User::GetShellState service function. | ||
| 50 | * Outputs: | ||
| 51 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 52 | * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0) | ||
| 53 | */ | ||
| 54 | static void GetShellState(Service::Interface* self) { | ||
| 55 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 56 | |||
| 57 | cmd_buff[1] = 0; | ||
| 58 | cmd_buff[2] = shell_open ? 1 : 0; | ||
| 59 | |||
| 60 | DEBUG_LOG(KERNEL, "PTM_U::GetShellState called"); | ||
| 61 | } | ||
| 62 | |||
| 63 | /** | ||
| 64 | * PTM_U::GetBatteryLevel service function | ||
| 65 | * Outputs: | ||
| 66 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 67 | * 2 : Battery level, 5 = completely full battery, 4 = mostly full battery, | ||
| 68 | * 3 = half full battery, 2 = low battery, 1 = critical battery. | ||
| 69 | */ | ||
| 70 | static void GetBatteryLevel(Service::Interface* self) { | ||
| 71 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 72 | |||
| 73 | // TODO(purpasmart96): This function is only a stub, | ||
| 74 | // it returns a valid result without implementing full functionality. | ||
| 75 | |||
| 76 | cmd_buff[1] = 0; // No error | ||
| 77 | cmd_buff[2] = static_cast<u32>(ChargeLevels::CompletelyFull); // Set to a completely full battery | ||
| 78 | |||
| 79 | WARN_LOG(KERNEL, "(STUBBED) called"); | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * PTM_U::GetBatteryChargeState service function | ||
| 84 | * Outputs: | ||
| 85 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 86 | * 2 : Output of function, 0 = not charging, 1 = charging. | ||
| 87 | */ | ||
| 88 | static void GetBatteryChargeState(Service::Interface* self) { | ||
| 89 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 90 | |||
| 91 | // TODO(purpasmart96): This function is only a stub, | ||
| 92 | // it returns a valid result without implementing full functionality. | ||
| 93 | |||
| 94 | cmd_buff[1] = 0; // No error | ||
| 95 | cmd_buff[2] = battery_is_charging ? 1 : 0; | ||
| 96 | |||
| 97 | WARN_LOG(KERNEL, "(STUBBED) called"); | ||
| 98 | } | ||
| 99 | |||
| 14 | const Interface::FunctionInfo FunctionTable[] = { | 100 | const Interface::FunctionInfo FunctionTable[] = { |
| 15 | {0x00010002, nullptr, "RegisterAlarmClient"}, | 101 | {0x00010002, nullptr, "RegisterAlarmClient"}, |
| 16 | {0x00020080, nullptr, "SetRtcAlarm"}, | 102 | {0x00020080, nullptr, "SetRtcAlarm"}, |
| 17 | {0x00030000, nullptr, "GetRtcAlarm"}, | 103 | {0x00030000, nullptr, "GetRtcAlarm"}, |
| 18 | {0x00040000, nullptr, "CancelRtcAlarm"}, | 104 | {0x00040000, nullptr, "CancelRtcAlarm"}, |
| 19 | {0x00050000, nullptr, "GetAdapterState"}, | 105 | {0x00050000, GetAdapterState, "GetAdapterState"}, |
| 20 | {0x00060000, nullptr, "GetShellState"}, | 106 | {0x00060000, GetShellState, "GetShellState"}, |
| 21 | {0x00070000, nullptr, "GetBatteryLevel"}, | 107 | {0x00070000, GetBatteryLevel, "GetBatteryLevel"}, |
| 22 | {0x00080000, nullptr, "GetBatteryChargeState"}, | 108 | {0x00080000, GetBatteryChargeState, "GetBatteryChargeState"}, |
| 23 | {0x00090000, nullptr, "GetPedometerState"}, | 109 | {0x00090000, nullptr, "GetPedometerState"}, |
| 24 | {0x000A0042, nullptr, "GetStepHistoryEntry"}, | 110 | {0x000A0042, nullptr, "GetStepHistoryEntry"}, |
| 25 | {0x000B00C2, nullptr, "GetStepHistory"}, | 111 | {0x000B00C2, nullptr, "GetStepHistory"}, |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 87d768856..a5805ed05 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 | } |
| @@ -279,10 +281,11 @@ static Result ReleaseMutex(Handle handle) { | |||
| 279 | return res.raw; | 281 | return res.raw; |
| 280 | } | 282 | } |
| 281 | 283 | ||
| 282 | /// Get current thread ID | 284 | /// Get the ID for the specified thread. |
| 283 | static Result GetThreadId(u32* thread_id, Handle thread) { | 285 | static Result GetThreadId(u32* thread_id, Handle handle) { |
| 284 | ERROR_LOG(SVC, "(UNIMPLEMENTED) called thread=0x%08X", thread); | 286 | DEBUG_LOG(SVC, "called thread=0x%08X", handle); |
| 285 | return 0; | 287 | ResultCode result = Kernel::GetThreadId(thread_id, handle); |
| 288 | return result.raw; | ||
| 286 | } | 289 | } |
| 287 | 290 | ||
| 288 | /// Query memory | 291 | /// Query memory |
| @@ -331,6 +334,9 @@ static Result ClearEvent(Handle evt) { | |||
| 331 | /// Sleep the current thread | 334 | /// Sleep the current thread |
| 332 | static void SleepThread(s64 nanoseconds) { | 335 | static void SleepThread(s64 nanoseconds) { |
| 333 | DEBUG_LOG(SVC, "called nanoseconds=%lld", nanoseconds); | 336 | DEBUG_LOG(SVC, "called nanoseconds=%lld", nanoseconds); |
| 337 | |||
| 338 | // Check for next thread to schedule | ||
| 339 | HLE::Reschedule(__func__); | ||
| 334 | } | 340 | } |
| 335 | 341 | ||
| 336 | /// This returns the total CPU ticks elapsed since the CPU was powered-on | 342 | /// This returns the total CPU ticks elapsed since the CPU was powered-on |
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 3ad801c63..af5e1b39b 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp | |||
| @@ -49,7 +49,7 @@ inline void Write(u32 addr, const T data) { | |||
| 49 | 49 | ||
| 50 | // Writes other than u32 are untested, so I'd rather have them abort than silently fail | 50 | // Writes other than u32 are untested, so I'd rather have them abort than silently fail |
| 51 | if (index >= Regs::NumIds() || !std::is_same<T,u32>::value) { | 51 | if (index >= Regs::NumIds() || !std::is_same<T,u32>::value) { |
| 52 | ERROR_LOG(GPU, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr); | 52 | ERROR_LOG(GPU, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr); |
| 53 | return; | 53 | return; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| @@ -140,8 +140,8 @@ inline void Write(u32 addr, const T data) { | |||
| 140 | 140 | ||
| 141 | DEBUG_LOG(GPU, "DisplayTriggerTransfer: 0x%08x bytes from 0x%08x(%ux%u)-> 0x%08x(%ux%u), dst format %x", | 141 | DEBUG_LOG(GPU, "DisplayTriggerTransfer: 0x%08x bytes from 0x%08x(%ux%u)-> 0x%08x(%ux%u), dst format %x", |
| 142 | config.output_height * config.output_width * 4, | 142 | config.output_height * config.output_width * 4, |
| 143 | config.GetPhysicalInputAddress(), config.input_width, config.input_height, | 143 | config.GetPhysicalInputAddress(), (u32)config.input_width, (u32)config.input_height, |
| 144 | config.GetPhysicalOutputAddress(), config.output_width, config.output_height, | 144 | config.GetPhysicalOutputAddress(), (u32)config.output_width, (u32)config.output_height, |
| 145 | config.output_format.Value()); | 145 | config.output_format.Value()); |
| 146 | } | 146 | } |
| 147 | break; | 147 | break; |
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp index 4d0719263..ea001673a 100644 --- a/src/core/hw/hw.cpp +++ b/src/core/hw/hw.cpp | |||
| @@ -68,7 +68,7 @@ inline void Write(u32 addr, const T data) { | |||
| 68 | break; | 68 | break; |
| 69 | 69 | ||
| 70 | default: | 70 | default: |
| 71 | ERROR_LOG(HW, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr); | 71 | ERROR_LOG(HW, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr); |
| 72 | } | 72 | } |
| 73 | } | 73 | } |
| 74 | 74 | ||
diff --git a/src/core/hw/ndma.cpp b/src/core/hw/ndma.cpp index e29a773f1..593e5de30 100644 --- a/src/core/hw/ndma.cpp +++ b/src/core/hw/ndma.cpp | |||
| @@ -15,7 +15,7 @@ inline void Read(T &var, const u32 addr) { | |||
| 15 | 15 | ||
| 16 | template <typename T> | 16 | template <typename T> |
| 17 | inline void Write(u32 addr, const T data) { | 17 | inline void Write(u32 addr, const T data) { |
| 18 | ERROR_LOG(NDMA, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr); | 18 | ERROR_LOG(NDMA, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | // Explicitly instantiate template functions because we aren't defining this in the header: | 21 | // Explicitly instantiate template functions because we aren't defining this in the header: |
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp new file mode 100644 index 000000000..7ef146359 --- /dev/null +++ b/src/core/loader/3dsx.cpp | |||
| @@ -0,0 +1,236 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2+ | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <vector> | ||
| 7 | |||
| 8 | #include "core/file_sys/archive_romfs.h" | ||
| 9 | #include "core/loader/elf.h" | ||
| 10 | #include "core/loader/ncch.h" | ||
| 11 | #include "core/hle/kernel/archive.h" | ||
| 12 | #include "core/mem_map.h" | ||
| 13 | |||
| 14 | #include "3dsx.h" | ||
| 15 | |||
| 16 | |||
| 17 | namespace Loader { | ||
| 18 | |||
| 19 | |||
| 20 | /** | ||
| 21 | * File layout: | ||
| 22 | * - File header | ||
| 23 | * - Code, rodata and data relocation table headers | ||
| 24 | * - Code segment | ||
| 25 | * - Rodata segment | ||
| 26 | * - Loadable (non-BSS) part of the data segment | ||
| 27 | * - Code relocation table | ||
| 28 | * - Rodata relocation table | ||
| 29 | * - Data relocation table | ||
| 30 | * | ||
| 31 | * Memory layout before relocations are applied: | ||
| 32 | * [0..codeSegSize) -> code segment | ||
| 33 | * [codeSegSize..rodataSegSize) -> rodata segment | ||
| 34 | * [rodataSegSize..dataSegSize) -> data segment | ||
| 35 | * | ||
| 36 | * Memory layout after relocations are applied: well, however the loader sets it up :) | ||
| 37 | * The entrypoint is always the start of the code segment. | ||
| 38 | * The BSS section must be cleared manually by the application. | ||
| 39 | */ | ||
| 40 | enum THREEDSX_Error { | ||
| 41 | ERROR_NONE = 0, | ||
| 42 | ERROR_READ = 1, | ||
| 43 | ERROR_FILE = 2, | ||
| 44 | ERROR_ALLOC = 3 | ||
| 45 | }; | ||
| 46 | static const u32 RELOCBUFSIZE = 512; | ||
| 47 | |||
| 48 | // File header | ||
| 49 | static const u32 THREEDSX_MAGIC = 0x58534433; // '3DSX' | ||
| 50 | #pragma pack(1) | ||
| 51 | struct THREEDSX_Header | ||
| 52 | { | ||
| 53 | u32 magic; | ||
| 54 | u16 header_size, reloc_hdr_size; | ||
| 55 | u32 format_ver; | ||
| 56 | u32 flags; | ||
| 57 | |||
| 58 | // Sizes of the code, rodata and data segments + | ||
| 59 | // size of the BSS section (uninitialized latter half of the data segment) | ||
| 60 | u32 code_seg_size, rodata_seg_size, data_seg_size, bss_size; | ||
| 61 | }; | ||
| 62 | |||
| 63 | // Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts. | ||
| 64 | struct THREEDSX_RelocHdr | ||
| 65 | { | ||
| 66 | // # of absolute relocations (that is, fix address to post-relocation memory layout) | ||
| 67 | u32 cross_segment_absolute; | ||
| 68 | // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be patched) | ||
| 69 | u32 cross_segment_relative; | ||
| 70 | // more? | ||
| 71 | |||
| 72 | // Relocations are written in this order: | ||
| 73 | // - Absolute relocations | ||
| 74 | // - Relative relocations | ||
| 75 | }; | ||
| 76 | |||
| 77 | // Relocation entry: from the current pointer, skip X words and patch Y words | ||
| 78 | struct THREEDSX_Reloc | ||
| 79 | { | ||
| 80 | u16 skip, patch; | ||
| 81 | }; | ||
| 82 | #pragma pack() | ||
| 83 | |||
| 84 | struct THREEloadinfo | ||
| 85 | { | ||
| 86 | u8* seg_ptrs[3]; // code, rodata & data | ||
| 87 | u32 seg_addrs[3]; | ||
| 88 | u32 seg_sizes[3]; | ||
| 89 | }; | ||
| 90 | |||
| 91 | class THREEDSXReader { | ||
| 92 | public: | ||
| 93 | static int Load3DSXFile(const std::string& filename, u32 base_addr); | ||
| 94 | }; | ||
| 95 | |||
| 96 | static u32 TranslateAddr(u32 addr, THREEloadinfo *loadinfo, u32* offsets) | ||
| 97 | { | ||
| 98 | if (addr < offsets[0]) | ||
| 99 | return loadinfo->seg_addrs[0] + addr; | ||
| 100 | if (addr < offsets[1]) | ||
| 101 | return loadinfo->seg_addrs[1] + addr - offsets[0]; | ||
| 102 | return loadinfo->seg_addrs[2] + addr - offsets[1]; | ||
| 103 | } | ||
| 104 | |||
| 105 | int THREEDSXReader::Load3DSXFile(const std::string& filename, u32 base_addr) | ||
| 106 | { | ||
| 107 | FileUtil::IOFile file(filename, "rb"); | ||
| 108 | if (!file.IsOpen()) { | ||
| 109 | return ERROR_FILE; | ||
| 110 | } | ||
| 111 | THREEDSX_Header hdr; | ||
| 112 | if (file.ReadBytes(&hdr, sizeof(hdr)) != sizeof(hdr)) | ||
| 113 | return ERROR_READ; | ||
| 114 | |||
| 115 | THREEloadinfo loadinfo; | ||
| 116 | //loadinfo segments must be a multiple of 0x1000 | ||
| 117 | loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) &~0xFFF; | ||
| 118 | loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) &~0xFFF; | ||
| 119 | loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) &~0xFFF; | ||
| 120 | u32 offsets[2] = { loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] }; | ||
| 121 | u32 data_load_size = (hdr.data_seg_size - hdr.bss_size + 0xFFF) &~0xFFF; | ||
| 122 | u32 bss_load_size = loadinfo.seg_sizes[2] - data_load_size; | ||
| 123 | u32 n_reloc_tables = hdr.reloc_hdr_size / 4; | ||
| 124 | std::vector<u8> all_mem(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + loadinfo.seg_sizes[2] + 3 * n_reloc_tables); | ||
| 125 | |||
| 126 | loadinfo.seg_addrs[0] = base_addr; | ||
| 127 | loadinfo.seg_addrs[1] = loadinfo.seg_addrs[0] + loadinfo.seg_sizes[0]; | ||
| 128 | loadinfo.seg_addrs[2] = loadinfo.seg_addrs[1] + loadinfo.seg_sizes[1]; | ||
| 129 | loadinfo.seg_ptrs[0] = &all_mem[0]; | ||
| 130 | loadinfo.seg_ptrs[1] = loadinfo.seg_ptrs[0] + loadinfo.seg_sizes[0]; | ||
| 131 | loadinfo.seg_ptrs[2] = loadinfo.seg_ptrs[1] + loadinfo.seg_sizes[1]; | ||
| 132 | |||
| 133 | // Skip header for future compatibility | ||
| 134 | file.Seek(hdr.header_size, SEEK_SET); | ||
| 135 | |||
| 136 | // Read the relocation headers | ||
| 137 | u32* relocs = (u32*)(loadinfo.seg_ptrs[2] + hdr.data_seg_size); | ||
| 138 | |||
| 139 | for (u32 current_segment = 0; current_segment < 3; current_segment++) { | ||
| 140 | if (file.ReadBytes(&relocs[current_segment*n_reloc_tables], n_reloc_tables * 4) != n_reloc_tables * 4) | ||
| 141 | return ERROR_READ; | ||
| 142 | } | ||
| 143 | |||
| 144 | // Read the segments | ||
| 145 | if (file.ReadBytes(loadinfo.seg_ptrs[0], hdr.code_seg_size) != hdr.code_seg_size) | ||
| 146 | return ERROR_READ; | ||
| 147 | if (file.ReadBytes(loadinfo.seg_ptrs[1], hdr.rodata_seg_size) != hdr.rodata_seg_size) | ||
| 148 | return ERROR_READ; | ||
| 149 | if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) != hdr.data_seg_size - hdr.bss_size) | ||
| 150 | return ERROR_READ; | ||
| 151 | |||
| 152 | // BSS clear | ||
| 153 | memset((char*)loadinfo.seg_ptrs[2] + hdr.data_seg_size - hdr.bss_size, 0, hdr.bss_size); | ||
| 154 | |||
| 155 | // Relocate the segments | ||
| 156 | for (u32 current_segment = 0; current_segment < 3; current_segment++) { | ||
| 157 | for (u32 current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; current_segment_reloc_table++) { | ||
| 158 | u32 n_relocs = relocs[current_segment*n_reloc_tables + current_segment_reloc_table]; | ||
| 159 | if (current_segment_reloc_table >= 2) { | ||
| 160 | // We are not using this table - ignore it because we don't know what it dose | ||
| 161 | file.Seek(n_relocs*sizeof(THREEDSX_Reloc), SEEK_CUR); | ||
| 162 | continue; | ||
| 163 | } | ||
| 164 | static THREEDSX_Reloc reloc_table[RELOCBUFSIZE]; | ||
| 165 | |||
| 166 | u32* pos = (u32*)loadinfo.seg_ptrs[current_segment]; | ||
| 167 | u32* end_pos = pos + (loadinfo.seg_sizes[current_segment] / 4); | ||
| 168 | |||
| 169 | while (n_relocs) { | ||
| 170 | u32 remaining = std::min(RELOCBUFSIZE, n_relocs); | ||
| 171 | n_relocs -= remaining; | ||
| 172 | |||
| 173 | if (file.ReadBytes(reloc_table, remaining*sizeof(THREEDSX_Reloc)) != remaining*sizeof(THREEDSX_Reloc)) | ||
| 174 | return ERROR_READ; | ||
| 175 | |||
| 176 | for (u32 current_inprogress = 0; current_inprogress < remaining && pos < end_pos; current_inprogress++) { | ||
| 177 | DEBUG_LOG(LOADER, "(t=%d,skip=%u,patch=%u)\n", | ||
| 178 | current_segment_reloc_table, (u32)reloc_table[current_inprogress].skip, (u32)reloc_table[current_inprogress].patch); | ||
| 179 | pos += reloc_table[current_inprogress].skip; | ||
| 180 | s32 num_patches = reloc_table[current_inprogress].patch; | ||
| 181 | while (0 < num_patches && pos < end_pos) { | ||
| 182 | u32 in_addr = (char*)pos - (char*)&all_mem[0]; | ||
| 183 | u32 addr = TranslateAddr(*pos, &loadinfo, offsets); | ||
| 184 | DEBUG_LOG(LOADER, "Patching %08X <-- rel(%08X,%d) (%08X)\n", | ||
| 185 | base_addr + in_addr, addr, current_segment_reloc_table, *pos); | ||
| 186 | switch (current_segment_reloc_table) { | ||
| 187 | case 0: *pos = (addr); break; | ||
| 188 | case 1: *pos = (addr - in_addr); break; | ||
| 189 | default: break; //this should never happen | ||
| 190 | } | ||
| 191 | pos++; | ||
| 192 | num_patches--; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | // Write the data | ||
| 200 | memcpy(Memory::GetPointer(base_addr), &all_mem[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + loadinfo.seg_sizes[2]); | ||
| 201 | |||
| 202 | DEBUG_LOG(LOADER, "CODE: %u pages\n", loadinfo.seg_sizes[0] / 0x1000); | ||
| 203 | DEBUG_LOG(LOADER, "RODATA: %u pages\n", loadinfo.seg_sizes[1] / 0x1000); | ||
| 204 | DEBUG_LOG(LOADER, "DATA: %u pages\n", data_load_size / 0x1000); | ||
| 205 | DEBUG_LOG(LOADER, "BSS: %u pages\n", bss_load_size / 0x1000); | ||
| 206 | |||
| 207 | return ERROR_NONE; | ||
| 208 | } | ||
| 209 | |||
| 210 | /// AppLoader_DSX constructor | ||
| 211 | AppLoader_THREEDSX::AppLoader_THREEDSX(const std::string& filename) : filename(filename) { | ||
| 212 | } | ||
| 213 | |||
| 214 | /// AppLoader_DSX destructor | ||
| 215 | AppLoader_THREEDSX::~AppLoader_THREEDSX() { | ||
| 216 | } | ||
| 217 | |||
| 218 | /** | ||
| 219 | * Loads a 3DSX file | ||
| 220 | * @return Success on success, otherwise Error | ||
| 221 | */ | ||
| 222 | ResultStatus AppLoader_THREEDSX::Load() { | ||
| 223 | INFO_LOG(LOADER, "Loading 3DSX file %s...", filename.c_str()); | ||
| 224 | FileUtil::IOFile file(filename, "rb"); | ||
| 225 | if (file.IsOpen()) { | ||
| 226 | |||
| 227 | THREEDSXReader reader; | ||
| 228 | reader.Load3DSXFile(filename, 0x00100000); | ||
| 229 | Kernel::LoadExec(0x00100000); | ||
| 230 | } else { | ||
| 231 | return ResultStatus::Error; | ||
| 232 | } | ||
| 233 | return ResultStatus::Success; | ||
| 234 | } | ||
| 235 | |||
| 236 | } // namespace Loader | ||
diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h new file mode 100644 index 000000000..848d3ef8a --- /dev/null +++ b/src/core/loader/3dsx.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | // Copyright 2014 Dolphin Emulator Project / Citra Emulator Project | ||
| 2 | // Licensed under GPLv2+ | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "core/loader/loader.h" | ||
| 9 | |||
| 10 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 11 | // Loader namespace | ||
| 12 | |||
| 13 | namespace Loader { | ||
| 14 | |||
| 15 | /// Loads an 3DSX file | ||
| 16 | class AppLoader_THREEDSX final : public AppLoader { | ||
| 17 | public: | ||
| 18 | AppLoader_THREEDSX(const std::string& filename); | ||
| 19 | ~AppLoader_THREEDSX() override; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Load the bootable file | ||
| 23 | * @return ResultStatus result of function | ||
| 24 | */ | ||
| 25 | ResultStatus Load() override; | ||
| 26 | |||
| 27 | private: | ||
| 28 | std::string filename; | ||
| 29 | bool is_loaded; | ||
| 30 | }; | ||
| 31 | |||
| 32 | } // namespace Loader | ||
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index a268e021a..174397b05 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | 6 | ||
| 7 | #include "core/file_sys/archive_romfs.h" | 7 | #include "core/file_sys/archive_romfs.h" |
| 8 | #include "core/loader/3dsx.h" | ||
| 8 | #include "core/loader/elf.h" | 9 | #include "core/loader/elf.h" |
| 9 | #include "core/loader/ncch.h" | 10 | #include "core/loader/ncch.h" |
| 10 | #include "core/hle/kernel/archive.h" | 11 | #include "core/hle/kernel/archive.h" |
| @@ -42,6 +43,8 @@ FileType IdentifyFile(const std::string &filename) { | |||
| 42 | return FileType::CCI; | 43 | return FileType::CCI; |
| 43 | } else if (extension == ".bin") { | 44 | } else if (extension == ".bin") { |
| 44 | return FileType::BIN; | 45 | return FileType::BIN; |
| 46 | } else if (extension == ".3dsx") { | ||
| 47 | return FileType::THREEDSX; | ||
| 45 | } | 48 | } |
| 46 | return FileType::Unknown; | 49 | return FileType::Unknown; |
| 47 | } | 50 | } |
| @@ -56,6 +59,10 @@ ResultStatus LoadFile(const std::string& filename) { | |||
| 56 | 59 | ||
| 57 | switch (IdentifyFile(filename)) { | 60 | switch (IdentifyFile(filename)) { |
| 58 | 61 | ||
| 62 | //3DSX file format... | ||
| 63 | case FileType::THREEDSX: | ||
| 64 | return AppLoader_THREEDSX(filename).Load(); | ||
| 65 | |||
| 59 | // Standard ELF file format... | 66 | // Standard ELF file format... |
| 60 | case FileType::ELF: | 67 | case FileType::ELF: |
| 61 | return AppLoader_ELF(filename).Load(); | 68 | return AppLoader_ELF(filename).Load(); |
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 68f843005..0f836d285 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -22,6 +22,7 @@ enum class FileType { | |||
| 22 | CIA, | 22 | CIA, |
| 23 | ELF, | 23 | ELF, |
| 24 | BIN, | 24 | BIN, |
| 25 | THREEDSX, //3DSX | ||
| 25 | }; | 26 | }; |
| 26 | 27 | ||
| 27 | /// Return type for functions in Loader namespace | 28 | /// Return type for functions in Loader namespace |
diff --git a/src/core/mem_map.h b/src/core/mem_map.h index a58c59244..f17afb60d 100644 --- a/src/core/mem_map.h +++ b/src/core/mem_map.h | |||
| @@ -16,10 +16,9 @@ typedef u32 PAddr; ///< Represents a pointer in the physical address space. | |||
| 16 | 16 | ||
| 17 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 17 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 18 | 18 | ||
| 19 | enum { | 19 | enum : u32 { |
| 20 | BOOTROM_SIZE = 0x00010000, ///< Bootrom (super secret code/data @ 0x8000) size | 20 | BOOTROM_SIZE = 0x00010000, ///< Bootrom (super secret code/data @ 0x8000) size |
| 21 | MPCORE_PRIV_SIZE = 0x00002000, ///< MPCore private memory region size | 21 | MPCORE_PRIV_SIZE = 0x00002000, ///< MPCore private memory region size |
| 22 | DSP_SIZE = 0x00080000, ///< DSP memory size | ||
| 23 | AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size | 22 | AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size |
| 24 | 23 | ||
| 25 | FCRAM_SIZE = 0x08000000, ///< FCRAM size | 24 | FCRAM_SIZE = 0x08000000, ///< FCRAM size |
| @@ -27,47 +26,42 @@ enum { | |||
| 27 | FCRAM_PADDR_END = (FCRAM_PADDR + FCRAM_SIZE), ///< FCRAM end of physical space | 26 | FCRAM_PADDR_END = (FCRAM_PADDR + FCRAM_SIZE), ///< FCRAM end of physical space |
| 28 | FCRAM_VADDR = 0x08000000, ///< FCRAM virtual address | 27 | FCRAM_VADDR = 0x08000000, ///< FCRAM virtual address |
| 29 | FCRAM_VADDR_END = (FCRAM_VADDR + FCRAM_SIZE), ///< FCRAM end of virtual space | 28 | FCRAM_VADDR_END = (FCRAM_VADDR + FCRAM_SIZE), ///< FCRAM end of virtual space |
| 30 | FCRAM_MASK = (FCRAM_SIZE - 1), ///< FCRAM mask | ||
| 31 | 29 | ||
| 32 | SHARED_MEMORY_SIZE = 0x04000000, ///< Shared memory size | 30 | SHARED_MEMORY_SIZE = 0x04000000, ///< Shared memory size |
| 33 | SHARED_MEMORY_VADDR = 0x10000000, ///< Shared memory | 31 | SHARED_MEMORY_VADDR = 0x10000000, ///< Shared memory |
| 34 | SHARED_MEMORY_VADDR_END = (SHARED_MEMORY_VADDR + SHARED_MEMORY_SIZE), | 32 | SHARED_MEMORY_VADDR_END = (SHARED_MEMORY_VADDR + SHARED_MEMORY_SIZE), |
| 35 | SHARED_MEMORY_MASK = (SHARED_MEMORY_SIZE - 1), | 33 | |
| 34 | DSP_MEMORY_SIZE = 0x00080000, ///< DSP memory size | ||
| 35 | DSP_MEMORY_VADDR = 0x1FF00000, ///< DSP memory virtual address | ||
| 36 | 36 | ||
| 37 | CONFIG_MEMORY_SIZE = 0x00001000, ///< Configuration memory size | 37 | CONFIG_MEMORY_SIZE = 0x00001000, ///< Configuration memory size |
| 38 | CONFIG_MEMORY_VADDR = 0x1FF80000, ///< Configuration memory virtual address | 38 | CONFIG_MEMORY_VADDR = 0x1FF80000, ///< Configuration memory virtual address |
| 39 | CONFIG_MEMORY_VADDR_END = (CONFIG_MEMORY_VADDR + CONFIG_MEMORY_SIZE), | 39 | CONFIG_MEMORY_VADDR_END = (CONFIG_MEMORY_VADDR + CONFIG_MEMORY_SIZE), |
| 40 | CONFIG_MEMORY_MASK = (CONFIG_MEMORY_SIZE - 1), | ||
| 41 | 40 | ||
| 42 | KERNEL_MEMORY_SIZE = 0x00001000, ///< Kernel memory size | 41 | KERNEL_MEMORY_SIZE = 0x00001000, ///< Kernel memory size |
| 43 | KERNEL_MEMORY_VADDR = 0xFFFF0000, ///< Kernel memory where the kthread objects etc are | 42 | KERNEL_MEMORY_VADDR = 0xFFFF0000, ///< Kernel memory where the kthread objects etc are |
| 44 | KERNEL_MEMORY_VADDR_END = (KERNEL_MEMORY_VADDR + KERNEL_MEMORY_SIZE), | 43 | KERNEL_MEMORY_VADDR_END = (KERNEL_MEMORY_VADDR + KERNEL_MEMORY_SIZE), |
| 45 | KERNEL_MEMORY_MASK = (KERNEL_MEMORY_SIZE - 1), | ||
| 46 | 44 | ||
| 47 | EXEFS_CODE_SIZE = 0x03F00000, | 45 | EXEFS_CODE_SIZE = 0x03F00000, |
| 48 | EXEFS_CODE_VADDR = 0x00100000, ///< ExeFS:/.code is loaded here | 46 | EXEFS_CODE_VADDR = 0x00100000, ///< ExeFS:/.code is loaded here |
| 49 | EXEFS_CODE_VADDR_END = (EXEFS_CODE_VADDR + EXEFS_CODE_SIZE), | 47 | EXEFS_CODE_VADDR_END = (EXEFS_CODE_VADDR + EXEFS_CODE_SIZE), |
| 50 | EXEFS_CODE_MASK = 0x03FFFFFF, | ||
| 51 | 48 | ||
| 52 | // Region of FCRAM used by system | 49 | // Region of FCRAM used by system |
| 53 | SYSTEM_MEMORY_SIZE = 0x02C00000, ///< 44MB | 50 | SYSTEM_MEMORY_SIZE = 0x02C00000, ///< 44MB |
| 54 | SYSTEM_MEMORY_VADDR = 0x04000000, | 51 | SYSTEM_MEMORY_VADDR = 0x04000000, |
| 55 | SYSTEM_MEMORY_VADDR_END = (SYSTEM_MEMORY_VADDR + SYSTEM_MEMORY_SIZE), | 52 | SYSTEM_MEMORY_VADDR_END = (SYSTEM_MEMORY_VADDR + SYSTEM_MEMORY_SIZE), |
| 56 | SYSTEM_MEMORY_MASK = 0x03FFFFFF, | ||
| 57 | 53 | ||
| 58 | HEAP_SIZE = FCRAM_SIZE, ///< Application heap size | 54 | HEAP_SIZE = FCRAM_SIZE, ///< Application heap size |
| 59 | //HEAP_PADDR = HEAP_GSP_SIZE, | 55 | //HEAP_PADDR = HEAP_GSP_SIZE, |
| 60 | //HEAP_PADDR_END = (HEAP_PADDR + HEAP_SIZE), | 56 | //HEAP_PADDR_END = (HEAP_PADDR + HEAP_SIZE), |
| 61 | HEAP_VADDR = 0x08000000, | 57 | HEAP_VADDR = 0x08000000, |
| 62 | HEAP_VADDR_END = (HEAP_VADDR + HEAP_SIZE), | 58 | HEAP_VADDR_END = (HEAP_VADDR + HEAP_SIZE), |
| 63 | HEAP_MASK = (HEAP_SIZE - 1), | ||
| 64 | 59 | ||
| 65 | HEAP_GSP_SIZE = 0x02000000, ///< GSP heap size... TODO: Define correctly? | 60 | HEAP_GSP_SIZE = 0x02000000, ///< GSP heap size... TODO: Define correctly? |
| 66 | HEAP_GSP_VADDR = 0x14000000, | 61 | HEAP_GSP_VADDR = 0x14000000, |
| 67 | HEAP_GSP_VADDR_END = (HEAP_GSP_VADDR + HEAP_GSP_SIZE), | 62 | HEAP_GSP_VADDR_END = (HEAP_GSP_VADDR + HEAP_GSP_SIZE), |
| 68 | HEAP_GSP_PADDR = 0x00000000, | 63 | HEAP_GSP_PADDR = 0x00000000, |
| 69 | HEAP_GSP_PADDR_END = (HEAP_GSP_PADDR + HEAP_GSP_SIZE), | 64 | HEAP_GSP_PADDR_END = (HEAP_GSP_PADDR + HEAP_GSP_SIZE), |
| 70 | HEAP_GSP_MASK = (HEAP_GSP_SIZE - 1), | ||
| 71 | 65 | ||
| 72 | HARDWARE_IO_SIZE = 0x01000000, | 66 | HARDWARE_IO_SIZE = 0x01000000, |
| 73 | HARDWARE_IO_PADDR = 0x10000000, ///< IO physical address start | 67 | HARDWARE_IO_PADDR = 0x10000000, ///< IO physical address start |
| @@ -80,12 +74,10 @@ enum { | |||
| 80 | VRAM_VADDR = 0x1F000000, | 74 | VRAM_VADDR = 0x1F000000, |
| 81 | VRAM_PADDR_END = (VRAM_PADDR + VRAM_SIZE), | 75 | VRAM_PADDR_END = (VRAM_PADDR + VRAM_SIZE), |
| 82 | VRAM_VADDR_END = (VRAM_VADDR + VRAM_SIZE), | 76 | VRAM_VADDR_END = (VRAM_VADDR + VRAM_SIZE), |
| 83 | VRAM_MASK = 0x007FFFFF, | ||
| 84 | 77 | ||
| 85 | SCRATCHPAD_SIZE = 0x00004000, ///< Typical stack size - TODO: Read from exheader | 78 | SCRATCHPAD_SIZE = 0x00004000, ///< Typical stack size - TODO: Read from exheader |
| 86 | SCRATCHPAD_VADDR_END = 0x10000000, | 79 | SCRATCHPAD_VADDR_END = 0x10000000, |
| 87 | SCRATCHPAD_VADDR = (SCRATCHPAD_VADDR_END - SCRATCHPAD_SIZE), ///< Stack space | 80 | SCRATCHPAD_VADDR = (SCRATCHPAD_VADDR_END - SCRATCHPAD_SIZE), ///< Stack space |
| 88 | SCRATCHPAD_MASK = (SCRATCHPAD_SIZE - 1), ///< Scratchpad memory mask | ||
| 89 | }; | 81 | }; |
| 90 | 82 | ||
| 91 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 83 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp index 443d5ad7e..1887bcedb 100644 --- a/src/core/mem_map_funcs.cpp +++ b/src/core/mem_map_funcs.cpp | |||
| @@ -56,7 +56,7 @@ inline void Read(T &var, const VAddr vaddr) { | |||
| 56 | 56 | ||
| 57 | // Kernel memory command buffer | 57 | // Kernel memory command buffer |
| 58 | if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) { | 58 | if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) { |
| 59 | var = *((const T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK]); | 59 | var = *((const T*)&g_kernel_mem[vaddr - KERNEL_MEMORY_VADDR]); |
| 60 | 60 | ||
| 61 | // Hardware I/O register reads | 61 | // Hardware I/O register reads |
| 62 | // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space | 62 | // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space |
| @@ -65,23 +65,23 @@ inline void Read(T &var, const VAddr vaddr) { | |||
| 65 | 65 | ||
| 66 | // ExeFS:/.code is loaded here | 66 | // ExeFS:/.code is loaded here |
| 67 | } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) { | 67 | } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) { |
| 68 | var = *((const T*)&g_exefs_code[vaddr & EXEFS_CODE_MASK]); | 68 | var = *((const T*)&g_exefs_code[vaddr - EXEFS_CODE_VADDR]); |
| 69 | 69 | ||
| 70 | // FCRAM - GSP heap | 70 | // FCRAM - GSP heap |
| 71 | } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { | 71 | } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { |
| 72 | var = *((const T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK]); | 72 | var = *((const T*)&g_heap_gsp[vaddr - HEAP_GSP_VADDR]); |
| 73 | 73 | ||
| 74 | // FCRAM - application heap | 74 | // FCRAM - application heap |
| 75 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { | 75 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { |
| 76 | var = *((const T*)&g_heap[vaddr & HEAP_MASK]); | 76 | var = *((const T*)&g_heap[vaddr - HEAP_VADDR]); |
| 77 | 77 | ||
| 78 | // Shared memory | 78 | // Shared memory |
| 79 | } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { | 79 | } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { |
| 80 | var = *((const T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK]); | 80 | var = *((const T*)&g_shared_mem[vaddr - SHARED_MEMORY_VADDR]); |
| 81 | 81 | ||
| 82 | // System memory | 82 | // System memory |
| 83 | } else if ((vaddr >= SYSTEM_MEMORY_VADDR) && (vaddr < SYSTEM_MEMORY_VADDR_END)) { | 83 | } else if ((vaddr >= SYSTEM_MEMORY_VADDR) && (vaddr < SYSTEM_MEMORY_VADDR_END)) { |
| 84 | var = *((const T*)&g_system_mem[vaddr & SYSTEM_MEMORY_MASK]); | 84 | var = *((const T*)&g_system_mem[vaddr - SYSTEM_MEMORY_VADDR]); |
| 85 | 85 | ||
| 86 | // Config memory | 86 | // Config memory |
| 87 | } else if ((vaddr >= CONFIG_MEMORY_VADDR) && (vaddr < CONFIG_MEMORY_VADDR_END)) { | 87 | } else if ((vaddr >= CONFIG_MEMORY_VADDR) && (vaddr < CONFIG_MEMORY_VADDR_END)) { |
| @@ -89,10 +89,10 @@ inline void Read(T &var, const VAddr vaddr) { | |||
| 89 | 89 | ||
| 90 | // VRAM | 90 | // VRAM |
| 91 | } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { | 91 | } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { |
| 92 | var = *((const T*)&g_vram[vaddr & VRAM_MASK]); | 92 | var = *((const T*)&g_vram[vaddr - VRAM_VADDR]); |
| 93 | 93 | ||
| 94 | } else { | 94 | } else { |
| 95 | ERROR_LOG(MEMMAP, "unknown Read%d @ 0x%08X", sizeof(var) * 8, vaddr); | 95 | ERROR_LOG(MEMMAP, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, vaddr); |
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | 98 | ||
| @@ -101,7 +101,7 @@ inline void Write(const VAddr vaddr, const T data) { | |||
| 101 | 101 | ||
| 102 | // Kernel memory command buffer | 102 | // Kernel memory command buffer |
| 103 | if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) { | 103 | if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) { |
| 104 | *(T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK] = data; | 104 | *(T*)&g_kernel_mem[vaddr - KERNEL_MEMORY_VADDR] = data; |
| 105 | 105 | ||
| 106 | // Hardware I/O register writes | 106 | // Hardware I/O register writes |
| 107 | // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space | 107 | // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space |
| @@ -110,27 +110,27 @@ inline void Write(const VAddr vaddr, const T data) { | |||
| 110 | 110 | ||
| 111 | // ExeFS:/.code is loaded here | 111 | // ExeFS:/.code is loaded here |
| 112 | } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) { | 112 | } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) { |
| 113 | *(T*)&g_exefs_code[vaddr & EXEFS_CODE_MASK] = data; | 113 | *(T*)&g_exefs_code[vaddr - EXEFS_CODE_VADDR] = data; |
| 114 | 114 | ||
| 115 | // FCRAM - GSP heap | 115 | // FCRAM - GSP heap |
| 116 | } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { | 116 | } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { |
| 117 | *(T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK] = data; | 117 | *(T*)&g_heap_gsp[vaddr - HEAP_GSP_VADDR] = data; |
| 118 | 118 | ||
| 119 | // FCRAM - application heap | 119 | // FCRAM - application heap |
| 120 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { | 120 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { |
| 121 | *(T*)&g_heap[vaddr & HEAP_MASK] = data; | 121 | *(T*)&g_heap[vaddr - HEAP_VADDR] = data; |
| 122 | 122 | ||
| 123 | // Shared memory | 123 | // Shared memory |
| 124 | } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { | 124 | } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { |
| 125 | *(T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK] = data; | 125 | *(T*)&g_shared_mem[vaddr - SHARED_MEMORY_VADDR] = data; |
| 126 | 126 | ||
| 127 | // System memory | 127 | // System memory |
| 128 | } else if ((vaddr >= SYSTEM_MEMORY_VADDR) && (vaddr < SYSTEM_MEMORY_VADDR_END)) { | 128 | } else if ((vaddr >= SYSTEM_MEMORY_VADDR) && (vaddr < SYSTEM_MEMORY_VADDR_END)) { |
| 129 | *(T*)&g_system_mem[vaddr & SYSTEM_MEMORY_MASK] = data; | 129 | *(T*)&g_system_mem[vaddr - SYSTEM_MEMORY_VADDR] = data; |
| 130 | 130 | ||
| 131 | // VRAM | 131 | // VRAM |
| 132 | } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { | 132 | } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { |
| 133 | *(T*)&g_vram[vaddr & VRAM_MASK] = data; | 133 | *(T*)&g_vram[vaddr - VRAM_VADDR] = data; |
| 134 | 134 | ||
| 135 | //} else if ((vaddr & 0xFFF00000) == 0x1FF00000) { | 135 | //} else if ((vaddr & 0xFFF00000) == 0x1FF00000) { |
| 136 | // _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory"); | 136 | // _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory"); |
| @@ -141,38 +141,38 @@ inline void Write(const VAddr vaddr, const T data) { | |||
| 141 | 141 | ||
| 142 | // Error out... | 142 | // Error out... |
| 143 | } else { | 143 | } else { |
| 144 | ERROR_LOG(MEMMAP, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, vaddr); | 144 | ERROR_LOG(MEMMAP, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, vaddr); |
| 145 | } | 145 | } |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | u8 *GetPointer(const VAddr vaddr) { | 148 | u8 *GetPointer(const VAddr vaddr) { |
| 149 | // Kernel memory command buffer | 149 | // Kernel memory command buffer |
| 150 | if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) { | 150 | if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) { |
| 151 | return g_kernel_mem + (vaddr & KERNEL_MEMORY_MASK); | 151 | return g_kernel_mem + (vaddr - KERNEL_MEMORY_VADDR); |
| 152 | 152 | ||
| 153 | // ExeFS:/.code is loaded here | 153 | // ExeFS:/.code is loaded here |
| 154 | } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) { | 154 | } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) { |
| 155 | return g_exefs_code + (vaddr & EXEFS_CODE_MASK); | 155 | return g_exefs_code + (vaddr - EXEFS_CODE_VADDR); |
| 156 | 156 | ||
| 157 | // FCRAM - GSP heap | 157 | // FCRAM - GSP heap |
| 158 | } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { | 158 | } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { |
| 159 | return g_heap_gsp + (vaddr & HEAP_GSP_MASK); | 159 | return g_heap_gsp + (vaddr - HEAP_GSP_VADDR); |
| 160 | 160 | ||
| 161 | // FCRAM - application heap | 161 | // FCRAM - application heap |
| 162 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { | 162 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { |
| 163 | return g_heap + (vaddr & HEAP_MASK); | 163 | return g_heap + (vaddr - HEAP_VADDR); |
| 164 | 164 | ||
| 165 | // Shared memory | 165 | // Shared memory |
| 166 | } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { | 166 | } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { |
| 167 | return g_shared_mem + (vaddr & SHARED_MEMORY_MASK); | 167 | return g_shared_mem + (vaddr - SHARED_MEMORY_VADDR); |
| 168 | 168 | ||
| 169 | // System memory | 169 | // System memory |
| 170 | } else if ((vaddr >= SYSTEM_MEMORY_VADDR) && (vaddr < SYSTEM_MEMORY_VADDR_END)) { | 170 | } else if ((vaddr >= SYSTEM_MEMORY_VADDR) && (vaddr < SYSTEM_MEMORY_VADDR_END)) { |
| 171 | return g_system_mem + (vaddr & SYSTEM_MEMORY_MASK); | 171 | return g_system_mem + (vaddr - SYSTEM_MEMORY_VADDR); |
| 172 | 172 | ||
| 173 | // VRAM | 173 | // VRAM |
| 174 | } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { | 174 | } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { |
| 175 | return g_vram + (vaddr & VRAM_MASK); | 175 | return g_vram + (vaddr - VRAM_VADDR); |
| 176 | 176 | ||
| 177 | } else { | 177 | } else { |
| 178 | ERROR_LOG(MEMMAP, "unknown GetPointer @ 0x%08x", vaddr); | 178 | ERROR_LOG(MEMMAP, "unknown GetPointer @ 0x%08x", vaddr); |
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 1ec727698..8a6ba2560 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -60,7 +60,7 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 60 | const u8* load_address = base_address + loader_config.data_offset; | 60 | const u8* load_address = base_address + loader_config.data_offset; |
| 61 | 61 | ||
| 62 | // TODO: What happens if a loader overwrites a previous one's data? | 62 | // TODO: What happens if a loader overwrites a previous one's data? |
| 63 | for (int component = 0; component < loader_config.component_count; ++component) { | 63 | for (unsigned component = 0; component < loader_config.component_count; ++component) { |
| 64 | u32 attribute_index = loader_config.GetComponent(component); | 64 | u32 attribute_index = loader_config.GetComponent(component); |
| 65 | vertex_attribute_sources[attribute_index] = load_address; | 65 | vertex_attribute_sources[attribute_index] = load_address; |
| 66 | vertex_attribute_strides[attribute_index] = static_cast<u32>(loader_config.byte_count); | 66 | vertex_attribute_strides[attribute_index] = static_cast<u32>(loader_config.byte_count); |
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 275b06b7c..8a5f11424 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp | |||
| @@ -155,7 +155,7 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data | |||
| 155 | 155 | ||
| 156 | // This is put into a try-catch block to make sure we notice unknown configurations. | 156 | // This is put into a try-catch block to make sure we notice unknown configurations. |
| 157 | std::vector<OutputRegisterInfo> output_info_table; | 157 | std::vector<OutputRegisterInfo> output_info_table; |
| 158 | for (int i = 0; i < 7; ++i) { | 158 | for (unsigned i = 0; i < 7; ++i) { |
| 159 | using OutputAttributes = Pica::Regs::VSOutputAttributes; | 159 | using OutputAttributes = Pica::Regs::VSOutputAttributes; |
| 160 | 160 | ||
| 161 | // TODO: It's still unclear how the attribute components map to the register! | 161 | // TODO: It's still unclear how the attribute components map to the register! |
| @@ -375,8 +375,8 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { | |||
| 375 | png_write_info(png_ptr, info_ptr); | 375 | png_write_info(png_ptr, info_ptr); |
| 376 | 376 | ||
| 377 | buf = new u8[row_stride * texture_config.height]; | 377 | buf = new u8[row_stride * texture_config.height]; |
| 378 | for (int y = 0; y < texture_config.height; ++y) { | 378 | for (unsigned y = 0; y < texture_config.height; ++y) { |
| 379 | for (int x = 0; x < texture_config.width; ++x) { | 379 | for (unsigned x = 0; x < texture_config.width; ++x) { |
| 380 | // Cf. rasterizer code for an explanation of this algorithm. | 380 | // Cf. rasterizer code for an explanation of this algorithm. |
| 381 | int texel_index_within_tile = 0; | 381 | int texel_index_within_tile = 0; |
| 382 | for (int block_size_index = 0; block_size_index < 3; ++block_size_index) { | 382 | for (int block_size_index = 0; block_size_index < 3; ++block_size_index) { |
| @@ -402,7 +402,7 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { | |||
| 402 | } | 402 | } |
| 403 | 403 | ||
| 404 | // Write image data | 404 | // Write image data |
| 405 | for (auto y = 0; y < texture_config.height; ++y) | 405 | for (unsigned y = 0; y < texture_config.height; ++y) |
| 406 | { | 406 | { |
| 407 | u8* row_ptr = (u8*)buf + y * row_stride; | 407 | u8* row_ptr = (u8*)buf + y * row_stride; |
| 408 | u8* ptr = row_ptr; | 408 | u8* ptr = row_ptr; |
diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index a0eb0418c..fdac9ae1a 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp | |||
| @@ -22,7 +22,7 @@ GLuint LoadShaders(const char* vertex_shader, const char* fragment_shader) { | |||
| 22 | // Compile Vertex Shader | 22 | // Compile Vertex Shader |
| 23 | DEBUG_LOG(GPU, "Compiling vertex shader."); | 23 | DEBUG_LOG(GPU, "Compiling vertex shader."); |
| 24 | 24 | ||
| 25 | glShaderSource(vertex_shader_id, 1, &vertex_shader, NULL); | 25 | glShaderSource(vertex_shader_id, 1, &vertex_shader, nullptr); |
| 26 | glCompileShader(vertex_shader_id); | 26 | glCompileShader(vertex_shader_id); |
| 27 | 27 | ||
| 28 | // Check Vertex Shader | 28 | // Check Vertex Shader |
| @@ -31,14 +31,14 @@ GLuint LoadShaders(const char* vertex_shader, const char* fragment_shader) { | |||
| 31 | 31 | ||
| 32 | if (info_log_length > 1) { | 32 | if (info_log_length > 1) { |
| 33 | std::vector<char> vertex_shader_error(info_log_length); | 33 | std::vector<char> vertex_shader_error(info_log_length); |
| 34 | glGetShaderInfoLog(vertex_shader_id, info_log_length, NULL, &vertex_shader_error[0]); | 34 | glGetShaderInfoLog(vertex_shader_id, info_log_length, nullptr, &vertex_shader_error[0]); |
| 35 | DEBUG_LOG(GPU, "%s", &vertex_shader_error[0]); | 35 | DEBUG_LOG(GPU, "%s", &vertex_shader_error[0]); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | // Compile Fragment Shader | 38 | // Compile Fragment Shader |
| 39 | DEBUG_LOG(GPU, "Compiling fragment shader."); | 39 | DEBUG_LOG(GPU, "Compiling fragment shader."); |
| 40 | 40 | ||
| 41 | glShaderSource(fragment_shader_id, 1, &fragment_shader, NULL); | 41 | glShaderSource(fragment_shader_id, 1, &fragment_shader, nullptr); |
| 42 | glCompileShader(fragment_shader_id); | 42 | glCompileShader(fragment_shader_id); |
| 43 | 43 | ||
| 44 | // Check Fragment Shader | 44 | // Check Fragment Shader |
| @@ -47,7 +47,7 @@ GLuint LoadShaders(const char* vertex_shader, const char* fragment_shader) { | |||
| 47 | 47 | ||
| 48 | if (info_log_length > 1) { | 48 | if (info_log_length > 1) { |
| 49 | std::vector<char> fragment_shader_error(info_log_length); | 49 | std::vector<char> fragment_shader_error(info_log_length); |
| 50 | glGetShaderInfoLog(fragment_shader_id, info_log_length, NULL, &fragment_shader_error[0]); | 50 | glGetShaderInfoLog(fragment_shader_id, info_log_length, nullptr, &fragment_shader_error[0]); |
| 51 | DEBUG_LOG(GPU, "%s", &fragment_shader_error[0]); | 51 | DEBUG_LOG(GPU, "%s", &fragment_shader_error[0]); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| @@ -65,7 +65,7 @@ GLuint LoadShaders(const char* vertex_shader, const char* fragment_shader) { | |||
| 65 | 65 | ||
| 66 | if (info_log_length > 1) { | 66 | if (info_log_length > 1) { |
| 67 | std::vector<char> program_error(info_log_length); | 67 | std::vector<char> program_error(info_log_length); |
| 68 | glGetProgramInfoLog(program_id, info_log_length, NULL, &program_error[0]); | 68 | glGetProgramInfoLog(program_id, info_log_length, nullptr, &program_error[0]); |
| 69 | DEBUG_LOG(GPU, "%s", &program_error[0]); | 69 | DEBUG_LOG(GPU, "%s", &program_error[0]); |
| 70 | } | 70 | } |
| 71 | 71 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index abbb4c2cb..06de6afbd 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -61,7 +61,7 @@ void RendererOpenGL::SwapBuffers() { | |||
| 61 | for(int i : {0, 1}) { | 61 | for(int i : {0, 1}) { |
| 62 | const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; | 62 | const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; |
| 63 | 63 | ||
| 64 | if (textures[i].width != framebuffer.width || textures[i].height != framebuffer.height) { | 64 | if (textures[i].width != (GLsizei)framebuffer.width || textures[i].height != (GLsizei)framebuffer.height) { |
| 65 | // Reallocate texture if the framebuffer size has changed. | 65 | // Reallocate texture if the framebuffer size has changed. |
| 66 | // This is expected to not happen very often and hence should not be a | 66 | // This is expected to not happen very often and hence should not be a |
| 67 | // performance problem. | 67 | // performance problem. |
| @@ -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; |
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index c779771c5..b581ff4da 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp | |||
| @@ -17,8 +17,8 @@ | |||
| 17 | 17 | ||
| 18 | namespace VideoCore { | 18 | namespace VideoCore { |
| 19 | 19 | ||
| 20 | EmuWindow* g_emu_window = NULL; ///< Frontend emulator window | 20 | EmuWindow* g_emu_window = nullptr; ///< Frontend emulator window |
| 21 | RendererBase* g_renderer = NULL; ///< Renderer plugin | 21 | RendererBase* g_renderer = nullptr; ///< Renderer plugin |
| 22 | int g_current_frame = 0; | 22 | int g_current_frame = 0; |
| 23 | 23 | ||
| 24 | /// Initialize the video core | 24 | /// Initialize the video core |