Document maps findings and start moving things out of README.md
This commit is contained in:
147
README.md
147
README.md
@@ -1,116 +1,25 @@
|
|||||||
# WH40K: Chaos Gate
|
# WH40K: Chaos Gate
|
||||||
|
|
||||||
Re-implementation of the WH40K binary using SDL.
|
Re-implementation of the WH40K binary.
|
||||||
|
|
||||||
**You must have a copy of the original game data to use this project**
|
**You must have a copy of the original game data to use this project**
|
||||||
|
|
||||||
Files:
|
|
||||||
|
|
||||||
```
|
|
||||||
Anim/
|
|
||||||
WarHammer.ani # Doesn't seem to be a RIFF file. 398M so very important.
|
|
||||||
* There's a pcx image header at `dd ... bs=1 skip=213` but it seems to be a false alert
|
|
||||||
* Hits for "AmigaOS bitmap font"... probably a false positive
|
|
||||||
* Lots of 8-byte reads when loading stuff in the mission editor
|
|
||||||
* Some ~4K reads, havent found one corresponding to a known format yet
|
|
||||||
Assign/
|
|
||||||
*.asn # Unknown, seems to be related to .obj files
|
|
||||||
Cursor/
|
|
||||||
*.ani # RIFF data
|
|
||||||
*.cur # Presumably standard windows-format non-animated cursors
|
|
||||||
Data/
|
|
||||||
*.dat # plaintext files defining properties of objects. No single format
|
|
||||||
PARSED:
|
|
||||||
Accounting.dat # key = value => internal/data/accounting.go
|
|
||||||
AniObjDef.dat # animated object definitions
|
|
||||||
GenericData.dat # Generic Game Settings
|
|
||||||
IN PROGRESS:
|
|
||||||
|
|
||||||
TODO:
|
|
||||||
ChaNames.dat # list of character names
|
|
||||||
Coordinates.dat # Weapon Firing Coordinates
|
|
||||||
Defs.dat # defines properties for objects and tiles, each of which seems to have an id
|
|
||||||
GDestroy.dat # table of what destroys what?
|
|
||||||
HasAction.dat # "Are there animation for each of the character" - list of booleans
|
|
||||||
MiniMap.dat # lots of seemingly random numbers. IDs?
|
|
||||||
MissionBriefing.dat # Contains all Campaign Mission Briefing Text. Sections: "CAMPAIGN MISSION X ... END CAMPAIGN MISSION X"
|
|
||||||
PWeight.dat # Personality weights for the individual character types
|
|
||||||
Random_AI.dat # contains the percentage of the different AI types for each of the different Chaos Squad Types
|
|
||||||
RandomPlanets.dat # Campaign Primary and Secondary Objectives
|
|
||||||
Sounds.dat # Sound Effect Data
|
|
||||||
SpellDef.dat # SPELL DEFINITIONS
|
|
||||||
StdWeap.dat # SQUAD STANDARD WEAPONS
|
|
||||||
Ultnames.dat # List of names for ultramarines
|
|
||||||
VehicDef.dat # VEHICLE DEFINITIONS
|
|
||||||
WeapDef.dat # Weapon definitions
|
|
||||||
PROBABLY NOT NEEDED:
|
|
||||||
BugHunt.dat # Contains SMF text for Bug hunt random missions
|
|
||||||
Credits.dat # list of credits
|
|
||||||
GenArm.dat # "Random campaign armory levels - space marine"
|
|
||||||
HeroArm.dat # "Random campaign armory levels - Veteran"
|
|
||||||
MHeroArm.dat # "Random campaign armory levels - Veteran"
|
|
||||||
PlanetDesc.dat # well-documented params. random mission generator params per planet.
|
|
||||||
RandChar.dat # Random character matrix. Information on what goes into a character matrix.
|
|
||||||
RandSMFtext.dat # SuperMacro Objectives for Campaign Random Mission Generator.
|
|
||||||
SpArm.dat # "RANDOM CAMPAIGN ARMORY LEVELS - Veteran"
|
|
||||||
VetArm.dat # "RANDOM CAMPAIGN ARMORY LEVELS - Veteran"
|
|
||||||
|
|
||||||
*.chk # checksums? Mentions all the .dat files
|
|
||||||
*.cyc # ColorCycle DataFile.
|
|
||||||
*.dta # localized strings and things
|
|
||||||
Encyclopedia.dta # encyclopedia entries
|
|
||||||
KeyMap.dta # unknown
|
|
||||||
Keymap.dta # unknown
|
|
||||||
USEng.dta # Localized strings
|
|
||||||
|
|
||||||
EquipmentMenuData # gzip-compressed, presumably to do with (initial?) squad configuration
|
|
||||||
Filters/
|
|
||||||
wh40k.flt # Audio filter(s?)
|
|
||||||
Fonts/
|
|
||||||
cboxfont # unknown
|
|
||||||
*.fnt # ASCII text. Map keycodes to sprites?
|
|
||||||
*.spr # sprites, presumably
|
|
||||||
Idx/
|
|
||||||
WarHammer.idx # unknown, 1.8M
|
|
||||||
Maps/
|
|
||||||
*.MAP # gzip-compressed, must be map definition, contains `WHMAP` constant and character names
|
|
||||||
*.TXT # scenario text
|
|
||||||
Menu/
|
|
||||||
*.mnu # plain text, linked to .obj file, contains definitions
|
|
||||||
*.obj # unknown, not 3D .obj format
|
|
||||||
Misc/
|
|
||||||
occlusio.lis # plain text, presumably occlusion mappings?
|
|
||||||
MultiMaps/
|
|
||||||
*.MAP # Like Maps/
|
|
||||||
*.TXT
|
|
||||||
Obj/
|
|
||||||
*.obj # must be visual data of some sort, one per placeable map object?
|
|
||||||
Pic/
|
|
||||||
*.pcx # Standard .pcx format
|
|
||||||
RandomMaps/
|
|
||||||
*.chk # multiplayer. worry about these another day
|
|
||||||
*.dat
|
|
||||||
Save_G/
|
|
||||||
*.sav # savedata, gzip-compressed, custom format
|
|
||||||
*.txt # Seems to be a copy of one of Maps/*.txt
|
|
||||||
Sets/
|
|
||||||
Data.chk # checksums? Mentions all the .set files
|
|
||||||
*.set # plain text, related to maps, lists a set of .obj files for that map?
|
|
||||||
SMK/
|
|
||||||
*.smk # Videos: RAD Game Tools Smacker Multimedia version 2
|
|
||||||
Sounds/
|
|
||||||
wh40k.ds # 0xffffffff then a list of .wav file names. Some sort of index?
|
|
||||||
Wav/
|
|
||||||
*.wav # normal WAV files, all mentioned in Sounds/wh40k.ds
|
|
||||||
```
|
|
||||||
|
|
||||||
WH40K.exe is the existing game engine
|
WH40K.exe is the existing game engine
|
||||||
|
|
||||||
WH40K_TD.exe is the map editor. Allows things to be saved as .MAP or as .SMF
|
WH40K_TD.exe is the map editor. Allows things to be saved as .MAP or as .SMF
|
||||||
("Super Macro File")
|
("Super Macro File")
|
||||||
|
|
||||||
"Mission Setup" includes information about available squad types
|
This README is a grab-bag of miscellaneous information about file formats at
|
||||||
|
present. This is being migrated to the [Formats overview](doc/formats/index.md)
|
||||||
|
as a precursor to making this file useful!
|
||||||
|
|
||||||
|
No game yet, nothing even close. I'm in the very early stages of trying to
|
||||||
|
understand the various file formats. Until then, you can play WH40L: Chaos Gate
|
||||||
|
in a WinXP VM, disconnected from the internet. It doesn't need 3D rendering!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Mission Setup" includes information about available squad types
|
||||||
|
|
||||||
From EquipDef.cpp Dumo: CEquipment we learn the following object types:
|
From EquipDef.cpp Dumo: CEquipment we learn the following object types:
|
||||||
|
|
||||||
@@ -404,4 +313,38 @@ Perhaps we have 24 bytes of header and that's the header-exclusive pixel data si
|
|||||||
Last 8 bits would then actually be the start of the image, but there's a lot
|
Last 8 bits would then actually be the start of the image, but there's a lot
|
||||||
of similarity between them...
|
of similarity between them...
|
||||||
|
|
||||||
|
It smells a bit like a DIB:
|
||||||
|
|
||||||
|
| Offset | Size | Example | Purpose |
|
||||||
|
| 0 | 2 | D1 00 (209) | ?
|
||||||
|
| 2 | 2 | 41 01 (321) | ?
|
||||||
|
| 4 | 2 | 80 00 (128) | Width? |
|
||||||
|
| 6 | 2 | 3F 00 (63) | Height?
|
||||||
|
| 8 | 4 | 00 00 00 00 | Could be pitch / stride?
|
||||||
|
| 12 | 4 | D1 10 00 00 | Size of pixel data
|
||||||
|
| 16 | 4 | 00 00 00 00 | ?
|
||||||
|
| 20 | 4 | 00 00 00 00 | ?
|
||||||
|
|
||||||
|
|
||||||
Now, how to convert the pixel data to an image?!?!
|
Now, how to convert the pixel data to an image?!?!
|
||||||
|
|
||||||
|
Average bits per pixel seems to be less-than-1, e.g. for crates.obj:
|
||||||
|
|
||||||
|
```
|
||||||
|
2018/03/16 21:21:37 CFrame 0: w=76 h=57 sz=3008 w*h=4332 bpp=0.6943674976915974
|
||||||
|
2018/03/16 21:21:37 CFrame 1: w=76 h=57 sz=2988 w*h=4332 bpp=0.6897506925207756
|
||||||
|
2018/03/16 21:21:37 CFrame 2: w=108 h=73 sz=5185 w*h=7884 bpp=0.6576610857432775
|
||||||
|
2018/03/16 21:21:37 CFrame 3: w=107 h=73 sz=5208 w*h=7811 bpp=0.6667520163871463
|
||||||
|
2018/03/16 21:21:37 CFrame 4: w=109 h=95 sz=7639 w*h=10355 bpp=0.7377112506035731
|
||||||
|
2018/03/16 21:21:37 CFrame 5: w=109 h=95 sz=7620 w*h=10355 bpp=0.7358763882182521
|
||||||
|
2018/03/16 21:21:37 CFrame 6: w=76 h=57 sz=2996 w*h=4332 bpp=0.6915974145891043
|
||||||
|
2018/03/16 21:21:37 CFrame 7: w=76 h=57 sz=2964 w*h=4332 bpp=0.6842105263157895
|
||||||
|
2018/03/16 21:21:37 CFrame 8: w=108 h=73 sz=5148 w*h=7884 bpp=0.6529680365296804
|
||||||
|
2018/03/16 21:21:37 CFrame 9: w=107 h=73 sz=5153 w*h=7811 bpp=0.659710664447574
|
||||||
|
2018/03/16 21:21:37 CFrame 10: w=109 h=95 sz=7423 w*h=10355 bpp=0.7168517624336069
|
||||||
|
2018/03/16 21:21:37 CFrame 11: w=109 h=95 sz=7487 w*h=10355 bpp=0.7230323515210043
|
||||||
|
```
|
||||||
|
|
||||||
|
So some form of compression? RLE?
|
||||||
|
|
||||||
|
How does WH40K_TD.EXE draw these?
|
||||||
|
122
doc/formats/index.md
Normal file
122
doc/formats/index.md
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
# Formats
|
||||||
|
|
||||||
|
Chaos Gate has over 700MB of data, organized (seemingly) logically into files in
|
||||||
|
directories. Being able to parse, display, and use that data is paramount to any
|
||||||
|
remake.
|
||||||
|
|
||||||
|
## Filesystem layout
|
||||||
|
|
||||||
|
* `Anim/`
|
||||||
|
* `WarHammer.ani` # Doesn't seem to be a RIFF file. 398M so very important.
|
||||||
|
* There's a pcx image header at `dd ... bs=1 skip=213` but it seems to be a false alert
|
||||||
|
* Hits for "AmigaOS bitmap font"... probably a false positive
|
||||||
|
* Lots of 8-byte reads when loading stuff in the mission editor
|
||||||
|
* Some ~4K reads, havent found one corresponding to a known format yet
|
||||||
|
* foo
|
||||||
|
* `Assign/`
|
||||||
|
* `*.asn` # Unknown, seems to be related to .obj files
|
||||||
|
* `Cursor/`
|
||||||
|
* `*.ani` # RIFF data
|
||||||
|
* `*.cur` # Presumably standard windows-format non-animated cursors
|
||||||
|
* `Data/`
|
||||||
|
* `*.dat` # plaintext files defining properties of objects. No single format
|
||||||
|
* **PARSED**
|
||||||
|
* `Accounting.dat` # key = value => internal/data/accounting.go
|
||||||
|
* `AniObjDef.dat` # animated object definitions
|
||||||
|
* `GenericData.dat` # Generic Game Settings
|
||||||
|
* **TODO**
|
||||||
|
* `ChaNames.dat` # list of character names
|
||||||
|
* `Coordinates.dat` # Weapon Firing Coordinates
|
||||||
|
* `Defs.dat` # defines properties for objects and tiles, each of which seems to have an id
|
||||||
|
* `GDestroy.dat` # table of what destroys what?
|
||||||
|
* `HasAction.dat` # "Are there animation for each of the character" - list of booleans
|
||||||
|
* `MiniMap.dat` # lots of seemingly random numbers. IDs?
|
||||||
|
* `MissionBriefing.dat` # Contains all Campaign Mission Briefing Text. Sections: "CAMPAIGN MISSION X ... END CAMPAIGN MISSION X"
|
||||||
|
* `PWeight.dat` # Personality weights for the individual character types
|
||||||
|
* `Random_AI.dat` # contains the percentage of the different AI types for each of the different Chaos Squad Types
|
||||||
|
* `RandomPlanets.dat` # Campaign Primary and Secondary Objectives
|
||||||
|
* `Sounds.dat` # Sound Effect Data
|
||||||
|
* `SpellDef.dat` # SPELL DEFINITIONS
|
||||||
|
* `StdWeap.dat` # SQUAD STANDARD WEAPONS
|
||||||
|
* `Ultnames.dat` # List of names for ultramarines
|
||||||
|
* `VehicDef.dat` # VEHICLE DEFINITIONS
|
||||||
|
* `WeapDef.dat` # Weapon definitions
|
||||||
|
* **PROBABLY NOT NEEDED**
|
||||||
|
* `BugHunt.dat` # Contains SMF text for Bug hunt random missions
|
||||||
|
* `Credits.dat` # list of credits
|
||||||
|
* `GenArm.dat` # "Random campaign armory levels - space marine"
|
||||||
|
* `HeroArm.dat` # "Random campaign armory levels - Veteran"
|
||||||
|
* `MHeroArm.dat` # "Random campaign armory levels - Veteran"
|
||||||
|
* `PlanetDesc.dat` # well-documented params. random mission generator params per planet.
|
||||||
|
* `RandChar.dat` # Random character matrix. Information on what goes into a character matrix.
|
||||||
|
* `RandSMFtext.dat` # SuperMacro Objectives for Campaign Random Mission Generator.
|
||||||
|
* `SpArm.dat` # "RANDOM CAMPAIGN ARMORY LEVELS - Veteran"
|
||||||
|
* `VetArm.dat` # "RANDOM CAMPAIGN ARMORY LEVELS - Veteran"
|
||||||
|
* `*.chk` # checksums? Mentions all the .dat files
|
||||||
|
* `*.cyc` # ColorCycle DataFile.
|
||||||
|
* `*.dta` # localized strings and things
|
||||||
|
* `Encyclopedia.dta` # encyclopedia entries
|
||||||
|
* `KeyMap.dta` # unknown
|
||||||
|
* `Keymap.dta` # unknown
|
||||||
|
* `USEng.dta` # Localized strings
|
||||||
|
* `EquipmentMenuData` # gzip-compressed, presumably to do with (initial?) squad configuration
|
||||||
|
* `Filters/`
|
||||||
|
* `wh40k.flt` # Audio filter(s?)
|
||||||
|
* `Fonts/`
|
||||||
|
* `cboxfont` # unknown
|
||||||
|
* `*.fnt` # ASCII text. Map keycodes to sprites?
|
||||||
|
* `*.spr` # sprites, presumably
|
||||||
|
* `Idx/`
|
||||||
|
* `WarHammer.idx` # unknown, 1.8M
|
||||||
|
* [`Maps/`](maps.md)
|
||||||
|
* `*.MAP`
|
||||||
|
* `*.TXT`
|
||||||
|
* `Menu/`
|
||||||
|
* `*.mnu` # plain text, linked to .obj file, contains definitions
|
||||||
|
* `*.obj` # unknown, not 3D .obj format
|
||||||
|
* `Misc/`
|
||||||
|
* `occlusio.lis` # plain text, presumably occlusion mappings?
|
||||||
|
* [`MultiMaps/`](maps.md#multimaps)
|
||||||
|
* `*.MAP`
|
||||||
|
* `*.TXT`
|
||||||
|
* `Obj/`
|
||||||
|
* `*.obj` # must be visual data of some sort, one per placeable map object?
|
||||||
|
* `Pic/`
|
||||||
|
* `*.pcx` # Standard .pcx format
|
||||||
|
* `RandomMaps/`
|
||||||
|
* `*.chk` # multiplayer. worry about these another day
|
||||||
|
* `*.dat`
|
||||||
|
* `Save_G/`
|
||||||
|
* `*.sav` # savedata, gzip-compressed, custom format
|
||||||
|
* `*.txt` # Seems to be a copy of one of Maps/*.txt
|
||||||
|
* `Sets/`
|
||||||
|
* `Data.chk` # checksums? Mentions all the .set files
|
||||||
|
* `*.set` # plain text, related to maps. Editor has a concept of map sets, which these must be
|
||||||
|
* [✓] `SMK/`
|
||||||
|
* `*.smk` # Videos: RAD Game Tools Smacker Multimedia version 2
|
||||||
|
* `Sounds/`
|
||||||
|
* `wh40k.ds` # 0xffffffff then a list of .wav file names. Some sort of index?
|
||||||
|
* [✓] `Wav/`
|
||||||
|
* `*.wav` # Normal WAV files
|
||||||
|
|
||||||
|
Phew.
|
||||||
|
|
||||||
|
## General notes
|
||||||
|
|
||||||
|
* For binary formats, integers seem to be stored in little-endian
|
||||||
|
* *Almost everything* seems to be in a data file somewhere. Helpful!
|
||||||
|
* `make loader` creates a `load` binary that will try to load various bits
|
||||||
|
of data from `investigation/` and `orig/`. I use it to investigate file
|
||||||
|
formats and the parsers I'm writing. Ensure you're in a `GOPATH`!
|
||||||
|
|
||||||
|
## Cross-links / associations
|
||||||
|
|
||||||
|
(Just some noticed so far)
|
||||||
|
|
||||||
|
* [`Assign/*.asn`](assign.md):
|
||||||
|
* [`Obj/*.obj`](obj.md).
|
||||||
|
* [`Maps/*.map`](maps.md):
|
||||||
|
* [`Maps/*.txt`](maps.md#associated-txt-file)
|
||||||
|
* [`Sets/*.set`](sets.md)
|
||||||
|
* [`Sounds/wh40k.ds`](sounds.md)
|
||||||
|
* `Wav/*.wav`
|
399
doc/formats/maps.md
Normal file
399
doc/formats/maps.md
Normal file
@@ -0,0 +1,399 @@
|
|||||||
|
# Map format information
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The `Map/` directory contains linked pairs of files: a `.TXT` and a `.MAP`.
|
||||||
|
The former appears to be structured text, with tilde-separated sections.
|
||||||
|
The latter is a custom format of some kind, GZip-compressed, with a `WHMAP`
|
||||||
|
constant and character names embedded
|
||||||
|
|
||||||
|
WH40K_TD.exe can read in and write out maps for us, for investigation \o/.
|
||||||
|
|
||||||
|
I update [structure](#structure) with details as I work them out, and put the
|
||||||
|
working in appropriately-named subsections *below* that section.
|
||||||
|
|
||||||
|
## Directory listing
|
||||||
|
|
||||||
|
```
|
||||||
|
total 1.5M
|
||||||
|
-rw-r--r-- 1 65K Nov 4 1998 Chapter01.MAP
|
||||||
|
-rw-r--r-- 1 429 Nov 7 1998 Chapter01.TXT
|
||||||
|
-rw-r--r-- 1 81K Nov 4 1998 Chapter02.MAP
|
||||||
|
-rw-r--r-- 1 587 Nov 7 1998 Chapter02.TXT
|
||||||
|
-rw-r--r-- 1 88K Nov 4 1998 Chapter03.MAP
|
||||||
|
-rw-r--r-- 1 597 Nov 7 1998 Chapter03.TXT
|
||||||
|
-rw-r--r-- 1 100K Jan 26 1999 Chapter04.MAP
|
||||||
|
-rw-r--r-- 1 538 Jan 26 1999 Chapter04.TXT
|
||||||
|
-rw-r--r-- 1 42K Jan 26 1999 Chapter05.MAP
|
||||||
|
-rw-r--r-- 1 1.3K Nov 7 1998 Chapter05.TXT
|
||||||
|
-rw-r--r-- 1 56K Nov 4 1998 Chapter06.MAP
|
||||||
|
-rw-r--r-- 1 572 Nov 7 1998 Chapter06.TXT
|
||||||
|
-rw-r--r-- 1 63K Jan 26 1999 Chapter07.MAP
|
||||||
|
-rw-r--r-- 1 750 Jan 26 1999 Chapter07.TXT
|
||||||
|
-rw-r--r-- 1 66K Nov 20 1998 Chapter08.MAP
|
||||||
|
-rw-r--r-- 1 638 Nov 7 1998 Chapter08.TXT
|
||||||
|
-rw-r--r-- 1 98K Jan 26 1999 Chapter09.MAP
|
||||||
|
-rw-r--r-- 1 656 Jan 26 1999 Chapter09.TXT
|
||||||
|
-rw-r--r-- 1 100K Nov 5 1998 Chapter10.MAP
|
||||||
|
-rw-r--r-- 1 622 Nov 7 1998 Chapter10.TXT
|
||||||
|
-rw-r--r-- 1 110K Nov 4 1998 Chapter11.MAP
|
||||||
|
-rw-r--r-- 1 396 Nov 7 1998 Chapter11.TXT
|
||||||
|
-rw-r--r-- 1 118K Jan 26 1999 Chapter12.MAP
|
||||||
|
-rw-r--r-- 1 593 Nov 7 1998 Chapter12.TXT
|
||||||
|
-rw-r--r-- 1 133K Nov 4 1998 Chapter13.MAP
|
||||||
|
-rw-r--r-- 1 1.1K Nov 7 1998 Chapter13.TXT
|
||||||
|
-rw-r--r-- 1 137K Jan 26 1999 Chapter14.MAP
|
||||||
|
-rw-r--r-- 1 641 Nov 7 1998 Chapter14.TXT
|
||||||
|
-rw-r--r-- 1 140K Nov 5 1998 Chapter15.MAP
|
||||||
|
-rw-r--r-- 1 338 Nov 7 1998 Chapter15.TXT
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Multimaps
|
||||||
|
|
||||||
|
There are also maps in the `MultiMaps/` directory. I guess they're reworks of
|
||||||
|
the `Maps/` entries for multiplayer with differing numbers of players -
|
||||||
|
`Chapter1_3P.MAP` would be the chapter1 map, just modified for 3-player
|
||||||
|
multiplayer. Ignore for now, but here's the directory listing:
|
||||||
|
|
||||||
|
```
|
||||||
|
total 1.4M
|
||||||
|
-rw-r--r-- 1 93K Nov 5 1998 Chapter10_2P.MAP
|
||||||
|
-rw-r--r-- 1 21 Nov 4 1998 Chapter10_2P.TXT
|
||||||
|
-rw-r--r-- 1 103K Nov 5 1998 Chapter11_4P.MAP
|
||||||
|
-rw-r--r-- 1 36 Nov 4 1998 Chapter11_4P.TXT
|
||||||
|
-rw-r--r-- 1 111K Jan 26 1999 Chapter12_2P.MAP
|
||||||
|
-rw-r--r-- 1 198 Nov 4 1998 Chapter12_2P.TXT
|
||||||
|
-rw-r--r-- 1 125K Jan 26 1999 Chapter13_4P.MAP
|
||||||
|
-rw-r--r-- 1 394 Nov 4 1998 Chapter13_4P.TXT
|
||||||
|
-rw-r--r-- 1 64K Nov 5 1998 Chapter1_3P.MAP
|
||||||
|
-rw-r--r-- 1 168 Nov 4 1998 Chapter1_3P.txt
|
||||||
|
-rw-r--r-- 1 127K Nov 4 1998 Chapter14_4P.MAP
|
||||||
|
-rw-r--r-- 1 21 Nov 4 1998 Chapter14_4P.TXT
|
||||||
|
-rw-r--r-- 1 127K Nov 7 1998 Chapter15_2P.MAP
|
||||||
|
-rw-r--r-- 1 21 Nov 4 1998 Chapter15_2P.TXT
|
||||||
|
-rw-r--r-- 1 75K Nov 4 1998 Chapter2_4P.MAP
|
||||||
|
-rw-r--r-- 1 109 Nov 4 1998 Chapter2_4P.txt
|
||||||
|
-rw-r--r-- 1 83K Nov 5 1998 Chapter3_2P.MAP
|
||||||
|
-rw-r--r-- 1 119 Nov 4 1998 Chapter3_2P.txt
|
||||||
|
-rw-r--r-- 1 92K Jan 26 1999 Chapter4_2P.MAP
|
||||||
|
-rw-r--r-- 1 21 Nov 4 1998 Chapter4_2P.txt
|
||||||
|
-rw-r--r-- 1 35K Nov 4 1998 Chapter5_3P.MAP
|
||||||
|
-rw-r--r-- 1 416 Nov 4 1998 Chapter5_3P.txt
|
||||||
|
-rw-r--r-- 1 48K Nov 5 1998 Chapter6_2P.MAP
|
||||||
|
-rw-r--r-- 1 357 Nov 4 1998 Chapter6_2P.txt
|
||||||
|
-rw-r--r-- 1 56K Nov 7 1998 Chapter7_2P.MAP
|
||||||
|
-rw-r--r-- 1 233 Nov 4 1998 Chapter7_2P.txt
|
||||||
|
-rw-r--r-- 1 59K Nov 4 1998 Chapter8_2P.MAP
|
||||||
|
-rw-r--r-- 1 240 Nov 4 1998 Chapter8_2P.txt
|
||||||
|
-rw-r--r-- 1 91K Nov 4 1998 Chapter9_4P.MAP
|
||||||
|
-rw-r--r-- 1 367 Nov 4 1998 Chapter9_4P.TXT
|
||||||
|
```
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
The .MAP files are compressed with gzip. All offsets are on the uncompressed
|
||||||
|
size.
|
||||||
|
|
||||||
|
(Incomplete) parser can be found [here](../../internal/maps/)
|
||||||
|
|
||||||
|
The start of Chapter01.MAP. It's header then per-map-coordinate data. Must
|
||||||
|
remember that maps have 7 height levels (7), so the volume we're describing is
|
||||||
|
actually WxLxH in all cases
|
||||||
|
|
||||||
|
```
|
||||||
|
00000000 01 00 00 00 .... # IsCampaignMap
|
||||||
|
00000004 1A 00 00 00 .... # MinWidth
|
||||||
|
00000008 14 00 00 00 .... # MinLength
|
||||||
|
0000000C 68 00 00 00 h... # MaxWidth
|
||||||
|
00000010 50 00 00 00 P... # MaxLength
|
||||||
|
00000014 01 00 00 00 .... # Unknown1
|
||||||
|
00000018 00 00 00 00 .... # Unknown2
|
||||||
|
0000001C 00 00 00 00 .... # Unknown3
|
||||||
|
00000020 00 00 00 00 .... # Unknown4
|
||||||
|
00000024 08 00 57 48 ..WH # Magic value
|
||||||
|
00000028 4D 41 50 00 MAP. # ...
|
||||||
|
0000002C 00 00 00 00 .... # Unknown
|
||||||
|
00000030 91 09 00 00 .... # Unknown - varies between maps of the same size
|
||||||
|
00000034 6D 61 70 30 map0 # Name of object set to load from `Sets/`
|
||||||
|
00000038 31 00 00 00 1... # ...
|
||||||
|
0000003C 00 00 00 00 .... # Unknown from here....
|
||||||
|
00000040 00 00 00 00 ....
|
||||||
|
00000044 00 00 00 00 ....
|
||||||
|
00000048 00 00 00 00 ....
|
||||||
|
0000004C 00 00 00 00 ....
|
||||||
|
00000050 00 00 00 00 ....
|
||||||
|
00000054 00 00 00 00 ....
|
||||||
|
00000058 00 00 00 00 ....
|
||||||
|
0000005C 00 00 00 00 ....
|
||||||
|
00000060 00 00 00 00 ....
|
||||||
|
00000064 00 00 00 00 ....
|
||||||
|
00000068 00 00 00 00 ....
|
||||||
|
0000006C 00 00 00 00 ....
|
||||||
|
00000070 00 00 00 00 ....
|
||||||
|
00000074 00 00 00 00 ....
|
||||||
|
00000078 00 00 00 00 ....
|
||||||
|
0000007C 00 00 00 00 ....
|
||||||
|
00000080 00 00 00 00 ....
|
||||||
|
00000084 00 00 00 00 ....
|
||||||
|
00000088 00 00 00 00 ....
|
||||||
|
0000008C 00 00 00 00 ....
|
||||||
|
00000090 00 00 00 00 ....
|
||||||
|
00000094 00 00 00 00 ....
|
||||||
|
00000098 00 00 00 00 ....
|
||||||
|
0000009C 00 00 00 00 ....
|
||||||
|
000000A0 00 00 00 00 ....
|
||||||
|
000000A4 00 00 00 00 ....
|
||||||
|
000000A8 00 00 00 00 ....
|
||||||
|
000000AC 00 00 00 00 ....
|
||||||
|
000000B0 00 00 00 00 ....
|
||||||
|
000000B4 38 00 30 00 8.0.
|
||||||
|
000000B8 00 00 3F 00 ..?.
|
||||||
|
000000BC 32 00 00 00 2...
|
||||||
|
000000C0 00 00 00 00 ....
|
||||||
|
000000C4 00 00 00 00 ....
|
||||||
|
000000C8 00 00 00 00 ....
|
||||||
|
000000CC 00 00 00 00 ....
|
||||||
|
000000D0 00 00 3F 00 ..?.
|
||||||
|
000000D4 32 00 01 00 2...
|
||||||
|
000000D8 00 00 0F 00 ....
|
||||||
|
000000DC 05 00 00 00 ....
|
||||||
|
000000E0 01 00 00 00 ....
|
||||||
|
000000E4 A2 FF 80 00 ....
|
||||||
|
000000E8 17 00 00 00 ....
|
||||||
|
000000EC FF FF FF FF ....
|
||||||
|
000000F0 FF FF FF FF ....
|
||||||
|
000000F4 FF FF FF FF ....
|
||||||
|
000000F8 FF FF FF FF ....
|
||||||
|
000000FC FF FF FF FF ....
|
||||||
|
00000100 FB 00 00 00 .... # It's plausible that per-coord data begins here
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Comparing some values across all maps bundled with the game:
|
||||||
|
|
||||||
|
* `Maps/`
|
||||||
|
* `Chapter10.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map10
|
||||||
|
* `Chapter12.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map12
|
||||||
|
* `Chapter15.MAP`: IsCampaignMap=1 W=0:130 L=0:100 SetName=map15
|
||||||
|
* `Chapter04.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map04
|
||||||
|
* `Chapter08.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map08
|
||||||
|
* `Chapter09.MAP`: IsCampaignMap=1 W=13:117 L=10:90 SetName=map09
|
||||||
|
* `Chapter03.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map03
|
||||||
|
* `Chapter11.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map11
|
||||||
|
* `Chapter13.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map13
|
||||||
|
* `Chapter02.MAP`: IsCampaignMap=1 W=13:117 L=10:90 SetName=map02
|
||||||
|
* `Chapter06.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map06
|
||||||
|
* `Chapter07.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map07
|
||||||
|
* `Chapter14.MAP`: IsCampaignMap=1 W=13:117 L=10:90 SetName=map14
|
||||||
|
* `Chapter01.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map01
|
||||||
|
* `Chapter05.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map05
|
||||||
|
* `MultiMaps/`
|
||||||
|
* `Chapter13_4P.MAP`: IsCampaignMap=0 W=26:104 L=20:80 SetName=map13
|
||||||
|
* `Chapter1_3P.MAP`: IsCampaignMap=0 W=26:104 L=20:80 SetName=map01
|
||||||
|
* `Chapter5_3P.MAP`: IsCampaignMap=0 W=26:104 L=20:80 SetName=map05
|
||||||
|
* `Chapter8_2P.MAP`: IsCampaignMap=0 W=26:104 L=20:80 SetName=map08
|
||||||
|
* `Chapter11_4P.MAP`: IsCampaignMap=0 W=26:104 L=20:80 SetName=map11
|
||||||
|
* `Chapter9_4P.MAP`: IsCampaignMap=0 W=13:117 L=10:90 SetName=map09
|
||||||
|
* `Chapter12_2P.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map12
|
||||||
|
* `Chapter15_2P.MAP`: IsCampaignMap=0 W=0:130 L=0:100 SetName=map15
|
||||||
|
* `Chapter2_4P.MAP`: IsCampaignMap=0 W=13:117 L=10:90 SetName=map02
|
||||||
|
* `Chapter4_2P.MAP`: IsCampaignMap=1 W=26:104 L=20:80 SetName=map04
|
||||||
|
* `Chapter10_2P.MAP`: IsCampaignMap=0 W=26:104 L=20:80 SetName=map10
|
||||||
|
* `Chapter14_4P.MAP`: IsCampaignMap=0 W=13:117 L=10:90 SetName=map14
|
||||||
|
* `Chapter3_2P.MAP`: IsCampaignMap=0 W=26:104 L=20:80 SetName=map03
|
||||||
|
* `Chapter6_2P.MAP`: IsCampaignMap=0 W=26:104 L=20:80 SetName=map06
|
||||||
|
* `Chapter7_2P.MAP`: IsCampaignMap=0 W=26:104 L=20:80 SetName=map07
|
||||||
|
|
||||||
|
## IsCampaignMap
|
||||||
|
|
||||||
|
This is just a theory, but every map that forms part of the single-player
|
||||||
|
campaign has a value of 0x01 for 0x0000 - 0x0003.
|
||||||
|
|
||||||
|
Most of the MP maps and the maps I generate for myself have the value of 0x0
|
||||||
|
instead. Perhaps `Chapter4_2P.MAP` and `Chapter12_2P.MAP` have it set by
|
||||||
|
accident? Or maybe it's another thing entirely.
|
||||||
|
|
||||||
|
TODO: try to trace what WH40K.exe does with this flag, if anything.
|
||||||
|
|
||||||
|
## Width and Length
|
||||||
|
|
||||||
|
Maximum allowed size by WH40K_TD.exe is 130x100. Minimum is 20x20.
|
||||||
|
|
||||||
|
To investigate this, I created maps of different sizes **only**, and observed
|
||||||
|
what differences this made in the putative header:
|
||||||
|
|
||||||
|
| Offset | 20x20 | 20x21 | 21x20 | 21x21 | 100x100 | 130x100 |
|
||||||
|
| ------ | ----- | ----- | ----- | ----- | ------- | ------- |
|
||||||
|
| 0x04 | 0x37 | 0x37 | 0x36 | 0x36 | 0x0F | 0x00 |
|
||||||
|
| 0x08 | 0x28 | 0x27 | 0x28 | 0x27 | 0x00 | 0x00 |
|
||||||
|
| 0x0C | 0x4B | 0x4B | 0x4B | 0x4B | 0x73 | 0x82 |
|
||||||
|
| 0x10 | 0x3C | 0x3C | 0x3C | 0x3C | 0x64 | 0x64 |
|
||||||
|
|
||||||
|
WH40K_TD.exe gives us coordinates for each point on each of these maps:
|
||||||
|
|
||||||
|
| Size | North | East | South | West | 0x04 | 0x08 | 0x0c | 0x10 |
|
||||||
|
| ------- | ----- | ------ | ------ | ----- | ---- | ---- | ---- | ---- |
|
||||||
|
| 20x20 | 55,40 | 74,40 | 74,59 | 55,59 | 55 | 40 | 75 | 60 |
|
||||||
|
| 20x21 | 55,39 | 74,39 | 74,59 | 55,59 | 55 | 39 | 75 | 60 |
|
||||||
|
| 21x20 | 54,40 | 74,40 | 74,59 | 54,59 | 54 | 40 | 75 | 60 |
|
||||||
|
| 100x100 | 15, 0 | 114, 0 | 114,99 | 15,99 | 15 | 0 | 115 | 100 |
|
||||||
|
| 130x100 | 0, 0 | 129, 0 | 129,99 | 0,99 | 0 | 0 | 130 | 100 |
|
||||||
|
|
||||||
|
|
||||||
|
So our valid coordinates range in width from `(*0x04, (*0x0c)-1)`, and for
|
||||||
|
length, from `(*0x08, (*0x10)-1)`
|
||||||
|
|
||||||
|
We're specifying a viewport on a statically-defined area with a width of 130,
|
||||||
|
and a length of 100. The viewport is centered on the middle of that area and
|
||||||
|
anything outside it is clipped away.
|
||||||
|
|
||||||
|
## Per-coordinate data
|
||||||
|
|
||||||
|
All .MAP files are the same size once uncompressed, regardles of width and
|
||||||
|
length parameters, suggesting that they each have fixed-sized records for every
|
||||||
|
possible coordinate, regardless.
|
||||||
|
|
||||||
|
Skipping the header we know about, we have data like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
000000A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
000000B0 00 00 00 00 1F 00 2C 00 00 00 00 00 00 00 00 00 ......,.........
|
||||||
|
000000C0 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
000000D0 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
000000E0 01 00 FC FF F3 FF 1C 00 10 00 00 00 FF FF FF FF ................
|
||||||
|
000000F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
|
||||||
|
00000100 FB 00 00 00 24 FF FF FF 51 02 00 00 00 06 00 FF ....$...Q.......
|
||||||
|
00000110 3F 00 00 00 82 01 00 00 00 00 00 FF 00 00 00 00 ?...............
|
||||||
|
00000120 39 00 00 00 87 01 00 00 00 00 00 FF 00 00 00 00 9...............
|
||||||
|
00000130 38 00 00 00 89 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00000140 38 00 00 00 85 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00000150 38 00 00 00 88 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00000160 38 00 00 00 89 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00000170 38 00 00 00 84 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00000180 38 00 00 00 89 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00000190 38 00 00 00 85 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
000001A0 38 00 00 00 8A 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
000001B0 38 00 00 00 82 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
000001C0 38 00 00 00 8A 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
000001D0 38 00 00 00 83 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
000001E0 38 00 00 00 83 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
000001F0 38 00 00 00 88 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
```
|
||||||
|
|
||||||
|
It would be very neat if the per-coordinate data started at 0x100 and took 16
|
||||||
|
bytes per coordinate.
|
||||||
|
|
||||||
|
Total number of possible coordinates is 100x130x7 = 91,000 = 1,456,000 bytes.
|
||||||
|
|
||||||
|
Uncompressed file size is always 1,458,915 bytes, leaving 2,915 bytes over for
|
||||||
|
header and any trailing data.
|
||||||
|
|
||||||
|
Looking at the data around 0x163890, we see:
|
||||||
|
|
||||||
|
```
|
||||||
|
00163800 38 00 00 00 00 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00163810 38 00 00 00 00 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00163820 38 00 00 00 00 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00163830 38 00 00 00 00 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00163840 38 00 00 00 00 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00163850 38 00 00 00 00 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00163860 38 00 00 00 00 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00163870 38 00 00 00 00 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00163880 38 00 00 00 00 01 00 00 00 00 00 FF 00 00 00 00 8...............
|
||||||
|
00163890 38 00 00 68 00 00 00 50 00 00 00 1A 00 00 00 14 8..h...P........
|
||||||
|
001638A0 00 00 00 3A 00 00 00 00 38 25 00 04 00 00 00 00 ...:....8%......
|
||||||
|
001638B0 00 00 00 1A 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
001638C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
001638D0 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 ................
|
||||||
|
001638E0 00 00 00 32 00 00 00 00 00 00 00 00 00 00 00 00 ...2............
|
||||||
|
001638F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00163900 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00163910 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00163920 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00163930 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00163940 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00163950 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00163960 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
00163970 00 00 00 00 00 00 00 00 00 00 00 00 00 17 4D 61 ..............Ma
|
||||||
|
00163980 6E 69 61 00 00 00 00 00 00 00 00 00 00 00 00 00 nia.............
|
||||||
|
```
|
||||||
|
|
||||||
|
So this looks like a good working theory.
|
||||||
|
|
||||||
|
Wherever they start, these rows must refer to the object sets somehow. We also
|
||||||
|
need to work out how they're arranged.
|
||||||
|
|
||||||
|
## Trailer
|
||||||
|
|
||||||
|
Assuming the theory above is correct, we have trailer data starting at
|
||||||
|
`0x163890`. Browsing through the `Chapter01.MAP` data, I see:
|
||||||
|
|
||||||
|
* Names:
|
||||||
|
* `0x163970`: Mania
|
||||||
|
* Dagon
|
||||||
|
* Nihasa
|
||||||
|
* Samnu
|
||||||
|
* Gigamen
|
||||||
|
* Valefor
|
||||||
|
* Apollyon
|
||||||
|
* Vassago
|
||||||
|
* Diabolus
|
||||||
|
* Asmodee
|
||||||
|
* Gamigin
|
||||||
|
* Beherit
|
||||||
|
* Marbas
|
||||||
|
* Lucifer
|
||||||
|
* Ahpuch
|
||||||
|
* Gorgon
|
||||||
|
* Loki
|
||||||
|
* Lucifer
|
||||||
|
* Mammon
|
||||||
|
* Baphomet
|
||||||
|
* Magot
|
||||||
|
* Belial
|
||||||
|
* Mamon
|
||||||
|
* ...
|
||||||
|
|
||||||
|
So we must have enemy characters placed on the map, although I don't remember
|
||||||
|
Chapter01 having *this many*...
|
||||||
|
|
||||||
|
At 0017C9DF we see the start of scenario text:
|
||||||
|
|
||||||
|
```
|
||||||
|
0017C9A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0017C9B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0017C9C0 00 00 00 02 00 00 00 00 00 00 00 32 00 00 00 01 ...........2....
|
||||||
|
0017C9D0 03 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 59 ...............Y
|
||||||
|
0017C9E0 6F 75 20 68 61 76 65 20 73 70 6F 74 74 65 64 20 ou have spotted
|
||||||
|
0017C9F0 61 6D 6D 75 6E 69 74 69 6F 6E 20 63 72 61 74 65 ammunition crate
|
||||||
|
0017CA00 73 20 77 69 74 68 20 49 6D 70 65 72 69 61 6C 20 s with Imperial
|
||||||
|
0017CA10 6D 61 72 6B 69 6E 67 73 2E 00 00 00 00 00 00 00 markings........
|
||||||
|
0017CA20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
```
|
||||||
|
|
||||||
|
Several records like this.
|
||||||
|
|
||||||
|
Around 001841A0: mission objectives!
|
||||||
|
|
||||||
|
```
|
||||||
|
00184190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
001841A0 00 00 00 00 00 00 4D 69 73 73 69 6F 6E 20 4F 62 ......Mission Ob
|
||||||
|
001841B0 6A 65 63 74 69 76 65 3A 0A 0A 45 6E 74 65 72 20 jective:..Enter
|
||||||
|
001841C0 74 68 65 20 74 65 6D 70 6C 65 20 6F 66 20 74 68 the temple of th
|
||||||
|
001841D0 65 20 43 68 61 6F 73 20 43 75 6C 74 69 73 74 20 e Chaos Cultist
|
||||||
|
001841E0 61 6E 64 20 72 65 74 72 69 65 76 65 20 74 68 65 and retrieve the
|
||||||
|
001841F0 20 72 65 6C 69 63 2E 20 0A 0A 52 65 63 6F 6D 6D relic. ..Recomm
|
||||||
|
00184200 65 6E 64 65 64 20 45 71 75 69 70 6D 65 6E 74 3A ended Equipment:
|
||||||
|
00184210 20 0A 0A 4B 72 61 6B 20 47 72 65 6E 61 64 65 73 ..Krak Grenades
|
||||||
|
00184220 20 0A 0A 41 6E 74 69 2D 50 6C 61 6E 74 20 47 72 ..Anti-Plant Gr
|
||||||
|
00184230 65 6E 61 64 65 73 0A 00 00 00 00 00 00 00 00 00 enades..........
|
||||||
|
00184240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
```
|
||||||
|
|
||||||
|
Since all the files are exactly the same length uncompressed, I'm going to
|
||||||
|
assume these are all a fixed number of fixed-size records when looking into it.
|
Reference in New Issue
Block a user