diff --git a/semestralka1/src/game/animation.cpp b/semestralka1/src/game/animation.cpp index e69de29..56a2ced 100644 --- a/semestralka1/src/game/animation.cpp +++ b/semestralka1/src/game/animation.cpp @@ -0,0 +1,16 @@ +// src/game/animation.cpp +#include "animation.h" + +AnimationController::AnimationController() { + anim_timer.start(); +} + +bool AnimationController::tick(int speed) { + if (anim_timer.elapsed_time() >= ANIMATION_TICK) { + // speed determines scroll steps per tick + shift += speed; + anim_timer.reset(); + return true; + } + return false; +} diff --git a/semestralka1/src/game/animation.h b/semestralka1/src/game/animation.h index e69de29..c775fdd 100644 --- a/semestralka1/src/game/animation.h +++ b/semestralka1/src/game/animation.h @@ -0,0 +1,20 @@ +// src/game/animation.h +#pragma once +#include "mbed.h" + +constexpr auto ANIMATION_TICK = 170ms; + +class AnimationController { +private: + Timer anim_timer; + int shift = 0; + +public: + AnimationController(); + + // Update animation, returns true if redraw needed + bool tick(int speed); + + // Getters + int get_shift() const { return shift; } +}; diff --git a/semestralka1/src/hardware/uart.cpp b/semestralka1/src/hardware/uart.cpp new file mode 100644 index 0000000..df79419 --- /dev/null +++ b/semestralka1/src/hardware/uart.cpp @@ -0,0 +1,51 @@ +// src/hardware/uart.cpp +#include "uart.h" +#include + +UartReader::UartReader(BufferedSerial &serial, DigitalOut &led_pin) + : serial_port(serial), led(led_pin) { + memset(rx_buffer, 0, sizeof(rx_buffer)); + memset(message, 0, sizeof(message)); +} + +UartEvent UartReader::poll() { + bool changed = false; + bool triggered = false; + + // cita spravu z uartu + if (serial_port.readable()) { + memset(rx_buffer, 0, sizeof(rx_buffer)); + ssize_t num = serial_port.read(rx_buffer, sizeof(rx_buffer) - 1); + if (num > 0) { + led = !led; // toogle ledky + strncpy(message, rx_buffer, sizeof(message) - 1); + message_active = true; + changed = true; + triggered = true; + } + } + + // casovac na 1s zobrazenia spravy + if (!timer_started) { + msg_timer.start(); + timer_started = true; + } + + // po jednu sekundu sa sprava zobrazi + if (message_active && msg_timer.elapsed_time() > MESSAGE_DISPLAY_DURATION) { + message_active = false; + memset(message, 0, sizeof(message)); + msg_timer.reset(); + changed = true; + } + + if (triggered) + return UartEvent::Triggered; + if (changed) + return UartEvent::MessageUpdate; + return UartEvent::NoChange; +} + +const char* UartReader::get_message() const { + return message_active ? message : nullptr; +} diff --git a/semestralka1/src/hardware/uart.h b/semestralka1/src/hardware/uart.h new file mode 100644 index 0000000..9499a8b --- /dev/null +++ b/semestralka1/src/hardware/uart.h @@ -0,0 +1,36 @@ +// src/hardware/uart.h +#pragma once +#include "mbed.h" +#include + +constexpr size_t UART_BUFFER_SIZE = 64; +constexpr auto MESSAGE_DISPLAY_DURATION = 1s; + +enum class UartEvent { + NoChange = 0, // No new data + MessageUpdate = 1, // Message changed (received or expired) + Triggered = 2 // New message received (trigger action) +}; + +class UartReader { +private: + BufferedSerial &serial_port; + DigitalOut &led; + + char rx_buffer[UART_BUFFER_SIZE]; + char message[UART_BUFFER_SIZE]; + bool message_active = false; + + Timer msg_timer; + bool timer_started = false; + +public: + UartReader(BufferedSerial &serial, DigitalOut &led_pin); + + // Poll for UART events + UartEvent poll(); + + // Get current message (nullptr if no active message) + const char* get_message() const; + bool has_message() const { return message_active; } +}; diff --git a/semestralka1/src/render/loop.cpp b/semestralka1/src/render/loop.cpp index ecbbf55..7633dc8 100644 --- a/semestralka1/src/render/loop.cpp +++ b/semestralka1/src/render/loop.cpp @@ -6,85 +6,23 @@ #include "mbed.h" #include "player.h" #include "../game/state.h" +#include "../game/animation.h" +#include "../hardware/uart.h" #include "../assets/character_frames.h" -#include extern BufferedSerial serial_port; extern DigitalOut led; // Constants -constexpr size_t BUFFER_SIZE = 64; -constexpr auto ANIMATION_TICK = 170ms; -constexpr auto MESSAGE_DISPLAY_DURATION = 1s; constexpr int PLAYER_X = 9; constexpr int PLAYER_Y = 6; -static char rx_buffer[BUFFER_SIZE]; -static char message[BUFFER_SIZE]; -static bool message_active = false; - void draw_mask(const char *unused_filename, int shift, const char *text); -// Returns: -// 0 = no change - walk1 -// 1 = normal redraw - walk2 -// 2 = button triggered - crawl1 -static int read_uart() { - bool changed = false; - bool triggered = false; - - // cita spravu z uartu - if (serial_port.readable()) { - memset(rx_buffer, 0, sizeof(rx_buffer)); - ssize_t num = serial_port.read(rx_buffer, sizeof(rx_buffer) - 1); - if (num > 0) { - led = !led; // toogle ledky - strncpy(message, rx_buffer, sizeof(message) - 1); - message_active = true; - changed = true; - triggered = true; - } - } - - // casovac na 1s zobrazenia spravy - static Timer msg_timer; - static bool timer_started = false; - if (!timer_started) { - msg_timer.start(); - timer_started = true; - } - - // po jednu sekundu sa sprava zobrazi - if (message_active && msg_timer.elapsed_time() > MESSAGE_DISPLAY_DURATION) { - message_active = false; - memset(message, 0, sizeof(message)); - msg_timer.reset(); - changed = true; - } - - if (triggered) - return 2; // LED toggled press - if (changed) - return 1; - return 0; -} - -static bool update_animation(Timer &anim_timer, int &shift, int speed) { - if (anim_timer.elapsed_time() >= ANIMATION_TICK) { - // speed determines scroll steps per tick - shift += speed; - anim_timer.reset(); - return true; - } - return false; -} - void render_loop(int speed) { WalkingState player_state; - - Timer anim_timer; - anim_timer.start(); - int shift = 0; + AnimationController animation; + UartReader uart(serial_port, led); CharacterPosition pos = {PLAYER_X, PLAYER_Y}; @@ -93,13 +31,13 @@ void render_loop(int speed) { while (true) { need_redraw = false; - int uart_state = read_uart(); // returns 0/1/2 + UartEvent uart_event = uart.poll(); - if (uart_state == 1) { + if (uart_event == UartEvent::MessageUpdate) { need_redraw = true; } - if (uart_state == 2) { + if (uart_event == UartEvent::Triggered) { // start crawl frame for x time player_state.start_crawl(); need_redraw = true; @@ -108,12 +46,12 @@ void render_loop(int speed) { // Check if crawl duration expired player_state.update(); - if (update_animation(anim_timer, shift, speed)) { + if (animation.tick(speed)) { need_redraw = true; } if (need_redraw) { - draw_mask(bg_file, shift, message_active ? message : nullptr); + draw_mask(bg_file, animation.get_shift(), uart.get_message()); CharacterFrame player_frame = player_state.get_character_frame(); CharacterPosition draw_pos = get_aligned_frame_position(pos, player_frame);