Skip to content
Merged
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
5 changes: 4 additions & 1 deletion PortMaster/device_info.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ fi
CFW_NAME="Unknown"
CFW_VERSION="Unknown"

if [ -f "/usr/share/plymouth/themes/text.plymouth" ]; then
if [ -d "/mnt/SDCARD/spruce" ]; then
CFW_NAME="spruce"
CFW_VERSION="$(cat /mnt/SDCARD/spruce/spruce 2>/dev/null)"
elif [ -f "/usr/share/plymouth/themes/text.plymouth" ]; then
CFW_INFO=$(grep "title=" "/usr/share/plymouth/themes/text.plymouth")
CFW_FFS=$(grep -a "title=" "/usr/share/plymouth/themes/text.plymouth" | cut -d'=' -f 2- | tr -cd 'a-zA-Z' | tr '[:upper:]' '[:lower:]')

Expand Down
23 changes: 23 additions & 0 deletions PortMaster/mod_spruce.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
#
# SPDX-License-Identifier: MIT
#

CUR_TTY="/dev/null"
GODOT2_OPTS="-r ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT} -f"
GODOT_OPTS="--resolution ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT} -f"

# No dialog pipe while a port runs; just print.
pm_message() {
echo "$1" > "$CUR_TTY"
}

pm_platform_helper() {
if [ -e "$PM_PIPE" ]; then
PortMasterDialogExit
fi
printf ""
}

# Device-specific settings live on the spruce card.
[ -f /mnt/SDCARD/spruce/portmaster/mod.txt ] && source /mnt/SDCARD/spruce/portmaster/mod.txt
10 changes: 5 additions & 5 deletions PortMaster/pylibs/harbourmaster/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@
HM_DEFAULT_SCRIPTS_DIR = Path('ports/').absolute()
HM_TESTING=True

elif Path("/mnt/sdcard/spruce").is_dir():
## Spruce (Miyoo Flip)
HM_DEFAULT_TOOLS_DIR = Path("/mnt/SDCARD/Roms/.portmaster")
HM_DEFAULT_PORTS_DIR = Path("/mnt/SDCARD/Roms/PORTS64")
HM_DEFAULT_SCRIPTS_DIR = Path("/mnt/SDCARD/Roms/PORTS64")
elif Path("/mnt/SDCARD/spruce").is_dir():
## spruceOS (Miyoo Flip, TrimUI, Anbernic, Powkiddy RGB30...)
HM_DEFAULT_TOOLS_DIR = Path("/mnt/SDCARD/Persistent/portmaster")
HM_DEFAULT_PORTS_DIR = Path("/mnt/SDCARD/Roms/ports")
HM_DEFAULT_SCRIPTS_DIR = Path("/mnt/SDCARD/Roms/ports")

elif Path("/mnt/SDCARD/MIYOO_EX/PortMaster").is_dir():
## TrimUI Smart Pro
Expand Down
36 changes: 36 additions & 0 deletions PortMaster/pylibs/harbourmaster/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,41 @@ def portmaster_install(self, bash_files):
shutil.copy(MY_DIR / "control.txt", CONTROL_HACK)


class PlatformSpruce(PlatformBase):
# spruce sets SDL_GAMECONTROLLERCONFIG per pad itself.
WANT_XBOX_FIX = False

def first_run(self):
self.portmaster_install([])

def portmaster_install(self, bash_files):
"""
Move files into place.
"""
super().portmaster_install(bash_files)

SP_DIR = self.hm.tools_dir / "PortMaster" / "spruce"
PM_DIR = self.hm.tools_dir / "PortMaster"

logger.debug(f'Copy {SP_DIR / "control.txt"} -> {PM_DIR / "control.txt"}')
shutil.copy(SP_DIR / "control.txt", PM_DIR / "control.txt")

logger.debug(f'Copy {SP_DIR / "PortMaster.txt"} -> {PM_DIR / "PortMaster.sh"}')
shutil.copy(SP_DIR / "PortMaster.txt", PM_DIR / "PortMaster.sh")

