#include "quakedef.h" #include #ifdef MULTITHREAD #include #endif #include #include #include "ftejslib.h" #ifndef isDedicated qboolean isDedicated; #endif 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); Sys_Printf("Error: %s\n", string); Con_Print ("Quake Error: "); Con_Print (string); Con_Print ("\n"); Host_Shutdown (); emscriptenfte_alert(string); exit (1); } void Sys_RecentServer(char *command, char *target, char *title, char *desc) { } qboolean Sys_RandomBytes(qbyte *string, int len) { return false; } //print into stdout void Sys_Printf (char *fmt, ...) { va_list argptr; char buf[1024]; va_start (argptr,fmt); vsnprintf (buf, sizeof(buf), fmt, argptr); emscriptenfte_print(buf); va_end (argptr); } unsigned int Sys_Milliseconds(void) { static int first = true; static unsigned long oldtime = 0, curtime = 0; unsigned long newtime; newtime = emscriptenfte_ticks_ms(); //return Date.now() if (first) { first = false; oldtime = newtime; } if (newtime < oldtime) Con_Printf("Sys_Milliseconds stepped backwards!\n"); else curtime += newtime - oldtime; oldtime = newtime; return curtime; } //return the current time, in the form of a double double Sys_DoubleTime (void) { return Sys_Milliseconds() / 1000.0; } //create a directory void Sys_mkdir (char *path) { } //unlink a file qboolean Sys_remove (char *path) { emscriptenfte_buf_delete(path); return true; } qboolean Sys_Rename (char *oldfname, char *newfname) { return emscriptenfte_buf_rename(oldfname, newfname); return false; } //someone used the 'quit' command #include "glquake.h" void Sys_Quit (void) { if (host_initialized) { qglClearColor(0,0,0,1); qglClear(GL_COLOR_BUFFER_BIT); Draw_FunString (0, 0, "Reload the page to restart"); Host_Shutdown(); } exit (0); } int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) { Con_DPrintf("Warning: Sys_EnumerateFiles not implemented\n"); return true; } //blink window if possible (it's not) void Sys_ServerActivity(void) { } void Sys_CloseLibrary(dllhandle_t *lib) { } dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs) { return NULL; } void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname) { return NULL; } void Sys_Init(void) { extern cvar_t vid_width, vid_height, vid_fullscreen; //vid_fullscreen takes effect only on mouse clicks, any suggestion to do a vid_restart is pointless. vid_fullscreen.flags &= ~CVAR_RENDERERLATCH; //these are not really supported. so silence any spam that suggests we do something about something not even supported. vid_width.flags &= ~CVAR_RENDERERLATCH; vid_height.flags &= ~CVAR_RENDERERLATCH; } void Sys_Shutdown(void) { } int VARGS Sys_DebugLog(char *file, char *fmt, ...) { return 0; }; qboolean Sys_InitTerminal(void) { return true; } char *Sys_ConsoleInput(void) { return NULL; } void Sys_CloseTerminal (void) { } void Sys_MainLoop(void) { static float oldtime; float newtime, time; newtime = Sys_DoubleTime (); if (!oldtime) oldtime = newtime; time = newtime - oldtime; Host_Frame (time); oldtime = newtime; } int QDECL main(int argc, char **argv) { quakeparms_t parms; memset(&parms, 0, sizeof(parms)); parms.basedir = ""; parms.argc = argc; parms.argv = (const char**)argv; COM_InitArgv (parms.argc, parms.argv); TL_InitLanguages(); Sys_Printf ("Host_Init\n"); Host_Init (&parms); //-1 fps should give vsync emscripten_set_main_loop(Sys_MainLoop, -1, false); return 0; } qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate) { return false; } static char *clipboard_buffer; char *Sys_GetClipboard(void) { return clipboard_buffer; } void Sys_CloseClipboard(char *bf) { } void Sys_SaveClipboard(char *text) { free(clipboard_buffer); clipboard_buffer = strdup(text); } #ifdef MULTITHREAD /* Thread creation calls */ void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize) { // SDL threads do not support setting thread stack size return (void *)SDL_CreateThread(func, args); } void Sys_WaitOnThread(void *thread) { SDL_WaitThread((SDL_Thread *)thread, NULL); } /* Mutex calls */ // SDL mutexes don't have try-locks for mutexes in the spec so we stick with 1-value semaphores void *Sys_CreateMutex(void) { 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) { 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); } #endif void Sys_Sleep (double seconds) { SDL_Delay(seconds * 1000); } //emscripten does not support the full set of sdl functions, so we stub the extras. int SDL_GetGammaRamp(Uint16 *redtable, Uint16 *greentable, Uint16 *bluetable) { return -1; } int SDL_SetGammaRamp(const Uint16 *redtable, const Uint16 *greentable, const Uint16 *bluetable) { return -1; } //SDL_GL_GetAttribute void SDL_UnloadObject(void *object) { } void *SDL_LoadObject(const char *sofile) { return NULL; } void *SDL_LoadFunction(void *handle, const char *name) { return NULL; } Uint8 SDL_GetAppState(void) { return SDL_APPACTIVE; } #define socklen_t int /* int getsockname(int socket, struct sockaddr *address, socklen_t *address_len) { return -1; } int getpeername(int socket, struct sockaddr *address, socklen_t *address_len) { return -1; } ssize_t sendto(int socket, const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len) { return -1; } */