From 92936a6e1199ea05bbccbd2d46208d71edc31f43 Mon Sep 17 00:00:00 2001 From: dajoho Date: Sun, 10 Dec 2023 21:17:35 +0100 Subject: [PATCH] Initial commit --- .project | 11 + Makefile | 13 + make.sh | 4 + pandash | Bin 0 -> 11552 bytes src/CommandLine/CommandLineArguments.cpp | 45 +++ src/CommandLine/CommandLineArguments.h | 19 ++ src/Fs/Fs.cpp | 8 + src/Fs/Fs.h | 12 + src/main.cpp | 350 +++++++++++++++++++++++ 9 files changed, 462 insertions(+) create mode 100644 .project create mode 100644 Makefile create mode 100755 make.sh create mode 100755 pandash create mode 100644 src/CommandLine/CommandLineArguments.cpp create mode 100644 src/CommandLine/CommandLineArguments.h create mode 100644 src/Fs/Fs.cpp create mode 100644 src/Fs/Fs.h create mode 100644 src/main.cpp diff --git a/.project b/.project new file mode 100644 index 0000000..021ee76 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + pandory500-pandash + + + + + + + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dd01641 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +all: clean pandash +CXX = /opt/armv8-teampandory_a500mini_gcc12-linux-gnueabihf/bin/armv8-teampandory_a500mini_gcc12-linux-gnueabihf-g++ +STRIP = /opt/armv8-teampandory_a500mini_gcc12-linux-gnueabihf/bin/armv8-teampandory_a500mini_gcc12-linux-gnueabihf-strip +INCLUDES = -Isrc +CFLAGS = -Os -s + +pandash: $(OBJS) + $(CXX) $(CFLAGS) $(INCLUDES) src/main.cpp src/CommandLine/CommandLineArguments.cpp src/Fs/Fs.cpp -o $@ + $(STRIP) pandash + upx -9 -f pandash + +clean: + rm -f pandash 2>/dev/null || true diff --git a/make.sh b/make.sh new file mode 100755 index 0000000..e4becc4 --- /dev/null +++ b/make.sh @@ -0,0 +1,4 @@ +#!/bin/bash +podman run -v "$(pwd):/pandash:Z" teampandory/teampandory-a500-private sh -c "cd /pandash; make" + +cp -fv pandash ../pandory-packagebuilder/pandory500/root/bin/ \ No newline at end of file diff --git a/pandash b/pandash new file mode 100755 index 0000000000000000000000000000000000000000..d1085cf743a74860527d3ffbc56aad7323990fd9 GIT binary patch literal 11552 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 CB23}{ literal 0 HcmV?d00001 diff --git a/src/CommandLine/CommandLineArguments.cpp b/src/CommandLine/CommandLineArguments.cpp new file mode 100644 index 0000000..da10d7d --- /dev/null +++ b/src/CommandLine/CommandLineArguments.cpp @@ -0,0 +1,45 @@ +#include +#include "CommandLineArguments.h" + +CommandLineArguments::CommandLineArguments(int argc, char *argv[]) { + argumentCount = argc; + argumentPointers = argv; +} + +int CommandLineArguments::getArgumentCount() { + return argumentCount; +} + +std::string CommandLineArguments::getArgument(int n) { + for (int i = 0; i < argumentCount; ++i) { + if (i == n) { + return std::string(argumentPointers[i]); + } + } + return std::string(); +} + +std::string CommandLineArguments::getPathArgument(int n) { + std::string arg = getArgument(n); + if (!arg.empty()) { + int len = arg.length(); + std::string end = arg.substr(len-1, 1); + if (end == ":") { + arg += "/"; + } + return arg; + } + return std::string(); +} + +std::string CommandLineArguments::getAllAsString() { + std::string stringArgs; + for (int i = 0; i < argumentCount; ++i) { + stringArgs.append(std::string(argumentPointers[i])+" "); + } + return stringArgs; +} + + + + diff --git a/src/CommandLine/CommandLineArguments.h b/src/CommandLine/CommandLineArguments.h new file mode 100644 index 0000000..7787380 --- /dev/null +++ b/src/CommandLine/CommandLineArguments.h @@ -0,0 +1,19 @@ +#ifndef TESTC_COMMANDLINEARGUMENTS_H +#define TESTC_COMMANDLINEARGUMENTS_H + +#include +#include +class CommandLineArguments { +protected: + int argumentCount; + char **argumentPointers; +public: + CommandLineArguments(int argc, char *argv[]); + int getArgumentCount(); + std::string getArgument(int n); + std::string getAllAsString(); + + std::string getPathArgument(int n); +}; + +#endif //TESTC_COMMANDLINEARGUMENTS_H diff --git a/src/Fs/Fs.cpp b/src/Fs/Fs.cpp new file mode 100644 index 0000000..9430b56 --- /dev/null +++ b/src/Fs/Fs.cpp @@ -0,0 +1,8 @@ +#include +#include +#include +#include "Fs.h" + +bool Fs::exists(const std::string& file) { + return std::filesystem::exists(file.c_str()); +} diff --git a/src/Fs/Fs.h b/src/Fs/Fs.h new file mode 100644 index 0000000..712bddc --- /dev/null +++ b/src/Fs/Fs.h @@ -0,0 +1,12 @@ +#ifndef PANDORER_FILESYSTEM_H +#define PANDORER_FILESYSTEM_H +#include +#include + +class Fs { +public: + static bool exists(const std::string& file); +}; + + +#endif //PANDORER_FILESYSTEM_H diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..71638bc --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,350 @@ +#include +#include +#include +#include +#include "CommandLine/CommandLineArguments.h" +#include "Fs/Fs.h" + +void pandoryExec(std::string const& cmd) +{ + std::cout << "Executing shell: " << cmd << std::endl; + system(cmd.c_str()); +} + +void freezeProcess(const std::string &processName) +{ + std::cout << "Freezing process: " << processName << std::endl; + std::string pauseCmd = "kill -STOP $(pidof "+ processName +") 2>/dev/null"; + pandoryExec(pauseCmd); +} + +void unfreezeProcess(const std::string &processName) +{ + std::cout << "Unfreezing process: " << processName << std::endl; + std::string pauseCmd = "kill -CONT $(pidof "+ processName +") 2>/dev/null"; + pandoryExec(pauseCmd); +} + +void shuffleMusic() +{ + pandoryExec("umount /tmp/pandory/share/retroarch/assets/sounds/bgm.mp3"); + pandoryExec("cd /mnt/Pandory/.user/bgm && ls | sed -n \"$((RANDOM%$(ls | wc -l)+1))p\" > /tmp/pandory_track"); + pandoryExec("busybox mount -o bind /mnt/Pandory/.user/bgm/$(cat /tmp/pandory_track) /tmp/pandory/share/retroarch/assets/sounds/bgm.mp3"); +} + + +void forceKill(const std::string &processName) +{ + std::cout << "Force killing process: " << processName << std::endl; + std::string cmd = "killall -9 " + processName + " 2>/dev/null"; + pandoryExec(cmd.c_str()); +} + +void yaft() +{ + pandoryExec("cp -fv /tmp/pandory/bin/shell /tmp/pandoryshell && chmod +x /tmp/pandoryshell"); + pandoryExec("/tmp/pandory/bin/yaft < /dev/tty0"); +} + +void ppsspp() +{ + pandoryExec("/tmp/pandory/bin/PPSSPPGold --fullscreen"); +} + +void retroarch() +{ + // if mode == retroarch + shuffleMusic(); + + // TODO: just complain instead if at 60hz. autopatch retroarch.cfg for 50/60hz + system("busybox ash /tmp/pandory/bin/checkfreq.sh"); + + system("mount -o bind /mnt/Pandory/.user/.config/retroarch/thumbnails/ /tmp/pandory/share/retroarch/thumbnails"); + system("mount -o loop,ro /mnt/Pandory/.pandorythumbs /tmp/pandory/share/retroarch/thumbnails"); + system("mount -o bind /tmp/pandory/share/retroarch/thumbnails/Arcade '/tmp/pandory/share/retroarch/thumbnails/FBNeo - Arcade Games'"); + system("mount -o bind /tmp/pandory/share/retroarch/thumbnails/Arcade '/tmp/pandory/share/retroarch/thumbnails/MAME'"); + pandoryExec("/tmp/pandory/bin/retroarch -c /mnt/Pandory/.user/.config/retroarch/retroarch.cfg"); +} + +void spectrum() +{ + pandoryExec("/tmp/pandory/bin/zesarux.sh"); +} + +void dosbox() +{ + pandoryExec("/tmp/pandory/bin/dosbox -conf /mnt/Pandory/.user/config/dosbox/dosbox-staging.conf"); +} + +void openbor() +{ + pandoryExec("cd /mnt/Pandory/.roms/OpenBOR && OpenBOR.elf"); +} + +void amiberry5(std::string const &executionMode, std::string const &romPath) +{ + forceKill("amiberry5"); + + std::string cmd = ""; + + if (romPath != "") { + cmd = "cd /mnt/Pandory/.user/.config/amiberry/; amiberry5 -o default_fullscreen_mode=1 -o default_vkbd_enabled=yes -o default_vkbd_exit=yes -o default_vkbd_style=Cool --autoload \""+romPath+"\""; + } else { + cmd = "cd /mnt/Pandory/.user/.config/amiberry/; amiberry5 -o default_fullscreen_mode=1"; + } + pandoryExec(cmd); +} + +void scummvm() +{ + pandoryExec("/tmp/pandory/bin/scummvm --config=/mnt/Pandory/.user/.config/scummvm/scummvm.ini"); +} + + +void darkplaces() +{ + pandoryExec("export LD_LIBRARY_PATH=\"/opt/gles/lib:$LD_LIBRARY_PATH\" && cd /mnt/Pandory/.roms/Quake/ && darkplaces-sdl"); + //pandoryExec("export LD_LIBRARY_PATH=\"/opt/gles/lib:$LD_LIBRARY_PATH\" && darkplaces.sh"); +} + +void emulationStation() +{ + pandoryExec("/tmp/pandory/bin/emulationstation"); +} + +void hatari() +{ + pandoryExec("/tmp/pandory/bin/hatari"); +} + +void vanillaTD() +{ + system("cd \"/mnt/Pandory/.roms/Vanilla Conquer/TD/\" && ./vanillatd"); +} + +void vanillaRA() +{ + system("cd \"/mnt/Pandory/.roms/Vanilla Conquer/RA/\" && ./vanillara"); +} + + + +void loadKernelModule(const std::string &module) +{ + std::string modulePath = "/tmp/pandory/lib/modules/"; + std::string cmd = "insmod " + modulePath + module + ".ko"; + system(cmd.c_str()); +} + +void enableNetwork() +{ + loadKernelModule("ipv4"); + loadKernelModule("af_packet"); + loadKernelModule("mii"); + loadKernelModule("rtl8150"); + loadKernelModule("r8152"); + loadKernelModule("tcp_cubic"); + + loadKernelModule("usbnet"); + loadKernelModule("libphy"); + + loadKernelModule("asix"); + //loadKernelModule("ax88179_178a"); + + loadKernelModule("catc"); + loadKernelModule("cdc_ether"); + loadKernelModule("ipheth"); + loadKernelModule("kaweth"); + loadKernelModule("pegasus"); + + loadKernelModule("squashfs"); + + // wait for interfaces and bring them up + system("sleep 5"); + system("ifconfig eth0 up"); + + //dhcp + system("busybox udhcpc -s /tmp/pandory/etc/udhcpc.script &"); + + system("cd /mnt/Pandory/.webserver && php -S 0.0.0.0:80 &"); + system("dropbear -r /mnt/Pandory/.user/.config/dropbear/dropbear_rsa_host_key -E -p 0.0.0.0:22 &"); +} + +void prepareBios() +{ + // Make a virtual kickstarts folder in /tmp + mkdir("/tmp/bios/", 0750); + chdir("/tmp/bios/"); + + // Symlink all the nand-kickstarts to /tmp/bios/ + system("find /usr/share/amiberry/kickstarts/ -type f -exec ash -c 'ln -sfv {} $(basename {})' \\;"); + + // Symlink all the libre amiberry-fallback-kickstarts to /tmp/bios/ + system("find /mnt/Pandory/.user/.config/amiberry/kickstarts/ -type f -exec ash -c 'ln -sfv {} $(basename {})' \\;"); + + // Rsync the preferred kickstarts to their correct names in the amiberry kickstart folder + system("rsync -av --size-only /usr/share/amiberry/kickstarts/kick34005.A500 '/mnt/Pandory/.user/.config/amiberry/kickstarts/Kickstart v1.3 rev 34.5 (1987)(Commodore)(A500-A1000-A2000-CDTV).rom'"); + system("rsync -av --size-only /usr/share/amiberry/kickstarts/kick37350.A600 '/mnt/Pandory/.user/.config/amiberry/kickstarts/Kickstart v2.05 rev 37.350 (1992)(Commodore)(A600HD)[!].rom'"); + system("rsync -av --size-only /usr/share/amiberry/kickstarts/kick40068.A1200 '/mnt/Pandory/.user/.config/amiberry/kickstarts/Kickstart v3.1 rev 40.68 (1993)(Commodore)(A1200)[!].rom'"); + + // ..and to the whdload boot folder + system("rsync -av --size-only /usr/share/amiberry/kickstarts/kick34005.A500 /mnt/Pandory/.user/.config/amiberry/whdboot/save-data/Kickstarts/"); + system("rsync -av --size-only /usr/share/amiberry/kickstarts/kick37350.A600 /mnt/Pandory/.user/.config/amiberry/whdboot/save-data/Kickstarts/"); + system("rsync -av --size-only /usr/share/amiberry/kickstarts/kick40068.A1200 /mnt/Pandory/.user/.config/amiberry/whdboot/save-data/Kickstarts/"); + + // ..and the rtb files, because whdload. the a600 one doesn't exist. + system("rsync -av --size-only /usr/share/amiberry/kickstarts/kick34005.A500.RTB /mnt/Pandory/.user/.config/amiberry/whdboot/save-data/Kickstarts/"); + system("rsync -av --size-only /usr/share/amiberry/kickstarts/kick40068.A1200.RTB /mnt/Pandory/.user/.config/amiberry/whdboot/save-data/Kickstarts/"); +} + +void parseAmiberryCommandLine(std::string const &name, std::string const &mode) +{ + std::string cmd = "ps -oargs | grep -v grep | grep amiberry | grep \""+name+"\" && touch /tmp/pandory_mode_" + mode; + pandoryExec(cmd); +} + +void clearCaches() +{ + pandoryExec("busybox sysctl vm.drop_caches=3"); +} + +int main(int argc, char *argv[]) +{ + // init pandory libraries and paths + setenv("LD_LIBRARY_PATH", "/tmp/pandory/usr/lib:/tmp/pandory/lib64:/tmp/pandory/lib", 1); + setenv("PATH", "/mnt/Pandory/.bin:/tmp/pandory/usr/bin:/tmp/pandory/sbin:/tmp/pandory/bin:/usr/bin:/sbin:/bin", 1); + + // empty caches + clearCaches(); + + + CommandLineArguments args = CommandLineArguments(argc, argv); + std::string mode = args.getArgument(1); + std::string rom = args.getArgument(2); + std::string romExtra = args.getArgument(3); + + if (mode == "network") { + enableNetwork(); + return 0; + } + + if (mode == "bios") { + prepareBios(); + return 0; + } + + if (mode == "amiberry5") { + std::string executionMode = args.getArgument(2); + std::string romPath = args.getArgument(3); + amiberry5(executionMode, romPath); + return 0; + } + + if (mode == "quake") { + freezeProcess("amiberry5"); + darkplaces(); + unfreezeProcess("amiberry5"); + return 0; + } + + + freezeProcess("manhattan"); + freezeProcess("skyline"); + freezeProcess("amiberry"); + + + if (!Fs::exists("/tmp/pandory_original_amiberry")) { + pandoryExec("mkdir /tmp/dbus/"); + pandoryExec("mount -o bind /mnt/Pandory/.user /root"); + pandoryExec("cp -f /usr/bin/amiberry /tmp/pandory_original_amiberry"); + pandoryExec("mount -o bind /tmp/pandory/bin/amiberry-proxy.sh /usr/bin/amiberry"); + pandoryExec("mount -o bind /tmp/pandory/share/terminfo/ /usr/share/terminfo/"); + + // fork network in the background + pandoryExec("pandash network &"); + + // prepare bios in the background -> do it sync instead of async + pandoryExec("pandash bios"); + + // rsync /etc/ to /tmp/etc/ and bind mount it back so it's writable + system("mkdir /tmp/etc/ && rsync -av /etc/ /tmp/etc/"); + system("mount -o bind /tmp/etc/ /etc/"); + + // make an empty mountpoint for dropbear and bind mount ssh configuration from usb stick + pandoryExec("mkdir /tmp/etc/dropbear/"); + //pandoryExec("mount -o bind /mnt/Pandory/.user/.config/dropbear/ /etc/dropbear/"); + pandoryExec("cp -fv /mnt/Pandory/.user/.config/dropbear/shadow /etc/shadow"); + pandoryExec("cp -fv /mnt/Pandory/.user/.config/dropbear/passwd /etc/passwd"); + } + + system("rm -f /tmp/pandory_mode_*"); + + parseAmiberryCommandLine("Start AMiNIMiga", "aminimiga"); + parseAmiberryCommandLine("Start AGS", "ags2"); + parseAmiberryCommandLine("Get Pandory500", "upgrade"); + + parseAmiberryCommandLine("Start PPSSPP (PSP)", "ppsspp"); + parseAmiberryCommandLine("Start Darkplaces (Quake)", "darkplaces"); + parseAmiberryCommandLine("Start Hatari (Atari)", "hatari"); + parseAmiberryCommandLine("Start Amiberry 5 (Amiga)", "amiberry5"); + parseAmiberryCommandLine("Start OpenBor (Beat-em-ups)", "openbor"); + parseAmiberryCommandLine("Start Terminal (Linux)", "terminal"); + parseAmiberryCommandLine("Start ScummVM (Adventure Games)", "scummvm"); + parseAmiberryCommandLine("Start Zesarux (Spectrum)", "spectrum"); + + parseAmiberryCommandLine("Start DOSBox Staging (IBM PC)", "dosbox"); + parseAmiberryCommandLine("Start Tiberian Dawn (C&C)", "vanillatd"); + parseAmiberryCommandLine("Start Red Alert (C&C)", "vanillara"); + + // free up memory + forceKill("amiberry"); + + // empty caches + clearCaches(); + + if (Fs::exists("/tmp/pandory_mode_ppsspp")) { + ppsspp(); + } else if (Fs::exists("/tmp/pandory_mode_terminal")) { + system("cp -fv /tmp/pandory/bin/shell /tmp/pandoryshell"); + yaft(); + } else if (Fs::exists("/tmp/pandory_mode_darkplaces")) { + darkplaces(); + } else if (Fs::exists("/tmp/pandory_mode_spectrum")) { + spectrum(); + } else if (Fs::exists("/tmp/pandory_mode_dosbox")) { + dosbox(); + } else if (Fs::exists("/tmp/pandory_mode_hatari")) { + hatari(); + } else if (Fs::exists("/tmp/pandory_mode_amiberry5")) { + // start amiberry with no arguments + amiberry5("", ""); + } else if (Fs::exists("/tmp/pandory_mode_scummvm")) { + scummvm(); + } else if (Fs::exists("/tmp/pandory_mode_openbor")) { + openbor(); + } else if (Fs::exists("/tmp/pandory_mode_vanillatd")) { + vanillaTD(); + } else if (Fs::exists("/tmp/pandory_mode_vanillara")) { + vanillaRA(); + } else if (Fs::exists("/tmp/pandory_mode_emulationstation")) { + emulationStation(); + } else if (Fs::exists("/tmp/pandory_mode_aminimiga")) { + pandoryExec("/mnt/AMiNIMiga/.pandory/boot.sh"); + pandoryExec("cd /mnt/Pandory/.user/.config/amiberry/; amiberry5 -o default_fullscreen_mode=1 -o config_path=/mnt/AMiNIMiga/.pandory/ --config /mnt/AMiNIMiga/.pandory/aminimiga.uae -s use_gui=no"); + } else if (Fs::exists("/tmp/pandory_mode_ags2")) { + pandoryExec("/mnt/AGS/.pandory/boot.sh"); + pandoryExec("cd /mnt/Pandory/.user/.config/amiberry/; amiberry5 -o default_fullscreen_mode=1 -o config_path=/mnt/AGS/.pandory/ --config /mnt/AGS/.pandory/ags.uae -s use_gui=no"); + } else if (Fs::exists("/tmp/pandory_mode_upgrade")) { + //pandoryExec("echo 'echo Upgrade to the full Pandory500 to add many emulators and new features to your A500 Mini. https://go.teampandory.com/a500 && sleep 10 && exit' > /tmp/pandoryshell"); + pandoryExec("mpv.sh /tmp/pandory/etc/pandory.mp4"); + } else { + retroarch(); + } + + unfreezeProcess("manhattan"); + unfreezeProcess("skyline"); + + // empty caches + clearCaches(); + return 0; +}