diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 90c14a1ff..0abc831fc 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -223,7 +223,7 @@ public: } if (_last_entry.counter >= 1) { - if (Config::getLogType() == "async") { + if (EmulatorSettings::GetInstance()->GetLogType() == "async") { message_queue.EmplaceWait(_last_entry); } else { ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); }); @@ -283,7 +283,7 @@ private: } if (_last_entry.counter >= 1) { - if (Config::getLogType() == "async") { + if (EmulatorSettings::GetInstance()->GetLogType() == "async") { message_queue.EmplaceWait(_last_entry); } else { ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); }); diff --git a/src/core/devtools/layer.cpp b/src/core/devtools/layer.cpp index 4f7093474..a8f84e199 100644 --- a/src/core/devtools/layer.cpp +++ b/src/core/devtools/layer.cpp @@ -473,7 +473,7 @@ void L::Draw() { if (ImGui::Begin("Volume Window", &show_volume, ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDocking)) { - Text("Volume: %d", Config::getVolumeSlider()); + Text("Volume: %d", EmulatorSettings::GetInstance()->GetVolumeSlider()); } End(); } diff --git a/src/core/libraries/audio/sdl_audio_in.cpp b/src/core/libraries/audio/sdl_audio_in.cpp index d36811175..760c26cec 100644 --- a/src/core/libraries/audio/sdl_audio_in.cpp +++ b/src/core/libraries/audio/sdl_audio_in.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include "audioin.h" #include "audioin_backend.h" @@ -21,7 +21,7 @@ public: fmt.channels = static_cast(port.channels_num); fmt.freq = static_cast(port.freq); - std::string micDevStr = Config::getMicDevice(); + std::string micDevStr = EmulatorSettings::GetInstance()->GetMicDevice(); uint32_t devId = 0; if (micDevStr == "None") { nullDevice = true; diff --git a/src/core/libraries/audio/sdl_audio_out.cpp b/src/core/libraries/audio/sdl_audio_out.cpp index ce2598759..78fd8574e 100644 --- a/src/core/libraries/audio/sdl_audio_out.cpp +++ b/src/core/libraries/audio/sdl_audio_out.cpp @@ -9,7 +9,7 @@ #include #include -#include "common/config.h" +#include "core/emulator_settings.h" #include "common/logging/log.h" #include "core/libraries/audio/audioout.h" #include "core/libraries/audio/audioout_backend.h" @@ -110,7 +110,7 @@ public: max_channel_gain = std::max(max_channel_gain, channel_gain); } - const float slider_gain = Config::getVolumeSlider() * 0.01f; // Faster than /100.0f + const float slider_gain = EmulatorSettings::GetInstance()->GetVolumeSlider() * 0.01f; // Faster than /100.0f const float total_gain = max_channel_gain * slider_gain; const float current = current_gain.load(std::memory_order_acquire); @@ -156,7 +156,7 @@ private: } // Initialize current gain - current_gain.store(Config::getVolumeSlider() * 0.01f, std::memory_order_relaxed); + current_gain.store(EmulatorSettings::GetInstance()->GetVolumeSlider() * 0.01f, std::memory_order_relaxed); if (!SelectConverter()) { FreeAlignedBuffer(); @@ -201,7 +201,7 @@ private: last_volume_check_time = current_time; - const float config_volume = Config::getVolumeSlider() * 0.01f; + const float config_volume = EmulatorSettings::GetInstance()->GetVolumeSlider() * 0.01f; const float stored_gain = current_gain.load(std::memory_order_acquire); // Only update if the difference is significant @@ -368,11 +368,11 @@ private: switch (type) { case OrbisAudioOutPort::Main: case OrbisAudioOutPort::Bgm: - return Config::getMainOutputDevice(); + return EmulatorSettings::GetInstance()->GetMainOutputDevice(); case OrbisAudioOutPort::PadSpk: - return Config::getPadSpkOutputDevice(); + return EmulatorSettings::GetInstance()->GetPadSpkOutputDevice(); default: - return Config::getMainOutputDevice(); + return EmulatorSettings::GetInstance()->GetMainOutputDevice(); } } diff --git a/src/core/libraries/np/np_matching2.cpp b/src/core/libraries/np/np_matching2.cpp index 423b84257..1d65dbe32 100644 --- a/src/core/libraries/np/np_matching2.cpp +++ b/src/core/libraries/np/np_matching2.cpp @@ -6,6 +6,7 @@ #include "common/config.h" #include "common/logging/log.h" +#include "core/emulator_settings.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/np/np_manager.h" @@ -376,7 +377,8 @@ int PS4_SYSV_ABI sceNpMatching2ContextStart(OrbisNpMatching2ContextId ctxId, u64 } std::scoped_lock lk{g_events_mutex}; - if (Config::getIsConnectedToNetwork() && Config::getPSNSignedIn()) { + if (EmulatorSettings::GetInstance()->IsConnectedToNetwork() && + EmulatorSettings::GetInstance()->IsPSNSignedIn()) { g_ctx_events.emplace_back(ctxId, ORBIS_NP_MATCHING2_CONTEXT_EVENT_STARTED, ORBIS_NP_MATCHING2_EVENT_CAUSE_CONTEXT_ACTION, 0); } else { diff --git a/src/core/libraries/np/np_web_api2.cpp b/src/core/libraries/np/np_web_api2.cpp index c03636e73..1c7088044 100644 --- a/src/core/libraries/np/np_web_api2.cpp +++ b/src/core/libraries/np/np_web_api2.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/config.h" +#include "core/emulator_settings.h" #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" @@ -207,7 +207,7 @@ s32 PS4_SYSV_ABI sceNpWebApi2SendMultipartRequest() { } s32 PS4_SYSV_ABI sceNpWebApi2SendRequest() { - if (!Config::getPSNSignedIn()) { + if (!EmulatorSettings::GetInstance()->IsPSNSignedIn()) { LOG_INFO(Lib_NpWebApi2, "called, returning PSN signed out."); return ORBIS_NP_WEBAPI2_ERROR_NOT_SIGNED_IN; } diff --git a/src/core/libraries/np/np_web_api_internal.cpp b/src/core/libraries/np/np_web_api_internal.cpp index 3d6c7de86..838ba005f 100644 --- a/src/core/libraries/np/np_web_api_internal.cpp +++ b/src/core/libraries/np/np_web_api_internal.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/config.h" +#include "core/emulator_settings.h" #include "common/elf_info.h" #include "core/libraries/kernel/process.h" #include "core/libraries/kernel/time.h" @@ -606,7 +606,7 @@ s32 sendRequest(s64 requestId, s32 partIndex, const void* pData, u64 dataSize, s unlockContext(context); // Stubbing sceNpManagerIntGetSigninState call with a config check. - if (!Config::getPSNSignedIn()) { + if (!EmulatorSettings::GetInstance()->IsPSNSignedIn()) { releaseRequest(request); releaseUserContext(user_context); releaseContext(context); @@ -1025,7 +1025,7 @@ s32 createServicePushEventFilterInternal( auto& handle = context->handles[handleId]; handle->userCount++; - if (pNpServiceName != nullptr && !Config::getPSNSignedIn()) { + if (pNpServiceName != nullptr && !EmulatorSettings::GetInstance()->IsPSNSignedIn()) { // Seems sceNpManagerIntGetUserList fails? LOG_DEBUG(Lib_NpWebApi, "Cannot create service push event while PSN is disabled"); handle->userCount--; @@ -1202,7 +1202,7 @@ s32 createExtendedPushEventFilterInternal( auto& handle = context->handles[handleId]; handle->userCount++; - if (pNpServiceName != nullptr && !Config::getPSNSignedIn()) { + if (pNpServiceName != nullptr && !EmulatorSettings::GetInstance()->IsPSNSignedIn()) { // Seems sceNpManagerIntGetUserList fails? LOG_DEBUG(Lib_NpWebApi, "Cannot create extended push event while PSN is disabled"); handle->userCount--; diff --git a/src/core/libraries/pad/pad.cpp b/src/core/libraries/pad/pad.cpp index c61ef26a0..4b1e8d876 100644 --- a/src/core/libraries/pad/pad.cpp +++ b/src/core/libraries/pad/pad.cpp @@ -437,10 +437,6 @@ int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) { if (!controller_id) { return ORBIS_PAD_ERROR_INVALID_HANDLE; } - auto controller_id = GamepadSelect::GetControllerIndexFromUserID(handle); - if (!controller_id) { - return ORBIS_PAD_ERROR_INVALID_HANDLE; - } auto controllers = *Common::Singleton::Instance(); auto& controller = *controllers[*controller_id]; int connected_count = 0; diff --git a/src/core/module.h b/src/core/module.h index 778344e33..47177f382 100644 --- a/src/core/module.h +++ b/src/core/module.h @@ -5,7 +5,7 @@ #include #include -#include "common/config.h" +#include "core/emulator_settings.h" #include "common/types.h" #include "core/loader/elf.h" #include "core/loader/symbols_resolver.h" @@ -166,7 +166,7 @@ public: } bool IsSystemLib() { - auto system_path = Config::getSysModulesPath(); + auto system_path = EmulatorSettings::GetInstance()->GetSysModulesDir(); if (file.string().starts_with(system_path.string().c_str())) { return true; } diff --git a/src/input/controller.cpp b/src/input/controller.cpp index 70fbf766a..ba1df5508 100644 --- a/src/input/controller.cpp +++ b/src/input/controller.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project +// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -103,16 +103,26 @@ void GameController::Axis(int id, Input::Axis axis, int value) { PushState(); } -void GameController::Gyro(int id, const float gyro[3]) { - m_state.OnGyro(gyro); +void GameController::Gyro(int id) { + m_state.OnGyro(gyro_buf); PushState(); } -void GameController::Acceleration(int id, const float acceleration[3]) { - m_state.OnAccel(acceleration); +void GameController::Acceleration(int id) { + m_state.OnAccel(accel_buf); PushState(); } +void GameController::UpdateGyro(int id, const float gyro[3]) { + std::lock_guard lg(m_states_queue_mutex); + std::memcpy(gyro_buf, gyro, sizeof(gyro)); +} + +void GameController::UpdateAcceleration(int id, const float acceleration[3]) { + std::lock_guard lg(m_states_queue_mutex); + std::memcpy(accel_buf, acceleration, sizeof(acceleration)); +} + void GameController::CalculateOrientation(Libraries::Pad::OrbisFVector3& acceleration, Libraries::Pad::OrbisFVector3& angularVelocity, float deltaTime, @@ -310,14 +320,6 @@ void GameController::PushState() { m_states_queue.Push(m_state); } -u32 GameController::Poll() { - std::scoped_lock lock{m_mutex}; - if (m_connected) { - PushState(); - } - return 33; -} - u8 GameControllers::GetGamepadIndexFromJoystickId(SDL_JoystickID id) { s32 index = SDL_GetGamepadPlayerIndex(SDL_GetGamepadFromID(id)); LOG_TRACE(Input, "Gamepad index: {}", index); diff --git a/src/input/controller.h b/src/input/controller.h index 26bb87b11..f22091d98 100644 --- a/src/input/controller.h +++ b/src/input/controller.h @@ -35,11 +35,17 @@ struct TouchpadEntry { }; struct State { + void OnButton(Libraries::Pad::OrbisPadButtonDataOffset, bool); + void OnAxis(Axis, int); + void OnTouchpad(int touchIndex, bool isDown, float x, float y); + void OnGyro(const float[3]); + void OnAccel(const float[3]); + Libraries::Pad::OrbisPadButtonDataOffset buttonsState{}; u64 time = 0; int axes[static_cast(Axis::AxisMax)] = {128, 128, 128, 128, 0, 0}; TouchpadEntry touchpad[2] = {{false, 0, 0}, {false, 0, 0}}; - Libraries::Pad::OrbisFVector3 acceleration = {0.0f, 0.0f, 0.0f}; + Libraries::Pad::OrbisFVector3 acceleration = {0.0f, -9.81f, 0.0f}; Libraries::Pad::OrbisFVector3 angularVelocity = {0.0f, 0.0f, 0.0f}; Libraries::Pad::OrbisFQuaternion orientation = {0.0f, 0.0f, 0.0f, 1.0f}; }; @@ -92,12 +98,13 @@ public: void Button(int id, Libraries::Pad::OrbisPadButtonDataOffset button, bool isPressed); void Axis(int id, Input::Axis axis, int value); - void Gyro(int id, const float gyro[3]); - void Acceleration(int id, const float acceleration[3]); + void Gyro(int id); + void Acceleration(int id); + void UpdateGyro(int id, const float gyro[3]); + void UpdateAcceleration(int id, const float acceleration[3]); void SetLightBarRGB(u8 r, u8 g, u8 b); bool SetVibration(u8 smallMotor, u8 largeMotor); void SetTouchpadState(int touchIndex, bool touchDown, float x, float y); - u32 Poll(); u8 GetTouchCount(); void SetTouchCount(u8 touchCount); @@ -120,6 +127,7 @@ public: float gyro_poll_rate; float accel_poll_rate; + float gyro_buf[3] = {0.0f, 0.0f, 0.0f}, accel_buf[3] = {0.0f, -9.81f, 0.0f}; u32 user_id = -1; // ORBIS_USER_SERVICE_USER_ID_INVALID SDL_Gamepad* m_sdl_gamepad = nullptr; static constexpr int max_smoothing_ticks = 2; diff --git a/src/input/input_handler.cpp b/src/input/input_handler.cpp index 195475b15..2dbfdb6a5 100644 --- a/src/input/input_handler.cpp +++ b/src/input/input_handler.cpp @@ -24,6 +24,7 @@ #include "common/path_util.h" #include "common/singleton.h" #include "core/devtools/layer.h" +#include "core/emulator_settings.h" #include "core/emulator_state.h" #include "input/controller.h" #include "input/input_mouse.h" @@ -391,11 +392,15 @@ void ParseInputConfig(const std::string game_id = "") { if (button_it != string_to_cbutton_map.end()) { // todo add new shit here connection = BindingConnection( - binding, &*std::ranges::find(output_arrays[std::clamp(output_gamepad_id - 1, 0, 3)].data, ControllerOutput(button_it->second))); + binding, + &*std::ranges::find(output_arrays[std::clamp(output_gamepad_id - 1, 0, 3)].data, + ControllerOutput(button_it->second))); connections.insert(connections.end(), connection); } else if (hotkey_it != string_to_hotkey_map.end()) { connection = BindingConnection( - binding, &*std::ranges::find(output_arrays[std::clamp(output_gamepad_id - 1, 0, 3)].data, ControllerOutput(hotkey_it->second))); + binding, + &*std::ranges::find(output_arrays[std::clamp(output_gamepad_id - 1, 0, 3)].data, + ControllerOutput(hotkey_it->second))); connections.insert(connections.end(), connection); } else if (axis_it != string_to_axis_map.end()) { // todo add new shit here @@ -612,13 +617,13 @@ void ControllerOutput::FinalizeUpdate(u8 gamepad_index) { case HOTKEY_REMOVE_VIRTUAL_USER: PushSDLEvent(SDL_EVENT_REMOVE_VIRTUAL_USER); case HOTKEY_VOLUME_UP: - Config::setVolumeSlider(std::clamp(Config::getVolumeSlider() + 10, 0, 500), - is_game_specific); + EmulatorSettings::GetInstance()->SetVolumeSlider( + std::clamp(EmulatorSettings::GetInstance()->GetVolumeSlider() + 10, 0, 500)); Overlay::ShowVolume(); break; case HOTKEY_VOLUME_DOWN: - Config::setVolumeSlider(std::clamp(Config::getVolumeSlider() - 10, 0, 500), - is_game_specific); + EmulatorSettings::GetInstance()->SetVolumeSlider( + std::clamp(EmulatorSettings::GetInstance()->GetVolumeSlider() - 10, 0, 500)); Overlay::ShowVolume(); break; case HOTKEY_QUIT: @@ -662,14 +667,12 @@ void ControllerOutput::FinalizeUpdate(u8 gamepad_index) { case Axis::TriggerLeft: ApplyDeadzone(new_param, lefttrigger_deadzone); controllers[gamepad_index]->Axis(0, c_axis, GetAxis(0x0, 0x7f, *new_param)); - controllers[gamepad_index]->Button(0, OrbisPadButtonDataOffset::L2, - *new_param > 0x20); + controllers[gamepad_index]->Button(0, OrbisPadButtonDataOffset::L2, *new_param > 0x20); return; case Axis::TriggerRight: ApplyDeadzone(new_param, righttrigger_deadzone); controllers[gamepad_index]->Axis(0, c_axis, GetAxis(0x0, 0x7f, *new_param)); - controllers[gamepad_index]->Button(0, OrbisPadButtonDataOffset::R2, - *new_param > 0x20); + controllers[gamepad_index]->Button(0, OrbisPadButtonDataOffset::R2, *new_param > 0x20); return; default: break; diff --git a/src/input/input_handler.h b/src/input/input_handler.h index 81ef90053..1218d2b2a 100644 --- a/src/input/input_handler.h +++ b/src/input/input_handler.h @@ -527,7 +527,7 @@ public: class ControllerAllOutputs { public: - static constexpr u64 output_count = 38; + static constexpr u64 output_count = 40; std::array data = { // Important: these have to be the first, or else they will update in the wrong order ControllerOutput(LEFTJOYSTICK_HALFMODE), @@ -577,6 +577,8 @@ public: ControllerOutput(HOTKEY_RENDERDOC), ControllerOutput(HOTKEY_ADD_VIRTUAL_USER), ControllerOutput(HOTKEY_REMOVE_VIRTUAL_USER), + ControllerOutput(HOTKEY_VOLUME_UP), + ControllerOutput(HOTKEY_VOLUME_DOWN), ControllerOutput(SDL_GAMEPAD_BUTTON_INVALID, SDL_GAMEPAD_AXIS_INVALID), }; diff --git a/src/input/input_mouse.cpp b/src/input/input_mouse.cpp index 0dc44608b..115f705fb 100644 --- a/src/input/input_mouse.cpp +++ b/src/input/input_mouse.cpp @@ -85,17 +85,17 @@ void EmulateJoystick(GameController* controller, u32 interval) { } } -constexpr float constant_down_accel[3] = {0.0f, 10.0f, 0.0f}; +constexpr float constant_down_accel[3] = {0.0f, -9.81, 0.0f}; void EmulateGyro(GameController* controller, u32 interval) { float d_x = 0, d_y = 0; SDL_GetRelativeMouseState(&d_x, &d_y); - controller->Acceleration(1, constant_down_accel); + controller->UpdateAcceleration(1, constant_down_accel); float gyro_from_mouse[3] = {-d_y / 100, -d_x / 100, 0.0f}; if (mouse_gyro_roll_mode) { gyro_from_mouse[1] = 0.0f; gyro_from_mouse[2] = -d_x / 100; } - controller->Gyro(1, gyro_from_mouse); + controller->UpdateGyro(1, gyro_from_mouse); } void EmulateTouchpad(GameController* controller, u32 interval) { diff --git a/src/main.cpp b/src/main.cpp index cf44139cf..09f8cea95 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -126,14 +126,14 @@ int main(int argc, char* argv[]) { // ---- Utility commands ---- if (addGameFolder) { - Config::addGameInstallDir(*addGameFolder); + EmulatorSettings::GetInstance()->AddGameInstallDir(*addGameFolder); Config::save(user_dir / "config.toml"); std::cout << "Game folder successfully saved.\n"; return 0; } if (setAddonFolder) { - Config::setAddonInstallDir(*setAddonFolder); + EmulatorSettings::GetInstance()->SetAddonInstallDir(*setAddonFolder); Config::save(user_dir / "config.toml"); std::cout << "Addon folder successfully saved.\n"; return 0; @@ -158,9 +158,9 @@ int main(int argc, char* argv[]) { if (fullscreenStr) { if (*fullscreenStr == "true") { - Config::setIsFullscreen(true); + EmulatorSettings::GetInstance()->SetFullScreen(true); } else if (*fullscreenStr == "false") { - Config::setIsFullscreen(false); + EmulatorSettings::GetInstance()->SetFullScreen(false); } else { std::cerr << "Error: Invalid argument for --fullscreen (use true|false)\n"; return 1; @@ -168,9 +168,9 @@ int main(int argc, char* argv[]) { } if (showFps) - Config::setShowFpsCounter(true); + EmulatorSettings::GetInstance()->SetShowFpsCounter(true); - if (configClean) + if (configClean) // TODO Config::setConfigMode(Config::ConfigMode::Clean); if (configGlobal) @@ -184,7 +184,7 @@ int main(int argc, char* argv[]) { if (!std::filesystem::exists(ebootPath)) { bool found = false; constexpr int maxDepth = 5; - for (const auto& installDir : Config::getGameInstallDirs()) { + for (const auto& installDir : EmulatorSettings::GetInstance()->GetGameInstallDirs()) { if (auto foundPath = Common::FS::FindGameByID(installDir, *gamePath, maxDepth)) { ebootPath = *foundPath; found = true;