Skip to content

Commit 7903c5f

Browse files
committed
Add ios virtual controller support.
1 parent 1bffd6c commit 7903c5f

17 files changed

+641
-0
lines changed

core/config/project_settings.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,13 @@ ProjectSettings::ProjectSettings() {
15761576
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false);
15771577
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false);
15781578
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1);
1579+
GLOBAL_DEF_BASIC("input_devices/virtual_controller/ios/enable_controller", false);
1580+
GLOBAL_DEF_BASIC("input_devices/virtual_controller/ios/enable_left_thumbstick", true);
1581+
GLOBAL_DEF_BASIC("input_devices/virtual_controller/ios/enable_right_thumbstick", true);
1582+
GLOBAL_DEF_BASIC("input_devices/virtual_controller/ios/enable_button_a", true);
1583+
GLOBAL_DEF_BASIC("input_devices/virtual_controller/ios/enable_button_b", true);
1584+
GLOBAL_DEF_BASIC("input_devices/virtual_controller/ios/enable_button_x", true);
1585+
GLOBAL_DEF_BASIC("input_devices/virtual_controller/ios/enable_button_y", true);
15791586

15801587
// These properties will not show up in the dialog. If you want to exclude whole groups, use add_hidden_prefix().
15811588
GLOBAL_DEF_INTERNAL("application/config/features", PackedStringArray());

