Hallo Besucher, der Thread wurde 9,4k mal aufgerufen und enthält 71 Antworten

letzter Beitrag von ThomBraxton am

Fullscreen Smooth Scroll zuckt

  • Double buffering ist hier m.E. nicht nötig. Als erstes würde ich den gewaltig großen Kopierloop, der screen+CRAM gleichzeitig bearbeitet, in kleinere Häppchen aufteilen. Bspw. 3 loops die jeweils nur sechs bis acht Zeilen verschieben. Das sollte vielleicht schon reichen.

  • Naja, das kommt drauf an was noch alles so in dem Frame passieren soll. Vielleicht kriegt man es so wie es jetzt ist irgendwie reingequetscht, aber selbst wenn sonst nichts weiter geplant wäre: wieso sollte man die Last so ungleich auf die Frames verteilen?

  • Die Last ist auch beim regulären double buffering nicht immer gleich verteilt.
    Außerdem sind hier ja nicht so viele Zeilen betroffen. Ohne double buffering geht einiges.
    Man schaue sich mal Green Beret an: 16 Zeilen mit CRAM-Verschiebung, sprite multiplexer, recht anspruchsvolle AI, Musik etc.


    ...auch wenn ich persönlich fast immer mit zwei screens arbeite, aber nur weil ich zu faul bin, timing Stress auszubügeln ;)

  • Die Last ist auch beim regulären double buffering nicht immer gleich verteilt.

    Ja, sie ist sogar immer noch total ungleich verteilt, nämlich in diesem Fall auf nur zwei von 8 Frames. Aber immerhin viel besser als alles in einem Frame ^^

  • Wer schafft die meisten Zeilen Scrolling screen + color in einem Frame (bzw mit der wenigsten Rasterzeit)?

    Ich weiß nicht. Die schnellste Lösung ist wohl, alles komplett zu unrollen. Am Ende gäbe es m.E. vermutlich lauter identische Beiträge auf Platz 1.

  • Uff... Also Softscrolling mit Double Buffering läuft...
    Alles noch total unoptimiert, aber die größten brainfucks habe ich wohl umschifft.


    Jetzt kommt aber das nächste Fragezeichen auf mich zu: wenn ich ständig zwischen screen und buffer switche, dann muss ich ja auch ständig zwei Screens updaten, ebenso Sprite Pointer etc, oder?
    Sieht man im angehängten File ganz gut, wo der Text blinkt, weil er immer nur auf einen der beiden Screens geschrieben wird. Ebenso auch beim Sprite, wenn man nach oben läuft.


    Also wenn ich z.B. bisher das Sprite so geändert habe:

    Code
    1. lda #sprite_pointer_0
    2. sta SCRRAM + $3f8


    Muss ich jetzt entweder eine Abfrage machen, ob ich mich im screen oder buffer befinde, oder einfach alles doppelt schreiben, wenn ich keinen Denkfehler habe?



    Code
    1. lda #sprite_pointer_0
    2. sta SCRRAM + $3f8
    3. sta SCRRAM_BUFFER + $3f8
  • ständig zwei Screens updaten, ebenso Sprite Pointer etc,

    Die Sprite Pointer sind das einzige, was außer dem Screen selber behandelt werden muss. Ich setze immer einfach beide Pointer, das ist glaube ich schneller und kleiner als eine Abfrage. Für den Teil des Screens, der nicht gescrollt wird, kannst Du entweder beide Screens identisch beschreiben, oder Du benutzt einen Raster-IRQ und schaltest nur für den scrollenden Teil den Screenbuffer um.

  • So langsam wird's - tausend Dank für Eure tolle Hilfe!


    Jetzt kopiere ich nur noch das color ram in einem Rutsch.
    Dennoch benötigt das ganze knapp zuviel Zeit und bringt die erste Zeile noch zum flackern.


    Dabei ist mir aufgefallen, dass der IRQ Trigger nur funktioniert, wenn ich einen Wert zwischen 0 und 38 eintrage. Alle Werte darüber führen aus dem IRQ nicht mehr zurück. Kann ich den IRQ nicht auch bei z.B. $F8 anspringen?




    Oder lässt sich bei der col ram Routine noch was rausholen?



  • Dabei ist mir aufgefallen, dass der IRQ Trigger nur funktioniert, wenn ich einen Wert zwischen 0 und 38 eintrage.

    Ein beliebter Fehler (ich spreche aus Erfahrung :whistling: ) ist es, Bit 8 der Rasterzeile zu ignorieren (ist in $d011). Wenn das gesetzt ist, wird auf die Rasterzeile in $d012 immer 256 aufaddiert. Setz Bit 8 mal explizit auf 0, das könnte es sein.

  • Leider nein, im Endeffekt verbrauche ich dadurch noch mehr Rasterzeit.

    Das stimmt zwar, aber Du gewinnst trotzdem Zeit: dadurch dass Du die obersten 7*8=56 Rasterzeilen schon erledigt hast, darf der Rasterstrahl bis zur 56.sichtbaren Zeile laufen bevor es flackert. Diese Zeit gewinnst Du, um den unteren Teil zu scrollen. Da Dein Loop im Moment auch in der letzten Iteration die allererste Zeile anfasst, musst Du im Moment schon fertig sein, bevor der Rasterstrahl diese erste Zeile erreicht.

  • Hmm. Es klingt logisch, nur will mein Gehirn dieser Reise nicht folgen ;)
    Hier mal der aktuelle Codes des Grauens (es gibt vermutlich viel schlauere Ansätze, zwischen screen und screen_buffer zu wechseln, aber dieser hier ist zumindest simpel)


  • Ein beliebter Fehler (ich spreche aus Erfahrung ) ist es, Bit 8 der Rasterzeile zu ignorieren (ist in $d011). Wenn das gesetzt ist, wird auf die Rasterzeile in $d012 immer 256 aufaddiert. Setz Bit 8 mal explizit auf 0, das könnte es sein.

    Danke für den Reminder - hat immerhin drei Rasterzeilen eingebracht (bis $fb geht das Interface)