summaryrefslogtreecommitdiff
path: root/arm9/source/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/source/main.c')
-rw-r--r--arm9/source/main.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/arm9/source/main.c b/arm9/source/main.c
new file mode 100644
index 0000000..a8d3273
--- /dev/null
+++ b/arm9/source/main.c
@@ -0,0 +1,118 @@
+#include <stdio.h>
+#include <time.h>
+#include <nds.h>
+#include "devices/clock.h"
+#include "devices/math.h"
+#include "devices/screen.h"
+#include "bang.h"
+#include "core.h"
+#include "main_debug.h"
+
+Bedrock br[5] = {};
+Bedrock *br_main;
+Bedrock *br_sub;
+bool main_on_bottom = TRUE;
+
+u8 main_program[] = {
+ #include "../include/sysinfo.br.inc"
+};
+u8 keyboard_program[] = {
+ #include "../include/sysinfo.br.inc"
+};
+
+// Change to the next screen layout.
+void change_layout(void) {
+ lcdSwap();
+ main_on_bottom = !main_on_bottom;
+}
+
+// Scan for input and handle emulator-specific keys.
+void receive_input(void) {
+ scanKeys();
+ if (keysDown() & KEY_SELECT) change_layout();
+}
+
+
+void run_br(Bedrock *br) {
+ if (br->awake) {
+ switch (evaluate(br, 1000)) {
+ case SIG_HALT: br->alive = FALSE; black_screen(br->scr.nds); br = NULL; return;
+ case SIG_SLEEP: br->awake = FALSE; return;
+ case SIG_DB1: debug_stacks(br); return;
+ case SIG_DB4: debug_assert(br); return;
+ default: return;
+ }
+ }
+}
+
+Screen scr_main = {
+ .bgv = BG_TILE_RAM(BG_SLOT_VIS),
+ .fgv = BG_TILE_RAM(FG_SLOT_VIS),
+ .bg = BG_TILE_RAM(BG_SLOT),
+ .fg = BG_TILE_RAM(FG_SLOT),
+ .map = BG_MAP_RAM(MAP_SLOT),
+ .pal = BG_PALETTE,
+};
+Screen scr_sub = {
+ .bgv = BG_TILE_RAM_SUB(BG_SLOT_VIS),
+ .fgv = BG_TILE_RAM_SUB(FG_SLOT_VIS),
+ .bg = BG_TILE_RAM_SUB(BG_SLOT),
+ .fg = BG_TILE_RAM_SUB(FG_SLOT),
+ .map = BG_MAP_RAM_SUB(MAP_SLOT),
+ .pal = BG_PALETTE_SUB,
+};
+
+int main(void) {
+ #define ALIVE(br) (br && br->alive)
+ #define AWAKE(br) (br && br->alive && br->awake)
+ #define ASLEEP(br) (br && br->alive && !br->awake)
+
+ init_screens();
+ init_clock();
+ lcdMainOnBottom();
+
+ // TODO: Remove
+ // consoleDemoInit();
+
+ // Load program
+ start_br(&br[0], main_program, sizeof(main_program));
+ start_br(&br[1], keyboard_program, sizeof(keyboard_program));
+ br_main = &br[0];
+ br_sub = &br[1];
+ br_main->scr.nds = &scr_main;
+ br_sub->scr.nds = &scr_sub;
+
+ while (1) {
+ if (AWAKE(br_main)) run_br(br_main);
+ if (AWAKE(br_sub)) run_br(br_sub);
+
+ bool main_flip = ASLEEP(br_main) && br_main->scr.dirty;
+ bool sub_flip = ASLEEP(br_sub) && br_sub->scr.dirty;
+ if (main_flip || sub_flip) swiWaitForVBlank();
+ if (main_flip) { flip_buffer(br_main->scr.nds); br_main->scr.dirty = false; }
+ if (sub_flip) { flip_buffer(br_sub->scr.nds); br_sub->scr.dirty = false; }
+
+ rouse:
+ receive_input();
+ if (ALIVE(br_main)) {
+ inp_read_navigation(&br_main->inp);
+ inp_read_gamepad(&br_main->inp);
+ if (main_on_bottom) inp_read_touch(&br_main->inp);
+ }
+ if (ALIVE(br_sub)) {
+ inp_read_navigation(&br_sub->inp);
+ inp_read_gamepad(&br_sub->inp);
+ if (!main_on_bottom) inp_read_touch(&br_sub->inp);
+ }
+ if (ASLEEP(br_main)) rouse_br(br_main);
+ if (ASLEEP(br_sub)) rouse_br(br_sub);
+ if (ASLEEP(br_main) && ASLEEP(br_sub)) {
+ // Sleep until next keypad event or clock tick.
+ swiIntrWait(1, IRQ_KEYS | IRQ_TIMER0);
+ goto rouse;
+ }
+
+ if (!br_main && !br_sub) return 0;
+ }
+}
+