Ayant deux et bientôt trois Naomi en netboot à la maison et ces Naomi ayant des jeux cibles qui leur sont propre (une NUC, une Naomi Gun, ...), le piforcetools.py ne me convient pas des masses.
En effet, pour booter chacune des machines, il me faut sélectionner la cible et ensuite choisir le jeu dans une liste commune à toutes les machines (plutôt longue).
J'ai donc ré-écrit une version de piforcetools.py qui pourrait plutôt être représenté comme un menu où les systèmes cibles sont disponibles avec les flèches horizontales et les jeux spécifiques en vertical :
Naomi 1 <--------> Naomi 2 <--------> Gun Cab <--------> Race Cab <--------> Commands
| | | | |
-> DeadOrAlive2 -> Exzeal -> Conf Mission -> Initial D -> Ping Naomi 1
-> Dolphin Blue -> Ikaruga -> Lupin the S -> Crazy Taxi -> Ping Naomi 2
-> Metal Slug 6 .... .... .... ....
-> Spawn
-> Virtua Tennis
....
Une petite vidéo vaut mieux qu'un long discours.
https://youtu.be/icO1robhGtUCeci étant, je ne connais pas vraiment les raspberry, ni même le python alors si vous avez des suggestions pour développer facilement sans devoir tester en aveugle sur un vrai raspberry, je suis preneur
J'en suis encore au débugging et à la gestion des imprévus mais voilà déjà une version un peu stable (le ping ne fonctionne pas et les répertoires de roms doivent exister). Pour remplacer piforcetools.py :
#!/usr/bin/python
# Written by TravistyOJ (AKA Capaneus)
# 20160309 - Modified by Solkan (for Gamoover.net)
import os, collections, signal, sys, subprocess, socket
import triforcetools
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate
from time import sleep
# Add or remove as many endpoints as you want
targetsIp = ["10.0.0.26", "10.0.0.24", "10.0.0.25", "10.0.0.27"]
targetsName = ["NUC 1", "NUC 2", "Gun Cab", "Race Cab"]
targetsRomDir = ["/boot/roms/", "/boot/roms/", "/boot/roms/Gun/", "/boot/roms/Racing/"] # Set absolute path of rom files ending with trailing /
commands = []
# Building commands list
for index in range(len(targetsIp)):
commands.append("Ping "+targetsName[index]+"\n "+targetsIp[index])
# Define a signal handler to turn off LCD before shutting down
def handler(signum = None, frame = None):
lcd = Adafruit_CharLCDPlate()
lcd.clear()
lcd.stop()
sys.exit(0)
signal.signal(signal.SIGTERM , handler)
# Determine hardware revision and initialize LCD
revision = "unknown"
cpuinfo = open("/proc/cpuinfo", "r")
for line in cpuinfo:
item = line.split(':', 1)
if item[0].strip() == "Revision":
revision = item[1].strip()
if revision.startswith('a'):
lcd = Adafruit_CharLCDPlate(busnum = 1)
else:
lcd = Adafruit_CharLCDPlate()
lcd.begin(16, 2)
lcd.clear()
lcd.message(" Piforce Tools\n Ver. Solkan")
sleep(2)
pressedButtons = []
gamesList = []
curr_menu_index = 0
curr_ip = 0
# Try to import game list script, if it fails, signal error on LCD
try:
from gamelist import games
except (SyntaxError, ImportError) as e:
lcd.clear()
lcd.message("Game List Error!\n Check Syntax")
sleep(5)
games = {}
# Build game dictionary of game files that can be found
for index in range(len(targetsIp)):
present_games = {}
for key, value in games.iteritems():
if os.path.isfile(targetsRomDir[index]+value):
present_games[key] = value
gamesList.insert(index, present_games)
# message first endpoint and first game at startup
lcd.clear()
lcd.message("* "+targetsName[curr_menu_index])
sleep(1)
lcd.clear()
iterator = iter(collections.OrderedDict(sorted(gamesList[curr_menu_index].items(), key=lambda t: t[0])))
selection = iterator.next()
previous = None
lcd.clear()
lcd.message(selection)
while True:
# Handle SELECT
if lcd.buttonPressed(lcd.SELECT):
if lcd.SELECT not in pressedButtons and selection != None:
pressedButtons.append(lcd.SELECT)
if selection[:5] == "Ping ":
lcd.clear()
lcd.message(" Pinging\n " + selection[6:20])
response = os.system("ping -c 1 " + selection[6:20])
lcd.clear()
if response == 0:
lcd.message("SUCCESS!")
else:
lcd.message("Netdimm is\n unreachable!")
sleep(2)
lcd.clear()
lcd.message(selection)
else:
lcd.clear()
lcd.message("Connecting...")
try:
triforcetools.connect(targetsIp[curr_menu_index], 10703)
except:
lcd.clear()
lcd.message("Error:\nConnect Failed")
sleep(1)
lcd.clear()
lcd.message(selection)
continue
lcd.clear()
lcd.message("Sending...")
lcd.setCursor(10, 0)
lcd.ToggleBlink()
triforcetools.HOST_SetMode(0, 1)
triforcetools.SECURITY_SetKeycode("\x00" * 8)
triforcetools.DIMM_UploadFile(targetsRomDir[curr_menu_index]+gamesList[curr_menu_index].get(selection))
triforcetools.HOST_Restart()
triforcetools.TIME_SetLimit(10*60*1000)
triforcetools.disconnect()
lcd.ToggleBlink()
lcd.clear()
lcd.message("Transfer\nComplete!")
sleep(5)
lcd.clear()
lcd.message(selection)
elif lcd.SELECT in pressedButtons:
pressedButtons.remove(lcd.SELECT)
# Handle LEFT
if lcd.buttonPressed(lcd.LEFT):
if lcd.LEFT not in pressedButtons:
pressedButtons.append(lcd.LEFT)
lcd.clear()
curr_menu_index -= 1
if curr_menu_index < 0:
curr_menu_index = len(targetsIp)
lcd.message("* Commands")
iterator = iter(commands)
else:
lcd.message("* "+targetsName[curr_menu_index])
iterator = iter(collections.OrderedDict(sorted(gamesList[curr_menu_index].items(), key=lambda t: t[0])))
sleep(1)
selection = iterator.next()
previous = None
lcd.clear()
lcd.message(selection)
elif lcd.LEFT in pressedButtons:
pressedButtons.remove(lcd.LEFT)
# Handle RIGHT
if lcd.buttonPressed(lcd.RIGHT):
if lcd.RIGHT not in pressedButtons:
pressedButtons.append(lcd.RIGHT)
lcd.clear()
curr_menu_index += 1
if curr_menu_index == len(targetsIp):
lcd.message("* Commands")
iterator = iter(commands)
else:
if curr_menu_index > len(targetsIp):
curr_menu_index = 0
lcd.message("* "+targetsName[curr_menu_index])
iterator = iter(collections.OrderedDict(sorted(gamesList[curr_menu_index].items(), key=lambda t: t[0])))
sleep(1)
selection = iterator.next()
previous = None
lcd.clear()
lcd.message(selection)
elif lcd.RIGHT in pressedButtons:
pressedButtons.remove(lcd.RIGHT)
# Handle UP
if lcd.buttonPressed(lcd.UP):
if lcd.UP not in pressedButtons and previous != None:
pressedButtons.append(lcd.UP)
if curr_menu_index < len(targetsIp):
iterator = iter(collections.OrderedDict(sorted(gamesList[curr_menu_index].items(), key=lambda t: t[0])))
else:
iterator = iter(commands)
needle = iterator.next()
selection = previous
previous = needle
while selection != needle and selection != previous:
previous = needle
try:
needle = iterator.next()
except StopIteration:
break
lcd.clear()
lcd.message(selection)
elif lcd.UP in pressedButtons:
pressedButtons.remove(lcd.UP)
# Handle DOWN
if lcd.buttonPressed(lcd.DOWN):
if lcd.DOWN not in pressedButtons:
pressedButtons.append(lcd.DOWN)
previous = selection
try:
selection = iterator.next()
except StopIteration:
# back to first element
if curr_menu_index < len(targetsIp):
iterator = iter(collections.OrderedDict(sorted(gamesList[curr_menu_index].items(), key=lambda t: t[0])))
else:
iterator = iter(commands)
selection = iterator.next()
lcd.clear()
lcd.message(selection)
elif lcd.DOWN in pressedButtons:
pressedButtons.remove(lcd.DOWN)