diff --git a/CarteSD/README_SD_IMAGES_LAUNCHER.txt b/CarteSD/README_SD_IMAGES_LAUNCHER.txt new file mode 100644 index 0000000..61f82a1 --- /dev/null +++ b/CarteSD/README_SD_IMAGES_LAUNCHER.txt @@ -0,0 +1,21 @@ +RaptorLauncher v0.9 - Images du launcher (RAW) +=============================================== + +Placez les images a la racine de la carte SD (dossier CarteSD), pas dans /games : + +- /boot.raw -> image de lancement (affichee au demarrage) +- /home_bg.raw -> image de fond de l'accueil (icones + noms dessines par-dessus) + +Configuration dans /settings.json : + +{ + "boot_splash_raw": "/boot.raw", + "boot_splash_ms": 1500, + "home_bg_raw": "/home_bg.raw" +} + +Notes : +- boot_splash_ms est en millisecondes (ex: 1000 = 1 seconde, 2000 = 2 secondes). +- Si boot.raw ou home_bg.raw n'existe pas (ou est invalide), le launcher reste en mode classique. +- Format attendu : RAW RGB565. +- Taille conseillee : 320x240 pour eviter recadrage/perte. diff --git a/CarteSD/boot.raw b/CarteSD/boot.raw new file mode 100644 index 0000000..bfb789d Binary files /dev/null and b/CarteSD/boot.raw differ diff --git a/CarteSD/home_bg.raw b/CarteSD/home_bg.raw new file mode 100644 index 0000000..cb83479 Binary files /dev/null and b/CarteSD/home_bg.raw differ diff --git a/README.md b/README.md index c10e14e..02b7566 100644 --- a/README.md +++ b/README.md @@ -51,3 +51,35 @@ ## Historique / corrigé Certaines remarques anciennes peuvent être partiellement obsolètes (ex. correctifs matériels/pins RGB déjà appliqués). Conserver ces points comme **historique**, et préciser l'état **corrigé/non corrigé** au fur et à mesure. + +## Vérification rapide — RaptorLauncher_V0.9 + +### Fond d'écran de l'accueil (derrière les icônes) +- Dans `RaptorLauncher_V0.9`, l'écran d'accueil efface d'abord l'écran avec `displayClear()`, puis dessine les icônes de jeux. +- Il n'y a pas de chargement d'image de fond globale pour la grille de jeux (pas de `home_bg` lu depuis la SD dans `drawHomeScreen()`). +- Résultat : en l'état, la v0.9 n'affiche pas de fond d'écran derrière les icônes sur la page qui liste les jeux. + +### Ordre d'affichage des jeux +- L'ordre est bien modifiable via `meta.json` de chaque jeu avec le champ `index` (ou `indice` en fallback). +- Le launcher trie d'abord par `index` croissant. +- En cas d'égalité d'`index`, il trie ensuite par nom (`name`) en ordre alphabétique. + +### Action pratique +- Pour changer l'ordre, modifier `index` dans `CarteSD/games//meta.json`, puis redémarrer le launcher. + +## Nouveaux réglages v0.9 (images RAW) + +Dans `settings.json` à la racine de la SD : + +```json +{ + "boot_splash_raw": "/boot.raw", + "boot_splash_ms": 1500, + "home_bg_raw": "/home_bg.raw" +} +``` + +- `boot_splash_raw` : image RAW affichée au démarrage (si absente/invalide = démarrage classique). +- `boot_splash_ms` : durée d'affichage au boot en millisecondes (0 à 10000). +- `home_bg_raw` : fond RAW de l'écran d'accueil (les icônes et noms des jeux sont dessinés par-dessus). +- Le bouton **Paramètres** de l'accueil est remplacé par une icône **roue dentée** dessinée en code (pas chargée depuis la SD). diff --git a/RaptorLauncher_V0.9/README.md b/RaptorLauncher_V0.9/README.md new file mode 100644 index 0000000..02b7566 --- /dev/null +++ b/RaptorLauncher_V0.9/README.md @@ -0,0 +1,85 @@ +# RaptorLauncher00 + +## Erreurs fréquentes (version courte) +- **Ne surchargez pas `setup()`** : initialisez seulement le matériel critique, puis laissez le reste non-bloquant dans `loop()`. +- **Toujours valider la SD avant lancement** : un jeu sans `game.bin` ou avec `meta.json` invalide doit être refusé proprement. +- **Assets visuels optionnels** : `home_bg.bmp` et `splash.bmp` doivent toujours avoir un fallback (pas de crash si absents/corrompus). +- **Sprites/images trop lourds** : surveiller RAM/PSRAM, surtout pendant les chargements BMP/RAW. +- **Ne pas masquer les erreurs série** : le moniteur série est la source principale de diagnostic terrain. + +## Retours d'expérience (détaillé) + +### 1) ParaRunner +- **Problème observé** : ralentissements/intermittences quand beaucoup de sprites sont manipulés en même temps. +- **Cause probable** : allocations fréquentes et redraw trop complet. +- **Solution recommandée** : + - Précharger les ressources critiques. + - Éviter les allocations répétées dans la boucle jeu. + - Limiter les redraws aux zones réellement modifiées. + +### 2) WiFiTouchConsole +- **Problème observé** : démarrage instable quand WiFi + init tactile + rendu lourd sont déclenchés trop tôt. +- **Cause probable** : pics CPU/mémoire au boot et délais bloquants dans `setup()`. +- **Solution recommandée** : + - Garder `setup()` court. + - Déporter les actions non critiques en tâches progressives dans `loop()`. + - Ajouter des logs explicites avant/après chaque étape de boot. + +### 3) Gestion sprites / performances +- **Problème observé** : frame drops et micro-freezes avec de nombreuses images ou redimensionnements. +- **Cause probable** : traitements graphiques coûteux en continu. +- **Solution recommandée** : + - Préférer assets à la bonne résolution. + - Éviter les conversions à chaud. + - Garder une cadence stable (boucle courte, pas de délais longs). + +### 4) `setup()` vs `loop()` +- **Problème observé** : crashes aléatoires quand "trop de choses" démarrent en même temps. +- **Cause probable** : contention mémoire/temps CPU au boot. +- **Solution recommandée** : + - `setup()` : init minimale et robuste. + - `loop()` : orchestration progressive/non-bloquante. + - Sur erreur, toujours remonter un code/raison lisible au série. + +### 5) Logique d'état launcher +- **Problème observé** : ambiguïtés UX (touches non évidentes, pagination confuse, retour page 1 implicite). +- **Cause probable** : zones tactiles trop proches ou feedback visuel insuffisant. +- **Solution recommandée** : + - Définir des hitbox nettes. + - Ajouter un feedback visuel instantané. + - Afficher un indicateur de page clair (`1/3`) et un retour page 1 explicite. + +## Historique / corrigé +Certaines remarques anciennes peuvent être partiellement obsolètes (ex. correctifs matériels/pins RGB déjà appliqués). Conserver ces points comme **historique**, et préciser l'état **corrigé/non corrigé** au fur et à mesure. + +## Vérification rapide — RaptorLauncher_V0.9 + +### Fond d'écran de l'accueil (derrière les icônes) +- Dans `RaptorLauncher_V0.9`, l'écran d'accueil efface d'abord l'écran avec `displayClear()`, puis dessine les icônes de jeux. +- Il n'y a pas de chargement d'image de fond globale pour la grille de jeux (pas de `home_bg` lu depuis la SD dans `drawHomeScreen()`). +- Résultat : en l'état, la v0.9 n'affiche pas de fond d'écran derrière les icônes sur la page qui liste les jeux. + +### Ordre d'affichage des jeux +- L'ordre est bien modifiable via `meta.json` de chaque jeu avec le champ `index` (ou `indice` en fallback). +- Le launcher trie d'abord par `index` croissant. +- En cas d'égalité d'`index`, il trie ensuite par nom (`name`) en ordre alphabétique. + +### Action pratique +- Pour changer l'ordre, modifier `index` dans `CarteSD/games//meta.json`, puis redémarrer le launcher. + +## Nouveaux réglages v0.9 (images RAW) + +Dans `settings.json` à la racine de la SD : + +```json +{ + "boot_splash_raw": "/boot.raw", + "boot_splash_ms": 1500, + "home_bg_raw": "/home_bg.raw" +} +``` + +- `boot_splash_raw` : image RAW affichée au démarrage (si absente/invalide = démarrage classique). +- `boot_splash_ms` : durée d'affichage au boot en millisecondes (0 à 10000). +- `home_bg_raw` : fond RAW de l'écran d'accueil (les icônes et noms des jeux sont dessinés par-dessus). +- Le bouton **Paramètres** de l'accueil est remplacé par une icône **roue dentée** dessinée en code (pas chargée depuis la SD). diff --git a/RaptorLauncher_V0.9/launcher_ui.cpp b/RaptorLauncher_V0.9/launcher_ui.cpp index 06d6c78..9d33c60 100644 --- a/RaptorLauncher_V0.9/launcher_ui.cpp +++ b/RaptorLauncher_V0.9/launcher_ui.cpp @@ -218,6 +218,12 @@ static String resolveGamePath(const GameInfo& game, const String& path) { return String(SD_MOUNT_POINT) + game.folder + "/" + path; } +static String resolveSdPath(const String& path) { + if (path.length() == 0) return ""; + if (path.startsWith("/")) return path; + return String("/") + path; +} + enum TextKey { TK_SETTINGS, TK_VOLUME, TK_BRIGHTNESS, TK_AUDIO_TEST, TK_TOUCH_TEST, TK_TOUCH_CALIB, TK_LANGUAGE, TK_WIFI, TK_SSID, TK_LED, TK_OPEN, TK_TAP, TK_RESET_SETTINGS, TK_BACK, TK_SAVE, TK_CANCEL, @@ -344,6 +350,39 @@ static void drawFooterButton(int x, int y, const char* text) { displayDrawText(x, y + 8, text); } +static void drawSettingsGearButton(int x, int y) { + static const uint16_t GEAR16[16] = { + 0b0000000110000000, + 0b0000011111100000, + 0b0000111001110000, + 0b0001110000111000, + 0b0011100000011100, + 0b0011001111001100, + 0b0110011111100110, + 0b0110011001100110, + 0b0110011001100110, + 0b0110011111100110, + 0b0011001111001100, + 0b0011100000011100, + 0b0001110000111000, + 0b0000111001110000, + 0b0000011111100000, + 0b0000000110000000 + }; + + int iconX = x + 16; + int iconY = y + 8; + + for (int row = 0; row < 16; row++) { + for (int col = 0; col < 16; col++) { + bool on = (GEAR16[row] >> (15 - col)) & 0x1; + if (on) { + displayFillRect(iconX + col, iconY + row, 1, 1, COLOR_TEXT); + } + } + } +} + static void drawPlayButton(int x, int y, int w, int h, const char* text) { displayFillRect(x, y, w, h, COLOR_PLAY_BOX); displayDrawRect(x, y, w, h, COLOR_INFO_TEXT); @@ -469,6 +508,13 @@ static void launchGameFromIndex(int index) { static void drawHomeScreen() { displayClear(); + String bgPath = resolveSdPath(settingsGet().home_bg_raw); + if (bgPath.length() > 0) { + if (!displayDrawRAW(bgPath.c_str(), 0, 0, displayWidth(), displayHeight())) { + Serial.println("[LAUNCHER] home_bg_raw absent/invalide -> fond classique"); + } + } + int pageCount = totalPages(); if (pageCount > 1) { @@ -518,7 +564,7 @@ static void drawHomeScreen() { } } - drawFooterButton(BTN_LEFT_X, BTN_LEFT_Y, tr(TK_PARAMETERS_BTN)); + drawSettingsGearButton(BTN_LEFT_X, BTN_LEFT_Y); if (pageCount > 1) { if (currentPage < pageCount - 1) { @@ -848,6 +894,16 @@ void launcherInit() { gWifiStatusText = ""; gLedSelectedColor = 0; ledManagerOff(); + + String splashPath = resolveSdPath(settingsGet().boot_splash_raw); + if (splashPath.length() > 0) { + if (displayDrawRAW(splashPath.c_str(), 0, 0, displayWidth(), displayHeight())) { + delay(settingsGet().boot_splash_ms); + } else { + Serial.println("[LAUNCHER] boot_splash_raw absent/invalide -> demarrage classique"); + } + } + gNeedsRedraw = true; } diff --git a/RaptorLauncher_V0.9/settings_manager.cpp b/RaptorLauncher_V0.9/settings_manager.cpp index f000494..98a7b79 100644 --- a/RaptorLauncher_V0.9/settings_manager.cpp +++ b/RaptorLauncher_V0.9/settings_manager.cpp @@ -16,9 +16,12 @@ static int clampValue(int v, int minV, int maxV) { void settingsSetDefaults() { gSettings.volume = 80; gSettings.brightness = 100; + gSettings.boot_splash_ms = 1500; gSettings.wifi_ssid = ""; gSettings.wifi_pass = ""; + gSettings.boot_splash_raw = ""; + gSettings.home_bg_raw = ""; gSettings.touch_x_min = 200; gSettings.touch_x_max = 3800; @@ -38,8 +41,11 @@ bool settingsSave() { JsonDocument doc; doc["volume"] = gSettings.volume; doc["brightness"] = gSettings.brightness; + doc["boot_splash_ms"] = gSettings.boot_splash_ms; doc["wifi_ssid"] = gSettings.wifi_ssid; doc["wifi_pass"] = gSettings.wifi_pass; + doc["boot_splash_raw"] = gSettings.boot_splash_raw; + doc["home_bg_raw"] = gSettings.home_bg_raw; doc["touch_x_min"] = gSettings.touch_x_min; doc["touch_x_max"] = gSettings.touch_x_max; doc["touch_y_min"] = gSettings.touch_y_min; @@ -110,9 +116,12 @@ bool settingsInit() { gSettings.volume = clampValue(doc["volume"] | 80, 0, 100); gSettings.brightness = clampValue(doc["brightness"] | 100, 0, 100); + gSettings.boot_splash_ms = clampValue(doc["boot_splash_ms"] | 1500, 0, 10000); gSettings.wifi_ssid = doc["wifi_ssid"] | ""; gSettings.wifi_pass = doc["wifi_pass"] | ""; + gSettings.boot_splash_raw = doc["boot_splash_raw"] | ""; + gSettings.home_bg_raw = doc["home_bg_raw"] | ""; gSettings.touch_x_min = doc["touch_x_min"] | 200; gSettings.touch_x_max = doc["touch_x_max"] | 3800; @@ -128,9 +137,15 @@ bool settingsInit() { Serial.print("[SETTINGS] brightness = "); Serial.println(gSettings.brightness); + Serial.print("[SETTINGS] boot_splash_ms = "); + Serial.println(gSettings.boot_splash_ms); Serial.print("[SETTINGS] wifi_ssid = "); Serial.println(gSettings.wifi_ssid); + Serial.print("[SETTINGS] boot_splash_raw = "); + Serial.println(gSettings.boot_splash_raw); + Serial.print("[SETTINGS] home_bg_raw = "); + Serial.println(gSettings.home_bg_raw); Serial.print("[SETTINGS] touch_x_min = "); Serial.println(gSettings.touch_x_min); diff --git a/RaptorLauncher_V0.9/settings_manager.h b/RaptorLauncher_V0.9/settings_manager.h index 013bad7..a99a184 100644 --- a/RaptorLauncher_V0.9/settings_manager.h +++ b/RaptorLauncher_V0.9/settings_manager.h @@ -4,9 +4,12 @@ struct SystemSettings { int volume; // 0 à 100 int brightness; // 0 à 100 + int boot_splash_ms; // 0 à 10000 String wifi_ssid; String wifi_pass; + String boot_splash_raw; // image RAW plein ecran au demarrage + String home_bg_raw; // image RAW fond ecran accueil int touch_x_min; int touch_x_max;