Beiträge von mrsid im Thema „Prince of Persia Disk Version ?“


    Ich habe gerade alle Bänke des EasyFlash Moduls ausgelesen. Von Bank 00 bis Bank 31 (Dezimal).

    Ja, die letzte LOROM bank hat die Speicherstände. Anbei die ganze Bankbelegung, falls es hilft...


    Aber gleich im 80 Zeichenmodus - O.K. der VDC kann keine Sprites, schon Problem 1 - und mit 2 MHZ. ^^

    Nicht wirklich ein Problem, der Apple II kann das ja auch nicht. Vorausgesetzt das Schreiben ins VDC RAM geht schnell genug, sollte es kein grosses Problem darstellen.


    Diese Routine kopiert nun per mvn befehl (bedeutend schneller als die REU)
    die entsprechenden Bänke aus dem SCPU-Ram ab $020000 nach $8000-$bfff

    Vergiss nicht das Schreibzugriffe ins ROM im RAM darunter landen müssen, und das man das ROM mit $01 ausblenden kann. Letzteres ist essentiell wichtig um aus der Bitmap darunter zu lesen, beim maskieren.

    mrsid: Vielen Dank für die ausführliche Erklärung.
    Eine Sache hat mich allerdings überrascht. Den Originalcode für den AppleII kenne ich zwar nicht, hätte aber vermutet, daß solche Dinge wie Gitterstäbe als Shapes plus Maskenshape abgelegt sind und für jeden Frame über die Figur gemalt werden, sofern sich die FIgur innerhalb des Shapes aufhält. Das hat den Vorteil, daß man keine ganze Bitmap für die Maske benötigt. Der Einsatz von Sprites macht die Sache natürlich etwas komplizierter, da man die Masken dann fürs Sprite passend zurechtschneiden und shiften muß, aber generell sollte es möglich sein, oder?

    Hier mal ein Beispiel der Maske für den ersten Raum:
    Bitte melde dich an, um dieses Bild zu sehen.

    Der Bildschirm wird mit Painter Algorithmus gezeichnet. Für die Elemente die den Spieler verdecken, wird nach dem Layer auf dem der Spieler ist die Maskenversion des Elements gezeichnet, und danach die Vordergrund Version des Elements.
    Nach dem Zeichnen des Raumes rauszufinden welche Maske man an der Stelle des Spielers braucht (der Raum wird ja nur einmal gezeichnet) würde bedeuten das man das meiste davon jedes Frame nochmal durchlaufen lassen müsste. Es schien mir wesentlich einfacher den ganzen Schirm als Maske zu speichern. Shiften muss man das dann auch noch.

    Kann man nicht die Animations phasen halbieren ? Sieht dann nicht mehr so smooth aus, aber das würde am Spielfluss ja nix ändern .

    Ja klar, siehe CPC version. Ich find's scheisse, aber manche haben andere Meinungen. Es wird dann immer noch sauknapp, aber wer's versuchen will...


    Kannst du noch sagen, wie viel die Cutscenes in etwa verbrauchen oder sind die schon in den 10% mit drin?

    Nicht viel. Vielleicht 2-3KB alles in allem.

    Zitat von ogd

    Hast du für die Spites auch Multiplexing benutzt?

    Nein, das hilft in dem Fall nicht allzu viel und macht das Timing und das Speicherlayout komplizierter.

    Zitat von ogd

    So eine C 128 Umsetzung würde dich vemutlich nicht reizen, oder? ;)

    Nein, das Interesse daran geht gegen null, so wie die Anzahl der C128 Benutzer... (ich hab selbst einen! ;) )

    Eine SCPU Anpassung sollte normalerweise kein Problem sein. Es sei denn, Illegale OP-Codes wurden verwendet.

    Nein, keinerlei illegale Opcodes wurden verwendet. Die wenigen 65C02 Opcodes musste ich durch äquivalenten Code ersetzen.

    Das Bit wird schon gezielt genutzt, wie man am Chameleon erkennen kann. Ich habe aber leider keinen C128 (und kein kompatibles Modul), um das zu testen. In VICE wird ja leider nicht emuliert, was der VIC IIe im 2-Mhz-Modus sieht. Für Entwickler ist das von daher ungeeignet, weil man evtl. Programmierfehler nicht immer sieht.

    Ja, es wird der 2MHz Modus verwendet. Ich hab' das natürlich auf einem echten C128 (D, Plastik) mit einem echten Easyflash getestet. Easyflash Support in der 1541 Ultimate oder dem Chameleon oder ein Easyflash 3 gab es damals noch gar nicht.
    Ein Bug beim Speichern auf einem C128 wurde in der Version 1.1 behoben.

    Das sind mir viel zu viele Halbwahrheiten und Spekulationen, also lasst mich da mal Licht in die Sache bringen.

    Erst mal ein Überblick:
    Prinzipiell scheitert's erst mal daran das die Originalversion auf 128KB ausgelegt wurde, weil das notwendig war um die ganzen Grafikdaten unterzubringen. D.h. hauptsächlich die Animations Frames für den Prince und einen Gegner. Dann dazu noch die Tiles für die Hintergrundgrafik dazugerechnet, das ist schonmal eine Menge. Alle diese Grafiken werden natürlich ständig gebraucht, man kann ja praktisch alle Aktionen jederzeit durchführen. Ladezeit for Sprung oder Kampf? Das wär glaub ich nix.
    Aufm Apple II brauchen diese Daten 30KB für den Spieler, 6KB für den Gegner und 13.5KB für die Hintergrundgrafik, also 49.5KB.

    Der Code fürs Spiel ist 48KB am Apple II. Vieles davon braucht man am C64 sicher nicht unbedingt so, aber das meiste schon. Gewisse Dinge (z.b. Joystickabfragen) muss man am Apple kompliziert ausprogrammieren, während man am C64 nur ein Register lesen muss. Einzelne Dinge könnte man u.U. auslagern und nachladen, aber das würde sicher nicht mehr als 10% davon ausmachen. Dazu muss man auch wissen das z.b. die Cutscenes im Spiel auch mit der Spiel Engine ablaufen, also eigentlich nicht separat sind.

    Das Spiel zeichnet die Räume mit Hilfe der Hintergrundgrafik Tiles in eine Bitmap (die Grafik geht nicht mit Zeichensatz, weil die 3 Stockwerke die man sieht nicht mit dem 8x8 Pixel Raster übereinstimmt). Damit man ordentlich animieren kann ohne das irgendwas ständig flackert wird ganz normales Double-Buffering verwendet. D.h. am Apple II 16KB für die zwei Bitmaps. Am C64 sind das auch gleich mal 16KB plus 2KB für die Screen Daten.
    Zusätzlich müssen die Spieler und Gegner Figuren auch hinter der Hintergrundgrafik stehen können, und an bestimmten Stellen (hinter einem Gitter) auch Pixel präzise ausmaskiert werden. Um das schnell zu lösen verwend' ich am C64 eine eigene Masken Bitmap (also nochmal 8KB, rechnet jemand mit?). Eine Lösung wie z.b. bei Caren wo die Spielfigur mit Sprites ausmaskiert wird ist nicht wirklich machbar, weil ich alle Sprites für Spieler und Gegner brauche (die Figuren sind ziemlich gross, z.b. wenn sie springen). Die Spielfiguren in die Bitmap zu zeichnen (wie am Apple II) würde durch die Farblimitierungen der C64 Multicolor Bitmap nicht gut aussehen, entweder wäre der Spieler auch blau wie der Hintergrund, oder man hätte unschönen "Color Clash", so wie bei vielen Spectrum Spielen.

    Die Level Beschreibung (also welche Räume, und wie die aussehen) braucht 2.25KB. Diverse Tabellen für die Animationen und für z.b. Multiplikation oder so brauchen auch noch mal 6KB. Von Musik und Soundeffekten reden wir noch gar nicht.

    Ist ja nicht so das ich nicht die anderen Optionen abgewägt hätte. Also erstmal REU:
    Dazu hab ich alle Grafikdaten in die REU geschaufelt, dabei die Figuren auch schon mal gespiegelt. Dann für jedes Frame die Sprite daten in einen Buffer im C64 RAM kopiert, dann maskiert. Aber es war noch immer viel zu viele Sachen im RAM und es ging sich noch immer nicht aus drei Bitmaps (2 Buffer und eine Maske) unterzubringen.
    Im Endeffekt gings mit der REU Version also einfach nicht vorwärts, ich stiess immer nur an Grenzen ohne Aussicht auf Lösungen. D.h das Projekt ist dadurch versandet und es hat fast ein Jahr gedauert bis ich mit dem neuen Modulansatz begonnen habe. Aber wer's ausprobieren will, die REU Version vom ersten Level gibt's hier, ist aber natürlich buggy und unfertig, das war der Stand von August 2009: Bitte melde dich an, um diesen Link zu sehen.
    Speicherbelegung von damals war circa so:


    Dann mit dem Modulansatz war alles einfacher:
    Man kann einfach vom ROM im Modul Teile einblenden, das geht nicht nur "erheblich schneller" wie oben beschrieben, sondern es braucht gar keine Zeit. Den Unterschied zwischen schnell und sofort muss man sich erstmal deutlich klar machen.
    Bei jedem C64 Modul, also egal ob EasyFlash, Ocean, Gmod2 oder sonst irgend einem ist es immer so das man direkt drauf zugreifen kann, d.h. man kann an die Adresse vom ROM springen und dort auch Code ausführen. Oder eben Daten direkt lesen, ohne Umweg über's RAM. Nur der VIC-II kann (im Normalfall) nicht auf das ROM zugreifen. Und beim Lesen der Grafikdaten kann ich sie auch gleich maskieren, ohne sie dann nochmal vom RAM lesen zu müssen.

    Aber prinzipiell ist das natürlich sehr geil. Wie ihr oben seht sind da erst <16KB (von $0400-$3fff) Code der Apple II version übernommen worden. Fast 32KB fehlen da noch. Also wohin damit? Natürlich ins ROM, und da das eh fast kein selbstmodifizierender Code ist, dann eben auch direkt von dort ausführen. Das geht natürlich mit einer REU gar nicht. Selbst umkopieren mit 1MB/s ist da nicht vergleichbar. Das ist ein ganz anderes Ding.

    Also darauf läuft's dann hinaus. Alles was man nicht ständig braucht kann ins ROM, dadurch wird Platz frei für die dritte Bitmap, dadurch werden die Hintergrund Animationen ohne Flackern erst möglich. Und dadurch ist dann schlussendlich Platz genug für alles, inklusive Musik und dergleichen.
    Und um das ganze dann in spielbare Bereiche zu beschleunigen braucht man Speed Code, d.h. die schnellstmögliche Variante um z.b. Speicherbereiche zu löschen, ohne Schleifen. Da gibts's dann im ROM Routinen um die Bitmaps zu löschen, die Sprite Buffer zu löschen, das Farbram zu löschen, etc. das braucht 8 mal 8KB Banken im ROM, also 64KB.

    Mit Modul sieht die Speicherbelegung im RAM dann so aus:



    Schlussendlich, welche anderen Optionen hätte es gegeben:

    - Unter Umständen hätte man jedes zweite Animations Frame weglassen können, oder die Grafikdaten irgendwie komprimieren und auf Double Buffering verzichten können, den Code komplett neu und effizienter schreiben.
    Wer Lust hat das zu tun, der Quellcode ist ja heutzutage öffentlich verfügbar, damals war das natürlich nicht so. Gewisse Dinge hab ich nie reverse-engineered, sondern einfach 1:1 übernommen, z.B. die Gegner KI. Wenn man das neu schreibt geht es sicher effizienter, aber dann hat man auch neue Bugs. Viel Spass.

    - Am C128 hätte man u.U. mit einigen kleinen Abstrichen alles irgendwie unterbringen können.

    Hoffe das hilft beim Verständnis, bin für Fragen natürlich jederzeit verfügbar.