diff --git a/core/input/input.cpp b/core/input/input.cpp index 257452b3d894..77a7f2745815 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -39,6 +39,10 @@ #include "core/os/thread.h" #endif +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#endif + static const char *_joy_buttons[(size_t)JoyButton::SDL_MAX] = { "a", "b", @@ -765,6 +769,24 @@ void Input::vibrate_handheld(int p_duration_ms) { OS::get_singleton()->vibrate_handheld(p_duration_ms); } +void Input::set_force_disable_joypad(bool p_force) { + force_disable_joypad = p_force; +} + +bool Input::get_enable_joypad() const { + if (force_disable_joypad) { + return false; + } + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return EDITOR_GET("input_devices/joypad/enabled"); + } +#endif + + return GLOBAL_GET("input_devices/joypad/enabled"); +} + void Input::set_gravity(const Vector3 &p_gravity) { _THREAD_SAFE_METHOD_ diff --git a/core/input/input.h b/core/input/input.h index dd613c4877df..081c789d1b8d 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -176,6 +176,8 @@ class Input : public Object { CursorShape default_shape = CURSOR_ARROW; + bool force_disable_joypad = false; + enum JoyType { TYPE_BUTTON, TYPE_AXIS, @@ -309,6 +311,9 @@ class Input : public Object { void parse_input_event(const Ref &p_event); + bool get_enable_joypad() const; + void set_force_disable_joypad(bool p_force); + void set_gravity(const Vector3 &p_gravity); void set_accelerometer(const Vector3 &p_accel); void set_magnetometer(const Vector3 &p_magnetometer); diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 3fc9e94427ec..dd71af060ef6 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1320,6 +1320,9 @@ If [code]false[/code], no input will be lost. [b]Note:[/b] You should in nearly all cases prefer the [code]false[/code] setting. The legacy behavior is to enable supporting old projects that rely on the old logic, without changes to script. + + If [code]true[/code], Godot will connect to joypads. If [code]false[/code], Godot will not connect to joypads. + Specifies the tablet driver to use. If left empty, the default driver will be used. [b]Note:[/b] The driver in use can be overridden at runtime via the [code]--tablet-driver[/code] [url=$DOCS_URL/tutorials/editor/command_line_tutorial.html]command line argument[/url]. diff --git a/main/main.cpp b/main/main.cpp index 281ef9a0d69b..34235cb09b17 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -152,6 +152,7 @@ static PhysicsServer2D *physics_server_2d = nullptr; static NavigationServer3D *navigation_server_3d = nullptr; static NavigationServer2D *navigation_server_2d = nullptr; static ThemeDB *theme_db = nullptr; +static bool force_disable_joypad = false; // We error out if setup2() doesn't turn this true static bool _start_success = false; @@ -1533,7 +1534,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->print("Missing --xr-mode argument, aborting.\n"); goto error; } - + } else if (I->get() == "--disable-joypad") { + force_disable_joypad = true; } else if (I->get() == "--benchmark") { OS::get_singleton()->set_use_benchmark(true); } else if (I->get() == "--benchmark-file") { @@ -2173,6 +2175,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph // GLOBAL_DEF("xr/openxr/in_editor", false); #endif + // Joypad settings. + GLOBAL_DEF_BASIC("input_devices/joypad/enabled", true); + Engine::get_singleton()->set_frame_delay(frame_delay); message_queue = memnew(MessageQueue); @@ -2358,6 +2363,7 @@ Error Main::setup2() { /* Initialize Input */ input = memnew(Input); + input->set_force_disable_joypad(force_disable_joypad); /* Initialize Display Server */ @@ -3500,6 +3506,11 @@ bool Main::start() { } } +#ifdef TOOLS_ENABLED + if (editor) { + EDITOR_DEF_RST("input_devices/joypad/enabled", true); + } +#endif OS::get_singleton()->benchmark_end_measure("startup_begin"); OS::get_singleton()->benchmark_dump(); diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index 60edb00dd284..08befb91133b 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -57,6 +57,7 @@ JoypadWindows::JoypadWindows(HWND *hwnd) { xinput_dll = nullptr; xinput_get_state = nullptr; xinput_set_state = nullptr; + is_enabled = Input::get_singleton()->get_enable_joypad(); load_xinput(); @@ -305,6 +306,10 @@ void JoypadWindows::close_joypad(int id) { } void JoypadWindows::probe_joypads() { + if (!is_enabled) { + return; + } + ERR_FAIL_NULL_MSG(dinput, "DirectInput not initialized. Rebooting your PC may solve this issue."); DWORD dwResult; for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) { @@ -345,6 +350,10 @@ void JoypadWindows::probe_joypads() { } void JoypadWindows::process_joypads() { + if (!is_enabled) { + return; + } + HRESULT hr; for (int i = 0; i < XUSER_MAX_COUNT; i++) { diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h index cfddbcc8dc0d..a063330e724d 100644 --- a/platform/windows/joypad_windows.h +++ b/platform/windows/joypad_windows.h @@ -119,6 +119,8 @@ class JoypadWindows { dinput_gamepad d_joypads[JOYPADS_MAX]; xinput_gamepad x_joypads[XUSER_MAX_COUNT]; + bool is_enabled = true; + static BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE *p_instance, void *p_context); static BOOL CALLBACK objectsCallback(const DIDEVICEOBJECTINSTANCE *instance, void *context);