diff --git a/internal/gamepad/gamepad_nintendosdk.cpp b/internal/gamepad/gamepad_nintendosdk.cpp new file mode 100644 index 000000000..0025fce07 --- /dev/null +++ b/internal/gamepad/gamepad_nintendosdk.cpp @@ -0,0 +1,31 @@ +// 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. + +//go:build nintendosdk + +// The actual implementaiton will be provided by -overlay. + +#include "gamepad_nintendosdk.h" + +extern "C" void ebitengine_UpdateGamepads() {} + +extern "C" int ebitengine_GetGamepadCount() { + return 0; +} + +extern "C" void ebitengine_GetGamepads(struct Gamepad *gamepads) {} + +extern "C" void ebitengine_VibrateGamepad(int id, double durationInSeconds, + double strongMagnitude, + double weakMagnitude) {} diff --git a/internal/gamepad/gamepad_nintendosdk.go b/internal/gamepad/gamepad_nintendosdk.go index da1baec93..a7cbfe106 100644 --- a/internal/gamepad/gamepad_nintendosdk.go +++ b/internal/gamepad/gamepad_nintendosdk.go @@ -16,15 +16,25 @@ package gamepad +// #cgo !darwin LDFLAGS: -Wl,-unresolved-symbols=ignore-all +// #cgo darwin LDFLAGS: -Wl,-undefined,dynamic_lookup +// +// #include "gamepad_nintendosdk.h" +// +// void ebitengine_UpdateGamepads(); +// int ebitengine_GetGamepadCount(); +// void ebitengine_GetGamepads(struct Gamepad* gamepads); +// void ebitengine_VibrateGamepad(int id, double durationInSeconds, double strongMagnitude, double weakMagnitude); +import "C" + import ( "time" "github.com/hajimehoshi/ebiten/v2/internal/gamepaddb" - "github.com/hajimehoshi/ebiten/v2/internal/nintendosdk" ) type nativeGamepadsImpl struct { - gamepads []nintendosdk.Gamepad + gamepads []C.struct_Gamepad ids map[int]struct{} } @@ -37,8 +47,17 @@ func (*nativeGamepadsImpl) init(gamepads *gamepads) error { } func (g *nativeGamepadsImpl) update(gamepads *gamepads) error { + C.ebitengine_UpdateGamepads() + g.gamepads = g.gamepads[:0] - g.gamepads = nintendosdk.AppendGamepads(g.gamepads) + if n := int(C.ebitengine_GetGamepadCount()); n > 0 { + if cap(g.gamepads) < n { + g.gamepads = make([]C.struct_Gamepad, n) + } else { + g.gamepads = g.gamepads[:n] + } + C.ebitengine_GetGamepads(&g.gamepads[0]) + } for id := range g.ids { delete(g.ids, id) @@ -48,27 +67,33 @@ func (g *nativeGamepadsImpl) update(gamepads *gamepads) error { if g.ids == nil { g.ids = map[int]struct{}{} } - g.ids[gp.ID] = struct{}{} + g.ids[int(gp.id)] = struct{}{} gamepad := gamepads.find(func(gamepad *Gamepad) bool { - return gamepad.native.(*nativeGamepadImpl).id == gp.ID + return gamepad.native.(*nativeGamepadImpl).id == int(gp.id) }) if gamepad == nil { gamepad = gamepads.add("", "") gamepad.native = &nativeGamepadImpl{ - id: gp.ID, - standard: gp.Standard, - axisValues: make([]float64, gp.AxisCount), - buttonPressed: make([]bool, gp.ButtonCount), - buttonValues: make([]float64, gp.ButtonCount), + id: int(gp.id), + standard: bool(gp.standard != 0), + axisValues: make([]float64, gp.axis_count), + buttonPressed: make([]bool, gp.button_count), + buttonValues: make([]float64, gp.button_count), } } gamepad.m.Lock() n := gamepad.native.(*nativeGamepadImpl) - copy(n.axisValues, gp.AxisValues[:]) - copy(n.buttonValues, gp.ButtonValues[:]) - copy(n.buttonPressed, gp.ButtonPressed[:]) + for i := range n.axisValues { + n.axisValues[i] = float64(gp.axis_values[i]) + } + for i := range n.buttonValues { + n.buttonValues[i] = float64(gp.button_values[i]) + } + for i := range n.buttonPressed { + n.buttonPressed[i] = gp.button_pressed[i] != 0 + } gamepad.m.Unlock() } @@ -146,5 +171,5 @@ func (*nativeGamepadImpl) hatState(hat int) int { } func (g *nativeGamepadImpl) vibrate(duration time.Duration, strongMagnitude float64, weakMagnitude float64) { - nintendosdk.VibrateGamepad(g.id, duration, strongMagnitude, weakMagnitude) + C.ebitengine_VibrateGamepad(C.int(g.id), C.double(float64(duration)/float64(time.Second)), C.double(strongMagnitude), C.double(weakMagnitude)) } diff --git a/internal/gamepad/gamepad_nintendosdk.h b/internal/gamepad/gamepad_nintendosdk.h new file mode 100644 index 000000000..72bfa5d86 --- /dev/null +++ b/internal/gamepad/gamepad_nintendosdk.h @@ -0,0 +1,25 @@ +// 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. + +//go:build nintendosdk + +struct Gamepad { + int id; + char standard; + int button_count; + int axis_count; + char button_pressed[32]; + float button_values[32]; + float axis_values[16]; +}; diff --git a/internal/nintendosdk/nintendosdk.go b/internal/nintendosdk/nintendosdk.go index ad5c313f6..b4696e5b4 100644 --- a/internal/nintendosdk/nintendosdk.go +++ b/internal/nintendosdk/nintendosdk.go @@ -21,16 +21,6 @@ package nintendosdk // // #include // -// struct Gamepad { -// int id; -// char standard; -// int button_num; -// int axis_num; -// char button_pressed[32]; -// float button_values[32]; -// float axis_values[16]; -// }; -// // struct Touch { // int id; // int x; @@ -44,27 +34,10 @@ package nintendosdk // void EbitenEndFrame(); // // // Input -// int EbitenGetGamepadNum(); -// void EbitenGetGamepads(struct Gamepad* gamepads); // int EbitenGetTouchNum(); // void EbitenGetTouches(struct Touch* touches); -// void EbitenVibrateGamepad(int id, double durationInSeconds, double strongMagnitude, double weakMagnitude); import "C" -import ( - "time" -) - -type Gamepad struct { - ID int - Standard bool - ButtonCount int - AxisCount int - ButtonPressed [32]bool - ButtonValues [32]float64 - AxisValues [16]float64 -} - type Touch struct { ID int X int @@ -89,39 +62,6 @@ func EndFrame() { C.EbitenEndFrame() } -var cGamepads []C.struct_Gamepad - -func AppendGamepads(gamepads []Gamepad) []Gamepad { - n := int(C.EbitenGetGamepadNum()) - if cap(cGamepads) < n { - cGamepads = append(cGamepads, make([]C.struct_Gamepad, n)...) - } else { - cGamepads = cGamepads[:n] - } - if n > 0 { - C.EbitenGetGamepads(&cGamepads[0]) - } - - for _, g := range cGamepads { - gamepad := Gamepad{ - ID: int(g.id), - Standard: g.standard != 0, - ButtonCount: int(g.button_num), - AxisCount: int(g.axis_num), - } - for i := 0; i < gamepad.ButtonCount; i++ { - gamepad.ButtonPressed[i] = g.button_pressed[i] != 0 - gamepad.ButtonValues[i] = float64(g.button_values[i]) - } - for i := 0; i < gamepad.AxisCount; i++ { - gamepad.AxisValues[i] = float64(g.axis_values[i]) - } - - gamepads = append(gamepads, gamepad) - } - return gamepads -} - var cTouches []C.struct_Touch func AppendTouches(touches []Touch) []Touch { @@ -145,7 +85,3 @@ func AppendTouches(touches []Touch) []Touch { } return touches } - -func VibrateGamepad(id int, duration time.Duration, strongMagnitude float64, weakMagnitude float64) { - C.EbitenVibrateGamepad(C.int(id), C.double(float64(duration)/float64(time.Second)), C.double(strongMagnitude), C.double(weakMagnitude)) -}