mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-22 20:01:21 +00:00
Cleanup the system specific code.
* Remove a bunch of unnecessary functions. * Reorder functions into logical groups. The orderig is now the same on Unix and Windows. While at it add several TODOs to the code. There's not need for special library loading functions for the game, the Windows backend still uses a lot of old and fishy DOS functions, etc. All this will be done at a later time.
This commit is contained in:
parent
acb50c6907
commit
2096d57eb8
3 changed files with 363 additions and 406 deletions
|
@ -19,32 +19,21 @@
|
||||||
*
|
*
|
||||||
* =======================================================================
|
* =======================================================================
|
||||||
*
|
*
|
||||||
* This file implements all system dependend generic funktions
|
* This file implements all system dependent generic functions.
|
||||||
*
|
*
|
||||||
* =======================================================================
|
* =======================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <dirent.h>
|
||||||
#include <signal.h>
|
#include <dlfcn.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/ipc.h>
|
|
||||||
#include <sys/shm.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <mach/clock.h>
|
#include <mach/clock.h>
|
||||||
|
@ -55,27 +44,67 @@
|
||||||
#include "../../common/header/glob.h"
|
#include "../../common/header/glob.h"
|
||||||
#include "../generic/header/input.h"
|
#include "../generic/header/input.h"
|
||||||
|
|
||||||
unsigned sys_frame_time;
|
// Pointer to game library
|
||||||
static void *game_library;
|
static void *game_library;
|
||||||
|
|
||||||
|
// File searching
|
||||||
static char findbase[MAX_OSPATH];
|
static char findbase[MAX_OSPATH];
|
||||||
static char findpath[MAX_OSPATH];
|
static char findpath[MAX_OSPATH];
|
||||||
static char findpattern[MAX_OSPATH];
|
static char findpattern[MAX_OSPATH];
|
||||||
static DIR *fdir;
|
static DIR *fdir;
|
||||||
|
|
||||||
|
// Evil hack to determine if stdin is available
|
||||||
qboolean stdin_active = true;
|
qboolean stdin_active = true;
|
||||||
|
|
||||||
|
// Console logfile
|
||||||
extern FILE *logfile;
|
extern FILE *logfile;
|
||||||
|
|
||||||
static qboolean
|
// TODO
|
||||||
CompareAttributes(char *path, char *name, unsigned musthave, unsigned canthave)
|
unsigned sys_frame_time;
|
||||||
|
|
||||||
|
/* ================================================================ */
|
||||||
|
|
||||||
|
void
|
||||||
|
Sys_Error(char *error, ...)
|
||||||
{
|
{
|
||||||
/* . and .. never match */
|
va_list argptr;
|
||||||
if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0))
|
char string[1024];
|
||||||
{
|
|
||||||
return false;
|
/* change stdin to non blocking */
|
||||||
|
fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~FNDELAY);
|
||||||
|
|
||||||
|
#ifndef DEDICATED_ONLY
|
||||||
|
CL_Shutdown();
|
||||||
|
#endif
|
||||||
|
Qcommon_Shutdown();
|
||||||
|
|
||||||
|
va_start(argptr, error);
|
||||||
|
vsnprintf(string, 1024, error, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
fprintf(stderr, "Error: %s\n", string);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
void
|
||||||
|
Sys_Quit(void)
|
||||||
|
{
|
||||||
|
#ifndef DEDICATED_ONLY
|
||||||
|
CL_Shutdown();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (logfile)
|
||||||
|
{
|
||||||
|
fclose(logfile);
|
||||||
|
logfile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qcommon_Shutdown();
|
||||||
|
fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~FNDELAY);
|
||||||
|
|
||||||
|
printf("------------------------------------\n");
|
||||||
|
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -83,6 +112,62 @@ Sys_Init(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================================ */
|
||||||
|
|
||||||
|
char *
|
||||||
|
Sys_ConsoleInput(void)
|
||||||
|
{
|
||||||
|
static char text[256];
|
||||||
|
int len;
|
||||||
|
fd_set fdset;
|
||||||
|
struct timeval timeout;
|
||||||
|
|
||||||
|
if (!dedicated || !dedicated->value)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stdin_active)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_ZERO(&fdset);
|
||||||
|
FD_SET(0, &fdset); /* stdin */
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
if ((select(1, &fdset, NULL, NULL, &timeout) == -1) || !FD_ISSET(0, &fdset))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = read(0, text, sizeof(text));
|
||||||
|
|
||||||
|
if (len == 0) /* eof! */
|
||||||
|
{
|
||||||
|
stdin_active = false;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len < 1)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
text[len - 1] = 0; /* rip off the /n and terminate */
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Sys_ConsoleOutput(char *string)
|
||||||
|
{
|
||||||
|
fputs(string, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================================ */
|
||||||
|
|
||||||
long long
|
long long
|
||||||
Sys_Microseconds(void)
|
Sys_Microseconds(void)
|
||||||
{
|
{
|
||||||
|
@ -146,22 +231,24 @@ Sys_Milliseconds(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sys_Mkdir(char *path)
|
Sys_Nanosleep(int nanosec)
|
||||||
{
|
{
|
||||||
mkdir(path, 0755);
|
struct timespec t = {0, nanosec};
|
||||||
|
nanosleep(&t, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
/* ================================================================ */
|
||||||
Sys_GetCurrentDirectory(void)
|
|
||||||
{
|
|
||||||
static char dir[MAX_OSPATH];
|
|
||||||
|
|
||||||
if (!getcwd(dir, sizeof(dir)))
|
static qboolean
|
||||||
|
CompareAttributes(char *path, char *name, unsigned musthave, unsigned canthave)
|
||||||
{
|
{
|
||||||
Sys_Error("Couldn't get current working directory");
|
/* . and .. never match */
|
||||||
|
if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dir;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
@ -248,148 +335,9 @@ Sys_FindClose(void)
|
||||||
fdir = NULL;
|
fdir = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/* ================================================================ */
|
||||||
Sys_ConsoleOutput(char *string)
|
|
||||||
{
|
|
||||||
fputs(string, stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
// TODO: Unnecessary, use generic functions instead.
|
||||||
Sys_Printf(char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list argptr;
|
|
||||||
char text[1024];
|
|
||||||
unsigned char *p;
|
|
||||||
|
|
||||||
va_start(argptr, fmt);
|
|
||||||
vsnprintf(text, 1024, fmt, argptr);
|
|
||||||
va_end(argptr);
|
|
||||||
|
|
||||||
for (p = (unsigned char *)text; *p; p++)
|
|
||||||
{
|
|
||||||
*p &= 0x7f;
|
|
||||||
|
|
||||||
if (((*p > 128) || (*p < 32)) && (*p != 10) && (*p != 13) && (*p != 9))
|
|
||||||
{
|
|
||||||
printf("[%02x]", *p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
putc(*p, stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sys_Quit(void)
|
|
||||||
{
|
|
||||||
#ifndef DEDICATED_ONLY
|
|
||||||
CL_Shutdown();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (logfile)
|
|
||||||
{
|
|
||||||
fclose(logfile);
|
|
||||||
logfile = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qcommon_Shutdown();
|
|
||||||
fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~FNDELAY);
|
|
||||||
|
|
||||||
printf("------------------------------------\n");
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sys_Error(char *error, ...)
|
|
||||||
{
|
|
||||||
va_list argptr;
|
|
||||||
char string[1024];
|
|
||||||
|
|
||||||
/* change stdin to non blocking */
|
|
||||||
fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~FNDELAY);
|
|
||||||
|
|
||||||
#ifndef DEDICATED_ONLY
|
|
||||||
CL_Shutdown();
|
|
||||||
#endif
|
|
||||||
Qcommon_Shutdown();
|
|
||||||
|
|
||||||
va_start(argptr, error);
|
|
||||||
vsnprintf(string, 1024, error, argptr);
|
|
||||||
va_end(argptr);
|
|
||||||
fprintf(stderr, "Error: %s\n", string);
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* returns -1 if not present
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
Sys_FileTime(char *path)
|
|
||||||
{
|
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
if (stat(path, &buf) == -1)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.st_mtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
floating_point_exception_handler(int whatever)
|
|
||||||
{
|
|
||||||
signal(SIGFPE, floating_point_exception_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
Sys_ConsoleInput(void)
|
|
||||||
{
|
|
||||||
static char text[256];
|
|
||||||
int len;
|
|
||||||
fd_set fdset;
|
|
||||||
struct timeval timeout;
|
|
||||||
|
|
||||||
if (!dedicated || !dedicated->value)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stdin_active)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&fdset);
|
|
||||||
FD_SET(0, &fdset); /* stdin */
|
|
||||||
timeout.tv_sec = 0;
|
|
||||||
timeout.tv_usec = 0;
|
|
||||||
|
|
||||||
if ((select(1, &fdset, NULL, NULL, &timeout) == -1) || !FD_ISSET(0, &fdset))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = read(0, text, sizeof(text));
|
|
||||||
|
|
||||||
if (len == 0) /* eof! */
|
|
||||||
{
|
|
||||||
stdin_active = false;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len < 1)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
text[len - 1] = 0; /* rip off the /n and terminate */
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Sys_UnloadGame(void)
|
Sys_UnloadGame(void)
|
||||||
|
@ -402,9 +350,6 @@ Sys_UnloadGame(void)
|
||||||
game_library = NULL;
|
game_library = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Loads the game dll
|
|
||||||
*/
|
|
||||||
void *
|
void *
|
||||||
Sys_GetGameAPI(void *parms)
|
Sys_GetGameAPI(void *parms)
|
||||||
{
|
{
|
||||||
|
@ -495,17 +440,15 @@ Sys_GetGameAPI(void *parms)
|
||||||
return GetGameAPI(parms);
|
return GetGameAPI(parms);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/* ================================================================ */
|
||||||
Sys_SendKeyEvents(void)
|
|
||||||
{
|
|
||||||
#ifndef DEDICATED_ONLY
|
|
||||||
IN_Update();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* grab frame time */
|
void
|
||||||
sys_frame_time = Sys_Milliseconds();
|
Sys_Mkdir(char *path)
|
||||||
|
{
|
||||||
|
mkdir(path, 0755);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
Sys_GetHomeDir(void)
|
Sys_GetHomeDir(void)
|
||||||
{
|
{
|
||||||
|
@ -524,6 +467,8 @@ Sys_GetHomeDir(void)
|
||||||
return gdir;
|
return gdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================================ */
|
||||||
|
|
||||||
void *
|
void *
|
||||||
Sys_GetProcAddress(void *handle, const char *sym)
|
Sys_GetProcAddress(void *handle, const char *sym)
|
||||||
{
|
{
|
||||||
|
@ -544,6 +489,15 @@ Sys_GetProcAddress(void *handle, const char *sym)
|
||||||
return dlsym(handle, sym);
|
return dlsym(handle, sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Sys_FreeLibrary(void *handle)
|
||||||
|
{
|
||||||
|
if (handle && dlclose(handle))
|
||||||
|
{
|
||||||
|
Com_Error(ERR_FATAL, "dlclose failed on %p: %s", handle, dlerror());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
Sys_LoadLibrary(const char *path, const char *sym, void **handle)
|
Sys_LoadLibrary(const char *path, const char *sym, void **handle)
|
||||||
{
|
{
|
||||||
|
@ -582,28 +536,17 @@ Sys_LoadLibrary(const char *path, const char *sym, void **handle)
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/* ================================================================ */
|
||||||
Sys_FreeLibrary(void *handle)
|
|
||||||
{
|
|
||||||
if (handle && dlclose(handle))
|
|
||||||
{
|
|
||||||
Com_Error(ERR_FATAL, "dlclose failed on %p: %s", handle, dlerror());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
// TODO: Remove.
|
||||||
* Just a dummy. There's no need on unixoid systems to
|
|
||||||
* redirect stdout and stderr.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
Sys_RedirectStdout(void)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Sys_Nanosleep(int nanosec)
|
Sys_SendKeyEvents(void)
|
||||||
{
|
{
|
||||||
struct timespec t = {0, nanosec};
|
#ifndef DEDICATED_ONLY
|
||||||
nanosleep(&t, NULL);
|
IN_Update();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* grab frame time */
|
||||||
|
sys_frame_time = Sys_Milliseconds();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,42 +19,43 @@
|
||||||
*
|
*
|
||||||
* =======================================================================
|
* =======================================================================
|
||||||
*
|
*
|
||||||
* This file is the starting point of the program and implements
|
* This file implements all system dependent generic functions.
|
||||||
* several support functions and the main loop.
|
|
||||||
*
|
*
|
||||||
* =======================================================================
|
* =======================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <conio.h>
|
||||||
|
#include <direct.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <direct.h>
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <conio.h>
|
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "../../common/header/common.h"
|
#include "../../common/header/common.h"
|
||||||
#include "../generic/header/input.h"
|
#include "../generic/header/input.h"
|
||||||
#include "header/resource.h"
|
#include "header/resource.h"
|
||||||
|
|
||||||
int starttime;
|
// stdin and stdout handles
|
||||||
|
|
||||||
static HANDLE hinput, houtput;
|
static HANDLE hinput, houtput;
|
||||||
|
|
||||||
|
// Game library handle
|
||||||
static HINSTANCE game_library;
|
static HINSTANCE game_library;
|
||||||
|
|
||||||
unsigned int sys_frame_time;
|
// Buffer for the dedicated server console
|
||||||
|
|
||||||
static char console_text[256];
|
static char console_text[256];
|
||||||
static int console_textlen;
|
static size_t console_textlen;
|
||||||
|
|
||||||
|
// File searching
|
||||||
char findbase[MAX_OSPATH];
|
char findbase[MAX_OSPATH];
|
||||||
char findpath[MAX_OSPATH];
|
char findpath[MAX_OSPATH];
|
||||||
int findhandle;
|
int findhandle;
|
||||||
|
|
||||||
|
// TODO
|
||||||
qboolean is_portable;
|
qboolean is_portable;
|
||||||
|
unsigned int sys_frame_time;
|
||||||
|
|
||||||
/* ================================================================ */
|
/* ================================================================ */
|
||||||
|
|
||||||
|
@ -108,11 +109,11 @@ Sys_Quit(void)
|
||||||
fclose(stderr);
|
fclose(stderr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
printf("------------------------------------\n");
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================================ */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Sys_Init(void)
|
Sys_Init(void)
|
||||||
{
|
{
|
||||||
|
@ -147,6 +148,8 @@ Sys_Init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================================ */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
Sys_ConsoleInput(void)
|
Sys_ConsoleInput(void)
|
||||||
{
|
{
|
||||||
|
@ -262,88 +265,8 @@ Sys_ConsoleOutput(char *string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Sys_SendKeyEvents(void)
|
|
||||||
{
|
|
||||||
#ifndef DEDICATED_ONLY
|
|
||||||
IN_Update();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* grab frame time */
|
|
||||||
sys_frame_time = timeGetTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ================================================================ */
|
/* ================================================================ */
|
||||||
|
|
||||||
void
|
|
||||||
Sys_UnloadGame(void)
|
|
||||||
{
|
|
||||||
if (!FreeLibrary(game_library))
|
|
||||||
{
|
|
||||||
Com_Error(ERR_FATAL, "FreeLibrary failed for game library");
|
|
||||||
}
|
|
||||||
|
|
||||||
game_library = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
Sys_GetGameAPI(void *parms)
|
|
||||||
{
|
|
||||||
void *(*GetGameAPI)(void *);
|
|
||||||
char name[MAX_OSPATH];
|
|
||||||
char *path = NULL;
|
|
||||||
|
|
||||||
if (game_library)
|
|
||||||
{
|
|
||||||
Com_Error(ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now run through the search paths */
|
|
||||||
path = NULL;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
path = FS_NextPath(path);
|
|
||||||
|
|
||||||
if (!path)
|
|
||||||
{
|
|
||||||
return NULL; /* couldn't find one anywhere */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try game.dll */
|
|
||||||
Com_sprintf(name, sizeof(name), "%s/%s", path, "game.dll");
|
|
||||||
game_library = LoadLibrary(name);
|
|
||||||
|
|
||||||
if (game_library)
|
|
||||||
{
|
|
||||||
Com_DPrintf("LoadLibrary (%s)\n", name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try gamex86.dll as fallback */
|
|
||||||
Com_sprintf(name, sizeof(name), "%s/%s", path, "gamex86.dll");
|
|
||||||
game_library = LoadLibrary(name);
|
|
||||||
|
|
||||||
if (game_library)
|
|
||||||
{
|
|
||||||
Com_DPrintf("LoadLibrary (%s)\n", name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GetGameAPI = (void *)GetProcAddress(game_library, "GetGameAPI");
|
|
||||||
|
|
||||||
if (!GetGameAPI)
|
|
||||||
{
|
|
||||||
Sys_UnloadGame();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetGameAPI(parms);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
long long
|
long long
|
||||||
Sys_Microseconds(void)
|
Sys_Microseconds(void)
|
||||||
{
|
{
|
||||||
|
@ -378,12 +301,6 @@ Sys_Milliseconds(void)
|
||||||
return (int)(Sys_Microseconds()/1000ll);
|
return (int)(Sys_Microseconds()/1000ll);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Sys_Sleep(int msec)
|
|
||||||
{
|
|
||||||
Sleep(msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sys_Nanosleep(int nanosec)
|
void Sys_Nanosleep(int nanosec)
|
||||||
{
|
{
|
||||||
HANDLE timer;
|
HANDLE timer;
|
||||||
|
@ -400,8 +317,10 @@ void Sys_Nanosleep(int nanosec)
|
||||||
CloseHandle(timer);
|
CloseHandle(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ================================================================ */
|
||||||
|
|
||||||
|
// TODO: Still uses broken DOS functions.
|
||||||
|
// Have a look at FindFirstFile(), FindNextFile() and FindClose().
|
||||||
static qboolean
|
static qboolean
|
||||||
CompareAttributes(unsigned found, unsigned musthave, unsigned canthave)
|
CompareAttributes(unsigned found, unsigned musthave, unsigned canthave)
|
||||||
{
|
{
|
||||||
|
@ -522,25 +441,86 @@ Sys_FindClose(void)
|
||||||
findhandle = 0;
|
findhandle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================================ */
|
||||||
|
|
||||||
|
// TODO: Unnecessary, use generic functions instead.
|
||||||
|
|
||||||
|
void
|
||||||
|
Sys_UnloadGame(void)
|
||||||
|
{
|
||||||
|
if (!FreeLibrary(game_library))
|
||||||
|
{
|
||||||
|
Com_Error(ERR_FATAL, "FreeLibrary failed for game library");
|
||||||
|
}
|
||||||
|
|
||||||
|
game_library = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
Sys_GetGameAPI(void *parms)
|
||||||
|
{
|
||||||
|
void *(*GetGameAPI)(void *);
|
||||||
|
char name[MAX_OSPATH];
|
||||||
|
char *path = NULL;
|
||||||
|
|
||||||
|
if (game_library)
|
||||||
|
{
|
||||||
|
Com_Error(ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now run through the search paths */
|
||||||
|
path = NULL;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
path = FS_NextPath(path);
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
{
|
||||||
|
return NULL; /* couldn't find one anywhere */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try game.dll */
|
||||||
|
Com_sprintf(name, sizeof(name), "%s/%s", path, "game.dll");
|
||||||
|
game_library = LoadLibrary(name);
|
||||||
|
|
||||||
|
if (game_library)
|
||||||
|
{
|
||||||
|
Com_DPrintf("LoadLibrary (%s)\n", name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try gamex86.dll as fallback */
|
||||||
|
Com_sprintf(name, sizeof(name), "%s/%s", path, "gamex86.dll");
|
||||||
|
game_library = LoadLibrary(name);
|
||||||
|
|
||||||
|
if (game_library)
|
||||||
|
{
|
||||||
|
Com_DPrintf("LoadLibrary (%s)\n", name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetGameAPI = (void *)GetProcAddress(game_library, "GetGameAPI");
|
||||||
|
|
||||||
|
if (!GetGameAPI)
|
||||||
|
{
|
||||||
|
Sys_UnloadGame();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetGameAPI(parms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================================================= */
|
||||||
|
|
||||||
void
|
void
|
||||||
Sys_Mkdir(char *path)
|
Sys_Mkdir(char *path)
|
||||||
{
|
{
|
||||||
|
// TODO: Use CreateDirectory() instead
|
||||||
_mkdir(path);
|
_mkdir(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
|
||||||
Sys_GetCurrentDirectory(void)
|
|
||||||
{
|
|
||||||
static char dir[MAX_OSPATH];
|
|
||||||
|
|
||||||
if (!_getcwd(dir, sizeof(dir)))
|
|
||||||
{
|
|
||||||
Sys_Error("Couldn't get current working directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
Sys_GetHomeDir(void)
|
Sys_GetHomeDir(void)
|
||||||
{
|
{
|
||||||
|
@ -608,97 +588,14 @@ Sys_GetHomeDir(void)
|
||||||
return gdir;
|
return gdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Sys_RedirectStdout(void)
|
|
||||||
{
|
|
||||||
char *cur;
|
|
||||||
char *old;
|
|
||||||
char dir[MAX_OSPATH];
|
|
||||||
char path_stdout[MAX_OSPATH];
|
|
||||||
char path_stderr[MAX_OSPATH];
|
|
||||||
const char *tmp;
|
|
||||||
|
|
||||||
if (is_portable) {
|
|
||||||
tmp = Sys_GetBinaryDir();
|
|
||||||
Q_strlcpy(dir, tmp, sizeof(dir));
|
|
||||||
} else {
|
|
||||||
tmp = Sys_GetHomeDir();
|
|
||||||
Q_strlcpy(dir, tmp, sizeof(dir));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = old = dir;
|
|
||||||
|
|
||||||
while (cur != NULL)
|
|
||||||
{
|
|
||||||
if ((cur - old) > 1)
|
|
||||||
{
|
|
||||||
*cur = '\0';
|
|
||||||
Sys_Mkdir(dir);
|
|
||||||
*cur = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
old = cur;
|
|
||||||
cur = strchr(old + 1, '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(path_stdout, sizeof(path_stdout), "%s/%s", dir, "stdout.txt");
|
|
||||||
snprintf(path_stderr, sizeof(path_stderr), "%s/%s", dir, "stderr.txt");
|
|
||||||
|
|
||||||
freopen(path_stdout, "w", stdout);
|
|
||||||
freopen(path_stderr, "w", stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
|
||||||
typedef enum YQ2_PROCESS_DPI_AWARENESS {
|
void *
|
||||||
YQ2_PROCESS_DPI_UNAWARE = 0,
|
Sys_GetProcAddress(void *handle, const char *sym)
|
||||||
YQ2_PROCESS_SYSTEM_DPI_AWARE = 1,
|
|
||||||
YQ2_PROCESS_PER_MONITOR_DPI_AWARE = 2
|
|
||||||
} YQ2_PROCESS_DPI_AWARENESS;
|
|
||||||
|
|
||||||
void
|
|
||||||
Sys_SetHighDPIMode(void)
|
|
||||||
{
|
{
|
||||||
/* For Vista, Win7 and Win8 */
|
return GetProcAddress(handle, sym);
|
||||||
BOOL(WINAPI *SetProcessDPIAware)(void) = NULL;
|
|
||||||
|
|
||||||
/* Win8.1 and later */
|
|
||||||
HRESULT(WINAPI *SetProcessDpiAwareness)(YQ2_PROCESS_DPI_AWARENESS dpiAwareness) = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
HINSTANCE userDLL = LoadLibrary("USER32.DLL");
|
|
||||||
|
|
||||||
if (userDLL)
|
|
||||||
{
|
|
||||||
SetProcessDPIAware = (BOOL(WINAPI *)(void)) GetProcAddress(userDLL,
|
|
||||||
"SetProcessDPIAware");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HINSTANCE shcoreDLL = LoadLibrary("SHCORE.DLL");
|
|
||||||
|
|
||||||
if (shcoreDLL)
|
|
||||||
{
|
|
||||||
SetProcessDpiAwareness = (HRESULT(WINAPI *)(YQ2_PROCESS_DPI_AWARENESS))
|
|
||||||
GetProcAddress(shcoreDLL, "SetProcessDpiAwareness");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (SetProcessDpiAwareness) {
|
|
||||||
SetProcessDpiAwareness(YQ2_PROCESS_PER_MONITOR_DPI_AWARE);
|
|
||||||
}
|
|
||||||
else if (SetProcessDPIAware) {
|
|
||||||
SetProcessDPIAware();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Sys_FreeLibrary(void *handle)
|
Sys_FreeLibrary(void *handle)
|
||||||
{
|
{
|
||||||
|
@ -754,9 +651,112 @@ Sys_LoadLibrary(const char *path, const char *sym, void **handle)
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
/* ======================================================================= */
|
||||||
Sys_GetProcAddress(void *handle, const char *sym)
|
|
||||||
|
// This one is Windows specific.
|
||||||
|
|
||||||
|
void
|
||||||
|
Sys_RedirectStdout(void)
|
||||||
{
|
{
|
||||||
return GetProcAddress(handle, sym);
|
char *cur;
|
||||||
|
char *old;
|
||||||
|
char dir[MAX_OSPATH];
|
||||||
|
char path_stdout[MAX_OSPATH];
|
||||||
|
char path_stderr[MAX_OSPATH];
|
||||||
|
const char *tmp;
|
||||||
|
|
||||||
|
if (is_portable) {
|
||||||
|
tmp = Sys_GetBinaryDir();
|
||||||
|
Q_strlcpy(dir, tmp, sizeof(dir));
|
||||||
|
} else {
|
||||||
|
tmp = Sys_GetHomeDir();
|
||||||
|
Q_strlcpy(dir, tmp, sizeof(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dir == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = old = dir;
|
||||||
|
|
||||||
|
while (cur != NULL)
|
||||||
|
{
|
||||||
|
if ((cur - old) > 1)
|
||||||
|
{
|
||||||
|
*cur = '\0';
|
||||||
|
Sys_Mkdir(dir);
|
||||||
|
*cur = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
old = cur;
|
||||||
|
cur = strchr(old + 1, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(path_stdout, sizeof(path_stdout), "%s/%s", dir, "stdout.txt");
|
||||||
|
snprintf(path_stderr, sizeof(path_stderr), "%s/%s", dir, "stderr.txt");
|
||||||
|
|
||||||
|
freopen(path_stdout, "w", stdout);
|
||||||
|
freopen(path_stderr, "w", stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================================================= */
|
||||||
|
|
||||||
|
// This one is windows specific.
|
||||||
|
|
||||||
|
typedef enum YQ2_PROCESS_DPI_AWARENESS {
|
||||||
|
YQ2_PROCESS_DPI_UNAWARE = 0,
|
||||||
|
YQ2_PROCESS_SYSTEM_DPI_AWARE = 1,
|
||||||
|
YQ2_PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||||
|
} YQ2_PROCESS_DPI_AWARENESS;
|
||||||
|
|
||||||
|
void
|
||||||
|
Sys_SetHighDPIMode(void)
|
||||||
|
{
|
||||||
|
/* For Vista, Win7 and Win8 */
|
||||||
|
BOOL(WINAPI *SetProcessDPIAware)(void) = NULL;
|
||||||
|
|
||||||
|
/* Win8.1 and later */
|
||||||
|
HRESULT(WINAPI *SetProcessDpiAwareness)(YQ2_PROCESS_DPI_AWARENESS dpiAwareness) = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
HINSTANCE userDLL = LoadLibrary("USER32.DLL");
|
||||||
|
|
||||||
|
if (userDLL)
|
||||||
|
{
|
||||||
|
SetProcessDPIAware = (BOOL(WINAPI *)(void)) GetProcAddress(userDLL,
|
||||||
|
"SetProcessDPIAware");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HINSTANCE shcoreDLL = LoadLibrary("SHCORE.DLL");
|
||||||
|
|
||||||
|
if (shcoreDLL)
|
||||||
|
{
|
||||||
|
SetProcessDpiAwareness = (HRESULT(WINAPI *)(YQ2_PROCESS_DPI_AWARENESS))
|
||||||
|
GetProcAddress(shcoreDLL, "SetProcessDpiAwareness");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (SetProcessDpiAwareness) {
|
||||||
|
SetProcessDpiAwareness(YQ2_PROCESS_PER_MONITOR_DPI_AWARE);
|
||||||
|
}
|
||||||
|
else if (SetProcessDPIAware) {
|
||||||
|
SetProcessDPIAware();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================================================= */
|
||||||
|
|
||||||
|
// TODO: Remove.
|
||||||
|
|
||||||
|
void
|
||||||
|
Sys_SendKeyEvents(void)
|
||||||
|
{
|
||||||
|
#ifndef DEDICATED_ONLY
|
||||||
|
IN_Update();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* grab frame time */
|
||||||
|
sys_frame_time = timeGetTime();
|
||||||
|
}
|
||||||
|
|
|
@ -755,28 +755,6 @@ extern vec3_t bytedirs[NUMVERTEXNORMALS];
|
||||||
/* this is in the client code, but can be used for debugging from server */
|
/* this is in the client code, but can be used for debugging from server */
|
||||||
void SCR_DebugGraph(float value, int color);
|
void SCR_DebugGraph(float value, int color);
|
||||||
|
|
||||||
void *Sys_GetGameAPI(void *parms);
|
|
||||||
/* NON-PORTABLE OSTYPE SERVICES */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Sys_Init(void);
|
|
||||||
void Sys_UnloadGame(void);
|
|
||||||
char *Sys_ConsoleInput(void);
|
|
||||||
void Sys_ConsoleOutput(char *string);
|
|
||||||
void Sys_SendKeyEvents(void);
|
|
||||||
void Sys_Error(char *error, ...);
|
|
||||||
void Sys_Quit(void);
|
|
||||||
char *Sys_GetHomeDir(void);
|
|
||||||
const char *Sys_GetBinaryDir(void);
|
|
||||||
long long Sys_Microseconds(void);
|
|
||||||
void Sys_FreeLibrary(void *handle);
|
|
||||||
void *Sys_LoadLibrary(const char *path, const char *sym, void **handle);
|
|
||||||
void *Sys_GetProcAddress(void *handle, const char *sym);
|
|
||||||
void Sys_RedirectStdout(void);
|
|
||||||
void Sys_SetupFPU(void);
|
|
||||||
void Sys_Nanosleep(int);
|
|
||||||
|
|
||||||
/* CLIENT / SERVER SYSTEMS */
|
/* CLIENT / SERVER SYSTEMS */
|
||||||
|
|
||||||
void CL_Init(void);
|
void CL_Init(void);
|
||||||
|
@ -790,4 +768,40 @@ void SV_Init(void);
|
||||||
void SV_Shutdown(char *finalmsg, qboolean reconnect);
|
void SV_Shutdown(char *finalmsg, qboolean reconnect);
|
||||||
void SV_Frame(int msec);
|
void SV_Frame(int msec);
|
||||||
|
|
||||||
|
/* ======================================================================= */
|
||||||
|
|
||||||
|
// Platform specific functions.
|
||||||
|
|
||||||
|
// system.c
|
||||||
|
char *Sys_ConsoleInput(void);
|
||||||
|
void Sys_ConsoleOutput(char *string);
|
||||||
|
void Sys_Error(char *error, ...);
|
||||||
|
void Sys_Quit(void);
|
||||||
|
void Sys_Init(void);
|
||||||
|
char *Sys_GetHomeDir(void);
|
||||||
|
long long Sys_Microseconds(void);
|
||||||
|
void Sys_Nanosleep(int);
|
||||||
|
void *Sys_GetProcAddress(void *handle, const char *sym);
|
||||||
|
void Sys_FreeLibrary(void *handle);
|
||||||
|
void *Sys_LoadLibrary(const char *path, const char *sym, void **handle);
|
||||||
|
|
||||||
|
// TODO: Use generic functions instead
|
||||||
|
void *Sys_GetGameAPI(void *parms);
|
||||||
|
void Sys_UnloadGame(void);
|
||||||
|
|
||||||
|
// TODO: Remove
|
||||||
|
void Sys_SendKeyEvents(void);
|
||||||
|
|
||||||
|
// Windows only (system.c)
|
||||||
|
#ifdef _WIN32
|
||||||
|
void Sys_RedirectStdout(void);
|
||||||
|
void Sys_SetHighDPIMode(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// misc.c
|
||||||
|
const char *Sys_GetBinaryDir(void);
|
||||||
|
void Sys_SetupFPU(void);
|
||||||
|
|
||||||
|
/* ======================================================================= */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue