Hallo Besucher, der Thread wurde 26k mal aufgerufen und enthält 203 Antworten

letzter Beitrag von 5ace am

Zarch (Virus) auf dem C64 1:1 machbar?

  • Feststellung:
    Die Geschwindigkeit für die Berechnung der Pixel, lässt sich extrem beschleunigen, wenn man
    1.) das Level verkleinert; um auch mehr oder größere Tabellen in den Speicher laden zu können.
    2.) alle Schleifen ausschreibt und alles nicht so wissenschaftlich sieht.

    Zu 1.)
    Das Level ist jetzt 64*64 = 4096 Bytes groß und scheint als Spielfläche ausreichend zu sein, d.h. man benötigt keine Tiles.
    Zur Geschwindigkeit: Um die 64 Höhen für den angezeigten Ausschnitt (8x8 Punkte) aus dem Level auszulesen, kann man einmal die Levelposition umrechnen und dann indiziert auf die ersten 32 Punkte zugreifen. Danach erhöht man das Highbyte der Levelposition und greift auf die restlichen 32 Punkte zu.
    Als zweiten Schritt kann man das angezeigte Gitter mit dem Softscroll-offset vorbereiten.

    Bspw:

    x[i] = 16*(i%8)+softscroll für alle 64 Punkte

    und

    z[i] = i*16+softscroll für die 8 Tiefen in das Feld.
    Im dritten Schritt wandelt man die 3D-Koordinaten mithilfe der bereits erwähnten Tabelle in Bildschirmkoordinaten um. xs[i] = x[i] / z[i%8] und ys[i] = (Levelhöhe für Punkt i + globaleHöhe) / z[i%8]
    Die Tabelle beinhaltet nur Absolutwerte, d.h. um eine x-Koordinate umzuwandeln, wird unterschieden, ob sich der Punkt links oder rechts von der Bildschirmmitte befindet und danach wird entsprechend zur Bildschirmmitte der Wert aus der Tabelle addiert oder von ihr abgezogen. Bei der y-Koordinate muss man sich keine Gedanken machen. Hier ist es eher wichtig, dass man sich im Rahmen der Tabellengröße bewegt.
    Jetzt können die Punkte gezeichnet werden.

    Zum Schluss lassen sich die gespeicherten Bildschirmkoordinten bei der nächsten Bewegung zum Löschen der Punkte nutzen.

    Zu 2.)
    Im Prinzip ist alles sehr einfach und der ausgeschrieben Code passt in ca. 1400 Byte.
    Angehängt ist ein Beispiel, bei welchem ich mir keine Mühe um das "Drumherum" gemacht habe und welches auch abstürzen kann.
    Es soll zur Demonstration der Geschwindigkeit dienen. Viel mehr ist realistisch gesehen nicht drin (, d.h. es kann nur langsamer werden).
    Die Berechnungen und Tabellen sind nicht geprüft/korrigiert etc. und das Level ist auch nicht wirklich im Speicher, sondern man sieht nur "Müll".
    Der Eindruck der Geschwindigkeit kommt mit Sicherheit auch durch die Nutzung einer Beschleunigungsfunktion bei der Steuerung.
    (...)

    Was zu tun wäre (, irgendwann einmal...):
    - Die Tabellen korrigieren. Evtl. versuchen sie nochmal zu verkleinern, um mehr Y-Werte zulassen zu können (am liebsten 255 ;) bzw. den genannten Trick mit dem Shift auszuprobieren.
    - Double-Buffering, d.h. am besten alles 2 mal unterbringen. (Speicher ist genug da)
    - Korrektur an der Steuerung (Ich glaube, dass ich irgendwo addiere statt zu subtrahieren o.ä. etc..)
    und dann könnte man sich wieder um die Linien und eine Füllroutine kümmern.

    testzarch5.prg

  • Es gibt übrigens noch ein ähnliches Spiel namens Hyperion

    Danke für den Hinweis. Interessantes Spiel. Kannte ich noch gar nicht. Sieht irgendwie aus wie eine Mischung aus "Virus" und "Starglider 2".

    Ich gehe davon aus, dass eine Division über log-Tabellen zu lange dauert, weil man je Punkt eine 16-Bit Multiplikation mit dem Kehrwert benötigt.

    Nein, das wäre auch zu ungenau. Die DIvision mit einer Logarithmentabelle erfolgt lediglich durch Subtraktion, d. h. a / b entspricht log(a) - log(b) (für b ungleich 0). Sollten die Werte nur 8 Bit-Werte sein, bietet es sich an, die Tabellen aus "Elite" zu nehmen. Diese sind so konstruiert, daß ein Übertrag nach der Division anzeigt, ob das Ergebnis größer ist als 255. Bei der perspektivischen Division muß man noch die Brennweite mit einbeziehen, die der Einfachheit halber bei einem 8-Bit-Rechner und einer Auflösung von 320 Pixeln 256 beträgt, d. h. entweder wird das Ergebnis mit 256 multiplziert oder vorher X bzw. Y oder Z wird durch 256 geteilt. Oder eben man nimmt den Übertrag als Hinweis und setzt das Ergebnis auf den Maximalwert 255, wenn ein Übertrag stattgefunden hat, oder holt sich den inversen Logarithmus als Ergebnis für den anderen Fall.

    Die Tabellen lassen sich berechnen mittels:

    Das ergibt:

    Die DIvision sieht dann so aus:

    Wenn man es ganz eilig hat, kann man die erste Subtraktion mit log_0 weglassen, aber dann wird das Ergebnis sehr ungenau. Die erste Version von Elite auf dem C64 verwendete sogar zwei Tabellen für log_inv in Abhängigkeit des Highbits aus der ersten Subtraktion, um so das Ergebnis genauer zu machen. Das entfiel in den späteren Versionen vermutlich aus Speicherplatzgründen.


    (Disclaimer: Alles ungetestet. Benutzung auf eigene Gefahr.)

  • Die DIvision sieht dann so aus:

    Vielen Dank. Dein Code und Deine Ausführungen waren sehr hilfreich.
    Ich habe gerade einige isolierte Tests gemacht und die Division scheint zu funktionieren.


    Wie würde man folgende Divison durchführen?
    15 / 2.25

    (Das Umschreiben als Bruch mit 15 * 4 / 9 und das Ausrechnen über die Tabelle funktioniert und ergibt 6, wobei ich nur eine Tabelle log_1 verwendet habe.)
    Kann man irgendwie low und highbyte einzeln ausrechnen ?
    Also 15/2 und 0/$40 (für 0.25)

    Warum ergeben 0/$40 und 1/$40 = 4 ? (Es wird scheinbar 256 / 64 ausgerecht.)

  • Wenn man statt Chars nun Tiles nehmen würde (z.B. 2x2 Tiles), hätte man eine Map, die um das 4-Fache größer wäre.

    Daran bin ich damals gescheitert, d.h. es lief teilweise mit Tiles, aber irgendwie nicht richtig und es wurden immer wieder Tiles falsch angezeigt.

    Hast du da schon mal einen anderen drüber schauen lassen?


    Ich würde die Tiles sogar noch deutlich größer machen, z.B. 8 x 6 Chars.

    Wieso gerade so eine Tilegröße? Und wie sähen die Farbattribute aus: Je Tile nur ein Colorramwert oder hat jedes Char in einem Tile eine individuelle Farbe?

  • Wieso gerade so eine Tilegröße?

    Das wären in meinem Mockup 2x2 "Landschafts-Kacheln" (hell-, bzw. dunkelgrün). Man könnte dann versuchen, die große Spielfläche aus bis zu 256 unterschiedlichen Tiles zusammenzubauen. Manche hätten Steigungen und Senkungen, andere hätten Küsten-Abschnitte und auf manchen würden Objekte (Häuser und Bäume) stehen.


    Das war aber nur so eine Idee, man kann die Tiles natürlich auch größer oder kleiner anlegen. Auch könnte man die Objekte unabhängig von den Tiles platzieren, müsste aber darauf achten, dass nicht jedes Objekt an jeder beliebigen Stelle stehen darf – vorwiegend wegen möglicher Color-Clashes.


    Das könnten 2 mögliche Tiles sein:

    Zarch-Virus-2D-Tile1.png Zarch-Virus-2D-Tile2.png


    Ich muss aber zugeben, dass ich von Tile-basierten Grafiken noch nicht viel Ahnung habe, da die bei meinen bisherigen Projekten (außer einem noch nicht veröffentlichten) nicht benötigt wurden.


    Je Tile nur ein Colorramwert oder hat jedes Char in einem Tile eine individuelle Farbe?

    Bei meinen großen Tiles hätten sie variierende ColorRAM-Einträge – vor allem wegen der Objekte. Reine Landschafts-Tiles hätten anfangs durchgehend gleiche ColorRAM-Farben – aber das kann sich während des Spiels ändern, weil sich durch den Virus-Befall die Farbe ändert. Dann könnte aus einem ColorRAM-Dunkelgrün ein ColorRAM-Rot werden – allerdings könnte man das notfalls für das ganze Tile machen. Fragst du wegen einer möglichst performanten Scroll-Routine?

  • Fragst du wegen einer möglichst performanten Scroll-Routine?

    Ja. Aber auch wegen dem Speicherverbrauch. Im Extremfall - jedes Tilechar ist individuell eingefärbt - müssten für jedes Zeichen mindestens 3 Bit - bei durchgängigem Multicolor mit überall gesetztem und damit vernachlässigbarem 4. Farbbit - oder 4 Bit mitverwaltet werden. Weil aber Bitextraktionen wiederrum Rechenzeit fressen, müsste man wohl doch auf ganze Bytes je Farbinfo ausweichen.


    Kurz gesagt: Die Scrollroutine muss am Besten in der Lage sein, bei jedem Bildwechsel (50 Hz) die ganze Spielfläche plus Farbram neu aufzubauen.

  • Hast du da schon mal einen anderen drüber schauen lassen?

    Nein. Aber ich muss mal schauen, wo ich den Quellcode davon noch habe. Ist ja schon einige Jahre her...

  • Die Scrollroutine muss am Besten in der Lage sein, bei jedem Bildwechsel (50 Hz) die ganze Spielfläche plus Farbram neu aufzubauen.

    Ich habe mal etwas rumexperimentiert (siehe Anhang)


    Vorläufiges Ergebnis:

    Wenn 25 Zeilen mal 39 Zeichen + Farben 50 mal in der Sekunde gescrollt werden, bleibt keine Rechenzeit mehr übrig.

  • Prinzipiell ist das auch meine Erfahrung, einen ganzen Screen zu scrollen mit Farbe benoetigt die gesamte Framezeit. Aber kannst Du vielleicht sagen welche Bedeutung bei Dir konkret die Randfarben haben?


    Wenn man also ein Spiel machen will mit scrollendem Farbscreen, muss man Tricks anwenden - ein haeufiger Trick ist es, eine entsprechend grosse Statusbar einzubauen (gar nicht mal so selten). Ein anderer Trick kann es sein, die Farbinformation nur fuer jedes 4. Char umzukopieren, dann braucht man halt ein strenges Tile-Raster fuer die Farben, was aber im Normalfall kein Problem darstellen sollte.

  • Aber kannst Du vielleicht sagen welche Bedeutung bei Dir konkret die Randfarben haben?

    Das sind nur Debuginfos, weil die große Kopierschleife in drei kleinere aufgeteilt werden musste, damit der Rasterstrahl nicht die Scrollroutine überholt und dadurch Tearing entsteht. Der schmale Streifen in der Mitte ist die übig gebliebene Rechenzeit.


    Zu Statusbar:

    Bin am überlegen, wie eine quadratische Spielfläche wirken könnte. So wie in Operation Wolf, also mind. ein Sprite opfern, um das Feinscrolling zu kaschieren.

  • Solange es nicht wie bei the Last V8 endet :emojiSmiley-28:, ist eine größere Statusbar doch durchaus akzeptabel. (siehe meine Demo) Da ist die Fläche quadratisch und man spart den Sprite x-Überlauf. ;)


    Action Biker scrollt bunt in alle Richtungen und verbraucht unten 7 Textzeilen für die Statusbar inkl. der Trennzeile zwischen Multicolor-Scrollbereich und Hires-Textstatusbereich. Das wäre als Iso-Engine schon eine coole Grundlage, falls da noch Rechenzeit für KI übrig wäre. :)


    Beim schon zuvor erwähnten Raid on Bungeling Bay scrollt fast der komplette Bildschirm mit weniger Farben. Das Spiel kann man eigentlich schon als Zarch/Virus Vorgänger/Inspiration einstufen. Man fliegt frei in alle Richtungen (Hubschrauber), hat eine Basis (Flugzeugträger) zum Rearm/Refuel, ein Inselszenario, eine Minimap, hat Gegner in der Luft und am Boden (Flugzeuge, Raketen, Boote, Geschütze), wird von Lenkraketen verfolgt, hat eine zeitliche Bedrohung, die man in Schach halten muss (Bau des Schlachtschiffs) und muss mit Bomben Bodenziele zerstören.


    Hier geht es ja um eine 1:1 Umsetzung, die technisch auf einer 1 MHz Kiste ohne GPU schlicht nicht machbar ist. Die Speccy Version ist auch nur eine Machbarkeitsstudie und weit entfernt vom Spielspaß. Blendet man die "blendende" 3D Darstellung aus, ist ROBB bereits das "Virus"-Spiel auf dem C64 und macht mir heutzutage sogar mehr Spaß, als Virus auf dem Amiga.

  • Ich hab da keine Ahnung von, aber vielleicht steht da ja was hilfreiches für Euch drin.


    Das original scheint mit der Maussteuerung ja nicht gerade gut bedienbar gewesen zu sein. Und auch ich komme spontan nicht damit zurecht in der Online-Version. Ratzfatz überdreht man den Kahn und befördert sich mit Thrust gen Erdboden.

    https://classicreload.com/zarch-lander.html

    In sofern liegt in make-it-simple evtl. sogar Verbesserugspotential.
    Ich finde, Pseudo-3D müsste schon sein als Anleihe. Aber diesen Eindruck sollte man soagr schon mit Retrofans unterschiedlichen Kacheln ausreichend rüberbringen, vaD wenn man mit einem Schattensprite unterstützt.

    Der fehlende Button wurde ja in einem der Demofiles schon mit lange/kurz Feuern gemacht. Funktioniert grundsätzlich. Man könnte auch mit einer Taste der Tastatur arbeiten. Wenn man den Joystick mit einer Hand hält so wie ich, bleibt halt keine Hand frei. Oder man nimmt den Feuerknopfeingang vom anderen Jostick und bedient den Schub über ein Gaspedal. Bräuchte man halt wieder Hardware. In Zeiten von 3-D-Druck evtl. machbar.


    Zitat

    Hier geht es ja um eine 1:1 Umsetzung, die technisch auf einer 1 MHz Kiste ohne GPU schlicht nicht machbar ist. Die Speccy Version ist auch nur eine Machbarkeitsstudie und weit entfernt vom Spielspaß. Blendet man die "blendende" 3D Darstellung aus, ist ROBB bereits das "Virus"-Spiel auf dem C64 und macht mir heutzutage sogar mehr Spaß, als Virus auf dem Amiga.

    Dann könnte man ja das ja auf ähnliche Weisen machen, noch die Zarch-Optik mit rein und schon ist es fertig. ;)
    Weiter so, ich bleibe gespannt. ;)


    mfg Tobias

  • Wenn 25 Zeilen mal 39 Zeichen + Farben 50 mal in der Sekunde gescrollt werden, bleibt keine Rechenzeit mehr übrig.

    Dann muss man wohl abspecken. Ich sehe auch das größte Potential darin, die Spielfläche zu verkleinern – solange man es nicht übertreibt und man das Geschehen nur noch durch einen Briefschlitz beobachten darf. Und dein Spielfeld scrollt schneller als man es wahrscheinlich benötigt. Wäre ein 25fps-Scrolling eine Option? Oder ruckelt das dann? Und falls es hilft, könnte man mein Design wahrscheinlich mit gewissen Verlusten so reduzieren, dass sich z.B. immer 2x2 Chars eine ColorRAM-Farbe teilen – würde das signifikant was bringen?


    Bin am überlegen, wie eine quadratische Spielfläche wirken könnte. So wie in Operation Wolf, also mind. ein Sprite opfern, um das Feinscrolling zu kaschieren.

    Klingt interessant. Hat das gegenüber einer vertikalen Aufteilung von Spielfeld und Statusanzeigen Nachteile, die zu beachten wären?


    Das original scheint mit der Maussteuerung ja nicht gerade gut bedienbar gewesen zu sein. [...] In sofern liegt in make-it-simple evtl. sogar Verbesserugspotential.

    Es ist ja auch meine Vorstellung, das Spiel nicht einfach schlechter zu machen als das Original, sondern dass man stattdessen ein wirklich gut spielbares C64-Spiel daraus machen könnte, das eben mehr ist eine Tech-Demo. Und man sieht ja, dass selbst vermeintlich "einfache" Sachen, wie Scrolling, für den C64 (trotz Hardware-Unterstützung) schon eine echte Herausforderung ist, und man tricksen muss, um selbst ein buntes 2D-Spiel auf den Screen zu bekommen.

  • Hier findet sich etwas Hintergrundinfo zu Virus/Zarch und auch paar Screenshots von anderen Systemen:


    The Making of Zarch


    Und hier ist ein kurzer Videoclip, in dem einer eine Zarchengine in "Dark Basic Pro" vorstellt. Ist natürlich neueren Datums (2010), aber vielleicht ganz interessant, um ein Gefühl für die Engine zu bekommen.


  • Beim schon zuvor erwähnten Raid on Bungeling Bay scrollt fast der komplette Bildschirm mit weniger Farben.

    Was mir an ROBB schon ganz gut gefällt, ist, dass die Position des Spielersprites dynamisch ist, also nicht einfach stumpf in der Mitte, sondern immer (je nach Flugrichtung) dahinter, sodass man nach vorn mehr Sicht hat als nach hinten (was bei schnellem Flug auch sinnvoll ist).

  • Und dein Spielfeld scrollt schneller als man es wahrscheinlich benötigt.

    Ja, das glaube ich auich. Das rasante Scrolling soll nur zeigen, ob die Scrollroutine in der Lage ist, den ganzen Bildschirm in 50 Hz upzudaten, um jede erdenkliche, unvorsehbare Flugrichtung abzudecken.


    Wäre ein 25fps-Scrolling eine Option? Oder ruckelt das dann?

    Da habe ich mir auch schon ein paar Gedanken gemacht. Also alternierend in einem Frame die Spiellogik und im anderen das Scrolling ausfrhren. Ist natürlich weniger geschmeidig dann und könnte sensible Spieler stören.


    Und falls es hilft, könnte man mein Design wahrscheinlich mit gewissen Verlusten so reduzieren, dass sich z.B. immer 2x2 Chars eine ColorRAM-Farbe teilen – würde das signifikant was bringen?

    Ich würde lieber vorher austesten, wie weit man ohne solche Gestaltungslimitierungen technisch kommen kann. Eine Idee ist zum Beispiel auf mehr Speedcode bzw. Selbstmodifikation zu setzen.

    Hat das gegenüber einer vertikalen Aufteilung von Spielfeld und Statusanzeigen Nachteile, die zu beachten wären?

    Bei einer (annähernd) quadritschen Spielfläche geht auf jeden Fall mind. ein Sprite für das eigentliche Spielgeschehen flöten. Operation Wolf nutzt das als Munitionsanzeige. Hier könnte man damit grob die Flughöhe und/oder den Energiestatus darstellen.

  • Beim schon zuvor erwähnten Raid on Bungeling Bay scrollt fast der komplette Bildschirm mit weniger Farben.

    Was mir an ROBB schon ganz gut gefällt, ist, dass die Position des Spielersprites dynamisch ist, also nicht einfach stumpf in der Mitte, sondern immer (je nach Flugrichtung) dahinter, sodass man nach vorn mehr Sicht hat als nach hinten (was bei schnellem Flug auch sinnvoll ist).

    Ja, das ist geil gemacht und fühlt sich super an, wenn man die Raketen auskurvt und sich elegant hinter die Jets schwingt. Das Fluggefühl ist für ein solches Spiel extrem wichtig.

    Auchz.B. bei Interceptor auf dem Amiga, ist die dynamisch folgende Aussenansicht einfach der Hit. Dagegen war die statisch steife Kamera bei Falcon schon enttäuschend.


    Solange es nicht wie bei the Last V8 endet :emojiSmiley-28: , ist eine größere Statusbar doch durchaus akzeptabel.

    Mit einer festen Punkteanzeige oben und einer kleinen Statusanzeige unten und wenn man links und rechts etwas Rand lässt, dann kriegt man das Spielfeld schon einigermaßen flott gescrollt. :D

    Hach, danke, dass du den Insider erkannt und verwandelt hast. :emojiSmiley-28: Der freie Bereich lässt sich auf jeden Fall gut und sinnvoll nutzen, vermutlich ist dann sogar genug Rechenpower übrig, um die 3D Darstellung zu vergrößern: