From b2526795a33fc9c9abc4eb44cbd72778e969d813 Mon Sep 17 00:00:00 2001 From: skymike03 Date: Fri, 11 Jul 2025 17:28:42 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20musique=20al=C3=A9atoire,=20et=20correc?= =?UTF-8?q?tion=20bug=20D-PAD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __main__.py | 46 ++++++++++++++++++++++++++++++++-------------- config.py | 5 +++++ controls.py | 6 +++++- display.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 92 insertions(+), 16 deletions(-) diff --git a/__main__.py b/__main__.py index 6f2a4a4..e73aca8 100644 --- a/__main__.py +++ b/__main__.py @@ -8,7 +8,8 @@ import logging import requests import sys import json -from display import init_display, draw_loading_screen, draw_error_screen, draw_platform_grid, draw_progress_screen, draw_controls, draw_gradient, draw_virtual_keyboard, draw_popup_result_download, draw_extension_warning, draw_pause_menu, draw_controls_help, draw_game_list, draw_history_list, draw_clear_history_dialog, draw_confirm_dialog, draw_redownload_game_cache_dialog, draw_popup, THEME_COLORS +import random +from display import init_display, draw_loading_screen, draw_error_screen, draw_platform_grid, draw_progress_screen, draw_controls, draw_gradient, draw_virtual_keyboard, draw_popup_result_download, draw_extension_warning, draw_pause_menu, draw_controls_help, draw_game_list, draw_history_list, draw_clear_history_dialog, draw_confirm_dialog, draw_redownload_game_cache_dialog, draw_popup, THEME_COLORS, set_music_popup, draw_music_popup from network import test_internet, download_rom, check_extension_before_download, extract_zip from controls import handle_controls, validate_menu_state from controls_mapper import load_controls_config, map_controls, draw_controls_mapping, ACTIONS @@ -124,23 +125,36 @@ if pygame.joystick.get_count() > 0: joystick.init() logger.debug("Gamepad initialisé") -# Initialisation du mixer Pygame -pygame.mixer.pre_init(44100, -16, 2, 4096) +# Initialisation de pygame.mixer pygame.mixer.init() # Dossier musique Batocera music_folder = "/userdata/roms/ports/RGSX/assets/music" music_files = [f for f in os.listdir(music_folder) if f.lower().endswith(('.ogg', '.mp3'))] -if music_files: - import random - music_file = random.choice(music_files) - music_path = os.path.join(music_folder, music_file) - logger.debug(f"Lecture de la musique : {music_path}") - pygame.mixer.music.load(music_path) - pygame.mixer.music.set_volume(0.5) - pygame.mixer.music.play(-1) -else: - logger.debug("Aucune musique trouvée dans /userdata/roms/ports/RGSX/assets/music") +current_music = None # Suivre la musique en cours + +def play_random_music(): + """Joue une musique aléatoire et configure l'événement de fin.""" + global current_music + if music_files: + # Éviter de rejouer la même musique consécutivement + available_music = [f for f in music_files if f != current_music] + if not available_music: # Si une seule musique, on la reprend + available_music = music_files + music_file = random.choice(available_music) + music_path = os.path.join(music_folder, music_file) + logger.debug(f"Lecture de la musique : {music_path}") + pygame.mixer.music.load(music_path) + pygame.mixer.music.set_volume(0.5) + pygame.mixer.music.play(loops=0) # Jouer une seule fois + pygame.mixer.music.set_endevent(pygame.USEREVENT + 1) # Événement de fin + current_music = music_file # Mettre à jour la musique en cours + set_music_popup(music_file) # Afficher le nom de la musique dans la popup + else: + logger.debug("Aucune musique trouvée dans /userdata/roms/ports/RGSX/assets/music") + +# Jouer la première musique au démarrage +play_random_music() # Fonction pour charger sources.json def load_sources(): @@ -302,7 +316,9 @@ async def main(): config.needs_redraw = True logger.debug("Événement QUIT détecté, passage à confirm_exit") continue - + elif event.type == pygame.USEREVENT + 1: # Fin de la musique + logger.debug("Fin de la musique actuelle, passage à la suivante") + play_random_music() start_config = config.controls_config.get("start", {}) if start_config and ( (event.type == pygame.KEYDOWN and start_config.get("type") == "key" and event.key == start_config.get("value")) or @@ -496,6 +512,8 @@ async def main(): config.needs_redraw = True logger.error(f"État de menu non valide détecté: {config.menu_state}, retour à platform") draw_controls(screen, config.menu_state) + screen = pygame.display.get_surface() + draw_music_popup(screen) # Ajouter l'appel à la popup pygame.display.flip() config.needs_redraw = False diff --git a/config.py b/config.py index 8a8c304..0cd6858 100644 --- a/config.py +++ b/config.py @@ -60,6 +60,11 @@ popup_message = "" # Message à afficher dans les popups popup_timer = 0 # Temps restant pour le popup en millisecondes (0 = inactif) last_frame_time = pygame.time.get_ticks() +# Variables globales pour la popup de musique +current_music_name = None +music_popup_start_time = None +MUSIC_POPUP_DURATION = 5 # Durée d'affichage en secondes + GRID_COLS = 3 # Number of columns in the platform grid GRID_ROWS = 4 # Number of rows in the platform grid diff --git a/controls.py b/controls.py index ed5729e..5a6abd8 100644 --- a/controls.py +++ b/controls.py @@ -96,6 +96,10 @@ def is_input_matched(event, action_name): input_type = mapping["type"] input_value = mapping["value"] + # Convertir input_value en tuple si c'est une liste (pour JOYHATMOTION) + if input_type == "hat" and isinstance(input_value, list): + input_value = tuple(input_value) + if input_type == "key" and event.type == pygame.KEYDOWN: return event.key == input_value elif input_type == "button" and event.type == pygame.JOYBUTTONDOWN: @@ -477,7 +481,7 @@ def handle_controls(event, sources, joystick, screen): config.previous_menu_state = config.menu_state # Ajouter cette ligne config.menu_state = "error" config.error_message = ( - "Attention il faut renseigner sa clé API (premium only) dans le fichier /userdata/saves/ports/rgsx/1fichier.api à ouvrir dans un editeur de texte et coller la clé API" + "Attention il faut renseigner sa clé API (premium only) dans le fichier /userdata/saves/ports/rgsx/1fichierAPI.txt à ouvrir dans un editeur de texte et coller la clé API" ) config.needs_redraw = True logger.error("Clé API 1fichier absente, téléchargement impossible.") diff --git a/display.py b/display.py index 318839d..5deba1e 100644 --- a/display.py +++ b/display.py @@ -1,5 +1,6 @@ import pygame # type: ignore import config +import os from utils import truncate_text_middle, wrap_text, load_system_image import logging import math @@ -1040,4 +1041,52 @@ def draw_popup(screen): countdown_text = f"Ce message se fermera dans {remaining_time} seconde{'s' if remaining_time != 1 else ''}" countdown_surface = config.small_font.render(countdown_text, True, THEME_COLORS["text"]) countdown_rect = countdown_surface.get_rect(center=(config.screen_width // 2, popup_y + margin_top_bottom + len(text_lines) * line_height + line_height // 2)) - screen.blit(countdown_surface, countdown_rect) \ No newline at end of file + screen.blit(countdown_surface, countdown_rect) + + +# Variables globales pour la popup de musique +current_music_name = None +music_popup_start_time = None +MUSIC_POPUP_DURATION = 5 # Durée d'affichage en secondes + +def draw_music_popup(screen): + """Affiche une popup discrète en bas à droite avec le nom de la musique en cours.""" + global current_music_name, music_popup_start_time + + if current_music_name is None or music_popup_start_time is None: + return + + # Vérifier si la popup doit encore être affichée + current_time = pygame.time.get_ticks() / 1000 # Temps en secondes + if current_time - music_popup_start_time > MUSIC_POPUP_DURATION: + current_music_name = None + music_popup_start_time = None + return + + # Paramètres de la popup + font = config.small_font + text = font.render(current_music_name, True, THEME_COLORS["text"]) + text_width, text_height = font.size(current_music_name) + padding = 10 + rect_width = text_width + 2 * padding + rect_height = text_height + 2 * padding + rect_x = config.screen_width - rect_width - 22 # 20 pixels de marge à droite + rect_y = config.screen_height - rect_height - 8 # 20 pixels de marge en bas + + # Créer une surface semi-transparente + popup_surface = pygame.Surface((rect_width, rect_height), pygame.SRCALPHA) + pygame.draw.rect(popup_surface, THEME_COLORS["fond_image"] + (180,), (0, 0, rect_width, rect_height), border_radius=8) + pygame.draw.rect(popup_surface, THEME_COLORS["border"] + (200,), (0, 0, rect_width, rect_height), 1, border_radius=8) + + # Ajouter le texte + text_rect = text.get_rect(center=(rect_width // 2, rect_height // 2)) + popup_surface.blit(text, text_rect) + + # Afficher la popup + screen.blit(popup_surface, (rect_x, rect_y)) + +def set_music_popup(music_name): + """Définit le nom de la musique à afficher dans la popup.""" + global current_music_name, music_popup_start_time + current_music_name = f"♬ {os.path.splitext(music_name)[0]}" # Utilise l'emoji ♬ directement + music_popup_start_time = pygame.time.get_ticks() / 1000 # Temps actuel en secondes \ No newline at end of file