Jelajahi Sumber

Add basic infrastructure for joypad support

Daniele Bartolini 10 tahun lalu
induk
melakukan
ae76f08adb

+ 44 - 1
src/core/os_event_queue.h

@@ -67,6 +67,23 @@ struct OsTouchEvent
 	bool pressed;
 };
 
+/// Represents an event fired by joystick
+struct OsJoypadEvent
+{
+	enum Enum
+	{
+		BUTTON,
+		AXIS
+	};
+
+	OsJoypadEvent::Enum type;
+	uint8_t button;
+	bool pressed;
+	float x;
+	float y;
+	float z;
+};
+
 /// Represents an event fired by accelerometer.
 struct OsAccelerometerEvent
 {
@@ -85,6 +102,7 @@ struct OsEvent
 		KEYBOARD,
 		MOUSE,
 		TOUCH,
+		JOYPAD,
 		ACCELEROMETER,
 
 		METRICS,
@@ -102,11 +120,12 @@ struct OsEvent
 		OsMouseEvent mouse;
 		OsKeyboardEvent keyboard;
 		OsTouchEvent touch;
+		OsJoypadEvent joypad;
 		OsAccelerometerEvent accelerometer;
 	};
 };
 
-#define MAX_OS_EVENTS 64
+#define MAX_OS_EVENTS 4096
 
 /// Single Producer Single Consumer event queue.
 /// Used only to pass events from os thread to main thread.
@@ -176,6 +195,30 @@ struct OsEventQueue
 		push_event(ev);
 	}
 
+	void push_joypad_event(uint8_t button, bool pressed)
+	{
+		OsEvent ev;
+		ev.type = OsEvent::JOYPAD;
+		ev.joypad.type = OsJoypadEvent::BUTTON;
+		ev.joypad.button = button;
+		ev.joypad.pressed = pressed;
+
+		push_event(ev);
+	}
+
+	void push_joypad_event(uint8_t axis, float x, float y, float z)
+	{
+		OsEvent ev;
+		ev.type = OsEvent::JOYPAD;
+		ev.joypad.type = OsJoypadEvent::AXIS;
+		ev.joypad.button = axis;
+		ev.joypad.x = x;
+		ev.joypad.y = y;
+		ev.joypad.z = z;
+
+		push_event(ev);
+	}
+
 	void push_touch_event(int16_t x, int16_t y, uint8_t pointer_id, bool pressed)
 	{
 		OsEvent ev;

+ 9 - 0
src/input/input_manager.cpp

@@ -16,14 +16,17 @@ InputManager::InputManager()
 	: _keyboard(NULL)
 	, _mouse(NULL)
 	, _touch(NULL)
+	, _joypad(NULL)
 {
 	_keyboard = create_input_device("Keyboard", KeyboardButton::COUNT, 0);
 	_mouse = create_input_device("Mouse", MouseButton::COUNT, 2);
 	_touch = create_input_device("Touch", TouchButton::COUNT, TouchButton::COUNT);
+	_joypad = create_input_device("Joypad", JoypadButton::COUNT, JoypadAxis::COUNT);
 }
 
 InputManager::~InputManager()
 {
+	default_allocator().deallocate(_joypad);
 	default_allocator().deallocate(_touch);
 	default_allocator().deallocate(_mouse);
 	default_allocator().deallocate(_keyboard);
@@ -71,11 +74,17 @@ InputDevice* InputManager::touch()
 	return _touch;
 }
 
+InputDevice* InputManager::joypad()
+{
+	return _joypad;
+}
+
 void InputManager::update()
 {
 	_keyboard->update();
 	_mouse->update();
 	_touch->update();
+	_joypad->update();
 }
 
 } // namespace crown

+ 4 - 0
src/input/input_manager.h

@@ -30,6 +30,9 @@ public:
 	/// Returns the default touch input device.
 	InputDevice* touch();
 
+	/// Returns the default joypad input device.
+	InputDevice* joypad();
+
 	/// Updates the input devices
 	void update();
 
@@ -38,6 +41,7 @@ private:
 	InputDevice* _keyboard;
 	InputDevice* _mouse;
 	InputDevice* _touch;
+	InputDevice* _joypad;
 };
 
 } // namespace crown

+ 43 - 0
src/input/input_types.h

@@ -8,6 +8,8 @@
 namespace crown
 {
 
+/// @defgroup Input Input
+
 class InputManager;
 struct InputDevice;
 
@@ -136,6 +138,8 @@ struct MouseButton
 };
 
 /// Enumerates touch panel buttons
+///
+/// @ingroup Input
 struct TouchButton
 {
 	enum Enum
@@ -148,4 +152,43 @@ struct TouchButton
 	};
 };
 
+/// Enumerates joypad buttons.
+///
+/// @ingroup Input
+struct JoypadButton
+{
+	enum Enum
+	{
+		UP,
+		DOWN,
+		LEFT,
+		RIGHT,
+		START,
+		BACK,
+		GUIDE,
+		LEFT_THUMB,
+		RIGHT_THUMB,
+		LEFT_SHOULDER,
+		RIGHT_SHOULDER,
+		A,
+		B,
+		X,
+		Y,
+		COUNT
+	};
+};
+
+/// Enumerates joypad axes.
+///
+/// @ingroup Input
+struct JoypadAxis
+{
+	enum Enum
+	{
+		LEFT,
+		RIGHT,
+		COUNT
+	};
+};
+
 } // namespace crown

