Add lime.ui.Joystick and dispatch joystick events

This commit is contained in:
Joshua Granick
2015-10-05 18:48:36 -07:00
parent 283e13386b
commit 8daeb8f1d8
14 changed files with 859 additions and 29 deletions

View File

@@ -196,6 +196,7 @@
<file name="src/backend/sdl/SDLWindow.cpp" />
<file name="src/backend/sdl/SDLRenderer.cpp" />
<file name="src/backend/sdl/SDLGamepad.cpp" />
<file name="src/backend/sdl/SDLJoystick.cpp" />
<file name="src/backend/sdl/SDLMouse.cpp" />
<file name="src/backend/sdl/SDLSystem.cpp" />
@@ -224,6 +225,7 @@
<file name="src/system/JNI.cpp" if="android" />
<file name="src/system/SensorEvent.cpp" />
<file name="src/ui/GamepadEvent.cpp" />
<file name="src/ui/JoystickEvent.cpp" />
<file name="src/ui/KeyEvent.cpp" />
<file name="src/ui/MouseEvent.cpp" />
<file name="src/ui/TextEvent.cpp" />

View File

@@ -10,11 +10,11 @@ namespace lime {
enum GamepadEventType {
AXIS_MOVE,
BUTTON_DOWN,
BUTTON_UP,
CONNECT,
DISCONNECT
GAMEPAD_AXIS_MOVE,
GAMEPAD_BUTTON_DOWN,
GAMEPAD_BUTTON_UP,
GAMEPAD_CONNECT,
GAMEPAD_DISCONNECT
};

View File

@@ -0,0 +1,25 @@
#ifndef LIME_UI_JOYSTICK_H
#define LIME_UI_JOYSTICK_H
namespace lime {
class Joystick {
public:
static const char* GetDeviceGUID (int id);
static const char* GetDeviceName (int id);
static int GetNumAxes (int id);
static int GetNumButtons (int id);
static int GetNumHats (int id);
static int GetNumTrackballs (int id);
};
}
#endif

View File

@@ -0,0 +1,48 @@
#ifndef LIME_UI_JOYSTICK_EVENT_H
#define LIME_UI_JOYSTICK_EVENT_H
#include <hx/CFFI.h>
namespace lime {
enum JoystickEventType {
JOYSTICK_AXIS_MOVE,
JOYSTICK_HAT_MOVE,
JOYSTICK_TRACKBALL_MOVE,
JOYSTICK_BUTTON_DOWN,
JOYSTICK_BUTTON_UP,
JOYSTICK_CONNECT,
JOYSTICK_DISCONNECT
};
class JoystickEvent {
public:
static AutoGCRoot* callback;
static AutoGCRoot* eventObject;
JoystickEvent ();
static void Dispatch (JoystickEvent* event);
double eventValue;
int id;
int index;
JoystickEventType type;
int x;
int y;
};
}
#endif

View File

@@ -31,6 +31,8 @@
#include <ui/FileDialog.h>
#include <ui/Gamepad.h>
#include <ui/GamepadEvent.h>
#include <ui/Joystick.h>
#include <ui/JoystickEvent.h>
#include <ui/KeyEvent.h>
#include <ui/Mouse.h>
#include <ui/MouseCursor.h>
@@ -784,6 +786,58 @@ namespace lime {
}
void lime_joystick_event_manager_register (value callback, value eventObject) {
JoystickEvent::callback = new AutoGCRoot (callback);
JoystickEvent::eventObject = new AutoGCRoot (eventObject);
}
value lime_joystick_get_device_guid (int id) {
const char* guid = Joystick::GetDeviceGUID (id);
return guid ? alloc_string (guid) : alloc_null ();
}
value lime_joystick_get_device_name (int id) {
const char* name = Joystick::GetDeviceName (id);
return name ? alloc_string (name) : alloc_null ();
}
int lime_joystick_get_num_axes (int id) {
return Joystick::GetNumAxes (id);
}
int lime_joystick_get_num_buttons (int id) {
return Joystick::GetNumButtons (id);
}
int lime_joystick_get_num_hats (int id) {
return Joystick::GetNumHats (id);
}
int lime_joystick_get_num_trackballs (int id) {
return Joystick::GetNumTrackballs (id);
}
value lime_jpeg_decode_bytes (value data, bool decodeData) {
ImageBuffer imageBuffer;
@@ -1358,6 +1412,13 @@ namespace lime {
DEFINE_PRIME3 (lime_image_encode);
DEFINE_PRIME1 (lime_image_load);
DEFINE_PRIME0 (lime_jni_getenv);
DEFINE_PRIME2v (lime_joystick_event_manager_register);
DEFINE_PRIME1 (lime_joystick_get_device_guid);
DEFINE_PRIME1 (lime_joystick_get_device_name);
DEFINE_PRIME1 (lime_joystick_get_num_axes);
DEFINE_PRIME1 (lime_joystick_get_num_buttons);
DEFINE_PRIME1 (lime_joystick_get_num_hats);
DEFINE_PRIME1 (lime_joystick_get_num_trackballs);
DEFINE_PRIME2 (lime_jpeg_decode_bytes);
DEFINE_PRIME2 (lime_jpeg_decode_file);
DEFINE_PRIME2v (lime_key_event_manager_register);

View File

@@ -1,5 +1,6 @@
#include "SDLApplication.h"
#include "SDLGamepad.h"
#include "SDLJoystick.h"
#ifdef HX_MACOS
#include <CoreFoundation/CoreFoundation.h>
@@ -16,8 +17,6 @@ namespace lime {
AutoGCRoot* Application::callback = 0;
SDLApplication* SDLApplication::currentApplication = 0;
static SDL_Joystick* accelerometer = 0;
static SDL_JoystickID accelerometerID = 0;
const int analogAxisDeadZone = 1000;
std::map<int, std::map<int, int> > gamepadsAxisMap;
@@ -46,6 +45,7 @@ namespace lime {
ApplicationEvent applicationEvent;
GamepadEvent gamepadEvent;
JoystickEvent joystickEvent;
KeyEvent keyEvent;
MouseEvent mouseEvent;
RenderEvent renderEvent;
@@ -54,18 +54,7 @@ namespace lime {
TouchEvent touchEvent;
WindowEvent windowEvent;
#if defined(IOS) || defined(ANDROID) || defined(TVOS)
for (int i = 0; i < SDL_NumJoysticks (); i++) {
if (strstr (SDL_JoystickNameForIndex (i), "Accelerometer")) {
accelerometer = SDL_JoystickOpen (i);
accelerometerID = SDL_JoystickInstanceID (accelerometer);
}
}
#endif
SDLJoystick::Init ();
#ifdef HX_MACOS
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ());
@@ -166,13 +155,16 @@ namespace lime {
case SDL_JOYAXISMOTION:
#if defined(IOS) || defined(ANDROID) || defined(TVOS)
if (event->jaxis.which == accelerometerID) {
if (SDLJoystick::IsAccelerometer (event->jaxis.which)) {
ProcessSensorEvent (event);
} else {
ProcessJoystickEvent (event);
}
#endif
break;
case SDL_JOYBALLMOTION:
@@ -182,7 +174,7 @@ namespace lime {
case SDL_JOYDEVICEADDED:
case SDL_JOYDEVICEREMOVED:
//joy
ProcessJoystickEvent (event);
break;
case SDL_KEYDOWN:
@@ -279,7 +271,7 @@ namespace lime {
}
gamepadEvent.type = AXIS_MOVE;
gamepadEvent.type = GAMEPAD_AXIS_MOVE;
gamepadEvent.axis = event->caxis.axis;
gamepadEvent.id = event->caxis.which;
@@ -305,7 +297,7 @@ namespace lime {
case SDL_CONTROLLERBUTTONDOWN:
gamepadEvent.type = BUTTON_DOWN;
gamepadEvent.type = GAMEPAD_BUTTON_DOWN;
gamepadEvent.button = event->cbutton.button;
gamepadEvent.id = event->cbutton.which;
@@ -314,7 +306,7 @@ namespace lime {
case SDL_CONTROLLERBUTTONUP:
gamepadEvent.type = BUTTON_UP;
gamepadEvent.type = GAMEPAD_BUTTON_UP;
gamepadEvent.button = event->cbutton.button;
gamepadEvent.id = event->cbutton.which;
@@ -325,7 +317,7 @@ namespace lime {
if (SDLGamepad::Connect (event->cdevice.which)) {
gamepadEvent.type = CONNECT;
gamepadEvent.type = GAMEPAD_CONNECT;
gamepadEvent.id = SDLGamepad::GetInstanceID (event->cdevice.which);
GamepadEvent::Dispatch (&gamepadEvent);
@@ -336,7 +328,7 @@ namespace lime {
case SDL_CONTROLLERDEVICEREMOVED: {
gamepadEvent.type = DISCONNECT;
gamepadEvent.type = GAMEPAD_DISCONNECT;
gamepadEvent.id = event->cdevice.which;
GamepadEvent::Dispatch (&gamepadEvent);
@@ -352,6 +344,113 @@ namespace lime {
}
void SDLApplication::ProcessJoystickEvent (SDL_Event* event) {
if (JoystickEvent::callback) {
switch (event->type) {
case SDL_JOYAXISMOTION:
if (!SDLJoystick::IsAccelerometer (event->jaxis.which)) {
joystickEvent.type = JOYSTICK_AXIS_MOVE;
joystickEvent.index = event->jaxis.axis;
joystickEvent.eventValue = event->jaxis.value / (event->jaxis.value > 0 ? 32767.0 : 32768.0);
joystickEvent.id = event->jaxis.which;
JoystickEvent::Dispatch (&joystickEvent);
}
break;
case SDL_JOYBALLMOTION:
if (!SDLJoystick::IsAccelerometer (event->jball.which)) {
joystickEvent.type = JOYSTICK_TRACKBALL_MOVE;
joystickEvent.index = event->jball.ball;
joystickEvent.x = event->jball.xrel;
joystickEvent.y = event->jball.yrel;
joystickEvent.id = event->jball.which;
JoystickEvent::Dispatch (&joystickEvent);
}
break;
case SDL_JOYBUTTONDOWN:
if (!SDLJoystick::IsAccelerometer (event->jbutton.which)) {
joystickEvent.type = JOYSTICK_BUTTON_DOWN;
joystickEvent.index = event->jbutton.button;
joystickEvent.id = event->jbutton.which;
JoystickEvent::Dispatch (&joystickEvent);
}
break;
case SDL_JOYBUTTONUP:
if (!SDLJoystick::IsAccelerometer (event->jbutton.which)) {
joystickEvent.type = JOYSTICK_BUTTON_UP;
joystickEvent.index = event->jbutton.button;
joystickEvent.id = event->jbutton.which;
JoystickEvent::Dispatch (&joystickEvent);
}
break;
case SDL_JOYHATMOTION:
if (!SDLJoystick::IsAccelerometer (event->jhat.which)) {
joystickEvent.type = JOYSTICK_HAT_MOVE;
joystickEvent.index = event->jhat.hat;
joystickEvent.x = event->jhat.value;
joystickEvent.id = event->jhat.which;
JoystickEvent::Dispatch (&joystickEvent);
}
break;
case SDL_JOYDEVICEADDED:
if (SDLJoystick::Connect (event->jdevice.which)) {
joystickEvent.type = JOYSTICK_CONNECT;
joystickEvent.id = event->jdevice.which;
JoystickEvent::Dispatch (&joystickEvent);
}
break;
case SDL_JOYDEVICEREMOVED:
if (!SDLJoystick::IsAccelerometer (event->jdevice.which)) {
joystickEvent.type = JOYSTICK_DISCONNECT;
joystickEvent.id = event->jdevice.which;
JoystickEvent::Dispatch (&joystickEvent);
SDLJoystick::Disconnect (event->jdevice.which);
}
break;
}
}
}
void SDLApplication::ProcessKeyEvent (SDL_Event* event) {
if (KeyEvent::callback) {

View File

@@ -8,6 +8,7 @@
#include <graphics/RenderEvent.h>
#include <system/SensorEvent.h>
#include <ui/GamepadEvent.h>
#include <ui/JoystickEvent.h>
#include <ui/KeyEvent.h>
#include <ui/MouseEvent.h>
#include <ui/TextEvent.h>
@@ -38,6 +39,7 @@ namespace lime {
void HandleEvent (SDL_Event* event);
void ProcessGamepadEvent (SDL_Event* event);
void ProcessJoystickEvent (SDL_Event* event);
void ProcessKeyEvent (SDL_Event* event);
void ProcessMouseEvent (SDL_Event* event);
void ProcessSensorEvent (SDL_Event* event);
@@ -55,6 +57,7 @@ namespace lime {
Uint32 currentUpdate;
double framePeriod;
GamepadEvent gamepadEvent;
JoystickEvent joystickEvent;
KeyEvent keyEvent;
Uint32 lastUpdate;
MouseEvent mouseEvent;

View File

@@ -0,0 +1,118 @@
#include "SDLJoystick.h"
namespace lime {
static SDL_Joystick* accelerometer = 0;
static SDL_JoystickID accelerometerID = -1;
std::map<int, SDL_Joystick*> joysticks = std::map<int, SDL_Joystick*> ();
bool SDLJoystick::Connect (int id) {
if (id != accelerometerID) {
SDL_Joystick* joystick = SDL_JoystickOpen (id);
if (joystick) {
joysticks[id] = joystick;
return true;
}
}
return false;
}
bool SDLJoystick::Disconnect (int id) {
if (joysticks.find (id) != joysticks.end ()) {
SDL_Joystick* joystick = joysticks[id];
SDL_JoystickClose (joystick);
joysticks.erase (id);
return true;
}
return false;
}
void SDLJoystick::Init () {
#if defined(IOS) || defined(ANDROID) || defined(TVOS)
for (int i = 0; i < SDL_NumJoysticks (); i++) {
if (strstr (SDL_JoystickNameForIndex (i), "Accelerometer")) {
accelerometer = SDL_JoystickOpen (i);
accelerometerID = SDL_JoystickInstanceID (accelerometer);
}
}
#endif
}
bool SDLJoystick::IsAccelerometer (int id) {
return (id == accelerometerID);
}
const char* Joystick::GetDeviceGUID (int id) {
char* guid = new char[64];
SDL_JoystickGetGUIDString (SDL_JoystickGetDeviceGUID (id), guid, 64);
return guid;
}
const char* Joystick::GetDeviceName (int id) {
return SDL_JoystickName (joysticks[id]);
}
int Joystick::GetNumAxes (int id) {
return SDL_JoystickNumAxes (joysticks[id]);
}
int Joystick::GetNumButtons (int id) {
return SDL_JoystickNumButtons (joysticks[id]);
}
int Joystick::GetNumHats (int id) {
return SDL_JoystickNumHats (joysticks[id]);
}
int Joystick::GetNumTrackballs (int id) {
return SDL_JoystickNumBalls (joysticks[id]);
}
}

View File

@@ -0,0 +1,28 @@
#ifndef LIME_SDL_JOYSTICK_H
#define LIME_SDL_JOYSTICK_H
#include <SDL.h>
#include <ui/Joystick.h>
#include <map>
namespace lime {
class SDLJoystick {
public:
static bool Connect (int id);
static bool Disconnect (int id);
static void Init ();
static bool IsAccelerometer (int id);
};
}
#endif

View File

@@ -22,7 +22,7 @@ namespace lime {
axisValue = 0;
button = 0;
id = 0;
type = AXIS_MOVE;
type = GAMEPAD_AXIS_MOVE;
}

View File

@@ -0,0 +1,64 @@
#include <hx/CFFI.h>
#include <ui/JoystickEvent.h>
namespace lime {
AutoGCRoot* JoystickEvent::callback = 0;
AutoGCRoot* JoystickEvent::eventObject = 0;
static int id_id;
static int id_index;
static int id_type;
static int id_value;
static int id_x;
static int id_y;
static bool init = false;
JoystickEvent::JoystickEvent () {
id = 0;
index = 0;
eventValue = 0;
x = 0;
y = 0;
type = JOYSTICK_AXIS_MOVE;
}
void JoystickEvent::Dispatch (JoystickEvent* event) {
if (JoystickEvent::callback) {
if (!init) {
id_id = val_id ("id");
id_index = val_id ("index");
id_type = val_id ("type");
id_value = val_id ("value");
id_x = val_id ("x");
id_y = val_id ("y");
init = true;
}
value object = (JoystickEvent::eventObject ? JoystickEvent::eventObject->get () : alloc_empty_object ());
alloc_field (object, id_id, alloc_int (event->id));
alloc_field (object, id_index, alloc_int (event->index));
alloc_field (object, id_type, alloc_int (event->type));
alloc_field (object, id_value, alloc_float (event->eventValue));
alloc_field (object, id_x, alloc_int (event->x));
alloc_field (object, id_y, alloc_int (event->y));
val_call0 (JoystickEvent::callback->get ());
}
}
}