mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-06-23 15:45:24 +00:00
ds1 encoder: fixed bug, when decoded and encoded back data wasn't the same = records' encoding methods was rewritten to use streamWriter.Pushbit
This commit is contained in:
parent
3dafb3ebcd
commit
5702d96cac
|
@ -4,7 +4,9 @@ import "bytes"
|
||||||
|
|
||||||
// StreamWriter allows you to create a byte array by streaming in writes of various sizes
|
// StreamWriter allows you to create a byte array by streaming in writes of various sizes
|
||||||
type StreamWriter struct {
|
type StreamWriter struct {
|
||||||
data *bytes.Buffer
|
data *bytes.Buffer
|
||||||
|
bitOffset int
|
||||||
|
bitCache byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateStreamWriter creates a new StreamWriter instance
|
// CreateStreamWriter creates a new StreamWriter instance
|
||||||
|
@ -28,6 +30,64 @@ func (v *StreamWriter) PushBytes(b ...byte) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *StreamWriter) PushBit(b bool) {
|
||||||
|
if b {
|
||||||
|
v.bitCache |= (1 << v.bitOffset)
|
||||||
|
}
|
||||||
|
v.bitOffset++
|
||||||
|
|
||||||
|
if v.bitOffset != bitsPerByte {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v.PushBytes(v.bitCache)
|
||||||
|
v.bitCache = 0
|
||||||
|
v.bitOffset = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *StreamWriter) PushBits(b byte, bits int) {
|
||||||
|
val := b
|
||||||
|
for i := 0; i < bits; i++ {
|
||||||
|
if val&1 == 1 {
|
||||||
|
v.PushBit(true)
|
||||||
|
} else {
|
||||||
|
v.PushBit(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
val >>= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *StreamWriter) PushBits16(b uint16, bits int) {
|
||||||
|
val := b
|
||||||
|
for i := 0; i < bits; i++ {
|
||||||
|
if val&1 == 1 {
|
||||||
|
v.PushBit(true)
|
||||||
|
} else {
|
||||||
|
v.PushBit(false)
|
||||||
|
}
|
||||||
|
val >>= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *StreamWriter) PushBits32(b uint32, bits int) {
|
||||||
|
val := b
|
||||||
|
for i := 0; i < bits; i++ {
|
||||||
|
if val&1 == 1 {
|
||||||
|
v.PushBit(true)
|
||||||
|
} else {
|
||||||
|
v.PushBit(false)
|
||||||
|
}
|
||||||
|
val >>= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *StreamWriter) ForcePushBits() {
|
||||||
|
for i := 0; i < bitsPerByte-v.bitOffset; i++ {
|
||||||
|
v.PushBit(0 != 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// PushInt16 writes a int16 word to the stream
|
// PushInt16 writes a int16 word to the stream
|
||||||
func (v *StreamWriter) PushInt16(val int16) {
|
func (v *StreamWriter) PushInt16(val int16) {
|
||||||
v.PushUint16(uint16(val))
|
v.PushUint16(uint16(val))
|
||||||
|
|
|
@ -534,23 +534,23 @@ func (ds1 *DS1) Marshal() []byte {
|
||||||
switch layerStreamType {
|
switch layerStreamType {
|
||||||
case d2enum.LayerStreamWall1, d2enum.LayerStreamWall2, d2enum.LayerStreamWall3, d2enum.LayerStreamWall4:
|
case d2enum.LayerStreamWall1, d2enum.LayerStreamWall2, d2enum.LayerStreamWall3, d2enum.LayerStreamWall4:
|
||||||
wallIndex := int(layerStreamType) - int(d2enum.LayerStreamWall1)
|
wallIndex := int(layerStreamType) - int(d2enum.LayerStreamWall1)
|
||||||
dw = ds1.Tiles[y][x].Walls[wallIndex].Encode()
|
ds1.Tiles[y][x].Walls[wallIndex].Encode(sw)
|
||||||
case d2enum.LayerStreamOrientation1, d2enum.LayerStreamOrientation2,
|
case d2enum.LayerStreamOrientation1, d2enum.LayerStreamOrientation2,
|
||||||
d2enum.LayerStreamOrientation3, d2enum.LayerStreamOrientation4:
|
d2enum.LayerStreamOrientation3, d2enum.LayerStreamOrientation4:
|
||||||
wallIndex := int(layerStreamType) - int(d2enum.LayerStreamOrientation1)
|
wallIndex := int(layerStreamType) - int(d2enum.LayerStreamOrientation1)
|
||||||
dw |= uint32(ds1.Tiles[y][x].Walls[wallIndex].Type)
|
dw |= uint32(ds1.Tiles[y][x].Walls[wallIndex].Type)
|
||||||
dw |= (uint32(ds1.Tiles[y][x].Walls[wallIndex].Zero) & 0xFFFFFF00) << 8 //nolint:gomnd // Bitmask
|
dw |= (uint32(ds1.Tiles[y][x].Walls[wallIndex].Zero) & 0xFFFFFF00) << 8 //nolint:gomnd // Bitmask
|
||||||
|
|
||||||
|
sw.PushUint32(dw)
|
||||||
case d2enum.LayerStreamFloor1, d2enum.LayerStreamFloor2:
|
case d2enum.LayerStreamFloor1, d2enum.LayerStreamFloor2:
|
||||||
floorIndex := int(layerStreamType) - int(d2enum.LayerStreamFloor1)
|
floorIndex := int(layerStreamType) - int(d2enum.LayerStreamFloor1)
|
||||||
dw = ds1.Tiles[y][x].Floors[floorIndex].Encode()
|
ds1.Tiles[y][x].Floors[floorIndex].Encode(sw)
|
||||||
case d2enum.LayerStreamShadow:
|
case d2enum.LayerStreamShadow:
|
||||||
dw = ds1.Tiles[y][x].Shadows[0].Encode()
|
ds1.Tiles[y][x].Shadows[0].Encode(sw)
|
||||||
case d2enum.LayerStreamSubstitute:
|
case d2enum.LayerStreamSubstitute:
|
||||||
dw = ds1.Tiles[y][x].Substitutions[0].Unknown
|
sw.PushUint32(ds1.Tiles[y][x].Substitutions[0].Unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.PushUint32(dw)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package d2ds1
|
package d2ds1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
|
||||||
|
)
|
||||||
|
|
||||||
// FloorShadowRecord represents a floor or shadow record in a DS1 file.
|
// FloorShadowRecord represents a floor or shadow record in a DS1 file.
|
||||||
type FloorShadowRecord struct {
|
type FloorShadowRecord struct {
|
||||||
Prop1 byte
|
Prop1 byte
|
||||||
|
@ -28,14 +32,12 @@ func (f *FloorShadowRecord) Decode(dw uint32) {
|
||||||
f.hidden = byte((dw & 0x80000000) >> 31) //nolint:gomnd // Bitmask
|
f.hidden = byte((dw & 0x80000000) >> 31) //nolint:gomnd // Bitmask
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode encodes floor-shadow record
|
// Encode adds Floor's bits to stream writter given
|
||||||
func (f *FloorShadowRecord) Encode() (dw uint32) {
|
func (f *FloorShadowRecord) Encode(sw *d2datautils.StreamWriter) {
|
||||||
dw |= uint32(f.Prop1) & 0xFF //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(f.Prop1), 8)
|
||||||
dw |= (uint32(f.Sequence) & 0x3F) << 8 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(f.Sequence), 6)
|
||||||
dw |= (uint32(f.Unknown1) & 0xFC) << 14 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(f.Unknown1), 6)
|
||||||
dw |= (uint32(f.Style) & 0x3F) << 20 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(f.Style), 6)
|
||||||
dw |= (uint32(f.Unknown2) & 0x7C) << 26 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(f.Unknown2), 5)
|
||||||
dw |= (uint32(f.hidden) & 0x01) << 31 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(f.hidden), 1)
|
||||||
|
|
||||||
return dw
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package d2ds1
|
package d2ds1
|
||||||
|
|
||||||
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
import (
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
|
)
|
||||||
|
|
||||||
// WallRecord represents a wall record.
|
// WallRecord represents a wall record.
|
||||||
type WallRecord struct {
|
type WallRecord struct {
|
||||||
|
@ -21,16 +24,14 @@ func (w *WallRecord) Hidden() bool {
|
||||||
return w.hidden > 0
|
return w.hidden > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode encodes wall record
|
// Encode adds wall's record's bytes into stream writer given
|
||||||
func (w *WallRecord) Encode() (dw uint32) {
|
func (w *WallRecord) Encode(sw *d2datautils.StreamWriter) {
|
||||||
dw |= uint32(w.Prop1) & 0xFF //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(w.Prop1), 8)
|
||||||
dw |= (uint32(w.Sequence) & 0x3F) << 8 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(w.Sequence), 6)
|
||||||
dw |= (uint32(w.Unknown1) & 0xFC) << 14 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(w.Unknown1), 6)
|
||||||
dw |= (uint32(w.Style) & 0x3F) << 20 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(w.Style), 6)
|
||||||
dw |= (uint32(w.Unknown2) & 0x7C) << 26 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(w.Unknown2), 5)
|
||||||
dw |= (uint32(w.hidden) & 0x01) << 31 //nolint:gomnd // Bitmask
|
sw.PushBits32(uint32(w.hidden), 1)
|
||||||
|
|
||||||
return dw
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes wall record
|
// Decode decodes wall record
|
||||||
|
|
Loading…
Reference in New Issue
Block a user