Last active
May 11, 2021 22:48
-
-
Save Binsk/7eca0b001603515a79348225dce13ae6 to your computer and use it in GitHub Desktop.
GameMaker: Studio 2.3 Linux Compiling Interface
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Author: Reuben Shea | |
# Date: Apr, 09 2021 | |
# This script handles re-compiling a GameMaker project remotely given the | |
# wine prefix and runtime version. It is merely a convenience script I wrote | |
# so I could use GMEdit and compile on Linux w/o having to have the engine | |
# open due to big projects lagging like all hell. | |
# This script requires that you have opened GM and attempted to compile your | |
# project at least once. This script will just re-compile based on whatever the | |
# last compile was. An actual 'build' command is being worked on but I'm not | |
# there yet. | |
# Check we aren't in root: | |
if [ "$EUID" -eq 0 ]; then | |
printf "This script cannot be run as root\n" | |
exit 0 | |
fi | |
# Define colors, if supported: | |
CB="" # Bold | |
CN="" # Normal | |
CI="" # Important | |
CC="" # Code | |
CE="" # Error | |
if [ -n "$(tput colors)" ] && [ "$(tput colors)" -ge 8 ]; then | |
CB="\e[1m" | |
CN="\e[0m" | |
CI="\e[36m" | |
CS="\e[32m" | |
CE="\e[31m" | |
CC="\e[33m" | |
fi | |
# Check that necessary packages are installed: | |
if ! hash wine &> /dev/null; then | |
printf "This script requires ${CB}wine${CN} as well as 32bit architecture\nenabled in order to run!\n${CI}Please see: https://wiki.winehq.org/download${CN}\n\n" | |
exit 1; | |
fi | |
if ! hash winetricks &> /dev/null; then | |
printf "This script requires ${CB}winetricks${CN} in order to run!\n${CI}Please see: https://wiki.winehq.org/winetricks${CN}\n\n" | |
exit 1; | |
fi | |
# Define default values: | |
HOME=$(printf ~/) | |
PREFIX_GMS="${HOME}.wine" # Prefix of GameMaker installation | |
RUNTIME_GMS="" # Runtime version (last if blank) | |
PREFIX_SHELL="${HOME}.wine_gmbuild" # Personall 'shell' prefix for running the game | |
PROJECT_PATH="" # NOT YET SUPPORTED | |
COMPILE_SILENT=0 | |
WINE_DEBUG_STRING="env WINEDEBUG='warn-all,fixme-all,trace-all,err-all'" | |
# Define our functions: | |
# Usage: FNC_display_help | |
FNC_display_help(){ | |
printf "Usage: gmbuild [ACTION] [OPTION]...\n" | |
printf "Build, run, or clean a GMS project from terminal.\n" | |
printf "\nIf no runtime or prefix is specified then the system\nwill use the latest avialable runtime and default\nwine prefix.\n" | |
printf "\nActions:\n" | |
printf "\trun\t\t\tRuns the active project in the specified prefix\n\t\t\t\tbased on previous build settings\n" | |
printf "\tbuild\t\t\tBuilds and runs a project in the specified prefix\n\t\t\t\tbased on the currently specified project path\n" | |
printf "\tclean\t\t\tCleans the project\n" | |
printf "\tkill\t\t\tKills any detached WINE processes in the\n\t\t\t\tprefix left from the previous run\n" | |
printf "\tlist\t\t\tLists available installed runtimes for the \n\t\t\t\tcurrent prefix\n" | |
printf "\tprintle\t\t\tPrints the last recorded runtime error\n" | |
printf "\tuninstall\t\tDestroys the WINE prefix auto-generated by\n\t\t\t\tthis script and any saved project settings\n" | |
printf "\nIf no action is provided then the system will boot into\nan interactive mode.\n" | |
printf "\nOptions:\n" | |
printf "\t-h, --help\t\t\tDisplay this help page\n" | |
printf "\t-r, --runtime=RUNTIME\t\tSpecify RUNTIME as the runtime version to use\n" | |
printf "\t-p, --prefix=PREFIX\t\tSpecify PREFIX as the active WINE prefix\n" | |
printf "\t-l, --load=PROJECT\t\tSpecify to load saved prefix and runtime values\n\t\t\t\t\tfor PROJECT\n" | |
printf "\t-wv, --wine-verbose\t\tEnable verbose WINE output\n" | |
printf "\t-s, --silent\t\t\tDisable all compliing output\n" | |
printf "\nTo save project settings for quick building, launch in\ninteractive mode, set your prefix and\nruntime, then type 'save' to store the settings.\n" | |
printf "\nExamples:\n" | |
printf "\tgmbuild list\t\t\t\n" | |
printf "\tgmbuild run -r \"2.3.2.420\" -p \"/home/\$USER/.wine\"\n" | |
printf "\tgmbuild kill\n" | |
printf "\tgmbuild run --load=DemoProject\n" | |
printf "\n" | |
} | |
# Usage: FNC_prefix_setup | |
FNC_prefix_setup(){ | |
printf "A special WINE prefix is required to run this script.\n"; | |
printf "This can take a while and requires an internet connection.\n\n" | |
printf "Would you like to set this up now? [Y/n]: " | |
read INPUT | |
if [ "$INPUT" != "" ] && [ "$INPUT" != "y" ] && [ "$INPUT" != "Y" ]; then | |
printf "Received negative response. Exiting...\n" | |
exit 0 | |
fi | |
printf "\nGenerating prefix...\n" | |
env WINEPREFIX="$PREFIX_SHELL" WINEARCH="win64" winetricks dotnet48 --force -q | |
env WINEPREFIX="$PREFIX_SHELL" wineserver -w | |
printf "\nPrefix generated!\n" | |
} | |
# Usage: FNC_save [name] | |
FNC_save(){ | |
if [ -f "${HOME}.gmbuild" ]; then | |
FILE=$(cat "${HOME}.gmbuild") | |
rm "${HOME}.gmbuild" &> /dev/null | |
for LINE in $FILE; do | |
if [ "$LINE" = "" ]; then | |
continue | |
fi | |
$MATCH=$(printf "$LINE" | grep -o -E "\[$1:(prefix|runtime)\]") | |
if [ "$MATCH" = "" ]; then | |
printf "$LINE\n" >> "${HOME}.gmbuild" | |
fi | |
done | |
fi | |
printf "[$1:prefix]=$PREFIX_GMS\n" >> "${HOME}.gmbuild" | |
printf "[$1:runtime]=$RUNTIME_GMS\n" >> "${HOME}.gmbuild" | |
} | |
# Usage: FNC_load [name] | |
FNC_load(){ | |
if [ ! -f "${HOME}.gmbuild" ]; then | |
printf "No settings file found\n" | |
return | |
fi | |
PFX=$(cat "${HOME}.gmbuild" | grep -E "\[$1\:prefix]" | sed -r "s/[^=]+=//") | |
RT=$(cat "${HOME}.gmbuild" | grep -E "\[$1\:runtime]" | sed -r "s/[^=]+=//") | |
if [ "$PFX" = "" ]; then | |
printf " Failed to load: No settings found for '$1'\n" | |
return | |
fi | |
if [ "$PFX" = "$PREFIX_SHELL" ] || [ ! -d "$PFX/drive_c/" ]; then | |
printf " Failed to load: Invalid WINE prefix\n" | |
printf "${PFX}\n" | |
return | |
fi | |
if [ ! -d "$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/Cache/runtimes/runtime-$RT" ] && [ "$RT" != "" ]; then | |
printf " Failed to load: Invalid runtime\n" | |
return | |
fi | |
PREFIX_GMS=$PFX | |
RUNTIME_GMS=$RT | |
printf " Loaded project settings for '$1'\n" | |
} | |
# Usage: FNC_read_json [file] [key] | |
FNC_read_json(){ | |
while read LINE; do | |
VALUE=$(grep "\"${2}\"" "${1}" | sed -r 's/^ *//;s/.*: *"//;s/",?//') | |
if [ "$VALUE" ]; then | |
printf "$VALUE" | |
return | |
fi | |
done < "$1" | |
} | |
# Usage: FNC_get_input [input] | |
# Sets two variables: | |
# 1. INPUT - Regular user input | |
# 2. SPECIAL - Name of special input (such as ARRLEFT) | |
FNC_get_input(){ | |
IFS_O=$IFS | |
IFS= | |
INPUT="${1}" | |
SPECIAL="" | |
CHARCOUNT=${#1} | |
while read -sn1 PREINPUT; do | |
case "$PREINPUT" in | |
$'\x1b') | |
read -sn1 PREINPUT | |
if [ "$PREINPUT" == "[" ]; then | |
read -sn1 PREINPUT | |
case "$PREINPUT" in | |
"A") SPECIAL="ARRUP"; break;; | |
"B") SPECIAL="ARRDOWN"; break;; | |
"C") SPECIAL="ARRRIGHT"; break;; | |
"D") SPECIAL="ARRLEFT"; break;; | |
esac | |
fi | |
;; | |
$'\177') | |
if [ "$CHARCOUNT" -gt 0 ]; then | |
echo -en "\b \b" | |
CHARCOUNT=$((CHARCOUNT-1)) | |
INPUT="${INPUT:0:${#INPUT}-1}" | |
fi | |
;; | |
"")break;; | |
*) | |
CHARCOUNT=$((CHARCOUNT+1)) | |
printf %s "$PREINPUT" | |
INPUT="${INPUT}${PREINPUT}" | |
;; | |
esac | |
done | |
IFS=$IFS_O | |
} | |
# Usage: var=FNC_get_runtime | |
FNC_get_runtime(){ | |
OPATH=$PWD | |
FPATH="$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/Cache/runtimes" 2> /dev/null | |
RT="" | |
if [ -d "$FPATH" ]; then | |
cd "$FPATH" | |
FILES=(*) | |
for DIR in ${FILES[@]}; do | |
RT="$(printf "$DIR" | sed -r "s/runtime-//")" | |
done | |
cd "$OPATH" | |
fi | |
printf "$RT" | |
} | |
# Usage: FNC_list_runtimes | |
FNC_list_runtimes(){ | |
printf " Searching in prefix: $PREFIX_GMS\n" | |
OPATH=$PWD | |
FPATH="$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/Cache/runtimes" 2> /dev/null | |
if [ -d "$FPATH" ]; then | |
cd "$FPATH" | |
FILES=(*) | |
for DIR in ${FILES[@]}; do | |
printf " $DIR\n" | sed "s/runtime-//" | |
done | |
cd "$ODIR" | |
else | |
printf " No runtimes found!\n\n Please compile with GMS once first and\n make sure you are in the correct prefix.\n" | |
fi | |
} | |
# Usage: FNC_create_symlinks | |
FNC_create_symlinks(){ | |
if [ -d "$PREFIX_SHELL/drive_c/ProgramData/GameMakerStudio2" ]; then | |
return | |
fi | |
ln -s "$PREFIX_GMS/drive_c/users/$USER/Application Data/GameMakerStudio2" "$PREFIX_SHELL/drive_c/users/$USER/Application Data/" | |
ln -s "$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2" "$PREFIX_SHELL/drive_c/ProgramData" | |
ln -s "$PREFIX_GMS/drive_c/Program Files/GameMaker Studio 2" "$PREFIX_SHELL/drive_c/Program Files/" | |
} | |
#Usage: FNC_delete_symlinks | |
FNC_delete_symlinks(){ | |
rm "$PREFIX_SHELL/drive_c/users/$USER/Application Data/GameMakerStudio2" &> /dev/null | |
rm "$PREFIX_SHELL/drive_c/ProgramData/GameMakerStudio2" &> /dev/null | |
rm "$PREFIX_SHELL/drive_c/Program Files/GameMaker Studio 2" &> /dev/null | |
} | |
FNC_printle(){ | |
if [ ! -f "${HOME}.gmbuild_log" ]; then | |
printf " No build log found\n" | |
return | |
fi | |
if ! hash perl &> /dev/null; then | |
printf " Could not find PERL! Using backup method...\n" | |
FNC_printle_backup | |
return | |
fi | |
perl -e ' | |
open(FILE, "<", "$ARGV[0].gmbuild_log"); | |
@output=(); | |
$CN = "$ARGV[1]"; | |
$CI = "$ARGV[2]"; | |
$CE = "$ARGV[3]"; | |
$CB = "$ARGV[4]"; | |
$CC = "$ARGV[5]"; | |
$ERROR_STATE = 0; | |
$ERROR_FOUND = 0; | |
while (<FILE>){ | |
$LINE="$_"; | |
if ($ERROR_STATE == 0 && $LINE =~ /^ERROR!!! :: ###/){ | |
$ERROR_STATE = 2; | |
$ERROR_FOUND = 1; | |
push(@output, "$CI$CB ERROR:\n ==================================$CN\n"); | |
$LINE=""; | |
} | |
elsif ($ERROR_STATE == 2 && $LINE =~ /^############/){ | |
$ERROR_STATE = 1; | |
$LINE=""; | |
push(@output, "\n ${CI}${CB}STACK TRACE:\n${CN}"); | |
} | |
elsif ($ERROR_STATE == 1 && $LINE !~ /^gml_/){ | |
$ERROR_STATE = 0; | |
push(@output, "$CI$CB ==================================$CN\n"); | |
$LINE=""; | |
} | |
else{ | |
if ($ERROR_STATE == 2){ | |
$LINE =~ s/\t+//g; | |
$LINE =~ s/(\w+) Event/$CI\1$CN Event/; | |
$LINE =~ s/^for (\w+) ([^:]+)/for \1 $CI\2$CN/; | |
$LINE =~ s/\(line ([0-9]+)/(${CI}line \1$CN/; | |
$LINE =~ s/^(at )?gml_([^_]+)/\1gml_$CI\2$CN/; | |
push(@output, " $LINE"); | |
} | |
elsif ($ERROR_STATE == 1){ | |
$LINE =~ s/\t+//g; | |
$LINE =~ s/\(line ([0-9]+)/(${CI}line \1${CN}/; | |
$LINE =~ s/^gml_([^_]+)/gml_${CI}\1${CN}/; | |
$LINE =~ s/\-(.*)$/-${CC}\1${CN}/; | |
push(@output, " $LINE"); | |
} | |
elsif ($LINE =~ /^Error/){ | |
$LINE =~ s/^Error/${CE}Error${CN}/; | |
$LINE =~ s/\(([^)]+)\)/(${CI}\1${CN})/g; | |
$ERROR_FOUND = 1; | |
push(@output, " $LINE"); | |
} | |
} | |
} | |
print(@output); | |
if ($ERROR_FOUND == 0){ | |
print(" No errors!\n"); | |
} | |
exit; | |
' -- "${HOME}" $(printf $CN) $(printf $CI) $(printf $CE) $(printf $CB) $(printf $CC) | |
} | |
#Usage: FNC_printle | |
FNC_printle_backup(){ | |
ERROR_STATE=0 # Current error checking state | |
ERROR_FOUND=0 # Bool if we found an error | |
STACK_TRACE=() # Stack trace of last error | |
LINE_NUM=1 | |
LINE_COUNT=$(wc -l "${HOME}.gmbuild_log" | grep -o -E "[0-9]+") | |
LAST_STRING="" | |
if [ "$LINE_COUNT" -gt 1000 ]; then | |
printf " Log is $LINE_COUNT lines long and could take a long time. Proceed? [Y/n]: " | |
read INPUT | |
if [ "$INPUT" != "" ] && [ "$INPUT" != "y" ] && [ "$INPUT" != "Y" ]; then | |
return | |
fi | |
fi | |
while read LINE; do | |
# We came across an error: | |
if [ "$ERROR_STATE" -eq 0 ] && [ "$(printf %s "$LINE" | grep -E -o "^ERROR!!! :: ###")" != "" ]; then | |
ERROR_STATE=2 | |
ERROR_FOUND=1 | |
printf " ${CI}${CB}ERROR:\n ==================================\n\n${CN}" | |
continue | |
fi | |
# We came across the end of the error message (but not the stack trace) | |
if [ "$ERROR_STATE" -eq 2 ] && [ "$(printf %s "$LINE" | grep -E -o "^############")" != "" ]; then | |
ERROR_STATE=1 | |
STACK_TRACE=() # Prepare to store new stack trace | |
continue | |
fi | |
# We came across the end of the error. Print the stack trace: | |
if [ "$ERROR_STATE" -eq 1 ] && [ "$(printf %s "$LINE" | grep -E -o "^gml_")" = "" ]; then | |
ERROR_STATE=0 | |
# Only print if we have a stack trace: | |
if [ ${#STACK_TRACE[@]} -gt 0 ]; then | |
printf "\n ${CI}${CB}STACK TRACE:\n${CN}" | |
for (( i=0; i<${#STACK_TRACE[@]}; i++ )); do | |
LINE="${STACK_TRACE[$i]}" | |
LINE="$(printf "$LINE" | sed -r "s/\t+//g")" | |
LINE="$(printf "$LINE" | sed -r "s/\(line ([0-9]+)/(\\${CI}line \1\\${CN}/")" | |
LINE="$(printf "$LINE" | sed -r "s/^gml_([^_]+)/gml_\\${CI}\1\\${CN}/")" # Resource type | |
LINE="$(printf "$LINE" | sed -r "s/\-(.*)$/-\\${CC}\1\\${CN}/")" | |
printf " $LINE\n" | |
done | |
fi | |
printf "${CI}${CB}\n ==================================\n${CN}" | |
LAST_LINE="" | |
continue; | |
fi | |
# Print regular error line: | |
if [ "$ERROR_STATE" -gt 0 ]; then | |
if [ "$ERROR_STATE" -eq 2 ]; then | |
LINE="$(printf "$LINE" | sed -r "s/\t+//g")" # Remove excess tabs | |
LINE="$(printf "$LINE" | sed -r "s/(\w+) Event/\\${CI}\1\\${CN} Event/")" #Name of event | |
LINE="$(printf "$LINE" | sed -r "s/^for (\w+) ([^:]+)/for \1 \\${CI}\2\\${CN}/")" # Name of object | |
LINE="$(printf "$LINE" | sed -r "s/\(line ([0-9]+)/(\\${CI}line \1\\${CN}/")" # Line number | |
LINE="$(printf "$LINE" | sed -r "s/^(at )?gml_([^_]+)/\1gml_\\${CI}\2\\${CN}/")" # Resource type | |
printf " $LINE\n" | |
LAST_LINE="" | |
else | |
STACK_TRACE+=("$LINE") | |
fi | |
else | |
if [ "$(printf %s "$LINE" | grep -E -o "^Error")" != "" ]; then | |
TMP="$(printf "$LINE" | sed -r "s/^Error/\\${CE}Error\\${CN}/")" | |
TMP="$(printf "$TMP" | sed -r "s/\(([^)]+)\)/(\\${CI}\1\\${CN})/g")" | |
printf "\n $TMP\n" | |
LAST_LINE="" | |
ERROR_FOUND=1 | |
else | |
for C in $(seq 0 $(printf "$LAST_LINE" | sed -r "s/(.)/\1\n/g" | grep -c -E ".")); do | |
echo -en "\b" | |
done | |
LAST_LINE=" Line: $LINE_NUM / $LINE_COUNT" | |
printf %s "$LAST_LINE" | |
fi | |
fi | |
LINE_NUM=$((LINE_NUM+1)) | |
# -- STUB -- # Add support for detecting [WARNING] lines, etc | |
done < "${HOME}.gmbuild_log" | |
# Check if we had errors for our final message: | |
if [ "$ERROR_FOUND" -eq 0 ]; then | |
printf "\n No errors!" | |
fi | |
printf "\n" | |
} | |
# Usage: FNC_build | |
FNC_build(){ | |
DISPLAY_WARNING=0 | |
printf "${CE}\n====================\n" | |
printf "TODO: Not implemented yet!\n" | |
printf "====================\n${CN}" | |
FPATH="$PREFIX_GMS/drive_c/users/$USER/Application Data/GameMakerStudio2/" | |
UMPATH="${FPATH}um.json" | |
if [ ! -f "$UMPATH" ]; then | |
printf "Failed to locate user properties file\n" | |
return | |
fi | |
# Select a default runtime if none set: | |
if [ "$RUNTIME_GMS" = "" ]; then | |
RUNTIME_GMS=$(FNC_get_runtime) | |
fi | |
USERID="$(FNC_read_json "$UMPATH" "userID")" | |
UNAME="$(FNC_read_json "$UMPATH" "username")" | |
UNAME="$(printf "$UNAME" | grep -o -E "^[^@]+")" | |
#Z_PROJECT_PATH="$(printf %s "Z:$PROJECT_PATH" | sed -r "s/\//\\\^/g" | sed -r "s/\\^/\\\/g")" | |
#NAME="$(printf "$PROJECT_PATH" | grep -E -o "([^/]+)\.yyp$" | sed -r "s/\.yyp//")" | |
#TEMP="C:\\\\users\\\\$USER\\\\Application Data\\\\GameMakerStudio2\\\\Temp\\\\GMS2TEMP" | |
#UPATH="C:\\\\users\\\\$USER\\\\Application Data\\\\GameMakerStudio2\\\\${UNAME}_${USERID}" | |
#CFG="Default" | |
#OPATH="C:\\\\users\\\\$USER\\\\Application Data\\\\GameMakerStudio2\\\\Temp\\\\GMS2TEMP" | |
#BPATH="C:\\\\ProgramData\\\\GameMakerStudio2\\\\Cache\\\\runtimes\\\\runtime-$RUNTIME_GMS\\\\BaseProject\\\\BaseProject.yyp" | |
Z_PROJECT_PATH="Z:$PROJECT_PATH" | |
# Generate random string for output folder name | |
RANDOM_STRING="" | |
RANDOM_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" | |
for i in {1..16} ; do | |
RANDOM_STRING=$(printf %s "${RANDOM_STRING}${RANDOM_CHARS:RANDOM%${#RANDOM_CHARS}:1}") | |
done | |
# Generate parameter strings: | |
NAME="$(printf "$PROJECT_PATH" | grep -E -o "([^/]+)\.yyp$" | sed -r "s/\.yyp//")" | |
TEMP="C:/users/$USER/Application Data/GameMakerStudio2/Temp/GMS2TEMP/" | |
UPATH="C:/users/$USER/Application Data/GameMakerStudio2/${UNAME}_${USERID}/" | |
CFG="Default" | |
OPATH="${TEMP}${NAME}_$RANDOM_STRING" | |
BPATH="C:/ProgramData/GameMakerStudio2/Cache/runtimes/runtime-$RUNTIME_GMS/BaseProject/BaseProject.yyp" | |
printf "${CI}\n====================\n" | |
printf %s "Project Path: $Z_PROJECT_PATH" | |
printf "\n" | |
printf %s "Project Name: $NAME" | |
printf "\n" | |
printf %s "Temp Path: $TEMP" | |
printf "\n" | |
printf %s "User Path: $UPATH" | |
printf "\n" | |
printf %s "Output Path: $OPATH" | |
printf "\n" | |
printf %s "Base Project Path: $BPATH" | |
printf "\n" | |
printf %s "Config: $CFG" | |
printf "\n====================\n\n${CN}" | |
if [ ! -f "$PROJECT_PATH" ]; then | |
printf "Failed to locate project: '$PROJECT_PATH'\n" | |
return | |
fi | |
DISPLAY_WARNING=1 | |
if [ "$COMPILE_SILENT" -eq 0 ]; then | |
(env WINEPREFIX="$PREFIX_SHELL" wine "$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/Cache/runtimes/runtime-$RUNTIME_GMS/bin/GMAssetCompiler.exe" /c /mv=1 /iv=0 /rv=0 /bv=0 /zpex /j=8 /gn="$NAME" /td="$TEMP" /zpuf="$UPATH" /m=windows /tgt=64 /nodnd /cfg="$CFG" /o="$OPATH" /sh=True /cvm /baseproject="$BPATH" "$Z_PROJECT_PATH" /v /bt=run -v -- Windows Run) | tee "${HOME}.gmbuild_log" | |
else | |
(env WINEPREFIX="$PREFIX_SHELL" wine "$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/Cache/runtimes/runtime-$RUNTIME_GMS/bin/GMAssetCompiler.exe" /c /zpex /j=8 /gn="$NAME" /td="$TEMP" /zpuf="$UPATH" /m=windows /tgt=64 /nodnd /cfg="$CFG" /o="$OPATH" /sh=True /cvm /baseproject="$BPATH" "$Z_PROJECT_PATH" /v /bt=run -v -- Windows Run) | tee "${HOME}.gmbuild_log" &>/dev/null | |
fi | |
} | |
# Usage: FNC_run | |
FNC_run(){ | |
DISPLAY_WARNING=0 | |
if [ ! -d "$PREFIX_GMS" ]; then | |
printf " Invalid WINE prefix\n" | |
return | |
fi | |
if [ ! -d "$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/" ]; then | |
printf " Could not find GameMaker: Studio 2.x installation\n" | |
return | |
fi | |
if [ "$RUNTIME_GMS" = "" ]; then | |
RUNTIME_GMS=$(FNC_get_runtime) | |
fi | |
FNC_create_symlinks # Make sure our prefix links to the right temp directories | |
printf "${CI}\n ====================\n" | |
printf " Running with runtime: $RUNTIME_GMS\n" | |
printf " Running in prefix: $PREFIX_GMS\n" | |
printf " ====================\n\n${CN}" | |
DISPLAY_WARNING=1 | |
if [ "$COMPILE_SILENT" -eq 0 ]; then | |
(env WINEPREFIX="$PREFIX_SHELL" $WINE_DEBUG_STRING wine "$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/Cache/runtimes/runtime-$RUNTIME_GMS/bin/Igor.exe" -j=8 -options="C:\\users\\$USER\\Application Data\\GameMakerStudio2\\Temp/GMS2TEMP\\build.bff" -v -- Windows Run) | tee "${HOME}.gmbuild_log" | |
else | |
(env WINEPREFIX="$PREFIX_SHELL" $WINE_DEBUG_STRING wine "$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/Cache/runtimes/runtime-$RUNTIME_GMS/bin/Igor.exe" -j=8 -options="C:\\users\\$USER\\Application Data\\GameMakerStudio2\\Temp/GMS2TEMP\\build.bff" -v -- Windows Run) | tee "${HOME}.gmbuild_log" &> /dev/null | |
fi | |
} | |
# Usage: FNC_clean | |
FNC_clean(){ | |
FNC_create_symlinks | |
if [ "$RUNTIME_GMS" = "" ]; then | |
RUNTIME_GMS=$(FNC_get_runtime) | |
fi | |
printf "${CI}\n ====================\n" | |
printf " Running with runtime: $RUNTIME_GMS\n" | |
printf " Running in prefix: $PREFIX_GMS\n" | |
printf " ====================\n\n${CN}" | |
(env WINEPREFIX="$PREFIX_SHELL" $WINE_DEBUG_STRING wine "$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/Cache/runtimes/runtime-$RUNTIME_GMS/bin/Igor.exe" -j=8 -options="C:\\users\\$USER\\Application Data\\GameMakerStudio2\\Temp/GMS2TEMP\\build.bff" -v -- Windows Clean) 2> /dev/null | |
printf " Project cleaned...\n" | |
} | |
# Usage: FNC_uninstall | |
FNC_uninstall(){ | |
rm -R "$PREFIX_SHELL/" &> /dev/null | |
rm -R "/home/$USER/.gmbuild" &> /dev/null | |
rm "${HOME}.gmbuild_log" &> /dev/null | |
rm "${HOME}.gmbuild_history" &> /dev/null | |
printf " Files removed\n" | |
} | |
# Usage: FNC_kill_wineserver | |
FNC_kill_wineserver(){ | |
env WINEPREFIX="$PREFIX_SHELL" wineserver -k &> /dev/null | |
} | |
# Usage: FNC_interactive_mode | |
FNC_interactive_mode(){ | |
printf "Entering interactive program, type 'exit' to terminate.\n" | |
printf "Available commands are:\t${CI}exit, help, run, clean, build, kill,\n\t\t\tset, get, list, save, load, printle,\n\t\t\tuninstall${CN}\n" | |
printf "; " | |
FINISHED=0 | |
LAST_COMMAND="" | |
LAST_INPUT="" | |
HISTORY_INDEX=0 | |
while [ "$FINISHED" -eq 0 ]; do | |
FNC_get_input "$LAST_INPUT" | |
PREINPUT="$INPUT" | |
# Handle basic up/down shortcuts: | |
case "$SPECIAL" in | |
"ARRUP") | |
if [ "$(ls "${HOME}" -a | grep ".gmbuild_history" -c)" -eq 0 ]; then | |
LAST_INPUT="" | |
continue | |
fi | |
HISTORY_INDEX=$((HISTORY_INDEX+1)) | |
LINE_COUNT=$(wc -l "${HOME}.gmbuild_history" | sed -r "s/[^0-9]//g") | |
if [ "$HISTORY_INDEX" -gt $((LINE_COUNT)) ]; then | |
HISTORY_INDEX=$((LINE_COUNT)) | |
fi | |
for (( i=0; i < ${#INPUT}; ++i )); do | |
echo -en "\b \b" | |
done | |
LAST_INPUT="$(tac "${HOME}.gmbuild_history" | head -n${HISTORY_INDEX} | tail -n1 2> /dev/null)" | |
printf "$LAST_INPUT" | |
continue | |
;; | |
"ARRDOWN") | |
if [ "$(ls "${HOME}" -a | grep ".gmbuild_history" -c)" -eq 0 ]; then | |
LAST_INPUT="" | |
continue | |
fi | |
HISTORY_INDEX=$((HISTORY_INDEX-1)) | |
if [ "$HISTORY_INDEX" -lt 0 ]; then | |
HISTORY_INDEX=0 | |
fi | |
for (( i=0; i < ${#INPUT}; ++i )); do | |
echo -en "\b \b" | |
done | |
if [ "$HISTORY_INDEX" -eq 0 ]; then | |
LAST_INPUT="" | |
else | |
LAST_INPUT="$(tac "${HOME}.gmbuild_history" | head -n${HISTORY_INDEX} | tail -n1 2> /dev/null)" | |
printf "$LAST_INPUT" | |
fi | |
continue | |
;; | |
"") | |
if [ "$INPUT" != "" ]; then | |
printf "$INPUT\n" >> "${HOME}.gmbuild_history" | |
fi | |
LAST_INPUT="" | |
HISTORY_INDEX=0 | |
printf "\n" | |
;; | |
*) | |
FNC_strlen "$INPUT" | |
for (( i=0; i < $LEN; ++i )); do | |
echo -en "\b \b" | |
done | |
LAST_INPUT="" | |
HISTORY_INDEX=0 | |
continue;; | |
esac | |
SETTO="" # Used if we find an equal sign | |
COMBINED_INPUT="$(printf "${LAST_COMMAND}${INPUT}" | sed "s/\s\s/\s/g")" | |
PREPEND="" | |
if [ "$(printf "$COMBINED_INPUT" | grep -o "=")" = "=" ]; then | |
INPUT="$(printf "$COMBINED_INPUT" | sed -r "s/^([^=]+)=.*$/\1/")" | |
SETTO="$(printf "$COMBINED_INPUT" | sed -r "s/[^=]+=(.*)$/\1/")" | |
SETTO="$(printf "$SETTO" | sed "s/^\s+//")" | |
SETTO="$(printf "$SETTO" | sed "s/\s+$//")" | |
else | |
INPUT="$COMBINED_INPUT" | |
fi | |
INPUT="$(printf "$INPUT" | sed "s/^\s+//")" | |
INPUT="$(printf "$INPUT" | sed "s/\s+$//")" | |
if [ "$INPUT" = "exit" ] || [ "$INPUT" = "quit" ]; then | |
FINISHED=1 | |
continue | |
elif [ "$INPUT" = "kill" ]; then | |
FNC_kill_wineserver | |
printf " Server killed...\n" | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "help" ]; then | |
FNC_display_help | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "list" ]; then | |
FNC_list_runtimes | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "set" ]; then | |
printf " Available set options:\n" | |
printf " \tprefix\n" | |
printf " \truntime\n" | |
PREPEND="set " | |
LAST_COMMAND="set " | |
elif [ "$INPUT" = "set runtime" ]; then | |
RT="" | |
if [ "$SETTO" != "" ]; then | |
RT=$SETTO | |
else | |
printf "; set runtime=" | |
read RT | |
fi | |
if [ ! -d "$PREFIX_GMS/drive_c/ProgramData/GameMakerStudio2/Cache/runtimes/runtime-$RT" ]; then | |
printf " Invalid runtime\n" | |
else | |
RUNTIME_GMS=$RT | |
printf " Set runtime to '$RT'\n" | |
fi | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "set prefix" ]; then | |
FNC_kill_wineserver | |
FNC_delete_symlinks | |
PFX="" | |
if [ "$SETTO" != "" ]; then | |
PFX=$SETTO | |
else | |
printf "; set prefix=" | |
read PFX | |
fi | |
if [ "$PFX" = "$PREFIX_SHELL" ] || [ ! -d "$PFX/drive_c" ]; then | |
printf " Invalid prefix\n" | |
else | |
PREFIX_GMS=$PFX | |
printf " Set prefix to '$PFX'\n" | |
fi | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "printle" ]; then | |
FNC_printle | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "get" ]; then | |
printf " Available get options:\n" | |
printf " \tprefix\n" | |
printf " \truntime\n" | |
PREPEND="get " | |
LAST_COMMAND="get " | |
elif [ "$INPUT" = "get runtime" ]; then | |
RT=$RUNTIME_GMS | |
if [ "$RUNTIME_GMS" = "" ]; then | |
RT=$(FNC_get_runtime) | |
fi | |
if [ "$RT" = "" ]; then | |
printf " No runtimes found!\n\n Please compile with GMS once first and\n make sure you are in the correct prefix.\n" | |
else | |
printf " Current runtime is '$RT'\n" | |
fi | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "get prefix" ]; then | |
printf " Current prefix is '$PREFIX_GMS'\n" | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "run" ]; then | |
FNC_kill_wineserver | |
FNC_run | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "build" ]; then | |
FNC_kill_wineserver | |
FNC_build | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "clean" ]; then | |
FNC_kill_wineserver | |
FNC_clean | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "uninstall" ]; then | |
FNC_kill_wineserver | |
FNC_uninstall | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "load" ]; then | |
printf " This will load and overwrite project settings. Continue? [Y/n]: " | |
read INPUT | |
if [ "$INPUT" != "Y" ] && [ "$INPUT" != "y" ] && [ "$INPUT" != "" ]; then | |
printf " Received negative response\n" | |
else | |
printf "; load project=" | |
read INPUT | |
FNC_load "$INPUT" | |
fi | |
LAST_COMMAND="" | |
elif [ "$INPUT" = "save" ]; then | |
printf " This will save current project settings. Contine? [Y/n]: " | |
read INPUT | |
if [ "$INPUT" != "Y" ] && [ "$INPUT" != "y" ] && [ "$INPUT" != "" ]; then | |
printf " Received negative response\n" | |
else | |
printf "; save project=" | |
read INPUT | |
FNC_save "$INPUT" | |
fi | |
LAST_COMMAND="" | |
elif [ "$PREINPUT" = "" ]; then | |
if [ "$LAST_COMMAND" != "" ]; then | |
printf " $LAST_COMMAND cleared...\n" | |
fi | |
LAST_COMMAND="" | |
else | |
printf " Invalid command\n" | |
LAST_COMMAND="" | |
fi | |
printf "; $PREPEND" | |
done | |
} | |
# Process input arguments: | |
LAST_ARG="" | |
CMD="" | |
for ARG in "$@"; do | |
PROC=1 | |
if [ "$LAST_ARG" = "" ]; then | |
PROC=0 | |
DD="$(printf %s "$ARG" | grep -o -E "^--[a-zA-Z]+=" | grep -o -E "[^=]+")" | |
if [ "$ARG" = "-r" ] || [ "$ARG" = "--runtime" ] || [ "$DD" = "--runtime" ]; then | |
LAST_ARG="-r" | |
if [ "$DD" = "--runtime" ]; then | |
ARG="$(printf %s "$ARG" | grep -o -E "=[^=]+" | grep -o -E "[^=]+")" | |
PROC=1 | |
fi | |
elif [ "$ARG" = "-p" ] || [ "$ARG" = "--prefix" ] || [ "$DD" = "--prefix" ]; then | |
LAST_ARG="-p" | |
if [ "$DD" = "--prefix" ]; then | |
ARG="$(printf %s "$ARG" | grep -o -E "=[^=]+" | grep -o -E "[^=]+")" | |
PROC=1 | |
fi | |
elif [ "$ARG" = "-l" ] || [ "$ARG" = "--load" ] || [ "$DD" = "--load" ]; then | |
LAST_ARG="-l" | |
if [ "$DD" = "--load" ]; then | |
ARG="$(printf %s "$ARG" | grep -o -E "=[^=]+" | grep -o -E "[^=]+")" | |
PROC=1 | |
fi | |
elif [ "$ARG" = "-h" ] || [ "$ARG" = "--help" ]; then | |
FNC_display_help | |
exit 0 | |
elif [ "$ARG" = "-wv" ] || [ "$ARG" = "--wine-verbose" ]; then | |
WINE_DEBUG_STRING="" | |
elif [ "$ARG" = "-s" ] || [ "$ARG" = "--silent" ]; then | |
COMPILE_SILENT=1 | |
elif [ "$CMD" = "" ]; then | |
CMD="$ARG" | |
fi | |
fi | |
if [ "$PROC" -eq 1 ]; then | |
if [ "$LAST_ARG" = "-r" ]; then | |
RUNTIME_GMS=$ARG | |
LAST_ARG="" | |
elif [ "$LAST_ARG" = "-p" ]; then | |
FNC_delete_symlinks | |
if [ "$ARG" = "$PREFIX_SHELL" ] || [ ! -d "$ARG/drive_c" ]; then | |
printf "Invalid prefix\n" | |
continue | |
fi | |
PREFIX_GMS=$ARG | |
LAST_ARG="" | |
elif [ "$LAST_ARG" = "-l" ]; then | |
FNC_load $ARG | |
LAST_ARG="" | |
else | |
FNC_display_help | |
kill 0 | |
fi | |
fi | |
done | |
# Test if our prefix has been set up: | |
if [ ! -d "$PREFIX_SHELL" ]; then | |
FNC_prefix_setup | |
fi | |
FNC_delete_symlinks | |
rm "${HOME}.gmbuild_history" &> /dev/null | |
# Execute stored commands: | |
if [ "$CMD" = "run" ]; then | |
FNC_run | |
if [ "$DISPLAY_WARNING" = "1" ]; then | |
printf "${CI}\n====================\n" | |
printf "You may need to manually kill the server!\n" | |
printf "Type 'gmbuild kill' after you close your build.\n" | |
printf "====================\n\n${CN}" | |
fi | |
elif [ "$CMD" = "build" ]; then | |
FNC_build | |
if [ "$DISPLAY_WARNING" = "1" ]; then | |
printf "${CI}\n====================\n" | |
printf "You may need to manually kill the server!\n" | |
printf "Type 'gmbuild kill' after you close your build.\n" | |
printf "====================\n\n${CN}" | |
fi | |
elif [ "$CMD" = "clean" ]; then | |
rm "${HOME}.gmbuild_log" &> /dev/null # Destroy any old logs | |
FNC_clean | |
elif [ "$CMD" = "kill" ]; then | |
FNC_kill_wineserver | |
printf "Server killed...\n" | |
elif [ "$CMD" = "list" ]; then | |
FNC_list_runtimes | |
elif [ "$CMD" = "uninstall" ]; then | |
FNC_kill_wineserver | |
FNC_uninstall | |
elif [ "$CMD" = "printle" ]; then | |
FNC_printle | |
elif [ "$CMD" = "" ]; then | |
rm "${HOME}.gmbuild_log" &> /dev/null # Destroy any old logs | |
FNC_interactive_mode | |
FNC_kill_wineserver | |
else | |
FNC_display_help | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment