forked from Mirrors/RGSX
537 lines
32 KiB
Python
537 lines
32 KiB
Python
import pygame
|
|
import config
|
|
from config import CONTROLS_CONFIG_PATH
|
|
import asyncio
|
|
import math
|
|
from display import draw_validation_transition
|
|
from network import download_rom, check_extension_before_download
|
|
from controls_mapper import get_readable_input_name
|
|
from utils import load_games # Ajout de l'import
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Constantes pour la répétition automatique
|
|
REPEAT_DELAY = 300 # Délai initial avant répétition (ms)
|
|
REPEAT_INTERVAL = 100 # Intervalle entre répétitions (ms)
|
|
JOYHAT_DEBOUNCE = 200 # Délai anti-rebond pour JOYHATMOTION (ms)
|
|
JOYAXIS_DEBOUNCE = 50 # Délai anti-rebond pour JOYAXISMOTION (ms)
|
|
REPEAT_ACTION_DEBOUNCE = 50 # Délai anti-rebond pour répétitions up/down/left/right (ms)
|
|
|
|
def load_controls_config(path=CONTROLS_CONFIG_PATH):
|
|
"""Charge la configuration des contrôles depuis un fichier JSON."""
|
|
try:
|
|
with open(path, "r") as f:
|
|
return json.load(f)
|
|
except (FileNotFoundError, json.JSONDecodeError) as e:
|
|
logging.error(f"Erreur lors de la lecture de {path} : {e}")
|
|
return {}
|
|
|
|
def is_input_matched(event, action_name):
|
|
"""Vérifie si l'événement correspond à l'action configurée."""
|
|
if not config.controls_config.get(action_name):
|
|
return False
|
|
mapping = config.controls_config[action_name]
|
|
input_type = mapping["type"]
|
|
input_value = mapping["value"]
|
|
|
|
event_type = event["type"] if isinstance(event, dict) else event.type
|
|
event_key = event.get("key") if isinstance(event, dict) else getattr(event, "key", None)
|
|
event_button = event.get("button") if isinstance(event, dict) else getattr(event, "button", None)
|
|
event_axis = event.get("axis") if isinstance(event, dict) else getattr(event, "axis", None)
|
|
event_value = event.get("value") if isinstance(event, dict) else getattr(event, "value", None)
|
|
|
|
if input_type == "key" and event_type in (pygame.KEYDOWN, pygame.KEYUP):
|
|
logger.debug(f"Vérification key: event_key={event_key}, input_value={input_value}")
|
|
return event_key == input_value
|
|
elif input_type == "button" and event_type in (pygame.JOYBUTTONDOWN, pygame.JOYBUTTONUP):
|
|
logger.debug(f"Vérification button: event_button={event_button}, input_value={input_value}")
|
|
return event_button == input_value
|
|
elif input_type == "axis" and event_type == pygame.JOYAXISMOTION:
|
|
axis, direction = input_value
|
|
result = event_axis == axis and abs(event_value) > 0.5 and (1 if event_value > 0 else -1) == direction
|
|
logger.debug(f"Vérification axis: event_axis={event_axis}, event_value={event_value}, input_value={input_value}, result={result}")
|
|
return result
|
|
elif input_type == "hat" and event_type == pygame.JOYHATMOTION:
|
|
# Convertir input_value en tuple pour comparaison
|
|
input_value_tuple = tuple(input_value) if isinstance(input_value, list) else input_value
|
|
logger.debug(f"Vérification hat: event_value={event_value}, input_value={input_value_tuple}")
|
|
return event_value == input_value_tuple
|
|
elif input_type == "mouse" and event_type == pygame.MOUSEBUTTONDOWN:
|
|
logger.debug(f"Vérification mouse: event_button={event_button}, input_value={input_value}")
|
|
return event_button == input_value
|
|
return False
|
|
|
|
def handle_controls(event, sources, joystick, screen):
|
|
"""Gère un événement clavier/joystick/souris et la répétition automatique.
|
|
Retourne 'quit', 'download', ou None.
|
|
"""
|
|
action = None
|
|
current_time = pygame.time.get_ticks()
|
|
|
|
# Debounce général
|
|
if current_time - config.last_state_change_time < config.debounce_delay:
|
|
return action
|
|
|
|
# Log des événements reçus
|
|
logger.debug(f"Événement reçu: type={event.type}, value={getattr(event, 'value', None)}")
|
|
|
|
# --- CLAVIER, MANETTE, SOURIS ---
|
|
if event.type in (pygame.KEYDOWN, pygame.JOYBUTTONDOWN, pygame.JOYAXISMOTION, pygame.JOYHATMOTION, pygame.MOUSEBUTTONDOWN):
|
|
# Débouncer les événements JOYHATMOTION
|
|
if event.type == pygame.JOYHATMOTION:
|
|
logger.debug(f"JOYHATMOTION détecté: hat={event.hat}, value={event.value}")
|
|
if event.value == (0, 0): # Ignorer les relâchements
|
|
return action
|
|
if current_time - config.repeat_last_action < JOYHAT_DEBOUNCE:
|
|
return action
|
|
|
|
# Débouncer les événements JOYAXISMOTION
|
|
if event.type == pygame.JOYAXISMOTION and current_time - config.repeat_last_action < JOYAXIS_DEBOUNCE:
|
|
return action
|
|
|
|
# Quitter l'appli
|
|
if event.type == pygame.QUIT:
|
|
logger.debug("Événement pygame.QUIT détecté")
|
|
return "quit"
|
|
|
|
# Vérification des actions mappées
|
|
for action_name in ["up", "down", "left", "right"]:
|
|
if is_input_matched(event, action_name):
|
|
logger.debug(f"Action mappée détectée: {action_name}, input={get_readable_input_name(event)}")
|
|
|
|
# Erreur
|
|
if config.menu_state == "error":
|
|
if is_input_matched(event, "confirm"):
|
|
config.menu_state = "loading"
|
|
logger.debug("Sortie erreur avec Confirm")
|
|
elif is_input_matched(event, "cancel"):
|
|
config.menu_state = "confirm_exit"
|
|
config.confirm_selection = 0
|
|
|
|
# Plateformes
|
|
elif config.menu_state == "platform":
|
|
max_index = min(9, len(config.platforms) - config.current_page * 9) - 1
|
|
current_grid_index = config.selected_platform - config.current_page * 9
|
|
row = current_grid_index // 3
|
|
if is_input_matched(event, "down"):
|
|
if current_grid_index + 3 <= max_index:
|
|
config.selected_platform += 3
|
|
config.repeat_action = "down"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "up"):
|
|
if current_grid_index - 3 >= 0:
|
|
config.selected_platform -= 3
|
|
config.repeat_action = "up"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "left"):
|
|
if current_grid_index % 3 != 0:
|
|
config.selected_platform -= 1
|
|
config.repeat_action = "left"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif config.current_page > 0:
|
|
config.current_page -= 1
|
|
config.selected_platform = config.current_page * 9 + row * 3 + 2
|
|
if config.selected_platform >= len(config.platforms):
|
|
config.selected_platform = len(config.platforms) - 1
|
|
config.repeat_action = "left"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "right"):
|
|
if current_grid_index % 3 != 2 and current_grid_index < max_index:
|
|
config.selected_platform += 1
|
|
config.repeat_action = "right"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif (config.current_page + 1) * 9 < len(config.platforms):
|
|
config.current_page += 1
|
|
config.selected_platform = config.current_page * 9 + row * 3
|
|
if config.selected_platform >= len(config.platforms):
|
|
config.selected_platform = len(config.platforms) - 1
|
|
config.repeat_action = "right"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "page_down"):
|
|
if (config.current_page + 1) * 9 < len(config.platforms):
|
|
config.current_page += 1
|
|
config.selected_platform = config.current_page * 9 + row * 3
|
|
if config.selected_platform >= len(config.platforms):
|
|
config.selected_platform = len(config.platforms) - 1
|
|
config.repeat_action = None # Réinitialiser la répétition
|
|
config.repeat_key = None
|
|
config.repeat_start_time = 0
|
|
config.repeat_last_action = current_time
|
|
config.needs_redraw = True
|
|
logger.debug("Page suivante, répétition réinitialisée")
|
|
elif is_input_matched(event, "progress"):
|
|
if config.download_tasks:
|
|
config.menu_state = "download_progress"
|
|
config.needs_redraw = True
|
|
logger.debug("Retour à download_progress depuis platform")
|
|
elif is_input_matched(event, "confirm"):
|
|
if config.platforms:
|
|
config.current_platform = config.selected_platform
|
|
config.games = load_games(config.platforms[config.current_platform]) # Appel à load_games depuis utils
|
|
config.filtered_games = config.games
|
|
config.filter_active = False
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
draw_validation_transition(screen, config.current_platform) # Animation de transition
|
|
config.menu_state = "game"
|
|
config.needs_redraw = True
|
|
logger.debug(f"Plateforme sélectionnée: {config.platforms[config.current_platform]}, {len(config.games)} jeux chargés")
|
|
elif is_input_matched(event, "cancel"):
|
|
config.menu_state = "confirm_exit"
|
|
config.confirm_selection = 0
|
|
|
|
# Jeux
|
|
elif config.menu_state == "game":
|
|
if config.search_mode:
|
|
if config.is_non_pc:
|
|
keyboard_layout = [
|
|
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
|
['A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
|
|
['Q', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M'],
|
|
['W', 'X', 'C', 'V', 'B', 'N']
|
|
]
|
|
row, col = config.selected_key
|
|
max_row = len(keyboard_layout) - 1
|
|
max_col = len(keyboard_layout[row]) - 1
|
|
if is_input_matched(event, "up"):
|
|
if row > 0:
|
|
config.selected_key = (row - 1, min(col, len(keyboard_layout[row - 1]) - 1))
|
|
config.repeat_action = "up"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "down"):
|
|
if row < max_row:
|
|
config.selected_key = (row + 1, min(col, len(keyboard_layout[row + 1]) - 1))
|
|
config.repeat_action = "down"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "left"):
|
|
if col > 0:
|
|
config.selected_key = (row, col - 1)
|
|
config.repeat_action = "left"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "right"):
|
|
if col < max_col:
|
|
config.selected_key = (row, col + 1)
|
|
config.repeat_action = "right"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "confirm"):
|
|
key = keyboard_layout[row][col]
|
|
if len(config.search_query) < 50:
|
|
config.search_query += key.lower()
|
|
config.filtered_games = [game for game in config.games if config.search_query.lower() in game[0].lower()] if config.search_query else config.games
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "delete"):
|
|
config.search_query = config.search_query[:-1]
|
|
config.filtered_games = [game for game in config.games if config.search_query.lower() in game[0].lower()] if config.search_query else config.games
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "space"):
|
|
config.search_query += " "
|
|
config.filtered_games = [game for game in config.games if config.search_query.lower() in game[0].lower()] if config.search_query else config.games
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "cancel"):
|
|
config.search_mode = False
|
|
config.search_query = ""
|
|
config.filtered_games = config.games
|
|
config.filter_active = False
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
config.needs_redraw = True
|
|
logger.debug("Filtre annulé")
|
|
elif is_input_matched(event, "filter"):
|
|
config.search_mode = False
|
|
config.filter_active = bool(config.search_query)
|
|
config.needs_redraw = True
|
|
else:
|
|
if is_input_matched(event, "confirm"):
|
|
config.search_mode = False
|
|
config.filter_active = bool(config.search_query)
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "cancel"):
|
|
config.search_mode = False
|
|
config.search_query = ""
|
|
config.filtered_games = config.games
|
|
config.filter_active = False
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
config.needs_redraw = True
|
|
logger.debug("Filtre annulé")
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key == pygame.K_BACKSPACE:
|
|
config.search_query = config.search_query[:-1]
|
|
config.filtered_games = [game for game in config.games if config.search_query.lower() in game[0].lower()] if config.search_query else config.games
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
config.needs_redraw = True
|
|
elif event.key == pygame.K_SPACE:
|
|
config.search_query += " "
|
|
config.filtered_games = [game for game in config.games if config.search_query.lower() in game[0].lower()] if config.search_query else config.games
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
config.needs_redraw = True
|
|
elif event.unicode.isprintable() and len(config.search_query) < 50:
|
|
config.search_query += event.unicode
|
|
config.filtered_games = [game for game in config.games if config.search_query.lower() in game[0].lower()] if config.search_query else config.games
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
config.needs_redraw = True
|
|
else:
|
|
if is_input_matched(event, "down"):
|
|
config.current_game = min(config.current_game + 1, len(config.filtered_games) - 1)
|
|
if config.current_game >= config.scroll_offset + config.visible_games:
|
|
config.scroll_offset += 1
|
|
config.repeat_action = "down"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "up"):
|
|
config.current_game = max(config.current_game - 1, 0)
|
|
if config.current_game < config.scroll_offset:
|
|
config.scroll_offset -= 1
|
|
config.repeat_action = "up"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "page_up"):
|
|
config.current_game = max(config.current_game - config.visible_games, 0)
|
|
config.scroll_offset = max(config.scroll_offset - config.visible_games, 0)
|
|
config.repeat_action = "page_up"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "page_down"):
|
|
config.current_game = min(config.current_game + config.visible_games, len(config.filtered_games) - 1)
|
|
config.scroll_offset = min(config.scroll_offset + config.visible_games, len(config.filtered_games) - config.visible_games)
|
|
config.repeat_action = "page_down"
|
|
config.repeat_start_time = current_time + REPEAT_DELAY
|
|
config.repeat_last_action = current_time
|
|
config.repeat_key = event.key if event.type == pygame.KEYDOWN else event.button if event.type == pygame.JOYBUTTONDOWN else (event.axis, 1 if event.value > 0 else -1) if event.type == pygame.JOYAXISMOTION else event.value
|
|
config.needs_redraw = True
|
|
elif is_input_matched(event, "confirm"):
|
|
if config.filtered_games:
|
|
action = "download"
|
|
elif is_input_matched(event, "filter"):
|
|
config.search_mode = True
|
|
config.search_query = ""
|
|
config.filtered_games = config.games
|
|
config.selected_key = (0, 0)
|
|
config.needs_redraw = True
|
|
logger.debug("Entrée en mode recherche")
|
|
elif is_input_matched(event, "cancel"):
|
|
config.menu_state = "platform"
|
|
config.current_game = 0
|
|
config.scroll_offset = 0
|
|
config.filter_active = False
|
|
config.filtered_games = config.games
|
|
config.needs_redraw = True
|
|
logger.debug("Retour à platform, filtre réinitialisé")
|
|
elif is_input_matched(event, "progress"):
|
|
if config.download_tasks:
|
|
config.menu_state = "download_progress"
|
|
config.needs_redraw = True
|
|
logger.debug("Retour à download_progress depuis game")
|
|
|
|
# Download progress
|
|
elif config.menu_state == "download_progress":
|
|
if is_input_matched(event, "cancel"):
|
|
if config.download_tasks:
|
|
task = list(config.download_tasks.keys())[0]
|
|
config.download_tasks[task][0].cancel()
|
|
url = config.download_tasks[task][1]
|
|
game_name = config.download_tasks[task][2]
|
|
if url in config.download_progress:
|
|
del config.download_progress[url]
|
|
del config.download_tasks[task]
|
|
config.download_result_message = f"Téléchargement annulé : {game_name}"
|
|
config.download_result_error = True
|
|
config.download_result_start_time = pygame.time.get_ticks()
|
|
config.menu_state = "download_result"
|
|
elif is_input_matched(event, "progress"):
|
|
config.menu_state = "game"
|
|
config.needs_redraw = True
|
|
logger.debug("Retour à game depuis download_progress")
|
|
|
|
# Confirmation de sortie
|
|
elif config.menu_state == "confirm_exit":
|
|
if is_input_matched(event, "left"):
|
|
config.confirm_selection = 1
|
|
config.needs_redraw = True
|
|
logger.debug("Sélection Oui")
|
|
elif is_input_matched(event, "right"):
|
|
config.confirm_selection = 0
|
|
config.needs_redraw = True
|
|
logger.debug("Sélection Non")
|
|
elif is_input_matched(event, "confirm"):
|
|
if config.confirm_selection == 1:
|
|
logger.debug("Retour de 'quit' pour fermer l'application")
|
|
return "quit"
|
|
else:
|
|
config.menu_state = "platform"
|
|
config.needs_redraw = True
|
|
logger.debug("Retour à platform depuis confirm_exit")
|
|
elif is_input_matched(event, "cancel"):
|
|
config.menu_state = "platform"
|
|
config.needs_redraw = True
|
|
logger.debug("Annulation confirm_exit")
|
|
|
|
# Avertissement d'extension
|
|
elif config.menu_state == "extension_warning":
|
|
if is_input_matched(event, "left"):
|
|
config.extension_confirm_selection = 1
|
|
config.needs_redraw = True
|
|
logger.debug("Sélection Oui (extension_warning)")
|
|
elif is_input_matched(event, "right"):
|
|
config.extension_confirm_selection = 0
|
|
config.needs_redraw = True
|
|
logger.debug("Sélection Non (extension_warning)")
|
|
elif is_input_matched(event, "confirm"):
|
|
if config.extension_confirm_selection == 1:
|
|
if config.pending_download:
|
|
url, platform, game_name, is_zip_non_supported = config.pending_download
|
|
task = asyncio.create_task(download_rom(url, platform, game_name, is_zip_non_supported=is_zip_non_supported))
|
|
config.download_tasks[task] = (task, url, game_name, platform)
|
|
config.menu_state = "download_progress"
|
|
config.pending_download = None
|
|
config.needs_redraw = True
|
|
else:
|
|
config.menu_state = "game"
|
|
config.needs_redraw = True
|
|
else:
|
|
config.menu_state = "game"
|
|
config.pending_download = None
|
|
config.needs_redraw = True
|
|
logger.debug("Téléchargement annulé (extension_warning)")
|
|
elif is_input_matched(event, "cancel"):
|
|
config.menu_state = "game"
|
|
config.pending_download = None
|
|
config.needs_redraw = True
|
|
logger.debug("Annulation extension_warning")
|
|
|
|
# Résultat téléchargement
|
|
elif config.menu_state == "download_result":
|
|
if is_input_matched(event, "confirm"):
|
|
config.menu_state = "game"
|
|
config.needs_redraw = True
|
|
logger.debug("Retour à game depuis download_result")
|
|
|
|
# Enregistrer la touche pour la répétition
|
|
if config.repeat_action in ["up", "down", "page_up", "page_down", "left", "right"]:
|
|
if event.type == pygame.KEYDOWN:
|
|
config.repeat_key = event.key
|
|
elif event.type == pygame.JOYBUTTONDOWN:
|
|
config.repeat_key = event.button
|
|
elif event.type == pygame.JOYAXISMOTION:
|
|
config.repeat_key = (event.axis, 1 if event.value > 0 else -1)
|
|
elif event.type == pygame.JOYHATMOTION:
|
|
config.repeat_key = event.value
|
|
config.repeat_last_action = current_time
|
|
|
|
elif event.type in (pygame.KEYUP, pygame.JOYBUTTONUP):
|
|
if config.menu_state in ("game", "platform") and is_input_matched(event, config.repeat_action):
|
|
config.repeat_action = None
|
|
config.repeat_key = None
|
|
config.repeat_start_time = 0
|
|
config.needs_redraw = True
|
|
|
|
# Gestion de la répétition automatique
|
|
if config.menu_state in ("game", "platform") and config.repeat_action:
|
|
if current_time >= config.repeat_start_time:
|
|
if config.repeat_action in ["up", "down", "left", "right"] and current_time - config.repeat_last_action < REPEAT_ACTION_DEBOUNCE:
|
|
return action
|
|
|
|
last_repeat_time = config.repeat_start_time - REPEAT_INTERVAL
|
|
config.repeat_last_action = current_time
|
|
if config.menu_state == "game":
|
|
if config.repeat_action == "down":
|
|
config.current_game = min(config.current_game + 1, len(config.filtered_games) - 1)
|
|
if config.current_game >= config.scroll_offset + config.visible_games:
|
|
config.scroll_offset += 1
|
|
config.needs_redraw = True
|
|
elif config.repeat_action == "up":
|
|
config.current_game = max(config.current_game - 1, 0)
|
|
if config.current_game < config.scroll_offset:
|
|
config.scroll_offset -= 1
|
|
config.needs_redraw = True
|
|
elif config.repeat_action == "page_down":
|
|
config.current_game = min(config.current_game + config.visible_games, len(config.filtered_games) - 1)
|
|
config.scroll_offset = min(config.scroll_offset + config.visible_games, len(config.filtered_games) - config.visible_games)
|
|
config.needs_redraw = True
|
|
elif config.repeat_action == "page_up":
|
|
config.current_game = max(config.current_game - config.visible_games, 0)
|
|
config.scroll_offset = max(config.scroll_offset - config.visible_games, 0)
|
|
config.needs_redraw = True
|
|
elif config.menu_state == "platform":
|
|
max_index = min(9, len(config.platforms) - config.current_page * 9) - 1
|
|
current_grid_index = config.selected_platform - config.current_page * 9
|
|
row = current_grid_index // 3
|
|
if config.repeat_action == "down":
|
|
if current_grid_index + 3 <= max_index:
|
|
config.selected_platform += 3
|
|
config.needs_redraw = True
|
|
elif config.repeat_action == "up":
|
|
if current_grid_index - 3 >= 0:
|
|
config.selected_platform -= 3
|
|
config.needs_redraw = True
|
|
elif config.repeat_action == "left":
|
|
if current_grid_index % 3 != 0:
|
|
config.selected_platform -= 1
|
|
config.needs_redraw = True
|
|
elif config.current_page > 0:
|
|
config.current_page -= 1
|
|
config.selected_platform = config.current_page * 9 + row * 3 + 2
|
|
if config.selected_platform >= len(config.platforms):
|
|
config.selected_platform = len(config.platforms) - 1
|
|
config.needs_redraw = True
|
|
elif config.repeat_action == "right":
|
|
if current_grid_index % 3 != 2 and current_grid_index < max_index:
|
|
config.selected_platform += 1
|
|
config.needs_redraw = True
|
|
elif (config.current_page + 1) * 9 < len(config.platforms):
|
|
config.current_page += 1
|
|
config.selected_platform = config.current_page * 9 + row * 3
|
|
if config.selected_platform >= len(config.platforms):
|
|
config.selected_platform = len(config.platforms) - 1
|
|
config.needs_redraw = True
|
|
config.repeat_start_time = last_repeat_time + REPEAT_INTERVAL
|
|
if config.repeat_start_time < current_time:
|
|
config.repeat_start_time = current_time + REPEAT_INTERVAL
|
|
|
|
return action |