Hello, Guest the thread was called14k times and contains 86 replays

last post from DMHas at the

Nufli File Specs?

  • Neuer Zwischenstand:


    Hab jetzt Rolands Tabellen analysiert. Musste feststellen, dass meine Vorstellung davon, wie die Sprites im Bild verteilt sind, falsch war. Ich dachte, sie liegen zusammenhängend vor, also ein komplettes Sprite und dann das nächste usw. Das ist nicht der Fall. Genauso dachte ich, dass die Sprites durch die y-Expandierung doppelt dicke Pixelzeilen hätten. Stimmt auch nicht. Ich kann daher nicht gemütlich ein Byte nach dem anderen aus der REU holen, sondern muss ständig springen. Das ist mir zu unübersichtlich, deswegen überlege ich, Rolands Tabellen direkt zu übernehmen (darf ich?)


    Frage dazu: Die Tabellen sehen so aus, als ob das erste Pixel links oben (und dann so weiter) vom rechten Rand des zugehörigen Sprites geholt wird (und nicht vom linken). Die erste Adresse ($5e85) ist eben das sechste Byte im ersten Sprite, das liegt am rechten Rand der zweiten Sprite-Pixelzeile. Soll das so sein oder passiert in deinem Editor mit dieser Adresse noch was (so dass die folgende Adresse $5e86 die eigentlich angesteuerte ist)?


    Es dauert noch...


    Arndt

  • zum Thema Tabellen verwenden. Überhaupt kein Problem. Nimm was immer du willst :)


    zu den Sprites.
    Verabschiede dich von der Vorstellung eines normalen Sprites, bei dem die Daten in der Form:
    1. Zeile 00, 01, 02
    2. Zeile 03, 04, 05
    usw.
    gespeichert sind.


    Durch das "Spritecrunching" wird die Spritedarstellung zu Beginn für den VIC völlig durcheinandergebracht.
    So beginnt eine Spritezeile plötzlich mit:


    05, 06, 07,
    und geht dann weiter...
    08, 09, 0a,
    0b, 0c, 0d,
    usw...


    Und normalerweise hört dann der VIC mit der Spritedarstellung auf, wenn die Zeile mit der Datenposition $3f beginnen würde (was ja normalerweise nach $3c, $3d, $3e) der Fall wären.
    Durch das anfängliche "Spritecrunching" passiert aber folgendes.


    die Zeilen sind:
    ...
    38, 39, 3a,
    3b, 3c, 3d,
    3e, 3f, ...oops? wo soll ich weitermachen? (Fragt sich der VIC)...ach, einfach am Anfang...also 00,
    01, 02, 03,
    04, 05, 06
    usw...


    ...und so hört das Sprite eben nicht wie normal nach 21 auf, sondern wird einfach weiter dargstellt.
    Daher muss ich im Code auch nicht so oft die Y-Spriteposition neu nach unten setzen.


    Und durch die y-Expandierung sind die Sprites:


    05, 06, 07,
    05, 06, 07,
    08, 09, 0a,
    08, 09, 0a,
    0b, 0c, 0d,
    0b, 0c, 0d,


    ....aber da eben immer zwischen den doppelten Zeilen $D018 (mit den Spritepointern) verändert wird,
    sind die Pixel auf dem Bildschirm eben nicht doppelt, sondern die Daten kommen immer wieder aus anderen Bereichen.


    ACHTUNG:
    Die erste Zeile (05,06,07) ist quasi nur einmal im sichtbaren Bereich, damit die Y-expandierten Spritepixel abwechselnd mit dem 2-Zeilen FLI (mit $D018) auftritt.


    Also:
    1. Zeile: $d018 = $78. Spritedaten: 05, 06, 07,
    2. Zeile: $d018 = $78. Spritedaten: 08, 09, 0a,
    3. Zeile: $d018 = $68. Spritedaten: 08, 09, 0a,
    4. Zeile: $d018 = $68. Spritedaten: 0b, 0c, 0d,
    5. Zeile: $d018 = $58. Spritedaten: 0b, 0c, 0d,
    ....

  • Gut, das war hilfreich. :-) Meine Vorstellung von Sprites gilt hier nicht. Alles ist anders. Nochmal: Wahnsinn! Wer findet sowas raus und nutzt das dann auch noch so umwerfend wie in so einem NuFLI-Bild? Ich wäre ohne deine Unterstützung nicht einen Millimeter vorangekommen!


    Hier jetzt der erste Versuch des NuFLI-Sprite-Layers, noch ohne die Farben. Ich habe deine Tabellen etwas algorithmisiert, da GoDot unter dauerhaftem Platzmangel leidet. Fünf 200-Byte-Tabellen? Geht da gar nicht. Also:


    Auf die Weise ist die $8c00-Tabelle komplett rausgefallen, da sie ja nur zwei Werte enthält. Die Tabellen $8d00 und $8f00 sind jetzt jeweils in drei Teile aufgesplittet und je 32 Bytes lang (16+8+8), die Indexierung läuft dabei über Ausmaskierung mit #31 bzw. #7 bezogen auf die Rasterlinie (bei der 16er-Tabelle) bzw. den Spritestreifen (also die Kachelspalte bei den 8er-Tabellen). $8cd0 und $8dd0 sind nun 6 Bytes lang (je Spritestreifen) und $8ed0 auch (das müssten die Offsets auf die drei Bytes einer waagerechten Spritelinie sein, wenn ich das richtig verstanden habe). Die Tabelle $8e00 für Sprite 6 ist jetzt 8 Bytes lang.


    Langer Rede kurzer Sinn: Alles ist wegen GoDot etwas "komprimierter". Wenn ich dann mein Testbild rendere, kommt das dabei raus:


    Erster Versuch für den Sprite-Layer


    Sieht irgendwie nicht so aus, wie es soll... :-(


    Im oberen Teil kommt nur das x-expandierte erste Byte des Sprites rüber (bei anderen Bildern sieht man auch die anderen beiden Spritebytes aber die sind dann falsch und wiederholen sich immer, genau wie im unteren Teil des Bildes). Im unteren Bildteil ist das Bild an derselben Stelle richtig wie oben, aber der Rest wird ebenfalls falsch geholt und wiederholt sich. Ich gehe als nächstes meine Algorithmen durch und mache stepweises Tracen, damit ich rausfinde, wo die Sache schiefgeht. Könnte was dauern.


    Arndt

  • Ja - Sprites kann man es kaum noch nennen...


    Ich versuch grad gedanklich noch irgendwie zu folgen.
    Was ist denn grad der Task ?


    Du versuchst Die Nufli Spritelayer in eine Hires Grafik zu verwandeln ? Und nun ist die Frage: " Woher die Daten für die Spritelayer aus dem Speicher lesen ? " - soweit korrekt ?


    Was also gesucht wird ist eine Formel oder Tabelle, bei der ich eine Bildschirmposition eingeben kann - und die dann eine Speicheradresse ausspuckt, in der steht : hier ist der Doppelpixel gesetzt oder nicht.


    Ein Sprite zieht sich also über 127 Rasterzeilen lang und ist je 3 bytes breit ? Also insgesamt 381 bytes pro Sprite ??


    Und dann wird auch noch alle 2 Rasterzeilen der Spritepointer zusammen mit dem Screenram gewechselt ?


    Also meine Herren - raus damit : Wo sind nun die Daten Versteckt und wie kann man sie abgreifen ?


    Beispiel:


    Sagen wir mal , ich will in Rasterzeile 10 vom oberen sichbaren Bereich aus gemessen das 1. Pixel von Sprite 1 Setzen.. - Welche Speicheradresse muß ich da wählen und warum ? :honk::tischkante:

  • Du versuchst Die Nufli Spritelayer in eine Hires Grafik zu verwandeln ? Und nun ist die Frage: " Woher die Daten für die Spritelayer aus dem Speicher lesen ? " - soweit korrekt ?

    Jepp, korrekt. Zusätzlich muss ich die Pixel auf 4Bit aufpusten, da GoDots Pixel eben 4 Bit breit sind.


    Quote

    Was also gesucht wird ist eine Formel oder Tabelle, bei der ich eine Bildschirmposition eingeben kann - und die dann eine Speicheradresse ausspuckt, in der steht : hier ist der Doppelpixel gesetzt oder nicht.

    Nein, das steht bereits in Rolands Tabellen drin, zusammen mit seinen kurzen Code-Schnippseln. Ich habe die Tabellen für GoDot nur etwas zusammengestrichen.


    Quote

    Ein Sprite zieht sich also über 127 Rasterzeilen lang und ist je 3 bytes breit ? Also insgesamt 381 bytes pro Sprite ??

    Hm, ein Sprite wird beim Sprite-Crunch eingeschaltet, schaltet sich aber (durch exaktes Timing) nicht wieder aus. Zum Hintergrund ist hier ein Artikel zu finden (der sich mit einer anderen Anwendung des Sprite Crunch beschäftigt). In dieser Zeit kann er ständig mit neuen Daten beschickt werden, also immer anders aussehen, wenn man weiß, wie.


    Quote

    Also meine Herren - raus damit : Wo sind nun die Daten Versteckt und wie kann man sie abgreifen ?


    Beispiel:


    Sagen wir mal , ich will in Rasterzeile 10 vom oberen sichbaren Bereich aus gemessen das 1. Pixel von Sprite 1 Setzen.. - Welche Speicheradresse muß ich da wählen und warum ? :honk::tischkante:

    Das steht in Rolands Tabellen! Rasterzeile 10 ergibt sich aus Tabelle $7f00, Byte 10 (Zählung ab 0): $14 (für Low), das zugehörige Hibyte steht in Tabelle $8d00 an Position 10: $4a. Dieser Wert muss noch mit verschiedenen anderen Werten (für die horizontale Position der Sprites und der Herkunft der Daten) zwischenbehandelt werden (dazu Tabelle $8c00 und die drei kleineren Tabellen).


    Übrigens hab ich oben eine falsche Angabe bei den Maskierungsbytes gemacht: Für 16 Bytes braucht man nicht #31 als Maske, sondern natürlich nur #15... (sorry, war im Eifer des Gefechts) ;-)


    Arndt

  • Ya! :tanz:
    Kleiner Fehler, große Wirkung! Ich dachte, ich hätte den Zeiger auf die Rasterlinie immer im Blick, war aber nicht so... ;-)


    Also, unser Testbild hat diesen Sprite-Layer:


    Der Sprite-Layer!


    An den großen Clash-Stellen sieht man die Übereinstimmung mit dem AFLI aus Post 23. Nächster Schritt: Die Spritefarben.


    Bitte warten... :f5:


    Arndt

  • ...und die Farben haben wir jetzt auch. Damit ist der Sprite-Layer für das AFLI komplett. Ich zeige nochmal alle Bilder nebeneinander:



    Links das NuFLI, in der Mitte der AFLI-Anteil daraus und rechts der Sprite-Layer mit den Farben, die im AFLI nicht dargestellt werden können (der blaue Hintergrund ist nur, damit man die Farben besser erkennen kann, was blau ist, ist eigentlich transparent). Die müssen dann noch zusammengebastelt werden, wobei der Sprite-Layer unter dem AFLI-Layer liegt, stimmt das, Roland?


    Jetzt fehlen noch die Sprites für den FLI-Bug. Roland, gibt's da was Besonderes zu beachten? Liegen da nicht zwei Sprite-Layer übereinander? Einer in Hires und einer in Multi? Sprite 0 = Hires, Sprite 7 = Multi? Ist das so?


    Bin ganz elektrisiert! ;-)


    Arndt


  • Die müssen dann noch zusammengebastelt werden, wobei der Sprite-Layer unter dem AFLI-Layer liegt, stimmt das, Roland?


    Jetzt fehlen noch die Sprites für den FLI-Bug. Roland, gibt's da was Besonderes zu beachten? Liegen da nicht zwei Sprite-Layer übereinander? Einer in Hires und einer in Multi? Sprite 0 = Hires, Sprite 7 = Multi? Ist das so?


    Ja. Sprites unter dem AFLI (zumind. den gesetzten AFLI Pixeln)


    FLI Bug: Ja. Genau so wie du es geschrieben hast.
    Nun aber zu den Spritefarben.
    Während der Darstellung von 2 Zeilen ist nur Zeit für das setzen von 6 Farben. Das war zunächst auch OK, da auf dem AFLI Screen nur 6 Sprites sind.
    Der FLI Bug Bereich war ursprünglich ungenutzt.
    Wenn nun aber im AFLI Bereich keine neue Spritefarbe für die nächste Zeile gesetzt werden muss, kann diese Zeit für das verändern der Sprites im FLI Bug Bereich verwendet werden.
    Dies wird in den Farbtabellen mit bestimmten High-Nibbles festgelegt. Die 6 Tabellen für die Spritefarben der 6 Sprites im AFLI Bereich sind ja:
    $2400 (Sprite 1)
    $2480 (Sprite 2)
    $2800 (Sprite 3)
    $2880 (Sprite 4)
    $2c00 (Sprite 5)
    $2c80 (Sprite 6)


    Die Werte darin bedeuten folgendes.
    $00-$0f Farbe für das jeweilige Sprite (abhängig von der Tabelle)
    $40-$4f Position, an der der Y-Wert der Sprites umgesetzt wird. (sind also über die Tabellen die Werte 41, 43, 45, 47, 49, 4b, 4d und 4f verteilt)
    $50-$5f Farbe für $d025 (für das Multicolor Sprite 7 im FLI Bug)
    $60-$6f Farbe für $d026 (für das Mutlicolor Sprite 7 im FLI Bug)
    $70-$7f Farbe für $d027 (für das Hiressprite 0 im FLI Bug)
    $e0-$ef Farbe für $d02e (für das Mutlicolor Sprite 7 im FLI Bug)


    Und weiterhin im FLI Bug Bereich zu beachten:
    Der ersten 2 Zeilen jedes 8 Zeilen Block ist auch 100% AFLI.
    Die Zeilen 3-8 jedes 8 Zeilen Block haben dann nur noch Hellgrau als Farben der Pixel. Damit kann man aber eben auch mit Hellgrau Bereiche der Sprite (wie im AFLI) überdecken.

  • Oh ja, das ist ja allerhand Info, die mir nicht klar war.


    Der Reihe nach: Die Farben sind bereits erledigt, Sprite 1 bis 6 sind korrekt gefärbt. Das siehst du hier im neuesten Testbild (wo allerdings die Sprites noch VOR den AFLI-Pixeln liegen, also nicht über die Pixelfehler wundern - es soll nur zeigen, wie dicht ich schon dran bin):


    Sprite-Layer noch vor dem AFLI


    (Das Bild ist von GoDot als GIF gespeichert mit der CoCo-Palette, das Braun in Deekays Palette war mir zu dunkel.)


    Was ich aber gar nicht wusste, ist, dass in den Farben die High-Nibbles auch was zu bedeuten haben (obwohl mir auffiel, dass da sowas vorkommt)! Darum frage ich an diesem Punkt lieber noch mal nach:

    $40-$4f Position, an der der Y-Wert der Sprites umgesetzt wird. (sind also über die Tabellen die Werte 41, 43, 45, 47, 49, 4b, 4d und 4f verteilt)

    "Umgesetzt"? Was meinst du damit genau? Ist das für die Einfärbung relevant?


    Und ich hab in unserem Testbild auch Werte mit einer 1 im High-Nibble. Was steckt da denn dahinter?


    Arndt

  • für die spriteeinfährbung im afli bereich sind nur die bytes mit 0 im highnibble. also nur werte von 00 - 0f.
    Wenn du die anderen bytes auch verwendest bekommst du im afli bereich falsche farben.



    die werte 40 - 4f sind für dich irrellevant. mit umgesetzt meinte ich, dass hier die y-position verändert, bzw. auf $d4 gesetzt wird.
    ich kann ja leider auch mit spritecrunching die sprites nicht über die gesamten 200 pixel ausdehnen.
    die sprites starten irgendwo vor der ersten afli bildzeile, und dort wird auch gleich die nächste position $aa gesetzt (bevor die erste afli zeile beginnt)
    nun muss ich halt noch einmal zwischen rasterzeile $aa und $d4 die 8 sprites auf die position $d4 setzen.
    und genau das wird mit den bytes 41 - 4f in den farbtabellen bestimmt. aber wie gesagt. für dich zunächst nicht wichtig.
    sollte godot allerdings auch bilder anderer formate IN nufli umwandeln können, dann muss das auch berücksichtigt werden.
    die werte 41, 43, 45, .... 4f müssen EINMAL in einer der farbtabellen zwischen den zeilen $xx55 und $xx6a auftauchen.


    und nun OOOOOooooooops!
    Nun stelle ich fest, dass der muflon nufli konverter wohl eine andere (ältere) darstellungsroutine verwendet, als der nufli editor.
    das fällt nicht auf, da die (ungepackten) bilder den displayer enthalten und so der unterschied nicht auffällt.


    der muflon konverter verwendet 40-4f für das setzen der sprite y-positionen.


    im nufli editor hab ich das aber anders. dort wird 10-1f dafür verwendet.
    (und auch noch highnibble 2 für das setzen von $d020)


    so finde ich in den mit muflon erstellten bildern, die anschließend mit dem editor bearbeitet wurden sowohl 11-1f, als auch 41-4f :(
    und da sind die 41-4f bytes völlig blödsinning, da dann im speedcode $d024 gesetzt wird (was allerdings nichts ausmacht)

  • 2 Zeilen AFLI im NUFLI-Kontext bedeuten doch aber im Prinzip 2 Zeilen "reines" Hires oder? :) Man hat 2 Farben für 8x2 Pixel. Echt AFLI wäre ja 2 Farben für 8x1 Pixel und 2 andere Farben für die darunter liegenden 8x1 Pixel.


    Ja, da hab ich mich falsch ausgedrückt. sind 2 farben für 8x2 Pixel. Wollte nur rüber bringen, dass dort eben nicht alles grau ist wie sonst im flibug, sondern so wie auch in anderen 8x2 blöcken des 2-zeilen aflis..

  • ah, und noch eine gemeinheit im flibug bereich.


    die farben können ja auch dort nur alle 2 zeilen verändert werden.
    mit einer gemeinheit.
    die farben aus der ersten farbtabelle ($2400) ändern die flibugspritefarben in zeilen 1, 3, 5, 7, ...usw. (und hier darf man im editor auch die borderfarbe $d020 nicht umsetzen)
    die farben aus den anderen farbtabellen ändern die flibugspritefaben in den zeilen 2, 4, 6, usw.



    das gilt aber nur im flibug bereich.


    im aflibereich wenn die farben bei allen 6 sprites in den zeilen 2, 4, 6, 8... geändert (also assynchron zum afli-farbwechsel)

  • Die FLI Sprites sind im Prinzip genauso verteilt, wie die anderen Sprites (zumind. was die Low-6-Bits betrifft).
    Was den Tabellen für den Speicherposition für die Highbytes + Low-oberersten-2-Bits betrifft müsste ich auch nochmal nachschauen :)


    Edit: Hier nun die Tabelle + Berechnungscode


    Spritedaten im fli bug:


    Ist ähnlich wie im afli screen.
    Positionsberechnung wieder mit X (00 bis 02) und Y (00 bis $c7)
    Initiale Lowbyte Offset wieder Tabelle $7f00.


    TXA
    CLC
    ADC $7F00,Y
    AND #$3F
    ORA $A800,Y
    STA $lowbyte sprite7
    STA $lowbyte sprite0
    LDA $A900,Y
    STA $highbyte sprite7
    CLC
    ADC #$02
    ORA #$10
    STA $highbyte sprite0



    >C:a800 c0 c0 80 80 40 40 00 00 c0 c0 80 80 40 40 00 00
    >C:a810 c0 c0 80 80 40 40 00 00 c0 c0 80 80 40 40 00 00
    >C:a820 c0 c0 80 80 40 40 00 00 c0 c0 80 80 40 40 00 00
    >C:a830 c0 c0 80 80 40 40 00 00 c0 c0 80 80 40 40 00 00
    >C:a840 c0 c0 80 80 40 40 00 00 c0 c0 80 80 40 40 00 00
    >C:a850 c0 c0 80 80 40 40 00 00 c0 c0 80 80 40 40 00 00
    >C:a860 c0 c0 80 80 40 40 00 00 c0 c0 80 80 40 40 00 00
    >C:a870 c0 c0 80 80 40 40 00 00 c0 c0 80 80 40 40 00 00
    >C:a880 00 00 40 40 80 80 c0 c0 00 00 40 40 80 80 c0 c0
    >C:a890 00 00 40 40 80 80 c0 c0 00 00 40 40 80 80 c0 c0
    >C:a8a0 00 00 40 40 80 80 c0 c0 40 40 80 80 c0 c0 00 00
    >C:a8b0 40 40 80 80 c0 c0 00 00 40 40 80 80 c0 c0 00 00
    >C:a8c0 40 40 80 80 c0 c0 00 00 00 00 00 00 00 00 00 00



    >C:a900 77 77 77 77 77 77 77 77 76 76 76 76 76 76 76 76
    >C:a910 77 77 77 77 77 77 77 77 76 76 76 76 76 76 76 76
    >C:a920 77 77 77 77 77 77 77 77 76 76 76 76 76 76 76 76
    >C:a930 77 77 77 77 77 77 77 77 76 76 76 76 76 76 76 76
    >C:a940 77 77 77 77 77 77 77 77 76 76 76 76 76 76 76 76
    >C:a950 77 77 77 77 77 77 77 77 76 76 76 76 76 76 76 76
    >C:a960 77 77 77 77 77 77 77 77 76 76 76 76 76 76 76 76
    >C:a970 77 77 77 77 77 77 77 77 76 76 76 76 76 76 76 76
    >C:a980 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
    >C:a990 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
    >C:a9a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
    >C:a9b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
    >C:a9c0 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00

  • Die FLI Sprites sind im Prinzip genauso verteilt, wie die anderen Sprites (zumind. was die Low-6-Bits betrifft).
    Was den Tabellen für den Speicherposition für die Highbytes + Low-oberersten-2-Bits betrifft müsste ich auch nochmal nachschauen :)

    Oh, bitte! Ich hab zwar verstanden, was da passiert, was aber nicht heißt, dass ich das einfach so nachprogrammieren könnte... ;-)


    Mist! Dummerweise bin ich die ganze nächste Woche auf Kurzurlaub. :-( Werde wenigstens meine Unterlagen mitnehmen, damit ich im Kopf weiterarbeiten kann. Hehe... :-)


    Arndt