summaryrefslogtreecommitdiff
path: root/src/win32/win_shared.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/win32/win_shared.c')
-rw-r--r--src/win32/win_shared.c351
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();
+}
+