+ 83 - 0
src/lua/lua_input.cpp

@@ -173,6 +173,62 @@ static int touch_axis(lua_State* L)
 	return 1;
 }
 
+static int joypad_name(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.push_string(device()->input_manager()->joypad()->name());
+	return 1;
+}
+
+static int joypad_num_buttons(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.push_uint32(device()->input_manager()->joypad()->num_buttons());
+	return 1;
+}
+
+static int joypad_num_axes(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.push_uint32(device()->input_manager()->joypad()->num_axes());
+	return 1;
+}
+
+static int joypad_pressed(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.push_bool(device()->input_manager()->joypad()->pressed((MouseButton::Enum) stack.get_int(1)));
+	return 1;
+}
+
+static int joypad_released(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.push_bool(device()->input_manager()->joypad()->released((MouseButton::Enum) stack.get_int(1)));
+	return 1;
+}
+
+static int joypad_any_pressed(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.push_bool(device()->input_manager()->joypad()->any_pressed());
+	return 1;
+}
+
+static int joypad_any_released(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.push_bool(device()->input_manager()->joypad()->any_released());
+	return 1;
+}
+
+static int joypad_axis(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.push_vector3(device()->input_manager()->joypad()->axis(stack.get_int(1)));
+	return 1;
+}
+
 void load_input(LuaEnvironment& env)
 {
 	env.load_module_function("Keyboard", "name",         keyboard_name);
@@ -284,6 +340,33 @@ void load_input(LuaEnvironment& env)
 	env.load_module_function("Touch", "any_pressed",  touch_any_pressed);
 	env.load_module_function("Touch", "any_released", touch_any_released);
 	env.load_module_function("Touch", "axis",         touch_axis);
+
+	env.load_module_function("Joypad", "name",         joypad_name);
+	env.load_module_function("Joypad", "num_buttons",  joypad_num_buttons);
+	env.load_module_function("Joypad", "num_axes",     joypad_num_axes);
+	env.load_module_function("Joypad", "pressed",      joypad_pressed);
+	env.load_module_function("Joypad", "released",     joypad_released);
+	env.load_module_function("Joypad", "any_pressed",  joypad_any_pressed);
+	env.load_module_function("Joypad", "any_released", joypad_any_released);
+	env.load_module_function("Joypad", "axis",         joypad_axis);
+
+	env.load_module_enum("JoypadButton", "UP",             JoypadButton::UP);
+	env.load_module_enum("JoypadButton", "DOWN",           JoypadButton::DOWN);
+	env.load_module_enum("JoypadButton", "LEFT",           JoypadButton::LEFT);
+	env.load_module_enum("JoypadButton", "RIGHT",          JoypadButton::RIGHT);
+	env.load_module_enum("JoypadButton", "START",          JoypadButton::START);
+	env.load_module_enum("JoypadButton", "BACK",           JoypadButton::BACK);
+	env.load_module_enum("JoypadButton", "LEFT_THUMB",     JoypadButton::LEFT_THUMB);
+	env.load_module_enum("JoypadButton", "RIGHT_THUMB",    JoypadButton::RIGHT_THUMB);
+	env.load_module_enum("JoypadButton", "LEFT_SHOULDER",  JoypadButton::LEFT_SHOULDER);
+	env.load_module_enum("JoypadButton", "RIGHT_SHOULDER", JoypadButton::RIGHT_SHOULDER);
+	env.load_module_enum("JoypadButton", "A",              JoypadButton::A);
+	env.load_module_enum("JoypadButton", "B",              JoypadButton::B);
+	env.load_module_enum("JoypadButton", "X",              JoypadButton::X);
+	env.load_module_enum("JoypadButton", "Y",              JoypadButton::Y);
+
+	env.load_module_enum("JoypadAxis", "LEFT",    JoypadAxis::LEFT);
+	env.load_module_enum("JoypadAxis", "RIGHT",   JoypadAxis::RIGHT);
 }
 
 } // namespace crown

+ 19 - 2
src/main/main.cpp

@@ -39,7 +39,7 @@ bool process_events()
 						im->touch()->set_axis(ev.pointer_id, vector3(ev.x, ev.y, 0.0f));
 						break;
 					default:
-						CE_FATAL("Oops, unknown touch event type");
+						CE_FATAL("Unknown touch event type");
 						break;
 				}
 				break;
@@ -59,7 +59,7 @@ bool process_events()
 						im->mouse()->set_axis(1, vector3(ev.wheel, 0.0f, 0.0f));
 						break;
 					default:
-						CE_FATAL("Oops, unknown mouse event type");
+						CE_FATAL("Unknown mouse event type");
 						break;
 				}
 				break;
@@ -70,6 +70,23 @@ bool process_events()
 				im->keyboard()->set_button_state(ev.button, ev.pressed);
 				break;
 			}
+			case OsEvent::JOYPAD:
+			{
+				const OsJoypadEvent& ev = event.joypad;
+				switch (ev.type)
+				{
+					case OsJoypadEvent::BUTTON:
+						im->joypad()->set_button_state(ev.button, ev.pressed);
+						break;
+					case OsJoypadEvent::AXIS:
+						im->joypad()->set_axis(ev.button, vector3(ev.x, ev.y, ev.z));
+						break;
+					default:
+						CE_FATAL("Unknown joypad event");
+						break;
+				}
+				break;
+			}
 			case OsEvent::METRICS:
 			{
 				const OsMetricsEvent& ev = event.metrics;