Script im Binärformat erstellen und auslesen



  • Hallo zusammen,
    ich schreibe eine RPG-Engine und das läuft darauf hinaus, dass der Nutzer der Engine eine spezielle Scriptsprache nutzt, um alle Elemente des Spiels und der Karte zu beschreiben. Natürlich wird es irgendwann auch einen visuellen Editor geben, das ist aber jetzt mal sekundär.

    Wie kann ich jetzt, um eventuell Geschwindigkeit und Dateigröße zu optimieren, möglichst sinnvoll ein hexadezimales Scriptformat erstellen? Nehmen wir als Beispiel mal sowas wie:

    item $ blue
    assign name "DestructorSword"
    assign attack 20 70
    

    Das Auslesen in eine struct und implementieren der Karte ist kein Thema. Aber sagen wir, ich möchte als Hexcode z.B. 'item' durch 03F1 ersetzen und 'assign' durch 04F7. Das Dollarzeichen und Strings müssten natürlich umgerechnet wären.
    Meine Versuche mit dem Schreiben der ausgelesenen structs in binäre Form erhöhten leider die Größe von 5KByte (Text) auf 90MByte (Binär). Ich vermute, dass das etwas mit meiner exzessiven Array-Nutzung zu tun haben könnte.

    Schonmal vielen Dank. 🙂

    Gruß,
    Cris



  • also bytecode als konfigurationsdatei?
    ich versteh nicht genau, wo das problem ist. kannst du bitte konkreter werden?

    ich rate mal ins blaue:
    also sinnvoll waere fopen(..., "rb").
    dann entscheidest du, ob die "opcodes" alle gleichlang sind oder verschieden.
    dann liest du die datei entweder zeichenweise (variable opcodelaenge) oder immer einen opcode (n bytes) auf einmal.
    auf jeden opcode reagierst du dann anders.



  • Ok, zur besseren Klärung des Problems mal ein Zusatz. Vielleicht klingt es, als hätte ich wenig Ahnung von der Programmierung wenn ich sage: ich habe nur grobe Ahnung vom Manipulieren binärer Dateien. Ironischer Weise ist mir das Arbeiten mit dem Hexeditor aber umso vertrauter.

    Ich bräuchte eine beispielhafte Analogie zum Arbeiten mit Strings, also "zeilenweises" Einlesen, Erkennen von Kommandos, Hinzufügen von Argumenten. Was ich an Einführungsthemen gelesen hab war immer sehr praxisfern für mich. Mag also sein, dass ich einfach nicht den Einstieg finde obwohl es ja vermutlich nicht so schwer sein kann... 😕



  • "zeilenweises" Einlesen

    char puffer[1234]; // beliebig gross, hauptsache lang genug. gibt mehr arbeit bei laengeren zeilen
    FILE *f = fopen("datei", "r");
    fgets(puffer, 1234, f);
    

    Erkennen von Kommandos

    const char *command = "foobar";
    const char *line = "foobar=123\n";
    char *res;
    res = strstr(line, command);
    if (!res) puts("not found");
    else printf("found at index %d", (int)(res-line));
    

    Hinzufügen von Argumenten

    // komplette datei lesen, daten im speicher aendern, wieder schreiben
    // dateien kann man nicht zeilenweise bearbeiten, nur lesen und komplett schreiben
    


  • Ok, ich bin sehr erfreut hier schnell Antworten zu bekommen. Leider ist offenbar aus meiner vermeintlichen Erklärung das Gegenteil herausgekommen: ich wollte in der Tat wissen, wie ich Kommandos mit variablen Argumenten in hexadezimaler, falls machbar, oder alternativ binärer Form schreiben und auslesen kann. Mit Strings habe ich schon genügend Erfahrung (was für mich in C sowieso essentiell ist).

    Also über ein Beispiel, das dem obigen äquivalent wäre, für das Schreiben und Lesen von Hex- oder Binär-Code wäre ich dankbar.



  • hexcodes lesen/schreiben gibts nicht. ist alles binaer. selbst textdateien.

    mit fread() und fwrite() liest und schreibst du byteweise.

    tutorial (dateizugriff ist dabei):
    http://www.pronix.de/pronix-4.html

    c referenz:
    http://www.dinkumware.com/manuals/reader.aspx?b=c/&h=index.html

    gib doch einfach mal ein paar testdaten vor (text) und ich bastel daraus ein halbwegs akzeptables binaerformat.



  • Ich werd gleich mal versuchen, über die genannten Links etwas Nützliches herauszufinden. Dennoch hier mal ein Beispiel:

    map Village
    [...]
    tile .
    repeat 6
    item *
    item | blue
    tile .
    repeat 11
    wall #
    row
    wall #
    tile .
    repeat 2
    tile 2
    script enter
    msg "This is a two.";
    tile .
    tile 4
    script enter
    msg "This is a four."
    msg "This is no two.";
    tile .
    repeat 2
    wall #
    tile .
    repeat 18
    wall #
    row
    [...]
    wall #
    

    Info: der Code beschreibt die Karte eines roguelike RPG. Der . und die # und die Ziffern sind das, was die "Grafik" ausmacht.

    create player
    assign name "Harry"
    assign color green
    move 4, 2;
    create game
    assign name "The prophecy"
    assign map "Village";
    

    Info: der Code beschreibt das Erstellen eines Spielers und eines Spiels mit der oben definierten Karte. Das ; steht am Ende jedes script- oder create-blocks.



  • das format hat schwaechen bedingt durch die redundanz.
    ich versuch mich mal an der definition:

    datensegment:
        1 byte    segmenttyp
            0x01  map
            0x02  script
            0x03  player
            0x04  game
        2 byte    (u16) laenge der daten im rest des segments (unsigned short int)
        n bytes   nutzdaten des segments
    map:
        2 byte    (u16) mapnummer
        1 byte    (u8) breite
        1 byte    (u8) hoehe
        n*4 bytes breite*hoehe*4 bytes, je 4 bytes fuer ein tile.
            1 byte    tile typ code
            1 byte    zeichen auf dem bildschirm
            2 bytes   nutzdaten (z.b. scriptnummer wenn >0)
    type codes fuer tiles:
        0x01      normales tile
        0x02      wall
    script:
        2 bytes   (u16) script nummer >0
        2 bytes   (u16)=n laenge des script codes
        n bytes   script code (kannst du dir noch ausdenken..., also wieder typecodes fuer kommandos und dann nutzdaten dran etc...)
    player:
        1 byte    (u8) laenge des namens
        n bytes   name (keine nullterminierung)
        1 byte    farbe
        2 bytes   x und y koordinaten
    game:
        1 byte    (u8) laenge des namens
        n bytes   name (keine nullterminierung)
        2 bytes   zugeteilte map nummer
    

    sowas in der art koennte ich mir vorstellen. dieses "format" wird aber garantiert nicht ausgereift sein.


Anmelden zum Antworten