Eigenes Videoformat

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Benutzeravatar
MSDOS622
Kommandozeilenfetischist
Beiträge: 152
Registriert: Sa 1. Mär 2014, 20:15

Re: Eigenes Videoformat

Beitrag von MSDOS622 »

Yo danke, aber dieser konvertieren macht manchmal hässliche Artefakte wenn man nicht unkomprimiert konvertiert.

Habe jetzt den originalen "Autodesk Animator Pro Player" von damals :'D

http://cd.textfiles.com/mmplus/DOS/ANIM/AAPLAYHI/


Funktioniert einwandfrei.
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

Ich denke ich bin bald fertig mit meinem Grafikformat.

Bin noch dabei, die Sache mit den Farben zu optimieren, nachdem
ich auch redundante Blöcke, d.h. indentische, nur einmal definiert
habe und stattdessen einen Verweis darauf gemacht habe als dieselben
Daten mehrmals zu speichern.

Jeder 8x8 Block hat ja seine jeweilige Methode, Farbinformationen
zu speichern, und dazu gehört auch immer ein Verweis zu einer Palette,
d.h. einem Datenbereich, in dem die zu verwendenden Farben gelistet
sind. Nun habe ich für optimal befunden, wenn sich die Listen überlappen,
wenn möglich. Die Informationen müssen sich dabei nur gegenseitig
beinhalten, Reihenfolge der Einträge ist egal.

Mal ganz einfaches Beispiel:

"Palette" 1: 26 89 66
(2 Bit Mapping)

"Palette" 2: 11 54 89 12 66
(3 Bit Mapping)

Speichern muss ich hier dann lediglich: 26 89 66 11 54 12
Das ist aber auch der günstigste Fall, indem eine längere
Palette die kürzere komplett beinhaltet - und die Werte
der kürzeren müssen innerhalb der mit der Bitbreite
möglichen Mappings adressierbar sein.
Und es sind hier nur zwei Paletten, in der Praxis hat man
aber deutlich mehr - je nachdem wie gut sie sich ineinander
verschachteln lassen.

Habe ich beispielsweise eine Palette mit der Länge 22,
dann ist das mit 5 Bit gemapt. Kommen mehrere Blöcke
vor, die mit 5 Bit gemapt werden, dann ist es wahrscheinlich,
je nach Bild, dass diese viele Farben gemeinsam haben,
und dass man diese Farben alle in einer Palette von 32
Einträgen unterbringen kann. Somit spart man sehr viel
Speicherplatz. Angenommen man hat 200 Blöcke mit im
Schnitt 20 Farben, dann lassen sich auf diese Weise rund 4KB
sparen.

Die Frage ist nun eben noch, und daran knoble ich, wie man
ganz allgemein die gesamten Palettendaten so verdrehen und
ineinanderschieben kann, dass diese möglichst kurz sind und
eben trotzdem alle Paletten aller vorkommenden Längen abdecken.
Ab wo in den Palettendaten gelesen werden soll wird mit einem
Byte oder Word, je nach tatsächlichem Offset, angegeben.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
MSDOS622
Kommandozeilenfetischist
Beiträge: 152
Registriert: Sa 1. Mär 2014, 20:15

Re: Eigenes Videoformat

Beitrag von MSDOS622 »

Ich bin schon auf ein umgewandeltes "Beispielvideo" gespannt :)
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

Ich will das erstmal verlustfrei auslegen, daher wird es vom Aussehen her nicht anders
sein als wenn man einfach unkomprimierte Bilder ausgibt.

Interessant ist es dann erst wenn man den Hintergrund versteht, und sich die gespeicherten
Daten mit ihrer Kompaktheit ansieht.

Ich habe mich bisher ersteinmal nur um Bilder speichern gekümmert, bei "Video" kommt dann
eben dazu, das nur das geändert wird wo tatsächlich etwas anders ist als beim vorherigen
Bild, und eben auch ganze Blöcke übersprungen werden, wenn da auch nichts passiert.

