I don't have any screenshots yet, but I've made quite a bit of progress.
I've deconstructed the .ATI files almost completely by analyzing the patterns in the data and I now understand the rules necessary for loading and saving data into the format. This is a big step for modding and level creation.
As a bonus, I think the other formats are very similar, if not exactly the same. If they are the same, then that means that I can create a single library for loading/saving the one type of file and just send it the necessary data. This won't make much of an impact on a final product, it just means that things might be a little easier on any programmers working with this code.Here's a brief summary of how the format works:
-In the beginning of the file, there are 4 bytes of data that are used for identifying the file format. This is nothing new, a lot of different types of files have something like this. In this particular format, the 4 bytes are 0x01 0x61 0x74 0x69, that translates to ati, which makes sense (the 0x01 is not an alphanumeric character).
After this, there is a hierarchy of data blocks. At the start of each block there is some information about the block, the "header". These block headers stumped me for a while because they weren't always the same size, and sometimes the block size was one byte and sometimes it was two bytes.. After a while I figured out that in those special cases, before the block header there was one byte that describes the header type. A header header... Anyway, I identified which bytes corresponded to which types of block headers and got that sorted out.
I'm not sure what all of the data in the block headers mean but here's an overview of the types of block headers I found
-Block header type 0 (Normal block header, no "header header")
--Byte 0: Unknown
--Byte 1: Unknown
--Byte 2: Size of block (in bytes)
--Byte 3: Length of block ID string
-Block header type 1 (header header byte: 0x82 or 0x81)
--Byte 0: Unknown
--Byte 1&2: (16-bit integer): Size of block (in bytes)
--Byte 3: Length of block ID string
-Block header type 2 (header header byte: 0x61)
--Byte 0: Unknown
--Byte 1: Size of block (in bytes)
--Byte 2: Unknown
--Byte 3: Unknown
--Byte 4: Length of block ID string
-Block header type 3 (header header byte: 0xA1)
--Byte 0: Unknown
--Byte 1&2: (16-bit integer): Size of block (in bytes)
--Byte 3: Unknown
--Byte 4: Unknown
--Byte 5: Length of block ID string
Immediately following this information is the block ID string ("ACTOR", "NAVNODE", "ACTOR_VARIABLES", ...), followed by 0x00, or "null".
Immediately following the 0x00 is a block of data with the size stated in the block header.
This block of data can contain more blocks of data like I just described, or a value or values. It could be anything really.
Here's a small example of what an ATI file contains:
+data/levels/u_jcowlishaw/screens/Attract/attract.ati
|+ACTOR Y:\Data\Actors\Widgets\Widget.atr.
| |-ID: 1
| |+Name
| | |-PressStartWidget
| |
| |+POS (x,y,z) (12 bytes, 3 floats)
| | |- 0.0, -15.1498, 0.0
| |
| |+ROT (Euler angles probably) (12 bytes, 3 floats)
| | |- 0.000061, 0.0, 0.0
| |
| |+Scale (x,y,z) (12 bytes, 3 floats)
| | |- 16.0, 2.0, 1.0
| |
| |+ACTOR_VARIABLES
| | |+W_FC
| | | |-0xFF (255)
| | |
| | |+W_TMN
| | | |-0x01 (1)
| | |
| | |+W_YLAY
| | | |-0x01 (1)
| | |
| | |+W_XLAY
| | | |-0x01 (1)
| |
| |+ etc,etc
You get the picture, it's a hierarchy of data.
If you want to see more, here's a partial deconstruction of a couple files:
attract.atr:
http://pastebin.com/rwg9CdK9pod01_03_ttjungle.atr:
http://codepad.org/cinaicfZIf you don't get turned on by information such as this, then just wait for some screenshots to emerge once I integrate my rendering engine and have whole levels to explore. Just a few more days.