123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954 |
- /*
- 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;
- }
- }
|