1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4 Copyright (C) 2000-2006 Tim Angus
5 
6 This file is part of Tremulous.
7 
8 Tremulous is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the License,
11 or (at your option) any later version.
12 
13 Tremulous is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Tremulous; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21 ===========================================================================
22 */
23 
24 #include "../qcommon/q_shared.h"
25 #include "../qcommon/qcommon.h"
26 #include "win_local.h"
27 #include <lmerr.h>
28 #include <lmcons.h>
29 #include <lmwksta.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <stdio.h>
33 #include <direct.h>
34 #include <io.h>
35 #include <conio.h>
36 
37 /*
38 ================
39 Sys_Milliseconds
40 ================
41 */
42 int			sys_timeBase;
Sys_Milliseconds(void)43 int Sys_Milliseconds (void)
44 {
45 	int			sys_curtime;
46 	static qboolean	initialized = qfalse;
47 
48 	if (!initialized) {
49 		sys_timeBase = timeGetTime();
50 		initialized = qtrue;
51 	}
52 	sys_curtime = timeGetTime() - sys_timeBase;
53 
54 	return sys_curtime;
55 }
56 
57 #ifndef __GNUC__ //see snapvectora.s
58 /*
59 ================
60 Sys_SnapVector
61 ================
62 */
Sys_SnapVector(float * v)63 void Sys_SnapVector( float *v )
64 {
65 	int i;
66 	float f;
67 
68 	f = *v;
69 	__asm	fld		f;
70 	__asm	fistp	i;
71 	*v = i;
72 	v++;
73 	f = *v;
74 	__asm	fld		f;
75 	__asm	fistp	i;
76 	*v = i;
77 	v++;
78 	f = *v;
79 	__asm	fld		f;
80 	__asm	fistp	i;
81 	*v = i;
82 }
83 #endif
84 
85 
86 /*
87 **
88 ** Disable all optimizations temporarily so this code works correctly!
89 **
90 */
91 #ifdef _MSC_VER
92 #pragma optimize( "", off )
93 #endif
94 
95 // If you fancy porting this stuff to AT&T then feel free... :)
96 // It's not actually used functionally though, so it may be a waste of effort
97 #ifndef __MINGW32__
98 /*
99 ** --------------------------------------------------------------------------------
100 **
101 ** PROCESSOR STUFF
102 **
103 ** --------------------------------------------------------------------------------
104 */
CPUID(int func,unsigned regs[4])105 static void CPUID( int func, unsigned regs[4] )
106 {
107 	unsigned regEAX, regEBX, regECX, regEDX;
108 
109 	__asm mov eax, func
110 	__asm __emit 00fh
111 	__asm __emit 0a2h
112 	__asm mov regEAX, eax
113 	__asm mov regEBX, ebx
114 	__asm mov regECX, ecx
115 	__asm mov regEDX, edx
116 
117 	regs[0] = regEAX;
118 	regs[1] = regEBX;
119 	regs[2] = regECX;
120 	regs[3] = regEDX;
121 }
122 
IsPentium(void)123 static int IsPentium( void )
124 {
125 	__asm
126 	{
127 		pushfd						// save eflags
128 		pop		eax
129 		test	eax, 0x00200000		// check ID bit
130 		jz		set21				// bit 21 is not set, so jump to set_21
131 		and		eax, 0xffdfffff		// clear bit 21
132 		push	eax					// save new value in register
133 		popfd						// store new value in flags
134 		pushfd
135 		pop		eax
136 		test	eax, 0x00200000		// check ID bit
137 		jz		good
138 		jmp		err					// cpuid not supported
139 set21:
140 		or		eax, 0x00200000		// set ID bit
141 		push	eax					// store new value
142 		popfd						// store new value in EFLAGS
143 		pushfd
144 		pop		eax
145 		test	eax, 0x00200000		// if bit 21 is on
146 		jnz		good
147 		jmp		err
148 	}
149 
150 err:
151 	return qfalse;
152 good:
153 	return qtrue;
154 }
155 
Is3DNOW(void)156 static int Is3DNOW( void )
157 {
158 	unsigned regs[4];
159 	char pstring[16];
160 	char processorString[13];
161 
162 	// get name of processor
163 	CPUID( 0, ( unsigned int * ) pstring );
164 	processorString[0] = pstring[4];
165 	processorString[1] = pstring[5];
166 	processorString[2] = pstring[6];
167 	processorString[3] = pstring[7];
168 	processorString[4] = pstring[12];
169 	processorString[5] = pstring[13];
170 	processorString[6] = pstring[14];
171 	processorString[7] = pstring[15];
172 	processorString[8] = pstring[8];
173 	processorString[9] = pstring[9];
174 	processorString[10] = pstring[10];
175 	processorString[11] = pstring[11];
176 	processorString[12] = 0;
177 
178 //  REMOVED because you can have 3DNow! on non-AMD systems
179 //	if ( strcmp( processorString, "AuthenticAMD" ) )
180 //		return qfalse;
181 
182 	// check AMD-specific functions
183 	CPUID( 0x80000000, regs );
184 	if ( regs[0] < 0x80000000 )
185 		return qfalse;
186 
187 	// bit 31 of EDX denotes 3DNOW! support
188 	CPUID( 0x80000001, regs );
189 	if ( regs[3] & ( 1 << 31 ) )
190 		return qtrue;
191 
192 	return qfalse;
193 }
194 
IsKNI(void)195 static int IsKNI( void )
196 {
197 	unsigned regs[4];
198 
199 	// get CPU feature bits
200 	CPUID( 1, regs );
201 
202 	// bit 25 of EDX denotes KNI existence
203 	if ( regs[3] & ( 1 << 25 ) )
204 		return qtrue;
205 
206 	return qfalse;
207 }
208 
IsMMX(void)209 static int IsMMX( void )
210 {
211 	unsigned regs[4];
212 
213 	// get CPU feature bits
214 	CPUID( 1, regs );
215 
216 	// bit 23 of EDX denotes MMX existence
217 	if ( regs[3] & ( 1 << 23 ) )
218 		return qtrue;
219 	return qfalse;
220 }
221 
Sys_GetProcessorId(void)222 int Sys_GetProcessorId( void )
223 {
224 #if defined _M_ALPHA
225 	return CPUID_AXP;
226 #elif !defined _M_IX86
227 	return CPUID_GENERIC;
228 #else
229 
230 	// verify we're at least a Pentium or 486 w/ CPUID support
231 	if ( !IsPentium() )
232 		return CPUID_INTEL_UNSUPPORTED;
233 
234 	// check for MMX
235 	if ( !IsMMX() )
236 	{
237 		// Pentium or PPro
238 		return CPUID_INTEL_PENTIUM;
239 	}
240 
241 	// see if we're an AMD 3DNOW! processor
242 	if ( Is3DNOW() )
243 	{
244 		return CPUID_AMD_3DNOW;
245 	}
246 
247 	// see if we're an Intel Katmai
248 	if ( IsKNI() )
249 	{
250 		return CPUID_INTEL_KATMAI;
251 	}
252 
253 	// by default we're functionally a vanilla Pentium/MMX or P2/MMX
254 	return CPUID_INTEL_MMX;
255 
256 #endif
257 }
258 #endif
259 
260 /*
261 **
262 ** Re-enable optimizations back to what they were
263 **
264 */
265 #ifdef _MSC_VER
266 #pragma optimize( "", on )
267 #endif
268 
269 //============================================
270 
Sys_GetCurrentUser(void)271 char *Sys_GetCurrentUser( void )
272 {
273 	static char s_userName[1024];
274 	unsigned long size = sizeof( s_userName );
275 
276 
277 	if ( !GetUserName( s_userName, &size ) )
278 		strcpy( s_userName, "player" );
279 
280 	if ( !s_userName[0] )
281 	{
282 		strcpy( s_userName, "player" );
283 	}
284 
285 	return s_userName;
286 }
287 
Sys_DefaultHomePath(void)288 char	*Sys_DefaultHomePath(void) {
289 	return NULL;
290 }
291 
Sys_DefaultInstallPath(void)292 char *Sys_DefaultInstallPath(void)
293 {
294 	return Sys_Cwd();
295 }
296 
297