Skip to content

Instantly share code, notes, and snippets.

@i30817
Last active December 10, 2023 09:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save i30817/b9f5e3aba0c54c5f5a81ba340c626d1b to your computer and use it in GitHub Desktop.
Save i30817/b9f5e3aba0c54c5f5a81ba340c626d1b to your computer and use it in GitHub Desktop.
retroplay amiga updates
#!/usr/bin/bash
hash lftp 2>/dev/null || { echo >&2 "Program requires lftp but it's not installed. Aborting."; exit 1; }
hash xmlstarlet 2>/dev/null || { echo >&2 "Program requires xmlstarlet but it's not installed. Aborting."; exit 1; }
hash zcat 2>/dev/null || { echo >&2 "Program requires zcat but it's not installed. Aborting."; exit 1; }
hash mktemp 2>/dev/null || { echo >&2 "Program requires mktemp but it's not installed. Aborting."; exit 1; }
#cd to the script dir if executed from outside
SCRIPT_PATH=$(dirname "$(readlink -f "$0")")
cd "$SCRIPT_PATH" || { echo >&2 "Program script dir does not exist. Aborting."; exit 1; }
#filter non-english or mt32 games or 'files' versions of the games
#(if it's there, image exists and is usally better) configs with this stone age xpath 1.0
function join_by { local d="$1"; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }
F=(\
"\"_De\"" "\"_Dk\"" "\"_Fr\"" "\"_Es\"" "\"_It\"" "\"_Nl\"" "\"_Cz\"" "\"_Pl\"" "\"_Se\"" "\"_Fi\"" "\"_Gr\"" "\"_DeFrIt\"" "\"_DeEsFrIt\"" "\"_MT32\"" "\"_Files\"" "\"_BETA\"" "\"Demo_\"" \
)
F=("${F[@]/#/contains(\@name,}")
F=("${F[@]/%/)}")
FILTER=$(join_by ' or ' "${F[@]}" )
DAT_DIR_1=$(mktemp -d)
DAT_DIR_2=$(mktemp -d)
DAT_DIR_3=$(mktemp -d)
#change these and you change the download dirs, so also rename them in the filesystem if you don't want to redownload a lot
mkdir -p amiga
GAMES="amiga/Amiga WHDLoad"
GAMES_BETA="amiga/Amiga WHDLoad(Beta)"
GAMES_HD="amiga/Amiga HD"
set -euo pipefail
OLDIFS="$IFS"
IFS=$'\n\t'
#we want to interpret the commands here, so it's unquoted
#this recently changed from ftp:amiga@grandis.nu to ftp:amiga@ftp.grandis.nu
lftp << EOF
set ssl:verify-certificate false
lftp "ftp://ftp:amiga@ftp.grandis.nu/Retroplay WHDLoad Packs/"
mget "Commodore Amiga - WHDLoad - Games (*.zip" -O "$DAT_DIR_1"
mirror --ignore-time -ve "Commodore_Amiga_-_WHDLoad_-_Games" "./$GAMES"
mget "Commodore Amiga - WHDLoad - Games - Beta*.zip" -O "$DAT_DIR_2"
mirror --ignore-time -ve "Commodore_Amiga_-_WHDLoad_-_Games_-_Beta_&_Unreleased" "./$GAMES_BETA"
mget "Commodore Amiga - HD Loaders*.zip" -O "$DAT_DIR_3"
mirror --ignore-time -ve "Commodore_Amiga_-_HD_Loaders_-_Games" "./$GAMES_HD"
bye
EOF
IFS="$OLDIFS"
#bash does not support =("$var") and xml starlet is dumb and needs to seek input files so <("$var") does not work
XSL_FILE=$(mktemp)
#xstl transformer of the xml from retroplay to the Logiqx XML retroarch expects
cat << 'EOF' > "$XSL_FILE"
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<!-- IdentityTransform -->
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<!-- Remove the useless retroplay 'header', 'machine' and 'machine/description' elements-->
<xsl:template match="header" />
<xsl:template match="machine">
<xsl:apply-templates select="rom"/>
</xsl:template>
<!-- transform the retroplay 'rom' element to have a wrapping 'machine' with the rom name minus extension-->
<xsl:template match="rom">
<!-- all of the files on these dirs on the retroplay dir have dot + 3 chars extensions -->
<!-- xsl strings start at '1' not '0' -->
<xsl:variable name="file" select="substring(@name,1, string-length(@name) - 4)" />
<xsl:variable name="tokens" select="str:tokenize($file, '_')" />
<xsl:variable name="suffix">
<xsl:for-each select="$tokens">
<xsl:if test="position()=2"><xsl:value-of select="."/></xsl:if>
<xsl:if test="position()&gt;2"><xsl:value-of select="concat(') (', .)"/></xsl:if>
</xsl:for-each>
</xsl:variable>
<machine>
<xsl:attribute name="name"><xsl:value-of select="$file"/></xsl:attribute>
<description>
<xsl:value-of select="concat($tokens[1],' (', $suffix, ')')"/>
</description>
<xsl:copy><xsl:apply-templates select="@* | node()" /></xsl:copy>
</machine>
</xsl:template>
</xsl:stylesheet>
EOF
#transform the datafiles to the format retroarch expects and remove the non-english games from the datafile
zcat -c "$DAT_DIR_1"/* | xmlstarlet fo --dropdtd | xmlstarlet tr --xinclude "$XSL_FILE" | xmlstarlet edit -d "//machine [$FILTER]" > "$DAT_DIR_1/games.dat"
zcat -c "$DAT_DIR_2"/* | xmlstarlet fo --dropdtd | xmlstarlet tr --xinclude "$XSL_FILE" | xmlstarlet edit -d "//machine [$FILTER]" > "$DAT_DIR_2/games.dat"
zcat -c "$DAT_DIR_3"/* | xmlstarlet fo --dropdtd | xmlstarlet tr --xinclude "$XSL_FILE" | xmlstarlet edit -d "//machine [$FILTER]" > "$DAT_DIR_3/games.dat"
#merges the files
cat << EOF > "$XSL_FILE"
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="utf-8"/>
<xsl:template match="/datafile">
<xsl:copy>
<xsl:copy-of select="document('$DAT_DIR_1/games.dat')/datafile/machine" />
<xsl:copy-of select="document('$DAT_DIR_2/games.dat')/datafile/machine" />
<xsl:copy-of select="document('$DAT_DIR_3/games.dat')/datafile/machine" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
EOF
echo "<datafile/>" | xmlstarlet tr --xinclude "$XSL_FILE" > "amiga/games.dat"
echo 'A playlist with only english games can be made in Retroarch manual scanner with the new dat.'
echo 'For thumbnails:'
echo ' pip install --force-reinstall libretrofuzz'
echo ' libretrofuzz --no-meta'
echo 'Then choose Commodore - Amiga twice (playlist and server directory).'
#alarm sound
printf "\a"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment