mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-20 23:47:16 -05:00
anim data encoder + unit test for encoding
This commit is contained in:
parent
00e26fb862
commit
e039c8ee70
@ -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()
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user