/*
===========================================================================
Return to Castle Wolfenstein multiplayer GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Return to Castle Wolfenstein multiplayer GPL Source Code (RTCW MP Source Code).
RTCW MP Source Code 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 3 of the License, or
(at your option) any later version.
RTCW MP Source Code 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 RTCW MP Source Code. If not, see .
In addition, the RTCW MP Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the RTCW MP Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../game/q_shared.h"
#include "../qcommon/qcommon.h"
#include "win_local.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
================
Sys_Milliseconds
================
*/
int sys_timeBase;
int Sys_Milliseconds( void ) {
int sys_curtime;
static qboolean initialized = qfalse;
if ( !initialized ) {
sys_timeBase = timeGetTime();
initialized = qtrue;
}
sys_curtime = timeGetTime() - sys_timeBase;
return sys_curtime;
}
/*
================
Sys_SnapVector
================
*/
long fastftol( float f ) {
static int tmp;
__asm fld f
__asm fistp tmp
__asm mov eax, tmp
}
void Sys_SnapVector( float *v ) {
int i;
float f;
f = *v;
__asm fld f;
__asm fistp i;
*v = i;
v++;
f = *v;
__asm fld f;
__asm fistp i;
*v = i;
v++;
f = *v;
__asm fld f;
__asm fistp i;
*v = i;
/*
*v = fastftol(*v);
v++;
*v = fastftol(*v);
v++;
*v = fastftol(*v);
*/
}
/*
**
** Disable all optimizations temporarily so this code works correctly!
**
*/
#pragma optimize( "", off )
/*
** --------------------------------------------------------------------------------
**
** PROCESSOR STUFF
**
** --------------------------------------------------------------------------------
*/
static void CPUID( int func, unsigned regs[4] ) {
unsigned regEAX, regEBX, regECX, regEDX;
__asm mov eax, func
__asm __emit 00fh
__asm __emit 0a2h
__asm mov regEAX, eax
__asm mov regEBX, ebx
__asm mov regECX, ecx
__asm mov regEDX, edx
regs[0] = regEAX;
regs[1] = regEBX;
regs[2] = regECX;
regs[3] = regEDX;
}
static int IsPentium( void ) {
__asm
{
pushfd // save eflags
pop eax
test eax, 0x00200000 // check ID bit
jz set21 // bit 21 is not set, so jump to set_21
and eax, 0xffdfffff // clear bit 21
push eax // save new value in register
popfd // store new value in flags
pushfd
pop eax
test eax, 0x00200000 // check ID bit
jz good
jmp err // cpuid not supported
set21:
or eax, 0x00200000 // set ID bit
push eax // store new value
popfd // store new value in EFLAGS
pushfd
pop eax
test eax, 0x00200000 // if bit 21 is on
jnz good
jmp err
}
err:
return qfalse;
good:
return qtrue;
}
static int Is3DNOW( void ) {
unsigned regs[4];
char pstring[16];
char processorString[13];
// get name of processor
CPUID( 0, ( unsigned int * ) pstring );
processorString[0] = pstring[4];
processorString[1] = pstring[5];
processorString[2] = pstring[6];
processorString[3] = pstring[7];
processorString[4] = pstring[12];
processorString[5] = pstring[13];
processorString[6] = pstring[14];
processorString[7] = pstring[15];
processorString[8] = pstring[8];
processorString[9] = pstring[9];
processorString[10] = pstring[10];
processorString[11] = pstring[11];
processorString[12] = 0;
// REMOVED because you can have 3DNow! on non-AMD systems
// if ( strcmp( processorString, "AuthenticAMD" ) )
// return qfalse;
// check AMD-specific functions
CPUID( 0x80000000, regs );
if ( regs[0] < 0x80000000 ) {
return qfalse;
}
// bit 31 of EDX denotes 3DNOW! support
CPUID( 0x80000001, regs );
if ( regs[3] & ( 1 << 31 ) ) {
return qtrue;
}
return qfalse;
}
static int IsKNI( void ) {
unsigned regs[4];
// get CPU feature bits
CPUID( 1, regs );
// bit 25 of EDX denotes KNI existence
if ( regs[3] & ( 1 << 25 ) ) {
return qtrue;
}
return qfalse;
}
static int IsMMX( void ) {
unsigned regs[4];
// get CPU feature bits
CPUID( 1, regs );
// bit 23 of EDX denotes MMX existence
if ( regs[3] & ( 1 << 23 ) ) {
return qtrue;
}
return qfalse;
}
static int IsP3() {
unsigned regs[4];
// get CPU feature bits
CPUID( 1, regs );
if ( regs[0] < 6 ) {
return qfalse;
}
if ( !( regs[3] & 0x1 ) ) {
return qfalse; // fp
}
if ( !( regs[3] & 0x8000 ) ) { // cmov
return qfalse;
}
if ( !( regs[3] & 0x800000 ) ) { // mmx
return qfalse;
}
if ( !( regs[3] & 0x2000000 ) ) { // simd
return qfalse;
}
return qtrue;
}
static int IsAthlon() {
unsigned regs[4];
char pstring[16];
char processorString[13];
// get name of processor
CPUID( 0, ( unsigned int * ) pstring );
processorString[0] = pstring[4];
processorString[1] = pstring[5];
processorString[2] = pstring[6];
processorString[3] = pstring[7];
processorString[4] = pstring[12];
processorString[5] = pstring[13];
processorString[6] = pstring[14];
processorString[7] = pstring[15];
processorString[8] = pstring[8];
processorString[9] = pstring[9];
processorString[10] = pstring[10];
processorString[11] = pstring[11];
processorString[12] = 0;
if ( strcmp( processorString, "AuthenticAMD" ) ) {
return qfalse;
}
CPUID( 0x80000000, regs );
if ( regs[0] < 0x80000001 ) {
return qfalse;
}
// get CPU feature bits
CPUID( 1, regs );
if ( regs[0] < 6 ) {
return qfalse;
}
CPUID( 0x80000001, regs );
if ( !( regs[3] & 0x1 ) ) {
return qfalse; // fp
}
if ( !( regs[3] & 0x8000 ) ) { // cmov
return qfalse;
}
if ( !( regs[3] & 0x800000 ) ) { // mmx
return qfalse;
}
if ( !( regs[3] & 0x400000 ) ) { // k7 mmx
return qfalse;
}
if ( !( regs[3] & 0x80000000 ) ) { // 3dnow
return qfalse;
}
if ( !( regs[3] & 0x40000000 ) ) { // advanced 3dnow
return qfalse;
}
return qtrue;
}
int Sys_GetProcessorId( void ) {
#if defined _M_ALPHA
return CPUID_AXP;
#elif !defined _M_IX86
return CPUID_GENERIC;
#else
// verify we're at least a Pentium or 486 w/ CPUID support
if ( !IsPentium() ) {
return CPUID_INTEL_UNSUPPORTED;
}
// check for MMX
if ( !IsMMX() ) {
// Pentium or PPro
return CPUID_INTEL_PENTIUM;
}
// see if we're an AMD 3DNOW! processor
if ( Is3DNOW() ) {
return CPUID_AMD_3DNOW;
}
// see if we're an Intel Katmai
if ( IsKNI() ) {
return CPUID_INTEL_KATMAI;
}
// by default we're functionally a vanilla Pentium/MMX or P2/MMX
return CPUID_INTEL_MMX;
#endif
}
int Sys_GetHighQualityCPU() {
return ( !IsP3() && !IsAthlon() ) ? 0 : 1;
}
/*
**
** Re-enable optimizations back to what they were
**
*/
#pragma optimize( "", on )
//============================================
char *Sys_GetCurrentUser( void ) {
static char s_userName[1024];
unsigned long size = sizeof( s_userName );
if ( !GetUserName( s_userName, &size ) ) {
strcpy( s_userName, "player" );
}
if ( !s_userName[0] ) {
strcpy( s_userName, "player" );
}
return s_userName;
}