mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 22:41:25 +12:00
input: try to fix macOS SDL crash
This commit is contained in:
parent
7367f72f4a
commit
7e27e1420e
1 changed files with 107 additions and 90 deletions
|
@ -9,8 +9,110 @@
|
||||||
|
|
||||||
LOG_CHANNEL(sdl_log, "SDL");
|
LOG_CHANNEL(sdl_log, "SDL");
|
||||||
|
|
||||||
std::mutex g_sdl_mutex;
|
struct sdl_instance
|
||||||
u32 g_sdl_handler_count = 0;
|
{
|
||||||
|
public:
|
||||||
|
sdl_instance() = default;
|
||||||
|
~sdl_instance()
|
||||||
|
{
|
||||||
|
// Only quit SDL once on exit. SDL uses a global state internally...
|
||||||
|
if (m_initialized)
|
||||||
|
{
|
||||||
|
sdl_log.notice("Quitting SDL ...");
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initialize()
|
||||||
|
{
|
||||||
|
// Only init SDL once. SDL uses a global state internally...
|
||||||
|
if (m_initialized)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sdl_log.notice("Initializing SDL ...");
|
||||||
|
|
||||||
|
// Set non-dynamic hints before SDL_Init
|
||||||
|
if (!SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"))
|
||||||
|
{
|
||||||
|
sdl_log.error("Could not set SDL_HINT_JOYSTICK_THREAD: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER) < 0)
|
||||||
|
{
|
||||||
|
sdl_log.error("Could not initialize! SDL Error: %s", SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
|
||||||
|
SDL_LogSetOutputFunction([](void*, int category, SDL_LogPriority priority, const char* message)
|
||||||
|
{
|
||||||
|
std::string category_name;
|
||||||
|
switch (category)
|
||||||
|
{
|
||||||
|
case SDL_LOG_CATEGORY_APPLICATION:
|
||||||
|
category_name = "app";
|
||||||
|
break;
|
||||||
|
case SDL_LOG_CATEGORY_ERROR:
|
||||||
|
category_name = "error";
|
||||||
|
break;
|
||||||
|
case SDL_LOG_CATEGORY_ASSERT:
|
||||||
|
category_name = "assert";
|
||||||
|
break;
|
||||||
|
case SDL_LOG_CATEGORY_SYSTEM:
|
||||||
|
category_name = "system";
|
||||||
|
break;
|
||||||
|
case SDL_LOG_CATEGORY_AUDIO:
|
||||||
|
category_name = "audio";
|
||||||
|
break;
|
||||||
|
case SDL_LOG_CATEGORY_VIDEO:
|
||||||
|
category_name = "video";
|
||||||
|
break;
|
||||||
|
case SDL_LOG_CATEGORY_RENDER:
|
||||||
|
category_name = "render";
|
||||||
|
break;
|
||||||
|
case SDL_LOG_CATEGORY_INPUT:
|
||||||
|
category_name = "input";
|
||||||
|
break;
|
||||||
|
case SDL_LOG_CATEGORY_TEST:
|
||||||
|
category_name = "test";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
category_name = fmt::format("unknown(%d)", category);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (priority)
|
||||||
|
{
|
||||||
|
case SDL_LOG_PRIORITY_VERBOSE:
|
||||||
|
case SDL_LOG_PRIORITY_DEBUG:
|
||||||
|
sdl_log.trace("%s: %s", category_name, message);
|
||||||
|
break;
|
||||||
|
case SDL_LOG_PRIORITY_INFO:
|
||||||
|
sdl_log.notice("%s: %s", category_name, message);
|
||||||
|
break;
|
||||||
|
case SDL_LOG_PRIORITY_WARN:
|
||||||
|
sdl_log.warning("%s: %s", category_name, message);
|
||||||
|
break;
|
||||||
|
case SDL_LOG_PRIORITY_ERROR:
|
||||||
|
sdl_log.error("%s: %s", category_name, message);
|
||||||
|
break;
|
||||||
|
case SDL_LOG_PRIORITY_CRITICAL:
|
||||||
|
sdl_log.error("%s: %s", category_name, message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, nullptr);
|
||||||
|
|
||||||
|
m_initialized = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_initialized = false;
|
||||||
|
};
|
||||||
|
|
||||||
constexpr u32 rumble_duration_ms = 500; // Some high number to keep rumble updates at a minimum.
|
constexpr u32 rumble_duration_ms = 500; // Some high number to keep rumble updates at a minimum.
|
||||||
constexpr u32 rumble_refresh_ms = rumble_duration_ms - 100; // We need to keep updating the rumble. Choose a refresh timeout that is unlikely to run into missed rumble updates.
|
constexpr u32 rumble_refresh_ms = rumble_duration_ms - 100; // We need to keep updating the rumble. Choose a refresh timeout that is unlikely to run into missed rumble updates.
|
||||||
|
@ -87,14 +189,6 @@ sdl_pad_handler::~sdl_pad_handler()
|
||||||
controller.second->sdl.game_controller = nullptr;
|
controller.second->sdl.game_controller = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only quit SDL if this is the last instance of the handler. SDL uses a global state internally...
|
|
||||||
std::lock_guard lock(g_sdl_mutex);
|
|
||||||
if (g_sdl_handler_count > 0 && --g_sdl_handler_count == 0)
|
|
||||||
{
|
|
||||||
sdl_log.notice("Quitting SDL ...");
|
|
||||||
SDL_Quit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdl_pad_handler::init_config(cfg_pad* cfg)
|
void sdl_pad_handler::init_config(cfg_pad* cfg)
|
||||||
|
@ -159,86 +253,9 @@ bool sdl_pad_handler::Init()
|
||||||
if (m_is_init)
|
if (m_is_init)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
std::lock_guard lock(g_sdl_mutex);
|
static sdl_instance s_sdl_instance {};
|
||||||
|
if (!s_sdl_instance.initialize())
|
||||||
// Only init SDL if this is the first instance of the handler. SDL uses a global state internally...
|
|
||||||
if (g_sdl_handler_count++ == 0)
|
|
||||||
{
|
|
||||||
sdl_log.notice("Initializing SDL ...");
|
|
||||||
|
|
||||||
// Set non-dynamic hints before SDL_Init
|
|
||||||
if (!SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"))
|
|
||||||
{
|
|
||||||
sdl_log.error("Could not set SDL_HINT_JOYSTICK_THREAD: %s", SDL_GetError());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER) < 0)
|
|
||||||
{
|
|
||||||
sdl_log.error("Could not initialize! SDL Error: %s", SDL_GetError());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
|
|
||||||
SDL_LogSetOutputFunction([](void*, int category, SDL_LogPriority priority, const char* message)
|
|
||||||
{
|
|
||||||
std::string category_name;
|
|
||||||
switch (category)
|
|
||||||
{
|
|
||||||
case SDL_LOG_CATEGORY_APPLICATION:
|
|
||||||
category_name = "app";
|
|
||||||
break;
|
|
||||||
case SDL_LOG_CATEGORY_ERROR:
|
|
||||||
category_name = "error";
|
|
||||||
break;
|
|
||||||
case SDL_LOG_CATEGORY_ASSERT:
|
|
||||||
category_name = "assert";
|
|
||||||
break;
|
|
||||||
case SDL_LOG_CATEGORY_SYSTEM:
|
|
||||||
category_name = "system";
|
|
||||||
break;
|
|
||||||
case SDL_LOG_CATEGORY_AUDIO:
|
|
||||||
category_name = "audio";
|
|
||||||
break;
|
|
||||||
case SDL_LOG_CATEGORY_VIDEO:
|
|
||||||
category_name = "video";
|
|
||||||
break;
|
|
||||||
case SDL_LOG_CATEGORY_RENDER:
|
|
||||||
category_name = "render";
|
|
||||||
break;
|
|
||||||
case SDL_LOG_CATEGORY_INPUT:
|
|
||||||
category_name = "input";
|
|
||||||
break;
|
|
||||||
case SDL_LOG_CATEGORY_TEST:
|
|
||||||
category_name = "test";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
category_name = fmt::format("unknown(%d)", category);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (priority)
|
|
||||||
{
|
|
||||||
case SDL_LOG_PRIORITY_VERBOSE:
|
|
||||||
case SDL_LOG_PRIORITY_DEBUG:
|
|
||||||
sdl_log.trace("%s: %s", category_name, message);
|
|
||||||
break;
|
|
||||||
case SDL_LOG_PRIORITY_INFO:
|
|
||||||
sdl_log.notice("%s: %s", category_name, message);
|
|
||||||
break;
|
|
||||||
case SDL_LOG_PRIORITY_WARN:
|
|
||||||
sdl_log.warning("%s: %s", category_name, message);
|
|
||||||
break;
|
|
||||||
case SDL_LOG_PRIORITY_ERROR:
|
|
||||||
sdl_log.error("%s: %s", category_name, message);
|
|
||||||
break;
|
|
||||||
case SDL_LOG_PRIORITY_CRITICAL:
|
|
||||||
sdl_log.error("%s: %s", category_name, message);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_cfg.io.load_sdl_mappings)
|
if (g_cfg.io.load_sdl_mappings)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue