Files
sml-projects/game-sml/shell/input-state.sml

96 lines
2.7 KiB
Standard ML
Raw Permalink Normal View History

structure InputState =
struct
val keyMappings = ref
{ left = CoreKey.KEY_S
, right = CoreKey.KEY_F
, down = CoreKey.KEY_D
, up = CoreKey.KEY_E
, attack = CoreKey.KEY_J
, jump = CoreKey.KEY_K
, escape = CoreKey.KEY_ESCAPE
}
fun setControls controls = keyMappings := controls
(* global state detecting button inputs *)
val state =
{ leftHeld = ref false
, rightHeld = ref false
, upHeld = ref false
, downHeld = ref false
, jumpHeld = ref false
, attackHeld = ref false
, escapeHeld = ref false
, newKeys = ref []
, width = ref (1920.0 : Real32.real)
, height = ref (1080.0 : Real32.real)
}
fun getSnapshot () =
let
val input =
{ leftHeld = !(#leftHeld state)
, rightHeld = !(#rightHeld state)
, upHeld = !(#upHeld state)
, downHeld = !(#downHeld state)
, attackHeld = !(#attackHeld state)
, jumpHeld = !(#jumpHeld state)
, escapeHeld = !(#escapeHeld state)
, newKeys = !(#newKeys state)
}
val () = #newKeys state := []
in
input
end
(* there are three action states reported by OS: PRESS, REPEAT and RELEASE.
* If input is PRESS or REPEAT, then return true, or else return false. *)
fun actionToBool action = action <> Input.RELEASE
fun handleKey (key, action) =
case GlfwKeyMap.codeFromKey key of
SOME code =>
let
val () =
if action = Input.PRESS then
#newKeys state := code :: !(#newKeys state)
else
()
val {left, right, down, up, attack, jump, escape} = !keyMappings
val action = actionToBool action
in
if code = left then #leftHeld state := action
else if code = up then #upHeld state := action
else if code = right then #rightHeld state := action
else if code = down then #downHeld state := action
else if code = attack then #attackHeld state := action
else if code = jump then #jumpHeld state := action
else if code = escape then #escapeHeld state := action
else ()
end
| NONE => ()
fun keyCallback (key, scancode, action, mods) =
if mods = 0 then handleKey (key, action) else ()
fun getWidth () =
!(#width state)
fun getHeight () =
!(#height state)
fun sizeCallback (width, height) =
(#width state := width; #height state := height)
fun registerCallbacks window =
let
val () = Input.exportKeyCallback keyCallback
val () = Input.setKeyCallback window
val () = Input.exportFramebufferSizeCallback sizeCallback
val () = Input.setFramebufferSizeCallback window
in
()
end
end