1041 lines
20 KiB
C
1041 lines
20 KiB
C
|
// sys_win.c -- Win32 system interface code
|
||
|
|
||
|
/*
|
||
|
* $Header: /H2 Mission Pack/SYS_WIN.C 8 4/13/98 1:01p Jmonroe $
|
||
|
*/
|
||
|
|
||
|
#include "quakedef.h"
|
||
|
#include <windows.h>
|
||
|
#include "winquake.h"
|
||
|
#include "errno.h"
|
||
|
#include "resource.h"
|
||
|
|
||
|
#define CRC_A 59461 // "Who's Ridin' With Chaos?"
|
||
|
#define CRC_B 54866 // "Santa needs a new sled!"
|
||
|
|
||
|
#ifdef GLQUAKE
|
||
|
#define MINIMUM_WIN_MEMORY 0x1000000
|
||
|
#define MAXIMUM_WIN_MEMORY 0x1800000
|
||
|
#else
|
||
|
#define MINIMUM_WIN_MEMORY 0x0C00000
|
||
|
#define MAXIMUM_WIN_MEMORY 0x1600000
|
||
|
#endif
|
||
|
|
||
|
#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 Win32AtLeastV4, WinNT;
|
||
|
qboolean LegitCopy = true;
|
||
|
|
||
|
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 = "Sticky Buns";
|
||
|
|
||
|
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);
|
||
|
|
||
|
cvar_t sys_delay = {"sys_delay","0", true};
|
||
|
|
||
|
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
|
||
|
FILE *sys_handles[MAX_HANDLES];
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
filelength
|
||
|
================
|
||
|
*/
|
||
|
int filelength (FILE *f)
|
||
|
{
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
int Sys_FileOpenRead (char *path, int *hndl)
|
||
|
{
|
||
|
FILE *f;
|
||
|
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)
|
||
|
{
|
||
|
FILE *f;
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
int Sys_FileTime (char *path)
|
||
|
{
|
||
|
FILE *f;
|
||
|
int t, retval;
|
||
|
|
||
|
t = VID_ForceUnlockedAndReturnState ();
|
||
|
|
||
|
f = fopen(path, "rb");
|
||
|
|
||
|
if (f)
|
||
|
{
|
||
|
fclose(f);
|
||
|
retval = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
retval = -1;
|
||
|
}
|
||
|
|
||
|
VID_ForceLockState (t);
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
void Sys_mkdir (char *path)
|
||
|
{
|
||
|
_mkdir (path);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
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
|
||
|
|
||
|
#ifdef SECURE_TIME
|
||
|
#include <time.h>
|
||
|
#define BuildTime 889138800
|
||
|
void CheckTime()
|
||
|
{
|
||
|
time_t now;
|
||
|
int days;
|
||
|
|
||
|
time( &now );
|
||
|
if ((now < BuildTime) || (now> BuildTime+26*24*60*60))
|
||
|
{
|
||
|
errormessage = "This version has expired.@Please contact Activision for a new version";
|
||
|
LegitCopy = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
Sys_Init
|
||
|
================
|
||
|
*/
|
||
|
void Sys_Init (void)
|
||
|
{
|
||
|
LARGE_INTEGER PerformanceFreq;
|
||
|
unsigned int lowpart, highpart;
|
||
|
OSVERSIONINFO vinfo;
|
||
|
static char temp[MAX_PATH+1];
|
||
|
int value,i;
|
||
|
HKEY hKey;
|
||
|
DWORD dwSize,dwType;
|
||
|
unsigned short crc;
|
||
|
|
||
|
MaskExceptions ();
|
||
|
Sys_SetFPCW ();
|
||
|
|
||
|
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 ();
|
||
|
|
||
|
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
|
||
|
|
||
|
if (!GetVersionEx (&vinfo))
|
||
|
Sys_Error ("Couldn't get OS info");
|
||
|
|
||
|
if (vinfo.dwMajorVersion < 4)
|
||
|
Win32AtLeastV4 = false;
|
||
|
else
|
||
|
Win32AtLeastV4 = true;
|
||
|
|
||
|
if (vinfo.dwPlatformId == VER_PLATFORM_WIN32s)
|
||
|
Sys_Error ("Hexen2 requires at least Win95 or NT 4.0");
|
||
|
|
||
|
if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
||
|
WinNT = true;
|
||
|
else
|
||
|
WinNT = false;
|
||
|
|
||
|
#ifdef SECURE
|
||
|
dwSize = sizeof(temp);
|
||
|
RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||
|
"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName",
|
||
|
0, KEY_READ, &hKey);
|
||
|
value = RegQueryValueEx(hKey,"RAID2",NULL,&dwType,temp,&dwSize);
|
||
|
|
||
|
if (value == ERROR_SUCCESS && dwType == REG_SZ)
|
||
|
{
|
||
|
CRC_Init(&crc);
|
||
|
dwSize = strlen(temp);
|
||
|
for(i=0;i<dwSize;i++)
|
||
|
{
|
||
|
CRC_ProcessByte(&crc,temp[i]);
|
||
|
}
|
||
|
i = CRC_Value(crc);
|
||
|
// Con_Printf("CRC is %d\n",i);
|
||
|
|
||
|
if (i != CRC_A && i != CRC_B)
|
||
|
LegitCopy = false;
|
||
|
}
|
||
|
else LegitCopy = false;
|
||
|
|
||
|
if (!LegitCopy)
|
||
|
errormessage = "You need to re-install Hexen 2 on this computer!";
|
||
|
|
||
|
#else
|
||
|
LegitCopy = true;
|
||
|
#endif
|
||
|
|
||
|
#ifdef ACTIVISION
|
||
|
FindEncryption();
|
||
|
#endif
|
||
|
|
||
|
#ifdef SECURE
|
||
|
FindCD();
|
||
|
#endif
|
||
|
#ifdef SECURE_TIME
|
||
|
CheckTime();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
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;
|
||
|
|
||
|
VID_ForceUnlockedAndReturnState ();
|
||
|
|
||
|
va_start (argptr, error);
|
||
|
vsprintf (text, error, argptr);
|
||
|
va_end (argptr);
|
||
|
|
||
|
if (isDedicated)
|
||
|
{
|
||
|
va_start (argptr, error);
|
||
|
vsprintf (text, error, argptr);
|
||
|
va_end (argptr);
|
||
|
|
||
|
sprintf (text2, "ERROR: %s\n", text);
|
||
|
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_FloatTime ();
|
||
|
sc_return_on_enter = true; // so Enter will get us out of here
|
||
|
|
||
|
while (!Sys_ConsoleInput () &&
|
||
|
((Sys_FloatTime () - starttime) < CONSOLE_ERROR_TIMEOUT))
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// switch to windowed so the message box is visible
|
||
|
VID_SetDefaultMode ();
|
||
|
MessageBox(NULL, text, "Hexen II Error", MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
|
||
|
}
|
||
|
|
||
|
Host_Shutdown ();
|
||
|
|
||
|
// shut down QHOST hooks if necessary
|
||
|
DeinitConProc ();
|
||
|
|
||
|
exit (1);
|
||
|
}
|
||
|
|
||
|
void Sys_Printf (char *fmt, ...)
|
||
|
{
|
||
|
va_list argptr;
|
||
|
char text[1024];
|
||
|
DWORD dummy;
|
||
|
|
||
|
if (isDedicated)
|
||
|
{
|
||
|
va_start (argptr,fmt);
|
||
|
vsprintf (text, fmt, argptr);
|
||
|
va_end (argptr);
|
||
|
|
||
|
WriteFile(houtput, text, strlen (text), &dummy, NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Sys_Quit (void)
|
||
|
{
|
||
|
|
||
|
VID_ForceUnlockedAndReturnState ();
|
||
|
|
||
|
Host_Shutdown();
|
||
|
|
||
|
if (tevent)
|
||
|
CloseHandle (tevent);
|
||
|
|
||
|
if (isDedicated)
|
||
|
FreeConsole ();
|
||
|
|
||
|
// shut down QHOST hooks if necessary
|
||
|
DeinitConProc ();
|
||
|
|
||
|
exit (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
Sys_FloatTime
|
||
|
================
|
||
|
*/
|
||
|
double Sys_FloatTime (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_FloatTime ();
|
||
|
|
||
|
j = COM_CheckParm("-starttime");
|
||
|
|
||
|
if (j)
|
||
|
{
|
||
|
curtime = (double) (atof(com_argv[j+1]));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
curtime = 0.0;
|
||
|
}
|
||
|
|
||
|
lastcurtime = curtime;
|
||
|
}
|
||
|
|
||
|
|
||
|
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;
|
||
|
|
||
|
|
||
|
#ifdef GLQUAKE
|
||
|
|
||
|
#define H2_PARAM_KEY "Software\\Hexen2"
|
||
|
#define H2_FLAG_VALUE "Flag"
|
||
|
|
||
|
#endif
|
||
|
|
||
|
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;
|
||
|
#ifdef GLQUAKE
|
||
|
HKEY hParamKey;
|
||
|
BOOL FlagValue;
|
||
|
DWORD cbBuffSize = sizeof(FlagValue);
|
||
|
#endif
|
||
|
|
||
|
/* previous instances do not exist in Win32 */
|
||
|
if (hPrevInstance)
|
||
|
return 0;
|
||
|
|
||
|
CL_RemoveGIPFiles(NULL);
|
||
|
|
||
|
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[strlen(cwd)-1] == '/')
|
||
|
cwd[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)
|
||
|
{
|
||
|
#ifdef GLQUAKE
|
||
|
RegCreateKeyEx(HKEY_LOCAL_MACHINE, H2_PARAM_KEY, 0, "GLH2", REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hParamKey, NULL);
|
||
|
if (RegQueryValueEx(hParamKey, H2_FLAG_VALUE, NULL, NULL, (LPBYTE)&FlagValue, &cbBuffSize) != ERROR_SUCCESS)
|
||
|
{
|
||
|
FlagValue = TRUE;
|
||
|
RegSetValueEx(hParamKey, H2_FLAG_VALUE, 0, REG_BINARY, (LPBYTE)&FlagValue, sizeof(FlagValue));
|
||
|
MessageBox(NULL,"GLHexen is a special, accelerated version of Hexen II that runs on some OpenGL-based 3D cards. Note that not all 3D accelerator cards will work with GLHexen. If you are experiencing trouble launching GLHexen on your machine, your card is either not GLHexen compliant or you need to update your drivers. Consult your manufacturer for OpenGL compatibility and driver updates.","GLHexen2",MB_OK|MB_ICONSTOP);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
hwnd_dialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL);
|
||
|
|
||
|
if (hwnd_dialog)
|
||
|
{
|
||
|
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 = atoi (com_argv[t]) * 1024;
|
||
|
}
|
||
|
|
||
|
parms.membase = malloc (parms.memsize);
|
||
|
|
||
|
if (!parms.membase)
|
||
|
Sys_Error ("Not enough memory free; check disk space\n");
|
||
|
|
||
|
if(COM_CheckParm("-nopagein") == 0)
|
||
|
{
|
||
|
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)atoi (com_argv[t+1]);
|
||
|
}
|
||
|
|
||
|
if ((t = COM_CheckParm ("-HPARENT")) > 0)
|
||
|
{
|
||
|
if (t < com_argc)
|
||
|
heventParent = (HANDLE)atoi (com_argv[t+1]);
|
||
|
}
|
||
|
|
||
|
if ((t = COM_CheckParm ("-HCHILD")) > 0)
|
||
|
{
|
||
|
if (t < com_argc)
|
||
|
heventChild = (HANDLE)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_FloatTime ();
|
||
|
|
||
|
Cvar_RegisterVariable (&sys_delay);
|
||
|
|
||
|
/* main window message loop */
|
||
|
while (1)
|
||
|
{
|
||
|
if (isDedicated)
|
||
|
{
|
||
|
newtime = Sys_FloatTime ();
|
||
|
time = newtime - oldtime;
|
||
|
|
||
|
while (time < sys_ticrate.value )
|
||
|
{
|
||
|
Sys_Sleep();
|
||
|
newtime = Sys_FloatTime ();
|
||
|
time = newtime - oldtime;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// yield the CPU for a little while when paused, minimized, or not the focus
|
||
|
if ((cl.paused && (!ActiveApp && !DDActive)) || Minimized)
|
||
|
{
|
||
|
SleepUntilInput (PAUSE_SLEEP);
|
||
|
scr_skipupdate = 1; // no point in bothering to draw
|
||
|
}
|
||
|
else if (!ActiveApp && !DDActive)
|
||
|
{
|
||
|
SleepUntilInput (NOT_FOCUS_SLEEP);
|
||
|
scr_skipupdate = 1; // no point in bothering to draw
|
||
|
}
|
||
|
|
||
|
newtime = Sys_FloatTime ();
|
||
|
time = newtime - oldtime;
|
||
|
}
|
||
|
|
||
|
if (sys_delay.value)
|
||
|
Sleep(sys_delay.value);
|
||
|
|
||
|
Host_Frame (time);
|
||
|
oldtime = newtime;
|
||
|
|
||
|
}
|
||
|
|
||
|
/* return success of application */
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* $Log: /H2 Mission Pack/SYS_WIN.C $
|
||
|
*
|
||
|
* 8 4/13/98 1:01p Jmonroe
|
||
|
* changed default to not use CDVolume
|
||
|
*
|
||
|
* 7 4/01/98 6:43p Jmonroe
|
||
|
* fixed boundschecker errors
|
||
|
*
|
||
|
* 6 3/16/98 6:25p Jmonroe
|
||
|
* set up euro secure checks
|
||
|
*
|
||
|
* 5 3/06/98 10:35a Jmonroe
|
||
|
*
|
||
|
* 4 3/05/98 5:13p Jmonroe
|
||
|
* added pr build security shit
|
||
|
*
|
||
|
* 3 3/01/98 8:20p Jmonroe
|
||
|
* removed the slow "quake" version of common functions
|
||
|
*
|
||
|
* 25 9/30/97 4:26p Rjohnson
|
||
|
* Updates
|
||
|
*
|
||
|
* 24 9/23/97 8:56p Rjohnson
|
||
|
* Updates
|
||
|
*
|
||
|
* 23 9/15/97 11:15a Rjohnson
|
||
|
* Updates
|
||
|
*
|
||
|
* 22 9/04/97 4:44p Rjohnson
|
||
|
* Updates
|
||
|
*
|
||
|
* 21 9/02/97 12:24a Rjohnson
|
||
|
* Checks for a cd
|
||
|
*
|
||
|
* 20 8/31/97 3:44p Rjohnson
|
||
|
* Memory change
|
||
|
*
|
||
|
* 19 8/27/97 12:10p Rjohnson
|
||
|
* Increased max memory
|
||
|
*
|
||
|
* 18 8/21/97 10:12p Rjohnson
|
||
|
* Demo Updates
|
||
|
*
|
||
|
* 17 8/21/97 11:05a Rjohnson
|
||
|
* Deleting gip files
|
||
|
*
|
||
|
* 16 8/20/97 2:59p Rjohnson
|
||
|
* Fix for crashes and saves
|
||
|
*
|
||
|
* 15 8/16/97 10:53a Rjohnson
|
||
|
* Comment
|
||
|
*
|
||
|
* 14 8/01/97 4:30p Rjohnson
|
||
|
* More encryption work
|
||
|
*
|
||
|
* 13 7/17/97 2:00p Rjohnson
|
||
|
* Added a security means to control the running of the game
|
||
|
*
|
||
|
* 12 6/16/97 12:25p Rjohnson
|
||
|
* Name changes from winquake to hexenii
|
||
|
*
|
||
|
* 11 6/16/97 3:13a Rjohnson
|
||
|
* Fixes for: allocating less memory, models clipping out, and plaques in
|
||
|
* gl version
|
||
|
*
|
||
|
* 10 5/13/97 4:54p Rjohnson
|
||
|
* Increased the memory requirements for the gl version
|
||
|
*
|
||
|
* 9 5/01/97 12:18a Bgokey
|
||
|
*
|
||
|
* 8 3/21/97 11:05a Rjohnson
|
||
|
* Increased minimum memory to 12 megs
|
||
|
*
|
||
|
* 7 3/07/97 2:24p Rjohnson
|
||
|
* Id Updates
|
||
|
*
|
||
|
* 6 2/24/97 3:12p Bgokey
|
||
|
* Added -nopagein.
|
||
|
*
|
||
|
* 5 2/18/97 4:55p Rjohnson
|
||
|
* Id Updates
|
||
|
*
|
||
|
* 4 1/02/97 11:16a Rjohnson
|
||
|
* Christmas work - added adaptive time, game delays, negative light,
|
||
|
* particle effects, etc
|
||
|
*
|
||
|
* 3 12/10/96 12:22p Rjohnson
|
||
|
* Code cleanup and made it so that quake won't try to do anything when it
|
||
|
* isn't the active app
|
||
|
*/
|