diff --git a/README.md b/README.md index b1e423e..1295b58 100644 --- a/README.md +++ b/README.md @@ -184,3 +184,10 @@ $ ./scripts/convert-wav ./orig/Wav As with video playback, the ambition is to *eventually* remove this dependency and operate on the unmodified files instead. + +## Resources + +Here's a collection of links that I'm finding useful or otherwise interesting, +and don't want to lose track of... + +* [Historical geocities modders](http://www.oocities.org/timessquare/galaxy/6777/) diff --git a/cmd/loader/main.go b/cmd/loader/main.go index 4a938a4..6000b54 100644 --- a/cmd/loader/main.go +++ b/cmd/loader/main.go @@ -221,5 +221,8 @@ func loadIdx(idxPath string) { for i, group := range idx.Groups { log.Printf("Group %2d: %4d records, start sprite is %6d", i, len(group.Records), group.Spec.SpriteIdx) + for i, rec := range group.Records { + log.Printf("\t%3d: %#+v", i, rec) + } } } diff --git a/doc/formats/maps.md b/doc/formats/maps.md index 66b255e..474f313 100644 --- a/doc/formats/maps.md +++ b/doc/formats/maps.md @@ -610,11 +610,6 @@ ignoring it for now. 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. Other notes... - -Characters are organised into Squads somehow. - Individual cells seem to have a flag to say "We have a character in us", but not the number for the character themselves, so the coordinates must be in the per-character records also. There are several candidates for this. @@ -645,8 +640,10 @@ suggested above: | 267 | 1 | Unknown | | 268 | 1 | Health | | 269 | 495 | ??? | -| 764 | 1(?) | Squad number? | -| 765 | 927 | ??? | +| 764 | 1(?) | Squad number | +| 765 | 895 | ??? | +| 1660 | 1? | Orientation? Could also be `0x680`... | +| 1661 | 31 | ??? | There's still a lot of bytes to dig through, but this allows me to load the character names from Chapter01 correctly, with the exception of record 57 which @@ -654,10 +651,13 @@ just contains `\x02` and is then null-terminated all the way through - but maybe that's just a data thing. How about their types? `HasAction.dat` lists numbers for character types, and -those show up immediately before the name. going from the character type to the -animation group is not yet fully deciphered - captains mess up a direct +those show up immediately before the name. Going from the character type to the +animation group is not yet fully deciphered - squad leaders mess up a direct correlation - but a fixed offset table allows me to draw the characters \o/. -Orientation is not yet deciphered, however. + +Putting 8 characters onto a map and orienting them in the compass points, we see +numbers ranging from 0 to 7 at 0x67c and 0x680. Assuming this is the scheme +used, north is value 1, northeast value 2, and northwest value 0. Given two characters of the same type, just in different locations, differing values are seen at: diff --git a/internal/assetstore/ani.go b/internal/assetstore/ani.go index 89ddf6c..135a03b 100644 --- a/internal/assetstore/ani.go +++ b/internal/assetstore/ani.go @@ -49,24 +49,37 @@ func (a *AssetStore) AnimationsObject() (*Object, error) { return obj, nil } -func (a *AssetStore) Animation(groupIdx, recIdx int) (*Animation, error) { - idx, err := a.AnimationsIndex() +func (a *AssetStore) Animation(groupIdx int, recId int, compass int) (*Animation, error) { + realIdx, err := a.AnimationsIndex() if err != nil { return nil, err } + // FIXME: are we using the right value if we need to make this change? + if compass == 0 { + compass = 8 + } + obj, err := a.AnimationsObject() if err != nil { return nil, err } - group := idx.Groups[groupIdx] + group := realIdx.Groups[groupIdx] if group.Spec.Count == 0 { return &Animation{}, nil } - // rec := group.Records[recIdx] - det := group.Details[recIdx] + var det *idx.Detail + for i, rec := range group.Records { + if /*int(rec.ActionID) == int(action) && */ int(rec.Compass) == compass { + det = &group.Details[i] + } + } + + if det == nil { + return nil, fmt.Errorf("Couldn't find anim (%v %v %v)", groupIdx, recId, compass) + } first := int(group.Spec.SpriteIdx) + int(det.FirstSprite) last := int(group.Spec.SpriteIdx) + int(det.LastSprite) @@ -80,7 +93,7 @@ func (a *AssetStore) Animation(groupIdx, recIdx int) (*Animation, error) { return &Animation{Frames: sprites}, nil } -func (a *AssetStore) CharacterAnimation(ctype data.CharacterType, action data.AnimAction) (*Animation, error) { +func (a *AssetStore) CharacterAnimation(ctype data.CharacterType, action data.AnimAction, compass int) (*Animation, error) { ha, err := a.HasAction() if err != nil { return nil, err @@ -122,7 +135,5 @@ func (a *AssetStore) CharacterAnimation(ctype data.CharacterType, action data.An return nil, fmt.Errorf("Unknown character type: %s", ctype) } - rec := ha.Index(ctype, action) - - return a.Animation(group, rec) + return a.Animation(group, int(action), compass) } diff --git a/internal/assetstore/map.go b/internal/assetstore/map.go index 32448f3..5fb2862 100644 --- a/internal/assetstore/map.go +++ b/internal/assetstore/map.go @@ -103,8 +103,8 @@ func (m *Map) SpritesForCell(x, y, z int) ([]*Sprite, error) { sprites = append(sprites, sprite) } if chr := m.CharacterAt(x, y, z); chr != nil { - // Look up the correct animation, get the frame, boom - anim, err := m.assets.CharacterAnimation(chr.Type, data.AnimActionNone) + // Look up the correct animation, get the frame, boom shakalaka + anim, err := m.assets.CharacterAnimation(chr.Type, data.AnimActionNone, int(chr.Orientation)) if err != nil { return nil, err } diff --git a/internal/maps/maps.go b/internal/maps/maps.go index cbb5891..dc965bc 100644 --- a/internal/maps/maps.go +++ b/internal/maps/maps.go @@ -124,7 +124,9 @@ type Character struct { XPos int `struc:"byte"` Unknown7 []byte `struc:"[317]byte"` SquadNumber byte `struc:"byte"` - Unknown8 []byte `struc:"[927]byte"` + Unknown8 []byte `struc:"[895]byte"` + Orientation byte `struc:"byte"` + Unknown9 []byte `struc:"[31]byte"` // TODO: each character may have a fixed number of subrecords for inventory }