2004-12-09 23:38:11 +00:00
|
|
|
#include "quakedef.h"
|
|
|
|
|
2004-12-10 21:31:53 +00:00
|
|
|
#include <SDL.h>
|
2007-12-30 00:09:34 +00:00
|
|
|
#ifdef MULTITHREAD
|
|
|
|
#include <SDL_thread.h>
|
|
|
|
#endif
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
#include <SDL_loadso.h>
|
|
|
|
|
2004-12-09 23:38:11 +00:00
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
#include <fcntl.h>
|
|
|
|
#endif
|
|
|
|
|
2005-11-29 23:14:45 +00:00
|
|
|
#ifndef isDedicated
|
2004-12-09 23:38:11 +00:00
|
|
|
qboolean isDedicated;
|
2005-11-29 23:14:45 +00:00
|
|
|
#endif
|
2004-12-09 23:38:11 +00:00
|
|
|
|
|
|
|
void Sys_Error (const char *error, ...)
|
|
|
|
{
|
|
|
|
va_list argptr;
|
|
|
|
char string[1024];
|
|
|
|
|
|
|
|
va_start (argptr,error);
|
|
|
|
vsnprintf (string, sizeof (string), error, argptr);
|
|
|
|
va_end (argptr);
|
|
|
|
fprintf(stderr, "Error: %s\n", string);
|
|
|
|
|
|
|
|
Con_Print ("Quake Error: ");
|
|
|
|
Con_Print (string);
|
|
|
|
Con_Print ("\n");
|
|
|
|
|
2005-01-12 08:38:31 +00:00
|
|
|
if (COM_CheckParm("-crashonerror"))
|
|
|
|
*(int*)-3 = 0;
|
|
|
|
|
2004-12-09 23:38:11 +00:00
|
|
|
Host_Shutdown ();
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
//print into stdout
|
|
|
|
void Sys_Printf (char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list argptr;
|
|
|
|
|
|
|
|
va_start (argptr,fmt);
|
|
|
|
vprintf (fmt,argptr);
|
|
|
|
va_end (argptr);
|
|
|
|
}
|
|
|
|
|
2007-07-23 12:05:41 +00:00
|
|
|
unsigned int Sys_Milliseconds(void)
|
|
|
|
{
|
|
|
|
static int first = true;
|
|
|
|
static unsigned long oldtime = 0, curtime = 0;
|
|
|
|
unsigned long newtime;
|
|
|
|
|
|
|
|
newtime = SDL_GetTicks();
|
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
first = false;
|
|
|
|
oldtime = newtime;
|
|
|
|
}
|
|
|
|
if (newtime < oldtime)
|
|
|
|
Con_Printf("Sys_Milliseconds stepped backwards!\n");
|
|
|
|
else
|
|
|
|
curtime += oldtime - newtime;
|
|
|
|
oldtime = newtime;
|
|
|
|
return curtime;
|
|
|
|
}
|
|
|
|
|
2004-12-09 23:38:11 +00:00
|
|
|
//return the current time, in the form of a double
|
|
|
|
double Sys_DoubleTime (void)
|
|
|
|
{
|
|
|
|
static int first = true;
|
|
|
|
static double oldtime = 0.0, curtime = 0.0;
|
|
|
|
double newtime;
|
|
|
|
|
|
|
|
newtime = (double) SDL_GetTicks() / 1000.0;
|
|
|
|
|
|
|
|
|
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
first = false;
|
|
|
|
oldtime = newtime;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (newtime < oldtime)
|
|
|
|
{
|
|
|
|
// warn if it's significant
|
|
|
|
if (newtime - oldtime < -0.01)
|
|
|
|
Con_Printf("Sys_DoubleTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
curtime += newtime - oldtime;
|
|
|
|
oldtime = newtime;
|
|
|
|
|
|
|
|
return curtime;
|
|
|
|
}
|
|
|
|
|
|
|
|
//create a directory
|
|
|
|
void Sys_mkdir (char *path)
|
|
|
|
{
|
|
|
|
#if WIN32
|
|
|
|
_mkdir (path);
|
|
|
|
#else
|
|
|
|
mkdir (path, 0777); //WARNING: DO NOT RUN AS ROOT!
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
//unlink a file
|
|
|
|
qboolean Sys_remove (char *path)
|
|
|
|
{
|
|
|
|
remove(path);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//someone used the 'quit' command
|
|
|
|
void Sys_Quit (void)
|
|
|
|
{
|
|
|
|
if (VID_ForceUnlockedAndReturnState)
|
|
|
|
VID_ForceUnlockedAndReturnState ();
|
|
|
|
|
|
|
|
Host_Shutdown();
|
|
|
|
|
|
|
|
exit (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//enumerate the files in a directory (of both gpath and match - match may not contain ..)
|
|
|
|
//calls the callback for each one until the callback returns 0
|
|
|
|
//SDL provides no file enumeration facilities.
|
2009-04-06 14:19:29 +00:00
|
|
|
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm)
|
2004-12-09 23:38:11 +00:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//blink window if possible (it's not)
|
|
|
|
void Sys_ServerActivity(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Without these two we cannot run Q2 gamecode.
|
|
|
|
void Sys_UnloadGame (void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void *Sys_GetGameAPI (void *parms)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
void Sys_CloseLibrary(dllhandle_t *lib)
|
|
|
|
{
|
2008-11-12 04:19:22 +00:00
|
|
|
SDL_UnloadObject((void*)lib);
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
2009-11-15 10:22:26 +00:00
|
|
|
dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
|
2008-11-09 22:29:28 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
void *lib;
|
|
|
|
|
|
|
|
lib = SDL_LoadObject(name);
|
|
|
|
if (!lib)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (i = 0; funcs[i].name; i++)
|
|
|
|
{
|
|
|
|
*funcs[i].funcptr = SDL_LoadFunction(lib, funcs[i].name);
|
|
|
|
if (!*funcs[i].funcptr)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (funcs[i].name)
|
|
|
|
{
|
|
|
|
Sys_CloseLibrary((dllhandle_t*)lib);
|
|
|
|
lib = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (dllhandle_t*)lib;
|
|
|
|
}
|
2004-12-09 23:38:11 +00:00
|
|
|
|
2004-12-10 21:31:53 +00:00
|
|
|
|
2004-12-09 23:38:11 +00:00
|
|
|
//used to see if a file exists or not.
|
|
|
|
int Sys_FileTime (char *path)
|
|
|
|
{
|
|
|
|
FILE *f;
|
|
|
|
|
|
|
|
f = fopen(path, "rb");
|
|
|
|
if (f)
|
|
|
|
{
|
|
|
|
fclose(f);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_Init(void)
|
|
|
|
{
|
|
|
|
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_CDROM | SDL_INIT_NOPARACHUTE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-12-05 16:47:29 +00:00
|
|
|
int VARGS Sys_DebugLog(char *file, char *fmt, ...)
|
2004-12-09 23:38:11 +00:00
|
|
|
{
|
|
|
|
FILE *fd;
|
|
|
|
va_list argptr;
|
|
|
|
static char data[1024];
|
|
|
|
|
|
|
|
va_start(argptr, fmt);
|
|
|
|
_vsnprintf(data, sizeof(data)-1, fmt, argptr);
|
|
|
|
va_end(argptr);
|
|
|
|
|
|
|
|
#if defined(CRAZYDEBUGGING) && CRAZYDEBUGGING > 1
|
|
|
|
{
|
|
|
|
static int sock;
|
|
|
|
if (!sock)
|
|
|
|
{
|
|
|
|
struct sockaddr_in sa;
|
|
|
|
netadr_t na;
|
|
|
|
int _true = true;
|
|
|
|
int listip;
|
|
|
|
listip = COM_CheckParm("-debugip");
|
|
|
|
NET_StringToAdr(listip?com_argv[listip+1]:"127.0.0.1", &na);
|
|
|
|
NetadrToSockadr(&na, (struct sockaddr_qstorage*)&sa);
|
|
|
|
sa.sin_port = htons(10000);
|
|
|
|
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
|
if (-1==connect(sock, (struct sockaddr*)&sa, sizeof(sa)))
|
|
|
|
Sys_Error("Couldn't send debug log lines\n");
|
|
|
|
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&_true, sizeof(_true));
|
|
|
|
}
|
|
|
|
send(sock, data, strlen(data), 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
fd = fopen(file, "wt");
|
2005-12-05 16:47:29 +00:00
|
|
|
if (fd)
|
|
|
|
{
|
|
|
|
fwrite(data, 1, strlen(data), fd);
|
|
|
|
fclose(fd);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
2004-12-09 23:38:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
qboolean Sys_InitTerminal(void)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
char *Sys_ConsoleInput(void)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
void Sys_CloseTerminal (void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
2006-04-02 03:47:06 +00:00
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#endif
|
|
|
|
|
2004-12-09 23:38:11 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
2005-01-12 08:38:31 +00:00
|
|
|
int main(int argc, char **argv)
|
2004-12-09 23:38:11 +00:00
|
|
|
{
|
|
|
|
float time, newtime, oldtime;
|
|
|
|
quakeparms_t parms;
|
|
|
|
int t;
|
|
|
|
|
|
|
|
parms.argv = argv;
|
|
|
|
|
|
|
|
parms.basedir = ".";
|
|
|
|
|
|
|
|
parms.argc = argc;
|
|
|
|
parms.argv = argv;
|
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
COM_InitArgv (parms.argc, parms.argv);
|
|
|
|
|
|
|
|
TL_InitLanguages();
|
|
|
|
|
2005-04-20 23:45:24 +00:00
|
|
|
parms.memsize = 0x2000000;
|
2004-12-09 23:38:11 +00:00
|
|
|
|
|
|
|
if (parms.memsize < 0x0800000)
|
|
|
|
parms.memsize = 0x0800000;
|
|
|
|
|
|
|
|
|
|
|
|
if (COM_CheckParm ("-heapsize"))
|
|
|
|
{
|
|
|
|
t = COM_CheckParm("-heapsize") + 1;
|
|
|
|
|
|
|
|
if (t < com_argc)
|
|
|
|
parms.memsize = Q_atoi (com_argv[t]) * 1024;
|
|
|
|
}
|
|
|
|
else if (COM_CheckParm ("-mem"))
|
|
|
|
{
|
|
|
|
t = COM_CheckParm("-mem") + 1;
|
|
|
|
|
|
|
|
if (t < com_argc)
|
|
|
|
parms.memsize = Q_atoi (com_argv[t]) * 1024*1024;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
parms.membase = VirtualAlloc (NULL, parms.memsize, MEM_RESERVE, PAGE_NOACCESS);
|
|
|
|
#else
|
|
|
|
parms.membase = malloc (parms.memsize);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Sys_Printf ("Host_Init\n");
|
|
|
|
Host_Init (&parms);
|
|
|
|
|
|
|
|
oldtime = Sys_DoubleTime ();
|
|
|
|
|
|
|
|
|
|
|
|
//client console should now be initialized.
|
|
|
|
|
|
|
|
/* main window message loop */
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
#ifndef CLIENTONLY
|
|
|
|
if (isDedicated)
|
|
|
|
{
|
|
|
|
NET_Sleep(100, false);
|
|
|
|
|
|
|
|
// find time passed since last cycle
|
|
|
|
newtime = Sys_DoubleTime ();
|
|
|
|
time = newtime - oldtime;
|
|
|
|
oldtime = newtime;
|
|
|
|
|
2005-10-31 19:53:37 +00:00
|
|
|
SV_Frame ();
|
2004-12-09 23:38:11 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
// yield the CPU for a little while when paused, minimized, or not the focus
|
2009-04-07 03:38:08 +00:00
|
|
|
if (!(SDL_GetAppState() & SDL_APPACTIVE))
|
2009-04-07 03:41:24 +00:00
|
|
|
SDL_Delay(1);
|
2004-12-09 23:38:11 +00:00
|
|
|
|
|
|
|
newtime = Sys_DoubleTime ();
|
|
|
|
time = newtime - oldtime;
|
|
|
|
Host_Frame (time);
|
|
|
|
oldtime = newtime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-04-15 03:31:23 +00:00
|
|
|
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2005-01-12 08:38:31 +00:00
|
|
|
void Sys_HighFPPrecision(void)
|
|
|
|
{
|
|
|
|
}
|
2004-12-09 23:38:11 +00:00
|
|
|
|
2005-01-12 08:38:31 +00:00
|
|
|
void Sys_LowFPPrecision(void)
|
|
|
|
{
|
|
|
|
}
|
2004-12-09 23:38:11 +00:00
|
|
|
|
2006-02-01 22:36:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char *Sys_GetClipboard(void)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
void Sys_CloseClipboard(char *bf)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
void Sys_SaveClipboard(char *text)
|
|
|
|
{
|
2007-07-23 12:05:41 +00:00
|
|
|
}
|
2007-12-30 00:09:34 +00:00
|
|
|
|
|
|
|
#ifdef MULTITHREAD
|
|
|
|
/* Thread creation calls */
|
2007-12-30 20:05:49 +00:00
|
|
|
void *Sys_CreateThread(int (*func)(void *), void *args, int stacksize)
|
2007-12-30 00:09:34 +00:00
|
|
|
{
|
|
|
|
// SDL threads do not support setting thread stack size
|
2007-12-30 20:05:49 +00:00
|
|
|
return (void *)SDL_CreateThread(func, args);
|
2007-12-30 00:09:34 +00:00
|
|
|
}
|
|
|
|
|
2007-12-30 20:05:49 +00:00
|
|
|
void Sys_WaitOnThread(void *thread)
|
|
|
|
{
|
|
|
|
SDL_WaitThread((SDL_Thread *)thread, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-30 00:09:34 +00:00
|
|
|
/* Mutex calls */
|
|
|
|
// SDL mutexes don't have try-locks for mutexes in the spec so we stick with 1-value semaphores
|
2008-06-01 05:42:23 +00:00
|
|
|
void *Sys_CreateMutex(void)
|
2007-12-30 00:09:34 +00:00
|
|
|
{
|
|
|
|
return (void *)SDL_CreateSemaphore(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Sys_TryLockMutex(void *mutex)
|
|
|
|
{
|
|
|
|
return !SDL_SemTryWait(mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Sys_LockMutex(void *mutex)
|
|
|
|
{
|
|
|
|
return !SDL_SemWait(mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Sys_UnlockMutex(void *mutex)
|
|
|
|
{
|
|
|
|
return !SDL_SemPost(mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_DestroyMutex(void *mutex)
|
|
|
|
{
|
2008-06-01 05:42:23 +00:00
|
|
|
SDL_DestroySemaphore(mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Conditional wait calls */
|
|
|
|
typedef struct condvar_s
|
|
|
|
{
|
|
|
|
SDL_mutex *mutex;
|
|
|
|
SDL_cond *cond;
|
|
|
|
} condvar_t;
|
|
|
|
|
|
|
|
void *Sys_CreateConditional(void)
|
|
|
|
{
|
|
|
|
condvar_t *condv;
|
|
|
|
SDL_mutex *mutex;
|
|
|
|
SDL_cond *cond;
|
|
|
|
|
|
|
|
condv = (condvar_t *)malloc(sizeof(condvar_t));
|
|
|
|
if (!condv)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
mutex = SDL_CreateMutex();
|
|
|
|
cond = SDL_CreateCond();
|
|
|
|
|
|
|
|
if (mutex)
|
|
|
|
{
|
|
|
|
if (cond)
|
|
|
|
{
|
|
|
|
condv->cond = cond;
|
|
|
|
condv->mutex = mutex;
|
|
|
|
|
|
|
|
return (void *)condv;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SDL_DestroyMutex(mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(condv);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Sys_LockConditional(void *condv)
|
|
|
|
{
|
|
|
|
return !SDL_mutexP(((condvar_t *)condv)->mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Sys_UnlockConditional(void *condv)
|
|
|
|
{
|
|
|
|
return !SDL_mutexV(((condvar_t *)condv)->mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Sys_ConditionWait(void *condv)
|
|
|
|
{
|
|
|
|
return !SDL_CondWait(((condvar_t *)condv)->cond, ((condvar_t *)condv)->mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Sys_ConditionSignal(void *condv)
|
|
|
|
{
|
|
|
|
return !SDL_CondSignal(((condvar_t *)condv)->cond);
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Sys_ConditionBroadcast(void *condv)
|
|
|
|
{
|
|
|
|
return !SDL_CondBroadcast(((condvar_t *)condv)->cond);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_DestroyConditional(void *condv)
|
|
|
|
{
|
|
|
|
condvar_t *cv = (condvar_t *)condv;
|
|
|
|
|
|
|
|
SDL_DestroyCond(cv->cond);
|
|
|
|
SDL_DestroyMutex(cv->mutex);
|
|
|
|
free(cv);
|
2007-12-30 00:09:34 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|