aboutsummaryrefslogtreecommitdiffstats
path: root/WinQuake/sys_dos.c
diff options
context:
space:
mode:
authorwyatt8740 <wyatt8740@yahoo.com>2014-01-06 12:02:16 -0500
committerwyatt8740 <wyatt8740@yahoo.com>2014-01-06 12:02:16 -0500
commita8f828a066773a59fdf646299359d35ae0e845af (patch)
tree86123409fc6f231cf4136e81159b63cb1e9ec102 /WinQuake/sys_dos.c
parentb2951690415054ae8705c07f8df7a4ba7cde382a (diff)
downloadquake-pum-a8f828a066773a59fdf646299359d35ae0e845af.tar.gz
Removed accidental upload of copyrighted map files
Diffstat (limited to 'WinQuake/sys_dos.c')
-rw-r--r--WinQuake/sys_dos.c1906
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;
+ }
+}
+
+