mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
parent
1b498a03cc
commit
4106fb15fe
@ -537,7 +537,7 @@ public class EbitenView extends ViewGroup implements InputManager.InputDeviceLis
|
|||||||
value = 0.0f;
|
value = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ebitenmobileview.onGamepadAxesChanged(event.getDeviceId(), axis, value);
|
Ebitenmobileview.onGamepadAxesOrHatsChanged(event.getDeviceId(), axis, value);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -562,20 +562,26 @@ public class EbitenView extends ViewGroup implements InputManager.InputDeviceLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean[] keyExistences = inputDevice.hasKeys(gamepadButtons);
|
boolean[] keyExistences = inputDevice.hasKeys(gamepadButtons);
|
||||||
int buttonNum = gamepadButtons.length - 1;
|
int nbuttons = 0;
|
||||||
for (int i = gamepadButtons.length - 1; i >= 0; i--) {
|
for (int i = 0; i < gamepadButtons.length; i++) {
|
||||||
if (keyExistences[i]) {
|
if (!keyExistences[i]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buttonNum--;
|
nbuttons++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int axisNum = axes.length - 1;
|
int naxes = 0;
|
||||||
for (int i = axes.length - 1; i >= 0; i--) {
|
int nhats2 = 0;
|
||||||
if (inputDevice.getMotionRange(axes[i], InputDevice.SOURCE_JOYSTICK) != null) {
|
for (int i = 0; i < axes.length; i++) {
|
||||||
|
InputDevice.MotionRange range = inputDevice.getMotionRange(axes[i], InputDevice.SOURCE_JOYSTICK);
|
||||||
|
if (range == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
axisNum--;
|
if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
|
||||||
|
nhats2++;
|
||||||
|
} else {
|
||||||
|
naxes++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String descriptor = inputDevice.getDescriptor();
|
String descriptor = inputDevice.getDescriptor();
|
||||||
@ -586,7 +592,7 @@ public class EbitenView extends ViewGroup implements InputManager.InputDeviceLis
|
|||||||
int buttonMask = getButtonMask(inputDevice);
|
int buttonMask = getButtonMask(inputDevice);
|
||||||
int axisMask = getAxisMask(inputDevice);
|
int axisMask = getAxisMask(inputDevice);
|
||||||
|
|
||||||
Ebitenmobileview.onGamepadAdded(deviceId, inputDevice.getName(), buttonNum, axisNum, descriptor, vendorId, productId, buttonMask, axisMask);
|
Ebitenmobileview.onGamepadAdded(deviceId, inputDevice.getName(), nbuttons, naxes, nhats2/2, descriptor, vendorId, productId, buttonMask, axisMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The implementation is copied from SDL:
|
// The implementation is copied from SDL:
|
||||||
|
File diff suppressed because one or more lines are too long
@ -335,17 +335,41 @@ func toStandardGamepadAxis(str string) (driver.StandardGamepadAxis, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buttonMappings(id string) map[driver.StandardGamepadButton]*mapping {
|
||||||
|
if m, ok := gamepadButtonMappings[id]; ok {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
if currentPlatform == platformAndroid {
|
||||||
|
// If the gamepad is not an HID API, use the default mapping on Android.
|
||||||
|
if id[14] != 'h' {
|
||||||
|
if addAndroidDefaultMappings(id) {
|
||||||
|
return gamepadButtonMappings[id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func axisMappings(id string) map[driver.StandardGamepadAxis]*mapping {
|
||||||
|
if m, ok := gamepadAxisMappings[id]; ok {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
if currentPlatform == platformAndroid {
|
||||||
|
// If the gamepad is not an HID API, use the default mapping on Android.
|
||||||
|
if id[14] != 'h' {
|
||||||
|
if addAndroidDefaultMappings(id) {
|
||||||
|
return gamepadAxisMappings[id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func HasStandardLayoutMapping(id string) bool {
|
func HasStandardLayoutMapping(id string) bool {
|
||||||
mappingsM.RLock()
|
mappingsM.RLock()
|
||||||
defer mappingsM.RUnlock()
|
defer mappingsM.RUnlock()
|
||||||
|
|
||||||
if _, ok := gamepadButtonMappings[id]; ok {
|
return buttonMappings(id) != nil || axisMappings(id) != nil
|
||||||
return true
|
|
||||||
}
|
|
||||||
if _, ok := gamepadAxisMappings[id]; ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type GamepadState interface {
|
type GamepadState interface {
|
||||||
@ -358,8 +382,8 @@ func AxisValue(id string, axis driver.StandardGamepadAxis, state GamepadState) f
|
|||||||
mappingsM.RLock()
|
mappingsM.RLock()
|
||||||
defer mappingsM.RUnlock()
|
defer mappingsM.RUnlock()
|
||||||
|
|
||||||
mappings, ok := gamepadAxisMappings[id]
|
mappings := axisMappings(id)
|
||||||
if !ok {
|
if mappings == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,8 +426,8 @@ func ButtonValue(id string, button driver.StandardGamepadButton, state GamepadSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buttonValue(id string, button driver.StandardGamepadButton, state GamepadState) float64 {
|
func buttonValue(id string, button driver.StandardGamepadButton, state GamepadState) float64 {
|
||||||
mappings, ok := gamepadButtonMappings[id]
|
mappings := buttonMappings(id)
|
||||||
if !ok {
|
if mappings == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +500,7 @@ func Update(mapping []byte) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement this (#1557)
|
// TODO: Implement this (#1557)
|
||||||
if currentPlatform == platformAndroid || currentPlatform == platformIOS {
|
if currentPlatform == platformIOS {
|
||||||
// Note: NOT returning an error, as mappings also do not matter right now.
|
// Note: NOT returning an error, as mappings also do not matter right now.
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
@ -501,3 +525,202 @@ func Update(mapping []byte) (bool, error) {
|
|||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addAndroidDefaultMappings(id string) bool {
|
||||||
|
// See https://github.com/libsdl-org/SDL/blob/120c76c84bbce4c1bfed4e9eb74e10678bd83120/include/SDL_gamecontroller.h#L655-L680
|
||||||
|
const (
|
||||||
|
SDLControllerButtonA = 0
|
||||||
|
SDLControllerButtonB = 1
|
||||||
|
SDLControllerButtonX = 2
|
||||||
|
SDLControllerButtonY = 3
|
||||||
|
SDLControllerButtonBack = 4
|
||||||
|
SDLControllerButtonGuide = 5
|
||||||
|
SDLControllerButtonStart = 6
|
||||||
|
SDLControllerButtonLeftStick = 7
|
||||||
|
SDLControllerButtonRightStick = 8
|
||||||
|
SDLControllerButtonLeftShoulder = 9
|
||||||
|
SDLControllerButtonRightShoulder = 10
|
||||||
|
SDLControllerButtonDpadUp = 11
|
||||||
|
SDLControllerButtonDpadDown = 12
|
||||||
|
SDLControllerButtonDpadLeft = 13
|
||||||
|
SDLControllerButtonDpadRight = 14
|
||||||
|
)
|
||||||
|
|
||||||
|
// See https://github.com/libsdl-org/SDL/blob/120c76c84bbce4c1bfed4e9eb74e10678bd83120/include/SDL_gamecontroller.h#L550-L560
|
||||||
|
const (
|
||||||
|
SDLControllerAxisLeftX = 0
|
||||||
|
SDLControllerAxisLeftY = 1
|
||||||
|
SDLControllerAxisRightX = 2
|
||||||
|
SDLControllerAxisRightY = 3
|
||||||
|
SDLControllerAxisTriggerLeft = 4
|
||||||
|
SDLControllerAxisTriggerRight = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
// See https://github.com/libsdl-org/SDL/blob/120c76c84bbce4c1bfed4e9eb74e10678bd83120/src/joystick/SDL_gamecontroller.c#L468-L568
|
||||||
|
|
||||||
|
const faceButtonMask = ((1 << SDLControllerButtonA) |
|
||||||
|
(1 << SDLControllerButtonB) |
|
||||||
|
(1 << SDLControllerButtonX) |
|
||||||
|
(1 << SDLControllerButtonY))
|
||||||
|
|
||||||
|
buttonMask := uint16(id[12]) | (uint16(id[13]) << 8)
|
||||||
|
axisMask := uint16(id[14]) | (uint16(id[15]) << 8)
|
||||||
|
if buttonMask == 0 && axisMask == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if buttonMask&faceButtonMask == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
gamepadButtonMappings[id] = map[driver.StandardGamepadButton]*mapping{}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonA) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonRightBottom] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonA,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonB) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonRightRight] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonB,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use the back button as "B" for easy UI navigation with TV remotes.
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonRightRight] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonBack,
|
||||||
|
}
|
||||||
|
buttonMask &= ^(uint16(1) << SDLControllerButtonBack)
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonX) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonRightLeft] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonY) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonRightTop] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonY,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonBack) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonCenterLeft] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonBack,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonGuide) != 0 {
|
||||||
|
// TODO: If SDKVersion >= 30, add this code:
|
||||||
|
//
|
||||||
|
// gamepadButtonMappings[id][driver.StandardGamepadButtonCenterCenter] = &mapping{
|
||||||
|
// Type: mappingTypeButton,
|
||||||
|
// Index: SDLControllerButtonGuide,
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonStart) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonCenterRight] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonStart,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonLeftStick) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonLeftStick] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonLeftStick,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonRightStick) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonRightStick] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonRightStick,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonLeftShoulder) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonFrontTopLeft] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonLeftShoulder,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonRightShoulder) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonFrontTopRight] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonRightShoulder,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonDpadUp) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonLeftTop] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonDpadUp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonDpadDown) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonLeftBottom] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonDpadDown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonDpadLeft) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonLeftLeft] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonDpadLeft,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buttonMask&(1<<SDLControllerButtonDpadRight) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonLeftRight] = &mapping{
|
||||||
|
Type: mappingTypeButton,
|
||||||
|
Index: SDLControllerButtonDpadRight,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if axisMask&(1<<SDLControllerAxisLeftX) != 0 {
|
||||||
|
gamepadAxisMappings[id][driver.StandardGamepadAxisLeftStickHorizontal] = &mapping{
|
||||||
|
Type: mappingTypeAxis,
|
||||||
|
Index: SDLControllerAxisLeftX,
|
||||||
|
AxisScale: 1,
|
||||||
|
AxisOffset: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if axisMask&(1<<SDLControllerAxisLeftY) != 0 {
|
||||||
|
gamepadAxisMappings[id][driver.StandardGamepadAxisLeftStickVertical] = &mapping{
|
||||||
|
Type: mappingTypeAxis,
|
||||||
|
Index: SDLControllerAxisLeftY,
|
||||||
|
AxisScale: 1,
|
||||||
|
AxisOffset: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if axisMask&(1<<SDLControllerAxisRightX) != 0 {
|
||||||
|
gamepadAxisMappings[id][driver.StandardGamepadAxisRightStickHorizontal] = &mapping{
|
||||||
|
Type: mappingTypeAxis,
|
||||||
|
Index: SDLControllerAxisRightX,
|
||||||
|
AxisScale: 1,
|
||||||
|
AxisOffset: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if axisMask&(1<<SDLControllerAxisRightY) != 0 {
|
||||||
|
gamepadAxisMappings[id][driver.StandardGamepadAxisRightStickVertical] = &mapping{
|
||||||
|
Type: mappingTypeAxis,
|
||||||
|
Index: SDLControllerAxisRightY,
|
||||||
|
AxisScale: 1,
|
||||||
|
AxisOffset: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if axisMask&(1<<SDLControllerAxisTriggerLeft) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonFrontBottomLeft] = &mapping{
|
||||||
|
Type: mappingTypeAxis,
|
||||||
|
Index: SDLControllerAxisTriggerLeft,
|
||||||
|
AxisScale: 1,
|
||||||
|
AxisOffset: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if axisMask&(1<<SDLControllerAxisTriggerRight) != 0 {
|
||||||
|
gamepadButtonMappings[id][driver.StandardGamepadButtonFrontBottomRight] = &mapping{
|
||||||
|
Type: mappingTypeAxis,
|
||||||
|
Index: SDLControllerAxisTriggerRight,
|
||||||
|
AxisScale: 1,
|
||||||
|
AxisOffset: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Input struct {
|
type Input struct {
|
||||||
@ -130,22 +131,54 @@ func (i *Input) IsGamepadButtonPressed(id driver.GamepadID, button driver.Gamepa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) IsStandardGamepadLayoutAvailable(id driver.GamepadID) bool {
|
func (i *Input) IsStandardGamepadLayoutAvailable(id driver.GamepadID) bool {
|
||||||
// TODO: Implement this (#1557)
|
i.ui.m.RLock()
|
||||||
|
defer i.ui.m.RUnlock()
|
||||||
|
|
||||||
|
for _, g := range i.gamepads {
|
||||||
|
if g.ID != id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return gamepaddb.HasStandardLayoutMapping(g.SDLID)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button driver.StandardGamepadButton) bool {
|
func (i *Input) IsStandardGamepadButtonPressed(id driver.GamepadID, button driver.StandardGamepadButton) bool {
|
||||||
// TODO: Implement this (#1557)
|
i.ui.m.RLock()
|
||||||
|
defer i.ui.m.RUnlock()
|
||||||
|
|
||||||
|
for _, g := range i.gamepads {
|
||||||
|
if g.ID != id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return gamepaddb.IsButtonPressed(g.SDLID, button, gamepadState{&g})
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) StandardGamepadButtonValue(id driver.GamepadID, button driver.StandardGamepadButton) float64 {
|
func (i *Input) StandardGamepadButtonValue(id driver.GamepadID, button driver.StandardGamepadButton) float64 {
|
||||||
// TODO: Implement this (#1557)
|
i.ui.m.RLock()
|
||||||
|
defer i.ui.m.RUnlock()
|
||||||
|
|
||||||
|
for _, g := range i.gamepads {
|
||||||
|
if g.ID != id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return gamepaddb.ButtonValue(g.SDLID, button, gamepadState{&g})
|
||||||
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) StandardGamepadAxisValue(id driver.GamepadID, axis driver.StandardGamepadAxis) float64 {
|
func (i *Input) StandardGamepadAxisValue(id driver.GamepadID, axis driver.StandardGamepadAxis) float64 {
|
||||||
// TODO: Implement this (#1557)
|
i.ui.m.RLock()
|
||||||
|
defer i.ui.m.RUnlock()
|
||||||
|
|
||||||
|
for _, g := range i.gamepads {
|
||||||
|
if g.ID != id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return gamepaddb.AxisValue(g.SDLID, axis, gamepadState{&g})
|
||||||
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,3 +254,19 @@ func (i *Input) update(keys map[driver.Key]struct{}, runes []rune, touches []Tou
|
|||||||
func (i *Input) resetForFrame() {
|
func (i *Input) resetForFrame() {
|
||||||
i.runes = nil
|
i.runes = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type gamepadState struct {
|
||||||
|
g *Gamepad
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s gamepadState) Axis(index int) float64 {
|
||||||
|
return float64(s.g.Axes[index])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s gamepadState) Button(index int) bool {
|
||||||
|
return s.g.Buttons[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s gamepadState) Hat(index int) int {
|
||||||
|
return s.g.Hats[index]
|
||||||
|
}
|
||||||
|
@ -466,6 +466,8 @@ type Gamepad struct {
|
|||||||
ButtonNum int
|
ButtonNum int
|
||||||
Axes [32]float32
|
Axes [32]float32
|
||||||
AxisNum int
|
AxisNum int
|
||||||
|
Hats [16]int
|
||||||
|
HatNum int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserInterface) UpdateInput(keys map[driver.Key]struct{}, runes []rune, touches []Touch) {
|
func (u *UserInterface) UpdateInput(keys map[driver.Key]struct{}, runes []rune, touches []Touch) {
|
||||||
|
@ -17,6 +17,7 @@ package ebitenmobileview
|
|||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
|
"math"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
"github.com/hajimehoshi/ebiten/v2/internal/driver"
|
||||||
@ -149,31 +150,34 @@ var androidAxisIDToAxisID = map[int]int{
|
|||||||
axisRx: 3,
|
axisRx: 3,
|
||||||
axisRy: 4,
|
axisRy: 4,
|
||||||
axisRz: 5,
|
axisRz: 5,
|
||||||
axisHatX: 6,
|
axisLtrigger: 6,
|
||||||
axisHatY: 7,
|
axisRtrigger: 7,
|
||||||
axisLtrigger: 8,
|
axisThrottle: 8,
|
||||||
axisRtrigger: 9,
|
axisRudder: 9,
|
||||||
axisThrottle: 10,
|
axisWheel: 10,
|
||||||
axisRudder: 11,
|
axisGas: 11,
|
||||||
axisWheel: 12,
|
axisBrake: 12,
|
||||||
axisGas: 13,
|
axisGeneric1: 13,
|
||||||
axisBrake: 14,
|
axisGeneric2: 14,
|
||||||
axisGeneric1: 15,
|
axisGeneric3: 15,
|
||||||
axisGeneric2: 16,
|
axisGeneric4: 16,
|
||||||
axisGeneric3: 17,
|
axisGeneric5: 17,
|
||||||
axisGeneric4: 18,
|
axisGeneric6: 18,
|
||||||
axisGeneric5: 19,
|
axisGeneric7: 19,
|
||||||
axisGeneric6: 20,
|
axisGeneric8: 20,
|
||||||
axisGeneric7: 21,
|
axisGeneric9: 21,
|
||||||
axisGeneric8: 22,
|
axisGeneric10: 22,
|
||||||
axisGeneric9: 23,
|
axisGeneric11: 23,
|
||||||
axisGeneric10: 24,
|
axisGeneric12: 24,
|
||||||
axisGeneric11: 25,
|
axisGeneric13: 25,
|
||||||
axisGeneric12: 26,
|
axisGeneric14: 26,
|
||||||
axisGeneric13: 27,
|
axisGeneric15: 27,
|
||||||
axisGeneric14: 28,
|
axisGeneric16: 28,
|
||||||
axisGeneric15: 29,
|
}
|
||||||
axisGeneric16: 30,
|
|
||||||
|
var androidAxisIDToHatID2 = map[int]int{
|
||||||
|
axisHatX: 0,
|
||||||
|
axisHatY: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -269,22 +273,58 @@ func OnKeyUpOnAndroid(keyCode int, source int, deviceID int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnGamepadAxesChanged(deviceID int, axisID int, value float32) {
|
func OnGamepadAxesOrHatsChanged(deviceID int, axisID int, value float32) {
|
||||||
id := gamepadIDFromDeviceID(deviceID)
|
id := gamepadIDFromDeviceID(deviceID)
|
||||||
g := gamepadFromGamepadID(id)
|
g := gamepadFromGamepadID(id)
|
||||||
if g == nil {
|
if g == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
aid, ok := androidAxisIDToAxisID[axisID]
|
|
||||||
if !ok {
|
if aid, ok := androidAxisIDToAxisID[axisID]; ok {
|
||||||
// Unexpected axis value.
|
g.Axes[aid] = value
|
||||||
|
updateGamepads()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if hid2, ok := androidAxisIDToHatID2[axisID]; ok {
|
||||||
|
const (
|
||||||
|
hatUp = 1
|
||||||
|
hatRight = 2
|
||||||
|
hatDown = 4
|
||||||
|
hatLeft = 8
|
||||||
|
)
|
||||||
|
hid := hid2 / 2
|
||||||
|
v := g.Hats[hid]
|
||||||
|
if hid2%2 == 0 {
|
||||||
|
hatX := int(math.Round(float64(value)))
|
||||||
|
if hatX < 0 {
|
||||||
|
v |= hatLeft
|
||||||
|
v &= ^hatRight
|
||||||
|
} else if hatX > 0 {
|
||||||
|
v &= ^hatLeft
|
||||||
|
v |= hatRight
|
||||||
|
} else {
|
||||||
|
v &= ^(hatLeft | hatRight)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hatY := int(math.Round(float64(value)))
|
||||||
|
if hatY < 0 {
|
||||||
|
v |= hatUp
|
||||||
|
v &= ^hatDown
|
||||||
|
} else if hatY > 0 {
|
||||||
|
v &= ^hatUp
|
||||||
|
v |= hatDown
|
||||||
|
} else {
|
||||||
|
v &= ^(hatUp | hatDown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.Hats[hid] = v
|
||||||
|
updateGamepads()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.Axes[aid] = value
|
|
||||||
updateGamepads()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnGamepadAdded(deviceID int, name string, buttonNum int, axisNum int, descriptor string, vendorID int, productID int, buttonMask int, axisMask int) {
|
func OnGamepadAdded(deviceID int, name string, buttonNum int, axisNum int, hatNum int, descriptor string, vendorID int, productID int, buttonMask int, axisMask int) {
|
||||||
// This emulates the implementation of Android_AddJoystick.
|
// This emulates the implementation of Android_AddJoystick.
|
||||||
// https://github.com/libsdl-org/SDL/blob/0e9560aea22818884921e5e5064953257bfe7fa7/src/joystick/android/SDL_sysjoystick.c#L386
|
// https://github.com/libsdl-org/SDL/blob/0e9560aea22818884921e5e5064953257bfe7fa7/src/joystick/android/SDL_sysjoystick.c#L386
|
||||||
const SDL_HARDWARE_BUS_BLUETOOTH = 0x05
|
const SDL_HARDWARE_BUS_BLUETOOTH = 0x05
|
||||||
@ -317,6 +357,7 @@ func OnGamepadAdded(deviceID int, name string, buttonNum int, axisNum int, descr
|
|||||||
Name: name,
|
Name: name,
|
||||||
ButtonNum: buttonNum,
|
ButtonNum: buttonNum,
|
||||||
AxisNum: axisNum,
|
AxisNum: axisNum,
|
||||||
|
HatNum: hatNum,
|
||||||
})
|
})
|
||||||
updateGamepads()
|
updateGamepads()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user