mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-07-11 01:24:28 +02:00
Reset controller colours on emulator shutdown (#4537)
* Reset controller colours on emulator shutdown * bruh moment * Don't use the destructor for this * clang, formatter of night * forgot to stage this file * ffs * fix tests * fixed tests? * gcn tests fixed? * now? * possible fixed --------- Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "common/arch.h"
|
||||
#include "common/assert.h"
|
||||
#include "emulator.h"
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
#define Crash() __asm__ __volatile__("int $3")
|
||||
@@ -13,13 +14,12 @@
|
||||
#endif
|
||||
|
||||
void assert_fail_impl() {
|
||||
Common::Log::Flush();
|
||||
Common::Singleton<Core::Emulator>::Instance()->Shutdown();
|
||||
Crash();
|
||||
}
|
||||
|
||||
[[noreturn]] void unreachable_impl() {
|
||||
Common::Log::Flush();
|
||||
Crash();
|
||||
assert_fail_impl();
|
||||
throw std::runtime_error("Unreachable code");
|
||||
}
|
||||
|
||||
|
||||
@@ -548,7 +548,7 @@ int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelDebugRaiseException(s32 error, s64 unk) {
|
||||
s32 PS4_SYSV_ABI sceKernelDebugRaiseException(u32 error, s64 unk) {
|
||||
if (unk != 0) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
@@ -556,7 +556,7 @@ s32 PS4_SYSV_ABI sceKernelDebugRaiseException(s32 error, s64 unk) {
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelDebugRaiseExceptionOnReleaseMode(s32 error, s64 unk) {
|
||||
s32 PS4_SYSV_ABI sceKernelDebugRaiseExceptionOnReleaseMode(u32 error, s64 unk) {
|
||||
if (unk != 0) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
@@ -556,18 +556,12 @@ int PS4_SYSV_ABI scePadResetLightBar(s32 handle) {
|
||||
s32 colour_index = u ? u->user_color - 1 : 0;
|
||||
Input::Colour colour{255, 0, 0};
|
||||
if (colour_index >= 0 && colour_index <= 3) {
|
||||
static constexpr Input::Colour colours[4]{
|
||||
{0, 0, 255}, // blue
|
||||
{255, 0, 0}, // red
|
||||
{0, 255, 0}, // green
|
||||
{255, 0, 255}, // pink
|
||||
};
|
||||
colour = colours[colour_index];
|
||||
colour = Input::g_user_colours[colour_index];
|
||||
} else {
|
||||
LOG_ERROR(Lib_Pad, "Invalid user colour value {} for controller {}, falling back to blue",
|
||||
colour_index, handle);
|
||||
}
|
||||
controller.SetLightBarRGB(colour.r, colour.g, colour.b);
|
||||
controller.SetLightBarRGB(colour);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "common/signal_context.h"
|
||||
#include "core/libraries/kernel/threads/exception.h"
|
||||
#include "core/signals.h"
|
||||
#include "emulator.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@@ -52,10 +53,6 @@ static LONG WINAPI SignalHandler(EXCEPTION_POINTERS* pExp) noexcept {
|
||||
case DBG_PRINTEXCEPTION_WIDE_C:
|
||||
// Used by OutputDebugString functions.
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
case EXCEPTION_BREAKPOINT:
|
||||
// This is almost certainly coming from our asserts/unreachables, no need to log it again.
|
||||
Common::Log::Flush();
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -64,8 +61,11 @@ static LONG WINAPI SignalHandler(EXCEPTION_POINTERS* pExp) noexcept {
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
LOG_CRITICAL(Debug, "Unhandled Exception code {:#x} at {}", code, address);
|
||||
Common::Log::Flush();
|
||||
// Breakpoints almost certainly come from our asserts/unreachables, no need to log it again.
|
||||
if (code != EXCEPTION_BREAKPOINT) {
|
||||
LOG_CRITICAL(Debug, "Unhandled Exception code {:#x} at {}", code, address);
|
||||
Common::Singleton<Core::Emulator>::Instance()->Shutdown();
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,8 @@ Frontend::WindowSDL* g_window = nullptr;
|
||||
|
||||
namespace Core {
|
||||
|
||||
std::mutex exit_mutex{};
|
||||
|
||||
Emulator::Emulator() {
|
||||
// Initialize NT API functions, set high priority and disable WER
|
||||
#ifdef _WIN32
|
||||
@@ -68,10 +70,26 @@ Emulator::Emulator() {
|
||||
WSADATA wsaData;
|
||||
WSAStartup(versionWanted, &wsaData);
|
||||
#endif
|
||||
std::at_quick_exit([]() { Common::Singleton<Core::Emulator>::Instance()->Shutdown(); });
|
||||
}
|
||||
|
||||
Emulator::~Emulator() {}
|
||||
|
||||
void Emulator::Shutdown() {
|
||||
static bool exit_done = false;
|
||||
std::scoped_lock l{exit_mutex};
|
||||
if (exit_done) {
|
||||
return;
|
||||
}
|
||||
Common::Log::Flush();
|
||||
if (controllers) {
|
||||
controllers->ResetLightbarColors();
|
||||
// need to give SDL time to do this before the runtime exits
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds{10});
|
||||
}
|
||||
exit_done = true;
|
||||
}
|
||||
|
||||
s32 ReadCompiledSdkVersion(const std::filesystem::path& file) {
|
||||
Core::Loader::Elf elf;
|
||||
elf.Open(file);
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
void Run(std::filesystem::path file, std::vector<std::string> args = {},
|
||||
std::optional<std::filesystem::path> game_folder = {});
|
||||
void UpdatePlayTime(const std::string& serial);
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* This will kill the current process and launch a new process with the same configuration
|
||||
|
||||
@@ -150,7 +150,7 @@ void GameController::UpdateAxisSmoothing() {
|
||||
m_state.UpdateAxisSmoothing();
|
||||
}
|
||||
|
||||
void GameController::SetLightBarRGB(u8 r, u8 g, u8 b) {
|
||||
void GameController::SetLightBarRGB(u8 const r, u8 const g, u8 const b) {
|
||||
if (override_colour.has_value()) {
|
||||
return;
|
||||
}
|
||||
@@ -160,6 +160,10 @@ void GameController::SetLightBarRGB(u8 r, u8 g, u8 b) {
|
||||
}
|
||||
}
|
||||
|
||||
void GameController::SetLightBarRGB(Colour const c) {
|
||||
SetLightBarRGB(c.r, c.g, c.b);
|
||||
}
|
||||
|
||||
Colour GameController::GetLightBarRGB() {
|
||||
return colour;
|
||||
}
|
||||
@@ -170,6 +174,22 @@ void GameController::PollLightColour() {
|
||||
}
|
||||
}
|
||||
|
||||
void GameControllers::ResetLightbarColors() {
|
||||
for (auto& c : controllers) {
|
||||
auto const* u = UserManagement.GetUserByID(c->user_id);
|
||||
if (!u || !c->m_sdl_gamepad) {
|
||||
continue;
|
||||
}
|
||||
auto const i = u->user_color - 1;
|
||||
if (i < 0 || i > 3) {
|
||||
continue;
|
||||
}
|
||||
auto const& col = g_user_colours[i];
|
||||
c->override_colour = std::nullopt;
|
||||
c->SetLightBarRGB(col);
|
||||
}
|
||||
}
|
||||
|
||||
bool GameController::SetVibration(u8 smallMotor, u8 largeMotor) {
|
||||
if (m_sdl_gamepad != nullptr) {
|
||||
return SDL_RumbleGamepad(m_sdl_gamepad, (smallMotor / 255.0f) * 0xFFFF,
|
||||
|
||||
@@ -43,6 +43,12 @@ struct TouchpadEntry {
|
||||
struct Colour {
|
||||
u8 r, g, b;
|
||||
};
|
||||
static constexpr Input::Colour g_user_colours[4]{
|
||||
{0, 0, 255}, // blue
|
||||
{255, 0, 0}, // red
|
||||
{0, 255, 0}, // green
|
||||
{255, 0, 255}, // pink
|
||||
};
|
||||
|
||||
struct State {
|
||||
private:
|
||||
@@ -127,7 +133,8 @@ public:
|
||||
void UpdateGyro(const float gyro[3]);
|
||||
void UpdateAcceleration(const float acceleration[3]);
|
||||
void UpdateAxisSmoothing();
|
||||
void SetLightBarRGB(u8 r, u8 g, u8 b);
|
||||
void SetLightBarRGB(u8 const r, u8 const g, u8 const b);
|
||||
void SetLightBarRGB(Colour const c);
|
||||
Colour GetLightBarRGB();
|
||||
void PollLightColour();
|
||||
bool SetVibration(u8 smallMotor, u8 largeMotor);
|
||||
@@ -205,6 +212,7 @@ public:
|
||||
controllers[i]->SetLightBarRGB(r, g, b);
|
||||
controllers[i]->override_colour = {r, g, b};
|
||||
}
|
||||
void ResetLightbarColors();
|
||||
};
|
||||
|
||||
} // namespace Input
|
||||
|
||||
@@ -25,6 +25,7 @@ set(SETTINGS_TEST_SOURCES
|
||||
|
||||
# Stubs that replace dependencies
|
||||
stubs/common_stub.cpp
|
||||
stubs/core_stub.cpp
|
||||
stubs/scm_rev_stub.cpp
|
||||
stubs/sdl_stub.cpp
|
||||
|
||||
@@ -115,6 +116,8 @@ set(GCN_TEST_SOURCES
|
||||
stubs/common_stub.cpp
|
||||
stubs/resource_tracking_pass_stub.cpp
|
||||
stubs/scm_rev_stub.cpp
|
||||
stubs/sdl_stub.cpp
|
||||
stubs/core_stub.cpp
|
||||
|
||||
gcn/gcn_test_runner.hpp
|
||||
gcn/gcn_test_runner.cpp
|
||||
@@ -226,6 +229,7 @@ set(HTTP_TEST_SOURCES
|
||||
stubs/scm_rev_stub.cpp
|
||||
stubs/sdl_stub.cpp
|
||||
stubs/loader_stub.cpp
|
||||
stubs/core_stub.cpp
|
||||
stubs/kernel_stub.cpp
|
||||
|
||||
# Tests
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "emulator.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
Emulator::Emulator() {}
|
||||
Emulator::~Emulator() {}
|
||||
void Emulator::Shutdown() {}
|
||||
|
||||
} // namespace Core
|
||||
@@ -2,17 +2,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <SDL3/SDL_messagebox.h>
|
||||
#include "sdl_window.h"
|
||||
|
||||
namespace Frontend {
|
||||
WindowSDL::~WindowSDL() = default;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool SDL_ShowMessageBox(const SDL_MessageBoxData* /* messageboxdata */, int* buttonid) {
|
||||
if (buttonid) *buttonid = 0; // "No",skip migration
|
||||
return true;
|
||||
}
|
||||
bool SDL_ShowMessageBox(const SDL_MessageBoxData* /* messageboxdata */, int* buttonid) {
|
||||
if (buttonid)
|
||||
*buttonid = 0; // "No",skip migration
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags /* flags */, const char* /* title */,
|
||||
const char* /* message */, SDL_Window* /* window */) {
|
||||
return true;
|
||||
}
|
||||
bool SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags /* flags */, const char* /* title */,
|
||||
const char* /* message */, SDL_Window* /* window */) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
Reference in New Issue
Block a user