Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
3
 * It is copyright by its individual contributors, as recorded in the
4
 * project's Git history.  See COPYING.txt at the top level for license
5
 * terms and a link to the Git history.
6
 */
7
/* Maths.h library header file */
8
 
9
#pragma once
10
 
11
#include <cstdint>
12
#include <stdlib.h>
13
#include "pstypes.h"
14
 
15
 
16
 
17
#define D_RAND_MAX 32767
18
 
19
#ifdef __cplusplus
20
#include <cstddef>
21
#include "dxxsconf.h"
22
#include "dsx-ns.h"
23
#include <array>
24
 
25
namespace dcx {
26
 
27
void d_srand (unsigned int seed);
28
__attribute_warn_unused_result
29
int d_rand ();                  // Random number function which returns in the range 0-0x7FFF
30
 
31
 
32
//=============================== FIXED POINT ===============================
33
 
34
typedef int64_t fix64;          //64 bits int, for timers
35
typedef int32_t fix;            //16 bits int, 16 bits frac
36
typedef int16_t fixang;         //angles
37
 
38
typedef struct quadint // integer 64 bit, previously called "quad"
39
  {
40
          union {
41
                  struct {
42
    uint32_t low;
43
    int32_t high;
44
                  };
45
                  int64_t q;
46
          };
47
  }
48
quadint;
49
 
50
 
51
//Convert an int to a fix/fix64 and back
52
static constexpr fix i2f(const int &i)
53
{
54
        return i << 16;
55
}
56
 
57
static constexpr int f2i(const fix &f)
58
{
59
        return f >> 16;
60
}
61
 
62
//Convert fix to float and float to fix
63
static constexpr float f2fl(const fix &f)
64
{
65
        return static_cast<float>(f) / static_cast<float>(65536.0);
66
}
67
 
68
static constexpr double f2db(const fix &f)
69
{
70
        return static_cast<double>(f) / 65536.0;
71
}
72
 
73
static constexpr fix fl2f(const float &f)
74
{
75
        return static_cast<fix>(f * 65536);
76
}
77
 
78
//Some handy constants
79
#define f0_0    0
80
#define f1_0    0x10000
81
#define f2_0    0x20000
82
#define f3_0    0x30000
83
#define f10_0   0xa0000
84
 
85
#define f0_5 0x8000
86
#define f0_1 0x199a
87
 
88
//Get the int part of a fix, with rounding
89
static constexpr int f2ir(const fix &f)
90
{
91
        return (f + f0_5) >> 16;
92
}
93
 
94
#define F0_0    f0_0
95
#define F1_0    f1_0
96
#define F2_0    f2_0
97
#define F3_0    f3_0
98
#define F10_0   f10_0
99
 
100
#define F0_5    f0_5
101
#define F0_1    f0_1
102
 
103
//multiply two fixes, return a fix(64)
104
__attribute_warn_unused_result
105
fix64 fixmul64 (fix a, fix b);
106
 
107
/* On x86/amd64 for Windows/Linux, truncating fix64->fix is free. */
108
__attribute_warn_unused_result
109
static inline fix fixmul(fix a, fix b)
110
{
111
        return static_cast<fix>(fixmul64(a, b));
112
}
113
 
114
//divide two fixes, return a fix
115
__attribute_warn_unused_result
116
fix fixdiv (fix a, fix b);
117
 
118
//multiply two fixes, then divide by a third, return a fix
119
__attribute_warn_unused_result
120
fix fixmuldiv (fix a, fix b, fix c);
121
 
122
//multiply two fixes, and add 64-bit product to a quadint
123
static inline void fixmulaccum (quadint * q, const fix &a, const fix &b)
124
{
125
        q->q += static_cast<int64_t>(a) * static_cast<int64_t>(b);
126
}
127
 
128
//extract a fix from a quadint product
129
__attribute_warn_unused_result
130
static inline fix fixquadadjust (const quadint *q)
131
{
132
        return static_cast<fix>(q->q >> 16);
133
}
134
 
135
//negate a quadint
136
static inline void fixquadnegate (quadint * q)
137
{
138
        q->q = -q->q;
139
}
140
 
141
//computes the square root of a long, returning a short
142
__attribute_warn_unused_result
143
ushort long_sqrt (int32_t a);
144
 
145
//computes the square root of a quadint, returning a long
146
__attribute_warn_unused_result
147
uint32_t quad_sqrt (quadint);
148
 
149
//computes the square root of a fix, returning a fix
150
__attribute_warn_unused_result
151
fix fix_sqrt (fix a);
152
 
153
struct fix_sincos_result
154
{
155
        fix sin, cos;
156
};
157
 
158
__attribute_warn_unused_result
159
fix_sincos_result fix_sincos(fix);
160
 
161
//compute sine and cosine of an angle, filling in the variables
162
//either of the pointers can be NULL
163
 
164
__attribute_warn_unused_result
165
fix fix_sin(fix a);
166
 
167
__attribute_warn_unused_result
168
fix fix_cos(fix a);
169
 
170
__attribute_warn_unused_result
171
fix fix_fastsin(fix a); //no interpolation
172
 
173
//compute inverse sine & cosine
174
__attribute_warn_unused_result
175
fixang fix_asin (fix v);
176
 
177
__attribute_warn_unused_result
178
fixang fix_acos (fix v);
179
 
180
//given cos & sin of an angle, return that angle.
181
//parms need not be normalized, that is, the ratio of the parms cos/sin must
182
//equal the ratio of the actual cos & sin for the result angle, but the parms 
183
//need not be the actual cos & sin.  
184
//NOTE: this is different from the standard C atan2, since it is left-handed.
185
__attribute_warn_unused_result
186
fixang fix_atan2 (fix cos, fix sin);
187
 
188
__attribute_warn_unused_result
189
int checkmuldiv(fix *r,fix a,fix b,fix c);
190
 
191
extern const std::array<ubyte, 256> guess_table;
192
extern const std::array<int16_t, 256> sincos_table;
193
extern const std::array<ushort, 258> asin_table;
194
extern const std::array<ushort, 258> acos_table;
195
 
196
static inline void clamp_fix_lh(fix& f, const fix& low, const fix& high)
197
{
198
        if (f < low)
199
                f = low;
200
        else if (high < f)
201
                f = high;
202
}
203
 
204
static inline void clamp_fix_symmetric(fix& f, const fix& bound)
205
{
206
        clamp_fix_lh(f, -bound, bound);
207
}
208
 
209
}
210
#endif