sys_linux.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. #include <unistd.h>
  2. #include <signal.h>
  3. #include <stdlib.h>
  4. #include <limits.h>
  5. #include <sys/time.h>
  6. #include <sys/types.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <stdarg.h>
  10. #include <stdio.h>
  11. #include <sys/ipc.h>
  12. #include <sys/shm.h>
  13. #include <sys/stat.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <sys/wait.h>
  17. #include <sys/mman.h>
  18. #include <errno.h>
  19. #include "quakedef.h"
  20. qboolean isDedicated;
  21. int nostdout = 0;
  22. char *basedir = ".";
  23. char *cachedir = "/tmp";
  24. cvar_t sys_linerefresh = {"sys_linerefresh","0"};// set for entity display
  25. // =======================================================================
  26. // General routines
  27. // =======================================================================
  28. void Sys_DebugNumber(int y, int val)
  29. {
  30. }
  31. /*
  32. void Sys_Printf (char *fmt, ...)
  33. {
  34. va_list argptr;
  35. char text[1024];
  36. va_start (argptr,fmt);
  37. vsprintf (text,fmt,argptr);
  38. va_end (argptr);
  39. fprintf(stderr, "%s", text);
  40. Con_Print (text);
  41. }
  42. void Sys_Printf (char *fmt, ...)
  43. {
  44. va_list argptr;
  45. char text[1024], *t_p;
  46. int l, r;
  47. if (nostdout)
  48. return;
  49. va_start (argptr,fmt);
  50. vsprintf (text,fmt,argptr);
  51. va_end (argptr);
  52. l = strlen(text);
  53. t_p = text;
  54. // make sure everything goes through, even though we are non-blocking
  55. while (l)
  56. {
  57. r = write (1, text, l);
  58. if (r != l)
  59. sleep (0);
  60. if (r > 0)
  61. {
  62. t_p += r;
  63. l -= r;
  64. }
  65. }
  66. }
  67. */
  68. void Sys_Printf (char *fmt, ...)
  69. {
  70. va_list argptr;
  71. char text[1024];
  72. unsigned char *p;
  73. va_start (argptr,fmt);
  74. vsprintf (text,fmt,argptr);
  75. va_end (argptr);
  76. if (strlen(text) > sizeof(text))
  77. Sys_Error("memory overwrite in Sys_Printf");
  78. if (nostdout)
  79. return;
  80. for (p = (unsigned char *)text; *p; p++) {
  81. *p &= 0x7f;
  82. if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
  83. printf("[%02x]", *p);
  84. else
  85. putc(*p, stdout);
  86. }
  87. }
  88. #if 0
  89. static char end1[] =
  90. "\x1b[?7h\x1b[40m\x1b[2J\x1b[0;1;41m\x1b[1;1H QUAKE: The Doomed Dimension \x1b[33mby \x1b[44mid\x1b[41m Software \x1b[2;1H ---------------------------------------------------------------------------- \x1b[3;1H CALL 1-800-IDGAMES TO ORDER OR FOR TECHNICAL SUPPORT \x1b[4;1H PRICE: $45.00 (PRICES MAY VARY OUTSIDE THE US.) \x1b[5;1H \x1b[6;1H \x1b[37mYes! You only have one fourth of this incredible epic. That is because most \x1b[7;1H of you have paid us nothing or at most, very little. You could steal the \x1b[8;1H game from a friend. But we both know you'll be punished by God if you do. \x1b[9;1H \x1b[33mWHY RISK ETERNAL DAMNATION? CALL 1-800-IDGAMES AND BUY NOW! \x1b[10;1H \x1b[37mRemember, we love you almost as much as He does. \x1b[11;1H \x1b[12;1H \x1b[33mProgramming: \x1b[37mJohn Carmack, Michael Abrash, John Cash \x1b[13;1H \x1b[33mDesign: \x1b[37mJohn Romero, Sandy Petersen, American McGee, Tim Willits \x1b[14;1H \x1b[33mArt: \x1b[37mAdrian Carmack, Kevin Cloud \x1b[15;1H \x1b[33mBiz: \x1b[37mJay Wilbur, Mike Wilson, Donna Jackson \x1b[16;1H \x1b[33mProjects: \x1b[37mShawn Green \x1b[33mSupport: \x1b[37mBarrett Alexander \x1b[17;1H \x1b[33mSound Effects: \x1b[37mTrent Reznor and Nine Inch Nails \x1b[18;1H For other information or details on ordering outside the US, check out the \x1b[19;1H files accompanying QUAKE or our website at http://www.idsoftware.com. \x1b[20;1H \x1b[0;41mQuake is a trademark of Id Software, inc., (c)1996 Id Software, inc. \x1b[21;1H All rights reserved. NIN logo is a registered trademark licensed to \x1b[22;1H Nothing Interactive, Inc. All rights reserved. \x1b[40m\x1b[23;1H\x1b[0m";
  91. static char end2[] =
  92. "\x1b[?7h\x1b[40m\x1b[2J\x1b[0;1;41m\x1b[1;1H QUAKE \x1b[33mby \x1b[44mid\x1b[41m Software \x1b[2;1H ----------------------------------------------------------------------------- \x1b[3;1H \x1b[37mWhy did you quit from the registered version of QUAKE? Did the \x1b[4;1H scary monsters frighten you? Or did Mr. Sandman tug at your \x1b[5;1H little lids? No matter! What is important is you love our \x1b[6;1H game, and gave us your money. Congratulations, you are probably \x1b[7;1H not a thief. \x1b[8;1H Thank You. \x1b[9;1H \x1b[33;44mid\x1b[41m Software is: \x1b[10;1H PROGRAMMING: \x1b[37mJohn Carmack, Michael Abrash, John Cash \x1b[11;1H \x1b[33mDESIGN: \x1b[37mJohn Romero, Sandy Petersen, American McGee, Tim Willits \x1b[12;1H \x1b[33mART: \x1b[37mAdrian Carmack, Kevin Cloud \x1b[13;1H \x1b[33mBIZ: \x1b[37mJay Wilbur, Mike Wilson \x1b[33mPROJECTS MAN: \x1b[37mShawn Green \x1b[14;1H \x1b[33mBIZ ASSIST: \x1b[37mDonna Jackson \x1b[33mSUPPORT: \x1b[37mBarrett Alexander \x1b[15;1H \x1b[33mSOUND EFFECTS AND MUSIC: \x1b[37mTrent Reznor and Nine Inch Nails \x1b[16;1H \x1b[17;1H If you need help running QUAKE refer to the text files in the \x1b[18;1H QUAKE directory, or our website at http://www.idsoftware.com. \x1b[19;1H If all else fails, call our technical support at 1-800-IDGAMES. \x1b[20;1H \x1b[0;41mQuake is a trademark of Id Software, inc., (c)1996 Id Software, inc. \x1b[21;1H All rights reserved. NIN logo is a registered trademark licensed \x1b[22;1H to Nothing Interactive, Inc. All rights reserved. \x1b[23;1H\x1b[40m\x1b[0m";
  93. #endif
  94. void Sys_Quit (void)
  95. {
  96. Host_Shutdown();
  97. fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
  98. #if 0
  99. if (registered.value)
  100. printf("%s", end2);
  101. else
  102. printf("%s", end1);
  103. #endif
  104. fflush(stdout);
  105. exit(0);
  106. }
  107. void Sys_Init(void)
  108. {
  109. #if id386
  110. Sys_SetFPCW();
  111. #endif
  112. }
  113. void Sys_Error (char *error, ...)
  114. {
  115. va_list argptr;
  116. char string[1024];
  117. // change stdin to non blocking
  118. fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
  119. va_start (argptr,error);
  120. vsprintf (string,error,argptr);
  121. va_end (argptr);
  122. fprintf(stderr, "Error: %s\n", string);
  123. Host_Shutdown ();
  124. exit (1);
  125. }
  126. void Sys_Warn (char *warning, ...)
  127. {
  128. va_list argptr;
  129. char string[1024];
  130. va_start (argptr,warning);
  131. vsprintf (string,warning,argptr);
  132. va_end (argptr);
  133. fprintf(stderr, "Warning: %s", string);
  134. }
  135. /*
  136. ============
  137. Sys_FileTime
  138. returns -1 if not present
  139. ============
  140. */
  141. int Sys_FileTime (char *path)
  142. {
  143. struct stat buf;
  144. if (stat (path,&buf) == -1)
  145. return -1;
  146. return buf.st_mtime;
  147. }
  148. void Sys_mkdir (char *path)
  149. {
  150. mkdir (path, 0777);
  151. }
  152. int Sys_FileOpenRead (char *path, int *handle)
  153. {
  154. int h;
  155. struct stat fileinfo;
  156. h = open (path, O_RDONLY, 0666);
  157. *handle = h;
  158. if (h == -1)
  159. return -1;
  160. if (fstat (h,&fileinfo) == -1)
  161. Sys_Error ("Error fstating %s", path);
  162. return fileinfo.st_size;
  163. }
  164. int Sys_FileOpenWrite (char *path)
  165. {
  166. int handle;
  167. umask (0);
  168. handle = open(path,O_RDWR | O_CREAT | O_TRUNC
  169. , 0666);
  170. if (handle == -1)
  171. Sys_Error ("Error opening %s: %s", path,strerror(errno));
  172. return handle;
  173. }
  174. int Sys_FileWrite (int handle, void *src, int count)
  175. {
  176. return write (handle, src, count);
  177. }
  178. void Sys_FileClose (int handle)
  179. {
  180. close (handle);
  181. }
  182. void Sys_FileSeek (int handle, int position)
  183. {
  184. lseek (handle, position, SEEK_SET);
  185. }
  186. int Sys_FileRead (int handle, void *dest, int count)
  187. {
  188. return read (handle, dest, count);
  189. }
  190. void Sys_DebugLog(char *file, char *fmt, ...)
  191. {
  192. va_list argptr;
  193. static char data[1024];
  194. int fd;
  195. va_start(argptr, fmt);
  196. vsprintf(data, fmt, argptr);
  197. va_end(argptr);
  198. // fd = open(file, O_WRONLY | O_BINARY | O_CREAT | O_APPEND, 0666);
  199. fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
  200. write(fd, data, strlen(data));
  201. close(fd);
  202. }
  203. void Sys_EditFile(char *filename)
  204. {
  205. char cmd[256];
  206. char *term;
  207. char *editor;
  208. term = getenv("TERM");
  209. if (term && !strcmp(term, "xterm"))
  210. {
  211. editor = getenv("VISUAL");
  212. if (!editor)
  213. editor = getenv("EDITOR");
  214. if (!editor)
  215. editor = getenv("EDIT");
  216. if (!editor)
  217. editor = "vi";
  218. sprintf(cmd, "xterm -e %s %s", editor, filename);
  219. system(cmd);
  220. }
  221. }
  222. double Sys_FloatTime (void)
  223. {
  224. struct timeval tp;
  225. struct timezone tzp;
  226. static int secbase;
  227. gettimeofday(&tp, &tzp);
  228. if (!secbase)
  229. {
  230. secbase = tp.tv_sec;
  231. return tp.tv_usec/1000000.0;
  232. }
  233. return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
  234. }
  235. // =======================================================================
  236. // Sleeps for microseconds
  237. // =======================================================================
  238. static volatile int oktogo;
  239. void alarm_handler(int x)
  240. {
  241. oktogo=1;
  242. }
  243. void Sys_LineRefresh(void)
  244. {
  245. }
  246. void floating_point_exception_handler(int whatever)
  247. {
  248. // Sys_Warn("floating point exception\n");
  249. signal(SIGFPE, floating_point_exception_handler);
  250. }
  251. char *Sys_ConsoleInput(void)
  252. {
  253. static char text[256];
  254. int len;
  255. fd_set fdset;
  256. struct timeval timeout;
  257. if (cls.state == ca_dedicated) {
  258. FD_ZERO(&fdset);
  259. FD_SET(0, &fdset); // stdin
  260. timeout.tv_sec = 0;
  261. timeout.tv_usec = 0;
  262. if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
  263. return NULL;
  264. len = read (0, text, sizeof(text));
  265. if (len < 1)
  266. return NULL;
  267. text[len-1] = 0; // rip off the /n and terminate
  268. return text;
  269. }
  270. return NULL;
  271. }
  272. #if !id386
  273. void Sys_HighFPPrecision (void)
  274. {
  275. }
  276. void Sys_LowFPPrecision (void)
  277. {
  278. }
  279. #endif
  280. int main (int c, char **v)
  281. {
  282. double time, oldtime, newtime;
  283. quakeparms_t parms;
  284. extern int vcrFile;
  285. extern int recording;
  286. int j;
  287. // static char cwd[1024];
  288. // signal(SIGFPE, floating_point_exception_handler);
  289. signal(SIGFPE, SIG_IGN);
  290. memset(&parms, 0, sizeof(parms));
  291. COM_InitArgv(c, v);
  292. parms.argc = com_argc;
  293. parms.argv = com_argv;
  294. #ifdef GLQUAKE
  295. parms.memsize = 16*1024*1024;
  296. #else
  297. parms.memsize = 8*1024*1024;
  298. #endif
  299. j = COM_CheckParm("-mem");
  300. if (j)
  301. parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024);
  302. parms.membase = malloc (parms.memsize);
  303. parms.basedir = basedir;
  304. // caching is disabled by default, use -cachedir to enable
  305. // parms.cachedir = cachedir;
  306. fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
  307. Host_Init(&parms);
  308. Sys_Init();
  309. if (COM_CheckParm("-nostdout"))
  310. nostdout = 1;
  311. else {
  312. fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
  313. printf ("Linux Quake -- Version %0.3f\n", LINUX_VERSION);
  314. }
  315. oldtime = Sys_FloatTime () - 0.1;
  316. while (1)
  317. {
  318. // find time spent rendering last frame
  319. newtime = Sys_FloatTime ();
  320. time = newtime - oldtime;
  321. if (cls.state == ca_dedicated)
  322. { // play vcrfiles at max speed
  323. if (time < sys_ticrate.value && (vcrFile == -1 || recording) )
  324. {
  325. usleep(1);
  326. continue; // not time to run a server only tic yet
  327. }
  328. time = sys_ticrate.value;
  329. }
  330. if (time > sys_ticrate.value*2)
  331. oldtime = newtime;
  332. else
  333. oldtime += time;
  334. Host_Frame (time);
  335. // graphic debugging aids
  336. if (sys_linerefresh.value)
  337. Sys_LineRefresh ();
  338. }
  339. }
  340. /*
  341. ================
  342. Sys_MakeCodeWriteable
  343. ================
  344. */
  345. void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
  346. {
  347. int r;
  348. unsigned long addr;
  349. int psize = getpagesize();
  350. addr = (startaddr & ~(psize-1)) - psize;
  351. // fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
  352. // addr, startaddr+length, length);
  353. r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
  354. if (r < 0)
  355. Sys_Error("Protection change failed\n");
  356. }