Browse Source

add new platform: clockwork pi GameShell

pull/563/head
danie1kr 6 years ago committed by Anders Jenbo
parent
commit
d728caaf94
  1. 1
      .gitignore
  2. 27
      CMake/cpigamesh_defs.cmake
  3. 4
      CMakeLists.txt
  4. BIN
      Packaging/cpi-gamesh/Devilution.png
  5. 291
      Packaging/cpi-gamesh/__init__.py
  6. 91
      Packaging/cpi-gamesh/build.sh
  7. 42
      Packaging/cpi-gamesh/readme.md

1
.gitignore vendored

@ -427,3 +427,4 @@ DerivedData/
### Nintendo Switch ### ### Nintendo Switch ###
exefs/main exefs/main
/out/isenseconfig/CPI-Debug

27
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")

4
CMakeLists.txt

@ -85,6 +85,10 @@ if(RETROFW)
include(retrofw_defs) include(retrofw_defs)
endif() endif()
if(CPIGAMESH)
include(cpigamesh_defs)
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD OR ${CMAKE_SYSTEM_NAME} STREQUAL OpenBSD) if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD OR ${CMAKE_SYSTEM_NAME} STREQUAL OpenBSD)
set(ASAN OFF) set(ASAN OFF)
set(UBSAN OFF) set(UBSAN OFF)

BIN
Packaging/cpi-gamesh/Devilution.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

291
Packaging/cpi-gamesh/__init__.py

@ -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)

91
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

42
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 |
Loading…
Cancel
Save