rres ist ein einfaches und benutzerfreundliches Dateiformat zum Paketieren von Ressourcen
rres
wurde entwickelt, um Spielressourcen (Bilder, Schriftarten, Text, Audio, Modelle ...) in ein einfaches, eigenständiges, umfassendes Format zu packen, das leicht zu lesen und zu schreiben ist und darauf ausgelegt ist, Daten schnell und effizient zu laden.
rres
ist von den folgenden Dateiformaten inspiriert: XNB (verwendet von XNA/MonoGame), RIFF, PNG und ZIP.
rresFileHeader
rresResourceChunk
rresResourceChunkInfo
rresResourceChunkData
rresResourceDataType
rresCentralDir
Einfachheit : rres
-Struktur ist einfach, ein Dateiheader und mehrere Ressourcen nacheinander. Dennoch verfügt jede Ressource über einen kleinen (32 Byte) Ressourcen-Info-Header mit mehreren verfügbaren Optionen.
Benutzerfreundlichkeit : rres
Bibliothek zum Lesen von .rres
Dateien ist klein und verfügt nur über die minimal erforderlichen Funktionen zum Lesen von Ressourcendaten aus ihrer ID. Es verwendet nur einen kleinen Satz Funktionen aus der Standard-C-Bibliothek. Zum einfachen Erstellen und Anzeigen von .rres
Dateien wird ein rrespacker
-Tool mit GUI/CLI bereitgestellt.
Flexibilität : rres
-Format unterstützt jede Art von Eingabedatei. Wenn Daten nicht als Basisdatentyp klassifiziert sind, können sie einfach als Rohdateidaten gepackt werden.
Portabilität : rres
Dateiformat ist nicht an eine bestimmte Engine gebunden. Die Basisbibliothek liest die Ressourcendaten lediglich im gepackten Zustand und diese Daten können beliebigen Engine-Strukturen zugeordnet werden. Ein Anwendungsbeispiel wurde mit der Hilfsbibliothek rres-raylib.h
bereitgestellt, die RRES-Daten Raylib-Strukturen zuordnet.
Sicherheit : rres
unterstützt bei Bedarf Komprimierung und Verschlüsselung pro Ressource. Trotz der Unterstützung, die das Dateiformat bietet, ist es jedoch Sache des Benutzers, es im rres
Packer-Tool und in der Engine-Mapping-Bibliothek zu implementieren. rres
erzwingt per Design keinen bestimmten Komprimierungs-/Verschlüsselungsalgorithmus
Erweiterbarkeit : rres
Dateiformat ist erweiterbar und unterstützt bei Bedarf neue Datentypen, neue Funktionen und benutzerdefinierte Daten.
Kostenlos und Open Source : rres
ist eine offene Spezifikation und eine kostenlose und Open Source-Bibliothek. Es kann mit dem bereitgestellten Tool ( rrespacker
) verwendet werden oder es kann ein benutzerdefinierter Packer/Loader für jede Engine implementiert werden. Die Formatbeschreibung kann auch als Lernmaterial für alle verwendet werden, die ihr eigenes Dateiformat für die Datenverpackung erstellen möchten.
Es gibt einige wichtige Gründe, Spiel-Asset-Daten in ein Format wie rres
zu packen. Hier sind einige gute Gründe dafür.
Organisation : Vermeiden Sie im endgültigen Spiel-Build Tausende von Dateien, die in Hunderten von Verzeichnissen verteilt sind. Alle Spieldateidaten können in einer oder mehreren .rres
Dateien organisiert werden. Dadurch bleibt das Spieleverzeichnis sauber und gut strukturiert.
Leistung : Durch das Speichern aller erforderlichen Dateien für ein Level/eine Karte in einer einzigen .rres
-Datei wird der Bedarf an Dateihandles für den Zugriff auf mehrere Dateien reduziert. Dateihandles sind eine Ressource des Betriebssystems und die Kosten für das Öffnen einer Datei sind nicht unerheblich und können zu Verzögerungen im Spiel führen. Auch die Datenzugriffszeiten innerhalb der .rres
Datei sind wichtig und können je nach Organisation der Dateien auch die Ladezeiten verbessern.
Sicherheit : Vermeiden Sie es, alle Spielinhalte direkt dem Benutzer zugänglich zu machen, um sie einfach kopieren oder ändern zu können. In eine .rres
Datei gepackte Daten sind für die meisten Benutzer schwieriger zu extrahieren und zu ändern. Schützen Sie die urheberrechtlich geschützten Vermögenswerte Ihres Spiels. rres
unterstützt auch die Datenkomprimierung und -verschlüsselung pro Ressource und sorgt so bei Bedarf für zusätzliche Sicherheit.
Downloadzeiten : Wenn auf Daten von einem Server zugegriffen und diese heruntergeladen werden müssen, verkürzt die Packung der Assets in eine oder mehrere .rres
-Dateien die Downloadzeiten im Vergleich zum Herunterladen jeder Datei einzeln.
rres
befindet sich seit 2014 in der Entwicklung. Ich habe dieses Projekt mit dem Ziel gestartet, ein XNB-ähnliches Verpackungsdateiformat für Raylib zu erstellen. In den letzten 8 Jahren wurde das Projekt im Rahmen eines Lernprozesses für Dateiformate mehrfach neu gestaltet und verbessert. In dieser Zeit habe ich Loader/Writer für mehr als 20 verschiedene Dateiformate implementiert und außerdem mehr als 12 benutzerdefinierte Dateiformate für mehrere benutzerdefinierte Raylibtech-Tools erstellt.
rres
-Dateiformat hat mindestens vier große Neugestaltungen durchlaufen:
Der erste Entwurf des Formats beschränkte sich darauf, eine Ressource nach der anderen zu packen. Jede Ressource bestand aus einem Ressourcen-Info-Header, gefolgt von einem festen Satz von vier möglichen Parametern und den Ressourcendaten. Entlang der .rres
Datei wurde eine .h
Header-Datei generiert, die die rresId
mit einem Ressourcendateinamen definiert (normalerweise der ursprüngliche Dateiname der unverarbeiteten Daten). Dieses Modell war ziemlich einfach und intuitiv, hatte jedoch einige wichtige Nachteile: Es berücksichtigte keine komplexen Datenteile, die mehrere Blöcke erfordern könnten, und es gab keine Möglichkeit, Originalquelldateien (oder ähnliche) zu extrahieren/abzurufen.
Der zweite Entwurf war viel komplexer und versuchte, die Mängel des ersten Entwurfs zu beheben. Im zweiten Entwurf könnte jede Ressource mehrere Datenblöcke in einer Art Baumstruktur enthalten. Tatsächlich ähnelte dieses Design dem RIFF-Dateiformat: Jeder Block konnte weitere Blöcke enthalten, jeder mit seinem Header und seinen Daten. Es wurden auch einige zusätzliche Ressourcenoptionen hinzugefügt, aber das Format wurde recht komplex zu verstehen und zu verwalten. Schließlich wurde die Testimplementierung verworfen und eine einfachere Alternative untersucht.
Der dritte Entwurf war eine Rückkehr zum ersten Entwurf: Einfachheit, aber Beibehaltung einiger Optionen für die einzelnen Ressourcen. Das Problem, dass mehrere Ressourcen aus einer einzigen Eingabedatei generiert wurden, wurde durch ein einfaches Offset-Feld im Ressourcen-Info-Header gelöst, das bei Bedarf auf die nächste verknüpfte Ressource verweist. Ressourcen wurden als Array von Ressourcenblöcken geladen. Ein optionaler Central Directory-Ressourcenblock wurde hinzugefügt, um Referenzen für die Eingabedateien beizubehalten. Das Format war gut, erforderte jedoch noch eine Implementierung und weitere Untersuchungen, es musste Engine-unabhängig sein und war immer noch von Raylib-Strukturen und -Funktionalitäten abhängig.
Während der Implementierung wurde ein vierter Entwurf erstellt. Fast alle Strukturen und Felder wurden überprüft und umbenannt, um Konsistenz und Einfachheit zu gewährleisten. Es wurde eine separate Bibliothek erstellt ( rres-raylib.h
), um die geladenen Ressourcendaten in benutzerdefinierte Bibliotheks-/Engine-Datentypen abzubilden. Jegliche Abhängigkeit von Raylib wurde entfernt, sodass es sich um ein vollständig Engine-unabhängiges Dateiformat handelt. Es wurden mehrere Anwendungsbeispiele für Raylib implementiert, um die Bibliothek-Engine-Verbindung von rres
zu veranschaulichen, und es wurden mehrere Arten des Ressourcenladens implementiert. Das rrespacker
-Tool wurde von Grund auf zum Generieren von rres
Dateien entwickelt. Es unterstützt eine schöne GUI-Oberfläche mit Drag-and-Drop-Unterstützung, aber auch eine leistungsstarke Befehlszeile für die Stapelverarbeitung. Die Komprimierungs- und Verschlüsselungsimplementierung wurde in die Benutzerbibliotheksimplementierung verschoben, um sie an das Verpackungstool anzupassen und das rres
-Dateiformat sauberer und einfacher zu halten.
Es war ein 8-jähriges Projekt , an dem ich immer wieder gearbeitet habe, mit vielen Neugestaltungen und Überarbeitungen, aber ich persönlich bin mit dem Endergebnis sehr zufrieden. rres
ist ein Ressourcenverpackungsdateiformat auf dem Niveau jedes professionellen Engine-Paketformats, ABER kostenlos und Open Source , verfügbar für jeden Spieleentwickler, der es verwenden, implementieren oder eine benutzerdefinierte Version erstellen möchte.
Das rres-Dateiformat besteht aus einem Dateiheader ( rresFileHeader
), gefolgt von einer Reihe von Ressourcenblöcken ( rresResourceChunk
). Jeder Ressourcenblock verfügt über einen Ressourceninformationsheader ( rresResourceChunkInfo
), der einen FOURCC
Datentypcode und Ressourcendateninformationen enthält. Die Ressourcendaten ( rresResourceChunkData
) enthalten je nach Typ einen kleinen Satz von Eigenschaften zur Identifizierung von Daten und können am Ende einige zusätzliche Daten enthalten.
Abb. 01. rres v1.0-Dateistruktur.
HINWEIS: rresResourceChunk(s) werden aus Eingabedateien generiert. Es ist wichtig zu beachten, dass Ressourcen nicht 1:1 Dateien zugeordnet werden können, eine Eingabedatei könnte mehrere Ressourcenblöcke generieren. Beispielsweise könnte eine .ttf-Eingabedatei einen Bildressourcenblock (Typ RRES_DATA_IMAGE
) sowie einen Ressourcenblock für Schriftartglypheninformationen (Typ RRES_DATA_FONT_GLYPHS
) generieren.
rresFileHeader ( 16 bytes )
Signature Id ( 4 bytes ) // File signature id: 'rres'
Version ( 2 bytes ) // Format version
Resource Count ( 2 bytes ) // Number of resource chunks contained
CD Offset ( 4 bytes ) // Central Directory offset (if available)
Reserved ( 4 bytes ) //
rresResourceChunk []
{
rresResourceChunkInfo ( 32 bytes )
Type ( 4 bytes ) // Resource type (FourCC)
Id ( 4 bytes ) // Resource identifier (CRC32 filename hash or custom)
Compressor ( 1 byte ) // Data compression algorithm
Cipher ( 1 byte ) // Data encryption algorithm
Flags ( 2 bytes ) // Data flags (if required)
Packed data Size ( 4 bytes ) // Packed data size (compressed/encrypted + custom data appended)
Base data Size ( 4 bytes ) // Base data size (uncompressed/unencrypted)
Next Offset ( 4 bytes ) // Next resource chunk offset (if required)
Reserved ( 4 bytes ) //
CRC32 ( 4 bytes ) // Resource Chunk Data CRC32
rresResourceChunkData ( n bytes ) // Packed data
Property Count ( 4 bytes ) // Number of properties contained
Properties [] ( 4 * i bytes ) // Resource data required properties, depend on Type
Data ( m bytes ) // Resource data
}
rresFileHeader
Die folgende C-Struktur definiert den rresFileHeader
:
// rres file header (16 bytes)
typedef struct rresFileHeader {
unsigned char id [ 4 ]; // File identifier: rres
unsigned short version ; // File version: 100 for version 1.0
unsigned short chunkCount ; // Number of resource chunks in the file (MAX: 65535)
unsigned int cdOffset ; // Central Directory offset in file (0 if not available)
unsigned int reserved ; //
} rresFileHeader ;
Feld | Beschreibung |
---|---|
id | Dateisignatur-ID, es müssen die vier Zeichen sein: r , r , e , s . |
version | Definiert die Version und Subversion des Formats. |
chunkCount | Anzahl der in der Datei vorhandenen Ressourcenblöcke. Beachten Sie, dass es größer sein könnte als die Anzahl der verarbeiteten Eingabedateien. |
cdOffset | Absoluter Offset des zentralen Verzeichnisses innerhalb der Datei. Beachten Sie, dass CDIR nur ein weiterer Ressourcenblocktyp ist. Das zentrale Verzeichnis kann in der Datei vorhanden sein oder nicht . Es wird empfohlen, es als letzten Block in der Datei zu platzieren, wenn ein benutzerdefinierter rres Packer implementiert ist. Weitere Informationen finden Sie im Abschnitt rresCentralDir . |
reserved | Dieses Feld ist bei Bedarf für zukünftige Ergänzungen reserviert. |
Tabelle 01. Beschreibung und Details rresFileHeader
Felder
Überlegungen:
rres
-Dateien sind konstruktionsbedingt auf maximal 65535 Ressourcenblöcke begrenzt. Für den Fall, dass mehr Ressourcen gepackt werden müssen, wird empfohlen, mehrere rres
Dateien zu erstellen.rres
-Dateien verwenden 32-Bit-Offsets, um die verschiedenen Ressourcenblöcke anzusprechen. Folglich können nicht mehr als ~4 GB an Daten adressiert werden . Bitte halten Sie die rres
Dateien kleiner als 4 GB . Wenn mehr Speicherplatz zum Verpacken von Ressourcen erforderlich ist, erstellen Sie mehrere rres
Dateien. rresResourceChunk
rres
Datei enthält eine Reihe von Ressourcenblöcken. Jeder Ressourcenblock stellt ein in sich geschlossenes Datenpaket dar. Ressourcenblöcke werden aus Eingabedateien bei der rres
Dateierstellung durch das rres
Packer-Tool generiert. Abhängig von der Dateierweiterung extrahiert das rres
Packer-Tool die erforderlichen Daten aus der Datei und generiert einen oder mehrere Ressourcenblöcke. Beispielsweise wird für eine Bilddatei ein Ressourcenblock vom type
RRES_DATA_IMAGE
generiert, der nur die Pixeldaten des Bildes und die erforderlichen Eigenschaften enthält, um diese Daten aus der Ressourcendatei zurückzulesen.
Es ist wichtig zu beachten, dass eine Eingabedatei beim Erstellen der rres
-Datei mehrere Ressourcenblöcke generieren kann. Eine .ttf
Eingabedatei könnte beispielsweise einen RRES_DATA_IMAGE
-Ressourcenblock und einen RRES_DATA_FONT_GLYPHS
-Ressourcenblock generieren. Es ist auch möglich, die Datei einfach als einfachen RRES_DATA_RAW
Ressourcenblocktyp zu packen. In diesem Fall wird die Eingabedatei nicht verarbeitet, sondern nur als Rohdaten gepackt.
Bei rres
Erstellung könnte rres
-Packer einen zusätzlichen Ressourcenblock vom Typ RRES_DATA_DIRECTORY
erstellen, der Daten über die verarbeiteten Eingabedateien enthält. In einigen Fällen kann es nützlich sein, beispielsweise den Namen der Eingabedatei direkt mit der ID der generierten Ressource(n) zu verknüpfen und die Daten auch in einer Dateistruktur zu extrahieren, die der ursprünglichen Eingabedatei ähnelt.
Jeder Ressourcenblock ist in zwei Teile unterteilt: rresResourceChunkInfo
+ rresResourceData
.
rresResourceChunkInfo
Die folgende C-Struktur definiert rresResourceChunkInfo
:
// rres resource chunk info header (32 bytes)
typedef struct rresResourceChunkInfo {
unsigned char type [ 4 ]; // Resource chunk type (FourCC)
unsigned int id ; // Resource chunk identifier (generated from filename CRC32 hash)
unsigned char compType ; // Data compression algorithm
unsigned char cipherType ; // Data encription algorithm
unsigned short flags ; // Data flags (if required)
unsigned int packedSize ; // Data chunk size (compressed/encrypted + custom data appended)
unsigned int baseSize ; // Data base size (uncompressed/unencrypted)
unsigned int nextOffset ; // Next resource chunk global offset (if resource has multiple chunks)
unsigned int reserved ; //
unsigned int crc32 ; // Data chunk CRC32 (propCount + props[] + data)
} rresResourceChunkInfo ;
Feld | Beschreibung |
---|---|
type | Ein FourCC Code und identifiziert den Typ der in rresResourceChunkData enthaltenen Ressourcendaten. Enum rresResourceDataType definiert mehrere Datentypen, neue können bei Bedarf hinzugefügt werden. |
id | Es handelt sich um eine globale Ressourcenkennung, die aus dem Eingabedateinamen mithilfe eines CRC32-Hashs generiert wird und nicht eindeutig ist. Eine Eingabedatei kann mehrere Ressourcenblöcke generieren. Alle generierten Blöcke haben dieselbe Kennung und werden beim Laden der Ressource gemeinsam geladen. Beispielsweise könnte eine Eingabe-.ttf-Datei zwei Ressourcenblöcke ( RRES_DATA_IMAGE + RRES_DATA_FONT_GLYPHS ) mit derselben Kennung generieren, die zusammen geladen werden, wenn ihre Kennung angefordert wird. Es liegt am Benutzer, zu entscheiden, was mit den geladenen Daten geschehen soll. |
compType | Definiert den Komprimierungsalgorithmus, der für die Ressourcenblockdaten verwendet wird. Die Komprimierung hängt von der mittleren Bibliothek zwischen rres und der Engine ab. rres.h definiert lediglich einige nützliche Algorithmuswerte, die bei der Implementierung der Komprimierung verwendet werden sollen. Die Komprimierung sollte immer vor der Verschlüsselung angewendet werden und komprimiert die gesamten rresResourceData ( Property Count + Properties[] + Data ). Wenn keine Datenverschlüsselung angewendet wird, definiert packedSize die Größe der komprimierten Daten. |
cipherType | Definiert den Verschlüsselungsalgorithmus, der für die Ressourcenblockdaten verwendet wird. Wie die Komprimierung hängt auch die Verschlüsselung von der mittleren Bibliothek zwischen rres und der Engine ab. rres.h definiert lediglich einige nützliche Algorithmuswerte, die bei der Implementierung der Verschlüsselung verwendet werden sollen. Die Verschlüsselung sollte nach der Komprimierung angewendet werden. Je nach Verschlüsselungsalgorithmus und Verschlüsselungsmodus kann es erforderlich sein, den Ressourcendaten ein zusätzliches Datenelement hinzuzufügen (z. B. Verschlüsselungs-MAC). Dies ist abhängig von der Implementierung und das RRES-Packer-Tool bzw. die RRES-Mittelbibliothek für die Engines ist dafür verantwortlich, dies zu verwalten zusätzliche Daten. Es wird empfohlen, es einfach an Ressourcendaten anzuhängen und bei packedSize zu berücksichtigen. |
flags | Reserviert für zusätzliche Flags, falls diese für die Implementierung erforderlich sind. |
packedSize | Definiert die gepackte Größe (komprimiert/verschlüsselt + zusätzliche Benutzerdaten) von rresResourceChunkData . Verpackte Daten könnten am Ende nach komprimierten/verschlüsselten Daten angehängte Benutzerdaten enthalten, zum Beispiel den Nonce/MAC für die verschlüsselten Daten. Dies ist jedoch abhängig von der Implementierung und wird vom rres Packer-Tool und der Benutzerbibliothek verwaltet, in die die Datenblöcke geladen werden Zielmotorstrukturen. |
baseSize | Definiert die Basisgröße (unkomprimiert/unverschlüsselt) von rresResourceChunkData . |
nextOffset | Definiert die globale Dateipositionsadresse für den nächsten zugehörigen Ressourcenblock. Dies ist nützlich für Eingabedateien, die mehrere Ressourcen generieren, z. B. Schriftarten oder Netze. |
reserved | Dieses Feld ist bei Bedarf für zukünftige Ergänzungen reserviert. |
crc32 | Wird über den gesamten rresResourceData Block ( packedSize ) berechnet und soll Datenbeschädigungsfehler erkennen. |
Tabelle 02. Beschreibung und Details rresResourceChunkInfo
Felder
rresResourceChunkData
rresResourceChunkData
enthält die folgenden Daten:
Property Count
: Anzahl der enthaltenen Eigenschaften, abhängig vom type
Properties[]
: Erforderliche Eigenschaften für Ressourcendaten, abhängig vom type
Data
: Rohdaten der Ressource, abhängig vom type
HINWEIS: rresResourceChunkData könnte zusätzliche Benutzerdaten enthalten. In diesen Fällen muss die zusätzliche Datengröße in packedSize
berücksichtigt werden.
rresResourceDataType
Der in rresResourceChunkInfo
angegebene type
definiert den Datentyp und die Anzahl der im Ressourcenblock enthaltenen Eigenschaften.
Hier handelt es sich um die aktuell definierten Datentypen. Bitte beachten Sie, dass einige Eingabedateien mehrere Ressourcenblöcke verschiedener Typen generieren können. Bei Bedarf können weitere Ressourcentypen hinzugefügt werden.
// rres resource chunk data type
// NOTE 1: Data type determines the properties and the data included in every chunk
// NOTE 2: This enum defines the basic resource data types, some input files could generate multiple resource chunks
typedef enum rresResourceDataType {
RRES_DATA_NULL = 0 , // FourCC: NULL - Reserved for empty chunks, no props/data
RRES_DATA_RAW = 1 , // FourCC: RAWD - Raw file data, input file is not processed, just packed as is
RRES_DATA_TEXT = 2 , // FourCC: TEXT - Text file data, byte data extracted from text file
RRES_DATA_IMAGE = 3 , // FourCC: IMGE - Image file data, pixel data extracted from image file
RRES_DATA_WAVE = 4 , // FourCC: WAVE - Audio file data, samples data extracted from audio file
RRES_DATA_VERTEX = 5 , // FourCC: VRTX - Vertex file data, extracted from a mesh file
RRES_DATA_FONT_GLYPHS = 6 , // FourCC: FNTG - Font glyphs info, generated from an input font file
RRES_DATA_LINK = 99 , // FourCC: LINK - External linked file, filepath as provided on file input
RRES_DATA_DIRECTORY = 100 , // FourCC: CDIR - Central directory for input files relation to resource chunks
// TODO: Add additional data types if required
} rresResourceDataType ;
Die aktuell definierten types
bestehen aus den folgenden Eigenschaften und Daten:
Ressourcentyp | FourCC | propsCount | Requisiten | Daten |
---|---|---|---|---|
RRES_DATA_NULL | NULL | 0 | - | - |
RRES_DATA_RAW | RAWD | 4 | props[0] :sizeprops[1] : extension01 props[2] : extension02 props[3] : reserviert | rohe Dateibytes |
RRES_DATA_TEXT | TEXT | 4 | props[0] :sizeprops[1] : rresTextEncoding props[2] : rresCodeLang props[3] :cultureCode | Textdaten |
RRES_DATA_IMAGE | IMGE | 4 | props[0] :Breiteprops[1] :höheprops[2] : rresPixelFormat props[3] :mipmaps | Pixeldaten |
RRES_DATA_WAVE | WAVE | 4 | props[0] :frameCountprops[1] :sampleRateprops[2] :sampleSizeprops[3] :Kanäle | Audio-Samples-Daten |
RRES_DATA_VERTEX | VRTX | 4 | props[0] :vertexCountprops[1] : rresVertexAttribute props[2] :componentCountprops[3] : rresVertexFormat | Scheitelpunktdaten |
RRES_DATA_FONT_GLYPHS | FNTG | 4 | props[0] :baseSizeprops[1] :glyphCountprops[2] :glyphPaddingprops[3] : rresFontStyle | rresFontGlyphInfo[0..glyphCount] |
RRES_DATA_LINK | LINK | 1 | props[0] :size | Dateipfaddaten |
RRES_DATA_DIRECTORY | CDIR | 1 | props[0] :entryCount | rresDirEntry[0..entryCount] |
Tabelle 03. rresResourceDataType
definierte Werte und Details
HINWEIS: RRES_DATA_RAW
enthält die gepackte Dateierweiterung als Teil seiner Eigenschaften. Die Erweiterung char
wird in einen 4-Byte unsigned int
konvertiert, beginnend mit einem Punkt. also ".png"
=> 0x2e706e67
. Falls die Erweiterung nicht relevant war, könnte die Benutzerimplementierung entscheiden, diese Eigenschaften auf 0
zu setzen.
Zur Vereinfachung der Zuweisung einiger Eigenschaften definiert rres.h
die folgenden enums
:
rresTextEncoding
: Definiert mehrere mögliche Textkodierungen, Standardwert ist 0 (UTF-8)rresCodeLang
: Definiert mehrere Programmiersprachen, nützlich beim Einbetten von Codedateien oder SkriptenrresPixelFormat
: Definiert mehrere Pixelformatwerte für BildpixeldatenrresVertexAttribute
: Definiert der Einfachheit halber mehrere Vertex-AttributtypenrresVertexFormat
: Definiert mehrere Datenformate für ScheitelpunktdatenrresFontStyle
: Definiert mehrere Schriftarten (Regular, Bold, Italic...), Standardwert ist 0 ( RRES_FONT_STYLE_DEFAULT
)rresCentralDir
Der Central Directory
Ressourcenblock ist ein spezieller Block, der in der rres
-Datei vorhanden sein kann oder nicht . Er speichert Informationen über die Eingabedateien, die zum Generieren der mehreren Ressourcenblöcke verarbeitet wurden, und könnte für Folgendes nützlich sein:
Verweisen Sie auf die Ressourcen anhand ihres ursprünglichen Dateinamens. Dies ist im Hinblick auf die Implementierung sehr nützlich, um die erforderlichen Codeänderungen zu minimieren, wenn rres
-Paketierung über ein bestehendes Projekt oder am Ende einer Projektentwicklung erfolgt, wenn das Laden aller Dateien direkt unter Verwendung der Dateinamen erfolgt ist.
Extrahieren Sie einige der Ressourcen in eine ähnliche Eingabedatei. Dies ist nur möglich, wenn die Eingabedatei nicht destruktiv verarbeitet wurde. Wenn beispielsweise eine.ttf-Datei verarbeitet wurde, um einen Glyphen-Bildatlas + Glyphen-Dateninformationen zu generieren, ist es nicht möglich, die ursprüngliche .ttf-Datei abzurufen.
rres
bietet einige hilfreiche Strukturen für den Umgang mit Central Directory
Ressourcenblockdaten:
// rres central directory entry
typedef struct rresDirEntry {
unsigned int id ; // Resource id
unsigned int offset ; // Resource global offset in file
unsigned int reserved ; // reserved
unsigned int fileNameSize ; // Resource fileName size (NULL terminator and 4-byte alignment padding considered)
char fileName [ RRES_MAX_CDIR_FILENAME_LENGTH ]; // Resource original fileName (NULL terminated and padded to 4-byte alignment)
} rresDirEntry ;
// rres central directory
// NOTE: This data represents the rresResourceChunkData
typedef struct rresCentralDir {
unsigned int count ; // Central directory entries count
rresDirEntry * entries ; // Central directory entries
} rresCentralDir ;
HINWEIS: Dateinameneinträge im Central Directory sind auf 4-Byte-Auffüllung ausgerichtet, um die Dateizugriffszeiten zu verkürzen.
rres.h
bietet eine Funktion zum Laden Central Directory
aus der rres
Datei, sofern verfügbar: rresLoadCentralDirectory()
sowie eine Funktion zum Abrufen einer Ressourcenkennung aus ihrem ursprünglichen Dateinamen: rresGetIdFromFileName()
.
Falls eine rres
-Datei ohne Central Directory
generiert wird, sollte eine sekundäre Header-Datei ( .h
) mit den ID-Referenzen für alle Ressourcen bereitgestellt werden, um im Benutzercode verwendet zu werden.
rres
ist als Engine-unabhängiges Dateiformat konzipiert, das mit jeder Spiel-Engine verwendet werden kann. Entwickler, die rres
einführen, können eine benutzerdefinierte Bibliothek und eine benutzerdefinierte Abstraktion implementieren, um generische rres
Daten den Datenstrukturen ihrer eigenen Engine sowie benutzerdefinierten rres
Paketierungstools zuzuordnen.
Das folgende Diagramm zeigt eine Beispielimplementierung von rres
für raylib
-Bibliothek.
Abb. 02. rres-Beispielimplementierung: benutzerdefinierte Engine-Bibliotheken und Tool.
rres
Implementierung besteht aus mehreren Teilen:
rres.h
rres-raylib.h
rrespacker
rres.h
Die Basis rres
-Bibliothek ist für das Lesen von rres
-Dateiressourcenblöcken in eine generische Ressourcenstruktur verantwortlich, die an den Benutzer zurückgegeben wird. Die vom Benutzer bereitgestellte Ressourcenstruktur rresResourceChunk
folgt rres
Spezifikationsstruktur ( rresResourceChunkInfo
+ rresResourceChunkData
). Folgende Strukturen stehen zur Verfügung:
rresResourceChunk
enthält einen einzelnen Block mit vom Benutzer benötigten Informationen und Daten: rresResourceChunkInfo
+ rresResourceChunkData
rresresourceChunkInfo
enthält die Informationen zum geladenen RessourcenblockrresResourceChunkData
enthält die tatsächlichen Daten für die Ressource: die erforderlichen Eigenschaften und die Rohdaten. Es ist wichtig zu beachten, dass es für den Fall, dass Daten komprimiert/verschlüsselt wurden, an der Benutzerbibliothek ( rres-raylib.h
) liegt, diese Daten zu verarbeiten. in diesen Fällen enthält chunk.data.raw
die komprimierten/verschlüsselten Daten und chunk.data.propCount = 0
und chunk.data.props = NULL
; Es liegt an der Benutzerbibliothek, die Eigenschaften nach der Dekomprimierung/Entschlüsselung zu füllen.rresResourceMulti
enthält mehrere rresResourceChunks
für eine verarbeitete Eingabedatei // rres resource chunk
typedef struct rresResourceChunk {
rresResourceChunkInfo info ; // Resource chunk info
rresResourceChunkData data ; // Resource chunk packed data, contains propCount, props[] and raw data
} rresResourceChunk ;
// rres resource chunk info header (32 bytes)
typedef struct rresResourceChunkInfo {
unsigned char type [ 4 ]; // Resource chunk type (FourCC)
unsigned int id ; // Resource chunk identifier (generated from filename CRC32 hash)
unsigned char compType ; // Data compression algorithm
unsigned char cipherType ; // Data encription algorithm
unsigned short flags ; // Data flags (if required)
unsigned int packedSize ; // Data chunk size (compressed/encrypted + custom data appended)
unsigned int baseSize ; // Data base size (uncompressed/unencrypted)
unsigned int nextOffset ; // Next resource chunk global offset (if resource has multiple chunks)
unsigned int reserved ; //
unsigned int crc32 ; // Data chunk CRC32 (propCount + props[] + data)
} rresResourceChunkInfo ;
// rres resource chunk data
typedef struct rresResourceChunkData {
unsigned int propCount ; // Resource chunk properties count
unsigned int * props ; // Resource chunk properties
void * raw ; // Resource chunk raw data
} rresResourceChunkData ;
// rres resource multi
// NOTE: It supports multiple resource chunks
typedef struct rresResourceMulti {
unsigned int count ; // Resource chunks count
rresResourceChunk * chunks ; // Resource chunks
} rresResourceMulti ;
Ein einzelner rresResourceChunk
kann mit der bereitgestellten Funktion rresLoadResourceChunk()
aus der .rres
Datei geladen und mit rresUnloadResourceChunk()
entladen werden.
Ein vollständiges rresResourceMulti
kann mit der bereitgestellten Funktion rresLoadResourceMulti()
aus der .rres
Datei geladen und mit rresUnloadResourceMulti()
entladen werden.
rres-raylib.h
Die Zuordnungsbibliothek enthält rres.h
und bietet Funktionen zum Zuordnen der aus der rres
Datei geladenen Ressourcen-Chunks-Daten in raylib
Strukturen. Die bereitgestellte API ist einfach und intuitiv und folgt raylib
-Konventionen:
RLAPI void * LoadDataFromResource ( rresResourceChunk chunk , int * size ); // Load raw data from rres resource chunk
RLAPI char * LoadTextFromResource ( rresResourceChunk chunk ); // Load text data from rres resource chunk
RLAPI Image LoadImageFromResource ( rresResourceChunk chunk ); // Load Image data from rres resource chunk
RLAPI Wave LoadWaveFromResource ( rresResourceChunk chunk ); // Load Wave data from rres resource chunk
RLAPI Font LoadFontFromResource ( rresResourceMulti multi ); // Load Font data from rres resource multiple chunks
RLAPI Mesh LoadMeshFromResource ( rresResourceMulti multi ); // Load Mesh data from rres resource multiple chunks
RLAPI int UnpackResourceChunk ( rresResourceChunk * chunk ); // Unpack resource chunk data (decompres/decrypt data)
RLAPI void SetBaseDirectory ( const char * baseDir ); // Set base directory for externally linked data
Beachten Sie, dass die Datendekomprimierung/-entschlüsselung in dieser benutzerdefinierten Bibliothek implementiert ist und den Benutzern UnpackResourceChunk()
zur Verfügung gestellt wird. rresResourceChunk
enthält der Einfachheit halber Kompressor-/Verschlüsselungs-ID-Werte. Die Unterstützung von Kompressoren und Verschlüsselungen hängt von der Benutzerimplementierung ab und muss mit dem Verpackungstool ( rrespacker
) abgestimmt sein.
rres
-Dateiformat ist Engine-unabhängig, Bibliotheken und Tools können für jede Engine/jedes Framework in jeder Programmiersprache erstellt werden.
rrespacker
rrespacker
ist das rres
Packtool, das für die Verarbeitung aller Eingabedateien und die Erstellung der rres
Datei gemäß der Spezifikation verantwortlich ist. Falls einige Komprimierungs-/Verschlüsselungsalgorithmen unterstützt werden, müssen sie von diesem Tool implementiert werden und dieselben Algorithmen sollten von der Mapping-Bibliothek unterstützt werden, in unserem Fall rres-raylib.h
.
Abb. 03. rrespacker-Tool, GUI-Schnittstelle, es unterstützt auch CLI für die Stapelverarbeitung.
rrespacker
kann online von itch.io verwendet (oder heruntergeladen) werden.
rres
Dateiformatspezifikationen, rres.h
Bibliothek und rres-raylib.h
Bibliothek sind unter der MIT-Lizenz lizenziert. Weitere Einzelheiten finden Sie unter LIZENZ.
Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)