1
0
forked from Mirrors/RGSX

- Updated application version to 2.2.0.8.

- Refactored menu states from "redownload_game_cache" to "reload_games_data".
- Added Xbox Elite controller configuration file.
This commit is contained in:
skymike03
2025-09-11 21:05:59 +02:00
parent a24391a028
commit 9e128574be
5 changed files with 49 additions and 122 deletions

View File

@@ -24,7 +24,7 @@ from display import (
draw_extension_warning, draw_pause_menu, draw_controls_help, draw_game_list, draw_extension_warning, draw_pause_menu, draw_controls_help, draw_game_list,
draw_display_menu, draw_display_menu,
draw_history_list, draw_clear_history_dialog, draw_cancel_download_dialog, draw_history_list, draw_clear_history_dialog, draw_cancel_download_dialog,
draw_confirm_dialog, draw_redownload_game_cache_dialog, draw_popup, draw_gradient, draw_confirm_dialog, draw_reload_games_data_dialog, draw_popup, draw_gradient,
THEME_COLORS THEME_COLORS
) )
from language import _ from language import _
@@ -204,6 +204,12 @@ else:
logger.debug(f"Joysticks détectés: {joystick_names}") logger.debug(f"Joysticks détectés: {joystick_names}")
for idx, name in enumerate(joystick_names): for idx, name in enumerate(joystick_names):
lname = name.lower() lname = name.lower()
# Détection spécifique Elite AVANT la détection générique Xbox
if ("microsoft xbox controller" in lname):
config.xbox_elite_controller = True
logger.debug(f"Controller detected (Xbox Elite): {name}")
print(f"Controller detected (Xbox Elite): {name}")
break
if ("xbox" in lname) or ("x-box" in lname) or ("xinput" in lname) or ("microsoft x-box" in lname) or ("x-box 360" in lname) or ("360" in lname): if ("xbox" in lname) or ("x-box" in lname) or ("xinput" in lname) or ("microsoft x-box" in lname) or ("x-box 360" in lname) or ("360" in lname):
config.xbox_controller = True config.xbox_controller = True
logger.debug(f"Controller detected : {name}") logger.debug(f"Controller detected : {name}")
@@ -500,10 +506,10 @@ async def main():
config.needs_redraw = True config.needs_redraw = True
continue continue
if config.menu_state == "redownload_game_cache": if config.menu_state == "reload_games_data":
action = handle_controls(event, sources, joystick, screen) action = handle_controls(event, sources, joystick, screen)
config.needs_redraw = True config.needs_redraw = True
#logger.debug(f"Événement transmis à handle_controls dans redownload_game_cache: {event.type}") #logger.debug(f"Événement transmis à handle_controls dans reload_games_data: {event.type}")
continue continue
if config.menu_state == "extension_warning": if config.menu_state == "extension_warning":
@@ -666,106 +672,7 @@ async def main():
config.menu_state = "history" # Passer à l'historique config.menu_state = "history" # Passer à l'historique
config.needs_redraw = True config.needs_redraw = True
logger.debug(f"Téléchargement démarré pour {game_name}, passage à l'historique") logger.debug(f"Téléchargement démarré pour {game_name}, passage à l'historique")
elif action == "redownload" and config.menu_state == "history" and config.history:
entry = config.history[config.current_history_item]
platform_name = entry["platform"]
game_name = entry["game_name"]
for game in config.games:
if isinstance(game, (list, tuple)) and game and game[0] == game_name and config.platforms[config.current_platform] == platform_name:
url = game[1] if len(game) > 1 else None
else:
continue
if not url:
logger.debug(f"Vérification pour retéléchargement de {game_name}, URL: {url}")
if is_1fichier_url(url):
if not config.API_KEY_1FICHIER:
# Fallback AllDebrid
try:
from utils import load_api_key_alldebrid
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
except Exception:
config.API_KEY_ALLDEBRID = getattr(config, "API_KEY_ALLDEBRID", "")
if not config.API_KEY_1FICHIER and not getattr(config, "API_KEY_ALLDEBRID", ""):
config.previous_menu_state = config.menu_state
config.menu_state = "error"
try:
both_paths = f"{os.path.join(config.SAVE_FOLDER,'1FichierAPI.txt')} or {os.path.join(config.SAVE_FOLDER,'AllDebridAPI.txt')}"
config.error_message = _("error_api_key").format(both_paths)
except Exception:
config.error_message = "Please enter API key (1fichier or AllDebrid)"
config.needs_redraw = True
logger.error("Clé API 1fichier et AllDebrid absentes")
config.pending_download = None
continue
pending = check_extension_before_download(url, platform_name, game_name)
if not pending:
config.menu_state = "error"
config.error_message = _("error_invalid_download_data") if _ else "Invalid download data"
config.needs_redraw = True
logger.error(f"check_extension_before_download a échoué pour {game_name}")
else:
from utils import is_extension_supported, load_extensions_json, sanitize_filename
from rgsx_settings import get_allow_unknown_extensions
is_supported = is_extension_supported(sanitize_filename(game_name), platform_name, load_extensions_json())
zip_ok = bool(pending[3])
allow_unknown = False
try:
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.pending_download = pending
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
config.needs_redraw = True
logger.debug(f"Extension non reconnue pour lien 1fichier, passage à extension_warning pour {game_name}")
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
success, message = download_from_1fichier(url, platform_name, game_name, zip_ok)
# Ancien popup download_result supprimé : retour direct à l'historique
config.download_result_message = message
config.download_result_error = not success
config.download_progress.clear()
config.pending_download = None
config.menu_state = "history"
config.needs_redraw = True
logger.debug(f"Retéléchargement 1fichier terminé pour {game_name}, succès={success}, message={message}, retour direct history")
else:
pending = check_extension_before_download(url, platform_name, game_name)
if not pending:
config.menu_state = "error"
config.error_message = _("error_invalid_download_data") if _ else "Invalid download data"
config.needs_redraw = True
logger.error(f"check_extension_before_download a échoué pour {game_name}")
else:
from utils import is_extension_supported, load_extensions_json, sanitize_filename
from rgsx_settings import get_allow_unknown_extensions
is_supported = is_extension_supported(sanitize_filename(game_name), platform_name, load_extensions_json())
zip_ok = bool(pending[3])
allow_unknown = False
try:
allow_unknown = get_allow_unknown_extensions()
except Exception:
allow_unknown = False
if (not is_supported and not zip_ok) and not allow_unknown:
config.pending_download = pending
config.menu_state = "extension_warning"
config.extension_confirm_selection = 0
config.needs_redraw = True
logger.debug(f"Extension non reconnue pour retéléchargement, passage à extension_warning pour {game_name}")
else:
config.previous_menu_state = config.menu_state
logger.debug(f"Previous menu state défini: {config.previous_menu_state}")
success, message = download_rom(url, platform_name, game_name, zip_ok)
config.download_result_message = message
config.download_result_error = not success
config.download_progress.clear()
config.pending_download = None
config.menu_state = "history"
config.needs_redraw = True
logger.debug(f"Retéléchargement terminé pour {game_name}, succès={success}, message={message}, retour direct history")
break
elif action in ("clear_history", "delete_history") and config.menu_state == "history": elif action in ("clear_history", "delete_history") and config.menu_state == "history":
# Ouvrir le dialogue de confirmation # Ouvrir le dialogue de confirmation
config.previous_menu_state = config.menu_state config.previous_menu_state = config.menu_state
@@ -906,8 +813,8 @@ async def main():
draw_clear_history_dialog(screen) draw_clear_history_dialog(screen)
elif config.menu_state == "confirm_cancel_download": elif config.menu_state == "confirm_cancel_download":
draw_cancel_download_dialog(screen) draw_cancel_download_dialog(screen)
elif config.menu_state == "redownload_game_cache": elif config.menu_state == "reload_games_data":
draw_redownload_game_cache_dialog(screen) draw_reload_games_data_dialog(screen)
elif config.menu_state == "restart_popup": elif config.menu_state == "restart_popup":
draw_popup(screen) draw_popup(screen)
elif config.menu_state == "accessibility_menu": elif config.menu_state == "accessibility_menu":