Weiterhin habe ich aber das Problem mit der Palette nicht gelöst.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

Bei der Video-Variante könnte es durchaus interessant werden, wenn man das mit FLI
vergleicht. Soweit ich mir erinnere kennt FLI nur Läuflängencodierung, da könnte meine
Variante effektiver sein.
Man könnte das an einem Block schonmal abschätzen:
Ein 8x8 Block in einem FLI, der sich komplett ändert, benötigt mindestens 64 Byte,
eher noch so 8-10 Byte mehr wegen der Lauflängencodierung.
Angenommen in diesem Block kommen nur 4 verschiedene Farben vor,
dann wären es bei mir (2 Bit) nur 16 Byte, plus ein Byte Header Info für den Block,
plus ein oder zwei Byte Verweis auf eine Palette, die man dann aber getrennt
betrachten muss, da sie mehrfach verwendet werden kann und bei Bildern
mit insgesamt nur 4 Farben auch nur einmal vorkommt.

Neben diesen Bit-Reduzierten Verfahren gibt es auch andere, z.B. wenn es sich
um einen Block handelt der fast nur durchgängig eine Farbe hat und lediglich
ein paar einzelne andere Pixel, dann wird das entsprechend kompakt abgespeichert,
bspw. nur 5 Byte.

Wenn ich das also mal fertig habe, mache ich wohl erstmal einen FLI to ... Converter.
wie soll ichs nennen? ZVD?
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
matze79
DOS-Gott
Beiträge: 7910
Registriert: So 9. Sep 2012, 20:48

Re: Eigenes Videoformat

Beitrag von matze79 »

BVF, Block Video Format

:D
https://www.shadowcircuit.de - Die kleine Community rund um Retro Computing
https://www.retroianer.de
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

Nee, ich denke mal ZVI ;) Aber das ist auch eher Nebensache.
MPEG und Konsorten sind ja auch Block-basierend.

Wichtiger wäre mal, das Palettenverfahren zu implementieren.

Beispiel:

Eine Palette sei: FDGAEKNL
die andere: ASDIEBFV

gemeinsam haben sie: F, D, A, E

Also kann man die beiden zusammenfassen: GKNL-FDAE-SIBV

...und hat 4 Einträge gespart.

Hat man nur 2 Paletten, dann ist das ganze sichtlich wenig kompliziert.
Zudem haben wir hier den Sonderfall, dass beide Paletten 8 Einträge lang sind.
Es ist so: Das Mapping einer Palette folgt mit 1, 2, 3, 4, oder 5 Bit (vielleicht
hinterher auch mit 6 Bit) und dementsprechend besteht eine jeweilige Adressierbarkeit
der Paletteneinträge mit einer "Spannweite" von 2, 4, 8, 16 oder 32.

Eine Palette mit 3 Bit Mapping kann daher eine Länge zwischen 5 und 8 haben.

Nehmen wir nun zwei Paletten an, eine mit der Länge 8, eine andere mit der Länge 5:
AEUHKFBC
ASDZC

gemeinsam: A, C
-> EUHKFB-AC-SDZ

So kann man an diese zusammengesetzten Palettendaten noch drei beliebige Werte
anhängen, ohne dass dies die Palette mit der Länge 5 beeinträchtigen würde.
Jedoch, wenn ich nicht irre, müssen für alle weiteren Schritte alle durch Striche
getrennten Abschnitte ihre Werte behalten, die aber innerhalb der Abschnitte umgestellt
werden dürfen - und der Teil rechts darf eben noch 3 Werte dazubekommen und diese 6
dürfen dann auch beliebig umgestellt werden.
Man könnte es also auch so schreiben: EUHKFB-AC-SDZxxx-...

Das alles scheint mir ein wenig komplex... Das hier ist schonmal der erste
Schritt, aber es muss bedacht werden, dass wir es hinterher nicht mit nur
zwei Paletten zu tun haben, sondern mit einigen dutzend.

