Mode X und EGA Parrallax

  • Nachdem ich jetzt im grunde schon zu viele Texturen habe, habe ich eine einfache Variante zum wechseln der geladenen Textur Datei in den MAP's hinterlegt.

    Testweise wurde immer alle 200 Texturen neu geldaden bei einem "Gebietswechsel", das dauert ca. 5 Sekunden auf dem 386DX40, denke das sind dennoch keine langen Ladezeiten, verglichen mit anderen Spielen.

    Wenn ich das ganze jetzt in 50 Textur Blöcke unterteile, kann ich die Anzahl neu zu ladender Texturen auf 1/4 beschränken, wodurch beim betreten von Räumen nur das notwendigste geladen werden müsste.

    Wird vermutlich 2 Sekunden dann dauern, das ist noch immer ziemlich Flott. Und man kann duch geschicktes auswählen der Texturen auch dafür sorgen das möglichst selten im speicher nach geladen werden muss.



    Hinterm Busch verstecken hilft nicht wirklich, die immer mehr werdenden NPC's finden einen doch irgendwann.

    Wenn man sie geschickt verteilt und ihnen Wege / Grenzen zuteilt, sind es immer genug das es nicht langweilig wird.

    Aber der 386 wird dennoch meist zügig genug mit ihnen fertig, klingt für heutige verhältnisse verrückt.

    Ab 10FPS sind die Bewegungen im Grunde bei diesem Grafik Aufbau schon spielbar flüssig, da das Spiel so angepasst ist das ab 10FPS die Bewegungen ohne einschränkungen abgearbeitet werden können.


    Bei Ultima 7 verhält es sich ähnlich, nur das man leider die Bremse für zu schnelle Rechner vergessen hatte damals. Weshalb es auf 486 schon oft zu schnell läuft.


    Ich habe einfach die FPS auf 73 limitiert und die Bewegungen werden ca. 10 pro Sekunde nur abgefragt.

    Hoffe es bleibt genug Zeit / Leistung für Soundeffekte übrig... aber das kommt erst später.

  • Wenn du die Texturen nur in teilen laden tust kannst du das evtl. auch schon vorher im Hintergrund, dann gäbe es eine Ausschlussliste nicht in einem Bildinhalt zusammen verwendet werden dürfen, auf der anderen Seite kannst du beliebig viele Blöcke haben.

    386SX- 20 Mhz "Erster eigener Rechner!2" NoName Komponenten

    486DX -30 "Industrie PC" auf Steckkarte

    Super Sockel 7 Gigabyte GA-5AA 3Dfx Voodoo 3500 TV

    AMD "Geode" ebenfalls Steckkarte für Backplane

    3x IBM Netvista 8364 "ThinRetroSystem" 1-2 von denen würde ich tauschen...


    "und noch so einiges mehr... "

  • Ich dachte mir, teste wie lange er für alle 200 braucht. Sind ca. 5 Sekunden.


    Momentan werden 200 Texturen bei Spiel start geladen, später werden dann immer 50er Blöcke gewechselt wenn sich die Grafik so sehr ändert das es nicht mehr in die ersten 200 Texturen passt.

    Also typischerweise dann in Dungeons oder in grösseren Gebäuden, wo jede Menge Proll herum steht und alles anders ausschaut wie draussen im freien.


    Momentan teils sich das in etwas so auf.


    -118 Texturen Aussenbereich davon sind 31 lediglich die Häuser von Aussen.

    -31 Texturen Gebäude innen, Wände, Betten, Böden, Treppen ... alles was man soeht wenn man einen Raum betritt.

    -33 Texturen "Dungeon"... das ist das Kellergewölbe der graue Dungeon, mit allem was dazu gehört. Feuer Fackeln Wände Böden Decken Gitter.


    ...wenn man 50 Testuren tauschen kann, wird man vermutlich bei extremeren bereichswechseln die wichtigsten teile tauschen können.

    es gibt ja auch Dinge die immer gleich bleiben, ein Fass, Bett, Feuer, Truhe ... können / müssen auch oft geladen werden in unterschiedlichen Bereichen.

  • Haus Variante "erweitert"


    Um bei den Häusern den Dachstuhl auch in diese Richtung gedreht darstellen zu können, sind ganze 24 zusätzliche Texturen erforderlich!

    Hier die neune Texturen, es fehlern noch 5 weitere um auch an der anderen Seite das Dach so ineinander über gehen zu lassen ... macht dann 29 Texturen (200Limit komplett!).

  • ist sehr schön geworden, jetzt noch "etwas" in das Dachgiebel Dreieck so wirkt es noch etwas "unnatürlich"

    386SX- 20 Mhz "Erster eigener Rechner!2" NoName Komponenten

    486DX -30 "Industrie PC" auf Steckkarte

    Super Sockel 7 Gigabyte GA-5AA 3Dfx Voodoo 3500 TV

    AMD "Geode" ebenfalls Steckkarte für Backplane

    3x IBM Netvista 8364 "ThinRetroSystem" 1-2 von denen würde ich tauschen...


    "und noch so einiges mehr... "

  • jetzt gibt es erstmal einiges an Möglichkeiten Häuser zu gestalten.

    Es sind insgesamt 48 Texturen, ich werde noch 2 Deko Texturen ergänzen für Häuser, dann ist es ein komplettes Grafik Set mit 50 Texturen.

    Das entspricht einer Textur Datei. Passt also alles so ziemlich gut zusammen.

  • Ganz ganz Toll! :love:

    386SX- 20 Mhz "Erster eigener Rechner!2" NoName Komponenten

    486DX -30 "Industrie PC" auf Steckkarte

    Super Sockel 7 Gigabyte GA-5AA 3Dfx Voodoo 3500 TV

    AMD "Geode" ebenfalls Steckkarte für Backplane

    3x IBM Netvista 8364 "ThinRetroSystem" 1-2 von denen würde ich tauschen...


    "und noch so einiges mehr... "

  • Anpassung der Textur Sets.


    Heute habe ich mir mal die Zeit genommen die Texturen in Textur Sets auf zu teilen.

    Leider mussten danach alle Maps neu erstellt werden, momentan existieren nur 3 Map Dateien zum testen.



    folgende Sets gibt es momentan.


    (Anzahl Texturen maximal 50 je Set)


    9=Texturen Aussenbereich Set 1 (49)

    8=Texturen Aussenbereich Set 2 (40)

    10=Haus Aussen Set 1 (49)

    11=Haus Innen Set 1 (37)

    12=Duungeon Set 1 (34)



    das Wechseln einer kompletten Map mit dem nachladen eines Textur Sets dauert ca. 2 Sekunden.

    Wenn ein Texturset geladen wird, erscheint oben links ein kleiner gelber Ladebalken, eventuell passe ich das später noch an.


    eine überlegung ist es weitere Textur Sets in den Ram zu laden EMS damit die nach dem ersten laden schneller nach geladen werden könnten.

    Ich würde den speicher dann in Blöcke untereteilen in dessen ersten Byte die Nummer des Textur Sets hinterlegt wird um welches es sich handelt.

    Man könnte dann einfach hin und her kopieren innerhalb des speichers.

  • Zeig doch mal die (inneren) Schleifen im Lade-Quelltext ;) Vielleicht kannst du auch das Laden beschleunigen, indem du die Textur-Sets schon im Editor oder mit einem zusätzlichen Tool in genau die Form bringst, die das Spiel nach dem Laden der Texturen braucht?

  • Die Texturen werden in ein Array geladen, aus welchem sich alle Textur Funktionen bedienen.

    Code
    //Array Texturen [X][Y]
    //X= Nummer Textur 0-199 derzeit genutzt
    
    //Y= Byte 1-1024 >>Pixel Farbwert | Byte 1025/1026 Ebene/Kolision
    
    unsigned char huge MXsprite[200][1026];


    Der Teil hier ladet die Texturen im speicher nach.



    der Teil gefällt mir nicht wirklich, wird zwar keine Welt ausmachen. Aber das geht bestimmt eleganter oder?


    wenn man das irgendwie schneller laden kann wäre nicht verkehrt.

  • Bin generell was auf am räumen im Programm:


    manchmal zwar etwas unübersichtlicher aber es spart vermutlich wieder was rechnerei und variablen schieben für die CPU.



    alt:

    Code
        tex=(px&15) + ((py&15)<<4);
        texBuX=(px>>4)&1;
        texBuY=(py>>4)&1;
    
        map= MapSp[texBuX][texBuY][tex];//Sprite Textur
        map= MXsprite[map][1025];//Sprite Eigenschaft

    neu:

    Code
        map= MXsprite[MapSp[(px>>4)&1][(py>>4)&1][(px&15) + ((py&15)<<4)]][1025];//Sprite Eigenschaft
  • Also diese ganze Kette von "if nr==..." könnte man schon mal mit switch/case machen, https://www.guru99.com/de/c-switch-case-statement.html


    Aber dein eigentliches Problem ist, dass du im Prinzip eine geschachtelte Schleife hast mit


    Code
    for offset2 = 0 to 49 do
      for offset1 = 0 to 1025 do
        sprite[offset2 + startslot][offset1] = lese ein einzelnes byte aus der datei
      done
    done

    Besser:


    Code
    for offset2 = 0 to 49 do
      ifs.read(sprite[offset2 + startslot][0], 1026)
    done

    Im Prinzip könntest du die 0 bis 49 Schleife auch noch weglassen, aber 1026 Bytes am Stück lesen macht denke ich schon viel Geschwindigkeitsunterschied :)


    Theoretisch könnte es dir passieren, dass ein read() Aufruf weniger Bytes liefert, als du wolltest, auch wenn das in DOS selten ist, also könnte man das "ifs.read(..., 1026)" narrensicherer ersetzen durch:


  • Bin generell was auf am räumen im Programm: ...


    manchmal zwar etwas unübersichtlicher aber es spart vermutlich wieder was rechnerei und variablen schieben für die CPU.

    Wenn der Compiler gut ist, müsste er eigentlich selbst merken, welche Variablen kurz genug benutzt werden, um sie gleich in CPU Register legen zu können. Daher finde ich die übersichtlichere Version besser, wenn die unübersichtlichere Version nicht tatsächlich merklich schneller läuft.

  • Bin generell was auf am räumen im Programm: ...


    manchmal zwar etwas unübersichtlicher aber es spart vermutlich wieder was rechnerei und variablen schieben für die CPU.

    Wenn der Compiler gut ist, müsste er eigentlich selbst merken, welche Variablen kurz genug benutzt werden, um sie gleich in CPU Register legen zu können. Daher finde ich die übersichtlichere Version besser, wenn die unübersichtlichere Version nicht tatsächlich merklich schneller läuft.

    habe ich jetzt schon manuel alles immer so geändert wie ich es für schneller hielt.

    Wurde die Variable mehrfach verwendet hatte ich die lange Variante genugtz, wurde die Variable nach jeder verwendung wieder geöändert, dann hatte ich das zusammen gelegt.


    249 Zeilen konnte ich damit einsparen verteilt auf einige Funktionen. Sind jetzt noch 5559 Zeilen Code über (wenn man leere Zeilen für die übersicht abzieht vermutlich die hälfte)

  • bei dem Compiler funktioniert das irgendwie nicht richtig.


    Irgendwie füllt der mir den speicher falsch. Ab und an sind fehler drin.



    ifs.read(sprite[offset2 + startslot], 1026)




    Im ersten Bild erkennt man das die erste Textur irgendwie falsche Werte hat.

    zwischendurch sind immer wieder vereinzelt Texturen falsch.

    Wenn ich die Pixel einzeln lade sind die Fehler nicht vorhanden.

  • Irgendwie füllt der mir den speicher falsch. Ab und an sind fehler drin.


    ifs.read(sprite[offset2 + startslot], 1026)

    Funktioniert ifs.read(sprite[offset2 + startslot][0], 1026) besser? Falls das nicht reicht: Rückgabewert von ifs.read abfragen und ggf. mehrfach lesen wie oben beschrieben?

  • ifs.read(sprite[offset2 + startslot][0], 1026) frisst der Compiler nicht

    [0] muss ich entfernen.




    das hier kann ich auch nicht machen weil ich [offset1] nicht in die Zeile packen darf, der Compiler akzeptiert das nicht.



    Compiler zu alt oder zickig vermute ich.

  • Wie lautet die ganze Fehlermeldung und was möchte dein ifs.read() laut Headerdatei oder Hilfe als Argumente?


    Deine Sprite-Sammlung ist ja "unsigned char huge MXsprite[200][1026]", ist zwar mehr als 64k, was aber eigentlich kein Problem sein sollte, wenn du nur 1026 Byte am Stück lesen willst.

Jetzt mitmachen!

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