diff options
| author | wyatt8740 <wyatt8740@yahoo.com> | 2014-01-06 12:02:16 -0500 |
|---|---|---|
| committer | wyatt8740 <wyatt8740@yahoo.com> | 2014-01-06 12:02:16 -0500 |
| commit | a8f828a066773a59fdf646299359d35ae0e845af (patch) | |
| tree | 86123409fc6f231cf4136e81159b63cb1e9ec102 /WinQuake/sys_dos.c | |
| parent | b2951690415054ae8705c07f8df7a4ba7cde382a (diff) | |
| download | quake-pum-a8f828a066773a59fdf646299359d35ae0e845af.tar.gz | |
Removed accidental upload of copyrighted map files
Diffstat (limited to 'WinQuake/sys_dos.c')
| -rw-r--r-- | WinQuake/sys_dos.c | 1906 |
1 files changed, 953 insertions, 953 deletions
diff --git a/WinQuake/sys_dos.c b/WinQuake/sys_dos.c index 0a9bc4a..53afd78 100644 --- a/WinQuake/sys_dos.c +++ b/WinQuake/sys_dos.c @@ -1,953 +1,953 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <stdlib.h> -#include <limits.h> -#include <sys/time.h> -#include <sys/types.h> -#include <dir.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdarg.h> -#include <stdio.h> -#include <sys/stat.h> -#include <string.h> -#include <dpmi.h> -#include <sys/nearptr.h> -#include <conio.h> - -#include "quakedef.h" -#include "dosisms.h" - -#define MINIMUM_WIN_MEMORY 0x800000 -#define MINIMUM_WIN_MEMORY_LEVELPAK (MINIMUM_WIN_MEMORY + 0x100000) - -int end_of_memory; -qboolean lockmem, lockunlockmem, unlockmem; -static int win95; - -#define STDOUT 1 - -#define KEYBUF_SIZE 256 -static unsigned char keybuf[KEYBUF_SIZE]; -static int keybuf_head=0; -static int keybuf_tail=0; - -static quakeparms_t quakeparms; -int sys_checksum; -static double curtime = 0.0; -static double lastcurtime = 0.0; -static double oldtime = 0.0; - -static qboolean isDedicated; - -static int minmem; - -float fptest_temp; - -extern char start_of_memory __asm__("start"); - -//============================================================================= - -// this is totally dependent on cwsdpmi putting the stack right after tge -// global data - -// This does evil things in a Win95 DOS box!!! -#if 0 -extern byte end; -#define CHECKBYTE 0xed -void Sys_InitStackCheck (void) -{ - int i; - - for (i=0 ; i<128*1024 ; i++) - (&end)[i] = CHECKBYTE; -} - -void Sys_StackCheck (void) -{ - int i; - - for (i=0 ; i<128*1024 ; i++) - if ( (&end)[i] != CHECKBYTE ) - break; - - Con_Printf ("%i undisturbed stack bytes\n", i); - if (end != CHECKBYTE) - Sys_Error ("System stack overflow!"); -} -#endif - -//============================================================================= - -byte scantokey[128] = - { -// 0 1 2 3 4 5 6 7 -// 8 9 A B C D E F - 0 , 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1 - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2 - 'b', 'n', 'm', ',', '.', '/', K_SHIFT,'*', - K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 - K_F6, K_F7, K_F8, K_F9, K_F10,0 , 0 , K_HOME, - K_UPARROW,K_PGUP,'-',K_LEFTARROW,'5',K_RIGHTARROW,'+',K_END, //4 - K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11, - K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 - }; - -byte shiftscantokey[128] = - { -// 0 1 2 3 4 5 6 7 -// 8 9 A B C D E F - 0 , 27, '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', K_BACKSPACE, 9, // 0 - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', 13 , K_CTRL,'A', 'S', // 1 - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', - '"' , '~', K_SHIFT,'|', 'Z', 'X', 'C', 'V', // 2 - 'B', 'N', 'M', '<', '>', '?', K_SHIFT,'*', - K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 - K_F6, K_F7, K_F8, K_F9, K_F10,0 , 0 , K_HOME, - K_UPARROW,K_PGUP,'_',K_LEFTARROW,'%',K_RIGHTARROW,'+',K_END, //4 - K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11, - K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 - }; - -void TrapKey(void) -{ -// static int ctrl=0; - keybuf[keybuf_head] = dos_inportb(0x60); - dos_outportb(0x20, 0x20); - /* - if (scantokey[keybuf[keybuf_head]&0x7f] == K_CTRL) - ctrl=keybuf[keybuf_head]&0x80; - if (ctrl && scantokey[keybuf[keybuf_head]&0x7f] == 'c') - Sys_Error("ctrl-c hit\n"); - */ - keybuf_head = (keybuf_head + 1) & (KEYBUF_SIZE-1); -} - -#define SC_UPARROW 0x48 -#define SC_DOWNARROW 0x50 -#define SC_LEFTARROW 0x4b -#define SC_RIGHTARROW 0x4d -#define SC_LEFTSHIFT 0x2a -#define SC_RIGHTSHIFT 0x36 -#define SC_RIGHTARROW 0x4d - -void MaskExceptions (void); -void Sys_InitFloatTime (void); -void Sys_PushFPCW_SetHigh (void); -void Sys_PopFPCW (void); - -#define LEAVE_FOR_CACHE (512*1024) //FIXME: tune -#define LOCKED_FOR_MALLOC (128*1024) //FIXME: tune - - -void Sys_DetectWin95 (void) -{ - __dpmi_regs r; - - r.x.ax = 0x160a; /* Get Windows Version */ - __dpmi_int(0x2f, &r); - - if(r.x.ax || r.h.bh < 4) /* Not windows or earlier than Win95 */ - { - win95 = 0; - lockmem = true; - lockunlockmem = false; - unlockmem = true; - } - else - { - win95 = 1; - lockunlockmem = COM_CheckParm ("-winlockunlock"); - - if (lockunlockmem) - lockmem = true; - else - lockmem = COM_CheckParm ("-winlock"); - - unlockmem = lockmem && !lockunlockmem; - } -} - - -void *dos_getmaxlockedmem(int *size) -{ - __dpmi_free_mem_info meminfo; - __dpmi_meminfo info; - int working_size; - void *working_memory; - int last_locked; - int extra, i, j, allocsize; - static char *msg = "Locking data..."; - int m, n; - byte *x; - -// first lock all the current executing image so the locked count will -// be accurate. It doesn't hurt to lock the memory multiple times - last_locked = __djgpp_selector_limit + 1; - info.size = last_locked - 4096; - info.address = __djgpp_base_address + 4096; - - if (lockmem) - { - if(__dpmi_lock_linear_region(&info)) - { - Sys_Error ("Lock of current memory at 0x%lx for %ldKb failed!\n", - info.address, info.size/1024); - } - } - - __dpmi_get_free_memory_information(&meminfo); - - if (!win95) /* Not windows or earlier than Win95 */ - { - working_size = meminfo.maximum_locked_page_allocation_in_pages * 4096; - } - else - { - working_size = meminfo.largest_available_free_block_in_bytes - - LEAVE_FOR_CACHE; - } - - working_size &= ~0xffff; /* Round down to 64K */ - working_size += 0x10000; - - do - { - working_size -= 0x10000; /* Decrease 64K and try again */ - working_memory = sbrk(working_size); - } while (working_memory == (void *)-1); - - extra = 0xfffc - ((unsigned)sbrk(0) & 0xffff); - - if (extra > 0) - { - sbrk(extra); - working_size += extra; - } - -// now grab the memory - info.address = last_locked + __djgpp_base_address; - - if (!win95) - { - info.size = __djgpp_selector_limit + 1 - last_locked; - - while (info.size > 0 && __dpmi_lock_linear_region(&info)) - { - info.size -= 0x1000; - working_size -= 0x1000; - sbrk(-0x1000); - } - } - else - { /* Win95 section */ - j = COM_CheckParm("-winmem"); - - if (standard_quake) - minmem = MINIMUM_WIN_MEMORY; - else - minmem = MINIMUM_WIN_MEMORY_LEVELPAK; - - if (j) - { - allocsize = ((int)(Q_atoi(com_argv[j+1]))) * 0x100000 + - LOCKED_FOR_MALLOC; - - if (allocsize < (minmem + LOCKED_FOR_MALLOC)) - allocsize = minmem + LOCKED_FOR_MALLOC; - } - else - { - allocsize = minmem + LOCKED_FOR_MALLOC; - } - - if (!lockmem) - { - // we won't lock, just sbrk the memory - info.size = allocsize; - goto UpdateSbrk; - } - - // lock the memory down - write (STDOUT, msg, strlen (msg)); - - for (j=allocsize ; j>(minmem + LOCKED_FOR_MALLOC) ; - j -= 0x100000) - { - info.size = j; - - if (!__dpmi_lock_linear_region(&info)) - goto Locked; - - write (STDOUT, ".", 1); - } - - // finally, try with the absolute minimum amount - for (i=0 ; i<10 ; i++) - { - info.size = minmem + LOCKED_FOR_MALLOC; - - if (!__dpmi_lock_linear_region(&info)) - goto Locked; - } - - Sys_Error ("Can't lock memory; %d Mb lockable RAM required. " - "Try shrinking smartdrv.", info.size / 0x100000); - -Locked: - -UpdateSbrk: - - info.address += info.size; - info.address -= __djgpp_base_address + 4; // ending point, malloc align - working_size = info.address - (int)working_memory; - sbrk(info.address-(int)sbrk(0)); // negative adjustment - } - - - if (lockunlockmem) - { - __dpmi_unlock_linear_region (&info); - printf ("Locked and unlocked %d Mb data\n", working_size / 0x100000); - } - else if (lockmem) - { - printf ("Locked %d Mb data\n", working_size / 0x100000); - } - else - { - printf ("Allocated %d Mb data\n", working_size / 0x100000); - } - -// touch all the memory to make sure it's there. The 16-page skip is to -// keep Win 95 from thinking we're trying to page ourselves in (we are -// doing that, of course, but there's no reason we shouldn't) - x = (byte *)working_memory; - - for (n=0 ; n<4 ; n++) - { - for (m=0 ; m<(working_size - 16 * 0x1000) ; m += 4) - { - sys_checksum += *(int *)&x[m]; - sys_checksum += *(int *)&x[m + 16 * 0x1000]; - } - } - -// give some of what we locked back for malloc before returning. Done -// by cheating and passing a negative value to sbrk - working_size -= LOCKED_FOR_MALLOC; - sbrk( -(LOCKED_FOR_MALLOC)); - *size = working_size; - return working_memory; -} - - -/* -============ -Sys_FileTime - -returns -1 if not present -============ -*/ -int Sys_FileTime (char *path) -{ - struct stat buf; - - if (stat (path,&buf) == -1) - return -1; - - return buf.st_mtime; -} - -void Sys_mkdir (char *path) -{ - mkdir (path, 0777); -} - - -void Sys_Sleep(void) -{ -} - - -char *Sys_ConsoleInput(void) -{ - static char text[256]; - static int len = 0; - char ch; - - if (!isDedicated) - return NULL; - - if (! kbhit()) - return NULL; - - ch = getche(); - - switch (ch) - { - case '\r': - putch('\n'); - if (len) - { - text[len] = 0; - len = 0; - return text; - } - break; - - case '\b': - putch(' '); - if (len) - { - len--; - putch('\b'); - } - break; - - default: - text[len] = ch; - len = (len + 1) & 0xff; - break; - } - - return NULL; -} - -void Sys_Init(void) -{ - - MaskExceptions (); - - Sys_SetFPCW (); - - dos_outportb(0x43, 0x34); // set system timer to mode 2 - dos_outportb(0x40, 0); // for the Sys_FloatTime() function - dos_outportb(0x40, 0); - - Sys_InitFloatTime (); - - _go32_interrupt_stack_size = 4 * 1024;; - _go32_rmcb_stack_size = 4 * 1024; -} - -void Sys_Shutdown(void) -{ - if (!isDedicated) - dos_restoreintr(9); - - if (unlockmem) - { - dos_unlockmem (&start_of_memory, - end_of_memory - (int)&start_of_memory); - dos_unlockmem (quakeparms.membase, quakeparms.memsize); - } -} - - -#define SC_RSHIFT 0x36 -#define SC_LSHIFT 0x2a -void Sys_SendKeyEvents (void) -{ - int k, next; - int outkey; - -// get key events - - while (keybuf_head != keybuf_tail) - { - - k = keybuf[keybuf_tail++]; - keybuf_tail &= (KEYBUF_SIZE-1); - - if (k==0xe0) - continue; // special / pause keys - next = keybuf[(keybuf_tail-2)&(KEYBUF_SIZE-1)]; - if (next == 0xe1) - continue; // pause key bullshit - if (k==0xc5 && next == 0x9d) - { - Key_Event (K_PAUSE, true); - continue; - } - - // extended keyboard shift key bullshit - if ( (k&0x7f)==SC_LSHIFT || (k&0x7f)==SC_RSHIFT ) - { - if ( keybuf[(keybuf_tail-2)&(KEYBUF_SIZE-1)]==0xe0 ) - continue; - k &= 0x80; - k |= SC_RSHIFT; - } - - if (k==0xc5 && keybuf[(keybuf_tail-2)&(KEYBUF_SIZE-1)] == 0x9d) - continue; // more pause bullshit - - outkey = scantokey[k & 0x7f]; - - if (k & 0x80) - Key_Event (outkey, false); - else - Key_Event (outkey, true); - - } - -} - - -// ======================================================================= -// General routines -// ======================================================================= - -/* -================ -Sys_Printf -================ -*/ - -void Sys_Printf (char *fmt, ...) -{ - va_list argptr; - char text[1024]; - - va_start (argptr,fmt); - vsprintf (text,fmt,argptr); - va_end (argptr); - - if (cls.state == ca_dedicated) - fprintf(stderr, "%s", text); -} - -void Sys_AtExit (void) -{ - -// shutdown only once (so Sys_Error can call this function to shutdown, then -// print the error message, then call exit without exit calling this function -// again) - Sys_Shutdown(); -} - - -void Sys_Quit (void) -{ - byte screen[80*25*2]; - byte *d; - char ver[6]; - int i; - - -// load the sell screen before shuting everything down - if (registered.value) - d = COM_LoadHunkFile ("end2.bin"); - else - d = COM_LoadHunkFile ("end1.bin"); - if (d) - memcpy (screen, d, sizeof(screen)); - -// write the version number directly to the end screen - sprintf (ver, " v%4.2f", VERSION); - for (i=0 ; i<6 ; i++) - screen[0*80*2 + 72*2 + i*2] = ver[i]; - - Host_Shutdown(); - -// do the text mode sell screen - if (d) - { - memcpy ((void *)real2ptr(0xb8000), screen,80*25*2); - - // set text pos - regs.x.ax = 0x0200; - regs.h.bh = 0; - regs.h.dl = 0; - regs.h.dh = 22; - dos_int86 (0x10); - } - else - printf ("couldn't load endscreen.\n"); - - exit(0); -} - -void Sys_Error (char *error, ...) -{ - va_list argptr; - char string[1024]; - - va_start (argptr,error); - vsprintf (string,error,argptr); - va_end (argptr); - - Host_Shutdown(); - fprintf(stderr, "Error: %s\n", string); -// Sys_AtExit is called by exit to shutdown the system - exit(0); -} - - -int Sys_FileOpenRead (char *path, int *handle) -{ - int h; - struct stat fileinfo; - - h = open (path, O_RDONLY|O_BINARY, 0666); - *handle = h; - if (h == -1) - return -1; - - if (fstat (h,&fileinfo) == -1) - Sys_Error ("Error fstating %s", path); - - return fileinfo.st_size; -} - -int Sys_FileOpenWrite (char *path) -{ - int handle; - - umask (0); - - handle = open(path,O_RDWR | O_BINARY | O_CREAT | O_TRUNC - , 0666); - - if (handle == -1) - Sys_Error ("Error opening %s: %s", path,strerror(errno)); - - return handle; -} - -void Sys_FileClose (int handle) -{ - close (handle); -} - -void Sys_FileSeek (int handle, int position) -{ - lseek (handle, position, SEEK_SET); -} - -int Sys_FileRead (int handle, void *dest, int count) -{ - return read (handle, dest, count); -} - -int Sys_FileWrite (int handle, void *data, int count) -{ - return write (handle, data, count); -} - -/* -================ -Sys_MakeCodeWriteable -================ -*/ -void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length) -{ - // it's always writeable -} - - -/* -================ -Sys_FloatTime -================ -*/ -double Sys_FloatTime (void) -{ - int r; - unsigned t, tick; - double ft, time; - static int sametimecount; - - Sys_PushFPCW_SetHigh (); - -//{static float t = 0; t=t+0.05; return t;} // DEBUG - - t = *(unsigned short*)real2ptr(0x46c) * 65536; - - dos_outportb(0x43, 0); // latch time - r = dos_inportb(0x40); - r |= dos_inportb(0x40) << 8; - r = (r-1) & 0xffff; - - tick = *(unsigned short*)real2ptr(0x46c) * 65536; - if ((tick != t) && (r & 0x8000)) - t = tick; - - ft = (double) (t+(65536-r)) / 1193200.0; - time = ft - oldtime; - oldtime = ft; - - if (time < 0) - { - if (time > -3000.0) - time = 0.0; - else - time += 3600.0; - } - - curtime += time; - - if (curtime == lastcurtime) - { - sametimecount++; - - if (sametimecount > 100000) - { - curtime += 1.0; - sametimecount = 0; - } - } - else - { - sametimecount = 0; - } - - lastcurtime = curtime; - - Sys_PopFPCW (); - - return curtime; -} - - -/* -================ -Sys_InitFloatTime -================ -*/ -void Sys_InitFloatTime (void) -{ - int j; - - Sys_FloatTime (); - - oldtime = curtime; - - j = COM_CheckParm("-starttime"); - - if (j) - { - curtime = (double) (Q_atof(com_argv[j+1])); - } - else - { - curtime = 0.0; - } - lastcurtime = curtime; -} - - -/* -================ -Sys_GetMemory -================ -*/ -void Sys_GetMemory(void) -{ - int j, tsize; - - j = COM_CheckParm("-mem"); - if (j) - { - quakeparms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024); - quakeparms.membase = malloc (quakeparms.memsize); - } - else - { - quakeparms.membase = dos_getmaxlockedmem (&quakeparms.memsize); - } - - fprintf(stderr, "malloc'd: %d\n", quakeparms.memsize); - - if (COM_CheckParm ("-heapsize")) - { - tsize = Q_atoi (com_argv[COM_CheckParm("-heapsize") + 1]) * 1024; - - if (tsize < quakeparms.memsize) - quakeparms.memsize = tsize; - } -} - - -/* -================ -Sys_PageInProgram - -walks the text, data, and bss to make sure it's all paged in so that the -actual physical memory detected by Sys_GetMemory is correct. -================ -*/ -void Sys_PageInProgram(void) -{ - int i, j; - - end_of_memory = (int)sbrk(0); - - if (lockmem) - { - if (dos_lockmem ((void *)&start_of_memory, - end_of_memory - (int)&start_of_memory)) - Sys_Error ("Couldn't lock text and data"); - } - - if (lockunlockmem) - { - dos_unlockmem((void *)&start_of_memory, - end_of_memory - (int)&start_of_memory); - printf ("Locked and unlocked %d Mb image\n", - (end_of_memory - (int)&start_of_memory) / 0x100000); - } - else if (lockmem) - { - printf ("Locked %d Mb image\n", - (end_of_memory - (int)&start_of_memory) / 0x100000); - } - else - { - printf ("Loaded %d Mb image\n", - (end_of_memory - (int)&start_of_memory) / 0x100000); - } - -// touch the entire image, doing the 16-page skip so Win95 doesn't think we're -// trying to page ourselves in - for (j=0 ; j<4 ; j++) - { - for(i=(int)&start_of_memory ; i<(end_of_memory - 16 * 0x1000) ; i += 4) - { - sys_checksum += *(int *)i; - sys_checksum += *(int *)(i + 16 * 0x1000); - } - } -} - - -/* -================ -Sys_NoFPUExceptionHandler -================ -*/ -void Sys_NoFPUExceptionHandler(int whatever) -{ - printf ("\nError: Quake requires a floating-point processor\n"); - exit (0); -} - - -/* -================ -Sys_DefaultExceptionHandler -================ -*/ -void Sys_DefaultExceptionHandler(int whatever) -{ -} - - -/* -================ -main -================ -*/ -int main (int c, char **v) -{ - double time, oldtime, newtime; - extern void (*dos_error_func)(char *, ...); - static char cwd[1024]; - - printf ("Quake v%4.2f\n", VERSION); - -// make sure there's an FPU - signal(SIGNOFP, Sys_NoFPUExceptionHandler); - signal(SIGABRT, Sys_DefaultExceptionHandler); - signal(SIGALRM, Sys_DefaultExceptionHandler); - signal(SIGKILL, Sys_DefaultExceptionHandler); - signal(SIGQUIT, Sys_DefaultExceptionHandler); - signal(SIGINT, Sys_DefaultExceptionHandler); - - if (fptest_temp >= 0.0) - fptest_temp += 0.1; - - COM_InitArgv (c, v); - - quakeparms.argc = com_argc; - quakeparms.argv = com_argv; - - dos_error_func = Sys_Error; - - Sys_DetectWin95 (); - Sys_PageInProgram (); - Sys_GetMemory (); - - atexit (Sys_AtExit); // in case we crash - - getwd (cwd); - if (cwd[Q_strlen(cwd)-1] == '/') cwd[Q_strlen(cwd)-1] = 0; - quakeparms.basedir = cwd; //"f:/quake"; - - isDedicated = (COM_CheckParm ("-dedicated") != 0); - - Sys_Init (); - - if (!isDedicated) - dos_registerintr(9, TrapKey); - -//Sys_InitStackCheck (); - - Host_Init(&quakeparms); - -//Sys_StackCheck (); - -//Con_Printf ("Top of stack: 0x%x\n", &time); - oldtime = Sys_FloatTime (); - while (1) - { - newtime = Sys_FloatTime (); - time = newtime - oldtime; - - if (cls.state == ca_dedicated && (time<sys_ticrate.value)) - continue; - - Host_Frame (time); - -//Sys_StackCheck (); - - oldtime = newtime; - } -} - - +/*
+Copyright (C) 1996-1997 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <dir.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <dpmi.h>
+#include <sys/nearptr.h>
+#include <conio.h>
+
+#include "quakedef.h"
+#include "dosisms.h"
+
+#define MINIMUM_WIN_MEMORY 0x800000
+#define MINIMUM_WIN_MEMORY_LEVELPAK (MINIMUM_WIN_MEMORY + 0x100000)
+
+int end_of_memory;
+qboolean lockmem, lockunlockmem, unlockmem;
+static int win95;
+
+#define STDOUT 1
+
+#define KEYBUF_SIZE 256
+static unsigned char keybuf[KEYBUF_SIZE];
+static int keybuf_head=0;
+static int keybuf_tail=0;
+
+static quakeparms_t quakeparms;
+int sys_checksum;
+static double curtime = 0.0;
+static double lastcurtime = 0.0;
+static double oldtime = 0.0;
+
+static qboolean isDedicated;
+
+static int minmem;
+
+float fptest_temp;
+
+extern char start_of_memory __asm__("start");
+
+//=============================================================================
+
+// this is totally dependent on cwsdpmi putting the stack right after tge
+// global data
+
+// This does evil things in a Win95 DOS box!!!
+#if 0
+extern byte end;
+#define CHECKBYTE 0xed
+void Sys_InitStackCheck (void)
+{
+ int i;
+
+ for (i=0 ; i<128*1024 ; i++)
+ (&end)[i] = CHECKBYTE;
+}
+
+void Sys_StackCheck (void)
+{
+ int i;
+
+ for (i=0 ; i<128*1024 ; i++)
+ if ( (&end)[i] != CHECKBYTE )
+ break;
+
+ Con_Printf ("%i undisturbed stack bytes\n", i);
+ if (end != CHECKBYTE)
+ Sys_Error ("System stack overflow!");
+}
+#endif
+
+//=============================================================================
+
+byte scantokey[128] =
+ {
+// 0 1 2 3 4 5 6 7
+// 8 9 A B C D E F
+ 0 , 27, '1', '2', '3', '4', '5', '6',
+ '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0
+ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
+ 'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
+ '\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2
+ 'b', 'n', 'm', ',', '.', '/', K_SHIFT,'*',
+ K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3
+ K_F6, K_F7, K_F8, K_F9, K_F10,0 , 0 , K_HOME,
+ K_UPARROW,K_PGUP,'-',K_LEFTARROW,'5',K_RIGHTARROW,'+',K_END, //4
+ K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11,
+ K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7
+ };
+
+byte shiftscantokey[128] =
+ {
+// 0 1 2 3 4 5 6 7
+// 8 9 A B C D E F
+ 0 , 27, '!', '@', '#', '$', '%', '^',
+ '&', '*', '(', ')', '_', '+', K_BACKSPACE, 9, // 0
+ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
+ 'O', 'P', '{', '}', 13 , K_CTRL,'A', 'S', // 1
+ 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
+ '"' , '~', K_SHIFT,'|', 'Z', 'X', 'C', 'V', // 2
+ 'B', 'N', 'M', '<', '>', '?', K_SHIFT,'*',
+ K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3
+ K_F6, K_F7, K_F8, K_F9, K_F10,0 , 0 , K_HOME,
+ K_UPARROW,K_PGUP,'_',K_LEFTARROW,'%',K_RIGHTARROW,'+',K_END, //4
+ K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11,
+ K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7
+ };
+
+void TrapKey(void)
+{
+// static int ctrl=0;
+ keybuf[keybuf_head] = dos_inportb(0x60);
+ dos_outportb(0x20, 0x20);
+ /*
+ if (scantokey[keybuf[keybuf_head]&0x7f] == K_CTRL)
+ ctrl=keybuf[keybuf_head]&0x80;
+ if (ctrl && scantokey[keybuf[keybuf_head]&0x7f] == 'c')
+ Sys_Error("ctrl-c hit\n");
+ */
+ keybuf_head = (keybuf_head + 1) & (KEYBUF_SIZE-1);
+}
+
+#define SC_UPARROW 0x48
+#define SC_DOWNARROW 0x50
+#define SC_LEFTARROW 0x4b
+#define SC_RIGHTARROW 0x4d
+#define SC_LEFTSHIFT 0x2a
+#define SC_RIGHTSHIFT 0x36
+#define SC_RIGHTARROW 0x4d
+
+void MaskExceptions (void);
+void Sys_InitFloatTime (void);
+void Sys_PushFPCW_SetHigh (void);
+void Sys_PopFPCW (void);
+
+#define LEAVE_FOR_CACHE (512*1024) //FIXME: tune
+#define LOCKED_FOR_MALLOC (128*1024) //FIXME: tune
+
+
+void Sys_DetectWin95 (void)
+{
+ __dpmi_regs r;
+
+ r.x.ax = 0x160a; /* Get Windows Version */
+ __dpmi_int(0x2f, &r);
+
+ if(r.x.ax || r.h.bh < 4) /* Not windows or earlier than Win95 */
+ {
+ win95 = 0;
+ lockmem = true;
+ lockunlockmem = false;
+ unlockmem = true;
+ }
+ else
+ {
+ win95 = 1;
+ lockunlockmem = COM_CheckParm ("-winlockunlock");
+
+ if (lockunlockmem)
+ lockmem = true;
+ else
+ lockmem = COM_CheckParm ("-winlock");
+
+ unlockmem = lockmem && !lockunlockmem;
+ }
+}
+
+
+void *dos_getmaxlockedmem(int *size)
+{
+ __dpmi_free_mem_info meminfo;
+ __dpmi_meminfo info;
+ int working_size;
+ void *working_memory;
+ int last_locked;
+ int extra, i, j, allocsize;
+ static char *msg = "Locking data...";
+ int m, n;
+ byte *x;
+
+// first lock all the current executing image so the locked count will
+// be accurate. It doesn't hurt to lock the memory multiple times
+ last_locked = __djgpp_selector_limit + 1;
+ info.size = last_locked - 4096;
+ info.address = __djgpp_base_address + 4096;
+
+ if (lockmem)
+ {
+ if(__dpmi_lock_linear_region(&info))
+ {
+ Sys_Error ("Lock of current memory at 0x%lx for %ldKb failed!\n",
+ info.address, info.size/1024);
+ }
+ }
+
+ __dpmi_get_free_memory_information(&meminfo);
+
+ if (!win95) /* Not windows or earlier than Win95 */
+ {
+ working_size = meminfo.maximum_locked_page_allocation_in_pages * 4096;
+ }
+ else
+ {
+ working_size = meminfo.largest_available_free_block_in_bytes -
+ LEAVE_FOR_CACHE;
+ }
+
+ working_size &= ~0xffff; /* Round down to 64K */
+ working_size += 0x10000;
+
+ do
+ {
+ working_size -= 0x10000; /* Decrease 64K and try again */
+ working_memory = sbrk(working_size);
+ } while (working_memory == (void *)-1);
+
+ extra = 0xfffc - ((unsigned)sbrk(0) & 0xffff);
+
+ if (extra > 0)
+ {
+ sbrk(extra);
+ working_size += extra;
+ }
+
+// now grab the memory
+ info.address = last_locked + __djgpp_base_address;
+
+ if (!win95)
+ {
+ info.size = __djgpp_selector_limit + 1 - last_locked;
+
+ while (info.size > 0 && __dpmi_lock_linear_region(&info))
+ {
+ info.size -= 0x1000;
+ working_size -= 0x1000;
+ sbrk(-0x1000);
+ }
+ }
+ else
+ { /* Win95 section */
+ j = COM_CheckParm("-winmem");
+
+ if (standard_quake)
+ minmem = MINIMUM_WIN_MEMORY;
+ else
+ minmem = MINIMUM_WIN_MEMORY_LEVELPAK;
+
+ if (j)
+ {
+ allocsize = ((int)(Q_atoi(com_argv[j+1]))) * 0x100000 +
+ LOCKED_FOR_MALLOC;
+
+ if (allocsize < (minmem + LOCKED_FOR_MALLOC))
+ allocsize = minmem + LOCKED_FOR_MALLOC;
+ }
+ else
+ {
+ allocsize = minmem + LOCKED_FOR_MALLOC;
+ }
+
+ if (!lockmem)
+ {
+ // we won't lock, just sbrk the memory
+ info.size = allocsize;
+ goto UpdateSbrk;
+ }
+
+ // lock the memory down
+ write (STDOUT, msg, strlen (msg));
+
+ for (j=allocsize ; j>(minmem + LOCKED_FOR_MALLOC) ;
+ j -= 0x100000)
+ {
+ info.size = j;
+
+ if (!__dpmi_lock_linear_region(&info))
+ goto Locked;
+
+ write (STDOUT, ".", 1);
+ }
+
+ // finally, try with the absolute minimum amount
+ for (i=0 ; i<10 ; i++)
+ {
+ info.size = minmem + LOCKED_FOR_MALLOC;
+
+ if (!__dpmi_lock_linear_region(&info))
+ goto Locked;
+ }
+
+ Sys_Error ("Can't lock memory; %d Mb lockable RAM required. "
+ "Try shrinking smartdrv.", info.size / 0x100000);
+
+Locked:
+
+UpdateSbrk:
+
+ info.address += info.size;
+ info.address -= __djgpp_base_address + 4; // ending point, malloc align
+ working_size = info.address - (int)working_memory;
+ sbrk(info.address-(int)sbrk(0)); // negative adjustment
+ }
+
+
+ if (lockunlockmem)
+ {
+ __dpmi_unlock_linear_region (&info);
+ printf ("Locked and unlocked %d Mb data\n", working_size / 0x100000);
+ }
+ else if (lockmem)
+ {
+ printf ("Locked %d Mb data\n", working_size / 0x100000);
+ }
+ else
+ {
+ printf ("Allocated %d Mb data\n", working_size / 0x100000);
+ }
+
+// touch all the memory to make sure it's there. The 16-page skip is to
+// keep Win 95 from thinking we're trying to page ourselves in (we are
+// doing that, of course, but there's no reason we shouldn't)
+ x = (byte *)working_memory;
+
+ for (n=0 ; n<4 ; n++)
+ {
+ for (m=0 ; m<(working_size - 16 * 0x1000) ; m += 4)
+ {
+ sys_checksum += *(int *)&x[m];
+ sys_checksum += *(int *)&x[m + 16 * 0x1000];
+ }
+ }
+
+// give some of what we locked back for malloc before returning. Done
+// by cheating and passing a negative value to sbrk
+ working_size -= LOCKED_FOR_MALLOC;
+ sbrk( -(LOCKED_FOR_MALLOC));
+ *size = working_size;
+ return working_memory;
+}
+
+
+/*
+============
+Sys_FileTime
+
+returns -1 if not present
+============
+*/
+int Sys_FileTime (char *path)
+{
+ struct stat buf;
+
+ if (stat (path,&buf) == -1)
+ return -1;
+
+ return buf.st_mtime;
+}
+
+void Sys_mkdir (char *path)
+{
+ mkdir (path, 0777);
+}
+
+
+void Sys_Sleep(void)
+{
+}
+
+
+char *Sys_ConsoleInput(void)
+{
+ static char text[256];
+ static int len = 0;
+ char ch;
+
+ if (!isDedicated)
+ return NULL;
+
+ if (! kbhit())
+ return NULL;
+
+ ch = getche();
+
+ switch (ch)
+ {
+ case '\r':
+ putch('\n');
+ if (len)
+ {
+ text[len] = 0;
+ len = 0;
+ return text;
+ }
+ break;
+
+ case '\b':
+ putch(' ');
+ if (len)
+ {
+ len--;
+ putch('\b');
+ }
+ break;
+
+ default:
+ text[len] = ch;
+ len = (len + 1) & 0xff;
+ break;
+ }
+
+ return NULL;
+}
+
+void Sys_Init(void)
+{
+
+ MaskExceptions ();
+
+ Sys_SetFPCW ();
+
+ dos_outportb(0x43, 0x34); // set system timer to mode 2
+ dos_outportb(0x40, 0); // for the Sys_FloatTime() function
+ dos_outportb(0x40, 0);
+
+ Sys_InitFloatTime ();
+
+ _go32_interrupt_stack_size = 4 * 1024;;
+ _go32_rmcb_stack_size = 4 * 1024;
+}
+
+void Sys_Shutdown(void)
+{
+ if (!isDedicated)
+ dos_restoreintr(9);
+
+ if (unlockmem)
+ {
+ dos_unlockmem (&start_of_memory,
+ end_of_memory - (int)&start_of_memory);
+ dos_unlockmem (quakeparms.membase, quakeparms.memsize);
+ }
+}
+
+
+#define SC_RSHIFT 0x36
+#define SC_LSHIFT 0x2a
+void Sys_SendKeyEvents (void)
+{
+ int k, next;
+ int outkey;
+
+// get key events
+
+ while (keybuf_head != keybuf_tail)
+ {
+
+ k = keybuf[keybuf_tail++];
+ keybuf_tail &= (KEYBUF_SIZE-1);
+
+ if (k==0xe0)
+ continue; // special / pause keys
+ next = keybuf[(keybuf_tail-2)&(KEYBUF_SIZE-1)];
+ if (next == 0xe1)
+ continue; // pause key bullshit
+ if (k==0xc5 && next == 0x9d)
+ {
+ Key_Event (K_PAUSE, true);
+ continue;
+ }
+
+ // extended keyboard shift key bullshit
+ if ( (k&0x7f)==SC_LSHIFT || (k&0x7f)==SC_RSHIFT )
+ {
+ if ( keybuf[(keybuf_tail-2)&(KEYBUF_SIZE-1)]==0xe0 )
+ continue;
+ k &= 0x80;
+ k |= SC_RSHIFT;
+ }
+
+ if (k==0xc5 && keybuf[(keybuf_tail-2)&(KEYBUF_SIZE-1)] == 0x9d)
+ continue; // more pause bullshit
+
+ outkey = scantokey[k & 0x7f];
+
+ if (k & 0x80)
+ Key_Event (outkey, false);
+ else
+ Key_Event (outkey, true);
+
+ }
+
+}
+
+
+// =======================================================================
+// General routines
+// =======================================================================
+
+/*
+================
+Sys_Printf
+================
+*/
+
+void Sys_Printf (char *fmt, ...)
+{
+ va_list argptr;
+ char text[1024];
+
+ va_start (argptr,fmt);
+ vsprintf (text,fmt,argptr);
+ va_end (argptr);
+
+ if (cls.state == ca_dedicated)
+ fprintf(stderr, "%s", text);
+}
+
+void Sys_AtExit (void)
+{
+
+// shutdown only once (so Sys_Error can call this function to shutdown, then
+// print the error message, then call exit without exit calling this function
+// again)
+ Sys_Shutdown();
+}
+
+
+void Sys_Quit (void)
+{
+ byte screen[80*25*2];
+ byte *d;
+ char ver[6];
+ int i;
+
+
+// load the sell screen before shuting everything down
+ if (registered.value)
+ d = COM_LoadHunkFile ("end2.bin");
+ else
+ d = COM_LoadHunkFile ("end1.bin");
+ if (d)
+ memcpy (screen, d, sizeof(screen));
+
+// write the version number directly to the end screen
+ sprintf (ver, " v%4.2f", VERSION);
+ for (i=0 ; i<6 ; i++)
+ screen[0*80*2 + 72*2 + i*2] = ver[i];
+
+ Host_Shutdown();
+
+// do the text mode sell screen
+ if (d)
+ {
+ memcpy ((void *)real2ptr(0xb8000), screen,80*25*2);
+
+ // set text pos
+ regs.x.ax = 0x0200;
+ regs.h.bh = 0;
+ regs.h.dl = 0;
+ regs.h.dh = 22;
+ dos_int86 (0x10);
+ }
+ else
+ printf ("couldn't load endscreen.\n");
+
+ exit(0);
+}
+
+void Sys_Error (char *error, ...)
+{
+ va_list argptr;
+ char string[1024];
+
+ va_start (argptr,error);
+ vsprintf (string,error,argptr);
+ va_end (argptr);
+
+ Host_Shutdown();
+ fprintf(stderr, "Error: %s\n", string);
+// Sys_AtExit is called by exit to shutdown the system
+ exit(0);
+}
+
+
+int Sys_FileOpenRead (char *path, int *handle)
+{
+ int h;
+ struct stat fileinfo;
+
+ h = open (path, O_RDONLY|O_BINARY, 0666);
+ *handle = h;
+ if (h == -1)
+ return -1;
+
+ if (fstat (h,&fileinfo) == -1)
+ Sys_Error ("Error fstating %s", path);
+
+ return fileinfo.st_size;
+}
+
+int Sys_FileOpenWrite (char *path)
+{
+ int handle;
+
+ umask (0);
+
+ handle = open(path,O_RDWR | O_BINARY | O_CREAT | O_TRUNC
+ , 0666);
+
+ if (handle == -1)
+ Sys_Error ("Error opening %s: %s", path,strerror(errno));
+
+ return handle;
+}
+
+void Sys_FileClose (int handle)
+{
+ close (handle);
+}
+
+void Sys_FileSeek (int handle, int position)
+{
+ lseek (handle, position, SEEK_SET);
+}
+
+int Sys_FileRead (int handle, void *dest, int count)
+{
+ return read (handle, dest, count);
+}
+
+int Sys_FileWrite (int handle, void *data, int count)
+{
+ return write (handle, data, count);
+}
+
+/*
+================
+Sys_MakeCodeWriteable
+================
+*/
+void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
+{
+ // it's always writeable
+}
+
+
+/*
+================
+Sys_FloatTime
+================
+*/
+double Sys_FloatTime (void)
+{
+ int r;
+ unsigned t, tick;
+ double ft, time;
+ static int sametimecount;
+
+ Sys_PushFPCW_SetHigh ();
+
+//{static float t = 0; t=t+0.05; return t;} // DEBUG
+
+ t = *(unsigned short*)real2ptr(0x46c) * 65536;
+
+ dos_outportb(0x43, 0); // latch time
+ r = dos_inportb(0x40);
+ r |= dos_inportb(0x40) << 8;
+ r = (r-1) & 0xffff;
+
+ tick = *(unsigned short*)real2ptr(0x46c) * 65536;
+ if ((tick != t) && (r & 0x8000))
+ t = tick;
+
+ ft = (double) (t+(65536-r)) / 1193200.0;
+ time = ft - oldtime;
+ oldtime = ft;
+
+ if (time < 0)
+ {
+ if (time > -3000.0)
+ time = 0.0;
+ else
+ time += 3600.0;
+ }
+
+ curtime += time;
+
+ if (curtime == lastcurtime)
+ {
+ sametimecount++;
+
+ if (sametimecount > 100000)
+ {
+ curtime += 1.0;
+ sametimecount = 0;
+ }
+ }
+ else
+ {
+ sametimecount = 0;
+ }
+
+ lastcurtime = curtime;
+
+ Sys_PopFPCW ();
+
+ return curtime;
+}
+
+
+/*
+================
+Sys_InitFloatTime
+================
+*/
+void Sys_InitFloatTime (void)
+{
+ int j;
+
+ Sys_FloatTime ();
+
+ oldtime = curtime;
+
+ j = COM_CheckParm("-starttime");
+
+ if (j)
+ {
+ curtime = (double) (Q_atof(com_argv[j+1]));
+ }
+ else
+ {
+ curtime = 0.0;
+ }
+ lastcurtime = curtime;
+}
+
+
+/*
+================
+Sys_GetMemory
+================
+*/
+void Sys_GetMemory(void)
+{
+ int j, tsize;
+
+ j = COM_CheckParm("-mem");
+ if (j)
+ {
+ quakeparms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024);
+ quakeparms.membase = malloc (quakeparms.memsize);
+ }
+ else
+ {
+ quakeparms.membase = dos_getmaxlockedmem (&quakeparms.memsize);
+ }
+
+ fprintf(stderr, "malloc'd: %d\n", quakeparms.memsize);
+
+ if (COM_CheckParm ("-heapsize"))
+ {
+ tsize = Q_atoi (com_argv[COM_CheckParm("-heapsize") + 1]) * 1024;
+
+ if (tsize < quakeparms.memsize)
+ quakeparms.memsize = tsize;
+ }
+}
+
+
+/*
+================
+Sys_PageInProgram
+
+walks the text, data, and bss to make sure it's all paged in so that the
+actual physical memory detected by Sys_GetMemory is correct.
+================
+*/
+void Sys_PageInProgram(void)
+{
+ int i, j;
+
+ end_of_memory = (int)sbrk(0);
+
+ if (lockmem)
+ {
+ if (dos_lockmem ((void *)&start_of_memory,
+ end_of_memory - (int)&start_of_memory))
+ Sys_Error ("Couldn't lock text and data");
+ }
+
+ if (lockunlockmem)
+ {
+ dos_unlockmem((void *)&start_of_memory,
+ end_of_memory - (int)&start_of_memory);
+ printf ("Locked and unlocked %d Mb image\n",
+ (end_of_memory - (int)&start_of_memory) / 0x100000);
+ }
+ else if (lockmem)
+ {
+ printf ("Locked %d Mb image\n",
+ (end_of_memory - (int)&start_of_memory) / 0x100000);
+ }
+ else
+ {
+ printf ("Loaded %d Mb image\n",
+ (end_of_memory - (int)&start_of_memory) / 0x100000);
+ }
+
+// touch the entire image, doing the 16-page skip so Win95 doesn't think we're
+// trying to page ourselves in
+ for (j=0 ; j<4 ; j++)
+ {
+ for(i=(int)&start_of_memory ; i<(end_of_memory - 16 * 0x1000) ; i += 4)
+ {
+ sys_checksum += *(int *)i;
+ sys_checksum += *(int *)(i + 16 * 0x1000);
+ }
+ }
+}
+
+
+/*
+================
+Sys_NoFPUExceptionHandler
+================
+*/
+void Sys_NoFPUExceptionHandler(int whatever)
+{
+ printf ("\nError: Quake requires a floating-point processor\n");
+ exit (0);
+}
+
+
+/*
+================
+Sys_DefaultExceptionHandler
+================
+*/
+void Sys_DefaultExceptionHandler(int whatever)
+{
+}
+
+
+/*
+================
+main
+================
+*/
+int main (int c, char **v)
+{
+ double time, oldtime, newtime;
+ extern void (*dos_error_func)(char *, ...);
+ static char cwd[1024];
+
+ printf ("Quake v%4.2f\n", VERSION);
+
+// make sure there's an FPU
+ signal(SIGNOFP, Sys_NoFPUExceptionHandler);
+ signal(SIGABRT, Sys_DefaultExceptionHandler);
+ signal(SIGALRM, Sys_DefaultExceptionHandler);
+ signal(SIGKILL, Sys_DefaultExceptionHandler);
+ signal(SIGQUIT, Sys_DefaultExceptionHandler);
+ signal(SIGINT, Sys_DefaultExceptionHandler);
+
+ if (fptest_temp >= 0.0)
+ fptest_temp += 0.1;
+
+ COM_InitArgv (c, v);
+
+ quakeparms.argc = com_argc;
+ quakeparms.argv = com_argv;
+
+ dos_error_func = Sys_Error;
+
+ Sys_DetectWin95 ();
+ Sys_PageInProgram ();
+ Sys_GetMemory ();
+
+ atexit (Sys_AtExit); // in case we crash
+
+ getwd (cwd);
+ if (cwd[Q_strlen(cwd)-1] == '/') cwd[Q_strlen(cwd)-1] = 0;
+ quakeparms.basedir = cwd; //"f:/quake";
+
+ isDedicated = (COM_CheckParm ("-dedicated") != 0);
+
+ Sys_Init ();
+
+ if (!isDedicated)
+ dos_registerintr(9, TrapKey);
+
+//Sys_InitStackCheck ();
+
+ Host_Init(&quakeparms);
+
+//Sys_StackCheck ();
+
+//Con_Printf ("Top of stack: 0x%x\n", &time);
+ oldtime = Sys_FloatTime ();
+ while (1)
+ {
+ newtime = Sys_FloatTime ();
+ time = newtime - oldtime;
+
+ if (cls.state == ca_dedicated && (time<sys_ticrate.value))
+ continue;
+
+ Host_Frame (time);
+
+//Sys_StackCheck ();
+
+ oldtime = newtime;
+ }
+}
+
+
|
