Files
octal_cookie/src/machine/input.odin
T

90 lines
2.6 KiB
Odin

package machine
import rl "vendor:raylib"
// @IDEA: Maybe add controller support?
// Input handling for CHIP-8 keypad (0x0-0xF) mapped to a standard keyboard.
// CHIP-8 uses a polling model, not hardware interrupts - we check key state each cycle.
// Standard CHIP-8 -> keyboard mapping:
// 1 2 3 C → 1 2 3 4
// 4 5 6 D → Q W E R
// 7 8 9 E → A S D F
// A 0 B F → Z X C V
handle_input :: proc(s: ^System) {
// Row 1
s.keypad[0x1] = rl.IsKeyDown(.ONE)
s.keypad[0x2] = rl.IsKeyDown(.TWO)
s.keypad[0x3] = rl.IsKeyDown(.THREE)
s.keypad[0xC] = rl.IsKeyDown(.FOUR)
// Row 2
s.keypad[0x4] = rl.IsKeyDown(.Q)
s.keypad[0x5] = rl.IsKeyDown(.W)
s.keypad[0x6] = rl.IsKeyDown(.E)
s.keypad[0xD] = rl.IsKeyDown(.R)
// Row 3
s.keypad[0x7] = rl.IsKeyDown(.A)
s.keypad[0x8] = rl.IsKeyDown(.S)
s.keypad[0x9] = rl.IsKeyDown(.D)
s.keypad[0xE] = rl.IsKeyDown(.F)
// Row 4
s.keypad[0xA] = rl.IsKeyDown(.Z)
s.keypad[0x0] = rl.IsKeyDown(.X)
s.keypad[0xB] = rl.IsKeyDown(.C)
s.keypad[0xF] = rl.IsKeyDown(.V)
// Track the last pressed key as a CHIP-8 index (0x0-0xF).
// Used by Fx0A which blocks until a key is pressed AND released.
// current_key holds the index until release is confirmed, then resets to -1.
key := rl.GetKeyPressed()
#partial switch key {
case .ONE: s.current_key = 0x1
case .TWO: s.current_key = 0x2
case .THREE: s.current_key = 0x3
case .FOUR: s.current_key = 0xC
case .Q: s.current_key = 0x4
case .W: s.current_key = 0x5
case .E: s.current_key = 0x6
case .R: s.current_key = 0xD
case .A: s.current_key = 0x7
case .S: s.current_key = 0x8
case .D: s.current_key = 0x9
case .F: s.current_key = 0xE
case .Z: s.current_key = 0xA
case .X: s.current_key = 0x0
case .C: s.current_key = 0xB
case .V: s.current_key = 0xF
}
}
// Returns true only when the tracked key is released.
// Used by Fx0A to check for a press-and-release.
check_if_key_released :: proc(key: i16) -> bool {
return rl.IsKeyReleased(chip8_key_to_raylib(key))
}
// Maps a CHIP-8 key index (0x0-0xF) back to its Raylib equivalent.
chip8_key_to_raylib :: proc(key: i16) -> rl.KeyboardKey {
switch key {
case 0x1: return .ONE
case 0x2: return .TWO
case 0x3: return .THREE
case 0xC: return .FOUR
case 0x4: return .Q
case 0x5: return .W
case 0x6: return .E
case 0xD: return .R
case 0x7: return .A
case 0x8: return .S
case 0x9: return .D
case 0xE: return .F
case 0xA: return .Z
case 0x0: return .X
case 0xB: return .C
case 0xF: return .V
case: return .KEY_NULL
}
}