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