diff --git a/basic1.cpp b/basic1.cpp index dec24c1..67fc5ae 100644 --- a/basic1.cpp +++ b/basic1.cpp @@ -552,8 +552,21 @@ int main() uint32_t game_start_time = 0; while (1) { - // Sleep until interrupt wakes us up (very power efficient!) - __wfi(); // Wait For Interrupt - CPU sleeps until any interrupt occurs + // Determine if we should sleep or stay awake for updates + bool stay_awake = false; + if (pending_refresh) stay_awake = true; + + if (launcher.is_game_selected()) { + Game* g = launcher.get_selected_game(); + if (g && g->wants_frame_updates()) { + stay_awake = true; + } + } + + if (!stay_awake) { + // Sleep until interrupt wakes us up (very power efficient!) + __wfi(); // Wait For Interrupt - CPU sleeps until any interrupt occurs + } InputEvent input = {INPUT_NONE, 0, 0, 0, 0, 0, false}; bool needs_refresh = false; @@ -639,41 +652,45 @@ int main() } needs_refresh = true; } - } else if (launcher.is_game_selected()) { + } + + if (launcher.is_game_selected()) { // No input, but check if game wants continuous updates current_game = launcher.get_selected_game(); if (current_game->wants_frame_updates()) { - // Send frame tick event for animation/physics updates - InputEvent frame_tick = {INPUT_FRAME_TICK, 0, 0, 0, 0, 0, true}; - needs_refresh = current_game->update(frame_tick); + // Only send frame tick if we're ready to draw the next frame + if (!is_refresh_in_progress()) { + InputEvent frame_tick = {INPUT_FRAME_TICK, 0, 0, 0, 0, 0, true}; + needs_refresh = current_game->update(frame_tick) || needs_refresh; + } } } // 4. Redraw and queue async refresh on Core 1 if (needs_refresh || pending_refresh) { - // Clear buffer and redraw entire UI with updated state - memset(bit_buffer, 0, V_WIDTH * V_HEIGHT / 8); - - if (launcher.is_game_selected()) { - current_game = launcher.get_selected_game(); - current_game->draw(); - } else { - launcher.draw(); - } - - // Request async refresh (non-blocking - handled by Core 1) - bool refresh_started = refresh_screen_async(bit_buffer, display); - - if (refresh_started) { - pending_refresh = false; // Refresh queued successfully - } else { - pending_refresh = true; // Core 1 busy, retry next iteration - if (config.debug_verbose) { - printf("Refresh pending - Core 1 still busy\n"); + // Only draw if Core 1 is finished with the buffer + if (!is_refresh_in_progress()) { + // Clear buffer and redraw entire UI with updated state + memset(bit_buffer, 0, V_WIDTH * V_HEIGHT / 8); + + if (launcher.is_game_selected()) { + current_game = launcher.get_selected_game(); + current_game->draw(); + } else { + launcher.draw(); } + + // Request async refresh (non-blocking - handled by Core 1) + bool refresh_started = refresh_screen_async(bit_buffer, display); + + if (refresh_started) { + pending_refresh = false; // Refresh queued successfully + } else { + pending_refresh = true; + } + } else { + pending_refresh = true; } - - // Core 0 continues immediately, Core 1 handles the refresh } // 5. Check if display should be dimmed due to inactivity diff --git a/emulator/game_launcher.cpp b/emulator/game_launcher.cpp index f1322ac..d63ad21 100644 --- a/emulator/game_launcher.cpp +++ b/emulator/game_launcher.cpp @@ -8,7 +8,8 @@ extern Font font_5x5_obj; GameLauncher::GameLauncher(uint16_t width, uint16_t height, LowLevelRenderer* renderer, LowLevelGUI* gui, InputManager* input_manager) : width(width), height(height), renderer(renderer), gui(gui), input_manager(input_manager), selected_index(0), selected_game(nullptr) {} -void GameLauncher::register_game(const char* name, const char* description, Game* (*factory)(uint16_t, uint16_t, LowLevelRenderer*, LowLevelGUI*, InputManager*)) { +void GameLauncher::register_game(const char* name, const char* description, + std::function factory) { GameEntry entry; entry.name = name; entry.description = description; diff --git a/emulator/main.cpp b/emulator/main.cpp index c33bf69..f87e341 100644 --- a/emulator/main.cpp +++ b/emulator/main.cpp @@ -62,13 +62,13 @@ int main() { InputEvent event = {INPUT_NONE, 0, 0, 0, 0, 0, false}; while (const auto sfEvent = display.pollEvent()) { - if (const auto* closed = sfEvent->getIf()) { + if (sfEvent->is()) { display.close(); running = false; - } else if (const auto* mousePressed = sfEvent->getIf()) { + } else if (const auto* mouse = sfEvent->getIf()) { event.type = INPUT_TOUCH_DOWN; - event.x = mousePressed->position.x; - event.y = mousePressed->position.y; + event.x = mouse->position.x; + event.y = mouse->position.y; event.valid = true; // Check for virtual buttons @@ -76,14 +76,14 @@ int main() { if (input_manager.check_virtual_buttons(event.x, event.y, virtual_type)) { event.type = virtual_type; } - } else if (const auto* keyPressed = sfEvent->getIf()) { - if (keyPressed->code == sf::Keyboard::Key::Space) { + } else if (const auto* key = sfEvent->getIf()) { + if (key->code == sf::Keyboard::Key::Space) { event.type = INPUT_BUTTON_0; event.valid = true; - } else if (keyPressed->code == sf::Keyboard::Key::Enter) { + } else if (key->code == sf::Keyboard::Key::Enter) { event.type = INPUT_BUTTON_1; event.valid = true; - } else if (keyPressed->code == sf::Keyboard::Key::Escape) { + } else if (key->code == sf::Keyboard::Key::Escape) { // Simulate long-press exit if (launcher.is_game_selected()) { launcher.reset(); @@ -107,8 +107,10 @@ int main() { needs_redraw = true; } } - } else if (launcher.is_game_selected()) { - // No user input, but check if game wants frame tick updates + } + + // Check if game wants frame tick updates (independent of user input) + if (launcher.is_game_selected()) { current_game = launcher.get_selected_game(); if (current_game->wants_frame_updates()) { InputEvent frame_event = {INPUT_FRAME_TICK, 0, 0, 0, 0, 0, true}; diff --git a/games/lua_bindings.cpp b/games/lua_bindings.cpp index 3748225..538982a 100644 --- a/games/lua_bindings.cpp +++ b/games/lua_bindings.cpp @@ -236,6 +236,10 @@ static void register_input_constants(lua_State* L) { lua_pushstring(L, "GESTURE"); lua_pushinteger(L, 6); lua_settable(L, -3); + + lua_pushstring(L, "FRAME_TICK"); + lua_pushinteger(L, 7); + lua_settable(L, -3); lua_setglobal(L, "INPUT"); } diff --git a/games/lua_examples/snake.lua b/games/lua_examples/snake.lua index 2d4174d..a491c9d 100644 --- a/games/lua_examples/snake.lua +++ b/games/lua_examples/snake.lua @@ -32,6 +32,9 @@ function init() game.vars.frame_count = 0 game.vars.move_speed = 10 -- Frames between moves + -- Enable continuous frame updates + game.set_frame_updates(true) + print("Snake Game initialized") end