aboutsummaryrefslogtreecommitdiff
path: root/arm9/source/devices/input.c
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-09-19 13:17:14 +1200
committerBen Bridle <ben@derelict.engineering>2025-09-19 13:32:32 +1200
commitbb1aa5958d1b67707dcf0f6b08bfaf0b408bd46e (patch)
treeb26d07ed58aaf7a5230fc3e28c103d616abfa9b8 /arm9/source/devices/input.c
parent9612c307f00c4313d73fe0c3a86c05c8d8cd514e (diff)
downloadbedrock-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.c93
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;
}
}
}