From a8f828a066773a59fdf646299359d35ae0e845af Mon Sep 17 00:00:00 2001 From: wyatt8740 Date: Mon, 6 Jan 2014 12:02:16 -0500 Subject: Removed accidental upload of copyrighted map files --- WinQuake/sys_dos.c | 1906 ++++++++++++++++++++++++++-------------------------- 1 file changed, 953 insertions(+), 953 deletions(-) (limited to 'WinQuake/sys_dos.c') 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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