mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-03 07:07:25 -05: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
|
||||
type StreamWriter struct {
|
||||
data *bytes.Buffer
|
||||
data *bytes.Buffer
|
||||
bitOffset int
|
||||
bitCache byte
|
||||
}
|
||||
|
||||
// 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
|
||||
func (v *StreamWriter) PushInt16(val int16) {
|
||||
v.PushUint16(uint16(val))
|
||||
|
@ -534,23 +534,23 @@ func (ds1 *DS1) Marshal() []byte {
|
||||
switch layerStreamType {
|
||||
case d2enum.LayerStreamWall1, d2enum.LayerStreamWall2, d2enum.LayerStreamWall3, d2enum.LayerStreamWall4:
|
||||
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,
|
||||
d2enum.LayerStreamOrientation3, d2enum.LayerStreamOrientation4:
|
||||
wallIndex := int(layerStreamType) - int(d2enum.LayerStreamOrientation1)
|
||||
dw |= uint32(ds1.Tiles[y][x].Walls[wallIndex].Type)
|
||||
dw |= (uint32(ds1.Tiles[y][x].Walls[wallIndex].Zero) & 0xFFFFFF00) << 8 //nolint:gomnd // Bitmask
|
||||
|
||||
sw.PushUint32(dw)
|
||||
case d2enum.LayerStreamFloor1, d2enum.LayerStreamFloor2:
|
||||
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:
|
||||
dw = ds1.Tiles[y][x].Shadows[0].Encode()
|
||||
ds1.Tiles[y][x].Shadows[0].Encode(sw)
|
||||
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
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
|
||||
)
|
||||
|
||||
// FloorShadowRecord represents a floor or shadow record in a DS1 file.
|
||||
type FloorShadowRecord struct {
|
||||
Prop1 byte
|
||||
@ -28,14 +32,12 @@ func (f *FloorShadowRecord) Decode(dw uint32) {
|
||||
f.hidden = byte((dw & 0x80000000) >> 31) //nolint:gomnd // Bitmask
|
||||
}
|
||||
|
||||
// Encode encodes floor-shadow record
|
||||
func (f *FloorShadowRecord) Encode() (dw uint32) {
|
||||
dw |= uint32(f.Prop1) & 0xFF //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(f.Sequence) & 0x3F) << 8 //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(f.Unknown1) & 0xFC) << 14 //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(f.Style) & 0x3F) << 20 //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(f.Unknown2) & 0x7C) << 26 //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(f.hidden) & 0x01) << 31 //nolint:gomnd // Bitmask
|
||||
|
||||
return dw
|
||||
// Encode adds Floor's bits to stream writter given
|
||||
func (f *FloorShadowRecord) Encode(sw *d2datautils.StreamWriter) {
|
||||
sw.PushBits32(uint32(f.Prop1), 8)
|
||||
sw.PushBits32(uint32(f.Sequence), 6)
|
||||
sw.PushBits32(uint32(f.Unknown1), 6)
|
||||
sw.PushBits32(uint32(f.Style), 6)
|
||||
sw.PushBits32(uint32(f.Unknown2), 5)
|
||||
sw.PushBits32(uint32(f.hidden), 1)
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
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.
|
||||
type WallRecord struct {
|
||||
@ -21,16 +24,14 @@ func (w *WallRecord) Hidden() bool {
|
||||
return w.hidden > 0
|
||||
}
|
||||
|
||||
// Encode encodes wall record
|
||||
func (w *WallRecord) Encode() (dw uint32) {
|
||||
dw |= uint32(w.Prop1) & 0xFF //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(w.Sequence) & 0x3F) << 8 //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(w.Unknown1) & 0xFC) << 14 //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(w.Style) & 0x3F) << 20 //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(w.Unknown2) & 0x7C) << 26 //nolint:gomnd // Bitmask
|
||||
dw |= (uint32(w.hidden) & 0x01) << 31 //nolint:gomnd // Bitmask
|
||||
|
||||
return dw
|
||||
// Encode adds wall's record's bytes into stream writer given
|
||||
func (w *WallRecord) Encode(sw *d2datautils.StreamWriter) {
|
||||
sw.PushBits32(uint32(w.Prop1), 8)
|
||||
sw.PushBits32(uint32(w.Sequence), 6)
|
||||
sw.PushBits32(uint32(w.Unknown1), 6)
|
||||
sw.PushBits32(uint32(w.Style), 6)
|
||||
sw.PushBits32(uint32(w.Unknown2), 5)
|
||||
sw.PushBits32(uint32(w.hidden), 1)
|
||||
}
|
||||
|
||||
// Decode decodes wall record
|
||||
|
Loading…
Reference in New Issue
Block a user