Hallo Besucher, der Thread wurde 5,9k mal aufgerufen und enthält 36 Antworten

letzter Beitrag von Bytebreaker am

Full Screen Scrolling mit ColorRAM

  • Huhu,


    mal eine Frage an alle, die sich schon mit Scrolling herumgeschlagen haben:
    Gibt es eine gängige Technik, das ColorRAM ohne Bild-Flackern mit dem Textbildschirmin alle 4 Richtungen mitzuscrollen?


    Das Scrollen des Textbildschirms geht mit Double Buffering und man hat ja 8 Frames Zeit, den Screeninhalt auf eine andere Videobank zu bewegen.


    Diese Zeit hat man aber nicht, um das ColorRAM zu verschieben. Horizontal habe ich es in beide Richtungen hinbekommen, das ColorRAM flacker- und zitterfrei mitzuscrollen.
    Vertikal gelingt es mir weder nach oben noch nach unten, nur das ScreenRAM lässt sich weich scrollen. Einen wirklich systematischen Ansatz habe ich bei alledem auch nicht, ich habe so lange herumprobiert, bis die Mischung aus abgearbeiteten Zyklen und abgewarteter Rasterzeile nicht zu Bildschirmschrott geführt hat.


    Vielleicht können wir hier ja eine kleine Diskussion darüber beginnen, ob es überhaupt gute Konzepte für ColorRAM Scrolling gibt und ob das überhaupt verbreitet war (Im Multicolor Textmodus hat man ja eigentlich genug Farben. dass eine dann immer gleich ist, ist dann eigentlich nicht so sehr auffällig).

  • Dieser Artikel aus der Codebase64 (von Cadaver) ist ziemlich interessant, was Scrolling (vor allem 8 Wege) und Tilemaps angeht..


    http://codebase64.org/doku.php?id=base:rant4&s[]=scrolling


    es gibt verschiedene Möglichkeiten. Das Screenram kann natürlich über mehrere Frames verteilt geupdated werden (doublebuffer). Für das Colorram gibt es verschiedene Wege das zu handlen.


    Ein Technik die mir nicht bekannt war ist einfach jedem Screenram Char eine eigene Farbe zuzuweisen und dann ein


    ldy SCREENRAM,x
    lda COLORTABLE,y
    sta COLORRAM,x


    zu machen. Braucht natürlich auch ungefähr ein ganzes Frame, aber anscheinend kann man das dadurch von Character Screen entkoppeln, ausserdem ist das dadurch für 8 Wege Scrolling anscheinend ganz praktisch. Den Codeschnipsel oben kann man auch mit dem Doublebuffer Update kombinieren und dann folgendes machen:


    lax OTHERSCREENBUFFER,y
    sta THISSCREENBUFFER,y
    lda COLORTABLE,x
    sta COLORRAM,y


    Dadurch machst du den Doublebuffer Update und gleichzeitig schreibst du das ins Colorram. Wahrscheinlich ist das irgendwie auch ganz praktisch für 8 Wege Scrolling.. (Irgendwie sowas ähnliches wird anscheinend auch in Sams Journey verwendet, was glaub ich "damals" Cadaver da bemängelt hatte.. Ich kann da falsch informiert sein, da weiß jeder andere hier wahrscheinlich eh mehr.)


    Was manche anscheinend auch machen ist ein:


    lda SCREENRAM,x
    sta COLORRAM,x


    .. Da das Colorram nur die unteren 4 bits auswertet hat man dadurch bis zu 16 chars die jeweils die gleiche Farbe haben können.


    Bin mir nicht sicher, wie das Turrican macht (das dürfte in Vice relativ leicht checkbar sein), aber eigentlich ist es laut Cadaver auch möglich das ColorRam separat mitzuscrollen und das sogar in NTSC, soweit ich mich erinnere. Bin gespannt, was hier noch an Techniken auftaucht :)..


    Ich glaub es gibt auch Optimierungen für einfarbige 4x4 Tiles (oder 2x2/3x3/5x5 etc), kann sein, dass oben in dem Artikel auch was darüber steht.


    Das wichtigste ist auf jeden Fall den Code soweit wie möglich zu entrollen. (Unter Beachtung der Rasterposition.) Was auch hilft ist selbstmodifizierenden Code einzusetzen um die Verschiebung in die Loops mit rein zu "encodieren". Beim Doublebuffer kannst du ja einfach den letzten Buffer mit nem X/Y Offset in den neuen übertragen.


    Hab den Artikel oben vor ein paar Monaten gelesen und fand den ziemlich cool.


    So.. Vielleicht hilft das ja auch schon ein bisschen.. :) Ist schon spät und ich schreib zu viel komischen Kram.. :) Wie gesagt, der Artikel oben ist wahrscheinlich top.. Was Multidirectionales Scrolling angeht.

  • Du musst schauen, dass Du vor dem Rasterstrahl bleibst. Das ist vor allem problematisch, wenn Du nach unten scrollst, denn dann musst Du ja die Zellen einer Spalte jeweils eins nach unten kopieren und folglich von unten nach oben vorgehen, damit Du Daten nicht unwiederbringlich überschreibst. So läufst Du dem Rasterstrahl leider entgegen und die Zeit reicht nicht, so dass bei den letzten Spalten Flackern auftritt.


    Die übliche Lösung ist, das ColorRAM in zwei Hälften zu scrollen, erst die obere Hälfte, denn die untere Hälfte. Eine Zelle in der Mitte jeder Spalte musst Du dann woanders zwischenspeichern. Dadurch kannst auch schon früher anfangen mit dem Scrollen, nämlich sobald der Rasterstrahl in der Mitte des Frames vorher angekommen ist. So habe ich es in Zeit der Stille gelöst und so reicht es auch für NTSC.


    EDIT: oh ja, das steht auch genauso auf der codebase, und ich glaube Cadavers Rant hatte ich auch damals als Inspiration hergenommen ^^ .

  • Bei 1-2 Pixel Scrolling könnte man das Farbram auch in einen Buffer schreiben. Für das kopieren in beide Buffer hat man dann 3 oder eben 7 Frames Zeit. Im letzten Frame wird der Buffer ins Farbram mit Speedcode umkopiert. Da nur eine Routine benötigt wird kommt man mit weniger als 6KB Speedcode aus. Mit 8 Takten pro Farbe verliert man dann nicht mehr soviel Rechenzeit.

  • Zwischenstand:


    Scrollen nach oben geht jetzt, da habe ich wirklich nur Acht geben müssen, dass im letzten Frame vor dem Video-Bankwechsel das Kopieren des FarbRAMs dem Rasterstrahl hinterherläuft und der Rasterstrahl somit nirgends "querläuft".


    Am Scrollen nach unten bin ich noch dran. Noch möchte ich den Code dafür nicht wegschmeißen und neu machen, weil 3 von 4 Scroll-Arten ja nun schon gehen und das Abwärtsscrollen ohne ColoRAM ja auch schon geht. Die 4 Scrollarten sollen später in einem Stück verwendbar sein und es soll daher viel ähnlichen / herauskürzbaren Code ergeben.


    Im Moment neige ich dazu, einen eigenen ColorRAM Buffer und Speed Code zu verwenden, auch wenn Claus' Lösung die elegantere ist. Dazu müsste ich aber das ganze Ding neu schreiben. dies tue ich vielleicht sogar ein andermal, aber noch nicht jetzt.


    In den nächsten Monaten plane ich dann, 4 Wege Full Screen Scrolling in einem Intro zu verwenden. Die genauen Ideen dafür fehlen mir aber noch. Danke für die guten Hinweise.


    Edit:


    Ich habe in dem zusammenhang auch das Spiel "Fort Apocalypse" auf C64 Wiki als 4 Wege Scrolling Beispiel gesehen. Das war 1982. Und da flackert nix! Alle Achtung. Es sei denn, im Multicolor Text Mode ist eine Farbe immer gleich, und das könnte der schwarze Hintergrund sein, der ist immer gleich und kann vom ColorRAM kommen. Trotzdem gut hinbekommen.

  • Das Scrollen ist finde ich noch überschaubar, unangenehmer wird es wenn Du Tiles verwenden willst und Du die neu hinzukommenden Spalten/Zeilen zusammenfriemeln musst. Das habe ich dreimal neu implementiert und war am Ende immer noch nicht wirklich glücklich mit dem Code. Drei Register sind einfach zu wenig für eine elegante Lösung (zumindest eine auf die ich gekommen wäre).

  • So, kurzes Update:


    Ich bin letztlich Acorns Weg gegangen für das Scrollen nach unten und habe ca 7 Kiometer Speedcode dafür geschrieben. Die ersten 16 ColorRAM-Zeilen werden über eine x-dekrementierte Schleife kopiert, der gesamte Rest per lda sta Folge.


    Zumindest mal ist die Scrollgeschwindigkeit bei allen 4 Richtungen nun gleich, auch wenn das Abwärtsscrollen am meisten Platz verbraucht. Eine Idee für ein Intro habe ich schon, danke für die Tips, dafür kommt ihr in die Greetings. :-)

  • Es gibt doch glaube ich noch den Trick, sofern das Bild aus Tiles aufgebaut sein sollte, also z.B. aus 4x4 Chars, und die Farbe immer nur pro Tile sich ändert und nicht pro Char, dann braucht man auch nur jede 4. Zeile bzw. jede 4. Spalte zu ändern, da die jeweils restlichen 3 gleich bleiben.


    Und dann kommt noch dazu dass einige Spiele eine auffällig breite Status-Bar haben, damit eben nicht der ganze Screen gescrollt werden muss...


    Was Fort Apocalypse angeht, das besteht doch eh aus nur 4 Farben oder? Da wird dann auch kein ColorRAM gescrollt. Genauso wie bei Boulder Dash usw.

  • Was @ZeHa schreibt ist mir auch schon oft aufgefallen.
    Sehr viele Spiele mit Multidirektionalem Scrolling (u.a.Turrican&Sam‘s Journey) haben eine recht hohe Statusbar am unteren Rand, die ungefähr 5-6 Zeilen in Anspruch nimmt.
    In meinen Tests seinerzeit klappte ein fullscreen Scrolling zwar, aber das Problem ist, das einfach nicht genug Rechenzeit übrig ist, um auch eine gescheite Spiellogik unterzubringen.

  • Richtig, aber das bedeutet ja ebenfalls weniger Chars die gescrollt werden muessen. Der Bereich rechts bleibt einfach schwarz, d.h. dort muessen weder Chars noch Farbinformationen gescrollt werden.

  • Wird dabei eigentlich immer die 1-8 Pixel (1 Char) r/l/o/u Register Verschiebemöglichkeit des VIC genutzt ?


    U. wie funktioniert das eigentlich ohne Spaltenaufploppen bei bspw. nach links Scrolling ? Da muss ja immer rechts am Rand die nächste Spalte nach einem Char Bildverschiebung nachgeliefert werden. U. ohne dass diese unsichtbar verdeckt wäre, würde man das ja immer sehen.. ? * U. sie müsste ja sogar nicht erst nach einem Char Verschiebung, sondern im gleichen Moment mitscrollen + schon wieder das nächste Anhängsel nach/bei jedem Pixel parat stehen (da würden sich ja diese dann mehrere Charreihen -8 müssten es dann hintereinander u. untereinander sein- überlappen, sowas geht ja natürlich gar nicht.. ;) ).
    Wie man sieht, viele Fragen / ala Ideen auf die ich da so kommen kann.


    Ich weiß dass das Erstellen des Bildes bereits vor der eigentlichen Darstellung, also vor dem Rasterstrahl, bewerkstelligt wird. Aber auch dann bleiben mir immernoch o.g. andere Frage(n), dass eigentlich ja bereits nach jedem einzelnen Pixel Verschiebung schon wieder rechts die nächste 1-Pixelspalte parat stehen muss (und so dünn sind Chars ja nunmal nicht ) und sowas an Kokolores halt.


    *Wenn man aber die Charspalte ganz rechts komplett mit schwarzen Sprites verdecken würde, könnte ich mir das problemlos ohne sichtbares Aufploppen vorstellen (mit zwei Bildschirmen im Ram) - das würde dann eben unsichtbar hinter der Spritewand passieren, aber sonst noch nicht.
    Bei einigen Textscrollern, sogar im Turrican 2 im Intro (ok, der geht glaube ich sogar im Rahmen weiter - ist also nochmal komplizierter), sieht man das ja auch total, dass da ganz rechts immer wieder die nächste Nachschub-Spalte kaputt aufploppt. (Und das NES hat sowas ähnliches an Problem in fast allen Titeln.)



    Hab' mich damit auch noch nicht beschäftigt, irgendwann müsste es daher vlt. verständlich sein. / Wollte auch nur 'mal so zwischenfragen, müsste eigentlich sowieso irgendwann besser einen Extrathread für die Basics an Fragen dazu aufmachen.

  • Ich denke, dass die meisten nicht VIC Tricks nutzen um ein Scrolling zu erzeugen (Demos mal außen vor).


    Daher werden die ein bis Pixel Offsets für horizontales und vertikales Scrolling verwendet.
    Damit man keine unschönen Effekte hat, kann man auf 38 Spalten und/oder auf 24 Zeilen umschalten.
    Daher braucht man keinen Zeilen oder Spalten mit Sprites abdecken.

  • Also ganz einfach gesagt:


    Eine Spalte bzw. Zeile am Scroll-Ende kann vom Rahmen per Bit-Schalter überdeckt werden. So kann man 8 Pixel per Register scrollen und wenn das erledigt erledigt ist, muss man, während der Rasterstrahl nicht dort ist wo man das Bild verändert, den gesamten Bildschirm um eine Spalte bzw Zeile zu 8 Pixel Breite, bzw. Höhe versetzen und kann den vom Rahmen verdeckten Bereich beschreiben, der dann pixelweise wieder herausgescrollt wird. Wenn dann das Scroll-Register wieder zurückgesetzt ist (mehr als 8 Pixel Versatz durch Register geht nicht) sieht der Beobachter das umkopierte Bild, als sei das Scroll-Register noch gesetzt. Das Scrollen per Register um 8 Pixel kann wieder losgehen. Dadurch entsteht die Illusion einer fließenden Bewegung.


    Man muss nicht die eigentliche Bitmap von Hand bewegen, aber immerhin 1000 Bytes ScreenRAM und in meinem Fall nochmal so viel ColorRAM. Das geht bei mir nur, indem man die 8 Frames Rasterzeit beim pixelweisen Scrolling zum Kopieren in Puffer und zweite Videobank nutzt.


    Es soll auch Leute geben, die zumindest ScreenRAM „one frame“ scrollen können, zu denen zähle ich aber aktuell nicht. ;-)

  • .. Wenn dann das Scroll-Register wieder zurückgesetzt ist (mehr als 8 Pixel Versatz durch Register geht nicht) sieht der Beobachter das umkopierte Bild, als sei das Scroll-Register noch gesetzt. ..

    Genauso wie im ganzen Post beschrieben dachte ich mir das auch, alles klar. Alsbald dies an Probl. :

    Eine Spalte bzw. Zeile am Scroll-Ende kann vom Rahmen per Bit-Schalter überdeckt werden.

    ...mit ebensolchem Trick gelöst wurde. Danke !


    [Umsetzung ist natürlich nochmal eine andere Sache (auch wegen Raster-Timing treffen Zeugs), in ASM hab' ich keine Übung. Bleibe von meinem eigenen Fun -denn das soll es ja zunächst machen- her eh erstmal immernoch bei Basic+Compiler mit ein paar simplen SYS ASM/Maschinencode Einstreuungen für simplere Sache als dies.]