// Copyright 2015 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include "input_common/input_common.h" #ifdef HAS_SDL #include "input_common/sdl_input/sdl_input.h" #endif #include "core/core_timing.h" #include "core/settings.h" namespace InputCommon { // Set to nullptr until initialized by a backend InputBase* g_user_input = nullptr; // Event id for CoreTiming static int input_event; // Ticks for CoreTiming event, same as VBlank in GPU static u64 frame_ticks; /// Callback for CoreTiming static void InputCallback(u64 userdata, int cycles_late) { // Call user input plugin Poll() if (g_user_input != nullptr) g_user_input->Poll(); // Reschedule recurrent event CoreTiming::ScheduleEvent(frame_ticks - cycles_late, input_event); } std::string InputBase::GetDeviceName() const { return device_name; } Service::HID::PadState InputBase::GetPadState() const { return controller.pad_state; } void Init(ControllerBackends backend) { switch (backend) { #ifdef HAS_SDL // SDL2 backend selected case ControllerBackends::SDL2: g_user_input = new SDLController(); break; #endif // No backend selected case ControllerBackends::NONE: break; // If no backend whatsoever inits, launch a critical log default: LOG_CRITICAL(Input, "Input backend initialization failed!"); break; } // Shutdown immediately if backend failed to initialize if (g_user_input != nullptr && !g_user_input->activated) { Shutdown(); return; } // Setup CoreTiming frame_ticks = 268123480 / Settings::values.gpu_refresh_rate / 16; input_event = CoreTiming::RegisterEvent("InputCommon::InputCallback", InputCallback); CoreTiming::ScheduleEvent(frame_ticks, input_event); } void Shutdown() { if (g_user_input != nullptr) { delete g_user_input; g_user_input = nullptr; } } } // namespace