Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
fixed.cpp
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/Code/Library/FIXED.CPP 2 10/05/98 3:30p 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.CPP *
27 * *
28 * Programmer : Joe L. Bostic *
29 * *
30 * Start Date : 06/20/96 *
31 * *
32 * Last Update : July 3, 1996 [JLB] *
33 * *
34 *---------------------------------------------------------------------------------------------*
35 * Functions: *
36 * fixed::As_ASCII -- Returns a pointer (static) of this number as an ASCII string. *
37 * fixed::To_ASCII -- Convert a fixed point number into an ASCII string. *
38 * fixed::fixed -- Constructor for fixed integral from ASCII initializer. *
39 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
40
41#include "fixed.h"
42#include <string.h>
43#include <stdlib.h>
44#include <stdio.h>
45#include <ctype.h>
46
47
48/*
49** These are some handy fixed point constants. Using these constants instead of manually
50** constructing them is not only faster, but more readable.
51*/
52const fixed fixed::_1_2(1, 2); // 1/2
53const fixed fixed::_1_3(1, 3); // 1/3
54const fixed fixed::_1_4(1, 4); // 1/4
55const fixed fixed::_3_4(3, 4); // 3/4
56const fixed fixed::_2_3(2, 3); // 2/3
57
58
59fixed::fixed(int numerator, int denominator)
60{
61 if (denominator == 0) {
62 Data.Raw = 0;
63 } else {
64 Data.Raw = (unsigned short)((unsigned)(numerator * 256) / (unsigned)denominator);
65 }
66}
67
68
69/***********************************************************************************************
70 * fixed::fixed -- Constructor for fixed integral from ASCII initializer. *
71 * *
72 * This will parse the ASCII initialization string into a fixed point number. *
73 * The source string can be a conventional fixed point representation (e.g., "1.0", ".25") *
74 * or a percent value (e.g. "100%", "25%", "150%"). For percent values, the trailing "%" *
75 * is required. *
76 * *
77 * INPUT: ascii -- Pointer to the ascii source to translate into a fixed point number. *
78 * *
79 * OUTPUT: none *
80 * *
81 * WARNINGS: It is possible to specify an ASCII string that has more precision and *
82 * magnitude than can be represented by the fixed point number. In such a case, *
83 * the resulting value is undefined. *
84 * *
85 * HISTORY: *
86 * 06/20/1996 JLB : Created. *
87 *=============================================================================================*/
88fixed::fixed(char const * ascii)
89{
90 /*
91 ** If there is no valid pointer, then default to zero value. This takes care of any
92 ** compiler confusion that would call this routine when the programmer wanted the
93 ** integer parameter constructor to be called.
94 */
95 if (ascii == NULL) {
96 Data.Raw = 0;
97 return;
98 }
99
100 /*
101 ** The whole part (if any) always starts with the first legal characters.
102 */
103 char const * wholepart = ascii;
104
105 /*
106 ** Skip any leading white space.
107 */
108 while (isspace(*ascii)) {
109 ascii++;
110 }
111
112 /*
113 ** Determine if the number is expressed as a percentage. Detect this by
114 ** seeing if there is a trailing "%" character.
115 */
116 char const * tptr = ascii;
117 while (isdigit(*tptr)) {
118 tptr++;
119 }
120
121 /*
122 ** Percentage value is specified as a whole number but is presumed to be
123 ** divided by 100 to get mathematical fixed point percentage value.
124 */
125 if (*tptr == '%') {
126 Data.Raw = (unsigned short)((atoi(ascii) * 256) / 100);
127 } else {
128
129 Data.Composite.Whole = Data.Composite.Fraction = 0;
130 if (wholepart && *wholepart != '.') {
131 Data.Composite.Whole = (unsigned char)atoi(wholepart);
132 }
133
134 char const * fracpart = strchr(ascii, '.');
135 if (fracpart) fracpart++;
136 if (fracpart) {
137 int frac = atoi(fracpart);
138
139// int len = 0;
140 int base = 1;
141 char const * fptr = fracpart;
142 while (isdigit(*fptr)) {
143 fptr++;
144// len++;
145 base *= 10;
146 }
147
148 Data.Composite.Fraction = (unsigned char)((256 * frac) / base);
149 }
150 }
151}
152
153
154/***********************************************************************************************
155 * fixed::To_ASCII -- Convert a fixed point number into an ASCII string. *
156 * *
157 * Use this routine to convert this fixed point number into an ASCII null terminated *
158 * string. This is the counterpart to the fixed point constructor that takes an ASCII *
159 * string. *
160 * *
161 * INPUT: buffer -- Pointer to the buffer to hold the fixed point ASCII string. *
162 * *
163 * maxlen -- The length of the buffer. *
164 * *
165 * OUTPUT: Returns with the number of characters placed in the buffer. The trailing null is *
166 * not counted in this total. *
167 * *
168 * WARNINGS: none *
169 * *
170 * HISTORY: *
171 * 07/03/1996 JLB : Created. *
172 *=============================================================================================*/
173int fixed::To_ASCII(char * buffer, int maxlen) const
174{
175 if (buffer == NULL) return(0);
176
177 /*
178 ** Determine the whole and fractional parts of the number. The fractional
179 ** part number is the value in 1000ths.
180 */
181 int whole = Data.Composite.Whole;
182 int frac = ((int)Data.Composite.Fraction * 1000) / 256;
183 char tbuffer[32];
184
185 /*
186 ** If there number consists only of a whole part, then the number is simply
187 ** printed into the buffer. If there is a fractional part, then there
188 ** will be a decimal place followed by up to three digits of accuracy for the
189 ** fractional component.
190 */
191 if (frac == 0) {
192 sprintf(tbuffer, "%d", whole);
193 } else {
194 sprintf(tbuffer, "%d.%02d", whole, frac);
195
196 char * ptr = &tbuffer[strlen(tbuffer)-1];
197 while (*ptr == '0') {
198 *ptr = '\0';
199 ptr--;
200 }
201 }
202
203 /*
204 ** If no maximum length to the output buffer was specified, then presume the
205 ** output buffer is just long enough to store the number and the trailing
206 ** zero.
207 */
208 if (maxlen == -1) {
209 maxlen = strlen(tbuffer)+1;
210 }
211
212 /*
213 ** Fill the output buffer with the ASCII number.
214 */
215 strncpy(buffer, tbuffer, maxlen);
216
217 /*
218 ** Return with the number of ASCII characters placed into the output buffer.
219 */
220 int len = strlen(tbuffer);
221 if (len < maxlen-1) return(len);
222 return(maxlen-1);
223}
224
225
226/***********************************************************************************************
227 * fixed::As_ASCII -- Returns a pointer (static) of this number as an ASCII string. *
228 * *
229 * This number will be converted into an ASCII string (using a static buffer) and the *
230 * string pointer will be returned. *
231 * *
232 * INPUT: none *
233 * *
234 * OUTPUT: Returns with a pointer to the ASCII representation of this fixed point number. *
235 * *
236 * WARNINGS: As with all static return pointers, the pointer is valid only until such time *
237 * as this routine is called again. *
238 * *
239 * HISTORY: *
240 * 07/03/1996 JLB : Created. *
241 *=============================================================================================*/
242char const * fixed::As_ASCII(void) const
243{
244 static char buffer[32];
245
246 To_ASCII(buffer, sizeof(buffer));
247 return(buffer);
248}
#define NULL
Definition BaseType.h:92
Definition fixed.h:73
int To_ASCII(char *buffer, int maxlen=-1) const
Definition fixed.cpp:173
static const fixed _1_2
Definition fixed.h:198
static const fixed _2_3
Definition fixed.h:202
static const fixed _1_4
Definition fixed.h:200
fixed(void)
Definition fixed.h:76
static const fixed _1_3
Definition fixed.h:199
static const fixed _3_4
Definition fixed.h:201
char const * As_ASCII(void) const
Definition fixed.cpp:242