View File

@@ -0,0 +1,19 @@
{
"confirm": { "type": "button", "button": 1, "display": "A" },
"cancel": { "type": "button", "button": 2, "display": "B" },
"clear_history": { "type": "button", "button": 3, "display": "X" },
"history": { "type": "button", "button": 4, "display": "Y" },
"delete": { "type": "button", "button": 5, "display": "LB" },
"space": { "type": "button", "button": 6, "display": "RB" },
"start": { "type": "button", "button": 8, "display": "Start" },
"filter": { "type": "button", "button": 7, "display": "Select" },
"up": { "type": "hat", "value": [0, 1], "display": "\u2191" },
"down": { "type": "hat", "value": [0, -1], "display": "\u2193" },
"left": { "type": "hat", "value": [-1, 0], "display": "\u2190" },
"right": { "type": "hat", "value": [1, 0], "display": "\u2192" },
"page_up": { "type": "axis", "axis": 5, "direction": -1, "display": "RT" },
"page_down": { "type": "axis", "axis": 2, "direction": -1, "display": "LT" },
"meta": {
"notes": "Mapping spécifique Xbox Elite basé sur log fourni. Triggers décalés: LEFT_TRIGGER=AXIS2 -, RIGHT_TRIGGER=AXIS5 -. Les boutons semblent décalés de +1 vs profil 360 standard."
}
}

