Station starten
- booten und nfs mounten:
$ sudo mount -a
- wiimote-foo starten:
$ sudo wminput -w -r -c /etc/cwiid/wminput/fullcircle
- tuxracer starten:
$ cd Projects/fc-extremetuxracer/ $ ./src/etracer
- Einen Kurs auswaehlen. Dieser wird immer wiederholt. Nach dem ersten Spiel erscheint der Fullcircle-Wartebildschirm. Nur in diesem kann man ueber eine Tastatur "x" eingeben, um Tuxracer zu verlassen.
- Wenn ein Level laeuft, kann man diesen mittels Druck auf "Home" oder "q" auf der Tastatur abgebrochen werden.
Konzept
Nutzer kann über eine Dialogstation Tuxracer spielen. Die Highscores werden nach jedem Spiel dazu verwendet, eine Visualisierung zu entwerfen. Die Steuerung kann über die Wiimote erfolgen - alternativ (wenn Fuckups passieren) auch über eine Tastatur.
Umsetzung
Die Dialogstation benötigt eine gepatchte Version von tuxracer:
$ git clone ssh://sesam/home/git/repo/fc-extremetuxracer.git
Abhängigkeiten installieren:
sudo apt-get install xorg-dev tcl-dev libsdl1.2-dev
TuxRacer kompilieren mit
./configure --with-tcl-inc=/usr/include/tcl make
Wiimote anschliessen
1 + 2 auf der Wiimote drücken, um in den Pairingmodus zu gelangen. Bluetooth-Adapter einstecken. Mit
sudo wminput -w -r
wird das Signal der Wiimote als Mausersatz genutzt. In /etc/cwiid/wminput sind verschiedene Profile hinterlegt, welche das Verhalten der Wiimote verändern.
Für FullCircle benutzen wir das folgende Profil (einfach /etc/cwiid/wminput/fullcircle anlegen):
# fullcircle
include buttons
Wiimote.A = KEY_A Wiimote.Up = KEY_UP Wiimote.Down = KEY_DOWN Wiimote.Left = KEY_LEFT Wiimote.Right = KEY_RIGHT
Mittels
sudo wminput -w -r -c /etc/cwiid/wminput/fullcircle
wird diese Konfiguration genutzt. *Danach* den gepatchten etracer starten:
cd <WOAUCHIMMER> ./src/etracer
Dabei darauf achten, dass die Ubuntu-Pakete für extreme tuxracer installiert sind - die Level-Dateien werden aus /usr/share/$foo geladen.
Der Ablauf beim Beenden eines Levels wird durch $HOME/bin/fc-run.sh gesteuert. Beispiel:
#!/bin/sh LOGFILE=$HOME/tmp/fc-run.log TMPSEQ=/tmp/seq.fcs TMPLEADER=/tmp/leader.fcs echo "Running fullcircle toolchain" echo "got commandline parameters $*" date >> $LOGFILE echo $* >> $LOGFILE echo "getting id..." ID=`fc-getid` echo "using ID ${ID}" >> $LOGFILE echo "printing badge." FILENAME=/media/player/input/${ID}.fcs fc-badge -n ${ID} fc-perlin -x "$*" -s $TMPSEQ fc-leader -s $TMPLEADER -n $ID fc-concat $TMPLEADER $TMPSEQ -s ${FILENAME}
Der NFS-Server muss natürlich auch gemounted werden - in diesem Fall unter /media/player. In /etc/fstab:
10.23.42.2:/srv/data /media/player nfs rw 0 0
Wenn ein USB-Seriell-Konverter benutzt wird, muss eine udev-Regel dafuer angelegt werden. Siehe z.B. http://carboncopycat.wordpress.com/2011/10/18/ubuntu-serial-converter-udev-rules/
Beschreibung des Hacks
HINT: Zum Ändern des Build-foos braucht es eine arkane Abfolge von
aclocal automake autoconf
Änderung des Spielablaufs
- In src/loop.cpp ist die Statemachine für den Ablauf der Menüaktionen. Dort wurde ein neuer Spielzustand FC_INFOSCREEN (definiert in src/fc_infoscreen.*) eingeführt. Der Ablauf wurde so verändert, dass nach dem Highscore-Screen ein Wartebildschirm eingeblendet wird.
TODO: Klären, welche Taste beim Drücken von "A" auf der Wiimote generiert wird - diese dann in src/fc_infoscreen.cpp eintragen. Im Moment veranlasst "Pfeil nach oben" das nächste Spiel.
Callback für FullCircle
Nach jedem komplettierten Level wird eine Instanz der Klasse "GameOver" angelegt. Dort einfach einen Systemaufruf eines Shellscripts mit dem Punktestand als Parameter reinhacken. Das Shellscript übernimmt dann das Rendern der Visualisierung und den Bondrucker-Foo.
In src/gameover.cpp einfach entsprechende Werte wie Highscore etc. abgreifen. Der Code ruft dann das Shellscript "$HOME/bin/fc-run.sh" auf.
C++-Code in gameover.cpp:
std::string exec(std::string cmd) { char buffer[128]; FILE* pipe = popen(cmd.c_str(), "r"); if (!pipe) { std::ostringstream oss; oss << "ERROR: cannot execute command "; oss << cmd; return oss.str(); } std::ostringstream oss; while(!feof(pipe)) { if(fgets(buffer, 128, pipe) != NULL) oss << buffer; } pclose(pipe); return oss.str(); }
GameOver::GameOver() { halt_sound( "flying_sound" ); halt_sound( "rock_sound" ); halt_sound( "ice_sound" ); halt_sound( "snow_sound" ); char * home_path; home_path = getenv ("HOME"); if (home_path!=NULL) { // Patch MD: Callback for fullcircle std::cout << "GameOver: Executing fullcircle toolchain" << std::endl; int minutes, seconds, hundredths; getTimeComponents( gameMgr->time, minutes, seconds, hundredths ); std::ostringstream oss; oss << home_path << "/bin/fc-run.sh"; oss << " " << minutes << "a" << seconds << "b" << hundredths; std::string command=oss.str(); std::cout << "Running " << command << std::endl; std::string run_log=exec(command); std::cout << "Log was: " << run_log << std::endl; } else { std::cout << "No HOME environment variable found - cannot locate fc-run.sh" << std::endl; }
Shellscript (Demo):
#!/bin/sh echo "Running fullcircle toolchain" echo "got commandline parameters $*" date >> $HOME/tmp/fc-run.log echo $* >> $HOME/tmp/fc-run.log