From b7e889fda5459b22cf8a313b0cff681917dd8522 Mon Sep 17 00:00:00 2001 From: DefKorns Date: Wed, 21 Oct 2026 14:49:07 +0000 Subject: [PATCH 1/9] Rebind the console language with clRebind so copyleft stays on the strings --- mod/etc/options_menu/themes/scripts/om_overlaythmcript | 9 +++++++-- mod/etc/options_menu/themes/scripts/om_themescript | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/mod/etc/options_menu/themes/scripts/om_overlaythmcript b/mod/etc/options_menu/themes/scripts/om_overlaythmcript index 466eabc..3646441 100644 --- a/mod/etc/options_menu/themes/scripts/om_overlaythmcript +++ b/mod/etc/options_menu/themes/scripts/om_overlaythmcript @@ -98,7 +98,12 @@ themeSelector() { # shellcheck source=/dev/null source "$cl_functions" clInit - clUmountLang - clMountLang + # older Console Language releases have no clRebind + if type clRebind >/dev/null 2>&1; then + clRebind + else + clUmountLang + clMountLang + fi fi } diff --git a/mod/etc/options_menu/themes/scripts/om_themescript b/mod/etc/options_menu/themes/scripts/om_themescript index b14a668..d51ba7d 100644 --- a/mod/etc/options_menu/themes/scripts/om_themescript +++ b/mod/etc/options_menu/themes/scripts/om_themescript @@ -258,8 +258,13 @@ themeSelector() { # shellcheck source=/dev/null source "$cl_functions" clInit - clUmountLang - clMountLang + # older Console Language releases have no clRebind + if type clRebind >/dev/null 2>&1; then + clRebind + else + clUmountLang + clMountLang + fi fi [ -z "$mountpoint" ] && echo "$applied" >"$applied_file" } From 74c008901759993844ae2728dd8a230dc505608c Mon Sep 17 00:00:00 2001 From: DefKorns Date: Wed, 21 Oct 2026 14:49:30 +0000 Subject: [PATCH 2/9] Fit themes to the firmware's font names and apply their palette on every region --- .../themes/scripts/om_overlaythmcript | 74 +++++++++++++++++++ .../themes/scripts/om_themescript | 74 +++++++++++++++++++ 2 files changed, 148 insertions(+) diff --git a/mod/etc/options_menu/themes/scripts/om_overlaythmcript b/mod/etc/options_menu/themes/scripts/om_overlaythmcript index 3646441..f9c66f1 100644 --- a/mod/etc/options_menu/themes/scripts/om_overlaythmcript +++ b/mod/etc/options_menu/themes/scripts/om_overlaythmcript @@ -15,6 +15,77 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +# corrected copies of theme files, at their path under the UI; they sit on top of the theme. +# /var is already a tmpfs at boot, where /tmp is still the NAND +theme_fixes="$mountpoint/var/theme_fixes" + +themeFixesUnbind() { + awk -v dir="$original_theme/" 'index($5, dir) == 1 && $4 ~ /\/theme_fixes\// { print $5 }' /proc/self/mountinfo | + sed -n '1!G;h;$p' | while IFS= read -r fix; do + umount "$fix" + done + rm -rf "$theme_fixes" +} + +# the USA/EUR firmwares name the s/m/l fonts *.font and the Super Famicom *.fnt; +# the UI exits when dependencies.json lists one that isn't there +themeDepsFix() { + local deps="$original_theme/dependencies.json" + local fixed="$theme_fixes/dependencies.json" + local font other + [ -f "$deps" ] || return 0 + mkdir -p "$theme_fixes" + cp -f "$deps" "$fixed" + for font in $(grep -o '"/fonts/[^"]*"' "$deps" | tr -d '"'); do + [ -e "$original_theme/resources$font" ] && continue + case "$font" in + *.font) other="${font%.font}.fnt" ;; + *.fnt) other="${font%.fnt}.font" ;; + *) continue ;; + esac + [ -e "$original_theme/resources$other" ] && sed -i "s#\"$font\"#\"$other\"#" "$fixed" + done + if cmp -s "$deps" "$fixed"; then + rm -f "$fixed" + else + mount -o bind "$fixed" "$deps" + fi +} + +# byte offset of the first occurrence of $2 in file $1 +byteOffset() { + local want + want="$(printf '%s' "$2" | od -An -tx1 | tr -d ' \n')" + od -An -v -tx1 "$1" | tr -s ' ' '\n' | grep . | awk -v want="$want" -v n="${#2}" ' + { s = s $1; if (length(s) > 2 * n) s = substr(s, 3); if (s == want) { print NR - n; exit } }' +} + +# each firmware reads only its own palette (env_.lua loads colors_); a theme made +# for another region gets its colors_*.lua renamed in place (same length) and bound over this one +themeColorsFix() { + local env_dir="$original_theme/resources/scripts/env" + local theme_env="$full_theme_path/resources/scripts/env" + local region src fixed offset + for region in jpn usa eur; do + [ -f "$env_dir/env_$region.lua" ] && break + done + [ -f "$env_dir/env_$region.lua" ] && [ ! -f "$theme_env/colors_$region.lua" ] || return 0 + for src in usa eur jpn; do + [ -f "$theme_env/colors_$src.lua" ] && break + done + [ -f "$theme_env/colors_$src.lua" ] || return 0 + fixed="$theme_fixes/resources/scripts/env/colors_$region.lua" + mkdir -p "${fixed%/*}" + cp -f "$theme_env/colors_$src.lua" "$fixed" + offset="$(byteOffset "$fixed" "colors_$src")" + if [ -z "$offset" ]; then + rm -f "$fixed" + return 0 + fi + printf 'colors_%s' "$region" | dd of="$fixed" bs=1 seek="$offset" conv=notrunc 2>/dev/null + mount -o bind "$fixed" "$env_dir/colors_$region.lua" +} + fontBindFix() { [ ! -f "${font_path}/title.fnt.backup" ] && cp "${font_path}/title.fnt" "${font_path}/title.fnt.backup" for font_name in title s m l small medium large; do @@ -91,8 +162,11 @@ themeSelector() { fontBindFix "restore" fi + themeFixesUnbind mountpoint -q "$original_theme" && umount "$original_theme" [ -d "$full_theme_path" ] && mount -t overlayfs -o lowerdir="$original_theme",upperdir="$full_theme_path" overlayfs "$original_theme" + themeDepsFix + themeColorsFix local cl_functions="$rootfs/etc/options_menu/console_language/scripts/cl_functions" if [ -f "$cl_functions" ]; then # shellcheck source=/dev/null diff --git a/mod/etc/options_menu/themes/scripts/om_themescript b/mod/etc/options_menu/themes/scripts/om_themescript index d51ba7d..a8d827b 100644 --- a/mod/etc/options_menu/themes/scripts/om_themescript +++ b/mod/etc/options_menu/themes/scripts/om_themescript @@ -35,6 +35,77 @@ unbindThemeMounts() { [ -n "$mount_points" ] && echo "$mount_points" | xargs umount } +# corrected copies of theme files, at their path under the UI; they sit on top of the theme. +# /var is already a tmpfs at boot, where /tmp is still the NAND +theme_fixes="$mountpoint/var/theme_fixes" + +themeFixesUnbind() { + awk -v dir="$original_theme/" 'index($5, dir) == 1 && $4 ~ /\/theme_fixes\// { print $5 }' /proc/self/mountinfo | + sed -n '1!G;h;$p' | while IFS= read -r fix; do + umount "$fix" + done + rm -rf "$theme_fixes" +} + +# the USA/EUR firmwares name the s/m/l fonts *.font and the Super Famicom *.fnt; +# the UI exits when dependencies.json lists one that isn't there +themeDepsFix() { + local deps="$original_theme/dependencies.json" + local fixed="$theme_fixes/dependencies.json" + local font other + [ -f "$deps" ] || return 0 + mkdir -p "$theme_fixes" + cp -f "$deps" "$fixed" + for font in $(grep -o '"/fonts/[^"]*"' "$deps" | tr -d '"'); do + [ -e "$original_theme/resources$font" ] && continue + case "$font" in + *.font) other="${font%.font}.fnt" ;; + *.fnt) other="${font%.fnt}.font" ;; + *) continue ;; + esac + [ -e "$original_theme/resources$other" ] && sed -i "s#\"$font\"#\"$other\"#" "$fixed" + done + if cmp -s "$deps" "$fixed"; then + rm -f "$fixed" + else + mount -o bind "$fixed" "$deps" + fi +} + +# byte offset of the first occurrence of $2 in file $1 +byteOffset() { + local want + want="$(printf '%s' "$2" | od -An -tx1 | tr -d ' \n')" + od -An -v -tx1 "$1" | tr -s ' ' '\n' | grep . | awk -v want="$want" -v n="${#2}" ' + { s = s $1; if (length(s) > 2 * n) s = substr(s, 3); if (s == want) { print NR - n; exit } }' +} + +# each firmware reads only its own palette (env_.lua loads colors_); a theme made +# for another region gets its colors_*.lua renamed in place (same length) and bound over this one +themeColorsFix() { + local env_dir="$original_theme/resources/scripts/env" + local theme_env="$full_theme_path/resources/scripts/env" + local region src fixed offset + for region in jpn usa eur; do + [ -f "$env_dir/env_$region.lua" ] && break + done + [ -f "$env_dir/env_$region.lua" ] && [ ! -f "$theme_env/colors_$region.lua" ] || return 0 + for src in usa eur jpn; do + [ -f "$theme_env/colors_$src.lua" ] && break + done + [ -f "$theme_env/colors_$src.lua" ] || return 0 + fixed="$theme_fixes/resources/scripts/env/colors_$region.lua" + mkdir -p "${fixed%/*}" + cp -f "$theme_env/colors_$src.lua" "$fixed" + offset="$(byteOffset "$fixed" "colors_$src")" + if [ -z "$offset" ]; then + rm -f "$fixed" + return 0 + fi + printf 'colors_%s' "$region" | dd of="$fixed" bs=1 seek="$offset" conv=notrunc 2>/dev/null + mount -o bind "$fixed" "$env_dir/colors_$region.lua" +} + fontBindFix() { [ ! -f "${font_path}/title.fnt.backup" ] && cp "${font_path}/title.fnt" "${font_path}/title.fnt.backup" for font_name in title s m l small medium large; do @@ -228,6 +299,7 @@ themeSelector() { fontBindFix "restore" fi + themeFixesUnbind unbindThemeMounts while grep -q " $original_theme overlayfs " /proc/mounts; do umount -l "$original_theme" || break @@ -252,6 +324,8 @@ themeSelector() { done fi [ -n "$assigned_music" ] && musicHackBind "$music_path/$assigned_music" "$music_path/$assigned_music" "$original_theme_audio" + themeDepsFix + themeColorsFix local cl_functions="$rootfs/etc/options_menu/console_language/scripts/cl_functions" if [ -f "$cl_functions" ]; then From 09754a84b3d93a33b8f9d2bbf9adf7e016218dd2 Mon Sep 17 00:00:00 2001 From: DefKorns Date: Wed, 21 Oct 2026 14:50:14 +0000 Subject: [PATCH 3/9] Restore the chmenu hook on install and write it through the live path --- mod/etc/options_menu/themes/scripts/om_vars | 6 ++++-- mod/install | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mod/etc/options_menu/themes/scripts/om_vars b/mod/etc/options_menu/themes/scripts/om_vars index 8e00292..a1f1d0a 100644 --- a/mod/etc/options_menu/themes/scripts/om_vars +++ b/mod/etc/options_menu/themes/scripts/om_vars @@ -459,10 +459,12 @@ injectFile() { if ! grep -q "# themeselector" "$injected_file"; then if [ "$scrpt" = "chmenu" ]; then + # sed -i gives the rootfs file a new inode, which /bin keeps hiding until a reboot # shellcheck disable=SC1004 - sed -i '/^overmount_games.*/a # themeselector fix \ + sed '/^overmount_games.*/a # themeselector fix \ themeSelector \ -fontFix' "/var/lib/hakchi/rootfs/bin/chmenu" +fontFix' /bin/chmenu >/tmp/chmenu.new && cat /tmp/chmenu.new >/bin/chmenu + rm -f /tmp/chmenu.new fi if [ "$scrpt" = "fontfix" ]; then diff --git a/mod/install b/mod/install index 2405022..eb41ce8 100644 --- a/mod/install +++ b/mod/install @@ -95,6 +95,14 @@ if [ -f "$theme_cfg" ] && ! grep -q "^ActiveThemeBorder=" "$theme_cfg"; then echo "ActiveThemeBorder=76,175,110" >> "$theme_cfg" fi +# the previous version's uninstall strips the chmenu hook; at boot the rootfs write shows at once +if ! grep -q "# themeselector fix" "$rootfs/bin/chmenu"; then + # shellcheck disable=SC1004 + sed -i '/^overmount_games.*/a # themeselector fix \ +themeSelector \ +fontFix' "$rootfs/bin/chmenu" +fi + sed '1,2d' "$om_themes_scripts/om_themescript" >"$b_file" [ ! -f "$p_file" ] && echo themeSelector >"$p_file" From e87a5eb737691e9c71ad767918fd1b1ea5dc0b96 Mon Sep 17 00:00:00 2001 From: DefKorns Date: Wed, 21 Oct 2026 14:55:11 +0000 Subject: [PATCH 4/9] Reload the current folder after a DIY preview instead of hopping folders --- .../themes/creator/scripts/om_preview | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/mod/etc/options_menu/themes/creator/scripts/om_preview b/mod/etc/options_menu/themes/creator/scripts/om_preview index d6d646e..24d7807 100644 --- a/mod/etc/options_menu/themes/creator/scripts/om_preview +++ b/mod/etc/options_menu/themes/creator/scripts/om_preview @@ -31,9 +31,17 @@ fi source "$b_file" themeSelector -echo "usleep 20000; \ -uistart; \ -chmenu 001; \ -usleep 200000; \ -chmenu 000; \ -/etc/init.d/S8103OptionsMenu restart " >/var/exec.flag +# chmenu refuses the folder already shown unless its state says otherwise +menu_state="/var/saves/$modname/menu" +current_menu="000" +[ -f "$menu_state" ] && current_menu="$(cat "$menu_state")" +cat >/var/exec.flag.tmp <"$menu_state" +/bin/chmenu "$current_menu" || /bin/chmenu 000 || { echo "$current_menu" >"$menu_state"; uistart; } +/etc/init.d/S8103OptionsMenu restart +EOF +mv /var/exec.flag.tmp /var/exec.flag From 5cfe0480652ea4d783f6a5ab8607ff07ef4e19a3 Mon Sep 17 00:00:00 2001 From: DefKorns Date: Wed, 21 Oct 2026 15:02:44 +0000 Subject: [PATCH 5/9] Reload the current folder after a DIY preview instead of hopping folders --- .../themes/creator/scripts/om_preview | 15 +-------------- mod/etc/options_menu/themes/scripts/om_vars | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/mod/etc/options_menu/themes/creator/scripts/om_preview b/mod/etc/options_menu/themes/creator/scripts/om_preview index 24d7807..c8000bb 100644 --- a/mod/etc/options_menu/themes/creator/scripts/om_preview +++ b/mod/etc/options_menu/themes/creator/scripts/om_preview @@ -31,17 +31,4 @@ fi source "$b_file" themeSelector -# chmenu refuses the folder already shown unless its state says otherwise -menu_state="/var/saves/$modname/menu" -current_menu="000" -[ -f "$menu_state" ] && current_menu="$(cat "$menu_state")" -cat >/var/exec.flag.tmp <"$menu_state" -/bin/chmenu "$current_menu" || /bin/chmenu 000 || { echo "$current_menu" >"$menu_state"; uistart; } -/etc/init.d/S8103OptionsMenu restart -EOF -mv /var/exec.flag.tmp /var/exec.flag +menuReloadLater diff --git a/mod/etc/options_menu/themes/scripts/om_vars b/mod/etc/options_menu/themes/scripts/om_vars index a1f1d0a..54ef4cc 100644 --- a/mod/etc/options_menu/themes/scripts/om_vars +++ b/mod/etc/options_menu/themes/scripts/om_vars @@ -908,6 +908,24 @@ diyHomePreviews() { done } +# the menu holds /dev/fb0, so remote-exec reloads the current folder (chmenu's hook remounts +# the theme); chmenu refuses the folder already shown unless its state says otherwise +menuReloadLater() { + menu_state="/var/saves/$modname/menu" + current_menu="000" + [ -f "$menu_state" ] && current_menu="$(cat "$menu_state")" + cat >/var/exec.flag.tmp <"$menu_state" +/bin/chmenu "$current_menu" || /bin/chmenu 000 || { echo "$current_menu" >"$menu_state"; uistart; } +/etc/init.d/S8103OptionsMenu restart +EOF + mv /var/exec.flag.tmp /var/exec.flag +} + diyThemeRemover() { disableCmds "diy" "del_diy" "preview" remove "$diy_selection_path" From 5915acaba3b4001fb8d1b337aff660abbb3eda70 Mon Sep 17 00:00:00 2001 From: DefKorns Date: Wed, 21 Oct 2026 15:02:58 +0000 Subject: [PATCH 6/9] Remount the active theme when a previewed DIY is cleaned --- .../options_menu/themes/creator/scripts/om_removediy | 11 ++++++++++- mod/etc/options_menu/themes/lang/de-DE.lang | 1 + mod/etc/options_menu/themes/lang/en-US.lang | 1 + mod/etc/options_menu/themes/lang/es-ES.lang | 1 + mod/etc/options_menu/themes/lang/fr-FR.lang | 1 + mod/etc/options_menu/themes/lang/it-IT.lang | 1 + mod/etc/options_menu/themes/lang/ja-JP.lang | 1 + mod/etc/options_menu/themes/lang/nl-NL.lang | 1 + mod/etc/options_menu/themes/lang/pt-PT.lang | 1 + mod/etc/options_menu/themes/lang/ru-RU.lang | 1 + 10 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mod/etc/options_menu/themes/creator/scripts/om_removediy b/mod/etc/options_menu/themes/creator/scripts/om_removediy index 27275da..e4fe880 100644 --- a/mod/etc/options_menu/themes/creator/scripts/om_removediy +++ b/mod/etc/options_menu/themes/creator/scripts/om_removediy @@ -20,6 +20,15 @@ source $mountpoint/etc/options_menu/themes/scripts/om_vars script_init +# a previewed DIY stays bound over the UI until the theme is mounted again +diy_bound="" +awk '$4 ~ /^\/diy_theme\// { found = 1 } END { exit !found }' /proc/self/mountinfo && diy_bound=1 + diyThemeRemover -$options_menu/lib/theme_manager --commandPath $om_mod_gen_cmds/ --scriptPath $om_mod_gen_scripts --title "$om_title" & +if [ -n "$diy_bound" ]; then + "$om_scripts/gen_splash" /tmp/om_splash.png THEME_RESTORING && decodepng /tmp/om_splash.png >/dev/fb0 + menuReloadLater +else + $options_menu/lib/theme_manager --commandPath $om_mod_gen_cmds/ --scriptPath $om_mod_gen_scripts --title "$om_title" & +fi diff --git a/mod/etc/options_menu/themes/lang/de-DE.lang b/mod/etc/options_menu/themes/lang/de-DE.lang index 60f8e13..543e306 100644 --- a/mod/etc/options_menu/themes/lang/de-DE.lang +++ b/mod/etc/options_menu/themes/lang/de-DE.lang @@ -82,6 +82,7 @@ THEME_MOVING_LINE2=Bitte warten . . . THEME_LOADING_ASSETS=Assets werden geladen... THEME_SAVING=Eigenes Theme wird gespeichert... THEME_PREVIEW_LOADING=Themenvorschau wird geladen... +THEME_RESTORING=Design wird wiederhergestellt... THEME_APPLYING_LINE1=Design wird übernommen THEME_APPLYING_LINE2=Neustart läuft . . . THEME_DELETE_IN_USE=Dieses Design ist aktiv und kann nicht entfernt werden. diff --git a/mod/etc/options_menu/themes/lang/en-US.lang b/mod/etc/options_menu/themes/lang/en-US.lang index a375a4e..9dbbb5c 100644 --- a/mod/etc/options_menu/themes/lang/en-US.lang +++ b/mod/etc/options_menu/themes/lang/en-US.lang @@ -82,6 +82,7 @@ THEME_MOVING_LINE2=Please Wait . . . THEME_LOADING_ASSETS=Loading assets... THEME_SAVING=Saving custom theme... THEME_PREVIEW_LOADING=Loading theme preview... +THEME_RESTORING=Restoring the theme... THEME_APPLYING_LINE1=Applying Theme THEME_APPLYING_LINE2=Rebooting Now . . . THEME_DELETE_IN_USE=This theme is in use and can't be removed. diff --git a/mod/etc/options_menu/themes/lang/es-ES.lang b/mod/etc/options_menu/themes/lang/es-ES.lang index eb8beab..ab6e562 100644 --- a/mod/etc/options_menu/themes/lang/es-ES.lang +++ b/mod/etc/options_menu/themes/lang/es-ES.lang @@ -82,6 +82,7 @@ THEME_MOVING_LINE2=Espere Por Favor . . . THEME_LOADING_ASSETS=Cargando recursos... THEME_SAVING=Guardando tema personalizado... THEME_PREVIEW_LOADING=Cargando vista previa del tema... +THEME_RESTORING=Restaurando el tema... THEME_APPLYING_LINE1=Aplicando Tema THEME_APPLYING_LINE2=Reiniciando Ahora . . . THEME_DELETE_IN_USE=Este tema está en uso y no se puede eliminar. diff --git a/mod/etc/options_menu/themes/lang/fr-FR.lang b/mod/etc/options_menu/themes/lang/fr-FR.lang index dc81e90..fe6055f 100644 --- a/mod/etc/options_menu/themes/lang/fr-FR.lang +++ b/mod/etc/options_menu/themes/lang/fr-FR.lang @@ -82,6 +82,7 @@ THEME_MOVING_LINE2=Veuillez Patienter . . . THEME_LOADING_ASSETS=Chargement des ressources... THEME_SAVING=Enregistrement du thème personnalisé... THEME_PREVIEW_LOADING=Chargement de l'aperçu du thème... +THEME_RESTORING=Restauration du thème... THEME_APPLYING_LINE1=Application du Thème THEME_APPLYING_LINE2=Redémarrage en Cours . . . THEME_DELETE_IN_USE=Ce thème est utilisé et ne peut pas être supprimé. diff --git a/mod/etc/options_menu/themes/lang/it-IT.lang b/mod/etc/options_menu/themes/lang/it-IT.lang index 43f9b64..420a31d 100644 --- a/mod/etc/options_menu/themes/lang/it-IT.lang +++ b/mod/etc/options_menu/themes/lang/it-IT.lang @@ -82,6 +82,7 @@ THEME_MOVING_LINE2=Attendere Prego . . . THEME_LOADING_ASSETS=Caricamento risorse... THEME_SAVING=Salvataggio tema personalizzato... THEME_PREVIEW_LOADING=Caricamento anteprima tema... +THEME_RESTORING=Ripristino del tema... THEME_APPLYING_LINE1=Applicazione del Tema in Corso THEME_APPLYING_LINE2=Riavvio in Corso . . . THEME_DELETE_IN_USE=Questo tema è in uso e non può essere eliminato. diff --git a/mod/etc/options_menu/themes/lang/ja-JP.lang b/mod/etc/options_menu/themes/lang/ja-JP.lang index 0574f37..0d5ae87 100644 --- a/mod/etc/options_menu/themes/lang/ja-JP.lang +++ b/mod/etc/options_menu/themes/lang/ja-JP.lang @@ -82,6 +82,7 @@ THEME_MOVING_LINE2=おまちください . . . THEME_LOADING_ASSETS=Assetをよみこみちゅう... THEME_SAVING=じぶんのThemeをほぞんちゅう... THEME_PREVIEW_LOADING=Themeのpreviewをよみこみちゅう... +THEME_RESTORING=Themeをもとにもどしています... THEME_APPLYING_LINE1=Themeを てきようしています THEME_APPLYING_LINE2=さいきどうしています . . . THEME_DELETE_IN_USE=このテーマは使用中のため削除できません。 diff --git a/mod/etc/options_menu/themes/lang/nl-NL.lang b/mod/etc/options_menu/themes/lang/nl-NL.lang index 06d6bf3..03737ba 100644 --- a/mod/etc/options_menu/themes/lang/nl-NL.lang +++ b/mod/etc/options_menu/themes/lang/nl-NL.lang @@ -82,6 +82,7 @@ THEME_MOVING_LINE2=Even Geduld . . . THEME_LOADING_ASSETS=Assets worden geladen... THEME_SAVING=Eigen thema wordt opgeslagen... THEME_PREVIEW_LOADING=Themavoorbeeld wordt geladen... +THEME_RESTORING=Thema wordt hersteld... THEME_APPLYING_LINE1=Thema Wordt Toegepast THEME_APPLYING_LINE2=Nu Herstarten . . . THEME_DELETE_IN_USE=Dit thema wordt gebruikt en kan niet worden verwijderd. diff --git a/mod/etc/options_menu/themes/lang/pt-PT.lang b/mod/etc/options_menu/themes/lang/pt-PT.lang index c1d6711..99ccf98 100644 --- a/mod/etc/options_menu/themes/lang/pt-PT.lang +++ b/mod/etc/options_menu/themes/lang/pt-PT.lang @@ -82,6 +82,7 @@ THEME_MOVING_LINE2=Aguarde Por Favor . . . THEME_LOADING_ASSETS=A carregar recursos... THEME_SAVING=A guardar tema personalizado... THEME_PREVIEW_LOADING=A carregar pré-visualização do tema... +THEME_RESTORING=A repor o tema... THEME_APPLYING_LINE1=A Aplicar o Tema THEME_APPLYING_LINE2=A Reiniciar Agora . . . THEME_DELETE_IN_USE=Este tema está em uso e não pode ser removido. diff --git a/mod/etc/options_menu/themes/lang/ru-RU.lang b/mod/etc/options_menu/themes/lang/ru-RU.lang index 423f19a..027b400 100644 --- a/mod/etc/options_menu/themes/lang/ru-RU.lang +++ b/mod/etc/options_menu/themes/lang/ru-RU.lang @@ -82,6 +82,7 @@ THEME_MOVING_LINE2=Пожалуйста, подождите . . . THEME_LOADING_ASSETS=Загрузка ресурсов... THEME_SAVING=Сохранение своей темы... THEME_PREVIEW_LOADING=Загрузка предпросмотра темы... +THEME_RESTORING=Восстановление темы... THEME_APPLYING_LINE1=Применение Темы THEME_APPLYING_LINE2=Перезагрузка . . . THEME_DELETE_IN_USE=Эта тема используется и не может быть удалена. From e044b3f01c193a8b44ec73c3293317e150cf2eaa Mon Sep 17 00:00:00 2001 From: DefKorns Date: Wed, 21 Oct 2026 15:03:20 +0000 Subject: [PATCH 7/9] Leave the UI alone while the theme name is still the install placeholder --- mod/etc/options_menu/themes/scripts/om_overlaythmcript | 3 +++ mod/etc/options_menu/themes/scripts/om_themescript | 3 +++ 2 files changed, 6 insertions(+) diff --git a/mod/etc/options_menu/themes/scripts/om_overlaythmcript b/mod/etc/options_menu/themes/scripts/om_overlaythmcript index f9c66f1..a41702a 100644 --- a/mod/etc/options_menu/themes/scripts/om_overlaythmcript +++ b/mod/etc/options_menu/themes/scripts/om_overlaythmcript @@ -149,6 +149,9 @@ themeSelector() { local title_font="$font_path/title.fnt" local title_theme_font="$full_theme_path/fonts/title.fnt" + # an install leaves the placeholder until a theme is applied from the menu + [ "$selected_theme" = "CHANGEME" ] && return 0 + if [ "$selected_theme" != "$previous_theme" ] || [ ! -f "$last_theme" ] || [ ! -f "$active_theme_file" ]; then echo "$selected_theme" >"$last_theme" echo "$full_theme_path" >"$active_theme_file" diff --git a/mod/etc/options_menu/themes/scripts/om_themescript b/mod/etc/options_menu/themes/scripts/om_themescript index a8d827b..6737210 100644 --- a/mod/etc/options_menu/themes/scripts/om_themescript +++ b/mod/etc/options_menu/themes/scripts/om_themescript @@ -281,6 +281,9 @@ themeSelector() { full_theme_path="$diy_theme" fi + # an install leaves the placeholder until a theme is applied from the menu + [ "$selected_theme" = "CHANGEME" ] && [ "$full_theme_path" != "$diy_theme" ] && return 0 + if [ "$selected_theme" != "$previous_theme" ] || [ ! -f "$last_theme" ] || [ ! -f "$active_theme_file" ]; then echo "$selected_theme" >"$last_theme" echo "$full_theme_path" >"$active_theme_file" From 598c92437809109f51098f046ed8df625fee2934 Mon Sep 17 00:00:00 2001 From: DefKorns Date: Wed, 21 Oct 2026 15:05:54 +0000 Subject: [PATCH 8/9] Refresh every changed theme font and read them from the theme actually chosen --- mod/etc/options_menu/themes/scripts/om_overlaythmcript | 9 +++------ mod/etc/options_menu/themes/scripts/om_themescript | 9 ++++----- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/mod/etc/options_menu/themes/scripts/om_overlaythmcript b/mod/etc/options_menu/themes/scripts/om_overlaythmcript index a41702a..fd7da43 100644 --- a/mod/etc/options_menu/themes/scripts/om_overlaythmcript +++ b/mod/etc/options_menu/themes/scripts/om_overlaythmcript @@ -90,7 +90,8 @@ fontBindFix() { [ ! -f "${font_path}/title.fnt.backup" ] && cp "${font_path}/title.fnt" "${font_path}/title.fnt.backup" for font_name in title s m l small medium large; do if [ "$1" == "backup" ] && [ -f "$full_theme_path/fonts/${font_name}.fnt" ]; then - cp "$full_theme_path/fonts/${font_name}.fnt" "${font_path}/${font_name}.fnt" + cmp -s "$full_theme_path/fonts/${font_name}.fnt" "${font_path}/${font_name}.fnt" || + cp "$full_theme_path/fonts/${font_name}.fnt" "${font_path}/${font_name}.fnt" elif [ "$font_name" == "title" ]; then cp "${font_path}/title.fnt.backup" "${font_path}/title.fnt" else @@ -146,8 +147,6 @@ themeSelector() { local font_path="$mountpoint/media/$modname/fonts" [ ! -d "$font_path" ] && font_path="$rootfs/usr/share/fonts" - local title_font="$font_path/title.fnt" - local title_theme_font="$full_theme_path/fonts/title.fnt" # an install leaves the placeholder until a theme is applied from the menu [ "$selected_theme" = "CHANGEME" ] && return 0 @@ -158,9 +157,7 @@ themeSelector() { fi if [ -d "$full_theme_path/fonts" ]; then - if [ "$(cksum "$title_font" | awk '{ print $1; }')" != "$(cksum "$title_theme_font" | awk '{ print $1; }')" ]; then - fontBindFix "backup" - fi + fontBindFix "backup" else fontBindFix "restore" fi diff --git a/mod/etc/options_menu/themes/scripts/om_themescript b/mod/etc/options_menu/themes/scripts/om_themescript index 6737210..914f597 100644 --- a/mod/etc/options_menu/themes/scripts/om_themescript +++ b/mod/etc/options_menu/themes/scripts/om_themescript @@ -110,7 +110,8 @@ fontBindFix() { [ ! -f "${font_path}/title.fnt.backup" ] && cp "${font_path}/title.fnt" "${font_path}/title.fnt.backup" for font_name in title s m l small medium large; do if [ "$1" == "backup" ] && [ -f "$full_theme_path/fonts/${font_name}.fnt" ]; then - cp "$full_theme_path/fonts/${font_name}.fnt" "${font_path}/${font_name}.fnt" + cmp -s "$full_theme_path/fonts/${font_name}.fnt" "${font_path}/${font_name}.fnt" || + cp "$full_theme_path/fonts/${font_name}.fnt" "${font_path}/${font_name}.fnt" elif [ "$font_name" == "title" ]; then cp "${font_path}/title.fnt.backup" "${font_path}/title.fnt" else @@ -240,8 +241,6 @@ themeSelector() { local full_theme_path="$themes_path/$selected_theme" local font_path="$mountpoint/media/$modname/fonts" [ ! -d "$font_path" ] && font_path="$rootfs/usr/share/fonts" - local title_font="$font_path/title.fnt" - local theme_font_path="$full_theme_path/fonts" local silent_wav="$rootfs/usr/share/themes/bgm_boot.wav" local music_path="$mountpoint/media/$modname/music_menu" @@ -296,8 +295,8 @@ themeSelector() { return 0 fi - if [ -d "$theme_font_path" ]; then - cmp -s "$title_font" "$theme_font_path/title.fnt" || fontBindFix "backup" + if [ -d "$full_theme_path/fonts" ]; then + fontBindFix "backup" else fontBindFix "restore" fi From d3cfb77a66fb8b7112b98a9cab7b82ca3c503a7b Mon Sep 17 00:00:00 2001 From: DefKorns Date: Wed, 21 Oct 2026 15:21:44 +0000 Subject: [PATCH 9/9] Use the Options Menu splash, unpack and menu reload helpers --- .../themes/creator/scripts/om_applytheme | 2 +- .../themes/creator/scripts/om_preview | 4 +- .../themes/creator/scripts/om_removediy | 4 +- mod/etc/options_menu/themes/scripts/om_vars | 51 +++---------------- 4 files changed, 13 insertions(+), 48 deletions(-) diff --git a/mod/etc/options_menu/themes/creator/scripts/om_applytheme b/mod/etc/options_menu/themes/creator/scripts/om_applytheme index f241e76..ebdbe5a 100644 --- a/mod/etc/options_menu/themes/creator/scripts/om_applytheme +++ b/mod/etc/options_menu/themes/creator/scripts/om_applytheme @@ -19,7 +19,7 @@ source $mountpoint/etc/options_menu/themes/scripts/om_vars script_init -"$om_scripts/gen_splash" /tmp/om_splash.png THEME_SAVING && decodepng /tmp/om_splash.png >/dev/fb0 +omSplash THEME_SAVING name="diy_theme" i=1 diff --git a/mod/etc/options_menu/themes/creator/scripts/om_preview b/mod/etc/options_menu/themes/creator/scripts/om_preview index c8000bb..a69c175 100644 --- a/mod/etc/options_menu/themes/creator/scripts/om_preview +++ b/mod/etc/options_menu/themes/creator/scripts/om_preview @@ -20,7 +20,7 @@ source $mountpoint/etc/options_menu/themes/scripts/om_vars script_init -"$om_scripts/gen_splash" /tmp/om_splash.png THEME_PREVIEW_LOADING && decodepng /tmp/om_splash.png >/dev/fb0 +omSplash THEME_PREVIEW_LOADING if [ ! -f "$b_file" ]; then sed '1,2d' $om_theme_script >"$b_file" echo "themeSelector" >"$p_file" @@ -31,4 +31,4 @@ fi source "$b_file" themeSelector -menuReloadLater +omReloadMenuLater /etc/init.d/S8103OptionsMenu restart diff --git a/mod/etc/options_menu/themes/creator/scripts/om_removediy b/mod/etc/options_menu/themes/creator/scripts/om_removediy index e4fe880..d0d2a50 100644 --- a/mod/etc/options_menu/themes/creator/scripts/om_removediy +++ b/mod/etc/options_menu/themes/creator/scripts/om_removediy @@ -27,8 +27,8 @@ awk '$4 ~ /^\/diy_theme\// { found = 1 } END { exit !found }' /proc/self/mountin diyThemeRemover if [ -n "$diy_bound" ]; then - "$om_scripts/gen_splash" /tmp/om_splash.png THEME_RESTORING && decodepng /tmp/om_splash.png >/dev/fb0 - menuReloadLater + omSplash THEME_RESTORING + omReloadMenuLater /etc/init.d/S8103OptionsMenu restart else $options_menu/lib/theme_manager --commandPath $om_mod_gen_cmds/ --scriptPath $om_mod_gen_scripts --title "$om_title" & fi diff --git a/mod/etc/options_menu/themes/scripts/om_vars b/mod/etc/options_menu/themes/scripts/om_vars index 54ef4cc..da68d4d 100644 --- a/mod/etc/options_menu/themes/scripts/om_vars +++ b/mod/etc/options_menu/themes/scripts/om_vars @@ -226,7 +226,7 @@ migrateThemes() { for item in "$nand_theme_path"/*; do name="${item##*/}" if [ "$name" != "$sfregion" ] && [ ! -e "$theme_path/$name" ]; then - "$om_scripts/gen_splash" /tmp/om_splash.png THEME_MOVING_LINE1 THEME_MOVING_LINE2 && decodepng /tmp/om_splash.png > /dev/fb0 + omSplash THEME_MOVING_LINE1 THEME_MOVING_LINE2 break fi done @@ -375,7 +375,7 @@ themeLoader() { sed -i \"s/selected_theme=\\\"CHANGEME\\\"/selected_theme=\\\"${thm}\\\"/g;\" \"$b_file\" " >> "$thm_script.sh" - echo "\"\$om_scripts/gen_splash\" /tmp/om_splash.png THEME_APPLYING_LINE1 THEME_APPLYING_LINE2 && decodepng /tmp/om_splash.png > /dev/fb0 + echo "omSplash THEME_APPLYING_LINE1 THEME_APPLYING_LINE2 sleep 1 hakchi reboot" >> "$thm_script.sh" @@ -404,11 +404,11 @@ removeRegionalTheme() { } getThemeList() { - "$om_scripts/gen_splash" /tmp/om_splash.png THEME_LIST_DOWNLOADING_LINE1 THEME_LIST_DOWNLOADING_LINE2 && decodepng /tmp/om_splash.png > /dev/fb0 + omSplash THEME_LIST_DOWNLOADING_LINE1 THEME_LIST_DOWNLOADING_LINE2 cd "$om_mod_sub" || exit if [ ! -x "$om_scripts/downloader" ]; then - "$om_scripts/gen_splash" /tmp/om_splash.png DOWNLOADER_MISSING_LINE1 DOWNLOADER_MISSING_LINE2 && decodepng /tmp/om_splash.png > /dev/fb0 + omSplash DOWNLOADER_MISSING_LINE1 DOWNLOADER_MISSING_LINE2 sleep 3 return 1 fi @@ -534,14 +534,7 @@ themeGenerator() { return "$rc" } -freeSpaceKb() { - df -Pk "$1" | awk 'NR==2 {print $4}' -} -unpackedSizeKb() { - size_kb=$(( $(tail -c4 "$1" | od -An -tu4) / 1024 + 1 )) - echo $(( size_kb + size_kb / 10 )) -} urlEncodeName() { printf '%s' "$1" | sed 's/%/%25/g; s/#/%23/g; s/?/%3F/g' @@ -610,20 +603,10 @@ abortDownload() { } unpackTheme() { - tarball="${system_name}.$1.tar.gz" unpacking="$1" - if [ "$(freeSpaceKb .)" -lt "$(unpackedSizeKb "$tarball")" ]; then - dl_rc=3 - gzip -t "$tarball" 2> /dev/null || dl_rc=1 - elif ! tar -xzf "$tarball"; then - dl_rc=1 - [ "$(freeSpaceKb .)" -lt 1024 ] && dl_rc=3 - else - remove "$tarball" - unpacking="" - return 0 - fi - rm -rf "$tarball" "$1" "$1.png" + omUnpack "${system_name}.$1.tar.gz" . + dl_rc=$? + [ "$dl_rc" = 0 ] || rm -rf "$1" "$1.png" unpacking="" return "$dl_rc" } @@ -851,7 +834,7 @@ diySpriteSelector() { } diyThemeChecker() { - [ "$1" = "loader" ] && { "$om_scripts/gen_splash" /tmp/om_splash.png THEME_LOADING_ASSETS && decodepng /tmp/om_splash.png > /dev/fb0; } + [ "$1" = "loader" ] && omSplash THEME_LOADING_ASSETS [ ! -d "$diy_theme_path" ] && mkdir -p "$diy_theme_path" @@ -908,24 +891,6 @@ diyHomePreviews() { done } -# the menu holds /dev/fb0, so remote-exec reloads the current folder (chmenu's hook remounts -# the theme); chmenu refuses the folder already shown unless its state says otherwise -menuReloadLater() { - menu_state="/var/saves/$modname/menu" - current_menu="000" - [ -f "$menu_state" ] && current_menu="$(cat "$menu_state")" - cat >/var/exec.flag.tmp <"$menu_state" -/bin/chmenu "$current_menu" || /bin/chmenu 000 || { echo "$current_menu" >"$menu_state"; uistart; } -/etc/init.d/S8103OptionsMenu restart -EOF - mv /var/exec.flag.tmp /var/exec.flag -} - diyThemeRemover() { disableCmds "diy" "del_diy" "preview" remove "$diy_selection_path"