// Entry point for the desktop emulator #include "low_level_display_sfml.h" #include "../display/low_level_render.h" #include "../display/low_level_gui.h" #include "game_launcher.h" #include "../games/demo_game.h" #include "../games/tic_tac_toe.h" #include "../games/monopoly/monopoly_game.h" #include "input_manager.h" #include #include #include #include #include constexpr int WIDTH = 400; constexpr int HEIGHT = 300; int main() { // Allocate 1-bit framebuffer (rounded up) size_t buffer_size = (WIDTH * HEIGHT + 7) / 8; std::vector framebuffer(buffer_size, 0); // Set up display, renderer, and GUI LowLevelDisplaySFML display(WIDTH, HEIGHT); if (!display.init()) { std::cerr << "Failed to initialize SFML display" << std::endl; return 1; } LowLevelRenderer renderer(framebuffer.data(), WIDTH, HEIGHT); LowLevelGUI gui(&renderer, font_5x5_obj); InputManager input_manager; // Emulator stub // Create GameLauncher GameLauncher launcher(WIDTH, HEIGHT, &renderer, &gui, &input_manager); launcher.register_game("Tic-Tac-Toe", "Classic 2-player game", [](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g, InputManager* im) -> Game* { return new TicTacToeGame(w, h, r, g, im); }); launcher.register_game("Monopoly", "Classic property trading game", [](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g, InputManager* im) -> Game* { return new MonopolyGame(w, h, r, g, im); }); launcher.register_game("Demo Game", "Simple test game", [](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g, InputManager* im) -> Game* { return new DemoGame(w, h, r, g, im); }); Game* current_game = nullptr; bool running = true; bool needs_redraw = true; while (display.isOpen() && running) { // Handle SFML events and translate to InputEvent InputEvent event = {INPUT_NONE, 0, 0, 0, 0, 0, false}; sf::Event sfEvent; while (display.pollEvent(sfEvent)) { if (sfEvent.type == sf::Event::Closed) { display.close(); running = false; } else if (sfEvent.type == sf::Event::MouseButtonPressed) { event.type = INPUT_TOUCH_DOWN; event.x = sfEvent.mouseButton.x; event.y = sfEvent.mouseButton.y; event.valid = true; // Check for virtual buttons InputType virtual_type; if (input_manager.check_virtual_buttons(event.x, event.y, virtual_type)) { event.type = virtual_type; } } else if (sfEvent.type == sf::Event::KeyPressed) { if (sfEvent.key.code == sf::Keyboard::Space) { event.type = INPUT_BUTTON_0; event.valid = true; } else if (sfEvent.key.code == sf::Keyboard::Enter) { event.type = INPUT_BUTTON_1; event.valid = true; } else if (sfEvent.key.code == sf::Keyboard::Escape) { // Simulate long-press exit if (launcher.is_game_selected()) { launcher.reset(); needs_redraw = true; } } } } if (event.valid) { if (launcher.is_game_selected()) { current_game = launcher.get_selected_game(); needs_redraw = current_game->update(event) || needs_redraw; if (current_game->wants_to_exit()) { launcher.reset(); needs_redraw = true; } } else { bool game_selected = launcher.update(event); if (game_selected) { needs_redraw = true; } } } if (needs_redraw) { renderer.clear_buffer(); if (launcher.is_game_selected()) { current_game = launcher.get_selected_game(); current_game->draw(); } else { launcher.draw(); } display.draw_buffer(framebuffer.data()); display.refresh(); needs_redraw = false; } } return 0; }