author | koda |
Thu, 24 Nov 2011 16:18:45 +0100 | |
changeset 6415 | af2047bb4f70 |
parent 6328 | d14adf1c7721 |
child 6443 | 23364a5fcc86 |
permissions | -rw-r--r-- |
351 | 1 |
(* |
1066 | 2 |
* Hedgewars, a free turn based strategy game |
4976 | 3 |
* Copyright (c) 2004-2011 Andrey Korotaev <unC0Rr@gmail.com> |
351 | 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; version 2 of the License |
|
8 |
* |
|
9 |
* This program is distributed in the hope that it will be useful, |
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
* GNU General Public License for more details. |
|
13 |
* |
|
14 |
* You should have received a copy of the GNU General Public License |
|
15 |
* along with this program; if not, write to the Free Software |
|
16 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
*) |
|
18 |
||
2630 | 19 |
{$INCLUDE "options.inc"} |
20 |
||
351 | 21 |
unit uFloat; |
5122 | 22 |
(* |
23 |
* This unit provides a custom data type, hwFloat. |
|
24 |
* |
|
25 |
* hwFloat represents a floating point number - the value and operations |
|
26 |
* of this numbers are independent from the hardware architecture |
|
27 |
* the game runs on. |
|
28 |
* |
|
29 |
* This is important for calculations that affect the course of the game |
|
30 |
* and would lead to different results if based on a hardware dependent |
|
31 |
* data type. |
|
32 |
* |
|
33 |
* Note: Not all comparisons are implemented. |
|
34 |
* |
|
35 |
* Note: Below you'll find a list of hwFloat constants: |
|
36 |
* E.g. _1 is an hwFloat with value 1.0, and -_0_9 is -0.9 |
|
5124 | 37 |
* Use and extend the list if needed, rather than using int2hwFloat() |
38 |
* with integer constants. |
|
5122 | 39 |
*) |
351 | 40 |
interface |
41 |
||
42 |
{$IFDEF FPC} |
|
2599 | 43 |
{$IFDEF ENDIAN_LITTLE} |
351 | 44 |
type hwFloat = record |
45 |
isNegative: boolean; |
|
46 |
case byte of |
|
47 |
0: (Frac, Round: Longword); |
|
48 |
1: (QWordValue : QWord); |
|
49 |
end; |
|
2599 | 50 |
{$ELSE} |
351 | 51 |
type hwFloat = record |
52 |
isNegative: boolean; |
|
53 |
case byte of |
|
54 |
0: (Round, Frac: Longword); |
|
55 |
1: (QWordValue : QWord); |
|
56 |
end; |
|
2599 | 57 |
{$ENDIF} |
351 | 58 |
|
5122 | 59 |
// Returns an hwFloat that represents the value of integer parameter i |
3599 | 60 |
function int2hwFloat (const i: LongInt) : hwFloat; inline; |
5151
cbadb9fa52fc
An experiment - make bazooka AI use float instead of hwFloat - should be as accurate, but faster.
nemo
parents:
5124
diff
changeset
|
61 |
function hwFloat2Float (const i: hwFloat) : extended; inline; |
351 | 62 |
|
5122 | 63 |
// The implemented operators |
64 |
||
6415 | 65 |
operator = (const z1, z2: hwFloat) z : boolean; inline; |
3599 | 66 |
operator + (const z1, z2: hwFloat) z : hwFloat; inline; |
67 |
operator - (const z1, z2: hwFloat) z : hwFloat; inline; |
|
3929
9a4bbc1f67a2
Inline most of uFloat (saves ~7.5% opcount on a test game), inline a few very short candidates in uMisc, comment out some unused functions in uMisc
nemo
parents:
3599
diff
changeset
|
68 |
operator - (const z1: hwFloat) z : hwFloat; inline; |
351 | 69 |
|
3929
9a4bbc1f67a2
Inline most of uFloat (saves ~7.5% opcount on a test game), inline a few very short candidates in uMisc, comment out some unused functions in uMisc
nemo
parents:
3599
diff
changeset
|
70 |
operator * (const z1, z2: hwFloat) z : hwFloat; inline; |
3599 | 71 |
operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
3929
9a4bbc1f67a2
Inline most of uFloat (saves ~7.5% opcount on a test game), inline a few very short candidates in uMisc, comment out some unused functions in uMisc
nemo
parents:
3599
diff
changeset
|
72 |
operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline; |
9a4bbc1f67a2
Inline most of uFloat (saves ~7.5% opcount on a test game), inline a few very short candidates in uMisc, comment out some unused functions in uMisc
nemo
parents:
3599
diff
changeset
|
73 |
operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
351 | 74 |
|
3929
9a4bbc1f67a2
Inline most of uFloat (saves ~7.5% opcount on a test game), inline a few very short candidates in uMisc, comment out some unused functions in uMisc
nemo
parents:
3599
diff
changeset
|
75 |
operator < (const z1, z2: hwFloat) b : boolean; inline; |
9a4bbc1f67a2
Inline most of uFloat (saves ~7.5% opcount on a test game), inline a few very short candidates in uMisc, comment out some unused functions in uMisc
nemo
parents:
3599
diff
changeset
|
76 |
operator > (const z1, z2: hwFloat) b : boolean; inline; |
351 | 77 |
|
5122 | 78 |
|
79 |
// Various functions for hwFloat (some are inlined in the resulting code for better performance) |
|
80 |
||
81 |
function cstr(const z: hwFloat): shortstring; // Returns a shortstring representations of the hwFloat. |
|
82 |
function hwRound(const t: hwFloat): LongInt; inline; // Does NOT really round but returns the integer representation of the hwFloat without fractional digits. (-_0_9 -> -0, _1_5 -> _1) |
|
83 |
function hwAbs(const t: hwFloat): hwFloat; inline; // Returns the value of t with positive sign. |
|
84 |
function hwSqr(const t: hwFloat): hwFloat; inline; // Returns the square value of parameter t. |
|
85 |
function hwSqrt(const t: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t. |
|
86 |
function Distance(const dx, dy: hwFloat): hwFloat; // Returns the distance between two points in 2-dimensional space, of which the parameters are the horizontal and vertical distance. |
|
87 |
function DistanceI(const dx, dy: LongInt): hwFloat; // Same as above for integer parameters. |
|
515 | 88 |
function AngleSin(const Angle: Longword): hwFloat; |
89 |
function AngleCos(const Angle: Longword): hwFloat; |
|
5122 | 90 |
function SignAs(const num, signum: hwFloat): hwFloat; inline; // Returns an hwFloat with the value of parameter num and the sign of signum. |
91 |
function hwSign(r: hwFloat): LongInt; inline; // Returns an integer with value 1 and sign of parameter r. |
|
5599
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
92 |
function isZero(const z: hwFloat): boolean; inline; |
2599 | 93 |
{$IFDEF FPC} |
538 | 94 |
{$J-} |
2599 | 95 |
{$ENDIF} |
611 | 96 |
{$WARNINGS OFF} |
5122 | 97 |
|
98 |
||
99 |
// some hwFloat constants |
|
100 |
||
351 | 101 |
const _1div1024: hwFloat = (isNegative: false; QWordValue: 4194304); |
102 |
_1div10000: hwFloat = (isNegative: false; QWordValue: 429496); |
|
103 |
_1div50000: hwFloat = (isNegative: false; QWordValue: 85899); |
|
104 |
_1div100000: hwFloat = (isNegative: false; QWordValue: 42950); |
|
105 |
_1div3: hwFloat = (isNegative: false; QWordValue: 1431655766); |
|
106 |
hwPi: hwFloat = (isNegative: false; QWordValue: 13493037704); |
|
107 |
_0_000004: hwFloat = (isNegative: false; QWordValue: 17179); |
|
3591 | 108 |
_0_000064: hwFloat = (isNegative: false; QWordValue: 274878); |
351 | 109 |
_0_0002: hwFloat = (isNegative: false; QWordValue: 858993); |
1586 | 110 |
_0_0005: hwFloat = (isNegative: false; QWordValue: 2147484); |
351 | 111 |
_0_001: hwFloat = (isNegative: false; QWordValue: 4294967); |
112 |
_0_003: hwFloat = (isNegative: false; QWordValue: 12884902); |
|
113 |
_0_004: hwFloat = (isNegative: false; QWordValue: 17179869); |
|
114 |
_0_005: hwFloat = (isNegative: false; QWordValue: 21474836); |
|
3428 | 115 |
_0_008: hwFloat = (isNegative: false; QWordValue: 34359738); |
351 | 116 |
_0_01: hwFloat = (isNegative: false; QWordValue: 42949673); |
117 |
_0_02: hwFloat = (isNegative: false; QWordValue: 85899345); |
|
118 |
_0_03: hwFloat = (isNegative: false; QWordValue: 128849018); |
|
6295
5b2b304a91ec
Due to the small values and friction, halve the step in low gravity, instead of the value
nemo
parents:
5843
diff
changeset
|
119 |
_0_07: hwFloat = (isNegative: false; QWordValue: 300647710); |
351 | 120 |
_0_08: hwFloat = (isNegative: false; QWordValue: 343597383); |
365 | 121 |
_0_1: hwFloat = (isNegative: false; QWordValue: 429496730); |
351 | 122 |
_0_15: hwFloat = (isNegative: false; QWordValue: 644245094); |
123 |
_0_2: hwFloat = (isNegative: false; QWordValue: 858993459); |
|
124 |
_0_25: hwFloat = (isNegative: false; QWordValue: 1073741824); |
|
125 |
_0_3: hwFloat = (isNegative: false; QWordValue: 1288490189); |
|
126 |
_0_35: hwFloat = (isNegative: false; QWordValue: 1503238553); |
|
2784 | 127 |
_0_375: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 8); |
835
6f567934cc44
Automatically use parachute when vertical speed is high enough
unc0rr
parents:
745
diff
changeset
|
128 |
_0_39: hwFloat = (isNegative: false; QWordValue: 1675037245); |
351 | 129 |
_0_4: hwFloat = (isNegative: false; QWordValue: 1717986918); |
130 |
_0_45: hwFloat = (isNegative: false; QWordValue: 1932735283); |
|
131 |
_0_5: hwFloat = (isNegative: false; QWordValue: 2147483648); |
|
132 |
_0_55: hwFloat = (isNegative: false; QWordValue: 2362232012); |
|
133 |
_0_6: hwFloat = (isNegative: false; QWordValue: 2576980377); |
|
3583 | 134 |
_0_64: hwFloat = (isNegative: false; QWordValue: 2748779064); |
358 | 135 |
_0_7: hwFloat = (isNegative: false; QWordValue: 3006477107); |
351 | 136 |
_0_8: hwFloat = (isNegative: false; QWordValue: 3435973837); |
137 |
_0_84: hwFloat = (isNegative: false; QWordValue: 3607772528); |
|
138 |
_0_87: hwFloat = (isNegative: false; QWordValue: 3736621547); |
|
139 |
_0_9: hwFloat = (isNegative: false; QWordValue: 3865470566); |
|
140 |
_0_93: hwFloat = (isNegative: false; QWordValue: 3994319585); |
|
141 |
_0_96: hwFloat = (isNegative: false; QWordValue: 4123168604); |
|
142 |
_0_995: hwFloat = (isNegative: false; QWordValue: 4273492459); |
|
143 |
_0_999: hwFloat = (isNegative: false; QWordValue: 4290672328); |
|
498 | 144 |
_0: hwFloat = (isNegative: false; QWordValue: 0); |
145 |
_1: hwFloat = (isNegative: false; QWordValue: 4294967296); |
|
513
69e06d710d46
Moving hedgehog could get another hedgehog moving forward
unc0rr
parents:
498
diff
changeset
|
146 |
_1_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3 div 2); |
3584 | 147 |
_1_9: hwFloat = (isNegative: false; QWordValue: 8160437862); |
498 | 148 |
_2: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2); |
149 |
_3: hwFloat = (isNegative: false; QWordValue: 4294967296 * 3); |
|
150 |
_4: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4); |
|
151 |
_5: hwFloat = (isNegative: false; QWordValue: 4294967296 * 5); |
|
152 |
_6: hwFloat = (isNegative: false; QWordValue: 4294967296 * 6); |
|
153 |
_10: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10); |
|
3422
41ae3c48faa0
* some changes/cleanups to portal, still much to do :/ * reverted nemo's temporary loop fix * notice: small loops possible again, so take care :P, bigger onces should be interrupted
sheepluva
parents:
3407
diff
changeset
|
154 |
_12: hwFloat = (isNegative: false; QWordValue: 4294967296 * 12); |
498 | 155 |
_16: hwFloat = (isNegative: false; QWordValue: 4294967296 * 16); |
156 |
_19: hwFloat = (isNegative: false; QWordValue: 4294967296 * 19); |
|
157 |
_20: hwFloat = (isNegative: false; QWordValue: 4294967296 * 20); |
|
158 |
_25: hwFloat = (isNegative: false; QWordValue: 4294967296 * 25); |
|
159 |
_30: hwFloat = (isNegative: false; QWordValue: 4294967296 * 30); |
|
2955
fb361d137524
Tweak to joke in french locale (everyone always fixes the spelling) updated explosive frames from Palewolf, increase explosive fall damage from 30 to 40
nemo
parents:
2948
diff
changeset
|
160 |
_40: hwFloat = (isNegative: false; QWordValue: 4294967296 * 40); |
3036
c6ba6531cb4b
Make barrels a little more likely to blow up. 25% more damage in fall
nemo
parents:
2955
diff
changeset
|
161 |
_50: hwFloat = (isNegative: false; QWordValue: 4294967296 * 50); |
2933 | 162 |
_70: hwFloat = (isNegative: false; QWordValue: 4294967296 * 70); |
5599
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
163 |
_90: hwFloat = (isNegative: false; QWordValue: 4294967296 * 90); |
498 | 164 |
_128: hwFloat = (isNegative: false; QWordValue: 4294967296 * 128); |
5599
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
165 |
_180: hwFloat = (isNegative: false; QWordValue: 4294967296 * 180); |
5319
51d8e4747876
bounce. tweak of values, remove friction modifier, move to weapon, to match timer behaviour
nemo
parents:
5192
diff
changeset
|
166 |
_250: hwFloat = (isNegative: false; QWordValue: 4294967296 * 250); |
1915 | 167 |
_256: hwFloat = (isNegative: false; QWordValue: 4294967296 * 256); |
1124 | 168 |
_300: hwFloat = (isNegative: false; QWordValue: 4294967296 * 300); |
5599
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
169 |
_360: hwFloat = (isNegative: false; QWordValue: 4294967296 * 360); |
498 | 170 |
_450: hwFloat = (isNegative: false; QWordValue: 4294967296 * 450); |
5319
51d8e4747876
bounce. tweak of values, remove friction modifier, move to weapon, to match timer behaviour
nemo
parents:
5192
diff
changeset
|
171 |
_1000: hwFloat = (isNegative: false; QWordValue: 4294967296 * 1000); |
611 | 172 |
_1024: hwFloat = (isNegative: false; QWordValue: 4294967296 * 1024); |
173 |
_2048: hwFloat = (isNegative: false; QWordValue: 4294967296 * 2048); |
|
1753 | 174 |
_4096: hwFloat = (isNegative: false; QWordValue: 4294967296 * 4096); |
498 | 175 |
_10000: hwFloat = (isNegative: false; QWordValue: 4294967296 * 10000); |
351 | 176 |
|
177 |
cLittle: hwFloat = (isNegative: false; QWordValue: 1); |
|
967 | 178 |
cHHKick: hwFloat = (isNegative: false; QWordValue: 42949673); // _0_01 |
611 | 179 |
{$WARNINGS ON} |
351 | 180 |
{$ENDIF} |
181 |
||
182 |
{$IFNDEF FPC} |
|
183 |
type hwFloat = Extended; |
|
184 |
{$ENDIF} |
|
185 |
||
186 |
implementation |
|
4415 | 187 |
uses uSinTable; |
351 | 188 |
|
3599 | 189 |
|
351 | 190 |
{$IFDEF FPC} |
191 |
||
515 | 192 |
function int2hwFloat (const i: LongInt) : hwFloat; |
351 | 193 |
begin |
498 | 194 |
int2hwFloat.isNegative:= i < 0; |
195 |
int2hwFloat.Round:= abs(i); |
|
196 |
int2hwFloat.Frac:= 0 |
|
351 | 197 |
end; |
198 |
||
5151
cbadb9fa52fc
An experiment - make bazooka AI use float instead of hwFloat - should be as accurate, but faster.
nemo
parents:
5124
diff
changeset
|
199 |
function hwFloat2Float (const i: hwFloat) : extended; |
cbadb9fa52fc
An experiment - make bazooka AI use float instead of hwFloat - should be as accurate, but faster.
nemo
parents:
5124
diff
changeset
|
200 |
begin |
cbadb9fa52fc
An experiment - make bazooka AI use float instead of hwFloat - should be as accurate, but faster.
nemo
parents:
5124
diff
changeset
|
201 |
hwFloat2Float:= i.QWordValue / $100000000; |
5192 | 202 |
if i.isNegative then hwFloat2Float:= -hwFloat2Float; |
5151
cbadb9fa52fc
An experiment - make bazooka AI use float instead of hwFloat - should be as accurate, but faster.
nemo
parents:
5124
diff
changeset
|
203 |
end; |
cbadb9fa52fc
An experiment - make bazooka AI use float instead of hwFloat - should be as accurate, but faster.
nemo
parents:
5124
diff
changeset
|
204 |
|
6415 | 205 |
operator = (const z1, z2: hwFloat) z : boolean; inline; |
5599
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
206 |
begin |
5665 | 207 |
z:= (z1.isNegative = z2.isNegative) and (z1.QWordValue = z2.QWordValue); |
5599
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
208 |
end; |
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
209 |
|
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
210 |
|
515 | 211 |
operator + (const z1, z2: hwFloat) z : hwFloat; |
351 | 212 |
begin |
213 |
if z1.isNegative = z2.isNegative then |
|
214 |
begin |
|
215 |
z.isNegative:= z1.isNegative; |
|
216 |
z.QWordValue:= z1.QWordValue + z2.QWordValue |
|
217 |
end |
|
218 |
else |
|
219 |
if z1.QWordValue > z2.QWordValue then |
|
220 |
begin |
|
221 |
z.isNegative:= z1.isNegative; |
|
222 |
z.QWordValue:= z1.QWordValue - z2.QWordValue |
|
223 |
end else |
|
224 |
begin |
|
225 |
z.isNegative:= z2.isNegative; |
|
226 |
z.QWordValue:= z2.QWordValue - z1.QWordValue |
|
227 |
end |
|
228 |
end; |
|
229 |
||
515 | 230 |
operator - (const z1, z2: hwFloat) z : hwFloat; |
351 | 231 |
begin |
232 |
if z1.isNegative = z2.isNegative then |
|
233 |
if z1.QWordValue > z2.QWordValue then |
|
234 |
begin |
|
235 |
z.isNegative:= z1.isNegative; |
|
236 |
z.QWordValue:= z1.QWordValue - z2.QWordValue |
|
237 |
end else |
|
238 |
begin |
|
239 |
z.isNegative:= not z2.isNegative; |
|
240 |
z.QWordValue:= z2.QWordValue - z1.QWordValue |
|
241 |
end |
|
242 |
else begin |
|
243 |
z.isNegative:= z1.isNegative; |
|
244 |
z.QWordValue:= z1.QWordValue + z2.QWordValue |
|
245 |
end |
|
246 |
end; |
|
247 |
||
515 | 248 |
operator - (const z1: hwFloat) z : hwFloat; |
351 | 249 |
begin |
250 |
z:= z1; |
|
251 |
z.isNegative:= not z.isNegative |
|
252 |
end; |
|
253 |
||
254 |
||
515 | 255 |
operator * (const z1, z2: hwFloat) z : hwFloat; |
351 | 256 |
begin |
257 |
z.isNegative:= z1.isNegative xor z2.isNegative; |
|
258 |
z.QWordValue:= QWord(z1.Round) * z2.Frac + |
|
259 |
QWord(z1.Frac) * z2.Round + |
|
260 |
((QWord(z1.Frac) * z2.Frac) shr 32); |
|
261 |
z.Round:= z.Round + QWord(z1.Round) * z2.Round; |
|
262 |
end; |
|
263 |
||
515 | 264 |
operator * (const z1: hwFloat; const z2: LongInt) z : hwFloat; |
351 | 265 |
begin |
266 |
z.isNegative:= z1.isNegative xor (z2 < 0); |
|
515 | 267 |
z.QWordValue:= z1.QWordValue * abs(z2) |
351 | 268 |
end; |
269 |
||
515 | 270 |
operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; |
351 | 271 |
var t: hwFloat; |
272 |
begin |
|
273 |
z.isNegative:= z1.isNegative xor z2.isNegative; |
|
274 |
z.Round:= z1.QWordValue div z2.QWordValue; |
|
275 |
t:= z1 - z2 * z.Round; |
|
276 |
if t.QWordValue = 0 then |
|
277 |
z.Frac:= 0 |
|
278 |
else |
|
279 |
begin |
|
280 |
while ((t.QWordValue and $8000000000000000) = 0) and |
|
281 |
((z2.QWordValue and $8000000000000000) = 0) do |
|
282 |
begin |
|
283 |
t.QWordValue:= t.QWordValue shl 1; |
|
284 |
z2.QWordValue:= z2.QWordValue shl 1 |
|
285 |
end; |
|
543
465e2ec8f05f
- Better randomness of placing hedgehogs on the land
unc0rr
parents:
538
diff
changeset
|
286 |
if z2.Round > 0 then z.Frac:= (t.QWordValue) div (z2.Round) |
465e2ec8f05f
- Better randomness of placing hedgehogs on the land
unc0rr
parents:
538
diff
changeset
|
287 |
else z.Frac:= 0 |
351 | 288 |
end |
289 |
end; |
|
290 |
||
515 | 291 |
operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; |
498 | 292 |
begin |
293 |
z.isNegative:= z1.isNegative xor (z2 < 0); |
|
515 | 294 |
z.QWordValue:= z1.QWordValue div abs(z2) |
498 | 295 |
end; |
296 |
||
515 | 297 |
operator < (const z1, z2: hwFloat) b : boolean; |
351 | 298 |
begin |
916 | 299 |
if z1.isNegative xor z2.isNegative then |
351 | 300 |
b:= z1.isNegative |
301 |
else |
|
302 |
if z1.QWordValue = z2.QWordValue then |
|
303 |
b:= false |
|
304 |
else |
|
305 |
b:= (z1.QWordValue < z2.QWordValue) xor z1.isNegative |
|
306 |
end; |
|
307 |
||
515 | 308 |
operator > (const z1, z2: hwFloat) b : boolean; |
351 | 309 |
begin |
916 | 310 |
if z1.isNegative xor z2.isNegative then |
351 | 311 |
b:= z2.isNegative |
312 |
else |
|
313 |
if z1.QWordValue = z2.QWordValue then |
|
314 |
b:= false |
|
315 |
else |
|
316 |
b:= (z1.QWordValue > z2.QWordValue) xor z2.isNegative |
|
317 |
end; |
|
318 |
||
2905 | 319 |
function cstr(const z: hwFloat): shortstring; |
320 |
var tmpstr: shortstring; |
|
351 | 321 |
begin |
322 |
str(z.Round, cstr); |
|
323 |
if z.Frac <> 0 then |
|
324 |
begin |
|
6311 | 325 |
str(z.Frac / $100000000:1:10, tmpstr); |
351 | 326 |
delete(tmpstr, 1, 2); |
327 |
cstr:= cstr + '.' + tmpstr |
|
328 |
end; |
|
329 |
if z.isNegative then cstr:= '-' + cstr |
|
330 |
end; |
|
331 |
||
515 | 332 |
function hwRound(const t: hwFloat): LongInt; |
351 | 333 |
begin |
2300 | 334 |
if t.isNegative then hwRound:= -(t.Round and $7FFFFFFF) |
335 |
else hwRound:= t.Round and $7FFFFFFF |
|
351 | 336 |
end; |
337 |
||
515 | 338 |
function hwAbs(const t: hwFloat): hwFloat; |
351 | 339 |
begin |
340 |
hwAbs:= t; |
|
341 |
hwAbs.isNegative:= false |
|
342 |
end; |
|
343 |
||
515 | 344 |
function hwSqr(const t: hwFloat): hwFloat; |
351 | 345 |
begin |
1433 | 346 |
hwSqr.isNegative:= false; |
347 |
hwSqr.QWordValue:= |
|
2948
3f21a9dc93d0
Replace tabs with spaces using 'expand -t 4' command
unc0rr
parents:
2933
diff
changeset
|
348 |
((QWord(t.Round) * t.Round) shl 32) |
3f21a9dc93d0
Replace tabs with spaces using 'expand -t 4' command
unc0rr
parents:
2933
diff
changeset
|
349 |
+ QWord(t.Round) * t.Frac * 2 |
3f21a9dc93d0
Replace tabs with spaces using 'expand -t 4' command
unc0rr
parents:
2933
diff
changeset
|
350 |
+ ((QWord(t.Frac) * t.Frac) shr 32); |
351 | 351 |
end; |
352 |
||
515 | 353 |
function hwSqrt(const t: hwFloat): hwFloat; |
738 | 354 |
var l, r: QWord; |
355 |
c: hwFloat; |
|
357 | 356 |
begin |
357 |
hwSqrt.isNegative:= false; |
|
744 | 358 |
|
359 |
if t.Round = 0 then |
|
360 |
begin |
|
361 |
l:= t.QWordValue; |
|
362 |
r:= $100000000 |
|
363 |
end else |
|
364 |
begin |
|
365 |
l:= $100000000; |
|
953
237fc147950c
Fix bug in hwSqrt when calculating square root of number >= 65536
unc0rr
parents:
916
diff
changeset
|
366 |
r:= t.QWordValue div 2 + $80000000; // r:= t / 2 + 0.5 |
237fc147950c
Fix bug in hwSqrt when calculating square root of number >= 65536
unc0rr
parents:
916
diff
changeset
|
367 |
if r > $FFFFFFFFFFFF then r:= $FFFFFFFFFFFF |
744 | 368 |
end; |
369 |
||
738 | 370 |
repeat |
371 |
c.QWordValue:= (l + r) div 2; |
|
372 |
if hwSqr(c).QWordValue > t.QWordValue then r:= c.QWordValue else l:= c.QWordValue |
|
373 |
until r - l <= 1; |
|
744 | 374 |
|
738 | 375 |
hwSqrt.QWordValue:= l |
357 | 376 |
end; |
377 |
||
515 | 378 |
function Distance(const dx, dy: hwFloat): hwFloat; |
351 | 379 |
begin |
738 | 380 |
Distance:= hwSqrt(hwSqr(dx) + hwSqr(dy)) |
351 | 381 |
end; |
382 |
||
515 | 383 |
function DistanceI(const dx, dy: LongInt): hwFloat; |
498 | 384 |
begin |
856 | 385 |
DistanceI:= hwSqrt(int2hwFloat(sqr(dx) + sqr(dy))) |
498 | 386 |
end; |
387 |
||
515 | 388 |
function SignAs(const num, signum: hwFloat): hwFloat; |
498 | 389 |
begin |
856 | 390 |
SignAs.QWordValue:= num.QWordValue; |
498 | 391 |
SignAs.isNegative:= signum.isNegative |
392 |
end; |
|
393 |
||
4374 | 394 |
function hwSign(r: hwFloat): LongInt; |
395 |
begin |
|
396 |
// yes, we have negative zero for a reason |
|
397 |
if r.isNegative then hwSign:= -1 else hwSign:= 1 |
|
398 |
end; |
|
399 |
||
357 | 400 |
|
515 | 401 |
function AngleSin(const Angle: Longword): hwFloat; |
351 | 402 |
begin |
3929
9a4bbc1f67a2
Inline most of uFloat (saves ~7.5% opcount on a test game), inline a few very short candidates in uMisc, comment out some unused functions in uMisc
nemo
parents:
3599
diff
changeset
|
403 |
//TryDo((Angle >= 0) and (Angle <= 2048), 'Sin param exceeds limits', true); |
351 | 404 |
AngleSin.isNegative:= false; |
357 | 405 |
if Angle < 1024 then AngleSin.QWordValue:= SinTable[Angle] |
406 |
else AngleSin.QWordValue:= SinTable[2048 - Angle] |
|
351 | 407 |
end; |
408 |
||
515 | 409 |
function AngleCos(const Angle: Longword): hwFloat; |
351 | 410 |
begin |
3929
9a4bbc1f67a2
Inline most of uFloat (saves ~7.5% opcount on a test game), inline a few very short candidates in uMisc, comment out some unused functions in uMisc
nemo
parents:
3599
diff
changeset
|
411 |
//TryDo((Angle >= 0) and (Angle <= 2048), 'Cos param exceeds limits', true); |
357 | 412 |
AngleCos.isNegative:= Angle > 1024; |
413 |
if Angle < 1024 then AngleCos.QWordValue:= SinTable[1024 - Angle] |
|
414 |
else AngleCos.QWordValue:= SinTable[Angle - 1024] |
|
351 | 415 |
end; |
416 |
||
5599
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
417 |
function isZero(const z: hwFloat): boolean; inline; |
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
418 |
begin |
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
419 |
isZero := z.QWordValue = 0; |
2e4b90f33a83
aiming fixed, inverted cursor on ammo menu, added equal and isZero function to uFloat, changed the way ammo menu opens, you must now click on the hog rather than anywhere on the screen
Xeli
parents:
5319
diff
changeset
|
420 |
end; |
351 | 421 |
{$ENDIF} |
422 |
||
423 |
end. |