View File

@@ -13,7 +13,7 @@ except Exception:
pygame = None # type: ignore pygame = None # type: ignore
# Version actuelle de l'application # Version actuelle de l'application
app_version = "2.2.0.7" app_version = "2.2.0.8"
def get_operating_system(): def get_operating_system():
"""Renvoie le nom du système d'exploitation.""" """Renvoie le nom du système d'exploitation."""
@@ -202,7 +202,6 @@ last_state_change_time = 0 # Temps du dernier changement d'état pour debounce
debounce_delay = 200 # Délai de debounce en millisecondes debounce_delay = 200 # Délai de debounce en millisecondes
platform_dicts = [] # Liste des dictionnaires de plateformes platform_dicts = [] # Liste des dictionnaires de plateformes
selected_key = (0, 0) # Position du curseur dans le clavier virtuel selected_key = (0, 0) # Position du curseur dans le clavier virtuel
redownload_confirm_selection = 0 # Sélection pour la confirmation de redownload
popup_message = "" # Message à afficher dans les popups popup_message = "" # Message à afficher dans les popups
popup_timer = 0 # Temps restant pour le popup en millisecondes (0 = inactif) popup_timer = 0 # Temps restant pour le popup en millisecondes (0 = inactif)
last_frame_time = pygame.time.get_ticks() if pygame is not None else 0 last_frame_time = pygame.time.get_ticks() if pygame is not None else 0
@@ -224,6 +223,7 @@ eightbitdo_controller = False
steam_controller = False steam_controller = False
trimui_controller = False trimui_controller = False
generic_controller = False generic_controller = False
xbox_elite_controller = False # Flag spécifique manette Xbox Elite
# --- Filtre plateformes (UI) --- # --- Filtre plateformes (UI) ---
selected_filter_index = 0 # index dans la liste visible triée selected_filter_index = 0 # index dans la liste visible triée

View File

@@ -33,7 +33,7 @@ key_states = {} # Dictionnaire pour suivre l'état des touches
VALID_STATES = [ VALID_STATES = [
"platform", "game", "confirm_exit", "platform", "game", "confirm_exit",
"extension_warning", "pause_menu", "controls_help", "history", "controls_mapping", "extension_warning", "pause_menu", "controls_help", "history", "controls_mapping",
"redownload_game_cache", "restart_popup", "error", "loading", "confirm_clear_history", "reload_games_data", "restart_popup", "error", "loading", "confirm_clear_history",
"language_select", "filter_platforms", "display_menu" "language_select", "filter_platforms", "display_menu"
] ]
@@ -105,7 +105,9 @@ def load_controls_config(path=CONTROLS_CONFIG_PATH):
candidates.append('steam_controller.json') candidates.append('steam_controller.json')
if getattr(config, 'trimui_controller', False): if getattr(config, 'trimui_controller', False):
candidates.append('trimui_controller.json') candidates.append('trimui_controller.json')
if getattr(config, 'xbox_controller', False): if getattr(config, 'xbox_elite_controller', False):
candidates.append('xbox_elite_controller.json')
elif getattr(config, 'xbox_controller', False):
candidates.append('xbox_controller.json') candidates.append('xbox_controller.json')
if getattr(config, 'nintendo_controller', False): if getattr(config, 'nintendo_controller', False):
candidates.append('nintendo_controller.json') candidates.append('nintendo_controller.json')
@@ -188,7 +190,7 @@ def handle_controls(event, sources, joystick, screen):
return "quit" return "quit"
# Menu pause # Menu pause
if is_input_matched(event, "start") and config.menu_state not in ("pause_menu", "controls_mapping", "redownload_game_cache"): if is_input_matched(event, "start") and config.menu_state not in ("pause_menu", "controls_mapping", "reload_games_data"):
config.previous_menu_state = config.menu_state config.previous_menu_state = config.menu_state
config.menu_state = "pause_menu" config.menu_state = "pause_menu"
config.selected_option = 0 config.selected_option = 0
@@ -529,11 +531,11 @@ def handle_controls(event, sources, joystick, screen):
config.scroll_offset = 0 config.scroll_offset = 0
config.needs_redraw = True config.needs_redraw = True
logger.debug("Retour à platform") logger.debug("Retour à platform")
elif is_input_matched(event, "redownload_game_cache"): elif is_input_matched(event, "reload_games_data"):
config.previous_menu_state = config.menu_state config.previous_menu_state = config.menu_state
config.menu_state = "redownload_game_cache" config.menu_state = "reload_games_data"
config.needs_redraw = True config.needs_redraw = True
logger.debug("Passage à redownload_game_cache depuis game") logger.debug("Passage à reload_games_data depuis game")
# Télécharger les jeux sélectionnés (multi) ou le jeu courant # Télécharger les jeux sélectionnés (multi) ou le jeu courant
elif is_input_matched(event, "confirm"): elif is_input_matched(event, "confirm"):
# Batch multi-sélection # Batch multi-sélection
@@ -1208,10 +1210,10 @@ def handle_controls(event, sources, joystick, screen):
logger.error(f"Erreur changement mode sources: {e}") logger.error(f"Erreur changement mode sources: {e}")
elif config.selected_option == 6: # Redownload game cache elif config.selected_option == 6: # Redownload game cache
config.previous_menu_state = validate_menu_state(config.previous_menu_state) config.previous_menu_state = validate_menu_state(config.previous_menu_state)
config.menu_state = "redownload_game_cache" config.menu_state = "reload_games_data"
config.redownload_confirm_selection = 0 config.redownload_confirm_selection = 0
config.needs_redraw = True config.needs_redraw = True
logger.debug(f"Passage à redownload_game_cache depuis pause_menu") logger.debug(f"Passage à reload_games_data depuis pause_menu")
elif config.selected_option == 7: # Music toggle elif config.selected_option == 7: # Music toggle
config.music_enabled = not config.music_enabled config.music_enabled = not config.music_enabled
save_music_config() save_music_config()
@@ -1354,13 +1356,13 @@ def handle_controls(event, sources, joystick, screen):
logger.debug("Retour à pause_menu depuis controls_mapping") logger.debug("Retour à pause_menu depuis controls_mapping")
# Redownload game cache # Redownload game cache
elif config.menu_state == "redownload_game_cache": elif config.menu_state == "reload_games_data":
if is_input_matched(event, "left") or is_input_matched(event, "right"): if is_input_matched(event, "left") or is_input_matched(event, "right"):
config.redownload_confirm_selection = 1 - config.redownload_confirm_selection config.redownload_confirm_selection = 1 - config.redownload_confirm_selection
config.needs_redraw = True config.needs_redraw = True
logger.debug(f"Changement sélection redownload_game_cache: {config.redownload_confirm_selection}") logger.debug(f"Changement sélection reload_games_data: {config.redownload_confirm_selection}")
elif is_input_matched(event, "confirm"): elif is_input_matched(event, "confirm"):
logger.debug(f"Action confirm dans redownload_game_cache, sélection={config.redownload_confirm_selection}") logger.debug(f"Action confirm dans reload_games_data, sélection={config.redownload_confirm_selection}")
if config.redownload_confirm_selection == 1: # Oui if config.redownload_confirm_selection == 1: # Oui
logger.debug("Début du redownload des jeux") logger.debug("Début du redownload des jeux")
config.download_tasks.clear() config.download_tasks.clear()
@@ -1409,7 +1411,7 @@ def handle_controls(event, sources, joystick, screen):
elif is_input_matched(event, "cancel"): elif is_input_matched(event, "cancel"):
config.menu_state = validate_menu_state(config.previous_menu_state) config.menu_state = validate_menu_state(config.previous_menu_state)
config.needs_redraw = True config.needs_redraw = True
logger.debug(f"Retour à {config.menu_state} depuis redownload_game_cache") logger.debug(f"Retour à {config.menu_state} depuis reload_games_data")
# Popup de redémarrage # Popup de redémarrage

