UFO: Alien Invasion
common.cpp
Go to the documentation of this file.
1 
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 #include "../shared/autoptr.h"
27 #include "common.h"
28 #include "http.h"
29 #include "../server/server.h"
30 #include "../shared/parse.h"
31 #include "../ports/system.h"
32 #include <set>
33 #include <vector>
34 #include <SDL.h>
35 
36 #define MAXPRINTMSG 4096
37 #define MAX_NUM_ARGVS 50
38 
40 
41 static int com_argc;
42 static const char* com_argv[MAX_NUM_ARGVS + 1];
43 
45 
49 static const char* consoleLogName = "ufoconsole.log";
50 static cvar_t* logfile_active; /* 1 = buffer log, 2 = flush after each print */
52 #ifndef DEDICATED_ONLY
53 static cvar_t* cl_maxfps;
55 #endif
64 
65 static qFILE logfile;
66 static qFILE pipefile;
67 
75 
76 #define TIMER_CHECK_INTERVAL 100
77 #define TIMER_CHECK_LAG 3
78 #define TIMER_LATENESS_HIGH 200
79 #define TIMER_LATENESS_LOW 50
80 #define TIMER_LATENESS_HISTORY 32
81 
82 struct timer {
84  int interval;
91 
93  void* data;
94 };
95 
97 public:
98  bool operator()(const ScheduleEventPtr& e1, const ScheduleEventPtr& e2) const {
99  return e1->when < e2->when;
100  }
101 };
102 
103 typedef std::multiset<ScheduleEventPtr, CompareScheduleEvent> EventPriorityQueue;
105 
106 static void Schedule_Timer(cvar_t* freq, event_func* func, event_check_func* check, void* data);
107 
108 /*
109 ==============================================================================
110 TARGETING FUNCTIONS
111 ==============================================================================
112 */
113 
231 float Com_GrenadeTarget (const vec3_t from, const vec3_t at, float speed, bool launched, bool rolled, vec3_t v0)
232 {
233  vec3_t delta;
234 
235  /* calculate target distance and height */
236  const float h = at[2] - from[2];
237  VectorSubtract(at, from, delta);
238  delta[2] = 0;
239  const float d = VectorLength(delta);
240 
241  /* check that it's not degenerate */
242  if (d == 0) {
243  return 0;
244  }
245 
246  /* precalculate some useful values */
247  const float g = GRAVITY;
248  const float gd2 = g * d * d;
249  const float len = sqrt(h * h + d * d);
250 
251  float v, alpha;
252  /* are we rolling? */
253  if (rolled) {
254  const float rollAngle = 3.0; /* angle to throw at for rolling, in degrees. */
255  alpha = rollAngle * torad;
256  const float theta = atan2(d, -h) - 2 * alpha;
257  const float k = gd2 / (len * cos(theta) - h);
258  if (k <= 0) /* impossible shot at any velocity */
259  return 0;
260  v = sqrt(k);
261  } else {
262  /* firstly try with the maximum speed possible */
263  v = speed;
264  const float k = (v * v * h + gd2) / (v * v * len);
265 
266  /* check whether the shot's possible */
267  if (launched && k >= -1 && k <= 1) {
268  /* it is possible, so calculate the angle */
269  alpha = 0.5 * (atan2(d, -h) - acos(k));
270  } else {
271  /* calculate the minimum possible velocity that would make it possible */
272  alpha = 0.5 * atan2(d, -h);
273  v = sqrt(gd2 / (len - h));
274  }
275  }
276 
277  /* calculate velocities */
278  const float vx = v * cos(alpha);
279  const float vy = v * sin(alpha);
280  VectorNormalizeFast(delta);
281  VectorScale(delta, vx, v0);
282  v0[2] = vy;
283 
284  /* prevent any rounding errors */
286  VectorScale(v0, v - DIST_EPSILON, v0);
287 
288  /* return time */
289  return d / vx;
290 }
291 
292 /*
293 ============================================================================
294 CLIENT / SERVER interactions
295 ============================================================================
296 */
297 
298 static char* rd_buffer;
299 static unsigned int rd_buffersize;
300 static struct net_stream* rd_stream;
301 
308 void Com_BeginRedirect (struct net_stream* stream, char* buffer, int buffersize)
309 {
310  if (!buffer || !buffersize)
311  return;
312 
313  rd_stream = stream;
314  rd_buffer = buffer;
315  if (buffersize > MAXPRINTMSG)
316  Com_Error(ERR_DROP, "redirect buffer may not be bigger than MAXPRINTMSG (%i)", MAXPRINTMSG);
317  rd_buffersize = buffersize;
318  rd_buffer[0] = '\0';
319 }
320 
325 void Com_EndRedirect (void)
326 {
328 
329  rd_stream = nullptr;
330  rd_buffer = nullptr;
331  rd_buffersize = 0;
332 }
333 
338 void Com_vPrintf (const char* fmt, va_list ap)
339 {
340  char msg[MAXPRINTMSG];
341 
342  Q_vsnprintf(msg, sizeof(msg), fmt, ap);
343 
344  /* redirect the output? */
345  if (rd_buffer) {
346  if ((strlen(msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) {
348  rd_buffer[0] = '\0';
349  }
350  Q_strcat(rd_buffer, sizeof(char) * rd_buffersize, "%s", msg);
351  return;
352  }
353 
354  Con_Print(msg);
355 
356  /* also echo to debugging console */
357  Sys_ConsoleOutput(msg);
358 
359  /* logfile */
361  if (!logfile.f) {
362  if (logfile_active->integer > 2)
364  else
366  }
367  if (logfile.f) {
368  /* strip color codes */
369  const char* output = msg;
370 
371  if (output[strlen(output) - 1] == '\n') {
372  char timestamp[40];
373  Com_MakeTimestamp(timestamp, sizeof(timestamp));
374  FS_Write(timestamp, strlen(timestamp), &logfile);
375  FS_Write(" ", 1, &logfile);
376  }
377 
378  FS_Write(output, strlen(output), &logfile);
379 
380  if (logfile_active->integer > 1)
381  fflush(logfile.f); /* force it to save every time */
382  }
383  }
384 }
385 
386 void Com_Printf (const char* const fmt, ...)
387 {
388  va_list ap;
389 
390  va_start(ap, fmt);
391  vPrintfPtr(fmt, ap);
392  va_end(ap);
393 }
394 
398 void Com_DPrintf (int level, const char* fmt, ...)
399 {
400  /* don't confuse non-developers with techie stuff... */
401  if (!developer)
402  return;
403 
404  if (developer->integer == 1 || (developer->integer & level)) {
405  va_list ap;
406 
407  va_start(ap, fmt);
408  vPrintfPtr(fmt, ap);
409  va_end(ap);
410  }
411 }
412 
417 void Com_Error (int code, const char* fmt, ...)
418 {
419  va_list argptr;
420  static char msg[MAXPRINTMSG];
421  static bool recursive = false;
422 
423  if (recursive)
424  Sys_Error("recursive error after: %s", msg);
425  recursive = true;
426 
427  va_start(argptr, fmt);
428  Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
429  va_end(argptr);
430 
431  switch (code) {
432  case ERR_DISCONNECT:
433  Com_Printf("%s\n", msg);
434  CL_Drop();
435  recursive = false;
436  Com_Drop();
437  case ERR_DROP:
438  Com_Printf("********************\n");
439  Com_Printf("ERROR: %s\n", msg);
440  Com_Printf("********************\n");
441  Sys_Backtrace();
442  SV_Shutdown("Server crashed.", false);
443  CL_Drop();
444  recursive = false;
445  Com_Drop();
446  default:
447  Com_Printf("%s\n", msg);
448  SV_Shutdown("Server fatal crashed", false);
449 
450  /* send an receive net messages a last time */
451  NET_Wait(0);
452 
454  if (pipefile.f != nullptr) {
456  FS_RemoveFile(va("%s/%s", FS_Gamedir(), pipefile.name));
457  }
458 
459  CL_Shutdown();
461  Sys_Error("Shutdown");
462  }
463 }
464 
465 void Com_Drop (void)
466 {
467  throw comDrop_t();
468 }
469 
471 {
472 #ifdef DEBUG
473 #if SDL_VERSION_ATLEAST(2, 0, 0)
474  SDL_MessageBoxData data;
475  SDL_MessageBoxButtonData okButton;
476  SDL_MessageBoxButtonData cancelButton;
477 
478  OBJZERO(data);
479  OBJZERO(okButton);
480  OBJZERO(cancelButton);
481 
482  okButton.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
483  okButton.text = "Yes";
484  okButton.buttonid = 1;
485 
486  cancelButton.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
487  cancelButton.text = "No";
488  cancelButton.buttonid = 2;
489 
490  const SDL_MessageBoxButtonData buttons[] = {okButton, cancelButton};
491  data.flags = SDL_MESSAGEBOX_ERROR;
492  data.title = "Error";
493  data.message = "Break into the debugger?";
494  data.numbuttons = lengthof(buttons);
495  data.buttons = buttons;
496  data.window = nullptr;
497 
498  int buttonid = -1;
499  SDL_ShowMessageBox(&data, &buttonid);
500  if (buttonid == 1) {
501  Sys_Breakpoint();
502  }
503 #endif
504 #endif
505 }
506 
511 void Com_Quit (void)
512 {
513 #ifdef DEDICATED_ONLY
514  Com_WriteConfigToFile("dedconfig.cfg");
515 #else
516  Com_WriteConfigToFile("config.cfg");
517 #endif
518 
519  SV_Shutdown("Server quit.", false);
520  SV_Clear();
521  CL_Shutdown();
522 
523  /* send an receive net messages a last time */
524  NET_Wait(0);
526  if (pipefile.f != nullptr) {
528  FS_RemoveFile(va("%s/%s", FS_Gamedir(), pipefile.name));
529  }
530  Sys_Quit();
531 }
532 
533 
538 int Com_ServerState (void)
539 {
540  return SV_GetServerState();
541 }
542 
547 void Com_SetServerState (int state)
548 {
549  Com_DPrintf(DEBUG_ENGINE, "Set server state to %i\n", state);
550  if (state == ss_dead)
551  SV_Shutdown("Server shutdown", false);
552  else if (state == ss_restart)
553  SV_Shutdown("Server map change", true);
554  sv->state = (server_state_t)state;
555 }
556 
560 int Com_Argc (void)
561 {
562  return com_argc;
563 }
564 
568 const char* Com_Argv (int arg)
569 {
570  if (arg < 0 || arg >= com_argc || !com_argv[arg])
571  return "";
572  return com_argv[arg];
573 }
574 
580 void Com_ClearArgv (int arg)
581 {
582  if (arg < 0 || arg >= com_argc || !com_argv[arg])
583  return;
584  com_argv[arg] = "";
585 }
586 
587 static void Com_InitArgv (int argc, char** argv)
588 {
589  if (argc > MAX_NUM_ARGVS)
590  Com_Error(ERR_FATAL, "argc > MAX_NUM_ARGVS");
591  com_argc = argc;
592  for (int i = 0; i < argc; i++) {
593  if (!argv[i] || strlen(argv[i]) >= MAX_TOKEN_CHARS)
594  com_argv[i] = "";
595  else
596  com_argv[i] = argv[i];
597  }
598 }
599 
600 #define MACRO_CVAR_ID_LENGTH 6
601 
607 const char* Com_MacroExpandString (const char* text)
608 {
609  static char expanded[MAX_STRING_CHARS];
610 
611  const char* scan = text;
612  if (!text || !*text)
613  return nullptr;
614 
615  const int len = strlen(scan);
616  if (len >= MAX_STRING_CHARS) {
617  Com_Printf("Line exceeded %i chars, discarded.\n", MAX_STRING_CHARS);
618  return nullptr;
619  }
620 
621  bool inquote = false;
622  int count = 0;
623  OBJZERO(expanded);
624  char* pos = expanded;
625 
626  /* also the \0 */
627  assert(scan[len] == '\0');
628  for (int i = 0; i <= len; i++) {
629  if (scan[i] == '"')
630  inquote ^= 1;
631  /* don't expand inside quotes */
632  if (inquote || strncmp(&scan[i], "*cvar:", MACRO_CVAR_ID_LENGTH)) {
633  *pos++ = scan[i];
634  continue;
635  }
636 
637  /* scan out the complete macro and only parse the cvar name */
638  const char* start = &scan[i + MACRO_CVAR_ID_LENGTH];
639  const char* token = Com_Parse(&start);
640  if (!start)
641  continue;
642 
643  /* skip the macro and the cvar name in the next loop */
645  i += strlen(token);
646  i--;
647 
648  /* get the cvar value */
649  const char* cvarvalue = Cvar_GetString(token);
650  if (!cvarvalue) {
651  Com_Printf("Could not get cvar value for cvar: %s\n", token);
652  return nullptr;
653  }
654 
655  const int j = strlen(cvarvalue);
656  if (strlen(pos) + j >= MAX_STRING_CHARS) {
657  Com_Printf("Expanded line exceeded %i chars, discarded.\n", MAX_STRING_CHARS);
658  return nullptr;
659  }
660 
661  /* copy the cvar value into the target buffer */
662  /* check for overflow is already done - so MAX_STRING_CHARS won't hurt here */
663  Q_strncpyz(pos, cvarvalue, j + 1);
664  pos += j;
665 
666  if (++count == 100) {
667  Com_Printf("Macro expansion loop, discarded.\n");
668  return nullptr;
669  }
670  }
671 
672  if (inquote) {
673  Com_Printf("Line has unmatched quote, discarded.\n");
674  return nullptr;
675  }
676 
677  if (count)
678  return expanded;
679 
680  return nullptr;
681 }
682 
683 void Com_UploadCrashDump (const char* crashDumpFile)
684 {
685  if (uploadcrashdump == nullptr || uploadcrashdump->integer != 1)
686  return;
687  upparam_t paramUser;
688  upparam_t paramVersion;
689  upparam_t paramOS;
690  const char* crashDumpURL = "https://ufoai.org/CrashDump.php";
691 
692  paramUser.name = "user";
693  paramUser.value = Sys_GetCurrentUser();
694  paramUser.next = &paramVersion;
695  paramVersion.name = "version";
696  paramVersion.value = UFO_VERSION;
697  paramVersion.next = &paramOS;
698  paramOS.name = "os";
699  paramOS.value = BUILDSTRING_OS;
700  paramOS.next = nullptr;
701 
702  HTTP_PutFile("crashdump", crashDumpFile, crashDumpURL, &paramUser);
703  HTTP_PutFile("crashdump", va("%s/%s", FS_Gamedir(), consoleLogName), crashDumpURL, &paramUser);
704 }
705 
717 bool Com_ConsoleCompleteCommand (const char* s, char* target, size_t bufSize, uint32_t* pos, uint32_t offset)
718 {
719  const char* cmd = nullptr, *cvar = nullptr, *use = nullptr;
720  char cmdLine[MAXCMDLINE] = "";
721  char cmdBase[MAXCMDLINE] = "";
722  bool append = true;
723 
724  if (!s[0] || s[0] == ' ')
725  return false;
726 
727  if (s[0] == '\\' || s[0] == '/') {
728  /* maybe we are using the same buffers - and we want to keep the slashes */
729  if (s == target)
730  offset++;
731  s++;
732  }
733 
734  assert(bufSize <= MAXCMDLINE);
735  assert(pos);
736 
737  /* don't try to search a command or cvar if we are already in the
738  * parameter stage */
739  if (strstr(s, " ")) {
740  Q_strncpyz(cmdLine, s, sizeof(cmdLine));
741  /* remove the last whitespace */
742  cmdLine[strlen(cmdLine) - 1] = '\0';
743 
744  char* tmp = cmdBase;
745  while (*s != ' ')
746  *tmp++ = *s++;
747  /* get rid of the whitespace */
748  s++;
749  /* terminate the string at whitespace position to separate the cmd */
750  *tmp = '\0';
751 
752  /* now strip away that part that is not yet completed */
753  tmp = strrchr(cmdLine, ' ');
754  if (tmp)
755  *tmp = '\0';
756 
757  const int cntParams = Cmd_CompleteCommandParameters(cmdBase, s, &cmd);
758  if (cntParams > 1)
759  Com_Printf("\n");
760  if (cmd) {
761  /* append the found parameter */
762  Q_strcat(cmdLine, sizeof(cmdLine), " %s", cmd);
763  append = false;
764  use = cmdLine;
765  } else
766  return false;
767  } else {
768  /* Cmd_GenericCompleteFunction uses one static buffer for output, so backup one completion here if available */
769  static char cmdBackup[MAX_QPATH];
770  const int cntCmd = Cmd_CompleteCommand(s, &cmd);
771  if (cmd)
772  Q_strncpyz(cmdBackup, cmd, sizeof(cmdBackup));
773  const int cntCvar = Cvar_CompleteVariable(s, &cvar);
774 
775  /* complete as much as possible, append only if one single match is found */
776  if (cntCmd > 0 && !cntCvar) {
777  use = cmd;
778  if (cntCmd != 1)
779  append = false;
780  } else if (!cntCmd && cntCvar > 0) {
781  use = cvar;
782  if (cntCvar != 1)
783  append = false;
784  } else if (cmd && cvar) {
785  const int maxLength = std::min(strlen(cmdBackup),strlen(cvar));
786  int idx = 0;
787  /* try to find similar content of cvar and cmd match */
788  Q_strncpyz(cmdLine, cmdBackup,sizeof(cmdLine));
789  for (; idx < maxLength; idx++) {
790  if (cmdBackup[idx] != cvar[idx]) {
791  cmdLine[idx] = '\0';
792  break;
793  }
794  }
795  if (idx == maxLength)
796  cmdLine[idx] = '\0';
797  use = cmdLine;
798  append = false;
799  }
800  }
801 
802  if (use) {
803  Q_strncpyz(&target[offset], use, bufSize - offset);
804  *pos = strlen(target);
805  if (append)
806  target[(*pos)++] = ' ';
807  target[*pos] = '\0';
808 
809  return true;
810  }
811 
812  return false;
813 }
814 
815 void Com_SetGameType (void)
816 {
817  int i;
818 
819  for (i = 0; i < csi.numGTs; i++) {
820  const gametype_t* gt = &csi.gts[i];
821  if (Q_streq(gt->id, sv_gametype->string)) {
822  int j;
823  const cvarlist_t* list;
824  if (sv_dedicated->integer)
825  Com_Printf("set gametype to: %s\n", gt->id);
826  for (j = 0, list = gt->cvars; j < gt->num_cvars; j++, list++) {
827  Cvar_Set(list->name, "%s", list->value);
828  if (sv_dedicated->integer)
829  Com_Printf(" %s = %s\n", list->name, list->value);
830  }
831  /*Com_Printf("Make sure to restart the map if you switched during a game\n");*/
832  break;
833  }
834  }
835 
836  if (i == csi.numGTs)
837  Com_Printf("Can't set the gametype - unknown value for cvar gametype: '%s'\n", sv_gametype->string);
838 }
839 
840 static void Com_GameTypeList_f (void)
841 {
842  Com_Printf("Available gametypes:\n");
843  for (int i = 0; i < csi.numGTs; i++) {
844  int j;
845  const gametype_t* gt = &csi.gts[i];
846  const cvarlist_t* list;
847 
848  Com_Printf("%s\n", gt->id);
849 
850  for (j = 0, list = gt->cvars; j < gt->num_cvars; j++, list++)
851  Com_Printf(" %s = %s\n", list->name, list->value);
852  }
853 }
854 
861 {
862  if (index < 0 || index >= MAX_CONFIGSTRINGS)
863  return false;
864 
865  /* CS_TILES and CS_POSITIONS can stretch over multiple configstrings,
866  * so don't access the middle parts. */
867  if (index > CS_TILES && index < CS_POSITIONS)
868  return false;
869  if (index > CS_POSITIONS && index < CS_MODELS)
870  return false;
871 
872  return true;
873 }
874 
875 #ifdef DEBUG
876 
879 static void Com_DebugHelp_f (void)
880 {
881  Cvar_PrintDebugCvars();
882 
883  Cmd_PrintDebugCommands();
884 }
885 
889 static void Com_DebugError_f (void)
890 {
891  if (Cmd_Argc() == 3) {
892  const char* errorType = Cmd_Argv(1);
893  if (Q_streq(errorType, "ERR_DROP"))
894  Com_Error(ERR_DROP, "%s", Cmd_Argv(2));
895  else if (Q_streq(errorType, "ERR_FATAL"))
896  Com_Error(ERR_FATAL, "%s", Cmd_Argv(2));
897  else if (Q_streq(errorType, "ERR_DISCONNECT"))
898  Com_Error(ERR_DISCONNECT, "%s", Cmd_Argv(2));
899  }
900  Com_Printf("Usage: %s <ERR_FATAL|ERR_DROP|ERR_DISCONNECT> <msg>\n", Cmd_Argv(0));
901 }
902 #endif
903 
904 
905 typedef struct debugLevel_s {
906  const char* str;
908 } debugLevel_t;
909 
910 static const debugLevel_t debugLevels[] = {
911  {"DEBUG_ALL", DEBUG_ALL},
912  {"DEBUG_ENGINE", DEBUG_ENGINE},
913  {"DEBUG_SHARED", DEBUG_SHARED},
914  {"DEBUG_SYSTEM", DEBUG_SYSTEM},
915  {"DEBUG_COMMANDS", DEBUG_COMMANDS},
916  {"DEBUG_CLIENT", DEBUG_CLIENT},
917  {"DEBUG_EVENTSYS", DEBUG_EVENTSYS},
918  {"DEBUG_ROUTING", DEBUG_ROUTING},
919  {"DEBUG_SERVER", DEBUG_SERVER},
920  {"DEBUG_GAME", DEBUG_GAME},
921  {"DEBUG_RENDERER", DEBUG_RENDERER},
922  {"DEBUG_SOUND", DEBUG_SOUND},
923 
924  {nullptr, 0}
925 };
926 
927 static void Com_DeveloperSet_f (void)
928 {
929  const int oldValue = Cvar_GetInteger("developer");
930  int newValue = oldValue;
931  int i = 0;
932 
933  if (Cmd_Argc() == 2) {
934  const char* debugLevel = Cmd_Argv(1);
935  while (debugLevels[i].str) {
936  if (Q_streq(debugLevel, debugLevels[i].str)) {
937  if (oldValue & debugLevels[i].debugLevel) /* if it's already set... */
938  newValue &= ~debugLevels[i].debugLevel; /* ...reset it. */
939  else
940  newValue |= debugLevels[i].debugLevel;
941  break;
942  }
943  i++;
944  }
945  if (!debugLevels[i].str) {
946  Com_Printf("No valid debug mode parameter\n");
947  return;
948  }
949  Cvar_SetValue("developer", newValue);
950  Com_Printf("Currently selected debug print levels\n");
951  i = 0;
952  while (debugLevels[i].str) {
953  if (newValue & debugLevels[i].debugLevel)
954  Com_Printf("* %s\n", debugLevels[i].str);
955  i++;
956  }
957  } else {
958  Com_Printf("Usage: %s <debug_level>\n", Cmd_Argv(0));
959  Com_Printf(" valid debug_levels are:\n");
960  while (debugLevels[i].str) {
961  Com_Printf(" * %s\n", debugLevels[i].str);
962  i++;
963  }
964  }
965 }
966 
967 #ifndef DEDICATED_ONLY
968 
971 static bool Com_CvarCheckMaxFPS (cvar_t* cvar)
972 {
973  /* don't allow setting maxfps too low (or game could stop responding) */
974  return Cvar_AssertValue(cvar, 10, 1000, true);
975 }
976 #endif
977 
981 void Com_WriteConfigToFile (const char* filename)
982 {
983  ScopedFile f;
984 
986  if (!f.file()) {
987  Com_Printf("Couldn't write %s.\n", filename);
988  return;
989  }
990 
991  FS_Printf(&f, "// generated by ufo, do not modify\n");
992  FS_Printf(&f, "// variables\n");
994  FS_Printf(&f, "// aliases\n");
996  Com_Printf("Wrote %s.\n", filename);
997 }
998 
999 void Com_SetRandomSeed (unsigned int seed)
1000 {
1001  srand(seed);
1002  /*Com_Printf("setting random seed to %i\n", seed);*/
1003 }
1004 
1005 const char* Com_ByteToBinary (byte x)
1006 {
1007  static char buf[9];
1008  const int mask = 1 << 7;
1009  char* b = buf;
1010 
1011  for (int cnt = 1; cnt <= 8; ++cnt) {
1012  *b++ = ((x & mask) == 0) ? '0' : '1';
1013  x <<= 1;
1014  if (cnt == 8)
1015  *b++ = '\0';
1016  }
1017 
1018  return buf;
1019 }
1020 
1021 const char* Com_UnsignedIntToBinary (uint32_t x)
1022 {
1023  static char buf[37];
1024  const int mask = 1 << 31;
1025  char* b = buf;
1026 
1027  for (int cnt = 1; cnt <= 32; ++cnt) {
1028  *b++ = ((x & mask) == 0) ? '0' : '1';
1029  x <<= 1;
1030  if (cnt % 8 == 0 && cnt != 32)
1031  *b++ = ' ';
1032  if (cnt == 32)
1033  *b++ = '\0';
1034  }
1035 
1036  return buf;
1037 }
1038 
1042 static void Com_WriteConfig_f (void)
1043 {
1044  char filename[MAX_QPATH];
1045 
1046  if (Cmd_Argc() != 2) {
1047  Com_Printf("Usage: %s <filename>\n", Cmd_Argv(0));
1048  return;
1049  }
1050 
1051  Q_strncpyz(filename, Cmd_Argv(1), sizeof(filename));
1052  Com_DefaultExtension(filename, sizeof(filename), ".cfg");
1054 }
1055 
1056 static void Cbuf_Execute_timer (int now, void* data)
1057 {
1058  Cbuf_Execute();
1059 }
1060 
1062 {
1063  vPrintfPtr = func;
1064 }
1065 
1067 {
1068  return vPrintfPtr;
1069 }
1070 
1078 void Qcommon_Init (int argc, char** argv)
1079 {
1080  logfile_active = nullptr;
1081  developer = nullptr;
1082 
1083  Sys_InitSignals();
1084 
1085  /* random seed */
1086  Com_SetRandomSeed(time(nullptr));
1087 
1088  com_aliasSysPool = Mem_CreatePool("Common: Alias system for commands and enums");
1089  com_cmdSysPool = Mem_CreatePool("Common: Command system");
1090  com_cmodelSysPool = Mem_CreatePool("Common: Collision model");
1091  com_cvarSysPool = Mem_CreatePool("Common: Cvar system");
1092  com_fileSysPool = Mem_CreatePool("Common: File system");
1093  com_genericPool = Mem_CreatePool("Generic");
1094  com_networkPool = Mem_CreatePool("Network");
1095 
1096  try {
1097  OBJZERO(csi);
1098 
1099  /* prepare enough of the subsystems to handle
1100  * cvar and command buffer management */
1101  Com_InitArgv(argc, argv);
1102 
1103  Swap_Init();
1104  Cbuf_Init();
1105 
1106  Cmd_Init();
1107  Cvar_Init();
1108 
1109  uploadcrashdump = Cvar_Get("uploadcrashdump", "1", 0, "upload crashdumps to the developers");
1110 
1111  Key_Init();
1112 
1113  /* we need to add the early commands twice, because
1114  * a basedir needs to be set before executing
1115  * config files, but we want other parms to override
1116  * the settings of the config files */
1117  Cbuf_AddEarlyCommands(false);
1118  Cbuf_Execute();
1119 
1120  FS_InitFilesystem(true);
1121 
1122  Cbuf_AddText("exec default.cfg\n");
1123 #ifdef DEDICATED_ONLY
1124  Cbuf_AddText("exec dedconfig.cfg\n");
1125 #else
1126  Cbuf_AddText("exec config.cfg\n");
1127 #endif
1128 
1129  Cbuf_AddEarlyCommands(true);
1130  Cbuf_Execute();
1131 
1132  Com_SetRenderModified(false);
1133  Com_SetUserinfoModified(false);
1134 
1135  /* init commands and vars */
1136  Cmd_AddCommand("saveconfig", Com_WriteConfig_f, "Write the configuration to file");
1137  Cmd_AddCommand("gametypelist", Com_GameTypeList_f, "List all available multiplayer game types");
1138 #ifdef DEBUG
1139  Cmd_AddCommand("debug_help", Com_DebugHelp_f, "Show some debugging help");
1140  Cmd_AddCommand("debug_error", Com_DebugError_f, "Just throw a fatal error to test error shutdown procedures");
1141 #endif
1142  Cmd_AddCommand("setdeveloper", Com_DeveloperSet_f, "Set the developer cvar to only get the debug output you want");
1143 
1144  developer = Cvar_Get("developer", "0", 0, "Activate developer output to logfile and gameconsole");
1145 #ifdef DEBUG
1146  logfile_active = Cvar_Get("logfile", "2", 0, "0 = deactivate logfile, 1 = write normal logfile, 2 = flush on every new line, 3 = always append to existing file");
1147 #else
1148  logfile_active = Cvar_Get("logfile", "1", 0, "0 = deactivate logfile, 1 = write normal logfile, 2 = flush on every new line, 3 = always append to existing file");
1149 #endif
1150  sv_gametype = Cvar_Get("sv_gametype", "fight1on1", CVAR_ARCHIVE | CVAR_SERVERINFO, "Sets the multiplayer gametype - see gametypelist command for a list of all gametypes");
1151  http_proxy = Cvar_Get("http_proxy", "", CVAR_ARCHIVE, "Use this proxy for http transfers");
1152  http_timeout = Cvar_Get("http_timeout", "3", CVAR_ARCHIVE, "Http connection and read timeout");
1154  masterserver_url = Cvar_Get("masterserver_url", MASTER_SERVER, CVAR_ARCHIVE, "URL of UFO:AI masterserver");
1155 #ifdef DEDICATED_ONLY
1156  sv_dedicated = Cvar_Get("sv_dedicated", "1", CVAR_SERVERINFO | CVAR_NOSET, "Is this a dedicated server?");
1157  /* don't allow to override this from commandline of config */
1158  Cvar_ForceSet("sv_dedicated", "1");
1159 #else
1160  sv_dedicated = Cvar_Get("sv_dedicated", "0", CVAR_SERVERINFO | CVAR_NOSET, "Is this a dedicated server?");
1161 
1162  /* set this to false for client - otherwise Qcommon_Frame would set the initial values to multiplayer */
1163  sv_gametype->modified = false;
1164 
1165  s_language = Cvar_Get("s_language", "", CVAR_ARCHIVE, "Game language - full language string e.g. en_EN.UTF-8");
1166  s_language->modified = false;
1167  cl_maxfps = Cvar_Get("cl_maxfps", "50", CVAR_ARCHIVE);
1169 #endif
1170 
1171  // 5 is an i7 with a medium gfx-card
1172  // 3 dual core with 2 GB
1173  // 2 EeePc with 1 GB
1174  // 1 smartphone
1175  const char* hwclassVal = "5";
1176 #ifdef __ANDROID__
1177 
1178  hwclassVal = "1";
1179 #endif
1180  hwclass = Cvar_Get("hwclass", hwclassVal, 0, "Defines the hardware class of this machine. 1 is the lowest, 5 is the highest.");
1181 
1182  const char* s = va("UFO: Alien Invasion %s %s %s %s", UFO_VERSION, CPUSTRING, "Sep 5 2022", BUILDSTRING);
1183  Cvar_Get("version", s, CVAR_NOSET, "Full version string");
1184  Cvar_Get("ver", UFO_VERSION, CVAR_SERVERINFO | CVAR_NOSET, "Version number");
1185 
1186  if (sv_dedicated->integer)
1187  Cmd_AddCommand("quit", Com_Quit, "Quits the game");
1188 
1189  Mem_Init();
1190  Sys_Init();
1191 
1192  NET_Init();
1193 
1194 #ifndef NO_HTTP
1195  curl_global_init(CURL_GLOBAL_NOTHING);
1196  Com_Printf("%s initialized.\n", curl_version());
1197 #endif
1198 
1199  SV_Init();
1200 
1201  /* e.g. init the client hunk that is used in script parsing */
1202  CL_Init();
1203 
1205 #ifndef DEDICATED_ONLY
1206  Cbuf_AddText("exec keys.cfg\n");
1207 #endif
1208 
1209  if (!sv_dedicated->integer)
1210  Cbuf_AddText("init\n");
1211  else
1212  Cbuf_AddText("dedicated_start\n");
1213  Cbuf_Execute();
1214 
1215  FS_ExecAutoexec();
1216 
1217  /* add + commands from command line
1218  * if the user didn't give any commands, run default action */
1219  if (Cbuf_AddLateCommands()) {
1220  /* the user asked for something explicit
1221  * so drop the loading plaque */
1223  }
1224 
1225  const cvar_t* com_pipefile = Cvar_Get("com_pipefile", "", CVAR_ARCHIVE, "Filename of the pipe that is used to send commands to the game");
1226  if (com_pipefile->string[0] != '\0') {
1227  FS_CreateOpenPipeFile(com_pipefile->string, &pipefile);
1228  }
1229 
1230  CL_InitAfter();
1231 
1232  /* Check memory integrity */
1234 
1235 #ifndef DEDICATED_ONLY
1236  if (!sv_dedicated->integer) {
1237  Schedule_Timer(cl_maxfps, &CL_Frame, nullptr, nullptr);
1238  Schedule_Timer(Cvar_Get("cl_slowfreq", "10", 0, nullptr), &CL_SlowFrame, nullptr, nullptr);
1239 
1240  /* now hide the console */
1241  Sys_ShowConsole(false);
1242  }
1243 #endif
1244 
1245  Schedule_Timer(Cvar_Get("sv_freq", "10", CVAR_NOSET, nullptr), &SV_Frame, nullptr, nullptr);
1246 
1248  Schedule_Timer(Cvar_Get("cbuf_freq", "10", 0, nullptr), &Cbuf_Execute_timer, nullptr, nullptr);
1249 
1250  Com_Printf("====== UFO Initialized ======\n");
1251  Com_Printf("=============================\n");
1252  } catch (comDrop_t const&) {
1253  Sys_Error("Error during initialization");
1254  }
1255 }
1256 
1260 void Com_ReadFromPipe (void)
1261 {
1262  if (pipefile.f == nullptr)
1263  return;
1264 
1265  char buffer[MAX_STRING_CHARS] = { "" };
1266  const int read = FS_Read2(buffer, sizeof(buffer), &pipefile, false);
1267  if (read > 0)
1268  Cmd_ExecuteString("%s", buffer);
1269 }
1270 
1271 static void tick_timer (int now, void* data)
1272 {
1273  struct timer* timer = (struct timer*)data;
1274  const int old_interval = timer->interval;
1275 
1276  /* Compute and store the lateness, updating the total */
1277  const int lateness = Sys_Milliseconds() - now;
1279  timer->recent_lateness[timer->next_lateness] = lateness;
1280  timer->total_lateness += lateness;
1281  timer->next_lateness++;
1283 
1284  /* Is it time to check the mean yet? */
1285  timer->next_check--;
1286  if (timer->next_check <= 0) {
1287  const int mean = timer->total_lateness / TIMER_LATENESS_HISTORY;
1288 
1289  /* We use a saturating counter to damp the adjustment */
1290 
1291  /* When we stay above the high water mark, increase the interval */
1292  if (mean > TIMER_LATENESS_HIGH)
1293  timer->checks_high = std::min(TIMER_CHECK_LAG, timer->checks_high + 1);
1294  else
1295  timer->checks_high = std::max(0, timer->checks_high - 1);
1296 
1298  timer->interval += 2;
1299 
1300  /* When we stay below the low water mark, decrease the interval */
1301  if (mean < TIMER_LATENESS_LOW)
1302  timer->checks_low = std::min(TIMER_CHECK_LAG, timer->checks_high + 1);
1303  else
1304  timer->checks_low = std::max(0, timer->checks_low - 1);
1305 
1307  timer->interval -= 1;
1308 
1309  /* Note that we slow the timer more quickly than we speed it up,
1310  * so it should tend to settle down in the vicinity of the low
1311  * water mark */
1312 
1314  }
1315 
1316  timer->interval = std::max(timer->interval, 1000 / timer->min_freq->integer);
1317 
1318  if (timer->interval != old_interval)
1319  Com_DPrintf(DEBUG_ENGINE, "Adjusted timer on %s to interval %d\n", timer->min_freq->name, timer->interval);
1320 
1321  try {
1322  timer->func(now, timer->data);
1323  } catch (comDrop_t const&) {
1324  }
1325 
1326  /* We correct for the lateness of this frame. We do not correct for
1327  * the time consumed by this frame - that's billed to the lateness
1328  * of future frames (so that the automagic slowdown can work) */
1329  Schedule_Event(now + lateness + timer->interval, &tick_timer, nullptr, nullptr, timer);
1330 }
1331 
1332 static void Schedule_Timer (cvar_t* freq, event_func* func, event_check_func* check, void* data)
1333 {
1334  struct timer* const timer = Mem_PoolAllocType(struct timer, com_genericPool);
1335  timer->min_freq = freq;
1336  timer->interval = 1000 / freq->integer;
1337  timer->next_lateness = 0;
1338  timer->total_lateness = 0;
1340  timer->checks_high = 0;
1341  timer->checks_low = 0;
1342  timer->func = func;
1343  timer->data = data;
1344  for (int i = 0; i < TIMER_LATENESS_HISTORY; i++)
1345  timer->recent_lateness[i] = 0;
1346 
1347  Schedule_Event(Sys_Milliseconds() + timer->interval, &tick_timer, check, nullptr, timer);
1348 }
1349 
1363 {
1365  event->when = when;
1366  event->func = func;
1367  event->check = check;
1368  event->clean = clean;
1369  event->data = data;
1370  event->delayFollowing = 0; /* Delay the following events of the same type (same event func) by the given amount of milliseconds if the check function returned false. */
1371  event->delay = nullptr;
1372 
1373  eventQueue.insert(event);
1374 
1375  return event;
1376 }
1377 
1383 static size_t Delay_Events (int now, EventPriorityQueue::iterator i)
1384 {
1385  const ScheduleEventPtr event = *i;
1386  EventPriorityQueue reOrder;
1387  EventPriorityQueue::iterator itEnd = eventQueue.end();
1388  for (; i != itEnd;) {
1389  ScheduleEventPtr tmpEvent = *i;
1390  if (tmpEvent->func != event->func) {
1391  ++i;
1392  continue;
1393  }
1394  if (tmpEvent->delay != nullptr && !tmpEvent->delay(now, tmpEvent->data)){
1395  ++i;
1396  continue;
1397  }
1398 
1399  tmpEvent->when += event->delayFollowing;
1400  reOrder.insert(tmpEvent);
1401  eventQueue.erase(i++);
1402  }
1403  for (EventPriorityQueue::iterator r = reOrder.begin(); r != reOrder.end(); ++r) {
1404  eventQueue.insert(*r);
1405  }
1406  return reOrder.size();
1407 }
1408 
1416 {
1417  for (EventPriorityQueue::iterator i = eventQueue.begin(); i != eventQueue.end(); ++i) {
1418  ScheduleEventPtr event = *i;
1419  if (event->when > now)
1420  break;
1421 
1422  if (event->check == nullptr || event->check(now, event->data)) {
1423  eventQueue.erase(i);
1424  return event;
1425  }
1426 
1427  /* delay all other events if this one is blocked */
1428  if (event->delayFollowing > 0) {
1429  if (Delay_Events(now, i) > 0) {
1430  if (event->notifyDelay != nullptr) {
1431  event->notifyDelay(now, event->notifyDelayUserData, event->delayFollowing);
1432  }
1433  break;
1434  }
1435  }
1436  }
1437  return ScheduleEventPtr();
1438 }
1439 
1447 {
1448  int filtered = 0;
1449 
1450  assert(filter);
1451 
1452  for (EventPriorityQueue::iterator i = eventQueue.begin(); i != eventQueue.end();) {
1453  ScheduleEventPtr event = *i;
1454  const bool keep = filter(event->when, event->func, event->check, event->data);
1455  if (keep) {
1456  ++i;
1457  continue;
1458  }
1459 
1460  if (event->clean != nullptr)
1461  event->clean(event->data);
1462 
1463  EventPriorityQueue::iterator removeIter = i++;
1464  eventQueue.erase(removeIter);
1465  filtered++;
1466  }
1467 
1468  return filtered;
1469 }
1470 
1480 static bool Event_FilterAll (int when, event_func* func, event_check_func* check, void* data)
1481 {
1482  return false;
1483 }
1484 
1493 void Qcommon_Frame (void)
1494 {
1495  try {
1496  /* If the next event is due... */
1498  if (event) {
1499  /* Dispatch the event */
1500  event->func(event->when, event->data);
1501  }
1502  } catch (comRestart_t const& restart) {
1503  SV_Shutdown("Restart.", false);
1504  CL_Shutdown();
1505  Qcommon_Shutdown();
1507  if (restart.gamedir != nullptr) {
1508  const char* restartArgv[] = {"", "+set", "fs_gamedir", restart.gamedir};
1509  Qcommon_Init(4, const_cast<char** >(restartArgv));
1510  } else {
1511  Qcommon_Init(0, nullptr);
1512  }
1513  } catch (comDrop_t const&) {
1514  return;
1515  }
1516 
1517  /* Now we spend time_to_next milliseconds working on whatever
1518  * IO is ready (but always try at least once, to make sure IO
1519  * doesn't stall) */
1520  int time_to_next;
1521  do {
1522  time_to_next = !eventQueue.empty() ? (eventQueue.begin()->get()->when - Sys_Milliseconds()) : 1000;
1523  if (time_to_next < 0)
1524  time_to_next = 0;
1525 
1526  NET_Wait(time_to_next);
1527  } while (time_to_next > 0);
1528 }
1529 
1537 void Qcommon_Shutdown (void)
1538 {
1539  HTTP_Cleanup();
1540 
1541  FS_Shutdown();
1542  Cvar_Shutdown();
1543  Cmd_Shutdown();
1544  NET_Shutdown();
1545  Mem_Shutdown();
1546  Com_Shutdown();
1547 }
void Com_SetRenderModified(bool modified)
Definition: cvar.cpp:66
vec_t VectorLength(const vec3_t v)
Calculate the length of a vector.
Definition: mathlib.cpp:434
char * name
Definition: cvar.h:72
void Qcommon_Frame(void)
This is the function that is called directly from main()
Definition: common.cpp:1493
const char * Cmd_Argv(int arg)
Returns a given argument.
Definition: cmd.cpp:516
void event_clean_func(void *data)
Definition: common.h:308
void Cmd_AddCommand(const char *cmdName, xcommand_t function, const char *desc)
Add a new command to the script interface.
Definition: cmd.cpp:744
cvar_t * s_language
Definition: common.cpp:54
void Cmd_Init(void)
Definition: cmd.cpp:1127
void Com_BreakIntoDebugger(void)
Definition: common.cpp:470
void Qcommon_Init(int argc, char **argv)
Init function.
Definition: common.cpp:1078
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
Definition: shared.cpp:535
Definition: filesys.h:54
void Sys_Error(const char *error,...)
Definition: g_main.cpp:421
const char * Com_Argv(int arg)
Returns an argument of script commandline.
Definition: common.cpp:568
int recent_lateness[TIMER_LATENESS_HISTORY]
Definition: common.cpp:85
Definition: http.h:59
int Cmd_CompleteCommand(const char *partial, const char **match)
Unix like tab completion for console commands.
Definition: cmd.cpp:924
static bool Com_CvarCheckMaxFPS(cvar_t *cvar)
Watches that the cvar cl_maxfps is never getting lower than 10.
Definition: common.cpp:971
const char * name
Definition: http.h:60
server_state_t SV_GetServerState(void)
Definition: sv_user.cpp:312
#define DEBUG_EVENTSYS
Definition: defines.h:64
int interval
Definition: common.cpp:84
#define MACRO_CVAR_ID_LENGTH
Definition: common.cpp:600
void Mem_Shutdown(void)
Definition: mem.cpp:603
cvar_t * sys_affinity
Definition: common.cpp:60
static const char * consoleLogName
Definition: common.cpp:49
void FS_ExecAutoexec(void)
cvar_t * min_freq
Definition: common.cpp:83
void NET_Shutdown(void)
Definition: net.cpp:337
int FS_OpenFile(const char *filename, qFILE *file, filemode_t mode)
Finds and opens the file in the search path.
Definition: files.cpp:162
#define DEBUG_SERVER
Definition: defines.h:60
#define DEBUG_ALL
Definition: defines.h:54
void NET_Init(void)
Definition: net.cpp:305
#define CPUSTRING
Definition: common.h:109
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don&#39;t need to have varargs versions of all text functi...
Definition: shared.cpp:410
char value[MAX_VAR]
Definition: q_shared.h:338
bool Cvar_AssertValue(cvar_t *cvar, float minVal, float maxVal, bool shouldBeIntegral)
Checks cvar values.
Definition: cvar.cpp:161
void Swap_Init(void)
Definition: byte.cpp:31
void Com_SetRandomSeed(unsigned int seed)
Definition: common.cpp:999
static qFILE logfile
Definition: common.cpp:65
FILE * f
Definition: filesys.h:56
void NET_Wait(int timeout)
Definition: net.cpp:423
struct upparam_s * next
Definition: http.h:62
csi_t csi
Definition: common.cpp:39
void event_func(int now, void *data)
Definition: common.h:300
void CL_SlowFrame(int now, void *data)
Definition: cl_main.cpp:1108
void Com_Quit(void)
Definition: common.cpp:511
#define TIMER_CHECK_INTERVAL
Definition: common.cpp:76
const char * filename
Definition: ioapi.h:41
memPool_t * com_aliasSysPool
Definition: common.cpp:68
int next_lateness
Definition: common.cpp:86
const char * gamedir
Definition: common.h:248
void Cbuf_AddText(const char *format,...)
Adds command text at the end of the buffer.
Definition: cmd.cpp:126
std::multiset< ScheduleEventPtr, CompareScheduleEvent > EventPriorityQueue
Definition: common.cpp:103
void HTTP_Cleanup(void)
UFO is exiting or we&#39;re changing servers. Clean up.
Definition: http.cpp:396
int integer
Definition: cvar.h:81
void Com_ParseScripts(bool onlyServer)
Definition: scripts.cpp:3619
#define DEBUG_SYSTEM
Definition: defines.h:57
void FS_RemoveFile(const char *osPath)
Definition: files.cpp:1692
void Com_vPrintf(const char *fmt, va_list ap)
Definition: common.cpp:338
#define TIMER_LATENESS_HISTORY
Definition: common.cpp:80
int debugLevel
Definition: common.cpp:907
QGL_EXTERN GLsizei const GLvoid * data
Definition: r_gl.h:89
cvar_t * sv_gametype
Definition: common.cpp:56
void Cvar_Shutdown(void)
Definition: cvar.cpp:1100
void Sys_ShowConsole(bool show)
static cvar_t * logfile_active
Definition: common.cpp:50
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
void Cvar_WriteVariables(qFILE *f)
appends lines containing "set variable value" for all variables with the archive flag set to true...
Definition: cvar.cpp:868
void VectorNormalizeFast(vec3_t v)
fast vector normalize routine that does not check to make sure that length != 0, nor does it return l...
Definition: mathlib.cpp:762
static void Com_GameTypeList_f(void)
Definition: common.cpp:840
#define SV_CMD_PRINT
Definition: q_shared.h:593
void Com_SetServerState(int state)
Definition: common.cpp:547
#define DEBUG_ROUTING
Definition: defines.h:66
void Key_Init(void)
Definition: cl_keys.cpp:776
#define CS_POSITIONS
Definition: q_shared.h:326
cvar_t * masterserver_url
Definition: common.cpp:57
#define VectorScale(in, scale, out)
Definition: vector.h:79
Definition: common.cpp:82
gametype_t gts[MAX_GAMETYPES]
Definition: q_shared.h:567
voidpf void * buf
Definition: ioapi.h:42
#define ERR_FATAL
Definition: common.h:210
#define CVAR_ARCHIVE
Definition: cvar.h:40
memPool_t * com_cmdSysPool
Definition: common.cpp:69
void Sys_InitSignals(void)
void CL_Drop(void)
Ensures the right menu cvars are set after error drop or map change.
Definition: cl_main.cpp:167
static unsigned int rd_buffersize
Definition: common.cpp:299
int Cvar_GetInteger(const char *varName)
Returns the int value of a cvar.
Definition: cvar.cpp:194
void Sys_Backtrace(void)
On platforms supporting it, print a backtrace.
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
#define Mem_CheckGlobalIntegrity()
Definition: mem.h:54
void Cmd_ExecuteString(const char *text,...)
A complete command line has been parsed, so try to execute it.
Definition: cmd.cpp:1007
cvar_t * http_proxy
Definition: common.cpp:47
void CL_InitAfter(void)
Init function for clients - called after menu was initialized and ufo-scripts were parsed...
Definition: cl_main.cpp:737
void(* vPrintfPtr_t)(const char *fmt, va_list ap)
Definition: common.h:285
const char * FS_Gamedir(void)
Called to find where to write a file (savegames, etc)
Definition: files.cpp:68
serverInstanceGame_t * sv
Definition: sv_init.cpp:36
static void Com_DeveloperSet_f(void)
Definition: common.cpp:927
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition: shared.cpp:457
void Sys_Init(void)
void NET_OOB_Printf(struct net_stream *s, const char *format,...)
Out of band print.
Definition: netpack.cpp:548
#define CS_MODELS
Definition: q_shared.h:327
char id[MAX_VAR]
Definition: q_shared.h:342
void * data
Definition: common.cpp:93
#define UFO_VERSION
Definition: common.h:36
static void Cbuf_Execute_timer(int now, void *data)
Definition: common.cpp:1056
#define ERR_DROP
Definition: common.h:211
#define DEBUG_CLIENT
Definition: defines.h:59
#define DEBUG_ENGINE
Definition: defines.h:56
int total_lateness
Definition: common.cpp:87
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags, const char *desc)
Init or return a cvar.
Definition: cvar.cpp:342
static cvar_t * cl_maxfps
Definition: common.cpp:53
void Cvar_Init(void)
Reads in all archived cvars.
Definition: cvar.cpp:1087
#define OBJZERO(obj)
Definition: shared.h:178
cvar_t * hwclass
Definition: common.cpp:62
int checks_low
Definition: common.cpp:90
ScheduleEventPtr Dequeue_Event(int now)
Finds and returns the first event in the event_queue that is due. If the event has a check function...
Definition: common.cpp:1415
bool HTTP_PutFile(const char *formName, const char *fileName, const char *url, const upparam_t *params)
Definition: http.cpp:265
void SCR_EndLoadingPlaque(void)
Definition: cl_screen.cpp:277
const char * Com_MacroExpandString(const char *text)
Expands strings with cvar values that are dereferenced by a &#39;*cvar&#39;.
Definition: common.cpp:607
static vPrintfPtr_t vPrintfPtr
Definition: common.cpp:44
int checks_high
Definition: common.cpp:89
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
Definition: cmd.cpp:505
void Con_Print(const char *txt)
Handles cursor positioning, line wrapping, etc All console printing must go through this in order to ...
Definition: cl_console.cpp:318
cvarlist_t cvars[MAX_CVARLISTINGAMETYPE]
Definition: q_shared.h:344
server_state_t
Definition: server.h:95
void Sys_ConsoleOutput(const char *string)
memPool_t * com_genericPool
Definition: common.cpp:73
void SV_Clear(void)
Cleanup when the whole game process is shutting down.
Definition: sv_main.cpp:1030
void Com_EndRedirect(void)
End the redirection of packets/output.
Definition: common.cpp:325
#define CVAR_NOSET
Definition: cvar.h:43
float Com_GrenadeTarget(const vec3_t from, const vec3_t at, float speed, bool launched, bool rolled, vec3_t v0)
Calculates parabola-type shot.
Definition: common.cpp:231
static void tick_timer(int now, void *data)
Definition: common.cpp:1271
void FS_InitFilesystem(bool writeToHomeDir)
Definition: files.cpp:890
#define Mem_CreatePool(name)
Definition: mem.h:32
cvar_t * http_timeout
Definition: common.cpp:48
#define BUILDSTRING
Definition: common.h:121
int FS_Printf(qFILE *f, const char *msg,...)
Can print chunks for 1024 chars into a file.
Definition: files.cpp:1497
static qFILE pipefile
Definition: common.cpp:66
void FS_CloseFile(qFILE *f)
#define MAX_TOKEN_CHARS
Definition: defines.h:372
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition: common.cpp:398
#define GRAVITY
Definition: q_shared.h:276
#define MAX_CONFIGSTRINGS
Definition: q_shared.h:330
static void Com_InitArgv(int argc, char **argv)
Definition: common.cpp:587
memPool_t * com_cvarSysPool
Definition: common.cpp:71
void SV_Init(void)
Only called once at startup, not for each game.
Definition: sv_main.cpp:960
static bool Event_FilterAll(int when, event_func *func, event_check_func *check, void *data)
Eventfilter that filter out all events.
Definition: common.cpp:1480
void CL_Init(void)
Definition: cl_main.cpp:1141
static void Com_WriteConfig_f(void)
Write the config file to a specific name.
Definition: common.cpp:1042
void CL_Frame(int now, void *data)
Definition: cl_main.cpp:1047
const char * Sys_GetCurrentUser(void)
bool Cbuf_AddLateCommands(void)
Adds command line parameters as script statements.
Definition: cmd.cpp:298
#define TIMER_LATENESS_HIGH
Definition: common.cpp:78
static EventPriorityQueue eventQueue
Definition: common.cpp:104
QGL_EXTERN GLuint index
Definition: r_gl.h:110
bool Com_CheckConfigStringIndex(int index)
Definition: common.cpp:860
void Com_UploadCrashDump(const char *crashDumpFile)
Definition: common.cpp:683
QGL_EXTERN GLuint count
Definition: r_gl.h:99
cvar_t * developer
Definition: common.cpp:46
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
static const char * com_argv[MAX_NUM_ARGVS+1]
Definition: common.cpp:42
vPrintfPtr_t Qcommon_GetPrintFunction(void)
Definition: common.cpp:1066
Definition: server.h:96
static void Schedule_Timer(cvar_t *freq, event_func *func, event_check_func *check, void *data)
Definition: common.cpp:1332
static size_t Delay_Events(int now, EventPriorityQueue::iterator i)
Delay the following events and return the amount of events delayed.
Definition: common.cpp:1383
const char * Com_UnsignedIntToBinary(uint32_t x)
Definition: common.cpp:1021
static struct net_stream * rd_stream
Definition: common.cpp:300
void Com_MakeTimestamp(char *ts, const size_t tslen)
Creates a timestamp with date and time at the specified location.
Definition: shared.cpp:352
#define MAXCMDLINE
Definition: common.h:283
void Com_BeginRedirect(struct net_stream *stream, char *buffer, int buffersize)
Redirect packets/output from server to client.
Definition: common.cpp:308
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
Definition: parse.cpp:107
const char * Com_ByteToBinary(byte x)
Definition: common.cpp:1005
The csi structure is the client-server-information structure which contains all the static data neede...
Definition: q_shared.h:515
#define MAXPRINTMSG
Definition: common.cpp:36
voidpf stream
Definition: ioapi.h:42
memPool_t * com_cmodelSysPool
Definition: common.cpp:70
void Cbuf_Init(void)
allocates an initial text buffer that will grow as needed
Definition: cmd.cpp:109
void Com_DefaultExtension(char *path, size_t len, const char *extension)
Sets a default extension if there is none.
Definition: shared.cpp:297
void Cmd_Shutdown(void)
Definition: cmd.cpp:1145
memPool_t * com_networkPool
Definition: common.cpp:74
#define TIMER_LATENESS_LOW
Definition: common.cpp:79
bool Com_ConsoleCompleteCommand(const char *s, char *target, size_t bufSize, uint32_t *pos, uint32_t offset)
Console completion for command and variables.
Definition: common.cpp:717
#define MAX_QPATH
Definition: filesys.h:40
QGL_EXTERN GLint i
Definition: r_gl.h:113
QGL_EXTERN GLuint GLchar GLuint * len
Definition: r_gl.h:99
int Com_Argc(void)
Returns the script commandline argument count.
Definition: common.cpp:560
char name[MAX_OSPATH]
Definition: filesys.h:57
#define MAX_STRING_CHARS
Definition: defines.h:90
cvar_t * sv_dedicated
Definition: common.cpp:51
void Mem_Init(void)
Definition: mem.cpp:588
void Com_ClearArgv(int arg)
Reset com_argv entry to empty string.
Definition: common.cpp:580
void CL_Shutdown(void)
Saves configuration file and shuts the client systems down.
Definition: cl_main.cpp:1219
void Qcommon_Shutdown(void)
Definition: common.cpp:1537
#define CS_TILES
Definition: q_shared.h:325
static cvar_t * uploadcrashdump
Definition: common.cpp:63
cvar_t * port
Definition: common.cpp:58
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
Definition: shared.cpp:475
static char * rd_buffer
Definition: common.cpp:298
void Qcommon_SetPrintFunction(vPrintfPtr_t func)
Definition: common.cpp:1061
int FS_Read2(void *buffer, int len, qFILE *f, bool failOnEmptyRead)
Read a file into a given buffer in memory.
Definition: files.cpp:327
#define DIST_EPSILON
Definition: defines.h:377
void Com_Shutdown(void)
Definition: scripts.cpp:3732
vec_t vec3_t[3]
Definition: ufotypes.h:39
void Com_SetGameType(void)
Definition: common.cpp:815
void Com_ReadFromPipe(void)
Read whatever is in com_pipefile, if anything, and execute it.
Definition: common.cpp:1260
#define torad
Definition: mathlib.h:50
void FS_CreateOpenPipeFile(const char *filename, qFILE *f)
Definition: files.cpp:47
int CL_FilterEventQueue(event_filter *filter)
Filters every event in the queue using the given function. Keeps all events for which the function re...
Definition: common.cpp:1446
definitions common between client and server, but not game lib
bool event_filter(int when, event_func *func, event_check_func *check, void *data)
Definition: common.h:307
#define MASTER_SERVER
Definition: common.h:124
memPool_t * com_fileSysPool
Definition: common.cpp:72
cvar_t * Cvar_ForceSet(const char *varName, const char *value)
Will set the variable even if NOSET or LATCH.
Definition: cvar.cpp:604
#define BUILDSTRING_OS
Definition: common.h:89
#define lengthof(x)
Definition: shared.h:105
#define DEBUG_SOUND
Definition: defines.h:63
server_state_t state
Definition: server.h:107
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
Definition: cvar.cpp:615
const char * Cvar_GetString(const char *varName)
Returns the value of cvar as string.
Definition: cvar.cpp:210
SharedPtr< scheduleEvent_t > ScheduleEventPtr
Definition: common.h:329
#define Q_streq(a, b)
Definition: shared.h:136
event_func * func
Definition: common.cpp:92
char name[MAX_VAR]
Definition: q_shared.h:337
int Cmd_CompleteCommandParameters(const char *command, const char *partial, const char **match)
Unix like tab completion for console commands parameters.
Definition: cmd.cpp:903
ScheduleEventPtr Schedule_Event(int when, event_func *func, event_check_func *check, event_clean_func *clean, void *data)
Schedules an event to run on or after the given time, and when its check function returns true...
Definition: common.cpp:1362
bool operator()(const ScheduleEventPtr &e1, const ScheduleEventPtr &e2) const
Definition: common.cpp:98
cvar_t * sys_os
Definition: common.cpp:61
#define MAX_NUM_ARGVS
Definition: common.cpp:37
#define Mem_PoolAllocType(type, pool)
Definition: mem.h:43
const char * value
Definition: http.h:61
#define DEBUG_SHARED
Definition: defines.h:55
voidpf uLong offset
Definition: ioapi.h:45
static const debugLevel_t debugLevels[]
Definition: common.cpp:910
bool buttons[16]
Definition: cl_joystick.cpp:44
void Cbuf_Execute(void)
Pulls off terminated lines of text from the command buffer and sends them through Cmd_ExecuteString...
Definition: cmd.cpp:214
bool modified
Definition: cvar.h:79
void Cvar_SetValue(const char *varName, float value)
Expands value to a string and calls Cvar_Set.
Definition: cvar.cpp:671
#define ERR_DISCONNECT
Definition: defines.h:112
int Cvar_CompleteVariable(const char *partial, const char **match)
Unix like tab completion for console variables.
Definition: cvar.cpp:258
uint8_t byte
Definition: ufotypes.h:34
QGL_EXTERN int GLboolean GLfloat * v
Definition: r_gl.h:120
QGL_EXTERN GLuint GLsizei bufSize
Definition: r_gl.h:110
void Sys_Quit(void)
#define DEBUG_RENDERER
Definition: defines.h:62
int next_check
Definition: common.cpp:88
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
Definition: cvar.h:71
int Com_ServerState(void)
Check whether we are the server or have a singleplayer tactical mission.
Definition: common.cpp:538
bool event_check_func(int now, void *data)
Definition: common.h:301
void Cbuf_AddEarlyCommands(bool clear)
Adds command line parameters as script statements Commands lead with a +, and continue until another ...
Definition: cmd.cpp:275
void Sys_Breakpoint(void)
Definition: unix_shared.cpp:84
void Com_Drop(void)
Definition: common.cpp:465
int numGTs
Definition: q_shared.h:568
cvar_t * sys_priority
Definition: common.cpp:59
#define DOUBLEQUOTE(x)
Definition: shared.h:90
void Cmd_WriteAliases(qFILE *f)
Write lines containing "aliasa alias value" for all aliases with the archive flag set to true...
Definition: cmd.cpp:454
#define VectorSubtract(a, b, dest)
Definition: vector.h:45
bool Cvar_SetCheckFunction(const char *varName, bool(*check)(cvar_t *cvar))
Set a checker function for cvar values.
Definition: cvar.cpp:139
#define CVAR_SERVERINFO
Definition: cvar.h:42
#define DEBUG_COMMANDS
Definition: defines.h:58
static int com_argc
Definition: common.cpp:41
#define DEBUG_GAME
Definition: defines.h:61
void FS_Shutdown(void)
Cleanup function.
Definition: files.cpp:1604
void SV_Frame(int now, void *)
Definition: sv_main.cpp:837
void Com_SetUserinfoModified(bool modified)
Definition: cvar.cpp:56
level_locals_t level
Definition: g_main.cpp:38
const char * str
Definition: common.cpp:906
void SV_Shutdown(const char *finalmsg, bool reconnect)
Called when each game quits, before Sys_Quit or Sys_Error.
Definition: sv_main.cpp:1042
int Sys_Milliseconds(void)
Definition: unix_shared.cpp:41
int FS_Write(const void *buffer, int len, qFILE *f)
Properly handles partial writes.
Definition: files.cpp:1513
void Com_WriteConfigToFile(const char *filename)
Definition: common.cpp:981
#define PORT_SERVER
Definition: common.h:137
#define TIMER_CHECK_LAG
Definition: common.cpp:77
char * string
Definition: cvar.h:73