Vielleicht probiere ich auch noch einmal, mit den kleinsten Paletten zuerst anzufangen.
Oder, anders, mit den Paletten anfangen, welche die meisten gemeinsamen Einträge haben.

Die Sache lohnt sich auf jeden Fall, denn bei einem 320x200 Bild habe ich 1000 Blöcke
und somit 1000 Paletten. Im ungünstigsten Fall hat jeder Block sagen wir mal 33 verschiedene
Farben, jedoch seien die Paletten jeweils ähnlich, bis auf ein paar verschiedene Einträge.
Durch geschicktes Sortieren, und da ab 33 Farben tatsächlich 64 Einträge addressiert
werden können, habe ich letztlich statt 1000*33 Paletteneinträge (= 33000 Byte) nur
z.B. 1 * 64 Paletteneinträge und habe somit rund 32 kb gespart. Das ist zwar ein
etwas realitätsfernes Beispiel, aber durchaus möglich.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

Ich häng echt jetzt schon länger fest an der Paletten-Sache. Wenn jemand eines Geistesbitz dazu hat,
lasst es mich wissen! Wie gesagt, es geht darum, mehrere (je nachdem mehrere hundert) Paletten
verschiedenster Länge und Belegung so ineinander zu verschachteln, dass sie per Offset abrufbar sind
und aber eben deutlich weniger Speicherplatz belegen, als würde man sie einfach alle "dumm" abspeichern.
Ein Hinweis, der helfen kann: Die Paletten haben jeweils eine maximal-Länge von 2er Potenzen und
werden auch so gemappt. Bspw. habe ich eine Palette der Länge 5, dann wird sie schon mit 3 Bit
gemappt und man kann ihr noch bis zu drei Werte einer anderen überlagern, ohne dass ihr das was ausmacht.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

Das mit den Paletten habe ich vorerst schonmal gelöst.

Das Projekt geht etwas langsam voran, aber ich bleibe dran...

Ersteinmal lege ich es nicht für Nur-Veränderungen-Speichern-Transparenz aus.

Nebenbei, gibt es in Assembler eigentlich etwas schnelleres bzw. gleiches
schnelles wie "OR AL, AL / JZ ... " ? Index 0 als transparent zu behandeln
ist nicht immer optimal.

Evtl. vorher ein Register (z.b ah) auf not al setzen und dann test al, ah?
Damit könnte al beliebige Werte haben.
mov ax, 13h
int 10h

while vorne_frei do vor;
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von DOSferatu »

es gibt für CX (bzw ECX) den Befehl JCXZ (bzw JECXZ), der springt, wenn CX=0 (bzw ECX=0) ist. Hier muß dann nicht erst "getestet" werden.

Einschränkungen:
1. Gibt es nicht für andere Register. (auch nicht für CL oder CH, aber man könnte ja z.B. CH auf 0 setzen und nur CL benutzen, dann wäre CX ja auch 0, wenn CL=0 ist)
2. Die Sprungweite für diesen Befehl ist maximal 8 Bit (also -128 bis +127 Byte).
3. Es gibt keinen gleichwertigen Sprungbefehl für den Fall, daß CX ungleich 0 ist.

Außerdem: Wenn sich die 0 aus dem Ergebnis einer BERECHNUNG (Leider nicht bei den Shift-Befehlen) ergibt, also Addition/Subtraktion/Multiplikation/Division und auch AND/OR/NOT/TEST/CMP, dann braucht man nicht nochmals testen, weil dann automatisch bereits das Zeroflag gesetzt wird (oder gelöscht ist, wenn Ergebnis <>0)

Ich, der ich Register immer gern total mißbrauche, d.h. die einzelnen Bytes der Register für verschiedene Zwecke einsetze, mache manchmal so etwas, wie:
Ich brauche in AH einen Wert (sagen wir $8A) und will einen anderen Wert nach AL laden und wenn dieser =0 (oder <>0) ist, springen:

