1use super::packet::datatable::ParseSendTable;
2use super::vector::{Vector, VectorXY};
3use crate::consthash::ConstFnvHash;
4use crate::demo::message::stringtable::log_base2;
5use crate::demo::packet::datatable::SendTableName;
6use crate::demo::parser::MalformedSendPropDefinitionError;
7use crate::demo::sendprop_gen::get_prop_names;
8use crate::{ParseError, ReadResult, Result, Stream};
9use bitbuffer::{
10 BitRead, BitReadStream, BitWrite, BitWriteSized, BitWriteStream, Endianness, LittleEndian,
11};
12use enumflags2::{bitflags, BitFlags};
13use num_traits::Signed;
14use parse_display::Display;
15use serde::de::Error;
16use serde::{Deserialize, Deserializer, Serialize, Serializer};
17use std::borrow::Cow;
18use std::cmp::min;
19use std::convert::{TryFrom, TryInto};
20use std::fmt::{self, Debug, Display, Formatter};
21use std::hash::Hash;
22use std::ops::{BitOr, Deref};
23
24#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
25#[derive(
26 BitWrite, PartialEq, Eq, Hash, Debug, Display, Clone, Serialize, Deserialize, Ord, PartialOrd,
27)]
28pub struct SendPropName(Cow<'static, str>);
29
30impl SendPropName {
31 pub fn as_str(&self) -> &str {
32 self.0.as_ref()
33 }
34}
35
36impl<E: Endianness> BitRead<'_, E> for SendPropName {
37 fn read(stream: &mut BitReadStream<'_, E>) -> bitbuffer::Result<Self> {
38 String::read(stream).map(SendPropName::from)
39 }
40}
41
42impl PartialEq<&str> for SendPropName {
43 fn eq(&self, other: &&str) -> bool {
44 self.as_str() == *other
45 }
46}
47
48impl From<String> for SendPropName {
49 fn from(value: String) -> Self {
50 Self(Cow::Owned(value))
51 }
52}
53
54impl From<&'static str> for SendPropName {
55 fn from(value: &'static str) -> Self {
56 SendPropName(Cow::Borrowed(value))
57 }
58}
59
60impl AsRef<str> for SendPropName {
61 fn as_ref(&self) -> &str {
62 self.0.as_ref()
63 }
64}
65
66impl Deref for SendPropName {
67 type Target = str;
68
69 fn deref(&self) -> &Self::Target {
70 self.0.deref()
71 }
72}
73
74#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct RawSendPropDefinition {
77 pub prop_type: SendPropType,
78 pub name: SendPropName,
79 pub identifier: SendPropIdentifier,
80 pub flags: SendPropFlags,
81 pub table_name: Option<SendTableName>,
82 pub low_value: Option<f32>,
83 pub high_value: Option<f32>,
84 pub bit_count: Option<u32>,
85 pub element_count: Option<u16>,
86 pub array_property: Option<Box<RawSendPropDefinition>>,
87 pub original_bit_count: Option<u32>,
88}
89
90impl PartialEq for RawSendPropDefinition {
91 fn eq(&self, other: &Self) -> bool {
92 self.identifier() == other.identifier()
93 }
94}
95
96impl fmt::Display for RawSendPropDefinition {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self.prop_type {
99 SendPropType::Vector | SendPropType::VectorXY => write!(
100 f,
101 "{}({})(flags: {}, low: {}, high: {}, bits: {})",
102 self.name,
103 self.prop_type,
104 self.flags,
105 self.low_value.unwrap_or_default(),
106 self.high_value.unwrap_or_default(),
107 self.bit_count.unwrap_or(96) / 3
108 ),
109 SendPropType::Float => write!(
110 f,
111 "{}({})(flags: {}, low: {}, high: {}, bits: {})",
112 self.name,
113 self.prop_type,
114 self.flags,
115 self.low_value.unwrap_or_default(),
116 self.high_value.unwrap_or_default(),
117 self.bit_count.unwrap_or(32)
118 ),
119 SendPropType::Int => write!(
120 f,
121 "{}({})(flags: {}, bits: {})",
122 self.name,
123 self.prop_type,
124 self.flags,
125 self.bit_count.unwrap_or(32)
126 ),
127 SendPropType::String => {
128 write!(f, "{}({})", self.name, self.prop_type)
129 }
130 SendPropType::Array => match &self.array_property {
131 Some(array_prop) => write!(
132 f,
133 "{}([{}({})] * {})",
134 self.name,
135 array_prop.prop_type,
136 array_prop.flags,
137 self.element_count.unwrap_or_default(),
138 ),
139 None => write!(f, "{}(Malformed array)", self.name),
140 },
141 SendPropType::DataTable => match &self.table_name {
142 Some(sub_table) => write!(f, "{}(DataTable = {})", self.name, sub_table),
143 None => write!(f, "{}(Malformed DataTable)", self.name),
144 },
145 SendPropType::NumSendPropTypes => {
146 write!(f, "{}(NumSendPropTypes)", self.name)
147 }
148 }
149 }
150}
151
152impl RawSendPropDefinition {
153 pub fn identifier(&self) -> SendPropIdentifier {
154 self.identifier
155 }
156
157 pub fn with_array_property(self, array_property: Self) -> Self {
158 RawSendPropDefinition {
159 prop_type: self.prop_type,
160 identifier: self.identifier,
161 name: self.name,
162 flags: self.flags,
163 table_name: self.table_name,
164 low_value: self.low_value,
165 high_value: self.high_value,
166 bit_count: self.bit_count,
167 element_count: self.element_count,
168 array_property: Some(Box::new(array_property)),
169 original_bit_count: self.original_bit_count,
170 }
171 }
172
173 pub fn get_data_table<'a>(&self, tables: &'a [ParseSendTable]) -> Option<&'a ParseSendTable> {
177 if self.prop_type == SendPropType::DataTable {
178 self.table_name
179 .as_ref()
180 .and_then(|name| tables.iter().find(|table| table.name == *name))
181 } else {
182 None
183 }
184 }
185
186 pub fn read(stream: &mut Stream, owner_table: &SendTableName) -> ReadResult<Self> {
187 let prop_type = SendPropType::read(stream)?;
188 let name: SendPropName = stream.read()?;
189 let identifier = SendPropIdentifier::new(owner_table.as_str(), name.as_str());
190 let flags = SendPropFlags::read(stream)?;
191 let mut table_name = None;
192 let mut element_count = None;
193 let mut low_value = None;
194 let mut high_value = None;
195 let mut bit_count = None;
196 if flags.contains(SendPropFlag::Exclude) || prop_type == SendPropType::DataTable {
197 table_name = Some(stream.read()?);
198 } else if prop_type == SendPropType::Array {
199 element_count = Some(stream.read_int(10)?);
200 } else {
201 low_value = Some(stream.read()?);
202 high_value = Some(stream.read()?);
203 bit_count = Some(stream.read_int(7)?);
204 }
205 let original_bit_count = bit_count;
206
207 if flags.contains(SendPropFlag::NoScale) {
208 if prop_type == SendPropType::Float {
209 bit_count = Some(32);
210 } else if prop_type == SendPropType::Vector
211 && !flags.contains(SendPropFlag::NormalVarInt)
212 {
213 bit_count = Some(32 * 3);
214 }
215 }
216
217 Ok(RawSendPropDefinition {
218 prop_type,
219 name,
220 identifier,
221 flags,
222 table_name,
223 low_value,
224 high_value,
225 bit_count,
226 element_count,
227 original_bit_count,
228 array_property: None,
229 })
230 }
231
232 pub fn is_exclude(&self) -> bool {
233 self.flags.contains(SendPropFlag::Exclude)
234 }
235
236 pub fn get_exclude_table(&self) -> Option<&SendTableName> {
237 if self.is_exclude() {
238 self.table_name.as_ref()
239 } else {
240 None
241 }
242 }
243}
244
245impl BitWrite<LittleEndian> for RawSendPropDefinition {
246 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
247 self.prop_type.write(stream)?;
248 self.name.write(stream)?;
249 self.flags.write(stream)?;
250
251 if let Some(table_name) = self.table_name.as_ref() {
252 table_name.write(stream)?;
253 }
254 if let Some(element_count) = self.element_count {
255 element_count.write_sized(stream, 10)?;
256 }
257 if let (Some(low_value), Some(high_value), Some(bit_count)) =
258 (self.low_value, self.high_value, self.original_bit_count)
259 {
260 low_value.write(stream)?;
261 high_value.write(stream)?;
262 bit_count.write_sized(stream, 7)?;
263 }
264
265 Ok(())
266 }
267}
268
269#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
270#[derive(BitRead, BitWrite, Copy, Clone, PartialEq, Debug, Display, Serialize, Deserialize)]
271#[discriminant_bits = 5]
272pub enum SendPropType {
273 Int = 0,
274 Float = 1,
275 Vector = 2,
276 VectorXY = 3,
277 String = 4,
278 Array = 5,
279 DataTable = 6,
280 NumSendPropTypes = 7,
281}
282
283#[bitflags]
284#[derive(Copy, Clone, PartialEq, Debug)]
285#[repr(u16)]
286pub enum SendPropFlag {
287 Unsigned = 1,
289 Coord = 2,
292 NoScale = 4,
294 RoundDown = 8,
296 RoundUp = 16,
298 Exclude = 64,
300 XYZE = 128,
302 InsideArray = 256,
305 ProxyAlwaysYes = 512,
308 ChangesOften = 1024,
310 IsVectorElement = 2048,
312 Collapsible = 4096,
317 CoordMP = 8192,
319 CoordMPLowPrecision = 16384,
322 CoordMPIntegral = 32768,
325 NormalVarInt = 32,
326}
327
328#[derive(Debug, Copy, Clone, PartialEq, Default, Serialize, Deserialize)]
329pub struct SendPropFlags(BitFlags<SendPropFlag>);
330
331#[cfg(feature = "schemars")]
332impl schemars::JsonSchema for SendPropFlags {
333 fn schema_name() -> String {
334 "SendPropFlags".into()
335 }
336
337 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
338 u16::json_schema(gen)
339 }
340}
341
342impl BitOr<SendPropFlag> for SendPropFlags {
343 type Output = SendPropFlags;
344
345 fn bitor(self, rhs: SendPropFlag) -> Self::Output {
346 Self(self.0 | rhs)
347 }
348}
349
350impl fmt::Display for SendPropFlags {
351 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352 let debug = format!("{:?}", self.0);
353 let flags: String = debug
354 .chars()
355 .skip_while(|c| *c != '[')
356 .take_while(|c| *c != ')')
357 .collect();
358 write!(f, "{}", flags)
359 }
360}
361
362impl SendPropFlags {
363 pub fn contains(self, other: SendPropFlag) -> bool {
364 self.0.contains(other)
365 }
366}
367
368impl BitRead<'_, LittleEndian> for SendPropFlags {
369 fn read(stream: &mut Stream) -> ReadResult<Self> {
370 Ok(SendPropFlags(BitFlags::from_bits_truncate(stream.read()?)))
372 }
373
374 fn bit_size() -> Option<usize> {
375 Some(16)
376 }
377}
378
379impl BitWrite<LittleEndian> for SendPropFlags {
380 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
381 self.0.bits().write(stream)
382 }
383}
384
385#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
386#[derive(Debug, Clone, Serialize, Deserialize)]
387pub enum FloatDefinition {
388 Coord,
389 CoordMP,
390 CoordMPLowPrecision,
391 CoordMPIntegral,
392 FloatNoScale,
393 NormalVarFloat,
394 Scaled { bit_count: u8, high: f32, low: f32 },
395}
396
397impl FloatDefinition {
398 pub fn new(
399 flags: SendPropFlags,
400 bit_count: Option<u32>,
401 high: Option<f32>,
402 low: Option<f32>,
403 ) -> std::result::Result<Self, MalformedSendPropDefinitionError> {
404 if flags.contains(SendPropFlag::Coord) {
405 Ok(FloatDefinition::Coord)
406 } else if flags.contains(SendPropFlag::CoordMP) {
407 Ok(FloatDefinition::CoordMP)
408 } else if flags.contains(SendPropFlag::CoordMPLowPrecision) {
409 Ok(FloatDefinition::CoordMPLowPrecision)
410 } else if flags.contains(SendPropFlag::CoordMPIntegral) {
411 Ok(FloatDefinition::CoordMPIntegral)
412 } else if flags.contains(SendPropFlag::NoScale) {
413 Ok(FloatDefinition::FloatNoScale)
414 } else if flags.contains(SendPropFlag::NormalVarInt) {
415 Ok(FloatDefinition::NormalVarFloat)
416 } else if let (Some(bit_count), Some(high), Some(low)) = (bit_count, high, low) {
417 Ok(FloatDefinition::Scaled {
418 bit_count: bit_count as u8,
419 high,
420 low,
421 })
422 } else {
423 Err(MalformedSendPropDefinitionError::UnsizedFloat)
424 }
425 }
426}
427
428#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
429#[derive(Debug, Clone, Serialize, Deserialize)]
430pub struct SendPropDefinition {
431 pub identifier: SendPropIdentifier,
432 pub parse_definition: SendPropParseDefinition,
433}
434
435impl TryFrom<&RawSendPropDefinition> for SendPropDefinition {
436 type Error = MalformedSendPropDefinitionError;
437
438 fn try_from(definition: &RawSendPropDefinition) -> std::result::Result<Self, Self::Error> {
439 let parse_definition = definition.try_into()?;
440 Ok(SendPropDefinition {
441 parse_definition,
442 identifier: definition.identifier(),
443 })
444 }
445}
446
447#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
448#[derive(Debug, Clone, Serialize, Deserialize)]
449pub enum SendPropParseDefinition {
450 NormalVarInt {
451 changes_often: bool,
452 unsigned: bool,
453 },
454 UnsignedInt {
455 changes_often: bool,
456 bit_count: u8,
457 },
458 Int {
459 changes_often: bool,
460 bit_count: u8,
461 },
462 Float {
463 changes_often: bool,
464 definition: FloatDefinition,
465 },
466 String {
467 changes_often: bool,
468 },
469 Vector {
470 changes_often: bool,
471 definition: FloatDefinition,
472 },
473 VectorXY {
474 changes_often: bool,
475 definition: FloatDefinition,
476 },
477 Array {
478 changes_often: bool,
479 inner_definition: Box<SendPropParseDefinition>,
480 count_bit_count: u16,
481 },
482}
483
484impl SendPropParseDefinition {
485 pub fn changes_often(&self) -> bool {
486 match self {
487 SendPropParseDefinition::NormalVarInt { changes_often, .. } => *changes_often,
488 SendPropParseDefinition::UnsignedInt { changes_often, .. } => *changes_often,
489 SendPropParseDefinition::Int { changes_often, .. } => *changes_often,
490 SendPropParseDefinition::Float { changes_often, .. } => *changes_often,
491 SendPropParseDefinition::String { changes_often, .. } => *changes_often,
492 SendPropParseDefinition::Vector { changes_often, .. } => *changes_often,
493 SendPropParseDefinition::VectorXY { changes_often, .. } => *changes_often,
494 SendPropParseDefinition::Array { changes_often, .. } => *changes_often,
495 }
496 }
497}
498
499impl TryFrom<&RawSendPropDefinition> for SendPropParseDefinition {
500 type Error = MalformedSendPropDefinitionError;
501
502 fn try_from(definition: &RawSendPropDefinition) -> std::result::Result<Self, Self::Error> {
503 let changes_often = definition.flags.contains(SendPropFlag::ChangesOften);
504 match definition.prop_type {
505 SendPropType::Int => {
506 if definition.flags.contains(SendPropFlag::NormalVarInt) {
507 Ok(SendPropParseDefinition::NormalVarInt {
508 changes_often,
509 unsigned: definition.flags.contains(SendPropFlag::Unsigned),
510 })
511 } else if definition.flags.contains(SendPropFlag::Unsigned) {
512 Ok(SendPropParseDefinition::UnsignedInt {
513 changes_often,
514 bit_count: definition.bit_count.unwrap_or(32) as u8,
515 })
516 } else {
517 Ok(SendPropParseDefinition::Int {
518 changes_often,
519 bit_count: definition.bit_count.unwrap_or(32) as u8,
520 })
521 }
522 }
523 SendPropType::Float => Ok(SendPropParseDefinition::Float {
524 changes_often,
525 definition: FloatDefinition::new(
526 definition.flags,
527 definition.bit_count,
528 definition.high_value,
529 definition.low_value,
530 )?,
531 }),
532 SendPropType::String => Ok(SendPropParseDefinition::String { changes_often }),
533 SendPropType::Vector => Ok(SendPropParseDefinition::Vector {
534 changes_often,
535 definition: FloatDefinition::new(
536 definition.flags,
537 definition.bit_count,
538 definition.high_value,
539 definition.low_value,
540 )?,
541 }),
542 SendPropType::VectorXY => Ok(SendPropParseDefinition::VectorXY {
543 changes_often,
544 definition: FloatDefinition::new(
545 definition.flags,
546 definition.bit_count,
547 definition.high_value,
548 definition.low_value,
549 )?,
550 }),
551 SendPropType::Array => {
552 let element_count = definition
553 .element_count
554 .ok_or(MalformedSendPropDefinitionError::UnsizedArray)?;
555 let count_bit_count = log_base2(element_count) as u16 + 1;
556 let child_definition = definition
557 .array_property
558 .as_deref()
559 .ok_or(MalformedSendPropDefinitionError::UntypedArray)?;
560 Ok(SendPropParseDefinition::Array {
561 changes_often,
562 inner_definition: Box::new(SendPropParseDefinition::try_from(
563 child_definition,
564 )?),
565 count_bit_count,
566 })
567 }
568 _ => Err(MalformedSendPropDefinitionError::InvalidPropType),
569 }
570 }
571}
572
573#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
574#[derive(Debug, Clone, Serialize, Deserialize)]
575#[serde(untagged)]
576pub enum SendPropValue {
577 Vector(Vector),
578 VectorXY(VectorXY),
579 Integer(i64),
580 Float(f32),
581 String(String),
582 Array(Vec<SendPropValue>),
583}
584
585impl PartialEq for SendPropValue {
586 fn eq(&self, other: &Self) -> bool {
587 match (self, other) {
589 (SendPropValue::Vector(value1), SendPropValue::Vector(value2)) => value1 == value2,
590 (SendPropValue::VectorXY(value1), SendPropValue::VectorXY(value2)) => value1 == value2,
591 (SendPropValue::Integer(value1), SendPropValue::Integer(value2)) => value1 == value2,
592 (SendPropValue::Float(value1), SendPropValue::Float(value2)) => value1 - value2 < 0.001,
593 (SendPropValue::String(value1), SendPropValue::String(value2)) => value1 == value2,
594 (SendPropValue::Array(value1), SendPropValue::Array(value2)) => value1 == value2,
595 (SendPropValue::Integer(value1), SendPropValue::Float(value2)) => {
596 *value1 as f64 == *value2 as f64
597 }
598 (SendPropValue::Float(value1), SendPropValue::Integer(value2)) => {
599 *value1 as f64 == *value2 as f64
600 }
601 (SendPropValue::Vector(value1), SendPropValue::VectorXY(value2)) => {
602 value1.x == value2.x && value1.y == value2.y && value1.z == 0.0
603 }
604 (SendPropValue::VectorXY(value1), SendPropValue::Vector(value2)) => {
605 value1.x == value2.x && value1.y == value2.y && value2.z == 0.0
606 }
607 (SendPropValue::Vector(value1), SendPropValue::Array(value2)) => {
608 value1 == value2.as_slice()
609 }
610 (SendPropValue::Array(value1), SendPropValue::Vector(value2)) => {
611 value2 == value1.as_slice()
612 }
613 (SendPropValue::VectorXY(value1), SendPropValue::Array(value2)) => {
614 value1 == value2.as_slice()
615 }
616 (SendPropValue::Array(value1), SendPropValue::VectorXY(value2)) => {
617 value2 == value1.as_slice()
618 }
619 _ => false,
620 }
621 }
622}
623
624impl fmt::Display for SendPropValue {
625 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
626 match self {
627 SendPropValue::Vector(vector) => Display::fmt(vector, f),
628 SendPropValue::VectorXY(vector) => Display::fmt(vector, f),
629 SendPropValue::Integer(int) => Display::fmt(int, f),
630 SendPropValue::Float(float) => Display::fmt(float, f),
631 SendPropValue::String(string) => Display::fmt(string, f),
632 SendPropValue::Array(array) => {
633 write!(f, "[")?;
634 for child in array {
635 write!(f, "{}", child)?;
636 }
637 write!(f, "]")
638 }
639 }
640 }
641}
642
643fn float_scale(bit_count: u8) -> f32 {
644 (1i32.wrapping_shl(bit_count as u32)) as f32 - 1.0
646}
647
648impl SendPropValue {
649 pub fn parse(stream: &mut Stream, definition: &SendPropParseDefinition) -> Result<Self> {
650 match definition {
651 SendPropParseDefinition::NormalVarInt { unsigned, .. } => {
652 read_var_int(stream, !*unsigned)
653 .map_err(ParseError::from)
654 .map(|int| int as i64)
655 .map(SendPropValue::from)
656 }
657 SendPropParseDefinition::UnsignedInt { bit_count, .. } => {
658 Ok((stream.read_sized::<u32>(*bit_count as usize)? as i64).into())
659 }
660 SendPropParseDefinition::Int { bit_count, .. } => stream
661 .read_int::<i32>((*bit_count) as usize)
662 .map_err(ParseError::from)
663 .map(SendPropValue::from),
664 SendPropParseDefinition::Float {
665 definition: float_definition,
666 ..
667 } => Self::read_float(stream, float_definition).map(SendPropValue::from),
668 SendPropParseDefinition::String { .. } => {
669 let length = stream.read_int(9)?;
670 stream
671 .read_sized::<String>(length)
672 .map_err(ParseError::from)
673 .map(SendPropValue::from)
674 }
675 SendPropParseDefinition::Vector {
676 definition: float_definition,
677 ..
678 } => Ok(Vector {
679 x: Self::read_float(stream, float_definition)?,
680 y: Self::read_float(stream, float_definition)?,
681 z: Self::read_float(stream, float_definition)?,
682 }
683 .into()),
684 SendPropParseDefinition::VectorXY {
685 definition: float_definition,
686 ..
687 } => Ok(VectorXY {
688 x: Self::read_float(stream, float_definition)?,
689 y: Self::read_float(stream, float_definition)?,
690 }
691 .into()),
692 SendPropParseDefinition::Array {
693 count_bit_count,
694 inner_definition,
695 ..
696 } => {
697 let count = stream.read_int(*count_bit_count as usize)?;
698 let mut values = Vec::with_capacity(min(count, 128));
699
700 for _ in 0..count {
701 values.push(Self::parse(stream, inner_definition)?);
702 }
703
704 Ok(values.into())
705 }
706 }
707 }
708 pub fn encode(
709 &self,
710 stream: &mut BitWriteStream<LittleEndian>,
711 definition: &SendPropParseDefinition,
712 ) -> Result<()> {
713 match definition {
714 SendPropParseDefinition::NormalVarInt { unsigned, .. } => {
715 let val: i64 = self.try_into()?;
716 write_var_int(val as i32, stream, !*unsigned)?;
717 Ok(())
718 }
719 SendPropParseDefinition::UnsignedInt { bit_count, .. } => {
720 let val: i64 = self.try_into()?;
721 (val as u32).write_sized(stream, *bit_count as usize)?;
722 Ok(())
723 }
724 SendPropParseDefinition::Int { bit_count, .. } => {
725 let val: i64 = self.try_into()?;
726 (val as i32).write_sized(stream, *bit_count as usize)?;
727 Ok(())
728 }
729 SendPropParseDefinition::Float {
730 definition: float_definition,
731 ..
732 } => {
733 let val: f32 = self.try_into()?;
734 Self::write_float(val, stream, float_definition)
735 }
736 SendPropParseDefinition::String { .. } => {
737 let val: &str = self.try_into()?;
738 (val.len() as u16).write_sized(stream, 9)?;
739 val.write_sized(stream, val.len())?;
740 Ok(())
741 }
742 SendPropParseDefinition::Vector {
743 definition: float_definition,
744 ..
745 } => {
746 let val: Vector = self.try_into()?;
747 Self::write_float(val.x, stream, float_definition)?;
748 Self::write_float(val.y, stream, float_definition)?;
749 Self::write_float(val.z, stream, float_definition)?;
750 Ok(())
751 }
752 SendPropParseDefinition::VectorXY {
753 definition: float_definition,
754 ..
755 } => {
756 let val: VectorXY = self.try_into()?;
757 Self::write_float(val.x, stream, float_definition)?;
758 Self::write_float(val.y, stream, float_definition)?;
759 Ok(())
760 }
761 SendPropParseDefinition::Array {
762 count_bit_count,
763 inner_definition,
764 ..
765 } => {
766 let array: &[SendPropValue] = self.try_into()?;
767 (array.len() as u16).write_sized(stream, *count_bit_count as usize)?;
768
769 for inner in array {
770 inner.encode(stream, inner_definition)?
771 }
772
773 Ok(())
774 }
775 }
776 }
777
778 fn read_float(stream: &mut Stream, definition: &FloatDefinition) -> Result<f32> {
779 match definition {
780 FloatDefinition::Coord => read_bit_coord(stream).map_err(ParseError::from),
781 FloatDefinition::CoordMP => {
782 read_bit_coord_mp(stream, false, false).map_err(ParseError::from)
783 }
784 FloatDefinition::CoordMPLowPrecision => {
785 read_bit_coord_mp(stream, false, true).map_err(ParseError::from)
786 }
787 FloatDefinition::CoordMPIntegral => {
788 read_bit_coord_mp(stream, true, false).map_err(ParseError::from)
789 }
790 FloatDefinition::FloatNoScale => stream.read().map_err(ParseError::from),
791 FloatDefinition::NormalVarFloat => read_bit_normal(stream).map_err(ParseError::from),
792 FloatDefinition::Scaled {
793 bit_count,
794 low,
795 high,
796 } => {
797 let raw: u32 = stream.read_int(*bit_count as usize)?;
798 let scale = float_scale(*bit_count);
799 let percentage = (raw as f32) / scale;
800 Ok(low + ((high - low) * percentage))
801 }
802 }
803 }
804
805 fn write_float(
806 val: f32,
807 stream: &mut BitWriteStream<LittleEndian>,
808 definition: &FloatDefinition,
809 ) -> Result<()> {
810 match definition {
811 FloatDefinition::Coord => write_bit_coord(val, stream).map_err(ParseError::from),
812 FloatDefinition::CoordMP => {
813 write_bit_coord_mp(val, stream, false, false).map_err(ParseError::from)
814 }
815 FloatDefinition::CoordMPLowPrecision => {
816 write_bit_coord_mp(val, stream, false, true).map_err(ParseError::from)
817 }
818 FloatDefinition::CoordMPIntegral => {
819 write_bit_coord_mp(val, stream, true, false).map_err(ParseError::from)
820 }
821 FloatDefinition::FloatNoScale => val.write(stream).map_err(ParseError::from),
822 FloatDefinition::NormalVarFloat => {
823 write_bit_normal(val, stream).map_err(ParseError::from)
824 }
825 FloatDefinition::Scaled {
826 bit_count,
827 low,
828 high,
829 } => {
830 let percentage = (val - low) / (high - low);
831 let scale = float_scale(*bit_count);
832 let raw = (percentage * scale).round() as u32;
833 raw.write_sized(stream, *bit_count as usize)?;
834
835 Ok(())
836 }
837 }
838 }
839}
840
841#[test]
842fn test_send_prop_value_roundtrip() {
843 use bitbuffer::{BitReadBuffer, BitReadStream};
844
845 fn send_prop_value_roundtrip(val: SendPropValue, def: SendPropParseDefinition) {
846 let mut data = Vec::new();
847 let pos = {
848 let mut write = BitWriteStream::new(&mut data, LittleEndian);
849 val.encode(&mut write, &def).unwrap();
850 write.bit_len()
851 };
852 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
853 assert_eq!(val, SendPropValue::parse(&mut read, &def).unwrap());
854 assert_eq!(pos, read.pos());
855 }
856 send_prop_value_roundtrip(
857 SendPropValue::Integer(0),
858 SendPropParseDefinition::UnsignedInt {
859 changes_often: false,
860 bit_count: 5,
861 },
862 );
863 send_prop_value_roundtrip(
864 SendPropValue::Integer(12),
865 SendPropParseDefinition::NormalVarInt {
866 changes_often: false,
867 unsigned: false,
868 },
869 );
870 send_prop_value_roundtrip(
871 SendPropValue::Integer(12),
872 SendPropParseDefinition::NormalVarInt {
873 changes_often: false,
874 unsigned: false,
875 },
876 );
877 send_prop_value_roundtrip(
878 SendPropValue::Integer(-12),
879 SendPropParseDefinition::NormalVarInt {
880 changes_often: false,
881 unsigned: true,
882 },
883 );
884 send_prop_value_roundtrip(
885 SendPropValue::String("foobar".into()),
886 SendPropParseDefinition::String {
887 changes_often: false,
888 },
889 );
890 send_prop_value_roundtrip(
891 SendPropValue::Vector(Vector {
892 x: 1.0,
893 y: 0.0,
894 z: 1.125,
895 }),
896 SendPropParseDefinition::Vector {
897 changes_often: false,
898 definition: FloatDefinition::Coord,
899 },
900 );
901 send_prop_value_roundtrip(
902 SendPropValue::VectorXY(VectorXY { x: 1.0, y: 0.0 }),
903 SendPropParseDefinition::VectorXY {
904 changes_often: false,
905 definition: FloatDefinition::FloatNoScale,
906 },
907 );
908 send_prop_value_roundtrip(
909 SendPropValue::Float(12.5),
910 SendPropParseDefinition::Float {
911 changes_often: false,
912 definition: FloatDefinition::CoordMP,
913 },
914 );
915 send_prop_value_roundtrip(
916 SendPropValue::Float(12.0),
917 SendPropParseDefinition::Float {
918 changes_often: false,
919 definition: FloatDefinition::CoordMPIntegral,
920 },
921 );
922 send_prop_value_roundtrip(
923 SendPropValue::Float(12.5),
924 SendPropParseDefinition::Float {
925 changes_often: false,
926 definition: FloatDefinition::CoordMPLowPrecision,
927 },
928 );
929 send_prop_value_roundtrip(
930 SendPropValue::Float(12.498169),
931 SendPropParseDefinition::Float {
932 changes_often: false,
933 definition: FloatDefinition::Scaled {
934 bit_count: 12,
935 high: 25.0,
936 low: 10.0,
937 },
938 },
939 );
940 send_prop_value_roundtrip(
941 SendPropValue::Array(vec![
942 SendPropValue::Integer(0),
943 SendPropValue::Integer(1),
944 SendPropValue::Integer(2),
945 ]),
946 SendPropParseDefinition::Array {
947 changes_often: false,
948 inner_definition: Box::new(SendPropParseDefinition::UnsignedInt {
949 changes_often: false,
950 bit_count: 3,
951 }),
952 count_bit_count: 5,
953 },
954 );
955
956 send_prop_value_roundtrip(
957 SendPropValue::Float(76.22549),
958 SendPropParseDefinition::Float {
959 changes_often: false,
960 definition: FloatDefinition::Scaled {
961 bit_count: 10,
962 high: 102.3,
963 low: 0.09990235,
964 },
965 },
966 );
967 send_prop_value_roundtrip(
968 SendPropValue::Vector(Vector {
969 x: 1.0,
970 y: -25.96875,
971 z: 0.1875,
972 }),
973 SendPropParseDefinition::Vector {
974 changes_often: false,
975 definition: FloatDefinition::CoordMP,
976 },
977 );
978 send_prop_value_roundtrip(
979 SendPropValue::Integer(-1),
980 SendPropParseDefinition::NormalVarInt {
981 changes_often: false,
982 unsigned: false,
983 },
984 );
985}
986
987impl From<i32> for SendPropValue {
988 fn from(value: i32) -> Self {
989 SendPropValue::Integer(value as i64)
990 }
991}
992
993impl From<i64> for SendPropValue {
994 fn from(value: i64) -> Self {
995 SendPropValue::Integer(value)
996 }
997}
998
999impl From<Vector> for SendPropValue {
1000 fn from(value: Vector) -> Self {
1001 SendPropValue::Vector(value)
1002 }
1003}
1004
1005impl From<VectorXY> for SendPropValue {
1006 fn from(value: VectorXY) -> Self {
1007 SendPropValue::VectorXY(value)
1008 }
1009}
1010
1011impl From<f32> for SendPropValue {
1012 fn from(value: f32) -> Self {
1013 SendPropValue::Float(value)
1014 }
1015}
1016
1017impl From<String> for SendPropValue {
1018 fn from(value: String) -> Self {
1019 SendPropValue::String(value)
1020 }
1021}
1022
1023impl From<Vec<SendPropValue>> for SendPropValue {
1024 fn from(value: Vec<SendPropValue>) -> Self {
1025 SendPropValue::Array(value)
1026 }
1027}
1028
1029impl TryFrom<&SendPropValue> for i64 {
1030 type Error = MalformedSendPropDefinitionError;
1031 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1032 match value {
1033 SendPropValue::Integer(val) => Ok(*val),
1034 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1035 expected: "integer",
1036 value: value.clone(),
1037 }),
1038 }
1039 }
1040}
1041
1042impl TryFrom<&SendPropValue> for bool {
1043 type Error = MalformedSendPropDefinitionError;
1044 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1045 match value {
1046 SendPropValue::Integer(val) => Ok(*val > 0),
1047 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1048 expected: "boolean",
1049 value: value.clone(),
1050 }),
1051 }
1052 }
1053}
1054
1055impl TryFrom<&SendPropValue> for Vector {
1056 type Error = MalformedSendPropDefinitionError;
1057 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1058 match value {
1059 SendPropValue::Vector(val) => Ok(*val),
1060 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1061 expected: "vector",
1062 value: value.clone(),
1063 }),
1064 }
1065 }
1066}
1067
1068impl TryFrom<&SendPropValue> for VectorXY {
1069 type Error = MalformedSendPropDefinitionError;
1070 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1071 match value {
1072 SendPropValue::VectorXY(val) => Ok(*val),
1073 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1074 expected: "vectorxy",
1075 value: value.clone(),
1076 }),
1077 }
1078 }
1079}
1080
1081impl TryFrom<&SendPropValue> for f32 {
1082 type Error = MalformedSendPropDefinitionError;
1083 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1084 match value {
1085 SendPropValue::Float(val) => Ok(*val),
1086 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1087 expected: "float",
1088 value: value.clone(),
1089 }),
1090 }
1091 }
1092}
1093
1094impl<'a> TryFrom<&'a SendPropValue> for &'a str {
1095 type Error = MalformedSendPropDefinitionError;
1096 fn try_from(value: &'a SendPropValue) -> std::result::Result<Self, Self::Error> {
1097 match value {
1098 SendPropValue::String(val) => Ok(val.as_str()),
1099 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1100 expected: "string",
1101 value: value.clone(),
1102 }),
1103 }
1104 }
1105}
1106
1107impl<'a> TryFrom<&'a SendPropValue> for &'a [SendPropValue] {
1108 type Error = MalformedSendPropDefinitionError;
1109 fn try_from(value: &'a SendPropValue) -> std::result::Result<Self, Self::Error> {
1110 match value {
1111 SendPropValue::Array(val) => Ok(val.as_slice()),
1112 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1113 expected: "array",
1114 value: value.clone(),
1115 }),
1116 }
1117 }
1118}
1119
1120#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
1121pub struct SendPropIdentifier(u64);
1122
1123impl SendPropIdentifier {
1124 pub const fn new(table: &str, prop: &str) -> Self {
1125 let hasher = ConstFnvHash::new().push_string(table).push_string(prop);
1126 SendPropIdentifier(hasher.finish())
1127 }
1128
1129 pub const fn from_const(raw: u64) -> Self {
1132 SendPropIdentifier(raw)
1133 }
1134
1135 pub fn table_name(&self) -> Option<SendTableName> {
1139 get_prop_names(*self).map(|(table, _)| table.into())
1140 }
1141
1142 pub fn prop_name(&self) -> Option<SendPropName> {
1146 get_prop_names(*self).map(|(_, prop)| prop.into())
1147 }
1148
1149 pub fn names(&self) -> Option<(SendTableName, SendPropName)> {
1153 get_prop_names(*self).map(|(table, prop)| (table.into(), prop.into()))
1154 }
1155}
1156
1157impl From<u64> for SendPropIdentifier {
1158 fn from(raw: u64) -> Self {
1159 SendPropIdentifier(raw)
1160 }
1161}
1162
1163impl From<SendPropIdentifier> for u64 {
1164 fn from(identifier: SendPropIdentifier) -> Self {
1165 identifier.0
1166 }
1167}
1168
1169impl Display for SendPropIdentifier {
1170 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1171 match get_prop_names(*self) {
1172 Some((table, prop)) => write!(f, "{}.{}", table, prop),
1173 None => write!(f, "Prop name {} not known", self.0),
1174 }
1175 }
1176}
1177
1178impl<'de> Deserialize<'de> for SendPropIdentifier {
1179 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
1180 where
1181 D: Deserializer<'de>,
1182 {
1183 #[derive(Deserialize)]
1184 #[serde(untagged)]
1185 enum Options<'a> {
1186 Num(u64),
1187 Str(Cow<'a, str>),
1188 }
1189
1190 let raw = Options::deserialize(deserializer)?;
1191 Ok(match raw {
1192 Options::Num(num) => SendPropIdentifier(num),
1193 Options::Str(s) => {
1194 let num: u64 = s.parse().map_err(D::Error::custom)?;
1195 SendPropIdentifier(num)
1196 }
1197 })
1198 }
1199}
1200
1201impl Serialize for SendPropIdentifier {
1202 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
1203 where
1204 S: Serializer,
1205 {
1206 self.0.to_string().serialize(serializer)
1207 }
1208}
1209
1210#[cfg(feature = "schema")]
1211impl schemars::JsonSchema for SendPropIdentifier {
1212 fn schema_name() -> String {
1213 "SendPropIdentifier".into()
1214 }
1215
1216 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1217 <String as schemars::JsonSchema>::json_schema(gen)
1218 }
1219}
1220
1221#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
1222#[derive(Clone, Display, PartialEq, Serialize, Deserialize)]
1223#[display("{index} = {value}")]
1224pub struct SendProp {
1225 pub index: u32,
1226 pub identifier: SendPropIdentifier,
1227 pub value: SendPropValue,
1228}
1229
1230impl Debug for SendProp {
1231 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1232 write!(f, "{} = {}", self.identifier, self.value)
1233 }
1234}
1235
1236pub fn read_var_int(stream: &mut Stream, signed: bool) -> ReadResult<i32> {
1237 let abs_int = crate::demo::message::stringtable::read_var_int(stream)? as i32;
1238
1239 if signed {
1240 Ok((abs_int >> 1) ^ -(abs_int & 1))
1241 } else {
1242 Ok(abs_int)
1243 }
1244}
1245
1246pub fn write_var_int(
1247 int: i32,
1248 stream: &mut BitWriteStream<LittleEndian>,
1249 signed: bool,
1250) -> ReadResult<()> {
1251 let abs = if signed {
1252 let int = (int << 1) ^ (int >> 31);
1253 u32::from_le_bytes(int.to_le_bytes())
1254 } else {
1255 int as u32
1256 };
1257
1258 crate::demo::message::stringtable::write_var_int(abs, stream)
1259}
1260
1261#[test]
1262fn test_var_int_roundtrip() {
1263 use bitbuffer::{BitReadBuffer, BitReadStream};
1264
1265 fn var_int_roundtrip(int: i32, signed: bool) {
1266 let mut data = Vec::new();
1267 let pos = {
1268 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1269 write_var_int(int, &mut write, signed).unwrap();
1270 write.bit_len()
1271 };
1272 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
1273 assert_eq!(int, read_var_int(&mut read, signed).unwrap());
1274 assert_eq!(pos, read.pos());
1275 }
1276 var_int_roundtrip(0, false);
1277 var_int_roundtrip(1, false);
1278 var_int_roundtrip(10, false);
1279 var_int_roundtrip(55, false);
1280 var_int_roundtrip(355, false);
1281 var_int_roundtrip(12354, false);
1282 var_int_roundtrip(123125412, false);
1283
1284 var_int_roundtrip(0, true);
1285 var_int_roundtrip(1, true);
1286 var_int_roundtrip(10, true);
1287 var_int_roundtrip(55, true);
1288 var_int_roundtrip(355, true);
1289 var_int_roundtrip(12354, true);
1290 var_int_roundtrip(123125412, true);
1291 var_int_roundtrip(-0, true);
1292 var_int_roundtrip(-1, true);
1293 var_int_roundtrip(-10, true);
1294 var_int_roundtrip(-55, true);
1295 var_int_roundtrip(-355, true);
1296 var_int_roundtrip(-12354, true);
1297 var_int_roundtrip(-123125412, true);
1298}
1299
1300pub fn read_bit_coord(stream: &mut Stream) -> ReadResult<f32> {
1301 let has_int = stream.read()?;
1302 let has_frac = stream.read()?;
1303
1304 Ok(if has_int || has_frac {
1305 let sign = if stream.read()? { -1f32 } else { 1f32 };
1306 let int_val: u16 = if has_int {
1307 stream.read_sized::<u16>(14)? + 1
1308 } else {
1309 0
1310 };
1311 let frac_val: u8 = if has_frac { stream.read_sized(5)? } else { 0 };
1312 let value = int_val as f32 + (frac_val as f32 * get_frac_factor(5));
1313 value * sign
1314 } else {
1315 0f32
1316 })
1317}
1318
1319pub fn write_bit_coord(val: f32, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
1320 let has_int = val.abs() >= 1.0;
1321 has_int.write(stream)?;
1322 let has_frac = val.fract() != 0.0;
1323 has_frac.write(stream)?;
1324
1325 if has_frac || has_int {
1326 let sign = val.is_negative();
1327 sign.write(stream)?;
1328 }
1329 let abs = val.abs();
1330 if has_int {
1331 (abs as u16 - 1).write_sized(stream, 14)?;
1332 }
1333 if has_frac {
1334 let frac_val = (abs.fract() / get_frac_factor(5)) as u8;
1335 frac_val.write_sized(stream, 5)?;
1336 }
1337 Ok(())
1338}
1339
1340#[test]
1341fn bit_coord_roundtrip() {
1342 use bitbuffer::BitReadBuffer;
1343
1344 let mut data = Vec::with_capacity(16);
1345 let (pos1, pos2, pos3, pos4) = {
1346 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1347 write_bit_coord(0.0, &mut write).unwrap();
1348 let pos1 = write.bit_len();
1349 write_bit_coord(123.0, &mut write).unwrap();
1350 let pos2 = write.bit_len();
1351 write_bit_coord(123.4375, &mut write).unwrap();
1352 let pos3 = write.bit_len();
1353 write_bit_coord(-0.4375, &mut write).unwrap();
1354 let pos4 = write.bit_len();
1355 (pos1, pos2, pos3, pos4)
1356 };
1357
1358 let mut read = Stream::from(BitReadBuffer::new(&data, LittleEndian));
1359 assert_eq!(0.0, read_bit_coord(&mut read).unwrap());
1360 assert_eq!(pos1, read.pos());
1361 assert_eq!(123.0, read_bit_coord(&mut read).unwrap());
1362 assert_eq!(pos2, read.pos());
1363 assert_eq!(123.4375, read_bit_coord(&mut read).unwrap());
1364 assert_eq!(pos3, read.pos());
1365 assert_eq!(-0.4375, read_bit_coord(&mut read).unwrap());
1366 assert_eq!(pos4, read.pos());
1367}
1368
1369fn get_frac_factor(bits: usize) -> f32 {
1370 1.0 / ((1 << bits) as f32)
1371}
1372
1373pub fn read_bit_coord_mp(
1374 stream: &mut Stream,
1375 is_integral: bool,
1376 low_precision: bool,
1377) -> ReadResult<f32> {
1378 let mut value = 0.0;
1379 let mut is_negative = false;
1380
1381 let in_bounds = stream.read()?;
1382 let has_int_val = stream.read()?;
1383
1384 if is_integral {
1385 if has_int_val {
1386 is_negative = stream.read()?;
1387
1388 let int_val = stream.read_sized::<u32>(if in_bounds { 11 } else { 14 })? + 1;
1389 value = int_val as f32;
1390 }
1391 } else {
1392 is_negative = stream.read()?;
1393 if has_int_val {
1394 let int_val = stream.read_sized::<u32>(if in_bounds { 11 } else { 14 })? + 1;
1395 value = int_val as f32;
1396 }
1397 let frac_bits = if low_precision { 3 } else { 5 };
1398 let frac_val: u32 = stream.read_sized(frac_bits)?;
1399 value += (frac_val as f32) * get_frac_factor(frac_bits);
1400 }
1401
1402 if is_negative {
1403 value = -value;
1404 }
1405
1406 Ok(value)
1407}
1408
1409pub fn write_bit_coord_mp(
1410 val: f32,
1411 stream: &mut BitWriteStream<LittleEndian>,
1412 is_integral: bool,
1413 low_precision: bool,
1414) -> ReadResult<()> {
1415 let abs = val.abs();
1416 let in_bounds = (abs as u32) < (1 << 11);
1417 let has_int_val = abs >= 1.0;
1418 in_bounds.write(stream)?;
1419 has_int_val.write(stream)?;
1420
1421 if is_integral {
1422 if has_int_val {
1423 val.is_sign_negative().write(stream)?;
1424 ((abs - 1.0) as u32).write_sized(stream, if in_bounds { 11 } else { 14 })?;
1425 }
1426 } else {
1427 val.is_sign_negative().write(stream)?;
1428 if has_int_val {
1429 ((abs - 1.0) as u32).write_sized(stream, if in_bounds { 11 } else { 14 })?;
1430 }
1431 let frac_bits = if low_precision { 3 } else { 5 };
1432 let frac_val = (abs.fract() / get_frac_factor(frac_bits)) as u32;
1433 frac_val.write_sized(stream, frac_bits)?;
1434 }
1435
1436 Ok(())
1437}
1438
1439#[test]
1440fn test_bit_coord_mp_roundtrip() {
1441 use bitbuffer::{BitReadBuffer, BitReadStream};
1442
1443 fn bit_coord_mp_normal(val: f32, is_integral: bool, low_precision: bool) {
1444 let mut data = Vec::with_capacity(16);
1445 let pos = {
1446 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1447 write_bit_coord_mp(val, &mut write, is_integral, low_precision).unwrap();
1448 write.bit_len()
1449 };
1450 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
1451 assert_eq!(
1452 val,
1453 read_bit_coord_mp(&mut read, is_integral, low_precision).unwrap()
1454 );
1455 assert_eq!(pos, read.pos());
1456 }
1457
1458 bit_coord_mp_normal(1.0, false, false);
1459
1460 bit_coord_mp_normal(0.0, false, false);
1461 bit_coord_mp_normal(0.5, false, false);
1462 bit_coord_mp_normal(-0.5, false, false);
1463 bit_coord_mp_normal(1234.5, false, false);
1464 bit_coord_mp_normal(-1234.5, false, false);
1465 bit_coord_mp_normal(2.0f32.powf(12.0) + 0.125, false, false);
1466
1467 bit_coord_mp_normal(0.0, false, true);
1468 bit_coord_mp_normal(0.5, false, true);
1469 bit_coord_mp_normal(-0.5, false, true);
1470 bit_coord_mp_normal(1234.5, false, true);
1471 bit_coord_mp_normal(-1234.5, false, true);
1472 bit_coord_mp_normal(2.0f32.powf(12.0) + 0.125, false, true);
1473
1474 bit_coord_mp_normal(0.0, true, false);
1475 bit_coord_mp_normal(1234.0, true, false);
1476 bit_coord_mp_normal(-1234.0, true, false);
1477 bit_coord_mp_normal(2.0f32.powf(12.0), true, false);
1478}
1479
1480pub fn read_bit_normal(stream: &mut Stream) -> ReadResult<f32> {
1481 let is_negative = stream.read()?;
1482 let frac_val: u16 = stream.read_sized(11)?;
1483 let value = (frac_val as f32) * get_frac_factor(11);
1484 if is_negative {
1485 Ok(-value)
1486 } else {
1487 Ok(value)
1488 }
1489}
1490
1491pub fn write_bit_normal(val: f32, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
1492 val.is_sign_negative().write(stream)?;
1493 let frac_val = (val.abs().fract() / get_frac_factor(11)) as u16;
1494 frac_val.write_sized(stream, 11)
1495}
1496
1497#[test]
1498fn test_bit_normal_roundtrip() {
1499 use bitbuffer::{BitReadBuffer, BitReadStream};
1500
1501 fn roundtrip_normal(val: f32) {
1502 let mut data = Vec::with_capacity(16);
1503 let pos = {
1504 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1505 write_bit_normal(val, &mut write).unwrap();
1506 write.bit_len()
1507 };
1508 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
1509 assert_eq!(val, read_bit_normal(&mut read).unwrap());
1510 assert_eq!(pos, read.pos());
1511 }
1512 roundtrip_normal(0.0);
1513 roundtrip_normal(-0.0);
1514 roundtrip_normal(0.5);
1515 roundtrip_normal(-0.5);
1516}