diff options
Diffstat (limited to 'src/win32/win_shared.c')
-rw-r--r-- | src/win32/win_shared.c | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/src/win32/win_shared.c b/src/win32/win_shared.c new file mode 100644 index 0000000..457a8d5 --- /dev/null +++ b/src/win32/win_shared.c @@ -0,0 +1,351 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous 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 Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" +#include "win_local.h" +#include <lmerr.h> +#include <lmcons.h> +#include <lmwksta.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <direct.h> +#include <io.h> +#include <conio.h> +#include <wincrypt.h> + +/* +================ +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; +} + +#ifndef __GNUC__ //see snapvectora.s +/* +================ +Sys_SnapVector +================ +*/ +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; +} +#endif + +qboolean Sys_RandomBytes( byte *string, int len ) +{ + HCRYPTPROV prov; + + if( !CryptAcquireContext( &prov, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) ) { + + return qfalse; + } + + if( !CryptGenRandom( prov, len, (BYTE *)string ) ) { + CryptReleaseContext( prov, 0 ); + return qfalse; + } + CryptReleaseContext( prov, 0 ); + return qtrue; +} + + +/* +** +** Disable all optimizations temporarily so this code works correctly! +** +*/ +#ifdef _MSC_VER +#pragma optimize( "", off ) +#endif + +// If you fancy porting this stuff to AT&T then feel free... :) +// It's not actually used functionally though, so it may be a waste of effort +#ifndef __MINGW32__ +/* +** -------------------------------------------------------------------------------- +** +** 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; +} + +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 +} +#endif + +/* +** +** Re-enable optimizations back to what they were +** +*/ +#ifdef _MSC_VER +#pragma optimize( "", on ) +#endif + +//============================================ + +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; +} + +char *Sys_DefaultHomePath(void) { + TCHAR szPath[MAX_PATH]; + static char path[MAX_OSPATH]; + FARPROC qSHGetFolderPath; + HMODULE shfolder = LoadLibrary("shfolder.dll"); + + if(shfolder == NULL) { + Com_Printf("Unable to load SHFolder.dll\n"); + return NULL; + } + + qSHGetFolderPath = GetProcAddress(shfolder, "SHGetFolderPathA"); + if(qSHGetFolderPath == NULL) + { + Com_Printf("Unable to find SHGetFolderPath in SHFolder.dll\n"); + FreeLibrary(shfolder); + return NULL; + } + + if( !SUCCEEDED( qSHGetFolderPath( NULL, CSIDL_APPDATA, + NULL, 0, szPath ) ) ) + { + Com_Printf("Unable to detect CSIDL_APPDATA\n"); + FreeLibrary(shfolder); + return NULL; + } + Q_strncpyz( path, szPath, sizeof(path) ); + Q_strcat( path, sizeof(path), "\\Tremulous" ); + FreeLibrary(shfolder); + if( !CreateDirectory( path, NULL ) ) + { + if( GetLastError() != ERROR_ALREADY_EXISTS ) + { + Com_Printf("Unable to create directory \"%s\"\n", path); + return NULL; + } + } + return path; +} + +char *Sys_DefaultInstallPath(void) +{ + return Sys_Cwd(); +} + |