diff options
author | Ben Bridle <ben@derelict.engineering> | 2024-12-16 14:52:54 +1300 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2024-12-16 14:52:54 +1300 |
commit | 0d9978228b9226d16ba8272a03dd7e6c9ad83b3d (patch) | |
tree | 442ce8a1d37f2f9a0e9e655d3250849e874c2d41 | |
parent | dbe8171815ea3b51c3ac87dae1996ae0d8f6eb04 (diff) | |
download | bedrock-nds-0d9978228b9226d16ba8272a03dd7e6c9ad83b3d.zip |
Implement a toggleable keyboard on the lower screen
-rw-r--r-- | arm9/source/core.c | 19 | ||||
-rw-r--r-- | arm9/source/core.h | 4 | ||||
-rw-r--r-- | arm9/source/devices/input.c | 5 | ||||
-rw-r--r-- | arm9/source/devices/input.h | 17 | ||||
-rw-r--r-- | arm9/source/devices/local.c | 11 | ||||
-rw-r--r-- | arm9/source/devices/local.h | 4 | ||||
-rw-r--r-- | arm9/source/devices/screen.c | 16 | ||||
-rw-r--r-- | arm9/source/devices/screen.h | 1 | ||||
-rw-r--r-- | arm9/source/main.c | 40 | ||||
-rw-r--r-- | arm9/source/main.h | 12 | ||||
-rw-r--r-- | arm9/source/types/circbuf.c | 20 | ||||
-rw-r--r-- | arm9/source/types/circbuf.h | 16 |
12 files changed, 149 insertions, 16 deletions
diff --git a/arm9/source/core.c b/arm9/source/core.c index 7584296..8abcfcb 100644 --- a/arm9/source/core.c +++ b/arm9/source/core.c @@ -35,6 +35,14 @@ void rouse_br(Bedrock *br) { br->sys.wake = 0x0; return; } + if (TEST(br->sys.sleep, 0x0400)) { // SCREEN + if (br->scr.wake) { + br->scr.wake = FALSE; + br->awake = TRUE; + br->sys.wake = 0x5; + return; + } + } if (TEST(br->sys.sleep, 0x0800)) { // INPUT if (br->inp.wake) { br->inp.wake = FALSE; @@ -121,8 +129,8 @@ u8 dev_read(Bedrock *br, u8 port) { case 0x45: return LOW(br->inp.x); case 0x46: return HIGH(br->inp.y); case 0x47: return LOW(br->inp.y); - case 0x48: return BOOL(br->inp.keyboard); - // TODO: Keyboard input + case 0x48: return BOOL(is_keyboard_open()); + case 0x49: return cb_read_byte(&br->inp.keybuffer); case 0x4A: return br->inp.navigation; case 0x4C: return br->inp.gamepad; // SCREEN DEVICE @@ -195,6 +203,9 @@ Signal dev_write(Bedrock *br, u8 port, u8 v) { case 0x3D: set_timer_low( &br->clk.t3,v); return 0; case 0x3E: set_timer_high(&br->clk.t4,v); return 0; case 0x3F: set_timer_low( &br->clk.t4,v); return 0; +// INPUT DEVICE + case 0x48: v ? open_keyboard() : close_keyboard(); return 0; + case 0x49: cb_clear(&br->inp.keybuffer); return 0; // SCREEN DEVICE case 0x54: SET_HIGH(br->scr.x,v); return 0; case 0x55: SET_LOW( br->scr.x,v); return 0; @@ -209,8 +220,8 @@ Signal dev_write(Bedrock *br, u8 port, u8 v) { case 0x5E: draw_dispatch(&br->scr,v); return 0; case 0x5F: move_cursor(&br->scr,v); return 0; // LOCAL DEVICE - case 0x86: printf("%c", v); return 0; - case 0x87: printf("%c", v); return 0; + case 0x86: std_write(v); return 0; + case 0x87: std_write(v); return 0; // FILE DEVICE case 0xA0: fs_push_entry(&br->fs,v); return 0; case 0xA1: fs_push_action(&br->fs,v); return 0; diff --git a/arm9/source/core.h b/arm9/source/core.h index ec3f2fc..765be3b 100644 --- a/arm9/source/core.h +++ b/arm9/source/core.h @@ -1,3 +1,6 @@ +#include <nds.h> +#include "main.h" + #ifndef CORE_H_ #define CORE_H_ @@ -7,6 +10,7 @@ #include "devices/clock.h" #include "devices/input.h" #include "devices/screen.h" + #include "devices/local.h" #include "devices/file.h" #define WST br->wst diff --git a/arm9/source/devices/input.c b/arm9/source/devices/input.c index a39f448..e5ac5be 100644 --- a/arm9/source/devices/input.c +++ b/arm9/source/devices/input.c @@ -2,6 +2,11 @@ #include "../bang.h" #include "input.h" +void inp_receive_byte(InputDevice *inp, u8 byte) { + cb_write_byte(&inp->keybuffer, byte); + inp->wake = true; +} + // Read gamepad state into an input device. void inp_read_gamepad(InputDevice *inp) { u32 held = keysHeld(); diff --git a/arm9/source/devices/input.h b/arm9/source/devices/input.h index e62bdd3..4f91ed5 100644 --- a/arm9/source/devices/input.h +++ b/arm9/source/devices/input.h @@ -1,15 +1,20 @@ +#include <nds.h> +#include "../types/circbuf.h" + #ifndef INPUT_H_ #define INPUT_H_ typedef struct { - bool pointer; // pointer active - bool keyboard; // keyboard active - u16 x,y; // pointer position - u8 navigation; // navigation state - u8 gamepad; // gamepad state - bool wake; // wake flag + bool pointer; // pointer active + bool keyboard; // keyboard active + CircBuf keybuffer; // queued keypresses + u16 x,y; // pointer position + u8 navigation; // navigation state + u8 gamepad; // gamepad state + bool wake; // wake flag } InputDevice; + void inp_receive_byte(InputDevice *inp, u8 byte); void inp_read_gamepad(InputDevice *inp); void inp_read_navigation(InputDevice *inp); void inp_read_touch(InputDevice *inp); diff --git a/arm9/source/devices/local.c b/arm9/source/devices/local.c index e69de29..e13a1f8 100644 --- a/arm9/source/devices/local.c +++ b/arm9/source/devices/local.c @@ -0,0 +1,11 @@ +#include "../main.h" +#include "local.h" + +void std_write(u8 byte) { + if (byte) { + receive_keyboard_byte(byte); + } else { + close_keyboard(); + + } +} diff --git a/arm9/source/devices/local.h b/arm9/source/devices/local.h index bf1393c..979f5ce 100644 --- a/arm9/source/devices/local.h +++ b/arm9/source/devices/local.h @@ -1,4 +1,8 @@ +#include <nds.h> + #ifndef LOCAL_H_ #define LOCAL_H_ + void std_write(u8 byte); + #endif diff --git a/arm9/source/devices/screen.c b/arm9/source/devices/screen.c index e394b55..698b754 100644 --- a/arm9/source/devices/screen.c +++ b/arm9/source/devices/screen.c @@ -36,12 +36,28 @@ Screen scr_sub = { .palv = BG_PALETTE_SUB, }; +// TODO: Make an enum thing for main/sub, combine these functions void scr_make_main(ScreenDevice *scr) { scr->nds = &scr_main; + for (int i=0; i<16; i++) { + scr->nds->pal[i] = scr->palette[i]; + } + scr->wake = true; } void scr_make_sub(ScreenDevice *scr) { scr->nds = &scr_sub; + for (int i=0; i<16; i++) { + scr->nds->pal[i] = scr->palette[i]; + } + scr->wake = true; +} + +void scr_unmake(ScreenDevice *scr) { + if (scr->nds) { + black_screen(scr->nds); + scr->nds = NULL; + } } void init_screens(void) { diff --git a/arm9/source/devices/screen.h b/arm9/source/devices/screen.h index 3e75334..1ff58e5 100644 --- a/arm9/source/devices/screen.h +++ b/arm9/source/devices/screen.h @@ -46,6 +46,7 @@ void init_screens(void); void scr_make_main(ScreenDevice *scr); void scr_make_sub(ScreenDevice *scr); + void scr_unmake(ScreenDevice *scr); void set_palette_high(ScreenDevice *scr, u8 high); void set_palette_low(ScreenDevice *scr, u8 low); diff --git a/arm9/source/main.c b/arm9/source/main.c index 095e089..239c1de 100644 --- a/arm9/source/main.c +++ b/arm9/source/main.c @@ -6,6 +6,7 @@ #include "devices/screen.h" #include "bang.h" #include "core.h" +#include "main.h" #define NUM_BR 5 @@ -21,13 +22,41 @@ u8 main_program[] = { #include "../include/cobalt.br.inc" }; u8 keyboard_program[] = { - 00 //#include "../include/sysinfo.br.inc" + #include "../include/keyboard.br.inc" }; + // Change to the next screen layout. void change_layout(void) { lcdSwap(); main_on_bottom = !main_on_bottom; + if (main_on_bottom) { + scr_unmake(&br_sub->scr); + } else { + scr_make_sub(&br_sub->scr); + } +} + +void receive_keyboard_byte(u8 byte) { + if (br_main) { + inp_receive_byte(&br_main->inp, byte); + } +} + +bool is_keyboard_open(void) { + return !main_on_bottom; +} + +void open_keyboard(void) { + if (main_on_bottom) { + change_layout(); + } +} + +void close_keyboard(void) { + if (!main_on_bottom) { + change_layout(); + } } // Scan for input and handle emulator-specific keys. @@ -63,7 +92,6 @@ int main(void) { br_main = &br[0]; br_sub = &br[1]; scr_make_main(&br_main->scr); - scr_make_sub(&br_sub->scr); while (1) { if (AWAKE(br_main)) run_br(br_main); @@ -77,15 +105,15 @@ int main(void) { rouse: receive_input(); - if (ALIVE(br_main)) { + if (ALIVE(br_main) && main_on_bottom) { inp_read_navigation(&br_main->inp); inp_read_gamepad(&br_main->inp); - if (main_on_bottom) inp_read_touch(&br_main->inp); + inp_read_touch(&br_main->inp); } - if (ALIVE(br_sub)) { + if (ALIVE(br_sub) && !main_on_bottom) { inp_read_navigation(&br_sub->inp); inp_read_gamepad(&br_sub->inp); - if (!main_on_bottom) inp_read_touch(&br_sub->inp); + inp_read_touch(&br_sub->inp); } if (ASLEEP(br_main)) rouse_br(br_main); if (ASLEEP(br_sub)) rouse_br(br_sub); diff --git a/arm9/source/main.h b/arm9/source/main.h new file mode 100644 index 0000000..14aa0dd --- /dev/null +++ b/arm9/source/main.h @@ -0,0 +1,12 @@ +#include <nds.h> + +#ifndef MAIN_H_ + #define MAIN_H_ + + void receive_keyboard_byte(u8 byte); + bool is_keyboard_open(void); + void open_keyboard(void); + void close_keyboard(void); + void change_layout(void); + +#endif diff --git a/arm9/source/types/circbuf.c b/arm9/source/types/circbuf.c new file mode 100644 index 0000000..532a5a0 --- /dev/null +++ b/arm9/source/types/circbuf.c @@ -0,0 +1,20 @@ +#include "circbuf.h" + +u8 cb_read_byte(CircBuf *buf) { + if (buf->front != buf->back) { + return buf->mem[buf->front++]; + } else { + return 0; + } +} + +void cb_write_byte(CircBuf *buf, u8 byte) { + if (((buf->back+1)&0xff) != buf->front) { + buf->mem[buf->back++] = byte; + } +} + +void cb_clear(CircBuf *buf) { + buf->front = 0; + buf->back = 0; +} diff --git a/arm9/source/types/circbuf.h b/arm9/source/types/circbuf.h new file mode 100644 index 0000000..305f8bf --- /dev/null +++ b/arm9/source/types/circbuf.h @@ -0,0 +1,16 @@ +#include <nds.h> + +#ifndef CIRCBUF_H_ + #define CIRCBUF_H_ + + typedef struct { + u8 mem[256]; + u8 front; // start of buffer, read from here until back + u8 back; // end of buffer, write past here until front + } CircBuf; + + u8 cb_read_byte(CircBuf *buf); + void cb_write_byte(CircBuf *buf, u8 byte); + void cb_clear(CircBuf *buf); + +#endif |