bash_files.append(PM_DIR / "PortMaster.sh")

XDG_DATA_HOME = Path(os.environ.get('XDG_DATA_HOME', Path.home() / '.local' / 'share'))
CONTROL_HACK = XDG_DATA_HOME / "PortMaster" / "control.txt"
CONTROL_HACK.parent.mkdir(parents=True, exist_ok=True)

logger.debug(f'Copy {SP_DIR / "control.txt"} -> {CONTROL_HACK}')
shutil.copy(SP_DIR / "control.txt", CONTROL_HACK)

def portmaster_post_install(self):
self.portmaster_install([])


class PlatformTesting(PlatformBase):
WANT_XBOX_FIX = False
WANT_SWAP_BUTTONS = False
Expand All @@ -1296,6 +1331,7 @@ def gamelist_file(self):
'muos': PlatformmuOS,
'miyoo': PlatformMiyoo,
'trimui': PlatformTrimUI,
'spruce': PlatformSpruce,
'retrodeck': PlatformRetroDECK,
'darwin': PlatformTesting,
'default': PlatformBase,
Expand Down
187 changes: 187 additions & 0 deletions PortMaster/spruce/PortMaster.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#!/bin/bash
#
# SPDX-License-Identifier: MIT
#

export HOME="/mnt/SDCARD"
export PATH="/mnt/SDCARD/Persistent/portmaster/bin/:$PATH"
export LD_LIBRARY_PATH="/mnt/SDCARD/Persistent/portmaster/lib:$LD_LIBRARY_PATH"
PM_PYTHON="/mnt/SDCARD/Persistent/portmaster/bin/python3"
export LD_PRELOAD=""
controlfolder="/mnt/SDCARD/Persistent/portmaster/PortMaster"
directory="/mnt/SDCARD/Roms/"

# Device-specific settings live on the spruce card.
[ -f /mnt/SDCARD/spruce/portmaster/portmaster.txt ] && source /mnt/SDCARD/spruce/portmaster/portmaster.txt


ESUDO=""
ESUDOKILL="-1" # for 351Elec and EmuELEC use "-1" (numeric one) or "-k"
export SDL_GAMECONTROLLERCONFIG_FILE="/usr/lib/gamecontrollerdb.txt"
# export SDL_GAMECONTROLLERCONFIG=$(grep "Deeplay" "/usr/lib/gamecontrollerdb.txt")

source "$controlfolder/device_info.txt"
[ -f "${controlfolder}/mod_${CFW_NAME}.txt" ] && source "${controlfolder}/mod_${CFW_NAME}.txt"
export HOME="/mnt/SDCARD"

## TODO: Change to PortMaster/tty when Johnnyonflame merges the changes in,
CUR_TTY=/dev/tty0

cd "$controlfolder"

> "$controlfolder/log.txt" && exec > >(tee "$controlfolder/log.txt") 2>&1

source "$controlfolder/utils/pmsplash.txt"

## Autoinstallation Code
# This will automatically install zips found within the `PortMaster/autoinstall` / `ports/autoinstall` directory using harbourmaster
AUTOINSTALL_DIR_1="$controlfolder/autoinstall"
AUTOINSTALL_DIR_2="$AUTOINSTALL_DIR_1"

if [ ! -d "$AUTOINSTALL_DIR_2" ]; then
mkdir -p "$AUTOINSTALL_DIR_2"
fi

# Check if there are any files to process before starting the dialog
AUTOINSTALL_FILES=$(find "$AUTOINSTALL_DIR_1" "$AUTOINSTALL_DIR_2" -type f \( -name "*.zip" -o -name "*.squashfs" \) 2>/dev/null)

if [ -n "$AUTOINSTALL_FILES" ]; then
source "$controlfolder/PortMasterDialog.txt"

GW=$(PortMasterIPCheck)
PortMasterDialogInit "no-check"

PortMasterDialog "messages_begin"
PortMasterDialog "message" "Auto-installation"