View File

@@ -1774,14 +1774,13 @@ def draw_confirm_dialog(screen):
draw_stylized_button(screen, _("button_yes"), rect_x + rect_width // 2 - button_width - 10, rect_y + text_height + margin_top_bottom, button_width, button_height, selected=config.confirm_selection == 1) draw_stylized_button(screen, _("button_yes"), rect_x + rect_width // 2 - button_width - 10, rect_y + text_height + margin_top_bottom, button_width, button_height, selected=config.confirm_selection == 1)
draw_stylized_button(screen, _("button_no"), rect_x + rect_width // 2 + 10, rect_y + text_height + margin_top_bottom, button_width, button_height, selected=config.confirm_selection == 0) draw_stylized_button(screen, _("button_no"), rect_x + rect_width // 2 + 10, rect_y + text_height + margin_top_bottom, button_width, button_height, selected=config.confirm_selection == 0)
# draw_redownload_game_cache_dialog
def draw_redownload_game_cache_dialog(screen): def draw_reload_games_data_dialog(screen):
"""Affiche la boîte de dialogue de confirmation pour retélécharger le cache des jeux.""" """Affiche la boîte de dialogue de confirmation pour retélécharger le cache des jeux."""
global OVERLAY global OVERLAY
if OVERLAY is None or OVERLAY.get_size() != (config.screen_width, config.screen_height): if OVERLAY is None or OVERLAY.get_size() != (config.screen_width, config.screen_height):
OVERLAY = pygame.Surface((config.screen_width, config.screen_height), pygame.SRCALPHA) OVERLAY = pygame.Surface((config.screen_width, config.screen_height), pygame.SRCALPHA)
OVERLAY.fill((0, 0, 0, 150)) OVERLAY.fill((0, 0, 0, 150))
logger.debug("OVERLAY recréé dans draw_redownload_game_cache_dialog")
screen.blit(OVERLAY, (0, 0)) screen.blit(OVERLAY, (0, 0))
message = _("confirm_redownload_cache") message = _("confirm_redownload_cache")