More map trailer work
This commit is contained in:
@@ -518,8 +518,6 @@ Around 001841A0: mission objectives!
|
||||
00184240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
```
|
||||
|
||||
The size of the trailer for Chapter01 is 139,483 bytes.
|
||||
|
||||
Relative offsets from the start of the trailer, we have:
|
||||
|
||||
| Offset | Text |
|
||||
@@ -581,30 +579,38 @@ TINYSQUAD.MAP.Trailer
|
||||
0000 0050: 00 00 00 32 00 00 00 00 00 00 00 00 00 00 00 00 ...2.... ........
|
||||
```
|
||||
|
||||
here's a first guess at a header:
|
||||
The size of the trailer for Chapter01 is 139,483 bytes, assuming it starts at
|
||||
`0x163890`. However, things may be a lot more sensible if we drop 3 bytes off
|
||||
the start of that to get the fields into little-endian alignment. Have I made a
|
||||
maths error above somewhere? Is it some sort of alignment thing? Do those 3
|
||||
bytes actually have meaning?
|
||||
|
||||
Ignoring them for now, here's a first guess at a header:
|
||||
|
||||
| Offset | Size | Meaning |
|
||||
| ------ | ---- | ------- |
|
||||
| 0 | 2 | ??? - invariant `38 00` |
|
||||
| 2 | 2 | ??? - varies |
|
||||
| 4 | 4 | ??? - varies |
|
||||
| 8 | 4 | ??? - varies |
|
||||
| 12 | 4 | ??? - varies |
|
||||
| 16 | 4 | Number of character records (58 vs 5) |
|
||||
| 20 | 4 | ??? - invariant `00 00 00 00` |
|
||||
| 0 | 4 | Map maximum X + 1 |
|
||||
| 4 | 4 | Map maximum Y + 1 |
|
||||
| 8 | 4 | Map minimum X |
|
||||
| 12 | 4 | Map minimum Y |
|
||||
| 16 | 4 | Number of character records |
|
||||
| 20 | 4 | Padding? - invariant `00 00 00 00` |
|
||||
| 24 | 2 | ??? - varies. Seems related to character/squad position? |
|
||||
| 26 | 2 | ??? - invariant `00 04` |
|
||||
| 28 | 4 | ??? - varies (0 vs 5) |
|
||||
| 32 | 4 | Number of objective/event records (26 vs 1) |
|
||||
| 36 | 36? | Padding? |
|
||||
| 32 | 4 | Number of thingies (26 vs 1) |
|
||||
| 36 | 20 | Padding? |
|
||||
|
||||
56 bytes of data is interesting because the value of that first, ignored byte is
|
||||
0x38 - perhaps it's a skip value + 2 bytes of padding? It's just weird. Keep
|
||||
ignoring it for now.
|
||||
|
||||
0x4b contains the next non-null byte; is the gap between the the number of
|
||||
objectives, and it, padding? Minus a bit? 0x50 is another non-null byte. Then
|
||||
thingies, and it, padding? Minus a bit? 0x50 is another non-null byte. Then
|
||||
it's all zeroes until one byte before the first name at 0xee.
|
||||
|
||||
It's hard to say where the alignment should be at this point. We need to compare
|
||||
more characters with each other. We might also be able to determine framing by
|
||||
looking at the *end* of the character block.
|
||||
more characters with each other. Other notes...
|
||||
|
||||
Characters are organised into Squads somehow.
|
||||
|
||||
@@ -615,6 +621,18 @@ per-character records also. There are several candidates for this.
|
||||
Placing a single character at (64,49) causes those bytes to show up at four
|
||||
offsets - 0x18 (!), 0x1F4, 0x1F8, and 0x6C8.
|
||||
|
||||
Generating a map with no characters at all, the trailer is 2,447 bytes, and the
|
||||
mission title starts at 0x3B (59). So we can say we have 20 bytes of padding as
|
||||
a first approximation?
|
||||
|
||||
The "trailer trailer", for want of a better term, seems to be organised as:
|
||||
|
||||
| Offset | Size | Meaning |
|
||||
| ----- | ---- | ------- |
|
||||
| 0 | 255 | Title |
|
||||
| 255 | 2048 | Briefing |
|
||||
| 2304 | 85 | ??? - each byte is 1 or 0. Spaced so it may be partly uint32 |
|
||||
|
||||
|
||||
## Soldiers At War
|
||||
|
||||
@@ -695,3 +713,11 @@ xxd -s 0xc0 -c 13 -l 260 -g 13 BIGGESTMAP.MAP
|
||||
000000e7: 00 00 85 01 00 00 00 00 00 ff 00 00 1f .............
|
||||
# ...
|
||||
```
|
||||
|
||||
This can be interpreted more or less the same way as the Chaos Gate maps now,
|
||||
and the `soldiers-at-war` branch contains a hacked-up implementation that kind
|
||||
of works \o/.
|
||||
|
||||
Does the same trailer apply?
|
||||
|
||||
|
||||
|
@@ -48,25 +48,40 @@ type Header struct {
|
||||
// Need to investigate the rest of the header too
|
||||
}
|
||||
|
||||
type Trailer struct {
|
||||
Unknown1 uint16
|
||||
Unknown2 uint16
|
||||
Unknown3 uint32
|
||||
Unknown4 uint32
|
||||
Unknown5 uint32
|
||||
type TrailerHeader struct {
|
||||
Discard1 [3]byte // No idea what this lot is
|
||||
MaxWidth uint32
|
||||
MaxLength uint32
|
||||
MinWidth uint32
|
||||
MinLength uint32
|
||||
|
||||
NumCharacters uint32
|
||||
Padding1 uint32
|
||||
Unknown6 uint16
|
||||
Unknown7 uint16
|
||||
Unknown8 uint32
|
||||
|
||||
Unknown1 uint32
|
||||
Unknown2 uint16
|
||||
Unknown3 uint16
|
||||
Unknown4 uint32
|
||||
NumThingies uint32
|
||||
Padding2 [36]byte
|
||||
Padding1 [20]byte
|
||||
}
|
||||
|
||||
type TrailerTrailer struct {
|
||||
Title [255]byte
|
||||
Briefing [2048]byte
|
||||
Unknown1 [85]uint8 // Maybe? each contains either 0 or 1? Hard to say
|
||||
}
|
||||
|
||||
type Character struct {
|
||||
Unknown1 uint32
|
||||
}
|
||||
|
||||
type Characters []Character
|
||||
|
||||
// TODO. These are triggers/reactors/etc.
|
||||
type Thingy struct {}
|
||||
|
||||
type Thingies []Thingy
|
||||
|
||||
func (h Header) Width() int {
|
||||
return int(h.MaxWidth - h.MinWidth)
|
||||
}
|
||||
@@ -189,7 +204,14 @@ func (h Header) Check() []error {
|
||||
type GameMap struct {
|
||||
Header
|
||||
Cells
|
||||
// TODO: parse this into sections
|
||||
TrailerHeader
|
||||
Characters
|
||||
Thingies
|
||||
TrailerTrailer
|
||||
|
||||
// TODO: parse this into sections. This is the text that comes from the
|
||||
// .TXT file. Maybe we don't need it at all since it should be duplicated in
|
||||
// the trailer.
|
||||
Text string
|
||||
}
|
||||
|
||||
@@ -305,5 +327,37 @@ func loadMapFile(filename string) (*GameMap, error) {
|
||||
return nil, fmt.Errorf("Error parsing cells for %s: %v", filename, err)
|
||||
}
|
||||
|
||||
if err := binary.Read(zr, binary.LittleEndian, &out.TrailerHeader); err != nil {
|
||||
return nil, fmt.Errorf("Error parsing trailer header for %s: %v", filename, err)
|
||||
}
|
||||
|
||||
log.Printf("Trailer Header: %#+v", out.TrailerHeader)
|
||||
/*
|
||||
// TODO: until we know how large each character record should be, we can't read this lot
|
||||
|
||||
out.Characters = make(Characters, int(out.TrailerHeader.NumCharacters))
|
||||
if err := binary.Read(zr, binary.LittleEndian, &out.Characters); err != nil {
|
||||
return nil, fmt.Errorf("Error parsing characters for %s: %v", filename, err)
|
||||
}
|
||||
|
||||
out.Thingies = make(Thingies, int(out.TrailerHeader.NumThingies))
|
||||
if err := binary.Read(zr, binary.LittleEndian, &out.Thingies); err != nil {
|
||||
return nil, fmt.Errorf("Error parsing thingies for %s: %v", filename, err)
|
||||
}
|
||||
|
||||
if err := binary.Read(zr, binary.LittleEndian, &out.TrailerTrailer); err != nil {
|
||||
return nil, fmt.Errorf("Error parsing trailer trailer for %s: %v", filename, err)
|
||||
}
|
||||
log.Printf("Trailer Trailer: %s", out.TrailerTrailer.String())
|
||||
*/
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (t *TrailerTrailer) String() string {
|
||||
return fmt.Sprintf(
|
||||
"title=%q briefing=%q rest=%#+v",
|
||||
strings.TrimRight(string(t.Title[:]), "\x00"),
|
||||
strings.TrimRight(string(t.Briefing[:]), "\x00"),
|
||||
t.Unknown1,
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user