Dies ist ein zeitraubender und oft schwieriger Schritt. Die Erstellung geeigneter und ansprechender Grafiken ist keine Kleinigkeit und verlangt, dass sie ihre Grafiksoftware gut beherrschen. Auf dieses ganze Gebiet möchte ich hier nicht eingehen, man könnte ein ganzes Buch nur darüber schreiben. Dieses Buch sollte aber besser ein Experte für Grafiksoftware schreiben.
Machen sie sich über Allegros DATAFILEs und das Utility grabber schlau, sie werden dieses Wissen brauchen! Schauen sie sich mit diesen Kenntnissen einfach einmal an, welche Grafiken in den bereits fertigen Spielgeräten verwendet wurden und wie diese in der Implementation eingesetzt wurden! Vielleicht können sie davon einiges gebrauchen. Die bereits fertige Arbeit anderer Menschen zu benutzen, ist ein billiger Weg, produktiver zu sein.
Legen sie die benötigten Grafiken und anderen Dateien in einem DATAFILE ab! Wenn sie den Namen dieser Datei im Array v_file hinterlegen, stellen sie sicher, dass schon bei der Initialisierung geprüft wird, ob diese Datei existiert - das vermeidet Laufzeitfehler, die für »normale« Anwender etwas frustrierend sind. Es ist besser, wenn das virtuelle GSG als nicht spielfähig gekennzeichnet ist und die Schaltfläche »Spielen« deaktiviert ist, als wenn der Spieler darauf klicken kann und eine aus seiner Sicht unverständliche Fehlermeldung präsentiert bekommt.
Das Makefile erzeugt aus dem DATAFILE eine Datei mit der Extension .def. Diese besteht aus #defines für die Elemente im DATAFILE, ist also im Grunde ein normales Header-File. Wenn sie diese Datei #includen und anschließend make depend aufrufen, wird der gesamte Vorgang der Erzeugung dieser Datei automatisiert, wenn sich etwas im DATAFILE geändert hat. Sie ersparen sich viele Probleme durch veraltete Konstanten nach einer Änderung im DATAFILE, wenn sie diesen Mechanismus verwenden. Generell sollten sie nach jedem neuen #include einmal make depend aufrufen, nur, um völlig sicher zu gehen.
Hinterlegen sie eine Funktion für graphic_init_f, welche die graphische Initialisierung beim Start des Automaten übernimmt4.8 und setzen sie das Flag MFL_PLAYABLE! Beides ist erforderlich. Wenn sie den Callback für die graphische Initialisierung nicht gesetzt haben, führt dies zu einem Programmabbruch beim Start der Virtuellen Zockhalle. Es ist ein schwerer interner Fehler4.9.
Typischerweise werden Zähler und Umlaufkörper initialisiert, indem in der Komponente uptr1 ein Zeiger auf eine Struktur mit den erforderlichen Daten und Einstellungen und in der Komponente gfx_init_cb die schon fertige Funktion hinterlegt wird. Der Code, der dabei geschrieben werden muss, macht keinen besonderen Spaß, erspart aber sehr viel Arbeit4.10. Desweiteren gibt es veränderliche Bitmaps, um Leuchtanzeigen oder ähnliche Elemente zu modellieren, tragen sie diese einfach in v_vbm ein.
Die variablen Bitmaps sind ein ganzes Thema für sich. Die darin liegenden Pointer auf BITMAP-Pointer sollten mit NULL initialisiert werden. Die Arrays werden vom Kernsystem alloziert und nach Spielende wieder freigegeben. Erst wenn gfx_init_cb aufgerufen wird, steht das Array zur Verfügung und kann mit den gewünschten Grafiken gefüllt werden. Dieser etwas verworren wirkende Ablauf dient der Vereinfachung4.11.
Damit das Spiel laufen kann, wird immer eine startaction_f für den Spielstart und eine endaction_f für das Spielende benötigt. Da diese Funktionen auch in einem Simulationslauf aufgerufen werden, gibt es das Makro machine_plays_for_real(). In Abhängigkeit vom Rückgabewert sollten die Initialisierungen für den Spielablauf erfolgen.
Diverse Funktionen mit dem Präfix prg_ ermöglichen es, Aktionen zu festgelegten Zeitpunkten zu veranlassen4.12, etwa den Start und Stopp einer Walze, das Anstoßen der Startaktion, der Endaktion, der Gewinnprüfung, des Einsatzabzuges. Tatsächlich können aber auch beliebige Funktionen aufgerufen werden. Machen sie von dieser Form der Steuerung Gebrauch, sie ist sehr nützlich4.13!
Typischerweise wird die graphische Initialisierung einen nahe gelegenen Zeitpunkt für die Startaktion setzen. Diese wird wiederum überprüfen, ob genügend Guthaben für einen Spielstart vorhanden ist und sich, wenn dies nicht der Fall ist, erneut für einen nahegelegenen Zeitpunkt setzen. Hierfür gibt es das Makro prg_startgame_loop(), das auch den Timer wieder auf Null stellt, weil ich die Erfahrung machen musste, dass man das leicht vergisst4.14. Ist aber genügend Guthaben vorhanden, so werden die Aktionen für den Spielablauf gesetzt. Die Endaktion des Spieles wird dann wiederum die Startaktion setzen, so dass das Spiel in einem ewigen Kreis läuft - bis es schließlich vom Spieler beendet wird.
Damit ein Gerät nicht sofort beendet wird, kann als wantquit_f die Funktion m_cb_wantquit_setflag hinterlegt werden. Sie automatisiert das normale Verhalten, ohne dass weitere Programmierungen nötig sind. Versuchen sie nicht, etwas komplizierteres zu machen, wenn dies nicht unbedingt sein muss!
Die Funktion timer_f wird regelmäßig aufgerufen. Sie stellt eine weitere Möglichkeit zur Steuerung dar, ist aber nicht so solide wie der vorgesehene Mechanismus der Programmsteuerung eines virtuellen GSG. In einem Multitasking-System kann es durchaus vorkommen, dass die Virtuelle Zockhalle nur wenig Rechenzeit abbekommt, und dann werden Timer-Schritte für diesen Callback übersprungen. Wenn nicht sehr sorgsam programmiert wurde, würde dies zum Überspringen von vorgemerkten Aktionen führen. Die sorgsame Programmierung ist aber schon fertig, und zwar in Form der vorgesehenen Programmsteuerung für virtuelle GSG. Dennoch ist timer_f sehr nützlich, zum Beispiel immer dann, wenn Elemente des Gerätes blinken sollen. Hier wäre das Verfahren mit der vorgesehenen Steuerung einfach zu umständlich, und es kommt auch nicht auf ganz exaktes Timing an4.15.
Um das Gerät bedienbar zu machen, gibt es noch die Funktion key_f, die bei jedem Tastendruck aufgerufen wird. Sie wird für jedes virtuelle GSG benötigt, das auch in irgend einer Weise bedienbar sein soll.
Mit diesen Mitteln sollte jedes Gerät programmiert werden können.
Übrigens: Wenn mit DEBUG=1 compiliert wurde, denn kann jedes Gerät mit Ctrl-E hart abgebrochen werden, falls überhaupt noch die Tastatur abgefragt wird. Das ist ein ideales Mittel bei jenen logischen Fehlern in den programmierten Aktionen eines GSG, die ein anderes Programmende unmöglich machen. Ich habe es auch manchmal benutzt4.16.