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