Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CarteSD/README_SD_IMAGES_LAUNCHER.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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,
"boot_splash_w": 320,
"boot_splash_h": 240,
"home_bg_raw": "/home_bg.raw",
"home_bg_w": 320,
"home_bg_h": 240
}

Notes :
- boot_splash_ms est en millisecondes (ex: 1000 = 1 seconde, 2000 = 2 secondes).
- boot_splash_w / boot_splash_h et home_bg_w / home_bg_h doivent correspondre EXACTEMENT a la taille du fichier RAW.
- Si ton image est exportee en 240x320, mets 240x320 dans le settings (sinon l'image parait brouillee/cassee).
- Si boot.raw ou home_bg.raw n'existe pas (ou est invalide), le launcher reste en mode classique.
- Format attendu : RAW RGB565 (endianness LE/BE detectee automatiquement par le launcher).
- Taille conseillee : 320x240 pour eviter recadrage/perte.
9 changes: 8 additions & 1 deletion CarteSD/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
{
"volume": 30,
"brightness": 25,
"boot_splash_raw": "/boot.raw",
"boot_splash_ms": 1500,
"boot_splash_w": 320,
"boot_splash_h": 240,
"home_bg_raw": "/home_bg.raw",
"home_bg_w": 320,
"home_bg_h": 240,
"wifi_ssid": "VivienJardot",
"wifi_pass": "VivienJardot1991",
"touch_x_min": 317,
Expand All @@ -11,4 +18,4 @@
"touch_offset_y": -2,
"led_brightness": 5,
"language": 1
}
}
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,43 @@

## 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/<NomDuJeu>/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,
"boot_splash_w": 320,
"boot_splash_h": 240,
"home_bg_raw": "/home_bg.raw",
"home_bg_w": 320,
"home_bg_h": 240
}
```

- `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).
- `boot_splash_w` / `boot_splash_h` : dimensions EXACTES du fichier RAW de splash.
- `home_bg_raw` : fond RAW de l'écran d'accueil (les icônes et noms des jeux sont dessinés par-dessus).
- `home_bg_w` / `home_bg_h` : dimensions EXACTES du fichier RAW du fond d'accueil.
- 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).
- Si les dimensions ne correspondent pas au fichier RAW, l'image peut apparaître brouillée/cassée.
- L'affichage RAW détecte automatiquement l'endianness (LE/BE) pour éviter les couleurs corrompues.
75 changes: 70 additions & 5 deletions RaptorLauncher_V0.9/display_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,52 @@ static uint16_t bmpColorTo565(uint8_t r, uint8_t g, uint8_t b) {
return lcd.color565(r, g, b);
}

static inline int c565r(uint16_t c) { return (c >> 11) & 0x1F; }
static inline int c565g(uint16_t c) { return (c >> 5) & 0x3F; }
static inline int c565b(uint16_t c) { return c & 0x1F; }

static bool detectRawLittleEndian(File& rawFile) {
const int SAMPLE_PIXELS = 256;
const int SAMPLE_BYTES = SAMPLE_PIXELS * 2;

uint8_t sample[SAMPLE_BYTES];
int n = rawFile.read(sample, SAMPLE_BYTES);
rawFile.seek(0);

if (n < 8) {
return true;
}

long scoreLE = 0;
long scoreBE = 0;
bool hasPrev = false;
uint16_t prevLE = 0;
uint16_t prevBE = 0;

for (int i = 0; i + 1 < n; i += 2) {
uint8_t b0 = sample[i];
uint8_t b1 = sample[i + 1];
uint16_t pxLE = ((uint16_t)b1 << 8) | (uint16_t)b0;
uint16_t pxBE = ((uint16_t)b0 << 8) | (uint16_t)b1;

if (hasPrev) {
scoreLE += abs(c565r(pxLE) - c565r(prevLE));
scoreLE += abs(c565g(pxLE) - c565g(prevLE));
scoreLE += abs(c565b(pxLE) - c565b(prevLE));

scoreBE += abs(c565r(pxBE) - c565r(prevBE));
scoreBE += abs(c565g(pxBE) - c565g(prevBE));
scoreBE += abs(c565b(pxBE) - c565b(prevBE));
}

prevLE = pxLE;
prevBE = pxBE;
hasPrev = true;
}

return scoreLE <= scoreBE;
}

