# Obj format information

The names of Obj files are highly suggestive of them being objects that can be
placed on [maps](map.md). Each map cell seems to have space for four objects to
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
assigned attributes in `.asn` files and referenced from `.map` files.

The container format is worked out, but the per-sprite data is still unknown, so
I'm documenting the former here while still investigating the latter.

The file begins with a header, with all values 32-bit little-endians:

| Offset | Meaning |
| ------ | ------- |
| 0x0000 | Number of sprites          |
| 0x0004 | Offset of sprite directory |
| 0x0008 | Size of sprite directory   |
| 0x000c | Offset of the sprite data  |
| 0x0010 | Size of the sprite data    | 

The sprite directory contains an 8-byte record per sprite. That record contains
two 32-bit little-endians:

| Offset | Meaning |
| ------ | ------- |
| 0x0000 | Relative offset of sprite in data block |
| 0x0004 | Size of sprite in data block |

For sanity checks, we can ensure that:

* The header, sprite directory and data blocks do not overlap or extend past the
  end of the file
* None of the individual sprites overlap each other or extend past the end of
  the data block

## Sprite structure

If the `type` field of an `.asn` field *does* tell us how to interpret sprite
data, I'll need to split this up per type. For now, I'm investigating a small
number of files in depth, and comparing across files in a shallow manner, so all
I need to do is manually select sets with the same type in the latter case.

First, the `blank.obj` file. `blank.asn` helpfully tells us that it's a single-
pixel tile and assigns it a type of 13. There are six sprites, all of which are
identical. Data dump:

```
-------------------------------------------------------------------------------
        0  1  2  3  4  5  6  7       01234567     0   1   2   3   4   5   6   7
-------------------------------------------------------------------------------
0x0000 10 01 61 01 01 00 01 00     |   a      |  16   1  97   1   1   0   1   0
0x0008 00 00 00 00 03 00 00 00     |          |   0   0   0   0   3   0   0   0
0x0010 00 00 00 00 00 00 00 00     |          |   0   0   0   0   0   0   0   0
0x0018 01 fd 00                    |          |   1 253   0
```

Total size is 27 bytes, so if there *is* only one pixel, it's tempting to
suggest that the first 24 bytes are header, and the final 3 bytes represent that
one pixel.

I think this is rendered as a 1px dot with the colour `#ff00ff` in WH40K_TD.exe:

![blank.obj as rendered by WH40K_TD.exe](img/blank.obj.png)

In the 64x64 tile, the dot is in the very centre.

The colour itself doesn't show up in the data directly, so it's not a simple RGB
array of pixels. WH40K_TD.exe is a 16-bit-colour application and may use a
palette, but these factoids don't help me make immediate sense of the data. If
there's a palette in the first 24 bytes, it's not obvious.

There are 45 `TYPE 13` .obj files in the game. Comparing the above with the
start of the second sprite in `pillar.obj`:

```
----------------------------------------------
        0  1  2  3  4  5  6  7       01234567
----------------------------------------------
0x0000 fa 00 25 01 2e 00 48 00     |       H  | 250   0  37   1  46   0  72   0 
0x0008 00 00 00 00 f4 0c 00 00     |          |   0   0   0   0 244  12   0   0 
0x0010 00 00 00 00 00 00 00 00     |          |   0   0   0   0   0   0   0   0 
0x0018 80 0f 90 1a 4b 1a 1b 4b     |     K  K | 128  15 144  26  75  26  27  75 
0x0020 1a 4c 1a 4b 19 19 49 19     |  L K  I  |  26  76  26  75  25  25  73  25 
0x0028 4a 18 4a 80 0f 00 80 0b     | J J      |  74  24  74 128  15   0 128  11 
0x0030 98 1a 4c 1a 4c 1a 9e 1a     |   L L    | 152  26  76  26  76  26 158  26 
0x0038 4c 1b 4b 1a 1a 49 19 48     | L K  I H |  76  27  75  26  26  73  25  72 
0x0040 18 18 48 19 4b 19 4b 19     |   H K K  |  24  24  72  25  75  25  75  25 
0x0048 9d 80 0b 00 80 08 9e 1a     |          | 157 128  11   0 128   8 158  26 
0x0050 4a 1a 1b 4d 9e 1a 4c 1b     | J  M  L  |  74  26  27  77 158  26  76  27 
0x0058 1b 4c 1b 4c 1a 1a 49 18     |  L L  I  |  27  76  27  76  26  26  73  24 
0x0060 48 17 49 18 19 4a 19 4b     | H I  J K |  72  23  73  24  25  74  25  75 
0x0068 19 9d 4a 1a 49 80 08 00     |   J I    |  25 157  74  26  73 128   8   0 
0x0070 80 07 a0 19 4b 1a 1b 4c     |     K  L | 128   7 160  25  75  26  27  76 
0x0078 1b 1b 4d 9e 1b 4c 1b 4d     |   M  L M |  27  27  77 158  27  76  27  77 
```

The first 24 bytes look quite different to the remainder of this file, lending
weight to the 24-byte header theory.


