mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 19:28:57 +01:00
mobile/ebitenmobileview: Implement gamepads' SDLID on Android
Fixes #1083
This commit is contained in:
parent
4ec49dd4cf
commit
bc3d1393a6
@ -532,7 +532,140 @@ public class EbitenView extends ViewGroup implements InputManager.InputDeviceLis
|
||||
axisNum--;
|
||||
}
|
||||
|
||||
Ebitenmobileview.onGamepadAdded(deviceId, inputDevice.getName(), buttonNum, axisNum);
|
||||
String descriptor = inputDevice.getDescriptor();
|
||||
int vendorId = inputDevice.getVendorId();
|
||||
int productId = inputDevice.getProductId();
|
||||
|
||||
// These values are required to calculate SDL's GUID.
|
||||
int buttonMask = getButtonMask(inputDevice);
|
||||
int axisMask = getAxisMask(inputDevice);
|
||||
|
||||
Ebitenmobileview.onGamepadAdded(deviceId, inputDevice.getName(), buttonNum, axisNum, descriptor, vendorId, productId, buttonMask, axisMask);
|
||||
}
|
||||
|
||||
// The implementation is copied from SDL:
|
||||
// https://hg.libsdl.org/SDL/file/bc90ce38f1e2/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java#l308
|
||||
private int getButtonMask(InputDevice joystickDevice) {
|
||||
int button_mask = 0;
|
||||
int[] keys = new int[] {
|
||||
KeyEvent.KEYCODE_BUTTON_A,
|
||||
KeyEvent.KEYCODE_BUTTON_B,
|
||||
KeyEvent.KEYCODE_BUTTON_X,
|
||||
KeyEvent.KEYCODE_BUTTON_Y,
|
||||
KeyEvent.KEYCODE_BACK,
|
||||
KeyEvent.KEYCODE_BUTTON_MODE,
|
||||
KeyEvent.KEYCODE_BUTTON_START,
|
||||
KeyEvent.KEYCODE_BUTTON_THUMBL,
|
||||
KeyEvent.KEYCODE_BUTTON_THUMBR,
|
||||
KeyEvent.KEYCODE_BUTTON_L1,
|
||||
KeyEvent.KEYCODE_BUTTON_R1,
|
||||
KeyEvent.KEYCODE_DPAD_UP,
|
||||
KeyEvent.KEYCODE_DPAD_DOWN,
|
||||
KeyEvent.KEYCODE_DPAD_LEFT,
|
||||
KeyEvent.KEYCODE_DPAD_RIGHT,
|
||||
KeyEvent.KEYCODE_BUTTON_SELECT,
|
||||
KeyEvent.KEYCODE_DPAD_CENTER,
|
||||
|
||||
// These don't map into any SDL controller buttons directly
|
||||
KeyEvent.KEYCODE_BUTTON_L2,
|
||||
KeyEvent.KEYCODE_BUTTON_R2,
|
||||
KeyEvent.KEYCODE_BUTTON_C,
|
||||
KeyEvent.KEYCODE_BUTTON_Z,
|
||||
KeyEvent.KEYCODE_BUTTON_1,
|
||||
KeyEvent.KEYCODE_BUTTON_2,
|
||||
KeyEvent.KEYCODE_BUTTON_3,
|
||||
KeyEvent.KEYCODE_BUTTON_4,
|
||||
KeyEvent.KEYCODE_BUTTON_5,
|
||||
KeyEvent.KEYCODE_BUTTON_6,
|
||||
KeyEvent.KEYCODE_BUTTON_7,
|
||||
KeyEvent.KEYCODE_BUTTON_8,
|
||||
KeyEvent.KEYCODE_BUTTON_9,
|
||||
KeyEvent.KEYCODE_BUTTON_10,
|
||||
KeyEvent.KEYCODE_BUTTON_11,
|
||||
KeyEvent.KEYCODE_BUTTON_12,
|
||||
KeyEvent.KEYCODE_BUTTON_13,
|
||||
KeyEvent.KEYCODE_BUTTON_14,
|
||||
KeyEvent.KEYCODE_BUTTON_15,
|
||||
KeyEvent.KEYCODE_BUTTON_16,
|
||||
};
|
||||
int[] masks = new int[] {
|
||||
(1 << 0), // A -> A
|
||||
(1 << 1), // B -> B
|
||||
(1 << 2), // X -> X
|
||||
(1 << 3), // Y -> Y
|
||||
(1 << 4), // BACK -> BACK
|
||||
(1 << 5), // MODE -> GUIDE
|
||||
(1 << 6), // START -> START
|
||||
(1 << 7), // THUMBL -> LEFTSTICK
|
||||
(1 << 8), // THUMBR -> RIGHTSTICK
|
||||
(1 << 9), // L1 -> LEFTSHOULDER
|
||||
(1 << 10), // R1 -> RIGHTSHOULDER
|
||||
(1 << 11), // DPAD_UP -> DPAD_UP
|
||||
(1 << 12), // DPAD_DOWN -> DPAD_DOWN
|
||||
(1 << 13), // DPAD_LEFT -> DPAD_LEFT
|
||||
(1 << 14), // DPAD_RIGHT -> DPAD_RIGHT
|
||||
(1 << 4), // SELECT -> BACK
|
||||
(1 << 0), // DPAD_CENTER -> A
|
||||
(1 << 15), // L2 -> ??
|
||||
(1 << 16), // R2 -> ??
|
||||
(1 << 17), // C -> ??
|
||||
(1 << 18), // Z -> ??
|
||||
(1 << 20), // 1 -> ??
|
||||
(1 << 21), // 2 -> ??
|
||||
(1 << 22), // 3 -> ??
|
||||
(1 << 23), // 4 -> ??
|
||||
(1 << 24), // 5 -> ??
|
||||
(1 << 25), // 6 -> ??
|
||||
(1 << 26), // 7 -> ??
|
||||
(1 << 27), // 8 -> ??
|
||||
(1 << 28), // 9 -> ??
|
||||
(1 << 29), // 10 -> ??
|
||||
(1 << 30), // 11 -> ??
|
||||
(1 << 31), // 12 -> ??
|
||||
// We're out of room...
|
||||
0xFFFFFFFF, // 13 -> ??
|
||||
0xFFFFFFFF, // 14 -> ??
|
||||
0xFFFFFFFF, // 15 -> ??
|
||||
0xFFFFFFFF, // 16 -> ??
|
||||
};
|
||||
boolean[] has_keys = joystickDevice.hasKeys(keys);
|
||||
for (int i = 0; i < keys.length; ++i) {
|
||||
if (has_keys[i]) {
|
||||
button_mask |= masks[i];
|
||||
}
|
||||
}
|
||||
return button_mask;
|
||||
}
|
||||
|
||||
private int getAxisMask(InputDevice joystickDevice) {
|
||||
final int SDL_CONTROLLER_AXIS_LEFTX = 0;
|
||||
final int SDL_CONTROLLER_AXIS_LEFTY = 1;
|
||||
final int SDL_CONTROLLER_AXIS_RIGHTX = 2;
|
||||
final int SDL_CONTROLLER_AXIS_RIGHTY = 3;
|
||||
final int SDL_CONTROLLER_AXIS_TRIGGERLEFT = 4;
|
||||
final int SDL_CONTROLLER_AXIS_TRIGGERRIGHT = 5;
|
||||
|
||||
int naxes = 0;
|
||||
for (InputDevice.MotionRange range : joystickDevice.getMotionRanges()) {
|
||||
if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
|
||||
if (range.getAxis() != MotionEvent.AXIS_HAT_X && range.getAxis() != MotionEvent.AXIS_HAT_Y) {
|
||||
naxes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// The variable is_accelerometer seems always false, then skip the checking:
|
||||
// https://hg.libsdl.org/SDL/file/bc90ce38f1e2/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java#l207
|
||||
int axisMask = 0;
|
||||
if (naxes >= 2) {
|
||||
axisMask |= ((1 << SDL_CONTROLLER_AXIS_LEFTX) | (1 << SDL_CONTROLLER_AXIS_LEFTY));
|
||||
}
|
||||
if (naxes >= 4) {
|
||||
axisMask |= ((1 << SDL_CONTROLLER_AXIS_RIGHTX) | (1 << SDL_CONTROLLER_AXIS_RIGHTY));
|
||||
}
|
||||
if (naxes >= 6) {
|
||||
axisMask |= ((1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT) | (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT));
|
||||
}
|
||||
return axisMask;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
File diff suppressed because one or more lines are too long
@ -15,6 +15,8 @@
|
||||
package ebitenmobileview
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"hash/crc32"
|
||||
"unicode"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/driver"
|
||||
@ -277,11 +279,36 @@ func OnGamepadAxesChanged(deviceID int, axisID int, value float32) {
|
||||
updateInput()
|
||||
}
|
||||
|
||||
func OnGamepadAdded(deviceID int, name string, buttonNum int, axisNum int) {
|
||||
func OnGamepadAdded(deviceID int, name string, buttonNum int, axisNum int, descriptor string, vendorID int, productID int, buttonMask int, axisMask int) {
|
||||
// This emulates the implementation of Android_AddJoystick.
|
||||
// https://hg.libsdl.org/SDL/file/bc90ce38f1e2/src/joystick/android/SDL_sysjoystick.c#l386
|
||||
const SDL_HARDWARE_BUS_BLUETOOTH = 0x05
|
||||
|
||||
var sdlid [16]byte
|
||||
sdlid[0] = byte(SDL_HARDWARE_BUS_BLUETOOTH)
|
||||
sdlid[1] = byte(SDL_HARDWARE_BUS_BLUETOOTH >> 8)
|
||||
if vendorID != 0 && productID != 0 {
|
||||
sdlid[4] = byte(vendorID)
|
||||
sdlid[5] = byte(vendorID >> 8)
|
||||
sdlid[8] = byte(productID)
|
||||
sdlid[9] = byte(productID >> 8)
|
||||
} else {
|
||||
crc := crc32.ChecksumIEEE(([]byte)(descriptor))
|
||||
copy(sdlid[4:8], ([]byte)(descriptor))
|
||||
sdlid[8] = byte(crc)
|
||||
sdlid[9] = byte(crc >> 8)
|
||||
sdlid[10] = byte(crc >> 16)
|
||||
sdlid[11] = byte(crc >> 24)
|
||||
}
|
||||
sdlid[12] = byte(buttonMask)
|
||||
sdlid[13] = byte(buttonMask >> 8)
|
||||
sdlid[14] = byte(axisMask)
|
||||
sdlid[15] = byte(axisMask >> 8)
|
||||
|
||||
id := gamepadIDFromDeviceID(deviceID)
|
||||
gamepads[id] = &mobile.Gamepad{
|
||||
ID: id,
|
||||
SDLID: "", // TODO: Implement this
|
||||
SDLID: hex.EncodeToString(sdlid[:]),
|
||||
Name: name,
|
||||
ButtonNum: buttonNum,
|
||||
AxisNum: axisNum,
|
||||
|
Loading…
Reference in New Issue
Block a user