mirror of
https://github.com/RetroGameSets/RGSX.git
synced 2026-03-19 16:26:00 +01:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0915a90fbe | ||
|
|
3ae3c151eb | ||
|
|
7460b12d71 | ||
|
|
2f437c1aa4 |
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@@ -119,6 +119,16 @@ jobs:
|
||||
|
||||
### 📖 Documentation
|
||||
[README.md](https://github.com/${{ github.repository }}/blob/main/README.md)
|
||||
|
||||
## SUPPORT US
|
||||
Donate , Buy me a beer or a coffee :
|
||||
if you want to support my project you can look here 🙂 https://bit.ly/donate-to-rgsx
|
||||
|
||||
Affiliate links :
|
||||
hi all if you want to buy a premium account, you can use affiliated links here to support dev of RGSX without donate anything :
|
||||
DEBRID-LINK.FR : https://debrid-link.fr/id/ow1DD
|
||||
1FICHIER.COM : https://1fichier.com/?af=3186111
|
||||
REAL-DEBRID.FR : http://real-debrid.com/?id=8441
|
||||
RELEASE_EOF
|
||||
|
||||
echo "✓ Release notes generated"
|
||||
|
||||
@@ -32,7 +32,7 @@ from display import (
|
||||
draw_display_menu, draw_filter_menu_choice, draw_filter_advanced, draw_filter_priority_config,
|
||||
draw_history_list, draw_clear_history_dialog, draw_cancel_download_dialog,
|
||||
draw_confirm_dialog, draw_reload_games_data_dialog, draw_popup, draw_gradient,
|
||||
draw_toast, show_toast, THEME_COLORS
|
||||
draw_toast, show_toast, THEME_COLORS, sync_display_metrics
|
||||
)
|
||||
from language import _
|
||||
from network import test_internet, download_rom, is_1fichier_url, download_from_1fichier, check_for_updates, cancel_all_downloads, download_queue_worker
|
||||
@@ -45,7 +45,7 @@ from utils import (
|
||||
)
|
||||
from history import load_history, save_history, load_downloaded_games
|
||||
from config import OTA_data_ZIP
|
||||
from rgsx_settings import get_sources_mode, get_custom_sources_url, get_sources_zip_url
|
||||
from rgsx_settings import get_sources_mode, get_custom_sources_url, get_sources_zip_url, get_display_fullscreen
|
||||
from accessibility import load_accessibility_settings
|
||||
|
||||
# Configuration du logging
|
||||
@@ -430,7 +430,7 @@ def stop_web_server():
|
||||
|
||||
# Boucle principale
|
||||
async def main():
|
||||
global current_music, music_files, music_folder, joystick
|
||||
global current_music, music_files, music_folder, joystick, screen
|
||||
logger.debug("Début main")
|
||||
|
||||
# Charger les filtres de jeux sauvegardés
|
||||
@@ -610,6 +610,27 @@ async def main():
|
||||
current_music = play_random_music(music_files, music_folder, current_music)
|
||||
continue
|
||||
|
||||
resize_events = {
|
||||
getattr(pygame, 'VIDEORESIZE', -1),
|
||||
getattr(pygame, 'WINDOWSIZECHANGED', -2),
|
||||
getattr(pygame, 'WINDOWRESIZED', -3),
|
||||
}
|
||||
if event.type in resize_events and not get_display_fullscreen():
|
||||
try:
|
||||
if event.type == getattr(pygame, 'VIDEORESIZE', -1):
|
||||
new_width = max(640, int(getattr(event, 'w', config.screen_width)))
|
||||
new_height = max(360, int(getattr(event, 'h', config.screen_height)))
|
||||
screen = pygame.display.set_mode((new_width, new_height), pygame.RESIZABLE)
|
||||
else:
|
||||
screen = pygame.display.get_surface() or screen
|
||||
|
||||
sync_display_metrics(screen)
|
||||
config.needs_redraw = True
|
||||
logger.debug(f"Fenêtre redimensionnée: {config.screen_width}x{config.screen_height}")
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors du redimensionnement de la fenêtre: {e}")
|
||||
continue
|
||||
|
||||
if event.type == pygame.QUIT:
|
||||
config.menu_state = "confirm_exit"
|
||||
config.confirm_selection = 0
|
||||
|
||||
@@ -26,7 +26,7 @@ except Exception:
|
||||
pygame = None # type: ignore
|
||||
|
||||
# Version actuelle de l'application
|
||||
app_version = "2.6.0.1"
|
||||
app_version = "2.6.0.3"
|
||||
|
||||
# Nombre de jours avant de proposer la mise à jour de la liste des jeux
|
||||
GAMELIST_UPDATE_DAYS = 7
|
||||
|
||||
@@ -2212,11 +2212,27 @@ def handle_controls(event, sources, joystick, screen):
|
||||
# Sous-menu Display
|
||||
elif config.menu_state == "pause_display_menu":
|
||||
sel = getattr(config, 'pause_display_selection', 0)
|
||||
# layout, font submenu, family, [monitor if multi], light, unknown, back
|
||||
# layout, font submenu, family, [monitor if multi], [display mode on Windows], light, unknown, back
|
||||
from rgsx_settings import get_available_monitors
|
||||
monitors = get_available_monitors()
|
||||
show_monitor = len(monitors) > 1
|
||||
total = 7 if show_monitor else 6 # dynamic total based on monitor count
|
||||
show_display_mode = getattr(config, 'OPERATING_SYSTEM', '') == "Windows"
|
||||
|
||||
monitor_index = 3 if show_monitor else None
|
||||
display_mode_index = 4 if show_monitor else 3
|
||||
if not show_display_mode:
|
||||
display_mode_index = None
|
||||
|
||||
next_index = 3
|
||||
if show_monitor:
|
||||
next_index += 1
|
||||
if show_display_mode:
|
||||
next_index += 1
|
||||
|
||||
light_index = next_index
|
||||
unknown_index = light_index + 1
|
||||
back_index = unknown_index + 1
|
||||
total = back_index + 1
|
||||
if is_input_matched(event, "up"):
|
||||
config.pause_display_selection = (sel - 1) % total
|
||||
config.needs_redraw = True
|
||||
@@ -2274,8 +2290,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur changement font family: {e}")
|
||||
# 3 monitor selection (only if multiple monitors)
|
||||
elif sel == 3 and show_monitor and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
# Monitor selection (only if multiple monitors)
|
||||
elif monitor_index is not None and sel == monitor_index and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
try:
|
||||
from rgsx_settings import get_display_monitor, set_display_monitor
|
||||
current = get_display_monitor()
|
||||
@@ -2286,8 +2302,19 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur changement moniteur: {e}")
|
||||
# light mode toggle (index 4 if show_monitor, else 3)
|
||||
elif ((sel == 4 and show_monitor) or (sel == 3 and not show_monitor)) and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
# Display mode toggle (Windows only)
|
||||
elif display_mode_index is not None and sel == display_mode_index and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
try:
|
||||
from rgsx_settings import get_display_fullscreen, set_display_fullscreen
|
||||
current = get_display_fullscreen()
|
||||
set_display_fullscreen(not current)
|
||||
config.popup_message = _("display_mode_restart_required") if _ else "Restart required to apply screen mode"
|
||||
config.popup_timer = 3000
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur toggle fullscreen/windowed: {e}")
|
||||
# Light mode toggle
|
||||
elif sel == light_index and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
try:
|
||||
from rgsx_settings import get_light_mode, set_light_mode
|
||||
current = get_light_mode()
|
||||
@@ -2297,8 +2324,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur toggle light mode: {e}")
|
||||
# allow unknown extensions (index 5 if show_monitor, else 4)
|
||||
elif ((sel == 5 and show_monitor) or (sel == 4 and not show_monitor)) and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
# Allow unknown extensions
|
||||
elif sel == unknown_index and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
try:
|
||||
current = get_allow_unknown_extensions()
|
||||
new_val = set_allow_unknown_extensions(not current)
|
||||
@@ -2307,8 +2334,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur toggle allow_unknown_extensions: {e}")
|
||||
# back (index 6 if show_monitor, else 5)
|
||||
elif ((sel == 6 and show_monitor) or (sel == 5 and not show_monitor)) and is_input_matched(event, "confirm"):
|
||||
# Back
|
||||
elif sel == back_index and is_input_matched(event, "confirm"):
|
||||
config.menu_state = "pause_menu"
|
||||
config.last_state_change_time = pygame.time.get_ticks()
|
||||
config.needs_redraw = True
|
||||
|
||||
@@ -30,6 +30,24 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
OVERLAY = None # Initialisé dans init_display()
|
||||
|
||||
|
||||
def sync_display_metrics(screen=None):
|
||||
"""Synchronise les dimensions globales et l'overlay avec la fenêtre courante."""
|
||||
global OVERLAY
|
||||
|
||||
if screen is None:
|
||||
screen = pygame.display.get_surface()
|
||||
if screen is None:
|
||||
return None
|
||||
|
||||
screen_width, screen_height = screen.get_size()
|
||||
config.screen_width = screen_width
|
||||
config.screen_height = screen_height
|
||||
|
||||
OVERLAY = pygame.Surface((screen_width, screen_height), pygame.SRCALPHA)
|
||||
OVERLAY.fill((5, 10, 20, 160))
|
||||
return screen
|
||||
|
||||
# --- Helpers: SVG icons for controls (local cache, optional cairosvg) ---
|
||||
_HELP_ICON_CACHE = {}
|
||||
|
||||
@@ -280,6 +298,7 @@ def init_display():
|
||||
settings = load_rgsx_settings()
|
||||
logger.debug(f"Settings chargés: display={settings.get('display', {})}")
|
||||
target_monitor = settings.get("display", {}).get("monitor", 0)
|
||||
is_fullscreen = get_display_fullscreen(settings)
|
||||
|
||||
|
||||
# Vérifier les variables d'environnement (priorité sur les settings)
|
||||
@@ -328,14 +347,24 @@ def init_display():
|
||||
screen_width = display_info.current_w
|
||||
screen_height = display_info.current_h
|
||||
|
||||
# Créer la fenêtre en plein écran
|
||||
flags = pygame.FULLSCREEN
|
||||
# Sur Linux/Batocera, utiliser SCALED pour respecter la résolution forcée d'EmulationStation
|
||||
if platform.system() == "Linux":
|
||||
flags |= pygame.SCALED
|
||||
# Sur certains systèmes Windows, NOFRAME aide pour le multi-écran
|
||||
elif platform.system() == "Windows":
|
||||
flags |= pygame.NOFRAME
|
||||
# Créer la fenêtre selon le mode d'affichage configuré.
|
||||
if is_fullscreen:
|
||||
flags = pygame.FULLSCREEN
|
||||
# Sur Linux/Batocera, utiliser SCALED pour respecter la résolution forcée d'EmulationStation
|
||||
if platform.system() == "Linux":
|
||||
flags |= pygame.SCALED
|
||||
# Sur certains systèmes Windows, NOFRAME aide pour le multi-écran
|
||||
elif platform.system() == "Windows":
|
||||
flags |= pygame.NOFRAME
|
||||
else:
|
||||
flags = pygame.RESIZABLE
|
||||
if platform.system() == "Windows":
|
||||
os.environ["SDL_VIDEO_CENTERED"] = "1"
|
||||
|
||||
desktop_width = screen_width
|
||||
desktop_height = screen_height
|
||||
screen_width = min(desktop_width, max(960, int(desktop_width * 0.9)))
|
||||
screen_height = min(desktop_height, max(540, int(desktop_height * 0.9)))
|
||||
|
||||
try:
|
||||
screen = pygame.display.set_mode((screen_width, screen_height), flags, display=target_monitor)
|
||||
@@ -345,15 +374,16 @@ def init_display():
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating display on monitor {target_monitor}: {e}")
|
||||
screen = pygame.display.set_mode((screen_width, screen_height), flags)
|
||||
|
||||
config.screen_width = screen_width
|
||||
config.screen_height = screen_height
|
||||
|
||||
screen = sync_display_metrics(screen)
|
||||
screen_width, screen_height = screen.get_size()
|
||||
|
||||
config.current_monitor = target_monitor
|
||||
|
||||
# Initialisation de OVERLAY avec effet glassmorphism
|
||||
OVERLAY = pygame.Surface((screen_width, screen_height), pygame.SRCALPHA)
|
||||
OVERLAY.fill((5, 10, 20, 160)) # Bleu très foncé semi-transparent pour effet verre
|
||||
logger.debug(f"Écran initialisé: {screen_width}x{screen_height} sur moniteur {target_monitor}")
|
||||
|
||||
logger.debug(
|
||||
f"Écran initialisé: {screen_width}x{screen_height} sur moniteur {target_monitor} "
|
||||
f"({'fullscreen' if is_fullscreen else 'windowed'})"
|
||||
)
|
||||
return screen
|
||||
|
||||
# Fond d'écran dégradé
|
||||
@@ -2995,6 +3025,13 @@ def draw_pause_display_menu(screen, selected_index):
|
||||
monitor_info = monitors[current_monitor] if current_monitor < num_monitors else monitors[0]
|
||||
monitor_value = f"{monitor_info['name']} ({monitor_info['resolution']})"
|
||||
monitor_txt = f"{_('display_monitor') if _ else 'Monitor'}: < {monitor_value} >"
|
||||
|
||||
# Display mode - Windows only
|
||||
show_display_mode_option = getattr(config, 'OPERATING_SYSTEM', '') == "Windows"
|
||||
if show_display_mode_option:
|
||||
is_fullscreen = get_display_fullscreen()
|
||||
display_mode_value = _("display_fullscreen") if is_fullscreen else _("display_windowed")
|
||||
display_mode_txt = f"{_('display_mode') if _ else 'Screen mode'}: < {display_mode_value} >"
|
||||
|
||||
# Allow unknown extensions
|
||||
allow_unknown = get_allow_unknown_extensions()
|
||||
@@ -3011,8 +3048,7 @@ def draw_pause_display_menu(screen, selected_index):
|
||||
|
||||
back_txt = _("menu_back") if _ else "Back"
|
||||
|
||||
# Build options list - conditional monitor option
|
||||
# layout, font submenu, family, [monitor if multi], light, unknown, back
|
||||
# Build options list - conditional monitor and display mode options
|
||||
font_submenu_txt = f"{_('submenu_display_font_size') if _ else 'Font Size'} >"
|
||||
options = [layout_txt, font_submenu_txt, font_family_txt]
|
||||
instruction_keys = [
|
||||
@@ -3024,6 +3060,10 @@ def draw_pause_display_menu(screen, selected_index):
|
||||
if show_monitor_option:
|
||||
options.append(monitor_txt)
|
||||
instruction_keys.append("instruction_display_monitor")
|
||||
|
||||
if show_display_mode_option:
|
||||
options.append(display_mode_txt)
|
||||
instruction_keys.append("instruction_display_mode")
|
||||
|
||||
options.extend([light_txt, unknown_txt, back_txt])
|
||||
instruction_keys.extend([
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
import os
|
||||
import logging
|
||||
import re
|
||||
import config
|
||||
from datetime import datetime
|
||||
|
||||
@@ -168,7 +169,7 @@ IGNORED_ROM_SCAN_EXTENSIONS = {
|
||||
|
||||
|
||||
def normalize_downloaded_game_name(game_name):
|
||||
"""Normalise un nom de jeu pour les comparaisons en ignorant l'extension."""
|
||||
"""Normalise un nom de jeu pour les comparaisons en ignorant extension et tags."""
|
||||
if not isinstance(game_name, str):
|
||||
return ""
|
||||
|
||||
@@ -176,7 +177,10 @@ def normalize_downloaded_game_name(game_name):
|
||||
if not normalized:
|
||||
return ""
|
||||
|
||||
return os.path.splitext(normalized)[0].strip().lower()
|
||||
normalized = os.path.splitext(normalized)[0]
|
||||
normalized = re.sub(r'\s*[\[(][^\])]*[\])]', '', normalized)
|
||||
normalized = re.sub(r'\s+', ' ', normalized)
|
||||
return normalized.strip().lower()
|
||||
|
||||
|
||||
def _normalize_downloaded_games_dict(downloaded):
|
||||
|
||||
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "2.6.0.1"
|
||||
"version": "2.6.0.3"
|
||||
}
|
||||
Reference in New Issue
Block a user