7 changed files with 456 additions and 0 deletions
@ -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") |
||||
|
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1,291 @@
|
||||
|
||||
import pygame |
||||
import validators |
||||
import commands |
||||
from UI.constants import Width,Height,ICON_TYPES,RUNSYS |
||||
from UI.simple_name_space import SimpleNamespace |
||||
from UI.page import Page |
||||
from UI.label import Label |
||||
from UI.icon_item import IconItem |
||||
from UI.keys_def import CurKeys, IsKeyMenuOrB, IsKeyStartOrA |
||||
from UI.skin_manager import MySkinManager |
||||
from UI.lang_manager import MyLangManager |
||||
|
||||
from libs.DBUS import is_wifi_connected_now,get_wifi_ip |
||||
from collections import deque |
||||
from enum import Enum |
||||
import os |
||||
import subprocess |
||||
import pipes |
||||
|
||||
class DevilutionPage(Page): |
||||
_FootMsg = ["Nav","Check","Upgrade","Back","Play"] |
||||
|
||||
_GameName = "devilutionX" |
||||
_GamePath = "/home/cpi/games/devilutionX" |
||||
_GameExecutable = _GamePath + "/bin/devilutionx" |
||||
_GameExecutableRevision = _GameExecutable + ".rev" |
||||
_GameBuildScript = _GamePath + "/Packaging/cpi-gamesh/build.sh -t " + pipes.quote(os.path.dirname(os.path.abspath( __file__ ))) |
||||
_GamePNG = _GamePath + "/Packaging/cpi-gamesh/Devilution.png" |
||||
_DevilutionDiabdatmpq = "/home/cpi/.local/share/diasurgical/devilution/diabdat.mpq" |
||||
_DevilutionDiabdatmpqPresent = False |
||||
_GameInstalled = False |
||||
|
||||
_CiteNewUpdate = "Ahh... fresh meat!" |
||||
_CiteCheckUpdate = "Lets search the books..." |
||||
_CiteWelcome = "Well, what can I do for ya?" |
||||
_CiteCompiling = "Stay awhile and listen." |
||||
_CiteDone = "You must venture through the portal..." |
||||
_CiteFailed = "Game Over. Better luck next time!" |
||||
|
||||
_GitURL = "https://github.com/danie1kr/devilutionX.git" |
||||
_GitBranch = "gameshell" |
||||
_GitRevision = "" |
||||
|
||||
_GameIcon = None |
||||
|
||||
_Process = None |
||||
_Labels = {} |
||||
_Coords = {} |
||||
|
||||
_ListFontObj = MyLangManager.TrFont("varela13") |
||||
_URLColor = MySkinManager.GiveColor('URL') |
||||
_TextColor = MySkinManager.GiveColor('Text') |
||||
|
||||
def __init__(self): |
||||
Page.__init__(self) |
||||
|
||||
def InitLabels(self): |
||||
|
||||
y = 15 |
||||
x = 11 |
||||
yInc = 19 |
||||
xGitRefLabelWidth = 48 |
||||
|
||||
labels = \ |
||||
[["greeting",self._CiteWelcome, self._TextColor, x, y], |
||||
["status", "", self._URLColor, x, y + 72-yInc], |
||||
["comment", "", self._TextColor, x, y + 72], |
||||
["console_out","",self._URLColor, x, y + 72 + yInc], |
||||
["label_rev","GIT Revisions: ", self._TextColor, x, 132], |
||||
["label_git_rev","Source: ", self._TextColor, x, 151], |
||||
["content_git_rev","", self._URLColor, x + xGitRefLabelWidth, 151], |
||||
["label_bin_rev","Bin: ", self._TextColor, x, 170], |
||||
["content_bin_rev","", self._URLColor, x + xGitRefLabelWidth, 170] |
||||
] |
||||
|
||||
for i in labels: |
||||
l = Label() |
||||
l.SetCanvasHWND(self._CanvasHWND) |
||||
l.Init(i[1],self._ListFontObj) |
||||
l.SetColor(i[2]) |
||||
self._Labels[ i[0] ] = l |
||||
|
||||
c = SimpleNamespace() |
||||
c.x = i[3] |
||||
c.y = i[4] |
||||
self._Coords[ i[0] ] = c |
||||
|
||||
def GitGetRevision(self): |
||||
if not os.path.exists(self._GamePath): |
||||
return "game not installed" |
||||
process = subprocess.Popen("cd " + pipes.quote(self._GamePath) + "; git rev-parse HEAD",stdout=subprocess.PIPE,stderr=subprocess.STDOUT, shell=True) |
||||
self._GitRevision = process.communicate()[0].strip() |
||||
process.wait() |
||||
return self._GitRevision |
||||
|
||||
def ExectuableGetRevision(self): |
||||
try: |
||||
with open(self._GameExecutableRevision, 'r') as file: |
||||
executableRevsion = file.read().replace('\n', '') |
||||
return executableRevsion |
||||
except: |
||||
return "unknown" |
||||
|
||||
def InitGameDirectory(self): |
||||
try: |
||||
os.makedirs(self._GamePath) |
||||
except: |
||||
pass |
||||
self.StartShellProcess("cd " + pipes.quote(self._GamePath) + "; git clone --single-branch --branch " + pipes.quote(self._GitBranch) + " " + pipes.quote(self._GitURL) + " .") |
||||
|
||||
def CheckDevilutionMPQ(self): |
||||
self._DevilutionDiabdatmpqPresent = os.path.isfile(self._DevilutionDiabdatmpq) |
||||
|
||||
def CheckGameInstalled(self): |
||||
self._GameInstalled = os.path.isfile(self._GameExecutable) |
||||
|
||||
def UpdateFootMsg(self): |
||||
if not self._GameInstalled: |
||||
self._FootMsg = ["Nav","","Install","Back",""] |
||||
self.UpdateLabel("status", "GIT Upgrade") |
||||
self.UpdateLabel("comment", "Press X to install") |
||||
elif not self._DevilutionDiabdatmpqPresent: |
||||
self._FootMsg = ["Nav","","Upgrade","Back","Re-check"] |
||||
self.UpdateLabel("status", "Gamefile diabdat.mpq missing") |
||||
self.UpdateLabel("comment", "see readme") |
||||
else: |
||||
self._FootMsg = ["Nav","","Upgrade","Back","Play"] |
||||
self.UpdateLabel("status", "Ready") |
||||
self.UpdateLabel("comment", self._CiteDone) |
||||
|
||||
def Init(self): |
||||
Page.Init(self) |
||||
|
||||
if self._Screen != None: |
||||
if self._Screen._CanvasHWND != None and self._CanvasHWND == None: |
||||
self._HWND = self._Screen._CanvasHWND |
||||
self._CanvasHWND = pygame.Surface( (self._Screen._Width,self._Screen._Height) ) |
||||
|
||||
if os.path.isfile(self._GamePNG): |
||||
self._GameIcon = IconItem() |
||||
self._GameIcon._ImageName = self._GamePNG |
||||
self._GameIcon._MyType = ICON_TYPES["STAT"] |
||||
self._GameIcon._Parent = self |
||||
self._GameIcon.Adjust(290,70,128,128,0) |
||||
|
||||
self.InitLabels() |
||||
self.CheckDevilutionMPQ() |
||||
self.CheckGameInstalled() |
||||
self.UpdateFootMsg() |
||||
|
||||
self.UpdateLabel("content_git_rev", self.GitGetRevision(), 24) |
||||
self.UpdateLabel("content_bin_rev", self.ExectuableGetRevision(), 24) |
||||
|
||||
def UpdateLabel(self, label, msg, maxLen=38): |
||||
print(label + ": " + msg) |
||||
if len(msg) > 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) |
||||
@ -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 |
||||
@ -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 | |
||||
Loading…
Reference in new issue