Kann man das Programm vom Simons'-Basic-Modul unabhängig machen? Es gar auf TSB portieren? Geht das überhaupt? Und was bräuchte es dazu? - Eine schöne Aufgabe!
Optik
Bild 1: Die Original-OberflächeEin Simons'-Basic-Projekt ruft natürlich gleich TSB auf den Plan: Läuft es mit TSB? Läuft es nicht? Wenn nicht: Warum nicht? Wenn doch: Kann man was daran verbessern? Zuerst die Ausgangslage (und damit zu den schlechten Nachrichten):
Ich war doch sehr gespannt auf den ersten Start des Spiels - und wurde, ehrlich gesagt, gleich enttäuscht. Denn - schaut euch das an (Bild 1) - sowas darf doch nicht sein: Da gibt sich jemand allergrößte Mühe, ein wirklich ziemlich komplexes Spiel in C64-Form zu übertragen - und kümmert sich überhaupt nicht um die Optik! Color Clashes wohin das Auge reicht! Und zwar nicht unabsichtlich oder versehentlich, sondern überall auf dem Spielfeld! Bereits die unveränderliche Landkarte in der Mitte des Feldes eckt an allen Seiten an, bevor das Spiel überhaupt beginnt! Ebenso die einzelnen Spielkarten im Rest des Feldes (siehe das schwarze Icon am rechten Spielfeldrand in Bild 1). So geht das nicht! Das kann man auch anders machen! Selbst, wenn man hier (löblicherweise!) ein Spiel im Hires-Modus vor sich sieht! Man muss nur ein bisschen darüber nachdenken, was man auf dem Bildschirm an Information denn so braucht.
Bild 2: Die TSB-OberflächeWas der Arndt dann auch gleich getan hat: Überflüssiges raus! Wozu die schwarzen Kompasskürzel in der Mitte, wenn sie schon am Rand des Spielfeldes stehen? Weg damit. Wie sind die Spielkarten aufgebaut? Es sind 32×32 Pixel große Kacheln, die oben und links die Begrenzungsstriche enthalten, damit beim Eintragen ins Feld das Quadratraster erhalten bleibt. Nur leider werden die Kacheln komplett eingefärbt, ohne Rücksicht auf die Einschränkungen des C64-Hires-Modus! Weg damit. Es reicht doch, wenn die Kartenfarben in der Kachelmitte angezeigt werden, um sie einem Spieler zuordnen zu können (übrigens genau wie beim Original-Brettspiel auch), und ohne die Begrenzungen so grob zu missachten. Und schließlich die Kompasskürzel in den Spielfeldecken: Im Original muss man erst mal darauf kommen, dass N-W, N-E usw. Abkürzungen für Himmelsrichtungen sein sollen! Weg damit und sie stattdessen erkennbarer machen!
In der Mitte habe ich die Randlinien um einen Pixel nach außen verlegt, um die schwarze Zeichenfarbe des Zielkreuzes loszuwerden (Ursache für die Color Clashes), was dann aber mit der Form der Kartenkacheln kollidierte. Rechts und unten sind die Kacheln nämlich offen und löschen die neuen Kantenstriche beim Eintragen ins Spielfeld. Deshalb passt TSB-NSO jetzt auf, ob eine Kartenkachel an die Landkarte in der Mitte grenzt und zieht dann den Kachelrand neu.
Auch die beiden Ende-Bildschirme sind anscheinend ohne großen Aufwand entstanden: in Farbe (vermutlich aus dem Brettspiel-Handbuch oder von der Verpackung) gescannt und einfach in farbiges Hires konvertiert. Besonders die Titelbeschriftungen haben darunter ziemlich gelitten (siehe Bilder 3 und 5). Forum64-User @Tobias hat sich dieser Beschriftungen angenommen und sie so im Bild verschoben, dass sie nun ohne Color Clashes angezeigt werden.



Bild 5: Original-Lose-Screen

