forked from Mirrors/RGSX
v2.2.1.0
- reorganization of all pause menu - add xbox elite controller support, correct bug for xbox 360 controller showing "Select" for History rather than "Y" - cleanup languages files - improve API key handling for 1fichier and AllDebrid and logging - update and simplify config variables and delete unused functions - virtual keyboard for filter games now showing evreytime you have controller plugged, even on computer, steamdeck, handheld.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,6 +2,7 @@ ports/RGSX/logs/
|
||||
ports/RGSX/images/
|
||||
ports/RGSX/games/
|
||||
ports/RGSX/__pycache__/
|
||||
ports/RGSX/scripts/
|
||||
ports/RGSX/sources.json
|
||||
ports/gamelist.xml
|
||||
windows/gamelist.xml
|
||||
|
||||
@@ -183,6 +183,7 @@ try:
|
||||
count = pygame.joystick.get_count()
|
||||
except Exception:
|
||||
count = 0
|
||||
|
||||
joystick_names = []
|
||||
for i in range(count):
|
||||
try:
|
||||
@@ -197,7 +198,14 @@ if not joystick_names:
|
||||
logger.debug("Aucun joystick détecté, utilisation du clavier par défaut.")
|
||||
config.joystick = False
|
||||
config.keyboard = True
|
||||
# Si aucune marque spécifique détectée mais un joystick est présent, marquer comme générique
|
||||
if not any([config.xbox_controller, config.playstation_controller, config.nintendo_controller,
|
||||
config.eightbitdo_controller, config.steam_controller, config.trimui_controller,
|
||||
config.logitech_controller]):
|
||||
config.generic_controller = True
|
||||
logger.debug("Aucun contrôleur spécifique détecté, utilisation du profil générique")
|
||||
else:
|
||||
# Des joysticks sont présents, activer le mode joystick et tenter la détection spécifique
|
||||
config.joystick = True
|
||||
config.keyboard = False
|
||||
print(f"Joysticks détectés: {joystick_names}")
|
||||
@@ -243,29 +251,18 @@ else:
|
||||
# Note: virtual keyboard display now depends on controller presence (config.joystick)
|
||||
logger.debug(f"Flags contrôleur: xbox={config.xbox_controller}, ps={config.playstation_controller}, nintendo={config.nintendo_controller}, eightbitdo={config.eightbitdo_controller}, steam={config.steam_controller}, trimui={config.trimui_controller}, logitech={config.logitech_controller}, generic={config.generic_controller}")
|
||||
|
||||
# Si aucune marque spécifique détectée mais un joystick est présent, marquer comme générique
|
||||
if not any([config.xbox_controller, config.playstation_controller, config.nintendo_controller,
|
||||
config.eightbitdo_controller, config.steam_controller, config.trimui_controller,
|
||||
config.logitech_controller]):
|
||||
config.generic_controller = True
|
||||
logger.debug("Aucun contrôleur spécifique détecté, utilisation du profil générique")
|
||||
|
||||
|
||||
|
||||
# Initialisation des variables de grille
|
||||
config.current_page = 0
|
||||
config.selected_platform = 0
|
||||
config.selected_key = (0, 0)
|
||||
config.transition_state = "none"
|
||||
|
||||
# Initialisation des variables de répétition
|
||||
config.repeat_action = None
|
||||
config.repeat_key = None
|
||||
config.repeat_start_time = 0
|
||||
config.repeat_last_action = 0
|
||||
|
||||
# Charger la configuration de la musique AVANT d'initialiser l'audio
|
||||
load_music_config()
|
||||
# Charger la configuration musique AVANT d'initialiser le mixer pour respecter le paramètre music_enabled
|
||||
try:
|
||||
load_music_config()
|
||||
logger.debug(f"Configuration musique chargée: music_enabled={getattr(config, 'music_enabled', True)}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Impossible de charger la configuration musique avant init mixer: {e}")
|
||||
|
||||
# Initialisation du mixer Pygame (déférée/évitable si musique désactivée)
|
||||
if getattr(config, 'music_enabled', True):
|
||||
@@ -447,6 +444,8 @@ async def main():
|
||||
):
|
||||
if config.menu_state not in ["pause_menu", "controls_help", "controls_mapping", "history", "confirm_clear_history"]:
|
||||
config.previous_menu_state = config.menu_state
|
||||
# Capturer l'état d'origine pour une sortie fiable du menu pause
|
||||
config.pause_origin_state = config.menu_state
|
||||
config.menu_state = "pause_menu"
|
||||
config.selected_option = 0
|
||||
config.needs_redraw = True
|
||||
@@ -454,13 +453,25 @@ async def main():
|
||||
continue
|
||||
|
||||
if config.menu_state == "pause_menu":
|
||||
action = handle_controls(event, sources, joystick, screen)
|
||||
config.needs_redraw = True
|
||||
#logger.debug(f"Événement transmis à handle_controls dans pause_menu: {event.type}")
|
||||
continue
|
||||
# Rien de spécifique ici, capturé par SIMPLE_HANDLE_STATES ci-dessous
|
||||
pass
|
||||
|
||||
# Gestion des événements pour le menu de filtrage des plateformes
|
||||
if config.menu_state == "filter_platforms":
|
||||
# États simples factorisés (déclenchent juste handle_controls + redraw)
|
||||
SIMPLE_HANDLE_STATES = {
|
||||
"pause_menu",
|
||||
"pause_controls_menu",
|
||||
"pause_display_menu",
|
||||
"pause_games_menu",
|
||||
"pause_settings_menu",
|
||||
"pause_api_keys_status",
|
||||
"filter_platforms",
|
||||
"display_menu",
|
||||
"language_select",
|
||||
"controls_help",
|
||||
"confirm_cancel_download",
|
||||
"reload_games_data",
|
||||
}
|
||||
if config.menu_state in SIMPLE_HANDLE_STATES:
|
||||
action = handle_controls(event, sources, joystick, screen)
|
||||
config.needs_redraw = True
|
||||
continue
|
||||
@@ -470,24 +481,6 @@ async def main():
|
||||
if handle_accessibility_events(event):
|
||||
config.needs_redraw = True
|
||||
continue
|
||||
if config.menu_state == "display_menu":
|
||||
# Les événements sont gérés dans controls.handle_controls
|
||||
action = handle_controls(event, sources, joystick, screen)
|
||||
config.needs_redraw = True
|
||||
continue
|
||||
|
||||
if config.menu_state == "language_select":
|
||||
# Gérer les événements du sélecteur de langue via le système unifié
|
||||
action = handle_controls(event, sources, joystick, screen)
|
||||
config.needs_redraw = True
|
||||
continue
|
||||
|
||||
if config.menu_state == "controls_help":
|
||||
action = handle_controls(event, sources, joystick, screen)
|
||||
config.needs_redraw = True
|
||||
#logger.debug(f"Événement transmis à handle_controls dans controls_help: {event.type}")
|
||||
continue
|
||||
|
||||
if config.menu_state == "confirm_clear_history":
|
||||
action = handle_controls(event, sources, joystick, screen)
|
||||
if action == "confirm":
|
||||
@@ -509,7 +502,6 @@ async def main():
|
||||
if config.menu_state == "reload_games_data":
|
||||
action = handle_controls(event, sources, joystick, screen)
|
||||
config.needs_redraw = True
|
||||
#logger.debug(f"Événement transmis à handle_controls dans reload_games_data: {event.type}")
|
||||
continue
|
||||
|
||||
if config.menu_state == "extension_warning":
|
||||
@@ -800,7 +792,21 @@ async def main():
|
||||
draw_extension_warning(screen)
|
||||
elif config.menu_state == "pause_menu":
|
||||
draw_pause_menu(screen, config.selected_option)
|
||||
#logger.debug("Rendu de draw_pause_menu")
|
||||
elif config.menu_state == "pause_controls_menu":
|
||||
from display import draw_pause_controls_menu
|
||||
draw_pause_controls_menu(screen, getattr(config, 'pause_controls_selection', 0))
|
||||
elif config.menu_state == "pause_display_menu":
|
||||
from display import draw_pause_display_menu
|
||||
draw_pause_display_menu(screen, getattr(config, 'pause_display_selection', 0))
|
||||
elif config.menu_state == "pause_games_menu":
|
||||
from display import draw_pause_games_menu
|
||||
draw_pause_games_menu(screen, getattr(config, 'pause_games_selection', 0))
|
||||
elif config.menu_state == "pause_settings_menu":
|
||||
from display import draw_pause_settings_menu
|
||||
draw_pause_settings_menu(screen, getattr(config, 'pause_settings_selection', 0))
|
||||
elif config.menu_state == "pause_api_keys_status":
|
||||
from display import draw_pause_api_keys_status
|
||||
draw_pause_api_keys_status(screen)
|
||||
elif config.menu_state == "filter_platforms":
|
||||
from display import draw_filter_platforms_menu
|
||||
draw_filter_platforms_menu(screen)
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"history": {
|
||||
"type": "button",
|
||||
"button": 3,
|
||||
"display": "Select"
|
||||
"display": "Y"
|
||||
},
|
||||
"clear_history": {
|
||||
"type": "button",
|
||||
|
||||
@@ -13,74 +13,34 @@ except Exception:
|
||||
pygame = None # type: ignore
|
||||
|
||||
# Version actuelle de l'application
|
||||
app_version = "2.2.0.8"
|
||||
|
||||
def get_operating_system():
|
||||
"""Renvoie le nom du système d'exploitation."""
|
||||
return platform.system()
|
||||
#log dans la console le système d'exploitation (désactivé en headless)
|
||||
if not HEADLESS:
|
||||
print(f"Système d'exploitation : {get_operating_system()}")
|
||||
app_version = "2.2.1.0"
|
||||
|
||||
|
||||
def get_application_root():
|
||||
"""Détermine le dossier de l'application de manière portable."""
|
||||
"""Détermine le dossier de l'application (PORTS)"""
|
||||
try:
|
||||
# Obtenir le chemin absolu du fichier config.py
|
||||
current_file = os.path.abspath(__file__)
|
||||
# Remonter au dossier parent de config.py (par exemple, dossier de l'application)
|
||||
app_root = os.path.dirname(os.path.dirname(current_file))
|
||||
if not HEADLESS:
|
||||
print(f"Dossier de l'application : {app_root}")
|
||||
return app_root
|
||||
except NameError:
|
||||
# Si __file__ n'est pas défini (par exemple, exécution dans un REPL)
|
||||
return os.path.abspath(os.getcwd())
|
||||
|
||||
def get_system_root():
|
||||
OPERATING_SYSTEM = get_operating_system()
|
||||
"""Détermine le dossier racine du système de fichiers (par exemple, /userdata ou C:\\)."""
|
||||
try:
|
||||
if OPERATING_SYSTEM == "Windows":
|
||||
# Sur Windows, extraire la lettre de disque
|
||||
current_path = os.path.abspath(__file__)
|
||||
drive, _ = os.path.splitdrive(current_path)
|
||||
system_root = drive + os.sep
|
||||
if not HEADLESS:
|
||||
print(f"Dossier racine du système : {system_root}")
|
||||
return system_root
|
||||
elif OPERATING_SYSTEM == "Linux":
|
||||
# tester si c'est batocera :
|
||||
if os.path.exists("/usr/share/batocera"):
|
||||
OPERATING_SYSTEM = "Batocera"
|
||||
|
||||
#remonter jusqu'à atteindre /userdata
|
||||
current_path = os.path.abspath(__file__)
|
||||
current_dir = current_path
|
||||
while current_dir != os.path.dirname(current_dir): # Tant qu'on peut remonter
|
||||
parent_dir = os.path.dirname(current_dir)
|
||||
if os.path.basename(parent_dir) == "userdata": # Vérifier si le parent est userdata
|
||||
system_root = parent_dir
|
||||
if not HEADLESS:
|
||||
print(f"Dossier racine du système : {system_root}")
|
||||
return system_root
|
||||
current_dir = parent_dir
|
||||
# Si userdata n'est pas trouvé, retourner /
|
||||
return "/"
|
||||
else:
|
||||
return "/"
|
||||
except NameError:
|
||||
|
||||
return "/" if not OPERATING_SYSTEM == "Windows" else os.path.splitdrive(os.getcwd())[0] + os.sep
|
||||
|
||||
def detect_operating_system():
|
||||
"""Renvoie le nom du système d'exploitation."""
|
||||
OPERATING_SYSTEM = platform.system()
|
||||
return OPERATING_SYSTEM
|
||||
|
||||
|
||||
# Chemins de base
|
||||
SYSTEM_FOLDER = get_system_root()
|
||||
APP_FOLDER = os.path.join(get_application_root(), "RGSX")
|
||||
ROMS_FOLDER = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "roms")
|
||||
SAVE_FOLDER = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "saves", "ports", "rgsx")
|
||||
RETROBAT_DATA_FOLDER = os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER)))
|
||||
|
||||
USERDATA_FOLDER = os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER)))
|
||||
ROMS_FOLDER = os.path.join(USERDATA_FOLDER, "roms")
|
||||
SAVE_FOLDER = os.path.join(USERDATA_FOLDER, "saves", "ports", "rgsx")
|
||||
GAMELISTXML = os.path.join(ROMS_FOLDER, "ports","gamelist.xml")
|
||||
GAMELISTXML_WINDOWS = os.path.join(ROMS_FOLDER, "windows","gamelist.xml")
|
||||
|
||||
|
||||
# Configuration du logging
|
||||
@@ -88,15 +48,12 @@ logger = logging.getLogger(__name__)
|
||||
log_dir = os.path.join(APP_FOLDER, "logs")
|
||||
log_file = os.path.join(log_dir, "RGSX.log")
|
||||
|
||||
# Chemins de base
|
||||
GAMELISTXML = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "roms", "ports", "gamelist.xml")
|
||||
GAMELISTXML_WINDOWS = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(APP_FOLDER))), "roms", "windows", "gamelist.xml")
|
||||
#Dossier /roms/ports/rgsx
|
||||
#Dossier de l'APP : /roms/ports/rgsx
|
||||
UPDATE_FOLDER = os.path.join(APP_FOLDER, "update")
|
||||
LANGUAGES_FOLDER = os.path.join(APP_FOLDER, "languages")
|
||||
MUSIC_FOLDER = os.path.join(APP_FOLDER, "assets", "music")
|
||||
|
||||
#Dossier /saves/ports/rgsx
|
||||
#Dossier de sauvegarde : /saves/ports/rgsx
|
||||
IMAGES_FOLDER = os.path.join(SAVE_FOLDER, "images")
|
||||
GAMES_FOLDER = os.path.join(SAVE_FOLDER, "games")
|
||||
SOURCES_FILE = os.path.join(SAVE_FOLDER, "systems_list.json")
|
||||
@@ -104,7 +61,12 @@ JSON_EXTENSIONS = os.path.join(SAVE_FOLDER, "rom_extensions.json")
|
||||
PRECONF_CONTROLS_PATH = os.path.join(APP_FOLDER, "assets", "controls")
|
||||
CONTROLS_CONFIG_PATH = os.path.join(SAVE_FOLDER, "controls.json")
|
||||
HISTORY_PATH = os.path.join(SAVE_FOLDER, "history.json")
|
||||
API_KEY_1FICHIER = os.path.join(SAVE_FOLDER, "1FichierAPI.txt")
|
||||
# Séparation chemin / valeur pour éviter les confusions lors du chargement
|
||||
API_KEY_1FICHIER_PATH = os.path.join(SAVE_FOLDER, "1FichierAPI.txt")
|
||||
API_KEY_ALLDEBRID_PATH = os.path.join(SAVE_FOLDER, "AllDebridAPI.txt")
|
||||
# Valeurs chargées (remplies dynamiquement par utils.load_api_key_*).
|
||||
API_KEY_1FICHIER = ""
|
||||
API_KEY_ALLDEBRID = ""
|
||||
RGSX_SETTINGS_PATH = os.path.join(SAVE_FOLDER, "rgsx_settings.json")
|
||||
|
||||
# URL
|
||||
@@ -117,14 +79,12 @@ OTA_data_ZIP = os.path.join(OTA_SERVER_URL, "games.zip")
|
||||
UNRAR_EXE = os.path.join(APP_FOLDER,"assets", "unrar.exe")
|
||||
XDVDFS_EXE = os.path.join(APP_FOLDER,"assets", "xdvdfs.exe")
|
||||
XDVDFS_LINUX = os.path.join(APP_FOLDER,"assets", "xdvdfs")
|
||||
unrar_download_exe = os.path.join(OTA_SERVER_URL, "unrar.exe")
|
||||
xdvdfs_download_exe = os.path.join(OTA_SERVER_URL, "xdvdfs.exe")
|
||||
|
||||
|
||||
xdvdfs_download_linux = os.path.join(OTA_SERVER_URL, "xdvdfs")
|
||||
|
||||
if not HEADLESS:
|
||||
# Print des chemins pour debug
|
||||
print(f"OPERATING_SYSTEM: {detect_operating_system()}")
|
||||
print(f"APP_FOLDER: {APP_FOLDER}")
|
||||
print(f"USERDATA_FOLDER: {USERDATA_FOLDER}")
|
||||
print(f"ROMS_FOLDER: {ROMS_FOLDER}")
|
||||
print(f"SAVE_FOLDER: {SAVE_FOLDER}")
|
||||
print(f"RGSX LOGS_FOLDER: {log_dir}")
|
||||
@@ -133,7 +93,6 @@ if not HEADLESS:
|
||||
print(f"IMAGES_FOLDER: {IMAGES_FOLDER}")
|
||||
print(f"GAMES_FOLDER: {GAMES_FOLDER}")
|
||||
print(f"SOURCES_FILE: {SOURCES_FILE}")
|
||||
print(f"OPERATING_SYSTEM: {get_operating_system()}")
|
||||
|
||||
|
||||
# Constantes pour la répétition automatique dans pause_menu
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
import shutil
|
||||
import pygame # type: ignore
|
||||
import config
|
||||
# Constantes pour la répétition automatique - importées de config.py
|
||||
from config import REPEAT_DELAY, REPEAT_INTERVAL, REPEAT_ACTION_DEBOUNCE
|
||||
from config import CONTROLS_CONFIG_PATH
|
||||
import shutil
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import config
|
||||
from config import REPEAT_DELAY, REPEAT_INTERVAL, REPEAT_ACTION_DEBOUNCE
|
||||
from config import CONTROLS_CONFIG_PATH
|
||||
from display import draw_validation_transition
|
||||
from network import download_rom, download_from_1fichier, is_1fichier_url
|
||||
from network import download_rom, download_from_1fichier, is_1fichier_url, request_cancel
|
||||
from utils import (
|
||||
load_games, check_extension_before_download, is_extension_supported,
|
||||
load_extensions_json, play_random_music, sanitize_filename,
|
||||
load_api_key_1fichier, load_api_key_alldebrid, save_music_config
|
||||
save_music_config, load_api_keys
|
||||
)
|
||||
from history import load_history, clear_history, add_to_history, save_history
|
||||
import logging
|
||||
@@ -34,16 +31,19 @@ VALID_STATES = [
|
||||
"platform", "game", "confirm_exit",
|
||||
"extension_warning", "pause_menu", "controls_help", "history", "controls_mapping",
|
||||
"reload_games_data", "restart_popup", "error", "loading", "confirm_clear_history",
|
||||
"language_select", "filter_platforms", "display_menu"
|
||||
"language_select", "filter_platforms", "display_menu",
|
||||
# Nouveaux sous-menus hiérarchiques (refonte pause menu)
|
||||
"pause_controls_menu", # sous-menu Controls (aide, remap)
|
||||
"pause_display_menu", # sous-menu Display (layout, font size, unsupported, unknown ext, filter)
|
||||
"pause_games_menu", # sous-menu Games (source mode, update/redownload cache)
|
||||
"pause_settings_menu", # sous-menu Settings (music on/off, symlink toggle, api keys status)
|
||||
"pause_api_keys_status" # sous-menu API Keys (affichage statut des clés)
|
||||
]
|
||||
|
||||
def validate_menu_state(state):
|
||||
if state not in VALID_STATES:
|
||||
logger.debug(f"État invalide {state}, retour à platform")
|
||||
return "platform"
|
||||
if state == "history": # Éviter de revenir à history
|
||||
logger.debug(f"État history non autorisé comme previous_menu_state, retour à platform")
|
||||
return "platform"
|
||||
return state
|
||||
|
||||
|
||||
@@ -133,6 +133,7 @@ def load_controls_config(path=CONTROLS_CONFIG_PATH):
|
||||
# 3) Fallback clavier par défaut
|
||||
logging.getLogger(__name__).info("Aucun fichier utilisateur ou préréglage trouvé, utilisation des contrôles par défaut")
|
||||
return default_config.copy()
|
||||
|
||||
except Exception as e:
|
||||
logging.getLogger(__name__).error(f"Erreur load_controls_config: {e}")
|
||||
return default_config.copy()
|
||||
@@ -318,6 +319,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.repeat_last_action = current_time
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "history"):
|
||||
# Capturer l'origine si on vient directement des plateformes
|
||||
config.history_origin = "platform"
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
logger.debug("Ouverture history depuis platform")
|
||||
@@ -334,6 +337,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
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"):
|
||||
# Capturer l'origine (plateformes) pour un retour correct si l'utilisateur choisit "Non"
|
||||
config.confirm_exit_origin = "platform"
|
||||
config.menu_state = "confirm_exit"
|
||||
config.confirm_selection = 0
|
||||
config.needs_redraw = True
|
||||
@@ -584,14 +589,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.current_history_item = len(config.history) -1
|
||||
task_id = str(pygame.time.get_ticks())
|
||||
if is_1fichier_url(url):
|
||||
config.API_KEY_1FICHIER = load_api_key_1fichier()
|
||||
if not config.API_KEY_1FICHIER:
|
||||
# Fallback AllDebrid
|
||||
try:
|
||||
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", ""):
|
||||
keys = load_api_keys()
|
||||
if not keys.get('1fichier') and not keys.get('alldebrid'):
|
||||
config.history[-1]["status"] = "Erreur"
|
||||
config.history[-1]["message"] = "API NOT FOUND"
|
||||
save_history(config.history)
|
||||
@@ -626,14 +625,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.current_history_item = len(config.history) - 1
|
||||
# Vérifier d'abord si c'est un lien 1fichier
|
||||
if is_1fichier_url(url):
|
||||
config.API_KEY_1FICHIER = load_api_key_1fichier()
|
||||
if not config.API_KEY_1FICHIER:
|
||||
# Fallback AllDebrid
|
||||
try:
|
||||
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", ""):
|
||||
keys = load_api_keys()
|
||||
if not keys.get('1fichier') and not keys.get('alldebrid'):
|
||||
config.previous_menu_state = config.menu_state
|
||||
config.menu_state = "error"
|
||||
try:
|
||||
@@ -748,13 +741,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
))
|
||||
config.current_history_item = len(config.history) - 1
|
||||
if is_1fichier_url(url):
|
||||
if not config.API_KEY_1FICHIER:
|
||||
# Fallback AllDebrid
|
||||
try:
|
||||
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", ""):
|
||||
keys = load_api_keys()
|
||||
if not keys.get('1fichier') and not keys.get('alldebrid'):
|
||||
config.previous_menu_state = config.menu_state
|
||||
config.menu_state = "error"
|
||||
try:
|
||||
@@ -821,14 +809,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.current_history_item = len(config.history) -1
|
||||
task_id = str(pygame.time.get_ticks())
|
||||
if is_1fichier_url(url):
|
||||
config.API_KEY_1FICHIER = load_api_key_1fichier()
|
||||
if not config.API_KEY_1FICHIER:
|
||||
# Fallback AllDebrid
|
||||
try:
|
||||
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", ""):
|
||||
keys = load_api_keys()
|
||||
if not keys.get('1fichier') and not keys.get('alldebrid'):
|
||||
config.history[-1]["status"] = "Erreur"
|
||||
config.history[-1]["message"] = "API NOT FOUND"
|
||||
save_history(config.history)
|
||||
@@ -892,14 +874,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.current_history_item = len(config.history) -1
|
||||
task_id = str(pygame.time.get_ticks())
|
||||
if is_1fichier_url(url):
|
||||
config.API_KEY_1FICHIER = load_api_key_1fichier()
|
||||
if not config.API_KEY_1FICHIER:
|
||||
# Fallback AllDebrid
|
||||
try:
|
||||
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", ""):
|
||||
keys = load_api_keys()
|
||||
if not keys.get('1fichier') and not keys.get('alldebrid'):
|
||||
config.history[-1]["status"] = "Erreur"
|
||||
config.history[-1]["message"] = "API NOT FOUND"
|
||||
save_history(config.history)
|
||||
@@ -969,75 +945,6 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.confirm_clear_selection = 0 # 0 pour "Non", 1 pour "Oui"
|
||||
config.needs_redraw = True
|
||||
logger.debug("Passage à confirm_clear_history depuis history")
|
||||
elif is_input_matched(event, "confirm"):
|
||||
if history:
|
||||
entry = history[config.current_history_item]
|
||||
platform = entry["platform"]
|
||||
game_name = entry["game_name"]
|
||||
for game in config.games:
|
||||
if game[0] == game_name and config.platforms[config.current_platform] == platform:
|
||||
config.pending_download = check_extension_before_download(game[1], platform, game_name)
|
||||
if config.pending_download:
|
||||
url, platform, game_name, is_zip_non_supported = config.pending_download
|
||||
# Recalculer le support exact et décider via le flag is_zip_non_supported
|
||||
is_supported = is_extension_supported(
|
||||
sanitize_filename(game_name),
|
||||
platform,
|
||||
load_extensions_json()
|
||||
)
|
||||
if not is_supported and not is_zip_non_supported:
|
||||
config.previous_menu_state = config.menu_state
|
||||
config.menu_state = "extension_warning"
|
||||
config.extension_confirm_selection = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Extension non supportée pour retéléchargement, passage à extension_warning pour {game_name}")
|
||||
else:
|
||||
task_id = str(pygame.time.get_ticks())
|
||||
if is_1fichier_url(url):
|
||||
if not config.API_KEY_1FICHIER:
|
||||
# Fallback AllDebrid
|
||||
try:
|
||||
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"
|
||||
logger.warning("clé api absente pour 1fichier et AllDebrid")
|
||||
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.history[-1]["status"] = "Erreur"
|
||||
config.history[-1]["progress"] = 0
|
||||
config.history[-1]["message"] = "API NOT FOUND"
|
||||
save_history(config.history)
|
||||
config.needs_redraw = True
|
||||
logger.error("Clé API 1fichier et AllDebrid absentes, retéléchargement impossible.")
|
||||
config.pending_download = None
|
||||
return action
|
||||
task = asyncio.create_task(download_from_1fichier(url, platform, game_name, is_zip_non_supported, task_id))
|
||||
else:
|
||||
task = asyncio.create_task(download_rom(url, platform, game_name, is_zip_non_supported, task_id))
|
||||
config.download_tasks[task_id] = (task, url, game_name, platform)
|
||||
config.previous_menu_state = config.menu_state
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Retéléchargement: {game_name} pour {platform} depuis {url}, task_id={task_id}")
|
||||
config.pending_download = None
|
||||
action = "redownload"
|
||||
else:
|
||||
config.menu_state = "error"
|
||||
try:
|
||||
config.error_message = _("error_invalid_download_data")
|
||||
except Exception:
|
||||
config.error_message = "Invalid download data"
|
||||
config.pending_download = None
|
||||
config.needs_redraw = True
|
||||
logger.error(f"config.pending_download est None pour {game_name}")
|
||||
break
|
||||
elif is_input_matched(event, "cancel") or is_input_matched(event, "history"):
|
||||
if config.history and config.current_history_item < len(config.history):
|
||||
entry = config.history[config.current_history_item]
|
||||
@@ -1047,7 +954,14 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.needs_redraw = True
|
||||
logger.debug("Demande d'annulation de téléchargement")
|
||||
return action
|
||||
config.menu_state = validate_menu_state(config.previous_menu_state)
|
||||
# Retour à l'origine capturée si disponible sinon previous_menu_state
|
||||
target = getattr(config, 'history_origin', getattr(config, 'previous_menu_state', 'platform'))
|
||||
config.menu_state = validate_menu_state(target)
|
||||
if hasattr(config, 'history_origin'):
|
||||
try:
|
||||
delattr(config, 'history_origin')
|
||||
except Exception:
|
||||
pass
|
||||
config.current_history_item = 0
|
||||
config.history_scroll_offset = 0
|
||||
config.needs_redraw = True
|
||||
@@ -1088,7 +1002,7 @@ def handle_controls(event, sources, joystick, screen):
|
||||
|
||||
# Confirmation vider l'historique
|
||||
elif config.menu_state == "confirm_clear_history":
|
||||
logger.debug(f"État confirm_clear_history, confirm_clear_selection={config.confirm_clear_selection}, événement={event.type}, valeur={getattr(event, 'value', None)}")
|
||||
|
||||
if is_input_matched(event, "confirm"):
|
||||
# 0 = Non, 1 = Oui
|
||||
if config.confirm_clear_selection == 1: # Oui
|
||||
@@ -1098,7 +1012,6 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.history_scroll_offset = 0
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
logger.info("Historique vidé après confirmation")
|
||||
else: # Non
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
@@ -1110,8 +1023,6 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.needs_redraw = True
|
||||
logger.debug("Annulation du vidage de l'historique, retour à history")
|
||||
|
||||
# État download_result supprimé
|
||||
|
||||
# Confirmation quitter
|
||||
elif config.menu_state == "confirm_exit":
|
||||
if is_input_matched(event, "confirm"):
|
||||
@@ -1128,9 +1039,16 @@ def handle_controls(event, sources, joystick, screen):
|
||||
pass
|
||||
return "quit"
|
||||
else:
|
||||
config.menu_state = validate_menu_state(config.previous_menu_state)
|
||||
# Retour à l'état capturé (confirm_exit_origin) sinon previous_menu_state sinon platform
|
||||
target = getattr(config, 'confirm_exit_origin', getattr(config, 'previous_menu_state', 'platform'))
|
||||
config.menu_state = validate_menu_state(target)
|
||||
if hasattr(config, 'confirm_exit_origin'):
|
||||
try:
|
||||
delattr(config, 'confirm_exit_origin')
|
||||
except Exception:
|
||||
pass
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Retour à {config.menu_state} depuis confirm_exit")
|
||||
logger.debug(f"Retour à {config.menu_state} depuis confirm_exit (annulation)")
|
||||
elif is_input_matched(event, "left") or is_input_matched(event, "right"):
|
||||
config.confirm_selection = 1 - config.confirm_selection
|
||||
config.needs_redraw = True
|
||||
@@ -1141,58 +1059,213 @@ def handle_controls(event, sources, joystick, screen):
|
||||
#logger.debug(f"État pause_menu, selected_option={config.selected_option}, événement={event.type}, valeur={getattr(event, 'value', None)}")
|
||||
# Start toggles back to previous state when already in pause
|
||||
if is_input_matched(event, "start"):
|
||||
config.menu_state = validate_menu_state(config.previous_menu_state)
|
||||
target = getattr(config, 'pause_origin_state', getattr(config, 'previous_menu_state', 'platform'))
|
||||
config.menu_state = validate_menu_state(target)
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Start: retour à {config.menu_state} depuis pause_menu")
|
||||
elif is_input_matched(event, "up"):
|
||||
config.selected_option = max(0, config.selected_option - 1)
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "down"):
|
||||
# Nombre d'options dynamique (inclut éventuellement l'option source des jeux)
|
||||
total = getattr(config, 'pause_menu_total_options', 11) # fallback 11 (Restart added)
|
||||
# Menu racine hiérarchique: nombre dynamique (langue + catégories)
|
||||
total = getattr(config, 'pause_menu_total_options', 7)
|
||||
config.selected_option = min(total - 1, config.selected_option + 1)
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "confirm"):
|
||||
if config.selected_option == 0: # Controls
|
||||
config.previous_menu_state = validate_menu_state(config.previous_menu_state)
|
||||
config.menu_state = "controls_help"
|
||||
if config.selected_option == 0: # Language selector direct
|
||||
config.menu_state = "language_select"
|
||||
config.previous_menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
#logger.debug(f"Passage à controls_help depuis pause_menu")
|
||||
elif config.selected_option == 1: # Remap controls
|
||||
elif config.selected_option == 1: # Controls submenu
|
||||
config.menu_state = "pause_controls_menu"
|
||||
if not hasattr(config, 'pause_controls_selection'):
|
||||
config.pause_controls_selection = 0
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
elif config.selected_option == 2: # Display submenu
|
||||
config.menu_state = "pause_display_menu"
|
||||
if not hasattr(config, 'pause_display_selection'):
|
||||
config.pause_display_selection = 0
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
elif config.selected_option == 3: # Games submenu
|
||||
config.menu_state = "pause_games_menu"
|
||||
if not hasattr(config, 'pause_games_selection'):
|
||||
config.pause_games_selection = 0
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
elif config.selected_option == 4: # Settings submenu
|
||||
config.menu_state = "pause_settings_menu"
|
||||
if not hasattr(config, 'pause_settings_selection'):
|
||||
config.pause_settings_selection = 0
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
elif config.selected_option == 5: # Restart
|
||||
from utils import restart_application
|
||||
restart_application(2000)
|
||||
elif config.selected_option == 6: # Quit
|
||||
# Capturer l'origine pause_menu pour retour si annulation
|
||||
config.confirm_exit_origin = "pause_menu"
|
||||
config.previous_menu_state = validate_menu_state(config.previous_menu_state)
|
||||
#logger.debug(f"Previous menu state avant controls_mapping: {config.previous_menu_state}")
|
||||
#Supprimer le fichier de configuration des contrôles s'il existe
|
||||
config.menu_state = "confirm_exit"
|
||||
config.confirm_selection = 0
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "cancel"):
|
||||
target = getattr(config, 'pause_origin_state', getattr(config, 'previous_menu_state', 'platform'))
|
||||
config.menu_state = validate_menu_state(target)
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Retour à {config.menu_state} depuis pause_menu")
|
||||
|
||||
# Sous-menu Controls
|
||||
elif config.menu_state == "pause_controls_menu":
|
||||
sel = getattr(config, 'pause_controls_selection', 0)
|
||||
if is_input_matched(event, "up"):
|
||||
config.pause_controls_selection = (sel - 1) % 3
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "down"):
|
||||
config.pause_controls_selection = (sel + 1) % 3
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "confirm"):
|
||||
if sel == 0: # Aide
|
||||
config.previous_menu_state = "pause_controls_menu"
|
||||
config.menu_state = "controls_help"
|
||||
elif sel == 1: # Remap
|
||||
if os.path.exists(config.CONTROLS_CONFIG_PATH):
|
||||
try:
|
||||
os.remove(config.CONTROLS_CONFIG_PATH)
|
||||
logger.debug(f"Fichier de configuration des contrôles supprimé: {config.CONTROLS_CONFIG_PATH}")
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de la suppression du fichier de configuration des contrôles: {e}")
|
||||
logger.error(f"Erreur suppression controls_config: {e}")
|
||||
config.previous_menu_state = "pause_controls_menu"
|
||||
config.menu_state = "controls_mapping"
|
||||
else: # Back
|
||||
config.menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "cancel") or is_input_matched(event, "start"):
|
||||
config.menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
|
||||
# Sous-menu Display
|
||||
elif config.menu_state == "pause_display_menu":
|
||||
sel = getattr(config, 'pause_display_selection', 0)
|
||||
total = 6 # layout, font, unsupported, unknown, filter, back
|
||||
if is_input_matched(event, "up"):
|
||||
config.pause_display_selection = (sel - 1) % total
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "down"):
|
||||
config.pause_display_selection = (sel + 1) % total
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm"):
|
||||
sel = getattr(config, 'pause_display_selection', 0)
|
||||
# 0 layout cycle
|
||||
if sel == 0 and (is_input_matched(event, "left") or is_input_matched(event, "right")):
|
||||
layouts = [(3,3),(3,4),(4,3),(4,4)]
|
||||
try:
|
||||
idx = layouts.index((config.GRID_COLS, config.GRID_ROWS))
|
||||
except ValueError:
|
||||
idx = 0
|
||||
idx = (idx + 1) % len(layouts) if is_input_matched(event, "right") else (idx - 1) % len(layouts)
|
||||
new_cols, new_rows = layouts[idx]
|
||||
try:
|
||||
from rgsx_settings import set_display_grid
|
||||
set_display_grid(new_cols, new_rows)
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur set_display_grid: {e}")
|
||||
config.GRID_COLS = new_cols
|
||||
config.GRID_ROWS = new_rows
|
||||
# Redémarrage automatique
|
||||
try:
|
||||
from utils import restart_application
|
||||
config.menu_state = "restart_popup"
|
||||
config.popup_message = _("popup_restarting") if _ else "Restarting..."
|
||||
config.popup_timer = 2000
|
||||
restart_application(2000)
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur restart après layout: {e}")
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Passage à controls_mapping depuis pause_menu")
|
||||
elif config.selected_option == 2: # History
|
||||
# 1 font size
|
||||
elif sel == 1 and (is_input_matched(event, "left") or is_input_matched(event, "right")):
|
||||
from accessibility import save_accessibility_settings
|
||||
opts = getattr(config, 'font_scale_options', [0.75,1.0,1.25,1.5,1.75])
|
||||
idx = getattr(config, 'current_font_scale_index', 1)
|
||||
idx = max(0, idx-1) if is_input_matched(event, "left") else min(len(opts)-1, idx+1)
|
||||
if idx != getattr(config, 'current_font_scale_index', 1):
|
||||
config.current_font_scale_index = idx
|
||||
scale = opts[idx]
|
||||
config.accessibility_settings["font_scale"] = scale
|
||||
try:
|
||||
save_accessibility_settings(config.accessibility_settings)
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur sauvegarde accessibilité: {e}")
|
||||
try:
|
||||
config.init_font()
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur init polices: {e}")
|
||||
config.needs_redraw = True
|
||||
# 2 unsupported toggle
|
||||
elif sel == 2 and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
try:
|
||||
from rgsx_settings import get_show_unsupported_platforms, set_show_unsupported_platforms
|
||||
current = get_show_unsupported_platforms()
|
||||
new_val = set_show_unsupported_platforms(not current)
|
||||
from utils import load_sources
|
||||
load_sources()
|
||||
config.popup_message = _("menu_show_unsupported_enabled") if new_val else _("menu_show_unsupported_disabled")
|
||||
config.popup_timer = 3000
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur toggle unsupported: {e}")
|
||||
# 3 allow unknown extensions
|
||||
elif sel == 3 and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
try:
|
||||
from rgsx_settings import get_allow_unknown_extensions, set_allow_unknown_extensions
|
||||
current = get_allow_unknown_extensions()
|
||||
new_val = set_allow_unknown_extensions(not current)
|
||||
config.popup_message = _("menu_allow_unknown_ext_enabled") if new_val else _("menu_allow_unknown_ext_disabled")
|
||||
config.popup_timer = 3000
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur toggle allow_unknown_extensions: {e}")
|
||||
# 4 filter platforms
|
||||
elif sel == 4 and (is_input_matched(event, "confirm") or is_input_matched(event, "right")):
|
||||
config.filter_return_to = "pause_display_menu"
|
||||
config.menu_state = "filter_platforms"
|
||||
config.selected_filter_index = 0
|
||||
config.filter_platforms_scroll_offset = 0
|
||||
config.needs_redraw = True
|
||||
# 5 back
|
||||
elif sel == 5 and (is_input_matched(event, "confirm")):
|
||||
config.menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "cancel") or is_input_matched(event, "start"):
|
||||
config.menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
|
||||
# Sous-menu Games
|
||||
elif config.menu_state == "pause_games_menu":
|
||||
sel = getattr(config, 'pause_games_selection', 0)
|
||||
total = 4 # history, source, redownload, back
|
||||
if is_input_matched(event, "up"):
|
||||
config.pause_games_selection = (sel - 1) % total
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "down"):
|
||||
config.pause_games_selection = (sel + 1) % total
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "confirm") or is_input_matched(event, "left") or is_input_matched(event, "right"):
|
||||
sel = getattr(config, 'pause_games_selection', 0)
|
||||
if sel == 0 and is_input_matched(event, "confirm"): # history
|
||||
config.history = load_history()
|
||||
config.current_history_item = 0
|
||||
config.history_scroll_offset = 0
|
||||
config.previous_menu_state = validate_menu_state(config.previous_menu_state)
|
||||
config.previous_menu_state = "pause_games_menu"
|
||||
config.menu_state = "history"
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Passage à history depuis pause_menu")
|
||||
elif config.selected_option == 3: # Language
|
||||
config.previous_menu_state = validate_menu_state(config.previous_menu_state)
|
||||
config.menu_state = "language_select"
|
||||
config.selected_language_index = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Passage à language_select depuis pause_menu")
|
||||
elif config.selected_option == 4: # Display
|
||||
config.previous_menu_state = validate_menu_state(config.previous_menu_state)
|
||||
config.menu_state = "display_menu"
|
||||
if not hasattr(config, 'display_menu_selection'):
|
||||
config.display_menu_selection = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug("Passage au menu affichage")
|
||||
elif config.selected_option == 5: # Source toggle (index shifted by removal of filter)
|
||||
elif sel == 1 and (is_input_matched(event, "confirm") or is_input_matched(event, "left") or is_input_matched(event, "right")):
|
||||
try:
|
||||
from rgsx_settings import get_sources_mode, set_sources_mode
|
||||
current_mode = get_sources_mode()
|
||||
@@ -1208,13 +1281,33 @@ def handle_controls(event, sources, joystick, screen):
|
||||
logger.info(f"Changement du mode des sources vers {new_mode}")
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur changement mode sources: {e}")
|
||||
elif config.selected_option == 6: # Redownload game cache
|
||||
config.previous_menu_state = validate_menu_state(config.previous_menu_state)
|
||||
elif sel == 2 and is_input_matched(event, "confirm"): # redownload cache
|
||||
config.previous_menu_state = "pause_games_menu"
|
||||
config.menu_state = "reload_games_data"
|
||||
config.redownload_confirm_selection = 0
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Passage à reload_games_data depuis pause_menu")
|
||||
elif config.selected_option == 7: # Music toggle
|
||||
elif sel == 3 and is_input_matched(event, "confirm"): # back
|
||||
config.menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "cancel") or is_input_matched(event, "start"):
|
||||
config.menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
|
||||
# Sous-menu Settings
|
||||
elif config.menu_state == "pause_settings_menu":
|
||||
sel = getattr(config, 'pause_settings_selection', 0)
|
||||
total = 4 # music, symlink, api keys, back
|
||||
if is_input_matched(event, "up"):
|
||||
config.pause_settings_selection = (sel - 1) % total
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "down"):
|
||||
config.pause_settings_selection = (sel + 1) % total
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "confirm") or is_input_matched(event, "left") or is_input_matched(event, "right"):
|
||||
sel = getattr(config, 'pause_settings_selection', 0)
|
||||
if sel == 0 and (is_input_matched(event, "confirm") or is_input_matched(event, "left") or is_input_matched(event, "right")):
|
||||
config.music_enabled = not config.music_enabled
|
||||
save_music_config()
|
||||
if config.music_enabled:
|
||||
@@ -1225,28 +1318,32 @@ def handle_controls(event, sources, joystick, screen):
|
||||
else:
|
||||
pygame.mixer.music.stop()
|
||||
config.needs_redraw = True
|
||||
logger.info(f"Musique {'activée' if config.music_enabled else 'désactivée'} via menu pause")
|
||||
elif config.selected_option == 8: # Symlink option
|
||||
logger.info(f"Musique {'activée' if config.music_enabled else 'désactivée'} via settings")
|
||||
elif sel == 1 and (is_input_matched(event, "confirm") or is_input_matched(event, "left") or is_input_matched(event, "right")):
|
||||
from rgsx_settings import set_symlink_option, get_symlink_option
|
||||
current_status = get_symlink_option()
|
||||
success, message = set_symlink_option(not current_status)
|
||||
config.popup_message = message
|
||||
config.popup_timer = 3000 if success else 5000
|
||||
config.needs_redraw = True
|
||||
logger.info(f"Symlink option {'activée' if not current_status else 'désactivée'} via menu pause")
|
||||
elif config.selected_option == 9: # Restart
|
||||
from utils import restart_application
|
||||
restart_application(2000)
|
||||
elif config.selected_option == 10: # Quit
|
||||
config.previous_menu_state = validate_menu_state(config.previous_menu_state)
|
||||
config.menu_state = "confirm_exit"
|
||||
config.confirm_selection = 0
|
||||
logger.info(f"Symlink option {'activée' if not current_status else 'désactivée'} via settings")
|
||||
elif sel == 2 and is_input_matched(event, "confirm"):
|
||||
config.menu_state = "pause_api_keys_status"
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Passage à confirm_exit depuis pause_menu")
|
||||
elif is_input_matched(event, "cancel"):
|
||||
config.menu_state = validate_menu_state(config.previous_menu_state)
|
||||
elif sel == 3 and is_input_matched(event, "confirm"):
|
||||
config.menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
elif is_input_matched(event, "cancel") or is_input_matched(event, "start"):
|
||||
config.menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
|
||||
elif config.menu_state == "pause_api_keys_status":
|
||||
if is_input_matched(event, "cancel") or is_input_matched(event, "confirm") or is_input_matched(event, "start"):
|
||||
config.menu_state = "pause_settings_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Retour à {config.menu_state} depuis pause_menu")
|
||||
|
||||
# Aide contrôles
|
||||
elif config.menu_state == "controls_help":
|
||||
@@ -1535,9 +1632,10 @@ def handle_controls(event, sources, joystick, screen):
|
||||
# Return either to display menu or pause menu depending on origin
|
||||
target = getattr(config, 'filter_return_to', 'pause_menu')
|
||||
config.menu_state = target
|
||||
if target == 'display_menu':
|
||||
# reset display selection to the Filter item for convenience
|
||||
if target == 'display_menu': # ancien cas (fallback)
|
||||
config.display_menu_selection = 3
|
||||
elif target == 'pause_display_menu': # nouveau sous-menu hiérarchique
|
||||
config.pause_display_selection = 4 # positionner sur Filter
|
||||
else:
|
||||
config.selected_option = 5 # keep pointer on Filter in pause menu
|
||||
config.filter_return_to = None
|
||||
@@ -1546,6 +1644,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.menu_state = target
|
||||
if target == 'display_menu':
|
||||
config.display_menu_selection = 3
|
||||
elif target == 'pause_display_menu':
|
||||
config.pause_display_selection = 4
|
||||
else:
|
||||
config.selected_option = 5
|
||||
config.filter_return_to = None
|
||||
@@ -1555,6 +1655,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.menu_state = target
|
||||
if target == 'display_menu':
|
||||
config.display_menu_selection = 3
|
||||
elif target == 'pause_display_menu':
|
||||
config.pause_display_selection = 4
|
||||
else:
|
||||
config.selected_option = 5
|
||||
config.filter_return_to = None
|
||||
|
||||
@@ -1403,54 +1403,178 @@ def draw_display_menu(screen):
|
||||
screen.blit(instruction_surface, instruction_rect)
|
||||
|
||||
def draw_pause_menu(screen, selected_option):
|
||||
"""Dessine le menu pause avec un style moderne."""
|
||||
"""Dessine le menu pause racine (catégories)."""
|
||||
screen.blit(OVERLAY, (0, 0))
|
||||
from rgsx_settings import get_symlink_option, get_sources_mode, get_show_unsupported_platforms
|
||||
mode = get_sources_mode()
|
||||
source_label = _("games_source_rgsx") if mode == "rgsx" else _("games_source_custom")
|
||||
if config.music_enabled:
|
||||
music_name = config.current_music_name or ""
|
||||
music_option = _("menu_music_enabled").format(music_name)
|
||||
else:
|
||||
music_option = _("menu_music_disabled")
|
||||
symlink_option = _("symlink_option_enabled") if get_symlink_option() else _("symlink_option_disabled")
|
||||
# Nouvel ordre: Language / Controls / Display / Games / Settings / Restart / Quit
|
||||
options = [
|
||||
_("menu_controls"), # 0
|
||||
_("menu_remap_controls"), # 1
|
||||
_("menu_history"), # 2
|
||||
_("menu_language"), # 3
|
||||
_("menu_display"), # 4 new merged display menu
|
||||
f"{_('menu_games_source_prefix')}: {source_label}", # 5 (shifted left)
|
||||
_("menu_redownload_cache"), # 6
|
||||
music_option, # 7
|
||||
symlink_option, # 8
|
||||
_("menu_restart"), # 9 (new)
|
||||
_("menu_quit") # 10
|
||||
_("menu_language") if _ else "Language", # 0 -> sélecteur de langue direct
|
||||
_("menu_controls"), # 1 -> sous-menu controls
|
||||
_("menu_display"), # 2 -> sous-menu display
|
||||
_("menu_games") if _ else "Games", # 3 -> sous-menu games (history + sources + update)
|
||||
_("menu_settings_category") if _ else "Settings", # 4 -> sous-menu settings
|
||||
_("menu_restart"), # 5 -> reboot
|
||||
_("menu_quit") # 6 -> quit
|
||||
]
|
||||
menu_width = int(config.screen_width * 0.8)
|
||||
line_height = config.font.get_height() + 10
|
||||
button_height = int(config.screen_height * 0.0463)
|
||||
margin_top_bottom = 20
|
||||
menu_height = len(options) * (button_height + 10) + 2 * margin_top_bottom
|
||||
menu_width = int(config.screen_width * 0.6)
|
||||
button_height = int(config.screen_height * 0.048)
|
||||
margin_top_bottom = 24
|
||||
menu_height = len(options) * (button_height + 12) + 2 * margin_top_bottom
|
||||
menu_x = (config.screen_width - menu_width) // 2
|
||||
menu_y = (config.screen_height - menu_height) // 2
|
||||
|
||||
pygame.draw.rect(screen, THEME_COLORS["button_idle"], (menu_x, menu_y, menu_width, menu_height), border_radius=12)
|
||||
pygame.draw.rect(screen, THEME_COLORS["border"], (menu_x, menu_y, menu_width, menu_height), 2, border_radius=12)
|
||||
|
||||
for i, option in enumerate(options):
|
||||
draw_stylized_button(
|
||||
screen,
|
||||
option,
|
||||
menu_x + 20,
|
||||
menu_y + margin_top_bottom + i * (button_height + 10),
|
||||
menu_y + margin_top_bottom + i * (button_height + 12),
|
||||
menu_width - 40,
|
||||
button_height,
|
||||
selected=i == selected_option
|
||||
)
|
||||
# Stocker le nombre total d'options pour la navigation dynamique
|
||||
config.pause_menu_total_options = len(options)
|
||||
|
||||
def _draw_submenu_generic(screen, title, options, selected_index):
|
||||
"""Helper générique pour dessiner un sous-menu hiérarchique."""
|
||||
screen.blit(OVERLAY, (0, 0))
|
||||
menu_width = int(config.screen_width * 0.72)
|
||||
button_height = int(config.screen_height * 0.045)
|
||||
margin_top_bottom = 26
|
||||
menu_height = (len(options)+1) * (button_height + 10) + 2 * margin_top_bottom # +1 pour le titre
|
||||
menu_x = (config.screen_width - menu_width) // 2
|
||||
menu_y = (config.screen_height - menu_height) // 2
|
||||
pygame.draw.rect(screen, THEME_COLORS["button_idle"], (menu_x, menu_y, menu_width, menu_height), border_radius=14)
|
||||
pygame.draw.rect(screen, THEME_COLORS["border"], (menu_x, menu_y, menu_width, menu_height), 2, border_radius=14)
|
||||
# Title
|
||||
title_surface = config.font.render(title, True, THEME_COLORS["text"])
|
||||
title_rect = title_surface.get_rect(center=(config.screen_width//2, menu_y + margin_top_bottom//2 + title_surface.get_height()//2))
|
||||
screen.blit(title_surface, title_rect)
|
||||
# Options
|
||||
start_y = title_rect.bottom + 10
|
||||
for i, opt in enumerate(options):
|
||||
draw_stylized_button(
|
||||
screen,
|
||||
opt,
|
||||
menu_x + 20,
|
||||
start_y + i * (button_height + 10),
|
||||
menu_width - 40,
|
||||
button_height,
|
||||
selected=(i == selected_index)
|
||||
)
|
||||
|
||||
def draw_pause_controls_menu(screen, selected_index):
|
||||
options = [
|
||||
_("menu_controls"), # aide contrôles (réutilisée)
|
||||
_("menu_remap_controls"), # remap
|
||||
_("menu_back") if _ else "Back"
|
||||
]
|
||||
_draw_submenu_generic(screen, _("menu_controls") if _ else "Controls", options, selected_index)
|
||||
|
||||
def draw_pause_display_menu(screen, selected_index):
|
||||
from rgsx_settings import get_show_unsupported_platforms, get_allow_unknown_extensions
|
||||
# Layout label
|
||||
layouts = [(3,3),(3,4),(4,3),(4,4)]
|
||||
try:
|
||||
idx = layouts.index((config.GRID_COLS, config.GRID_ROWS))
|
||||
except ValueError:
|
||||
idx = 0
|
||||
layout_value = f"{layouts[idx][0]}x{layouts[idx][1]}"
|
||||
layout_txt = f"{_('submenu_display_layout') if _ else 'Layout'}: < {layout_value} >"
|
||||
# Font size
|
||||
opts = getattr(config, 'font_scale_options', [0.75, 1.0, 1.25, 1.5, 1.75])
|
||||
cur_idx = getattr(config, 'current_font_scale_index', 1)
|
||||
font_value = f"{opts[cur_idx]}x"
|
||||
font_txt = f"{_('submenu_display_font_size') if _ else 'Font Size'}: < {font_value} >"
|
||||
unsupported = get_show_unsupported_platforms()
|
||||
status_unsupported = _('status_on') if unsupported else _('status_off')
|
||||
# Construire label sans statut pour insérer les chevrons proprement
|
||||
raw_unsupported_label = _('submenu_display_show_unsupported') if _ else 'Show unsupported systems: {status}'
|
||||
# Retirer éventuel placeholder et ponctuation finale
|
||||
if '{status}' in raw_unsupported_label:
|
||||
raw_unsupported_label = raw_unsupported_label.split('{status}')[0].rstrip(' :')
|
||||
unsupported_txt = f"{raw_unsupported_label}: < {status_unsupported} >"
|
||||
allow_unknown = get_allow_unknown_extensions()
|
||||
status_unknown = _('status_on') if allow_unknown else _('status_off')
|
||||
raw_unknown_label = _('submenu_display_allow_unknown_ext') if _ else 'Hide unknown ext warn: {status}'
|
||||
if '{status}' in raw_unknown_label:
|
||||
raw_unknown_label = raw_unknown_label.split('{status}')[0].rstrip(' :')
|
||||
unknown_txt = f"{raw_unknown_label}: < {status_unknown} >"
|
||||
filter_txt = _("submenu_display_filter_platforms") if _ else "Filter Platforms"
|
||||
back_txt = _("menu_back") if _ else "Back"
|
||||
options = [layout_txt, font_txt, unsupported_txt, unknown_txt, filter_txt, back_txt]
|
||||
_draw_submenu_generic(screen, _("menu_display"), options, selected_index)
|
||||
|
||||
def draw_pause_games_menu(screen, selected_index):
|
||||
from rgsx_settings import get_sources_mode
|
||||
mode = get_sources_mode()
|
||||
source_label = _("games_source_rgsx") if mode == "rgsx" else _("games_source_custom")
|
||||
source_txt = f"{_('menu_games_source_prefix')}: < {source_label} >"
|
||||
update_txt = _("menu_redownload_cache")
|
||||
# Première entrée: Historique des téléchargements (utiliser la clé menu_history)
|
||||
history_txt = _("menu_history") if _ else "History"
|
||||
back_txt = _("menu_back") if _ else "Back"
|
||||
options = [history_txt, source_txt, update_txt, back_txt]
|
||||
_draw_submenu_generic(screen, _("menu_games") if _ else "Games", options, selected_index)
|
||||
|
||||
def draw_pause_settings_menu(screen, selected_index):
|
||||
from rgsx_settings import get_symlink_option
|
||||
# Music
|
||||
if config.music_enabled:
|
||||
music_name = config.current_music_name or ""
|
||||
music_option = _("menu_music_enabled").format(music_name)
|
||||
else:
|
||||
music_option = _("menu_music_disabled")
|
||||
# Uniformiser en < value > pour les réglages basculables
|
||||
if ' : ' in music_option:
|
||||
base, val = music_option.split(' : ',1)
|
||||
music_option = f"{base} : < {val.strip()} >"
|
||||
symlink_option = _("symlink_option_enabled") if get_symlink_option() else _("symlink_option_disabled")
|
||||
if ' ' in symlink_option:
|
||||
parts = symlink_option.split(' ',1)
|
||||
# On garde phrase intacte si elle n'a pas de forme label: valeur ; sinon transformer
|
||||
if ' : ' in symlink_option:
|
||||
base, val = symlink_option.split(' : ',1)
|
||||
symlink_option = f"{base} : < {val.strip()} >"
|
||||
api_keys_txt = _("menu_api_keys_status") if _ else "API Keys"
|
||||
back_txt = _("menu_back") if _ else "Back"
|
||||
options = [music_option, symlink_option, api_keys_txt, back_txt]
|
||||
_draw_submenu_generic(screen, _("menu_settings_category") if _ else "Settings", options, selected_index)
|
||||
|
||||
def draw_pause_api_keys_status(screen):
|
||||
screen.blit(OVERLAY, (0,0))
|
||||
from utils import load_api_keys
|
||||
keys = load_api_keys()
|
||||
# Layout simple
|
||||
lines = [
|
||||
_("api_keys_status_title") if _ else "API Keys Status",
|
||||
("1fichier", keys.get('1fichier')),
|
||||
("AllDebrid", keys.get('alldebrid'))
|
||||
]
|
||||
menu_width = int(config.screen_width * 0.55)
|
||||
menu_height = int(config.screen_height * 0.35)
|
||||
menu_x = (config.screen_width - menu_width)//2
|
||||
menu_y = (config.screen_height - menu_height)//2
|
||||
pygame.draw.rect(screen, THEME_COLORS["button_idle"], (menu_x, menu_y, menu_width, menu_height), border_radius=16)
|
||||
pygame.draw.rect(screen, THEME_COLORS["border"], (menu_x, menu_y, menu_width, menu_height), 2, border_radius=16)
|
||||
title_surface = config.font.render(lines[0], True, THEME_COLORS["text"])
|
||||
title_rect = title_surface.get_rect(center=(config.screen_width//2, menu_y + 40))
|
||||
screen.blit(title_surface, title_rect)
|
||||
status_on = _("status_present") if _ else "Present"
|
||||
status_off = _("status_missing") if _ else "Missing"
|
||||
y = title_rect.bottom + 20
|
||||
for provider, present in lines[1:]:
|
||||
status_txt = status_on if present else status_off
|
||||
text = f"{provider}: {status_txt}"
|
||||
surf = config.small_font.render(text, True, THEME_COLORS["text"])
|
||||
rect = surf.get_rect(center=(config.screen_width//2, y))
|
||||
screen.blit(surf, rect)
|
||||
y += surf.get_height() + 12
|
||||
back_txt = _("menu_back") if _ else "Back"
|
||||
back_surf = config.small_font.render(back_txt, True, THEME_COLORS["fond_lignes"]) # Indication
|
||||
back_rect = back_surf.get_rect(center=(config.screen_width//2, menu_y + menu_height - 30))
|
||||
screen.blit(back_surf, back_rect)
|
||||
|
||||
def draw_filter_platforms_menu(screen):
|
||||
"""Affiche le menu de filtrage des plateformes (afficher/masquer)."""
|
||||
from rgsx_settings import load_rgsx_settings
|
||||
@@ -1591,8 +1715,11 @@ def draw_controls_help(screen, previous_state):
|
||||
|
||||
# États autorisés (même logique qu'avant)
|
||||
allowed_states = {
|
||||
# États classiques où l'aide était accessible
|
||||
"error", "platform", "game", "confirm_exit",
|
||||
"extension_warning", "history", "clear_history"
|
||||
"extension_warning", "history", "clear_history",
|
||||
# Nouveaux états hiérarchiques pause
|
||||
"pause_controls_menu", "pause_menu"
|
||||
}
|
||||
if previous_state not in allowed_states:
|
||||
return
|
||||
|
||||
@@ -51,7 +51,6 @@ def save_history(history):
|
||||
os.makedirs(os.path.dirname(history_path), exist_ok=True)
|
||||
with open(history_path, "w", encoding='utf-8') as f:
|
||||
json.dump(history, f, indent=2, ensure_ascii=False)
|
||||
logger.debug(f"Historique sauvegardé dans {history_path}")
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de l'écriture de {history_path} : {e}")
|
||||
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
{
|
||||
"controls_mapping_title": "Steuerung konfigurieren",
|
||||
"controls_mapping_instruction": "3 Sekunden halten zum Konfigurieren:",
|
||||
"controls_mapping_waiting": "Warte auf eine Taste oder einen Button...",
|
||||
"controls_mapping_press": "Drücke eine Taste oder einen Button",
|
||||
"welcome_message": "Willkommen bei RGSX",
|
||||
"disclaimer_line1": "Es ist gefährlich, allein zu gehen, nimm alles, was du brauchst!",
|
||||
"disclaimer_line2": "Aber lade nur Spiele herunter,",
|
||||
"disclaimer_line3": "von denen du die Originale besitzt!",
|
||||
"disclaimer_line4": "RGSX ist nicht verantwortlich für heruntergeladene Inhalte,",
|
||||
"disclaimer_line5": "und hostet keine ROMs.",
|
||||
|
||||
"loading_test_connection": "Verbindung wird getestet...",
|
||||
"loading_download_data": "Spiele und Bilder werden heruntergeladen...",
|
||||
"loading_progress": "Fortschritt: {0}%",
|
||||
@@ -19,27 +14,18 @@
|
||||
"loading_extracting_data": "Der initiale Datenordner wird entpackt...",
|
||||
"loading_load_systems": "Systeme werden geladen...",
|
||||
"error_extract_data_failed": "Herunterladen oder Entpacken des initialen Datenordners fehlgeschlagen.",
|
||||
"error_sources_load_failed": "Quellen konnten nicht geladen werden. Öffne das Menü und wähle dann Spiele-Cache erneut herunterladen",
|
||||
|
||||
"error_no_internet": "Keine Internetverbindung. Überprüfe dein Netzwerk.",
|
||||
"error_controls_mapping": "Fehler beim Zuordnen der Steuerung",
|
||||
"error_api_key": "Achtung, du musst deinen API-Schlüssel (nur Premium) in der Datei {0} eingeben",
|
||||
"error_api_key_extended": "Achtung, du musst deinen API-Schlüssel (nur Premium) in der Datei /userdata/saves/ports/rgsx/1FichierAPI.txt einfügen. Öffne die Datei in einem Texteditor und füge den API-Schlüssel ein",
|
||||
"error_invalid_download_data": "Ungültige Downloaddaten",
|
||||
"error_delete_sources": "Fehler beim Löschen der Datei systems_list.json oder Ordner",
|
||||
"error_extension": "Nicht unterstützte Erweiterung oder Downloadfehler",
|
||||
"error_no_download": "Keine Downloads ausstehend.",
|
||||
|
||||
"platform_no_platform": "Keine Plattform",
|
||||
"platform_page": "Seite {0}/{1}",
|
||||
|
||||
"game_no_games": "Keine Spiele verfügbar",
|
||||
"game_count": "{0} ({1} Spiele)",
|
||||
"game_filter": "Aktiver Filter: {0}",
|
||||
"game_search": "Filtern: {0}",
|
||||
"game_header_name": "Name",
|
||||
"game_header_size": "Größe",
|
||||
|
||||
"history_title": "Downloads ({0})",
|
||||
"history_empty": "Keine Downloads im Verlauf",
|
||||
"history_column_system": "System",
|
||||
@@ -51,28 +37,21 @@
|
||||
"history_status_completed": "Abgeschlossen",
|
||||
"history_status_error": "Fehler: {0}",
|
||||
"history_status_canceled": "Abgebrochen",
|
||||
|
||||
"download_status": "{0}: {1}",
|
||||
"download_progress": "{0}% {1} MB / {2} MB",
|
||||
"download_canceled": "Download vom Benutzer abgebrochen.",
|
||||
|
||||
"extension_warning_zip": "Die Datei '{0}' ist ein Archiv und Batocera unterstützt keine Archive für dieses System. Die automatische Extraktion der Datei erfolgt nach dem Download, fortfahren?",
|
||||
"extension_warning_unsupported": "Die Dateierweiterung für '{0}' wird laut der Konfiguration es_systems.cfg von Batocera nicht unterstützt. Möchtest du fortfahren?",
|
||||
"extension_warning_enable_unknown_hint": "\nUm diese Meldung auszublenden: \"Warnung bei unbekannter Erweiterung ausblenden\" in Pausenmenü > Anzeige aktivieren",
|
||||
|
||||
"confirm_exit": "Anwendung beenden?",
|
||||
"confirm_exit_with_downloads": "Achtung: {0} Download(s) laufen. Trotzdem beenden?",
|
||||
"confirm_clear_history": "Verlauf löschen?",
|
||||
"confirm_redownload_cache": "Spieleliste aktualisieren?",
|
||||
|
||||
"popup_redownload_success": "Cache gelöscht, bitte die Anwendung neu starten",
|
||||
"popup_no_cache": "Kein Cache gefunden.\nBitte starte die Anwendung neu, um die Spiele zu laden.",
|
||||
"popup_countdown": "Diese Nachricht schließt in {0} Sekunde{1}",
|
||||
|
||||
"language_select_title": "Sprachauswahl",
|
||||
"language_select_instruction": "Verwende die Pfeiltasten zum Navigieren und Enter zum Auswählen",
|
||||
"language_changed": "Sprache geändert zu {0}",
|
||||
|
||||
"menu_controls": "Steuerung",
|
||||
"menu_remap_controls": "Steuerung neu zuordnen",
|
||||
"menu_history": "Verlauf",
|
||||
@@ -81,21 +60,13 @@
|
||||
"menu_display": "Anzeige",
|
||||
"display_layout": "Anzeigelayout",
|
||||
"menu_redownload_cache": "Spieleliste aktualisieren",
|
||||
"menu_music_toggle": "Musik ein/aus",
|
||||
"menu_music_enabled": "Musik aktiviert: {0}",
|
||||
"menu_music_disabled": "Musik deaktiviert",
|
||||
"menu_restart": "Neustart",
|
||||
"menu_filter_platforms": "Systeme filtern",
|
||||
"filter_platforms_title": "Systemsichtbarkeit",
|
||||
"filter_all": "Alle anzeigen",
|
||||
"filter_none": "Alle ausblenden",
|
||||
"filter_apply": "Anwenden",
|
||||
"filter_back": "Zurück",
|
||||
"filter_platforms_info": "Sichtbar: {0} | Versteckt: {1} / Gesamt: {2}",
|
||||
"filter_unsaved_warning": "Ungespeicherte Änderungen",
|
||||
"menu_show_unsupported_on": "Nicht unterstützte Systeme anzeigen: Ja",
|
||||
"menu_show_unsupported_off": "Nicht unterstützte Systeme anzeigen: Nein",
|
||||
"menu_show_unsupported_text": "systeme versteckt",
|
||||
"menu_show_unsupported_enabled": "Sichtbarkeit nicht unterstützter Systeme aktiviert",
|
||||
"menu_show_unsupported_disabled": "Sichtbarkeit nicht unterstützter Systeme deaktiviert",
|
||||
"menu_allow_unknown_ext_on": "Warnung bei unbekannter Erweiterung ausblenden: Ja",
|
||||
@@ -103,64 +74,15 @@
|
||||
"menu_allow_unknown_ext_enabled": "Ausblenden der Warnung bei unbekannter Erweiterung aktiviert",
|
||||
"menu_allow_unknown_ext_disabled": "Ausblenden der Warnung bei unbekannter Erweiterung deaktiviert",
|
||||
"menu_quit": "Beenden",
|
||||
|
||||
"button_yes": "Ja",
|
||||
"button_no": "Nein",
|
||||
"button_OK": "OK",
|
||||
"popup_restarting": "Neustart...",
|
||||
|
||||
"controls_hold_message": "3 Sekunden halten für: '{0}'",
|
||||
"controls_skip_message": "Drücke Esc, um zu überspringen (nur PC)",
|
||||
"controls_waiting": "Warten...",
|
||||
"controls_hold": "3 Sekunden halten",
|
||||
|
||||
"controls_action_confirm": "Bestätigen",
|
||||
"controls_action_cancel": "Abbrechen",
|
||||
"controls_action_up": "Hoch",
|
||||
"controls_action_down": "Runter",
|
||||
"controls_action_left": "Links",
|
||||
"controls_action_right": "Rechts",
|
||||
"controls_action_page_up": "Vorherige Seite",
|
||||
"controls_action_page_down": "Nächste Seite",
|
||||
"controls_action_clear_history": "Mehrfachauswahl / Verlauf leeren",
|
||||
"controls_action_history": "Verlauf",
|
||||
"controls_action_filter": "Filtern",
|
||||
"controls_action_delete": "Löschen",
|
||||
"controls_action_space": "Leerzeichen",
|
||||
"controls_action_start": "Hilfe / Einstellungen",
|
||||
|
||||
"controls_desc_confirm": "Bestätigen (z.B.: A, Enter)",
|
||||
"controls_desc_cancel": "Abbrechen/Zurück (z.B.: B, Rücktaste)",
|
||||
"controls_desc_up": "Nach oben navigieren",
|
||||
"controls_desc_down": "Nach unten navigieren",
|
||||
"controls_desc_left": "Nach links navigieren",
|
||||
"controls_desc_right": "Nach rechts navigieren",
|
||||
"controls_desc_page_up": "Vorherige Seite/Schnelles Scrollen nach oben (z.B.: BildAuf, LB)",
|
||||
"controls_desc_page_down": "Nächste Seite/Schnelles Scrollen nach unten (z.B.: BildAb, RB)",
|
||||
"controls_desc_clear_history": "Mehrfachauswahl (Spieleliste) / Verlauf löschen (Verlaufsmenü) (z.B.: X)",
|
||||
"controls_desc_history": "Verlauf öffnen (z.B.: H, Y)",
|
||||
"controls_desc_filter": "Filter öffnen (z.B.: F, Select)",
|
||||
"controls_desc_delete": "Zeichen löschen (z.B.: LT, Entf)",
|
||||
"controls_desc_space": "Leerzeichen hinzufügen (z.B.: RT, Leertaste)",
|
||||
"controls_desc_start": "Pausenmenü öffnen (z.B.: Start, AltGr)",
|
||||
|
||||
|
||||
"action_retry": "Wiederholen",
|
||||
"action_quit": "Beenden",
|
||||
"action_select": "Auswählen",
|
||||
"action_history": "Verlauf",
|
||||
"action_download": "Herunterladen",
|
||||
"action_filter": "Filtern",
|
||||
"action_cancel": "Abbrechen",
|
||||
"action_back": "Zurück",
|
||||
"action_navigate": "Navigieren",
|
||||
"action_page": "Seite",
|
||||
"action_cancel_download": "Download abbrechen",
|
||||
"action_background": "Hintergrund",
|
||||
"action_confirm": "Bestätigen",
|
||||
"action_redownload": "Erneut herunterladen",
|
||||
"action_clear_history": "Verlauf löschen",
|
||||
|
||||
"network_checking_updates": "Updates werden geprüft...",
|
||||
"network_update_available": "Update verfügbar: {0}",
|
||||
"network_extracting_update": "Update wird extrahiert...",
|
||||
@@ -175,7 +97,6 @@
|
||||
"network_extraction_partial": "Extraktion erfolgreich, aber einige Dateien wurden aufgrund von Fehlern übersprungen: {0}",
|
||||
"network_extraction_success": "Extraktion erfolgreich",
|
||||
"network_zip_extraction_error": "Fehler beim Extrahieren des ZIP {0}: {1}",
|
||||
"network_permission_error": "Keine Schreibberechtigung für {0}",
|
||||
"network_file_not_found": "Die Datei {0} existiert nicht",
|
||||
"network_cannot_get_filename": "Dateiname konnte nicht abgerufen werden",
|
||||
"network_cannot_get_download_url": "Download-URL konnte nicht abgerufen werden",
|
||||
@@ -191,36 +112,40 @@
|
||||
"controls_pages": "Seiten",
|
||||
"controls_confirm_select": "Bestätigen/Auswählen",
|
||||
"controls_cancel_back": "Abbrechen/Zurück",
|
||||
"controls_history": "Verlauf",
|
||||
"controls_clear_history": "Mehrfachauswahl / Verlauf",
|
||||
"controls_filter_search": "Filtern/Suchen",
|
||||
"network_download_failed": "Download nach {0} Versuchen fehlgeschlagen",
|
||||
"network_api_error": "Fehler bei der API-Anfrage, der Schlüssel könnte falsch sein: {0}",
|
||||
"network_download_error": "Downloadfehler {0}: {1}",
|
||||
"network_download_ok": "Download erfolgreich: {0}",
|
||||
|
||||
"utils_extracted": "Extrahiert: {0}",
|
||||
"utils_corrupt_zip": "Beschädigtes ZIP-Archiv: {0}",
|
||||
"utils_permission_denied": "Berechtigung während der Extraktion verweigert: {0}",
|
||||
"utils_extraction_failed": "Extraktion fehlgeschlagen: {0}",
|
||||
"utils_unrar_unavailable": "Befehl unrar nicht verfügbar",
|
||||
"utils_rar_list_failed": "Fehler beim Auflisten der RAR-Dateien: {0}",
|
||||
"utils_xdvdfs_unavailable": "xdvdfs-Tool nicht verfügbar (fehlend oder keine Berechtigung)",
|
||||
|
||||
"menu_symlink_option": "Symlink-Option",
|
||||
"symlink_option_enabled": "Symlink-Option aktiviert",
|
||||
"symlink_option_disabled": "Symlink-Option deaktiviert",
|
||||
"symlink_settings_saved_successfully": "Symlink-Einstellungen erfolgreich gespeichert",
|
||||
"symlink_settings_save_error": "Fehler beim Speichern der Symlink-Einstellungen"
|
||||
,
|
||||
"menu_games_source_prefix": "Spielquelle",
|
||||
"games_source_rgsx": "RGSX",
|
||||
"sources_mode_rgsx_select_info": "RGSX: Spieleliste aktualisieren",
|
||||
"games_source_custom": "Benutzerdefiniert"
|
||||
,
|
||||
"games_source_custom": "Benutzerdefiniert",
|
||||
"sources_mode_custom_select_info": "Benutzerdefiniert: URL in {0} setzen und Spieleliste aktualisieren",
|
||||
"sources_mode_custom_missing_url": "Keine benutzerdefinierte URL gesetzt (bearbeite {0})",
|
||||
"sources_mode_custom_download_error": "Download der benutzerdefinierten Quelle fehlgeschlagen",
|
||||
"menu_show_unsupported_and_hidden": "{0} nicht unterstützte und ausgeblendete Systeme anzeigen",
|
||||
"menu_show_unsupported_all_displayed": "Alle Systeme angezeigt"
|
||||
"menu_show_unsupported_all_displayed": "Alle Systeme angezeigt",
|
||||
"menu_settings_category": "Einstellungen",
|
||||
"menu_back": "Zurück",
|
||||
"submenu_display_layout": "Layout",
|
||||
"submenu_display_font_size": "Schriftgröße",
|
||||
"submenu_display_show_unsupported": "Nicht unterstützte Systeme: {status}",
|
||||
"submenu_display_allow_unknown_ext": "Warnung unbek. Ext verbergen: {status}",
|
||||
"submenu_display_filter_platforms": "Systeme filtern",
|
||||
"status_on": "An",
|
||||
"status_off": "Aus",
|
||||
"status_present": "Vorhanden",
|
||||
"status_missing": "Fehlt",
|
||||
"menu_api_keys_status": "API-Schlüssel",
|
||||
"api_keys_status_title": "Status der API-Schlüssel",
|
||||
"menu_games": "Spiele"
|
||||
}
|
||||
@@ -1,15 +1,10 @@
|
||||
{
|
||||
"controls_mapping_title": "Controls configuration",
|
||||
"controls_mapping_instruction": "Hold for 3s to configure:",
|
||||
"controls_mapping_waiting": "Waiting for a key or button...",
|
||||
"controls_mapping_press": "Press a key or button",
|
||||
"welcome_message": "Welcome to RGSX",
|
||||
"disclaimer_line1": "It's dangerous to go alone, take all you need!",
|
||||
"disclaimer_line2": "But only download games",
|
||||
"disclaimer_line3": "that you already own!",
|
||||
"disclaimer_line4": "RGSX is not responsible for downloaded content,",
|
||||
"disclaimer_line5": "and does not host ROMs.",
|
||||
|
||||
"loading_test_connection": "Testing connection...",
|
||||
"loading_download_data": "Downloading initial Data folder...",
|
||||
"loading_progress": "Progress: {0}%",
|
||||
@@ -19,27 +14,18 @@
|
||||
"loading_extracting_data": "Extracting initial Data folder...",
|
||||
"loading_load_systems": "Loading systems...",
|
||||
"error_extract_data_failed": "Failed to download or extract the initial Data folder.",
|
||||
"error_sources_load_failed": "Failed to load sources. Open the menu then select Redownload Games cache",
|
||||
|
||||
"error_no_internet": "No Internet connection. Check your network.",
|
||||
"error_controls_mapping": "Failed to map controls",
|
||||
"error_api_key": "Please enter your API key (premium only) in the file {0}",
|
||||
"error_api_key_extended": "Please enter your API key (premium only) in the file /userdata/saves/ports/rgsx/1FichierAPI.txt by opening it in a text editor and pasting your API key",
|
||||
"error_invalid_download_data": "Invalid download data",
|
||||
"error_delete_sources": "Error deleting systems_list.json file or folders",
|
||||
"error_extension": "Unsupported extension or download error",
|
||||
"error_no_download": "No pending download.",
|
||||
|
||||
"platform_no_platform": "No platform",
|
||||
"platform_page": "Page {0}/{1}",
|
||||
|
||||
"game_no_games": "No games available",
|
||||
"game_count": "{0} ({1} games)",
|
||||
"game_filter": "Active filter: {0}",
|
||||
"game_search": "Filter: {0}",
|
||||
"game_header_name": "Name",
|
||||
"game_header_size": "Size",
|
||||
|
||||
"history_title": "Downloads ({0})",
|
||||
"history_empty": "No downloads in history",
|
||||
"history_column_system": "System",
|
||||
@@ -51,28 +37,21 @@
|
||||
"history_status_completed": "Completed",
|
||||
"history_status_error": "Error: {0}",
|
||||
"history_status_canceled": "Canceled",
|
||||
|
||||
"download_status": "{0}: {1}",
|
||||
"download_progress": "{0}% {1} MB / {2} MB",
|
||||
"download_canceled": "Download canceled by user.",
|
||||
|
||||
"extension_warning_zip": "The file '{0}' is an archive and Batocera does not support archives for this system. Automatic extraction will occur after download, continue?",
|
||||
"extension_warning_unsupported": "The file extension for '{0}' is not supported by Batocera according to the es_systems.cfg configuration. Do you want to continue?",
|
||||
"extension_warning_enable_unknown_hint": "\nTo hide this message: enable \"Hide unknown extension warning\" in Pause Menu > Display",
|
||||
|
||||
"confirm_exit": "Exit application?",
|
||||
"confirm_exit_with_downloads": "Attention: {0} download(s) in progress. Quit anyway?",
|
||||
"confirm_clear_history": "Clear history?",
|
||||
"confirm_redownload_cache": "Update games list?",
|
||||
|
||||
"popup_redownload_success": "Cache cleared, please restart the application",
|
||||
"popup_no_cache": "No cache found.\nPlease restart the application to load games.",
|
||||
"popup_countdown": "This message will close in {0} second{1}",
|
||||
|
||||
"language_select_title": "Language Selection",
|
||||
"language_select_instruction": "Use arrow keys to navigate and Enter to select",
|
||||
"language_changed": "Language changed to {0}",
|
||||
|
||||
"menu_controls": "Controls",
|
||||
"menu_remap_controls": "Remap controls",
|
||||
"menu_history": "History",
|
||||
@@ -81,21 +60,13 @@
|
||||
"menu_display": "Display",
|
||||
"display_layout": "Display layout",
|
||||
"menu_redownload_cache": "Update games list",
|
||||
"menu_music_toggle": "Toggle music",
|
||||
"menu_music_enabled": "Music enabled: {0}",
|
||||
"menu_music_disabled": "Music disabled",
|
||||
"menu_restart": "Restart",
|
||||
"menu_filter_platforms": "Filter systems",
|
||||
"filter_platforms_title": "Systems visibility",
|
||||
"filter_all": "Show all",
|
||||
"filter_none": "Hide all",
|
||||
"filter_apply": "Apply",
|
||||
"filter_back": "Back",
|
||||
"filter_platforms_info": "Visible: {0} | Hidden: {1} / Total: {2}",
|
||||
"filter_unsaved_warning": "Unsaved changes",
|
||||
"menu_show_unsupported_on": "Show unsupported systems: Yes",
|
||||
"menu_show_unsupported_off": "Show unsupported systems: No",
|
||||
"menu_show_unsupported_text": "hidden systems",
|
||||
"menu_show_unsupported_enabled": "Unsupported systems visibility enabled",
|
||||
"menu_show_unsupported_disabled": "Unsupported systems visibility disabled",
|
||||
"menu_allow_unknown_ext_on": "Hide unknown extension warning: Yes",
|
||||
@@ -103,64 +74,15 @@
|
||||
"menu_allow_unknown_ext_enabled": "Hide unknown extension warning enabled",
|
||||
"menu_allow_unknown_ext_disabled": "Hide unknown extension warning disabled",
|
||||
"menu_quit": "Quit",
|
||||
|
||||
"button_yes": "Yes",
|
||||
"button_no": "No",
|
||||
"button_OK": "OK",
|
||||
"popup_restarting": "Restarting...",
|
||||
|
||||
"controls_hold_message": "Hold for 3s for: '{0}'",
|
||||
"controls_skip_message": "Press Esc to skip (PC only)",
|
||||
"controls_waiting": "Waiting...",
|
||||
"controls_hold": "Hold 3s",
|
||||
|
||||
"controls_action_confirm": "Confirm",
|
||||
"controls_action_cancel": "Cancel",
|
||||
"controls_action_up": "Up",
|
||||
"controls_action_down": "Down",
|
||||
"controls_action_left": "Left",
|
||||
"controls_action_right": "Right",
|
||||
"controls_action_page_up": "Previous Page",
|
||||
"controls_action_page_down": "Next Page",
|
||||
"controls_action_clear_history": "Multi-select / Clear History",
|
||||
"controls_action_history": "History",
|
||||
"controls_action_filter": "Filter",
|
||||
"controls_action_delete": "Delete",
|
||||
"controls_action_space": "Space",
|
||||
"controls_action_start": "Help / Settings",
|
||||
|
||||
"controls_desc_confirm": "Validate (e.g. A, Enter)",
|
||||
"controls_desc_cancel": "Cancel/Back (e.g. B, Backspace)",
|
||||
"controls_desc_up": "Navigate up",
|
||||
"controls_desc_down": "Navigate down",
|
||||
"controls_desc_left": "Navigate left",
|
||||
"controls_desc_right": "Navigate right",
|
||||
"controls_desc_page_up": "Previous page/Fast scroll up (e.g. PageUp, LB)",
|
||||
"controls_desc_page_down": "Next page/Fast scroll down (e.g. PageDown, RB)",
|
||||
"controls_desc_clear_history": "Multi-select (game list) / Clear history (history menu) (e.g. X)",
|
||||
"controls_desc_history": "Open history (e.g. H, Y)",
|
||||
"controls_desc_filter": "Open filter (e.g. F, Select)",
|
||||
"controls_desc_delete": "Delete character (e.g. LT, Delete)",
|
||||
"controls_desc_space": "Add space (e.g. RT, Space)",
|
||||
"controls_desc_start": "Open pause menu (e.g. Start, AltGr)",
|
||||
|
||||
|
||||
"action_retry": "Retry",
|
||||
"action_quit": "Quit",
|
||||
"action_select": "Select",
|
||||
"action_history": "History",
|
||||
"action_download": "Download",
|
||||
"action_filter": "Filter",
|
||||
"action_cancel": "Cancel",
|
||||
"action_back": "Back",
|
||||
"action_navigate": "Navigate",
|
||||
"action_page": "Page",
|
||||
"action_cancel_download": "Cancel download",
|
||||
"action_background": "Background",
|
||||
"action_confirm": "Confirm",
|
||||
"action_redownload": "Redownload",
|
||||
"action_clear_history": "Clear history",
|
||||
|
||||
"network_checking_updates": "Checking for updates...",
|
||||
"network_update_available": "Update available: {0}",
|
||||
"network_extracting_update": "Extracting update...",
|
||||
@@ -175,7 +97,6 @@
|
||||
"network_extraction_success": "Extraction successful",
|
||||
"network_download_extract_ok": "Download and extraction successful of {0}",
|
||||
"network_zip_extraction_error": "Error extracting ZIP {0}: {1}",
|
||||
"network_permission_error": "No write permission in {0}",
|
||||
"network_file_not_found": "File {0} does not exist",
|
||||
"network_cannot_get_filename": "Cannot retrieve filename",
|
||||
"network_cannot_get_download_url": "Cannot retrieve download URL",
|
||||
@@ -183,14 +104,12 @@
|
||||
"network_api_error": "API request error, the key may be incorrect: {0}",
|
||||
"network_download_error": "Download error {0}: {1}",
|
||||
"network_download_ok": "Download OK: {0}",
|
||||
|
||||
"utils_extracted": "Extracted: {0}",
|
||||
"utils_corrupt_zip": "Corrupted ZIP archive: {0}",
|
||||
"utils_permission_denied": "Permission denied during extraction: {0}",
|
||||
"utils_extraction_failed": "Extraction failed: {0}",
|
||||
"utils_unrar_unavailable": "Unrar command not available",
|
||||
"utils_rar_list_failed": "Failed to list RAR files: {0}",
|
||||
"utils_xdvdfs_unavailable": "xdvdfs tool unavailable (missing or permission denied)",
|
||||
"download_initializing": "Initializing...",
|
||||
"accessibility_font_size": "Font size: {0}",
|
||||
"confirm_cancel_download": "Cancel current download?",
|
||||
@@ -203,24 +122,30 @@
|
||||
"controls_pages": "Pages",
|
||||
"controls_confirm_select": "Confirm/Select",
|
||||
"controls_cancel_back": "Cancel/Back",
|
||||
"controls_history": "History",
|
||||
"controls_clear_history": "Multi-select / History",
|
||||
"controls_filter_search": "Filter/Search",
|
||||
|
||||
"menu_symlink_option": "Symlink Option",
|
||||
"symlink_option_enabled": "Symlink option enabled",
|
||||
"symlink_option_disabled": "Symlink option disabled",
|
||||
"symlink_settings_saved_successfully": "Symlink settings saved successfully",
|
||||
"symlink_settings_save_error": "Error saving symlink settings",
|
||||
|
||||
"menu_games_source_prefix": "Game source",
|
||||
"games_source_rgsx": "RGSX",
|
||||
"sources_mode_rgsx_select_info": "RGSX: update the games list",
|
||||
"games_source_custom": "Custom",
|
||||
|
||||
"sources_mode_custom_select_info": "Custom mode: set URL in {0} then update games list",
|
||||
"sources_mode_custom_missing_url": "No custom URL set (edit {0})",
|
||||
"sources_mode_custom_download_error": "Custom source download failed",
|
||||
"menu_show_unsupported_and_hidden": "Show unsupported and hidden {0} systems",
|
||||
"menu_show_unsupported_all_displayed": "Hide all unsupported systems"
|
||||
"menu_show_unsupported_all_displayed": "Hide all unsupported systems",
|
||||
"menu_settings_category": "Settings",
|
||||
"menu_back": "Back",
|
||||
"submenu_display_layout": "Layout",
|
||||
"submenu_display_font_size": "Font Size",
|
||||
"submenu_display_show_unsupported": "Show unsupported systems: {status}",
|
||||
"submenu_display_allow_unknown_ext": "Hide unknown ext warn: {status}",
|
||||
"submenu_display_filter_platforms": "Filter systems",
|
||||
"status_on": "On",
|
||||
"status_off": "Off",
|
||||
"status_present": "Present",
|
||||
"status_missing": "Missing",
|
||||
"menu_api_keys_status": "API Keys",
|
||||
"api_keys_status_title": "API Keys Status",
|
||||
"menu_games": "Games"
|
||||
}
|
||||
@@ -1,15 +1,10 @@
|
||||
{
|
||||
"controls_mapping_title": "Configuración de controles",
|
||||
"controls_mapping_instruction": "Mantén pulsado 3s para configurar:",
|
||||
"controls_mapping_waiting": "Esperando una tecla o botón...",
|
||||
"controls_mapping_press": "Pulsa una tecla o botón",
|
||||
"welcome_message": "Bienvenido a RGSX",
|
||||
"disclaimer_line1": "¡Es peligroso ir solo, toma todo lo que necesites!",
|
||||
"disclaimer_line2": "Pero solo descarga juegos",
|
||||
"disclaimer_line3": "de los que poseas los originales.",
|
||||
"disclaimer_line4": "RGSX no es responsable del contenido descargado,",
|
||||
"disclaimer_line5": "y no aloja ROMs.",
|
||||
|
||||
"loading_test_connection": "Probando conexión...",
|
||||
"loading_download_data": "Descargando juegos e imágenes...",
|
||||
"loading_progress": "Progreso: {0}%",
|
||||
@@ -19,28 +14,18 @@
|
||||
"loading_extracting_data": "Extrayendo la carpeta de datos inicial...",
|
||||
"loading_load_systems": "Cargando sistemas...",
|
||||
"error_extract_data_failed": "Error al descargar o extraer la carpeta de datos inicial.",
|
||||
"error_sources_load_failed": "Error al cargar las fuentes. Abre el menú y selecciona Volver a descargar la caché de juegos",
|
||||
|
||||
|
||||
"error_no_internet": "Sin conexión a Internet. Verifica tu red.",
|
||||
"error_controls_mapping": "Error al mapear los controles",
|
||||
"error_api_key": "Atención, debes ingresar tu clave API (solo premium) en el archivo {0}",
|
||||
"error_api_key_extended": "Atención, debes ingresar tu clave API (solo premium) en el archivo /userdata/saves/ports/rgsx/1FichierAPI.txt, abrirlo en un editor de texto y pegar la clave API",
|
||||
"error_invalid_download_data": "Datos de descarga no válidos",
|
||||
"error_delete_sources": "Error al eliminar el archivo systems_list.json o carpetas",
|
||||
"error_extension": "Extensión no soportada o error de descarga",
|
||||
"error_no_download": "No hay descargas pendientes.",
|
||||
|
||||
"platform_no_platform": "Ninguna plataforma",
|
||||
"platform_page": "Página {0}/{1}",
|
||||
|
||||
"game_no_games": "No hay juegos disponibles",
|
||||
"game_count": "{0} ({1} juegos)",
|
||||
"game_filter": "Filtro activo: {0}",
|
||||
"game_search": "Filtrar: {0}",
|
||||
"game_header_name": "Nombre",
|
||||
"game_header_size": "Tamaño",
|
||||
|
||||
"history_title": "Descargas ({0})",
|
||||
"history_empty": "No hay descargas en el historial",
|
||||
"history_column_system": "Sistema",
|
||||
@@ -52,28 +37,21 @@
|
||||
"history_status_completed": "Completado",
|
||||
"history_status_error": "Error: {0}",
|
||||
"history_status_canceled": "Cancelado",
|
||||
|
||||
"download_status": "{0}: {1}",
|
||||
"download_progress": "{0}% {1} MB / {2} MB",
|
||||
"download_canceled": "Descarga cancelada por el usuario.",
|
||||
|
||||
"extension_warning_zip": "El archivo '{0}' es un archivo comprimido y Batocera no soporta archivos comprimidos para este sistema. La extracción automática del archivo se realizará después de la descarga, ¿continuar?",
|
||||
"extension_warning_unsupported": "La extensión del archivo '{0}' no está soportada por Batocera según la configuración es_systems.cfg. ¿Deseas continuar?",
|
||||
"extension_warning_enable_unknown_hint": "\nPara no mostrar este mensaje: activa \"Ocultar aviso de extensión desconocida\" en Menú de pausa > Pantalla",
|
||||
|
||||
"confirm_exit": "¿Salir de la aplicación?",
|
||||
"confirm_exit_with_downloads": "Atención: {0} descarga(s) en curso. ¿Salir de todas formas?",
|
||||
"confirm_clear_history": "¿Vaciar el historial?",
|
||||
"confirm_redownload_cache": "¿Actualizar la lista de juegos?",
|
||||
|
||||
"popup_redownload_success": "Caché borrada, por favor reinicia la aplicación",
|
||||
"popup_no_cache": "No se encontró caché.\nPor favor, reinicia la aplicación para cargar los juegos.",
|
||||
"popup_countdown": "Este mensaje se cerrará en {0} segundo{1}",
|
||||
|
||||
"language_select_title": "Selección de idioma",
|
||||
"language_select_instruction": "Usa las flechas para navegar y Enter para seleccionar",
|
||||
"language_changed": "Idioma cambiado a {0}",
|
||||
|
||||
"menu_controls": "Controles",
|
||||
"menu_remap_controls": "Remapear controles",
|
||||
"menu_history": "Historial",
|
||||
@@ -82,21 +60,13 @@
|
||||
"menu_display": "Pantalla",
|
||||
"display_layout": "Distribución",
|
||||
"menu_redownload_cache": "Actualizar lista de juegos",
|
||||
"menu_music_toggle": "Activar/Desactivar música",
|
||||
"menu_music_enabled": "Música activada: {0}",
|
||||
"menu_music_disabled": "Música desactivada",
|
||||
"menu_restart": "Reiniciar",
|
||||
"menu_filter_platforms": "Filtrar sistemas",
|
||||
"filter_platforms_title": "Visibilidad de sistemas",
|
||||
"filter_all": "Mostrar todo",
|
||||
"filter_none": "Ocultar todo",
|
||||
"filter_apply": "Aplicar",
|
||||
"filter_back": "Volver",
|
||||
"filter_platforms_info": "Visibles: {0} | Ocultos: {1} / Total: {2}",
|
||||
"filter_unsaved_warning": "Cambios no guardados",
|
||||
"menu_show_unsupported_on": "Mostrar sistemas no soportados: Sí",
|
||||
"menu_show_unsupported_off": "Mostrar sistemas no soportados: No",
|
||||
"menu_show_unsupported_text": "sistemas ocultos",
|
||||
"menu_show_unsupported_enabled": "Visibilidad de sistemas no soportados activada",
|
||||
"menu_show_unsupported_disabled": "Visibilidad de sistemas no soportados desactivada",
|
||||
"menu_allow_unknown_ext_on": "Ocultar aviso de extensión desconocida: Sí",
|
||||
@@ -104,64 +74,15 @@
|
||||
"menu_allow_unknown_ext_enabled": "Aviso de extensión desconocida oculto (activado)",
|
||||
"menu_allow_unknown_ext_disabled": "Aviso de extensión desconocida visible (desactivado)",
|
||||
"menu_quit": "Salir",
|
||||
|
||||
"button_yes": "Sí",
|
||||
"button_no": "No",
|
||||
"button_OK": "OK",
|
||||
"popup_restarting": "Reiniciando...",
|
||||
|
||||
"controls_hold_message": "Mantén presionado durante 3s para: '{0}'",
|
||||
"controls_skip_message": "Presiona Esc para omitir (solo PC)",
|
||||
"controls_waiting": "Esperando...",
|
||||
"controls_hold": "Mantener 3s",
|
||||
|
||||
"controls_action_confirm": "Confirmar",
|
||||
"controls_action_cancel": "Cancelar",
|
||||
"controls_action_up": "Arriba",
|
||||
"controls_action_down": "Abajo",
|
||||
"controls_action_left": "Izquierda",
|
||||
"controls_action_right": "Derecha",
|
||||
"controls_action_page_up": "Página anterior",
|
||||
"controls_action_page_down": "Página siguiente",
|
||||
"controls_action_clear_history": "Multi-selección / Vaciar historial",
|
||||
"controls_action_history": "Historial",
|
||||
"controls_action_filter": "Filtrar",
|
||||
"controls_action_delete": "Eliminar",
|
||||
"controls_action_space": "Espacio",
|
||||
"controls_action_start": "Ayuda / Configuración",
|
||||
|
||||
"controls_desc_confirm": "Validar (ej: A, Enter)",
|
||||
"controls_desc_cancel": "Cancelar/Volver (ej: B, Retroceso)",
|
||||
"controls_desc_up": "Navegar hacia arriba",
|
||||
"controls_desc_down": "Navegar hacia abajo",
|
||||
"controls_desc_left": "Navegar a izquierda",
|
||||
"controls_desc_right": "Navegar a derecha",
|
||||
"controls_desc_page_up": "Página anterior/Desplazamiento rápido arriba (ej: RePág, LB)",
|
||||
"controls_desc_page_down": "Página siguiente/Desplazamiento rápido abajo (ej: AvPág, RB)",
|
||||
"controls_desc_clear_history": "Multi-selección (lista juegos) / Vaciar historial (menú historial) (ej: X)",
|
||||
"controls_desc_history": "Abrir historial (ej: H, Y)",
|
||||
"controls_desc_filter": "Abrir filtro (ej: F, Select)",
|
||||
"controls_desc_delete": "Eliminar carácter (ej: LT, Supr)",
|
||||
"controls_desc_space": "Añadir espacio (ej: RT, Espacio)",
|
||||
"controls_desc_start": "Abrir el menú de pausa (ej: Start, AltGr)",
|
||||
|
||||
|
||||
"action_retry": "Reintentar",
|
||||
"action_quit": "Salir",
|
||||
"action_select": "Seleccionar",
|
||||
"action_history": "Historial",
|
||||
"action_download": "Descargar",
|
||||
"action_filter": "Filtrar",
|
||||
"action_cancel": "Cancelar",
|
||||
"action_back": "Volver",
|
||||
"action_navigate": "Navegar",
|
||||
"action_page": "Página",
|
||||
"action_cancel_download": "Cancelar la descarga",
|
||||
"action_background": "Fondo",
|
||||
"action_confirm": "Confirmar",
|
||||
"action_redownload": "Volver a descargar",
|
||||
"action_clear_history": "Vaciar el historial",
|
||||
|
||||
"network_checking_updates": "Verificando actualizaciones...",
|
||||
"network_update_available": "Actualización disponible: {0}",
|
||||
"network_extracting_update": "Extrayendo la actualización...",
|
||||
@@ -176,7 +97,6 @@
|
||||
"network_extraction_partial": "Extracción exitosa, pero algunos archivos fueron omitidos debido a errores: {0}",
|
||||
"network_extraction_success": "Extracción exitosa",
|
||||
"network_zip_extraction_error": "Error al extraer el ZIP {0}: {1}",
|
||||
"network_permission_error": "Sin permiso de escritura en {0}",
|
||||
"network_file_not_found": "El archivo {0} no existe",
|
||||
"network_cannot_get_filename": "No se pudo obtener el nombre del archivo",
|
||||
"network_cannot_get_download_url": "No se pudo obtener la URL de descarga",
|
||||
@@ -192,28 +112,19 @@
|
||||
"controls_pages": "Páginas",
|
||||
"controls_confirm_select": "Confirmar/Seleccionar",
|
||||
"controls_cancel_back": "Cancelar/Volver",
|
||||
"controls_history": "Historial",
|
||||
"controls_clear_history": "Multi-selección / Historial",
|
||||
"controls_filter_search": "Filtrar/Buscar",
|
||||
"network_download_failed": "Error en la descarga tras {0} intentos",
|
||||
"network_api_error": "Error en la solicitud de API, la clave puede ser incorrecta: {0}",
|
||||
"network_download_error": "Error en la descarga {0}: {1}",
|
||||
"network_download_ok": "Descarga exitosa: {0}",
|
||||
|
||||
"utils_extracted": "Extraído: {0}",
|
||||
"utils_corrupt_zip": "Archivo ZIP corrupto: {0}",
|
||||
"utils_permission_denied": "Permiso denegado durante la extracción: {0}",
|
||||
"utils_extraction_failed": "Error en la extracción: {0}",
|
||||
"utils_unrar_unavailable": "Comando unrar no disponible",
|
||||
"utils_rar_list_failed": "Error al listar los archivos RAR: {0}",
|
||||
"utils_xdvdfs_unavailable": "Herramienta xdvdfs no disponible (faltante o sin permisos)",
|
||||
|
||||
"menu_symlink_option": "Opción Symlink",
|
||||
"symlink_option_enabled": "Opción symlink habilitada",
|
||||
"symlink_option_disabled": "Opción symlink deshabilitada",
|
||||
"symlink_settings_saved_successfully": "Configuración symlink guardada con éxito",
|
||||
"symlink_settings_save_error": "Error al guardar la configuración symlink",
|
||||
|
||||
"menu_games_source_prefix": "Origen de juegos",
|
||||
"games_source_rgsx": "RGSX",
|
||||
"sources_mode_rgsx_select_info": "RGSX: actualizar la lista de juegos",
|
||||
@@ -222,5 +133,19 @@
|
||||
"sources_mode_custom_missing_url": "No se ha establecido URL personalizada (editar {0})",
|
||||
"sources_mode_custom_download_error": "Fallo en la descarga de la fuente personalizada",
|
||||
"menu_show_unsupported_and_hidden": "Mostrar {0} sistemas no soportados y ocultos",
|
||||
"menu_show_unsupported_all_displayed": "Todos los sistemas mostrados"
|
||||
"menu_show_unsupported_all_displayed": "Todos los sistemas mostrados",
|
||||
"menu_settings_category": "Ajustes",
|
||||
"menu_back": "Volver",
|
||||
"submenu_display_layout": "Disposición",
|
||||
"submenu_display_font_size": "Tamaño Fuente",
|
||||
"submenu_display_show_unsupported": "Mostrar sistemas no soportados: {status}",
|
||||
"submenu_display_allow_unknown_ext": "Ocultar aviso ext. desconocida: {status}",
|
||||
"submenu_display_filter_platforms": "Filtrar sistemas",
|
||||
"status_on": "Sí",
|
||||
"status_off": "No",
|
||||
"status_present": "Presente",
|
||||
"status_missing": "Ausente",
|
||||
"menu_api_keys_status": "Claves API",
|
||||
"api_keys_status_title": "Estado de las claves API",
|
||||
"menu_games": "Juegos"
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
"disclaimer_line3": "dont vous possédez les originaux !",
|
||||
"disclaimer_line4": "RGSX n'est pas responsable des contenus téléchargés,",
|
||||
"disclaimer_line5": "et n'heberge pas de ROMs.",
|
||||
|
||||
"loading_test_connection": "Test de la connexion...",
|
||||
"loading_download_data": "Téléchargement des jeux et images...",
|
||||
"loading_progress": "Progression : {0}%",
|
||||
@@ -15,28 +14,18 @@
|
||||
"loading_extracting_data": "Extraction du dossier de données initial...",
|
||||
"loading_load_systems": "Chargement des systèmes...",
|
||||
"error_extract_data_failed": "Échec du téléchargement ou de l'extraction du dossier de données initial.",
|
||||
"error_sources_load_failed": "Échec de chargement des sources, ouvrir le menu puis sélectionner Retélécharger le cache des jeux",
|
||||
|
||||
|
||||
"error_no_internet": "Pas de connexion Internet. Vérifiez votre réseau.",
|
||||
"error_controls_mapping": "Échec du mappage des contrôles",
|
||||
"error_api_key": "Attention il faut renseigner sa clé API (premium only) dans le fichier {0}",
|
||||
"error_api_key_extended": "Attention il faut renseigner sa clé API (premium only) dans le fichier /userdata/saves/ports/rgsx/1FichierAPI.txt à ouvrir dans un éditeur de texte et coller la clé API",
|
||||
"error_invalid_download_data": "Données de téléchargement invalides",
|
||||
"error_delete_sources": "Erreur lors de la suppression du fichier systems_list.json ou dossiers",
|
||||
"error_extension": "Extension non supportée ou erreur de téléchargement",
|
||||
"error_no_download": "Aucun téléchargement en attente.",
|
||||
|
||||
"platform_no_platform": "Aucune plateforme",
|
||||
"platform_page": "Page {0}/{1}",
|
||||
|
||||
"game_no_games": "Aucun jeu disponible",
|
||||
"game_count": "{0} ({1} jeux)",
|
||||
"game_filter": "Filtre actif : {0}",
|
||||
"game_search": "Filtrer : {0}",
|
||||
"game_header_name": "Nom",
|
||||
"game_header_size": "Taille",
|
||||
|
||||
"history_title": "Téléchargements ({0})",
|
||||
"history_empty": "Aucun téléchargement dans l'historique",
|
||||
"history_column_system": "Système",
|
||||
@@ -48,28 +37,21 @@
|
||||
"history_status_completed": "Terminé",
|
||||
"history_status_error": "Erreur : {0}",
|
||||
"history_status_canceled": "Annulé",
|
||||
|
||||
"download_status": "{0} : {1}",
|
||||
"download_progress": "{0}% {1} Mo / {2} Mo",
|
||||
"download_canceled": "Téléchargement annulé par l'utilisateur.",
|
||||
|
||||
"extension_warning_zip": "Le fichier '{0}' est une archive et Batocera ne prend pas en charge les archives pour ce système. L'extraction automatique du fichier aura lieu après le téléchargement, continuer ?",
|
||||
"extension_warning_unsupported": "L'extension du fichier '{0}' n'est pas supportée par Batocera d'après la configuration es_systems.cfg. Voulez-vous continuer ?",
|
||||
"extension_warning_enable_unknown_hint": "\nPour ne plus afficher ce messager : Activer l'option \"Masquer avertissement\" dans le Menu Pause>Display",
|
||||
|
||||
"confirm_exit": "Quitter l'application ?",
|
||||
"confirm_exit_with_downloads": "Attention : {0} téléchargement(s) en cours. Quitter quand même ?",
|
||||
"confirm_clear_history": "Vider l'historique ?",
|
||||
"confirm_redownload_cache": "Mettre à jour la liste des jeux ?",
|
||||
|
||||
"popup_redownload_success": "Le cache a été effacé, merci de relancer l'application",
|
||||
"popup_no_cache": "Aucun cache trouvé.\nVeuillez redémarrer l'application pour charger les jeux.",
|
||||
"popup_countdown": "Ce message se fermera dans {0} seconde{1}",
|
||||
|
||||
"language_select_title": "Sélection de la langue",
|
||||
"language_select_instruction": "Utilisez les flèches pour naviguer et Entrée pour sélectionner",
|
||||
"language_changed": "Langue changée pour {0}",
|
||||
|
||||
"menu_controls": "Contrôles",
|
||||
"menu_remap_controls": "Remapper les contrôles",
|
||||
"menu_history": "Historique",
|
||||
@@ -79,85 +61,28 @@
|
||||
"display_layout": "Disposition",
|
||||
"menu_redownload_cache": "Mettre à jour la liste des jeux",
|
||||
"menu_quit": "Quitter",
|
||||
"menu_music_toggle": "Activer/Désactiver la musique",
|
||||
"menu_music_enabled": "Musique activée : {0}",
|
||||
"menu_music_disabled": "Musique désactivée",
|
||||
"menu_music_disabled": "Musique désactivée",
|
||||
"menu_restart": "Redémarrer",
|
||||
"menu_filter_platforms": "Filtrer les systèmes",
|
||||
"filter_platforms_title": "Affichage des systèmes",
|
||||
"filter_all": "Tout afficher",
|
||||
"filter_none": "Tout masquer",
|
||||
"filter_apply": "Appliquer",
|
||||
"filter_back": "Retour",
|
||||
"filter_platforms_info": "Visibles: {0} | Masqués: {1} / Total: {2}",
|
||||
"filter_unsaved_warning": "Modifications non sauvegardées",
|
||||
"menu_show_unsupported_on": "Afficher systèmes non supportés : Oui",
|
||||
"menu_show_unsupported_off": "Afficher systèmes non supportés : Non",
|
||||
"menu_show_unsupported_text": "systèmes cachés",
|
||||
"menu_show_unsupported_enabled": "Affichage systèmes non supportés activé",
|
||||
"menu_show_unsupported_disabled": "Affichage systèmes non supportés désactivé",
|
||||
"menu_allow_unknown_ext_on": "Masquer avertissement extension inconnue : Oui",
|
||||
"menu_allow_unknown_ext_off": "Masquer avertissement extension inconnue : Non",
|
||||
"menu_allow_unknown_ext_enabled": "Masquer avertissement extension inconnue activé",
|
||||
"menu_allow_unknown_ext_disabled": "Masquer avertissement extension inconnue désactivé",
|
||||
|
||||
"button_yes": "Oui",
|
||||
"button_no": "Non",
|
||||
"button_OK": "OK",
|
||||
"popup_restarting": "Redémarrage...",
|
||||
|
||||
"controls_hold_message": "Maintenez pendant 3s pour : '{0}'",
|
||||
"controls_skip_message": "Appuyez sur Échap pour passer(Pc only)",
|
||||
"controls_waiting": "Attente...",
|
||||
"controls_hold": "Maintenez 3s",
|
||||
|
||||
"controls_action_confirm": "Confirmer",
|
||||
"controls_action_cancel": "Annuler",
|
||||
"controls_action_up": "Haut",
|
||||
"controls_action_down": "Bas",
|
||||
"controls_action_left": "Gauche",
|
||||
"controls_action_right": "Droite",
|
||||
"controls_action_page_up": "Page Précédente",
|
||||
"controls_action_page_down": "Page Suivante",
|
||||
"controls_action_clear_history": "Multi-sélection / Vider Historique",
|
||||
"controls_action_history": "Historique",
|
||||
"controls_action_filter": "Filtrer",
|
||||
"controls_action_delete": "Supprimer",
|
||||
"controls_action_space": "Espace",
|
||||
"controls_action_start": "Aide / Réglages",
|
||||
|
||||
"controls_desc_confirm": "Valider (ex: A, Entrée)",
|
||||
"controls_desc_cancel": "Annuler/Retour (ex: B, Echap)",
|
||||
"controls_desc_up": "Naviguer vers le haut",
|
||||
"controls_desc_down": "Naviguer vers le bas",
|
||||
"controls_desc_left": "Naviguer à gauche",
|
||||
"controls_desc_right": "Naviguer à droite",
|
||||
"controls_desc_page_up": "Défilement Rapide - (ex: PageUp, LB)",
|
||||
"controls_desc_page_down": "Défilement Rapide + (ex: PageDown, RB)",
|
||||
"controls_desc_history": "Ouvrir l'historique (ex: H, Y)",
|
||||
"controls_desc_clear_history": "Multi-sélection (liste jeux) / Vider historique (menu historique) (ex: X)",
|
||||
"controls_desc_filter": "Mode Filtre : Ouvrir/Valider (ex: F, Select)",
|
||||
"controls_desc_delete": "Mode Filtre : Supprimer caractère (ex: LT, Suppr)",
|
||||
"controls_desc_space": "Mode Filtre : Ajouter espace (ex: RT, Espace)",
|
||||
"controls_desc_start": "Ouvrir le menu pause (ex: Start, AltGr)",
|
||||
|
||||
|
||||
"action_retry": "Retenter",
|
||||
"action_quit": "Quitter",
|
||||
"action_select": "Sélectionner",
|
||||
"action_history": "Historique",
|
||||
"action_download": "Télécharger",
|
||||
"action_filter": "Filtrer",
|
||||
"action_cancel": "Annuler",
|
||||
"action_back": "Retour",
|
||||
"action_navigate": "Naviguer",
|
||||
"action_page": "Page",
|
||||
"action_cancel_download": "Annuler le téléchargement",
|
||||
"action_background": "Arrière plan",
|
||||
"action_confirm": "Confirmer",
|
||||
"action_redownload": "Retélécharger",
|
||||
"action_clear_history": "Vider l'historique",
|
||||
|
||||
"network_checking_updates": "Vérification des mises à jour...",
|
||||
"network_update_available": "Mise à jour disponible : {0}",
|
||||
"network_extracting_update": "Extraction de la mise à jour...",
|
||||
@@ -172,10 +97,9 @@
|
||||
"network_extraction_partial": "Extraction réussie, mais certains fichiers ont été ignorés en raison d'erreurs : {0}",
|
||||
"network_extraction_success": "Extraction réussie",
|
||||
"network_zip_extraction_error": "Erreur lors de l'extraction du ZIP {0}: {1}",
|
||||
"network_permission_error": "Pas de permission d'écriture dans {0}",
|
||||
"network_file_not_found": "Le fichier {0} n'existe pas",
|
||||
"network_cannot_get_filename": "Impossible de récupérer le nom du fichier",
|
||||
"network_cannot_get_download_url": "Impossible de récupérer l'URL de téléchargement",
|
||||
"network_cannot_get_download_url": "Impossible de récupérer l'URL de téléchargement",
|
||||
"download_initializing": "Initialisation en cours...",
|
||||
"accessibility_font_size": "Taille de police : {0}",
|
||||
"confirm_cancel_download": "Annuler le téléchargement en cours ?",
|
||||
@@ -188,32 +112,19 @@
|
||||
"controls_pages": "Pages",
|
||||
"controls_confirm_select": "Confirmer/Sélectionner",
|
||||
"controls_cancel_back": "Annuler/Retour",
|
||||
"controls_history": "Historique",
|
||||
"controls_clear_history": "Multi-sélection / Historique",
|
||||
"controls_filter_search": "Filtrer/Rechercher",
|
||||
"network_download_failed": "Échec du téléchargement après {0} tentatives",
|
||||
"network_api_error": "Erreur lors de la requête API, la clé est peut-être incorrecte: {0}",
|
||||
"network_download_error": "Erreur téléchargement {0}: {1}",
|
||||
"network_download_ok": "Téléchargement ok : {0}",
|
||||
|
||||
"utils_extracted": "Extracted: {0}",
|
||||
"utils_corrupt_zip": "Archive ZIP corrompue: {0}",
|
||||
"utils_permission_denied": "Permission refusée lors de l'extraction: {0}",
|
||||
"utils_extraction_failed": "Échec de l'extraction: {0}",
|
||||
"utils_unrar_unavailable": "Commande unrar non disponible",
|
||||
"utils_rar_list_failed": "Échec de la liste des fichiers RAR: {0}",
|
||||
"utils_xdvdfs_unavailable": "Outil xdvdfs indisponible (manquant ou permission refusée)",
|
||||
"controls_mapping_title": "Configuration des contrôles",
|
||||
"controls_mapping_instruction": "Maintenir 3s pour configurer :",
|
||||
"controls_mapping_waiting": "En attente d'une touche ou d'un bouton...",
|
||||
"controls_mapping_press": "Appuyez sur une touche ou un bouton",
|
||||
|
||||
"menu_symlink_option": "Option Symlink",
|
||||
"symlink_option_enabled": "Option symlink activée",
|
||||
"symlink_option_disabled": "Option symlink désactivée",
|
||||
"symlink_settings_saved_successfully": "Paramètres symlink sauvegardés avec succès",
|
||||
"symlink_settings_save_error": "Erreur lors de la sauvegarde des paramètres symlink",
|
||||
|
||||
"menu_games_source_prefix": "Source des jeux",
|
||||
"games_source_rgsx": "RGSX",
|
||||
"sources_mode_rgsx_select_info": "RGSX : mettre à jour la liste des jeux",
|
||||
@@ -222,5 +133,19 @@
|
||||
"sources_mode_custom_missing_url": "Aucune URL personnalisée définie (modifier {0})",
|
||||
"sources_mode_custom_download_error": "Échec du téléchargement de la source personnalisée",
|
||||
"menu_show_unsupported_and_hidden": "Afficher les systèmes non supportés et masqués : {0}",
|
||||
"menu_show_unsupported_all_displayed": "Tous les systèmes sont affichés"
|
||||
"menu_show_unsupported_all_displayed": "Tous les systèmes sont affichés",
|
||||
"menu_settings_category": "Réglages",
|
||||
"menu_back": "Retour",
|
||||
"submenu_display_layout": "Disposition",
|
||||
"submenu_display_font_size": "Taille Police",
|
||||
"submenu_display_show_unsupported": "Afficher systèmes non supportés : {status}",
|
||||
"submenu_display_allow_unknown_ext": "Masquer avert. ext inconnue : {status}",
|
||||
"submenu_display_filter_platforms": "Filtrer systèmes",
|
||||
"status_on": "Oui",
|
||||
"status_off": "Non",
|
||||
"status_present": "Présente",
|
||||
"status_missing": "Absente",
|
||||
"menu_api_keys_status": "Clés API",
|
||||
"api_keys_status_title": "Statut des clés API",
|
||||
"menu_games": "Jeux"
|
||||
}
|
||||
@@ -1,224 +1,151 @@
|
||||
{
|
||||
"controls_mapping_title": "Configurazione dei controlli",
|
||||
"controls_mapping_instruction": "Tieni premuto per 3s per configurare:",
|
||||
"controls_mapping_waiting": "In attesa di un tasto o pulsante...",
|
||||
"controls_mapping_press": "Premi un tasto o un pulsante",
|
||||
"welcome_message": "Benvenuto in RGSX",
|
||||
"disclaimer_line1": "È pericoloso andare da soli, prendi tutto ciò che ti serve!",
|
||||
"disclaimer_line2": "Ma scarica solo giochi",
|
||||
"disclaimer_line3": "che possiedi già!",
|
||||
"disclaimer_line4": "RGSX non è responsabile dei contenuti scaricati,",
|
||||
"disclaimer_line5": "e non ospita ROM.",
|
||||
|
||||
"loading_test_connection": "Verifica connessione...",
|
||||
"loading_download_data": "Download cartella Dati iniziale...",
|
||||
"loading_progress": "Progresso: {0}%",
|
||||
"loading_check_updates": "Verifica aggiornamenti... Attendere...",
|
||||
"error_check_updates_failed": "Impossibile verificare gli aggiornamenti.",
|
||||
"loading_downloading_games_images": "Download giochi e immagini...",
|
||||
"loading_extracting_data": "Estrazione cartella Dati iniziale...",
|
||||
"loading_load_systems": "Caricamento sistemi...",
|
||||
"error_extract_data_failed": "Errore nel download o nell'estrazione della cartella Dati iniziale.",
|
||||
"error_sources_load_failed": "Errore nel caricamento delle sorgenti. Apri il menu e seleziona Aggiorna cache giochi",
|
||||
|
||||
"error_no_internet": "Nessuna connessione Internet. Controlla la rete.",
|
||||
"error_controls_mapping": "Impossibile mappare i controlli",
|
||||
"error_api_key": "Inserisci la tua API key (solo premium) nel file {0}",
|
||||
"error_api_key_extended": "Inserisci la tua API key (solo premium) nel file /userdata/saves/ports/rgsx/1FichierAPI.txt aprendolo in un editor e incollando la chiave",
|
||||
"error_invalid_download_data": "Dati di download non validi",
|
||||
"error_delete_sources": "Errore nell'eliminazione del file systems_list.json o delle cartelle",
|
||||
"error_extension": "Estensione non supportata o errore di download",
|
||||
"error_no_download": "Nessun download in sospeso.",
|
||||
|
||||
"platform_no_platform": "Nessuna piattaforma",
|
||||
"platform_page": "Pagina {0}/{1}",
|
||||
|
||||
"game_no_games": "Nessun gioco disponibile",
|
||||
"game_count": "{0} ({1} giochi)",
|
||||
"game_filter": "Filtro attivo: {0}",
|
||||
"game_search": "Filtro: {0}",
|
||||
"game_header_name": "Nome",
|
||||
"game_header_size": "Dimensione",
|
||||
|
||||
"history_title": "Download ({0})",
|
||||
"history_empty": "Nessun download nella cronologia",
|
||||
"history_column_system": "Sistema",
|
||||
"history_column_game": "Nome del gioco",
|
||||
"history_column_size": "Dimensione",
|
||||
"history_column_status": "Stato",
|
||||
"history_status_downloading": "Download: {0}%",
|
||||
"history_status_extracting": "Estrazione: {0}%",
|
||||
"history_status_completed": "Completato",
|
||||
"history_status_error": "Errore: {0}",
|
||||
"history_status_canceled": "Annullato",
|
||||
|
||||
"download_status": "{0}: {1}",
|
||||
"download_progress": "{0}% {1} MB / {2} MB",
|
||||
"download_canceled": "Download annullato dall'utente.",
|
||||
|
||||
"extension_warning_zip": "Il file '{0}' è un archivio e Batocera non supporta archivi per questo sistema. L'estrazione automatica avverrà dopo il download, continuare?",
|
||||
"extension_warning_unsupported": "L'estensione del file '{0}' non è supportata da Batocera secondo la configurazione di es_systems.cfg. Vuoi continuare?",
|
||||
"extension_warning_enable_unknown_hint": "\nPer non visualizzare questo messaggio: abilita \"Nascondi avviso estensione sconosciuta\" in Menu Pausa > Schermo",
|
||||
|
||||
"confirm_exit": "Uscire dall'applicazione?",
|
||||
"confirm_exit_with_downloads": "Attenzione: {0} download in corso. Uscire comunque?",
|
||||
"confirm_clear_history": "Cancellare la cronologia?",
|
||||
"confirm_redownload_cache": "Aggiornare l'elenco dei giochi?",
|
||||
|
||||
"popup_redownload_success": "Cache pulita, riavvia l'applicazione",
|
||||
"popup_no_cache": "Nessuna cache trovata.\nRiavvia l'applicazione per caricare i giochi.",
|
||||
"popup_countdown": "Questo messaggio si chiuderà tra {0} secondo{1}",
|
||||
|
||||
"language_select_title": "Selezione lingua",
|
||||
"language_select_instruction": "Usa le frecce per navigare e Invio per selezionare",
|
||||
"language_changed": "Lingua cambiata in {0}",
|
||||
|
||||
"menu_controls": "Controlli",
|
||||
"menu_remap_controls": "Rimappa controlli",
|
||||
"menu_history": "Cronologia",
|
||||
"menu_language": "Lingua",
|
||||
"menu_accessibility": "Accessibilità",
|
||||
"menu_display": "Schermo",
|
||||
"display_layout": "Layout schermo",
|
||||
"menu_redownload_cache": "Aggiorna elenco giochi",
|
||||
"menu_music_toggle": "Attiva/Disattiva musica",
|
||||
"menu_music_enabled": "Musica attivata: {0}",
|
||||
"menu_music_disabled": "Musica disattivata",
|
||||
"menu_restart": "Riavvia",
|
||||
"menu_filter_platforms": "Filtra sistemi",
|
||||
"filter_platforms_title": "Visibilità sistemi",
|
||||
"filter_all": "Mostra tutto",
|
||||
"filter_none": "Nascondi tutto",
|
||||
"filter_apply": "Applica",
|
||||
"filter_back": "Indietro",
|
||||
"filter_platforms_info": "Visibili: {0} | Nascosti: {1} / Totale: {2}",
|
||||
"filter_unsaved_warning": "Modifiche non salvate",
|
||||
"menu_show_unsupported_on": "Mostra sistemi non supportati: Sì",
|
||||
"menu_show_unsupported_off": "Mostra sistemi non supportati: No",
|
||||
"menu_show_unsupported_text": "sistemi nascosti",
|
||||
"menu_show_unsupported_enabled": "Visibilità sistemi non supportati abilitata",
|
||||
"menu_show_unsupported_disabled": "Visibilità sistemi non supportati disabilitata",
|
||||
"menu_allow_unknown_ext_on": "Nascondi avviso estensione sconosciuta: Sì",
|
||||
"menu_allow_unknown_ext_off": "Nascondi avviso estensione sconosciuta: No",
|
||||
"menu_allow_unknown_ext_enabled": "Nascondi avviso estensione sconosciuta abilitato",
|
||||
"menu_allow_unknown_ext_disabled": "Nascondi avviso estensione sconosciuta disabilitato",
|
||||
"menu_quit": "Esci",
|
||||
|
||||
"button_yes": "Sì",
|
||||
"button_no": "No",
|
||||
"button_OK": "OK",
|
||||
"popup_restarting": "Riavvio...",
|
||||
|
||||
"controls_hold_message": "Tieni premuto per 3s per: '{0}'",
|
||||
"controls_skip_message": "Premi Esc per ignorare (solo PC)",
|
||||
"controls_waiting": "In attesa...",
|
||||
"controls_hold": "Tieni premuto 3s",
|
||||
|
||||
"controls_action_confirm": "Conferma",
|
||||
"controls_action_cancel": "Annulla",
|
||||
"controls_action_up": "Su",
|
||||
"controls_action_down": "Giù",
|
||||
"controls_action_left": "Sinistra",
|
||||
"controls_action_right": "Destra",
|
||||
"controls_action_page_up": "Pagina precedente",
|
||||
"controls_action_page_down": "Pagina successiva",
|
||||
"controls_action_clear_history": "Selezione multipla / Cancella cronologia",
|
||||
"controls_action_history": "Cronologia",
|
||||
"controls_action_filter": "Filtro",
|
||||
"controls_action_delete": "Elimina",
|
||||
"controls_action_space": "Spazio",
|
||||
"controls_action_start": "Aiuto / Impostazioni",
|
||||
|
||||
"controls_desc_confirm": "Conferma (es. A, Invio)",
|
||||
"controls_desc_cancel": "Annulla/Indietro (es. B, Backspace)",
|
||||
"controls_desc_up": "Naviga in alto",
|
||||
"controls_desc_down": "Naviga in basso",
|
||||
"controls_desc_left": "Naviga a sinistra",
|
||||
"controls_desc_right": "Naviga a destra",
|
||||
"controls_desc_page_up": "Pagina precedente/Scorrimento veloce su (es. PagSu, LB)",
|
||||
"controls_desc_page_down": "Pagina successiva/Scorrimento veloce giù (es. PagGiù, RB)",
|
||||
"controls_desc_clear_history": "Selezione multipla (lista giochi) / Cancella cronologia (menu cronologia) (es. X)",
|
||||
"controls_desc_history": "Apri cronologia (es. H, Y)",
|
||||
"controls_desc_filter": "Apri filtro (es. F, Select)",
|
||||
"controls_desc_delete": "Elimina carattere (es. LT, Canc)",
|
||||
"controls_desc_space": "Aggiungi spazio (es. RT, Spazio)",
|
||||
"controls_desc_start": "Apri menu pausa (es. Start, AltGr)",
|
||||
|
||||
"action_retry": "Riprova",
|
||||
"action_quit": "Esci",
|
||||
"action_select": "Seleziona",
|
||||
"action_history": "Cronologia",
|
||||
"action_download": "Scarica",
|
||||
"action_filter": "Filtro",
|
||||
"action_cancel": "Annulla",
|
||||
"action_back": "Indietro",
|
||||
"action_navigate": "Naviga",
|
||||
"action_page": "Pagina",
|
||||
"action_cancel_download": "Annulla download",
|
||||
"action_background": "Sfondo",
|
||||
"action_confirm": "Conferma",
|
||||
"action_redownload": "Scarica di nuovo",
|
||||
"action_clear_history": "Cancella cronologia",
|
||||
|
||||
"network_checking_updates": "Verifica aggiornamenti...",
|
||||
"network_update_available": "Aggiornamento disponibile: {0}",
|
||||
"network_extracting_update": "Estrazione aggiornamento...",
|
||||
"network_update_completed": "Aggiornamento completato",
|
||||
"network_update_success": "Aggiornamento a {0} completato con successo. Riavvia l'applicazione.",
|
||||
"network_update_success_message": "Aggiornamento completato con successo",
|
||||
"network_no_update_available": "Nessun aggiornamento disponibile",
|
||||
"network_update_error": "Errore durante l'aggiornamento: {0}",
|
||||
"network_check_update_error": "Errore durante il controllo degli aggiornamenti: {0}",
|
||||
"network_extraction_failed": "Impossibile estrarre l'aggiornamento: {0}",
|
||||
"network_extraction_partial": "Estrazione riuscita, ma alcuni file sono stati ignorati a causa di errori: {0}",
|
||||
"network_extraction_success": "Estrazione riuscita",
|
||||
"network_download_extract_ok": "Download ed estrazione riusciti di {0}",
|
||||
"network_zip_extraction_error": "Errore durante l'estrazione dello ZIP {0}: {1}",
|
||||
"network_permission_error": "Nessun permesso di scrittura in {0}",
|
||||
"network_file_not_found": "Il file {0} non esiste",
|
||||
"network_cannot_get_filename": "Impossibile ottenere il nome del file",
|
||||
"network_cannot_get_download_url": "Impossibile ottenere l'URL di download",
|
||||
"network_download_failed": "Download fallito dopo {0} tentativi",
|
||||
"network_api_error": "Errore richiesta API, la chiave potrebbe essere errata: {0}",
|
||||
"network_download_error": "Errore download {0}: {1}",
|
||||
"network_download_ok": "Download OK: {0}",
|
||||
|
||||
"utils_extracted": "Estratto: {0}",
|
||||
"utils_corrupt_zip": "Archivio ZIP corrotto: {0}",
|
||||
"utils_permission_denied": "Permesso negato durante l'estrazione: {0}",
|
||||
"utils_extraction_failed": "Estrazione fallita: {0}",
|
||||
"utils_unrar_unavailable": "Comando unrar non disponibile",
|
||||
"utils_rar_list_failed": "Impossibile elencare i file RAR: {0}",
|
||||
"utils_xdvdfs_unavailable": "Strumento xdvdfs non disponibile (mancante o permesso negato)",
|
||||
"download_initializing": "Inizializzazione...",
|
||||
"accessibility_font_size": "Dimensione carattere: {0}",
|
||||
"confirm_cancel_download": "Annullare il download corrente?",
|
||||
"controls_help_title": "Guida ai controlli",
|
||||
"controls_category_navigation": "Navigazione",
|
||||
"controls_category_main_actions": "Azioni principali",
|
||||
"controls_category_downloads": "Download",
|
||||
"controls_category_search": "Ricerca",
|
||||
"controls_navigation": "Navigazione",
|
||||
"controls_pages": "Pagine",
|
||||
"controls_confirm_select": "Conferma/Seleziona",
|
||||
"controls_cancel_back": "Annulla/Indietro",
|
||||
"controls_history": "Cronologia",
|
||||
"controls_clear_history": "Selezione multipla / Cronologia",
|
||||
"controls_filter_search": "Filtro/Ricerca",
|
||||
|
||||
"menu_symlink_option": "Opzione Symlink",
|
||||
"symlink_option_enabled": "Opzione symlink abilitata",
|
||||
"symlink_option_disabled": "Opzione symlink disabilitata",
|
||||
"symlink_settings_saved_successfully": "Impostazioni symlink salvate con successo",
|
||||
"symlink_settings_save_error": "Errore nel salvataggio delle impostazioni symlink",
|
||||
|
||||
"menu_games_source_prefix": "Sorgente giochi",
|
||||
"games_source_rgsx": "RGSX",
|
||||
"sources_mode_rgsx_select_info": "RGSX: aggiorna l'elenco dei giochi",
|
||||
"games_source_custom": "Personalizzato",
|
||||
"sources_mode_custom_select_info": "Modalità personalizzata: imposta l'URL in {0} poi aggiorna l'elenco giochi",
|
||||
"sources_mode_custom_missing_url": "Nessun URL personalizzato impostato (modifica {0})",
|
||||
"sources_mode_custom_download_error": "Download sorgente personalizzata fallito",
|
||||
"menu_show_unsupported_and_hidden": "Mostra {0} sistemi non supportati e nascosti",
|
||||
"menu_show_unsupported_all_displayed": "Tutti i sistemi visualizzati"
|
||||
}
|
||||
"welcome_message": "Benvenuto in RGSX",
|
||||
"disclaimer_line1": "È pericoloso andare da soli, prendi tutto ciò che ti serve!",
|
||||
"disclaimer_line2": "Ma scarica solo giochi",
|
||||
"disclaimer_line3": "che possiedi già!",
|
||||
"disclaimer_line4": "RGSX non è responsabile dei contenuti scaricati,",
|
||||
"disclaimer_line5": "e non ospita ROM.",
|
||||
"loading_test_connection": "Verifica connessione...",
|
||||
"loading_download_data": "Download cartella Dati iniziale...",
|
||||
"loading_progress": "Progresso: {0}%",
|
||||
"loading_check_updates": "Verifica aggiornamenti... Attendere...",
|
||||
"error_check_updates_failed": "Impossibile verificare gli aggiornamenti.",
|
||||
"loading_downloading_games_images": "Download giochi e immagini...",
|
||||
"loading_extracting_data": "Estrazione cartella Dati iniziale...",
|
||||
"loading_load_systems": "Caricamento sistemi...",
|
||||
"error_extract_data_failed": "Errore nel download o nell'estrazione della cartella Dati iniziale.",
|
||||
"error_no_internet": "Nessuna connessione Internet. Controlla la rete.",
|
||||
"error_api_key": "Inserisci la tua API key (solo premium) nel file {0}",
|
||||
"error_invalid_download_data": "Dati di download non validi",
|
||||
"error_delete_sources": "Errore nell'eliminazione del file systems_list.json o delle cartelle",
|
||||
"platform_no_platform": "Nessuna piattaforma",
|
||||
"platform_page": "Pagina {0}/{1}",
|
||||
"game_no_games": "Nessun gioco disponibile",
|
||||
"game_count": "{0} ({1} giochi)",
|
||||
"game_filter": "Filtro attivo: {0}",
|
||||
"game_search": "Filtro: {0}",
|
||||
"game_header_name": "Nome",
|
||||
"game_header_size": "Dimensione",
|
||||
"history_title": "Download ({0})",
|
||||
"history_empty": "Nessun download nella cronologia",
|
||||
"history_column_system": "Sistema",
|
||||
"history_column_game": "Nome del gioco",
|
||||
"history_column_size": "Dimensione",
|
||||
"history_column_status": "Stato",
|
||||
"history_status_downloading": "Download: {0}%",
|
||||
"history_status_extracting": "Estrazione: {0}%",
|
||||
"history_status_completed": "Completato",
|
||||
"history_status_error": "Errore: {0}",
|
||||
"history_status_canceled": "Annullato",
|
||||
"download_status": "{0}: {1}",
|
||||
"download_canceled": "Download annullato dall'utente.",
|
||||
"extension_warning_zip": "Il file '{0}' è un archivio e Batocera non supporta archivi per questo sistema. L'estrazione automatica avverrà dopo il download, continuare?",
|
||||
"extension_warning_unsupported": "L'estensione del file '{0}' non è supportata da Batocera secondo la configurazione di es_systems.cfg. Vuoi continuare?",
|
||||
"extension_warning_enable_unknown_hint": "\nPer non visualizzare questo messaggio: abilita \"Nascondi avviso estensione sconosciuta\" in Menu Pausa > Schermo",
|
||||
"confirm_exit": "Uscire dall'applicazione?",
|
||||
"confirm_exit_with_downloads": "Attenzione: {0} download in corso. Uscire comunque?",
|
||||
"confirm_clear_history": "Cancellare la cronologia?",
|
||||
"confirm_redownload_cache": "Aggiornare l'elenco dei giochi?",
|
||||
"popup_redownload_success": "Cache pulita, riavvia l'applicazione",
|
||||
"popup_no_cache": "Nessuna cache trovata.\nRiavvia l'applicazione per caricare i giochi.",
|
||||
"popup_countdown": "Questo messaggio si chiuderà tra {0} secondo{1}",
|
||||
"language_select_title": "Selezione lingua",
|
||||
"language_select_instruction": "Usa le frecce per navigare e Invio per selezionare",
|
||||
"language_changed": "Lingua cambiata in {0}",
|
||||
"menu_controls": "Controlli",
|
||||
"menu_remap_controls": "Rimappa controlli",
|
||||
"menu_history": "Cronologia",
|
||||
"menu_language": "Lingua",
|
||||
"menu_accessibility": "Accessibilità",
|
||||
"menu_display": "Schermo",
|
||||
"display_layout": "Layout schermo",
|
||||
"menu_redownload_cache": "Aggiorna elenco giochi",
|
||||
"menu_music_enabled": "Musica attivata: {0}",
|
||||
"menu_music_disabled": "Musica disattivata",
|
||||
"menu_restart": "Riavvia",
|
||||
"menu_filter_platforms": "Filtra sistemi",
|
||||
"filter_platforms_title": "Visibilità sistemi",
|
||||
"filter_platforms_info": "Visibili: {0} | Nascosti: {1} / Totale: {2}",
|
||||
"filter_unsaved_warning": "Modifiche non salvate",
|
||||
"menu_show_unsupported_enabled": "Visibilità sistemi non supportati abilitata",
|
||||
"menu_show_unsupported_disabled": "Visibilità sistemi non supportati disabilitata",
|
||||
"menu_allow_unknown_ext_on": "Nascondi avviso estensione sconosciuta: Sì",
|
||||
"menu_allow_unknown_ext_off": "Nascondi avviso estensione sconosciuta: No",
|
||||
"menu_allow_unknown_ext_enabled": "Nascondi avviso estensione sconosciuta abilitato",
|
||||
"menu_allow_unknown_ext_disabled": "Nascondi avviso estensione sconosciuta disabilitato",
|
||||
"menu_quit": "Esci",
|
||||
"button_yes": "Sì",
|
||||
"button_no": "No",
|
||||
"button_OK": "OK",
|
||||
"popup_restarting": "Riavvio...",
|
||||
"controls_action_clear_history": "Selezione multipla / Cancella cronologia",
|
||||
"controls_action_history": "Cronologia",
|
||||
"controls_action_delete": "Elimina",
|
||||
"controls_action_space": "Spazio",
|
||||
"controls_action_start": "Aiuto / Impostazioni",
|
||||
"network_checking_updates": "Verifica aggiornamenti...",
|
||||
"network_update_available": "Aggiornamento disponibile: {0}",
|
||||
"network_extracting_update": "Estrazione aggiornamento...",
|
||||
"network_update_completed": "Aggiornamento completato",
|
||||
"network_update_success": "Aggiornamento a {0} completato con successo. Riavvia l'applicazione.",
|
||||
"network_update_success_message": "Aggiornamento completato con successo",
|
||||
"network_no_update_available": "Nessun aggiornamento disponibile",
|
||||
"network_update_error": "Errore durante l'aggiornamento: {0}",
|
||||
"network_check_update_error": "Errore durante il controllo degli aggiornamenti: {0}",
|
||||
"network_extraction_failed": "Impossibile estrarre l'aggiornamento: {0}",
|
||||
"network_extraction_partial": "Estrazione riuscita, ma alcuni file sono stati ignorati a causa di errori: {0}",
|
||||
"network_extraction_success": "Estrazione riuscita",
|
||||
"network_download_extract_ok": "Download ed estrazione riusciti di {0}",
|
||||
"network_zip_extraction_error": "Errore durante l'estrazione dello ZIP {0}: {1}",
|
||||
"network_file_not_found": "Il file {0} non esiste",
|
||||
"network_cannot_get_filename": "Impossibile ottenere il nome del file",
|
||||
"network_cannot_get_download_url": "Impossibile ottenere l'URL di download",
|
||||
"network_download_failed": "Download fallito dopo {0} tentativi",
|
||||
"network_api_error": "Errore richiesta API, la chiave potrebbe essere errata: {0}",
|
||||
"network_download_error": "Errore download {0}: {1}",
|
||||
"network_download_ok": "Download OK: {0}",
|
||||
"utils_extracted": "Estratto: {0}",
|
||||
"utils_corrupt_zip": "Archivio ZIP corrotto: {0}",
|
||||
"utils_permission_denied": "Permesso negato durante l'estrazione: {0}",
|
||||
"utils_extraction_failed": "Estrazione fallita: {0}",
|
||||
"utils_unrar_unavailable": "Comando unrar non disponibile",
|
||||
"utils_rar_list_failed": "Impossibile elencare i file RAR: {0}",
|
||||
"download_initializing": "Inizializzazione...",
|
||||
"accessibility_font_size": "Dimensione carattere: {0}",
|
||||
"confirm_cancel_download": "Annullare il download corrente?",
|
||||
"controls_help_title": "Guida ai controlli",
|
||||
"controls_category_navigation": "Navigazione",
|
||||
"controls_category_main_actions": "Azioni principali",
|
||||
"controls_category_downloads": "Download",
|
||||
"controls_category_search": "Ricerca",
|
||||
"controls_navigation": "Navigazione",
|
||||
"controls_pages": "Pagine",
|
||||
"controls_confirm_select": "Conferma/Seleziona",
|
||||
"controls_cancel_back": "Annulla/Indietro",
|
||||
"controls_filter_search": "Filtro/Ricerca",
|
||||
"symlink_option_enabled": "Opzione symlink abilitata",
|
||||
"symlink_option_disabled": "Opzione symlink disabilitata",
|
||||
"menu_games_source_prefix": "Sorgente giochi",
|
||||
"games_source_rgsx": "RGSX",
|
||||
"sources_mode_rgsx_select_info": "RGSX: aggiorna l'elenco dei giochi",
|
||||
"games_source_custom": "Personalizzato",
|
||||
"sources_mode_custom_select_info": "Modalità personalizzata: imposta l'URL in {0} poi aggiorna l'elenco giochi",
|
||||
"sources_mode_custom_missing_url": "Nessun URL personalizzato impostato (modifica {0})",
|
||||
"sources_mode_custom_download_error": "Download sorgente personalizzata fallito",
|
||||
"menu_show_unsupported_and_hidden": "Mostra {0} sistemi non supportati e nascosti",
|
||||
"menu_show_unsupported_all_displayed": "Tutti i sistemi visualizzati",
|
||||
"menu_settings_category": "Impostazioni",
|
||||
"menu_back": "Indietro",
|
||||
"submenu_display_layout": "Layout",
|
||||
"submenu_display_font_size": "Dimensione Carattere",
|
||||
"submenu_display_show_unsupported": "Mostra sistemi non supportati: {status}",
|
||||
"submenu_display_allow_unknown_ext": "Nascondi avviso est. sconosciuta: {status}",
|
||||
"submenu_display_filter_platforms": "Filtra sistemi",
|
||||
"status_on": "Sì",
|
||||
"status_off": "No",
|
||||
"status_present": "Presente",
|
||||
"status_missing": "Assente",
|
||||
"menu_api_keys_status": "Chiavi API",
|
||||
"api_keys_status_title": "Stato delle chiavi API",
|
||||
"menu_games": "Giochi"
|
||||
}
|
||||
@@ -1,15 +1,10 @@
|
||||
{
|
||||
"controls_mapping_title": "Configuração dos controles",
|
||||
"controls_mapping_instruction": "Mantenha pressionado por 3s para configurar:",
|
||||
"controls_mapping_waiting": "Aguardando uma tecla ou botão...",
|
||||
"controls_mapping_press": "Pressione uma tecla ou botão",
|
||||
"welcome_message": "Bem-vindo ao RGSX",
|
||||
"disclaimer_line1": "É perigoso ir sozinho, leve tudo o que precisar!",
|
||||
"disclaimer_line2": "Mas baixe apenas jogos",
|
||||
"disclaimer_line3": "que você já possui!",
|
||||
"disclaimer_line4": "O RGSX não é responsável pelo conteúdo baixado,",
|
||||
"disclaimer_line5": "e não hospeda ROMs.",
|
||||
|
||||
"loading_test_connection": "Testando conexão...",
|
||||
"loading_download_data": "Baixando pasta inicial Data...",
|
||||
"loading_progress": "Progresso: {0}%",
|
||||
@@ -19,27 +14,18 @@
|
||||
"loading_extracting_data": "Extraindo pasta inicial Data...",
|
||||
"loading_load_systems": "Carregando sistemas...",
|
||||
"error_extract_data_failed": "Falha ao baixar ou extrair a pasta inicial Data.",
|
||||
"error_sources_load_failed": "Falha ao carregar fontes. Abra o menu e selecione Redownload Games cache",
|
||||
|
||||
"error_no_internet": "Sem conexão com a Internet. Verifique sua rede.",
|
||||
"error_controls_mapping": "Falha ao mapear controles",
|
||||
"error_api_key": "Insira sua chave API (somente premium) no arquivo {0}",
|
||||
"error_api_key_extended": "Insira sua chave API (somente premium) no arquivo /userdata/saves/ports/rgsx/1FichierAPI.txt abrindo-o em um editor de texto e colando sua chave",
|
||||
"error_invalid_download_data": "Dados de download inválidos",
|
||||
"error_delete_sources": "Erro ao deletar arquivo sources.json ou pastas",
|
||||
"error_extension": "Extensão não suportada ou erro no download",
|
||||
"error_no_download": "Nenhum download pendente.",
|
||||
|
||||
"platform_no_platform": "Sem plataforma",
|
||||
"platform_page": "Página {0}/{1}",
|
||||
|
||||
"game_no_games": "Nenhum jogo disponível",
|
||||
"game_count": "{0} ({1} jogos)",
|
||||
"game_filter": "Filtro ativo: {0}",
|
||||
"game_search": "Filtro: {0}",
|
||||
"game_header_name": "Nome",
|
||||
"game_header_size": "Tamanho",
|
||||
|
||||
"history_title": "Downloads ({0})",
|
||||
"history_empty": "Nenhum download no histórico",
|
||||
"history_column_system": "Sistema",
|
||||
@@ -51,28 +37,21 @@
|
||||
"history_status_completed": "Concluído",
|
||||
"history_status_error": "Erro: {0}",
|
||||
"history_status_canceled": "Cancelado",
|
||||
|
||||
"download_status": "{0}: {1}",
|
||||
"download_progress": "{0}% {1} MB / {2} MB",
|
||||
"download_canceled": "Download cancelado pelo usuário.",
|
||||
|
||||
"extension_warning_zip": "O arquivo '{0}' é um arquivo compactado e o Batocera não suporta arquivos compactados para este sistema. A extração automática ocorrerá após o download, continuar?",
|
||||
"extension_warning_unsupported": "A extensão do arquivo '{0}' não é suportada pelo Batocera segundo a configuração es_systems.cfg. Deseja continuar?",
|
||||
"extension_warning_enable_unknown_hint": "\nPara não ver esta mensagem: ative \"Ocultar aviso de extensão desconhecida\" em Menu de Pausa > Exibição",
|
||||
|
||||
"confirm_exit": "Sair da aplicação?",
|
||||
"confirm_exit_with_downloads": "Atenção: {0} download(s) em andamento. Sair mesmo assim?",
|
||||
"confirm_clear_history": "Limpar histórico?",
|
||||
"confirm_redownload_cache": "Atualizar lista de jogos?",
|
||||
|
||||
"popup_redownload_success": "Cache limpo, reinicie a aplicação",
|
||||
"popup_no_cache": "Nenhum cache encontrado.\nReinicie a aplicação para carregar os jogos.",
|
||||
"popup_countdown": "Esta mensagem fechará em {0} segundo{1}",
|
||||
|
||||
"language_select_title": "Seleção de Idioma",
|
||||
"language_select_instruction": "Use as setas para navegar e Enter para selecionar",
|
||||
"language_changed": "Idioma alterado para {0}",
|
||||
|
||||
"menu_controls": "Controles",
|
||||
"menu_remap_controls": "Remapear controles",
|
||||
"menu_history": "Histórico",
|
||||
@@ -81,21 +60,13 @@
|
||||
"menu_display": "Exibição",
|
||||
"display_layout": "Layout de exibição",
|
||||
"menu_redownload_cache": "Atualizar lista de jogos",
|
||||
"menu_music_toggle": "Ativar/Desativar música",
|
||||
"menu_music_enabled": "Música ativada: {0}",
|
||||
"menu_music_disabled": "Música desativada",
|
||||
"menu_restart": "Reiniciar",
|
||||
"menu_filter_platforms": "Filtrar sistemas",
|
||||
"filter_platforms_title": "Visibilidade dos sistemas",
|
||||
"filter_all": "Mostrar todos",
|
||||
"filter_none": "Ocultar todos",
|
||||
"filter_apply": "Aplicar",
|
||||
"filter_back": "Voltar",
|
||||
"filter_platforms_info": "Visíveis: {0} | Ocultos: {1} / Total: {2}",
|
||||
"filter_unsaved_warning": "Alterações não salvas",
|
||||
"menu_show_unsupported_on": "Mostrar sistemas não suportados: Sim",
|
||||
"menu_show_unsupported_off": "Mostrar sistemas não suportados: Não",
|
||||
"menu_show_unsupported_text": "sistemas ocultos",
|
||||
"menu_show_unsupported_enabled": "Visibilidade de sistemas não suportados ativada",
|
||||
"menu_show_unsupported_disabled": "Visibilidade de sistemas não suportados desativada",
|
||||
"menu_allow_unknown_ext_on": "Ocultar aviso de extensão desconhecida: Sim",
|
||||
@@ -103,63 +74,15 @@
|
||||
"menu_allow_unknown_ext_enabled": "Aviso de extensão desconhecida oculto (ativado)",
|
||||
"menu_allow_unknown_ext_disabled": "Aviso de extensão desconhecida visível (desativado)",
|
||||
"menu_quit": "Sair",
|
||||
|
||||
"button_yes": "Sim",
|
||||
"button_no": "Não",
|
||||
"button_OK": "OK",
|
||||
"popup_restarting": "Reiniciando...",
|
||||
|
||||
"controls_hold_message": "Mantenha pressionado por 3s para: '{0}'",
|
||||
"controls_skip_message": "Pressione Esc para ignorar (somente PC)",
|
||||
"controls_waiting": "Aguardando...",
|
||||
"controls_hold": "Segure 3s",
|
||||
|
||||
"controls_action_confirm": "Confirmar",
|
||||
"controls_action_cancel": "Cancelar",
|
||||
"controls_action_up": "Cima",
|
||||
"controls_action_down": "Baixo",
|
||||
"controls_action_left": "Esquerda",
|
||||
"controls_action_right": "Direita",
|
||||
"controls_action_page_up": "Página anterior",
|
||||
"controls_action_page_down": "Próxima página",
|
||||
"controls_action_clear_history": "Seleção múltipla / Limpar histórico",
|
||||
"controls_action_history": "Histórico",
|
||||
"controls_action_filter": "Filtro",
|
||||
"controls_action_delete": "Deletar",
|
||||
"controls_action_space": "Espaço",
|
||||
"controls_action_start": "Ajuda / Configurações",
|
||||
|
||||
"controls_desc_confirm": "Validar (ex: A, Enter)",
|
||||
"controls_desc_cancel": "Cancelar/Voltar (ex: B, Backspace)",
|
||||
"controls_desc_up": "Navegar para cima",
|
||||
"controls_desc_down": "Navegar para baixo",
|
||||
"controls_desc_left": "Navegar para a esquerda",
|
||||
"controls_desc_right": "Navegar para a direita",
|
||||
"controls_desc_page_up": "Página anterior/Rolagem rápida para cima (ex: PageUp, LB)",
|
||||
"controls_desc_page_down": "Próxima página/Rolagem rápida para baixo (ex: PageDown, RB)",
|
||||
"controls_desc_clear_history": "Seleção múltipla (lista) / Limpar histórico (histórico) (ex: X)",
|
||||
"controls_desc_history": "Abrir histórico (ex: H, Y)",
|
||||
"controls_desc_filter": "Abrir filtro (ex: F, Select)",
|
||||
"controls_desc_delete": "Deletar caractere (ex: LT, Delete)",
|
||||
"controls_desc_space": "Adicionar espaço (ex: RT, Space)",
|
||||
"controls_desc_start": "Abrir menu de pausa (ex: Start, AltGr)",
|
||||
|
||||
"action_retry": "Repetir",
|
||||
"action_quit": "Sair",
|
||||
"action_select": "Selecionar",
|
||||
"action_history": "Histórico",
|
||||
"action_download": "Baixar",
|
||||
"action_filter": "Filtrar",
|
||||
"action_cancel": "Cancelar",
|
||||
"action_back": "Voltar",
|
||||
"action_navigate": "Navegar",
|
||||
"action_page": "Página",
|
||||
"action_cancel_download": "Cancelar download",
|
||||
"action_background": "Segundo plano",
|
||||
"action_confirm": "Confirmar",
|
||||
"action_redownload": "Rebaixar",
|
||||
"action_clear_history": "Limpar histórico",
|
||||
|
||||
"network_checking_updates": "Verificando atualizações...",
|
||||
"network_update_available": "Atualização disponível: {0}",
|
||||
"network_extracting_update": "Extraindo atualização...",
|
||||
@@ -174,7 +97,6 @@
|
||||
"network_extraction_success": "Extração concluída",
|
||||
"network_download_extract_ok": "Download e extração concluídos de {0}",
|
||||
"network_zip_extraction_error": "Erro ao extrair ZIP {0}: {1}",
|
||||
"network_permission_error": "Sem permissão de escrita em {0}",
|
||||
"network_file_not_found": "Arquivo {0} não existe",
|
||||
"network_cannot_get_filename": "Não foi possível obter o nome do arquivo",
|
||||
"network_cannot_get_download_url": "Não foi possível obter a URL de download",
|
||||
@@ -182,14 +104,12 @@
|
||||
"network_api_error": "Erro na requisição da API, a chave pode estar incorreta: {0}",
|
||||
"network_download_error": "Erro de download {0}: {1}",
|
||||
"network_download_ok": "Download OK: {0}",
|
||||
|
||||
"utils_extracted": "Extraído: {0}",
|
||||
"utils_corrupt_zip": "Arquivo ZIP corrompido: {0}",
|
||||
"utils_permission_denied": "Permissão negada durante extração: {0}",
|
||||
"utils_extraction_failed": "Extração falhou: {0}",
|
||||
"utils_unrar_unavailable": "Comando unrar não disponível",
|
||||
"utils_rar_list_failed": "Falha ao listar arquivos RAR: {0}",
|
||||
"utils_xdvdfs_unavailable": "Ferramenta xdvdfs indisponível (faltando ou sem permissão)",
|
||||
"download_initializing": "Inicializando...",
|
||||
"accessibility_font_size": "Tamanho da fonte: {0}",
|
||||
"confirm_cancel_download": "Cancelar download atual?",
|
||||
@@ -202,16 +122,9 @@
|
||||
"controls_pages": "Páginas",
|
||||
"controls_confirm_select": "Confirmar/Selecionar",
|
||||
"controls_cancel_back": "Cancelar/Voltar",
|
||||
"controls_history": "Histórico",
|
||||
"controls_clear_history": "Seleção múltipla / Histórico",
|
||||
"controls_filter_search": "Filtrar/Buscar",
|
||||
|
||||
"menu_symlink_option": "Opção de Symlink",
|
||||
"symlink_option_enabled": "Opção de symlink ativada",
|
||||
"symlink_option_disabled": "Opção de symlink desativada",
|
||||
"symlink_settings_saved_successfully": "Configurações de symlink salvas com sucesso",
|
||||
"symlink_settings_save_error": "Erro ao salvar configurações de symlink",
|
||||
|
||||
"menu_games_source_prefix": "Fonte de jogos",
|
||||
"games_source_rgsx": "RGSX",
|
||||
"sources_mode_rgsx_select_info": "RGSX: atualizar a lista de jogos",
|
||||
@@ -220,5 +133,19 @@
|
||||
"sources_mode_custom_missing_url": "Nenhuma URL personalizada definida (edite {0})",
|
||||
"sources_mode_custom_download_error": "Falha no download da fonte personalizada",
|
||||
"menu_show_unsupported_and_hidden": "Mostrar {0} sistemas não suportados e ocultos",
|
||||
"menu_show_unsupported_all_displayed": "Todos os sistemas exibidos"
|
||||
"menu_show_unsupported_all_displayed": "Todos os sistemas exibidos",
|
||||
"menu_settings_category": "Configurações",
|
||||
"menu_back": "Voltar",
|
||||
"submenu_display_layout": "Layout",
|
||||
"submenu_display_font_size": "Tamanho da Fonte",
|
||||
"submenu_display_show_unsupported": "Mostrar sistemas não suportados: {status}",
|
||||
"submenu_display_allow_unknown_ext": "Ocultar aviso ext. desconhecida: {status}",
|
||||
"submenu_display_filter_platforms": "Filtrar sistemas",
|
||||
"status_on": "Sim",
|
||||
"status_off": "Não",
|
||||
"status_present": "Presente",
|
||||
"status_missing": "Ausente",
|
||||
"menu_api_keys_status": "Chaves API",
|
||||
"api_keys_status_title": "Status das chaves API",
|
||||
"menu_games": "Jogos"
|
||||
}
|
||||
@@ -15,7 +15,7 @@ try:
|
||||
except Exception:
|
||||
pygame = None # type: ignore
|
||||
from config import OTA_VERSION_ENDPOINT,APP_FOLDER, UPDATE_FOLDER, OTA_UPDATE_ZIP
|
||||
from utils import sanitize_filename, extract_zip, extract_rar, load_api_key_1fichier, load_api_key_alldebrid, normalize_platform_name
|
||||
from utils import sanitize_filename, extract_zip, extract_rar, load_api_key_1fichier, load_api_key_alldebrid, normalize_platform_name, load_api_keys
|
||||
from history import save_history
|
||||
import logging
|
||||
import datetime
|
||||
@@ -318,8 +318,8 @@ async def download_rom(url, platform, game_name, is_zip_non_supported=False, tas
|
||||
|
||||
# Spécifique: si le système est "BIOS" on force le dossier BIOS
|
||||
if platform_folder == "bios" or platform == "BIOS" or platform == "- BIOS by TMCTV -":
|
||||
dest_dir = config.RETROBAT_DATA_FOLDER
|
||||
logger.debug(f"Plateforme 'BIOS' détectée, destination forcée vers RETROBAT_DATA_FOLDER: {dest_dir}")
|
||||
dest_dir = config.USERDATA_FOLDER
|
||||
logger.debug(f"Plateforme 'BIOS' détectée, destination forcée vers USERDATA_FOLDER: {dest_dir}")
|
||||
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
if not os.access(dest_dir, os.W_OK):
|
||||
@@ -634,13 +634,16 @@ async def download_rom(url, platform, game_name, is_zip_non_supported=False, tas
|
||||
return result[0], result[1]
|
||||
|
||||
async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=False, task_id=None):
|
||||
config.API_KEY_1FICHIER = load_api_key_1fichier()
|
||||
if not config.API_KEY_1FICHIER:
|
||||
# Fallback: essayer AllDebrid
|
||||
config.API_KEY_ALLDEBRID = load_api_key_alldebrid()
|
||||
logger.debug(f"Clé API 1fichier absente, fallback AllDebrid: {'présente' if config.API_KEY_ALLDEBRID else 'absente'}")
|
||||
# Charger/rafraîchir les clés API (mtime aware)
|
||||
keys_info = load_api_keys()
|
||||
config.API_KEY_1FICHIER = keys_info.get('1fichier', '')
|
||||
config.API_KEY_ALLDEBRID = keys_info.get('alldebrid', '')
|
||||
if not config.API_KEY_1FICHIER and config.API_KEY_ALLDEBRID:
|
||||
logger.debug("Clé 1fichier absente, utilisation fallback AllDebrid")
|
||||
elif not config.API_KEY_1FICHIER and not config.API_KEY_ALLDEBRID:
|
||||
logger.debug("Aucune clé API disponible (1fichier ni AllDebrid)")
|
||||
logger.debug(f"Début téléchargement 1fichier: {game_name} depuis {url}, is_zip_non_supported={is_zip_non_supported}, task_id={task_id}")
|
||||
logger.debug(f"Clé API 1fichier: {'présente' if config.API_KEY_1FICHIER else 'absente'}")
|
||||
logger.debug(f"Clé API 1fichier: {'présente' if config.API_KEY_1FICHIER else 'absente'} / AllDebrid: {'présente' if config.API_KEY_ALLDEBRID else 'absente'} (reloaded={keys_info.get('reloaded')})")
|
||||
result = [None, None]
|
||||
|
||||
# Créer une queue spécifique pour cette tâche
|
||||
@@ -673,8 +676,8 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
|
||||
|
||||
# Spécifique: si le système est "- BIOS by TMCTV -" on force le dossier BIOS
|
||||
if platform_folder == "bios" or platform == "BIOS" or platform == "- BIOS by TMCTV -":
|
||||
dest_dir = config.RETROBAT_DATA_FOLDER
|
||||
logger.debug(f"Plateforme '- BIOS by TMCTV -' détectée, destination forcée vers RETROBAT_DATA_FOLDER: {dest_dir}")
|
||||
dest_dir = config.USERDATA_FOLDER
|
||||
logger.debug(f"Plateforme '- BIOS by TMCTV -' détectée, destination forcée vers USERDATA_FOLDER: {dest_dir}")
|
||||
|
||||
logger.debug(f"Vérification répertoire destination: {dest_dir}")
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
@@ -685,6 +688,7 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
|
||||
|
||||
# Choisir la stratégie d'accès: 1fichier direct via API, sinon AllDebrid pour débrider
|
||||
if config.API_KEY_1FICHIER:
|
||||
logger.debug("Mode téléchargement sélectionné: 1fichier (API directe)")
|
||||
headers = {
|
||||
"Authorization": f"Bearer {config.API_KEY_1FICHIER}",
|
||||
"Content-Type": "application/json"
|
||||
@@ -726,6 +730,7 @@ async def download_from_1fichier(url, platform, game_name, is_zip_non_supported=
|
||||
logger.debug(f"URL de téléchargement obtenue via 1fichier: {final_url}")
|
||||
else:
|
||||
# AllDebrid: débrider l'URL 1fichier vers une URL directe
|
||||
logger.debug("Mode téléchargement sélectionné: AllDebrid (fallback, débridage 1fichier)")
|
||||
if not getattr(config, 'API_KEY_ALLDEBRID', ''):
|
||||
logger.error("Aucune clé API (1fichier/AllDebrid) disponible")
|
||||
result[0] = False
|
||||
|
||||
@@ -122,14 +122,14 @@ def load_extensions_json():
|
||||
|
||||
def _detect_es_systems_cfg_paths():
|
||||
"""Retourne une liste de chemins possibles pour es_systems.cfg selon l'OS.
|
||||
- RetroBat (Windows): {config.RETROBAT_DATA_FOLDER}\\system\\templates\\emulationstation\\es_systems.cfg
|
||||
- RetroBat (Windows): {config.USERDATA_FOLDER}\\system\\templates\\emulationstation\\es_systems.cfg
|
||||
- Batocera (Linux): /usr/share/emulationstation/es_systems.cfg
|
||||
Ajoute aussi les fichiers customs: /userdata/system/configs/emulationstation/es_systems_*.cfg
|
||||
"""
|
||||
candidates = []
|
||||
try:
|
||||
if platform.system() == 'Windows':
|
||||
base = getattr(config, 'RETROBAT_DATA_FOLDER', None)
|
||||
base = getattr(config, 'USERDATA_FOLDER', None)
|
||||
if base:
|
||||
candidates.append(os.path.join(base, 'system', 'templates', 'emulationstation', 'es_systems.cfg'))
|
||||
else:
|
||||
@@ -1250,66 +1250,82 @@ def set_music_popup(music_name):
|
||||
config.music_popup_start_time = pygame.time.get_ticks() / 1000 # Temps actuel en secondes
|
||||
config.needs_redraw = True # Forcer le redraw pour afficher le nom de la musique
|
||||
|
||||
def load_api_key_1fichier():
|
||||
"""Charge la clé API 1fichier depuis le dossier de sauvegarde, crée le fichier si absent."""
|
||||
API_KEY_1FICHIER = os.path.join(config.SAVE_FOLDER, "1FichierAPI.txt")
|
||||
logger.debug(f"Chemin du fichier de clé API: {API_KEY_1FICHIER}")
|
||||
logger.debug(f"Tentative de chargement de la clé API depuis: {API_KEY_1FICHIER}")
|
||||
try:
|
||||
# Vérifie si le fichier existe déjà
|
||||
if not os.path.exists(API_KEY_1FICHIER):
|
||||
logger.info(f"Fichier de clé API non trouvé")
|
||||
# Crée le dossier parent si nécessaire
|
||||
os.makedirs(config.SAVE_FOLDER, exist_ok=True)
|
||||
# Crée le fichier vide si absent
|
||||
with open(API_KEY_1FICHIER, "w") as f:
|
||||
f.write("")
|
||||
logger.info(f"Fichier de clé API créé : {API_KEY_1FICHIER}")
|
||||
return ""
|
||||
except OSError as e:
|
||||
logger.error(f"Erreur lors de la création du fichier de clé API : {e}")
|
||||
return ""
|
||||
# Lit la clé API depuis le fichier
|
||||
try:
|
||||
with open(API_KEY_1FICHIER, "r", encoding="utf-8") as f:
|
||||
api_key = f.read().strip()
|
||||
logger.debug(f"Clé API 1fichier lue: '{api_key}' (longueur: {len(api_key)})")
|
||||
if not api_key:
|
||||
logger.warning("Clé API 1fichier vide, veuillez la renseigner dans le fichier pour pouvoir utiliser les fonctionnalités de téléchargement sur 1fichier.")
|
||||
API_KEY_1FICHIER = api_key
|
||||
config.API_KEY_1FICHIER = api_key
|
||||
logger.debug(f"Clé API 1fichier chargée dans la configuration : '{config.API_KEY_1FICHIER}'")
|
||||
return api_key
|
||||
except OSError as e:
|
||||
logger.error(f"Erreur lors de la lecture de la clé API : {e}")
|
||||
return ""
|
||||
def load_api_keys(force: bool = False):
|
||||
"""Charge les clés API (1fichier, AllDebrid) en une seule passe.
|
||||
|
||||
def load_api_key_alldebrid():
|
||||
"""Charge la clé API AllDebrid depuis le dossier de sauvegarde, crée le fichier si absent."""
|
||||
- Crée les fichiers vides s'ils n'existent pas
|
||||
- Met à jour config.API_KEY_1FICHIER et config.API_KEY_ALLDEBRID
|
||||
- Utilise un cache basé sur le mtime pour éviter des relectures
|
||||
- force=True ignore le cache et relit systématiquement
|
||||
|
||||
Retourne: { '1fichier': str, 'alldebrid': str, 'reloaded': bool }
|
||||
"""
|
||||
try:
|
||||
api_file = os.path.join(config.SAVE_FOLDER, "AllDebridAPI.txt")
|
||||
logger.debug(f"Chemin du fichier de clé API AllDebrid: {api_file}")
|
||||
if not os.path.exists(api_file):
|
||||
logger.info("Fichier de clé API AllDebrid non trouvé")
|
||||
os.makedirs(config.SAVE_FOLDER, exist_ok=True)
|
||||
with open(api_file, "w", encoding="utf-8") as f:
|
||||
f.write("")
|
||||
logger.info(f"Fichier de clé API AllDebrid créé : {api_file}")
|
||||
return ""
|
||||
with open(api_file, "r", encoding="utf-8") as f:
|
||||
api_key = f.read().strip()
|
||||
logger.debug(f"Clé API AllDebrid lue: '{api_key}' (longueur: {len(api_key)})")
|
||||
if not api_key:
|
||||
logger.warning("Clé API AllDebrid vide, renseignez-la dans AllDebridAPI.txt pour activer le débridage.")
|
||||
# Stocke dans la config pour usage global
|
||||
try:
|
||||
config.API_KEY_ALLDEBRID = api_key
|
||||
except Exception:
|
||||
pass
|
||||
return api_key
|
||||
paths = {
|
||||
'1fichier': getattr(config, 'API_KEY_1FICHIER_PATH', ''),
|
||||
'alldebrid': getattr(config, 'API_KEY_ALLDEBRID_PATH', ''),
|
||||
}
|
||||
cache_attr = '_api_keys_cache'
|
||||
if not hasattr(config, cache_attr):
|
||||
setattr(config, cache_attr, {'1fichier_mtime': None, 'alldebrid_mtime': None})
|
||||
cache_data = getattr(config, cache_attr)
|
||||
reloaded = False
|
||||
|
||||
for key_name, path in paths.items():
|
||||
if not path:
|
||||
continue
|
||||
# Création fichier vide si absent
|
||||
try:
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, 'w', encoding='utf-8') as f:
|
||||
f.write("")
|
||||
except Exception as ce:
|
||||
logger.error(f"Impossible de préparer le fichier clé {key_name}: {ce}")
|
||||
continue
|
||||
try:
|
||||
mtime = os.path.getmtime(path)
|
||||
except Exception:
|
||||
mtime = None
|
||||
cache_key = f"{key_name}_mtime"
|
||||
if force or (mtime is not None and mtime != cache_data.get(cache_key)):
|
||||
# Lecture
|
||||
try:
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
value = f.read().strip()
|
||||
except Exception as re:
|
||||
logger.error(f"Erreur lecture clé {key_name}: {re}")
|
||||
value = ""
|
||||
# Assignation dans config
|
||||
if key_name == '1fichier':
|
||||
config.API_KEY_1FICHIER = value
|
||||
else:
|
||||
config.API_KEY_ALLDEBRID = value
|
||||
cache_data[cache_key] = mtime
|
||||
reloaded = True
|
||||
return {
|
||||
'1fichier': getattr(config, 'API_KEY_1FICHIER', ''),
|
||||
'alldebrid': getattr(config, 'API_KEY_ALLDEBRID', ''),
|
||||
'reloaded': reloaded
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors du chargement de la clé API AllDebrid: {e}")
|
||||
return ""
|
||||
logger.error(f"Erreur load_api_keys: {e}")
|
||||
return {
|
||||
'1fichier': getattr(config, 'API_KEY_1FICHIER', ''),
|
||||
'alldebrid': getattr(config, 'API_KEY_ALLDEBRID', ''),
|
||||
'reloaded': False
|
||||
}
|
||||
|
||||
# Wrappers rétro-compatibilité (dépréciés)
|
||||
def load_api_key_1fichier(force: bool = False): # pragma: no cover
|
||||
return load_api_keys(force).get('1fichier', '')
|
||||
|
||||
def load_api_key_alldebrid(force: bool = False): # pragma: no cover
|
||||
return load_api_keys(force).get('alldebrid', '')
|
||||
|
||||
# Ancien nom conservé comme alias
|
||||
def ensure_api_keys_loaded(force: bool = False): # pragma: no cover
|
||||
return load_api_keys(force)
|
||||
|
||||
def load_music_config():
|
||||
"""Charge la configuration musique depuis rgsx_settings.json."""
|
||||
|
||||
Reference in New Issue
Block a user