Skip to content

Instantly share code, notes, and snippets.

@igor725
Last active October 21, 2023 15:09
Show Gist options
  • Select an option

  • Save igor725/5cff93614c8286e7d7ff348a70dace91 to your computer and use it in GitHub Desktop.

Select an option

Save igor725/5cff93614c8286e7d7ff348a70dace91 to your computer and use it in GitHub Desktop.
RPCSX emulator runner script
#!/bin/bash
# How to use
# 1. Download the script with one of two ways:
# 1.1 WGET: wget https://gist.githubusercontent.com/igor725/5cff93614c8286e7d7ff348a70dace91/raw/rpcsx.run
# 1.2 CURL: curl https://gist.githubusercontent.com/igor725/5cff93614c8286e7d7ff348a70dace91/raw/rpcsx.run -o rpcsx.run
# 2. Run `chmod +x ./rpcsx.run`
# 3. And then `./rpcsx.run -h`
set -o pipefail;
set -o vi;
function load_enlang () {
LANG_YES_EXTENDED="Yes, I am sure";
LANG_YES_ANS_1="Yes";
LANG_YES_ANS_2="Y";
LANG_NO_ANS_1="No";
LANG_NO_ANS_2="N";
LANG_NO_CONFIG="Erm, .config is missing for some reason and I can't fix it. Please create it in your home directory.";
LANG_NO_SED="No sed??? I can't work in such conditions :(";
LANG_NO_AWK="Oh my god! Where is your awk? I can't run like that...";
LANG_CFG_CORRUPTED="Hold on... Something is not right there. My config file seems corrupted!";
LANG_CFG_ASK="Do you want to meet setup wizard again?";
LANG_USAGE_LINE_1="Usage";
LANG_USAGE_LINE_2="Arguments";
LANG_USAGE_LINE_3="Delete your current config and run setup wizard again";
LANG_USAGE_LINE_4="Print your current configuration";
LANG_USAGE_LINE_5="Set firmware version to use";
LANG_USAGE_LINE_6="Game that you want to run";
LANG_USAGE_LINE_7="Show the entire games list";
LANG_USAGE_LINE_8="Symlink a game to the rpcsx.run's game library";
LANG_USAGE_LINE_9="Example";
LANG_USAGE_LINE_10=" or";
LANG_USAGE_LINE_11="Enable MangoHud";
LANG_USAGE_LINE_12="Limit FPS to 60 (enables MangoHud)";
LANG_USAGE_LINE_13="Enable experimental audio support";
LANG_USAGE_LINE_14="Append an extra argument to the emulator command";
LANG_USAGE_LINE_15="Disable logging entirely (performance tests)";
LANG_USAGE_LINE_16="Update rpcsx.run if needed (requires curl or wget)";
LANG_USAGE_LINE_17="Update RPCSX and recompile it if needed (requires GIT and CMake)";
LANG_USAGE_LINE_18="Show GIT diff before updating the script/recompiling rpcsx";
LANG_USAGE_LINE_19="Experimental rpcsx.run features (not ready to use functionality)";
LANG_USAGE_LINE_20="Perform full game library test";
LANG_USAGE_LINE_21="Buy me a crypto latte:\033[32m https://funding.igvx.ru/ \033[0m";
LANG_CFG_PRINT_LINE_1="Your current settings";
LANG_CFG_PRINT_LINE_2="rpcsx.run version";
LANG_CFG_PRINT_LINE_3="RPCSX path";
LANG_CFG_PRINT_LINE_4="Cache";
LANG_CFG_PRINT_LINE_5="Firmwares";
LANG_CFG_PRINT_LINE_6="Default firmware";
LANG_CFG_PRINT_LINE_7="Games";
LANG_TOELF_CONV="Converting";
LANG_TOELF_NONEED="already elf, why bother.";
LANG_TOELF_EXIST="elf already exists";
LANG_DIFF_ASK="Do you accept these changes?";
LANG_DIFF_STOP="Understood. Aborting updater.";
LANG_UPD_RPCSX_START="Starting the RPCSX updater...";
LANG_UPD_RPCSX_FAIL_STRUC="failed, invalid RPCSX directory structure.";
LANG_UPD_RPCSX_FAIL_GIT="failed, cannot fetch the git repo";
LANG_UPD_RPCSX_OK="updated, compiling now";
LANG_UPD_RPCSX_FAIL_CMP="Compilation failed!";
LANG_UPD_RPCSX_FAIL_MRG="failed, merge conflict";
LANG_UPD_304="up to date";
LANG_UPD_SCRIPT_START="Starting the rpcsx.run updater...";
LANG_UPD_SCRIPT_FAIL_CURL="curl failed! HTTP error, please check ./rpcsx.hdrs";
LANG_UPD_SCRIPT_NO_PRG="I can't see neither curl nor wget :(";
LANG_UPD_SCRIPT_OK="updated!";
LANG_ADDGAME_OK="%G successfully added to your rpcsx.run game library!";
LANG_ADDGAME_EXIST="This game is already in your library";
LANG_ADDGAME_INVALID="Not a ps4 game directory";
LANG_WARN_NO_MANGOHUD="I can't see MangoHud here. Am I blind?! Please install it first.";
LANG_WARN_NO_DIFF="I can't find any diff tool on your pc, sorry.";
LANG_CASECH_LINE_1="Warning!! The specified folder is on the partition with a case-sensitive filesytem!";
LANG_CASECH_LINE_2="The PS4 has a case-insensitive filesystem, so the emulator won't work correctly on this partition.";
LANG_CASECH_LINE_3="If you know exactly what you doing then ignore this message.";
LANG_CASECH_LINE_4="This message will be disabled until the next rpcsx.run reconfig operation.";
LANG_CASECH_FAIL="Warning!! Failed to check the filesystem case sensetivity.";
LANG_CFGW_WELC_LINE_1="Welcome to rpcsx.run configuration wizard!";
LANG_CFGW_WELC_LINE_2="Let's configure your emulator, shall we?";
LANG_CFGW_WELC_LINE_3="Press [Enter] to start the configuration process.";
LANG_CFGW_RPCSX_DIR="Your RPCSX directory";
LANG_CFGW_RPCSX_CACHE="Your RPCSX cache path";
LANG_CFGW_RPCSX_GAMES="Your games directory";
LANG_CFGW_FIRM_NOTE_LINE_1="Okay, now listen carefully!";
LANG_CFGW_FIRM_NOTE_LINE_2="The next step is the path to your firmwares.";
LANG_CFGW_FIRM_NOTE_LINE_3="The directory structure should look like this: <some path>/systems/<firmware version>/{common, priv, sys, vsh}";
LANG_CFGW_FIRM_NOTE_LINE_4="E.g. /home/igor725/rpcsx/firmwares/5.05 and in this folder there are common, priv, etc.";
LANG_CFGW_FIRM_NOTE_LINE_5="Press [Enter] to proceed";
LANG_CFGW_RPCSX_FIRMWARES="Your firmwares directory";
LANG_CFGW_RPCSX_DFIRMWARE="Default firmware version to boot";
LANG_CFGW_CONF_NOTE_LINE_1="Do you confirm that all data you entered is correct?";
LANG_CFGW_CONF_NOTE_LINE_2="Warning!! If some paths entered incorrectly, it may lead to DATA LOSS!!";
LANG_CFGW_CONF_NOTE_LINE_3="All paths and values you provided will be written to %CF";
LANG_CFGW_CONF_NOTE_LINE_4="If you entirely sure type: \"%IAMSURE\"";
LANG_CFGW_CONF_NOTE_LINE_5="Press Ctrl+C or type \"$LANG_NO_ANS_1\" if not.";
LANG_CFGW_SAVING="Very fine. Saving the data...";
LANG_CFGW_OK="ok! Exiting now...";
LANG_CFGW_NOSAVE="Understood, I won't save anything";
LANG_CFGW_IOFAIL="failed, do I have permission to write the config file?";
LANG_CFGW_NOINPUT="You need to type something, no more autoanswers, sorry.";
LANG_CFGW_WTF="I'm expecting Yes or No from you, not the \"%SHET\" thing.";
LANG_ECFGW_RPCSXDIR="RPCSX directory";
LANG_ECFGW_RPCSXCACHE="RPCSX cache directory";
LANG_ECFGW_RPCSXGAMES="RPCSX games directory";
LANG_ECFGW_RPCSXFIRMW="PS4 firmwares directory";
LANG_ECFGW_RPCSXDFIRM="Default firmware";
LANG_ECFGW_SAVEANDEXIT="Save and exit";
LANG_ECFGW_JUSTEXIT="Exit (Q or Ctrl + C)";
LANG_ECFGW_ZENSCR="Please select path in the zenity window";
LANG_ECFGW_NOFWFI_TEXT="Selected directory does not contains \"%FI\" file";
LANG_ECFGW_NOFWDIR="Firmwares directory need to be set first";
LANG_ECFGW_INVFWDIR="Firmware folder must be inside the \"%FP\" folder";
LANG_ECFGW_FIELDS="All red-marked fields must be filled!";
LANG_ECFGW_NOSAVE="Are you sure you want to close the setup wizard without saving?";
LANG_ECFGW_NOZENITY="Warning!! No zenity found, falling back to default wizard";
LANG_GAMELIB_MSG="Here is what I found";
LANG_GAMELIB_QUIT="Quit the script";
LANG_GAMELIB_INV="You must enter the number between 1 and %MN!";
LANG_GAMELIB_NOTFOUND="There is no such game or your library is empty.";
LANG_GAMELIB_NOEBOOT="No eboot.bin/eboot.elf found in the game directory!";
LANG_GAMELIB_ENJOY="Enjoy!";
LANG_EMU_CRASH_LINE_1="Oh no! Looks like your emulator crashed :(";
LANG_EMU_CRASH_LINE_2_1="I'd be happy to save a log for you, but you told me not to...";
LANG_EMU_CRASH_LINE_2_2="You might want send a log to the devs so I saved it for you!";
LANG_EMU_CRASH_LINE_3_2="It can be accessed here: %LF";
}
function load_rulang () {
LANG_YES_EXTENDED="Да, я уверен";
LANG_YES_ANS_1="Да";
LANG_YES_ANS_2="Д";
LANG_NO_ANS_1="Нет";
LANG_NO_ANS_2="Н";
LANG_NO_CONFIG="Эм, папка .config по какой-то причине не существует и мне не удалось это исправить. Пожалуйста, создай её в своей домашней директории.";
LANG_NO_SED="Нет sed?? Я не могу работать в таких условиях :(";
LANG_NO_AWK="О боги! Куда ты дел свой awk? Я так точно не заработаю...";
LANG_CFG_CORRUPTED="Подожди-ка, что то тут не так... Ага! Мой файл конфигурации поврежден!";
LANG_CFG_ASK="Хочешь ли ты встретиться с мастером настройки снова?";
LANG_USAGE_LINE_1="Использование";
LANG_USAGE_LINE_2="Аргументы";
LANG_USAGE_LINE_3="Удалить текущую конфигурацию и запустить процесс настройки заново";
LANG_USAGE_LINE_4="Показать текущую конфигурацию";
LANG_USAGE_LINE_5="Задать версию прошивки для запуска";
LANG_USAGE_LINE_6="Полное или часть названия игры, которую нужно запустить";
LANG_USAGE_LINE_7="Показать весь список игр";
LANG_USAGE_LINE_8="Создать ссылку до папки игры в библиотеке rpcsx.run";
LANG_USAGE_LINE_9="Пример";
LANG_USAGE_LINE_10=" или";
LANG_USAGE_LINE_11="Включить оверлей MangoHud";
LANG_USAGE_LINE_12="Ограничить FPS до 60 (включает MangoHud)";
LANG_USAGE_LINE_13="Включить экспериментальную поддержку звука";
LANG_USAGE_LINE_14="Передать дополнительный аргумент эмулятору";
LANG_USAGE_LINE_15="Полностью отключить логирование (тест производительности)";
LANG_USAGE_LINE_16="Проверить обновления скрипта rpcsx.run (нужен curl, либо wget)";
LANG_USAGE_LINE_17="Проверить обновления RPCSX и перекомпилировать, если нужно (нужен GIT и CMake)";
LANG_USAGE_LINE_18="Показать разницу в коде перед установкой обновления скрипта или эмулятора";
LANG_USAGE_LINE_19="Эксперементальные (не готовые к использованию) функции rpcsx.run";
LANG_USAGE_LINE_20="Выполнить полный тест игровой библиотеки";
LANG_USAGE_LINE_21="Купить мне крипто-латте на биткоиновом молоке:\033[32m https://funding.igvx.ru/ \033[0m";
LANG_CFG_PRINT_LINE_1="Текущие настройки скрипта";
LANG_CFG_PRINT_LINE_2="Версия rpcsx.run";
LANG_CFG_PRINT_LINE_3="Путь до RPCSX";
LANG_CFG_PRINT_LINE_4="Кэш";
LANG_CFG_PRINT_LINE_5="Прошивки";
LANG_CFG_PRINT_LINE_6="Прошивка по-умолчанию";
LANG_CFG_PRINT_LINE_7="Игры";
LANG_TOELF_CONV="Конвертация";
LANG_TOELF_NONEED="уже elf, пропускаем";
LANG_TOELF_EXIST="elf существует";
LANG_DIFF_ASK="Принять эти изменения?";
LANG_DIFF_STOP="Понял. Отменяю обновление.";
LANG_UPD_RPCSX_START="Проверяю обновления для RPCSX...";
LANG_UPD_RPCSX_FAIL_STRUC="ошибка, неизвестная структура директории RPCSX";
LANG_UPD_RPCSX_FAIL_GIT="ошибка, не удалось получить информацию о репозитории";
LANG_UPD_RPCSX_OK="обновлено, запускаю компиляцию";
LANG_UPD_RPCSX_FAIL_CMP="Неудачная компиляция";
LANG_UPD_RPCSX_FAIL_MRG="ошибка, конфликт слияния";
LANG_UPD_304="обновлений нет";
LANG_UPD_SCRIPT_START="Проверяю обновления для rpcsx.run...";
LANG_UPD_SCRIPT_FAIL_CURL="ошибка curl! Информация об ошибке записана в ./rpcsx.hdrs";
LANG_UPD_SCRIPT_NO_PRG="Не вижу у тебя в системе ни curl, ни wget :(";
LANG_UPD_SCRIPT_OK="обновлено!";
LANG_ADDGAME_OK="%G успешно добавлена в вашу библиотеку rpcsx.run!";
LANG_ADDGAME_EXIST="Эта игра уже в твоей библиотеке";
LANG_ADDGAME_INVALID="Указанная директория не является папкой игры PS4";
LANG_WARN_NO_MANGOHUD="Не вижу MangoHud. Я ослеп? Сомневаюсь. Значит его нужно установить.";
LANG_WARN_NO_DIFF="Я не нашёл никаких инструментов для сравнения файлов";
LANG_CFGW_WELC_LINE_1="Добро пожаловать в мастер настройки rpcsx.run!";
LANG_CFGW_WELC_LINE_2="Давай-ка настроим всё как надо?";
LANG_CFGW_WELC_LINE_3="Нажми [Enter] чтобы начать процесс настройки.";
LANG_CFGW_RPCSX_DIR="Ваша папка с RPCSX";
LANG_CFGW_RPCSX_CACHE="Папка для кеша RPCSX";
LANG_CFGW_RPCSX_GAMES="Папка с играми";
LANG_CFGW_FIRM_NOTE_LINE_1="Так, теперь слушай внимательно!";
LANG_CFGW_FIRM_NOTE_LINE_2="Следующим шагом нужно указать путь до папки с прошивками.";
LANG_CFGW_FIRM_NOTE_LINE_3="Структура директории с прошивками должна выглядеть так: <какой-нибудь путь>/firmwares/<версия прошивки>/{common, priv, sys, vsh}";
LANG_CFGW_FIRM_NOTE_LINE_4="Н.р. /home/igor725/rpcsx/firmwares/5.05 и в этой папке лежат common, priv, и т.д.";
LANG_CFGW_FIRM_NOTE_LINE_5="Нажми [Enter] чтобы продолжить";
LANG_CFGW_RPCSX_FIRMWARES="Путь до папки с прошивками";
LANG_CFGW_RPCSX_DFIRMWARE="Прошивка по-умолчанию";
LANG_CFGW_CONF_NOTE_LINE_1="Подтверждаешь ли ты, что все введенные данные верны?";
LANG_CFGW_CONF_NOTE_LINE_2="Внимание!! Если некоторые пути введены некорректно, то это может привести к ПОТЕРЕ ДАННЫХ!!";
LANG_CFGW_CONF_NOTE_LINE_3="Все заданные пути будут записаны в файл %CF";
LANG_CFGW_CONF_NOTE_LINE_4="Если ты полностью уверен в себе, напиши: \"%IAMSURE\"";
LANG_CFGW_CONF_NOTE_LINE_5="Нажми Ctrl+C или введи \"$LANG_NO_ANS_1\" если нет.";
LANG_CFGW_SAVING="Отлично. Сохраняю данные...";
LANG_CFGW_OK="всё ок, завершаю работу...";
LANG_CFGW_NOSAVE="Понятно, я не буду ничего сохранять";
LANG_CFGW_IOFAIL="ошибка записи, предположительно отсутствуют права на файл.";
LANG_CFGW_NOINPUT="Тебе нужно что-то ввести ручками, автоответов больше не осталось, увы.";
LANG_CFGW_WTF="Я вообще-то ожидал что-то типа Да/Нет, но никак не \"%SHET\"...";
LANG_ECFGW_RPCSXDIR="Папка RPCSX";
LANG_ECFGW_RPCSXCACHE="Папка для кеша RPCSX";
LANG_ECFGW_RPCSXGAMES="Папка с PS4 играми";
LANG_ECFGW_RPCSXFIRMW="Папка прошивок PS4";
LANG_ECFGW_RPCSXDFIRM="Стандартная прошивка";
LANG_ECFGW_SAVEANDEXIT="Сохранить и выйти";
LANG_ECFGW_JUSTEXIT="Выйти (Q или Ctrl + C)";
LANG_ECFGW_ZENSCR="Чтобы продолжить выбери папку в открывшемся окне";
LANG_ECFGW_NOFWFI_TEXT="Выбранная папка не содержит файл \"%FI\"";
LANG_ECFGW_NOFWDIR="Сначала нужно выбрать папку с прошивками";
LANG_ECFGW_INVFWDIR="Папка прошивки должна находиться внутри папки \"%FP\"";
LANG_ECFGW_FIELDS="Все помеченные красным поля должны быть заполнены!";
LANG_ECFGW_NOSAVE="Ты уверен, что хочешь выйти без сохранения?";
LANG_ECFGW_NOZENITY="Не удалось отыскать в системе zenity, переключаюсь на старого мастера настройки";
LANG_GAMELIB_MSG="Вот что я нашёл";
LANG_GAMELIB_QUIT="Завершить скрипт";
LANG_GAMELIB_INV="Необходимо ввести число от 1 до %MN!";
LANG_GAMELIB_NOTFOUND="Указанная игра не найдена в библиотеке";
LANG_GAMELIB_NOEBOOT="Файл eboot.bin/eboot.elf не найден в папке игры!";
LANG_GAMELIB_ENJOY="Приятной игры!";
LANG_EMU_CRASH_LINE_1="О нет! Похоже эмулятор крашнулся :(";
LANG_EMU_CRASH_LINE_2_1="Я был бы рад создать для тебя краш лог, но ты мне сказал этого не делать...";
LANG_EMU_CRASH_LINE_2_2="Возможно ты захочешь отправить лог разработчикам, так что я сохранил его для тебя!";
LANG_EMU_CRASH_LINE_3_2="Находится он здесь: %LF";
}
case "$LANG" in
ru_RU.UTF-8) load_rulang;;
*) load_enlang;;
esac
WHO=`whoami`;
NOLOG=0;
ARGS="$@";
CASE_WARNED=0;
EXPERIMENTAL=0;
RPCSX_RUN_ETAG="none";
RPCSX_RUN_UPDATE=0;
RPCSX_RUN_LIBTEST=0;
RPCSX_ADDOPTS="";
RPCSX_UPDATE=0;
ENABLE_DIFF=0;
MANGOHUD_ON=0;
MANGOHUD_LIMIT60=0;
CFG_FILE="/home/$WHO/.config/rpcsx.run-conf";
if ! mkdir -p `dirname $CFG_FILE`; then
echo "$LANG_NO_CONFIG";
close_script 1;
fi
if ! which sed 2>&1 >/dev/null; then
echo "$LANG_NO_SED";
close_script 1;
fi
if ! which awk 2>&1 >/dev/null; then
echo "$LANG_NO_AWK";
close_script 1;
fi
function close_script () {
# TODO Do something may be
exit $1;
}
function restart_script () {
exec "$0" $ARGS;
close_script $?;
}
function cnt_lines () {
printf `wc -l "$1" | awk '{print $1}'`;
}
function config_corrupted () {
echo "$LANG_CFG_CORRUPTED";
read -e -p "$LANG_CFG_ASK [$LANG_YES_ANS_2]/$LANG_NO_ANS_2: " ANS;
if [ "$ANS" == "" ] || [ "${ANS,,}" == "${LANG_YES_ANS_1,,}" ] || [ "${ANS,,}" == "${LANG_YES_ANS_2,,}" ]; then
config_empty;
exec "$0";
close_script $?;
else
echo "Goodbye then.";
fi
close_script 1;
}
function config_save () {
if touch "$CFG_FILE"; then
> "$CFG_FILE";
echo "RPCSX_DIR=\"$RPCSX_DIR\"" >> "$CFG_FILE";
echo "RPCSX_CACHE=\"$RPCSX_CACHE\"" >> "$CFG_FILE";
echo "RPCSX_FIRMWARES=\"$RPCSX_FIRMWARES\"" >> "$CFG_FILE";
echo "RPCSX_DFIRMWARE=\"$RPCSX_DFIRMWARE\"" >> "$CFG_FILE";
echo "RPCSX_GAMES=\"$RPCSX_GAMES\"" >> "$CFG_FILE";
echo "RPCSX_RUN_ETAG=\"$RPCSX_RUN_ETAG\"" >> "$CFG_FILE";
return 0;
fi
return 1;
}
function config_empty () {
mv "$CFG_FILE" "$CFG_FILE.old";
}
if [ -f "$CFG_FILE" ]; then
. "$CFG_FILE";
if [ ! -d "$RPCSX_DIR" ]; then config_corrupted; fi
if [ ! -d "$RPCSX_FIRMWARES" ]; then config_corrupted; fi
if [ ! -d "$RPCSX_GAMES" ]; then config_corrupted; fi
fi
function print_usage () {
echo "rpcsx.run script by igor725";
echo "$LANG_USAGE_LINE_1:";
echo -e "\t$0 -f5.05 -gCUSA01337";
echo -e "\n$LANG_USAGE_LINE_2:";
echo -e "\t-r - $LANG_USAGE_LINE_3";
echo -e "\t-p - $LANG_USAGE_LINE_4";
echo -e "\t-f - $LANG_USAGE_LINE_5";
echo -e "\t-g - $LANG_USAGE_LINE_6";
echo -e "\t-g.a - $LANG_USAGE_LINE_7";
echo -e "\t-G - $LANG_USAGE_LINE_8";
echo -e "\t\t $LANG_USAGE_LINE_9: -G/mnt/me/MyGames/Sonic\\ Mania";
echo -e "\t\t $LANG_USAGE_LINE_10: -G/mnt/me/MyGames/Sonic\\ Mania:Sanic";
echo -e "\t-m - $LANG_USAGE_LINE_11";
echo -e "\t-v - $LANG_USAGE_LINE_12";
echo -e "\t-a - $LANG_USAGE_LINE_13";
echo -e "\t-A - $LANG_USAGE_LINE_14";
echo -e "\t-l - $LANG_USAGE_LINE_15";
echo -e "\t-u - $LANG_USAGE_LINE_16";
echo -e "\t-U - $LANG_USAGE_LINE_17";
echo -e "\t-d - $LANG_USAGE_LINE_18";
echo -e "\t-e - $LANG_USAGE_LINE_19";
echo -e "\t-t - $LANG_USAGE_LINE_20";
echo -e "\n$LANG_USAGE_LINE_21";
close_script 0;
}
function fetch_updates () {
if git --version &> /dev/null; then
local upstream=`git rev-parse --abbrev-ref --symbolic-full-name @{u} 2> /dev/null`;
if [ $? -ne 0 ]; then return; fi
local info=`git rev-list --left-right --count "$upstream"...@ 2> /dev/null`;
local behind=`echo $info | awk -F'[^0-9]+' '{ print $1 }'`;
if [ $? -eq 0 ]; then
echo -ne "Your rpcsx is $(echo $info | awk -F'[^0-9]+' '{ print $2 }') commits ahead, $behind commits behind $upstream";
if [ $behind -gt 0 ]; then
echo ", upgrade possible!";
else
echo "";
fi
fi
fi
}
function print_cfg () {
echo "$LANG_CFG_PRINT_LINE_1: ";
echo -e "\t$LANG_CFG_PRINT_LINE_7: ${RPCSX_RUN_ETAG:0:8}";
echo -e "\t$LANG_CFG_PRINT_LINE_2: $RPCSX_DIR";
echo -e "\t$LANG_CFG_PRINT_LINE_3: $RPCSX_CACHE";
echo -e "\t$LANG_CFG_PRINT_LINE_4: $RPCSX_FIRMWARES";
echo -e "\t$LANG_CFG_PRINT_LINE_5: $RPCSX_DFIRMWARE";
echo -e "\t$LANG_CFG_PRINT_LINE_6: $RPCSX_GAMES";
pushd "$RPCSX_DIR" &> /dev/null;
fetch_updates;
popd &> /dev/null;
if [ "$ARGS" == "-p" ]; then
close_script 0;
fi
}
function test_file () {
if [ -f "$1" ]; then
return 1;
else
return 0;
fi
}
function accept_question () {
while true; do
read -e -p "$LANG_DIFF_ASK $LANG_YES_ANS_2/[$LANG_NO_ANS_2]: " ACCEPT_CH;
if [ "${ACCEPT_CH,,}" == "${LANG_NO_ANS_1,,}" ] || [ "$ACCEPT_CH" == "${LANG_NO_ANS_2,,}" ] || [ "$ACCEPT_CH" == "" ]; then
echo "$LANG_DIFF_STOP";
return 1;
elif [ "${ACCEPT_CH,,}" == "${LANG_YES_ANS_1,,}" ] || [ "${ACCEPT_CH,,}" == "${LANG_YES_ANS_2,,}" ]; then
return 0;
fi
done
}
function check_for_emu_update () {
echo -n "$LANG_UPD_RPCSX_START";
if [ ! -f "$RPCSX_DIR/../../CMakeLists.txt" ]; then
echo "$LANG_UPD_RPCSX_FAIL_STRUC";
return;
fi
pushd "$RPCSX_DIR/../" > /dev/null; # Go to build directory
if ! git fetch --all &> /dev/null; then
echo "$LANG_UPD_RPCSX_FAIL_GIT";
popd > /dev/null;
return;
fi
local git_branch=`git rev-parse --abbrev-ref --symbolic-full-name @{u}`;
if [ $(git rev-list HEAD..$git_branch --count) -eq 0 ]; then
echo "$LANG_UPD_304";
popd > /dev/null;
return;
fi
if [ $ENABLE_DIFF -eq 1 ]; then
git diff HEAD..$git_branch;
accept_question;
fi
if git merge --ff-only &> /dev/null; then
echo "$LANG_UPD_RPCSX_OK";
if ! cmake .. || ! cmake --build . -j$(nproc); then
echo "$LANG_UPD_RPCSX_FAIL_CMP";
return;
fi
popd > /dev/null;
return;
fi
echo "$LANG_UPD_RPCSX_FAIL_MRG";
popd > /dev/null;
}
URL="https://gist.githubusercontent.com/igor725/5cff93614c8286e7d7ff348a70dace91/raw/rpcsx.run";
RPCSX_RUN_UPDATED=0;
function process_headers () {
RPCSX_RUN_ETAG=`sed -e '/\s*etag/I!d' -e 's/^\s*etag: //I' -e 's/"//Ig' ./rpcsx.hdrs | tr -d '\r'`;
if [ $RPCSX_RUN_ETAG == "" ]; then
RPCSX_RUN_ETAG="none";
fi
if grep -E 'HTTP/.*\s*200' ./rpcsx.hdrs &> /dev/null; then
RPCSX_RUN_UPDATED=1;
elif grep -E 'HTTP/.*\s*304' ./rpcsx.hdrs &> /dev/null; then
RPCSX_RUN_UPDATED=0;
else
echo "http error";
return 0;
fi
rm ./rpcsx.hdrs;
}
function process_data () {
if [ $ENABLE_DIFF -eq 1 ] && [ $RPCSX_RUN_UPDATED -eq 1 ]; then
diff --color $0 ./rpcsx.tmp | less -r;
accept_question;
fi
}
function check_for_update () {
echo -n "$LANG_UPD_SCRIPT_START";
HEADER="If-None-Match: \"$RPCSX_RUN_ETAG\"";
if curl --version &> /dev/null; then
if ! curl -D ./rpcsx.hdrs $URL -v --header "$HEADER" -o ./rpcsx.tmp 2> /dev/null; then
echo "$LANG_UPD_SCRIPT_FAIL_CURL";
close_script 1;
fi
elif wget --version &> /dev/null; then
# This fucker errors even on HTTP/304
wget -S $URL -o ./rpcsx.hdrs --header="$HEADER" -O ./rpcsx.tmp;
else
echo "$LANG_UPD_SCRIPT_NO_PRG";
close_script 1;
fi
process_headers;
process_data;
if [ $RPCSX_RUN_UPDATED -eq 1 ]; then
mv ./rpcsx.tmp $0;
chmod +x $0;
config_save;
echo "$LANG_UPD_SCRIPT_OK";
restart_script;
else
echo "$LANG_UPD_304";
fi
close_script 0;
}
function add_game () {
local gfolder="";
local gdname="";
if [[ "$1" == *":"* ]]; then
gfolder=`echo "$1" | cut -d ':' -f 1`;
gdname=`echo "$1" | cut -d ':' -f 2`;
else
gfolder="$1";
gdname=`basename "$1"`;
fi
gfolder=`readlink -f "$gfolder"`;
if [ -f "$gfolder/eboot.bin" ] || [ -f "$gfolder/eboot.elf" ]; then
if [ -L "$RPCSX_GAMES/$gdname" ]; then
echo "$LANG_ADDGAME_EXIST";
close_script 1;
fi
echo "${LANG_ADDGAME_OK/'%G'/$gdname}";
ln -s "$gfolder" "$RPCSX_GAMES/$gdname";
close_script 0;
fi
echo "$LANG_ADDGAME_INVALID";
close_script 1;
}
function check_case () {
if [ $CASE_WARNED -eq 1 ]; then
return 0;
fi
local fn="$1/rpcsx.rUn-cAse";
local res=0;
if touch "$fn"; then
if ! stat "$1/rpcsx.run-case" &> /dev/null; then
echo -e "\n$LANG_CASECH_LINE_1";
echo "$LANG_CASECH_LINE_2";
res=1;
fi
rm "$fn";
else
echo -e "\n$LANG_CASECH_FAIL";
res=1;
fi
if [ $res -eq 1 ]; then
echo "$LANG_CASECH_LINE_3";
echo "$LANG_CASECH_LINE_4";
fi
CASE_WARNED=1;
}
while getopts hametIlvUudrpf:g:A:G: flag
do
case "${flag}" in
h) print_usage;;
r) config_empty;;
m) MANGOHUD_ON=1;;
u) RPCSX_RUN_UPDATE=1;;
U) RPCSX_UPDATE=1;;
d) ENABLE_DIFF=1;;
a) RPCSX_ADDOPTS+=" -a";;
e) EXPERIMENTAL=1;;
A) RPCSX_ADDOPTS+=" ${OPTARG}";;
l) NOLOG=1;;
t) RPCSX_RUN_LIBTEST=1;;
p) print_cfg;;
v) MANGOHUD_LIMIT60=1;;
f) DESIRED_FIRMWARE=${OPTARG};;
g) DESIRED_GAME=${OPTARG};;
G) add_game "${OPTARG}";;
esac
done
if [ $MANGOHUD_ON -eq 1 ] || [ $MANGOHUD_LIMIT60 -eq 1 ]; then
if ! which mangohud &> /dev/null; then
echo "$LANG_WARN_NO_MANGOHUD";
MANGOHUD_ON=0;
fi
if [ $MANGOHUD_LIMIT60 -eq 1 ]; then
export MANGOHUD_CONFIG="fps_limit=60";
MANGOHUD_ON=1;
else
export MANGOHUD_CONFIG="";
fi
fi
if [ $ENABLE_DIFF -eq 1 ]; then
if ! which diff &> /dev/null; then
echo "$LANG_WARN_NO_DIFF";
close_script 1;
fi
fi
function experimental_wizard () {
if ! zenity --version &> /dev/null; then
return 1;
fi
local width=$(tput cols);
local height=$(tput lines);
local sw_center=$(($width / 2));
local sh_center=$(($height / 2));
local lines=();
local paths=( );
lines[0]="$LANG_ECFGW_RPCSXDIR";
lines[1]="$LANG_ECFGW_RPCSXCACHE";
lines[2]="$LANG_ECFGW_RPCSXGAMES";
lines[3]="$LANG_ECFGW_RPCSXFIRMW";
lines[4]="$LANG_ECFGW_RPCSXDFIRM";
lines[5]="$LANG_ECFGW_SAVEANDEXIT";
lines[6]="$LANG_ECFGW_JUSTEXIT";
local about_mini="RPCSX.run by igor725";
local required_set=(0 -1 -1 -1 0 -1 -1);
local lines_cnt=${#lines[@]};
local lines_center=$(($lines_cnt / 2));
local lines_start=$(($sh_center - $lines_center));
local line_selected=0;
enable_cursor () { echo -en "\033[?25h"; }
disable_cursor () { echo -en "\033[?25l"; }
cursor_to () { echo -en "\033[$2;${1:-1}H"; }
clear_screen () { echo -en "\033[2J"; }
cursor_right () { echo -en "\033[${1:-1}C"; }
read_input () {
local key;
IFS= read -rsn1 key 2>/dev/null >&2;
if [[ $key = "" ]]; then echo enter; fi
if [[ $key = "q" ]]; then echo exit; fi
if [[ $key = $'\x1b' ]]; then
read -rsn2 key;
if [[ $key = "[A" ]]; then echo up; fi
if [[ $key = "[B" ]]; then echo down; fi
fi
}
local maxline=0;
local drawlines=( );
redraw_menu () {
clear_screen;
cursor_to $(($width - ${#about_mini} + 1)) 0;
echo -n $about_mini;
for ((i = 0; i < $lines_cnt; i++)); do
local dline="${lines[$i]}${paths[$i]}";
drawlines[$i]=$dline;
local linew=${#dline};
if [ $linew -gt $maxline ]; then
maxline=$linew;
fi
done
for ((i = 0; i < $lines_cnt; i++)); do
cursor_to $(($sw_center - $maxline / 2)) $(($lines_start + $i));
case ${required_set[$i]} in
0) echo -en "\033[31m";;
1) echo -en "\033[32m";;
*) echo -en "\033[0m";;
esac
echo "${drawlines[$i]}";
done
}
update_selection () {
if [ $line_selected -lt 0 ]; then line_selected=$(($lines_cnt - 1)); fi
if [ $line_selected -ge $lines_cnt ]; then line_selected=0; fi
for ((i = 0; i < $lines_cnt; i++)); do
cursor_to $(($sw_center - $maxline / 2 - 4)) $(($lines_start + $i));
if [ $i -eq $line_selected ]; then
echo -n ">>$(cursor_right $(($maxline + 4)))<<";
else
echo -n " $(cursor_right $(($maxline + 4))) ";
fi
done
}
zenity_screen () {
cursor_to $(($sw_center - ${#LANG_ECFGW_ZENSCR} / 2)) $sh_center;
echo -en "\033[2J$LANG_ECFGW_ZENSCR";
}
pick_dir () {
local start="$1";
if [ "$start" = "" ]; then
start=$(pwd);
fi
while true; do
local ret=0;
local path=$(zenity --file-selection --directory --filename="$start/");
if [[ "$path" != "" ]]; then
if [ "$3" != "" ] && [ -f "$path/$3/$2" ]; then
path="$path/$3";
fi
if compgen -G "$path/$2" > /dev/null; then
echo -n "$path";
return 0;
elif [ "$2" != "" ]; then
zenity --error --title "" --text "${LANG_ECFGW_NOFWFI_TEXT/'%FI'/$2}";
fi
else
break;
fi
done
return 1;
}
update_optional_directories () {
if [ "$RPCSX_DIR" != "" ]; then
if [ "$RPCSX_CACHE" = "" ]; then RPCSX_CACHE="$RPCSX_DIR/cache"; required_set[1]=1; fi
if [ "$RPCSX_GAMES" = "" ]; then RPCSX_GAMES="$RPCSX_DIR/games"; required_set[2]=1; fi
if [ "$RPCSX_FIRMWARES" = "" ]; then RPCSX_FIRMWARES="$RPCSX_DIR/firmwares"; required_set[3]=1; fi
fi
redraw_menu;
return 0;
}
set_rpcsx_dir () {
zenity_screen;
RPCSX_DIR=$(pick_dir "" "rpcsx-os" "build/bin");
if [ "$RPCSX_DIR" != "" ]; then required_set[0]=1; fi
redraw_menu;
}
set_cache_dir () {
RPCSX_CACHE=$(pick_dir "$RPCSX_DIR");
}
set_games_dir () {
zenity_screen;
RPCSX_DIR=$(pick_dir "$RPCSX_DIR");
redraw_menu;
}
set_firms_dir () {
zenity_screen;
RPCSX_FIRMWARES=$(pick_dir "$RPCSX_DIR" "*/common/lib/libc.sprx");
if [ "$RPCSX_FIRMWARES" != "" ]; then required_set[3]=1; fi
redraw_menu;
}
set_deflt_fir () {
update_optional_directories;
if [ "$RPCSX_FIRMWARES" = "" ]; then
zenity_screen;
zenity --error --title "" --text "$LANG_ECFGW_NOFWDIR";
else
zenity_screen;
local dpath=$(pick_dir "$RPCSX_FIRMWARES" "common/lib/libc.sprx");
if [[ $(dirname "$dpath") -ef "$RPCSX_FIRMWARES" ]]; then
RPCSX_DFIRMWARE=$(basename "$dpath");
required_set[4]=1;
else
zenity --error --title "" --text "${LANG_ECFGW_INVFWDIR/'%FP'/$RPCSX_FIRMWARES}";
fi
fi
redraw_menu;
}
all_cfg_set () {
update_optional_directories;
for ((i = 0; i < $lines_cnt; i++)); do
if [ ${required_set[$i]} -eq 0 ]; then
return 1;
fi
done
return 0;
}
save_and_exit () {
if all_cfg_set; then
config_save;
menu_exit;
else
zenity_screen;
zenity --error --title "" --text "$LANG_ECFGW_FIELDS";
redraw_menu;
fi
}
exit_confirmw () {
if zenity --question --title "" --text "$LANG_ECFGW_NOSAVE"; then
menu_exit;
fi
}
option_select () {
case $line_selected in
0) set_rpcsx_dir;;
1) set_cache_dir;;
2) set_games_dir;;
3) set_firms_dir;;
4) set_deflt_fir;;
5) save_and_exit;;
6) exit_confirmw;;
esac
}
menu_exit () {
enable_cursor;
cursor_to 0 0;
clear_screen;
stty echo;
close_script $1;
};
trap "menu_exit;" 2;
stty -echo;
disable_cursor;
redraw_menu;
update_selection;
while true; do
case `read_input` in
enter) option_select;;
exit) break;;
up) line_selected=$(($line_selected - 1));;
down) line_selected=$(($line_selected + 1));;
esac
update_selection;
done
menu_exit;
}
function run_emu () {
local EBOOT="$GAME_PATH/eboot.bin";
local DEBOOT="$GAME_PATH/eboot.elf";
local EMUBIN="/app0/eboot.bin";
if [ -f "$DEBOOT" ]; then
EMUBIN="/app0/eboot.elf";
fi
rm -f /dev/shm/rpcsx-*;
rm -r $RPCSX_CACHE 2>/dev/null;
mkdir $RPCSX_CACHE;
local RUN="$RPCSX_DIR/rpcsx-os";
if [ $RPCSX_RUN_LIBTEST -eq 1 ]; then
RUN="timeout --preserve-status 2m $RUN";
fi
if [ $MANGOHUD_ON -eq 1 ]; then
RUN="mangohud $RUN";
fi
local LOGNAME=$(basename "$GAME_PATH");
local LOGNAME+=$(date +" %d-%m-%y_%H-%M-%S");
local LOGDIR="$RPCSX_DIR/logs/$DESIRED_FIRMWARE";
local LOGFILE="$LOGDIR/$LOGNAME.log";
mkdir -p "$LOGDIR";
if [ $NOLOG -eq 1 ]; then
$RUN $RPCSX_ADDOPTS\
--mount "$RPCSX_CACHE" "/data"\
--mount "$RPCSX_FIRMWARES/$DESIRED_FIRMWARE" "/system"\
--mount "$GAME_PATH" "/app0"\
"$EMUBIN" &> /dev/null;
else
$RUN $RPCSX_ADDOPTS\
--mount "$RPCSX_CACHE" "/data"\
--mount "$RPCSX_FIRMWARES/$DESIRED_FIRMWARE" "/system"\
--mount "$GAME_PATH" "/app0"\
"$EMUBIN" 2>&1 |& tee "$LOGFILE";
fi
if [ $? -ne 0 ]; then
echo -e "\n\n\n";
echo "$LANG_EMU_CRASH_LINE_1";
if [ $NOLOG -eq 1 ]; then
echo "$LANG_EMU_CRASH_LINE_2_1";
else
echo "$LANG_EMU_CRASH_LINE_2_2";
echo "${LANG_EMU_CRASH_LINE_3_2/'%LF'/$LOGFILE}";
fi
return 1;
fi
return 0;
}
function perform_libtest () {
local succ=( );
local fail=( );
while IFS= read -r GAME_PATH; do
if run_emu; then
succ+=("$GAME_PATH");
else
fail+=("$GAME_PATH");
fi
done <<< "$FOUND_DIRS";
local sc=${#succ[@]};
local fc=${#fail[@]};
echo "Successful ($sc):";
echo "${succ[@]}";
echo "Crashed ($fc):";
echo "${fail[@]}";
}
if [ ! -f "$CFG_FILE" ]; then
if [ $EXPERIMENTAL -eq 1 ]; then
if experimental_wizard; then
close_script 0;
else
echo "$LANG_ECFGW_NOZENITY";
fi
fi
echo "$LANG_CFGW_WELC_LINE_1";
echo "$LANG_CFGW_WELC_LINE_2";
echo "$LANG_CFGW_WELC_LINE_3";
read -e;
CURRVAL=`which rpcsx-os 2>&1 >/dev/null`;
if [ $? -ne 0 ]; then
CURRVAL="/home/$WHO/rpcsx/build/bin";
fi
while true; do
read -e -p "$LANG_CFGW_RPCSX_DIR [$CURRVAL]: " RPCSX_DIR;
if [ "$RPCSX_DIR" == "" ]; then
RPCSX_DIR="$CURRVAL";
else
RPCSX_DIR=`readlink -f $RPCSX_DIR`;
fi
if [[ -d "$RPCSX_DIR" && -f "$RPCSX_DIR/rpcsx-os" ]]; then break; fi
if [[ -d "$RPCSX_DIR/build/bin" && -f "$RPCSX_DIR/build/bin/rpcsx-os" ]]; then
RPCSX_DIR="$RPCSX_DIR/build/bin";
break;
fi;
done
CURRVAL="$RPCSX_DIR/cache";
while true; do
read -e -p "$LANG_CFGW_RPCSX_CACHE [$CURRVAL]: " RPCSX_CACHE;
if [ "$RPCSX_CACHE" == "" ]; then
RPCSX_CACHE="$CURRVAL";
else
RPCSX_CACHE=`readlink -f $RPCSX_CACHE`;
fi
if [ -d "$RPCSX_CACHE" ]; then
check_case "$RPCSX_CACHE";
break;
else
if mkdir "$RPCSX_CACHE"; then
check_case "$RPCSX_CACHE";
break;
fi
fi
done
CURRVAL="$RPCSX_DIR/games";
while true; do
read -e -p "$LANG_CFGW_RPCSX_GAMES [$CURRVAL]: " RPCSX_GAMES;
if [ "$RPCSX_GAMES" == "" ]; then
RPCSX_GAMES="$CURRVAL";
else
RPCSX_GAMES=`readlink -f $RPCSX_GAMES`;
fi
if [ -d "$RPCSX_GAMES" ]; then
check_case "$RPCSX_GAMES";
break;
else
if mkdir $RPCSX_GAMES; then
check_case "$RPCSX_GAMES";
break;
fi
fi
done
echo -e "\n\n\n";
echo "$LANG_CFGW_FIRM_NOTE_LINE_1";
echo "$LANG_CFGW_FIRM_NOTE_LINE_2";
echo "$LANG_CFGW_FIRM_NOTE_LINE_3";
echo "$LANG_CFGW_FIRM_NOTE_LINE_4";
echo "$LANG_CFGW_FIRM_NOTE_LINE_5";
read -e;
CURRVAL="$RPCSX_DIR/firmwares";
while true; do
read -e -p "$LANG_CFGW_RPCSX_FIRMWARES [$CURRVAL]: " RPCSX_FIRMWARES;
if [ "$RPCSX_FIRMWARES" == "" ]; then
RPCSX_FIRMWARES="$CURRVAL";
else
RPCSX_FIRMWARES=`readlink -f "$RPCSX_FIRMWARES"`;
fi
if mkdir -p $RPCSX_FIRMWARES 2> /dev/null; then
check_case "$RPCSX_FIRMWARES";
break;
fi
done
CURRVAL="5.05";
read -e -p "$LANG_CFGW_RPCSX_DFIRMWARE [$CURRVAL]: " RPCSX_DFIRMWARE;
if [ "$RPCSX_DFIRMWARE" == "" ]; then RPCSX_DFIRMWARE="$CURRVAL"; fi
echo -e "\n\n\n";
echo "$LANG_CFGW_CONF_NOTE_LINE_1";
echo "$LANG_CFGW_CONF_NOTE_LINE_2";
echo "${LANG_CFGW_CONF_NOTE_LINE_3/'%CF'/$CFG_FILE}";
echo "${LANG_CFGW_CONF_NOTE_LINE_4/'%IAMSURE'/$LANG_YES_EXTENDED}";
echo "$LANG_CFGW_CONF_NOTE_LINE_5";
while true; do
read -p "> " YESIAM;
if [ "$YESIAM" == "$LANG_YES_EXTENDED" ]; then
echo -n "$LANG_CFGW_SAVING";
if config_save; then
echo "$LANG_CFGW_OK";
close_script 0;
fi
echo "$LANG_CFGW_IOFAIL";
elif [ "${YESIAM,,}" == "${LANG_NO_ANS_1,,}" ] || [ "${YESIAM,,}" == "${LANG_NO_ANS_2,,}" ]; then
echo "$LANG_CFGW_NOSAVE"
close_script 1;
elif [ "$YESIAM" == "" ]; then
echo "$LANG_CFGW_NOINPUT"
else
echo "${LANG_CFGW_WTF/'%SHET'/$YESIAM}";
fi
done
else
if [ $RPCSX_UPDATE -eq 1 ]; then
check_for_emu_update;
fi
if [ $RPCSX_RUN_UPDATE -eq 1 ]; then
check_for_update;
fi
if [ $RPCSX_RUN_LIBTEST -eq 1 ]; then
DESIRED_GAME='.a';
fi
if [ "$DESIRED_GAME" != "" ]; then
if [ "$DESIRED_FIRMWARE" == "" ]; then
DESIRED_FIRMWARE=$RPCSX_DFIRMWARE;
fi
if [ "$DESIRED_GAME" == '.a' ]; then
FOUND_DIRS=`find "$RPCSX_GAMES"/* -maxdepth 0 -type d -or -type l 2>/dev/null | awk 'NF'`;
else
FOUND_DIRS=`find "$RPCSX_GAMES"/* -maxdepth 0 \( -type d -or -type l \) -iname *"$DESIRED_GAME"* 2>/dev/null | awk 'NF'`;
fi
MAX_NUMBER=`echo "$FOUND_DIRS" | wc -l`;
if [ $MAX_NUMBER -gt 1 ]; then
if [ $RPCSX_RUN_LIBTEST -eq 1 ]; then
perform_libtest;
exit 0;
fi
LCOUNTER=1
echo "$LANG_GAMELIB_MSG:";
while IFS= read -r a; do
_NAME=$(basename "$a");
echo "$LCOUNTER. $_NAME";
(( LCOUNTER++ ));
done <<< "$FOUND_DIRS";
echo "$LCOUNTER. $LANG_GAMELIB_QUIT (Ctrl+C)";
DGM=0;
while true; do
read -e -p "> " DGM;
if [ "$DGM" != "" ] && [ -n $DGM ] && [ "$DGM" -eq "$DGM" ] && [ $DGM -gt 0 ] && [ $DGM -le $MAX_NUMBER ]; then
break;
fi
if [ "$DGM" == "$LCOUNTER" ]; then
close_script 0;
fi
echo "${LANG_GAMELIB_INV/'%MN'/$MAX_NUMBER}";
done
if [ $DGM -eq 0 ]; then
echo "Goodbye!";
close_script 0;
fi
GAME_PATH=`printf "$FOUND_DIRS" | sed "$DGM!d;q"`;
elif [ "$FOUND_DIRS" == "" ]; then
echo "$LANG_GAMELIB_NOTFOUND";
close_script 1;
elif [ $MAX_NUMBER -eq 1 ]; then
GAME_PATH=$FOUND_DIRS;
fi
echo "$LANG_GAMELIB_ENJOY";
run_emu;
if [ $MAX_NUMBER -gt 1 ]; then
restart_script;
fi
else
print_usage;
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment