progress implementing SML-side handling of controller

This commit is contained in:
2026-01-20 07:10:15 +00:00
parent f2bffc4b6b
commit 73d30bfb1f
5 changed files with 126 additions and 32 deletions

View File

@@ -45,9 +45,12 @@ GLFWgamepadstate state;
float* axes;
int axesCount = -1;
void getGamepadState(int joystickID) {
if (glfwGetGamepadState(joystickID, &state)) {
int getGamepadState(int joystickID) {
if (glfwJoystickIsGamepad(joystickID) && glfwGetGamepadState(joystickID, &state)) {
axes = glfwGetJoystickAxes(joystickID, &axesCount);
return 1;
} else {
return 0;
}
}

View File

@@ -55,7 +55,7 @@ struct
(* gamepad bindings below *)
val getGamepadState =
_import "getGamepadState" public : int -> unit;
_import "getGamepadState" public : int -> int;
val getLeftJoystickXAxisState =
_import "getLeftJoystickXAxisState" public : unit -> Real32.real;

View File

@@ -145,28 +145,6 @@ struct
updateLoop (0, InputMailbox.getMessagesAndClear (), app)
end
fun getGamepadState () =
let
val () = Input.getGamepadState 0
val () = Input.getGamepadState 1
val () = Input.getGamepadState 2
val () = Input.getGamepadState 3
val () = Input.getGamepadState 4
val () = Input.getGamepadState 5
val () = Input.getGamepadState 6
val () = Input.getGamepadState 7
val () = Input.getGamepadState 8
val () = Input.getGamepadState 9
val () = Input.getGamepadState 10
val () = Input.getGamepadState 11
val () = Input.getGamepadState 12
val () = Input.getGamepadState 13
val () = Input.getGamepadState 14
val () = Input.getGamepadState 15
in
()
end
fun helpLoop (app, shellState as {window, ...}: t) =
case Glfw.windowShouldClose window of
false =>
@@ -176,13 +154,7 @@ fun getGamepadState () =
val _ = Gles3.clearColor (0.89, 0.89, 0.89, 1.0)
val _ = Gles3.clear ()
val () = getGamepadState ()
val xAxis = Input.getLeftJoystickXAxisState ()
val yAxis = Input.getLeftJoystickYAxisState ()
val () = print ("x axis = " ^ Real32.toString xAxis ^ "\n")
val () = print ("y axis = " ^ Real32.toString yAxis ^ "\n")
val () = print "\n"
val () = GlfwGamepad.query ()
val app = update app
val _ = draw shellState

118
shell/glfw-gamepad.sml Normal file
View File

@@ -0,0 +1,118 @@
structure GlfwGamepad =
struct
datatype joystick_dir = UP | LEFT | DOWN | RIGHT | CENTRE | L2 | R2
fun isInDeadZone (x, y) =
x < 0.1 andalso x > ~0.1 andalso y < 0.1 andalso y > ~0.1
(* todo: query L2 and R2, and handle them *)
fun axisToDir (x, y) =
if isInDeadZone (x, y) then CENTRE
else if abs x > abs y then if x > 0.0 then RIGHT else LEFT
else if y > 0.0 then DOWN
else UP
fun getGamepadState () =
Input.getGamepadState 0 <> 0 orelse Input.getGamepadState 1 <> 0
orelse Input.getGamepadState 2 <> 0 orelse Input.getGamepadState 3 <> 0
orelse Input.getGamepadState 4 <> 0 orelse Input.getGamepadState 5 <> 0
orelse Input.getGamepadState 6 <> 0 orelse Input.getGamepadState 7 <> 0
orelse Input.getGamepadState 8 <> 0 orelse Input.getGamepadState 9 <> 0
orelse Input.getGamepadState 10 <> 0 orelse Input.getGamepadState 11 <> 0
orelse Input.getGamepadState 12 <> 0 orelse Input.getGamepadState 13 <> 0
orelse Input.getGamepadState 14 <> 0 orelse Input.getGamepadState 15 <> 0
local open InputMsg
in
fun handleTrianglePressed (x, y) =
let
val chr =
case axisToDir (x, y) of
CENTRE => #"a"
| UP => #"e"
| RIGHT => #"i"
| DOWN => #"m"
| LEFT => #"q"
| L2 => #"u"
| R2 => #"y"
in
InputMailbox.append (CHAR_EVENT chr)
end
fun handleCirclePressed (x, y) =
let
val chr =
case axisToDir (x, y) of
CENTRE => #"b"
| UP => #"f"
| RIGHT => #"j"
| DOWN => #"n"
| LEFT => #"r"
| L2 => #"v"
| R2 => #"z"
in
InputMailbox.append (CHAR_EVENT chr)
end
fun handleCrossPressed (x, y) =
case axisToDir (x, y) of
CENTRE => InputMailbox.append (CHAR_EVENT #"c")
| UP => InputMailbox.append (CHAR_EVENT #"g")
| RIGHT => InputMailbox.append (CHAR_EVENT #"k")
| DOWN => InputMailbox.append (CHAR_EVENT #"o")
| LEFT => InputMailbox.append (CHAR_EVENT #"s")
| L2 => InputMailbox.append (CHAR_EVENT #"w")
| R2 =>
(* todo: either shift or enter *)
raise Fail "glfw-gamepad.sml: 77\n"
fun handleSquarePressed (x, y) =
case axisToDir (x, y) of
CENTRE => InputMailbox.append (CHAR_EVENT #"d")
| UP => InputMailbox.append (CHAR_EVENT #"h")
| RIGHT => InputMailbox.append (CHAR_EVENT #"l")
| DOWN => InputMailbox.append (CHAR_EVENT #"p")
| LEFT => InputMailbox.append (CHAR_EVENT #"t")
| L2 => InputMailbox.append (CHAR_EVENT #"x")
| R2 =>
(* todo: either shift or enter *)
raise Fail "glfw-gamepad.sml: 87\n"
end
fun handleIfJoystickIsPresent () =
let
open InputMsg
val xAxis = Input.getLeftJoystickXAxisState ()
val yAxis = Input.getLeftJoystickYAxisState ()
val crossPrressed = Input.isCrossButtonPressed ()
val circlePressed = Input.isCircleButtonPressed ()
val squarePressed = Input.isSquareButtonPressed ()
val trianglePressed = Input.isTriangleButtonPressed ()
val r1Pressed = Input.isR1ButtonPressed ()
val l1Pressed = Input.isL1ButtonPressed ()
in
if crossPrressed <> 0 then
(* pressing two buttons at the same time is a no-op *)
if
circlePressed <> 0 orelse squarePressed <> 0
orelse trianglePressed <> 0 orelse r1Pressed <> 0
orelse l1Pressed <> 0
then ()
else handleCrossPressed (xAxis, yAxis)
else if circlePressed <> 0 then
if
squarePressed <> 0 orelse trianglePressed <> 0 orelse r1Pressed <> 0
orelse l1Pressed <> 0
then ()
else handleCirclePressed (xAxis, yAxis)
else
()
end
fun query () =
if getGamepadState () then handleIfJoystickIsPresent ()
else (* nothing to do if no gamepad is present *) ()
end

View File

@@ -82,6 +82,7 @@ shell/draw-mailbox.sml
shell/exception-logger.sml
shell/updater.sml
shell/glfw-gamepad.sml
shell/gl-shaders.sml
shell/gl-draw.sml
shell/shell.sml