1 /** 2 * @file 3 * @brief definitions common between client and server, but not game lib 4 */ 5 6 /* 7 Copyright (C) 1997-2001 Id Software, Inc. 8 9 This program is free software; you can redistribute it and/or 10 modify it under the terms of the GNU General Public License 11 as published by the Free Software Foundation; either version 2 12 of the License, or (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 18 See the GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 24 */ 25 26 #pragma once 27 28 #include "../shared/ufotypes.h" 29 #include "../shared/byte.h" 30 #include "../shared/shared.h" 31 #include "../shared/mathlib.h" 32 #include "../shared/defines.h" 33 #include "cvar.h" 34 #include "mem.h" 35 36 #define UFO_VERSION "2.5" 37 #define GAME_TITLE "UFO:AI" 38 #define GAME_TITLE_LONG "UFO:Alien Invasion" 39 40 #ifdef _WIN32 41 # define BUILDSTRING_OS "Win32" 42 # ifndef SO_EXT 43 # define SO_EXT "dll" 44 # endif 45 46 #elif defined __linux__ 47 # define BUILDSTRING_OS "Linux" 48 # ifndef SO_EXT 49 # define SO_EXT "so" 50 # endif 51 52 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) 53 # define BUILDSTRING_OS "FreeBSD" 54 # ifndef SO_EXT 55 # define SO_EXT "so" 56 # endif 57 58 #elif defined __sun 59 # define BUILDSTRING_OS "Solaris" 60 # ifndef SO_EXT 61 # define SO_EXT "so" 62 # endif 63 64 #elif defined (__APPLE__) || defined (MACOSX) 65 # define BUILDSTRING_OS "MacOSX" 66 # ifndef SO_EXT 67 # define SO_EXT "dylib" 68 # endif 69 70 #elif defined ANDROID 71 # define BUILDSTRING_OS "Android" 72 # ifndef SO_EXT 73 # define SO_EXT "so" 74 # endif 75 76 #else 77 # define BUILDSTRING_OS "Unknown" 78 #endif 79 80 #if defined __alpha__ || defined __alpha || defined _M_ALPHA 81 # define CPUSTRING "Alpha" 82 #elif defined __amd64__ || defined __amd64 || defined __x86_64__ || defined __x86_64 || defined _M_X64 83 # define CPUSTRING "AMD64" 84 #elif defined __arm__ || defined __thumb__ || defined _ARM 85 # define CPUSTRING "ARM" 86 #elif defined i386 || defined __i386__ || defined __i386 || defined _M_IX86 || defined __X86__ || defined _X86_ || defined __THW_INTEL__ || defined __I86__ || defined __INTEL__ 87 # define CPUSTRING "IA-32" 88 #elif defined __ia64__ || defined _IA64 || defined __IA64__ || defined __ia64 || defined _M_IA64 89 # define CPUSTRING "IA-64" 90 #elif defined __mips__ || defined mips || defined __mips || defined __MIPS__ 91 # define CPUSTRING "MIPS" 92 #elif defined __powerpc || defined __powerpc__ || defined __POWERPC__ || defined __ppc__ || defined _M_PPC || defined _ARCH_PPC 93 # define CPUSTRING "PowerPC" 94 #elif defined __sparc__ || defined __sparc 95 # define CPUSTRING "SPARC" 96 #else 97 # define CPUSTRING "Unknown" 98 #endif 99 100 #ifdef DEBUG 101 # define BUILDSTRING_VARIANT "DEBUG" 102 #else 103 # define BUILDSTRING_VARIANT "RELEASE" 104 #endif 105 106 #ifdef UFO_REVISION 107 # define BUILDSTRING BUILDSTRING_OS " " BUILDSTRING_VARIANT " build " UFO_REVISION 108 #else 109 # define BUILDSTRING BUILDSTRING_OS " " BUILDSTRING_VARIANT 110 #endif 111 112 #define MASTER_SERVER "http://ufoai.org/" /* sponsored by NineX */ 113 114 /* 115 ============================================================== 116 PROTOCOL 117 ============================================================== 118 */ 119 120 /* protocol.h -- communications protocols */ 121 122 #define PROTOCOL_VERSION 18 123 124 #define PORT_CLIENT 27901 125 #define PORT_SERVER 27910 126 127 /** 128 * @brief server to client 129 * the svc_strings[] array in cl_parse.c should mirror this 130 */ 131 enum svc_ops_e { 132 svc_bad, 133 134 /** the rest are private to the client and server */ 135 svc_nop, 136 svc_ping, 137 svc_disconnect, 138 svc_reconnect, 139 svc_print, /**< [byte] id [string] null terminated string */ 140 svc_stufftext, /**< [string] stuffed into client's console buffer, should be \n terminated */ 141 svc_serverdata, /**< [long] protocol, spawncount, playernum, mapname, ... */ 142 svc_configstring, /**< [short] [string] */ 143 svc_event, /**< event like move or inventory usage - see EV_* and @sa CL_ParseEvent */ 144 svc_oob = 0xff 145 }; 146 147 #define MAX_SVC_STUFFTEXT 1024 148 #define MAX_SVC_PRINT 1024 149 #define MAX_SVC_RECONNECT 256 150 #define MAX_SVC_DISCONNECT 256 151 #define MAX_CLC_STRINGCMD 512 152 153 typedef int32_t svc_ops_t; 154 155 /*============================================== */ 156 157 /** 158 * @brief client to server 159 */ 160 enum clc_ops_e { 161 clc_bad, 162 clc_nop, 163 clc_ack, /**< answer on a ping */ 164 clc_endround, 165 clc_teaminfo, 166 clc_initactorstates, 167 clc_action, 168 clc_userinfo, /**< [[userinfo string] */ 169 clc_stringcmd, /**< [string] message */ 170 clc_oob = svc_oob /**< out of band - connectionless */ 171 }; 172 173 #define SOUND_ATTN_NONE 0.0f /**< full volume the entire level */ 174 #define SOUND_ATTN_NORM 1.0f 175 #define SOUND_ATTN_IDLE 1.2f 176 #define SOUND_ATTN_STATIC 3.0f /**< dimish very rapidly with distance */ 177 #define SOUND_ATTN_MAX SOUND_ATTN_STATIC 178 179 #include "../ports/system.h" 180 #include "cmd.h" 181 #include "cvar.h" 182 #include "cmodel.h" 183 #include "filesys.h" 184 #include "scripts.h" 185 #include "net.h" 186 #include "dbuffer.h" 187 #include "netpack.h" 188 189 /* 190 ============================================================== 191 MISC 192 ============================================================== 193 */ 194 195 #define ANGLE2SHORT(x) ((int)((x)*65536/360) & 65535) 196 #define SHORT2ANGLE(x) ((x)*(360.0/65536)) 197 198 #define ERR_FATAL 0 /* exit the entire game with a popup window */ 199 #define ERR_DROP 1 /* print to console and disconnect from game */ 200 #define ERR_QUIT 2 /* not an error, just a normal exit */ 201 202 #define Q_COLOR_ESCAPE '^' 203 #define Q_IsColorString(p) ((p) && *(p) == Q_COLOR_ESCAPE && *((p) + 1) && isalnum(*((p) + 1))) 204 205 #define S_COLOR_BLACK "^0" 206 #define S_COLOR_RED "^1" 207 #define S_COLOR_GREEN "^2" 208 #define S_COLOR_YELLOW "^3" 209 #define S_COLOR_BLUE "^4" 210 #define S_COLOR_CYAN "^5" 211 #define S_COLOR_MAGENTA "^6" 212 #define S_COLOR_WHITE "^7" 213 214 #define CON_COLOR_BLACK 0 215 #define CON_COLOR_RED 1 216 #define CON_COLOR_GREEN 2 217 #define CON_COLOR_YELLOW 3 218 #define CON_COLOR_BLUE 4 219 #define CON_COLOR_CYAN 5 220 #define CON_COLOR_MAGENTA 6 221 #define CON_COLOR_WHITE 7 222 #define MAX_COLORS 8 223 224 void Com_BeginRedirect(struct net_stream *stream, char* buffer, int buffersize); 225 void Com_EndRedirect(void); 226 void Com_vPrintf(const char* fmt, va_list); 227 228 typedef void (*exceptionCallback_t)(void); 229 230 /** 231 * Thrown by Com_Drop(). 232 */ 233 struct comDrop_t {}; 234 class comRestart_t { 235 public: 236 const char* gamedir; comRestart_t(const char * _gamedir)237 comRestart_t (const char* _gamedir) : gamedir(_gamedir ? strdup(_gamedir) : nullptr) {} ~comRestart_t()238 virtual ~comRestart_t () { free(static_cast<void*>(const_cast<char*>(gamedir))); } 239 }; 240 241 void Com_Drop(void) __attribute__((noreturn)); 242 void Com_Quit(void); 243 void Com_BreakIntoDebugger(void); 244 void Com_WriteConfigToFile(const char* filename); 245 void Cvar_WriteVariables(qFILE *f); 246 247 int Com_ServerState(void); 248 void Com_SetServerState(int state); 249 void Com_SetRandomSeed(unsigned int seed); 250 const char* Com_UnsignedIntToBinary(uint32_t x); 251 const char* Com_ByteToBinary(byte x); 252 253 #include "md4.h" 254 const char* Com_MD5File(const char* fn, int length = 0); 255 const char* Com_MD5Buffer(const byte* buf, size_t len); 256 257 extern cvar_t* http_proxy; 258 extern cvar_t* http_timeout; 259 extern cvar_t* developer; 260 extern cvar_t* sv_dedicated; 261 extern cvar_t* sv_maxclients; 262 extern cvar_t* sv_gametype; 263 extern cvar_t* masterserver_url; 264 extern cvar_t* port; 265 266 extern cvar_t* sys_priority; 267 extern cvar_t* sys_affinity; 268 extern cvar_t* sys_os; 269 extern cvar_t* hwclass; 270 271 /* Time information. */ 272 /** 273 * @brief Engine-side time information in the game. 274 * @note Use this in your custom structs that need to get saved or sent over the network. 275 * @sa dateLong_t For runtime use (human readable). 276 * @sa CP_DateConvertLong 277 */ 278 typedef struct date_s { 279 int day; /**< Number of elapsed days since 1st january of year 0 */ 280 int sec; /**< Number of elapsed seconds since the beginning of current day */ 281 } date_t; 282 283 /* Time Constants */ 284 #define DAYS_PER_YEAR 365 285 #define DAYS_PER_YEAR_AVG 365.25 286 /** DAYS_PER_MONTH -> @sa monthLength[] array in campaign.c */ 287 #define MONTHS_PER_YEAR 12 288 #define SEASONS_PER_YEAR 4 289 #define SECONDS_PER_DAY 86400 /**< (24 * 60 * 60) */ 290 #define SECONDS_PER_HOUR 3600 /**< (60 * 60) */ 291 #define SECONDS_PER_MINUTE 60 /**< (60) */ 292 #define MINUTES_PER_HOUR 60 /**< (60) */ 293 #define HOURS_PER_DAY 24 294 295 #define MAXCMDLINE 256 296 297 typedef void (*vPrintfPtr_t)(const char* fmt, va_list ap); 298 vPrintfPtr_t Qcommon_GetPrintFunction(void); 299 void Qcommon_SetPrintFunction(vPrintfPtr_t func); 300 301 void Qcommon_Init(int argc, char** argv); 302 void Qcommon_Frame(void); 303 void Qcommon_Shutdown(void); 304 void Com_SetGameType(void); 305 void Com_ReadFromPipe(void); 306 float Com_GrenadeTarget(const vec3_t from, const vec3_t at, float speed, bool launched, bool rolled, vec3_t v0); 307 bool Com_CheckConfigStringIndex(int index); 308 void Con_Print(const char* txt); 309 310 /* Event timing */ 311 312 typedef void event_func(int now, void* data); 313 typedef bool event_check_func(int now, void* data); 314 typedef bool event_delay_func(int now, void* data); 315 typedef void event_notify_delay_func(int now, void* data, int delay); 316 /** 317 * @return @c true to keep the event, @c false to remove it from the queue 318 */ 319 typedef bool event_filter(int when, event_func* func, event_check_func* check, void* data); 320 typedef void event_clean_func(void* data); 321 322 struct scheduleEvent_t { 323 int when; 324 int delayFollowing; 325 event_func* func; 326 event_check_func* check; 327 /** 328 * @brief Called when the check failed and we have to delay events in the queue 329 * @return @c false if there should be no delay for this event, @c true if it should 330 * get delayed 331 * @param[in] now The current time 332 * @param[in] data The event userdata 333 */ 334 event_delay_func *delay; 335 event_notify_delay_func *notifyDelay; 336 void* notifyDelayUserData; 337 event_clean_func *clean; 338 void* data; 339 }; 340 341 typedef SharedPtr<scheduleEvent_t> ScheduleEventPtr; 342 343 ScheduleEventPtr Schedule_Event(int when, event_func* func, event_check_func* check, event_clean_func *clean, void* data); 344 int CL_FilterEventQueue(event_filter *filter); 345 346 /* 347 ============================================================== 348 CLIENT / SERVER SYSTEMS 349 ============================================================== 350 */ 351 352 void CL_Init(void); 353 void CL_Drop(void); 354 void CL_Shutdown(void); 355 int CL_Milliseconds(void); 356 void CL_Frame(int now, void* data); 357 void CL_SlowFrame(int now, void* data); 358 bool CL_ParseClientData(const char* type, const char* name, const char** text); 359 void SCR_BeginLoadingPlaque(void); 360 void SCR_EndLoadingPlaque(void); 361 void CL_InitAfter(void); 362 363 void SV_Init(void); 364 void SV_Clear(void); 365 void SV_Shutdown(const char* finalmsg, bool reconnect); 366 void SV_ShutdownWhenEmpty(void); 367 void SV_Frame(int now, void*); 368 mapData_t* SV_GetMapData(void); 369 mapTiles_t* SV_GetMapTiles(void); 370 371 /*============================================================================ */ 372 373 extern memPool_t* com_aliasSysPool; 374 extern memPool_t* com_cmdSysPool; 375 extern memPool_t* com_cmodelSysPool; 376 extern memPool_t* com_cvarSysPool; 377 extern memPool_t* com_fileSysPool; 378 extern memPool_t* com_genericPool; 379 extern memPool_t* com_networkPool; 380 381 /*============================================================================ */ 382 383 int Com_Argc(void); 384 const char* Com_Argv(int arg); /* range and null checked */ 385 void Com_ClearArgv(int arg); 386 const char* Com_MacroExpandString(const char* text); 387 void Com_UploadCrashDump(const char* crashDumpFile); 388 bool Com_CheckDuplicateFile(const char* file, const char* wildcard); 389 390 bool Com_ConsoleCompleteCommand(const char* s, char* target, size_t bufSize, uint32_t* pos, uint32_t offset); 391 392 void Key_Init(void); 393 394 395 /** Remove element at index from array of size n. n gets adjusted to the new 396 * array size, so must be an lvalue */ 397 #define REMOVE_ELEM(array, index, n) \ 398 do { \ 399 size_t idx__ = (index); \ 400 size_t n__ = --(n); \ 401 assert(idx__ <= n__); \ 402 memmove((array) + idx__, (array) + idx__ + 1, (n__ - idx__) * sizeof(*(array))); \ 403 OBJZERO((array)[n__]); \ 404 } while (0) 405 406 /** Same as REMOVE_ELEM() and also updates the idx attribute of every moved 407 * element */ 408 #define REMOVE_ELEM_ADJUST_IDX(array, index, n) \ 409 do { \ 410 size_t idx__ = (index); \ 411 size_t n__; \ 412 size_t i__; \ 413 REMOVE_ELEM(array, index, n); \ 414 n__ = (n); \ 415 for (i__ = idx__; i__ < n__; ++i__) \ 416 --(array)[i__].idx; \ 417 } while (0) 418 419 #define HASH_Add(hash, elem, index) \ 420 do { \ 421 const int hashIndex = (index); \ 422 assert(hashIndex >= 0); \ 423 assert(hashIndex < lengthof(hash)); \ 424 (elem)->hash_next = (hash)[hashIndex]; \ 425 (hash)[hashIndex] = (elem); \ 426 } while (0) 427 428 #define HASH_Delete(anchor) (*(anchor) = (*(anchor))->hash_next) 429