More file format musing
This commit is contained in:
@@ -1,18 +1,71 @@
|
||||
# `Anim/WarHammer.ani`
|
||||
|
||||
This turns out to simply be an [`obj`](obj.md#WarHammer.ani) file. However, some
|
||||
other files are implicated in its interpretation:
|
||||
This turns out to simply be an [`obj`](obj.md) file.
|
||||
|
||||
- `Data/AniObDef.dat`
|
||||
The first 1,064 sprites are all of the same Ultramarine, carryng a bolter. There
|
||||
are eight "facing" orientations:
|
||||
|
||||
* North
|
||||
* Northeast
|
||||
* East
|
||||
* Southeast
|
||||
* South
|
||||
* Southwest
|
||||
* West
|
||||
* Northwest
|
||||
|
||||
For each orientation, an action is pictured in a variable number of frames. The
|
||||
final frame for each action appears to be "stationary".
|
||||
|
||||
* Walk (13 frames)
|
||||
* Run (9 frames)
|
||||
* Crouch down (8 frames)
|
||||
* Stand up (8 frames)
|
||||
* Take aim (standing) (6 frames)
|
||||
* Fire (standing) (6 frames)
|
||||
* Relax aim (standing) (6 frames)
|
||||
* Throw grenade (standing) (18 frames)
|
||||
* Take aim (crouched) (5 frames)
|
||||
* Fire (crouched) (5 frames)
|
||||
* Relax aim (crouched) (5 frames)
|
||||
* Throw grenade (crouched) (17 frames)
|
||||
* Draw melee weapon (standing) (10 frames)
|
||||
* Strike down with melee weapon (standing) (8 frames)
|
||||
* Stab with melee weapon (standing) (9 frames)
|
||||
|
||||
Added together and multiplied by 87, that's 1064.
|
||||
|
||||
The next sprite is a walking-north action for an ultramarine with a flamer. The
|
||||
total number of frames for this character is 1120 - 56 additional frames, or 7
|
||||
per orientation. Could be an extra action, or an extra frame per action.
|
||||
|
||||
Also notable is that while the bolter showed muzzle flash in the animation, the
|
||||
flamer only showed a tiny hint of fire. I think the animation for spewing flame
|
||||
is held elsewhere.
|
||||
|
||||
I strongly suspect the actions and the number of frames in each action are
|
||||
configurable. So, what other files are implicated in its interpretation? Here's
|
||||
a few possibilities:
|
||||
|
||||
* `Data/AniObDef.dat`
|
||||
* `Data/Coordinates.dat`
|
||||
* `Data/HasAction.dat`
|
||||
* `Data/VehicDef.dat`
|
||||
* `Data/WeapDef.dat`
|
||||
- `Idx/WarHammer.idx`
|
||||
|
||||
Including comments, the former is 4098 lines, giving approx. 45 lines for each
|
||||
## `Data/AniObDef.dat`
|
||||
|
||||
Including comments, this is 4098 lines, giving approx. 45 lines for each
|
||||
of the ~188 characters in the `ani`. That doesn't seem many, and there's no
|
||||
obvious correspondence between the commented-on names (`SMOKE01`?) and the
|
||||
viewed frames... but then, I've not viewed all the frames.
|
||||
|
||||
Still, I think a focus in `WarHammer.idx` (1,880,078 bytes, binary, so around
|
||||
10KiB per character, in theory) is more reasonable.
|
||||
|
||||
## `Idx/WarHammer.idx`
|
||||
|
||||
`WarHammer.idx` (1,880,078 bytes, binary, so around 10KiB per character, in
|
||||
theory) is more reasonable.
|
||||
|
||||
Here's a list of operations on the file when `WH40K_TD.EXE` is instructed to
|
||||
place an Ultramarine squad:
|
||||
@@ -310,22 +363,15 @@ read(<WarHammer.ani>, "\xbe\xe5\xb6\x09\x0c\x0f\x00\x00", 8) = 8
|
||||
|
||||
</details>
|
||||
|
||||
Notable is that we still load 5 type 2 records, even though there's just a
|
||||
single librarian, and 8 compass points. Why 5?
|
||||
Notable is that we read from `idx` **before** we read from `ani` - so it does
|
||||
seem like the former should tell us where to pull from the latter.
|
||||
|
||||
Also notable is that we read from `idx` **before** we read from `ani`.
|
||||
We still load 5 type 2 records, even though there's just a single librarian, and
|
||||
8 compass points. Why 5? After looking in `idx`, we load 10 sprites from `ani`,
|
||||
which is at least a multiple. Do any of the records we load from `idx` specify
|
||||
sprite directory offsets that match?
|
||||
|
||||
Other data may be loaded at program start, of course. What other files seem
|
||||
relevant?
|
||||
|
||||
* `Data/AniObDef.dat`
|
||||
* `Data/HasAction.dat`
|
||||
* `Data/VehicDef.dat`
|
||||
* `Data/WeapDef.dat`
|
||||
|
||||
These all reference animations in one way or another.
|
||||
|
||||
## `HasAction.dat`
|
||||
## `Data/HasAction.dat`
|
||||
|
||||
This file seems relevant as it says whether or not particular animations exist
|
||||
for the different types of character, which maps directly to what is stored in
|
||||
|
@@ -9,7 +9,7 @@ remake.
|
||||
* [✓] [`Anim/`](obj.md#WarHammer.ani)
|
||||
* [`WarHammer.ani`](obj.md#WarHammer.ani)
|
||||
* [`Assign/`](obj.md#assign)
|
||||
* `*.asn` # Unknown, seems to be related to .obj files
|
||||
* `*.asn` # Specify properties for frames in .obj files
|
||||
* `Cursor/`
|
||||
* `*.ani` # RIFF data, standard ANI format \o/
|
||||
* [`Cursors.cur`](obj.md) # `obj` file containing pointers and drag elements
|
||||
@@ -23,6 +23,7 @@ remake.
|
||||
* **TODO**
|
||||
* `ChaNames.dat` # list of character names
|
||||
* `Coordinates.dat` # Weapon Firing Coordinates
|
||||
* `Credits.dat` # list of credits
|
||||
* `Defs.dat` # defines properties for objects and tiles, each of which seems to have an id
|
||||
* `GDestroy.dat` # table of what destroys what?
|
||||
|
||||
@@ -39,7 +40,6 @@ remake.
|
||||
* `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"
|
||||
@@ -49,11 +49,9 @@ remake.
|
||||
* `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
|
||||
* `Cycle.cyc` # ColorCycle DataFile.
|
||||
* `Encyclopedia.dta` # encyclopedia entries
|
||||
* `KeyMap.dta` # unknown
|
||||
* `Keymap.dta` # unknown
|
||||
* `keymap.dta` # unknown
|
||||
* `USEng.dta` # Localized strings
|
||||
* `EquipmentMenuData` # gzip-compressed, presumably to do with (initial?) squad configuration
|
||||
* `Filters/`
|
||||
@@ -105,7 +103,7 @@ Phew.
|
||||
* *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`!
|
||||
formats and the parsers I'm writing.
|
||||
|
||||
## Cross-links / associations
|
||||
|
||||
|
@@ -6,80 +6,6 @@ be placed on it - a `SURFACE`, `LEFT`, `RIGHT`, and `CENTER`. Maps reference
|
||||
objects in a space-efficient way via sets, which seem to be a kind of object
|
||||
palette.
|
||||
|
||||
## Assign
|
||||
|
||||
The `Assign/` directory contains a matching `.asn` file for each `Obj/*.obj`.
|
||||
It's a plain-text format which seems to assign properties to frames, and has
|
||||
references to a `<name>.flc` file which does not exist in the tree.
|
||||
|
||||
Theory: .obj files were originally generated from `.flc` files. This is an
|
||||
AutoDesk format for visual data, so this suggests the .obj files contain pixels
|
||||
\o/
|
||||
|
||||
`blank.asn` references 6 frames (0-5):
|
||||
|
||||
```
|
||||
# single pixel tile
|
||||
# transpix.obj/.asn
|
||||
#/--> transpix.flc
|
||||
#
|
||||
|
||||
0-5:DEF 1;
|
||||
|
||||
|
||||
0-5:TYPE 13;
|
||||
|
||||
|
||||
END OF FILE
|
||||
```
|
||||
|
||||
`jungtil.asn` references 18 frames (0-17):
|
||||
|
||||
```
|
||||
# jungle floor
|
||||
# jungtil.obj/.asn
|
||||
# /--> d:\warflics\missions\jungtil.flc
|
||||
#
|
||||
|
||||
0:DEF 2;
|
||||
1-11:DEF 454;
|
||||
|
||||
|
||||
#damaged frames!!!!
|
||||
12:DEF 2;
|
||||
13-16:DEF 454;
|
||||
17:DEF 454;
|
||||
|
||||
|
||||
0:TYPE 2;
|
||||
1-11:TYPE 0;
|
||||
12:TYPE 2;
|
||||
13-16:TYPE 0;
|
||||
17:TYPE 0;
|
||||
|
||||
|
||||
0:DESTROY 12;
|
||||
1-3:DESTROY 13;
|
||||
4-6:DESTROY 14;
|
||||
7-9:DESTROY 15;
|
||||
10-11:DESTROY 16;
|
||||
17:DESTROY 15;
|
||||
|
||||
1-11:Dmg1Lnk 17;
|
||||
|
||||
END OF FILE
|
||||
```
|
||||
|
||||
So it seems this visual data can have quite complicated attributes. At a minimum
|
||||
we see:
|
||||
|
||||
* `TYPE`
|
||||
* `DEF`
|
||||
* `DESTROY`
|
||||
* `Dmg1Lnk`
|
||||
|
||||
The `type` field **may** tell us what format each sprite is in.
|
||||
|
||||
## OBJ container structure
|
||||
|
||||
`.obj` files represent visual data. They contain a number of sprites, which are
|
||||
@@ -512,60 +438,144 @@ break *0x41DD10
|
||||
This lets me focus very narrowly on what happens when loading sprites, and
|
||||
might give clues.
|
||||
|
||||
## Assign
|
||||
|
||||
The `Assign/` directory contains a matching `.asn` file for each `Obj/*.obj`.
|
||||
It's a plain-text format which seems to assign properties to frames, and has
|
||||
references to a `<name>.flc` file which does not exist in the tree.
|
||||
|
||||
Theory: .obj files were originally generated from `.flc` files. This is an
|
||||
AutoDesk format for visual data, so this suggests the .obj files contain pixels
|
||||
\o/
|
||||
|
||||
`blank.asn` references 6 frames (0-5):
|
||||
|
||||
```
|
||||
# single pixel tile
|
||||
# transpix.obj/.asn
|
||||
#/--> transpix.flc
|
||||
#
|
||||
|
||||
0-5:DEF 1;
|
||||
|
||||
|
||||
0-5:TYPE 13;
|
||||
|
||||
|
||||
END OF FILE
|
||||
```
|
||||
|
||||
`jungtil.asn` references 18 frames (0-17):
|
||||
|
||||
```
|
||||
# jungle floor
|
||||
# jungtil.obj/.asn
|
||||
# /--> d:\warflics\missions\jungtil.flc
|
||||
#
|
||||
|
||||
0:DEF 2;
|
||||
1-11:DEF 454;
|
||||
|
||||
|
||||
#damaged frames!!!!
|
||||
12:DEF 2;
|
||||
13-16:DEF 454;
|
||||
17:DEF 454;
|
||||
|
||||
|
||||
0:TYPE 2;
|
||||
1-11:TYPE 0;
|
||||
12:TYPE 2;
|
||||
13-16:TYPE 0;
|
||||
17:TYPE 0;
|
||||
|
||||
|
||||
0:DESTROY 12;
|
||||
1-3:DESTROY 13;
|
||||
4-6:DESTROY 14;
|
||||
7-9:DESTROY 15;
|
||||
10-11:DESTROY 16;
|
||||
17:DESTROY 15;
|
||||
|
||||
1-11:Dmg1Lnk 17;
|
||||
|
||||
END OF FILE
|
||||
```
|
||||
|
||||
So it seems this visual data can have quite complicated attributes. We see:
|
||||
|
||||
* `DEF`
|
||||
* `DESTROY`
|
||||
* `Dmg1Lnk`
|
||||
* `MacroLnk`
|
||||
* `TYPE`
|
||||
|
||||
Each command takes the form:
|
||||
|
||||
```
|
||||
<sprite-spec>:<command> <args>;
|
||||
```
|
||||
|
||||
The sprite-spec can either be a single number, or a range of n-m.
|
||||
|
||||
### `DESTROY`
|
||||
|
||||
### `DEF`
|
||||
|
||||
I wonder if this `DEF`ines sprites an object, represented by an integer. In
|
||||
`Data/Defs.dat`, we see sections that `EDIT <integer>`. Perhaps the two point to
|
||||
the same thing?
|
||||
|
||||
`Assign/cabbage.asn` has `DEF 17` and `DEF 20`, covering two ranges of sprites.
|
||||
`Data/Defs.dat` has `EDIT 17 # TREE LEAVES` and `EDIT 20 # NON-CENTERED CENTER
|
||||
BUSHES`.
|
||||
|
||||
`Assign/TZEENTCH.asn` has `DEF 24` and `DEF 25`. `Data/Defs.dat` has `EDIT 24 #
|
||||
SWITCHES & HOSES AS CENTER OBJS...RIGHT` and `EDIT 25 # SWITCHES & HOSES AS
|
||||
CENTER OBJS...LEFT`.
|
||||
|
||||
`Assign/altar.asn` has `DEF 232`, and `Data/Defs.data` has `EDIT 232 # MRS
|
||||
BUILDING PIECES - POOL TABLE`.
|
||||
|
||||
These all seem really close.
|
||||
|
||||
Then we have `EDIT 19 #big rocks` and these instances of `DEF 19;`:
|
||||
|
||||
```
|
||||
Assign/grayroks.asn:5:0-7:DEF 19;
|
||||
Assign/grayroks.asn:9:8-15:DEF 19;
|
||||
Assign/sn_roks.asn:6:0-7:DEF 19;
|
||||
Assign/sn_roks.asn:10:8-15:DEF 19;
|
||||
```
|
||||
|
||||
The sprites for `grayroks` depicts some grey rocks, while `sn_roks` depicts
|
||||
the same, but with snow on them. So this seems correct to me.
|
||||
|
||||
Does each object ID represent a unique thing? Or is it an index for a set of
|
||||
characteristics that may be shared across multiple things? A set could quite
|
||||
easily specify both `grayroks` and `sn_roks` for a map...
|
||||
|
||||
### `Dmg1Lnk`
|
||||
|
||||
This command is fairly easy. It takes a sprite-spec and says "if damage has been
|
||||
sustained and you would normally display these sprites, display this sprite
|
||||
instead". This is particularly obvious for the `cabbage` pair.
|
||||
|
||||
### `MacroLnk`
|
||||
|
||||
### `TYPE`
|
||||
|
||||
|
||||
## WarHammer.ani
|
||||
|
||||
This 400MiB file appears to be a standard object file, it's just very large.
|
||||
The directory contains 188,286 sprites!
|
||||
|
||||
The first 1,064 sprites are all of the same Ultramarine, carryng a bolter. There
|
||||
are eight "facing" orientations:
|
||||
|
||||
* North
|
||||
* Northeast
|
||||
* East
|
||||
* Southeast
|
||||
* South
|
||||
* Southwest
|
||||
* West
|
||||
* Northwest
|
||||
|
||||
For each orientation, an action is pictured in a variable number of frames. The
|
||||
final frame appears to be "stationary".
|
||||
|
||||
* Walk (13 frames)
|
||||
* Run (9 frames)
|
||||
* Crouch down (8 frames)
|
||||
* Stand up (8 frames)
|
||||
* Take aim (standing) (6 frames)
|
||||
* Fire (standing) (6 frames)
|
||||
* Relax aim (standing) (6 frames)
|
||||
* Throw grenade (standing) (18 frames)
|
||||
* Take aim (crouched) (5 frames)
|
||||
* Fire (crouched) (5 frames)
|
||||
* Relax aim (crouched) (5 frames)
|
||||
* Throw grenade (crouched) (17 frames)
|
||||
* Draw melee weapon (standing) (10 frames)
|
||||
* Strike down with melee weapon (standing) (8 frames)
|
||||
* Stab with melee weapon (standing) (9 frames)
|
||||
|
||||
Added together and multiplied by 87, that's 1064.
|
||||
|
||||
The next sprite is a walking-north action for an ultramarine with a flamer. The
|
||||
total number of frames for this character is 1120 - 56 additional frames, or 7
|
||||
per orientation. Could be an extra action, or an extra frame per action.
|
||||
|
||||
Also notable is that while the bolter showed muzzle flash in the animation, the
|
||||
flamer only showed a tiny hint of fire. I think the animation for spewing flame
|
||||
is held elsewhere.
|
||||
|
||||
I strongly suspect the actions and the number of frames in each action are
|
||||
configurable. But where?
|
||||
|
||||
The field at 0x10 in the sprite header is set in `WarHammer.ani`, but not in
|
||||
The field at 0x10 in each sprite header is set in `WarHammer.ani`, but not in
|
||||
the other object files encountered so far. However, it seems to be
|
||||
set statically to the bytes `[212 113 59 1]` for all of them.
|
||||
|
||||
Assuming ~1000 sprites per character, `WarHammer.ani` contains 188 characters.
|
||||
|
||||
Two other files have been implicated in animation - `Data/AniObDefs.dat` and
|
||||
`Idx/WarHammer.idx`. More on those in `ani.md`.
|
||||
`Idx/WarHammer.idx`. More on those in [ani.md](ani.md)
|
||||
|
Reference in New Issue
Block a user