WIP Gameengine

  • Überlegt wie ich mehrere Paletten codiere, letztlich habe ich mich entschieden maximal 2 Paletten zu unterstützen, dafür ist dann auch der Header 1 Byte kleiner - zeit zum Codieren:


    Also Standardbild samt Nachtvariante rausgekramt:


    beide erstmal einzeln gepackt:


    Tag=104.387bytes

    Nacht=102.752 Bytes


    Und jetzt beide zusammen:


    Trommelwirbel!



    241.572 Bytes 8|

    mal schauen was da los ist... immerhin wird das ganze "richtig" ge- und entpackt....


    und so schaut das ganze aus wenn das Nachtbild nur mit den Informationen vom Tagbild gepackt wird...


    :-/


    evtl werde ich den Befehl Replace Platte Entires überarbeiten, Aktuell sieht der so aus:


    Befehl Index Farbe_Palette_1 Farbe_Palette_2 Index Farbe.... Terminator


    die Änderung könnte sein


    Befehl Index_Palette_1 Farbe_Palette_1 Index_Palette_1 Farbe..... Terminator_1 Index_Palette_2 Farbe_Palette_2 Index_Palette_2 Farbe..... Terminator 2


    Sprich aktuell sind beide Paletten gemischt gespeichert - was bei unterschiedlicher Farbzahl zu unnötig vielen Palettenwechseln führen könnte (vmtl. ist hier genau das passiert), zukünftig könnten die Paletten nacheinander gespeichert werden... wird aber bei der Codierung kompliziert...

    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

    Einmal editiert, zuletzt von Dosenware ()

  • Mal schauen, muss den Thread auch mal auf den aktuellen Stand bringen.

    _______________________________


    Ich fürchte multiple Paletten sind bei dem Bildmaterial hier ein roter Hering weil die Farbzahl für Tag und Nacht unterschiedlich ist - werde mich wohl auf Varianten beschränken müssen...

    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

  • Farben gezählt und einen Geist gejagt... und editiert.


    Für die Varianten und allgemein die Transparenz brauche ich eine Ersatzfarbe (irgendein Wert muss halt im Speicher stehen) - diese Farbe darf im Bild selbst nicht vorkommen.

    Die retroeren unter euch werden sich noch an Overlays mit z.b. TV-Karten und Videodateien erinnern, wo bei einem Screenshot an der Stelle nur ein pinkes etwas zu sehen war: Pink war da die Transparenzfarbe - ich brauch da was ähnliches, aber einfach eine feste Farbe nehmen ist an der Stelle blöd.

    Daher:

    - erstmal schauen was für Farben im Bild vorkommen

    - und dann eine "auswürfeln" die nicht drin ist und als Transparenz nutzen.


    für das erstere habe ich mal "schnell" eine kleine Routine geschrieben.


    Die Variante ist zur Abwechslung mal schnell - absurd viel schneller als die gleichnamige Prozedur hier:

    WIP Gameengine


    Im Grunde ist das Prinzip einfach:


    -ich nutze 16 Bit Farben, d.h. ich kann maximal 65536 verschiedene Farbwerte haben, gleichzeitig zähle ich die Häufigkeit der Farben - allerdings nur 16 Bittig, d.h. nur bis 65536.

    65536 Werte a 16 Bit machen insgesamt 128kb Speichernutzung - ist viel aber noch managebar.


    -Anschließend nutze ich die Farbe als Index für meinen internen Farbzähler (help_struc) - d.h. statt irgendwas zu Vergleichen springe ich direkt zum entsprechenden Eintrag und erhöhe den Zähler um 1, was dann _richtig_ schnell ist (Merke: der Beste Vergleich ist kein Vergleich)


    -und zu guter Letzt, wenn ich mit allem durch bin, packe ich das ganze in die potentiell platzsparendere countcol Struktur - diese würde zwar im worst Case 256k belegen, aber dazu müsste ein Bild schon alle 65536 verfügbaren Farben nutzen.

    Das inzwischen allseits bekannte Testbild nutzt z.b. ~2700 Farben - das macht ~10,8kb, was immernoch deutlich kleiner als die 128k ist die mein interner Farbzähler nutzt


    Und nun sind wir beim Geist:

    Ich hatte Abstürze... ständig... Fehler gesucht (auch welche gefunden) - aber ich bin nicht weitergekommen... unter Dos(box) probiert: Läuft.

    Win 3.11 hat dem Programm einfach nicht genug Speicher gegönnt - der Pif-Editor hat dem Spuk dann ein Ende bereitet


    PS.

    Als nächstes gehts daran die Tranzparenzfarbe zu ermitteln, die verschiedenen Varianttypen (Animation, Variant, Set (was tatsächlich keine Variante ist)) zu implementieren (Speichern und Laden)


    Noch eine kleine Idee für das laden Transparenter BMPs:

    If Alpha>$7F then übertrage Farbe

    sonst setze Transparenzfarbe ein

    Könnte mir eine Menge Kopfschmerzen ersparen (aktuell musste ich die Bilder per Hand anpassen, weil sonst immer ein Rand von der 8Bittigen Transparenz überblieb)


    PPS. Dort oben wird übrigens die eigentliche Arbeit in 8 Zeilen erledigt - von denen 2 Zeilen nichts machen und nur der Strukturierung dienen.

    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

    3 Mal editiert, zuletzt von Dosenware ()

  • Ein paar Überlegungen dazu wo ich eigentlich hin will: (wird noch Editiert, dient ein bisschen als Notizblock für mich)


    PIC - Containerformat


    Da Pic mehrere Bilder in einer Datei unterstützt ist der Header ist aufgeteilt in den Pic Header und den Variant Header.


    Header Pic:

    Size_X, Size_Y: word; - Größe der Bilder {0=1}

    Variants:byte; - Zahl der Varianten; {0=1 - maximal 128}

    Sprungliste von Varianten - Variants einträge zu 32 Bytes (ab Variant 1)


    Variantheader

    type:byte - Animation, Animation mit Difframe (d.h. der letzte Frame führt zur wiederherstellung des ersten Frames, ist bei Animationen schneller), independent/Variant of Frame 0 Variant0 (bei V0F0=independant), Transparenz j/n

    Frames:byte: Anzahl der Frames (0=1, maximal 256)

    Palettesize:byte; - Größe der Palette {0=1}

    Transparenzfarbe:word - wird nur ausgewertet wenn Transparenzbit in type gesetzt ist

    IF type=Animation with Loopframe then Sprungadresse zu Frame 1 (Frame 0 wird ja nicht mehr genutzt - Sprungadresse ließe sich aber auch zur Laufzeit ermitteln)

    IFtype=Independant then Startpalette


    Bilddaten


    Beschreibungen

    type

    XXXX PTVA


    A

    0 - No type

    1 - Animation with Loopframe (nach dem letzten Frame wird ein weiterer frame eingefügt der den Ursprungsframe wiederherstellt - das ist beim dekodieren mitunter schneller)


    V

    0 - Variant of Variant 0 frame 0 - hier wird als Frame 0 ein differenzbild gespeichert

    1 - independent - hier wird ein komplettes Bild gespeichert


    T

    0 - ohne Transparenz

    1 - Mit Transparenz


    P

    0 - Nur 1 Palette

    1 - 2 Paletten




    _________________________________________________________________

    Programm convert

    Parameter Richtung, Dateiliste (bei Richtung decompress ist es der Dateiname (Überlegen wie wir das machen - in einem Pic können 131072 Bilder Stecken (2 Paletten, 256 Varianten zu 256 Frames) - mit Zahlen+Buchstaben kommen wir auf >16000 kombinationen bei 4 Stellen)

    Dateiliste enthält Dateiname + Variant, Frame of Variant, Palette


    Auf Korrektheit der Eingabestrings prüfen.


    Format Eingabestring:

    Dateiname,XXX,YYY,Z


    Dateiname

    1-12 Zeichen

    - Komma dient als Separator - wenn kein Komma nach Zeichen 12 -> Fehler

    - auf unzulässige Zeichen Prüfen '?' z.b. (dürfte bereits von assign+reset+ioresult erschlagen worden sein)

    - '/' als erstes Zeichen Bedeutet Zeile ist Kommentar


    XXX

    Dezimalzahl, 1-3 Zeichen, Nummer der Variante

    - A:=0; While (X>='0')and(X<='9')and(A<256) do A:=A*10+(X-ord('0'));

    - If (A>255)or(X<>',')then Error

    - Wenn Schleife abbricht muss A<256 (Nummer der Variante) und X=',' (Separator) sein, sonst Fehler


    YYY

    wie XXX, Nummer des Frames der Variante - Wenn YYY>0 wird ->type Animation? (First Frame?/gleicher Dateiname für first frame und Baseframe für First Frame= Baseframe?)


    Z

    Dezimalzahl, 1 Zeichen, Nummer der Palette

    - nur 0, bzw 1 zulässig

    - nächstes Zeichen entweder nicht existent, oder keine Zahl


    auf continuität achten, wenn Variant 2 existiert, muss Variant 1 existieren

    prüfen, ob angegebene Dateien existieren, zulässige Bitmaps sind und die gleiche Größe haben.


    ______

    procedure Convert


    Argumente:

    - Ausgabename

    - Eingabename: array[$00..$FF] of string[12]; {byte 0 des Strings speichert länge - Länge=0 -> leer - d.h. Strings mit 0 Initialisieren)}

    Evtl. String[13] nutzen (aber nur String [12] verwenden) letztes byte (evtl letzte 2 byte) für Attribute nutzen - z.b. typ + zugehörigkeit zu Variante/Palette

    bei typ=Animation wird nur der Typ des ersten Frames ausgewertet

    Variant 0=Baseframe


    Eingabenamen evtl. sicheheitshalber sortieren nach Variante und Palette - und überprüfen ob im Dateinamen ungültige Zeichen sind.

    Bei Convert: nachfolgebild auf Palette überprüfen

    Alle Bilder einer Variante auf Palette vor start prüfen

    Vor Start Anzahl der Varianten und Paletten zählen um im Header Platz für die Variantsdressen zu machen

    Vor Start Transparenzfarbe suchen (type= Variant of Frame 1)


    NICHT VERGESSEN! für den Start der Varianten wird die Endpalette vom Baseframe genutzt -> d.h. Endpalette vom Startframe speichern


    ___________________________________________


    Ziele nach convert:


    Generierung der Ressourcendatei um Overhead loszuwerden

    - dabei Kompression (Huffmann) der Pic-Dateien

    - Symbol EOP in Kompression einbauen für die Trennung der Pic-Dateien

    - Speicherung der Positionen im Header der Ressourcendatei


    Header der Ressourcendatei:

    - Anzahl der gespeicherten Bilder

    - Liste der Positionen (Einfach Liste mit $FFFF FFFF terminiert, Anzahl nur für Prüfung auf korrekten Zugriff nutzen?)



    Tracking der Dateien: LFN->8.3->Pic_Vatiante/Palette->Nummer_In_Ressourcendatei für automatische konvertierung bei Compilieren des skripts (in dem Zusammenhang auch Tracking der Variablen/Skrips) und letzlich Speichern und wiederverwenden der Trackinginformationen für Savegamekompatibilität


    Savegames:

    Aufbau: Variablenid,Wert (16Bit/16Bit)


    ___________________________________________


    Vorüberlegungen zur procedure convert:


    type filestruc

    f:file

    bufferpos:longint

    Buffer:[0..3FFF]of word;

    Dataoffset

    sizex,sizey

    transparencycolor

    Bitdepth

    colormasks, 4 longints - RGBA


    function Get_BMP_Pixel(filestruc, pos_x,pos_y)

    if pos<filestruc.bufferpos then seek;fpos.bufferpos:=pos;read(buffer)

    if pos>filestruc.bufferpos+buffersize(inPixel) then seek;fpos.bufferpos:=pos;read(buffer)

    return buffer[pos-bufferpos]


    BMP_Header

    {00}BM:word; {Zeichenkette BM}

    {02}SizeOfFile:longint; {eigentlich DWord, größe der Datei {unzuverlässig}

    {06}Reserved1:longint;

    {0A}DataOffset:longint; {Offset der Bilddaten}

    {0E}SizeOfBitmapInfoHeader:longint; {Größe des Headers - Dateikopf (-14 bytes)}

    {12}Width:longint;

    {16}Height:longint; {if <0 then top down}

    {1A}Reserved2:word;

    {1C}Bitcount:word; {muss 1,4,8,16,24, oder 32 sein}

    {1E}biCompression:Longint; (0=unkomprimiert, 1/2 RLE - nicht supported, 3=unkomprimiert mit Farbmaske (Aplha, nur bei 16 und 32 Bit erlaubt))

    {22}biSizeImage:Longint;

    {26}Reserved3:longint;

    {2A}Reserved4:longint;

    {2E}biClrUsed:longint; {nur gültig wenn biBitCount=4, oder 8 - Anzahl der Einträge der Farbtabelle 0=max)

    {32}biClrImportant:longint; {Anzahl der verwendeten Farben der Farbtabelle (0=alle) - transparenz?)

    {36}ColorMaskG:longint; {nur wenn biCompression=3, auf Offset achten}

    {3A}ColorMaskG:longint;

    {3E}ColorMaskR:longint;

    {36}ColorMaskA:longint;


    00F8 -> F800

    E007 -> 07E0

    1F00 -> 001F




    function OpenBMP(var BMPF:BMPFileStruc;fname:string);

    begin

    Header extrahieren + mglw umsortieren für Adressierung?


    - vor jeder Variante die Frames durchgehen und die Transparenzfarbe suchen.

    Farbtreffertabelle:array[0..0FFF] of word;


    Farbtreffertabelle[(Color and $FFF0)shr 4]:=1 shl (color and $000F);

    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

    29 Mal editiert, zuletzt von Dosenware ()

  • am ersten Nutzerprogramm arbeiten... Wow, was für ein Aufwand sämtliche Fehler abzufangen.


    Auch hat sich das Bildformat etwas geändert: es unterstützt nur noch 8 Varianten - statt 256

    Ist einfach der Tatsache geschuldet dass ich sonst mehr arbeit invesieren müsste um Pascals 64k Grenze zu umschiffen - und es nicht wirklich etwas bringt.


    Damit lassen sich in einer Pic-Datei nur noch:

    8 Varianten zu je 256 Frames mit 2 Verschiedenen Paletten = 4096 Bilder unterbringen (ok, es sind nur 2048 Bilder, bei den anderen 2048 Bildern ist nur die Farbe anders)


    Das einzige was das Ding bisher macht ist die Dateiliste für die Konvertierung einzulesen und es ist jetzt schon riesig


    BTW. Falls sich wer wundert was ich da mit dem String mache:

    Ein String ist in Pascal nur ein Array[0..255] of Char.

    Wobei der Eintrag 0 als Zahl ausgewertet wird, die die Länge angibt - so kann ich die Speicherstellen weiter hinten für andere Zwecke nutzen - schließlich ist der String auf 12 Zeichen (8+.+3) begrenzt.

    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

  • Unterprogramm: OpenBMP


    Aufgaben:

    BMPs in ein Temporäres Dateiformat übertragen

    Zeilen umsortieren von Bottom up zu Top down (deutlich einfacher zu verarbeiten/Adressieren)

    Farbtreffertabelle generieren


    Parameter:

    Eingabedateiname

    Ausgabedateiname - Namensformat: VariantennummerFramenummerPalettennummer.TMP -> "V00F00P0.TMP" - Zahlen im Hexformat. (V00F00P0= Variante 0, Frame 0 Palette 0)


    Ausgabeformat:

    Dateiheader

    Height, width:word;

    Farbtreffertabelle:array[0..0FFF] of word;

    Transparenzfarbe: 0=keine Transparenzfarbe - für ARGB Formate verwendet

    16Bit Bilddaten


    Eingabeformat:

    Windowsbitmap 8Bit, 16Bit X555, 16Bit A555, 16Bit 565, 24Bit, 32Bit A888, 32Bit X888



    Internes:


    Besonderheiten Eingabeformat:

    8Bit - indiziert -> Farbtabelle, mglw. Farbmasken auf länge des Infoheaders achten - Farbmasken können zwar vorhanden sein, aber sie werden nicht ausgewertet

    16/32 Bit -> biCompression=3, d.h. Farbmasken, konvertierung der Bilddaten mittels der Masken nötig

    16Bit X555/A555 -> Grünanteil um eins nach links Bitshiften

    16Bit A555/32Bit ARGB -> Alphakanal beachten

    24Bit Farbmasken können vorhanden sein, aber sie werden nicht ausgewertet


    ->Für vorhandensein/nutzen von Farbmasken ist biCompression ausschlaggebend


    Aufbau BMP Header:

    0A dw Offset Bilddaten

    0E dw Größe des Infoheaders -> Wert +0E = Offset Bilddaten bzw. bei indexed Mode der begin der Farbtabelle

    12 lo Breite

    16 lo Höhe - wenn Wert <0 dann TopDown Bitmap

    1C wo Bittiefefe

    1E dw biCompression - 00=unkomprimiert (=24Bit), 03=unkomprimiert, Farbmasken (=16/32 Bit) ---- 01/02= RLE Codiert, wird nicht unterstützt, Basta

    2E db biClrUsed - Zahl der Einträge der Farbtabelle

    36 dw 4xdw Farbmasken, Reihenfolge: BGRA - nicht immer vorhanden auf Offset der Bilddaten achten


    Setzen Farbtreffertabelle:

    Farbtreffertabelle:array[0..0FFF] of word;


    Farbtreffertabelle[(Color and $FFF0)shr 4]:=1 shl (color and $000F); (nötig um eine Transparenzfarbe (wird normal nicht dargestellt) zu bestimmen)


    Tabellenindex=(Color and $FFF0)shr 4;

    Bitposition=1 shl (color and $000F);


    Bei Generierung der Farbtreffertabelle ggf. auf Alpha achten.


    Verarbeitung Farbmasken:

    WIP

    Bitshift der Farbmaske bestimmen für Konvertierung.

    Bitbreite der Farbmasken bestimmen, Bitshift ggf. anpassen (z.b. für 555->565 konvertierung - G wird 1 linksgeshifted), ggf. Breite der Farbmaske anpassen (d.h. bei 888->565 Konversion untere Bits nullen)


    Bei Verwendung von Alpha nur voll sichtbare Pixel konvertieren (bei 8Bit Alpha schwellenwert?) und vor der Konvertierung eine Transparenzfarbe bestimmen, d.h. 2 Durchläufe.


    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

    4 Mal editiert, zuletzt von Dosenware ()

  • Ok, Bitmaskengenerierung für die Konvertierung ins 16 Bit 565 Format steht. (16Bit 565 =5Bit für Rot, 6Bit für Grün, 5Bit für Blau)


    Dies ist nötig um verschiedene Eingabeformate zu unterstützen, geplant ist BMP mit 8,16,24 und 32 Bit - diese kommen in verschiedenen Variationen vor, weshalb ich nicht einfach mit Festwerten arbeiten kann.


    Hier mal die Ausgaben der Header und der angepassten Bitmasken für die 16 Bit 565 Konvertierung.


    Die ersten beiden Bilder zeigen den Unterschied zwischen Bildern mit Farbrauminformationen (die ich nicht auswerte - mit Ausnahme möglicher Farbmasken) und jenen ohne: der Header hat unterschiedliche Größen. Der Offset der Daten ergibt sich normalerweise aus $0E+Headersize - mit einer Ausnahme, dazu aber später mehr.

    Beide Bilder sind im 16 Bit 565 Format codiert, praktischerweise nutzen sie auch gleich das Doskompatible Dafenformat, so dass die Bitmasken nicht angepasst werden müssen.


    Diese beiden Bilder zeigen die 15 Bit Formate, einmal mit und einmal ohne Transparenz, man beachte die angepassten Bitmasken und Bitverschiebungen für die Konvertierung ins 565 Format


    24 Bit 888 Format, hier gibt es wohl kein Format mit Farbmasken (Compression steht auf 0, 3=Farbmasken) - lustigerweise werden dennoch Farbmasken gespeichert, sie werden nur nicht genutzt, auch hier bitte auf die Anpassung der Bitshift und Bitmasken achten

    Hier muss ich übrigens auch eigene Farbmasken für die konvertierung nutzen - das sieht im wesentlichen so aus wie die Maske für 32Bit.


    32Bit, einmal mit Alpha, einmal ohne.


    8Bit und hier haben wir oben erwähnte Ausnahme: Man beachte die Diskrepanz zwischen der Headersize und dem Dataoffset - der Grund ist recht einfach: Das ist ein indexed Mode, d.h. es wird mit einer Farbpalette gearbeitet - diese ist direkt hinter dem Header gespeichert und besteht aus n 32 Bit Werten, wobei n die Zahl der genutzten Farben ist.

    Lustigerweise werden hier ebenfalls Farbmasken (nur bei Speicherung mit Farbrauminformationen) gespeichert, aber nicht genutzt.

    Eine kleine Besonderheit hier: Bild 2 ist Lauflängencodiert (Compression=1) eine kodierung die letztlich auch ich in meinem Bildformat verwende, wenn auch in abgewandelter Form. (RL Bitmaps werden von meinem Programm nicht unterstützt)


    Hier muss ich übrigens auch eigene Farbmasken für die konvertierung nutzen - das sieht im wesentlichen so aus wie die Maske für 32Bit. Allerdings wird diese nur auf die Farbpalette angewendet und nicht auf die Bilddaten selbst.

    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

    Einmal editiert, zuletzt von Dosenware ()

  • Sieht alles sehr kompetent aus. :)

    Geht es diesen Winter weiter oder ist das Projekt eingestellt?

  • Ich versuche gerade herauszufinden was ich da programmiert habe... zeitweise
    das interresse kommt langsam zurück, aber ich müsste mich da auch erst wieder einarbeiten -.-

    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

  • Grüße,


    wie kann ich in Pascal einen ExitCode beim beenden des Programms an Dos übergeben? (z.b. für die Verwendung in Batch programmen)

    RunError und Halt scheinen mir etwas unangebracht da die wohl eher für Fehler gedacht sind.

    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

  • Ok, neue Packroutine für die Bilddaten:

    hier erstmal Notizen dazu:


    Nutzung des Programms:



    Internes:


    Überprüfung ob Datei vorhanden:

    File und Variant header:



    Packroutine:


    - Parameter der Packroutine - f_input f_output palette transparenzfarbe

    (damit lässt sich diese routine für neue dateien, dem hinzufügen von frames und varianten verwenden - braucht dazu halt vorbereitende routinen für die vorarbeit)

    - mit TMP Dateien Arbeiten Packtest für Varianten als diff und normal -> das kleinere wird genommen

    - mit 2 32k puffern Arbeiten um beliebig große Bilder verarbeiten zu können (Bilder erst in 16Bit konvertieren und als Temp speichern, oder on the fly konvertierung) - probleme: Dateiende, Farbensuche für Paletten

    Von allen Dingen auf Erden ist die Intelligenz am gerechtesten verteilt: Jeder glaubt, er hätte genug davon.

    3 Mal editiert, zuletzt von Dosenware ()

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!