diff --git a/ent/decoders.go b/ent/decoders.go index 990abd4..1c1b814 100644 --- a/ent/decoders.go +++ b/ent/decoders.go @@ -23,10 +23,13 @@ func newFieldDecoder(n *Namespace, f *Field) decoder { return decodeVarInt64 case "int8", "int16", "int32", "int64": return decodeZigZag - case "float32": + case "CNetworkedQuantizedFloat", "float32": return floatDecoder(f) case "Vector": return vectorDecoder(f) + case "CGameSceneNodeHandle": + // ehhh maybe no? + return decodeVarInt32 } // the field is itself an entity contained within the outer entity. @@ -46,18 +49,6 @@ func decodeVarInt32(br bit.Reader) interface{} { return bit.ReadVarInt32(br) } func decodeVarInt64(br bit.Reader) interface{} { return bit.ReadVarInt(br) } func decodeZigZag(br bit.Reader) interface{} { return bit.ReadZigZag(br) } -func floatDecoder(f *Field) decoder { - if f.bits <= 0 || f.bits >= 32 { - return ieeeFloat32Decoder - } - return nil -} - -// reads an IEEE 754 binary float value off of the stream -func ieeeFloat32Decoder(br bit.Reader) interface{} { - return math.Float32frombits(uint32(br.ReadBits(32))) -} - func entityDecoder(c *Class) decoder { return func(br bit.Reader) interface{} { if bit.ReadBool(br) { diff --git a/ent/field.go b/ent/field.go index 95dd15e..c979307 100644 --- a/ent/field.go +++ b/ent/field.go @@ -8,19 +8,19 @@ import ( ) type Field struct { - _type Symbol // type of data held by the field - name Symbol // name of the field - sendNode Symbol // not sure what this is - bits int // number of bits used to encode field? - low *float32 // lower limit of field values - high *float32 // upper limit of field values - flags int // dunno what these flags do - serializer *Symbol // class on which the field was defined - serializerVersion *int32 // version of the class on which the field was defined - class *Class // source class on which the field was originally defined - encoder *Symbol // binary encoder, named explicitly in protobuf - decoder // decodes field values from a bit stream - isTemplate bool // whether or not the field is a template type + _type Symbol // type of data held by the field + name Symbol // name of the field + sendNode Symbol // not sure what this is + bits uint // number of bits used to encode field? + low float32 // lower limit of field values + high float32 // upper limit of field values + flags int // dunno what these flags do + serializer *Symbol // class on which the field was defined + serializerVersion *int32 // version of the class on which the field was defined + class *Class // source class on which the field was originally defined + encoder *Symbol // binary encoder, named explicitly in protobuf + decoder // decodes field values from a bit stream + isTemplate bool // whether or not the field is a template type templateType string elemType string } @@ -34,12 +34,8 @@ func (f Field) String() string { if f.flags > 0 { fmt.Fprintf(&buf, " flags: %d", f.flags) } - if f.low != nil { - fmt.Fprintf(&buf, " low: %f", *f.low) - } - if f.high != nil { - fmt.Fprintf(&buf, " high: %f", *f.high) - } + fmt.Fprintf(&buf, " low: %f", f.low) + fmt.Fprintf(&buf, " high: %f", f.high) if f.serializer != nil { fmt.Fprintf(&buf, " serializer: %s", *f.serializer) } @@ -56,10 +52,10 @@ func (f Field) String() string { func (f *Field) fromProto(flat *dota.ProtoFlattenedSerializerFieldT, t *SymbolTable) { f._type = t.Symbol(int(flat.GetVarTypeSym())) f.name = t.Symbol(int(flat.GetVarNameSym())) - f.bits = int(flat.GetBitCount()) + f.bits = uint(flat.GetBitCount()) f.flags = int(flat.GetEncodeFlags()) - f.low = flat.LowValue - f.high = flat.HighValue + f.low = flat.GetLowValue() + f.high = flat.GetHighValue() if flat.FieldSerializerNameSym == nil { f.serializer = nil diff --git a/ent/float_decoders.go b/ent/float_decoders.go new file mode 100644 index 0000000..55739dd --- /dev/null +++ b/ent/float_decoders.go @@ -0,0 +1,69 @@ +package ent + +import ( + "math" + + "github.com/jordanorelli/hyperstone/bit" +) + +const ( + f_round_down = 1 << iota + f_round_up + f_encode_zero + f_encode_ints +) + +func floatDecoder(f *Field) decoder { + if f.bits <= 0 || f.bits >= 32 { + return ieeeFloat32Decoder + } + + // a quantized field value must have some range specified, otherwise the + // quantization makes no sense. + if f.low == 0 && f.high == 0 { + panic("quantization rules make no sense") + } + + flags := f.flags + + // number of input steps + // steps := int(1< 0 { + panic("how can you round down and up at the same time") + } + + // output width of each step + // step_width := span * inv_steps + + return func(br bit.Reader) interface{} { + if flags&f_round_down > 0 { + return nil + } + if flags&f_round_up > 0 { + panic("round up flag not done yet") + } + if flags&f_encode_zero > 0 { + panic("encode zero flag not done yet") + } + if flags&f_encode_ints > 0 { + panic("encode ints flag not done yet") + } + return nil + } +} + +// reads an IEEE 754 binary float value off of the stream +func ieeeFloat32Decoder(br bit.Reader) interface{} { + return math.Float32frombits(uint32(br.ReadBits(32))) +} diff --git a/ent/selection.go b/ent/selection.go index b9d43b2..f970261 100644 --- a/ent/selection.go +++ b/ent/selection.go @@ -18,42 +18,36 @@ type selection struct { func (s selection) path() []int { return s.vals[:s.count] } -func (s selection) fill(dest slotted, br bit.Reader) error { +func (s selection) fill(offset int, dest slotted, br bit.Reader) error { + slot := s.vals[offset] + Debug.Printf("fill selection %v", s) - switch s.count { + switch s.count - offset { case 0: panic("selection makes no sense") case 1: - fn := dest.getSlotDecoder(s.vals[0]) + fn := dest.getSlotDecoder(slot) if fn == nil { switch v := dest.(type) { case *Entity: - Info.Fatalf("%v entity has no decoder for slot %d (%v)", v.Class, s.vals[0], v.Class.Fields[s.vals[0]]) + Info.Fatalf("%v entity has no decoder for slot %d (%v)", v.Class, slot, v.Class.Fields[slot]) default: - Info.Fatalf("slotted value %v has no decoder for slot %d", dest, s.vals[0]) + Info.Fatalf("slotted value %v has no decoder for slot %d", dest, slot) } } val := fn(br) - old := dest.getSlotValue(s.vals[0]) - dest.setSlotValue(s.vals[0], val) + old := dest.getSlotValue(slot) + dest.setSlotValue(slot, val) Debug.Printf("%v -> %v", old, val) return nil default: Debug.Printf("fill child selection...") - inner := dest.getSlotValue(s.vals[0]) - inner_s, ok := inner.(slotted) + v := dest.getSlotValue(slot) + vs, ok := v.(slotted) if !ok { return fmt.Errorf("child selection refers to a slot that doesn't contain a slotted value") } - return s.next().fill(inner_s, br) - } -} - -func (s selection) next() selection { - // rofl this is weird - return selection{ - count: s.count - 1, - vals: [6]int{s.vals[1], s.vals[2], s.vals[3], s.vals[4], s.vals[5], 0}, + return s.fill(offset+1, vs, br) } } diff --git a/ent/slotted.go b/ent/slotted.go index 3666524..3adfefd 100644 --- a/ent/slotted.go +++ b/ent/slotted.go @@ -17,7 +17,7 @@ func fillSlots(dest slotted, sr *selectionReader, br bit.Reader) error { } for _, s := range selections { - if err := s.fill(dest, br); err != nil { + if err := s.fill(0, dest, br); err != nil { return err } }