mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
parent
3cafb0f6fd
commit
4a569be6f6
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module github.com/hajimehoshi/ebiten/v2
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/ebitengine/purego v0.0.0-20220910041003-a51c01493ff9
|
||||
github.com/ebitengine/purego v0.2.0-alpha.0.20220915044048-aa1b0f680473
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220806181222-55e207c401ad
|
||||
github.com/hajimehoshi/bitmapfont/v2 v2.2.1
|
||||
github.com/hajimehoshi/go-mp3 v0.3.3
|
||||
|
4
go.sum
4
go.sum
@ -1,7 +1,7 @@
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/ebitengine/purego v0.0.0-20220907032450-cf3e27c364c7/go.mod h1:Eh8I3yvknDYZeCuXH9kRNaPuHEwvXDCk378o9xszmHg=
|
||||
github.com/ebitengine/purego v0.0.0-20220910041003-a51c01493ff9 h1:SWRYqW9r4JvlnVnDurFzaF+0X60GG5QZD8n0U9cq3Gw=
|
||||
github.com/ebitengine/purego v0.0.0-20220910041003-a51c01493ff9/go.mod h1:Eh8I3yvknDYZeCuXH9kRNaPuHEwvXDCk378o9xszmHg=
|
||||
github.com/ebitengine/purego v0.2.0-alpha.0.20220915044048-aa1b0f680473 h1:gvI3mxzjexvkakZNJkYRZOIWRQTGa8ucsQtQ/tN2VJk=
|
||||
github.com/ebitengine/purego v0.2.0-alpha.0.20220915044048-aa1b0f680473/go.mod h1:8K86Hsai2ghNjg9h/9P9tDdLAhUNwqNg10OESLDOam8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220806181222-55e207c401ad h1:kX51IjbsJPCvzV9jUoVQG9GEUqIq5hjfYzXTqQ52Rh8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220806181222-55e207c401ad/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/hajimehoshi/bitmapfont/v2 v2.2.1 h1:y7zcy02/UgO24IL3COqYtrRZzhRucNBtmCo/SNU648k=
|
||||
|
138
internal/gamepad/api_cf_darwin.go
Normal file
138
internal/gamepad/api_cf_darwin.go
Normal file
@ -0,0 +1,138 @@
|
||||
// Copyright 2022 The Ebitengine Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gamepad
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ebitengine/purego"
|
||||
)
|
||||
|
||||
type _CFIndex int64
|
||||
type _CFAllocatorRef uintptr
|
||||
type _CFArrayRef uintptr
|
||||
type _CFDictionaryRef uintptr
|
||||
type _CFNumberRef uintptr
|
||||
type _CFTypeRef uintptr
|
||||
type _CFRunLoopRef uintptr
|
||||
type _CFNumberType uintptr
|
||||
type _CFStringRef uintptr
|
||||
type _CFArrayCallBacks struct{}
|
||||
type _CFDictionaryKeyCallBacks struct{}
|
||||
type _CFDictionaryValueCallBacks struct{}
|
||||
type _CFRunLoopRunResult int32
|
||||
type _CFRunLoopMode = _CFStringRef
|
||||
type _CFTimeInterval float64
|
||||
type _CFTypeID uint64
|
||||
type _CFStringEncoding uint32
|
||||
|
||||
var kCFAllocatorDefault _CFAllocatorRef = 0
|
||||
|
||||
const (
|
||||
kCFStringEncodingUTF8 _CFStringEncoding = 0x08000100
|
||||
)
|
||||
|
||||
const (
|
||||
kCFNumberSInt32Type _CFNumberType = 3
|
||||
kCFNumberIntType _CFNumberType = 9
|
||||
)
|
||||
|
||||
var (
|
||||
corefoundation = purego.Dlopen("CoreFoundation.framework/CoreFoundation", purego.RTLD_GLOBAL)
|
||||
procCFNumberCreate = purego.Dlsym(corefoundation, "CFNumberCreate")
|
||||
procCFNumberGetValue = purego.Dlsym(corefoundation, "CFNumberGetValue")
|
||||
procCFArrayCreate = purego.Dlsym(corefoundation, "CFArrayCreate")
|
||||
procCFArrayGetCount = purego.Dlsym(corefoundation, "CFArrayGetCount")
|
||||
procCFArrayGetValueAtIndex = purego.Dlsym(corefoundation, "CFArrayGetValueAtIndex")
|
||||
procCFDictionaryCreate = purego.Dlsym(corefoundation, "CFDictionaryCreate")
|
||||
procCFRelease = purego.Dlsym(corefoundation, "CFRelease")
|
||||
procCFRunLoopGetMain = purego.Dlsym(corefoundation, "CFRunLoopGetMain")
|
||||
procCFRunLoopRunInMode = purego.Dlsym(corefoundation, "CFRunLoopRunInMode")
|
||||
procCFGetTypeID = purego.Dlsym(corefoundation, "CFGetTypeID")
|
||||
procCFStringGetCString = purego.Dlsym(corefoundation, "CFStringGetCString")
|
||||
procCFStringCreateWithCString = purego.Dlsym(corefoundation, "CFStringCreateWithCString")
|
||||
|
||||
kCFTypeDictionaryKeyCallBacks = purego.Dlsym(corefoundation, "kCFTypeDictionaryKeyCallBacks")
|
||||
kCFTypeDictionaryValueCallBacks = purego.Dlsym(corefoundation, "kCFTypeDictionaryValueCallBacks")
|
||||
kCFTypeArrayCallBacks = purego.Dlsym(corefoundation, "kCFTypeArrayCallBacks")
|
||||
kCFRunLoopDefaultMode = purego.Dlsym(corefoundation, "kCFRunLoopDefaultMode")
|
||||
)
|
||||
|
||||
func _CFNumberCreate(allocator _CFAllocatorRef, theType _CFNumberType, valuePtr unsafe.Pointer) _CFNumberRef {
|
||||
number, _, _ := purego.SyscallN(procCFNumberCreate, uintptr(allocator), uintptr(theType), uintptr(valuePtr))
|
||||
return _CFNumberRef(number)
|
||||
}
|
||||
|
||||
func _CFNumberGetValue(number _CFNumberRef, theType _CFNumberType, valuePtr unsafe.Pointer) bool {
|
||||
ret, _, _ := purego.SyscallN(procCFNumberGetValue, uintptr(number), uintptr(theType), uintptr(valuePtr))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func _CFArrayCreate(allocator _CFAllocatorRef, values *unsafe.Pointer, numValues _CFIndex, callbacks *_CFArrayCallBacks) _CFArrayRef {
|
||||
ret, _, _ := purego.SyscallN(procCFArrayCreate, uintptr(allocator), uintptr(unsafe.Pointer(values)), uintptr(numValues), uintptr(unsafe.Pointer(callbacks)))
|
||||
return _CFArrayRef(ret)
|
||||
}
|
||||
|
||||
func _CFArrayGetValueAtIndex(array _CFArrayRef, index _CFIndex) uintptr {
|
||||
ret, _, _ := purego.SyscallN(procCFArrayGetValueAtIndex, uintptr(array), uintptr(index))
|
||||
return ret
|
||||
}
|
||||
|
||||
func _CFArrayGetCount(array _CFArrayRef) _CFIndex {
|
||||
ret, _, _ := purego.SyscallN(procCFArrayGetCount, uintptr(array))
|
||||
return _CFIndex(ret)
|
||||
}
|
||||
|
||||
func _CFDictionaryCreate(allocator _CFAllocatorRef, keys *unsafe.Pointer, values *unsafe.Pointer, numValues _CFIndex, keyCallBacks *_CFDictionaryKeyCallBacks, valueCallBacks *_CFDictionaryValueCallBacks) _CFDictionaryRef {
|
||||
ret, _, _ := purego.SyscallN(procCFDictionaryCreate, uintptr(allocator), uintptr(unsafe.Pointer(keys)), uintptr(unsafe.Pointer(values)), uintptr(numValues), uintptr(unsafe.Pointer(keyCallBacks)), uintptr(unsafe.Pointer(valueCallBacks)))
|
||||
return _CFDictionaryRef(ret)
|
||||
}
|
||||
|
||||
func _CFRelease(cf _CFTypeRef) {
|
||||
purego.SyscallN(procCFRelease, uintptr(cf))
|
||||
}
|
||||
|
||||
func _CFRunLoopGetMain() _CFRunLoopRef {
|
||||
ret, _, _ := purego.SyscallN(procCFRunLoopGetMain)
|
||||
return _CFRunLoopRef(ret)
|
||||
}
|
||||
|
||||
func _CFRunLoopRunInMode(mode _CFRunLoopMode, seconds _CFTimeInterval, returnAfterSourceHandled bool) _CFRunLoopRunResult {
|
||||
var b uintptr = 0
|
||||
if returnAfterSourceHandled {
|
||||
b = 1
|
||||
}
|
||||
if seconds != 0 {
|
||||
panic("corefoundation: seconds greater than 0 is not supported")
|
||||
}
|
||||
//TODO: support floats
|
||||
ret, _, _ := purego.SyscallN(procCFRunLoopRunInMode, uintptr(mode), b)
|
||||
return _CFRunLoopRunResult(ret)
|
||||
}
|
||||
|
||||
func _CFGetTypeID(cf _CFTypeRef) _CFTypeID {
|
||||
ret, _, _ := purego.SyscallN(procCFGetTypeID, uintptr(cf))
|
||||
return _CFTypeID(ret)
|
||||
}
|
||||
|
||||
func _CFStringGetCString(theString _CFStringRef, buffer []byte, encoding _CFStringEncoding) bool {
|
||||
ret, _, _ := purego.SyscallN(procCFStringGetCString, uintptr(theString), uintptr(unsafe.Pointer(&buffer[0])), uintptr(len(buffer)), uintptr(encoding))
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func _CFStringCreateWithCString(alloc _CFAllocatorRef, cstr []byte, encoding _CFStringEncoding) _CFStringRef {
|
||||
ret, _, _ := purego.SyscallN(procCFStringCreateWithCString, uintptr(alloc), uintptr(unsafe.Pointer(&cstr[0])), uintptr(encoding))
|
||||
return _CFStringRef(ret)
|
||||
}
|
185
internal/gamepad/api_hid_darwin.go
Normal file
185
internal/gamepad/api_hid_darwin.go
Normal file
@ -0,0 +1,185 @@
|
||||
// Copyright 2022 The Ebitengine Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gamepad
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/ebitengine/purego"
|
||||
)
|
||||
|
||||
const kIOReturnSuccess = 0
|
||||
|
||||
const kIOHIDOptionsTypeNone _IOOptionBits = 0
|
||||
|
||||
const (
|
||||
kIOHIDElementTypeInput_Misc = 1
|
||||
kIOHIDElementTypeInput_Button = 2
|
||||
kIOHIDElementTypeInput_Axis = 3
|
||||
)
|
||||
|
||||
const (
|
||||
kHIDPage_GenericDesktop = 0x1
|
||||
kHIDPage_Simulation = 0x2
|
||||
kHIDPage_Button = 0x9
|
||||
kHIDPage_Consumer = 0x0C
|
||||
)
|
||||
|
||||
const (
|
||||
kHIDUsage_GD_Joystick = 0x4
|
||||
kHIDUsage_GD_GamePad = 0x5
|
||||
kHIDUsage_GD_MultiAxisController = 0x8
|
||||
kHIDUsage_GD_X = 0x30
|
||||
kHIDUsage_GD_Y = 0x31
|
||||
kHIDUsage_GD_Z = 0x32
|
||||
kHIDUsage_GD_Rx = 0x33
|
||||
kHIDUsage_GD_Ry = 0x34
|
||||
kHIDUsage_GD_Rz = 0x35
|
||||
kHIDUsage_GD_Slider = 0x36
|
||||
kHIDUsage_GD_Dial = 0x37
|
||||
kHIDUsage_GD_Wheel = 0x38
|
||||
kHIDUsage_GD_Hatswitch = 0x39
|
||||
kHIDUsage_GD_Start = 0x3D
|
||||
kHIDUsage_GD_Select = 0x3E
|
||||
kHIDUsage_GD_SystemMainMenu = 0x85
|
||||
kHIDUsage_GD_DPadUp = 0x90
|
||||
kHIDUsage_GD_DPadDown = 0x91
|
||||
kHIDUsage_GD_DPadRight = 0x92
|
||||
kHIDUsage_GD_DPadLeft = 0x93
|
||||
kHIDUsage_Sim_Rudder = 0xBA
|
||||
kHIDUsage_Sim_Throttle = 0xBB
|
||||
kHIDUsage_Sim_Accelerator = 0xC4
|
||||
kHIDUsage_Sim_Brake = 0xC5
|
||||
kHIDUsage_Sim_Steering = 0xC8
|
||||
)
|
||||
|
||||
var (
|
||||
kIOHIDVendorIDKey = []byte("VendorID\x00")
|
||||
kIOHIDProductIDKey = []byte("ProductID\x00")
|
||||
kIOHIDVersionNumberKey = []byte("VersionNumber\x00")
|
||||
kIOHIDProductKey = []byte("Product\x00")
|
||||
kIOHIDDeviceUsagePageKey = []byte("DeviceUsagePage\x00")
|
||||
kIOHIDDeviceUsageKey = []byte("DeviceUsage\x00")
|
||||
)
|
||||
|
||||
type _IOOptionBits uint32
|
||||
type _IOHIDManagerRef uintptr
|
||||
type _IOHIDDeviceRef uintptr
|
||||
type _IOHIDElementRef uintptr
|
||||
type _IOHIDValueRef uintptr
|
||||
type _IOReturn int
|
||||
type _IOHIDElementType uint
|
||||
|
||||
type _IOHIDDeviceCallback func(context unsafe.Pointer, result _IOReturn, sender unsafe.Pointer, device _IOHIDDeviceRef)
|
||||
|
||||
var (
|
||||
iokit = purego.Dlopen("IOKit.framework/IOKit", purego.RTLD_GLOBAL)
|
||||
|
||||
procIOHIDElementGetTypeID = purego.Dlsym(iokit, "IOHIDElementGetTypeID")
|
||||
procIOHIDManagerCreate = purego.Dlsym(iokit, "IOHIDManagerCreate")
|
||||
procIOHIDDeviceGetProperty = purego.Dlsym(iokit, "IOHIDDeviceGetProperty")
|
||||
procIOHIDManagerOpen = purego.Dlsym(iokit, "IOHIDManagerOpen")
|
||||
procIOHIDManagerSetDeviceMatchingMultiple = purego.Dlsym(iokit, "IOHIDManagerSetDeviceMatchingMultiple")
|
||||
procIOHIDManagerRegisterDeviceMatchingCallback = purego.Dlsym(iokit, "IOHIDManagerRegisterDeviceMatchingCallback")
|
||||
procIOHIDManagerRegisterDeviceRemovalCallback = purego.Dlsym(iokit, "IOHIDManagerRegisterDeviceRemovalCallback")
|
||||
procIOHIDManagerScheduleWithRunLoop = purego.Dlsym(iokit, "IOHIDManagerScheduleWithRunLoop")
|
||||
procIOHIDElementGetType = purego.Dlsym(iokit, "IOHIDElementGetType")
|
||||
procIOHIDElementGetUsage = purego.Dlsym(iokit, "IOHIDElementGetUsage")
|
||||
procIOHIDElementGetUsagePage = purego.Dlsym(iokit, "IOHIDElementGetUsagePage")
|
||||
procIOHIDElementGetLogicalMin = purego.Dlsym(iokit, "IOHIDElementGetLogicalMin")
|
||||
procIOHIDElementGetLogicalMax = purego.Dlsym(iokit, "IOHIDElementGetLogicalMax")
|
||||
procIOHIDDeviceGetValue = purego.Dlsym(iokit, "IOHIDDeviceGetValue")
|
||||
procIOHIDValueGetIntegerValue = purego.Dlsym(iokit, "IOHIDValueGetIntegerValue")
|
||||
procIOHIDDeviceCopyMatchingElements = purego.Dlsym(iokit, "IOHIDDeviceCopyMatchingElements")
|
||||
)
|
||||
|
||||
func _IOHIDElementGetTypeID() _CFTypeID {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDElementGetTypeID)
|
||||
return _CFTypeID(ret)
|
||||
}
|
||||
|
||||
func _IOHIDManagerCreate(allocator _CFAllocatorRef, options _IOOptionBits) _IOHIDManagerRef {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDManagerCreate, uintptr(allocator), uintptr(options))
|
||||
return _IOHIDManagerRef(ret)
|
||||
}
|
||||
|
||||
func _IOHIDDeviceGetProperty(device _IOHIDDeviceRef, key _CFStringRef) _CFTypeRef {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDDeviceGetProperty, uintptr(device), uintptr(key))
|
||||
return _CFTypeRef(ret)
|
||||
}
|
||||
|
||||
func _IOHIDManagerOpen(manager _IOHIDManagerRef, options _IOOptionBits) _IOReturn {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDManagerOpen, uintptr(manager), uintptr(options))
|
||||
return _IOReturn(ret)
|
||||
}
|
||||
|
||||
func _IOHIDManagerSetDeviceMatchingMultiple(manager _IOHIDManagerRef, multiple _CFArrayRef) {
|
||||
purego.SyscallN(procIOHIDManagerSetDeviceMatchingMultiple, uintptr(manager), uintptr(multiple))
|
||||
}
|
||||
|
||||
func _IOHIDManagerRegisterDeviceMatchingCallback(manager _IOHIDManagerRef, callback _IOHIDDeviceCallback, context unsafe.Pointer) {
|
||||
purego.SyscallN(procIOHIDManagerRegisterDeviceMatchingCallback, uintptr(manager), purego.NewCallback(callback), uintptr(context))
|
||||
}
|
||||
|
||||
func _IOHIDManagerRegisterDeviceRemovalCallback(manager _IOHIDManagerRef, callback _IOHIDDeviceCallback, context unsafe.Pointer) {
|
||||
purego.SyscallN(procIOHIDManagerRegisterDeviceRemovalCallback, uintptr(manager), purego.NewCallback(callback), uintptr(context))
|
||||
}
|
||||
|
||||
func _IOHIDManagerScheduleWithRunLoop(manager _IOHIDManagerRef, runLoop _CFRunLoopRef, runLoopMode _CFStringRef) {
|
||||
purego.SyscallN(procIOHIDManagerScheduleWithRunLoop, uintptr(manager), uintptr(runLoop), uintptr(runLoopMode))
|
||||
}
|
||||
|
||||
func _IOHIDElementGetType(element _IOHIDElementRef) _IOHIDElementType {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDElementGetType, uintptr(element))
|
||||
return _IOHIDElementType(ret)
|
||||
}
|
||||
|
||||
func _IOHIDElementGetUsage(element _IOHIDElementRef) uint32 {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDElementGetUsage, uintptr(element))
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func _IOHIDElementGetUsagePage(element _IOHIDElementRef) uint32 {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDElementGetUsagePage, uintptr(element))
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func _IOHIDElementGetLogicalMin(element _IOHIDElementRef) _CFIndex {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDElementGetLogicalMin, uintptr(element))
|
||||
return _CFIndex(ret)
|
||||
}
|
||||
|
||||
func _IOHIDElementGetLogicalMax(element _IOHIDElementRef) _CFIndex {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDElementGetLogicalMax, uintptr(element))
|
||||
return _CFIndex(ret)
|
||||
}
|
||||
|
||||
func _IOHIDDeviceGetValue(device _IOHIDDeviceRef, element _IOHIDElementRef, pValue *_IOHIDValueRef) _IOReturn {
|
||||
if pValue == nil {
|
||||
panic("IOHID: pValue cannot be nil")
|
||||
}
|
||||
ret, _, _ := purego.SyscallN(procIOHIDDeviceGetValue, uintptr(device), uintptr(element), uintptr(unsafe.Pointer(pValue)))
|
||||
return _IOReturn(ret)
|
||||
}
|
||||
|
||||
func _IOHIDValueGetIntegerValue(value _IOHIDValueRef) _CFIndex {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDValueGetIntegerValue, uintptr(value))
|
||||
return _CFIndex(ret)
|
||||
}
|
||||
|
||||
func _IOHIDDeviceCopyMatchingElements(device _IOHIDDeviceRef, matching _CFDictionaryRef, options _IOOptionBits) _CFArrayRef {
|
||||
ret, _, _ := purego.SyscallN(procIOHIDDeviceCopyMatchingElements, uintptr(device), uintptr(matching), uintptr(options))
|
||||
return _CFArrayRef(ret)
|
||||
}
|
@ -21,6 +21,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
@ -28,43 +29,10 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/gamepaddb"
|
||||
)
|
||||
|
||||
// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit
|
||||
//
|
||||
// #include <ForceFeedback/ForceFeedback.h>
|
||||
// #include <IOKit/hid/IOHIDLib.h>
|
||||
//
|
||||
// static CFStringRef cfStringRefIOHIDVendorIDKey() {
|
||||
// return CFSTR(kIOHIDVendorIDKey);
|
||||
// }
|
||||
//
|
||||
// static CFStringRef cfStringRefIOHIDProductIDKey() {
|
||||
// return CFSTR(kIOHIDProductIDKey);
|
||||
// }
|
||||
//
|
||||
// static CFStringRef cfStringRefIOHIDVersionNumberKey() {
|
||||
// return CFSTR(kIOHIDVersionNumberKey);
|
||||
// }
|
||||
//
|
||||
// static CFStringRef cfStringRefIOHIDProductKey() {
|
||||
// return CFSTR(kIOHIDProductKey);
|
||||
// }
|
||||
//
|
||||
// static CFStringRef cfStringRefIOHIDDeviceUsagePageKey() {
|
||||
// return CFSTR(kIOHIDDeviceUsagePageKey);
|
||||
// }
|
||||
//
|
||||
// static CFStringRef cfStringRefIOHIDDeviceUsageKey() {
|
||||
// return CFSTR(kIOHIDDeviceUsageKey);
|
||||
// }
|
||||
//
|
||||
// void ebitenGamepadMatchingCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef device);
|
||||
// void ebitenGamepadRemovalCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef device);
|
||||
import "C"
|
||||
|
||||
type nativeGamepadsImpl struct {
|
||||
hidManager C.IOHIDManagerRef
|
||||
devicesToAdd []C.IOHIDDeviceRef
|
||||
devicesToRemove []C.IOHIDDeviceRef
|
||||
hidManager _IOHIDManagerRef
|
||||
devicesToAdd []_IOHIDDeviceRef
|
||||
devicesToRemove []_IOHIDDeviceRef
|
||||
devicesM sync.Mutex
|
||||
}
|
||||
|
||||
@ -73,82 +41,80 @@ func newNativeGamepadsImpl() nativeGamepads {
|
||||
}
|
||||
|
||||
func (g *nativeGamepadsImpl) init(gamepads *gamepads) error {
|
||||
var dicts []C.CFDictionaryRef
|
||||
var dicts []_CFDictionaryRef
|
||||
|
||||
page := C.kHIDPage_GenericDesktop
|
||||
page := kHIDPage_GenericDesktop
|
||||
for _, usage := range []uint{
|
||||
C.kHIDUsage_GD_Joystick,
|
||||
C.kHIDUsage_GD_GamePad,
|
||||
C.kHIDUsage_GD_MultiAxisController,
|
||||
kHIDUsage_GD_Joystick,
|
||||
kHIDUsage_GD_GamePad,
|
||||
kHIDUsage_GD_MultiAxisController,
|
||||
} {
|
||||
pageRef := C.CFNumberCreate(C.kCFAllocatorDefault, C.kCFNumberIntType, unsafe.Pointer(&page))
|
||||
pageRef := _CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, unsafe.Pointer(&page))
|
||||
if pageRef == 0 {
|
||||
return errors.New("gamepad: CFNumberCreate returned nil")
|
||||
}
|
||||
defer C.CFRelease(C.CFTypeRef(pageRef))
|
||||
defer _CFRelease(_CFTypeRef(pageRef))
|
||||
|
||||
usageRef := C.CFNumberCreate(C.kCFAllocatorDefault, C.kCFNumberIntType, unsafe.Pointer(&usage))
|
||||
usageRef := _CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, unsafe.Pointer(&usage))
|
||||
if usageRef == 0 {
|
||||
return errors.New("gamepad: CFNumberCreate returned nil")
|
||||
}
|
||||
defer C.CFRelease(C.CFTypeRef(usageRef))
|
||||
defer _CFRelease(_CFTypeRef(usageRef))
|
||||
|
||||
keys := []C.CFStringRef{
|
||||
C.cfStringRefIOHIDDeviceUsagePageKey(),
|
||||
C.cfStringRefIOHIDDeviceUsageKey(),
|
||||
keys := []_CFStringRef{
|
||||
_CFStringCreateWithCString(kCFAllocatorDefault, kIOHIDDeviceUsagePageKey, kCFStringEncodingUTF8),
|
||||
_CFStringCreateWithCString(kCFAllocatorDefault, kIOHIDDeviceUsageKey, kCFStringEncodingUTF8),
|
||||
}
|
||||
values := []C.CFNumberRef{
|
||||
values := []_CFNumberRef{
|
||||
pageRef,
|
||||
usageRef,
|
||||
}
|
||||
|
||||
dict := C.CFDictionaryCreate(C.kCFAllocatorDefault,
|
||||
dict := _CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(*unsafe.Pointer)(unsafe.Pointer(&keys[0])),
|
||||
(*unsafe.Pointer)(unsafe.Pointer(&values[0])),
|
||||
C.CFIndex(len(keys)), &C.kCFTypeDictionaryKeyCallBacks, &C.kCFTypeDictionaryValueCallBacks)
|
||||
_CFIndex(len(keys)), *(**_CFDictionaryKeyCallBacks)(unsafe.Pointer(&kCFTypeDictionaryKeyCallBacks)), *(**_CFDictionaryValueCallBacks)(unsafe.Pointer(&kCFTypeDictionaryValueCallBacks)))
|
||||
if dict == 0 {
|
||||
return errors.New("gamepad: CFDictionaryCreate returned nil")
|
||||
}
|
||||
defer C.CFRelease(C.CFTypeRef(dict))
|
||||
defer _CFRelease(_CFTypeRef(dict))
|
||||
|
||||
dicts = append(dicts, dict)
|
||||
}
|
||||
|
||||
matching := C.CFArrayCreate(C.kCFAllocatorDefault,
|
||||
matching := _CFArrayCreate(kCFAllocatorDefault,
|
||||
(*unsafe.Pointer)(unsafe.Pointer(&dicts[0])),
|
||||
C.CFIndex(len(dicts)), &C.kCFTypeArrayCallBacks)
|
||||
_CFIndex(len(dicts)), *(**_CFArrayCallBacks)(unsafe.Pointer(&kCFTypeArrayCallBacks)))
|
||||
if matching == 0 {
|
||||
return errors.New("gamepad: CFArrayCreateMutable returned nil")
|
||||
}
|
||||
defer C.CFRelease(C.CFTypeRef(matching))
|
||||
defer _CFRelease(_CFTypeRef(matching))
|
||||
|
||||
g.hidManager = C.IOHIDManagerCreate(C.kCFAllocatorDefault, C.kIOHIDOptionsTypeNone)
|
||||
if C.IOHIDManagerOpen(g.hidManager, C.kIOHIDOptionsTypeNone) != C.kIOReturnSuccess {
|
||||
g.hidManager = _IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)
|
||||
if _IOHIDManagerOpen(g.hidManager, kIOHIDOptionsTypeNone) != kIOReturnSuccess {
|
||||
return errors.New("gamepad: IOHIDManagerOpen failed")
|
||||
}
|
||||
|
||||
C.IOHIDManagerSetDeviceMatchingMultiple(g.hidManager, matching)
|
||||
C.IOHIDManagerRegisterDeviceMatchingCallback(g.hidManager, C.IOHIDDeviceCallback(C.ebitenGamepadMatchingCallback), nil)
|
||||
C.IOHIDManagerRegisterDeviceRemovalCallback(g.hidManager, C.IOHIDDeviceCallback(C.ebitenGamepadRemovalCallback), nil)
|
||||
_IOHIDManagerSetDeviceMatchingMultiple(g.hidManager, matching)
|
||||
_IOHIDManagerRegisterDeviceMatchingCallback(g.hidManager, ebitenGamepadMatchingCallback, nil)
|
||||
_IOHIDManagerRegisterDeviceRemovalCallback(g.hidManager, ebitenGamepadRemovalCallback, nil)
|
||||
|
||||
C.IOHIDManagerScheduleWithRunLoop(g.hidManager, C.CFRunLoopGetMain(), C.kCFRunLoopDefaultMode)
|
||||
_IOHIDManagerScheduleWithRunLoop(g.hidManager, _CFRunLoopGetMain(), **(**_CFStringRef)(unsafe.Pointer(&kCFRunLoopDefaultMode)))
|
||||
|
||||
// Execute the run loop once in order to register any initially-attached gamepads.
|
||||
C.CFRunLoopRunInMode(C.kCFRunLoopDefaultMode, 0, 0 /* false */)
|
||||
_CFRunLoopRunInMode(**(**_CFStringRef)(unsafe.Pointer(&kCFRunLoopDefaultMode)), 0, false)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//export ebitenGamepadMatchingCallback
|
||||
func ebitenGamepadMatchingCallback(ctx unsafe.Pointer, res C.IOReturn, sender unsafe.Pointer, device C.IOHIDDeviceRef) {
|
||||
func ebitenGamepadMatchingCallback(ctx unsafe.Pointer, res _IOReturn, sender unsafe.Pointer, device _IOHIDDeviceRef) {
|
||||
n := theGamepads.native.(*nativeGamepadsImpl)
|
||||
n.devicesM.Lock()
|
||||
defer n.devicesM.Unlock()
|
||||
n.devicesToAdd = append(n.devicesToAdd, device)
|
||||
}
|
||||
|
||||
//export ebitenGamepadRemovalCallback
|
||||
func ebitenGamepadRemovalCallback(ctx unsafe.Pointer, res C.IOReturn, sender unsafe.Pointer, device C.IOHIDDeviceRef) {
|
||||
func ebitenGamepadRemovalCallback(ctx unsafe.Pointer, res _IOReturn, sender unsafe.Pointer, device _IOHIDDeviceRef) {
|
||||
n := theGamepads.native.(*nativeGamepadsImpl)
|
||||
n.devicesM.Lock()
|
||||
defer n.devicesM.Unlock()
|
||||
@ -173,7 +139,7 @@ func (g *nativeGamepadsImpl) update(gamepads *gamepads) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *nativeGamepadsImpl) addDevice(device C.IOHIDDeviceRef, gamepads *gamepads) {
|
||||
func (g *nativeGamepadsImpl) addDevice(device _IOHIDDeviceRef, gamepads *gamepads) {
|
||||
if gamepads.find(func(g *Gamepad) bool {
|
||||
return g.native.(*nativeGamepadImpl).device == device
|
||||
}) != nil {
|
||||
@ -181,25 +147,25 @@ func (g *nativeGamepadsImpl) addDevice(device C.IOHIDDeviceRef, gamepads *gamepa
|
||||
}
|
||||
|
||||
name := "Unknown"
|
||||
if prop := C.IOHIDDeviceGetProperty(device, C.cfStringRefIOHIDProductKey()); prop != 0 {
|
||||
var cstr [256]C.char
|
||||
C.CFStringGetCString(C.CFStringRef(prop), &cstr[0], C.CFIndex(len(cstr)), C.kCFStringEncodingUTF8)
|
||||
name = C.GoString(&cstr[0])
|
||||
if prop := _IOHIDDeviceGetProperty(_IOHIDDeviceRef(device), _CFStringCreateWithCString(kCFAllocatorDefault, kIOHIDProductKey, kCFStringEncodingUTF8)); prop != 0 {
|
||||
var cstr [256]byte
|
||||
_CFStringGetCString(_CFStringRef(prop), cstr[:], kCFStringEncodingUTF8)
|
||||
name = strings.TrimRight(string(cstr[:]), "\x00")
|
||||
}
|
||||
|
||||
var vendor uint32
|
||||
if prop := C.IOHIDDeviceGetProperty(device, C.cfStringRefIOHIDVendorIDKey()); prop != 0 {
|
||||
C.CFNumberGetValue(C.CFNumberRef(prop), C.kCFNumberSInt32Type, unsafe.Pointer(&vendor))
|
||||
if prop := _IOHIDDeviceGetProperty(_IOHIDDeviceRef(device), _CFStringCreateWithCString(kCFAllocatorDefault, kIOHIDVendorIDKey, kCFStringEncodingUTF8)); prop != 0 {
|
||||
_CFNumberGetValue(_CFNumberRef(prop), kCFNumberSInt32Type, unsafe.Pointer(&vendor))
|
||||
}
|
||||
|
||||
var product uint32
|
||||
if prop := C.IOHIDDeviceGetProperty(device, C.cfStringRefIOHIDProductIDKey()); prop != 0 {
|
||||
C.CFNumberGetValue(C.CFNumberRef(prop), C.kCFNumberSInt32Type, unsafe.Pointer(&product))
|
||||
if prop := _IOHIDDeviceGetProperty(_IOHIDDeviceRef(device), _CFStringCreateWithCString(kCFAllocatorDefault, kIOHIDProductIDKey, kCFStringEncodingUTF8)); prop != 0 {
|
||||
_CFNumberGetValue(_CFNumberRef(prop), kCFNumberSInt32Type, unsafe.Pointer(&product))
|
||||
}
|
||||
|
||||
var version uint32
|
||||
if prop := C.IOHIDDeviceGetProperty(device, C.cfStringRefIOHIDVersionNumberKey()); prop != 0 {
|
||||
C.CFNumberGetValue(C.CFNumberRef(prop), C.kCFNumberSInt32Type, unsafe.Pointer(&version))
|
||||
if prop := _IOHIDDeviceGetProperty(_IOHIDDeviceRef(device), _CFStringCreateWithCString(kCFAllocatorDefault, kIOHIDVersionNumberKey, kCFStringEncodingUTF8)); prop != 0 {
|
||||
_CFNumberGetValue(_CFNumberRef(prop), kCFNumberSInt32Type, unsafe.Pointer(&version))
|
||||
}
|
||||
|
||||
var sdlID string
|
||||
@ -217,8 +183,8 @@ func (g *nativeGamepadsImpl) addDevice(device C.IOHIDDeviceRef, gamepads *gamepa
|
||||
bs[0], bs[1], bs[2], bs[3], bs[4], bs[5], bs[6], bs[7], bs[8], bs[9], bs[10], bs[11])
|
||||
}
|
||||
|
||||
elements := C.IOHIDDeviceCopyMatchingElements(device, 0, C.kIOHIDOptionsTypeNone)
|
||||
defer C.CFRelease(C.CFTypeRef(elements))
|
||||
elements := _IOHIDDeviceCopyMatchingElements(device, 0, kIOHIDOptionsTypeNone)
|
||||
defer _CFRelease(_CFTypeRef(elements))
|
||||
|
||||
n := &nativeGamepadImpl{
|
||||
device: device,
|
||||
@ -226,71 +192,71 @@ func (g *nativeGamepadsImpl) addDevice(device C.IOHIDDeviceRef, gamepads *gamepa
|
||||
gp := gamepads.add(name, sdlID)
|
||||
gp.native = n
|
||||
|
||||
for i := C.CFIndex(0); i < C.CFArrayGetCount(elements); i++ {
|
||||
native := (C.IOHIDElementRef)(C.CFArrayGetValueAtIndex(elements, i))
|
||||
if C.CFGetTypeID(C.CFTypeRef(native)) != C.IOHIDElementGetTypeID() {
|
||||
for i := _CFIndex(0); i < _CFArrayGetCount(_CFArrayRef(elements)); i++ {
|
||||
native := (_IOHIDElementRef)(_CFArrayGetValueAtIndex(_CFArrayRef(elements), i))
|
||||
if _CFGetTypeID(_CFTypeRef(native)) != _IOHIDElementGetTypeID() {
|
||||
continue
|
||||
}
|
||||
|
||||
typ := C.IOHIDElementGetType(native)
|
||||
if typ != C.kIOHIDElementTypeInput_Axis &&
|
||||
typ != C.kIOHIDElementTypeInput_Button &&
|
||||
typ != C.kIOHIDElementTypeInput_Misc {
|
||||
typ := _IOHIDElementGetType(native)
|
||||
if typ != kIOHIDElementTypeInput_Axis &&
|
||||
typ != kIOHIDElementTypeInput_Button &&
|
||||
typ != kIOHIDElementTypeInput_Misc {
|
||||
continue
|
||||
}
|
||||
|
||||
usage := C.IOHIDElementGetUsage(native)
|
||||
page := C.IOHIDElementGetUsagePage(native)
|
||||
usage := _IOHIDElementGetUsage(native)
|
||||
page := _IOHIDElementGetUsagePage(native)
|
||||
|
||||
switch page {
|
||||
case C.kHIDPage_GenericDesktop:
|
||||
case kHIDPage_GenericDesktop:
|
||||
switch usage {
|
||||
case C.kHIDUsage_GD_X, C.kHIDUsage_GD_Y, C.kHIDUsage_GD_Z,
|
||||
C.kHIDUsage_GD_Rx, C.kHIDUsage_GD_Ry, C.kHIDUsage_GD_Rz,
|
||||
C.kHIDUsage_GD_Slider, C.kHIDUsage_GD_Dial, C.kHIDUsage_GD_Wheel:
|
||||
case kHIDUsage_GD_X, kHIDUsage_GD_Y, kHIDUsage_GD_Z,
|
||||
kHIDUsage_GD_Rx, kHIDUsage_GD_Ry, kHIDUsage_GD_Rz,
|
||||
kHIDUsage_GD_Slider, kHIDUsage_GD_Dial, kHIDUsage_GD_Wheel:
|
||||
n.axes = append(n.axes, element{
|
||||
native: native,
|
||||
usage: int(usage),
|
||||
index: len(n.axes),
|
||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||
minimum: int(_IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(_IOHIDElementGetLogicalMax(native)),
|
||||
})
|
||||
case C.kHIDUsage_GD_Hatswitch:
|
||||
case kHIDUsage_GD_Hatswitch:
|
||||
n.hats = append(n.hats, element{
|
||||
native: native,
|
||||
usage: int(usage),
|
||||
index: len(n.hats),
|
||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||
minimum: int(_IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(_IOHIDElementGetLogicalMax(native)),
|
||||
})
|
||||
case C.kHIDUsage_GD_DPadUp, C.kHIDUsage_GD_DPadRight, C.kHIDUsage_GD_DPadDown, C.kHIDUsage_GD_DPadLeft,
|
||||
C.kHIDUsage_GD_SystemMainMenu, C.kHIDUsage_GD_Select, C.kHIDUsage_GD_Start:
|
||||
case kHIDUsage_GD_DPadUp, kHIDUsage_GD_DPadRight, kHIDUsage_GD_DPadDown, kHIDUsage_GD_DPadLeft,
|
||||
kHIDUsage_GD_SystemMainMenu, kHIDUsage_GD_Select, kHIDUsage_GD_Start:
|
||||
n.buttons = append(n.buttons, element{
|
||||
native: native,
|
||||
usage: int(usage),
|
||||
index: len(n.buttons),
|
||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||
minimum: int(_IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(_IOHIDElementGetLogicalMax(native)),
|
||||
})
|
||||
}
|
||||
case C.kHIDPage_Simulation:
|
||||
case kHIDPage_Simulation:
|
||||
switch usage {
|
||||
case C.kHIDUsage_Sim_Accelerator, C.kHIDUsage_Sim_Brake, C.kHIDUsage_Sim_Throttle, C.kHIDUsage_Sim_Rudder, C.kHIDUsage_Sim_Steering:
|
||||
case kHIDUsage_Sim_Accelerator, kHIDUsage_Sim_Brake, kHIDUsage_Sim_Throttle, kHIDUsage_Sim_Rudder, kHIDUsage_Sim_Steering:
|
||||
n.axes = append(n.axes, element{
|
||||
native: native,
|
||||
usage: int(usage),
|
||||
index: len(n.axes),
|
||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||
minimum: int(_IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(_IOHIDElementGetLogicalMax(native)),
|
||||
})
|
||||
}
|
||||
case C.kHIDPage_Button, C.kHIDPage_Consumer:
|
||||
case kHIDPage_Button, kHIDPage_Consumer:
|
||||
n.buttons = append(n.buttons, element{
|
||||
native: native,
|
||||
usage: int(usage),
|
||||
index: len(n.buttons),
|
||||
minimum: int(C.IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(C.IOHIDElementGetLogicalMax(native)),
|
||||
minimum: int(_IOHIDElementGetLogicalMin(native)),
|
||||
maximum: int(_IOHIDElementGetLogicalMax(native)),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -301,7 +267,7 @@ func (g *nativeGamepadsImpl) addDevice(device C.IOHIDDeviceRef, gamepads *gamepa
|
||||
}
|
||||
|
||||
type element struct {
|
||||
native C.IOHIDElementRef
|
||||
native _IOHIDElementRef
|
||||
usage int
|
||||
index int
|
||||
minimum int
|
||||
@ -329,7 +295,7 @@ func (e elements) Swap(i, j int) {
|
||||
}
|
||||
|
||||
type nativeGamepadImpl struct {
|
||||
device C.IOHIDDeviceRef
|
||||
device _IOHIDDeviceRef
|
||||
axes elements
|
||||
buttons elements
|
||||
hats elements
|
||||
@ -340,11 +306,10 @@ type nativeGamepadImpl struct {
|
||||
}
|
||||
|
||||
func (g *nativeGamepadImpl) elementValue(e *element) int {
|
||||
var valueRef C.IOHIDValueRef
|
||||
if C.IOHIDDeviceGetValue(g.device, e.native, &valueRef) == C.kIOReturnSuccess {
|
||||
return int(C.IOHIDValueGetIntegerValue(valueRef))
|
||||
var valueRef _IOHIDValueRef
|
||||
if _IOHIDDeviceGetValue(g.device, e.native, &valueRef) == kIOReturnSuccess {
|
||||
return int(_IOHIDValueGetIntegerValue(valueRef))
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user