static bool readLE16(File& f, uint16_t& value) {
uint8_t b0, b1;
if (f.read(&b0, 1) != 1) return false;
Expand Down Expand Up @@ -215,6 +261,17 @@ bool displayDrawRAW(const char* path, int x, int y, int width, int height) {
return false;
}

size_t expectedSize = (size_t)width * (size_t)height * 2;
size_t fileSize = (size_t)rawFile.size();
if (fileSize != expectedSize) {
Serial.print("[RAW] taille fichier invalide. attendu=");
Serial.print(expectedSize);
Serial.print(" octets, recu=");
Serial.println(fileSize);
rawFile.close();
return false;
}

if (x >= lcd.width() || y >= lcd.height()) {
Serial.println("[RAW] image hors ecran");
rawFile.close();
Expand All @@ -240,19 +297,27 @@ bool displayDrawRAW(const char* path, int x, int y, int width, int height) {
return false;
}

lcd.setSwapBytes(true);
bool littleEndian = detectRawLittleEndian(rawFile);
Serial.print("[RAW] endian detecte: ");
Serial.println(littleEndian ? "LE" : "BE");

lcd.setSwapBytes(false);

for (int row = 0; row < drawHeight; row++) {
for (int col = 0; col < drawWidth; col++) {
uint8_t hi, lo;
if (rawFile.read(&hi, 1) != 1 || rawFile.read(&lo, 1) != 1) {
uint8_t b0, b1;
if (rawFile.read(&b0, 1) != 1 || rawFile.read(&b1, 1) != 1) {
Serial.println("[RAW] lecture pixel impossible");
lcd.setSwapBytes(false);
free(lineBuffer);
rawFile.close();
return false;
}
lineBuffer[col] = ((uint16_t)hi << 8) | (uint16_t)lo;
if (littleEndian) {
lineBuffer[col] = ((uint16_t)b1 << 8) | (uint16_t)b0;
} else {
lineBuffer[col] = ((uint16_t)b0 << 8) | (uint16_t)b1;
}
}

if (width > drawWidth) {
Expand Down Expand Up @@ -431,4 +496,4 @@ bool displayDrawBMPScaled(const char* path, int x, int y, int maxWidth, int maxH
}

return false;
}
}
58 changes: 57 additions & 1 deletion RaptorLauncher_V0.9/launcher_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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, settingsGet().home_bg_w, settingsGet().home_bg_h)) {
Serial.println("[LAUNCHER] home_bg_raw absent/invalide -> fond classique");
}
}

int pageCount = totalPages();

if (pageCount > 1) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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, settingsGet().boot_splash_w, settingsGet().boot_splash_h)) {
delay(settingsGet().boot_splash_ms);
} else {
Serial.println("[LAUNCHER] boot_splash_raw absent/invalide -> demarrage classique");
}
}

gNeedsRedraw = true;
}

Expand Down
35 changes: 35 additions & 0 deletions RaptorLauncher_V0.9/settings_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,16 @@ static int clampValue(int v, int minV, int maxV) {
void settingsSetDefaults() {
gSettings.volume = 80;
gSettings.brightness = 100;
gSettings.boot_splash_ms = 1500;
gSettings.boot_splash_w = 320;
gSettings.boot_splash_h = 240;

gSettings.wifi_ssid = "";
gSettings.wifi_pass = "";
gSettings.boot_splash_raw = "";
gSettings.home_bg_raw = "";
gSettings.home_bg_w = 320;
gSettings.home_bg_h = 240;

gSettings.touch_x_min = 200;
gSettings.touch_x_max = 3800;
Expand All @@ -38,8 +45,15 @@ bool settingsSave() {
JsonDocument doc;
doc["volume"] = gSettings.volume;
doc["brightness"] = gSettings.brightness;
doc["boot_splash_ms"] = gSettings.boot_splash_ms;
doc["boot_splash_w"] = gSettings.boot_splash_w;
doc["boot_splash_h"] = gSettings.boot_splash_h;
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["home_bg_w"] = gSettings.home_bg_w;
doc["home_bg_h"] = gSettings.home_bg_h;
doc["touch_x_min"] = gSettings.touch_x_min;
doc["touch_x_max"] = gSettings.touch_x_max;
doc["touch_y_min"] = gSettings.touch_y_min;
Expand Down Expand Up @@ -110,9 +124,16 @@ 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.boot_splash_w = clampValue(doc["boot_splash_w"] | 320, 1, 1024);
gSettings.boot_splash_h = clampValue(doc["boot_splash_h"] | 240, 1, 1024);

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.home_bg_w = clampValue(doc["home_bg_w"] | 320, 1, 1024);
gSettings.home_bg_h = clampValue(doc["home_bg_h"] | 240, 1, 1024);

gSettings.touch_x_min = doc["touch_x_min"] | 200;
gSettings.touch_x_max = doc["touch_x_max"] | 3800;
Expand All @@ -128,9 +149,23 @@ 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] boot_splash_w = ");
Serial.println(gSettings.boot_splash_w);
Serial.print("[SETTINGS] boot_splash_h = ");
Serial.println(gSettings.boot_splash_h);

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] home_bg_w = ");
Serial.println(gSettings.home_bg_w);
Serial.print("[SETTINGS] home_bg_h = ");
Serial.println(gSettings.home_bg_h);

Serial.print("[SETTINGS] touch_x_min = ");
Serial.println(gSettings.touch_x_min);
Expand Down
7 changes: 7 additions & 0 deletions RaptorLauncher_V0.9/settings_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
struct SystemSettings {
int volume; // 0 à 100
int brightness; // 0 à 100
int boot_splash_ms; // 0 à 10000
int boot_splash_w; // largeur RAW splash
int boot_splash_h; // hauteur RAW splash

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 home_bg_w; // largeur RAW fond accueil
int home_bg_h; // hauteur RAW fond accueil

int touch_x_min;
int touch_x_max;
Expand Down