1 package org.libsdl.app;
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Comparator;
8 import android.content.Context;
10 import android.view.*;
11 import android.util.Log;
20 int vendor_id,
int product_id,
21 boolean is_accelerometer,
int button_mask,
22 int naxes,
int nhats,
int nballs);
27 public static native
int onNativePadUp(
int device_id,
int keycode);
30 public static native
void onNativeHat(
int device_id,
int hat_id,
36 private static final String
TAG =
"SDLControllerManager";
39 if (mJoystickHandler == null) {
40 if (Build.VERSION.SDK_INT >= 19) {
41 mJoystickHandler =
new SDLJoystickHandler_API19();
42 }
else if (Build.VERSION.SDK_INT >= 16) {
43 mJoystickHandler =
new SDLJoystickHandler_API16();
44 }
else if (Build.VERSION.SDK_INT >= 12) {
45 mJoystickHandler =
new SDLJoystickHandler_API12();
47 mJoystickHandler =
new SDLJoystickHandler();
51 if (mHapticHandler == null) {
52 if (Build.VERSION.SDK_INT >= 26) {
53 mHapticHandler =
new SDLHapticHandler_API26();
55 mHapticHandler =
new SDLHapticHandler();
62 return mJoystickHandler.handleMotionEvent(event);
69 mJoystickHandler.pollInputDevices();
76 mHapticHandler.pollHapticDevices();
83 mHapticHandler.run(device_id, intensity, length);
91 mHapticHandler.stop(device_id);
96 InputDevice
device = InputDevice.getDevice(deviceId);
99 if ((device == null) || (deviceId < 0)) {
102 int sources = device.getSources();
117 return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) ||
118 ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) ||
119 ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
126 class SDLJoystickHandler {
133 public boolean handleMotionEvent(MotionEvent
event) {
145 class SDLJoystickHandler_API12
extends SDLJoystickHandler {
147 static class SDLJoystick {
148 public int device_id;
151 public ArrayList<InputDevice.MotionRange> axes;
152 public ArrayList<InputDevice.MotionRange> hats;
154 static class RangeComparator
implements Comparator<InputDevice.MotionRange> {
156 public int compare(InputDevice.MotionRange arg0, InputDevice.MotionRange
arg1) {
158 int arg0Axis = arg0.getAxis();
159 int arg1Axis =
arg1.getAxis();
160 if (arg0Axis == MotionEvent.AXIS_GAS) {
161 arg0Axis = MotionEvent.AXIS_BRAKE;
162 }
else if (arg0Axis == MotionEvent.AXIS_BRAKE) {
163 arg0Axis = MotionEvent.AXIS_GAS;
165 if (arg1Axis == MotionEvent.AXIS_GAS) {
166 arg1Axis = MotionEvent.AXIS_BRAKE;
167 }
else if (arg1Axis == MotionEvent.AXIS_BRAKE) {
168 arg1Axis = MotionEvent.AXIS_GAS;
171 return arg0Axis - arg1Axis;
175 private ArrayList<SDLJoystick> mJoysticks;
177 public SDLJoystickHandler_API12() {
179 mJoysticks =
new ArrayList<SDLJoystick>();
184 int[] deviceIds = InputDevice.getDeviceIds();
185 for(
int i=0;
i < deviceIds.length; ++
i) {
186 SDLJoystick joystick = getJoystick(deviceIds[
i]);
187 if (joystick == null) {
188 joystick =
new SDLJoystick();
189 InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]);
191 joystick.device_id = deviceIds[
i];
192 joystick.name = joystickDevice.getName();
193 joystick.desc = getJoystickDescriptor(joystickDevice);
194 joystick.axes =
new ArrayList<InputDevice.MotionRange>();
195 joystick.hats =
new ArrayList<InputDevice.MotionRange>();
197 List<InputDevice.MotionRange> ranges = joystickDevice.getMotionRanges();
198 Collections.sort(ranges,
new RangeComparator());
199 for (InputDevice.MotionRange
range : ranges ) {
200 if ((
range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
201 if (
range.getAxis() == MotionEvent.AXIS_HAT_X ||
202 range.getAxis() == MotionEvent.AXIS_HAT_Y) {
203 joystick.hats.add(
range);
206 joystick.axes.add(
range);
211 mJoysticks.add(joystick);
212 SDLControllerManager.
nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, getVendorId(joystickDevice), getProductId(joystickDevice),
false, getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0);
218 ArrayList<Integer> removedDevices =
new ArrayList<Integer>();
219 for(
int i=0;
i < mJoysticks.size();
i++) {
220 int device_id = mJoysticks.get(
i).device_id;
222 for (j=0; j < deviceIds.length; j++) {
223 if (device_id == deviceIds[j])
break;
225 if (j == deviceIds.length) {
226 removedDevices.add(Integer.valueOf(device_id));
230 for(
int i=0;
i < removedDevices.size();
i++) {
231 int device_id = removedDevices.get(
i).intValue();
233 for (
int j=0;
j < mJoysticks.size();
j++) {
234 if (mJoysticks.get(
j).device_id == device_id) {
235 mJoysticks.remove(
j);
242 protected SDLJoystick getJoystick(
int device_id) {
243 for(
int i=0;
i < mJoysticks.size();
i++) {
244 if (mJoysticks.get(
i).device_id == device_id) {
245 return mJoysticks.get(
i);
252 public boolean handleMotionEvent(MotionEvent
event) {
253 if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
254 int actionPointerIndex =
event.getActionIndex();
255 int action =
event.getActionMasked();
257 case MotionEvent.ACTION_MOVE:
258 SDLJoystick joystick = getJoystick(event.getDeviceId());
259 if ( joystick != null ) {
260 for (
int i = 0;
i < joystick.axes.size();
i++) {
261 InputDevice.MotionRange
range = joystick.axes.get(
i);
263 float value = (
event.getAxisValue(
range.getAxis(), actionPointerIndex) -
range.getMin() ) /
range.getRange() * 2.0f - 1.0f;
266 for (
int i = 0;
i < joystick.hats.size();
i+=2) {
267 int hatX = Math.round(event.getAxisValue( joystick.hats.get(
i).getAxis(), actionPointerIndex ) );
268 int hatY = Math.round(event.getAxisValue( joystick.hats.get(
i+1).getAxis(), actionPointerIndex ) );
280 public String getJoystickDescriptor(InputDevice joystickDevice) {
281 return joystickDevice.getName();
283 public int getProductId(InputDevice joystickDevice) {
286 public int getVendorId(InputDevice joystickDevice) {
289 public int getButtonMask(InputDevice joystickDevice) {
294 class SDLJoystickHandler_API16
extends SDLJoystickHandler_API12 {
297 public String getJoystickDescriptor(InputDevice joystickDevice) {
298 String desc = joystickDevice.getDescriptor();
300 if (desc != null && !desc.isEmpty()) {
304 return super.getJoystickDescriptor(joystickDevice);
308 class SDLJoystickHandler_API19
extends SDLJoystickHandler_API16 {
311 public int getProductId(InputDevice joystickDevice) {
312 return joystickDevice.getProductId();
316 public int getVendorId(InputDevice joystickDevice) {
317 return joystickDevice.getVendorId();
321 public int getButtonMask(InputDevice joystickDevice) {
323 int[] keys =
new int[] {
324 KeyEvent.KEYCODE_BUTTON_A,
325 KeyEvent.KEYCODE_BUTTON_B,
326 KeyEvent.KEYCODE_BUTTON_X,
327 KeyEvent.KEYCODE_BUTTON_Y,
328 KeyEvent.KEYCODE_BACK,
329 KeyEvent.KEYCODE_BUTTON_MODE,
330 KeyEvent.KEYCODE_BUTTON_START,
331 KeyEvent.KEYCODE_BUTTON_THUMBL,
332 KeyEvent.KEYCODE_BUTTON_THUMBR,
333 KeyEvent.KEYCODE_BUTTON_L1,
334 KeyEvent.KEYCODE_BUTTON_R1,
335 KeyEvent.KEYCODE_DPAD_UP,
336 KeyEvent.KEYCODE_DPAD_DOWN,
337 KeyEvent.KEYCODE_DPAD_LEFT,
338 KeyEvent.KEYCODE_DPAD_RIGHT,
339 KeyEvent.KEYCODE_BUTTON_SELECT,
340 KeyEvent.KEYCODE_DPAD_CENTER,
343 KeyEvent.KEYCODE_BUTTON_L2,
344 KeyEvent.KEYCODE_BUTTON_R2,
345 KeyEvent.KEYCODE_BUTTON_C,
346 KeyEvent.KEYCODE_BUTTON_Z,
347 KeyEvent.KEYCODE_BUTTON_1,
348 KeyEvent.KEYCODE_BUTTON_2,
349 KeyEvent.KEYCODE_BUTTON_3,
350 KeyEvent.KEYCODE_BUTTON_4,
351 KeyEvent.KEYCODE_BUTTON_5,
352 KeyEvent.KEYCODE_BUTTON_6,
353 KeyEvent.KEYCODE_BUTTON_7,
354 KeyEvent.KEYCODE_BUTTON_8,
355 KeyEvent.KEYCODE_BUTTON_9,
356 KeyEvent.KEYCODE_BUTTON_10,
357 KeyEvent.KEYCODE_BUTTON_11,
358 KeyEvent.KEYCODE_BUTTON_12,
359 KeyEvent.KEYCODE_BUTTON_13,
360 KeyEvent.KEYCODE_BUTTON_14,
361 KeyEvent.KEYCODE_BUTTON_15,
362 KeyEvent.KEYCODE_BUTTON_16,
364 int[] masks =
new int[] {
404 boolean[] has_keys = joystickDevice.hasKeys(keys);
405 for (
int i = 0;
i < keys.length; ++
i) {
407 button_mask |= masks[
i];
414 class SDLHapticHandler_API26
extends SDLHapticHandler {
416 public void run(
int device_id,
float intensity,
int length) {
417 SDLHaptic
haptic = getHaptic(device_id);
418 if (haptic != null) {
419 Log.d(
"SDL",
"Rtest: Vibe with intensity " + intensity +
" for " + length);
420 if (intensity == 0.0
f) {
425 int vibeValue = Math.round(intensity * 255);
427 if (vibeValue > 255) {
435 haptic.vib.vibrate(VibrationEffect.createOneShot(length, vibeValue));
437 catch (Exception
e) {
440 haptic.vib.vibrate(length);
446 class SDLHapticHandler {
449 public int device_id;
454 private ArrayList<SDLHaptic> mHaptics;
456 public SDLHapticHandler() {
457 mHaptics =
new ArrayList<SDLHaptic>();
460 public void run(
int device_id,
float intensity,
int length) {
461 SDLHaptic
haptic = getHaptic(device_id);
462 if (haptic != null) {
463 haptic.vib.vibrate(length);
467 public void stop(
int device_id) {
468 SDLHaptic
haptic = getHaptic(device_id);
469 if (haptic != null) {
476 final int deviceId_VIBRATOR_SERVICE = 999999;
477 boolean hasVibratorService =
false;
479 int[] deviceIds = InputDevice.getDeviceIds();
485 if (Build.VERSION.SDK_INT >= 16)
487 for (
int i = deviceIds.length - 1;
i > -1;
i--) {
488 SDLHaptic
haptic = getHaptic(deviceIds[
i]);
489 if (haptic == null) {
490 InputDevice
device = InputDevice.getDevice(deviceIds[i]);
491 Vibrator vib = device.getVibrator();
492 if (vib.hasVibrator()) {
493 haptic =
new SDLHaptic();
494 haptic.device_id = deviceIds[
i];
495 haptic.name = device.getName();
497 mHaptics.add(haptic);
505 Vibrator vib = (Vibrator)
SDL.
getContext().getSystemService(Context.VIBRATOR_SERVICE);
507 if (Build.VERSION.SDK_INT >= 11) {
508 hasVibratorService = vib.hasVibrator();
510 hasVibratorService =
true;
513 if (hasVibratorService) {
514 SDLHaptic
haptic = getHaptic(deviceId_VIBRATOR_SERVICE);
515 if (haptic == null) {
516 haptic =
new SDLHaptic();
517 haptic.device_id = deviceId_VIBRATOR_SERVICE;
518 haptic.name =
"VIBRATOR_SERVICE";
520 mHaptics.add(haptic);
527 ArrayList<Integer> removedDevices =
new ArrayList<Integer>();
528 for(
int i=0;
i < mHaptics.size();
i++) {
529 int device_id = mHaptics.get(
i).device_id;
531 for (j=0; j < deviceIds.length; j++) {
532 if (device_id == deviceIds[j])
break;
535 if (device_id == deviceId_VIBRATOR_SERVICE && hasVibratorService) {
537 }
else if (j == deviceIds.length) {
538 removedDevices.add(device_id);
542 for(
int i=0;
i < removedDevices.size();
i++) {
543 int device_id = removedDevices.get(
i);
545 for (
int j=0;
j < mHaptics.size();
j++) {
546 if (mHaptics.get(
j).device_id == device_id) {
554 protected SDLHaptic getHaptic(
int device_id) {
555 for(
int i=0;
i < mHaptics.size();
i++) {
556 if (mHaptics.get(
i).device_id == device_id) {
557 return mHaptics.get(
i);
564 class SDLGenericMotionListener_API12
implements View.OnGenericMotionListener {
567 public boolean onGenericMotion(View
v, MotionEvent
event) {
571 switch ( event.getSource() ) {
572 case InputDevice.SOURCE_JOYSTICK:
573 case InputDevice.SOURCE_GAMEPAD:
574 case InputDevice.SOURCE_DPAD:
577 case InputDevice.SOURCE_MOUSE:
581 action =
event.getActionMasked();
583 case MotionEvent.ACTION_SCROLL:
584 x =
event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
585 y =
event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
589 case MotionEvent.ACTION_HOVER_MOVE:
609 public boolean supportsRelativeMouse() {
613 public boolean inRelativeMode() {
617 public boolean setRelativeMouseEnabled(
boolean enabled) {
621 public void reclaimRelativeMouseModeIfNeeded()
626 public float getEventX(MotionEvent event) {
627 return event.getX(0);
630 public float getEventY(MotionEvent event) {
631 return event.getY(0);
636 class SDLGenericMotionListener_API24
extends SDLGenericMotionListener_API12 {
639 private boolean mRelativeModeEnabled;
642 public boolean onGenericMotion(View
v, MotionEvent
event) {
646 switch ( event.getSource() ) {
647 case InputDevice.SOURCE_JOYSTICK:
648 case InputDevice.SOURCE_GAMEPAD:
649 case InputDevice.SOURCE_DPAD:
652 case InputDevice.SOURCE_MOUSE:
656 action =
event.getActionMasked();
658 case MotionEvent.ACTION_SCROLL:
659 x =
event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
660 y =
event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
664 case MotionEvent.ACTION_HOVER_MOVE:
665 if (mRelativeModeEnabled) {
666 x =
event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
667 y =
event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
691 public boolean supportsRelativeMouse() {
696 public boolean inRelativeMode() {
697 return mRelativeModeEnabled;
701 public boolean setRelativeMouseEnabled(
boolean enabled) {
702 mRelativeModeEnabled =
enabled;
707 public float getEventX(MotionEvent event) {
708 if (mRelativeModeEnabled) {
709 return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
712 return event.getX(0);
717 public float getEventY(MotionEvent event) {
718 if (mRelativeModeEnabled) {
719 return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
722 return event.getY(0);
728 class SDLGenericMotionListener_API26
extends SDLGenericMotionListener_API24 {
730 private boolean mRelativeModeEnabled;
733 public boolean onGenericMotion(View
v, MotionEvent
event) {
737 switch ( event.getSource() ) {
738 case InputDevice.SOURCE_JOYSTICK:
739 case InputDevice.SOURCE_GAMEPAD:
740 case InputDevice.SOURCE_DPAD:
743 case InputDevice.SOURCE_MOUSE:
749 action =
event.getActionMasked();
751 case MotionEvent.ACTION_SCROLL:
752 x =
event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
753 y =
event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
757 case MotionEvent.ACTION_HOVER_MOVE:
768 case InputDevice.SOURCE_MOUSE_RELATIVE:
772 action =
event.getActionMasked();
774 case MotionEvent.ACTION_SCROLL:
775 x =
event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
776 y =
event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
780 case MotionEvent.ACTION_HOVER_MOVE:
800 public boolean supportsRelativeMouse() {
805 public boolean inRelativeMode() {
806 return mRelativeModeEnabled;
810 public boolean setRelativeMouseEnabled(
boolean enabled) {
818 mRelativeModeEnabled =
enabled;
828 public void reclaimRelativeMouseModeIfNeeded()
836 public float getEventX(MotionEvent event) {
838 return event.getX(0);
842 public float getEventY(MotionEvent event) {
844 return event.getY(0);
static boolean isDeXMode()
static boolean isDeviceSDLJoystick(int deviceId)
static native int nativeAddJoystick(int device_id, String name, String desc, int vendor_id, int product_id, boolean is_accelerometer, int button_mask, int naxes, int nhats, int nballs)
static void hapticRun(int device_id, float intensity, int length)
static void hapticStop(int device_id)
static native void onNativeMouse(int button, int action, float x, float y, boolean relative)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
static native int nativeRemoveHaptic(int device_id)
GLint GLint GLint GLint GLint x
GLuint GLuint GLuint GLuint arg1
static native int onNativePadUp(int device_id, int keycode)
static native int onNativePadDown(int device_id, int keycode)
static View getContentView()
static boolean handleJoystickMotionEvent(MotionEvent event)
GLuint const GLchar * name
static native int nativeSetupJNI()
static native void onNativeJoy(int device_id, int axis, float value)
static SDL_AudioDeviceID device
static void pollHapticDevices()
static void pollInputDevices()
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
static boolean mSeparateMouseAndTouch
GLsizei const GLfloat * value
static SDLHapticHandler mHapticHandler
GLint GLint GLint GLint GLint GLint y
static native int nativeRemoveJoystick(int device_id)
GLenum GLenum GLsizei const GLuint GLboolean enabled
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
static SDLJoystickHandler mJoystickHandler
static native void onNativeHat(int device_id, int hat_id, int x, int y)
static SDL_Haptic * haptic
static Context getContext()
static native int nativeAddHaptic(int device_id, String name)
GLuint GLsizei GLsizei * length