1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 *
19 */
20
21 /**
22 * @file globals.h
23 * Some global definitions and includes
24 * @author The GemRB Project
25 */
26
27
28 #ifndef GLOBALS_H
29 #define GLOBALS_H
30
31 #include "ie_types.h"
32 #include <type_traits>
33
34 #define VERSION_GEMRB "0.9.0"
35
36 #define GEMRB_STRING "GemRB v" VERSION_GEMRB
37 #define PACKAGE "GemRB"
38
39 #ifdef ANDROID
40 # define S_IEXEC S_IXUSR
41 # define S_IREAD S_IRUSR
42 # define S_IWRITE S_IWUSR
43 #endif
44
45 #include "RGBAColor.h"
46 #include "SClassID.h"
47 #include "errors.h"
48
49 #include "Region.h"
50 #include "System/DataStream.h"
51 #include "System/String.h"
52
53 #include <algorithm>
54 #include <chrono>
55
56 #include "System/Logging.h"
57
58 #include <bitset>
59 #include <climits>
60
61 namespace GemRB {
62
63 //Global Variables
64
65 #define IE_NORMAL 0
66 #define IE_SHADED 1
67
68 #define IE_STR_STRREFON 1
69 #define IE_STR_SOUND 2
70 #define IE_STR_SPEECH 4
71 #define IE_STR_ALLOW_ZERO 8 //0 strref is allowed
72 #define IE_STR_STRREFOFF 256
73
74 // checked against the strref itself
75 #define IE_STR_ALTREF 0x0100000 // use alternate tlk file: dialogf.tlk
76
77 // bitflag operations
78 // !!! Keep these synchronized with GUIDefines.py !!!
79 #define OP_SET 0 //gemrb extension
80 #define OP_AND 1
81 #define OP_OR 2
82 #define OP_XOR 3
83 #define OP_NAND 4 //gemrb extension
84
85 /////feature flags
86 enum GameFeatureFlags : uint32_t {
87 GF_HAS_KAPUTZ, //pst
88 GF_ALL_STRINGS_TAGGED, //bg1, pst, iwd1
89 GF_HAS_SONGLIST, //bg2
90 GF_TEAM_MOVEMENT, //pst
91 GF_UPPER_BUTTON_TEXT, //bg2
92 GF_LOWER_LABEL_TEXT, //bg2
93 GF_HAS_PARTY_INI, //iwd2
94 GF_SOUNDFOLDERS, //iwd2
95 GF_IGNORE_BUTTON_FRAMES, // all?
96 GF_ONE_BYTE_ANIMID, // pst
97 GF_HAS_DPLAYER, // not pst
98 GF_HAS_EXPTABLE, // iwd, iwd2
99 GF_HAS_BEASTS_INI, //pst; also for quests.ini
100 GF_HAS_DESC_ICON, //bg
101 GF_HAS_PICK_SOUND, //pst
102 GF_IWD_MAP_DIMENSIONS, //iwd, iwd2
103 GF_AUTOMAP_INI, //pst
104 GF_SMALL_FOG, //bg1, pst
105 GF_REVERSE_DOOR, //pst
106 GF_PROTAGONIST_TALKS, //pst
107 GF_HAS_SPELLLIST, //iwd2
108 GF_IWD2_SCRIPTNAME, //iwd2, iwd, how
109 GF_DIALOGUE_SCROLLS, //pst
110 GF_KNOW_WORLD, //iwd2
111 GF_REVERSE_TOHIT, //all except iwd2
112 GF_SAVE_FOR_HALF, //pst
113 GF_CHARNAMEISGABBER, //iwd2
114 GF_MAGICBIT, //iwd, iwd2
115 GF_CHECK_ABILITIES, //bg2 (others?)
116 GF_CHALLENGERATING, //iwd2
117 GF_SPELLBOOKICONHACK, //bg2
118 GF_ENHANCED_EFFECTS, //iwd2 (maybe iwd/how too)
119 GF_DEATH_ON_ZERO_STAT, //not in iwd2
120 GF_SPAWN_INI, //pst, iwd, iwd2
121 GF_IWD2_DEATHVARFORMAT, //iwd branch (maybe pst)
122 GF_RESDATA_INI, //pst
123 GF_OVERRIDE_CURSORPOS, //pst, iwd2
124 GF_BREAKABLE_WEAPONS, //only bg1
125 GF_3ED_RULES, //iwd2
126 GF_LEVELSLOT_PER_CLASS, //iwd2
127 GF_SELECTIVE_MAGIC_RES, //bg2, iwd2, (how)
128 GF_HAS_HIDE_IN_SHADOWS, // bg2, iwd2
129 GF_AREA_VISITED_VAR, //iwd, iwd2
130 GF_PROPER_BACKSTAB, //bg2, iwd2, how?
131 GF_ONSCREEN_TEXT, //pst
132 GF_SPECIFIC_DMG_BONUS, //how, iwd2
133 GF_STRREF_SAVEGAME, //iwd2
134 GF_SIMPLE_DISRUPTION, // ToBEx: simplified disruption
135 GF_BIOGRAPHY_RES, //iwd branch
136 GF_NO_BIOGRAPHY, //pst
137 GF_STEAL_IS_ATTACK, //bg2 for sure
138 GF_CUTSCENE_AREASCRIPTS, //bg1, maybe more
139 GF_FLEXIBLE_WMAP, //iwd
140 GF_AUTOSEARCH_HIDDEN, //all except iwd2
141 GF_PST_STATE_FLAGS, //pst complicates this
142 GF_NO_DROP_CAN_MOVE, //bg1
143 GF_JOURNAL_HAS_SECTIONS, //bg2
144 GF_CASTING_SOUNDS, //all except pst and bg1
145 GF_CASTING_SOUNDS2, //bg2
146 GF_FORCE_AREA_SCRIPT, //how and iwd2 (maybe iwd1)
147 GF_AREA_OVERRIDE, //pst maze and other hardcode
148 GF_NO_NEW_VARIABLES, //pst
149 GF_SOUNDS_INI, //iwd/how/iwd2
150 GF_USEPOINT_400, //all except pst and iwd2
151 GF_USEPOINT_200, //iwd2
152 GF_HAS_FLOAT_MENU, //pst
153 GF_RARE_ACTION_VB, //pst
154 GF_NO_UNDROPPABLE, //iwd,how
155 GF_START_ACTIVE, //bg1
156 GF_INFOPOINT_DIALOGS, //pst, but only bg1 has garbage there
157 GF_IMPLICIT_AREAANIM_BACKGROUND, //idw,how,iwd2
158 GF_HEAL_ON_100PLUS, //bg1, bg2, pst
159 GF_IN_PARTY_ALLOWS_DEAD, //all except bg2
160 GF_ZERO_TIMER_IS_VALID, // how, not bg2, other unknown
161 GF_SHOP_RECHARGE, // all?
162 GF_MELEEHEADER_USESPROJECTILE, // minimally bg2
163 GF_FORCE_DIALOGPAUSE, // all except if using v1.04 DLG files (bg2, special)
164 GF_RANDOM_BANTER_DIALOGS, // bg1
165 GF_FIXED_MORALE_OPCODE, // bg2
166 GF_HAPPINESS, // all except pst and iwd2
167 GF_EFFICIENT_OR, // does the OR trigger shortcircuit on success or not? Only in iwd2
168 GF_LAYERED_WATER_TILES, // TileOverlay for water has an extra half transparent layer (all but BG1)
169
170 GF_COUNT // sentinal count
171 };
172
173 //the number of item usage fields (used in CREItem and STOItem)
174 #define CHARGE_COUNTERS 3
175
176 /////AI global defines
177 #define AI_UPDATE_TIME 15
178
179 /////maximum animation orientation count (used in many places)
180 #define MAX_ORIENT 16
181
182 /////globally used functions
183
184 class Scriptable;
185 class Actor;
186
187 GEM_EXPORT double AngleFromPoints(const Point& p1, const Point& p2);
188 GEM_EXPORT Point RotatePoint(const Point& p, double angle);
189 GEM_EXPORT unsigned char GetOrient(const Point &s, const Point &d);
190 GEM_EXPORT unsigned int Distance(const Point &pos, const Point &pos2);
191 GEM_EXPORT unsigned int Distance(const Point &pos, const Scriptable *b);
192 GEM_EXPORT unsigned int SquaredDistance(const Point &pos, const Point &pos2);
193 GEM_EXPORT unsigned int SquaredMapDistance(const Point &pos, const Scriptable *b);
194 GEM_EXPORT unsigned int PersonalDistance(const Point &p, const Scriptable *b);
195 GEM_EXPORT unsigned int SquaredPersonalDistance(const Point &pos, const Scriptable *b);
196 GEM_EXPORT unsigned int Distance(const Scriptable *a, const Scriptable *b);
197 GEM_EXPORT unsigned int SquaredDistance(const Scriptable *a, const Scriptable *b);
198 GEM_EXPORT unsigned int PersonalDistance(const Scriptable *a, const Scriptable *b);
199 GEM_EXPORT unsigned int SquaredPersonalDistance(const Scriptable *a, const Scriptable *b);
200 GEM_EXPORT unsigned int SquaredMapDistance(const Scriptable *a, const Scriptable *b);
201 GEM_EXPORT unsigned int PersonalLineDistance(const Point &v, const Point &w, const Scriptable *s, double *proj);
202 GEM_EXPORT double Feet2Pixels(int feet, double angle);
203 GEM_EXPORT bool WithinAudibleRange(const Actor *actor, const Point &dest);
204 GEM_EXPORT bool WithinRange(const Actor *actor, const Point &dest, int distance);
205 GEM_EXPORT bool WithinPersonalRange(const Scriptable *actor, const Scriptable *dest, int distance);
206 GEM_EXPORT int EARelation(const Scriptable *a, const Actor *b);
207 GEM_EXPORT bool Schedule(ieDword schedule, ieDword time);
208
209 #define SCHEDULE_MASK(time) (1 << core->Time.GetHour(time - core->Time.hour_size/2))
210
GetTicks()211 inline unsigned long GetTicks()
212 {
213 using namespace std::chrono;
214 return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
215 }
216
valid_number(const char * string,long & val)217 inline bool valid_number(const char* string, long& val)
218 {
219 char* endpr;
220
221 val = (long) strtoul( string, &endpr, 0 );
222 return ( const char * ) endpr != string;
223 }
224
225 template <typename T>
SetBits(T & flag,const T & value,int mode)226 inline bool SetBits(T& flag, const T& value, int mode)
227 {
228 switch(mode) {
229 case OP_OR: flag |= value; break;
230 case OP_NAND: flag &= ~value; break;
231 case OP_SET: flag = value; break;
232 case OP_AND: flag &= value; break;
233 case OP_XOR: flag ^= value; break;
234 default:
235 Log(ERROR, "SetBits", "Unrecognized Bit Operation %i", mode);
236 return false;
237 }
238 return true;
239 }
240
241 template <typename T>
CountBits(const T & i)242 inline size_t CountBits(const T& i)
243 {
244 // using a bitset is guaranteed to be portable
245 // it is also usually much faster than a loop over the bits since it is often implemented with a CPU popcount instruction
246 static std::bitset<sizeof(T) * CHAR_BIT> bits;
247 bits = i;
248 return bits.count();
249 }
250
251 template <typename T>
Clamp(const T & n,const T & lower,const T & upper)252 inline T Clamp(const T& n, const T& lower, const T& upper)
253 {
254 return std::max(lower, std::min(n, upper));
255 }
256
257 template <>
Clamp(const Point & p,const Point & lower,const Point & upper)258 inline Point Clamp(const Point& p, const Point& lower, const Point& upper)
259 {
260 Point ret;
261 ret.x = std::max(lower.x, std::min(p.x, upper.x));
262 ret.y = std::max(lower.y, std::min(p.y, upper.y));
263 return ret;
264 }
265
266 // WARNING: these are meant to be fast, if you are concerned with overflow/underflow don't use them
267 template <typename T>
CeilDivUnsigned(T dividend,T divisor)268 inline T CeilDivUnsigned(T dividend, T divisor)
269 {
270 //static_assert(std::is_unsigned<T>::value, "This quick round only works for positive values.");
271 return (dividend + divisor - 1) / divisor;
272 }
273
274 template <typename T>
CeilDivSlow(T dividend,T divisor)275 inline T CeilDivSlow(T dividend, T divisor)
276 {
277 if (divisor < 0) {
278 return (dividend - divisor - 1) / divisor;
279 } else {
280 return (dividend + divisor - 1) / divisor;
281 }
282 }
283
284 template <typename T>
CeilDiv(T dividend,T divisor)285 inline T CeilDiv(T dividend, T divisor)
286 {
287 static_assert(std::is_integral<T>::value, "Only integral types allowed");
288 // the compiler should be able to boil all this away (at least in release mode)
289 // and just inline the fastest version supported by T
290 if (std::is_unsigned<T>::value) {
291 return CeilDivUnsigned(dividend, divisor);
292 } else {
293 return CeilDivSlow(dividend, divisor);
294 }
295 }
296
297 //we need 32+6 bytes at least, because we store 'context' in the variable
298 //name too
299 #define MAX_VARIABLE_LENGTH 40
300
301 //the maximum supported game CD count
302 #define MAX_CD 6
303
304 }
305
306 #endif //! GLOBALS_H
307
308
309