2025-02-17 03:13:45 +00:00
|
|
|
structure ParseControls =
|
|
|
|
|
struct
|
|
|
|
|
datatype action =
|
|
|
|
|
ACTION_LEFT
|
|
|
|
|
| ACTION_RIGHT
|
|
|
|
|
| ACTION_UP
|
|
|
|
|
| ACTION_DOWN
|
|
|
|
|
| ACTION_JUMP
|
|
|
|
|
| ACTION_ATTACK
|
|
|
|
|
|
|
|
|
|
fun actionFromString str =
|
|
|
|
|
case str of
|
|
|
|
|
"ACTION_LEFT" => SOME ACTION_LEFT
|
|
|
|
|
| "ACTION_RIGHT" => SOME ACTION_RIGHT
|
|
|
|
|
| "ACTION_UP" => SOME ACTION_UP
|
|
|
|
|
| "ACTION_DOWN" => SOME ACTION_DOWN
|
2025-02-17 03:48:31 +00:00
|
|
|
| "ACTION_JUMP" => SOME ACTION_JUMP
|
2025-02-17 03:13:45 +00:00
|
|
|
| "ACTION_ATTACK" => SOME ACTION_ATTACK
|
|
|
|
|
| _ => NONE
|
|
|
|
|
|
|
|
|
|
fun findColon (pos, str) =
|
|
|
|
|
if pos = String.size str then
|
|
|
|
|
~1
|
|
|
|
|
else
|
|
|
|
|
let val chr = String.sub (str, pos)
|
|
|
|
|
in if chr = #":" then pos else findColon (pos + 1, str)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
type parsed_keys =
|
|
|
|
|
{ left: CoreKey.key_code option
|
|
|
|
|
, right: CoreKey.key_code option
|
|
|
|
|
, up: CoreKey.key_code option
|
|
|
|
|
, down: CoreKey.key_code option
|
|
|
|
|
, jump: CoreKey.key_code option
|
|
|
|
|
, attack: CoreKey.key_code option
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun updateControls (action, key, controls: parsed_keys) =
|
|
|
|
|
let
|
|
|
|
|
val {left, right, up, down, jump, attack} = controls
|
|
|
|
|
in
|
|
|
|
|
case action of
|
|
|
|
|
ACTION_LEFT =>
|
|
|
|
|
{ left = SOME key
|
|
|
|
|
, right = right
|
|
|
|
|
, up = up
|
|
|
|
|
, down = down
|
|
|
|
|
, jump = jump
|
|
|
|
|
, attack = attack
|
|
|
|
|
}
|
|
|
|
|
| ACTION_RIGHT =>
|
|
|
|
|
{ left = left
|
|
|
|
|
, right = SOME key
|
|
|
|
|
, up = up
|
|
|
|
|
, down = down
|
|
|
|
|
, jump = jump
|
|
|
|
|
, attack = attack
|
|
|
|
|
}
|
|
|
|
|
| ACTION_UP =>
|
|
|
|
|
{ left = left
|
|
|
|
|
, right = right
|
|
|
|
|
, up = SOME key
|
|
|
|
|
, down = down
|
|
|
|
|
, jump = jump
|
|
|
|
|
, attack = attack
|
|
|
|
|
}
|
|
|
|
|
| ACTION_DOWN =>
|
|
|
|
|
{ left = left
|
|
|
|
|
, right = right
|
|
|
|
|
, up = up
|
|
|
|
|
, down = SOME key
|
|
|
|
|
, jump = jump
|
|
|
|
|
, attack = attack
|
|
|
|
|
}
|
|
|
|
|
| ACTION_JUMP =>
|
|
|
|
|
{ left = left
|
|
|
|
|
, right = right
|
|
|
|
|
, up = up
|
|
|
|
|
, down = down
|
|
|
|
|
, jump = SOME key
|
|
|
|
|
, attack = attack
|
|
|
|
|
}
|
|
|
|
|
| ACTION_ATTACK =>
|
|
|
|
|
{ left = left
|
|
|
|
|
, right = right
|
|
|
|
|
, up = up
|
|
|
|
|
, down = down
|
|
|
|
|
, jump = jump
|
|
|
|
|
, attack = SOME key
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun returnControls controls =
|
|
|
|
|
let
|
|
|
|
|
val {left, right, up, down, jump, attack} = controls
|
|
|
|
|
in
|
|
|
|
|
case (left, right, up, down, jump, attack) of
|
|
|
|
|
(SOME left, SOME right, SOME up, SOME down, SOME jump, SOME attack) =>
|
|
|
|
|
SOME
|
|
|
|
|
{ left = left
|
|
|
|
|
, right = right
|
|
|
|
|
, up = up
|
|
|
|
|
, down = down
|
|
|
|
|
, jump = jump
|
|
|
|
|
, attack = attack
|
2025-02-20 13:32:37 +00:00
|
|
|
, escape = CoreKey.KEY_ESCAPE
|
2025-02-17 03:13:45 +00:00
|
|
|
}
|
|
|
|
|
| _ => NONE
|
|
|
|
|
end
|
|
|
|
|
|
2025-02-17 03:48:31 +00:00
|
|
|
(* We don't want to attempt to parse strings
|
|
|
|
|
* which have trailing spaces or newlines
|
|
|
|
|
* so get the length of the last non-space chr *)
|
|
|
|
|
fun getLastPos (pos, line) =
|
|
|
|
|
if pos = String.size line then
|
|
|
|
|
String.size line - 1
|
|
|
|
|
else
|
|
|
|
|
let val chr = String.sub (line, pos)
|
|
|
|
|
in if Char.isSpace chr then pos - 1 else getLastPos (pos + 1, line)
|
|
|
|
|
end
|
|
|
|
|
|
2025-02-17 03:13:45 +00:00
|
|
|
fun helpParse (controls, io) =
|
|
|
|
|
case TextIO.inputLine io of
|
|
|
|
|
SOME line =>
|
|
|
|
|
let
|
|
|
|
|
val colon = findColon (0, line)
|
|
|
|
|
in
|
|
|
|
|
if colon = ~1 then
|
|
|
|
|
helpParse (controls, io)
|
|
|
|
|
else
|
|
|
|
|
let
|
2025-02-17 03:48:31 +00:00
|
|
|
val actionString = String.substring (line, 0, colon)
|
2025-02-17 03:13:45 +00:00
|
|
|
val action = actionFromString actionString
|
|
|
|
|
|
2025-02-17 03:48:31 +00:00
|
|
|
val keyStart = colon + 1
|
|
|
|
|
val keyFinish = getLastPos (keyStart, line)
|
|
|
|
|
val keyLength = keyFinish - keyStart + 1
|
|
|
|
|
val keyString = String.substring (line, keyStart, keyLength)
|
2025-02-17 03:13:45 +00:00
|
|
|
val key = CoreKey.keyFromString keyString
|
|
|
|
|
|
|
|
|
|
val controls =
|
|
|
|
|
(case (action, key) of
|
|
|
|
|
(SOME action, SOME key) =>
|
|
|
|
|
updateControls (action, key, controls)
|
|
|
|
|
| (_, _) => controls)
|
|
|
|
|
in
|
|
|
|
|
helpParse (controls, io)
|
|
|
|
|
end
|
|
|
|
|
end
|
2025-02-17 03:48:31 +00:00
|
|
|
| NONE => let val () = TextIO.closeIn io in returnControls controls end
|
2025-02-17 03:13:45 +00:00
|
|
|
|
|
|
|
|
fun parse () =
|
|
|
|
|
let
|
|
|
|
|
val initial =
|
|
|
|
|
{ left = NONE
|
|
|
|
|
, right = NONE
|
|
|
|
|
, up = NONE
|
|
|
|
|
, down = NONE
|
|
|
|
|
, jump = NONE
|
|
|
|
|
, attack = NONE
|
|
|
|
|
}
|
|
|
|
|
val io = TextIO.openIn "controls.config"
|
|
|
|
|
in
|
|
|
|
|
helpParse (initial, io)
|
|
|
|
|
end
|
|
|
|
|
end
|