sys_unix.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include <sys/types.h>
  16. #include "qwsvdef.h"
  17. #ifdef NeXT
  18. #include <libc.h>
  19. #endif
  20. #if defined(__linux__) || defined(sun)
  21. #include <sys/stat.h>
  22. #include <unistd.h>
  23. #include <sys/time.h>
  24. #include <errno.h>
  25. #else
  26. #include <sys/dir.h>
  27. #endif
  28. cvar_t sys_nostdout = {"sys_nostdout","0"};
  29. cvar_t sys_extrasleep = {"sys_extrasleep","0"};
  30. qboolean stdin_ready;
  31. /*
  32. ===============================================================================
  33. REQUIRED SYS FUNCTIONS
  34. ===============================================================================
  35. */
  36. /*
  37. ============
  38. Sys_FileTime
  39. returns -1 if not present
  40. ============
  41. */
  42. int Sys_FileTime (char *path)
  43. {
  44. struct stat buf;
  45. if (stat (path,&buf) == -1)
  46. return -1;
  47. return buf.st_mtime;
  48. }
  49. /*
  50. ============
  51. Sys_mkdir
  52. ============
  53. */
  54. void Sys_mkdir (char *path)
  55. {
  56. if (mkdir (path, 0777) != -1)
  57. return;
  58. if (errno != EEXIST)
  59. Sys_Error ("mkdir %s: %s",path, strerror(errno));
  60. }
  61. /*
  62. ================
  63. Sys_DoubleTime
  64. ================
  65. */
  66. double Sys_DoubleTime (void)
  67. {
  68. struct timeval tp;
  69. struct timezone tzp;
  70. static int secbase;
  71. gettimeofday(&tp, &tzp);
  72. if (!secbase)
  73. {
  74. secbase = tp.tv_sec;
  75. return tp.tv_usec/1000000.0;
  76. }
  77. return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
  78. }
  79. /*
  80. ================
  81. Sys_Error
  82. ================
  83. */
  84. void Sys_Error (char *error, ...)
  85. {
  86. va_list argptr;
  87. char string[1024];
  88. va_start (argptr,error);
  89. vsprintf (string,error,argptr);
  90. va_end (argptr);
  91. printf ("Fatal error: %s\n",string);
  92. exit (1);
  93. }
  94. /*
  95. ================
  96. Sys_Printf
  97. ================
  98. */
  99. void Sys_Printf (char *fmt, ...)
  100. {
  101. va_list argptr;
  102. static char text[2048];
  103. unsigned char *p;
  104. va_start (argptr,fmt);
  105. vsprintf (text,fmt,argptr);
  106. va_end (argptr);
  107. if (strlen(text) > sizeof(text))
  108. Sys_Error("memory overwrite in Sys_Printf");
  109. if (sys_nostdout.value)
  110. return;
  111. for (p = (unsigned char *)text; *p; p++) {
  112. *p &= 0x7f;
  113. if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
  114. printf("[%02x]", *p);
  115. else
  116. putc(*p, stdout);
  117. }
  118. fflush(stdout);
  119. }
  120. /*
  121. ================
  122. Sys_Quit
  123. ================
  124. */
  125. void Sys_Quit (void)
  126. {
  127. exit (0); // appkit isn't running
  128. }
  129. static int do_stdin = 1;
  130. /*
  131. ================
  132. Sys_ConsoleInput
  133. Checks for a complete line of text typed in at the console, then forwards
  134. it to the host command processor
  135. ================
  136. */
  137. char *Sys_ConsoleInput (void)
  138. {
  139. static char text[256];
  140. int len;
  141. if (!stdin_ready || !do_stdin)
  142. return NULL; // the select didn't say it was ready
  143. stdin_ready = false;
  144. len = read (0, text, sizeof(text));
  145. if (len == 0) {
  146. // end of file
  147. do_stdin = 0;
  148. return NULL;
  149. }
  150. if (len < 1)
  151. return NULL;
  152. text[len-1] = 0; // rip off the /n and terminate
  153. return text;
  154. }
  155. /*
  156. =============
  157. Sys_Init
  158. Quake calls this so the system can register variables before host_hunklevel
  159. is marked
  160. =============
  161. */
  162. void Sys_Init (void)
  163. {
  164. Cvar_RegisterVariable (&sys_nostdout);
  165. Cvar_RegisterVariable (&sys_extrasleep);
  166. }
  167. /*
  168. =============
  169. main
  170. =============
  171. */
  172. void main(int argc, char *argv[])
  173. {
  174. double time, oldtime, newtime;
  175. quakeparms_t parms;
  176. fd_set fdset;
  177. extern int net_socket;
  178. struct timeval timeout;
  179. int j;
  180. memset (&parms, 0, sizeof(parms));
  181. COM_InitArgv (argc, argv);
  182. parms.argc = com_argc;
  183. parms.argv = com_argv;
  184. parms.memsize = 16*1024*1024;
  185. j = COM_CheckParm("-mem");
  186. if (j)
  187. parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024);
  188. if ((parms.membase = malloc (parms.memsize)) == NULL)
  189. Sys_Error("Can't allocate %ld\n", parms.memsize);
  190. parms.basedir = ".";
  191. /*
  192. if (Sys_FileTime ("id1/pak0.pak") != -1)
  193. else
  194. parms.basedir = "/raid/quake/v2";
  195. */
  196. SV_Init (&parms);
  197. // run one frame immediately for first heartbeat
  198. SV_Frame (0.1);
  199. //
  200. // main loop
  201. //
  202. oldtime = Sys_DoubleTime () - 0.1;
  203. while (1)
  204. {
  205. // select on the net socket and stdin
  206. // the only reason we have a timeout at all is so that if the last
  207. // connected client times out, the message would not otherwise
  208. // be printed until the next event.
  209. FD_ZERO(&fdset);
  210. if (do_stdin)
  211. FD_SET(0, &fdset);
  212. FD_SET(net_socket, &fdset);
  213. timeout.tv_sec = 1;
  214. timeout.tv_usec = 0;
  215. if (select (net_socket+1, &fdset, NULL, NULL, &timeout) == -1)
  216. continue;
  217. stdin_ready = FD_ISSET(0, &fdset);
  218. // find time passed since last cycle
  219. newtime = Sys_DoubleTime ();
  220. time = newtime - oldtime;
  221. oldtime = newtime;
  222. SV_Frame (time);
  223. // extrasleep is just a way to generate a fucked up connection on purpose
  224. if (sys_extrasleep.value)
  225. usleep (sys_extrasleep.value);
  226. }
  227. }