core/input/input.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ void Input::_bind_methods() {
188188
ClassDB::bind_method(D_METHOD("is_emulating_mouse_from_touch"), &Input::is_emulating_mouse_from_touch);
189189
ClassDB::bind_method(D_METHOD("set_emulate_touch_from_mouse", "enable"), &Input::set_emulate_touch_from_mouse);
190190
ClassDB::bind_method(D_METHOD("is_emulating_touch_from_mouse"), &Input::is_emulating_touch_from_mouse);
191+
ClassDB::bind_method(D_METHOD("get_virtual_controller"), &Input::get_virtual_controller);
191192

192193
ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_mode"), "set_mouse_mode", "get_mouse_mode");
193194
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_accumulated_input"), "set_use_accumulated_input", "is_using_accumulated_input");
@@ -1054,6 +1055,10 @@ bool Input::is_emulating_touch_from_mouse() const {
10541055
return emulate_touch_from_mouse;
10551056
}
10561057

1058+
VirtualController *Input::get_virtual_controller() {
1059+
return OS::get_singleton()->get_virtual_controller();
1060+
}
1061+
10571062
// Calling this whenever the game window is focused helps unsticking the "touch mouse"
10581063
// if the OS or its abstraction class hasn't properly reported that touch pointers raised
10591064
void Input::ensure_touch_mouse_raised() {

core/input/input.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define INPUT_H
3333

3434
#include "core/input/input_event.h"
35+
#include "core/input/virtual_controller.h"
3536
#include "core/object/object.h"
3637
#include "core/os/keyboard.h"
3738
#include "core/os/thread_safe.h"
@@ -383,6 +384,8 @@ class Input : public Object {
383384
void set_use_accumulated_input(bool p_enable);
384385
bool is_using_accumulated_input();
385386

387+
VirtualController *get_virtual_controller();
388+
386389
void release_pressed_events();
387390

388391
void set_event_dispatch_function(EventDispatchFunc p_function);

core/input/virtual_controller.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**************************************************************************/
2+
/* virtual_controller.cpp */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#include "virtual_controller.h"
32+
33+
void VirtualController::_bind_methods() {
34+
ClassDB::bind_method(D_METHOD("enable"), &VirtualController::enable);
35+
ClassDB::bind_method(D_METHOD("disable"), &VirtualController::disable);
36+
ClassDB::bind_method(D_METHOD("is_enabled"), &VirtualController::is_enabled);
37+
ClassDB::bind_method(D_METHOD("set_enabled_left_thumbstick", "enable"), &VirtualController::set_enabled_left_thumbstick);
38+
ClassDB::bind_method(D_METHOD("is_enabled_left_thumbstick"), &VirtualController::is_enabled_left_thumbstick);
39+
ClassDB::bind_method(D_METHOD("set_enabled_right_thumbstick", "enable"), &VirtualController::set_enabled_right_thumbstick);
40+
ClassDB::bind_method(D_METHOD("is_enabled_right_thumbstick"), &VirtualController::is_enabled_right_thumbstick);
41+
ClassDB::bind_method(D_METHOD("set_enabled_button_a", "enable"), &VirtualController::set_enabled_button_a);
42+
ClassDB::bind_method(D_METHOD("is_enabled_button_a"), &VirtualController::is_enabled_button_a);
43+
ClassDB::bind_method(D_METHOD("set_enabled_button_b", "enable"), &VirtualController::set_enabled_button_b);
44+
ClassDB::bind_method(D_METHOD("is_enabled_button_b"), &VirtualController::is_enabled_button_b);
45+
ClassDB::bind_method(D_METHOD("set_enabled_button_x", "enable"), &VirtualController::set_enabled_button_x);
46+
ClassDB::bind_method(D_METHOD("is_enabled_button_x"), &VirtualController::is_enabled_button_x);
47+
ClassDB::bind_method(D_METHOD("set_enabled_button_y", "enable"), &VirtualController::set_enabled_button_y);
48+
ClassDB::bind_method(D_METHOD("is_enabled_button_y"), &VirtualController::is_enabled_button_y);
49+
}

core/input/virtual_controller.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**************************************************************************/
2+
/* virtual_controller.h */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#ifndef VIRTUAL_CONTROLLER_H
32+
#define VIRTUAL_CONTROLLER_H
33+
34+
#include "core/object/class_db.h"
35+
36+
class VirtualController : public Object {
37+
GDCLASS(VirtualController, Object);
38+
39+
protected:
40+
static void _bind_methods();
41+
42+
public:
43+
virtual void enable() = 0;
44+
virtual void disable() = 0;
45+
virtual bool is_enabled() = 0;
46+
virtual void set_enabled_left_thumbstick(bool p_enabled) = 0;
47+
virtual bool is_enabled_left_thumbstick() = 0;
48+
virtual void set_enabled_right_thumbstick(bool p_enabled) = 0;
49+
virtual bool is_enabled_right_thumbstick() = 0;
50+
virtual void set_enabled_button_a(bool p_enabled) = 0;
51+
virtual bool is_enabled_button_a() = 0;
52+
virtual void set_enabled_button_b(bool p_enabled) = 0;
53+
virtual bool is_enabled_button_b() = 0;
54+
virtual void set_enabled_button_x(bool p_enabled) = 0;
55+
virtual bool is_enabled_button_x() = 0;
56+
virtual void set_enabled_button_y(bool p_enabled) = 0;
57+
virtual bool is_enabled_button_y() = 0;
58+
};
59+
60+
#endif // VIRTUAL_CONTROLLER_H

core/os/os.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,10 @@ void OS::benchmark_dump() {
700700
#endif
701701
}
702702

703+
VirtualController *OS::get_virtual_controller() const {
704+
return nullptr;
705+
}
706+
703707
OS::OS() {
704708
singleton = this;
705709

core/os/os.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define OS_H
3333

3434
#include "core/config/engine.h"
35+
#include "core/input/virtual_controller.h"
3536
#include "core/io/logger.h"
3637
#include "core/io/remote_filesystem_client.h"
3738
#include "core/os/time_enums.h"
@@ -344,6 +345,8 @@ class OS {
344345
// This is invoked by the GDExtensionManager after loading GDExtensions specified by the project.
345346
virtual void load_platform_gdextensions() const {}
346347

348+
virtual VirtualController *get_virtual_controller() const;
349+
347350
OS();
348351
virtual ~OS();
349352
};

core/register_core_types.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "core/input/input.h"
4343
#include "core/input/input_map.h"
4444
#include "core/input/shortcut.h"
45+
#include "core/input/virtual_controller.h"
4546
#include "core/io/config_file.h"
4647
#include "core/io/dir_access.h"
4748
#include "core/io/dtls_server.h"
@@ -298,6 +299,8 @@ void register_core_types() {
298299
GDREGISTER_NATIVE_STRUCT(AudioFrame, "float left;float right");
299300
GDREGISTER_NATIVE_STRUCT(ScriptLanguageExtensionProfilingInfo, "StringName signature;uint64_t call_count;uint64_t total_time;uint64_t self_time");
300301

302+
GDREGISTER_ABSTRACT_CLASS(VirtualController);
303+
301304
worker_thread_pool = memnew(WorkerThreadPool);
302305

303306
OS::get_singleton()->benchmark_end_measure("Core", "Register Types");

doc/classes/Input.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,13 @@
195195
By default, the deadzone is automatically calculated from the average of the action deadzones. However, you can override the deadzone to be whatever you want (on the range of 0 to 1).
196196
</description>
197197
</method>
198+
<method name="get_virtual_controller">
199+
<return type="VirtualController" />
200+
<description>
201+
Return platform-specific virtual controller or null. (See [VirtualController])
202+
[b]Note:[/b] Currently implemented only on iOS 15.0+.
203+
</description>
204+
</method>
198205
<method name="is_action_just_pressed" qualifiers="const">
199206
<return type="bool" />
200207
<param index="0" name="action" type="StringName" />

doc/classes/ProjectSettings.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,28 @@
14561456
<member name="input_devices/sensors/enable_magnetometer" type="bool" setter="" getter="" default="false">
14571457
If [code]true[/code], the magnetometer sensor is enabled and [method Input.get_magnetometer] returns valid data.
14581458
</member>
1459+
<member name="input_devices/virtual_controller/ios/enable_button_a" type="bool" setter="" getter="" default="true">
1460+
If [code]true[/code], the button "A" shows in the virtual controller.
1461+
</member>
1462+
<member name="input_devices/virtual_controller/ios/enable_button_b" type="bool" setter="" getter="" default="true">
1463+
If [code]true[/code], the button "B" shows in the virtual controller.
1464+
</member>
1465+
<member name="input_devices/virtual_controller/ios/enable_button_x" type="bool" setter="" getter="" default="true">
1466+
If [code]true[/code], the button "X" shows in the virtual controller.
1467+
</member>
1468+
<member name="input_devices/virtual_controller/ios/enable_button_y" type="bool" setter="" getter="" default="true">
1469+
If [code]true[/code], the button "Y" shows in the virtual controller.
1470+
</member>
1471+
<member name="input_devices/virtual_controller/ios/enable_controller" type="bool" setter="" getter="" default="false">
1472+
If [code]true[/code], if there are no physical controllers connected, the game shows the virtual controller.
1473+
[b]Note:[/b] Currently implemented only on iOS 15.0+.
1474+
</member>
1475+
<member name="input_devices/virtual_controller/ios/enable_left_thumbstick" type="bool" setter="" getter="" default="true">
1476+
If [code]true[/code], the left thumbstick shows in the virtual controller.
1477+
</member>
1478+
<member name="input_devices/virtual_controller/ios/enable_right_thumbstick" type="bool" setter="" getter="" default="true">
1479+
If [code]true[/code], the right thumbstick shows in the virtual controller.
1480+
</member>
14591481
<member name="internationalization/locale/fallback" type="String" setter="" getter="" default="&quot;en&quot;">
14601482
The locale to fall back to if a translation isn't available in a given language. If left empty, [code]en[/code] (English) will be used.
14611483
</member>

0 commit comments

Comments
 (0)