diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-09-19 13:17:14 +1200 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-09-19 13:32:32 +1200 |
commit | bb1aa5958d1b67707dcf0f6b08bfaf0b408bd46e (patch) | |
tree | b26d07ed58aaf7a5230fc3e28c103d616abfa9b8 /arm9/source/devices/input.c | |
parent | 9612c307f00c4313d73fe0c3a86c05c8d8cd514e (diff) | |
download | bedrock-nds-bb1aa5958d1b67707dcf0f6b08bfaf0b408bd46e.zip |
Massive rewrite
This commit rewrites the emulator halfway from scratch to make it
easier to change and maintain in the future. The emulator core was
rewritten to adhere to the released Bedrock specification (earlier
versions implemented an older prototype specification, which is no
longer relevant).
This commit also adds proper support for running multiple concurrent
Bedrock instances. This was previously supported in a limited manner
for the on-screen keyboard, but now works for any regular program as
well, with switching being performed by pressing the L or R bumper
buttons. This is disabled by default, as programs will still need to
be baked into the emulator and hand-loaded.
Diffstat (limited to 'arm9/source/devices/input.c')
-rw-r--r-- | arm9/source/devices/input.c | 93 |
1 files changed, 54 insertions, 39 deletions
diff --git a/arm9/source/devices/input.c b/arm9/source/devices/input.c index e5ac5be..401f053 100644 --- a/arm9/source/devices/input.c +++ b/arm9/source/devices/input.c @@ -1,14 +1,40 @@ -#include <nds.h> -#include "../bang.h" #include "input.h" +#include "../config.h" -void inp_receive_byte(InputDevice *inp, u8 byte) { - cb_write_byte(&inp->keybuffer, byte); - inp->wake = true; + +// Reset an input device. +void input_reset(InputDevice *input) { + input->pointer = false; + input->keyboard = false; + input->x = 0; + input->y = 0; + input->x_read = 0; + input->y_read = 0; + circbuf_clear(&input->keybuffer); + input->gamepad = 0; + input->wake = false; +} + +// Update the cached read value for the pointer x coordinate. +void input_read_x(InputDevice *input) { + input->x_read = input->x; +} + +// Update the cached read value for the pointer y coordinate. +void input_read_y(InputDevice *input) { + input->y_read = input->y; } -// Read gamepad state into an input device. -void inp_read_gamepad(InputDevice *inp) { +// Receive a byte from a keyboard. +// TODO: Make this function Unicode-aware by receiving a u32 instead of +// a u8, so that the keybuffer can be checked for capacity before pushing. +void input_receive_key(InputDevice *input, u8 byte) { + circbuf_write(&input->keybuffer, byte); + input->wake = true; +} + +// Read the current gamepad state. +void input_update_gamepad(InputDevice *input) { u32 held = keysHeld(); u8 gamepad = ( TEST(held, KEY_UP) << 7 @@ -20,45 +46,34 @@ void inp_read_gamepad(InputDevice *inp) { | TEST(held, KEY_X) << 1 | TEST(held, KEY_Y) << 0 ); - if (gamepad != inp->gamepad) { - inp->wake = TRUE; - inp->gamepad = gamepad; + // If the L and R bumper keys aren't being used to switch between + // instances, map them to be alternate X and Y keys. + if (!SWITCH_BETWEEN_INSTANCES) { + gamepad |= TEST(held, KEY_L) << 1; + gamepad |= TEST(held, KEY_R) << 0; } -} - -// Read navigation state into an input device. -void inp_read_navigation(InputDevice *inp) { - u32 held = keysHeld(); - u8 navigation = ( - TEST(held, KEY_UP) << 7 - | TEST(held, KEY_DOWN) << 6 - | TEST(held, KEY_LEFT) << 5 - | TEST(held, KEY_RIGHT) << 4 - | TEST(held, KEY_A) << 3 - | TEST(held, KEY_B) << 2 - | TEST(held, KEY_R) << 1 - | TEST(held, KEY_L) << 0 - ); - if (navigation != inp->navigation) { - inp->wake = TRUE; - inp->navigation = navigation; + if (gamepad != input->gamepad) { + input->wake = true; + input->gamepad = gamepad; } } -// Read touchscreen state into an input device. -void inp_read_touch(InputDevice *inp) { +// Read the current touchscreen state. +void input_update_touch(InputDevice *input) { + // Test if pointer is active. bool pointer = TEST(keysHeld(), KEY_TOUCH); - if (pointer != inp->pointer) { - inp->wake = TRUE; - inp->pointer = pointer; + if (pointer != input->pointer) { + input->wake = true; + input->pointer = pointer; } + // Update pointer position. if (pointer) { - touchPosition pos; - touchRead(&pos); - if (pos.px != inp->x || pos.py != inp->y) { - inp->wake = TRUE; - inp->x = pos.px; - inp->y = pos.py; + touchPosition position; + touchRead(&position); + if (position.px != input->x || position.py != input->y) { + input->wake = true; + input->x = position.px; + input->y = position.py; } } } |