UFO: Alien Invasion
Loading...
Searching...
No Matches
win_shared.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 1997-2001 Id Software, Inc.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25
26#include "../../common/common.h"
27#include "win_local.h"
28#include <fcntl.h>
29#include <direct.h>
30#include <io.h>
31#include <conio.h>
32#include <mmsystem.h>
33#include <shellapi.h>
34
35#if defined(_MSC_VER)
36#include <intrin.h>
37#endif
38
40
41static void Sys_Utf8ToUtf16 (const char* source, LPWSTR dest, size_t destlen)
42{
43 const int len = MultiByteToWideChar(CP_UTF8, 0, source, -1, dest, destlen - 1);
44 dest[len] = 0;
45}
46
47static void Sys_Utf16ToUtf8 (const LPWSTR source, char* dest, size_t destsize)
48{
49 const int len = WideCharToMultiByte(CP_UTF8, 0, source, -1, dest, destsize - 1, nullptr, nullptr);
50 dest[len] = '\0';
51}
52
54{
55 static int base = 0;
56
57 /* let base retain 16 bits of effectively random data */
58 if (!base)
59 base = timeGetTime() & 0xffff0000;
60
61 return timeGetTime() - base;
62}
63
64void Sys_Mkdir (const char* path)
65{
66 WCHAR wpath[MAX_OSPATH];
67 Sys_Utf8ToUtf16(path, wpath, lengthof(wpath));
68 _wmkdir(wpath);
69}
70
71void Sys_Breakpoint (void)
72{
73#if defined(_MSC_VER)
74 __debugbreak();
75#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
76 __asm__ __volatile__ ( "int $3\n\t" );
77#endif
78}
79
80#ifdef COMPILE_UFO
86{
87 SYSTEM_INFO sysInfo;
88 /* 1 - use core #0
89 * 2 - use core #1
90 * 3 - use cores #0 and #1 */
91 HANDLE proc = GetCurrentProcess();
92
93 if (sys_priority->modified) {
94 if (sys_priority->integer < 0)
95 Cvar_SetValue("sys_priority", 0);
96 else if (sys_priority->integer > 2)
97 Cvar_SetValue("sys_priority", 2);
98
99 sys_priority->modified = false;
100
101 switch (sys_priority->integer) {
102 case 0:
103 SetPriorityClass(proc, NORMAL_PRIORITY_CLASS);
104 Com_Printf("Priority changed to NORMAL\n");
105 break;
106 case 1:
107 SetPriorityClass(proc, HIGH_PRIORITY_CLASS);
108 Com_Printf("Priority changed to HIGH\n");
109 break;
110 default:
111 SetPriorityClass(proc, REALTIME_PRIORITY_CLASS);
112 Com_Printf("Priority changed to REALTIME\n");
113 break;
114 }
115 }
116
117 if (sys_affinity->modified) {
118 DWORD_PTR procAffinity = 0;
119 GetSystemInfo(&sysInfo);
120 Com_Printf("Found %i processors\n", (int)sysInfo.dwNumberOfProcessors);
121 sys_affinity->modified = false;
122 if (sysInfo.dwNumberOfProcessors >= 2) {
123 switch (sys_affinity->integer) {
124 case 0:
125 Com_Printf("Use all cores\n");
126 procAffinity = (1 << sysInfo.dwNumberOfProcessors) - 1;
127 break;
128 case 1:
129 Com_Printf("Use two cores\n");
130 procAffinity = 3;
131 break;
132 case 2:
133 Com_Printf("Only use one core\n");
134 procAffinity = 1;
135 break;
136 }
137 } else {
138 Com_Printf("...only found one processor\n");
139 }
140 SetProcessAffinityMask(proc, procAffinity);
141 }
142
143 CloseHandle(proc);
144}
145#endif
146
147const char* Sys_SetLocale (const char* localeID)
148{
149 Sys_Setenv("LANG", localeID);
150 Sys_Setenv("LANGUAGE", localeID);
151 Sys_Setenv("LC_NUMERIC", "C");
152
153 return localeID;
154}
155
156const char* Sys_GetLocale (void)
157{
158 if (getenv("LANGUAGE"))
159 return getenv("LANGUAGE");
160 else
161 /* Setting to en will always work in every windows. */
162 return "en";
163}
164
165static char findbase[MAX_OSPATH];
166static char findpath[MAX_OSPATH];
167static char findname[MAX_OSPATH];
168static WCHAR wfindpath[MAX_OSPATH];
169static intptr_t findhandle;
170
171static bool CompareAttributes (unsigned found, unsigned musthave, unsigned canthave)
172{
173 if ((found & _A_RDONLY) && (canthave & SFF_RDONLY))
174 return false;
175 if ((found & _A_HIDDEN) && (canthave & SFF_HIDDEN))
176 return false;
177 if ((found & _A_SYSTEM) && (canthave & SFF_SYSTEM))
178 return false;
179 if ((found & _A_SUBDIR) && (canthave & SFF_SUBDIR))
180 return false;
181 if ((found & _A_ARCH) && (canthave & SFF_ARCH))
182 return false;
183
184 if ((musthave & SFF_RDONLY) && !(found & _A_RDONLY))
185 return false;
186 if ((musthave & SFF_HIDDEN) && !(found & _A_HIDDEN))
187 return false;
188 if ((musthave & SFF_SYSTEM) && !(found & _A_SYSTEM))
189 return false;
190 if ((musthave & SFF_SUBDIR) && !(found & _A_SUBDIR))
191 return false;
192 if ((musthave & SFF_ARCH) && !(found & _A_ARCH))
193 return false;
194
195 return true;
196}
197
202char* Sys_FindFirst (const char* path, unsigned musthave, unsigned canthave)
203{
204 struct _wfinddata_t findinfo;
205
206 if (findhandle)
207 Sys_Error("Sys_BeginFind without close");
208 findhandle = 0;
209
210 Com_FilePath(path, findbase, sizeof(findbase));
212 findhandle = _wfindfirst(wfindpath, &findinfo);
213 while (findhandle != -1) {
214 /* found one that matched */
215 if (!Q_streq(findname, ".") && !Q_streq(findname, "..") &&
216 CompareAttributes(findinfo.attrib, musthave, canthave)) {
217 Sys_Utf16ToUtf8(findinfo.name, findname, sizeof(findname));
218 Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, findname);
219 return findpath;
220 /* doesn't match - try the next one */
221 } else if (_wfindnext(findhandle, &findinfo) == -1) {
222 /* ok, no further entries here - leave the while loop */
223 _findclose(findhandle);
224 findhandle = -1;
225 }
226 }
227
228 /* none found */
229 return nullptr;
230}
231
236char* Sys_FindNext (unsigned musthave, unsigned canthave)
237{
238 struct _wfinddata_t findinfo;
239
240 if (findhandle == -1)
241 return nullptr;
242
243 /* until we found the next entry */
244 while (_wfindnext(findhandle, &findinfo) != -1) {
245 if (!Q_streq(findname, ".") && !Q_streq(findname, "..") &&
246 CompareAttributes(findinfo.attrib, musthave, canthave)) {
247 Sys_Utf16ToUtf8(findinfo.name, findname, sizeof(findname));
248 Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, findname);
249 return findpath;
250 }
251 }
252
253 /* none found */
254 return nullptr;
255}
256
263void Sys_FindClose (void)
264{
265 if (findhandle != -1)
266 _findclose(findhandle);
267 findhandle = 0;
268}
269
270#define MAX_FOUND_FILES 0x1000
271
272void Sys_ListFilteredFiles (const char* basedir, const char* subdirs, const char* filter, linkedList_t** list)
273{
274 char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
275 char filename[MAX_OSPATH];
276 struct _wfinddata_t findinfo;
277
278 if (subdirs[0] != '\0') {
279 Com_sprintf(search, sizeof(search), "%s\\%s\\*", basedir, subdirs);
280 } else {
281 Com_sprintf(search, sizeof(search), "%s\\*", basedir);
282 }
283
285 const int findhandle = _wfindfirst(wfindpath, &findinfo);
286 if (findhandle == -1)
287 return;
288
289 do {
290 if (findinfo.attrib & _A_SUBDIR) {
291 if (Q_strcasecmp(findname, ".") && Q_strcasecmp(findname, "..")) {
292 Sys_Utf16ToUtf8(findinfo.name, findname, sizeof(findname));
293 if (subdirs[0] != '\0') {
294 Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s\\%s", subdirs, findname);
295 } else {
296 Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", findname);
297 }
298 Sys_ListFilteredFiles(basedir, newsubdirs, filter, list);
299 }
300 }
301 Com_sprintf(filename, sizeof(filename), "%s\\%s", subdirs, findname);
302 if (!Com_Filter(filter, filename))
303 continue;
305 } while (_wfindnext(findhandle, &findinfo) != -1);
306
307 _findclose(findhandle);
308}
309
310void Sys_Quit (void)
311{
312 timeEndPeriod(1);
313
314#ifdef COMPILE_UFO
315 CL_Shutdown();
317#elif COMPILE_MAP
318 Mem_Shutdown();
319#endif
320
321 /* exit(0) */
322 ExitProcess(0);
323}
324
325#ifdef COMPILE_MAP
332static void Sys_ColoredOutput (const char* text, unsigned int fgColor, bool toStdOut)
333{
334 /* paint this colors (gray on black). */
335 unsigned int cliPaintColor = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
336 /* store default current colors. */
337 unsigned int cliCurColor = cliPaintColor;
338 CONSOLE_SCREEN_BUFFER_INFO cliInfo;
339 const DWORD handle = toStdOut ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE;
340 const HANDLE console = GetStdHandle(handle);
341
342 if (GetConsoleScreenBufferInfo(console, &cliInfo)) {
343 /* store current colors. */
344 cliCurColor = cliInfo.wAttributes;
345 /* is BACKGROUND == FOREGROUND */
346 if (cliCurColor == (fgColor << 4)) {
347 /* your fgColor on black background. */
348 cliPaintColor = fgColor;
349 } else {
350 /* remove foreground color. */
351 cliPaintColor = cliCurColor >> 4;
352 cliPaintColor <<= 4;
353 /* set foreground color. */
354 cliPaintColor |= fgColor;
355 }
356 }
357
358 SetConsoleTextAttribute(console, cliPaintColor);
359 if (toStdOut)
360 fprintf(stdout, "%s\n", text);
361 else
362 fprintf(stderr, "Error: %s\n", text);
363 SetConsoleTextAttribute(console, cliCurColor);
364
365 CloseHandle(console);
366}
367
368void Sys_Error (const char* error, ...)
369{
370 va_list argptr;
371 char text[1024];
372
373 va_start(argptr, error);
374 Q_vsnprintf(text, sizeof(text), error, argptr);
375 va_end(argptr);
376
377 /* red text to stderr. */
378 Sys_ColoredOutput(text, FOREGROUND_RED | FOREGROUND_INTENSITY, false);
379
380 ExitProcess(1);
381}
382#endif
383
387const char* Sys_GetCurrentUser (void)
388{
389 static char s_userName[1024];
390 WCHAR w_userName[1024];
391 unsigned long size = lengthof(w_userName);
392
393 if (!GetUserNameW(w_userName, &size))
394 Q_strncpyz(s_userName, "", sizeof(s_userName));
395 else
396 Sys_Utf16ToUtf8(w_userName, s_userName, sizeof(s_userName));
397
398 return s_userName;
399}
400
404char* Sys_Cwd (void)
405{
406 static char cwd[MAX_OSPATH];
407 WCHAR wcwd[MAX_OSPATH];
408
409 if (_wgetcwd(wcwd, lengthof(wcwd)) == nullptr)
410 return nullptr;
411 else
412 Sys_Utf16ToUtf8(wcwd, cwd, sizeof(cwd));
413
414 return cwd;
415}
416
420void Sys_NormPath (char* path)
421{
422 char* tmp = path;
423
424 while (*tmp) {
425 if (*tmp == '\\')
426 *tmp = '/';
427 else
428 *tmp = tolower(*tmp);
429 tmp++;
430 }
431}
432
440{
441 static char path[MAX_PATH];
442
443 const HMODULE shfolder = LoadLibrary("shfolder.dll");
444
445 if (shfolder == nullptr) {
446 Com_Printf("Unable to load SHFolder.dll\n");
447 return nullptr;
448 }
449
450 typedef HRESULT WINAPI SHGetFolderPath_t(HWND, int, HANDLE, DWORD, LPWSTR);
451 SHGetFolderPath_t* const qSHGetFolderPath = (SHGetFolderPath_t*)GetProcAddress(shfolder, "SHGetFolderPathW");
452 if (qSHGetFolderPath == nullptr) {
453 Com_Printf("Unable to find SHGetFolderPath in SHFolder.dll\n");
454 FreeLibrary(shfolder);
455 return nullptr;
456 }
457
458 WCHAR wpath[MAX_PATH];
459 if (!SUCCEEDED(qSHGetFolderPath(nullptr, CSIDL_APPDATA, nullptr, 0, wpath))) {
460 Com_Printf("Unable to detect CSIDL_APPDATA\n");
461 FreeLibrary(shfolder);
462 return nullptr;
463 }
464
465 Sys_Utf16ToUtf8(wpath, path, sizeof(path));
466 Q_strcat(path, sizeof(path), "\\UFOAI");
467 FreeLibrary(shfolder);
468
469 Sys_Utf8ToUtf16(path, wpath, MAX_PATH);
470 if (!CreateDirectoryW(wpath, nullptr)) {
471 if (GetLastError() != ERROR_ALREADY_EXISTS) {
472 Com_Printf("Unable to create directory \"%s\"\n", path);
473 return nullptr;
474 }
475 }
476
477 Sys_Utf16ToUtf8(wpath, path, sizeof(path));
478 return path;
479}
480
484void Sys_Sleep (int milliseconds)
485{
486 if (milliseconds < 1)
487 milliseconds = 1;
488 Sleep(milliseconds);
489}
490
496int Sys_Setenv (const char* name, const char* value)
497{
498 const size_t n = strlen(name) + strlen(value) + 2;
499 char* str = (char*)malloc(n); /* do not convert this to allocation from managed pool, using malloc is intentional */
500
501 strcat(strcat(strcpy(str, name), "="), value);
502 if (putenv(str))
503 return 0; /* putenv returns nonzero if fails */
504
505 return SetEnvironmentVariable(name, value);
506}
507
509{
510}
511
512void Sys_Mkfifo (const char* ospath, qFILE* f)
513{
514}
515
516void Sys_OpenURL (const char* url)
517{
518 ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
519}
520
521FILE* Sys_Fopen (const char* filename, const char* mode)
522{
523 WCHAR wname[MAX_OSPATH];
524 WCHAR wmode[MAX_VAR];
525 Sys_Utf8ToUtf16(filename, wname, lengthof(wname));
526 Sys_Utf8ToUtf16(mode, wmode, lengthof(wmode));
527 return _wfopen(wname, wmode);
528}
529
530int Sys_Remove (const char* filename)
531{
532 WCHAR wname[MAX_OSPATH];
533 Sys_Utf8ToUtf16(filename, wname, lengthof(wname));
534 return _wremove(wname);
535}
536
537int Sys_Rename (const char* oldname, const char* newname)
538{
539 WCHAR woldname[MAX_OSPATH];
540 WCHAR wnewname[MAX_OSPATH];
541 Sys_Utf8ToUtf16(oldname, woldname, lengthof(woldname));
542 Sys_Utf8ToUtf16(newname, wnewname, lengthof(wnewname));
543 return _wrename(woldname, wnewname);
544}
545
546int Sys_Access (const char* filename, int mode)
547{
548 WCHAR wname[MAX_OSPATH];
549 Sys_Utf8ToUtf16(filename, wname, lengthof(wname));
550 return _waccess(wname, mode);
551}
void CL_Shutdown(void)
Saves configuration file and shuts the client systems down.
Definition cl_main.cpp:1219
cvar_t * sys_priority
Definition common.cpp:59
cvar_t * sys_affinity
Definition common.cpp:60
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
void Qcommon_Shutdown(void)
Definition common.cpp:1555
definitions common between client and server, but not game lib
void Cvar_SetValue(const char *varName, float value)
Expands value to a string and calls Cvar_Set.
Definition cvar.cpp:671
#define MAX_OSPATH
Definition filesys.h:44
#define SFF_ARCH
Definition filesys.h:123
#define SFF_HIDDEN
Definition filesys.h:124
#define SFF_RDONLY
Definition filesys.h:125
#define SFF_SUBDIR
Definition filesys.h:126
#define SFF_SYSTEM
Definition filesys.h:127
void Sys_Error(const char *error,...)
Definition g_main.cpp:421
voidpf void uLong size
Definition ioapi.h:42
const char * filename
Definition ioapi.h:41
const char int mode
Definition ioapi.h:41
void LIST_AddString(linkedList_t **listDest, const char *data)
Adds an string to a new or to an already existing linked list. The string is copied here.
Definition list.cpp:139
void Mem_Shutdown(void)
Definition mem.cpp:518
QGL_EXTERN GLuint GLchar GLuint * len
Definition r_gl.h:99
QGL_EXTERN GLenum GLuint * dest
Definition r_gl.h:101
QGL_EXTERN GLfloat f
Definition r_gl.h:114
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
#define Q_strcasecmp(a, b)
Definition shared.h:131
#define Q_streq(a, b)
Definition shared.h:136
#define MAX_VAR
Definition shared.h:36
#define lengthof(x)
Definition shared.h:105
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
void Com_FilePath(const char *in, char *out, size_t size)
Returns the path up to, but not including the last /.
Definition shared.cpp:319
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
Definition shared.cpp:535
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
Definition shared.cpp:475
int Com_Filter(const char *pattern, const char *text)
Match the pattern PATTERN against the string TEXT;.
Definition shared.cpp:145
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
void Sys_SetAffinityAndPriority(void)
#define FILE
static char findbase[MAX_OSPATH]
static char findpath[MAX_OSPATH]
Win32-specific UFO header file.
HINSTANCE global_hInstance
#define DWORD_PTR
Definition win_local.h:34
void Sys_Sleep(int milliseconds)
Calls the win32 sleep function.
char * Sys_Cwd(void)
Get current working dir.
void Sys_Breakpoint(void)
void Sys_NormPath(char *path)
Normalize path (remove all \ ).
FILE * Sys_Fopen(const char *filename, const char *mode)
void Sys_InitSignals(void)
int Sys_Remove(const char *filename)
const char * Sys_GetLocale(void)
static intptr_t findhandle
void Sys_OpenURL(const char *url)
int Sys_Rename(const char *oldname, const char *newname)
char * Sys_GetHomeDirectory(void)
Get the home directory in Application Data.
void Sys_Quit(void)
void Sys_ListFilteredFiles(const char *basedir, const char *subdirs, const char *filter, linkedList_t **list)
static bool CompareAttributes(unsigned found, unsigned musthave, unsigned canthave)
static WCHAR wfindpath[MAX_OSPATH]
void Sys_Mkfifo(const char *ospath, qFILE *f)
char * Sys_FindFirst(const char *path, unsigned musthave, unsigned canthave)
Opens the directory and returns the first file that matches our searchrules.
int Sys_Milliseconds(void)
void Sys_Mkdir(const char *path)
void Sys_FindClose(void)
Closes the find handle.
static char findname[MAX_OSPATH]
int Sys_Setenv(const char *name, const char *value)
set/unset environment variables (empty value removes it)
static void Sys_Utf16ToUtf8(const LPWSTR source, char *dest, size_t destsize)
int Sys_Access(const char *filename, int mode)
static void Sys_Utf8ToUtf16(const char *source, LPWSTR dest, size_t destlen)
const char * Sys_GetCurrentUser(void)
Get current user.
char * Sys_FindNext(unsigned musthave, unsigned canthave)
Returns the next file of the already opened directory (Sys_FindFirst) that matches our search mask.
const char * Sys_SetLocale(const char *localeID)