diff options
| author | Travis Bradshaw <travis.bradshaw@idsoftware.com> | 2012-01-31 14:32:09 -0600 |
|---|---|---|
| committer | Travis Bradshaw <travis.bradshaw@idsoftware.com> | 2012-01-31 14:32:09 -0600 |
| commit | 0023db327bc1db00068284b70e1db45857aeee35 (patch) | |
| tree | 01dd8366d20bd674741cfe8ceb069d82a2e33973 /WinQuake/sys_dos.c | |
| download | quake-pum-0023db327bc1db00068284b70e1db45857aeee35.tar.gz | |
The Quake sources as originally release under the GPL license on December 21, 1999
Diffstat (limited to 'WinQuake/sys_dos.c')
| -rw-r--r-- | WinQuake/sys_dos.c | 953 |
1 files changed, 953 insertions, 0 deletions
diff --git a/WinQuake/sys_dos.c b/WinQuake/sys_dos.c new file mode 100644 index 0000000..0a9bc4a --- /dev/null +++ b/WinQuake/sys_dos.c @@ -0,0 +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; + } +} + + |