Bild 6: TSB-Lose-Screen
Platzproblem
Ein großer Vorteil von Simons' Basic als Modul ist, dass der 8-KB-Bereich unter dem Basic-ROM ($A000 bis $BFFF) frei bleibt, ganz im Gegensatz zur Diskversion (von der sich TSB ableitet). Diese Eigenschaft haben sich die Entwickler von NSO zunutze gemacht und dorthin die Maschinenspracheteile ihres Projekts gelegt (2080 Bytes ab $A100). Das ist eigentlich ein KO-Kriterium für eine TSB-Portierung, denn dort liegt 8 KB TSB-Code. Wenn das überschrieben wird, läuft TSB nicht mehr. Aus der Traum? Nein, nicht mit Arndt!
Die Lösung des Modul-Problems ist: ein anderes Modul, nur eines, dass sehr viel flexibler ist und nicht nur einem einzigen Zweck dient: eine REU! Mit ihr kann man die 2080 Problembytes bei der Initialisierung des Spiels puffern und bei Bedarf (beim Aufruf der Maschinenspracheroutinen in NSO) aus- und wieder einblenden! Wegen des DMA-Zugriffs der REU merkt man nichts davon, es entsteht kein spürbarer Geschwindigkeitsverlust. Hier die zwei Zeilen TSB-Code, die das ganze Platzproblem aus der Welt schaffen:
# save 2080 bytes from $a100 to $a91f 41650 proc prepare mc 41660 i0=$a100:i1=2080:memdef i1,i0,i0,3,0,0:memsave 41670 end proc # exchange 2080 bytes from $a100 to $a91f 41700 proc exchange 41710 i0=$a100:i1=2080:memdef i1,i0,i0,3:memread 41720 end proc
Mit drei TSB-Befehlen ist also das Problem vom Tisch: MEMDEF, MEMSAVE und MEMREAD. Diese Vorgehensweise wurde hier übrigens erstmalig bei TSB angewendet und eröffnet viel Potenzial in anderen Anwendungsgebieten.
Bildaufbau
Man mag es gar nicht laut sagen, aber für jedes kleinste Ereignis auf dem Spielfeld wird im Original-NSO das Floppylaufwerk herangezogen! Es befindet sich praktisch im Dauerstress! Mit dem Aufruf von sage und schreibe 67 einzelnen Dateien kommt das Laufwerk während des Spiels nicht ein einziges Mal zur Ruhe! Abgesehen davon, dass das Dauerrödeln einen als C64-User doch ziemlich in Anspannung versetzt, ist es außerdem noch schneckenlangsam! - Das ist der zweite scheinbar unlösbare Knackpunkt des Spiels. Wie löst man das dennoch?
Na, radikal! Man packt alle 67 Kartendateien in eine einzige ("tiles/reu") und holt sich die aktuellen Daten dann dort ab! Nur, wohin mit dieser Datei? Im C64 - zumal unter TSB - ist ja Platz Mangelware, siehe oben. Wir haben aber schon die REU im Einsatz, warum nicht auch für diesen Zweck? Gesagt, getan, jetzt hat die Diskette 67 Dateien weniger, das Laufwerk wird nur am Spieleanfang und -ende benötigt und alles läuft in Windeseile ab. Eine Win-Win-Situation wie sie im Buche steht! Ein Karteneintrag ins Spielfeld dauert nicht mehr mehrere Sekunden, sondern nur noch ein Augenzwinkern.
Geschwindigkeit
Und damit wären wir beim Thema Ablaufgeschwindigkeit angelangt. Abgesehen vom eben beschriebenen langsamen Diskettenzugriff hat NSO noch andere, interne Bremsfaktoren. Da wäre der exzessive Gebrauch von GOTO. Vor allem rückwärts gerichtete GOTOs kosten bei so umfangreichen Programmen wie diesem (rund 100 Blocks) richtig Zeit, da der Interpreter in dem Fall vom Anfang des Programms her die richtige Zeilennummer sucht. CALL und EXEC suchen sogar immer vom Programmstart aus, was bei Simons' Basic - um so mehr bei langen PROC-Namen - richtig ins Kontor schlägt.
Wie gut, dass es TSB gibt! TSB hat Strukturbefehle, die GOTOs und damit lange Suchaktionen vermeiden helfen, und - vor allen Dingen! - CALL und EXEC arbeiten blitzschnell, weil sie nicht das ganze Programm durchsuchen, um die richtige Stelle zu finden, sondern nur eine Tabelle mit den PROC-Adressen. Also, auch in diesem Punkt (Geschwindigkeit) ist eine Portierung nach TSB eine gute Idee!
Allein das Neumischen der Spielkarten nach jeder Spielrunde lässt sich nicht abkürzen. Das ist und bleibt ein echter Verzögerungsfaktor. Doch statt 53 Sekunden, die das Programm nach Abschluss der letzten Aktion einer Spielrunde und der Anzeige der Rundenergebnisse braucht, dauert es in TSB nur noch 7 Sekunden für dasselbe. Der Übergang von einem Spieler zum nächsten dauert in TSB 5 Sekunden und die Durchführung einer Spielanweisung 3 Sekunden. Beim Original sind das 17 Sekunden für den Übergang und 34 Sekunden für eine Anweisung (u.a. wegen der Diskzugriffe). Selbst die Latenz der Joystickreaktionen ist unter Simons' Basic deutlich spürbar (mindestens 1 Sekunde). Unter TSB reagiert der Joystick so gut wie augenblicklich.
Fehler und Verbesserungen
Tja, Fehler haben wir auch gefunden (und mit "wir" meine ich auch Forum64-User @Goodwell, der mir beim Testen der TSB-Version zur Hand gegangen ist):
· Einen schwerwiegenden Fehler sogar, denn er führt zum Absturz des Spiels: Eine zu spät erfolgende Bereichsüberschreitungsabfrage führt in Programmzeile 7110 zum Absturz. Die nötige Abfrage steht erst eine Zeile später. Nun (in der TSB-Version) erfolgt sie richtigerweise vor Zeile 7110 (in Z. 7020).
· Einen weiteren fatalen Fehler haben wir beim Kampf um den Bankrott entdeckt (und behoben). Hat ein Spieler weniger als 100.000$ und keinerlei weitere Besitztümer, gerät das Programm in eine Endlosschleife, ohne Möglichkeit diese abzubrechen. Es zwingt den Spieler dazu, etwas zu verkaufen, was aber mangels Masse gar nicht geht.
· Einen ärgerlichen Fehler gibt es in der Routine, bei der eine Bohrkonzessionen ersteigert werden kann (Z. 26500 bis Z. 26999). An dieser Stelle durften (mussten!) auch bereits bankrott gegangene Mitspieler ein Gebot abgeben. Auch das ist in der TSB-Version unterbunden (das IF in Z. 26550).
· Es fehlt ein ordentliches Randomize (jetzt mit RND(0) in TSB), denn jeder Neustart des Spiels brachte die gleiche Spielkonstellation hervor.
· Eine weitere Nachlässigkeit (der lieblosen Optik vorausgehend) drängt sich auch beim Starten des Spiels auf: LOAD "*",8 funktioniert nicht! Der Hinweis darauf, was man tun muss (LOAD "north sea oil",8), wird nur eher beiläufig erwähnt, man muss in der Hilfe schon fast danach suchen.
· Wiederum optisch nachlässig: Ein unschöner Strich rechts unten in den Fingersprites im Bildschirm des Schuldenmachens und -begleichens. Es handelte sich um eine Arbeitsvariable der Menü-Routinen, die einfach in die Spritedefinitionsblocks gelegt wurde.
· Für die Entlarvung eines ganz gemeinen Fehlers haben wir gar die Claude-KI bemüht, die den entscheidenden Tipp gab: Nach einem "Nationalise"-Vorgang (Verstaatlichung aller Eigentümer) berechnet NSO die Spielerschulden falsch (addiert sie als Guthaben! Zeilen 2500 bis 2840). In Z. 2510 wird das jetzt in TSB unterbunden.
Und die Verbesserungen? Ich hoffe, dass sie als solche aufgefasst werden:
· Ein Sieger muss als erster die 5-Millionen-Dollar-Marke beim Vermögen überschritten haben. Das ist das Ziel des Spiels. Ich denke aber, es macht keinen Sinn, NSO fortzuführen, wenn außer dir alle anderen Mitspieler bankrott sind. Die TSB-Version kürt dich in diesem Fall auch ohne 5 Millionen zum Sieger (Z. 3500 bis 3570: die Variablen A und I sorgen dafür - wie sollten sie auch anders heißen).
· Der "Tastatur-Klick" (bzw. der Feuertastenton) gefiel mir nicht, viel zu tief. Er klingt nun schon eher nach Reaktion auf eine Eingabe (Z. 46010).
· Auch die anderen Tonausgaben habe ich überarbeitet: den Error-Sound (Z. 43150), die Lose- und Win-Sounds (Z. 51010 und 51120) und auch die Musik beim Booten (die Tonlängen waren ziemlich chaotisch angegeben).
· Und natürlich die Optik: Das Spielfeld hat jetzt nicht mehr so grelle (weiße) Umrandungen, es gibt keine Color Clashes mehr, die Farbzuordnung ist dezenter.
Zusammengefasst
Insgesamt habe ich am Basic-Code von NSO sehr viele, sehr tiefgreifende Änderungen vorgenommen, nicht nur, um das Programm REU-kompatibel zu bekommen, sondern auch, um damit Abläufe schneller vonstatten gehen zu lassen. Dazu gehört auch, den Code möglichst kompakt zu bekommen, damit noch genügend freies RAM für Basic bleibt und das Programm möglichst unterbrechungsfrei (Stichwort "Garbage Collection") arbeiten kann. Trotz umfangreicher Einfügungen bezüglich der Optik und der REU-Funktionalität (s. oben) ist NSO für TSB zwei Blocks kürzer als das Original.
Auch an den zusätzlichen Maschinenprogrammen habe ich Hand angelegt, eins ist sogar komplett weggefallen ("quadtiledraw", zuständig für die Anzeige der Wetterbedingungen), da diese Aufgabe von TSB direkt erledigt werden kann. Zwei der anderen Routinen ("drawtile" und "spritemenu2") mussten an die veränderten Programmverhältnisse angepasst werden. Einzig unverändert ist die Routine "fileloader".
Da das Original unter der Lizenz GPL 3.0 steht, denke ich, dass ich meine Version von NSO ohne rechtliche Bedenken zur allgemeinen Verfügung stellen kann. Ein D64 mit NSO für TSB befindet sich hier im Downloadbereich. Man startet es mit LOAD":*",8 und RUN. Dabei werden sowohl TSB als auch NSO geladen und ausgeführt. Die empfehlenswerte Anleitung (auf Englisch) findet sich hier auf der Github-Seite des Originals.
Hinweis: Wer nach einem abgeschlossenen Spiel direkt eine weitere Runde spielen möchte, muss von Hand das Spielbrett und seine Färbung nachladen:
SCRLD DEF $C0,4,1,2: SCRLD 1,use,5,"board":SCRLD RESTORE
Schließlich kann man mit RUN neu starten.
Das ursprüngliche Bootlogo (Bild 7) haben wir - um die Veränderungen im Programm von Anfang an zu verdeutlichen - auch durch ein neues ersetzt, für das wir den PETSCII-Künstler t0m3000 gewinnen konnten (Bild 8).
Bild 7: Das Bootlogo des Originals (mit Angabe der Portierung: AD).
Bild 8: Das neue Bootlogo für die TSB-Version (T3K ist das Kürzel für t0m3000).
Download North Sea Oil TSB (als D64-Datei)