1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-20 06:05:23 +00:00

data encoding: added COF encoder

This commit is contained in:
M. Sz 2021-01-30 17:09:37 +01:00
parent 374944dfc4
commit 157f110105
4 changed files with 102 additions and 8 deletions

View File

@ -37,3 +37,7 @@ func (i CompositeType) String() string {
} }
return _CompositeType_name[_CompositeType_index[i]:_CompositeType_index[i+1]] return _CompositeType_name[_CompositeType_index[i]:_CompositeType_index[i+1]]
} }
func (i CompositeType) Int() int {
return int(i)
}

View File

@ -35,6 +35,10 @@ const (
// COF is a structure that represents a COF file. // COF is a structure that represents a COF file.
type COF struct { type COF struct {
// unknown bytes for header
unknownHeaderBytes []byte
// unknown bytes (first "body's" bytes)
unknown1 []byte
NumberOfDirections int NumberOfDirections int
FramesPerDirection int FramesPerDirection int
NumberOfLayers int NumberOfLayers int
@ -62,9 +66,19 @@ func Load(fileData []byte) (*COF, error) {
result.NumberOfLayers = int(b[headerNumLayers]) result.NumberOfLayers = int(b[headerNumLayers])
result.FramesPerDirection = int(b[headerFramesPerDir]) result.FramesPerDirection = int(b[headerFramesPerDir])
result.NumberOfDirections = int(b[headerNumDirs]) result.NumberOfDirections = int(b[headerNumDirs])
result.unknownHeaderBytes = b[headerNumDirs+1 : headerSpeed]
result.Speed = int(b[headerSpeed]) result.Speed = int(b[headerSpeed])
streamReader.SkipBytes(3) //nolint:gomnd // Unknown data // read unknown bytes
// previous streamReader.SkipBytes(3)
for i := 0; i < 3; i++ {
b, errSR := streamReader.ReadByte()
if errSR != nil {
return nil, errSR
}
result.unknown1 = append(result.unknown1, b)
}
result.CofLayers = make([]CofLayer, result.NumberOfLayers) result.CofLayers = make([]CofLayer, result.NumberOfLayers)
result.CompositeLayers = make(map[d2enum.CompositeType]int) result.CompositeLayers = make(map[d2enum.CompositeType]int)
@ -83,6 +97,7 @@ func Load(fileData []byte) (*COF, error) {
layer.Transparent = b[layerTransparent] > 0 layer.Transparent = b[layerTransparent] > 0
layer.DrawEffect = d2enum.DrawEffect(b[layerDrawEffect]) layer.DrawEffect = d2enum.DrawEffect(b[layerDrawEffect])
layer.weaponClassByte = b[layerWeaponClass:]
layer.WeaponClass = d2enum.WeaponClassFromString(strings.TrimSpace(strings.ReplaceAll( layer.WeaponClass = d2enum.WeaponClassFromString(strings.TrimSpace(strings.ReplaceAll(
string(b[layerWeaponClass:]), badCharacter, ""))) string(b[layerWeaponClass:]), badCharacter, "")))
@ -124,3 +139,50 @@ func Load(fileData []byte) (*COF, error) {
return result, nil return result, nil
} }
// Unmarshal unmarshals COF into byte slince
func (c *COF) Unmarshal() []byte {
var result []byte
result = append(result, byte(c.NumberOfLayers))
result = append(result, byte(c.FramesPerDirection))
result = append(result, byte(c.NumberOfDirections))
result = append(result, c.unknownHeaderBytes...)
result = append(result, byte(c.Speed))
result = append(result, c.unknown1...)
for i := range c.CofLayers {
result = append(result, byte(c.CofLayers[i].Type.Int()))
result = append(result, c.CofLayers[i].Shadow)
if c.CofLayers[i].Selectable {
result = append(result, byte(1))
} else {
result = append(result, byte(0))
}
if c.CofLayers[i].Transparent {
result = append(result, byte(1))
} else {
result = append(result, byte(0))
}
result = append(result, byte(c.CofLayers[i].DrawEffect))
result = append(result, c.CofLayers[i].weaponClassByte...)
}
for _, i := range c.AnimationFrames {
result = append(result, byte(i))
}
for direction := 0; direction < c.NumberOfDirections; direction++ {
for frame := 0; frame < c.FramesPerDirection; frame++ {
for i := 0; i < c.NumberOfLayers; i++ {
result = append(result, byte(c.Priority[direction][frame][i]))
}
}
}
return result
}

View File

@ -4,10 +4,11 @@ import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
// CofLayer is a structure that represents a single layer in a COF file. // CofLayer is a structure that represents a single layer in a COF file.
type CofLayer struct { type CofLayer struct {
Type d2enum.CompositeType Type d2enum.CompositeType
Shadow byte Shadow byte
Selectable bool Selectable bool
Transparent bool Transparent bool
DrawEffect d2enum.DrawEffect DrawEffect d2enum.DrawEffect
WeaponClass d2enum.WeaponClass WeaponClass d2enum.WeaponClass
weaponClassByte []byte
} }

View File

@ -1,6 +1,9 @@
package d2dcc package d2dcc
import ( import (
//"fmt"
//"os"
"errors" "errors"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
@ -18,6 +21,7 @@ type DCC struct {
Directions []*DCCDirection Directions []*DCCDirection
directionOffsets []int directionOffsets []int
fileData []byte fileData []byte
size int32
} }
// Load loads a DCC file. // Load loads a DCC file.
@ -44,7 +48,8 @@ func Load(fileData []byte) (*DCC, error) {
return nil, errors.New("this value isn't 1. It has to be 1") return nil, errors.New("this value isn't 1. It has to be 1")
} }
bm.GetInt32() // TotalSizeCoded size := bm.GetInt32() // TotalSizeCoded
result.size = size
result.directionOffsets = make([]int, result.NumberOfDirections) result.directionOffsets = make([]int, result.NumberOfDirections)
@ -53,9 +58,31 @@ func Load(fileData []byte) (*DCC, error) {
result.Directions[i] = result.decodeDirection(i) result.Directions[i] = result.decodeDirection(i)
} }
/*fmt.Println(fileData)
fmt.Println("\n\n\n")
fmt.Println(result.Encode())
os.Exit(0)*/
return result, nil return result, nil
} }
func (d *DCC) Encode() []byte {
var result []byte
result = append(result, byte(d.Signature))
result = append(result, byte(d.Version))
result = append(result, byte(d.NumberOfDirections))
result = append(result, byte(d.FramesPerDirection))
result = append(result, 0, 0, 0, 1)
result = append(result, 0, 0, 0, byte(d.size), 84, 4, 0)
for i := 0; i < d.NumberOfDirections; i++ {
result = append(result, byte(d.directionOffsets[i]))
}
return result
}
// decodeDirection decodes and returns the given direction // decodeDirection decodes and returns the given direction
func (d *DCC) decodeDirection(direction int) *DCCDirection { func (d *DCC) decodeDirection(direction int) *DCCDirection {
return CreateDCCDirection(d2datautils.CreateBitMuncher(d.fileData, return CreateDCCDirection(d2datautils.CreateBitMuncher(d.fileData,