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)) if value2.len() == 3 => {
608 SendPropValue::Float(value1.x) == value2[0]
609 && SendPropValue::Float(value1.y) == value2[1]
610 && SendPropValue::Float(value1.z) == value2[2]
611 }
612 (SendPropValue::Array(value1), SendPropValue::Vector(value2)) if value1.len() == 3 => {
613 SendPropValue::Float(value2.x) == value1[0]
614 && SendPropValue::Float(value2.y) == value1[1]
615 && SendPropValue::Float(value2.z) == value1[2]
616 }
617 (SendPropValue::VectorXY(value1), SendPropValue::Array(value2))
618 if value2.len() == 2 =>
619 {
620 SendPropValue::Float(value1.x) == value2[0]
621 && SendPropValue::Float(value1.y) == value2[1]
622 }
623 (SendPropValue::Array(value1), SendPropValue::VectorXY(value2))
624 if value1.len() == 2 =>
625 {
626 SendPropValue::Float(value2.x) == value1[0]
627 && SendPropValue::Float(value2.y) == value1[1]
628 }
629 _ => false,
630 }
631 }
632}
633
634impl fmt::Display for SendPropValue {
635 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
636 match self {
637 SendPropValue::Vector(vector) => Display::fmt(vector, f),
638 SendPropValue::VectorXY(vector) => Display::fmt(vector, f),
639 SendPropValue::Integer(int) => Display::fmt(int, f),
640 SendPropValue::Float(float) => Display::fmt(float, f),
641 SendPropValue::String(string) => Display::fmt(string, f),
642 SendPropValue::Array(array) => {
643 write!(f, "[")?;
644 for child in array {
645 write!(f, "{}", child)?;
646 }
647 write!(f, "]")
648 }
649 }
650 }
651}
652
653fn float_scale(bit_count: u8) -> f32 {
654 (1i32.wrapping_shl(bit_count as u32)) as f32 - 1.0
656}
657
658impl SendPropValue {
659 pub fn parse(stream: &mut Stream, definition: &SendPropParseDefinition) -> Result<Self> {
660 match definition {
661 SendPropParseDefinition::NormalVarInt { unsigned, .. } => {
662 read_var_int(stream, !*unsigned)
663 .map_err(ParseError::from)
664 .map(|int| int as i64)
665 .map(SendPropValue::from)
666 }
667 SendPropParseDefinition::UnsignedInt { bit_count, .. } => {
668 Ok((stream.read_sized::<u32>(*bit_count as usize)? as i64).into())
669 }
670 SendPropParseDefinition::Int { bit_count, .. } => stream
671 .read_int::<i32>((*bit_count) as usize)
672 .map_err(ParseError::from)
673 .map(SendPropValue::from),
674 SendPropParseDefinition::Float {
675 definition: float_definition,
676 ..
677 } => Self::read_float(stream, float_definition).map(SendPropValue::from),
678 SendPropParseDefinition::String { .. } => {
679 let length = stream.read_int(9)?;
680 stream
681 .read_sized::<String>(length)
682 .map_err(ParseError::from)
683 .map(SendPropValue::from)
684 }
685 SendPropParseDefinition::Vector {
686 definition: float_definition,
687 ..
688 } => Ok(Vector {
689 x: Self::read_float(stream, float_definition)?,
690 y: Self::read_float(stream, float_definition)?,
691 z: Self::read_float(stream, float_definition)?,
692 }
693 .into()),
694 SendPropParseDefinition::VectorXY {
695 definition: float_definition,
696 ..
697 } => Ok(VectorXY {
698 x: Self::read_float(stream, float_definition)?,
699 y: Self::read_float(stream, float_definition)?,
700 }
701 .into()),
702 SendPropParseDefinition::Array {
703 count_bit_count,
704 inner_definition,
705 ..
706 } => {
707 let count = stream.read_int(*count_bit_count as usize)?;
708 let mut values = Vec::with_capacity(min(count, 128));
709
710 for _ in 0..count {
711 values.push(Self::parse(stream, inner_definition)?);
712 }
713
714 Ok(values.into())
715 }
716 }
717 }
718 pub fn encode(
719 &self,
720 stream: &mut BitWriteStream<LittleEndian>,
721 definition: &SendPropParseDefinition,
722 ) -> Result<()> {
723 match definition {
724 SendPropParseDefinition::NormalVarInt { unsigned, .. } => {
725 let val: i64 = self.try_into()?;
726 write_var_int(val as i32, stream, !*unsigned)?;
727 Ok(())
728 }
729 SendPropParseDefinition::UnsignedInt { bit_count, .. } => {
730 let val: i64 = self.try_into()?;
731 (val as u32).write_sized(stream, *bit_count as usize)?;
732 Ok(())
733 }
734 SendPropParseDefinition::Int { bit_count, .. } => {
735 let val: i64 = self.try_into()?;
736 (val as i32).write_sized(stream, *bit_count as usize)?;
737 Ok(())
738 }
739 SendPropParseDefinition::Float {
740 definition: float_definition,
741 ..
742 } => {
743 let val: f32 = self.try_into()?;
744 Self::write_float(val, stream, float_definition)
745 }
746 SendPropParseDefinition::String { .. } => {
747 let val: &str = self.try_into()?;
748 (val.len() as u16).write_sized(stream, 9)?;
749 val.write_sized(stream, val.len())?;
750 Ok(())
751 }
752 SendPropParseDefinition::Vector {
753 definition: float_definition,
754 ..
755 } => {
756 let val: Vector = self.try_into()?;
757 Self::write_float(val.x, stream, float_definition)?;
758 Self::write_float(val.y, stream, float_definition)?;
759 Self::write_float(val.z, stream, float_definition)?;
760 Ok(())
761 }
762 SendPropParseDefinition::VectorXY {
763 definition: float_definition,
764 ..
765 } => {
766 let val: VectorXY = self.try_into()?;
767 Self::write_float(val.x, stream, float_definition)?;
768 Self::write_float(val.y, stream, float_definition)?;
769 Ok(())
770 }
771 SendPropParseDefinition::Array {
772 count_bit_count,
773 inner_definition,
774 ..
775 } => {
776 let array: &[SendPropValue] = self.try_into()?;
777 (array.len() as u16).write_sized(stream, *count_bit_count as usize)?;
778
779 for inner in array {
780 inner.encode(stream, inner_definition)?
781 }
782
783 Ok(())
784 }
785 }
786 }
787
788 fn read_float(stream: &mut Stream, definition: &FloatDefinition) -> Result<f32> {
789 match definition {
790 FloatDefinition::Coord => read_bit_coord(stream).map_err(ParseError::from),
791 FloatDefinition::CoordMP => {
792 read_bit_coord_mp(stream, false, false).map_err(ParseError::from)
793 }
794 FloatDefinition::CoordMPLowPrecision => {
795 read_bit_coord_mp(stream, false, true).map_err(ParseError::from)
796 }
797 FloatDefinition::CoordMPIntegral => {
798 read_bit_coord_mp(stream, true, false).map_err(ParseError::from)
799 }
800 FloatDefinition::FloatNoScale => stream.read().map_err(ParseError::from),
801 FloatDefinition::NormalVarFloat => read_bit_normal(stream).map_err(ParseError::from),
802 FloatDefinition::Scaled {
803 bit_count,
804 low,
805 high,
806 } => {
807 let raw: u32 = stream.read_int(*bit_count as usize)?;
808 let scale = float_scale(*bit_count);
809 let percentage = (raw as f32) / scale;
810 Ok(low + ((high - low) * percentage))
811 }
812 }
813 }
814
815 fn write_float(
816 val: f32,
817 stream: &mut BitWriteStream<LittleEndian>,
818 definition: &FloatDefinition,
819 ) -> Result<()> {
820 match definition {
821 FloatDefinition::Coord => write_bit_coord(val, stream).map_err(ParseError::from),
822 FloatDefinition::CoordMP => {
823 write_bit_coord_mp(val, stream, false, false).map_err(ParseError::from)
824 }
825 FloatDefinition::CoordMPLowPrecision => {
826 write_bit_coord_mp(val, stream, false, true).map_err(ParseError::from)
827 }
828 FloatDefinition::CoordMPIntegral => {
829 write_bit_coord_mp(val, stream, true, false).map_err(ParseError::from)
830 }
831 FloatDefinition::FloatNoScale => val.write(stream).map_err(ParseError::from),
832 FloatDefinition::NormalVarFloat => {
833 write_bit_normal(val, stream).map_err(ParseError::from)
834 }
835 FloatDefinition::Scaled {
836 bit_count,
837 low,
838 high,
839 } => {
840 let percentage = (val - low) / (high - low);
841 let scale = float_scale(*bit_count);
842 let raw = (percentage * scale).round() as u32;
843 raw.write_sized(stream, *bit_count as usize)?;
844
845 Ok(())
846 }
847 }
848 }
849}
850
851#[test]
852fn test_send_prop_value_roundtrip() {
853 use bitbuffer::{BitReadBuffer, BitReadStream};
854
855 fn send_prop_value_roundtrip(val: SendPropValue, def: SendPropParseDefinition) {
856 let mut data = Vec::new();
857 let pos = {
858 let mut write = BitWriteStream::new(&mut data, LittleEndian);
859 val.encode(&mut write, &def).unwrap();
860 write.bit_len()
861 };
862 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
863 assert_eq!(val, SendPropValue::parse(&mut read, &def).unwrap());
864 assert_eq!(pos, read.pos());
865 }
866 send_prop_value_roundtrip(
867 SendPropValue::Integer(0),
868 SendPropParseDefinition::UnsignedInt {
869 changes_often: false,
870 bit_count: 5,
871 },
872 );
873 send_prop_value_roundtrip(
874 SendPropValue::Integer(12),
875 SendPropParseDefinition::NormalVarInt {
876 changes_often: false,
877 unsigned: false,
878 },
879 );
880 send_prop_value_roundtrip(
881 SendPropValue::Integer(12),
882 SendPropParseDefinition::NormalVarInt {
883 changes_often: false,
884 unsigned: false,
885 },
886 );
887 send_prop_value_roundtrip(
888 SendPropValue::Integer(-12),
889 SendPropParseDefinition::NormalVarInt {
890 changes_often: false,
891 unsigned: true,
892 },
893 );
894 send_prop_value_roundtrip(
895 SendPropValue::String("foobar".into()),
896 SendPropParseDefinition::String {
897 changes_often: false,
898 },
899 );
900 send_prop_value_roundtrip(
901 SendPropValue::Vector(Vector {
902 x: 1.0,
903 y: 0.0,
904 z: 1.125,
905 }),
906 SendPropParseDefinition::Vector {
907 changes_often: false,
908 definition: FloatDefinition::Coord,
909 },
910 );
911 send_prop_value_roundtrip(
912 SendPropValue::VectorXY(VectorXY { x: 1.0, y: 0.0 }),
913 SendPropParseDefinition::VectorXY {
914 changes_often: false,
915 definition: FloatDefinition::FloatNoScale,
916 },
917 );
918 send_prop_value_roundtrip(
919 SendPropValue::Float(12.5),
920 SendPropParseDefinition::Float {
921 changes_often: false,
922 definition: FloatDefinition::CoordMP,
923 },
924 );
925 send_prop_value_roundtrip(
926 SendPropValue::Float(12.0),
927 SendPropParseDefinition::Float {
928 changes_often: false,
929 definition: FloatDefinition::CoordMPIntegral,
930 },
931 );
932 send_prop_value_roundtrip(
933 SendPropValue::Float(12.5),
934 SendPropParseDefinition::Float {
935 changes_often: false,
936 definition: FloatDefinition::CoordMPLowPrecision,
937 },
938 );
939 send_prop_value_roundtrip(
940 SendPropValue::Float(12.498169),
941 SendPropParseDefinition::Float {
942 changes_often: false,
943 definition: FloatDefinition::Scaled {
944 bit_count: 12,
945 high: 25.0,
946 low: 10.0,
947 },
948 },
949 );
950 send_prop_value_roundtrip(
951 SendPropValue::Array(vec![
952 SendPropValue::Integer(0),
953 SendPropValue::Integer(1),
954 SendPropValue::Integer(2),
955 ]),
956 SendPropParseDefinition::Array {
957 changes_often: false,
958 inner_definition: Box::new(SendPropParseDefinition::UnsignedInt {
959 changes_often: false,
960 bit_count: 3,
961 }),
962 count_bit_count: 5,
963 },
964 );
965
966 send_prop_value_roundtrip(
967 SendPropValue::Float(76.22549),
968 SendPropParseDefinition::Float {
969 changes_often: false,
970 definition: FloatDefinition::Scaled {
971 bit_count: 10,
972 high: 102.3,
973 low: 0.09990235,
974 },
975 },
976 );
977 send_prop_value_roundtrip(
978 SendPropValue::Vector(Vector {
979 x: 1.0,
980 y: -25.96875,
981 z: 0.1875,
982 }),
983 SendPropParseDefinition::Vector {
984 changes_often: false,
985 definition: FloatDefinition::CoordMP,
986 },
987 );
988 send_prop_value_roundtrip(
989 SendPropValue::Integer(-1),
990 SendPropParseDefinition::NormalVarInt {
991 changes_often: false,
992 unsigned: false,
993 },
994 );
995}
996
997impl From<i32> for SendPropValue {
998 fn from(value: i32) -> Self {
999 SendPropValue::Integer(value as i64)
1000 }
1001}
1002
1003impl From<i64> for SendPropValue {
1004 fn from(value: i64) -> Self {
1005 SendPropValue::Integer(value)
1006 }
1007}
1008
1009impl From<Vector> for SendPropValue {
1010 fn from(value: Vector) -> Self {
1011 SendPropValue::Vector(value)
1012 }
1013}
1014
1015impl From<VectorXY> for SendPropValue {
1016 fn from(value: VectorXY) -> Self {
1017 SendPropValue::VectorXY(value)
1018 }
1019}
1020
1021impl From<f32> for SendPropValue {
1022 fn from(value: f32) -> Self {
1023 SendPropValue::Float(value)
1024 }
1025}
1026
1027impl From<String> for SendPropValue {
1028 fn from(value: String) -> Self {
1029 SendPropValue::String(value)
1030 }
1031}
1032
1033impl From<Vec<SendPropValue>> for SendPropValue {
1034 fn from(value: Vec<SendPropValue>) -> Self {
1035 SendPropValue::Array(value)
1036 }
1037}
1038
1039impl TryFrom<&SendPropValue> for i64 {
1040 type Error = MalformedSendPropDefinitionError;
1041 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1042 match value {
1043 SendPropValue::Integer(val) => Ok(*val),
1044 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1045 expected: "integer",
1046 value: value.clone(),
1047 }),
1048 }
1049 }
1050}
1051
1052impl TryFrom<&SendPropValue> for Vector {
1053 type Error = MalformedSendPropDefinitionError;
1054 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1055 match value {
1056 SendPropValue::Vector(val) => Ok(*val),
1057 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1058 expected: "vector",
1059 value: value.clone(),
1060 }),
1061 }
1062 }
1063}
1064
1065impl TryFrom<&SendPropValue> for VectorXY {
1066 type Error = MalformedSendPropDefinitionError;
1067 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1068 match value {
1069 SendPropValue::VectorXY(val) => Ok(*val),
1070 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1071 expected: "vectorxy",
1072 value: value.clone(),
1073 }),
1074 }
1075 }
1076}
1077
1078impl TryFrom<&SendPropValue> for f32 {
1079 type Error = MalformedSendPropDefinitionError;
1080 fn try_from(value: &SendPropValue) -> std::result::Result<Self, Self::Error> {
1081 match value {
1082 SendPropValue::Float(val) => Ok(*val),
1083 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1084 expected: "float",
1085 value: value.clone(),
1086 }),
1087 }
1088 }
1089}
1090
1091impl<'a> TryFrom<&'a SendPropValue> for &'a str {
1092 type Error = MalformedSendPropDefinitionError;
1093 fn try_from(value: &'a SendPropValue) -> std::result::Result<Self, Self::Error> {
1094 match value {
1095 SendPropValue::String(val) => Ok(val.as_str()),
1096 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1097 expected: "string",
1098 value: value.clone(),
1099 }),
1100 }
1101 }
1102}
1103
1104impl<'a> TryFrom<&'a SendPropValue> for &'a [SendPropValue] {
1105 type Error = MalformedSendPropDefinitionError;
1106 fn try_from(value: &'a SendPropValue) -> std::result::Result<Self, Self::Error> {
1107 match value {
1108 SendPropValue::Array(val) => Ok(val.as_slice()),
1109 _ => Err(MalformedSendPropDefinitionError::WrongPropType {
1110 expected: "array",
1111 value: value.clone(),
1112 }),
1113 }
1114 }
1115}
1116
1117#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
1118pub struct SendPropIdentifier(u64);
1119
1120impl SendPropIdentifier {
1121 pub const fn new(table: &str, prop: &str) -> Self {
1122 let hasher = ConstFnvHash::new().push_string(table).push_string(prop);
1123 SendPropIdentifier(hasher.finish())
1124 }
1125
1126 pub fn table_name(&self) -> Option<SendTableName> {
1130 get_prop_names(*self).map(|(table, _)| table.into())
1131 }
1132
1133 pub fn prop_name(&self) -> Option<SendPropName> {
1137 get_prop_names(*self).map(|(_, prop)| prop.into())
1138 }
1139
1140 pub fn names(&self) -> Option<(SendTableName, SendPropName)> {
1144 get_prop_names(*self).map(|(table, prop)| (table.into(), prop.into()))
1145 }
1146}
1147
1148impl From<u64> for SendPropIdentifier {
1149 fn from(raw: u64) -> Self {
1150 SendPropIdentifier(raw)
1151 }
1152}
1153
1154impl From<SendPropIdentifier> for u64 {
1155 fn from(identifier: SendPropIdentifier) -> Self {
1156 identifier.0
1157 }
1158}
1159
1160impl Display for SendPropIdentifier {
1161 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1162 match get_prop_names(*self) {
1163 Some((table, prop)) => write!(f, "{}.{}", table, prop),
1164 None => write!(f, "Prop name {} not known", self.0),
1165 }
1166 }
1167}
1168
1169impl<'de> Deserialize<'de> for SendPropIdentifier {
1170 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
1171 where
1172 D: Deserializer<'de>,
1173 {
1174 #[derive(Deserialize)]
1175 #[serde(untagged)]
1176 enum Options<'a> {
1177 Num(u64),
1178 Str(&'a str),
1179 }
1180
1181 let raw = Options::deserialize(deserializer)?;
1182 Ok(match raw {
1183 Options::Num(num) => SendPropIdentifier(num),
1184 Options::Str(s) => {
1185 let num: u64 = s.parse().map_err(D::Error::custom)?;
1186 SendPropIdentifier(num)
1187 }
1188 })
1189 }
1190}
1191
1192impl Serialize for SendPropIdentifier {
1193 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
1194 where
1195 S: Serializer,
1196 {
1197 self.0.to_string().serialize(serializer)
1198 }
1199}
1200
1201#[cfg(feature = "schema")]
1202impl schemars::JsonSchema for SendPropIdentifier {
1203 fn schema_name() -> String {
1204 "SendPropIdentifier".into()
1205 }
1206
1207 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1208 <String as schemars::JsonSchema>::json_schema(gen)
1209 }
1210}
1211
1212#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
1213#[derive(Clone, Display, PartialEq, Serialize, Deserialize)]
1214#[display("{index} = {value}")]
1215pub struct SendProp {
1216 pub index: u32,
1217 pub identifier: SendPropIdentifier,
1218 pub value: SendPropValue,
1219}
1220
1221impl Debug for SendProp {
1222 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1223 write!(f, "{} = {}", self.identifier, self.value)
1224 }
1225}
1226
1227pub fn read_var_int(stream: &mut Stream, signed: bool) -> ReadResult<i32> {
1228 let abs_int = crate::demo::message::stringtable::read_var_int(stream)? as i32;
1229
1230 if signed {
1231 Ok((abs_int >> 1) ^ -(abs_int & 1))
1232 } else {
1233 Ok(abs_int)
1234 }
1235}
1236
1237pub fn write_var_int(
1238 int: i32,
1239 stream: &mut BitWriteStream<LittleEndian>,
1240 signed: bool,
1241) -> ReadResult<()> {
1242 let abs = if signed {
1243 let int = (int << 1) ^ (int >> 31);
1244 u32::from_le_bytes(int.to_le_bytes())
1245 } else {
1246 int as u32
1247 };
1248
1249 crate::demo::message::stringtable::write_var_int(abs, stream)
1250}
1251
1252#[test]
1253fn test_var_int_roundtrip() {
1254 use bitbuffer::{BitReadBuffer, BitReadStream};
1255
1256 fn var_int_roundtrip(int: i32, signed: bool) {
1257 let mut data = Vec::new();
1258 let pos = {
1259 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1260 write_var_int(int, &mut write, signed).unwrap();
1261 write.bit_len()
1262 };
1263 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
1264 assert_eq!(int, read_var_int(&mut read, signed).unwrap());
1265 assert_eq!(pos, read.pos());
1266 }
1267 var_int_roundtrip(0, false);
1268 var_int_roundtrip(1, false);
1269 var_int_roundtrip(10, false);
1270 var_int_roundtrip(55, false);
1271 var_int_roundtrip(355, false);
1272 var_int_roundtrip(12354, false);
1273 var_int_roundtrip(123125412, false);
1274
1275 var_int_roundtrip(0, true);
1276 var_int_roundtrip(1, true);
1277 var_int_roundtrip(10, true);
1278 var_int_roundtrip(55, true);
1279 var_int_roundtrip(355, true);
1280 var_int_roundtrip(12354, true);
1281 var_int_roundtrip(123125412, true);
1282 var_int_roundtrip(-0, true);
1283 var_int_roundtrip(-1, true);
1284 var_int_roundtrip(-10, true);
1285 var_int_roundtrip(-55, true);
1286 var_int_roundtrip(-355, true);
1287 var_int_roundtrip(-12354, true);
1288 var_int_roundtrip(-123125412, true);
1289}
1290
1291pub fn read_bit_coord(stream: &mut Stream) -> ReadResult<f32> {
1292 let has_int = stream.read()?;
1293 let has_frac = stream.read()?;
1294
1295 Ok(if has_int || has_frac {
1296 let sign = if stream.read()? { -1f32 } else { 1f32 };
1297 let int_val: u16 = if has_int {
1298 stream.read_sized::<u16>(14)? + 1
1299 } else {
1300 0
1301 };
1302 let frac_val: u8 = if has_frac { stream.read_sized(5)? } else { 0 };
1303 let value = int_val as f32 + (frac_val as f32 * get_frac_factor(5));
1304 value * sign
1305 } else {
1306 0f32
1307 })
1308}
1309
1310pub fn write_bit_coord(val: f32, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
1311 let has_int = val.abs() >= 1.0;
1312 has_int.write(stream)?;
1313 let has_frac = val.fract() != 0.0;
1314 has_frac.write(stream)?;
1315
1316 if has_frac || has_int {
1317 let sign = val.is_negative();
1318 sign.write(stream)?;
1319 }
1320 let abs = val.abs();
1321 if has_int {
1322 (abs as u16 - 1).write_sized(stream, 14)?;
1323 }
1324 if has_frac {
1325 let frac_val = (abs.fract() / get_frac_factor(5)) as u8;
1326 frac_val.write_sized(stream, 5)?;
1327 }
1328 Ok(())
1329}
1330
1331#[test]
1332fn bit_coord_roundtrip() {
1333 use bitbuffer::BitReadBuffer;
1334
1335 let mut data = Vec::with_capacity(16);
1336 let (pos1, pos2, pos3, pos4) = {
1337 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1338 write_bit_coord(0.0, &mut write).unwrap();
1339 let pos1 = write.bit_len();
1340 write_bit_coord(123.0, &mut write).unwrap();
1341 let pos2 = write.bit_len();
1342 write_bit_coord(123.4375, &mut write).unwrap();
1343 let pos3 = write.bit_len();
1344 write_bit_coord(-0.4375, &mut write).unwrap();
1345 let pos4 = write.bit_len();
1346 (pos1, pos2, pos3, pos4)
1347 };
1348
1349 let mut read = Stream::from(BitReadBuffer::new(&data, LittleEndian));
1350 assert_eq!(0.0, read_bit_coord(&mut read).unwrap());
1351 assert_eq!(pos1, read.pos());
1352 assert_eq!(123.0, read_bit_coord(&mut read).unwrap());
1353 assert_eq!(pos2, read.pos());
1354 assert_eq!(123.4375, read_bit_coord(&mut read).unwrap());
1355 assert_eq!(pos3, read.pos());
1356 assert_eq!(-0.4375, read_bit_coord(&mut read).unwrap());
1357 assert_eq!(pos4, read.pos());
1358}
1359
1360fn get_frac_factor(bits: usize) -> f32 {
1361 1.0 / ((1 << bits) as f32)
1362}
1363
1364pub fn read_bit_coord_mp(
1365 stream: &mut Stream,
1366 is_integral: bool,
1367 low_precision: bool,
1368) -> ReadResult<f32> {
1369 let mut value = 0.0;
1370 let mut is_negative = false;
1371
1372 let in_bounds = stream.read()?;
1373 let has_int_val = stream.read()?;
1374
1375 if is_integral {
1376 if has_int_val {
1377 is_negative = stream.read()?;
1378
1379 let int_val = stream.read_sized::<u32>(if in_bounds { 11 } else { 14 })? + 1;
1380 value = int_val as f32;
1381 }
1382 } else {
1383 is_negative = stream.read()?;
1384 if has_int_val {
1385 let int_val = stream.read_sized::<u32>(if in_bounds { 11 } else { 14 })? + 1;
1386 value = int_val as f32;
1387 }
1388 let frac_bits = if low_precision { 3 } else { 5 };
1389 let frac_val: u32 = stream.read_sized(frac_bits)?;
1390 value += (frac_val as f32) * get_frac_factor(frac_bits);
1391 }
1392
1393 if is_negative {
1394 value = -value;
1395 }
1396
1397 Ok(value)
1398}
1399
1400pub fn write_bit_coord_mp(
1401 val: f32,
1402 stream: &mut BitWriteStream<LittleEndian>,
1403 is_integral: bool,
1404 low_precision: bool,
1405) -> ReadResult<()> {
1406 let abs = val.abs();
1407 let in_bounds = (abs as u32) < (1 << 11);
1408 let has_int_val = abs >= 1.0;
1409 in_bounds.write(stream)?;
1410 has_int_val.write(stream)?;
1411
1412 if is_integral {
1413 if has_int_val {
1414 val.is_sign_negative().write(stream)?;
1415 ((abs - 1.0) as u32).write_sized(stream, if in_bounds { 11 } else { 14 })?;
1416 }
1417 } else {
1418 val.is_sign_negative().write(stream)?;
1419 if has_int_val {
1420 ((abs - 1.0) as u32).write_sized(stream, if in_bounds { 11 } else { 14 })?;
1421 }
1422 let frac_bits = if low_precision { 3 } else { 5 };
1423 let frac_val = (abs.fract() / get_frac_factor(frac_bits)) as u32;
1424 frac_val.write_sized(stream, frac_bits)?;
1425 }
1426
1427 Ok(())
1428}
1429
1430#[test]
1431fn test_bit_coord_mp_roundtrip() {
1432 use bitbuffer::{BitReadBuffer, BitReadStream};
1433
1434 fn bit_coord_mp_normal(val: f32, is_integral: bool, low_precision: bool) {
1435 let mut data = Vec::with_capacity(16);
1436 let pos = {
1437 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1438 write_bit_coord_mp(val, &mut write, is_integral, low_precision).unwrap();
1439 write.bit_len()
1440 };
1441 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
1442 assert_eq!(
1443 val,
1444 read_bit_coord_mp(&mut read, is_integral, low_precision).unwrap()
1445 );
1446 assert_eq!(pos, read.pos());
1447 }
1448
1449 bit_coord_mp_normal(1.0, false, false);
1450
1451 bit_coord_mp_normal(0.0, false, false);
1452 bit_coord_mp_normal(0.5, false, false);
1453 bit_coord_mp_normal(-0.5, false, false);
1454 bit_coord_mp_normal(1234.5, false, false);
1455 bit_coord_mp_normal(-1234.5, false, false);
1456 bit_coord_mp_normal(2.0f32.powf(12.0) + 0.125, false, false);
1457
1458 bit_coord_mp_normal(0.0, false, true);
1459 bit_coord_mp_normal(0.5, false, true);
1460 bit_coord_mp_normal(-0.5, false, true);
1461 bit_coord_mp_normal(1234.5, false, true);
1462 bit_coord_mp_normal(-1234.5, false, true);
1463 bit_coord_mp_normal(2.0f32.powf(12.0) + 0.125, false, true);
1464
1465 bit_coord_mp_normal(0.0, true, false);
1466 bit_coord_mp_normal(1234.0, true, false);
1467 bit_coord_mp_normal(-1234.0, true, false);
1468 bit_coord_mp_normal(2.0f32.powf(12.0), true, false);
1469}
1470
1471pub fn read_bit_normal(stream: &mut Stream) -> ReadResult<f32> {
1472 let is_negative = stream.read()?;
1473 let frac_val: u16 = stream.read_sized(11)?;
1474 let value = (frac_val as f32) * get_frac_factor(11);
1475 if is_negative {
1476 Ok(-value)
1477 } else {
1478 Ok(value)
1479 }
1480}
1481
1482pub fn write_bit_normal(val: f32, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
1483 val.is_sign_negative().write(stream)?;
1484 let frac_val = (val.abs().fract() / get_frac_factor(11)) as u16;
1485 frac_val.write_sized(stream, 11)
1486}
1487
1488#[test]
1489fn test_bit_normal_roundtrip() {
1490 use bitbuffer::{BitReadBuffer, BitReadStream};
1491
1492 fn roundtrip_normal(val: f32) {
1493 let mut data = Vec::with_capacity(16);
1494 let pos = {
1495 let mut write = BitWriteStream::new(&mut data, LittleEndian);
1496 write_bit_normal(val, &mut write).unwrap();
1497 write.bit_len()
1498 };
1499 let mut read = BitReadStream::new(BitReadBuffer::new(&data, LittleEndian));
1500 assert_eq!(val, read_bit_normal(&mut read).unwrap());
1501 assert_eq!(pos, read.pos());
1502 }
1503 roundtrip_normal(0.0);
1504 roundtrip_normal(-0.0);
1505 roundtrip_normal(0.5);
1506 roundtrip_normal(-0.5);
1507}