From d728caaf94e257c50e33ce19da497317f4acc1a5 Mon Sep 17 00:00:00 2001 From: danie1kr Date: Wed, 29 Jan 2020 22:35:49 +0100 Subject: [PATCH] add new platform: clockwork pi GameShell --- .gitignore | 1 + CMake/cpigamesh_defs.cmake | 27 +++ CMakeLists.txt | 4 + Packaging/cpi-gamesh/Devilution.png | Bin 0 -> 4226 bytes Packaging/cpi-gamesh/__init__.py | 291 ++++++++++++++++++++++++++++ Packaging/cpi-gamesh/build.sh | 91 +++++++++ Packaging/cpi-gamesh/readme.md | 42 ++++ 7 files changed, 456 insertions(+) create mode 100644 CMake/cpigamesh_defs.cmake create mode 100644 Packaging/cpi-gamesh/Devilution.png create mode 100644 Packaging/cpi-gamesh/__init__.py create mode 100644 Packaging/cpi-gamesh/build.sh create mode 100644 Packaging/cpi-gamesh/readme.md diff --git a/.gitignore b/.gitignore index a0fb0136b..f594e8be6 100644 --- a/.gitignore +++ b/.gitignore @@ -427,3 +427,4 @@ DerivedData/ ### Nintendo Switch ### exefs/main +/out/isenseconfig/CPI-Debug diff --git a/CMake/cpigamesh_defs.cmake b/CMake/cpigamesh_defs.cmake new file mode 100644 index 000000000..1d23141af --- /dev/null +++ b/CMake/cpigamesh_defs.cmake @@ -0,0 +1,27 @@ +set(NONET ON) +set(PREFILL_PLAYER_NAME ON) +set(HAS_KBCTRL 1) +set(BINARY_RELEASE ON) +set(LTO ON) +set(DIST ON) +set(DEBUG OFF) +set(ASAN OFF) +set(UBSAN OFF) +set(KBCTRL_BUTTON_DPAD_LEFT SDLK_LEFT) +set(KBCTRL_BUTTON_DPAD_RIGHT SDLK_RIGHT) +set(KBCTRL_BUTTON_DPAD_UP SDLK_UP) +set(KBCTRL_BUTTON_DPAD_DOWN SDLK_DOWN) +set(KBCTRL_BUTTON_X SDLK_i) +set(KBCTRL_BUTTON_Y SDLK_u) +set(KBCTRL_BUTTON_B SDLK_k) +set(KBCTRL_BUTTON_A SDLK_j) +set(KBCTRL_BUTTON_RIGHTSHOULDER SDLK_l) +set(KBCTRL_BUTTON_LEFTSHOULDER SDLK_h) +set(KBCTRL_BUTTON_AXIS_TRIGGERLEFT SDLK_y) +set(KBCTRL_BUTTON_AXIS_TRIGGERRIGHT SDLK_o) +set(KBCTRL_BUTTON_LEFTSTICK SDLK_PAGEUP) +set(KBCTRL_BUTTON_RIGHTSTICK SDLK_PAGEDOWN) +set(KBCTRL_BUTTON_START SDLK_RETURN) +set(KBCTRL_BUTTON_BACK SDLK_SPACE) + +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") diff --git a/CMakeLists.txt b/CMakeLists.txt index 72cb1600c..ed03c6d45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,10 @@ if(RETROFW) include(retrofw_defs) endif() +if(CPIGAMESH) + include(cpigamesh_defs) +endif() + if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD OR ${CMAKE_SYSTEM_NAME} STREQUAL OpenBSD) set(ASAN OFF) set(UBSAN OFF) diff --git a/Packaging/cpi-gamesh/Devilution.png b/Packaging/cpi-gamesh/Devilution.png new file mode 100644 index 0000000000000000000000000000000000000000..1bb11fbaf9264e7645b040e02c64096998064f02 GIT binary patch literal 4226 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 maxLen: + m = msg[:maxLen] + "..." + else: + m = msg + self._Labels[label].SetText(m) + + def StartShellProcess(self, cmd): + print("StartShellProcess " + cmd) + proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT, shell=True) + while(True): + line = proc.stdout.readline() + if line: + self.UpdateLabel("console_out", line.strip(), 48) + self._Screen.Draw() + self._Screen.SwapAndShow() + if line == '' and proc.poll() is not None: + break + self.UpdateLabel("console_out", "") + self._Screen.Draw() + self._Screen.SwapAndShow() + + def GitUpgrade(self): + self.UpdateLabel("status", "GIT Upgrade") + self.UpdateLabel("comment", self._CiteCheckUpdate) + + curRev = "unset" + if not os.path.exists(self._GamePath): + self.InitGameDirectory() + else: + curRev = self.GitGetRevision() + self.StartShellProcess("cd " + pipes.quote(self._GamePath) + "; git pull") + + self._GitRevision = self.GitGetRevision() + self.UpdateLabel("content_git_rev", self._GitRevision, 24) + + if curRev != self._GitRevision: + self.UpdateLabel("comment", self._CiteNewUpdate) + else: + self.UpdateLabel("comment", self._CiteDone) + + self._Screen.Draw() + self._Screen.SwapAndShow() + + def GitExectuableIsGitRevision(self): + return self.GitGetRevision() == self.ExectuableGetRevision() + + def Build(self): + self.UpdateLabel("status", "Building") + self.StartShellProcess(self._GameBuildScript) + + def UpgradeAndBuild(self): + self.GitUpgrade() + self.UpdateLabel("comment", self._CiteCompiling) + self._Screen.Draw() + self._Screen.SwapAndShow() + if not self.GitExectuableIsGitRevision(): + self.Build() + + self.UpdateLabel("content_git_rev", self.GitGetRevision(), 24) + self.UpdateLabel("content_bin_rev", self.ExectuableGetRevision(), 24) + + self.UpdateLabel("status", "Done") + if self.GitExectuableIsGitRevision(): + self.UpdateLabel("comment", self._CiteDone) + else: + self.UpdateLabel("comment", self._CiteFailed) + + self.CheckDevilutionMPQ() + self.CheckGameInstalled() + self.UpdateFootMsg() + + self._Screen.Draw() + self._Screen.SwapAndShow() + + def KeyDown(self,event): + + if IsKeyMenuOrB(event.key): + self.ReturnToUpLevelPage() + self._Screen.Draw() + self._Screen.SwapAndShow() + + if self._DevilutionDiabdatmpqPresent and self._GameInstalled: + if IsKeyStartOrA(event.key): + pygame.event.post( pygame.event.Event(RUNSYS, message=self._GameExecutable)) + if event.key == CurKeys["X"]: + self.UpgradeAndBuild() + elif not self._GameInstalled: + if event.key == CurKeys["X"]: + self.UpgradeAndBuild() + elif not self._DevilutionDiabdatmpqPresent: + if IsKeyStartOrA(event.key): + self.CheckDevilutionMPQ() + self.CheckGameInstalled() + self.UpdateFootMsg() + self._Screen.Draw() + self._Screen.SwapAndShow() + + def Draw(self): + self.ClearCanvas() + + if self._GameIcon != None: + self._GameIcon.Draw() + + for i in self._Labels: + if i in self._Coords: + self._Labels[i].NewCoord( self._Coords[i].x, self._Coords[i].y) + self._Labels[i].Draw() + + if self._HWND != None: + self._HWND.fill(MySkinManager.GiveColor('White')) + self._HWND.blit(self._CanvasHWND,(self._PosX,self._PosY,self._Width, self._Height ) ) + + +class APIOBJ(object): + + _Page = None + def __init__(self): + pass + def Init(self,main_screen): + self._Page = DevilutionPage() + self._Page._Screen = main_screen + self._Page._Name ="devilutionX" + self._Page.Init() + + def API(self,main_screen): + if main_screen !=None: + main_screen.PushPage(self._Page) + main_screen.Draw() + main_screen.SwapAndShow() + +OBJ = APIOBJ() +def Init(main_screen): + OBJ.Init(main_screen) +def API(main_screen): + OBJ.API(main_screen) diff --git a/Packaging/cpi-gamesh/build.sh b/Packaging/cpi-gamesh/build.sh new file mode 100644 index 000000000..bba6b4888 --- /dev/null +++ b/Packaging/cpi-gamesh/build.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + +set -euo pipefail + +echo "Building for target: clockwork pi GameSH" + +declare -r DIR="$(dirname "${BASH_SOURCE[0]}")" +cd "$DIR" +declare -r ABSDIR="$(pwd)" + +usage() { + echo "${BASH_SOURCE[0]} [--target /path/to/devliution/in/gameshell/menu] [--usage]" + exit 1 +} + +POSITIONAL=() +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -t|--target) + TARGET="$2" + shift # past argument + shift # past value + ;; + --help|-h|--usage|-u) + usage + shift # past argument + ;; + *) # unknown option + POSITIONAL+=("$1") # save it in an array for later + shift # past argument + ;; +esac +done +set -- "${POSITIONAL[@]}" # restore positional parameters + +install_deps() { + sudo apt install -y cmake libsdl2-ttf-dev libsdl2-mixer-dev +} + +main() { + install_deps + build + install +} + +build() { + mkdir -p ../../build + cd ../../build + rm -f CMakeCache.txt + + local -a defs=(-DCPIGAMESH=ON) + cmake .. ${defs[@]} + make -j $(getconf _NPROCESSORS_ONLN) + cd - +} + +install() { + mkdir -p /home/cpi/games/devilutionX/bin + cp /home/cpi/games/devilutionX/build/devilutionx /home/cpi/games/devilutionX/bin + git rev-parse HEAD > /home/cpi/games/devilutionX/bin/devilutionx.rev + + if [ -z ${TARGET+x} ]; then + local target_dir="25_devilutionX" + else + local target_dir=${TARGET#"/home/cpi/apps/Menu/"} + fi + + local script_dir="/home/cpi/apps/Menu/$target_dir" + + local target_dir_base=`basename "$target_dir"` + local target_dir_dir=`dirname "$target_dir"` + local icon_name="${target_dir_dir}/${target_dir_base#*_}" + + local icon_dir="/home/cpi/launcher/skin/default/Menu/GameShell/${icon_name}.png" + + echo $target_dir + echo $script_dir + echo $target_dir_base + echo $target_dir_dir + echo $icon_name + echo $icon_dir + + mkdir -p $script_dir + cp __init__.py $script_dir + cp Devilution.png $icon_dir +} + +main diff --git a/Packaging/cpi-gamesh/readme.md b/Packaging/cpi-gamesh/readme.md new file mode 100644 index 000000000..80d23ef0c --- /dev/null +++ b/Packaging/cpi-gamesh/readme.md @@ -0,0 +1,42 @@ + +### devilutionX package for ClockworkPi GameShell +For more information about this device see [here](https://www.clockworkpi.com/gameshell). + +## Install devilutionX on the CPi GameShell + +To install devilutionX, just copy the [\_\_init__.py](https://raw.githubusercontent.com/danie1kr/devilutionX/gameshell/Packaging/cpi-gamesh/__init__.py) to a newly created folder under /home/cpi/apps/Menu and run it from the menu. The folder then symbolizes the devilutionX icon. +From this menu, you can press 'X' to clone the git repository for devilutionX and compile the code. Dependencies are installed automatically (cmake and SDL development packages). +Once installed, 'X' pulls the updated code and does the compiling. Note that any changes made locally to the source are reverted before pulling. + +Currently, the code is cloned from [a fork](https://github.com/danie1kr/devilutionX.git), branch "gameshell". + +When the compile is finished and the diabdat.mpq is in place at '/home/cpi/.local/share/diasurgical/devilution/', you can play the game. Enjoy! + +## Play devilutionX on the CPi GameShell + +When the game is compiled and the diabdat.mpq is in place, you can press "A" in the devilutionX menu to play. + +The following key mapping is in place. +Unfortunately, the mapping is not trivial as devilutionX and GameShell use their own not(yet) compatible shift mechanism. +The mapping is based on the standard GameShell keyboard layout, devilutionX uses the Nintento mapping. + +| GameShell Key | Keyboard Key | devilutionX Key | devilutionX Action | +| --------------------- | --------------- | ------------------------- | ------------------ | +| D-Pad | Arrows | D-Pad | move hero | +| Select + D-Pad | Space + Arrows | Back + D-Pad | simulate mouse | +| B | K | A | attack nearby enemies, talk to townspeople and merchants, pickup/place items in the inventory, OK while in main menu | +| A | J | B | select spell, back while in menus | +| Y | I | X | pickup items, open nearby chests and doors, use item in the inventory | +| X | U | Y | cast spell, delete character while in main menu | +| Select | Space | Select | Select | +| Start | Enter | Start | game menu, skip movie | +| LK1 | H | L1 | use health item from belt | +| Start + Left | Enter + Left | Start + Left | character sheet | +| Start + Right | Enter + Right | Start + Right | inventory | +| LK5 | L | R1 | use mana item from belt | +| Start + Down | Enter + Down | Start + Down | automap | +| Select + LK1 | Space + H | Select + L1 | left mouse click | +| Start + X | Enter + U | Start + Y | quest log | +| Start + A | Enter + J | Start + B | spell book | +| Select + LK5 | Space + L | Select + R1 | right mouse click | +| Select + A/B/X/Y | Space + J/K/U/I | Select + A/B/X/Y | hot spell |