Skip to content

Instantly share code, notes, and snippets.

@remixer-dec
Created February 23, 2026 22:34
Show Gist options
  • Select an option

  • Save remixer-dec/0a38b53b07f51990345ec9dec89664cd to your computer and use it in GitHub Desktop.

Select an option

Save remixer-dec/0a38b53b07f51990345ec9dec89664cd to your computer and use it in GitHub Desktop.
FreeCol Trimui Smart Pro launch script (compatibility fix)
#!/bin/bash
XDG_DATA_HOME=${XDG_DATA_HOME:-$HOME/.local/share}
if [ -d "/opt/system/Tools/PortMaster/" ]; then
controlfolder="/opt/system/Tools/PortMaster"
elif [ -d "/opt/tools/PortMaster/" ]; then
controlfolder="/opt/tools/PortMaster"
elif [ -d "$XDG_DATA_HOME/PortMaster/" ]; then
controlfolder="$XDG_DATA_HOME/PortMaster"
else
controlfolder="/roms/ports/PortMaster"
fi
source $controlfolder/control.txt
get_controls
[ -f "${controlfolder}/mod_${CFW_NAME}.txt" ] && source "${controlfolder}/mod_${CFW_NAME}.txt"
GAMEDIR=/$directory/ports/freecol
jar_filename="FreeCol.jar"
gptk_filename="FreeCol.gptk"
> "$GAMEDIR/log.txt" && exec > >(tee "$GAMEDIR/log.txt") 2>&1
echo "[INFO] Script started at $(date)"
CONFDIR="$GAMEDIR/conf/"
$ESUDO mkdir -p "${CONFDIR}"
export LD_LIBRARY_PATH="$GAMEDIR/libs.${DEVICE_ARCH}:$LD_LIBRARY_PATH"
export SDL_GAMECONTROLLERCONFIG="$sdl_controllerconfig"
export TEXTINPUTINTERACTIVE="Y"
# ───────────────────────────────────────────────────────────────
# Kill old Weston/seatd processes to prevent VT conflicts
# ───────────────────────────────────────────────────────────────
echo "[INFO] Killing old Weston/seatd processes..."
$ESUDO pkill -9 wp_weston 2>/dev/null || true
$ESUDO pkill -9 westonwrap.sh 2>/dev/null || true
$ESUDO pkill -9 seatd 2>/dev/null || true
sleep 0.5
# ───────────────────────────────────────────────────────────────
# Mount Weston runtime
# ───────────────────────────────────────────────────────────────
weston_dir=/tmp/weston
$ESUDO mkdir -p "${weston_dir}"
weston_runtime="weston_pkg_0.2"
if mountpoint -q "$weston_dir"; then
echo "[INFO] Unmounting existing $weston_dir..."
$ESUDO umount "$weston_dir" 2>/dev/null || true
fi
if [ ! -f "$controlfolder/libs/${weston_runtime}.squashfs" ]; then
if [ ! -f "$controlfolder/harbourmaster" ]; then
pm_message "This port requires the latest PortMaster to run, please go to https://portmaster.games/ for more info."
sleep 5
exit 1
fi
$ESUDO $controlfolder/harbourmaster --quiet --no-check runtime_check "${weston_runtime}.squashfs"
fi
$ESUDO mount "$controlfolder/libs/${weston_runtime}.squashfs" "${weston_dir}"
echo "[INFO] Mounted Weston runtime"
# ───────────────────────────────────────────────────────────────
# Setup XDG_RUNTIME_DIR with correct permissions
# ───────────────────────────────────────────────────────────────
export XDG_RUNTIME_DIR="/tmp/weston_runtime"
$ESUDO mkdir -p "$XDG_RUNTIME_DIR"
$ESUDO chmod 0700 "$XDG_RUNTIME_DIR"
$ESUDO chown root:root "$XDG_RUNTIME_DIR"
echo "[INFO] Created XDG_RUNTIME_DIR with correct permissions"
$ESUDO mkdir -p /run
$ESUDO chmod 755 /run
# ───────────────────────────────────────────────────────────────
# JRE load runtime
# ───────────────────────────────────────────────────────────────
runtime="zulu17.54.21-ca-jre17.0.13-linux"
export JAVA_HOME="$HOME/zulu17.54.21-ca-jre17.0.13-linux.aarch64"
$ESUDO mkdir -p "${JAVA_HOME}"
if mountpoint -q "$JAVA_HOME"; then
echo "[INFO] Unmounting existing $JAVA_HOME..."
$ESUDO umount "$JAVA_HOME" 2>/dev/null || true
fi
if [ ! -f "$controlfolder/libs/${runtime}.squashfs" ]; then
if [ ! -f "$controlfolder/harbourmaster" ]; then
pm_message "This port requires the latest PortMaster to run, please go to https://portmaster.games/ for more info."
sleep 5
exit 1
fi
$ESUDO $controlfolder/harbourmaster --quiet --no-check runtime_check "${runtime}.squashfs"
fi
$ESUDO mount "$controlfolder/libs/${runtime}.squashfs" "${JAVA_HOME}"
export PATH="$JAVA_HOME/bin:$PATH"
echo "[INFO] Mounted Java runtime"
cd $GAMEDIR
# ───────────────────────────────────────────────────────────────
# Extract game data if needed
# ───────────────────────────────────────────────────────────────
ARCHIVE_FILE="data.tar.gz"
if [[ -f "$ARCHIVE_FILE" ]]; then
pm_message "Extracting game data, this can take a few minutes..."
if [ "$CFW_NAME" = "muOS" ]; then
if gunzip -c "$ARCHIVE_FILE" | tar xf -; then
pm_message "Extraction successful."
$ESUDO rm -f "$ARCHIVE_FILE"
else
pm_message "Error: Extraction failed."
sleep 5
exit 1
fi
else
if tar -xzf "$ARCHIVE_FILE"; then
pm_message "Extraction successful."
$ESUDO rm -f "$ARCHIVE_FILE"
else
pm_message "Error: Extraction failed."
sleep 5
exit 1
fi
fi
elif [ ! -d 'data/' ]; then
pm_message "Error: No data directory present and Archive file $ARCHIVE_FILE not found."
sleep 5
exit 1
fi
# ───────────────────────────────────────────────────────────────
# Free up memory
# ───────────────────────────────────────────────────────────────
echo "[INFO] Freeing up memory..."
$ESUDO pkill adbd 2>/dev/null || true
# ───────────────────────────────────────────────────────────────
# Start GPTOKEYB
# ───────────────────────────────────────────────────────────────
$GPTOKEYB "java" -c "$GAMEDIR/$gptk_filename" &
sleep 0.6 # For TSP only, do not move/modify this line.
# ───────────────────────────────────────────────────────────────
# Launch FreeCol via Weston (Non-Reparenting Fix + Fonts + Software Render)
# ───────────────────────────────────────────────────────────────
pm_platform_helper "$JAVA_HOME/bin/java"
sleep 0.5
$ESUDO pkill -9 seatd 2>/dev/null || true
sleep 0.3
cd $weston_dir
$ESUDO ./seatd &
sleep 0.7
cd $GAMEDIR
# 1. Setup Fonts (Critical for Java)
mkdir -p "$GAMEDIR/conf/fonts"
$ESUDO mkdir -p /tmp/fontconfig
if [ -f "/mnt/SDCARD/System/resources/DejaVuSans.ttf" ]; then
cp "/mnt/SDCARD/System/resources/DejaVuSans.ttf" "$GAMEDIR/conf/fonts/"
fi
if [ -f "/usr/trimui/res/regular.ttf" ]; then
cp "/usr/trimui/res/regular.ttf" "$GAMEDIR/conf/fonts/"
fi
cat > "$GAMEDIR/conf/fonts.conf" << EOF
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>$GAMEDIR/conf/fonts</dir>
<cachedir>/tmp/fontconfig</cachedir>
</fontconfig>
EOF
export FONTCONFIG_FILE="$GAMEDIR/conf/fonts.conf"
export FONTCONFIG_PATH="$GAMEDIR/conf"
# 2. THE VIDEO FIX (Java Window Manager Fixes)
# _JAVA_AWT_WM_NONREPARENTING=1 -> Stops Java from creating invisible container windows
# AWT_TOOLKIT=XToolkit -> Forces standard X11 toolkit
export _JAVA_AWT_WM_NONREPARENTING=1
export AWT_TOOLKIT=XToolkit
export XDG_DATA_HOME="$CONFDIR"
# 3. Define Command
# Using Software Rendering (opengl=false) because it's the most reliable for 2D Strategy games
# --no-splash is vital to prevent Weston grabbing the wrong window
# 3. Define Command
# FORCE Software Rendering. Since we are routing through Weston's DRM backend,
# pure X11 Java drawing will be safely composited to the screen.
export ORIG_APP_CMD="$JAVA_HOME/bin/java -Xmx724M \
-Dsun.java2d.opengl=false \
-Dsun.java2d.xrender=false \
-Dsun.awt.noerasebackground=true \
-Dsun.java2d.fontpath=$GAMEDIR/conf/fonts \
-jar $GAMEDIR/$jar_filename \
--full-screen < /dev/null"
# 4. Copy and patch westonwrap.sh
# We only need the BusyBox array slice patch now. Driver Xwayland overrides
# are unnecessary because we are using standard System/DRM graphics mode.
cp "$weston_dir/westonwrap.sh" /tmp/westonwrap.patched.sh
sed -i 's|^export app_command="\${@:5}"|export app_command="$ORIG_APP_CMD"|' /tmp/westonwrap.patched.sh
chmod +x /tmp/westonwrap.patched.sh
# 5. Bind-mount and Launch
$ESUDO mount --bind /tmp/westonwrap.patched.sh $weston_dir/westonwrap.sh
echo "[INFO] Bind-mounted patched westonwrap.sh"
# Changed "headless noop kiosk crusty_glx_gl4es"
# to "drm gl kiosk system"
# This makes Weston physically draw the screen instead of black-holing the X11 surface,
# and prevents Java from loading Crusty and racing the hardware context.
$ESUDO env \
XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR" \
WRAPPED_LIBRARY_PATH="$GAMEDIR/libs.${DEVICE_ARCH}/:$LD_LIBRARY_PATH" \
PATH=$PATH \
JAVA_HOME="$JAVA_HOME" \
WAYLAND_DISPLAY="" \
DISPLAY=:0 \
FONTCONFIG_FILE="$FONTCONFIG_FILE" \
FONTCONFIG_PATH="$FONTCONFIG_PATH" \
_JAVA_AWT_WM_NONREPARENTING=1 \
$weston_dir/westonwrap.sh drm gl kiosk system \
"dummy" &> /tmp/freecol.txt
# ───────────────────────────────────────────────────────────────
# Cleanup
# ───────────────────────────────────────────────────────────────
echo "[INFO] Cleaning up..."
$ESUDO pkill -f wp_weston 2>/dev/null || true
sleep 0.5
$ESUDO $weston_dir/westonwrap.sh cleanup 2>/dev/null || true
$ESUDO umount $weston_dir/westonwrap.sh 2>/dev/null || true
rm -f /tmp/westonwrap.patched.sh
if [[ "$PM_CAN_MOUNT" != "N" ]]; then
$ESUDO umount "${weston_dir}" 2>/dev/null || true
$ESUDO umount "${JAVA_HOME}" 2>/dev/null || true
fi
if [ -d "$XDG_RUNTIME_DIR" ]; then
find "$XDG_RUNTIME_DIR" -name "wayland-*.lock" -delete 2>/dev/null || true
fi
pm_finish
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment