Hallo Besucher, der Thread wurde 8,3k mal aufgerufen und enthält 43 Antworten

letzter Beitrag von Sokrates am

SuperPad64 und Race+ - Entwicklungsinfos

  • Hast du weitere Literatur verwendet?

    Nein, außer wenn Internetseiten wie Codebase64 oder das Assembler-Wiki unter Literatur fallen...


    Was hat dich dazu inspiriert?

    Das waren die Spiele "Rally Speedway" und "Cave" (siehe erster Eintrag oben).


    Gab es Probleme mit den Tools (mich interessiert natürlich der ACME)?

    Als ich mit ACME begonnen habe, hätte ich mir eine Dokumentation dazu gewünscht. Ich bin dann aber mit dem Wiki Eintrag sehr gut klargekommen. Eine Anfrage für einen Spezialfall (wie werden 2-Byte-Codes statt 3-Byte Codes generiert, z.B. ADC $F0 statt ADC $00F0) hat mir Mac Bacon innerhalb einer halben Stunde (!) beantwortet. Mein Fazit: ACME ist ein super Werkzeug! Dir natürlich ein Dankeschön für Deine Compilationen, die verwende ich ;-)


    Gerade den Teil mit CSAM gelesen... Hab das Ding seit Jahren in Benutzung, buchstäblich tausende Frames umgewandelt. Leider noch etwas unausgegoren, das Tool

    Man merkt dem Werkzeug schon an, dass er es erst mal für sich und seine Anwendungsfälle geschrieben hat (ich hatte mich z. B. anfangs gewundert, dass das Werkzeug nicht alle meine geladenen Bilder verwendet hat). Umso netter von ihm, dass er das Werkzeug für alle öffentlich gemacht hat.


    Algo arbeitet gerade an einer neuen Version. Meinen Input hat er schon erhalten, Du könntest Ihm doch auch Dein Feedback geben? Es ist sicher für ihn auch eine Motivation weiterzumachen, wenn er sieht, wieviele Leute sein Werkzeug einsetzen.

  • gefällt mir auch immer. Dem Nicht-Programmierer entgeht ja schnell was hinter so einem Spiel steckt ausser scrolling :)
    Und der/die Programmierer lernt von anderen Ansätzen dazu, oder merkt welche Probleme sich bei welchem Genre auftun. Weiter so :-)

  • gefällt mir auch immer.

    Danke! Vielleicht kannst Du ja dann zu Caren etwas Ähnliches machen? Ein paar sehr interessante Details waren zwar schon hier und da zu lesen (Wegeberechnung, Assembler Code-Generierung, trickreiche Sprite-Maskierung, Nutzung von extrem vielen Animationen von v3to, usw.), aber da gibt es doch bestimmt noch viel mehr!


    Dem Nicht-Programmierer entgeht ja schnell was hinter so einem Spiel steckt ausser scrolling

    Hm, da fällt mir ein, im nächsten Abschnitt könnte ich ja etwas zum Scrolling schreiben...

  • In Ausgabe 1 der ReGame steht bisher der ausfuehrlichste Artikel (auf Englisch).
    Das PDF ist frei zum download wenn Ausgabe #2 erscheint. Die wie ich finde spannendsten Aspekte habe ich meist irgendwo schon erwaehnt was die reine Engine angeht.
    Aktuell stecke ich die Zeit eher in die Entwicklung als Beschreibung aber man weiss ja nie :)

  • Aktuell stecke ich die Zeit eher in die Entwicklung als Beschreibung aber man weiss ja nie

    Ist ja eher was für die Zeit danach...


    In Ausgabe 1 der ReGame steht bisher der ausfuehrlichste Artikel (auf Englisch).

    Ein guter Tipp, wenn Du magst kannst Du das ja nochmal im Forum posten, wenn das PDF verfügbar ist.

  • Nachtrag zum Artkel von Game Programming Gems 4.
    Ich hab einen der Autoren des Artikels angeschrieben, vielleicht gibt es grünes Licht, den hier öffentlich zu machen.
    Ansonsten mich per Mail fragen.

  • Nachtrag zum Artkel von Game Programming Gems 4.
    Ich hab einen der Autoren des Artikels angeschrieben, vielleicht gibt es grünes Licht, den hier öffentlich zu machen.
    Ansonsten mich per Mail fragen.

    Oha, danke! Das wäre ja eine tolle Ergänzung!

  • Scrolling


    Es gibt verschiedene Ansätze, butterweiches Scrolling auf dem C64 zu implementieren. Diese wurden auch schon hier im Forum diskutiert. "RACE+" verwendet keinen dieser Ansätze und hat daher auch nicht immer ein garantiert weiches Scrolling. Warum?


    Das hat im Wesentlichen zwei Gründe: zum einen muss die Scroll-Engine - anders als etwa bei horizontal scrollenden Shootern - beliebige Scroll-Geschwindigkeiten ermöglichen. Zum anderen hängt die benötigte Anzahl der Rechenzeit zwischen zwei Scroll-Schritten von der Anzahl der Spieler ab. Das gilt verstärkt beim Einsatz von relativ rechenaufwändigen Robotern.


    Die variablen Scroll-Geschwindigkeiten entstehen durch die variablen Geschwindigkeiten der Fahrzeuge. Scrolling setzt ein, sobald das erste Fahrzeug eine vorgegebene X-Positions-Grenze innerhalb des Bildschirmes erreicht. Die Grenze ist so gewählt, dass das führende Fahrzeug durchaus noch auf die kommende Strecke reagieren kann, aber durch die geringe Vorausschau zumindest ein kleiner Vorteil für hinten liegende Fahrzeuge entsteht. Hat noch kein Fahrzeug diese Grenze erreicht, so wird nur relativ die X-Position geändert. Das Scrolling wird vom Fahrzeug mit der größten neu berechneten X-Position bestimmt.


    Da sich das Fahrzeug aber nicht über die gegebene Grenze bewegen kann werden entsprechend alle anderen Fahrzeuge relativ im Bildschirm nach hinten versetzt. Durch das Scrolling bewegen sie sich natürlich dabei bezogen auf die Gesamtstrecke immer noch korrekt gemäß ihren Geschwindigkeiten. Stoßen Fahrzeuge durch die relative Rückversetzung an den linken Bildschirmrand, so erhalten sie Strafpunkte und werden nach rechts gestoßen. Hier gilt es zu beachten: wurde diese Stoßgeschwindigkeit zu gering gegenüber der maximalen Fahrzeuggeschwindigkeit gewählt, so können Fahrzeuge nach links aus dem Spiel verschwinden.


    Die Scroll-Geschwindigkeit hängt also direkt von der Geschwindigkeit eines Fahrzeuges ab. Je nach Fahrzeug-Parametrierung kann es sein, dass der Bildschirm nicht nur um eine Spalte verschoben werden muss, sondern durchaus um mehrere Spalten. Damit muss beim Scrolling mal mehr und mal weniger Speicher verschoben werden, was entsprechend eine Bandbreite bei den Laufzeiten ergibt. Damit können auch mal mehr oder weniger Frames für die Berechnung verwendet werden, was das geübte Auge als "Ruckler" wahrnehmen kann.


    Der zweite Grund ist die Abhängigkeit der Rechenzeit von der Anzahl der Spieler und der Roboter: der Aufwand für Bewegungen, Kollisionen und die Wegeberechnungen wachsen überproportional mit der Anzahl. Überproportional deshalb, da für manche Funktionen Sortierungen nötig sind. Damit kann auch hier die Anzahl der benötigten Frames variieren. Sind acht Spieler aktiv, so wird das Spiel doch recht langsam. Nach meinen Beobachtungen wird das zum Teil durch die erhöhte Anstrengung der einzelnen Spieler kompensiert: in der Hitze des Gefechtes wird die Langsamkeit nicht ganz so wahrgenommen.


    Um die Rechenzeitproblematik beim Scrolling in Grenzen zu halten, verwendet die Scroll-Engine zum einen Double-Buffering um Flackern zu vermeiden, zum anderen wird das Color-Ram nicht mit verschoben, um Rechenzeit zu sparen. Eine Lösungsmöglichkeit für weicheres Scrolling wäre, immer die maximal möglichen Berechnungszeiten zwischen zwei Scroll-Schritten als Maßstab zu nehmen. Da diese jedoch bei Nutzung von 7 Robotern sehr hoch ist, wollte ich das den Spielern für eine Fahrt mit nur 2-3 Robotern nicht zumuten. Ein weiterer Punkt wäre der verstärkte Einsatz von Speedcode (was nichts anderes ist als ein cooler Name für das aufrollen von Schleifen). Speedcode kommt beim Scrolling nur für das Einfügen neuer Spalten zum Einsatz. Grund: Speedcode verbraucht viel Speicher, im Spiel wird jedoch jeder Mehrbedarf an Speicher direkt von der Länge der Rennstrecke abgezogen (da diese ja in den noch frei verfügbaren Speicher generiert wird) - auch hier also wieder ein Kompromiss zwischen Speicher und Laufzeit und den dazugehörigen Funktionalitäten im Spiel.

  • Musik und Soundeffekte


    Sidwave ist für die Musik und die Soundeffekte im Spiel verantwortlich. Hier ein kurzer Beitrag von ihm:


    "Als ich mit der Musik für RACE begann, habe ich nur auf den Titel-Bildschirm gestarrt ... und ich dachte an Monaco Grand Prix von Jeroen Tel ... dann habe ich darauf basierend die Titel-Melodie entwickelt. Sie ist kurz und solle nach "Rennen" klingen, dass alles kam aus dem Nachdenken über Jeroens Monaco Grand Prix heraus ... Nun, was den Rest angeht, der Programmierer des Spiels, Steffen Görzig, hatte mir seine Wünsche mitgeteilt, und es gab zusätzlich die Bezeichnungen der Rennstrecken, wie: Wüste, Stadt usw. ... also habe ich zuerst über eine Wüste nachgedacht, und das hat mich automatisch dazu veranlasst, zuerst das Stück für die Wüstenstrecke zu erstellen ... genauso bin ich mit dem Rest vorgegangen. Es läuft ziemlich automatisch aus meiner Intuition heraus. Wie die SFX sein sollten war sehr spezifisch von Steffen beschrieben. Daher habe ich alles getan, was ich konnte, damit sie funktionieren und passen. Am Ende hatten wir ein gutes Ergebnis mit dem sowohl der Spielmacher als auch ich glücklich waren. Ich bin immer noch glücklich, diesen Spiele-Soundtrack gemacht zu haben, war eine tolle Sache für mich!"


    PAL- und NTSC-Systeme sind bekanntermaßen unterschiedlich, das gilt auch für die Musik. Die Musikroutine wird bei NTSC-Systemen jeden 6. Bildaufbau nicht aufgerufen. Damit wird die Musik bei PAL- und NTSC-Systemen in Summe gleich schnell gespielt, ohne weiteren Speicherplatz zu benötigen. Die Idee dazu habe ich hier aus dem Forum64, ich kann mich aber leider nicht mehr an einen Namen erinnern. Natürlich wird dadurch die Qualität der Musik bei NTSC gemindert, aber immerhin läuft das Spiel komplett auch auf allen NTSC-Varianten.


    Im Spiel kann man von Musik auf Motorgeräusche umschalten. Doch wie sollen die Motorgeräusche von 8 Fahrzeugen auf die nur 3 Stimmen des SID-Chips abgebildet werden? Die Umsetzung der Motorgeräusche geschieht in Analogie zur Drehzahl eines Motors mit nur einem Gang: langsame Geschwindigkeit = niedrige Drehzahl = tiefe Frequenz, hohe Geschwindigkeit = hohe Drehzahl = hohe Frequenz. Beim Hören dominieren die hohen Frequenzen, was schneller Fahrt entspricht. Damit ergibt sich folgende Lösung: die Fahrzeug werden erst nach ihrer Geschwindigkeit sortiert, dann werden die Geschwindigkeiten der drei schnellsten Fahrzeuge mit eine entsprechenden Frequenzen auf die drei Stimmen des SID-abgebildet. So ist sichergestellt, dass immer ein Motorgeräusch entsteht, auch wenn nur ein Fahrzeug sich bewegt. Langsame Fahrzeuge gehen auch akustisch "unter".


    MP3-Versionen der Musikstücke sind übrigens in den beiden "RACE+"-Editionen enthalten.

  • SuperPad64


    Was ist das Wichtigste bei einem Mehrspieler-Spiel? Genau, mehrere Mitspieler! Für die braucht man natürlich passende Eingabegeräte in ausreichender Anzahl und deswegen kamen Sebastian @poly.play und Steffen @Sokrates auf mich zu und fragten, ob ich nicht ein Layout für einen 8-fach-Super-Nintendo-Gamepad-Adapter machen könne, die Schaltung dazu gäbe es bereits. Ja, OK, warum nicht...


    Die ursprünglich vorgesehene Schaltung von Wolfram Sang (ninja/dreams) sah vor, bis zu acht SNES-Gamepads an die zwei Controlports des C64 anzuschließen. Durch entsprechende Programmierung der Joystickleitungen konnten so den Gamepads ihre Daten entlockt werden. Leider stellte sich nach einem Testaufbau heraus, dass zwar das Auslesen der Gamepads funktionierte, es bei eingesteckten Gamepads aber Probleme mit der Tastaturabfrage gab, was schon das Laden eines Spiels unmöglich machte, da man den LOAD-Befehl nicht korrekt eintippen konnte.


    Die Ursache für dieses Verhalten ist, dass sich beim C64 Tastaturmatrix und Joysticks die Leitungen teilen und sich dabei leider in die Quere kommen können. Normale Joysticks stören die Tastatur nicht solange sie in Mittelstellung stehen und alle Schalter geöffnet sind, die SNES-Gamepads kennen jedoch leider keinen hochohmigen Zustand, so dass sie immer entweder eine logische '1' oder '0' auf die Leitung legen, was in Folge die Tastaturabfrage stört.


    Die Lösung dieses Problems war die Gamepads einfach nicht an die Joystick-Anschlüsse sondern an den Userport anzuschließen, der doch für genau solche Basteleien existiert. Zur Sicherheit wurde den Datenleitungen noch Treiberbausteine spendiert und eine selbstrücksetzende Sicherung eingebaut, um den C64 möglichst vor Schäden zu schützen.


    Bestückte Leiteplatte:


    Fertig eingebaut in Gehäuse:



    Ein Super-Nintendo-Gamepad ist sehr simpel aufgebaut, es besteht im Prinzip nur aus zwölf Tasten und einem Schieberegister. Das Latch-Signal speichert den aktuellen Zustand aller Tasten und das Takt-Signal schiebt immer das nächste Bit auf die Datenleitung. Das Timing ist nicht kritisch und wird einfach in Software erledigt, wobei der Takt sogar direkt vom CIA-Baustein des Userports automatisch nach jedem Lesezugriff generiert wird. Wenn nicht alle 12 Tasten interessieren, kann die Abfrage auch jederzeit früher abgebrochen werden, was etwas Zeit und wenn man sich auf 8 Bits beschränkt auch etwas RAM spart.



    Zum Auslesen aller 12 Tasten aller 8 Gamepads muss man also nur den Latch-Puls erzeugen und dann 12 mal vom Userport lesen was jeweils den Zustand einer Taste aller 8 Gamepads liefert (D0 = Controller 1, D1 = Controller 2 usw.).


    Wenn man mehr als 12 Bits ausliest, liefern die Gamepads zunächst vier Einsen und danach nur noch Nullen. Dieses Verhalten kann man gut zur Detektion von eingesteckten Gamepads ausnutzen: wenn man z.B. 20 Bits liest und nur die letzten 8 betrachtet, liefert ein SNES-Gamepad immer den Wert $F0.


    Alle Daten des SuperPad64 mit Codebeispielen liegen zur freien Verwendung unter:
    http://wiki.polyplay.xyz/doku.php/superpad64

  • Multi-Adapter Unterstützung


    Das Spiel kann direkt mit dem SuperPad64 Adapter zusammen bestellt werden. Es werden aber auch andere gängige Mehrspieler-Adapter unterstützt, um eine möglichst breite Spielbarkeit zu gewährleisten. Die Wahl fiel dabei auf den Inception-Adapter (wegen der 8 Joystickanschlüsse) und den 4-Spieler Adapter von Protovision/icomp (ist recht verbreitet und wird auch im Emulator VICE unterstützt). Das Spiel kann dank dieser Adapter-Auswahl mit bis zu 8 Spielern direkt am C64 und mit bis zu 4 Spielern am PC gespielt werden.



    Um die Spieler nicht unnötig mit Konfigurationen zu belästigen sollte eine automatische Detektion der Adapter stattfinden. Für den SuperPad64 wurde dank Oliver Tscherwitschke schnell eine Lösung gefunden. Der Inception erlaubt ebenfalls eine Detektion. Für den 4-Spieler Adapter ist mir keine Möglichkeit der Detektion bekannt. Glücklicherweise ist das ist in dieser Konstellation auch nicht nötig, da sich zum einen die anderen beiden Adapter detektieren lassen. Zum anderen erzeugt die Abfrage der zusätzlichen zwei Anschlüsse des 4-Spieler Adapters bei Abwesenheit des Adapters keine Eingaben für diese zusätzlichen Anschlüsse. Damit kann die 4-Spieler Adapter Ausleseroutine auch für die zwei Joysticks in den Standard-Controlports genutzt werden, falls gar kein Adapter vorhanden ist.


    Die Detektion läuft in folgenden Schritten ab:
    1) SuperPad64 vorhanden? Falls ja, diesen initialisieren und nutzen. Falls nein, weiter mit 2)
    2) Inception vorhanden? Falls ja, diesen initialisieren und nutzen. Falls nein, weiter mit 3)
    3) 4-Spieler Adapter initialisieren und nutzen


    Die Detektion der beiden ersten Adapter kann sicher feststellen, wenn kein Adapter angeschlossen ist. Es könnte allerdings theoretisch noch passieren, dass ein anderes angeschlossenes Gerät versehentlich als Adapter erkannt wird (mir ist derzeit kein Fall bekannt).


    Für die Spieler ergibt sich dadurch folgende Priorisierung:
    1) SuperPad64
    2) Inception
    3) 4-Spieler Adapter und Standard-Controlports
    4) Nur Standard-Controlports


    Sind mehrere Adapter angeschlossen, so wird der Adapter mit der höheren Priorität genommen (sind z. B. SuperPad64 und der Inception Adapter gleichzeitig angeschlossen, so kann nur mit dem SuperPad64 gespielt werden). Ist kein Adapter angeschlossen, kann mit den Standard-Controlports gespielt werden. Source Code für die Detektion und die Abfrage habe ich auf Codebase64.org zur Verfügung gestellt.


    Um die Bedienung bei mehreren Spielern vor Ort zu erleichtern, ist das Spiel ist so gestaltet, dass es auch komplett nur mit Joysticks/Joypads gesteuert werden kann. Die Unterstützung der Adapter ist also auch schon beim Titelbild vorhanden (Feuer für Spielstart). Einzige Ausnahme: der Abbruch eines aktuellen Rennens erfolgt über die "Q"-Taste. Das erhöht allerdings nur die Bedienbequemlichkeit und wird für die eigentliche Spielbarkeit nicht benötigt.

  • Spieldesign


    Die grundlegende Spielidee wurde schon in einem vorangegangenen Abschnitt beschreiben. Hier möchte ich erläutern, wie sich das Spiel im Lauf der Entwicklung durch Design-Entscheidungen verändert hat. Die Änderungen kamen zum einen aus eigenen Einsichten heraus zustande, größtenteils waren sie aber durch die Tester motiviert.


    In "Rally Speedway" wird das Spiel unterbrochen, sobald ein Spieler den Rand erreicht. Der langsamere Fahrer erhält eine Zeitstrafe (penalty) und das Rennen wird mit neuer Startaufstellung an derselben Stelle fortgeführt. So wurde es auch zuerst im Meisterschaft-Modus von "RACE+" implementiert. Bei acht Spielern führt dies allerdings zu andauernden Unterbrechungen, ein Spielfluss kommt nicht zu Stande. Daher wurde die Unterbrechung durch einen kräftigen Stoß in die Scroll-Richtung ersetzt, die Zeitstrafe wurde beibehalten.


    Ursprünglich war für Rennstrecken nur eine lange Runde geplant. Das ist für die prozedurale Generierung von Rennstrecken kein Problem: jeder verfügbare Speicher wird einfach "vollgeneriert". Mit jedem neuen Feature schrumpfte der verfügbare Speicher jedoch. Am Ende halfen auch radikale Maßnahmen nicht mehr (Reduktion der Bilder bei der Flaggenanimation von 10 auf 4 und herausnehmen eines Musikstückes): die Strecken wurden zu kurz. Was tun? Die Lösung war, eine Strecke gleich mehrere Runden fahren zu lassen. Das sind Spieler auch aus anderen Rennspielen gewohnt. Da die Rundenanzahl sogar noch einstellbar ist, wurde so aus einer Notlösung ein Feature.


    Anfangs gab es nur den Meisterschaft-Modus, die Ergänzung um den Modus Autoschlacht kam erst später dazu. Der Gedanke war den Spielern eine zusätzliche Spielerfahrung zu geben (zwei zum Preis von einem - sozusagen), ohne dafür die Spiele-Engine von Grund auf neu entwickeln zu müssen: grundlegende Techniken konnten wiederverwendet werden.


    Die visuellen Rückmeldungen für die Spieler waren anfangs zum Teil zu wenig offensichtlich. So wurde zum Beispiel bei Änderungen der Einstellungen zum Fahrverhalten eine Visualisierung mittels "SPEED" und "GRIP" hinzugefügt (siehe Bilder). Bei der Autoschlacht wurden Schäden zwar durch den Score angezeigt, aber im Schlachtgetümmel hat kein Spieler Zeit auf diesen zu achten. Daher blinken die Fahrzeuge bei Schäden nun, je schneller das Blinken desto höher der aktuelle Schaden.


    Die erste Version "RACE" war eine reine Mehrspielerversion. Ein einzelner Spieler konnte zwar fahren, aber der Spaß ganz alleine zu fahren ist begrenzt - auf Fahrspaß und Highscore. Die Motivation im Mehrspielerfall zu gewinnen hat im Wesentlichen zwei Gründe: zum einen das Erreichen eines Highscores, vor allem aber geht es darum seine Freunde zu besiegen! Die große Anzahl der Strecken im Spiel hat auch den Hintergrund, dass bei Partys eine zufällige Strecke ausgewählt werden kann, welche dann mit hoher Wahrscheinlichkeit noch keiner der Spieler vorab gefahren hat - so hat niemand von vornherein einen Vorteil. Da, wie schon erwähnt, der typische Anwendungsfall bei C64 Spielen heute Einzelspieler sind, kamen Roboter hinzu.


    Fährt man aber nur mit Robotern, so entfällt die wesentliche Motivation: Freunde besiegen. Deshalb wurde ein zusätzliches Belohnungssystem eingeführt: das Sternesystem. Gewinnt man gegen mindestens zwei Roboter so erhält man einen Stern. Hat man genügend Sterne gesammelt, so werden weitere Strecken freigeschaltet. Zu Beginn sind bereits 64 Strecken pro Umgebung spielbar. Das ist ein Kompromiss: zum einen sollen für Partys immer noch genügend Strecken vorhanden sein, damit niemand durch vorheriges üben Vorteile hat. Zum anderen sollen es aber auch nicht zu viele Strecken sein, damit die Motivation bleibt neue Strecken freifahren zu wollen und man sich nicht mit den bereits vorhandenen begnügt. Und es wurde natürlich eine Belohnung eingebaut, wenn alle Sterne eingesammelt sind - auch wenn ich mir nur schwer vorstellen kann, dass sich jemand auf regulärem Wege die Zeit dafür nimmt :-).


    Bei der Benutzerführung in den Menüs gab es Detailverbesserungen, wie etwa eine beschleunigte Steckennummeränderung bei längerer Betätigung oder die Rückkehrmöglichkeit in das vorherige Menü. Diese Feinheiten haben zwar keine Auswirkungen auf das Spiel selbst, das Spiel fühlt sich aber im Gesamteindruck "besser an".


    Der meiste Testaufwand ging in die Optimierung von Fahrparametern. Hier ist die Anzahl an Einstellmöglichkeiten groß und die Vorlieben der Tester sind unterschiedlich. Am Ende stehen nun drei mögliche Einstellungen zum Fahrverhalten, von welchen hoffentlich die eine oder andere Einstellung den Geschmack des geneigten Spielers anspricht.


    Natürlich haben es auch viele Ideen nicht bis ins Spiel geschafft, wie zum Beispiel Waffen oder nützliche Extragegenstände, unterschiedliche Fahrzeugtypen mit individuellen Einstellungen pro Fahrzeug, ein Karrieremodus, Windschattenfahren, Extra-Beschleunigung für zurückliegende Fahrzeuge und vieles mehr. Als Hobby-Projekt wäre das Spiel dann nie fertig geworden...

  • Huhu,


    mich wuerden ein paar programmiertechnische Entscheidungen interessieren.
    Welche Teile davon hast Du in C, welche in ASM umgesetzt?
    Woraus ergaben sich fuer Dich dadurch Vor- oder Nachteile?
    Ich vermute es war eine enorme Zeitersparnis bei den bereits von Dir genannten Berechnungen, aber gab es auch Abstriche/Nachteile?
    Zum Beispiel in Hinblick auf Scrolling oder Rundenlaenge?
    Wuerdest Du es bzw diese Mischung nochmal so angehen?


    Lieben Dank so oder so, auch wenn Du keine Zeit fuer diese Fragen haben solltest.

  • Kann man das SuperPad64 auch alleine erwerben? und was kostet er?
    Wirst du welche davon auf die DoReCo mitbringen, falls du dort bist?

    Auf der DoReCo bin ich leider nicht, das SuperPad64 kann bei PolyPlay für 45 Euro zzgl. Versand käuflich erworben werden. Wer lieber selbst bastelt, findet hier die Bauanleitung und Bestückungsliste. Unter diesem Link findet sich auch der Assembler-Code für die Ansteuerung des SuperPad64. Für viele Anwendungsfälle finden sich optimierte Routinen (von 4 Pads 5 Bit lesen bis hin zu von 8 Pads 12 Bits lesen). Das war Sebastian, lvr und mir wichtig: die Zeit für das Hobby ist oft beschränkt, da ist man als Coder oft dankbar, wenn man einfach mal Code verwenden kann ohne sich vorher tief in ein Thema "reinfuchsen" zu müssen. Der Code für eine Multi-Adapter Unterstützung (SuperPad64, Inception, 4-Spieler-Adapter) findet sich hier.

  • Heyo,


    Lieben Dank so oder so, auch wenn Du keine Zeit fuer diese Fragen haben solltest.

    die Zeit nehme ich mir natürlich! :-)


    Oha, viele gute Fragen, die ich mir zum Teil schon selbst gestellt habe.


    >Welche Teile davon hast Du in C, welche in ASM umgesetzt?
    Erst habe ich alles in C geschrieben (außer dem Titelbild/-musik, das war gleich Assembler). Dann habe ich nach und nach viele Routinen mittels Inline-Assembler optimiert. Die Struktur des Programms habe ich bis auf wenige Ausnahmen belassen, die Optimierungen waren daher meist lokal innerhalb einer Funktion. Es ging in den meisten Fällen um Speicheroptimierung, ab und zu auch um Geschwindigkeit (z.B. bei der Fahrphysik).


    >Woraus ergaben sich fuer Dich dadurch Vor- oder Nachteile?
    Vorteil durch C: ich konnte erst mal aus dem Python-Programm fast 1:1 die Fahrphysik übernehmen. Die animierte Flagge im Startmenü, bei welcher ein Teil der Flagge bei laufender Animation durch Text ersetzt wird ist eine heftige State-Machine, die hätte ich mir in Assembler erst mal nicht zugetraut (bzw. dann halt anders gelöst). Nachteile beim Einsatz von C: mehr Speicherverbrauch und Laufzeit, teilweise mangelnde Transparenz (verwendete Zeropage-Adressen, Stackbedarf), Optimierungen haben mit Inline-Assembler zusammen teilweise fehlerhaften Code generiert.


    >Ich vermute es war eine enorme Zeitersparnis bei den bereits von Dir genannten Berechnungen, aber gab es auch Abstriche/Nachteile?
    Nachteile beim Einsatz von Assembler? Nur, dass es wie geschrieben manchmal fehlerhaften Code bei C-Compiler-Optimierungen zusammen mit Inline-Assembler Code gab.


    >Zum Beispiel in Hinblick auf Scrolling oder Rundenlaenge?
    Der C-Compiler erzeugt schon Speicher-Overhead. Das wirkt sich bei prozedural generierten Strecken direkt auf die Rundenlänge aus. Hier habe ich nach und nach allen C-Code durch Inline-Assembler ersetzt, der Speicheroptimierung gebracht hat ohne die Struktur selbst ändern zu müssen - das wäre mir zu aufwändig gewesen. Teile vom Scrolling sind Speed-Code (der einzige Speed-Code im Programm), generell ist beliebig schnelles Scrolling sowieso schwerlich machbar, zumal mit möglichst wenig Speicher.


    >Wuerdest Du es bzw diese Mischung nochmal so angehen?
    Ohne den C-Compiler hätte ich vielleicht gar nicht wieder mit Retro-Computing begonnen. Das war für mich der perfekte Einstieg: ein bekannte Umgebung, in welcher ich schnell meine Ideen umsetzen konnte. In der damaligen Situation würde ich wieder so einsteigen, nach heutigem Wissen würde ich direkt mit Assembler loslegen.

  • Total interessant das Ganze :thumbup: .


    Hier habe ich nach und nach allen C-Code durch Inline-Assembler ersetzt, der Speicheroptimierung gebracht hat ohne die Struktur selbst ändern zu müssen

    Hast du da vielleicht mal einen vorher/nachher Code-Schnipsel als Beispiel?


    nach heutigem Wissen würde ich direkt mit Assembler loslegen.

    Mir geht's gerade andersrum durch den Kopf. Es gibt einfach vieles, was in direktem Assembler (für mich) einfach ätzend umzusetzen ist. Da ist mir jegliche Hochsprache willkommen, auch wenn es nur (gut kompiliertes) BASIC sein mag. Wenn es (in dem Programmteil) nicht wirklich auf Speed ankommt und der Code dadurch nicht exorbitant größer als Assembler wird, kann ich/man damit gut leben. 'C' werde ich mir im Leben nicht mehr antun. 'Python' bin ich dran. Wenn man z. B. vom 'BASIC BOSS' die Direktiven befolgt/nutzt/ausreizt, kann das ein interessantes Rennen mit anderen/'richtigen' Hochsprachen sein, behaupte ich mal.


    In der damaligen Situation würde ich wieder so einsteigen, nach heutigem Wissen würde ich direkt mit Assembler loslegen.

    Wirklich? Es ist doch wahrscheinlich einfach, einen gegebenen Codeteil nach Assembler umzufrickeln, als from-scratch zu coden, oder nicht?

  • Total interessant das Ganze .

    Dsa freut mich!


    Hast du da vielleicht mal einen vorher/nachher Code-Schnipsel als Beispiel?

    Ein kurzes Beispiel aus der "Siegerehrung" beim Battle: Das Gewinnerfahrzeug kann durch drücken des Feuerknopfes sein Auto drehen, so kann der Sieger leicht identifiziert werden. Gewinnen die Roboter, so drehen sich alle Roboter. Als C-Code:


    Dasselbe Beispiel als C-Code gemischt mit Inline-Assembler:


    Es sieht natürlich nicht sehr elegant aus, aber immerhin kann man C-Code mit allen Macros und Kontrollflußanweisungen gleichzeitig mit Assembler verwenden!


    Mir geht's gerade andersrum durch den Kopf. Es gibt einfach vieles, was in direktem Assembler (für mich) einfach ätzend umzusetzen ist. Da ist mir jegliche Hochsprache willkommen, auch wenn es nur (gut kompiliertes) BASIC sein mag. Wenn es (in dem Programmteil) nicht wirklich auf Speed ankommt und der Code dadurch nicht exorbitant größer als Assembler wird, kann ich/man damit gut leben. 'C' werde ich mir im Leben nicht mehr antun. 'Python' bin ich dran. Wenn man z. B. vom 'BASIC BOSS' die Direktiven befolgt/nutzt/ausreizt, kann das ein interessantes Rennen mit anderen/'richtigen' Hochsprachen sein, behaupte ich mal.

    Das kann ich nachvollziehen und ist ja auch der Grund, warum Hochsprachen erfunden wurden :-) Bei meinen Hobby sehe ich ein optimales Ergebnis allerdings als Herausforderung. Natürlich hängt es auch von der Aufgabe ab: RACE+ ist ein Autorennen für bis zu 8 Spieler oder Robotern und generierten Rennstrecken. Damit ist klar, dass letztlich die Laufzeit UND der Speicher optimiert werden müssen, das geht in Assembler am besten. Mir hat bei der Optimierung des C-Codes am Ende auch die Kontrolle gefehlt: C nimmt einen viel ab (deshalb ist es ja leichter Programme hinzuschreiben), was bei der Optimierung dann Probleme bereitet: ich musste z.B. den C-eigenen Stack händisch umbiegen, wohin die C-Variablen geschrieben werden muss aus dem Compiler-Output gelesen werden, um z.B. nicht ausversehen dorthin die Rennstrecke zu generieren. Alles machbar, aber letztlich auch ein Lernprozess und damit zeitaufwändig.


    Bei neuen Projekten schalte ich inzwischen als erstes alles ab (ROMs, Interrupts): dann gehört die Maschine ganz mir und wenn dann ein Fehler auftritt liegt es ganz allein an meinem Code :-)


    Wirklich? Es ist doch wahrscheinlich einfach, einen gegebenen Codeteil nach Assembler umzufrickeln, als from-scratch zu coden, oder nicht?

    Erst C-Code und dann Teile in Assembler umsetzen hat den Vorteil, dass schneller etwas läuft. Allerdings muss die Portierung dann auch noch gemacht werden und bringt unschöne Einschränkungen mit sich (s.o.). Wenn man gleich in Assembler coded ist man im Endeffekt bei meiner Anwendung "schnelles Rennspiel" wahrscheinlich sogar schneller, allerdings sieht man erst später Ergebnisse als in C.

  • Dasselbe Beispiel als C-Code gemischt mit Inline-Assembler

    Und das hat in etwa wie viele Bytes eingespart? Um Takte dürfte es an der Stelle wohl eher nicht gegangen sein, oder doch?


    Es sieht natürlich nicht sehr elegant aus, aber immerhin kann man C-Code mit allen Macros und Kontrollflußanweisungen gleichzeitig mit Assembler verwenden!

    Die Lesbarkeit geht beim Mix jedenfalls ordentlich flöten :cry .


    Bei neuen Projekten schalte ich inzwischen als erstes alles ab (ROMs, Interrupts): dann gehört die Maschine ganz mir und wenn dann ein Fehler auftritt liegt es ganz allein an meinem Code

    Da sträube ich mich irgendwie immer vor. Warum, weiß ich auch nicht :nixwiss::freak .


    Wenn man gleich in Assembler coded ist man im Endeffekt bei meiner Anwendung "schnelles Rennspiel" wahrscheinlich sogar schneller, allerdings sieht man erst später Ergebnisse als in C.

    Kann ich leider nicht beurteilen. Ich vermute aber, dass man es in C aber vielleicht auch mit weniger Fehlersuche zu tun hat, wo es in Assembler mal z. B. an einem blöden Carry-Flag hakt, wo man (übertrieben) drei Tage nach sucht. Oder?


    Gern noch mehr aus deinem Nähkästchen :bia .

  • Und das hat in etwa wie viele Bytes eingespart? Um Takte dürfte es an der Stelle wohl eher nicht gegangen sein, oder doch?

    Das hat 10 Bytes gepart. Hört sich nicht viel an, aber in Summe habe ich so mehrere Kilobyte gepart. An den meisten Stellen ging es um Speicherersparnis, nur manchmal um Speed (Scrolling, Physik, Roboter, ...).


    Die Lesbarkeit geht beim Mix jedenfalls ordentlich flöten .

    Ja, das ist ein Nachteil. Ich habe für die Verständlichkeit oft die Original C-Version auskommentiert behalten.


    >Bei neuen Projekten schalte ich inzwischen als erstes alles ab (ROMs, Interrupts): dann gehört die Maschine ganz mir und wenn dann ein Fehler auftritt liegt es ganz allein an meinem Code

    Da sträube ich mich irgendwie immer vor. Warum, weiß ich auch nicht .

    Ehrlich gesagt ist das etwas, was mich am C64 inzwischen am meisten begeistert: nichts ist "heilig", man kann (fast) alles machen und kontrollieren! Im Extremfall kann der Speicher von $0002-$ffff genutzt werden, nicht maskierbare Interrupts können natürlich trotzdem ausgeschaltet werden, das RAM unter der Zeropage-Adressen $00 und $01 kann ausgelesen werden, von den ganzen VIC-Tricks ganz zu schweigen! Wie toll ist das denn alles!


    Kann ich leider nicht beurteilen. Ich vermute aber, dass man es in C aber vielleicht auch mit weniger Fehlersuche zu tun hat, wo es in Assembler mal z. B. an einem blöden Carry-Flag hakt, wo man (übertrieben) drei Tage nach sucht. Oder?

    Ich habe mir abgewöhnt Fehler zu machen: das kostet ja doch nur Zeit und Nerven :-)
    Und falls es doch mal auftritt: mit dem Vice-Monitor komme ich inzwischen gut klar beim debuggen, das ist i.d.R. schneller als mein übliches "printf-Debugging" in C.