Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
fixed.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(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/* $Header: /Commando/Library/FIXED.H 1 7/22/97 12:00p Greg_h $ */
20/***********************************************************************************************
21 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
22 ***********************************************************************************************
23 * *
24 * Project Name : Command & Conquer *
25 * *
26 * File Name : FIXED.H *
27 * *
28 * Programmer : Joe L. Bostic *
29 * *
30 * Start Date : 06/19/96 *
31 * *
32 * Last Update : June 19, 1996 [JLB] *
33 * *
34 *---------------------------------------------------------------------------------------------*
35 * Functions: *
36 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
37
38
39#ifndef FIXED_H
40#define FIXED_H
41
42#include "bool.h"
43//#pragma warning 604 9
44//#pragma warning 595 9
45
46/*
47** This is a very simple fixed point class that functions like a regular integral type. However
48** it is under certain restrictions. The whole part must not exceed 255. The fractional part is
49** limited to an accuracy of 1/256. It cannot represent or properly handle negative values. It
50** really isn't all that fast (if an FPU is guaranteed to be present than using "float" might be
51** more efficient). It doesn't detect overflow or underflow in mathematical or bit-shift operations.
52**
53** Take careful note that the normal mathematical operators return integers and not fixed point
54** values if either of the components is an integer. This is the normal C auto-upcasting rule
55** as it would apply presuming that integers are considered to be of higher precision than
56** fixed point numbers. This allows the result of these operators to generate values with greater
57** magnitude than is normally possible if the result were coerced into a fixed point number.
58** If the result should be fixed point, then ensure that both parameters are fixed point.
59**
60** Note that although integers are used as the parameters in the mathematical operators, this
61** does not imply that negative parameters are supported. The use of integers is as a convenience
62** to the programmer -- constant integers are presumed signed. If unsigned parameters were
63** specified, then the compiler would have ambiguous conversion situation in the case of constant
64** integers (e.g. 1, 10, 32, etc). This is most important for the constructor when dealing with the
65** "0" parameter case. In that situation the compiler might interpret the "0" as a null pointer rather
66** than an unsigned integer. There should be no adverse consequences of using signed integer parameters
67** since the precision/magnitude of these integers far exceeds the fixed point component counterparts.
68**
69** Note that when integer values are returns from the arithmetic operators, the value is rounded
70** to the nearest whole integer value. This differs from normal integer math that always rounds down.
71*/
72class fixed
73{
74 public:
75 // The default constructor must not touch the data members in any way.
76 fixed(void) {}
77
78 // Convenient constructor if numerator and denominator components are known.
79 fixed(int numerator, int denominator);
80
81 // Conversion constructor to get fixed point from integer.
82 fixed(int value) {Data.Composite.Fraction = 0;Data.Composite.Whole = (unsigned char)value;}
83
84 // Constructor if ASCII image of number is known.
85 fixed(char const * ascii);
86
87 // Convert to integer when implicitly required.
88 operator unsigned (void) const {return(((unsigned)Data.Raw+(256/2)) / 256);}
89
90 /*
91 ** The standard operators as they apply to in-place operation.
92 */
93 fixed & operator *= (fixed const & rvalue) {Data.Raw = (unsigned short)(((int)Data.Raw * rvalue.Data.Raw) / 256);return(*this);}
94 fixed & operator *= (int rvalue) {Data.Raw = (unsigned short)(Data.Raw * rvalue);return(*this);}
95 fixed & operator /= (fixed const & rvalue) {if (rvalue.Data.Raw != 0 && rvalue.Data.Raw != 256) Data.Raw = (unsigned short)(((int)Data.Raw * 256) / rvalue);return(*this);}
96 fixed & operator /= (int rvalue) {if (rvalue) Data.Raw = (unsigned short)((unsigned)Data.Raw / rvalue);return(*this);}
97 fixed & operator += (fixed const & rvalue) {Data.Raw += rvalue.Data.Raw;return(*this);}
98 fixed & operator -= (fixed const & rvalue) {Data.Raw -= rvalue.Data.Raw;return(*this);}
99
100 /*
101 ** The standard "My Dear Aunt Sally" operators. The integer versions of multiply
102 ** and divide are more efficient than using the fixed point counterparts.
103 */
104// const fixed operator * (fixed const & rvalue) const {return(fixed(*this) *= rvalue);}
105 const fixed operator * (fixed const & rvalue) const {fixed temp = *this;temp.Data.Raw = (unsigned short)(((int)temp.Data.Raw * (int)rvalue.Data.Raw) / 256);return(temp);}
106 const int operator * (int rvalue) const {return ((((unsigned)Data.Raw * rvalue) + (256/2)) / 256);}
107// const fixed operator / (fixed const & rvalue) const {return(fixed(*this) /= rvalue);}
108 const fixed operator / (fixed const & rvalue) const {fixed temp = *this;if (rvalue.Data.Raw != 0 && rvalue.Data.Raw != 256) temp.Data.Raw = (unsigned short)(((int)temp.Data.Raw * 256) / rvalue.Data.Raw);return(temp);}
109 const int operator / (int rvalue) const {if (rvalue) return(((unsigned)Data.Raw+(256/2)) / ((unsigned)rvalue*256));return(*this);}
110// const fixed operator + (fixed const & rvalue) const {return(fixed(*this) += rvalue);}
111 const fixed operator + (fixed const & rvalue) const {fixed temp = *this;temp += rvalue;return(temp);}
112 const int operator + (int rvalue) const {return((((unsigned)Data.Raw+(256/2))/256) + rvalue);}
113// const fixed operator - (fixed const & rvalue) const {return(fixed(*this) -= rvalue);}
114 const fixed operator - (fixed const & rvalue) const {fixed temp = *this;temp -= rvalue;return(temp);}
115 const int operator - (int rvalue) const {return((((unsigned)Data.Raw+(256/2))/256) - rvalue);}
116
117 /*
118 ** The Shift operators are more efficient than using multiplies or divides by power-of-2 numbers.
119 */
120 fixed & operator >>= (unsigned rvalue) {Data.Raw >>= rvalue;return(*this);}
121 fixed & operator <<= (unsigned rvalue) {Data.Raw <<= rvalue;return(*this);}
122 const fixed operator >> (unsigned rvalue) const {fixed temp = *this;temp >>= rvalue;return(temp);}
123 const fixed operator << (unsigned rvalue) const {fixed temp = *this;temp <<= rvalue;return(temp);}
124
125 /*
126 ** The full set of comparison operators.
127 */
128 bool operator == (fixed const & rvalue) const {return(Data.Raw == rvalue.Data.Raw);}
129 bool operator != (fixed const & rvalue) const {return(Data.Raw != rvalue.Data.Raw);}
130 bool operator < (fixed const & rvalue) const {return(Data.Raw < rvalue.Data.Raw);}
131 bool operator > (fixed const & rvalue) const {return(Data.Raw > rvalue.Data.Raw);}
132 bool operator <= (fixed const & rvalue) const {return(Data.Raw <= rvalue.Data.Raw);}
133 bool operator >= (fixed const & rvalue) const {return(Data.Raw >= rvalue.Data.Raw);}
134 bool operator ! (void) const {return(Data.Raw == 0);}
135
136 /*
137 ** Comparison to integers requires consideration of fractional component.
138 */
139 bool operator < (int rvalue) const {return(Data.Raw < (rvalue*256));}
140 bool operator > (int rvalue) const {return(Data.Raw > (rvalue*256));}
141 bool operator <= (int rvalue) const {return(Data.Raw <= (rvalue*256));}
142 bool operator >= (int rvalue) const {return(Data.Raw >= (rvalue*256));}
143 bool operator == (int rvalue) const {return(Data.Raw == (rvalue*256));}
144 bool operator != (int rvalue) const {return(Data.Raw != (rvalue*256));}
145
146 /*
147 ** Friend functions to handle the alternate positioning of fixed and integer parameters.
148 */
149 friend const int operator * (int lvalue, fixed const & rvalue) {return(rvalue * lvalue);}
150 friend const int operator / (int lvalue, fixed const & rvalue) {if (rvalue.Data.Raw == 0 || rvalue.Data.Raw == 256) return (lvalue); return(((unsigned)(lvalue * 256)+(256/2)) / rvalue.Data.Raw);}
151 friend const int operator + (int lvalue, fixed const & rvalue) {return(rvalue + lvalue);}
152 friend const int operator - (int lvalue, fixed const & rvalue) {return((((lvalue*256) - rvalue.Data.Raw) + (256/2)) / 256);}
153 friend bool operator < (unsigned lvalue, fixed const & rvalue) {return((lvalue*256) < rvalue.Data.Raw);}
154 friend bool operator > (unsigned lvalue, fixed const & rvalue) {return((lvalue*256) > rvalue.Data.Raw);}
155 friend bool operator <= (unsigned lvalue, fixed const & rvalue) {return((lvalue*256) <= rvalue.Data.Raw);}
156 friend bool operator >= (unsigned lvalue, fixed const & rvalue) {return((lvalue*256) >= rvalue.Data.Raw);}
157 friend bool operator == (unsigned lvalue, fixed const & rvalue) {return((lvalue*256) == rvalue.Data.Raw);}
158 friend bool operator != (unsigned lvalue, fixed const & rvalue) {return((lvalue*256) != rvalue.Data.Raw);}
159 friend int operator *= (int & lvalue, fixed const & rvalue) {lvalue = lvalue * rvalue;return(lvalue);}
160 friend int operator /= (int & lvalue, fixed const & rvalue) {lvalue = lvalue / rvalue;return(lvalue);}
161 friend int operator += (int & lvalue, fixed const & rvalue) {lvalue = lvalue + rvalue;return(lvalue);}
162 friend int operator -= (int & lvalue, fixed const & rvalue) {lvalue = lvalue - rvalue;return(lvalue);}
163
164 /*
165 ** Helper functions to handle simple and common operations on fixed point numbers.
166 */
167 void Round_Up(void) {Data.Raw += (unsigned short)(256-1);Data.Composite.Fraction = 0;}
168 void Round_Down(void) {Data.Composite.Fraction = 0;}
169 void Round(void) {if (Data.Composite.Fraction >= 256/2) Round_Up();Round_Down();}
170 void Saturate(unsigned capvalue) {if (Data.Raw > (capvalue*256)) Data.Raw = (unsigned short)(capvalue*256);}
171 void Saturate(fixed const & capvalue) {if (*this > capvalue) *this = capvalue;}
172 void Sub_Saturate(unsigned capvalue) {if (Data.Raw >= (capvalue*256)) Data.Raw = (unsigned short)((capvalue*256)-1);}
173 void Sub_Saturate(fixed const & capvalue) {if (*this >= capvalue) Data.Raw = (unsigned short)(capvalue.Data.Raw-1);}
174 void Inverse(void) {*this = fixed(1) / *this;}
175
176 /*
177 ** Friend helper functions that work in the typical C fashion of passing the object to
178 ** be processed as a parameter to the function.
179 */
180 friend const fixed Round_Up(fixed const & value) {fixed temp = value; temp.Round_Up();return(temp);}
181 friend const fixed Round_Down(fixed const & value) {fixed temp = value; temp.Round_Down();return(temp);}
182 friend const fixed Round(fixed const & value) {fixed temp = value; temp.Round();return(temp);}
183 friend const fixed Saturate(fixed const & value, unsigned capvalue) {fixed temp = value;temp.Saturate(capvalue);return(temp);}
184 friend const fixed Saturate(fixed const & value, fixed const & capvalue) {fixed temp = value;temp.Saturate(capvalue);return(temp);}
185 friend const fixed Sub_Saturate(fixed const & value, unsigned capvalue) {fixed temp = value;temp.Sub_Saturate(capvalue);return(temp);}
186 friend const fixed Sub_Saturate(fixed const & value, fixed const & capvalue) {fixed temp = value;temp.Sub_Saturate(capvalue);return(temp);}
187 friend const fixed Inverse(fixed const & value) {fixed temp = value;temp.Inverse();return(temp);}
188
189 /*
190 ** Conversion of the fixed point number into an ASCII string.
191 */
192 int To_ASCII(char * buffer, int maxlen=-1) const;
193 char const * As_ASCII(void) const;
194
195 /*
196 ** Helper constants that provide some convenient fixed point values.
197 */
198 static const fixed _1_2;
199 static const fixed _1_3;
200 static const fixed _1_4;
201 static const fixed _3_4;
202 static const fixed _2_3;
203
204 private:
205 union {
206 struct {
207#ifdef BIG_ENDIAN
208 unsigned char Whole;
209 unsigned char Fraction;
210#else
211 unsigned char Fraction;
212 unsigned char Whole;
213#endif
215 unsigned short Raw;
216 } Data;
217};
218
219
220#endif
void const char * value
const fixed operator<<(unsigned rvalue) const
Definition fixed.h:123
bool operator<=(fixed const &rvalue) const
Definition fixed.h:132
bool operator>=(fixed const &rvalue) const
Definition fixed.h:133
int To_ASCII(char *buffer, int maxlen=-1) const
Definition fixed.cpp:173
bool operator!=(fixed const &rvalue) const
Definition fixed.h:129
void Saturate(fixed const &capvalue)
Definition fixed.h:171
const fixed operator>>(unsigned rvalue) const
Definition fixed.h:122
const fixed operator-(fixed const &rvalue) const
Definition fixed.h:114
friend const fixed Round(fixed const &value)
Definition fixed.h:182
bool operator==(fixed const &rvalue) const
Definition fixed.h:128
bool operator<(fixed const &rvalue) const
Definition fixed.h:130
fixed(int value)
Definition fixed.h:82
friend const fixed Inverse(fixed const &value)
Definition fixed.h:187
friend const fixed Sub_Saturate(fixed const &value, fixed const &capvalue)
Definition fixed.h:186
static const fixed _1_2
Definition fixed.h:198
fixed & operator<<=(unsigned rvalue)
Definition fixed.h:121
static const fixed _2_3
Definition fixed.h:202
fixed & operator-=(fixed const &rvalue)
Definition fixed.h:98
unsigned short Raw
Definition fixed.h:215
void Round(void)
Definition fixed.h:169
fixed & operator>>=(unsigned rvalue)
Definition fixed.h:120
static const fixed _1_4
Definition fixed.h:200
unsigned char Fraction
Definition fixed.h:211
unsigned char Whole
Definition fixed.h:212
bool operator!(void) const
Definition fixed.h:134
fixed & operator*=(fixed const &rvalue)
Definition fixed.h:93
friend const fixed Saturate(fixed const &value, fixed const &capvalue)
Definition fixed.h:184
fixed(void)
Definition fixed.h:76
const fixed operator+(fixed const &rvalue) const
Definition fixed.h:111
void Round_Up(void)
Definition fixed.h:167
fixed & operator/=(fixed const &rvalue)
Definition fixed.h:95
void Round_Down(void)
Definition fixed.h:168
void Saturate(unsigned capvalue)
Definition fixed.h:170
void Sub_Saturate(unsigned capvalue)
Definition fixed.h:172
const fixed operator*(fixed const &rvalue) const
Definition fixed.h:105
void Inverse(void)
Definition fixed.h:174
friend const fixed Round_Down(fixed const &value)
Definition fixed.h:181
bool operator>(fixed const &rvalue) const
Definition fixed.h:131
void Sub_Saturate(fixed const &capvalue)
Definition fixed.h:173
static const fixed _1_3
Definition fixed.h:199
struct fixed::@141331102007176150364077173260123361077306114004::@374377020112267201331161232154127230072223061360 Composite
fixed & operator+=(fixed const &rvalue)
Definition fixed.h:97
static const fixed _3_4
Definition fixed.h:201
char const * As_ASCII(void) const
Definition fixed.cpp:242
friend const fixed Saturate(fixed const &value, unsigned capvalue)
Definition fixed.h:183
friend const fixed Sub_Saturate(fixed const &value, unsigned capvalue)
Definition fixed.h:185
friend const fixed Round_Up(fixed const &value)
Definition fixed.h:180
const fixed operator/(fixed const &rvalue) const
Definition fixed.h:108