Added basic android gamepad support (#97)

This commit is contained in:
saschawillems 2016-03-20 21:46:49 +01:00
parent bc71f44c75
commit d7bbb0c7a2
3 changed files with 62 additions and 0 deletions

View file

@ -368,6 +368,34 @@ void VulkanExampleBase::renderLoop()
if (prepared) if (prepared)
{ {
render(); render();
// Check gamepad state
const float deadZone = 0.10f;
// todo : check if gamepad is present
// todo : time based and relative axis positions
bool updateView = false;
// Rotate
if (abs(gamePadState.axes.x) > deadZone)
{
rotation.y += gamePadState.axes.x * 0.25f * rotationSpeed;
updateView = true;
}
if (abs(gamePadState.axes.y) > deadZone)
{
rotation.x -= gamePadState.axes.y * 0.25f * rotationSpeed;
updateView = true;
}
// Zoom
if (abs(gamePadState.axes.rz) > deadZone)
{
zoom -= gamePadState.axes.rz * 0.005f * zoomSpeed;
updateView = true;
}
if (updateView)
{
viewChanged();
}
} }
} }
#elif defined(__linux__) #elif defined(__linux__)
@ -892,6 +920,27 @@ void VulkanExampleBase::handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
} }
} }
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
int32_t VulkanExampleBase::handleAppInput(struct android_app* app, AInputEvent* event)
{
VulkanExampleBase* vulkanExample = (VulkanExampleBase*)app->userData;
if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
{
if (AInputEvent_getSource(event) == AINPUT_SOURCE_JOYSTICK)
{
vulkanExample->gamePadState.axes.x = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_X, 0);
vulkanExample->gamePadState.axes.y = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_Y, 0);
vulkanExample->gamePadState.axes.z = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_Z, 0);
vulkanExample->gamePadState.axes.rz = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_RZ, 0);
}
else
{
// todo : touch input
}
return 1;
}
return 0;
}
void VulkanExampleBase::handleAppCommand(android_app * app, int32_t cmd) void VulkanExampleBase::handleAppCommand(android_app * app, int32_t cmd)
{ {
assert(app->userData != NULL); assert(app->userData != NULL);

View file

@ -158,6 +158,17 @@ public:
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
android_app* androidApp; android_app* androidApp;
bool animating = true; bool animating = true;
// Gamepad state (only one)
struct
{
struct
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
float rz = 0.0f;
} axes;
} gamePadState;
#elif defined(__linux__) #elif defined(__linux__)
struct { struct {
bool left = false; bool left = false;
@ -182,6 +193,7 @@ public:
HWND setupWindow(HINSTANCE hinstance, WNDPROC wndproc); HWND setupWindow(HINSTANCE hinstance, WNDPROC wndproc);
void handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void handleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
static int32_t handleAppInput(struct android_app* app, AInputEvent* event);
static void handleAppCommand(android_app* app, int32_t cmd); static void handleAppCommand(android_app* app, int32_t cmd);
#elif defined(__linux__) #elif defined(__linux__)
xcb_window_t setupWindow(); xcb_window_t setupWindow();

View file

@ -927,6 +927,7 @@ int main(const int argc, const char *argv[])
// Attach vulkan example to global android application state // Attach vulkan example to global android application state
state->userData = vulkanExample; state->userData = vulkanExample;
state->onAppCmd = VulkanExample::handleAppCommand; state->onAppCmd = VulkanExample::handleAppCommand;
state->onInputEvent = VulkanExample::handleAppInput;
vulkanExample->androidApp = state; vulkanExample->androidApp = state;
#elif defined(__linux__) #elif defined(__linux__)
vulkanExample->setupWindow(); vulkanExample->setupWindow();