diff --git a/rpcs3/Emu/Cell/Modules/cellPad.cpp b/rpcs3/Emu/Cell/Modules/cellPad.cpp index 61a8ea3a2b..e81f6a95f4 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPad.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "Emu/IdManager.h" #include "Emu/system_config.h" -#include "Emu/System.h" #include "Emu/Cell/PPUModule.h" #include "Emu/Cell/lv2/sys_process.h" #include "Emu/Cell/lv2/sys_sync.h" @@ -166,11 +165,7 @@ void cellPad_NotifyStateChange(usz index, u64 /*state*/, bool locked) extern void pad_state_notify_state_change(usz index, u32 state) { - // Prevents accidental calls from pad handlers while the emulation is not running. - if (Emu.IsRunning()) - { - send_sys_io_connect_event(index, state); - } + send_sys_io_connect_event(index, state); } error_code cellPadInit(ppu_thread& ppu, u32 max_connect) diff --git a/rpcs3/Emu/Io/Null/NullPadHandler.h b/rpcs3/Emu/Io/Null/NullPadHandler.h index 5c9f79ceac..46da136a7c 100644 --- a/rpcs3/Emu/Io/Null/NullPadHandler.h +++ b/rpcs3/Emu/Io/Null/NullPadHandler.h @@ -5,7 +5,7 @@ class NullPadHandler final : public PadHandlerBase { public: - NullPadHandler() : PadHandlerBase(pad_handler::null) + NullPadHandler(bool emulation) : PadHandlerBase(pad_handler::null, emulation) { b_has_pressure_intensity_button = false; } diff --git a/rpcs3/Emu/Io/PadHandler.cpp b/rpcs3/Emu/Io/PadHandler.cpp index 3ec2e113eb..3dc42e769c 100644 --- a/rpcs3/Emu/Io/PadHandler.cpp +++ b/rpcs3/Emu/Io/PadHandler.cpp @@ -9,7 +9,7 @@ cfg_input g_cfg_input; extern void pad_state_notify_state_change(usz index, u32 state); -PadHandlerBase::PadHandlerBase(pad_handler type) : m_type(type) +PadHandlerBase::PadHandlerBase(pad_handler type, bool emulation) : m_type(type), m_emulation(emulation) { } @@ -747,7 +747,11 @@ void PadHandlerBase::process() input_log.success("%s device %d connected", m_type, i); pad->m_port_status |= CELL_PAD_STATUS_CONNECTED + CELL_PAD_STATUS_ASSIGN_CHANGES; - pad_state_notify_state_change(i, CELL_PAD_STATUS_CONNECTED); + + if (m_emulation) + { + pad_state_notify_state_change(i, CELL_PAD_STATUS_CONNECTED); + } last_connection_status[i] = true; connected_devices++; @@ -771,7 +775,11 @@ void PadHandlerBase::process() input_log.success("%s device %d connected by force", m_type, i); pad->m_port_status |= CELL_PAD_STATUS_CONNECTED + CELL_PAD_STATUS_ASSIGN_CHANGES; - pad_state_notify_state_change(i, CELL_PAD_STATUS_CONNECTED); + + if (m_emulation) + { + pad_state_notify_state_change(i, CELL_PAD_STATUS_CONNECTED); + } last_connection_status[i] = true; connected_devices++; @@ -786,7 +794,10 @@ void PadHandlerBase::process() pad->m_port_status &= ~CELL_PAD_STATUS_CONNECTED; pad->m_port_status |= CELL_PAD_STATUS_ASSIGN_CHANGES; - pad_state_notify_state_change(i, CELL_PAD_STATUS_DISCONNECTED); + if (m_emulation) + { + pad_state_notify_state_change(i, CELL_PAD_STATUS_DISCONNECTED); + } last_connection_status[i] = false; connected_devices--; diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index 4028ea7100..e0c38f62a8 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -248,6 +248,7 @@ public: pad_handler m_type; bool m_is_init = false; + bool m_emulation = false; std::string name_string() const; usz max_devices() const; @@ -265,7 +266,7 @@ public: void convert_stick_values(u16& x_out, u16& y_out, const s32& x_in, const s32& y_in, const s32& deadzone, const s32& padsquircling) const; virtual bool Init() { return true; } - PadHandlerBase(pad_handler type = pad_handler::null); + PadHandlerBase(pad_handler type = pad_handler::null, bool emulation = false); virtual ~PadHandlerBase() = default; // Sets window to config the controller(optional) virtual void SetPadData(const std::string& /*padId*/, u8 /*player_id*/, u8 /*large_motor*/, u8 /*small_motor*/, s32 /*r*/, s32 /*g*/, s32 /*b*/, bool /*player_led*/, bool /*battery_led*/, u32 /*battery_led_brightness*/) {} diff --git a/rpcs3/Input/ds3_pad_handler.cpp b/rpcs3/Input/ds3_pad_handler.cpp index 23ce0a911f..c2fd3aa156 100644 --- a/rpcs3/Input/ds3_pad_handler.cpp +++ b/rpcs3/Input/ds3_pad_handler.cpp @@ -43,8 +43,8 @@ constexpr std::array battery_capacity = {0, 1, 25, 50, 75, 100}; constexpr id_pair SONY_DS3_ID_0 = {0x054C, 0x0268}; -ds3_pad_handler::ds3_pad_handler() - : hid_pad_handler(pad_handler::ds3, {SONY_DS3_ID_0}) +ds3_pad_handler::ds3_pad_handler(bool emulation) + : hid_pad_handler(pad_handler::ds3, emulation, {SONY_DS3_ID_0}) { button_list = { diff --git a/rpcs3/Input/ds3_pad_handler.h b/rpcs3/Input/ds3_pad_handler.h index f97952d379..327feead80 100644 --- a/rpcs3/Input/ds3_pad_handler.h +++ b/rpcs3/Input/ds3_pad_handler.h @@ -77,7 +77,7 @@ class ds3_pad_handler final : public hid_pad_handler #endif public: - ds3_pad_handler(); + ds3_pad_handler(bool emulation); ~ds3_pad_handler(); void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override; diff --git a/rpcs3/Input/ds4_pad_handler.cpp b/rpcs3/Input/ds4_pad_handler.cpp index a7a4849200..c1f96b9bef 100644 --- a/rpcs3/Input/ds4_pad_handler.cpp +++ b/rpcs3/Input/ds4_pad_handler.cpp @@ -72,8 +72,8 @@ namespace }*/ } -ds4_pad_handler::ds4_pad_handler() - : hid_pad_handler(pad_handler::ds4, {SONY_DS4_ID_0, SONY_DS4_ID_1, SONY_DS4_ID_2, ZEROPLUS_ID_0}) +ds4_pad_handler::ds4_pad_handler(bool emulation) + : hid_pad_handler(pad_handler::ds4, emulation, {SONY_DS4_ID_0, SONY_DS4_ID_1, SONY_DS4_ID_2, ZEROPLUS_ID_0}) { // Unique names for the config files and our pad settings dialog button_list = diff --git a/rpcs3/Input/ds4_pad_handler.h b/rpcs3/Input/ds4_pad_handler.h index 1f9ba60449..448528404b 100644 --- a/rpcs3/Input/ds4_pad_handler.h +++ b/rpcs3/Input/ds4_pad_handler.h @@ -53,7 +53,7 @@ class ds4_pad_handler final : public hid_pad_handler }; public: - ds4_pad_handler(); + ds4_pad_handler(bool emulation); ~ds4_pad_handler(); void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override; diff --git a/rpcs3/Input/dualsense_pad_handler.cpp b/rpcs3/Input/dualsense_pad_handler.cpp index dd17de8bd9..12e6f46fca 100644 --- a/rpcs3/Input/dualsense_pad_handler.cpp +++ b/rpcs3/Input/dualsense_pad_handler.cpp @@ -96,8 +96,8 @@ namespace static_assert(sizeof(struct output_report_usb) == DUALSENSE_USB_REPORT_SIZE); } -dualsense_pad_handler::dualsense_pad_handler() - : hid_pad_handler(pad_handler::dualsense, {SONY_DUALSENSE_ID_0, SONY_DUALSENSE_ID_1}) +dualsense_pad_handler::dualsense_pad_handler(bool emulation) + : hid_pad_handler(pad_handler::dualsense, emulation, {SONY_DUALSENSE_ID_0, SONY_DUALSENSE_ID_1}) { // Unique names for the config files and our pad settings dialog button_list = diff --git a/rpcs3/Input/dualsense_pad_handler.h b/rpcs3/Input/dualsense_pad_handler.h index 282a994e70..fec445bb3a 100644 --- a/rpcs3/Input/dualsense_pad_handler.h +++ b/rpcs3/Input/dualsense_pad_handler.h @@ -79,7 +79,7 @@ class dualsense_pad_handler final : public hid_pad_handler }; public: - dualsense_pad_handler(); + dualsense_pad_handler(bool emulation); ~dualsense_pad_handler(); void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override; diff --git a/rpcs3/Input/evdev_joystick_handler.cpp b/rpcs3/Input/evdev_joystick_handler.cpp index 894eed7256..d486442c93 100644 --- a/rpcs3/Input/evdev_joystick_handler.cpp +++ b/rpcs3/Input/evdev_joystick_handler.cpp @@ -19,8 +19,8 @@ LOG_CHANNEL(evdev_log, "evdev"); -evdev_joystick_handler::evdev_joystick_handler() - : PadHandlerBase(pad_handler::evdev) +evdev_joystick_handler::evdev_joystick_handler(bool emulation) + : PadHandlerBase(pad_handler::evdev, emulation) { init_configs(); diff --git a/rpcs3/Input/evdev_joystick_handler.h b/rpcs3/Input/evdev_joystick_handler.h index e7ab8b5c28..ef3832d431 100644 --- a/rpcs3/Input/evdev_joystick_handler.h +++ b/rpcs3/Input/evdev_joystick_handler.h @@ -394,7 +394,7 @@ class evdev_joystick_handler final : public PadHandlerBase }; public: - evdev_joystick_handler(); + evdev_joystick_handler(bool emulation); ~evdev_joystick_handler(); void init_config(cfg_pad* cfg) override; diff --git a/rpcs3/Input/gui_pad_thread.cpp b/rpcs3/Input/gui_pad_thread.cpp index 7695f50169..968997561f 100644 --- a/rpcs3/Input/gui_pad_thread.cpp +++ b/rpcs3/Input/gui_pad_thread.cpp @@ -115,45 +115,12 @@ bool gui_pad_thread::init() for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; i++) // max 7 pads { cfg_player* cfg = g_cfg_input.player[i]; - std::shared_ptr cur_pad_handler; const pad_handler handler_type = cfg->handler.get(); + std::shared_ptr cur_pad_handler = GetHandler(handler_type); - switch (handler_type) + if (!cur_pad_handler) { - case pad_handler::ds3: - cur_pad_handler = std::make_shared(); - break; - case pad_handler::ds4: - cur_pad_handler = std::make_shared(); - break; - case pad_handler::dualsense: - cur_pad_handler = std::make_shared(); - break; - case pad_handler::skateboard: - cur_pad_handler = std::make_shared(); - break; -#ifdef _WIN32 - case pad_handler::xinput: - cur_pad_handler = std::make_shared(); - break; - case pad_handler::mm: - cur_pad_handler = std::make_shared(); - break; -#endif -#ifdef HAVE_SDL2 - case pad_handler::sdl: - cur_pad_handler = std::make_shared(); - break; -#endif -#ifdef HAVE_LIBEVDEV - case pad_handler::evdev: - cur_pad_handler = std::make_shared(); - break; -#endif - case pad_handler::keyboard: - case pad_handler::null: - // Makes no sense to use this if we are in the GUI anyway continue; } @@ -230,26 +197,26 @@ std::shared_ptr gui_pad_thread::GetHandler(pad_handler type) // Makes no sense to use this if we are in the GUI anyway return nullptr; case pad_handler::ds3: - return std::make_unique(); + return std::make_shared(false); case pad_handler::ds4: - return std::make_unique(); + return std::make_shared(false); case pad_handler::dualsense: - return std::make_unique(); + return std::make_shared(false); case pad_handler::skateboard: - return std::make_unique(); + return std::make_shared(false); #ifdef _WIN32 case pad_handler::xinput: - return std::make_unique(); + return std::make_shared(false); case pad_handler::mm: - return std::make_unique(); + return std::make_shared(false); #endif #ifdef HAVE_SDL2 case pad_handler::sdl: - return std::make_unique(); + return std::make_shared(false); #endif #ifdef HAVE_LIBEVDEV case pad_handler::evdev: - return std::make_unique(); + return std::make_shared(false); #endif } diff --git a/rpcs3/Input/hid_pad_handler.cpp b/rpcs3/Input/hid_pad_handler.cpp index 4d8a7f63e9..ef1600d709 100644 --- a/rpcs3/Input/hid_pad_handler.cpp +++ b/rpcs3/Input/hid_pad_handler.cpp @@ -21,8 +21,8 @@ static std::mutex s_hid_mutex; // hid_pad_handler is created by pad_thread and p static u8 s_hid_instances{0}; template -hid_pad_handler::hid_pad_handler(pad_handler type, std::vector ids) - : PadHandlerBase(type), m_ids(std::move(ids)) +hid_pad_handler::hid_pad_handler(pad_handler type, bool emulation, std::vector ids) + : PadHandlerBase(type, emulation), m_ids(std::move(ids)) { std::scoped_lock lock(s_hid_mutex); ensure(s_hid_instances++ < 255); diff --git a/rpcs3/Input/hid_pad_handler.h b/rpcs3/Input/hid_pad_handler.h index 943b6c2435..9de2e3f9d5 100644 --- a/rpcs3/Input/hid_pad_handler.h +++ b/rpcs3/Input/hid_pad_handler.h @@ -54,7 +54,7 @@ template class hid_pad_handler : public PadHandlerBase { public: - hid_pad_handler(pad_handler type, std::vector ids); + hid_pad_handler(pad_handler type, bool emulation, std::vector ids); ~hid_pad_handler(); bool Init() override; diff --git a/rpcs3/Input/keyboard_pad_handler.cpp b/rpcs3/Input/keyboard_pad_handler.cpp index f1d31c2a11..fe5925e656 100644 --- a/rpcs3/Input/keyboard_pad_handler.cpp +++ b/rpcs3/Input/keyboard_pad_handler.cpp @@ -16,9 +16,9 @@ bool keyboard_pad_handler::Init() return true; } -keyboard_pad_handler::keyboard_pad_handler() +keyboard_pad_handler::keyboard_pad_handler(bool emulation) : QObject() - , PadHandlerBase(pad_handler::keyboard) + , PadHandlerBase(pad_handler::keyboard, emulation) { init_configs(); diff --git a/rpcs3/Input/keyboard_pad_handler.h b/rpcs3/Input/keyboard_pad_handler.h index f5199a3edf..88fe2fe9c3 100644 --- a/rpcs3/Input/keyboard_pad_handler.h +++ b/rpcs3/Input/keyboard_pad_handler.h @@ -69,7 +69,7 @@ class keyboard_pad_handler final : public QObject, public PadHandlerBase public: bool Init() override; - keyboard_pad_handler(); + keyboard_pad_handler(bool emulation); void SetTargetWindow(QWindow* target); void processKeyEvent(QKeyEvent* event, bool pressed); diff --git a/rpcs3/Input/mm_joystick_handler.cpp b/rpcs3/Input/mm_joystick_handler.cpp index 1f8e6ec93e..3223c8079d 100644 --- a/rpcs3/Input/mm_joystick_handler.cpp +++ b/rpcs3/Input/mm_joystick_handler.cpp @@ -2,7 +2,7 @@ #include "mm_joystick_handler.h" #include "Emu/Io/pad_config.h" -mm_joystick_handler::mm_joystick_handler() : PadHandlerBase(pad_handler::mm) +mm_joystick_handler::mm_joystick_handler(bool emulation) : PadHandlerBase(pad_handler::mm, emulation) { init_configs(); diff --git a/rpcs3/Input/mm_joystick_handler.h b/rpcs3/Input/mm_joystick_handler.h index 0babc9987a..7ec990d281 100644 --- a/rpcs3/Input/mm_joystick_handler.h +++ b/rpcs3/Input/mm_joystick_handler.h @@ -109,7 +109,7 @@ class mm_joystick_handler final : public PadHandlerBase }; public: - mm_joystick_handler(); + mm_joystick_handler(bool emulation); bool Init() override; diff --git a/rpcs3/Input/pad_thread.cpp b/rpcs3/Input/pad_thread.cpp index 3e013b00a2..2a6127dcd5 100644 --- a/rpcs3/Input/pad_thread.cpp +++ b/rpcs3/Input/pad_thread.cpp @@ -136,7 +136,7 @@ void pad_thread::Init() std::shared_ptr keyptr; // Always have a Null Pad Handler - std::shared_ptr nullpad = std::make_shared(); + std::shared_ptr nullpad = std::make_shared(true); handlers.emplace(pad_handler::null, nullpad); for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; i++) // max 7 pads @@ -152,47 +152,18 @@ void pad_thread::Init() } else { - switch (handler_type) + if (handler_type == pad_handler::keyboard) { - case pad_handler::keyboard: - keyptr = std::make_shared(); + keyptr = std::make_shared(true); keyptr->moveToThread(static_cast(m_curthread)); keyptr->SetTargetWindow(static_cast(m_curwindow)); cur_pad_handler = keyptr; - break; - case pad_handler::ds3: - cur_pad_handler = std::make_shared(); - break; - case pad_handler::ds4: - cur_pad_handler = std::make_shared(); - break; - case pad_handler::dualsense: - cur_pad_handler = std::make_shared(); - break; - case pad_handler::skateboard: - cur_pad_handler = std::make_shared(); - break; -#ifdef _WIN32 - case pad_handler::xinput: - cur_pad_handler = std::make_shared(); - break; - case pad_handler::mm: - cur_pad_handler = std::make_shared(); - break; -#endif -#ifdef HAVE_SDL2 - case pad_handler::sdl: - cur_pad_handler = std::make_shared(); - break; -#endif -#ifdef HAVE_LIBEVDEV - case pad_handler::evdev: - cur_pad_handler = std::make_shared(); - break; -#endif - case pad_handler::null: - break; } + else + { + cur_pad_handler = GetHandler(handler_type); + } + handlers.emplace(handler_type, cur_pad_handler); } cur_pad_handler->Init(); @@ -604,30 +575,30 @@ std::shared_ptr pad_thread::GetHandler(pad_handler type) switch (type) { case pad_handler::null: - return std::make_unique(); + return std::make_shared(true); case pad_handler::keyboard: - return std::make_unique(); + return std::make_shared(true); case pad_handler::ds3: - return std::make_unique(); + return std::make_shared(true); case pad_handler::ds4: - return std::make_unique(); + return std::make_shared(true); case pad_handler::dualsense: - return std::make_unique(); + return std::make_shared(true); case pad_handler::skateboard: - return std::make_unique(); + return std::make_shared(true); #ifdef _WIN32 case pad_handler::xinput: - return std::make_unique(); + return std::make_shared(true); case pad_handler::mm: - return std::make_unique(); + return std::make_shared(true); #endif #ifdef HAVE_SDL2 case pad_handler::sdl: - return std::make_unique(); + return std::make_shared(true); #endif #ifdef HAVE_LIBEVDEV case pad_handler::evdev: - return std::make_unique(); + return std::make_shared(true); #endif } diff --git a/rpcs3/Input/sdl_pad_handler.cpp b/rpcs3/Input/sdl_pad_handler.cpp index 838207e655..9c65d83210 100644 --- a/rpcs3/Input/sdl_pad_handler.cpp +++ b/rpcs3/Input/sdl_pad_handler.cpp @@ -10,7 +10,7 @@ LOG_CHANNEL(sdl_log, "SDL"); 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. -sdl_pad_handler::sdl_pad_handler() : PadHandlerBase(pad_handler::sdl) +sdl_pad_handler::sdl_pad_handler(bool emulation) : PadHandlerBase(pad_handler::sdl, emulation) { button_list = { diff --git a/rpcs3/Input/sdl_pad_handler.h b/rpcs3/Input/sdl_pad_handler.h index a070423b96..779aef06c6 100644 --- a/rpcs3/Input/sdl_pad_handler.h +++ b/rpcs3/Input/sdl_pad_handler.h @@ -95,7 +95,7 @@ class sdl_pad_handler : public PadHandlerBase }; public: - sdl_pad_handler(); + sdl_pad_handler(bool emulation); ~sdl_pad_handler(); SDLDevice::sdl_info get_sdl_info(int i); diff --git a/rpcs3/Input/skateboard_pad_handler.cpp b/rpcs3/Input/skateboard_pad_handler.cpp index ab58806a4e..f78c3af3c1 100644 --- a/rpcs3/Input/skateboard_pad_handler.cpp +++ b/rpcs3/Input/skateboard_pad_handler.cpp @@ -37,8 +37,8 @@ namespace static constexpr std::array disconnected_state = { 0x00, 0x00, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; } -skateboard_pad_handler::skateboard_pad_handler() - : hid_pad_handler(pad_handler::skateboard, {SKATEBOARD_ID_0}) +skateboard_pad_handler::skateboard_pad_handler(bool emulation) + : hid_pad_handler(pad_handler::skateboard, emulation, {SKATEBOARD_ID_0}) { // Unique names for the config files and our pad settings dialog button_list = diff --git a/rpcs3/Input/skateboard_pad_handler.h b/rpcs3/Input/skateboard_pad_handler.h index 37520d55c5..df239122ed 100644 --- a/rpcs3/Input/skateboard_pad_handler.h +++ b/rpcs3/Input/skateboard_pad_handler.h @@ -170,7 +170,7 @@ class skateboard_pad_handler final : public hid_pad_handler }; public: - skateboard_pad_handler(); + skateboard_pad_handler(bool emulation); ~skateboard_pad_handler(); void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override; diff --git a/rpcs3/Input/xinput_pad_handler.cpp b/rpcs3/Input/xinput_pad_handler.cpp index 5287df594b..f49345dac9 100644 --- a/rpcs3/Input/xinput_pad_handler.cpp +++ b/rpcs3/Input/xinput_pad_handler.cpp @@ -14,7 +14,7 @@ namespace XINPUT_INFO }; } // namespace XINPUT_INFO -xinput_pad_handler::xinput_pad_handler() : PadHandlerBase(pad_handler::xinput) +xinput_pad_handler::xinput_pad_handler(bool emulation) : PadHandlerBase(pad_handler::xinput, emulation) { // Unique names for the config files and our pad settings dialog button_list = diff --git a/rpcs3/Input/xinput_pad_handler.h b/rpcs3/Input/xinput_pad_handler.h index 49595f7696..ef58cf6dea 100644 --- a/rpcs3/Input/xinput_pad_handler.h +++ b/rpcs3/Input/xinput_pad_handler.h @@ -102,7 +102,7 @@ class xinput_pad_handler final : public PadHandlerBase }; public: - xinput_pad_handler(); + xinput_pad_handler(bool emulation); ~xinput_pad_handler(); bool Init() override;