Difference between revisions of "Graphics directory"
From Worms Knowledge Base
m |
m (Wording, sections, code formatting) |
||
(2 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
{{ParentArticle|[[File formats]]}} | {{ParentArticle|[[File formats]]}} | ||
− | A Worms directory (a DIR file) | + | A Worms directory (a DIR file) acts as a file archive, containing (usually graphics) files. Its built-in hash table allows fast access to files by the file name. |
− | + | == File Format == | |
+ | The format (as well as others) was first reverse-engineered by [[Jon Skeet]], and implemented in [[Fudge Boy]]'s [[WA directory editor|sprite editor]]. | ||
− | + | * A 12-byte header, consisting of: | |
− | + | ** A 4-byte signature, "DIR\x1A" | |
− | * | + | ** Complete file length, including header and table of contents (4 bytes) |
− | ** | + | ** Address (file offset) of the directory table of contents (4 bytes) |
− | ** | + | * The actual data of the files stored in the directory |
− | ** | + | * The table of contents, consisting of: |
− | * | + | ** A signature (?) DWORD, 0x0000000A (4 bytes) |
− | * | + | ** A 1024-entry DWORD hash table (4096 bytes). Each entry is an offset (relative to the start of the TOC) to the first file entry, whose file name matches this hash, or 0 for no matching file entries. |
− | ** | + | ** The list of files stored in the directory. Each list entry consists of: |
− | ** | + | *** Offset (relative to the start of the TOC) to the next entry for this hash value, or 0 for none (4 bytes) |
− | ** | + | *** Offset within DIR file of this file entry's data (4 bytes) |
− | *** | + | *** Length of file (4 bytes) |
− | *** | + | *** The file name, padded to a multiple of 4 characters (with at least one after trailing \0). |
− | *** | + | |
− | *** | + | |
+ | == Hash Calculation == | ||
The hash function (with which the hashes to the file names are calculated) is as follows: | The hash function (with which the hashes to the file names are calculated) is as follows: | ||
#define HASH_BITS 10 | #define HASH_BITS 10 | ||
− | #define HASH_SIZE (1<<HASH_BITS) | + | #define HASH_SIZE (1 << HASH_BITS) |
− | static int hash (char *str) | + | |
+ | static int hash(char *str) | ||
{ | { | ||
− | int sum=0; | + | int sum = 0; |
while (*str) | while (*str) | ||
{ | { | ||
− | sum=((sum<<1)%HASH_SIZE)|(sum>>(HASH_BITS-1)&1); | + | sum = ((sum << 1) % HASH_SIZE) | (sum >> (HASH_BITS - 1) & 1); |
− | sum+=(unsigned char)*str++; | + | sum += (unsigned char)*str++; |
sum %= HASH_SIZE; | sum %= HASH_SIZE; | ||
} | } | ||
return sum; | return sum; | ||
} | } | ||
− | |||
− |
Latest revision as of 16:38, 17 April 2017
(Up to File formats)
A Worms directory (a DIR file) acts as a file archive, containing (usually graphics) files. Its built-in hash table allows fast access to files by the file name.
File Format
The format (as well as others) was first reverse-engineered by Jon Skeet, and implemented in Fudge Boy's sprite editor.
- A 12-byte header, consisting of:
- A 4-byte signature, "DIR\x1A"
- Complete file length, including header and table of contents (4 bytes)
- Address (file offset) of the directory table of contents (4 bytes)
- The actual data of the files stored in the directory
- The table of contents, consisting of:
- A signature (?) DWORD, 0x0000000A (4 bytes)
- A 1024-entry DWORD hash table (4096 bytes). Each entry is an offset (relative to the start of the TOC) to the first file entry, whose file name matches this hash, or 0 for no matching file entries.
- The list of files stored in the directory. Each list entry consists of:
- Offset (relative to the start of the TOC) to the next entry for this hash value, or 0 for none (4 bytes)
- Offset within DIR file of this file entry's data (4 bytes)
- Length of file (4 bytes)
- The file name, padded to a multiple of 4 characters (with at least one after trailing \0).
Hash Calculation
The hash function (with which the hashes to the file names are calculated) is as follows:
#define HASH_BITS 10 #define HASH_SIZE (1 << HASH_BITS) static int hash(char *str) { int sum = 0; while (*str) { sum = ((sum << 1) % HASH_SIZE) | (sum >> (HASH_BITS - 1) & 1); sum += (unsigned char)*str++; sum %= HASH_SIZE; } return sum; }