import sys import pygame import os from .input import Input from .command import Command from .game import Game import logging import json WHITE = (255, 255, 255) BLACK = (0, 0, 0) IS_DEVELOPMENT_MODE = os.getenv("DEVELOPMENT", "") not in ["", "0"] ROTATION_ENABLED = not IS_DEVELOPMENT_MODE OPTIONS = Game.all() + ["Quit"] logger = logging.getLogger(__name__) WIDTH = HEIGHT = FONT = screen = selected_index = None ORIGINAL_WIDTH = ORIGINAL_HEIGHT = None rotated_surface = None rotation_angle = 0 def init_display(): global WIDTH, HEIGHT, FONT, screen, selected_index, ORIGINAL_WIDTH, ORIGINAL_HEIGHT ORIGINAL_WIDTH = pygame.display.Info().current_w // 2 ORIGINAL_HEIGHT = pygame.display.Info().current_h // 2 WIDTH, HEIGHT = ORIGINAL_WIDTH, ORIGINAL_HEIGHT FONT = pygame.font.Font(None, 36) screen = pygame.display.set_mode( (WIDTH, HEIGHT) if IS_DEVELOPMENT_MODE else (0, 0), pygame.RESIZABLE if IS_DEVELOPMENT_MODE else pygame.FULLSCREEN, ) selected_index = 0 def draw_menu(is_joint_mode=False): global rotated_surface base_surface = pygame.Surface((WIDTH, HEIGHT)) base_surface.fill(WHITE) is_vertical = is_joint_mode start_y = 100 if is_vertical else 150 spacing = 40 if is_vertical else 50 title_text = FONT.render("SplitScreen Duo", True, BLACK) base_surface.blit(title_text, (WIDTH // 2 - title_text.get_width() // 2, start_y - 50)) for i, option in enumerate(OPTIONS): text = FONT.render(option, True, BLACK if i != selected_index else (200, 0, 0)) base_surface.blit(text, (WIDTH // 2 - text.get_width() // 2, start_y + i * spacing)) if ROTATION_ENABLED and not is_joint_mode and rotation_angle != 0: rotated_surface = pygame.transform.rotate(base_surface, rotation_angle) pos_x = (WIDTH - rotated_surface.get_width()) // 2 pos_y = (HEIGHT - rotated_surface.get_height()) // 2 screen.fill(WHITE) screen.blit(rotated_surface, (pos_x, pos_y)) else: screen.blit(base_surface, (0, 0)) pygame.display.flip() def set_screen_orientation(is_joint_mode): global WIDTH, HEIGHT, screen, ORIGINAL_WIDTH, ORIGINAL_HEIGHT, rotation_angle instance = os.getenv("INSTANCE", "Unknown") rotation_angle = 0 # Reset rotation angle if is_joint_mode: WIDTH = ORIGINAL_WIDTH HEIGHT = ORIGINAL_HEIGHT * 2 else: if ROTATION_ENABLED and not is_joint_mode: if instance == "primary": rotation_angle = 90 # Primary: Right is down elif instance == "secondary": rotation_angle = -90 # Secondary: Left is down WIDTH = ORIGINAL_WIDTH HEIGHT = ORIGINAL_HEIGHT screen = pygame.display.set_mode( (WIDTH, HEIGHT) if IS_DEVELOPMENT_MODE else (0, 0), pygame.RESIZABLE if IS_DEVELOPMENT_MODE else pygame.FULLSCREEN, ) logger.info(f"screen orientation changed: is_joint={is_joint_mode}, rotation={rotation_angle}, instance={instance}") def process_events(serial, instance, is_joint_mode): global selected_index input_handler = Input(debug=IS_DEVELOPMENT_MODE) is_joint_mode_value = is_joint_mode[0] if isinstance(is_joint_mode, list) else is_joint_mode for event in pygame.event.get(): if event.type == pygame.QUIT: return {"command": Command.QUIT.value, "action": None, "value": None} action = input_handler.get_input(event, rotation_angle, is_joint_mode_value) if action == "UP": selected_index = (selected_index - 1) % len(OPTIONS) elif action == "DOWN": selected_index = (selected_index + 1) % len(OPTIONS) elif action == "SELECT": if OPTIONS[selected_index] == "Quit": if instance == "primary": return { "command": Command.QUIT.value, "action": None, "value": None, } else: pygame.quit() sys.exit() else: return { "command": Command.SELECT_GAME.value, "action": None, "value": OPTIONS[selected_index], } elif action == "QUIT": return {"command": Command.QUIT.value, "action": None, "value": None} if ( event.type == pygame.KEYDOWN and event.key == pygame.K_b and instance == "primary" ): is_joint_mode[0] = not is_joint_mode[0] if instance == "primary": set_screen_orientation(is_joint_mode[0]) logger.info(f"toggled joint mode to {is_joint_mode[0]}") command = ( Command.ENTER_JOINT_MODE.value if is_joint_mode[0] else Command.EXIT_JOINT_MODE.value ) serial.write(json.dumps({"command": command}).encode("utf-8")) draw_menu(is_joint_mode[0] if isinstance(is_joint_mode, list) else is_joint_mode) return None