| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- //
- // Filename: encodertypeentry.cpp
- // Project: wwbitpack.lib
- // Author: Tom Spencer-Smith
- // Date: June 2000
- // Description:
- //
- //-----------------------------------------------------------------------------
- #include "encodertypeentry.h" // I WANNA BE FIRST!
- #include <math.h>
- #include <limits.h>
- #include "wwdebug.h"
- #include "miscutil.h"
- #include "mathutil.h"
- static const int MAX_BITS = 32;
- //-----------------------------------------------------------------------------
- cEncoderTypeEntry::cEncoderTypeEntry()
- {
- Invalidate();
- }
- //-----------------------------------------------------------------------------
- bool cEncoderTypeEntry::Is_Valid() const
- {
- return
- ((Max - Min > -MISCUTIL_EPSILON) &&
- (Resolution > -MISCUTIL_EPSILON) &&
- (BitPrecision >= 0));
- }
- //-----------------------------------------------------------------------------
- void cEncoderTypeEntry::Invalidate()
- {
- Min = 1;
- Max = -1;
- Resolution = -1;
- BitPrecision = 0;
- }
- //-----------------------------------------------------------------------------
- bool cEncoderTypeEntry::Is_Value_In_Range(double value) const
- {
- return (value >= Min - MISCUTIL_EPSILON && value <= Max + MISCUTIL_EPSILON);
- }
- //-----------------------------------------------------------------------------
- void cEncoderTypeEntry::Init(double min, double max, double resolution)
- {
- WWASSERT(!Is_Valid());
- WWASSERT(max - min > -MISCUTIL_EPSILON);
- WWASSERT(resolution > MISCUTIL_EPSILON);
- Min = min;
- Max = max;
- Calc_Bit_Precision(resolution);
- WWASSERT(Is_Valid());
- }
- //-----------------------------------------------------------------------------
- void cEncoderTypeEntry::Init(int num_bits)
- {
- WWASSERT(!Is_Valid());
- WWASSERT(num_bits > 0 && num_bits <= 32);
- Min = 0;
- BitPrecision = num_bits;
- Resolution = 1;
- UINT max = 0;
- for (int i = 0; i < num_bits; i++) {
- max += 1 << i;
- }
- Max = max;
- WWASSERT(Is_Valid());
- }
- //-----------------------------------------------------------------------------
- bool cEncoderTypeEntry::Scale(double value, ULONG & scaled_value)
- {
- WWASSERT(Is_Valid());
- bool is_in_range = Is_Value_In_Range(value);
- if (!is_in_range) {
- value = Clamp(value);
- }
- scaled_value = static_cast<ULONG>
- (cMathUtil::Round((value - Min) / Resolution));
- return is_in_range;
- }
- //-----------------------------------------------------------------------------
- double cEncoderTypeEntry::Unscale(ULONG u_value)
- {
- WWASSERT(Is_Valid());
- double value = Min + u_value * Resolution;
- WWASSERT(Is_Value_In_Range(value));
- return value;
- }
- //-----------------------------------------------------------------------------
- double cEncoderTypeEntry::Clamp(double value)
- {
- WWASSERT(Is_Valid());
- double retval = value;
-
- if (retval < Min) {
- retval = Min;
- } else if (retval > Max) {
- retval = Max;
- }
- return retval;
- }
- //-----------------------------------------------------------------------------
- void cEncoderTypeEntry::Calc_Bit_Precision(double resolution)
- {
- //
- // Calculate the minimum number of bits required to encode this type with
- // the specified resolution.
- //
- WWASSERT(Max - Min > -MISCUTIL_EPSILON);
- WWASSERT(resolution > MISCUTIL_EPSILON);
- double f_units = (double) ceil((Max - Min) / resolution - MISCUTIL_EPSILON) + 1;
- WWASSERT(f_units <= UINT_MAX + MISCUTIL_EPSILON);
- UINT units = (UINT) f_units;
- BitPrecision = 0;
- UINT max_units = 0;
- while (max_units < units) {
- max_units += 1 << BitPrecision;
- BitPrecision++;
- if (BitPrecision == 1) {
- max_units++;
- }
- }
- WWASSERT(BitPrecision > 0 && BitPrecision <= MAX_BITS);
- WWASSERT(max_units > 0);
- Resolution = (Max - Min) / (double) (max_units - 1);
- /*TSS2001
- if (Resolution > 0) {
- WWASSERT(max_units ==
- (UINT) ceil((Max - Min) / Resolution - MISCUTIL_EPSILON) + 1);
- }
- */
- }
|