mov DX,$8A00
or DL,WERT {Hier eben den zu holenden WERT, also die Speicherreferenz oder was auch immer}
jz @IsZero {oder eben jnz @IsNotZero oder was auch immer}

Man kann auch schön das jeweils oberste Bit testen (setzt/löscht ja das Sign Register).

Assembler-Programmieren macht so einen Spaß - in Hochsprache müßte man manchmal eine umständliche Befehlskaskade basteln, was in Assembler mit Flags, geteilten Registern und Entscheidungstabellen geht...

Nichts gegen intelligente Algorithmen - aber wenn diese dann auch noch an die technischen Gegebenheiten der ausführenden Maschine angepaßt werden - erst dann rockt das Ganze so richtig...

(Schade, daß die Programmierer, die das zu schätzen wissen, immer weniger werden. Wahrscheinlich, weil mit systemunabhängig geschriebener Software - die dann vielleicht auch nicht ganz so performant ist - in kürzerer Zeit mehr Geld verdient werden kann.)
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

So, nun habe ich endlich etwas zum Zeigen.

Erste ZVID Version (meinetwegen beta alpha oder sonstwas) ist fertig !

Das sind ein paar Videos, von Spielen, und von ein paar FLI's zum Größenvergleich, ich kündigte ja an,
dass die Komprimierung effektiver sein würde als FLI.
Einfach ZVDEMO aufrufen und den Videonamen eingeben, oder als Kommandozeilenparameter, ohne Erweiterung.
Die Palette habe ich jeweils aus Prinzip extra gespeichert, weil das so in der letzendlichen Verwendung des Formats
auch so sein wird, denn es soll eigentlich gar kein Videoformat werden wie AVI oder soetwas, sondern vielmehr die
effiziente Speicherung von Grafiken ermöglichen, die man dann in einem Spiel etc. verwenden kann.

Die Demo macht am Anfang eine kurze Pause, damit sich Röhrenmonitore
auf den anderen Bildschirmmodus einschwingen können.

Hier der Link:

http://www.zatzen.net/zvdemo.zip (1,25 MB)



Hier mal der Größenvergleich FLI - ZVD:

SKELLY -- FLI: 151K ZVD: 61K

SMLSPIDR -- FLI: 228K ZVD: 132K

EARTH -- FLI: 192K ZVD: 139K

HIT_ANY -- FLI: 647K ZVD: 209K

TIGERCAT -- FLI: 99K ZVD: 53K

JABBER -- FLI: 46K ZVD: 37K

FLY -- FLI: 46K ZVD: 25K

MARILYN -- FLI: 37K ZVD: 19K

Je nach Ausgangsmaterial ist die ZVD Kompression auch deutlich effektiver als ZIP.
Darauf dann aber nochmal ZIP abgewendet, wird es nochmals eine ganze Ecke kleiner.
Im Moment sind die Viewer-Routinen noch langsam, aber das wird sich ändern.

Die Vorgehensweise des Formats ist:
- alles in 8x8 Blöcke zerlegen
- diese Blöcke jeweils so klein wie möglich speichern (nur so viel Bits wie nötig etc.)
- Redundante (d.h. mehrfach vorkommende) Blöcke gesondert abspeichern und
in den jeweiligen Bildern nur Verweise darauf speichern
- gleiche aufeinanderfolgende Blöcke RLE codieren.
- nicht für jeden bitreduziert-optimiert codierten Block die indizierten Farben speichern,
sondern die indizierten Daten für alle Blöcke in einer Gesamtpalette sammeln, diese
möglichst kompakt optimieren, und dann für jeden Block nur ein Offset in diese Daten
hinein speichern, je nach Offsetposition ein Byte oder ein Word.

