// src/render/loop.cpp #include "loop.h" #include "../assets/background_frame.h" #include "player_positioning.h" #include "background.h" #include "mbed.h" #include "player.h" #include "../game/state.h" #include "../game/animation.h" #include "../hardware/uart.h" #include "../render/player.h" #include "../timing/speed_controller.h" #include "../timing/movement_controller.h" extern BufferedSerial serial_port; extern DigitalOut led; // Constants // constexpr int PLAYER_X = 9; constexpr int PLAYER_X = 29; constexpr int PLAYER_Y = 6; void draw_mask(const char *unused_filename, int shift, const char *text); void render_loop(int speed) { WalkingState player_state; AnimationController animation; UartReader uart(serial_port); MovementController mover(PLAYER_X, VIEW_WIDTH); SpeedController timing; timing.set_ground_speed(speed); CharacterPosition pos = {PLAYER_X, PLAYER_Y}; const char *bg_file = "background_dark_inverted.txt"; bool need_redraw = false; int anim_tick_counter = 0; int tick_counter = 0; int player_speed = 6; player_state.set_state(PlayerState::Run); while (true) { tick_counter++; mover.update_position(player_speed, timing.get_ground_speed()); pos.x = mover.get_position(); need_redraw = false; UartEvent uart_event = uart.poll(); if (uart_event == UartEvent::MessageUpdate) { need_redraw = true; } if (uart_event == UartEvent::Triggered) { // start crawl frame for x time player_state.start_crawl(); need_redraw = true; } // Check if crawl duration expired player_state.update(); if (animation.tick(speed)) { anim_tick_counter++; need_redraw = true; } if (need_redraw) { player_state.toggle_walk_frame(player_speed, anim_tick_counter); draw_mask(bg_file, animation.get_shift(), uart.get_message()); FrameSelection frame = player_state.get_frame_selection(); CharacterPosition draw_pos = get_aligned_frame_position(pos, frame.movement, frame.frame_index); draw_character(draw_pos.x, draw_pos.y, frame.movement, frame.frame_index); ThisThread::sleep_for(50ms); } ThisThread::sleep_for(25ms); } }