# 1. Install PortMaster.zip first
for autoinstall_dir in "$AUTOINSTALL_DIR_1" "$AUTOINSTALL_DIR_2"; do
if [ -f "$autoinstall_dir/PortMaster.zip" ]; then
if [ "$(PortMasterDialogResult "install" "$autoinstall_dir/PortMaster.zip")" = "OKAY" ]; then
$ESUDO rm -f "$autoinstall_dir/PortMaster.zip"
PortMasterDialog "message" "- SUCCESS: PortMaster.zip"
else
PortMasterDialog "message" "- FAILURE: PortMaster.zip"
fi
break # Stop after finding and processing the first one
fi
done

# 2. Install runtimes.zip and/or runtimes.{full,popular}.${DEVICE_ARCH}.zip
for autoinstall_dir in "$AUTOINSTALL_DIR_1" "$AUTOINSTALL_DIR_2"; do
if [ -f "$autoinstall_dir/runtimes.zip" ]; then
# Old runtimes.zip do not include an architecture comment.
ZIP_COMMENT="$(unzip -z "$file_name" | tail -n1 | cut -d' ' -f1)"
if [ "$ZIP_COMMENT" = "${DEVICE_ARCH}" ] || [ "$ZIP_COMMENT" = "Archive:" ]; then
PortMasterDialog "message" "- Installing runtimes.zip."
$ESUDO unzip -o "$autoinstall_dir/runtimes.zip" -d "$controlfolder/libs" | while IFS= read -r line; do
case "$line" in
*'inflating:'*|*'extracting:'*)
filename=$(echo "$line" | awk '{print $2}')
PortMasterDialog "message" " - $(basename $filename)"
;;
esac
done
$ESUDO rm -f "$autoinstall_dir/runtimes.zip"
PortMasterDialog "message" "- SUCCESS: runtimes.zip"
else
PortMasterDialogMessageBox "Unable to install runtime.zip, it is for the wrong architecture.\n\nDeleting file from autoinstall/."
$ESUDO rm -f "$autoinstall_dir/runtimes.zip"
fi
fi

if ls "$autoinstall_dir"/runtimes*.zip >/dev/null 2>&1; then
for file_name in "$autoinstall_dir"/runtimes*.zip; do
if [ -f "$file_name" ]; then
# Newer runtimes.full.ARCH.zip and friends includes the architecture as a comment.
if [ "$(unzip -z "$file_name" | tail -n1 | cut -d' ' -f1)" = "${DEVICE_ARCH}" ]; then
PortMasterDialog "message" "- Installing $(basename "$file_name")."
$ESUDO unzip -o "$file_name" -d "$controlfolder/libs" | while IFS= read -r line; do
case "$line" in
*'inflating:'*|*'extracting:'*)
filename=$(echo "$line" | awk '{print $2}')
PortMasterDialog "message" " - $(basename $filename)"
;;
esac
done
$ESUDO rm -f "$file_name"
PortMasterDialog "message" "- SUCCESS: $(basename "$file_name")"
else
PortMasterDialogMessageBox "Unable to install $(basename "$file_name"), it is for the wrong architecture.\n\nDeleting file from autoinstall directory."
$ESUDO rm -f "$file_name"
fi
fi
done
fi
done