Eine ZVID-Datei kann mehrere Frames enthalten (Viewer unterstützt derzeit ca. 8000), es gibt vier Bänke,
die redundante Blockdaten enthalten. Vier deshalb, falls die redundanten Blockdaten größer als 64K oder
gar 192K werden. Die Erfahrung wird aber zeigen ob das wirlich nötig ist, wenn nicht kann ich mir beim
Viewer eine Pointer-Ebene sparen, was auch eine kleine Geschwindigkeitssteigerung mit sich bringen würde.
Schliesslich noch die "Paletten"-Daten, sprich die Indizes für die verschiedenen Blöcke, bspw. wenn ein Block
mit 3 Bit gespeichert wird, braucht er noch je nachdem 5-8 Indizes welche Farben gemeint sind.

Verbesserungswürdig ist momentan vor allem der Viewer für den Real Mode, dort sind die Assembler-Routinen
noch nicht optimal, und es gibt statt Sprungtabelle für die Routinen derzeit noch IF-Abfragen.
Zudem, und das ist wohl das größte Manko, wird momentan, zum ersten sicheren Testen, noch doppelt und dreifach
Speicher herumgeschoben, heisst: Die Daten aus dem Blockdaten-Stream werden ersteinmal in einen Puffer für
die decodier-Routinen kopiert, dann in einen 8x8 Pixel-Puffer decodiert, und dieser dann erst in den Bildschirmpuffer
kopiert.
Bei der Demo kommt noch hinzu, dass ich eben noch einen Screenpuffer vorschalte, damit das Bild bei zu viel
Leistungsanforderung nicht schwabbelt sondern alles nur langsamer wird.

Umso interessanter wäre Feedback von euch, wie langsam oder schnell das jetzt schon auf diesem oder jenem System läuft,
und ob die Framerate (hier standard-Timer-mäßig 18.2 fps) erreicht wird.
Einige Videos sind aber gecaptured und auf 18.2 fps konvertiert obwohl sie in echt noch weniger Framerate hatten, daher
kann man das nicht immer so gut beurteilen.
Die Festplatte meines Pentiums ist leider gerade defekt, und der neue Rechner hat kein Diskettenlaufwerk um eine Boot Disk
zu machen. Okay, Boot CD-ROM wäre eine Optium.

Beim Converter bzw. Encoder sollte noch hinzugefügt werden, dass auch Spiegelungen der Blöcke als redundant erkannt
werden, das würde noch ein wenig die Blockdaten jedes Frames reduzieren und gleichzeitig die Datengröße der redundanten
Blöcke je nach Quellmaterial deutlich verkleinern.
Auch könnte man prüfen, ob ganze Frames mehrfach vorkommen, das wäre aber eher nur interessant für Videos und
weniger für Sprites.

Der Converter ist übrigens in Freepascal geschrieben, da es sehr hohe Speicherauslagen gibt (gerne mal 100MB im RAM bei
Videos), und dennoch ist er sehr langsam. Aber er funktioniert, und wenn es nur wenige tausend Blöcke sind geht das auch
innerhalb einer Sekunde. Man muss eben bedenken, dass wir bei einem Video mit sagen wir mal 1000 Frames eben eine
Million Blöcke haben!

Auch werde ich für zukünftige Versionen noch weitere Blocktypen einbauen. Derzeit gibt es nur Blöcke komplett einfarbig
oder transparent, Blockdaten 1-5 Bit, Block 1:1 nur kopieren (ab 33 versch. Farben / Block).
Denkbar sind Blocktypen, wenn z.B. ein Block hauptsächlich eine Farbe darstellt, und nur ein paar Pixel eine andere Farbe
haben, dann speichert man nur diese Hauptfarbe und die paar Pixel mit Koordinaten (d.h. Blockposition 0-63).
Zudem können auch geditherte Bereiche einer Grafik sehr effizient gespeichert werden, indem einfach nur die beiden
Farben vermerkt werden.

