Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
2000-01-08 04:50:26 +00:00
|
|
|
Portions Copyright (C) 1999,2000 Nelson Rush.
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
*/
|
|
|
|
// sys_win.c -- Win32 system interface code
|
|
|
|
|
|
|
|
#include "quakedef.h"
|
|
|
|
#include "winquake.h"
|
|
|
|
#include "resource.h"
|
2000-01-04 23:36:31 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <limits.h>
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
|
|
|
|
#define MINIMUM_WIN_MEMORY 0x0880000
|
|
|
|
#define MAXIMUM_WIN_MEMORY 0x1000000
|
|
|
|
|
|
|
|
#define CONSOLE_ERROR_TIMEOUT 60.0 // # of seconds to wait on Sys_Error running
|
|
|
|
// dedicated before exiting
|
|
|
|
#define PAUSE_SLEEP 50 // sleep time on pause or minimization
|
|
|
|
#define NOT_FOCUS_SLEEP 20 // sleep time when not focus
|
|
|
|
|
|
|
|
int starttime;
|
|
|
|
qboolean ActiveApp, Minimized;
|
|
|
|
qboolean WinNT;
|
|
|
|
|
|
|
|
static double pfreq;
|
|
|
|
static double curtime = 0.0;
|
|
|
|
static double lastcurtime = 0.0;
|
|
|
|
static int lowshift;
|
|
|
|
qboolean isDedicated;
|
|
|
|
static qboolean sc_return_on_enter = false;
|
|
|
|
HANDLE hinput, houtput;
|
|
|
|
|
|
|
|
static char *tracking_tag = "Clams & Mooses";
|
|
|
|
|
|
|
|
static HANDLE tevent;
|
|
|
|
static HANDLE hFile;
|
|
|
|
static HANDLE heventParent;
|
|
|
|
static HANDLE heventChild;
|
|
|
|
|
|
|
|
void MaskExceptions (void);
|
|
|
|
void Sys_InitFloatTime (void);
|
|
|
|
void Sys_PushFPCW_SetHigh (void);
|
|
|
|
void Sys_PopFPCW (void);
|
|
|
|
|
|
|
|
volatile int sys_checksum;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
Sys_PageIn
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
void Sys_PageIn (void *ptr, int size)
|
|
|
|
{
|
|
|
|
byte *x;
|
|
|
|
int j, m, n;
|
|
|
|
|
|
|
|
// 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 *)ptr;
|
|
|
|
|
|
|
|
for (n=0 ; n<4 ; n++)
|
|
|
|
{
|
|
|
|
for (m=0 ; m<(size - 16 * 0x1000) ; m += 4)
|
|
|
|
{
|
|
|
|
sys_checksum += *(int *)&x[m];
|
|
|
|
sys_checksum += *(int *)&x[m + 16 * 0x1000];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============================================================================
|
|
|
|
|
|
|
|
FILE IO
|
|
|
|
|
|
|
|
===============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define MAX_HANDLES 10
|
2000-02-08 07:23:09 +00:00
|
|
|
QFile *sys_handles[MAX_HANDLES];
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
|
|
|
|
int findhandle (void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=1 ; i<MAX_HANDLES ; i++)
|
|
|
|
if (!sys_handles[i])
|
|
|
|
return i;
|
|
|
|
Sys_Error ("out of handles");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2000-01-04 23:36:31 +00:00
|
|
|
#if 0
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
/*
|
|
|
|
================
|
|
|
|
filelength
|
|
|
|
================
|
|
|
|
*/
|
2000-02-08 07:23:09 +00:00
|
|
|
int filelength (QFile *f)
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
{
|
|
|
|
int pos;
|
|
|
|
int end;
|
|
|
|
int t;
|
|
|
|
|
|
|
|
t = VID_ForceUnlockedAndReturnState ();
|
|
|
|
|
|
|
|
pos = ftell (f);
|
|
|
|
fseek (f, 0, SEEK_END);
|
|
|
|
end = ftell (f);
|
|
|
|
fseek (f, pos, SEEK_SET);
|
|
|
|
|
|
|
|
VID_ForceLockState (t);
|
|
|
|
|
|
|
|
return end;
|
|
|
|
}
|
2000-01-04 23:36:31 +00:00
|
|
|
#endif
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
|
|
|
|
int Sys_FileOpenRead (char *path, int *hndl)
|
|
|
|
{
|
2000-02-08 07:23:09 +00:00
|
|
|
QFile *f;
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
int i, retval;
|
|
|
|
int t;
|
|
|
|
|
|
|
|
t = VID_ForceUnlockedAndReturnState ();
|
|
|
|
|
|
|
|
i = findhandle ();
|
|
|
|
|
|
|
|
f = fopen(path, "rb");
|
|
|
|
|
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
*hndl = -1;
|
|
|
|
retval = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sys_handles[i] = f;
|
|
|
|
*hndl = i;
|
|
|
|
retval = filelength(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
VID_ForceLockState (t);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Sys_FileOpenWrite (char *path)
|
|
|
|
{
|
2000-02-08 07:23:09 +00:00
|
|
|
QFile *f;
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
int i;
|
|
|
|
int t;
|
|
|
|
|
|
|
|
t = VID_ForceUnlockedAndReturnState ();
|
|
|
|
|
|
|
|
i = findhandle ();
|
|
|
|
|
|
|
|
f = fopen(path, "wb");
|
|
|
|
if (!f)
|
|
|
|
Sys_Error ("Error opening %s: %s", path,strerror(errno));
|
|
|
|
sys_handles[i] = f;
|
|
|
|
|
|
|
|
VID_ForceLockState (t);
|
|
|
|
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_FileClose (int handle)
|
|
|
|
{
|
|
|
|
int t;
|
|
|
|
|
|
|
|
t = VID_ForceUnlockedAndReturnState ();
|
|
|
|
fclose (sys_handles[handle]);
|
|
|
|
sys_handles[handle] = NULL;
|
|
|
|
VID_ForceLockState (t);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_FileSeek (int handle, int position)
|
|
|
|
{
|
|
|
|
int t;
|
|
|
|
|
|
|
|
t = VID_ForceUnlockedAndReturnState ();
|
|
|
|
fseek (sys_handles[handle], position, SEEK_SET);
|
|
|
|
VID_ForceLockState (t);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Sys_FileRead (int handle, void *dest, int count)
|
|
|
|
{
|
|
|
|
int t, x;
|
|
|
|
|
|
|
|
t = VID_ForceUnlockedAndReturnState ();
|
|
|
|
x = fread (dest, 1, count, sys_handles[handle]);
|
|
|
|
VID_ForceLockState (t);
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Sys_FileWrite (int handle, void *data, int count)
|
|
|
|
{
|
|
|
|
int t, x;
|
|
|
|
|
|
|
|
t = VID_ForceUnlockedAndReturnState ();
|
|
|
|
x = fwrite (data, 1, count, sys_handles[handle]);
|
|
|
|
VID_ForceLockState (t);
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============================================================================
|
|
|
|
|
|
|
|
SYSTEM IO
|
|
|
|
|
|
|
|
===============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
Sys_MakeCodeWriteable
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
|
|
|
|
{
|
|
|
|
DWORD flOldProtect;
|
|
|
|
|
|
|
|
if (!VirtualProtect((LPVOID)startaddr, length, PAGE_READWRITE, &flOldProtect))
|
|
|
|
Sys_Error("Protection change failed\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _M_IX86
|
|
|
|
|
|
|
|
void Sys_SetFPCW (void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_PushFPCW_SetHigh (void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_PopFPCW (void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void MaskExceptions (void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
Sys_Init
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
void Sys_Init (void)
|
|
|
|
{
|
|
|
|
LARGE_INTEGER PerformanceFreq;
|
|
|
|
unsigned int lowpart, highpart;
|
|
|
|
OSVERSIONINFO vinfo;
|
|
|
|
|
|
|
|
MaskExceptions ();
|
|
|
|
Sys_SetFPCW ();
|
|
|
|
|
2000-01-04 23:36:31 +00:00
|
|
|
#if 0
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
if (!QueryPerformanceFrequency (&PerformanceFreq))
|
|
|
|
Sys_Error ("No hardware timer available");
|
|
|
|
|
|
|
|
// get 32 out of the 64 time bits such that we have around
|
|
|
|
// 1 microsecond resolution
|
|
|
|
lowpart = (unsigned int)PerformanceFreq.LowPart;
|
|
|
|
highpart = (unsigned int)PerformanceFreq.HighPart;
|
|
|
|
lowshift = 0;
|
|
|
|
|
|
|
|
while (highpart || (lowpart > 2000000.0))
|
|
|
|
{
|
|
|
|
lowshift++;
|
|
|
|
lowpart >>= 1;
|
|
|
|
lowpart |= (highpart & 1) << 31;
|
|
|
|
highpart >>= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pfreq = 1.0 / (double)lowpart;
|
|
|
|
|
|
|
|
Sys_InitFloatTime ();
|
2000-01-04 23:36:31 +00:00
|
|
|
#endif
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
|
|
|
|
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
|
|
|
|
|
|
|
|
if (!GetVersionEx (&vinfo))
|
|
|
|
Sys_Error ("Couldn't get OS info");
|
|
|
|
|
|
|
|
if ((vinfo.dwMajorVersion < 4) ||
|
|
|
|
(vinfo.dwPlatformId == VER_PLATFORM_WIN32s))
|
|
|
|
{
|
|
|
|
Sys_Error ("WinQuake requires at least Win95 or NT 4.0");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
|
|
WinNT = true;
|
|
|
|
else
|
|
|
|
WinNT = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Sys_Error (char *error, ...)
|
|
|
|
{
|
|
|
|
va_list argptr;
|
|
|
|
char text[1024], text2[1024];
|
|
|
|
char *text3 = "Press Enter to exit\n";
|
|
|
|
char *text4 = "***********************************\n";
|
|
|
|
char *text5 = "\n";
|
|
|
|
DWORD dummy;
|
|
|
|
double starttime;
|
|
|
|
static int in_sys_error0 = 0;
|
|
|
|
static int in_sys_error1 = 0;
|
|
|
|
static int in_sys_error2 = 0;
|
|
|
|
static int in_sys_error3 = 0;
|
|
|
|
|
|
|
|
if (!in_sys_error3)
|
|
|
|
{
|
|
|
|
in_sys_error3 = 1;
|
|
|
|
VID_ForceUnlockedAndReturnState ();
|
|
|
|
}
|
|
|
|
|
|
|
|
va_start (argptr, error);
|
2000-01-08 13:55:33 +00:00
|
|
|
vsnprintf (text, sizeof(text), error, argptr);
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
va_end (argptr);
|
|
|
|
|
|
|
|
if (isDedicated)
|
|
|
|
{
|
|
|
|
va_start (argptr, error);
|
2000-01-08 13:55:33 +00:00
|
|
|
vsnprintf (text, sizeof(text), error, argptr);
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
va_end (argptr);
|
|
|
|
|
2000-01-05 00:05:48 +00:00
|
|
|
snprintf(text2, sizeof(text2), "ERROR: %s\n", text);
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
WriteFile (houtput, text5, strlen (text5), &dummy, NULL);
|
|
|
|
WriteFile (houtput, text4, strlen (text4), &dummy, NULL);
|
|
|
|
WriteFile (houtput, text2, strlen (text2), &dummy, NULL);
|
|
|
|
WriteFile (houtput, text3, strlen (text3), &dummy, NULL);
|
|
|
|
WriteFile (houtput, text4, strlen (text4), &dummy, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
starttime = Sys_DoubleTime ();
|
|
|
|
sc_return_on_enter = true; // so Enter will get us out of here
|
|
|
|
|
|
|
|
while (!Sys_ConsoleInput () &&
|
|
|
|
((Sys_DoubleTime () - starttime) < CONSOLE_ERROR_TIMEOUT))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// switch to windowed so the message box is visible, unless we already
|
|
|
|
// tried that and failed
|
|
|
|
if (!in_sys_error0)
|
|
|
|
{
|
|
|
|
in_sys_error0 = 1;
|
|
|
|
VID_SetDefaultMode ();
|
|
|
|
MessageBox(NULL, text, "Quake Error",
|
|
|
|
MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MessageBox(NULL, text, "Double Quake Error",
|
|
|
|
MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!in_sys_error1)
|
|
|
|
{
|
|
|
|
in_sys_error1 = 1;
|
|
|
|
Host_Shutdown ();
|
|
|
|
}
|
|
|
|
|
|
|
|
// shut down QHOST hooks if necessary
|
|
|
|
if (!in_sys_error2)
|
|
|
|
{
|
|
|
|
in_sys_error2 = 1;
|
|
|
|
DeinitConProc ();
|
|
|
|
}
|
|
|
|
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_Quit (void)
|
|
|
|
{
|
|
|
|
|
|
|
|
VID_ForceUnlockedAndReturnState ();
|
|
|
|
|
|
|
|
Host_Shutdown();
|
|
|
|
|
|
|
|
if (tevent)
|
|
|
|
CloseHandle (tevent);
|
|
|
|
|
|
|
|
if (isDedicated)
|
|
|
|
FreeConsole ();
|
|
|
|
|
|
|
|
// shut down QHOST hooks if necessary
|
|
|
|
DeinitConProc ();
|
|
|
|
|
|
|
|
exit (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-04 23:36:31 +00:00
|
|
|
#if 0
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
/*
|
|
|
|
================
|
|
|
|
Sys_DoubleTime
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
double Sys_DoubleTime (void)
|
|
|
|
{
|
|
|
|
static int sametimecount;
|
|
|
|
static unsigned int oldtime;
|
|
|
|
static int first = 1;
|
|
|
|
LARGE_INTEGER PerformanceCount;
|
|
|
|
unsigned int temp, t2;
|
|
|
|
double time;
|
|
|
|
|
|
|
|
Sys_PushFPCW_SetHigh ();
|
|
|
|
|
|
|
|
QueryPerformanceCounter (&PerformanceCount);
|
|
|
|
|
|
|
|
temp = ((unsigned int)PerformanceCount.LowPart >> lowshift) |
|
|
|
|
((unsigned int)PerformanceCount.HighPart << (32 - lowshift));
|
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
oldtime = temp;
|
|
|
|
first = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// check for turnover or backward time
|
|
|
|
if ((temp <= oldtime) && ((oldtime - temp) < 0x10000000))
|
|
|
|
{
|
|
|
|
oldtime = temp; // so we can't get stuck
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
t2 = temp - oldtime;
|
|
|
|
|
|
|
|
time = (double)t2 * pfreq;
|
|
|
|
oldtime = temp;
|
|
|
|
|
|
|
|
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_DoubleTime ();
|
|
|
|
|
|
|
|
j = COM_CheckParm("-starttime");
|
|
|
|
|
|
|
|
if (j)
|
|
|
|
{
|
|
|
|
curtime = (double) (Q_atof(com_argv[j+1]));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
curtime = 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
lastcurtime = curtime;
|
|
|
|
}
|
2000-01-04 23:36:31 +00:00
|
|
|
#endif
|
|
|
|
|
Created new subdir: uquake. Pick your favorite U word for the meaning --
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified,
Unity, etc. You know the drill.
This takes care of the "standalone" problem with the wrong name, and the
recent snafu with multiple developers working on the same files
simultaneously...expect me (and probably others) to start locking dirs when
updates are taking place.
And yes, this update is really as large as it looks. Software only at the
moment, but I will have the makefile updated to build the GL builds as
well.
1999-12-26 13:51:52 +00:00
|
|
|
char *Sys_ConsoleInput (void)
|
|
|
|
{
|
|
|
|
static char text[256];
|
|
|
|
static int len;
|
|
|
|
INPUT_RECORD recs[1024];
|
|
|
|
int count;
|
|
|
|
int i, dummy;
|
|
|
|
int ch, numread, numevents;
|
|
|
|
|
|
|
|
if (!isDedicated)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
for ( ;; )
|
|
|
|
{
|
|
|
|
if (!GetNumberOfConsoleInputEvents (hinput, &numevents))
|
|
|
|
Sys_Error ("Error getting # of console events");
|
|
|
|
|
|
|
|
if (numevents <= 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (!ReadConsoleInput(hinput, recs, 1, &numread))
|
|
|
|
Sys_Error ("Error reading console input");
|
|
|
|
|
|
|
|
if (numread != 1)
|
|
|
|
Sys_Error ("Couldn't read console input");
|
|
|
|
|
|
|
|
if (recs[0].EventType == KEY_EVENT)
|
|
|
|
{
|
|
|
|
if (!recs[0].Event.KeyEvent.bKeyDown)
|
|
|
|
{
|
|
|
|
ch = recs[0].Event.KeyEvent.uChar.AsciiChar;
|
|
|
|
|
|
|
|
switch (ch)
|
|
|
|
{
|
|
|
|
case '\r':
|
|
|
|
WriteFile(houtput, "\r\n", 2, &dummy, NULL);
|
|
|
|
|
|
|
|
if (len)
|
|
|
|
{
|
|
|
|
text[len] = 0;
|
|
|
|
len = 0;
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
else if (sc_return_on_enter)
|
|
|
|
{
|
|
|
|
// special case to allow exiting from the error handler on Enter
|
|
|
|
text[0] = '\r';
|
|
|
|
len = 0;
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '\b':
|
|
|
|
WriteFile(houtput, "\b \b", 3, &dummy, NULL);
|
|
|
|
if (len)
|
|
|
|
{
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (ch >= ' ')
|
|
|
|
{
|
|
|
|
WriteFile(houtput, &ch, 1, &dummy, NULL);
|
|
|
|
text[len] = ch;
|
|
|
|
len = (len + 1) & 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_Sleep (void)
|
|
|
|
{
|
|
|
|
Sleep (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Sys_SendKeyEvents (void)
|
|
|
|
{
|
|
|
|
MSG msg;
|
|
|
|
|
|
|
|
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
|
|
|
|
{
|
|
|
|
// we always update if there are any event, even if we're paused
|
|
|
|
scr_skipupdate = 0;
|
|
|
|
|
|
|
|
if (!GetMessage (&msg, NULL, 0, 0))
|
|
|
|
Sys_Quit ();
|
|
|
|
|
|
|
|
TranslateMessage (&msg);
|
|
|
|
DispatchMessage (&msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============================================================================
|
|
|
|
|
|
|
|
WINDOWS CRAP
|
|
|
|
|
|
|
|
==============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
==================
|
|
|
|
WinMain
|
|
|
|
==================
|
|
|
|
*/
|
|
|
|
void SleepUntilInput (int time)
|
|
|
|
{
|
|
|
|
|
|
|
|
MsgWaitForMultipleObjects(1, &tevent, FALSE, time, QS_ALLINPUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
==================
|
|
|
|
WinMain
|
|
|
|
==================
|
|
|
|
*/
|
|
|
|
HINSTANCE global_hInstance;
|
|
|
|
int global_nCmdShow;
|
|
|
|
char *argv[MAX_NUM_ARGVS];
|
|
|
|
static char *empty_string = "";
|
|
|
|
HWND hwnd_dialog;
|
|
|
|
|
|
|
|
|
|
|
|
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
|
|
|
{
|
|
|
|
MSG msg;
|
|
|
|
quakeparms_t parms;
|
|
|
|
double time, oldtime, newtime;
|
|
|
|
MEMORYSTATUS lpBuffer;
|
|
|
|
static char cwd[1024];
|
|
|
|
int t;
|
|
|
|
RECT rect;
|
|
|
|
|
|
|
|
/* previous instances do not exist in Win32 */
|
|
|
|
if (hPrevInstance)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
global_hInstance = hInstance;
|
|
|
|
global_nCmdShow = nCmdShow;
|
|
|
|
|
|
|
|
lpBuffer.dwLength = sizeof(MEMORYSTATUS);
|
|
|
|
GlobalMemoryStatus (&lpBuffer);
|
|
|
|
|
|
|
|
if (!GetCurrentDirectory (sizeof(cwd), cwd))
|
|
|
|
Sys_Error ("Couldn't determine current directory");
|
|
|
|
|
|
|
|
if (cwd[Q_strlen(cwd)-1] == '/')
|
|
|
|
cwd[Q_strlen(cwd)-1] = 0;
|
|
|
|
|
|
|
|
parms.basedir = cwd;
|
|
|
|
parms.cachedir = NULL;
|
|
|
|
|
|
|
|
parms.argc = 1;
|
|
|
|
argv[0] = empty_string;
|
|
|
|
|
|
|
|
while (*lpCmdLine && (parms.argc < MAX_NUM_ARGVS))
|
|
|
|
{
|
|
|
|
while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126)))
|
|
|
|
lpCmdLine++;
|
|
|
|
|
|
|
|
if (*lpCmdLine)
|
|
|
|
{
|
|
|
|
argv[parms.argc] = lpCmdLine;
|
|
|
|
parms.argc++;
|
|
|
|
|
|
|
|
while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126)))
|
|
|
|
lpCmdLine++;
|
|
|
|
|
|
|
|
if (*lpCmdLine)
|
|
|
|
{
|
|
|
|
*lpCmdLine = 0;
|
|
|
|
lpCmdLine++;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
parms.argv = argv;
|
|
|
|
|
|
|
|
COM_InitArgv (parms.argc, parms.argv);
|
|
|
|
|
|
|
|
parms.argc = com_argc;
|
|
|
|
parms.argv = com_argv;
|
|
|
|
|
|
|
|
isDedicated = (COM_CheckParm ("-dedicated") != 0);
|
|
|
|
|
|
|
|
if (!isDedicated)
|
|
|
|
{
|
|
|
|
hwnd_dialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL);
|
|
|
|
|
|
|
|
if (hwnd_dialog)
|
|
|
|
{
|
|
|
|
if (GetWindowRect (hwnd_dialog, &rect))
|
|
|
|
{
|
|
|
|
if (rect.left > (rect.top * 2))
|
|
|
|
{
|
|
|
|
SetWindowPos (hwnd_dialog, 0,
|
|
|
|
(rect.left / 2) - ((rect.right - rect.left) / 2),
|
|
|
|
rect.top, 0, 0,
|
|
|
|
SWP_NOZORDER | SWP_NOSIZE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ShowWindow (hwnd_dialog, SW_SHOWDEFAULT);
|
|
|
|
UpdateWindow (hwnd_dialog);
|
|
|
|
SetForegroundWindow (hwnd_dialog);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// take the greater of all the available memory or half the total memory,
|
|
|
|
// but at least 8 Mb and no more than 16 Mb, unless they explicitly
|
|
|
|
// request otherwise
|
|
|
|
parms.memsize = lpBuffer.dwAvailPhys;
|
|
|
|
|
|
|
|
if (parms.memsize < MINIMUM_WIN_MEMORY)
|
|
|
|
parms.memsize = MINIMUM_WIN_MEMORY;
|
|
|
|
|
|
|
|
if (parms.memsize < (lpBuffer.dwTotalPhys >> 1))
|
|
|
|
parms.memsize = lpBuffer.dwTotalPhys >> 1;
|
|
|
|
|
|
|
|
if (parms.memsize > MAXIMUM_WIN_MEMORY)
|
|
|
|
parms.memsize = MAXIMUM_WIN_MEMORY;
|
|
|
|
|
|
|
|
if (COM_CheckParm ("-heapsize"))
|
|
|
|
{
|
|
|
|
t = COM_CheckParm("-heapsize") + 1;
|
|
|
|
|
|
|
|
if (t < com_argc)
|
|
|
|
parms.memsize = Q_atoi (com_argv[t]) * 1024;
|
|
|
|
}
|
|
|
|
|
|
|
|
parms.membase = malloc (parms.memsize);
|
|
|
|
|
|
|
|
if (!parms.membase)
|
|
|
|
Sys_Error ("Not enough memory free; check disk space\n");
|
|
|
|
|
|
|
|
Sys_PageIn (parms.membase, parms.memsize);
|
|
|
|
|
|
|
|
tevent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
|
|
|
|
|
|
if (!tevent)
|
|
|
|
Sys_Error ("Couldn't create event");
|
|
|
|
|
|
|
|
if (isDedicated)
|
|
|
|
{
|
|
|
|
if (!AllocConsole ())
|
|
|
|
{
|
|
|
|
Sys_Error ("Couldn't create dedicated server console");
|
|
|
|
}
|
|
|
|
|
|
|
|
hinput = GetStdHandle (STD_INPUT_HANDLE);
|
|
|
|
houtput = GetStdHandle (STD_OUTPUT_HANDLE);
|
|
|
|
|
|
|
|
// give QHOST a chance to hook into the console
|
|
|
|
if ((t = COM_CheckParm ("-HFILE")) > 0)
|
|
|
|
{
|
|
|
|
if (t < com_argc)
|
|
|
|
hFile = (HANDLE)Q_atoi (com_argv[t+1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((t = COM_CheckParm ("-HPARENT")) > 0)
|
|
|
|
{
|
|
|
|
if (t < com_argc)
|
|
|
|
heventParent = (HANDLE)Q_atoi (com_argv[t+1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((t = COM_CheckParm ("-HCHILD")) > 0)
|
|
|
|
{
|
|
|
|
if (t < com_argc)
|
|
|
|
heventChild = (HANDLE)Q_atoi (com_argv[t+1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
InitConProc (hFile, heventParent, heventChild);
|
|
|
|
}
|
|
|
|
|
|
|
|
Sys_Init ();
|
|
|
|
|
|
|
|
// because sound is off until we become active
|
|
|
|
S_BlockSound ();
|
|
|
|
|
|
|
|
Sys_Printf ("Host_Init\n");
|
|
|
|
Host_Init (&parms);
|
|
|
|
|
|
|
|
oldtime = Sys_DoubleTime ();
|
|
|
|
|
|
|
|
/* main window message loop */
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
if (isDedicated)
|
|
|
|
{
|
|
|
|
newtime = Sys_DoubleTime ();
|
|
|
|
time = newtime - oldtime;
|
|
|
|
|
|
|
|
while (time < sys_ticrate.value )
|
|
|
|
{
|
|
|
|
Sys_Sleep();
|
|
|
|
newtime = Sys_DoubleTime ();
|
|
|
|
time = newtime - oldtime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// yield the CPU for a little while when paused, minimized, or not the focus
|
|
|
|
if ((cl.paused && (!ActiveApp && !DDActive)) || Minimized || block_drawing)
|
|
|
|
{
|
|
|
|
SleepUntilInput (PAUSE_SLEEP);
|
|
|
|
scr_skipupdate = 1; // no point in bothering to draw
|
|
|
|
}
|
|
|
|
else if (!ActiveApp && !DDActive)
|
|
|
|
{
|
|
|
|
SleepUntilInput (NOT_FOCUS_SLEEP);
|
|
|
|
}
|
|
|
|
|
|
|
|
newtime = Sys_DoubleTime ();
|
|
|
|
time = newtime - oldtime;
|
|
|
|
}
|
|
|
|
|
|
|
|
Host_Frame (time);
|
|
|
|
oldtime = newtime;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return success of application */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|