1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-10-01 15:46:17 -04:00

anim data encoder + unit test for encoding

This commit is contained in:
M. Sz 2021-02-26 14:57:55 +01:00
parent 00e26fb862
commit e039c8ee70
2 changed files with 178 additions and 1 deletions

View File

@ -147,8 +147,85 @@ func Load(data []byte) (*AnimationData, error) {
}
if reader.Position() != uint64(len(data)) {
return nil, errors.New("unable to parse animation data")
return nil, fmt.Errorf("unable to parse animation data: %d != %d", reader.Position(), len(data))
}
return animdata, nil
}
// Marshal encodes animation data back into byte slice
// basing on AnimationData.records
func (ad *AnimationData) Marshal() []byte {
sw := d2datautils.CreateStreamWriter()
// keys - all entries in animationData
keys := make([]string, len(ad.entries))
// we must manually add index
idx := 0
for i := range ad.entries {
keys[idx] = i
idx++
}
// name terminates current name
name := 0
// recordIdx determinates current record index
recordIdx := 0
// numberOfEntries is a number of entries in all map indexes
var numberOfEntries int = 0
for i := 0; i < len(keys); i++ {
numberOfEntries += len(ad.entries[keys[i]])
}
for idx := 0; idx < numBlocks; idx++ {
// number of records (max is maxRecordsPerObject)
l := 0
// first condition: end up with all this and push 0 to dhe end
if numberOfEntries == 0 {
sw.PushUint32(0)
continue
// second condition - if number of entries left is smaller than
// maxRecordsPerBlock, push...
} else if numberOfEntries < maxRecordsPerBlock {
l = int(numberOfEntries)
sw.PushUint32(uint32(l))
} else {
// else use maxRecordsPerBlock
l = maxRecordsPerBlock
sw.PushUint32(maxRecordsPerBlock)
}
for currentRecordIdx := 0; currentRecordIdx < l; currentRecordIdx++ {
numberOfEntries--
if recordIdx == len(ad.entries[keys[name]]) {
recordIdx = 0
name++
}
animationRecord := ad.entries[keys[name]][recordIdx]
recordIdx++
name := animationRecord.name
missingZeroBytes := byteCountName - len(name)
fmt.Println(name)
sw.PushBytes([]byte(name)...)
for i := 0; i < missingZeroBytes; i++ {
sw.PushBytes(0)
}
sw.PushUint32(animationRecord.framesPerDirection)
sw.PushUint16(animationRecord.speed)
for i := 0; i < byteCountSpeedPadding; i++ {
sw.PushBytes(0)
}
for event := 0; event < numEvents; event++ {
sw.PushBytes(byte(animationRecord.events[event]))
}
}
}
return sw.GetBytes()
}

View File

@ -1,11 +1,57 @@
package d2animdata
import (
"fmt"
"log"
"os"
"testing"
)
func exampleData() *AnimationData {
testEntries := []*AnimationDataRecord{
&AnimationDataRecord{
"TST",
5, 8,
map[int]AnimationEvent{
1: AnimationEventNone,
},
},
&AnimationDataRecord{
"TST",
8, 3,
map[int]AnimationEvent{
2: AnimationEventNone,
},
},
}
testEntries2 := []*AnimationDataRecord{
&AnimationDataRecord{
"TTT",
7, 8,
map[int]AnimationEvent{
1: AnimationEventNone,
},
},
&AnimationDataRecord{
"TTT",
8, 9,
map[int]AnimationEvent{
8: AnimationEventNone,
},
},
}
result := &AnimationData{
entries: map[string][]*AnimationDataRecord{
"TST": testEntries,
"TTT": testEntries2,
},
}
return result
}
func TestLoad(t *testing.T) {
testFile, fileErr := os.Open("testdata/AnimData.d2")
if fileErr != nil {
@ -154,3 +200,57 @@ func TestAnimationDataRecord_FPS(t *testing.T) {
t.Error("incorrect fps")
}
}
func TestAnimationDataRecord_Marshal(t *testing.T) {
file, fileErr := os.Open("testdata/AnimData.d2")
if fileErr != nil {
t.Error("cannot open test data file")
return
}
data := make([]byte, 0)
buf := make([]byte, 16)
for {
numRead, err := file.Read(buf)
data = append(data, buf[:numRead]...)
if err != nil {
break
}
}
ad, err := Load(data)
if err != nil {
t.Error(err)
}
newData := ad.Marshal()
newAd, err := Load(newData)
if err != nil {
t.Error(err)
}
keys1 := make([]string, 0)
for i := range ad.entries {
keys1 = append(keys1, i)
}
keys2 := make([]string, 0)
for i := range newAd.entries {
keys2 = append(keys2, i)
}
if len(keys1) != len(keys2) {
t.Fatalf("unexpected length of keys in first and second dict: %d, %d", len(keys1), len(keys2))
}
fmt.Println(len(ad.entries["TST"]))
for key := range newAd.entries {
for n, i := range newAd.entries[key] {
fmt.Println(i.speed, ad.entries[key][n].speed)
if i.speed != ad.entries[key][n].speed {
t.Fatal("unexpected record set")
}
}
}
}