Ich habe hier für die Demo ersteinmmal nur Vollbild-Videos gemacht. Prinzipiell wird man das Format aber auch für Sprites
einsetzen können.
Ich gehe davon aus, dass mit gründlicher Optimierung des Viewers noch eine deutliche Geschwindigkeitsteigerung drin ist.
Trotzdem wird es natürlich nie so schnell sein wie ein einfacher Kopiervorgang.
Je nachdem was wichtiger ist, Geschwindigkeit oder Speicherplatz, kann man abwägen, ob es Sinn macht, das Format zu
verwenden.
Natürlich kann man auch Mischen, bspw. Hintergrundgrafiken nur schnell kopieren und eher kleine Sprites, aber mit vielen
Bewegungsphasen, mit ZVID einbinden. Die Handhabung der Unit ist sehr simpel, zuerst initialisieren, wie viele "slots" ein-
gerichtet werden sollen, d.h. wie viele .ZVD Dateien man laden will, auch übergibt man den Pointer des Videopuffers und die
X-Y Dimensionen von diesem. Zum Laden einer .ZVD gibt es eine Routine, ganz einfach nur Dateiname und "slot"-Nummer
angeben. Dann kann mittels einer Procedure aus einem beliebigen slot ein beliebiger Frame an beliebiger X-Y Position
dargestellt werden.

Auch wenn das Format im Prinzip langsamer ist als simple Sprite-Routinen, kann es sich unter Umständen die Waage halten,
aus zwei Gründen, in Zusammenhang mit Transparenz:
- Für Blöcke, die effektiv keine transparente Farbe enthalten,
findet keine pixelweise Transparenzprüfung statt.
- Blöcke, die komplett transparent sind, werden gar nicht erst
Pixel für Pixel durchgeprüft sondern es wird lediglich einfach
die Zieladresse entsprechend erhöht um den Bereich zu überspringen.

Die Bit-decodier-Routinen sind momentan noch ziemlich langsam, da ich sie ersteinmal generell gehalten habe. So werden
bei 1 Bit Codierung insgesamt 128 Byte gelesen, plus 64x ein Byte aus der Palette, die Bitposition gezählt u.a. Wenn ich das
konkretisiere und die Schleifen "entrolle", dann kann ich da viel effizienter rangehen, es genügt dann bei 1 Bit, alle 8 Pixel
ein Byte zu lesen, um daraus den Paletten-Index zu bestimmen - und eine 2-Farben-Palette kann bequem in Registern
gehalten werden, so dass das decodieren einer 1-Bit-Grafik sogar schneller gehen könnte als das kopieren einer 8-Bit-Grafik
- wenn Registerarbeit deutlich schneller ist als Speicher-Lesen.

Bei Interesse kann ich gerne noch Details über das Format erklären.
Es ist vielleicht eine gute Sache für Leute, die nicht gerne
viele gleiche Bytes aneinandergereiht mögen.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

EDIT: Hier war eine noch ziemlich schlechte 1Bit Decodier-Routine, ich habe das mal rausgenommen.
Zuletzt geändert von zatzen am Mo 21. Jul 2014, 01:04, insgesamt 1-mal geändert.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

Ich hatte gestern noch eine Routine hier gepostet, aber hier eine kompaktere Version, die direkt
mit al arbeitet und sich das Carry Flag zu Nutze macht, und dadurch nochmal vereinfacht und
womöglich schneller ist. Und ich habe jetzt zwei Schleifen. Den gestrigen Beitrag wollte ich jetzt
eigentlich löschen, nachdem ich sehe wie schlecht die Routine war, aber das geht hier nicht...

Code: Alles auswählen

procedure decode_bitstream_asm_1; assembler;
asm

  push ds

  les di, outblkbuf_pointer
  lds si, bitdata_pointer

  mov dx, ds:[si+40] { 2 Farben Palette in DX laden }

  xor ah, ah
  mov bx, 8

  @outerloop:
    lodsb
    mov cx, bx
    inc ah

    @loop:

      shr al, 1
      jnc @null
      mov es:[di], dh
      jmp @done
      @null:
      mov es:[di], dl
      @done:
      inc di

    dec cx
    jnz @loop

  test ah, bl
  jz @outerloop

  pop ds

end;
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

