From f2506eef06e8524546e17363bcb0289dc1ceb88a Mon Sep 17 00:00:00 2001 From: Rodrigo Alfonso Date: Sat, 4 Jan 2025 03:12:46 -0300 Subject: [PATCH] Refactor: Extracting repeated functions in examples to a common file --- examples/LinkCableMultiboot_demo/src/main.cpp | 62 ++------ examples/LinkCable_basic/src/main.cpp | 16 +- examples/LinkCable_full/Makefile | 5 +- examples/LinkCable_full/src/main.cpp | 23 +-- examples/LinkCable_full/src/main.h | 3 +- .../LinkCable_full/src/scenes/TestScene.cpp | 10 +- .../LinkCable_full/src/utils/InputHandler.h | 39 ----- examples/LinkCable_stress/src/main.cpp | 118 ++++----------- examples/LinkCable_stress/src/main.h | 2 +- examples/LinkCube_demo/src/main.cpp | 34 +---- examples/LinkGPIO_demo/src/main.cpp | 15 +- examples/LinkMobile_demo/src/main.cpp | 56 +++---- examples/LinkMobile_demo/src/main.h | 3 +- examples/LinkPS2Keyboard_demo/src/main.cpp | 21 +-- examples/LinkPS2Mouse_demo/src/main.cpp | 28 +--- examples/LinkRawCable_demo/src/main.cpp | 43 +++--- examples/LinkRawWireless_demo/Makefile | 5 +- examples/LinkRawWireless_demo/src/main.cpp | 14 +- .../src/scenes/DebugScene.cpp | 6 +- .../src/utils/InputHandler.h | 39 ----- .../src/utils/SceneUtils.h | 40 ----- examples/LinkSPI_demo/src/main.cpp | 21 +-- examples/LinkUART_demo/src/main.cpp | 17 +-- examples/LinkUniversal_basic/src/main.cpp | 40 +---- examples/LinkWirelessMultiboot_demo/Makefile | 5 +- .../LinkWirelessMultiboot_demo/src/main.cpp | 15 +- .../src/scenes/MultibootScene.cpp | 8 +- .../src/scenes/MultibootScene.h | 1 - .../src/utils/InputHandler.h | 39 ----- .../src/utils/SceneUtils.h | 40 ----- examples/LinkWireless_demo/src/main.cpp | 137 +++++++----------- examples/_lib/common.cpp | 0 examples/_lib/common.h | 88 +++++++++++ .../libgba-sprite-engine/scene.cpp} | 2 +- .../libgba-sprite-engine/scene.h} | 43 ++++-- 35 files changed, 331 insertions(+), 707 deletions(-) delete mode 100644 examples/LinkCable_full/src/utils/InputHandler.h delete mode 100644 examples/LinkRawWireless_demo/src/utils/InputHandler.h delete mode 100644 examples/LinkRawWireless_demo/src/utils/SceneUtils.h delete mode 100644 examples/LinkWirelessMultiboot_demo/src/utils/InputHandler.h delete mode 100644 examples/LinkWirelessMultiboot_demo/src/utils/SceneUtils.h create mode 100644 examples/_lib/common.cpp create mode 100644 examples/_lib/common.h rename examples/{LinkCable_full/src/utils/SceneUtils.cpp => _lib/libgba-sprite-engine/scene.cpp} (93%) rename examples/{LinkCable_full/src/utils/SceneUtils.h => _lib/libgba-sprite-engine/scene.h} (50%) diff --git a/examples/LinkCableMultiboot_demo/src/main.cpp b/examples/LinkCableMultiboot_demo/src/main.cpp index c4ab3a3..e39c41c 100644 --- a/examples/LinkCableMultiboot_demo/src/main.cpp +++ b/examples/LinkCableMultiboot_demo/src/main.cpp @@ -1,9 +1,8 @@ // (0) Include the header #include "../../../lib/LinkCableMultiboot.hpp" -#include #include -#include +#include "../../_lib/common.h" extern "C" { #include "../../_lib/libgbfs/gbfs.h" @@ -13,10 +12,6 @@ static const GBFS_FILE* fs = find_first_gbfs_file(0); static u32 selectedFile = 0; static bool spi = false; -void log(std::string text); -void waitFor(u16 key); -bool didPress(u16 key, bool& pressed); - // (1) Create a LinkCableMultiboot instance LinkCableMultiboot* linkCableMultiboot = new LinkCableMultiboot(); @@ -33,8 +28,7 @@ void selectRight() { } void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); irq_init(NULL); irq_add(II_VBLANK, NULL); @@ -45,11 +39,11 @@ int main() { // Ensure there are GBFS files if (fs == NULL) { - log("! GBFS file not found"); + Common::log("! GBFS file not found"); while (true) ; } else if (gbfs_get_nth_obj(fs, 0, NULL, NULL) == NULL) { - log("! No files found (GBFS)"); + Common::log("! No files found (GBFS)"); while (true) ; } @@ -70,17 +64,18 @@ int main() { } // Toggle mode - if (didPress(KEY_L, l)) + if (Common::didPress(KEY_L, l)) spi = !spi; // Select ROM - if (didPress(KEY_LEFT, left)) + if (Common::didPress(KEY_LEFT, left)) selectLeft(); - if (didPress(KEY_RIGHT, right)) + if (Common::didPress(KEY_RIGHT, right)) selectRight(); // Menu - log("LinkCableMultiboot_demo\n (v7.1.0)\n\n" + Common::log( + "LinkCableMultiboot_demo\n (v7.1.0)\n\n" "Press A to send the ROM...\n" "Press B to launch the ROM...\nLEFT/RIGHT: select ROM\nL: toggle " "mode\n\nSelected ROM:\n " + @@ -88,8 +83,8 @@ int main() { std::string(spi ? "SPI (GBC cable)" : "MULTI_PLAY (GBA cable)")); // Send ROM - if (didPress(KEY_A, a)) { - log("Sending... (SELECT to cancel)"); + if (Common::didPress(KEY_A, a)) { + Common::log("Sending... (SELECT to cancel)"); // (2) Send the ROM auto result = linkCableMultiboot->sendRom( @@ -102,14 +97,14 @@ int main() { : LinkCableMultiboot::TransferMode::MULTI_PLAY); // Print results and wait - log("Result: " + std::to_string(result) + "\n" + - "Press DOWN to continue..."); - waitFor(KEY_DOWN); + Common::log("Result: " + std::to_string(result) + "\n" + + "Press DOWN to continue..."); + Common::waitForKey(KEY_DOWN); } // Launch ROM - if (didPress(KEY_B, b)) { - log("Launching..."); + if (Common::didPress(KEY_B, b)) { + Common::log("Launching..."); VBlankIntrWait(); REG_IME = 0; @@ -137,28 +132,3 @@ int main() { return 0; } - -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} - -void waitFor(u16 key) { - u16 keys; - do { - keys = ~REG_KEYS & KEY_ANY; - } while (!(keys & key)); -} - -bool didPress(u16 key, bool& pressed) { - u16 keys = ~REG_KEYS & KEY_ANY; - bool isPressedNow = false; - if ((keys & key) && !pressed) { - pressed = true; - isPressedNow = true; - } - if (pressed && !(keys & key)) - pressed = false; - return isPressedNow; -} diff --git a/examples/LinkCable_basic/src/main.cpp b/examples/LinkCable_basic/src/main.cpp index 356be92..4f5b465 100644 --- a/examples/LinkCable_basic/src/main.cpp +++ b/examples/LinkCable_basic/src/main.cpp @@ -4,18 +4,14 @@ // (0) Include the header #include "../../../lib/LinkCable.hpp" -#include -#include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" -void log(std::string text); - // (1) Create a LinkCable instance LinkCable* linkCable = new LinkCable(); void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); // (2) Add the required interrupt service routines interrupt_init(); @@ -67,14 +63,8 @@ int main() { } VBlankIntrWait(); - log(output); + Common::log(output); } return 0; } - -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} diff --git a/examples/LinkCable_full/Makefile b/examples/LinkCable_full/Makefile index fc3c706..0edd7d9 100644 --- a/examples/LinkCable_full/Makefile +++ b/examples/LinkCable_full/Makefile @@ -123,9 +123,8 @@ TITLE := $(PROJ) LIBS := -ltonc -lugba -lgba-sprite-engine BUILD := build -SRCDIRS := src ../_lib ../../lib \ - src/scenes \ - src/utils +SRCDIRS := src ../_lib ../_lib/libgba-sprite-engine ../../lib \ + src/scenes DATADIRS := INCDIRS := src LIBDIRS := $(TONCLIB) $(PWD)/../_lib/libugba $(PWD)/../_lib/libgba-sprite-engine diff --git a/examples/LinkCable_full/src/main.cpp b/examples/LinkCable_full/src/main.cpp index d7ee865..0507411 100644 --- a/examples/LinkCable_full/src/main.cpp +++ b/examples/LinkCable_full/src/main.cpp @@ -4,8 +4,8 @@ #include "main.h" #include #include "../../_lib/interrupt.h" +#include "../../_lib/libgba-sprite-engine/scene.h" #include "scenes/TestScene.h" -#include "utils/SceneUtils.h" void setUpInterrupts(); void printTutorial(); @@ -46,11 +46,11 @@ int main() { // log player ID/count and important flags TextStream::instance().setText( - "P" + asStr(linkConnection->currentPlayerId()) + "/" + - asStr(linkConnection->playerCount()) + "-R" + - asStr(isBitHigh(REG_SIOCNT, BIT_READY)) + "-S" + - asStr(isBitHigh(REG_SIOCNT, BIT_ERROR)) + "-E" + - asStr(isBitHigh(REG_SIOCNT, BIT_START)), + "P" + std::to_string(linkConnection->currentPlayerId()) + "/" + + std::to_string(linkConnection->playerCount()) + "-R" + + std::to_string(Common::isBitHigh(REG_SIOCNT, BIT_READY)) + "-S" + + std::to_string(Common::isBitHigh(REG_SIOCNT, BIT_ERROR)) + "-E" + + std::to_string(Common::isBitHigh(REG_SIOCNT, BIT_START)), 0, 14); engine->update(); @@ -61,15 +61,6 @@ int main() { return 0; } -inline void ISR_reset() { - REG_IME = 0; - RegisterRamReset(RESET_REG | RESET_VRAM); -#if MULTIBOOT_BUILD == 1 - *(vu8*)0x03007FFA = 0x01; -#endif - SoftReset(); -} - inline void setUpInterrupts() { interrupt_init(); @@ -93,7 +84,7 @@ inline void setUpInterrupts() { // A+B+START+SELECT = SoftReset REG_KEYCNT = 0b1100000000001111; - interrupt_set_handler(INTR_KEYPAD, ISR_reset); + interrupt_set_handler(INTR_KEYPAD, Common::ISR_reset); interrupt_enable(INTR_KEYPAD); } diff --git a/examples/LinkCable_full/src/main.h b/examples/LinkCable_full/src/main.h index f194cae..d1a7b54 100644 --- a/examples/LinkCable_full/src/main.h +++ b/examples/LinkCable_full/src/main.h @@ -9,7 +9,8 @@ #include "../../../lib/LinkUniversal.hpp" #endif -#include +#include "../../_lib/common.h" +#include "../../_lib/libgba-sprite-engine/scene.h" #ifndef USE_LINK_UNIVERSAL extern LinkCable* linkConnection; diff --git a/examples/LinkCable_full/src/scenes/TestScene.cpp b/examples/LinkCable_full/src/scenes/TestScene.cpp index 7c8cba9..4177097 100644 --- a/examples/LinkCable_full/src/scenes/TestScene.cpp +++ b/examples/LinkCable_full/src/scenes/TestScene.cpp @@ -3,8 +3,6 @@ #include #include "../main.h" -#include "utils/InputHandler.h" -#include "utils/SceneUtils.h" TestScene::TestScene(std::shared_ptr engine) : Scene(engine) {} @@ -20,7 +18,7 @@ static std::unique_ptr selectHandler = std::unique_ptr(new InputHandler()); inline void send(u16 data) { - DEBULOG("-> " + asStr(data)); + DEBULOG("-> " + std::to_string(data)); linkConnection->send(data); } @@ -58,7 +56,7 @@ void TestScene::tick(u16 keys) { if (!isConnected && linkConnection->isConnected()) { isConnected = true; initialized = false; - DEBULOG("! connected (" + asStr(linkConnection->playerCount()) + + DEBULOG("! connected (" + std::to_string(linkConnection->playerCount()) + " players)"); } if (isConnected && !linkConnection->isConnected()) { @@ -98,8 +96,8 @@ void TestScene::tick(u16 keys) { while (linkConnection->canRead(i)) { u16 message = linkConnection->read(i); if (i != linkConnection->currentPlayerId()) - DEBULOG("<-p" + asStr(i) + ": " + asStr(message) + " (frame " + - asStr(frameCounter) + ")"); + DEBULOG("<-p" + std::to_string(i) + ": " + std::to_string(message) + + " (frame " + std::to_string(frameCounter) + ")"); } } } diff --git a/examples/LinkCable_full/src/utils/InputHandler.h b/examples/LinkCable_full/src/utils/InputHandler.h deleted file mode 100644 index ebe25fe..0000000 --- a/examples/LinkCable_full/src/utils/InputHandler.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef INPUT_HANDLER_H -#define INPUT_HANDLER_H - -#include - -class InputHandler { - public: - InputHandler() { - this->isPressed = false; - this->isWaiting = true; - } - - inline bool getIsPressed() { return isPressed; } - - inline bool hasBeenPressedNow() { return isNewPressEvent; } - inline bool hasBeenReleasedNow() { return isNewReleaseEvent; } - - inline bool getHandledFlag() { return handledFlag; } - inline void setHandledFlag(bool value) { handledFlag = value; } - - inline void setIsPressed(bool isPressed) { - bool isNewPressEvent = !this->isWaiting && !this->isPressed && isPressed; - bool isNewReleaseEvent = !this->isWaiting && this->isPressed && !isPressed; - this->isPressed = isPressed; - this->isWaiting = this->isWaiting && isPressed; - - this->isNewPressEvent = isNewPressEvent; - this->isNewReleaseEvent = isNewReleaseEvent; - } - - protected: - bool isPressed = false; - bool isNewPressEvent = false; - bool isNewReleaseEvent = false; - bool handledFlag = false; - bool isWaiting = false; -}; - -#endif // INPUT_HANDLER_H diff --git a/examples/LinkCable_stress/src/main.cpp b/examples/LinkCable_stress/src/main.cpp index 46b16d0..d80ea42 100644 --- a/examples/LinkCable_stress/src/main.cpp +++ b/examples/LinkCable_stress/src/main.cpp @@ -17,7 +17,6 @@ // - The interval can be changed mid-test with the LEFT/RIGHT keys. #include "main.h" -#include #include "../../_lib/interrupt.h" #define FINAL_VALUE 65534 @@ -25,13 +24,7 @@ void test(bool withSync); void measureLatency(bool withPong); void forceSync(); -void log(std::string text); -void waitFor(u16 key); -bool didPress(u16 key, bool& pressed); bool needsReset(); -void profileStart(); -u32 profileStop(); -u32 toMs(u32 cycles); #ifndef USE_LINK_UNIVERSAL LinkCable* linkCable = new LinkCable(); @@ -75,8 +68,8 @@ void setInterval(u16 interval) { } void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); + Common::initTTE(); interrupt_init(); @@ -115,9 +108,9 @@ int main() { "A: Test packet loss\nB: Test packet sync\nL: Measure ping latency\nR: " "Measure ping-pong latency\n\nHold DOWN: Initial t=100\nHold UP: " "Initial t=25\n\nLEFT/RIGHT: Change t\nSTART: Add lag\nSELECT: Reset "; - log(output); + Common::log(output); - waitFor(KEY_A | KEY_B | KEY_L | KEY_R); + Common::waitForKey(KEY_A | KEY_B | KEY_L | KEY_R); u16 initialKeys = ~REG_KEYS & KEY_ANY; u32 interval = 50; @@ -150,7 +143,7 @@ void test(bool withSync) { bool increasingInterval = false; bool decreasingInterval = false; - log("Waiting for data..."); + Common::log("Waiting for data..."); while (true) { if (needsReset()) @@ -158,14 +151,15 @@ void test(bool withSync) { u16 keys = ~REG_KEYS & KEY_ANY; if (keys & KEY_START) { - log("Lagging..."); + Common::log("Lagging..."); Link::wait(1500); } - if (didPress(KEY_RIGHT, increasingInterval) && getInterval() < 200) { + if (Common::didPress(KEY_RIGHT, increasingInterval) && + getInterval() < 200) { setInterval(getInterval() + 5); linkConnection->resetTimer(); } - if (didPress(KEY_LEFT, decreasingInterval) && getInterval() > 5) { + if (Common::didPress(KEY_LEFT, decreasingInterval) && getInterval() > 5) { setInterval(getInterval() - 5); linkConnection->resetTimer(); } @@ -229,14 +223,14 @@ void test(bool withSync) { } VBlankIntrWait(); - log(output); + Common::log(output); if (error) { while (true) if (needsReset()) return; } else if (localCounter == FINAL_VALUE && expectedCounter == FINAL_VALUE) { - log("Test passed!"); + Common::log("Test passed!"); while (true) if (needsReset()) return; @@ -245,7 +239,7 @@ void test(bool withSync) { } void measureLatency(bool withPong) { - log("Waiting for data..."); + Common::log("Waiting for data..."); bool didInitialize = false; u32 counter = 0; @@ -260,15 +254,16 @@ void measureLatency(bool withPong) { u16 keys = ~REG_KEYS & KEY_ANY; if (keys & KEY_START) { - log("Lagging..."); + Common::log("Lagging..."); Link::wait(1500); } - if (didPress(KEY_RIGHT, increasingInterval) && getInterval() < 200) { + if (Common::didPress(KEY_RIGHT, increasingInterval) && + getInterval() < 200) { setInterval(getInterval() + 5); linkConnection->resetTimer(); counter = samples = totalMs = 0; } - if (didPress(KEY_LEFT, decreasingInterval) && getInterval() > 5) { + if (Common::didPress(KEY_LEFT, decreasingInterval) && getInterval() > 5) { setInterval(getInterval() - 5); linkConnection->resetTimer(); counter = samples = totalMs = 0; @@ -290,36 +285,36 @@ void measureLatency(bool withPong) { u32 sentPacket = ++counter; - profileStart(); + Common::profileStart(); linkConnection->send(sentPacket); if (!linkConnection->waitFor(remotePlayerId, needsReset)) { - log("No response! (1) Press DOWN"); - profileStop(); - waitFor(KEY_DOWN); + Common::log("No response! (1) Press DOWN"); + Common::profileStop(); + Common::waitForKey(KEY_DOWN); return; } u16 receivedPacket = linkConnection->read(remotePlayerId); if (withPong) { linkConnection->send(receivedPacket); if (!linkConnection->waitFor(remotePlayerId, needsReset)) { - log("No response! (2) Press DOWN"); - profileStop(); - waitFor(KEY_DOWN); + Common::log("No response! (2) Press DOWN"); + Common::profileStop(); + Common::waitForKey(KEY_DOWN); return; } u16 validation = linkConnection->read(remotePlayerId); if (validation != sentPacket) { - log("Invalid response! Press DOWN\n value = " + - std::to_string(validation) + - "\n expected = " + std::to_string(sentPacket)); - profileStop(); - waitFor(KEY_DOWN); + Common::log("Invalid response! Press DOWN\n value = " + + std::to_string(validation) + + "\n expected = " + std::to_string(sentPacket)); + Common::profileStop(); + Common::waitForKey(KEY_DOWN); return; } } - u32 elapsedCycles = profileStop(); + u32 elapsedCycles = Common::profileStop(); - u32 elapsedMilliseconds = toMs(elapsedCycles); + u32 elapsedMilliseconds = Common::toMs(elapsedCycles); samples++; totalMs += elapsedMilliseconds; u32 average = Div(totalMs, samples); @@ -330,10 +325,10 @@ void measureLatency(bool withPong) { std::to_string(average) + " ms avg" + "\nValue sent:\n " + std::to_string(sentPacket); VBlankIntrWait(); - log(output); + Common::log(output); } else { VBlankIntrWait(); - log("Waiting..."); + Common::log("Waiting..."); } } } @@ -348,56 +343,7 @@ void forceSync() { linkConnection->read(remotePlayerId); } -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} - -void waitFor(u16 key) { - u16 keys; - do { - keys = ~REG_KEYS & KEY_ANY; - } while (!(keys & key)); -} - -bool didPress(u16 key, bool& pressed) { - u16 keys = ~REG_KEYS & KEY_ANY; - bool isPressedNow = false; - if ((keys & key) && !pressed) { - pressed = true; - isPressedNow = true; - } - if (pressed && !(keys & key)) - pressed = false; - return isPressedNow; -} - bool needsReset() { u16 keys = ~REG_KEYS & KEY_ANY; return keys & KEY_SELECT; } - -void profileStart() { - REG_TM1CNT_L = 0; - REG_TM2CNT_L = 0; - - REG_TM1CNT_H = 0; - REG_TM2CNT_H = 0; - - REG_TM2CNT_H = TM_ENABLE | TM_CASCADE; - REG_TM1CNT_H = TM_ENABLE | TM_FREQ_1; -} - -u32 profileStop() { - REG_TM1CNT_H = 0; - REG_TM2CNT_H = 0; - - return (REG_TM1CNT_L | (REG_TM2CNT_L << 16)); -} - -u32 toMs(u32 cycles) { - // CPU Frequency * time per frame = cycles per frame - // 16780000 * (1/60) ~= 279666 - return (cycles * 1000) / (279666 * 60); -} diff --git a/examples/LinkCable_stress/src/main.h b/examples/LinkCable_stress/src/main.h index f194cae..f19fe80 100644 --- a/examples/LinkCable_stress/src/main.h +++ b/examples/LinkCable_stress/src/main.h @@ -9,7 +9,7 @@ #include "../../../lib/LinkUniversal.hpp" #endif -#include +#include "../../_lib/common.h" #ifndef USE_LINK_UNIVERSAL extern LinkCable* linkConnection; diff --git a/examples/LinkCube_demo/src/main.cpp b/examples/LinkCube_demo/src/main.cpp index 670b007..f1c92c9 100644 --- a/examples/LinkCube_demo/src/main.cpp +++ b/examples/LinkCube_demo/src/main.cpp @@ -1,12 +1,9 @@ // (0) Include the header #include "../../../lib/LinkCube.hpp" -#include -#include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" -void log(std::string text); -bool didPress(unsigned short key, bool& pressed); inline void VBLANK() {} bool a = false, b = false, l = false; @@ -15,8 +12,7 @@ bool a = false, b = false, l = false; LinkCube* linkCube = new LinkCube(); void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); // (2) Add the interrupt service routines interrupt_init(); @@ -48,13 +44,13 @@ int main() { ")\n\nReceived:\n" + received; // (4) Send 32-bit values - if (didPress(KEY_A, a)) { + if (Common::didPress(KEY_A, a)) { counter++; linkCube->send(counter); } // +1024 - if (didPress(KEY_L, l)) { + if (Common::didPress(KEY_L, l)) { counter += 1024; linkCube->send(counter); } @@ -65,7 +61,7 @@ int main() { } // Clear - if (didPress(KEY_B, b)) + if (Common::didPress(KEY_B, b)) received = ""; // Reset warning @@ -82,26 +78,8 @@ int main() { // Print VBlankIntrWait(); - log(output); + Common::log(output); } return 0; } - -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} - -bool didPress(u16 key, bool& pressed) { - u16 keys = ~REG_KEYS & KEY_ANY; - bool isPressedNow = false; - if ((keys & key) && !pressed) { - pressed = true; - isPressedNow = true; - } - if (pressed && !(keys & key)) - pressed = false; - return isPressedNow; -} diff --git a/examples/LinkGPIO_demo/src/main.cpp b/examples/LinkGPIO_demo/src/main.cpp index 76419d5..d791978 100644 --- a/examples/LinkGPIO_demo/src/main.cpp +++ b/examples/LinkGPIO_demo/src/main.cpp @@ -1,10 +1,8 @@ // (0) Include the header #include "../../../lib/LinkGPIO.hpp" -#include -#include +#include "../../_lib/common.h" -void log(std::string text); std::string mode(std::string name, LinkGPIO::Pin pin); std::string value(std::string name, LinkGPIO::Pin pin, bool isHigh); @@ -12,8 +10,7 @@ std::string value(std::string name, LinkGPIO::Pin pin, bool isHigh); LinkGPIO* linkGPIO = new LinkGPIO(); void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); irq_init(NULL); irq_add(II_VBLANK, NULL); @@ -80,18 +77,12 @@ int main() { // Print VBlankIntrWait(); - log(output); + Common::log(output); } return 0; } -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} - std::string mode(std::string name, LinkGPIO::Pin pin) { return name + ": " + (linkGPIO->getMode(pin) == LinkGPIO::Direction::OUTPUT ? "OUTPUT\n" diff --git a/examples/LinkMobile_demo/src/main.cpp b/examples/LinkMobile_demo/src/main.cpp index b4bde32..0e11e45 100644 --- a/examples/LinkMobile_demo/src/main.cpp +++ b/examples/LinkMobile_demo/src/main.cpp @@ -5,7 +5,6 @@ #include "main.h" -#include #include #include "../../_lib/interrupt.h" @@ -35,8 +34,7 @@ std::string selectedDomain = ""; LinkMobile* linkMobile = nullptr; void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); } int main() { @@ -77,7 +75,7 @@ start: } // SELECT = stop - if (didPress(KEY_SELECT, select)) { + if (Common::didPress(KEY_SELECT, select)) { bool didShutdown = linkMobile->getState() == LinkMobile::State::SHUTDOWN; if (hasError || didShutdown) { @@ -103,13 +101,13 @@ start: switch (linkMobile->getState()) { case LinkMobile::State::SESSION_ACTIVE: { // L = Read Configuration - if (didPress(KEY_L, l)) { + if (Common::didPress(KEY_L, l)) { readConfiguration(); waitForA(); } // R = Call someone - if (didPress(KEY_R, r)) { + if (Common::didPress(KEY_R, r)) { std::string number = getNumberInput(); if (number != "") { // (4) Call someone @@ -118,7 +116,7 @@ start: } // START = Call the ISP - if (didPress(KEY_START, start)) { + if (Common::didPress(KEY_START, start)) { std::string password = getPasswordInput(); if (password != "") { // (7) Connect to the internet @@ -129,7 +127,7 @@ start: } case LinkMobile::State::CALL_ESTABLISHED: { // L = hang up - if (didPress(KEY_L, l)) { + if (Common::didPress(KEY_L, l)) { // (6) Hang up linkMobile->hangUp(); } @@ -137,7 +135,7 @@ start: } case LinkMobile::State::PPP_ACTIVE: { // A = DNS query - if (didPress(KEY_A, a) && !waitingDNS) { + if (Common::didPress(KEY_A, a) && !waitingDNS) { std::string domain = getDomainInput(); if (domain != "") { // (8) Run DNS queries @@ -146,7 +144,7 @@ start: } } // L = hang up - if (didPress(KEY_L, l)) { + if (Common::didPress(KEY_L, l)) { // (6) Hang up linkMobile->hangUp(); } @@ -249,7 +247,7 @@ void handlePPP() { log("Downloading... (" + std::to_string(chunk) + ", " + std::to_string(retry) + ")\n (hold START = close conn)\n\n" + output); - if (didPress(KEY_START, start)) { + if (Common::didPress(KEY_START, start)) { log("Closing..."); LinkMobile::CloseConn closeConn; linkMobile->closeConnection( @@ -424,43 +422,43 @@ std::string getInput(std::string& field, std::string output = "Type " + inputName + ":\n\n"; output += ">> " + field + "\n\n"; - if (didPress(KEY_RIGHT, right)) { + if (Common::didPress(KEY_RIGHT, right)) { selectedX++; if (selectedX >= (int)renderRows[0].size()) selectedX = renderRows[0].size() - 1; } - if (didPress(KEY_LEFT, left)) { + if (Common::didPress(KEY_LEFT, left)) { selectedX--; if (selectedX < 0) selectedX = 0; } - if (didPress(KEY_UP, up)) { + if (Common::didPress(KEY_UP, up)) { selectedY--; if (selectedY < 0) selectedY = 0; } - if (didPress(KEY_DOWN, down)) { + if (Common::didPress(KEY_DOWN, down)) { selectedY++; if (selectedY >= (int)renderRows.size()) selectedY = renderRows.size() - 1; } - if (didPress(KEY_B, b)) { + if (Common::didPress(KEY_B, b)) { if (field.size() > 0) field = field.substr(0, field.size() - 1); else return ""; } - if (didPress(KEY_A, a)) { + if (Common::didPress(KEY_A, a)) { if (field.size() < maxChars) field += renderRows[selectedY][selectedX]; } - if (didPress(KEY_SELECT, select)) { + if (Common::didPress(KEY_SELECT, select)) { field = defaultValues[selectedDefaultValue].value; selectedDefaultValue = (selectedDefaultValue + 1) % defaultValues.size(); } - if (didPress(KEY_START, start)) + if (Common::didPress(KEY_START, start)) return field; - if (altName != "" && didPress(KEY_L, l)) + if (altName != "" && Common::didPress(KEY_L, l)) altActive = !altActive; for (int y = 0; y < (int)renderRows.size(); y++) { @@ -589,9 +587,7 @@ std::string getResultString(LinkMobile::CommandResult cmdResult) { void log(std::string text) { if (linkMobile != nullptr) VBlankIntrWait(); - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); + Common::log(text); } std::string toStr(char* chars, int size) { @@ -602,20 +598,8 @@ std::string toStr(char* chars, int size) { return std::string(copiedChars); } -bool didPress(u16 key, bool& pressed) { - u16 keys = ~REG_KEYS & KEY_ANY; - bool isPressedNow = false; - if ((keys & key) && !pressed) { - pressed = true; - isPressedNow = true; - } - if (pressed && !(keys & key)) - pressed = false; - return isPressedNow; -} - void waitForA() { - while (!didPress(KEY_A, a)) + while (!Common::didPress(KEY_A, a)) ; } diff --git a/examples/LinkMobile_demo/src/main.h b/examples/LinkMobile_demo/src/main.h index ec745f1..2d1c518 100644 --- a/examples/LinkMobile_demo/src/main.h +++ b/examples/LinkMobile_demo/src/main.h @@ -3,8 +3,8 @@ #include "../../../lib/LinkMobile.hpp" -#include #include +#include "../../_lib/common.h" struct DefaultValue { std::string name; @@ -44,7 +44,6 @@ std::string getResultString(LinkMobile::CommandResult cmdResult); void log(std::string text); std::string toStr(char* chars, int size); -bool didPress(unsigned short key, bool& pressed); void waitForA(); template diff --git a/examples/LinkPS2Keyboard_demo/src/main.cpp b/examples/LinkPS2Keyboard_demo/src/main.cpp index 6f32dff..0a0c54c 100644 --- a/examples/LinkPS2Keyboard_demo/src/main.cpp +++ b/examples/LinkPS2Keyboard_demo/src/main.cpp @@ -1,11 +1,9 @@ -#include -#include -#include "../../_lib/interrupt.h" - // (0) Include the header #include "../../../lib/LinkPS2Keyboard.hpp" -void log(std::string text); +#include "../../_lib/common.h" +#include "../../_lib/interrupt.h" + static std::string scanCodes = ""; static std::string output = ""; static u32 irqs = 0; @@ -22,8 +20,7 @@ LinkPS2Keyboard* linkPS2Keyboard = new LinkPS2Keyboard([](u8 scanCode) { }); void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); // (2) Add the interrupt service routines interrupt_init(); @@ -47,7 +44,7 @@ int main() { if (keys & KEY_A) { // (3) Initialize the library - log("Waiting..."); + Common::log("Waiting..."); linkPS2Keyboard->activate(); VBlankIntrWait(); continue; @@ -63,14 +60,8 @@ int main() { // Print VBlankIntrWait(); LINK_PS2_KEYBOARD_ISR_VBLANK(); - log(output); + Common::log(output); } return 0; } - -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} diff --git a/examples/LinkPS2Mouse_demo/src/main.cpp b/examples/LinkPS2Mouse_demo/src/main.cpp index d96b9d4..1d30998 100644 --- a/examples/LinkPS2Mouse_demo/src/main.cpp +++ b/examples/LinkPS2Mouse_demo/src/main.cpp @@ -1,29 +1,17 @@ // (0) Include the header #include "../../../lib/LinkPS2Mouse.hpp" -#include -#include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" -void log(std::string text); inline void VBLANK() {} inline void TIMER() {} // (1) Create a LinkPS2Mouse instance LinkPS2Mouse* linkPS2Mouse = new LinkPS2Mouse(2); -inline void ISR_reset() { - REG_IME = 0; - RegisterRamReset(RESET_REG | RESET_VRAM); -#if MULTIBOOT_BUILD == 1 - *(vu8*)0x03007FFA = 0x01; -#endif - SoftReset(); -} - void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); // (2) Add the interrupt service routines interrupt_init(); @@ -34,7 +22,7 @@ void init() { // B = SoftReset REG_KEYCNT = 0b10 | (1 << 14); - interrupt_set_handler(INTR_KEYPAD, ISR_reset); + interrupt_set_handler(INTR_KEYPAD, Common::ISR_reset); interrupt_enable(INTR_KEYPAD); } @@ -52,7 +40,7 @@ int main() { if (keys & KEY_A) { // (3) Initialize the library - log("Waiting..."); + Common::log("Waiting..."); linkPS2Mouse->activate(); VBlankIntrWait(); continue; @@ -67,14 +55,8 @@ int main() { // Print VBlankIntrWait(); - log(output); + Common::log(output); } return 0; } - -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} diff --git a/examples/LinkRawCable_demo/src/main.cpp b/examples/LinkRawCable_demo/src/main.cpp index 00f6d90..b27cf1f 100644 --- a/examples/LinkRawCable_demo/src/main.cpp +++ b/examples/LinkRawCable_demo/src/main.cpp @@ -1,19 +1,16 @@ // (0) Include the header #include "../../../lib/LinkRawCable.hpp" -#include -#include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" -void log(std::string text); inline void VBLANK() {} // (1) Create a LinkRawCable instance LinkRawCable* linkRawCable = new LinkRawCable(); void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); // (2) Add the interrupt service routines interrupt_init(); @@ -54,7 +51,7 @@ int main() { output += "isReady() = " + std::to_string(linkRawCable->isReady()) + "\n\n"; if (firstTransfer) { - log(output + "Waiting..."); + Common::log(output + "Waiting..."); firstTransfer = false; } @@ -62,19 +59,19 @@ int main() { // (4)/(5) Exchange 16-bit data with the connected consoles if (prevKeys == 0 && keys != 0 && linkRawCable->isReady()) { counter++; - log(output + "..."); + Common::log(output + "..."); LinkRawCable::Response response = linkRawCable->transfer(counter, []() { u16 keys = ~REG_KEYS & KEY_ANY; return (keys & KEY_L) && (keys & KEY_R); }); - log(output + ">> " + std::to_string(counter)); + Common::log(output + ">> " + std::to_string(counter)); Link::wait(228 * 60); - log(output + "<< [" + std::to_string(response.data[0]) + "," + - std::to_string(response.data[1]) + "," + - std::to_string(response.data[2]) + "," + - std::to_string(response.data[3]) + "]\n" + - "_pID: " + std::to_string(response.playerId)); + Common::log(output + "<< [" + std::to_string(response.data[0]) + "," + + std::to_string(response.data[1]) + "," + + std::to_string(response.data[2]) + "," + + std::to_string(response.data[3]) + "]\n" + + "_pID: " + std::to_string(response.playerId)); Link::wait(228 * 60); } } else { @@ -83,16 +80,16 @@ int main() { linkRawCable->getAsyncState() == LinkRawCable::AsyncState::IDLE) { counter++; linkRawCable->transferAsync(counter); - log(output + ">> " + std::to_string(counter)); + Common::log(output + ">> " + std::to_string(counter)); Link::wait(228 * 60); } if (linkRawCable->getAsyncState() == LinkRawCable::AsyncState::READY) { LinkRawCable::Response response = linkRawCable->getAsyncData(); - log(output + "<< [" + std::to_string(response.data[0]) + "," + - std::to_string(response.data[1]) + "," + - std::to_string(response.data[2]) + "," + - std::to_string(response.data[3]) + "]\n" + - "_pID: " + std::to_string(response.playerId)); + Common::log(output + "<< [" + std::to_string(response.data[0]) + "," + + std::to_string(response.data[1]) + "," + + std::to_string(response.data[2]) + "," + + std::to_string(response.data[3]) + "]\n" + + "_pID: " + std::to_string(response.playerId)); Link::wait(228 * 60); } } @@ -107,15 +104,9 @@ int main() { // Print VBlankIntrWait(); - log(output); + Common::log(output); prevKeys = keys; } return 0; } - -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} diff --git a/examples/LinkRawWireless_demo/Makefile b/examples/LinkRawWireless_demo/Makefile index fc3c706..0edd7d9 100644 --- a/examples/LinkRawWireless_demo/Makefile +++ b/examples/LinkRawWireless_demo/Makefile @@ -123,9 +123,8 @@ TITLE := $(PROJ) LIBS := -ltonc -lugba -lgba-sprite-engine BUILD := build -SRCDIRS := src ../_lib ../../lib \ - src/scenes \ - src/utils +SRCDIRS := src ../_lib ../_lib/libgba-sprite-engine ../../lib \ + src/scenes DATADIRS := INCDIRS := src LIBDIRS := $(TONCLIB) $(PWD)/../_lib/libugba $(PWD)/../_lib/libgba-sprite-engine diff --git a/examples/LinkRawWireless_demo/src/main.cpp b/examples/LinkRawWireless_demo/src/main.cpp index 472b8ef..a8af54d 100644 --- a/examples/LinkRawWireless_demo/src/main.cpp +++ b/examples/LinkRawWireless_demo/src/main.cpp @@ -3,10 +3,9 @@ #include "../../../lib/LinkRawWireless.hpp" #include -#include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" #include "scenes/DebugScene.h" -#include "utils/SceneUtils.h" void setUpInterrupts(); void printTutorial(); @@ -29,15 +28,6 @@ int main() { return 0; } -inline void ISR_reset() { - REG_IME = 0; - RegisterRamReset(RESET_REG | RESET_VRAM); -#if MULTIBOOT_BUILD == 1 - *(vu8*)0x03007FFA = 0x01; -#endif - SoftReset(); -} - inline void setUpInterrupts() { interrupt_init(); @@ -46,6 +36,6 @@ inline void setUpInterrupts() { // A+B+START+SELECT = SoftReset REG_KEYCNT = 0b1100000000001111; - interrupt_set_handler(INTR_KEYPAD, ISR_reset); + interrupt_set_handler(INTR_KEYPAD, Common::ISR_reset); interrupt_enable(INTR_KEYPAD); } diff --git a/examples/LinkRawWireless_demo/src/scenes/DebugScene.cpp b/examples/LinkRawWireless_demo/src/scenes/DebugScene.cpp index c71f122..2f681b6 100644 --- a/examples/LinkRawWireless_demo/src/scenes/DebugScene.cpp +++ b/examples/LinkRawWireless_demo/src/scenes/DebugScene.cpp @@ -5,12 +5,10 @@ #include "DebugScene.h" #include -#include #include #include - -#include "utils/InputHandler.h" -#include "utils/SceneUtils.h" +#include "../../../_lib/common.h" +#include "../../../_lib/libgba-sprite-engine/scene.h" DebugScene::DebugScene(std::shared_ptr engine) : Scene(engine) {} diff --git a/examples/LinkRawWireless_demo/src/utils/InputHandler.h b/examples/LinkRawWireless_demo/src/utils/InputHandler.h deleted file mode 100644 index ebe25fe..0000000 --- a/examples/LinkRawWireless_demo/src/utils/InputHandler.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef INPUT_HANDLER_H -#define INPUT_HANDLER_H - -#include - -class InputHandler { - public: - InputHandler() { - this->isPressed = false; - this->isWaiting = true; - } - - inline bool getIsPressed() { return isPressed; } - - inline bool hasBeenPressedNow() { return isNewPressEvent; } - inline bool hasBeenReleasedNow() { return isNewReleaseEvent; } - - inline bool getHandledFlag() { return handledFlag; } - inline void setHandledFlag(bool value) { handledFlag = value; } - - inline void setIsPressed(bool isPressed) { - bool isNewPressEvent = !this->isWaiting && !this->isPressed && isPressed; - bool isNewReleaseEvent = !this->isWaiting && this->isPressed && !isPressed; - this->isPressed = isPressed; - this->isWaiting = this->isWaiting && isPressed; - - this->isNewPressEvent = isNewPressEvent; - this->isNewReleaseEvent = isNewReleaseEvent; - } - - protected: - bool isPressed = false; - bool isNewPressEvent = false; - bool isNewReleaseEvent = false; - bool handledFlag = false; - bool isWaiting = false; -}; - -#endif // INPUT_HANDLER_H diff --git a/examples/LinkRawWireless_demo/src/utils/SceneUtils.h b/examples/LinkRawWireless_demo/src/utils/SceneUtils.h deleted file mode 100644 index 54e5aa7..0000000 --- a/examples/LinkRawWireless_demo/src/utils/SceneUtils.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef SCENE_UTILS_H -#define SCENE_UTILS_H - -#include -#include -#include -#include - -const u32 TEXT_MIDDLE_COL = 12; - -inline std::string asStr(u16 data) { - return std::to_string(data); -} - -inline void BACKGROUND_enable(bool bg0, bool bg1, bool bg2, bool bg3) { - REG_DISPCNT = bg0 ? REG_DISPCNT | DCNT_BG0 : REG_DISPCNT & ~DCNT_BG0; - REG_DISPCNT = bg1 ? REG_DISPCNT | DCNT_BG1 : REG_DISPCNT & ~DCNT_BG1; - REG_DISPCNT = bg2 ? REG_DISPCNT | DCNT_BG2 : REG_DISPCNT & ~DCNT_BG2; - REG_DISPCNT = bg3 ? REG_DISPCNT | DCNT_BG3 : REG_DISPCNT & ~DCNT_BG3; -} - -inline void SPRITE_disable() { - REG_DISPCNT = REG_DISPCNT & ~DCNT_OBJ; -} - -inline void SCENE_init() { - TextStream::instance().clear(); - TextStream::instance().scroll(0, 0); - TextStream::instance().setMosaic(false); - - BACKGROUND_enable(false, false, false, false); - SPRITE_disable(); -} - -inline void SCENE_write(std::string text, u32 row) { - TextStream::instance().setText(text, row, - TEXT_MIDDLE_COL - text.length() / 2); -} - -#endif // SCENE_UTILS_H diff --git a/examples/LinkSPI_demo/src/main.cpp b/examples/LinkSPI_demo/src/main.cpp index 978954f..ba3a619 100644 --- a/examples/LinkSPI_demo/src/main.cpp +++ b/examples/LinkSPI_demo/src/main.cpp @@ -1,19 +1,16 @@ // (0) Include the header #include "../../../lib/LinkSPI.hpp" -#include -#include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" -void log(std::string text); inline void VBLANK() {} // (1) Create a LinkSPI instance LinkSPI* linkSPI = new LinkSPI(); void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); // (2) Add the interrupt service routines interrupt_init(); @@ -65,7 +62,7 @@ int main() { linkSPI->getMode() == LinkSPI::Mode::SLAVE ? "[slave]" : "[master]"; output += std::string(modeName) + "\n"; if (firstTransfer) { - log(output + "Waiting..."); + Common::log(output + "Waiting..."); firstTransfer = false; } @@ -86,11 +83,11 @@ int main() { u16 keys = ~REG_KEYS & KEY_ANY; return (keys & KEY_L) && (keys & KEY_R); }); - log(output + ">> " + std::to_string(counter)); + Common::log(output + ">> " + std::to_string(counter)); Link::wait(228 * 60); } if (linkSPI->getAsyncState() == LinkSPI::AsyncState::READY) { - log(output + "<< " + std::to_string(linkSPI->getAsyncData())); + Common::log(output + "<< " + std::to_string(linkSPI->getAsyncData())); Link::wait(228 * 60); } } @@ -105,14 +102,8 @@ int main() { // Print VBlankIntrWait(); - log(output); + Common::log(output); } return 0; } - -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} diff --git a/examples/LinkUART_demo/src/main.cpp b/examples/LinkUART_demo/src/main.cpp index 4f39f68..7989527 100644 --- a/examples/LinkUART_demo/src/main.cpp +++ b/examples/LinkUART_demo/src/main.cpp @@ -1,11 +1,9 @@ // (0) Include the header #include "../../../lib/LinkUART.hpp" -#include -#include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" -void log(std::string text); inline void VBLANK() {} std::string received = ""; @@ -15,8 +13,7 @@ u32 lines = 0; LinkUART* linkUART = new LinkUART(); void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); // (2) Add the interrupt service routines interrupt_init(); @@ -49,7 +46,7 @@ int main() { } else { // Title if (firstTransfer) { - log(output + "Waiting..."); + Common::log(output + "Waiting..."); firstTransfer = false; } @@ -83,14 +80,8 @@ int main() { // Print VBlankIntrWait(); - log(output); + Common::log(output); } return 0; } - -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} diff --git a/examples/LinkUniversal_basic/src/main.cpp b/examples/LinkUniversal_basic/src/main.cpp index e899607..e4ab2fa 100644 --- a/examples/LinkUniversal_basic/src/main.cpp +++ b/examples/LinkUniversal_basic/src/main.cpp @@ -4,33 +4,20 @@ // (0) Include the header #include "../../../lib/LinkUniversal.hpp" -#include -#include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" -void log(std::string text); -void waitFor(u16 key); - LinkUniversal* linkUniversal = nullptr; void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); -} - -inline void ISR_reset() { - REG_IME = 0; - RegisterRamReset(RESET_REG | RESET_VRAM); -#if MULTIBOOT_BUILD == 1 - *(vu8*)0x03007FFA = 0x01; -#endif - SoftReset(); + Common::initTTE(); } int main() { init(); - log("LinkUniversal_basic (v7.1.0)\n" + Common::log( + "LinkUniversal_basic (v7.1.0)\n" "Press A to start\n\n" "hold LEFT on start:\n -> force cable\n\n" "hold RIGHT on start:\n -> force wireless\n\n" @@ -38,7 +25,7 @@ int main() { "hold DOWN on start:\n -> force wireless client\n\n" "hold B on start:\n -> set 2 players (wireless)\n\nhold R on start:\n -> " "restore wireless multiboot"); - waitFor(KEY_A); + Common::waitForKey(KEY_A); u16 initialKeys = ~REG_KEYS & KEY_ANY; bool forceCable = initialKeys & KEY_LEFT; bool forceWireless = initialKeys & KEY_RIGHT; @@ -83,7 +70,7 @@ int main() { // B+START+SELECT = SoftReset REG_KEYCNT = 0b1100000000001110; - interrupt_set_handler(INTR_KEYPAD, ISR_reset); + interrupt_set_handler(INTR_KEYPAD, Common::ISR_reset); interrupt_enable(INTR_KEYPAD); // (3) Initialize the library @@ -133,21 +120,8 @@ int main() { } VBlankIntrWait(); - log(output); + Common::log(output); } return 0; } - -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} - -void waitFor(u16 key) { - u16 keys; - do { - keys = ~REG_KEYS & KEY_ANY; - } while (!(keys & key)); -} diff --git a/examples/LinkWirelessMultiboot_demo/Makefile b/examples/LinkWirelessMultiboot_demo/Makefile index 45f56c3..0504ccc 100644 --- a/examples/LinkWirelessMultiboot_demo/Makefile +++ b/examples/LinkWirelessMultiboot_demo/Makefile @@ -123,9 +123,8 @@ TITLE := $(PROJ) LIBS := -ltonc -lugba -lgba-sprite-engine BUILD := build -SRCDIRS := src ../_lib ../../lib ../_lib/libgbfs \ - src/scenes \ - src/utils +SRCDIRS := src ../_lib ../_lib/libgba-sprite-engine ../../lib ../_lib/libgbfs \ + src/scenes DATADIRS := INCDIRS := src LIBDIRS := $(TONCLIB) $(PWD)/../_lib/libugba $(PWD)/../_lib/libgba-sprite-engine diff --git a/examples/LinkWirelessMultiboot_demo/src/main.cpp b/examples/LinkWirelessMultiboot_demo/src/main.cpp index fce6737..c8411e9 100644 --- a/examples/LinkWirelessMultiboot_demo/src/main.cpp +++ b/examples/LinkWirelessMultiboot_demo/src/main.cpp @@ -1,10 +1,10 @@ #include "../../../lib/LinkWirelessMultiboot.hpp" #include -#include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" +#include "../../_lib/libgba-sprite-engine/scene.h" #include "scenes/MultibootScene.h" -#include "utils/SceneUtils.h" void setUpInterrupts(); void printTutorial(); @@ -28,15 +28,6 @@ int main() { return 0; } -inline void ISR_reset() { - REG_IME = 0; - RegisterRamReset(RESET_REG | RESET_VRAM); -#if MULTIBOOT_BUILD == 1 - *(vu8*)0x03007FFA = 0x01; -#endif - SoftReset(); -} - inline void setUpInterrupts() { interrupt_init(); @@ -45,6 +36,6 @@ inline void setUpInterrupts() { // A+B+START+SELECT = SoftReset REG_KEYCNT = 0b1100000000001111; - interrupt_set_handler(INTR_KEYPAD, ISR_reset); + interrupt_set_handler(INTR_KEYPAD, Common::ISR_reset); interrupt_enable(INTR_KEYPAD); } diff --git a/examples/LinkWirelessMultiboot_demo/src/scenes/MultibootScene.cpp b/examples/LinkWirelessMultiboot_demo/src/scenes/MultibootScene.cpp index f0a2a74..f1a33e7 100644 --- a/examples/LinkWirelessMultiboot_demo/src/scenes/MultibootScene.cpp +++ b/examples/LinkWirelessMultiboot_demo/src/scenes/MultibootScene.cpp @@ -4,15 +4,13 @@ #include "MultibootScene.h" #include -#include #include #include - -#include "utils/InputHandler.h" -#include "utils/SceneUtils.h" +#include "../../../_lib/common.h" +#include "../../../_lib/libgba-sprite-engine/scene.h" extern "C" { -#include "../../_lib/libgbfs/gbfs.h" +#include "../../../_lib/libgbfs/gbfs.h" } static const GBFS_FILE* fs = find_first_gbfs_file(0); diff --git a/examples/LinkWirelessMultiboot_demo/src/scenes/MultibootScene.h b/examples/LinkWirelessMultiboot_demo/src/scenes/MultibootScene.h index 293c009..9c2f94e 100644 --- a/examples/LinkWirelessMultiboot_demo/src/scenes/MultibootScene.h +++ b/examples/LinkWirelessMultiboot_demo/src/scenes/MultibootScene.h @@ -5,7 +5,6 @@ #include #include #include - #include #include diff --git a/examples/LinkWirelessMultiboot_demo/src/utils/InputHandler.h b/examples/LinkWirelessMultiboot_demo/src/utils/InputHandler.h deleted file mode 100644 index ebe25fe..0000000 --- a/examples/LinkWirelessMultiboot_demo/src/utils/InputHandler.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef INPUT_HANDLER_H -#define INPUT_HANDLER_H - -#include - -class InputHandler { - public: - InputHandler() { - this->isPressed = false; - this->isWaiting = true; - } - - inline bool getIsPressed() { return isPressed; } - - inline bool hasBeenPressedNow() { return isNewPressEvent; } - inline bool hasBeenReleasedNow() { return isNewReleaseEvent; } - - inline bool getHandledFlag() { return handledFlag; } - inline void setHandledFlag(bool value) { handledFlag = value; } - - inline void setIsPressed(bool isPressed) { - bool isNewPressEvent = !this->isWaiting && !this->isPressed && isPressed; - bool isNewReleaseEvent = !this->isWaiting && this->isPressed && !isPressed; - this->isPressed = isPressed; - this->isWaiting = this->isWaiting && isPressed; - - this->isNewPressEvent = isNewPressEvent; - this->isNewReleaseEvent = isNewReleaseEvent; - } - - protected: - bool isPressed = false; - bool isNewPressEvent = false; - bool isNewReleaseEvent = false; - bool handledFlag = false; - bool isWaiting = false; -}; - -#endif // INPUT_HANDLER_H diff --git a/examples/LinkWirelessMultiboot_demo/src/utils/SceneUtils.h b/examples/LinkWirelessMultiboot_demo/src/utils/SceneUtils.h deleted file mode 100644 index 54e5aa7..0000000 --- a/examples/LinkWirelessMultiboot_demo/src/utils/SceneUtils.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef SCENE_UTILS_H -#define SCENE_UTILS_H - -#include -#include -#include -#include - -const u32 TEXT_MIDDLE_COL = 12; - -inline std::string asStr(u16 data) { - return std::to_string(data); -} - -inline void BACKGROUND_enable(bool bg0, bool bg1, bool bg2, bool bg3) { - REG_DISPCNT = bg0 ? REG_DISPCNT | DCNT_BG0 : REG_DISPCNT & ~DCNT_BG0; - REG_DISPCNT = bg1 ? REG_DISPCNT | DCNT_BG1 : REG_DISPCNT & ~DCNT_BG1; - REG_DISPCNT = bg2 ? REG_DISPCNT | DCNT_BG2 : REG_DISPCNT & ~DCNT_BG2; - REG_DISPCNT = bg3 ? REG_DISPCNT | DCNT_BG3 : REG_DISPCNT & ~DCNT_BG3; -} - -inline void SPRITE_disable() { - REG_DISPCNT = REG_DISPCNT & ~DCNT_OBJ; -} - -inline void SCENE_init() { - TextStream::instance().clear(); - TextStream::instance().scroll(0, 0); - TextStream::instance().setMosaic(false); - - BACKGROUND_enable(false, false, false, false); - SPRITE_disable(); -} - -inline void SCENE_write(std::string text, u32 row) { - TextStream::instance().setText(text, row, - TEXT_MIDDLE_COL - text.length() / 2); -} - -#endif // SCENE_UTILS_H diff --git a/examples/LinkWireless_demo/src/main.cpp b/examples/LinkWireless_demo/src/main.cpp index ea04460..37fd3aa 100644 --- a/examples/LinkWireless_demo/src/main.cpp +++ b/examples/LinkWireless_demo/src/main.cpp @@ -1,22 +1,17 @@ // (0) Include the header #include "../../../lib/LinkWireless.hpp" -#include #include #include -#include #include +#include "../../_lib/common.h" #include "../../_lib/interrupt.h" -#ifdef PROFILING_ENABLED -#include -#endif - #define CHECK_ERRORS(MESSAGE) \ if ((lastError = linkWireless->getLastError()) || \ linkWireless->getState() == LinkWireless::State::NEEDS_RESET) { \ - log(std::string(MESSAGE) + " (" + std::to_string(lastError) + ") [" + \ - std::to_string(linkWireless->getState()) + "]"); \ + Common::log(std::string(MESSAGE) + " (" + std::to_string(lastError) + \ + ") [" + std::to_string(linkWireless->getState()) + "]"); \ hang(); \ linkWireless->activate(); \ return; \ @@ -26,9 +21,6 @@ void activate(); void serve(); void connect(); void messageLoop(); -void log(std::string text); -void waitFor(u16 key); -bool didPress(u16 key, bool& pressed); void hang(); LinkWireless::Error lastError; @@ -37,8 +29,7 @@ bool forwarding, retransmission; u32 maxPlayers; void init() { - REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; - tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); + Common::initTTE(); } int main() { @@ -63,15 +54,15 @@ int main() { start: // Options - log("LinkWireless_demo (v7.1.0)\n" + buildSettings + - "\n" - "Press A to start\n\n" - "hold LEFT on start:\n -> disable forwarding\n\n" - "hold UP on start:\n -> disable retransmission\n\n" - "hold RIGHT on start:\n -> restore from multiboot\n -> high " - "timeout\n\n" - "hold B on start:\n -> set 2 players"); - waitFor(KEY_A); + Common::log("LinkWireless_demo (v7.1.0)\n" + buildSettings + + "\n" + "Press A to start\n\n" + "hold LEFT on start:\n -> disable forwarding\n\n" + "hold UP on start:\n -> disable retransmission\n\n" + "hold RIGHT on start:\n -> restore from multiboot\n -> high " + "timeout\n\n" + "hold B on start:\n -> set 2 players"); + Common::waitForKey(KEY_A); u16 initialKeys = ~REG_KEYS & KEY_ANY; forwarding = !(initialKeys & KEY_LEFT); retransmission = !(initialKeys & KEY_UP); @@ -83,7 +74,7 @@ start: forwarding, retransmission, maxPlayers, isRestoringFromMultiboot ? 1000 : LINK_WIRELESS_DEFAULT_TIMEOUT, LINK_WIRELESS_DEFAULT_INTERVAL, LINK_WIRELESS_DEFAULT_SEND_TIMER_ID); - // linkWireless->debug = [](std::string str) { log(str); }; + // linkWireless->debug = [](std::string str) { Common::log(str); }; // (2) Add the required interrupt service routines interrupt_init(); @@ -99,7 +90,7 @@ start: // Restore from multiboot bool success = linkWireless->restoreFromMultiboot(); if (!success) { - log("Multiboot restoration failed!"); + Common::log("Multiboot restoration failed!"); hang(); } } else { @@ -114,7 +105,7 @@ start: while (true) { u16 keys = ~REG_KEYS & KEY_ANY; - // If a session is already active (multiboot), go straight the message loop + // If a session is active (multiboot), go straight to the message loop if (linkWireless->isSessionActive()) { messageLoop(); VBlankIntrWait(); @@ -122,7 +113,8 @@ start: } // Menu - log(std::string("") + + Common::log( + std::string("") + "L = Serve\nR = Connect\n\n (DOWN = ok)\n " "(SELECT = cancel)\n (START = activate)\n\n-> forwarding: " + (forwarding ? "ON" : "OFF") + @@ -143,15 +135,15 @@ start: } // START = Activate - if (didPress(KEY_START, activating)) + if (Common::didPress(KEY_START, activating)) activate(); // L = Serve - if (didPress(KEY_L, serving)) + if (Common::didPress(KEY_L, serving)) serve(); // R = Connect - if (didPress(KEY_R, connecting)) + if (Common::didPress(KEY_R, connecting)) connect(); VBlankIntrWait(); @@ -161,29 +153,29 @@ start: } void activate() { - log("Trying..."); + Common::log("Trying..."); if (linkWireless->activate()) - log("Activated!"); + Common::log("Activated!"); else - log("Activation failed! :("); + Common::log("Activation failed! :("); hang(); } void serve() { - log("Serving..."); + Common::log("Serving..."); // (4) Start a server linkWireless->serve("LinkWireless", "Demo"); CHECK_ERRORS("Serve failed :(") - log("Listening..."); + Common::log("Listening..."); do { u16 keys = ~REG_KEYS & KEY_ANY; if (keys & KEY_SELECT) { - log("Canceled!"); + Common::log("Canceled!"); linkWireless->activate(); hang(); return; @@ -192,7 +184,7 @@ void serve() { !linkWireless->isConnected()); CHECK_ERRORS("Accept failed :(") - log("Connection accepted!"); + Common::log("Connection accepted!"); messageLoop(); } @@ -206,7 +198,7 @@ void connect() { std::string dots = ""; for (u32 i = 0; i < dotsCount; i++) dots += "."; - log("Searching" + dots); + Common::log("Searching" + dots); }; // (5) Connect to a server @@ -215,7 +207,7 @@ void connect() { CHECK_ERRORS("Search failed :(") if (servers[0].id == LINK_WIRELESS_END) { - log("Nothing found :("); + Common::log("Nothing found :("); hang(); return; } else { @@ -238,10 +230,10 @@ void connect() { str += " -> user: " + std::string(server.userName) + "\n"; str += "\n"; } - log(str); + Common::log(str); } - waitFor(KEY_START | KEY_SELECT); + Common::waitForKey(KEY_START | KEY_SELECT); if ((~REG_KEYS & KEY_ANY) & KEY_SELECT) { linkWireless->activate(); return; @@ -253,7 +245,7 @@ void connect() { while (linkWireless->getState() == LinkWireless::State::CONNECTING) { u16 keys = ~REG_KEYS & KEY_ANY; if (keys & KEY_SELECT) { - log("Canceled!"); + Common::log("Canceled!"); linkWireless->activate(); hang(); return; @@ -263,14 +255,14 @@ void connect() { CHECK_ERRORS("Connect failed 2 :(") } - log("Connected! " + std::to_string(linkWireless->currentPlayerId()) + "\n" + - "Waiting for server..."); + Common::log("Connected! " + std::to_string(linkWireless->currentPlayerId()) + + "\n" + "Waiting for server..."); while (linkWireless->getState() == LinkWireless::State::CONNECTED && !linkWireless->isConnected()) { u16 keys = ~REG_KEYS & KEY_ANY; if (keys & KEY_SELECT) { - log("Canceled!"); + Common::log("Canceled!"); linkWireless->activate(); hang(); return; @@ -371,7 +363,7 @@ void messageLoop() { } // Packet loss check setting - if (didPress(KEY_UP, switching)) { + if (Common::didPress(KEY_UP, switching)) { #ifdef PROFILING_ENABLED // In the profiler ROM, pressing UP will update the broadcast data if (linkWireless->getState() == LinkWireless::State::SERVING && @@ -381,8 +373,8 @@ void messageLoop() { counters[0]); if (linkWireless->getLastError() == LinkWireless::Error::BUSY_TRY_AGAIN) { - log("Busy! Can't update."); - waitFor(KEY_DOWN); + Common::log("Busy! Can't update."); + Common::waitForKey(KEY_DOWN); } } @@ -390,12 +382,12 @@ void messageLoop() { if (linkWireless->getState() == LinkWireless::State::SERVING && !linkWireless->isServerClosed() && (keys & KEY_START)) { if (linkWireless->closeServer()) { - log("Server closed!"); - waitFor(KEY_DOWN); + Common::log("Server closed!"); + Common::waitForKey(KEY_DOWN); } else if (linkWireless->getLastError() == LinkWireless::Error::BUSY_TRY_AGAIN) { - log("Busy! Can't close."); - waitFor(KEY_DOWN); + Common::log("Busy! Can't close."); + Common::waitForKey(KEY_DOWN); } } #endif @@ -412,17 +404,17 @@ void messageLoop() { } // Normal output + std::string altOptionName = "Packet loss check"; +#ifdef PROFILING_ENABLED + altOptionName = "Show profiler"; +#endif std::string output = "Player #" + std::to_string(linkWireless->currentPlayerId()) + " (" + std::to_string(linkWireless->playerCount()) + " total)" + "\n\n(press A to increment counter)\n(hold B to do it " - "continuously)\n(hold LEFT for double send)\n\nPacket loss check: " + - (altView ? "ON" : "OFF") + "\n(switch with UP)\n\n"; - -#ifdef PROFILING_ENABLED - output = std::regex_replace(output, std::regex("Packet loss check"), - "Show profiler"); -#endif + "continuously)\n(hold LEFT for double send)\n\n" + + altOptionName + ": " + (altView ? "ON" : "OFF") + + "\n(switch with UP)\n\n"; for (u32 i = 0; i < linkWireless->playerCount(); i++) { output += @@ -485,35 +477,10 @@ void messageLoop() { // Print VBlankIntrWait(); - log(output); + Common::log(output); } } -void log(std::string text) { - tte_erase_screen(); - tte_write("#{P:0,0}"); - tte_write(text.c_str()); -} - -void waitFor(u16 key) { - u16 keys; - do { - keys = ~REG_KEYS & KEY_ANY; - } while (!(keys & key)); -} - -bool didPress(u16 key, bool& pressed) { - u16 keys = ~REG_KEYS & KEY_ANY; - bool isPressedNow = false; - if ((keys & key) && !pressed) { - pressed = true; - isPressedNow = true; - } - if (pressed && !(keys & key)) - pressed = false; - return isPressedNow; -} - void hang() { - waitFor(KEY_DOWN); + Common::waitForKey(KEY_DOWN); } diff --git a/examples/_lib/common.cpp b/examples/_lib/common.cpp new file mode 100644 index 0000000..e69de29 diff --git a/examples/_lib/common.h b/examples/_lib/common.h new file mode 100644 index 0000000..f822b14 --- /dev/null +++ b/examples/_lib/common.h @@ -0,0 +1,88 @@ +#ifndef LINK_EXAMPLES_COMMON_H +#define LINK_EXAMPLES_COMMON_H + +#include +#include + +namespace Common { + +// TTE + +inline void initTTE() { + REG_DISPCNT = DCNT_MODE0 | DCNT_BG0; + tte_init_se_default(0, BG_CBB(0) | BG_SBB(31)); +} + +inline void log(std::string text) { + tte_erase_screen(); + tte_write("#{P:0,0}"); + tte_write(text.c_str()); +} + +// BIOS + +inline void ISR_reset() { + REG_IME = 0; + RegisterRamReset(RESET_REG | RESET_VRAM); +#if MULTIBOOT_BUILD == 1 + *(vu8*)0x03007FFA = 0x01; +#endif + SoftReset(); +} + +// Input + +inline bool didPress(u16 key, bool& pressed) { + u16 keys = ~REG_KEYS & KEY_ANY; + bool isPressedNow = false; + if ((keys & key) && !pressed) { + pressed = true; + isPressedNow = true; + } + if (pressed && !(keys & key)) + pressed = false; + return isPressedNow; +} + +inline void waitForKey(u16 key) { + u16 keys; + do { + keys = ~REG_KEYS & KEY_ANY; + } while (!(keys & key)); +} + +// Profiling + +inline u32 toMs(u32 cycles) { + // CPU Frequency * time per frame = cycles per frame + // 16780000 * (1/60) ~= 279666 + return (cycles * 1000) / (279666 * 60); +} + +inline void profileStart() { + REG_TM1CNT_L = 0; + REG_TM2CNT_L = 0; + + REG_TM1CNT_H = 0; + REG_TM2CNT_H = 0; + + REG_TM2CNT_H = TM_ENABLE | TM_CASCADE; + REG_TM1CNT_H = TM_ENABLE | TM_FREQ_1; +} + +inline u32 profileStop() { + REG_TM1CNT_H = 0; + REG_TM2CNT_H = 0; + + return (REG_TM1CNT_L | (REG_TM2CNT_L << 16)); +} + +// Bits + +inline bool isBitHigh(u16 data, u8 bit) { + return (data >> bit) & 1; +} + +} // namespace Common + +#endif // LINK_EXAMPLES_COMMON_H diff --git a/examples/LinkCable_full/src/utils/SceneUtils.cpp b/examples/_lib/libgba-sprite-engine/scene.cpp similarity index 93% rename from examples/LinkCable_full/src/utils/SceneUtils.cpp rename to examples/_lib/libgba-sprite-engine/scene.cpp index 05d39b8..e94db06 100644 --- a/examples/LinkCable_full/src/utils/SceneUtils.cpp +++ b/examples/_lib/libgba-sprite-engine/scene.cpp @@ -1,4 +1,4 @@ -#include "SceneUtils.h" +#include "scene.h" #include diff --git a/examples/LinkCable_full/src/utils/SceneUtils.h b/examples/_lib/libgba-sprite-engine/scene.h similarity index 50% rename from examples/LinkCable_full/src/utils/SceneUtils.h rename to examples/_lib/libgba-sprite-engine/scene.h index 2e51996..7728343 100644 --- a/examples/LinkCable_full/src/utils/SceneUtils.h +++ b/examples/_lib/libgba-sprite-engine/scene.h @@ -1,5 +1,5 @@ -#ifndef SCENE_UTILS_H -#define SCENE_UTILS_H +#ifndef LINK_EXAMPLES_SCENE_H +#define LINK_EXAMPLES_SCENE_H #include #include @@ -11,13 +11,38 @@ const u32 TEXT_MIDDLE_COL = 12; extern int DEBULOG_LINE; void DEBULOG(std::string string); -inline std::string asStr(u16 data) { - return std::to_string(data); -} +class InputHandler { + public: + InputHandler() { + this->isPressed = false; + this->isWaiting = true; + } -inline bool isBitHigh(u16 data, u8 bit) { - return (data >> bit) & 1; -} + bool getIsPressed() { return isPressed; } + + bool hasBeenPressedNow() { return isNewPressEvent; } + bool hasBeenReleasedNow() { return isNewReleaseEvent; } + + bool getHandledFlag() { return handledFlag; } + void setHandledFlag(bool value) { handledFlag = value; } + + void setIsPressed(bool isPressed) { + bool isNewPressEvent = !this->isWaiting && !this->isPressed && isPressed; + bool isNewReleaseEvent = !this->isWaiting && this->isPressed && !isPressed; + this->isPressed = isPressed; + this->isWaiting = this->isWaiting && isPressed; + + this->isNewPressEvent = isNewPressEvent; + this->isNewReleaseEvent = isNewReleaseEvent; + } + + protected: + bool isPressed = false; + bool isNewPressEvent = false; + bool isNewReleaseEvent = false; + bool handledFlag = false; + bool isWaiting = false; +}; inline void BACKGROUND_enable(bool bg0, bool bg1, bool bg2, bool bg3) { REG_DISPCNT = bg0 ? REG_DISPCNT | DCNT_BG0 : REG_DISPCNT & ~DCNT_BG0; @@ -44,4 +69,4 @@ inline void SCENE_write(std::string text, u32 row) { TEXT_MIDDLE_COL - text.length() / 2); } -#endif // SCENE_UTILS_H +#endif // LINK_EXAMPLES_SCENE_H