# 3. Install *.squashfs files
for autoinstall_dir in "$AUTOINSTALL_DIR_1" "$AUTOINSTALL_DIR_2"; do
if ls "$autoinstall_dir"/*.squashfs >/dev/null 2>&1; then
for file_name in "$autoinstall_dir"/*.squashfs; do
if [ -f "$file_name" ]; then
$ESUDO mv -f "$file_name" "$controlfolder/libs"
PortMasterDialog "message" "- SUCCESS: $(basename "$file_name")"
fi
done
fi
done

# 4. Install remaining *.zip files
for autoinstall_dir in "$AUTOINSTALL_DIR_1" "$AUTOINSTALL_DIR_2"; do
if ls "$autoinstall_dir"/*.zip >/dev/null 2>&1; then
for file_name in "$autoinstall_dir"/*.zip; do
# Skip files we've already processed
base_file=$(basename "$file_name")
if [ "$base_file" = "PortMaster.zip" ]; then
continue
fi

if [ -f "$file_name" ]; then
if [ "$(PortMasterDialogResult "install" "$file_name")" = "OKAY" ]; then
$ESUDO rm -f "$file_name"
PortMasterDialog "message" "- SUCCESS: $base_file"
else
PortMasterDialog "message" "- FAILURE: $base_file"
fi
fi
done
fi
done

PortMasterDialog "messages_end"
if [ -z "$GW" ]; then
PortMasterDialogMessageBox "Finished running autoinstall.\n\nNo internet connection present so exiting."
PortMasterDialogExit

exit 0
else
PortMasterDialogMessageBox "Finished running autoinstall."
PortMasterDialogExit
fi
fi


export TERM=linux
# $ESUDO chmod 666 $CUR_TTY
# printf "\033c" > $CUR_TTY

# # Do it twice, it's just as nice!
# cat /dev/zero > /dev/fb0 2>/dev/null
# cat /dev/zero > /dev/fb0 2>/dev/null

echo "Starting PortMaster."

$ESUDO chmod -R +x .

$ESUDO rm -f "${controlfolder}/.pugwash-reboot"
# Run once; a self-update asks for a restart, spruce relaunches instead.
if [ -x "$PM_PYTHON" ]; then
$ESUDO "$PM_PYTHON" ./pugwash
else
$ESUDO ./pugwash
fi

unset LD_LIBRARY_PATH
unset SDL_GAMECONTROLLERCONFIG
PATH="$OLD_PATH"
42 changes: 42 additions & 0 deletions PortMaster/spruce/control.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
#
# SPDX-License-Identifier: MIT
#

CUR_TTY=/dev/null

export controlfolder="/mnt/SDCARD/Persistent/portmaster/PortMaster"

# Ports use $directory/ports/<game>; PORTS_DIR comes from spruce's launcher.
directory="$(dirname "${PORTS_DIR:-/mnt/SDCARD/Roms/ports}")"
export directory="${directory%/}/"

export PM_PYTHON="/mnt/SDCARD/Persistent/portmaster/bin/python3"
export PATH="/mnt/SDCARD/Persistent/portmaster/bin:$PATH"
export LD_LIBRARY_PATH="/mnt/SDCARD/Persistent/portmaster/lib:$LD_LIBRARY_PATH"

# Device-specific settings live on the spruce card.
[ -f /mnt/SDCARD/spruce/portmaster/control.txt ] && source /mnt/SDCARD/spruce/portmaster/control.txt

export ESUDO=""
export ESUDOKILL="-1" # for 351Elec and EmuELEC use "-1" (numeric one) or "-k"

export SDL_GAMECONTROLLERCONFIG_FILE="$controlfolder/gamecontrollerdb.txt"

SDLDBFILE="${SDL_GAMECONTROLLERCONFIG_FILE}"
[ -z "${SDLDBFILE}" ] && SDLDBFILE="${controlfolder}/gamecontrollerdb.txt"
SDLDBUSERFILE="${HOME}/.config/SDL-GameControllerDB/gamecontrollerdb.txt"
[ ! -f "${SDLDBUSERFILE}" ] && SDLDBUSERFILE="$SDL_GAMECONTROLLERCONFIG_FILE"

get_controls() {
LOWRES="N"
ANALOGSTICKS=$ANALOG_STICKS
# spruce exports the pad map itself; keep it.
sdl_controllerconfig="$SDL_GAMECONTROLLERCONFIG"
}

source $controlfolder/device_info.txt
source $controlfolder/funcs.txt

export GPTOKEYB2="$ESUDO env LD_PRELOAD=$controlfolder/libinterpose.${DEVICE_ARCH}.so $controlfolder/gptokeyb2 $ESUDOKILL"
export GPTOKEYB="$ESUDO $controlfolder/gptokeyb $ESUDOKILL"