Hier die 2-Bit-Routine, mit 4 Farben in 32 Bit Register.
Optimierungsvorschläge willkommen, allerdings sind hier vorerst alles nur Routinen die aus einem
bereitgestellten Puffer in einen linearen Puffer decodieren, der dann, ggf. noch unter Tranzparenz-
prüfung, in den Bildschirmpuffer kopiert wird. Letztlich soll alles möglichst direkt aus den codierten
Daten in den Bildschirmpuffer dekodiert werden.

Code: Alles auswählen

procedure decode_bitstream_asm_2; assembler;
asm

  push ds

  les di, outblkbuf_pointer
  lds si, bitdata_pointer

  db 66h; mov bx, ds:[si+40] { Farben 0-3 in EBX laden }

  xor cx, cx

  @outerloop:

    inc ch
    xor ah, ah
    lodsb

    @loop:

      inc ah

      db 66h; mov dx, bx { EDX mit EBX beladen }
      mov cl, al
      and cl, 3              { cl enthaelt nun index auf palette: 0, 1, 2 oder 3 }
      shl cl, 3               { mit 8 multiplizieren }
      db 66h; shr dx, cl { EDX um cl bits rechtsshiften -> Farbnummer in DL }
      mov es:[di], dl
      inc di
      shr al, 2          { al eine Position weiter nach rechts }

    test ah, 4
    jz @loop

  test ch, 16
  jz @outerloop


  pop ds

end;
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Eigenes Videoformat

Beitrag von zatzen »

Hier die 3-Bit-Routine. Fraglich ist, ob das so wirklich schneller ist als wenn
man die 8 verschiedenen Farben per Tabelle aus dem Speicher laden würde.
Zudemo wirds hier für eine Transparenzprüfung etwas knapp mit den Registern.
Ob man FS oder GS auch als Zähler missbrauchen kann? Segmentregister sind
doch eher langsam, wenn ich mich recht erinnere?

Ich warte jetzt ersteinmal ab, ob das hier überhaupt jemanden interessiert. Aber ich werde
später noch die Tabellen-Version der Routine hier posten.

Für MSDOS622 (den User hier) kompiliere ich sehr bald einmal die Soundblaster-FLI's zu einem
ZVD, so wie in der Demo, nur ohne Ton.

Code: Alles auswählen

procedure decode_bitstream_asm_3; assembler;
asm

  push ds

  les di, outblkbuf_pointer
  lds si, bitdata_pointer

  db 66h; mov bx, ds:[si+40] { Farben 0-3 in EBX }
  db 66h; mov dx, ds:[si+44] { Farben 4-7 in EDX }

  xor ch, ch
  @outerloop:

    mov ax, ds:[si+1] { untere 3 Byte von EAX... }
    db 66h; shl ax, 8 { ... }
    mov al, ds:[si]   { ... mit Daten für 8 Pixel (= 1 Zeile) beladen }
    add si, 3

  @loop:

    mov cl, al
    shl cl, 6  { oberste 6 Bit rausschieben, Bit 2 landet im CF }

    jc @edx  { Carry gesetzt -> Farbe 4-7 -> EBX }
      shr cl, 3 { 3 Bit nach rechts, dadurch die übrigen 2 Bit mit 8 mult. }
      db 66h; ror bx, cl { EBX um CL bits rechtsrotieren -> Farbe in BL }
      mov es:[di], bl
      db 66h; rol bx, cl { zurueckrotieren }
      jmp @done
    @edx:
      shr cl, 3
      db 66h; ror dx, cl { s.o. -> Farbe in DL }
      mov es:[di], dl
      db 66h; rol dx, cl { zurueckrotieren }
    @done:
      inc di
      db 66h; shr ax, 3 { EAX 3 Bit weiter schieben }

  inc ch
  test ch, 7
  jnz @loop

  test ch, 64
  jz @outerloop

  pop ds

end;
mov ax, 13h
int 10h

while vorne_frei do vor;
Antworten