encodertypeentry.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. //
  19. // Filename: encodertypeentry.cpp
  20. // Project: wwbitpack.lib
  21. // Author: Tom Spencer-Smith
  22. // Date: June 2000
  23. // Description:
  24. //
  25. //-----------------------------------------------------------------------------
  26. #include "encodertypeentry.h" // I WANNA BE FIRST!
  27. #include <math.h>
  28. #include <limits.h>
  29. #include "wwdebug.h"
  30. #include "miscutil.h"
  31. #include "mathutil.h"
  32. static const int MAX_BITS = 32;
  33. //-----------------------------------------------------------------------------
  34. cEncoderTypeEntry::cEncoderTypeEntry()
  35. {
  36. Invalidate();
  37. }
  38. //-----------------------------------------------------------------------------
  39. bool cEncoderTypeEntry::Is_Valid() const
  40. {
  41. return
  42. ((Max - Min > -MISCUTIL_EPSILON) &&
  43. (Resolution > -MISCUTIL_EPSILON) &&
  44. (BitPrecision >= 0));
  45. }
  46. //-----------------------------------------------------------------------------
  47. void cEncoderTypeEntry::Invalidate()
  48. {
  49. Min = 1;
  50. Max = -1;
  51. Resolution = -1;
  52. BitPrecision = 0;
  53. }
  54. //-----------------------------------------------------------------------------
  55. bool cEncoderTypeEntry::Is_Value_In_Range(double value) const
  56. {
  57. return (value >= Min - MISCUTIL_EPSILON && value <= Max + MISCUTIL_EPSILON);
  58. }
  59. //-----------------------------------------------------------------------------
  60. void cEncoderTypeEntry::Init(double min, double max, double resolution)
  61. {
  62. WWASSERT(!Is_Valid());
  63. WWASSERT(max - min > -MISCUTIL_EPSILON);
  64. WWASSERT(resolution > MISCUTIL_EPSILON);
  65. Min = min;
  66. Max = max;
  67. Calc_Bit_Precision(resolution);
  68. WWASSERT(Is_Valid());
  69. }
  70. //-----------------------------------------------------------------------------
  71. void cEncoderTypeEntry::Init(int num_bits)
  72. {
  73. WWASSERT(!Is_Valid());
  74. WWASSERT(num_bits > 0 && num_bits <= 32);
  75. Min = 0;
  76. BitPrecision = num_bits;
  77. Resolution = 1;
  78. UINT max = 0;
  79. for (int i = 0; i < num_bits; i++) {
  80. max += 1 << i;
  81. }
  82. Max = max;
  83. WWASSERT(Is_Valid());
  84. }
  85. //-----------------------------------------------------------------------------
  86. bool cEncoderTypeEntry::Scale(double value, ULONG & scaled_value)
  87. {
  88. WWASSERT(Is_Valid());
  89. bool is_in_range = Is_Value_In_Range(value);
  90. if (!is_in_range) {
  91. value = Clamp(value);
  92. }
  93. scaled_value = static_cast<ULONG>
  94. (cMathUtil::Round((value - Min) / Resolution));
  95. return is_in_range;
  96. }
  97. //-----------------------------------------------------------------------------
  98. double cEncoderTypeEntry::Unscale(ULONG u_value)
  99. {
  100. WWASSERT(Is_Valid());
  101. double value = Min + u_value * Resolution;
  102. WWASSERT(Is_Value_In_Range(value));
  103. return value;
  104. }
  105. //-----------------------------------------------------------------------------
  106. double cEncoderTypeEntry::Clamp(double value)
  107. {
  108. WWASSERT(Is_Valid());
  109. double retval = value;
  110. if (retval < Min) {
  111. retval = Min;
  112. } else if (retval > Max) {
  113. retval = Max;
  114. }
  115. return retval;
  116. }
  117. //-----------------------------------------------------------------------------
  118. void cEncoderTypeEntry::Calc_Bit_Precision(double resolution)
  119. {
  120. //
  121. // Calculate the minimum number of bits required to encode this type with
  122. // the specified resolution.
  123. //
  124. WWASSERT(Max - Min > -MISCUTIL_EPSILON);
  125. WWASSERT(resolution > MISCUTIL_EPSILON);
  126. double f_units = (double) ceil((Max - Min) / resolution - MISCUTIL_EPSILON) + 1;
  127. WWASSERT(f_units <= UINT_MAX + MISCUTIL_EPSILON);
  128. UINT units = (UINT) f_units;
  129. BitPrecision = 0;
  130. UINT max_units = 0;
  131. while (max_units < units) {
  132. max_units += 1 << BitPrecision;
  133. BitPrecision++;
  134. if (BitPrecision == 1) {
  135. max_units++;
  136. }
  137. }
  138. WWASSERT(BitPrecision > 0 && BitPrecision <= MAX_BITS);
  139. WWASSERT(max_units > 0);
  140. Resolution = (Max - Min) / (double) (max_units - 1);
  141. /*TSS2001
  142. if (Resolution > 0) {
  143. WWASSERT(max_units ==
  144. (UINT) ceil((Max - Min) / Resolution - MISCUTIL_EPSILON) + 1);
  145. }
  146. */
  147. }