mirror of
https://github.com/RetroGameSets/RGSX.git
synced 2026-03-21 09:15:27 +01:00
Compare commits
1 Commits
v2.3.1.9
...
v2.3.1.9.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3bbb15c40 |
379
README.md
379
README.md
@@ -1,241 +1,234 @@
|
||||
# 🎮 Retro Game Sets Xtra (RGSX)
|
||||
|
||||
## SUPPORT / HELP: https://discord.gg/Vph9jwg3VV
|
||||
## LISEZ-MOI / INSTRUCTIONS EN FRANCAIS : https://github.com/RetroGameSets/RGSX/blob/main/README_FR.md
|
||||
**[Discord Support](https://discord.gg/Vph9jwg3VV)** • **[Installation](#-installation)** • **[French Documentation](https://github.com/RetroGameSets/RGSX/blob/main/README_FR.md)**
|
||||
|
||||
RGSX is a Python application using Pygame for its graphical interface, created by and for the RetroGameSets community. It is completely free.
|
||||
|
||||
The application currently supports multiple download sources such as myrient and 1fichier (with optional unlocking / fallback via AllDebrid and Real-Debrid). Sources can be updated frequently.
|
||||
|
||||
## INSTALLATION : https://github.com/RetroGameSets/RGSX#-installation
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- **Game downloads**: Supports ZIP files and handles unsupported raw archives automatically based on allowed extensions defined in EmulationStation's `es_systems.cfg` (and custom `es_systems_*.cfg` on Batocera). RGSX reads the per‑system allowed extensions and extracts archives automatically if the target system does not support zipped files.
|
||||
- Most downloads require no account or authentication.
|
||||
- Systems tagged with `(1fichier)` in their name require a valid API key (1Fichier, AllDebrid or Real-Debrid) for premium links.
|
||||
|
||||
---
|
||||
> ## IMPORTANT (1Fichier / AllDebrid / Real-Debrid)
|
||||
> To download from 1Fichier links you may use one of: your 1Fichier API key, an AllDebrid API key (automatic fallback), or a Real-Debrid API key (fallback if others missing / limited).
|
||||
>
|
||||
> Where to paste your API key (file must contain ONLY the key):
|
||||
> - `/saves/ports/rgsx/1FichierAPI.txt` (1Fichier API key)
|
||||
> - `/saves/ports/rgsx/AllDebridAPI.txt` (AllDebrid API key – optional fallback)
|
||||
> - `/saves/ports/rgsx/RealDebridAPI.txt` (Real-Debrid API key – optional fallback)
|
||||
>
|
||||
> Do NOT create these files manually. Launch RGSX once: it will auto‑create the empty files if they are missing. Then open the relevant file and paste your key.
|
||||
---
|
||||
|
||||
**🧰 Command Line (CLI) Usage**
|
||||
|
||||
RGSX also provides a headless command‑line interface to list platforms/games and download ROMs:
|
||||
|
||||
- French CLI guide: https://github.com/RetroGameSets/RGSX/blob/main/README_CLI.md
|
||||
- English CLI guide: https://github.com/RetroGameSets/RGSX/blob/main/README_CLI_EN.md
|
||||
|
||||
- **Download history**: View all current and past downloads.
|
||||
- **Multi‑selection downloads**: Mark several games using the key mapped to Clear History (default X) to prepare a batch, then Confirm to launch sequential downloads.
|
||||
- **Control customization**: Remap keyboard / controller buttons; many popular pads are auto‑configured on first launch.
|
||||
- **Platform grid layouts**: Switch between 3x3, 3x4, 4x3, 4x4.
|
||||
- **Hide unsupported systems**: Automatically hides systems whose ROM folder is missing (toggle in Display menu).
|
||||
- **Change font & size**: Accessibility & readability adjustments directly in the menu.
|
||||
- **Search / filter mode**: Quickly filter games by name; includes on‑screen virtual keyboard for controllers.
|
||||
- **Multi‑language interface**: Switch language any time in the menu.
|
||||
- **Adaptive interface**: Scales cleanly from 800x600 up to 1080p (higher resolutions untested but should work).
|
||||
- **Auto update & restart**: The application restarts itself after applying an update.
|
||||
- **System & extension discovery**: On first run, RGSX parses `es_systems.cfg` (Batocera / RetroBat) and generates `/saves/ports/rgsx/rom_extensions.json` plus the supported systems list.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Requirements
|
||||
|
||||
### Operating System
|
||||
- Batocera / Knulli or RetroBat
|
||||
|
||||
### Hardware
|
||||
- PC, Raspberry Pi, handheld console...
|
||||
- Controller (recommended) or keyboard
|
||||
- Active internet connection
|
||||
|
||||
### Disk Space
|
||||
- ~100 MB for the application (additional space for downloaded games)
|
||||
A free, user-friendly ROM downloader for Batocera, Knulli, and RetroBat with multi-source support.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Installation
|
||||
|
||||
### Automatic Method (Batocera / Knulli)
|
||||
### Quick Install (Batocera / Knulli)
|
||||
|
||||
On the target system:
|
||||
- On Batocera PC: open an xTERM (F1 > Applications > xTERM), or
|
||||
- From another machine: connect via SSH (root / linux) using PuTTY, PowerShell, etc.
|
||||
**SSH or Terminal access required:**
|
||||
```bash
|
||||
curl -L bit.ly/rgsx-install | sh
|
||||
```
|
||||
|
||||
Run:
|
||||
`curl -L bit.ly/rgsx-install | sh`
|
||||
After installation:
|
||||
1. Update game lists: `Menu > Game Settings > Update game list`
|
||||
2. Find RGSX under **PORTS** or **Homebrew and ports**
|
||||
|
||||
Wait for the script to finish (log file and on‑screen output). Then update the game list via:
|
||||
`Menu > Game Settings > Update game list`
|
||||
### Manual Install (All Systems)
|
||||
1. **Download**: [RGSX_full_latest.zip](https://github.com/RetroGameSets/RGSX/releases/latest/download/RGSX_full_latest.zip)
|
||||
2. **Extract**:
|
||||
- **Batocera/Knulli**: Extract `ports` folder to `/roms/`
|
||||
- **RetroBat**: Extract both `ports` and `windows` folders to `/roms/`
|
||||
3. **Refresh**: `Menu > Game Settings > Update game list`
|
||||
|
||||
You will find RGSX under the "PORTS" or "Homebrew and ports" system. Physical paths created: `/roms/ports/RGSX` (and `/roms/windows/RGSX` on RetroBat environments as needed).
|
||||
### Manual Update (if automatic update failed)
|
||||
Download latest release : [RGSX_update_latest.zip](https://github.com/RetroGameSets/RGSX/releases/latest/download/RGSX_full_latest.zip)
|
||||
|
||||
### Manual Method (RetroBat / Batocera)
|
||||
|
||||
1. Download ZIP: https://github.com/RetroGameSets/RGSX/archive/refs/heads/main.zip
|
||||
2. Extract into your ROMS folder:
|
||||
- Batocera: only extract the `ports` folder contents
|
||||
- RetroBat: extract both `ports` and `windows`
|
||||
3. Ensure you now have: `/roms/ports/RGSX` and (RetroBat) `/roms/windows/RGSX`
|
||||
4. Update the game list: `Menu > Game Settings > Update game list`
|
||||
**Installed paths:**
|
||||
- `/roms/ports/RGSX` (all systems)
|
||||
- `/roms/windows/RGSX` (RetroBat only)
|
||||
|
||||
---
|
||||
|
||||
## 🏁 First Launch
|
||||
## 🎮 Usage
|
||||
|
||||
- RGSX appears in the "WINDOWS" system on RetroBat, and in "PORTS" / "Homebrew and ports" on Batocera/Knulli.
|
||||
- On first launch, if your controller matches a predefined profile in `/roms/ports/RGSX/assets/controls`, mapping is auto‑imported.
|
||||
- The app then downloads required data (system images, game lists, etc.).
|
||||
- If controls act strangely or are corrupt, delete `/saves/ports/rgsx/controls.json` and restart (it will be regenerated).
|
||||
### First Launch
|
||||
|
||||
INFO (RetroBat only): On the first run, Python (~50 MB) is downloaded into `/system/tools/python`. The screen may appear frozen on the loading splash for several seconds—this is normal. Installation output is logged in `/roms/ports/RGSX-INSTALL.log` (share this if you need support).
|
||||
- Auto-downloads system images and game lists
|
||||
- Auto-configures controls if your controller is recognized
|
||||
- **Controls broken?** Delete `/saves/ports/rgsx/controls.json` and restart
|
||||
|
||||
**Keyboard Mode**: When no controller is detected, controls display as `[Key]` instead of icons.
|
||||
|
||||
### Pause Menu Structure
|
||||
|
||||
**Controls**
|
||||
- View Controls Help
|
||||
- Remap Controls
|
||||
|
||||
**Display**
|
||||
- Layout (3×3, 3×4, 4×3, 4×4)
|
||||
- Font Size (general UI)
|
||||
- Footer Font Size (controls/version text)
|
||||
- Font Family (pixel fonts)
|
||||
- Hide Unknown Extension Warning
|
||||
|
||||
**Games**
|
||||
- Download History
|
||||
- Source Mode (RGSX / Custom)
|
||||
- Update Game Cache
|
||||
- Show Unsupported Platforms
|
||||
- Hide Premium Systems
|
||||
- Filter Platforms
|
||||
|
||||
**Settings**
|
||||
- Background Music Toggle
|
||||
- Symlink Options (Batocera)
|
||||
- Web Service (Batocera)
|
||||
- API Keys Management
|
||||
- Language Selection
|
||||
|
||||
---
|
||||
|
||||
## 🕹️ Usage
|
||||
## ✨ Features
|
||||
|
||||
### Menu Navigation
|
||||
- 🎯 **Smart System Detection** – Auto-discovers supported systems from `es_systems.cfg`
|
||||
- 📦 **Intelligent Archive Handling** – Auto-extracts archives when systems don't support ZIP files
|
||||
- 🔑 **Premium Unlocking** – 1Fichier API + AllDebrid/Real-Debrid fallback for unlimited downloads
|
||||
- 🎨 **Fully Customizable** – Layout (3×3 to 4×4), fonts, font sizes (UI + footer), languages (EN/FR/DE/ES/IT/PT)
|
||||
- 🎮 **Controller-First Design** – Auto-mapping for popular controllers + custom remapping support
|
||||
- 🔍 **Advanced Filtering** – Search by name, hide/show unsupported systems, filter platforms
|
||||
- 📊 **Download Management** – Queue system, history tracking, progress notifications
|
||||
- 🌐 **Custom Sources** – Use your own game repository URLs
|
||||
- ♿ **Accessibility** – Separate font scaling for UI and footer, keyboard-only mode support
|
||||
|
||||
- Use D‑Pad / Arrow keys to move between platforms, games, and options.
|
||||
- Press the Start key (default: `P` or controller Start) for the pause menu with all configuration options.
|
||||
- From the pause menu you can regenerate cached system/game/image lists to pull latest updates.
|
||||
|
||||
### Display Menu
|
||||
|
||||
- Layout: switch platform grid (3x3, 3x4, 4x3, 4x4)
|
||||
- Font size: adjust text scale (accessibility)
|
||||
- Show unsupported systems: toggle systems whose ROM directory is missing
|
||||
- Filter systems: persistently include/exclude systems by name
|
||||
> ### 🔑 API Keys Setup
|
||||
> For unlimited 1Fichier downloads, add your API key(s) to `/saves/ports/rgsx/`:
|
||||
> - `1FichierAPI.txt` – 1Fichier API key (recommended)
|
||||
> - `AllDebridAPI.txt` – AllDebrid fallback (optional)
|
||||
> - `RealDebridAPI.txt` – Real-Debrid fallback (optional)
|
||||
>
|
||||
> **Each file must contain ONLY the key, no extra text.**
|
||||
|
||||
### Downloading Games
|
||||
|
||||
1. Select a platform then a game
|
||||
2. Press the Confirm key (default: Enter / A) to start downloading
|
||||
3. (Optional) Press the Clear History key (default: X) on multiple games to toggle multi‑selection ([X] marker), then Confirm to launch a sequential batch
|
||||
4. Track progress in the HISTORY menu
|
||||
1. Browse platforms → Select game
|
||||
2. **Direct Download**: Press `Confirm`
|
||||
3. **Queue Download**: Press `X` (West button)
|
||||
4. Track progress in **History** menu or via popup notifications
|
||||
|
||||
### Control Customization
|
||||
### Custom Game Sources
|
||||
|
||||
- Open pause menu → Reconfigure controls
|
||||
- Hold each desired key/button for ~3 seconds when prompted
|
||||
- Button labels adapt to your pad (A/B/X/Y, LB/RB/LT/RT, etc.)
|
||||
- Delete `/saves/ports/rgsx/controls.json` if mapping breaks; restart to regenerate
|
||||
Switch to custom sources via **Pause Menu > Games > Source Mode**.
|
||||
|
||||
### History
|
||||
|
||||
- Access from pause menu or press the History key (default: H)
|
||||
- Select an entry to re‑download (e.g. after an error or cancellation)
|
||||
- CLEAR button empties the list only (does not delete installed games)
|
||||
- BACK cancels an active download
|
||||
|
||||
### Logs
|
||||
|
||||
Logs are stored at: `/roms/ports/RGSX/logs/RGSX.log` (provide this for troubleshooting).
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Changelog
|
||||
See Discord or GitHub commits for the latest changes.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Custom Game Sources
|
||||
Switch the game source in the pause menu (Game Source: RGSX / Custom).
|
||||
|
||||
Custom mode expects an HTTP/HTTPS ZIP URL pointing to a sources archive mirroring the default structure. Configure in:
|
||||
`{rgsx_settings path}` → key: `sources.custom_url`
|
||||
|
||||
Behavior:
|
||||
- If custom mode is selected and URL is empty/invalid → empty list + popup (no fallback)
|
||||
- Fix the URL then choose "Update games list" (restart if prompted)
|
||||
|
||||
Example `rgsx_settings.json` snippet:
|
||||
Configure in `/saves/ports/rgsx/rgsx_settings.json`:
|
||||
```json
|
||||
"sources": {
|
||||
"mode": "custom",
|
||||
"custom_url": "https://example.com/my-sources.zip"
|
||||
{
|
||||
"sources": {
|
||||
"mode": "custom",
|
||||
"custom_url": "https://example.com/my-sources.zip"
|
||||
}
|
||||
}
|
||||
```
|
||||
Switch back to RGSX mode any time via the pause menu.
|
||||
**Note**: If custom mode activated but Invalid/empty URL = using /saves/ports/rgsx/games.zip . You need to update games cache on RGSX menu after fixing URL.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Project Structure
|
||||
```
|
||||
/roms/windows/RGSX
|
||||
│
|
||||
├── RGSX Retrobat.bat # Windows/RetroBat launcher (not needed on Batocera/Knulli)
|
||||
## 🌐 Web Interface (Batocera/Knulli Only)
|
||||
|
||||
/roms/ports/
|
||||
├── RGSX-INSTALL.log # Install log (first scripted install)
|
||||
└── RGSX/
|
||||
├── __main__.py # Main entry point
|
||||
├── controls.py # Input handling & menu navigation events
|
||||
├── controls_mapper.py # Interactive control remapping & auto button naming
|
||||
├── display.py # Pygame rendering layer
|
||||
├── config.py # Global paths / parameters
|
||||
├── rgsx_settings.py # Unified settings manager
|
||||
├── network.py # Download logic (multi-provider, fallback)
|
||||
├── history.py # Download history store & UI logic
|
||||
├── language.py # Localization manager
|
||||
├── accessibility.py # Accessibility options (fonts, layout)
|
||||
├── utils.py # Helper utilities (text wrapping, truncation, etc.)
|
||||
├── update_gamelist.py # Game list updater (Batocera/Knulli)
|
||||
├── update_gamelist_windows.py # RetroBat gamelist auto-update on launch
|
||||
├── assets/ # Fonts, binaries, music, predefined control maps
|
||||
├── languages/ # Translation files
|
||||
└── logs/
|
||||
└── RGSX.log # Runtime log
|
||||
RGSX includes a web interface that launched automatically when using RGSX for remote browsing and downloading games from any device on your network.
|
||||
|
||||
/saves/ports/RGSX/
|
||||
├── systems_list.json # Discovered systems / folders / images
|
||||
├── games/ # Platform game link repositories
|
||||
├── images/ # Downloaded platform images
|
||||
├── rgsx_settings.json # Unified config (settings, language, music, symlinks, sources)
|
||||
├── controls.json # Generated control mapping
|
||||
├── history.json # Download history database
|
||||
├── rom_extensions.json # Allowed ROM extensions cache from es_systems.cfg
|
||||
├── 1FichierAPI.txt # 1Fichier API key (empty until you paste key)
|
||||
├── AllDebridAPI.txt # AllDebrid API key (optional fallback)
|
||||
└── RealDebridAPI.txt # Real-Debrid API key (optional fallback)
|
||||
### Accessing the Web Interface
|
||||
|
||||
1. **Find your Batocera IP address**:
|
||||
- Check Batocera menu: `Network Settings`
|
||||
- Or from terminal: `ip addr show`
|
||||
|
||||
2. **Open in browser**: `http://[BATOCERA_IP]:5000` or `http://BATOCERA:5000`
|
||||
- Example: `http://192.168.1.100:5000`
|
||||
|
||||
3. **Available from any device**: Phone, tablet, PC on the same network
|
||||
|
||||
### Web Interface Features
|
||||
|
||||
- 📱 **Mobile-Friendly** – Responsive design works on all screen sizes
|
||||
- 🔍 **Browse All Systems** – View all platforms and games
|
||||
- ⬇️ **Remote Downloads** – Queue downloads directly to your Batocera
|
||||
- 📊 **Real-Time Status** – See active downloads and history
|
||||
- 🎮 **Same Game Lists** – Uses identical sources as the main app
|
||||
|
||||
|
||||
### Enable/Disable Web Service at Boot, without the need to launch RGSX
|
||||
|
||||
**Method 1: From RGSX Menu**
|
||||
1. Open **Pause Menu** (Start/ALTGr)
|
||||
2. Navigate to **Settings > Web Service**
|
||||
3. Toggle **Enable at Boot**
|
||||
4. Restart your device
|
||||
|
||||
**Method 2: Manual Configuration**
|
||||
|
||||
Edit `/saves/ports/rgsx/rgsx_settings.json`:
|
||||
```json
|
||||
{
|
||||
"web_service": {
|
||||
"enabled_at_boot": true
|
||||
}
|
||||
}
|
||||
```
|
||||
**Port Configuration**: The web service runs on port `5000` by default. Ensure this port is not blocked by firewall rules.
|
||||
|
||||
---
|
||||
|
||||
## 📁 File Structure
|
||||
|
||||
```
|
||||
/roms/ports/RGSX/
|
||||
├── __main__.py # Entry point
|
||||
├── controls.py # Input handling
|
||||
├── display.py # Rendering engine
|
||||
├── network.py # Download manager
|
||||
├── rgsx_settings.py # Settings manager
|
||||
├── assets/controls/ # Controller profiles
|
||||
├── languages/ # Translations (EN/FR/DE/ES/IT/PT)
|
||||
└── logs/RGSX.log # Runtime logs
|
||||
|
||||
/roms/windows/RGSX/
|
||||
└── RGSX Retrobat.bat # RetroBat launcher
|
||||
|
||||
/saves/ports/rgsx/
|
||||
├── rgsx_settings.json # User preferences
|
||||
├── controls.json # Control mapping
|
||||
├── history.json # Download history
|
||||
├── rom_extensions.json # Supported extensions cache
|
||||
├── systems_list.json # Detected systems
|
||||
├── games/ # Game databases (per platform)
|
||||
├── images/ # Platform images
|
||||
├── 1FichierAPI.txt # 1Fichier API key
|
||||
├── AllDebridAPI.txt # AllDebrid API key
|
||||
└── RealDebridAPI.txt # Real-Debrid API key
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Troubleshooting
|
||||
|
||||
| Issue | Solution |
|
||||
|-------|----------|
|
||||
| Controls not working | Delete `/saves/ports/rgsx/controls.json` + restart |
|
||||
| Games not showing | Pause Menu > Games > Update Game Cache |
|
||||
| Download stuck | Check API keys in `/saves/ports/rgsx/` |
|
||||
| App crashes | Check `/roms/ports/RGSX/logs/RGSX.log` |
|
||||
| Layout change not applied | Restart RGSX after changing layout |
|
||||
|
||||
**Need help?** Share logs from `/roms/ports/RGSX/logs/` on [Discord](https://discord.gg/Vph9jwg3VV).
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
### Report a Bug
|
||||
1. Review `/roms/ports/RGSX/logs/RGSX.log`.
|
||||
2. Open a GitHub issue with a clear description + relevant log excerpt OR share it on Discord.
|
||||
|
||||
### Propose a Feature
|
||||
- Open an issue (or discuss on Discord first) describing the feature and its integration.
|
||||
|
||||
### Contribute Code
|
||||
1. Fork the repository & create a feature branch:
|
||||
```bash
|
||||
git checkout -b feature/your-feature-name
|
||||
```
|
||||
2. Test on Batocera / RetroBat.
|
||||
3. Open a Pull Request with a detailed summary.
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Known Issues
|
||||
- (None currently listed)
|
||||
- **Bug Reports**: Open GitHub issue with logs or post on Discord
|
||||
- **Feature Requests**: Discuss on Discord first, then open issue
|
||||
- **Code Contributions**:
|
||||
```bash
|
||||
git checkout -b feature/your-feature
|
||||
# Test on Batocera/RetroBat
|
||||
# Submit Pull Request
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 License
|
||||
This project is free software. You are free to use, modify, and distribute it under the terms of the included license.
|
||||
|
||||
Developed with ❤️ for retro gaming enthusiasts.
|
||||
Free and open-source software. Use, modify, and distribute freely.
|
||||
|
||||
## Thanks to all contributors, and followers of this app
|
||||
|
||||
[](https://starchart.cc/RetroGameSets/RGSX)
|
||||
|
||||
**Developed with ❤️ for the retro gaming community.**
|
||||
@@ -13,7 +13,7 @@ except Exception:
|
||||
pygame = None # type: ignore
|
||||
|
||||
# Version actuelle de l'application
|
||||
app_version = "2.3.1.9"
|
||||
app_version = "2.3.1.9.1"
|
||||
|
||||
|
||||
def get_application_root():
|
||||
|
||||
@@ -1415,7 +1415,7 @@ def handle_controls(event, sources, joystick, screen):
|
||||
# Sous-menu Display
|
||||
elif config.menu_state == "pause_display_menu":
|
||||
sel = getattr(config, 'pause_display_selection', 0)
|
||||
total = 9 # layout, font size, footer font size, font family, unsupported, unknown, hide premium, filter, back
|
||||
total = 6 # layout, font size, footer font size, font family, unknown, back
|
||||
if is_input_matched(event, "up"):
|
||||
config.pause_display_selection = (sel - 1) % total
|
||||
config.needs_redraw = True
|
||||
@@ -1518,19 +1518,8 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur changement font family: {e}")
|
||||
# 4 unsupported toggle
|
||||
# 4 allow unknown extensions
|
||||
elif sel == 4 and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
try:
|
||||
current = get_show_unsupported_platforms()
|
||||
new_val = set_show_unsupported_platforms(not current)
|
||||
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}")
|
||||
# 5 allow unknown extensions
|
||||
elif sel == 5 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)
|
||||
@@ -1539,25 +1528,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}")
|
||||
# 6 hide premium systems
|
||||
elif sel == 6 and (is_input_matched(event, "confirm") or is_input_matched(event, "left") or is_input_matched(event, "right")):
|
||||
try:
|
||||
cur = get_hide_premium_systems()
|
||||
new_val = set_hide_premium_systems(not cur)
|
||||
config.popup_message = ("Premium hidden" if new_val else "Premium visible") if _ is None else (_("popup_hide_premium_on") if new_val else _("popup_hide_premium_off"))
|
||||
config.popup_timer = 2500
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur toggle hide_premium_systems: {e}")
|
||||
# 7 filter platforms
|
||||
elif sel == 7 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
|
||||
# 8 back
|
||||
elif sel == 8 and (is_input_matched(event, "confirm")):
|
||||
# 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
|
||||
@@ -1569,7 +1541,7 @@ def handle_controls(event, sources, joystick, screen):
|
||||
# Sous-menu Games
|
||||
elif config.menu_state == "pause_games_menu":
|
||||
sel = getattr(config, 'pause_games_selection', 0)
|
||||
total = 4 # history, source, redownload, back
|
||||
total = 7 # history, source, redownload, unsupported, hide premium, filter, back
|
||||
if is_input_matched(event, "up"):
|
||||
config.pause_games_selection = (sel - 1) % total
|
||||
config.needs_redraw = True
|
||||
@@ -1605,7 +1577,35 @@ def handle_controls(event, sources, joystick, screen):
|
||||
config.menu_state = "reload_games_data"
|
||||
config.redownload_confirm_selection = 0
|
||||
config.needs_redraw = True
|
||||
elif sel == 3 and is_input_matched(event, "confirm"): # back
|
||||
# 3 unsupported toggle
|
||||
elif sel == 3 and (is_input_matched(event, "left") or is_input_matched(event, "right") or is_input_matched(event, "confirm")):
|
||||
try:
|
||||
current = get_show_unsupported_platforms()
|
||||
new_val = set_show_unsupported_platforms(not current)
|
||||
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}")
|
||||
# 4 hide premium systems
|
||||
elif sel == 4 and (is_input_matched(event, "confirm") or is_input_matched(event, "left") or is_input_matched(event, "right")):
|
||||
try:
|
||||
cur = get_hide_premium_systems()
|
||||
new_val = set_hide_premium_systems(not cur)
|
||||
config.popup_message = ("Premium hidden" if new_val else "Premium visible") if _ is None else (_("popup_hide_premium_on") if new_val else _("popup_hide_premium_off"))
|
||||
config.popup_timer = 2500
|
||||
config.needs_redraw = True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur toggle hide_premium_systems: {e}")
|
||||
# 5 filter platforms
|
||||
elif sel == 5 and (is_input_matched(event, "confirm") or is_input_matched(event, "right")):
|
||||
config.filter_return_to = "pause_games_menu"
|
||||
config.menu_state = "filter_platforms"
|
||||
config.selected_filter_index = 0
|
||||
config.filter_platforms_scroll_offset = 0
|
||||
config.needs_redraw = True
|
||||
elif sel == 6 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
|
||||
|
||||
@@ -1978,9 +1978,7 @@ def draw_pause_controls_menu(screen, selected_index):
|
||||
|
||||
def draw_pause_display_menu(screen, selected_index):
|
||||
from rgsx_settings import (
|
||||
get_show_unsupported_platforms,
|
||||
get_allow_unknown_extensions,
|
||||
get_hide_premium_systems,
|
||||
get_font_family
|
||||
)
|
||||
# Layout label
|
||||
@@ -2011,38 +2009,21 @@ def draw_pause_display_menu(screen, selected_index):
|
||||
fam_label = family_map.get(current_family, current_family)
|
||||
font_family_txt = f"{_('submenu_display_font_family') if _ else 'Font'}: < {fam_label} >"
|
||||
|
||||
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} >"
|
||||
# Hide premium systems
|
||||
hide_premium = get_hide_premium_systems()
|
||||
status_hide_premium = _('status_on') if hide_premium else _('status_off')
|
||||
hide_premium_label = _('menu_hide_premium_systems') if _ else 'Hide Premium systems'
|
||||
hide_premium_txt = f"{hide_premium_label}: < {status_hide_premium} >"
|
||||
filter_txt = _("submenu_display_filter_platforms") if _ else "Filter Platforms"
|
||||
back_txt = _("menu_back") if _ else "Back"
|
||||
options = [layout_txt, font_txt, footer_font_txt, font_family_txt, unsupported_txt, unknown_txt, hide_premium_txt, filter_txt, back_txt]
|
||||
options = [layout_txt, font_txt, footer_font_txt, font_family_txt, unknown_txt, back_txt]
|
||||
_draw_submenu_generic(screen, _("menu_display"), options, selected_index)
|
||||
instruction_keys = [
|
||||
"instruction_display_layout",
|
||||
"instruction_display_font_size",
|
||||
"instruction_display_footer_font_size",
|
||||
"instruction_display_font_family",
|
||||
"instruction_display_show_unsupported",
|
||||
"instruction_display_unknown_ext",
|
||||
"instruction_display_hide_premium",
|
||||
"instruction_display_filter_platforms",
|
||||
"instruction_generic_back",
|
||||
]
|
||||
key = instruction_keys[selected_index] if 0 <= selected_index < len(instruction_keys) else None
|
||||
@@ -2059,19 +2040,40 @@ def draw_pause_display_menu(screen, selected_index):
|
||||
draw_menu_instruction(screen, _(key), last_button_bottom)
|
||||
|
||||
def draw_pause_games_menu(screen, selected_index):
|
||||
from rgsx_settings import get_sources_mode
|
||||
from rgsx_settings import get_sources_mode, get_show_unsupported_platforms, get_hide_premium_systems
|
||||
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")
|
||||
history_txt = _("menu_history") if _ else "History"
|
||||
|
||||
# Show unsupported systems
|
||||
unsupported = get_show_unsupported_platforms()
|
||||
status_unsupported = _('status_on') if unsupported else _('status_off')
|
||||
raw_unsupported_label = _('submenu_display_show_unsupported') if _ else 'Show unsupported systems: {status}'
|
||||
if '{status}' in raw_unsupported_label:
|
||||
raw_unsupported_label = raw_unsupported_label.split('{status}')[0].rstrip(' :')
|
||||
unsupported_txt = f"{raw_unsupported_label}: < {status_unsupported} >"
|
||||
|
||||
# Hide premium systems
|
||||
hide_premium = get_hide_premium_systems()
|
||||
status_hide_premium = _('status_on') if hide_premium else _('status_off')
|
||||
hide_premium_label = _('menu_hide_premium_systems') if _ else 'Hide Premium systems'
|
||||
hide_premium_txt = f"{hide_premium_label}: < {status_hide_premium} >"
|
||||
|
||||
# Filter platforms
|
||||
filter_txt = _("submenu_display_filter_platforms") if _ else "Filter Platforms"
|
||||
|
||||
back_txt = _("menu_back") if _ else "Back"
|
||||
options = [history_txt, source_txt, update_txt, back_txt]
|
||||
options = [history_txt, source_txt, update_txt, unsupported_txt, hide_premium_txt, filter_txt, back_txt]
|
||||
_draw_submenu_generic(screen, _("menu_games") if _ else "Games", options, selected_index)
|
||||
instruction_keys = [
|
||||
"instruction_games_history",
|
||||
"instruction_games_source_mode",
|
||||
"instruction_games_update_cache",
|
||||
"instruction_display_show_unsupported",
|
||||
"instruction_display_hide_premium",
|
||||
"instruction_display_filter_platforms",
|
||||
"instruction_generic_back",
|
||||
]
|
||||
key = instruction_keys[selected_index] if 0 <= selected_index < len(instruction_keys) else None
|
||||
@@ -2084,7 +2086,31 @@ def draw_pause_games_menu(screen, selected_index):
|
||||
title_rect_height = title_surface.get_height()
|
||||
start_y = menu_y + margin_top_bottom//2 + title_rect_height + 10 + 10
|
||||
last_button_bottom = start_y + (len(options)-1) * (button_height + 10) + button_height
|
||||
draw_menu_instruction(screen, _(key), last_button_bottom)
|
||||
text = _(key)
|
||||
if key == "instruction_display_hide_premium":
|
||||
# Inject dynamic list of premium providers from config.PREMIUM_HOST_MARKERS
|
||||
try:
|
||||
from config import PREMIUM_HOST_MARKERS
|
||||
# Clean, preserve order, remove duplicates (case-insensitive)
|
||||
seen = set()
|
||||
providers_clean = []
|
||||
for p in PREMIUM_HOST_MARKERS:
|
||||
p_lower = p.lower()
|
||||
if p_lower not in seen:
|
||||
seen.add(p_lower)
|
||||
providers_clean.append(p)
|
||||
providers_str = ", ".join(providers_clean)
|
||||
if not providers_str:
|
||||
providers_str = "1fichier, etc."
|
||||
if "{providers}" in text:
|
||||
text = text.format(providers=providers_str)
|
||||
else:
|
||||
# fallback si placeholder absent
|
||||
text = f"{text} ({providers_str})"
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
draw_menu_instruction(screen, text, last_button_bottom)
|
||||
|
||||
def draw_pause_settings_menu(screen, selected_index):
|
||||
from rgsx_settings import get_symlink_option
|
||||
@@ -2369,22 +2395,22 @@ def draw_controls_help(screen, previous_state):
|
||||
# Contenu des catégories (avec icônes si disponibles)
|
||||
control_categories = {
|
||||
_("controls_category_navigation"): [
|
||||
("icons", ["up", "down", "left", "right"], f"{get_control_display('up', '↑')} {get_control_display('down', '↓')} {get_control_display('left', '←')} {get_control_display('right', '→')} : {_('controls_navigation')}"),
|
||||
("icons", ["page_up", "page_down"], f"{get_control_display('page_up', 'LB')} {get_control_display('page_down', 'RB')} : {_('controls_pages')}"),
|
||||
("icons", ["up", "down", "left", "right"], _('controls_navigation')),
|
||||
("icons", ["page_up", "page_down"], _('controls_pages')),
|
||||
],
|
||||
_("controls_category_main_actions"): [
|
||||
("icons", ["confirm"], f"{get_control_display('confirm', 'A')} : {_('controls_confirm_select')}"),
|
||||
("icons", ["cancel"], f"{get_control_display('cancel', 'B')} : {_('controls_cancel_back')}"),
|
||||
("icons", ["start"], f"{get_control_display('start', 'Start')} : {_('controls_action_start')}"),
|
||||
("icons", ["confirm"], _('controls_confirm_select')),
|
||||
("icons", ["cancel"], _('controls_cancel_back')),
|
||||
("icons", ["start"], _('controls_action_start')),
|
||||
],
|
||||
_("controls_category_downloads"): [
|
||||
("icons", ["history"], f"{get_control_display('history', 'Y')} : {_('controls_action_history')}"),
|
||||
("icons", ["clear_history"], f"{get_control_display('clear_history', 'X')} : {_('controls_action_clear_history')}"),
|
||||
("icons", ["history"], _('controls_action_history')),
|
||||
("icons", ["clear_history"], _('controls_action_clear_history')),
|
||||
],
|
||||
_("controls_category_search"): [
|
||||
("icons", ["filter"], f"{get_control_display('filter', 'Select')} : {_('controls_filter_search')}"),
|
||||
("icons", ["delete"], f"{get_control_display('delete', 'Suppr')} : {_('controls_action_delete')}"),
|
||||
("icons", ["space"], f"{get_control_display('space', 'Espace')} : {_('controls_action_space')}"),
|
||||
("icons", ["filter"], _('controls_filter_search')),
|
||||
("icons", ["delete"], _('controls_action_delete')),
|
||||
("icons", ["space"], _('controls_action_space')),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "2.3.1.9"
|
||||
"version": "2.3.1.9.1"
|
||||
}
|
||||
Reference in New Issue
Block a user