diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fbc341733..b02d0f69c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -192,9 +192,6 @@ endif() target_compile_definitions(SRB2SDL2 PRIVATE -D_LARGEFILE64_SOURCE) -set(SRB2_HAVE_THREADS ON) -target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_THREADS) - if("${SRB2_CONFIG_HWRENDER}") target_compile_definitions(SRB2SDL2 PRIVATE -DHWRENDER) add_subdirectory(hardware) diff --git a/src/Makefile.d/dedicated.mk b/src/Makefile.d/dedicated.mk index 698ea5531..af7904887 100644 --- a/src/Makefile.d/dedicated.mk +++ b/src/Makefile.d/dedicated.mk @@ -13,10 +13,7 @@ ifdef MINGW libs+=-mconsole endif -ifndef NOTHREADS -opts+=-DHAVE_THREADS sources+=dedicated/i_threads.c -endif NOOPENMPT=1 NOGME=1 diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk index d5e83989c..d07d23f51 100644 --- a/src/Makefile.d/sdl.mk +++ b/src/Makefile.d/sdl.mk @@ -43,10 +43,7 @@ sources+=sdl/mixer_sound.c endif endif -ifndef NOTHREADS -opts+=-DHAVE_THREADS sources+=sdl/i_threads.c -endif ifdef SDL_PKGCONFIG $(eval $(call Use_pkg_config,SDL)) diff --git a/src/command.c b/src/command.c index ab6cfc08a..be892e57a 100644 --- a/src/command.c +++ b/src/command.c @@ -16,6 +16,10 @@ /// /// code shamelessly inspired by the QuakeC sources, thanks Id :) +#ifdef __EMSCRIPTEN__ +#include +#endif + #include "doomdef.h" #include "doomstat.h" #include "command.h" @@ -277,7 +281,11 @@ void COM_BufExecute(void) /** Executes a string immediately. Used for skirting around WAIT commands. */ -void COM_ImmedExecute(const char *ptext) +void +#ifdef __EMSCRIPTEN__ +EMSCRIPTEN_KEEPALIVE +#endif +COM_ImmedExecute(const char *ptext) { size_t i = 0, j = 0; char line[1024] = ""; diff --git a/src/console.c b/src/console.c index 50ecfec9c..182995063 100644 --- a/src/console.c +++ b/src/console.c @@ -45,15 +45,10 @@ #define MAXHUDLINES 20 -#ifdef HAVE_THREADS I_mutex con_mutex; # define Lock_state() I_lock_mutex(&con_mutex) # define Unlock_state() I_unlock_mutex(con_mutex) -#else/*HAVE_THREADS*/ -# define Lock_state() -# define Unlock_state() -#endif/*HAVE_THREADS*/ static boolean con_started = false; // console has been initialised boolean con_startup = false; // true at game startup diff --git a/src/console.h b/src/console.h index 2af01f1a3..77ed29d7c 100644 --- a/src/console.h +++ b/src/console.h @@ -21,9 +21,7 @@ void CON_StopRefresh(void); boolean CON_Responder(event_t *ev); -#ifdef HAVE_THREADS extern I_mutex con_mutex; -#endif // set true when screen size has changed, to adapt console extern boolean con_recalc; diff --git a/src/d_main.c b/src/d_main.c index d75a4d501..5d8211393 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -15,6 +15,10 @@ /// plus functions to parse command line parameters, configure game /// parameters, and call the startup functions. +#ifdef __EMSCRIPTEN__ +#include +#endif + #if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) #include #include @@ -244,15 +248,11 @@ void D_ProcessEvents(void) } // Menu input -#ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); -#endif { eaten = M_Responder(ev); } -#ifdef HAVE_THREADS I_unlock_mutex(m_menu_mutex); -#endif if (eaten) continue; // menu ate the event @@ -264,15 +264,11 @@ void D_ProcessEvents(void) } // console input -#ifdef HAVE_THREADS I_lock_mutex(&con_mutex); -#endif { eaten = CON_Responder(ev); } -#ifdef HAVE_THREADS I_unlock_mutex(con_mutex); -#endif if (eaten) continue; // ate the event @@ -596,13 +592,9 @@ static void D_Display(void) // vid size change is now finished if it was on... vid.recalc = 0; -#ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); -#endif M_Drawer(); // menu is drawn even on top of everything -#ifdef HAVE_THREADS I_unlock_mutex(m_menu_mutex); -#endif // focus lost moved to M_Drawer CON_Drawer(); @@ -705,16 +697,11 @@ static void D_Display(void) tic_t rendergametic; +static void D_RunFrame(void); +static tic_t oldentertics = 0; + void D_SRB2Loop(void) { - tic_t entertic = 0, oldentertics = 0, realtics = 0, rendertimeout = INFTICS; - double deltatics = 0.0; - double deltasecs = 0.0; - static lumpnum_t gstartuplumpnum; - - boolean interp = false; - boolean doDisplay = false; - if (dedicated) server = true; @@ -750,21 +737,68 @@ void D_SRB2Loop(void) // hack to start on a nice clear console screen. COM_ImmedExecute("cls;version"); +#ifdef __EMSCRIPTEN__ + EM_ASM( + try { + StartedMainLoopCallback(); + } catch (err) { + console.log('Faild to find StartedMainLoopCallback()'); + } + ); +#endif + I_FinishUpdate(); // page flip or blit buffer /* LMFAO this was showing garbage under OpenGL because I_FinishUpdate was called afterward */ /* Smells like a hack... Don't fade Sonic's ass into the title screen. */ + if (gamestate != GS_TITLESCREEN) { - gstartuplumpnum = W_CheckNumForPatchName("STARTUP"); + lumpnum_t gstartuplumpnum = W_CheckNumForPatchName("STARTUP"); if (gstartuplumpnum == LUMPERROR) gstartuplumpnum = W_GetNumForPatchName("MISSING"); V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH)); } - +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(D_RunFrame, 0, 1); +#else for (;;) + { + D_RunFrame(); + } +#endif +} + +static boolean D_LockFrame = false; + +#ifdef __EMSCRIPTEN__ +int EMSCRIPTEN_KEEPALIVE pause_loop(void) +{ + D_LockFrame = true; + emscripten_pause_main_loop(); + return 0; +} + +int EMSCRIPTEN_KEEPALIVE resume_loop(void) +{ + D_LockFrame = false; + emscripten_resume_main_loop(); + return 0; +} +#endif + +static void D_RunFrame(void) +{ + static tic_t entertic = 0, realtics = 0, rendertimeout = INFTICS; + static double deltatics = 0.0; + static double deltasecs = 0.0; + + static boolean interp = false; + static boolean doDisplay = false; + + if (!D_LockFrame) { // capbudget is the minimum precise_t duration of a single loop iteration precise_t capbudget; @@ -920,6 +954,7 @@ void D_SRB2Loop(void) deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision(); deltatics = deltasecs * NEWTICRATE; } + return; } // diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 643e24f5a..d35b647b4 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -1181,10 +1181,8 @@ static void I_RegisterSignals (void) INT32 I_StartupSystem(void) { -#ifdef HAVE_THREADS I_start_threads(); I_AddExitFunc(I_stop_threads); -#endif I_StartupConsole(); I_RegisterSignals(); #ifndef NOMUMBLE diff --git a/src/dedicated/i_threads.c b/src/dedicated/i_threads.c index 55c0a069e..f8d9bc87a 100644 --- a/src/dedicated/i_threads.c +++ b/src/dedicated/i_threads.c @@ -15,7 +15,6 @@ #include "../i_threads.h" #include "../doomdef.h" -#include "../doomtype.h" typedef struct thread_s thread_t; @@ -42,10 +41,11 @@ static void *HandleThread(void *data) return NULL; } -void I_spawn_thread(const char *name, I_thread_fn entry, void *userdata) +int I_spawn_thread(const char *name, I_thread_fn entry, void *userdata) { thread_t *thread; (void)name; + pthread_mutex_lock(&thread_lock); thread = thread_list; while (thread != NULL) @@ -69,6 +69,13 @@ void I_spawn_thread(const char *name, I_thread_fn entry, void *userdata) thread->userdata = userdata; pthread_create(&thread->thread, NULL, HandleThread, thread); pthread_mutex_unlock(&thread_lock); + + return true; +} + +int I_can_thread(void) +{ + return true; } int I_thread_is_stopped(void) diff --git a/src/doomdef.h b/src/doomdef.h index 81ab7bbfb..07973e11e 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -703,7 +703,9 @@ extern int /// This stops the game from storing backups of the states, sprites, and mobjinfo tables. /// Though this info is compressed under normal circumstances, it's still a lot of extra /// memory that never gets touched. +#if !(defined (__EMSCRIPTEN__) && (__SIZEOF_SIZE_T__ == 4)) #define ALLOW_RESETDATA +#endif /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.) //#define REDSANALOG @@ -731,7 +733,7 @@ extern int /// Maintain compatibility with older 2.2 demos #define OLD22DEMOCOMPAT -#ifdef HAVE_CURL +#if defined (HAVE_CURL) && !(defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)) #define MASTERSERVER #else #undef UPDATE_ALERT diff --git a/src/doomtype.h b/src/doomtype.h index 415669ac4..df97398d4 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -110,7 +110,7 @@ int startswith (const char *base, const char *tag); int endswith (const char *base, const char *tag); char *xstrtok(char *line, const char *delims); -#if defined (_WIN32) || defined (__HAIKU__) +#if defined (_WIN32) || defined (__HAIKU__) || defined (__EMSCRIPTEN__) #define HAVE_DOSSTR_FUNCS #endif @@ -156,6 +156,7 @@ typedef int32_t boolean; #endif #ifndef __cplusplus +#ifndef __bool_true_false_are_defined #ifndef _WIN32 enum {false = 0, true = 1}; #else @@ -163,6 +164,7 @@ enum {false = 0, true = 1}; #define true TRUE #endif #endif +#endif /* 7.18.2.1 Limits of exact-width integer types */ @@ -245,6 +247,8 @@ enum {false = 0, true = 1}; #define FUNCNOINLINE __attribute__((noinline)) + #define FUNCWARNRV __attribute__((warn_unused_result)) + #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4 #ifdef __i386__ // i386 only #define FUNCTARGET(X) __attribute__ ((__target__ (X))) @@ -296,6 +300,9 @@ enum {false = 0, true = 1}; #ifndef FUNCTARGET #define FUNCTARGET(x) #endif +#ifndef FUNCWARNRV +#define FUNCWARNRV +#endif #ifndef ATTRPACK #define ATTRPACK #endif diff --git a/src/f_finale.c b/src/f_finale.c index c6d957292..264c18d53 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -919,13 +919,9 @@ void F_IntroTicker(void) I_OsPolling(); I_UpdateNoBlit(); -#ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); -#endif M_Drawer(); // menu is drawn even on top of wipes -#ifdef HAVE_THREADS I_unlock_mutex(m_menu_mutex); -#endif I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001 if (moviemode) // make sure we save frames for the white hold too diff --git a/src/f_wipe.c b/src/f_wipe.c index 1ea32d0eb..dc588c13b 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -601,13 +601,9 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) if (drawMenu) { -#ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); -#endif M_Drawer(); // menu is drawn even on top of wipes -#ifdef HAVE_THREADS I_unlock_mutex(m_menu_mutex); -#endif } I_FinishUpdate(); // page flip or blit buffer diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 02a32957a..1de2f1d62 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -227,7 +227,6 @@ FUNCPRINTF static void GL_MSG_Error(const char *format, ...) /* 1.0 functions */ /* Miscellaneous */ #define pglClearColor glClearColor -//glClear #define pglColorMask glColorMask #define pglAlphaFunc glAlphaFunc #define pglBlendFunc glBlendFunc @@ -237,9 +236,7 @@ FUNCPRINTF static void GL_MSG_Error(const char *format, ...) #define pglEnable glEnable #define pglDisable glDisable #define pglGetFloatv glGetFloatv -//glGetIntegerv -//glGetString -#define pglHint glHint +#define pglPolygonMode glPolygonMode /* Depth Buffer */ #define pglClearDepth glClearDepth @@ -283,6 +280,7 @@ FUNCPRINTF static void GL_MSG_Error(const char *format, ...) /* Texture mapping */ #define pglTexEnvi glTexEnvi #define pglTexParameteri glTexParameteri +#define pglTexImage1D glTexImage1D #define pglTexImage2D glTexImage2D #define pglTexSubImage2D glTexSubImage2D @@ -668,6 +666,7 @@ void SetupGLFunc4(void) { /* 1.2 funcs */ pglTexImage3D = GetGLFunc("glTexImage3D"); + /* 1.3 funcs */ pglActiveTexture = GetGLFunc("glActiveTexture"); pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f"); diff --git a/src/i_threads.h b/src/i_threads.h index fe6ab4fb0..097d1accc 100644 --- a/src/i_threads.h +++ b/src/i_threads.h @@ -9,20 +9,21 @@ /// \file i_threads.h /// \brief Multithreading abstraction -#ifdef HAVE_THREADS - #ifndef I_THREADS_H #define I_THREADS_H +#include "doomtype.h" + typedef void (*I_thread_fn)(void *userdata); typedef void * I_mutex; typedef void * I_cond; +int I_can_thread (void) FUNCWARNRV; void I_start_threads (void); void I_stop_threads (void); -void I_spawn_thread (const char *name, I_thread_fn, void *userdata); +int I_spawn_thread (const char *name, I_thread_fn, void *userdata) FUNCWARNRV; /* check in your thread whether to return early */ int I_thread_is_stopped (void); @@ -36,4 +37,3 @@ void I_wake_one_cond (I_cond *); void I_wake_all_cond (I_cond *); #endif/*I_THREADS_H*/ -#endif/*HAVE_THREADS*/ diff --git a/src/m_menu.c b/src/m_menu.c index be1b421f7..52e119723 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -123,9 +123,7 @@ typedef enum NUM_QUITMESSAGES } text_enum; -#ifdef HAVE_THREADS I_mutex m_menu_mutex; -#endif M_waiting_mode_t m_waiting_mode = M_NOT_WAITING; @@ -3802,29 +3800,32 @@ void M_SetupNextMenu(menu_t *menudef) { INT16 i; -#if defined (MASTERSERVER) && defined (HAVE_THREADS) - if (currentMenu == &MP_RoomDef || currentMenu == &MP_ConnectDef) +#if defined (MASTERSERVER) + if (I_can_thread()) { - I_lock_mutex(&ms_QueryId_mutex); + if (currentMenu == &MP_RoomDef || currentMenu == &MP_ConnectDef) { - ms_QueryId++; - } - I_unlock_mutex(ms_QueryId_mutex); - } - - if (currentMenu == &MP_ConnectDef) - { - I_lock_mutex(&ms_ServerList_mutex); - { - if (ms_ServerList) + I_lock_mutex(&ms_QueryId_mutex); { - free(ms_ServerList); - ms_ServerList = NULL; + ms_QueryId++; } + I_unlock_mutex(ms_QueryId_mutex); + } + + if (currentMenu == &MP_ConnectDef) + { + I_lock_mutex(&ms_ServerList_mutex); + { + if (ms_ServerList) + { + free(ms_ServerList); + ms_ServerList = NULL; + } + } + I_unlock_mutex(ms_ServerList_mutex); } - I_unlock_mutex(ms_ServerList_mutex); } -#endif/*HAVE_THREADS*/ +#endif/*MASTERSERVER*/ if (currentMenu->quitroutine) { @@ -3891,7 +3892,7 @@ void M_Ticker(void) if (currentMenu == &OP_ScreenshotOptionsDef) M_SetupScreenshotMenu(); -#if defined (MASTERSERVER) && defined (HAVE_THREADS) +#if defined (MASTERSERVER) if (!netgame) return; @@ -11378,7 +11379,7 @@ static boolean M_CheckMODVersion(int id) } #endif/*UPDATE_ALERT*/ -#if defined (MASTERSERVER) && defined (HAVE_THREADS) +#if defined (MASTERSERVER) static void Check_new_version_thread (int *id) { @@ -11435,7 +11436,7 @@ Check_new_version_thread (int *id) free(id); } -#endif/*defined (MASTERSERVER) && defined (HAVE_THREADS)*/ +#endif/*defined (MASTERSERVER)*/ static void M_ConnectMenu(INT32 choice) { @@ -11477,7 +11478,7 @@ UINT32 roomIds[NUM_LIST_ROOMS]; static void M_RoomMenu(INT32 choice) { INT32 i; -#if defined (MASTERSERVER) && defined (HAVE_THREADS) +#if defined (MASTERSERVER) int *id; #endif @@ -11500,44 +11501,53 @@ static void M_RoomMenu(INT32 choice) M_SetupNextMenu(&MP_RoomDef); #ifdef MASTERSERVER -#ifdef HAVE_THREADS + if (I_can_thread()) + { #ifdef UPDATE_ALERT - m_waiting_mode = M_WAITING_VERSION; + m_waiting_mode = M_WAITING_VERSION; #else/*UPDATE_ALERT*/ - m_waiting_mode = M_WAITING_ROOMS; + m_waiting_mode = M_WAITING_ROOMS; #endif/*UPDATE_ALERT*/ - MP_RoomMenu[0].text = ""; + MP_RoomMenu[0].text = ""; - id = malloc(sizeof *id); + id = malloc(sizeof *id); - I_lock_mutex(&ms_QueryId_mutex); - { - *id = ms_QueryId; + I_lock_mutex(&ms_QueryId_mutex); + { + *id = ms_QueryId; + } + I_unlock_mutex(ms_QueryId_mutex); + + if(!I_spawn_thread("check-new-version", + (I_thread_fn)Check_new_version_thread, id)) + { + free(id); + } } - I_unlock_mutex(ms_QueryId_mutex); - - I_spawn_thread("check-new-version", - (I_thread_fn)Check_new_version_thread, id); -#else/*HAVE_THREADS*/ + else + { #ifdef UPDATE_ALERT - if (M_CheckMODVersion(0)) + if (M_CheckMODVersion(0)) #endif/*UPDATE_ALERT*/ - { - GetRoomsList(currentMenu->prevMenu == &MP_ServerDef, 0); + { + GetRoomsList(currentMenu->prevMenu == &MP_ServerDef, 0); + } } -#endif/*HAVE_THREADS*/ #endif/*MASTERSERVER*/ } static void M_ChooseRoom(INT32 choice) { -#if defined (MASTERSERVER) && defined (HAVE_THREADS) - I_lock_mutex(&ms_QueryId_mutex); +#if defined (MASTERSERVER) + if (I_can_thread()) { - ms_QueryId++; + I_lock_mutex(&ms_QueryId_mutex); + { + ms_QueryId++; + } + I_unlock_mutex(ms_QueryId_mutex); } - I_unlock_mutex(ms_QueryId_mutex); #endif if (choice == 0) diff --git a/src/m_menu.h b/src/m_menu.h index dc8bef8b1..ecfe182d3 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -352,9 +352,7 @@ void M_ClearMenus(boolean callexitmenufunc); // Maybe this goes here????? Who knows. boolean M_MouseNeeded(void); -#ifdef HAVE_THREADS extern I_mutex m_menu_mutex; -#endif extern menu_t *currentMenu; diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c index c740d53a6..c7749d0f0 100644 --- a/src/netcode/client_connection.c +++ b/src/netcode/client_connection.c @@ -392,7 +392,7 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node) M_SortServerList(); } -#if defined (MASTERSERVER) && defined (HAVE_THREADS) +#if defined (MASTERSERVER) struct Fetch_servers_ctx { int room; @@ -437,7 +437,7 @@ Fetch_servers_thread (struct Fetch_servers_ctx *ctx) free(ctx); } -#endif // defined (MASTERSERVER) && defined (HAVE_THREADS) +#endif // defined (MASTERSERVER) void CL_QueryServerList (msg_server_t *server_list) { @@ -493,34 +493,41 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) #ifdef MASTERSERVER if (internetsearch) { -#ifdef HAVE_THREADS - struct Fetch_servers_ctx *ctx; - - ctx = malloc(sizeof *ctx); - - // This called from M_Refresh so I don't use a mutex - m_waiting_mode = M_WAITING_SERVERS; - - I_lock_mutex(&ms_QueryId_mutex); + if (I_can_thread()) { - ctx->id = ms_QueryId; + struct Fetch_servers_ctx *ctx; + + ctx = malloc(sizeof *ctx); + + // This called from M_Refresh so I don't use a mutex + m_waiting_mode = M_WAITING_SERVERS; + + I_lock_mutex(&ms_QueryId_mutex); + { + ctx->id = ms_QueryId; + } + I_unlock_mutex(ms_QueryId_mutex); + + ctx->room = room; + + if (!I_spawn_thread("fetch-servers", (I_thread_fn)Fetch_servers_thread, ctx)) + { + free(ctx); + } } - I_unlock_mutex(ms_QueryId_mutex); - - ctx->room = room; - - I_spawn_thread("fetch-servers", (I_thread_fn)Fetch_servers_thread, ctx); -#else - msg_server_t *server_list; - - server_list = GetShortServersList(room, 0); - - if (server_list) + else { - CL_QueryServerList(server_list); - free(server_list); + msg_server_t *server_list; + + server_list = GetShortServersList(room, 0); + + if (server_list) + { + CL_QueryServerList(server_list); + free(server_list); + } } -#endif + } #endif // MASTERSERVER } @@ -1187,13 +1194,9 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic F_TitleScreenDrawer(); } CL_DrawConnectionStatus(); -#ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); -#endif M_Drawer(); //Needed for drawing messageboxes on the connection screen -#ifdef HAVE_THREADS I_unlock_mutex(m_menu_mutex); -#endif I_UpdateNoVsync(); // page flip or blit buffer if (moviemode) M_SaveFrame(); diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 6702e2591..7c469699d 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1645,13 +1645,9 @@ void NetUpdate(void) if (nowtime != resptime) { resptime = nowtime; -#ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); -#endif M_Ticker(); -#ifdef HAVE_THREADS I_unlock_mutex(m_menu_mutex); -#endif CON_Ticker(); } diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index bfb67838f..27c924dd8 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -112,6 +112,7 @@ static pauseddownload_t *pauseddownload = NULL; file_download_t filedownload; static CURL *http_handle; +static char curl_errbuf[CURL_ERROR_SIZE]; static CURLM *multi_handle; static UINT32 curl_dlnow; static UINT32 curl_dltotal; @@ -1604,6 +1605,10 @@ static int curlprogress_callback(void *clientp, curl_off_t dltotal, curl_off_t d boolean CURLPrepareFile(const char* url, int dfilenum) { HTTP_login *login; + CURLcode cc; + + if (!I_can_thread()) + return false; #ifdef PARANOIA if (M_CheckParm("-nodownload")) @@ -1612,13 +1617,32 @@ boolean CURLPrepareFile(const char* url, int dfilenum) if (!multi_handle) { - curl_global_init(CURL_GLOBAL_ALL); - multi_handle = curl_multi_init(); + cc = curl_global_init(CURL_GLOBAL_ALL); + if (cc < 0) + { + I_OutputMsg("libcurl: curl_global_init() returned %d\n", cc); + } + else + { + multi_handle = curl_multi_init(); + } + if (!multi_handle) + { + I_OutputMsg("libcurl: curl_multi_init() failed\n"); + curl_global_cleanup(); + return false; + } } http_handle = curl_easy_init(); - if (http_handle && multi_handle) + if (http_handle) { + CURLMcode mc; + + cc = curl_easy_setopt(http_handle, CURLOPT_ERRORBUFFER, curl_errbuf); + if (cc != CURLE_OK) I_OutputMsg("libcurl: CURLOPT_ERRORBUFFER failed\n"); + curl_errbuf[0] = 0x00; + I_mkdir(downloaddir, 0755); curl_curfile = &fileneeded[dfilenum]; @@ -1632,50 +1656,76 @@ boolean CURLPrepareFile(const char* url, int dfilenum) for (INT32 j = 0; j < 16; j++) sprintf(&md5tmp[j*2], "%02x", curl_curfile->md5sum[j]); - curl_easy_setopt(http_handle, CURLOPT_URL, va("%s/%s?md5=%s", url, curl_realname, md5tmp)); + cc = curl_easy_setopt(http_handle, CURLOPT_URL, va("%s/%s?md5=%s", url, curl_realname, md5tmp)); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); // Only allow HTTP and HTTPS #if (LIBCURL_VERSION_MAJOR <= 7) && (LIBCURL_VERSION_MINOR < 85) - curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); + cc = curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); #else - curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS_STR, "http,https"); + cc = curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS_STR, "http,https"); #endif + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); // Set user agent, as some servers won't accept invalid user agents. - curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("Sonic Robo Blast 2/%s", VERSIONSTRING)); + cc = curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("Sonic Robo Blast 2/%s", VERSIONSTRING)); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); // Authenticate if the user so wishes login = CURLGetLogin(url, NULL); if (login) { - curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + cc = curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); } // Follow a redirect request, if sent by the server. - curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); + cc = curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); - curl_easy_setopt(http_handle, CURLOPT_FAILONERROR, 1L); + cc = curl_easy_setopt(http_handle, CURLOPT_FAILONERROR, 1L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); CONS_Printf("Downloading addon \"%s\" from %s\n", curl_realname, url); strcatbf(curl_curfile->filename, downloaddir, "/"); curl_curfile->file = fopen(curl_curfile->filename, "wb"); - curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, curl_curfile->file); - curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, curlwrite_data); - curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0L); - curl_easy_setopt(http_handle, CURLOPT_XFERINFOFUNCTION, curlprogress_callback); + + cc = curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, curl_curfile->file); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); + + cc = curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, curlwrite_data); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); + + cc = curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); + + cc = curl_easy_setopt(http_handle, CURLOPT_XFERINFOFUNCTION, curlprogress_callback); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); curl_curfile->status = FS_DOWNLOADING; - curl_multi_add_handle(multi_handle, http_handle); - curl_multi_perform(multi_handle, &curl_runninghandles); + mc = curl_multi_add_handle(multi_handle, http_handle); + if (mc != CURLM_OK) I_OutputMsg("libcurl: %s\n", curl_multi_strerror(mc)); + + mc = curl_multi_perform(multi_handle, &curl_runninghandles); + if (mc != CURLM_OK) I_OutputMsg("libcurl: %s\n", curl_multi_strerror(mc)); + curl_starttime = time(NULL); filedownload.current = dfilenum; filedownload.http_running = true; - I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL); + if (!I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL)) + { + mc = curl_multi_cleanup(multi_handle); + if (mc != CURLM_OK) I_OutputMsg("libcurl: %s\n", curl_multi_strerror(mc)); + curl_global_cleanup(); + multi_handle = NULL; + filedownload.http_running = false; + return false; + } return true; } @@ -1709,14 +1759,15 @@ void CURLGetFile(void) { if (curl_runninghandles) { - curl_multi_perform(multi_handle, &curl_runninghandles); + mc = curl_multi_perform(multi_handle, &curl_runninghandles); + if (mc != CURLM_OK) I_OutputMsg("libcurl: %s\n", curl_multi_strerror(mc)); /* wait for activity, timeout or "nothing" */ mc = curl_multi_wait(multi_handle, NULL, 0, 1000, NULL); if (mc != CURLM_OK) { - CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc); + CONS_Alert(CONS_WARNING, "curl_multi_wait() failed: %s.\n", curl_multi_strerror(mc)); continue; } curl_curfile->currentsize = curl_dlnow; @@ -1740,7 +1791,10 @@ void CURLGetFile(void) long response_code = 0; if (easyres == CURLE_HTTP_RETURNED_ERROR) - curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code); + { + CURLcode cc = curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", curl_errbuf); + } if (response_code == 404) curl_curfile->failed = FDOWNLOAD_FAIL_NOTFOUND; @@ -1781,7 +1835,8 @@ void CURLGetFile(void) curl_curfile->file = NULL; filedownload.remaining--; - curl_multi_remove_handle(multi_handle, e); + mc = curl_multi_remove_handle(multi_handle, e); + if (mc != CURLM_OK) I_OutputMsg("libcurl: %s\n", curl_multi_strerror(mc)); curl_easy_cleanup(e); if (!filedownload.remaining) @@ -1792,7 +1847,8 @@ void CURLGetFile(void) if (!filedownload.remaining || !filedownload.http_running) { - curl_multi_cleanup(multi_handle); + mc = curl_multi_cleanup(multi_handle); + if (mc != CURLM_OK) I_OutputMsg("libcurl: %s\n", curl_multi_strerror(mc)); curl_global_cleanup(); multi_handle = NULL; } diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index 0fe1e9934..1623e1dec 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -70,9 +70,7 @@ static boolean hms_allow_ipv6; static boolean hms_allow_ipv4; static char *hms_api; -#ifdef HAVE_THREADS static I_mutex hms_api_mutex; -#endif static char *hms_server_token; #ifndef NO_IPV6 @@ -86,7 +84,8 @@ struct HMS_buffer CURL *curl; char *buffer; int needle; - int end; + int end; + char *errbuf; }; static void @@ -160,6 +159,7 @@ HMS_connect (int proto, const char *format, ...) size_t seek; size_t token_length; struct HMS_buffer *buffer; + CURLcode cc; #ifdef NO_IPV6 if (proto == PROTO_V6) @@ -183,7 +183,7 @@ HMS_connect (int proto, const char *format, ...) curl = curl_easy_init(); - if (! curl) + if (!curl) { Contact_error(); Blame("From curl_easy_init.\n"); @@ -201,9 +201,7 @@ HMS_connect (int proto, const char *format, ...) token_length = 0; } -#ifdef HAVE_THREADS I_lock_mutex(&hms_api_mutex); -#endif init_user_agent_once(); @@ -215,9 +213,7 @@ HMS_connect (int proto, const char *format, ...) sprintf(url, "%s/", hms_api); -#ifdef HAVE_THREADS I_unlock_mutex(hms_api_mutex); -#endif va_start (ap, format); seek += vsprintf(&url[seek], format, ap); @@ -233,40 +229,65 @@ HMS_connect (int proto, const char *format, ...) buffer->end = DEFAULT_BUFFER_SIZE; buffer->buffer = malloc(buffer->end); buffer->needle = 0; + buffer->errbuf = malloc(CURL_ERROR_SIZE); + buffer->errbuf[0] = 0x00; + + cc = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer->errbuf); if (cv_masterserver_debug.value) { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(curl, CURLOPT_STDERR, logstream); + cc = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + + cc = curl_easy_setopt(curl, CURLOPT_STDERR, logstream); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); } - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + cc = curl_easy_setopt(curl, CURLOPT_URL, url); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + + cc = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); #ifndef NO_IPV6 if (proto == PROTO_V6 || (proto == PROTO_ANY && !hms_allow_ipv4)) { - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); + cc = curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + if (M_CheckParm("-bindaddr6") && M_IsNextParm()) { - curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + cc = curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); } } if (proto == PROTO_V4 || (proto == PROTO_ANY && !hms_allow_ipv6)) #endif { - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + cc = curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + if (M_CheckParm("-bindaddr") && M_IsNextParm()) { - curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + cc = curl_easy_setopt(curl, CURLOPT_INTERFACE, M_GetNextParm()); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); } } - curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer); + cc = curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); - curl_easy_setopt(curl, CURLOPT_USERAGENT, hms_useragent); + cc = curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 30L); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + + cc = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + + cc = curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); + + cc = curl_easy_setopt(curl, CURLOPT_USERAGENT, hms_useragent); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); curl_free(quack_token); free(url); @@ -288,15 +309,15 @@ HMS_do (struct HMS_buffer *buffer) { Contact_error(); Blame( - "From curl_easy_perform: %s\n", - curl_easy_strerror(cc) + "From curl_easy_perform: %s\n", buffer->errbuf ); return 0; } buffer->buffer[buffer->needle] = '\0'; - curl_easy_getinfo(buffer->curl, CURLINFO_RESPONSE_CODE, &status); + cc = curl_easy_getinfo(buffer->curl, CURLINFO_RESPONSE_CODE, &status); + if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf); if (status != 200) { @@ -379,7 +400,6 @@ HMS_fetch_rooms (int joining, int query_id) */ if (joining || id_no != 0) { -#ifdef HAVE_THREADS I_lock_mutex(&ms_QueryId_mutex); { if (query_id != ms_QueryId) @@ -389,7 +409,6 @@ HMS_fetch_rooms (int joining, int query_id) if (! doing_shit) break; -#endif room_list[i].header.buffer[0] = 1; @@ -413,9 +432,7 @@ HMS_fetch_rooms (int joining, int query_id) if (doing_shit) { -#ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); -#endif { for (i = 0; room_list[i].header.buffer[0]; i++) { @@ -427,9 +444,7 @@ HMS_fetch_rooms (int joining, int query_id) } } } -#ifdef HAVE_THREADS I_unlock_mutex(m_menu_mutex); -#endif } } else @@ -710,7 +725,6 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id) if (address && port && title && version) { -#ifdef HAVE_THREADS I_lock_mutex(&ms_QueryId_mutex); { if (query_id != ms_QueryId) @@ -720,7 +734,6 @@ HMS_fetch_servers (msg_server_t *list, int room_number, int query_id) if (! doing_shit) break; -#endif if (strcmp(version, local_version) == 0) { @@ -809,16 +822,12 @@ HMS_compare_mod_version (char *buffer, size_t buffer_size) void HMS_set_api (char *api) { -#ifdef HAVE_THREADS I_lock_mutex(&hms_api_mutex); -#endif { free(hms_api); hms_api = api; } -#ifdef HAVE_THREADS I_unlock_mutex(hms_api_mutex); -#endif } #endif/*MASTERSERVER*/ diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index f56c37d8a..bc8a5d1c4 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -274,9 +274,18 @@ static void init_upnpc_once(struct upnpdata *upnpdata); static void I_InitUPnP(void) { + if (!I_can_thread()) + { + UPNP_support = false; + return; + } upnpuser = malloc(sizeof *upnpuser); upnpuser->upnpc_started = 0; - I_spawn_thread("init_upnpc_once", (I_thread_fn)init_upnpc_once, upnpuser); + if (!I_spawn_thread("init_upnpc_once", (I_thread_fn)init_upnpc_once, upnpuser)) + { + UPNP_support = false; + free(upnpuser); + } } static void @@ -1113,6 +1122,12 @@ static boolean UDP_Socket(void) boolean I_InitTcpDriver(void) { boolean tcp_was_up = init_tcp_driver; + +#ifdef __EMSCRIPTEN__ + I_OutputMsg("Compiled without networking support\n"); + return false; +#endif + if (!init_tcp_driver) { #ifdef USE_WINSOCK diff --git a/src/netcode/mserv.c b/src/netcode/mserv.c index f17db4b6e..848bfad3a 100644 --- a/src/netcode/mserv.c +++ b/src/netcode/mserv.c @@ -35,16 +35,11 @@ static boolean MSUpdateAgain; static time_t MSLastPing; -#ifdef HAVE_THREADS static I_mutex MSMutex; static I_cond MSCond; # define Lock_state() I_lock_mutex (&MSMutex) # define Unlock_state() I_unlock_mutex (MSMutex) -#else/*HAVE_THREADS*/ -# define Lock_state() -# define Unlock_state() -#endif/*HAVE_THREADS*/ static void Command_Listserv_f(void); @@ -72,13 +67,11 @@ consvar_t cv_masterserver_room_id = CVAR_INIT ("masterserver_room_id", "-1", CV_ static INT16 ms_RoomId = -1; -#if defined (MASTERSERVER) && defined (HAVE_THREADS) int ms_QueryId; I_mutex ms_QueryId_mutex; msg_server_t *ms_ServerList; I_mutex ms_ServerList_mutex; -#endif UINT16 current_port = 0; @@ -110,13 +103,9 @@ void AddMServCommands(void) static void WarnGUI (void) { -#ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); -#endif M_StartMessage(M_GetText("There was a problem connecting to\nthe Master Server\n\nCheck the console for details.\n"), NULL, MM_NOTHING); -#ifdef HAVE_THREADS I_unlock_mutex(m_menu_mutex); -#endif } #define NUM_LIST_SERVER MAXSERVERLIST @@ -160,14 +149,12 @@ char *GetMODVersion(int id) c = HMS_compare_mod_version(buffer, 16); -#ifdef HAVE_THREADS I_lock_mutex(&ms_QueryId_mutex); { if (id != ms_QueryId) c = -1; } I_unlock_mutex(ms_QueryId_mutex); -#endif if (c > 0) return buffer; @@ -294,9 +281,7 @@ Finish_unlist (void) } Unlock_state(); -#ifdef HAVE_THREADS I_wake_all_cond(&MSCond); -#endif } Lock_state(); @@ -307,7 +292,6 @@ Finish_unlist (void) Unlock_state(); } -#ifdef HAVE_THREADS static int * Server_id (void) { @@ -402,53 +386,67 @@ Change_masterserver_thread (char *api) HMS_set_api(api); } -#endif/*HAVE_THREADS*/ void RegisterServer(void) { -#ifdef MASTERSERVER -#ifdef HAVE_THREADS - I_spawn_thread( - "register-server", - (I_thread_fn)Register_server_thread, - New_server_id() - ); -#else - Finish_registration(); -#endif -#endif/*MASTERSERVER*/ + if (I_can_thread()) + { + void *nsid = New_server_id(); + if (!I_spawn_thread( + "register-server", + (I_thread_fn)Register_server_thread, + nsid + )) + { + free(nsid); + } + } + else + { + Finish_registration(); + } } static void UpdateServer(void) { -#ifdef HAVE_THREADS - I_spawn_thread( - "update-server", - (I_thread_fn)Update_server_thread, - Server_id() - ); -#else - Finish_update(); -#endif + if (I_can_thread()) + { + void *sid = Server_id(); + if (!I_spawn_thread( + "update-server", + (I_thread_fn)Update_server_thread, + sid + )) + { + free(sid); + } + } + else + { + Finish_update(); + } } void UnregisterServer(void) { -#ifdef MASTERSERVER -#ifdef HAVE_THREADS - I_spawn_thread( - "unlist-server", - (I_thread_fn)Unlist_server_thread, - Server_id() - ); -#else - Finish_unlist(); -#endif -#endif/*MASTERSERVER*/ + if (I_can_thread()) + { + if (!I_spawn_thread( + "unlist-server", + (I_thread_fn)Unlist_server_thread, + Server_id() + )) + { + ; + } + } + else + { + Finish_unlist(); + } } -static boolean -Online (void) +static boolean Online(void) { return ( serverrunning && cv_masterserver_room_id.value > 0 ); } @@ -482,26 +480,35 @@ static inline void SendPingToMasterServer(void) void MasterClient_Ticker(void) { -#ifdef MASTERSERVER SendPingToMasterServer(); -#endif } static void Set_api (const char *api) { -#ifdef HAVE_THREADS - I_spawn_thread( - "change-masterserver", - (I_thread_fn)Change_masterserver_thread, - strdup(api) - ); -#else - HMS_set_api(strdup(api)); -#endif + char *dapi = strdup(api); + if (I_can_thread()) + { + if (!I_spawn_thread( + "change-masterserver", + (I_thread_fn)Change_masterserver_thread, + dapi + )) + { + free(dapi); + } + } + else + { + HMS_set_api(dapi); + } } +#else /*MASTERSERVER*/ -#endif/*MASTERSERVER*/ +void RegisterServer(void) {} +void UnregisterServer(void) {} + +#endif static boolean ServerName_CanChange(const char* newvalue) { @@ -544,7 +551,9 @@ static void RoomId_OnChange(void) { UnregisterServer(); ms_RoomId = cv_masterserver_room_id.value; +#ifdef MASTERSERVER if (Online()) +#endif RegisterServer(); } } diff --git a/src/netcode/mserv.h b/src/netcode/mserv.h index ed3c9b27b..8065bdc4e 100644 --- a/src/netcode/mserv.h +++ b/src/netcode/mserv.h @@ -71,13 +71,11 @@ extern consvar_t cv_masterserver_timeout; extern consvar_t cv_masterserver_debug; extern consvar_t cv_masterserver_token; -#ifdef HAVE_THREADS extern int ms_QueryId; extern I_mutex ms_QueryId_mutex; extern msg_server_t *ms_ServerList; extern I_mutex ms_ServerList_mutex; -#endif void RegisterServer(void); void UnregisterServer(void); diff --git a/src/p_saveg.c b/src/p_saveg.c index 650622f59..c33cc0f82 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -302,7 +302,7 @@ typedef enum DRONE = 0x80, } player_saveflags; -static inline void P_ArchivePlayer(save_t *save_p) +FUNCINLINE static ATTRINLINE void P_ArchivePlayer(save_t *save_p) { const player_t *player = &players[consoleplayer]; SINT8 pllives = player->lives; @@ -334,7 +334,7 @@ static inline void P_ArchivePlayer(save_t *save_p) P_WriteINT32(save_p, player->continues); } -static inline void P_UnArchivePlayer(save_t *save_p) +FUNCINLINE static ATTRINLINE void P_UnArchivePlayer(save_t *save_p) { #ifdef NEWSKINSAVES INT16 backwardsCompat = P_ReadUINT16(save_p); @@ -2088,7 +2088,7 @@ typedef enum tc_end } specials_e; -static inline UINT32 SaveMobjnum(const mobj_t *mobj) +FUNCINLINE static ATTRINLINE UINT32 SaveMobjnum(const mobj_t *mobj) { if (mobj) return mobj->mobjnum; return 0; @@ -2106,7 +2106,7 @@ static UINT32 SaveLine(const line_t *line) return 0xFFFFFFFF; } -static inline UINT32 SavePlayer(const player_t *player) +FUNCINLINE static ATTRINLINE UINT32 SavePlayer(const player_t *player) { if (player) return (UINT32)(player - players); return 0xFFFFFFFF; @@ -2646,7 +2646,7 @@ static void SaveGlowThinker(save_t *save_p, const thinker_t *th, const UINT8 typ P_WriteINT16(save_p, ht->speed); } -static inline void SaveFireflickerThinker(save_t *save_p, const thinker_t *th, const UINT8 type) +FUNCINLINE static ATTRINLINE void SaveFireflickerThinker(save_t *save_p, const thinker_t *th, const UINT8 type) { const fireflicker_t *ht = (const void *)th; P_WriteUINT8(save_p, type); @@ -2696,7 +2696,7 @@ static void SaveCrumbleThinker(save_t *save_p, const thinker_t *th, const UINT8 P_WriteUINT8(save_p, ht->flags); } -static inline void SaveScrollThinker(save_t *save_p, const thinker_t *th, const UINT8 type) +FUNCINLINE static ATTRINLINE void SaveScrollThinker(save_t *save_p, const thinker_t *th, const UINT8 type) { const scroll_t *ht = (const void *)th; P_WriteUINT8(save_p, type); @@ -2712,7 +2712,7 @@ static inline void SaveScrollThinker(save_t *save_p, const thinker_t *th, const P_WriteUINT8(save_p, ht->type); } -static inline void SaveFrictionThinker(save_t *save_p, const thinker_t *th, const UINT8 type) +FUNCINLINE static ATTRINLINE void SaveFrictionThinker(save_t *save_p, const thinker_t *th, const UINT8 type) { const friction_t *ht = (const void *)th; P_WriteUINT8(save_p, type); @@ -2723,7 +2723,7 @@ static inline void SaveFrictionThinker(save_t *save_p, const thinker_t *th, cons P_WriteUINT8(save_p, ht->roverfriction); } -static inline void SavePusherThinker(save_t *save_p, const thinker_t *th, const UINT8 type) +FUNCINLINE static ATTRINLINE void SavePusherThinker(save_t *save_p, const thinker_t *th, const UINT8 type) { const pusher_t *ht = (const void *)th; P_WriteUINT8(save_p, type); @@ -2828,7 +2828,7 @@ static void SavePlaneDisplaceThinker(save_t *save_p, const thinker_t *th, const P_WriteUINT8(save_p, ht->type); } -static inline void SaveDynamicLineSlopeThinker(save_t *save_p, const thinker_t *th, const UINT8 type) +FUNCINLINE static ATTRINLINE void SaveDynamicLineSlopeThinker(save_t *save_p, const thinker_t *th, const UINT8 type) { const dynlineplanethink_t* ht = (const void*)th; @@ -2839,7 +2839,7 @@ static inline void SaveDynamicLineSlopeThinker(save_t *save_p, const thinker_t * P_WriteFixed(save_p, ht->extent); } -static inline void SaveDynamicVertexSlopeThinker(save_t *save_p, const thinker_t *th, const UINT8 type) +FUNCINLINE static ATTRINLINE void SaveDynamicVertexSlopeThinker(save_t *save_p, const thinker_t *th, const UINT8 type) { size_t i; const dynvertexplanethink_t* ht = (const void*)th; @@ -2854,7 +2854,7 @@ static inline void SaveDynamicVertexSlopeThinker(save_t *save_p, const thinker_t P_WriteUINT8(save_p, ht->relative); } -static inline void SavePolyrotatetThinker(save_t *save_p, const thinker_t *th, const UINT8 type) +FUNCINLINE static ATTRINLINE void SavePolyrotatetThinker(save_t *save_p, const thinker_t *th, const UINT8 type) { const polyrotate_t *ht = (const void *)th; P_WriteUINT8(save_p, type); @@ -3219,7 +3219,7 @@ mobj_t *P_FindNewPosition(UINT32 oldposition) return NULL; } -static inline mobj_t *LoadMobj(UINT32 mobjnum) +FUNCINLINE static ATTRINLINE mobj_t *LoadMobj(UINT32 mobjnum) { if (mobjnum == 0) return NULL; return (mobj_t *)(size_t)mobjnum; @@ -3237,13 +3237,13 @@ static line_t *LoadLine(UINT32 line) return &lines[line]; } -static inline player_t *LoadPlayer(UINT32 player) +FUNCINLINE static ATTRINLINE player_t *LoadPlayer(UINT32 player) { if (player >= MAXPLAYERS) return NULL; return &players[player]; } -static inline pslope_t *LoadSlope(UINT32 slopeid) +FUNCINLINE static ATTRINLINE pslope_t* LoadSlope(UINT32 slopeid) { pslope_t *p = slopelist; if (slopeid > slopecount) return NULL; @@ -3887,7 +3887,7 @@ static thinker_t* LoadScrollThinker(save_t *save_p, actionf_p1 thinker) return &ht->thinker; } -static inline thinker_t* LoadFrictionThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadFrictionThinker(save_t *save_p, actionf_p1 thinker) { friction_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3915,7 +3915,7 @@ static thinker_t* LoadPusherThinker(save_t *save_p, actionf_p1 thinker) return &ht->thinker; } -static inline thinker_t* LoadLaserThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadLaserThinker(save_t *save_p, actionf_p1 thinker) { laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3925,7 +3925,7 @@ static inline thinker_t* LoadLaserThinker(save_t *save_p, actionf_p1 thinker) return &ht->thinker; } -static inline thinker_t* LoadLightlevelThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadLightlevelThinker(save_t *save_p, actionf_p1 thinker) { lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3940,7 +3940,7 @@ static inline thinker_t* LoadLightlevelThinker(save_t *save_p, actionf_p1 thinke return &ht->thinker; } -static inline thinker_t* LoadExecutorThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadExecutorThinker(save_t *save_p, actionf_p1 thinker) { executor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3951,7 +3951,7 @@ static inline thinker_t* LoadExecutorThinker(save_t *save_p, actionf_p1 thinker) return &ht->thinker; } -static inline thinker_t* LoadDisappearThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadDisappearThinker(save_t *save_p, actionf_p1 thinker) { disappear_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3965,7 +3965,7 @@ static inline thinker_t* LoadDisappearThinker(save_t *save_p, actionf_p1 thinker return &ht->thinker; } -static inline thinker_t* LoadFadeThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadFadeThinker(save_t *save_p, actionf_p1 thinker) { sector_t *ss; fade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -4007,7 +4007,7 @@ static inline thinker_t* LoadFadeThinker(save_t *save_p, actionf_p1 thinker) return &ht->thinker; } -static inline thinker_t* LoadFadeColormapThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadFadeColormapThinker(save_t *save_p, actionf_p1 thinker) { fadecolormap_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -4022,7 +4022,7 @@ static inline thinker_t* LoadFadeColormapThinker(save_t *save_p, actionf_p1 thin return &ht->thinker; } -static inline thinker_t* LoadPlaneDisplaceThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadPlaneDisplaceThinker(save_t *save_p, actionf_p1 thinker) { planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -4035,7 +4035,7 @@ static inline thinker_t* LoadPlaneDisplaceThinker(save_t *save_p, actionf_p1 thi return &ht->thinker; } -static inline thinker_t* LoadDynamicLineSlopeThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadDynamicLineSlopeThinker(save_t *save_p, actionf_p1 thinker) { dynlineplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -4047,7 +4047,7 @@ static inline thinker_t* LoadDynamicLineSlopeThinker(save_t *save_p, actionf_p1 return &ht->thinker; } -static inline thinker_t* LoadDynamicVertexSlopeThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadDynamicVertexSlopeThinker(save_t *save_p, actionf_p1 thinker) { size_t i; dynvertexplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); @@ -4063,7 +4063,7 @@ static inline thinker_t* LoadDynamicVertexSlopeThinker(save_t *save_p, actionf_p return &ht->thinker; } -static inline thinker_t* LoadPolyrotatetThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadPolyrotatetThinker(save_t *save_p, actionf_p1 thinker) { polyrotate_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -4087,7 +4087,7 @@ static thinker_t* LoadPolymoveThinker(save_t *save_p, actionf_p1 thinker) return &ht->thinker; } -static inline thinker_t* LoadPolywaypointThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadPolywaypointThinker(save_t *save_p, actionf_p1 thinker) { polywaypoint_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -4102,7 +4102,7 @@ static inline thinker_t* LoadPolywaypointThinker(save_t *save_p, actionf_p1 thin return &ht->thinker; } -static inline thinker_t* LoadPolyslidedoorThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadPolyslidedoorThinker(save_t *save_p, actionf_p1 thinker) { polyslidedoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -4122,7 +4122,7 @@ static inline thinker_t* LoadPolyslidedoorThinker(save_t *save_p, actionf_p1 thi return &ht->thinker; } -static inline thinker_t* LoadPolyswingdoorThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadPolyswingdoorThinker(save_t *save_p, actionf_p1 thinker) { polyswingdoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -4137,7 +4137,7 @@ static inline thinker_t* LoadPolyswingdoorThinker(save_t *save_p, actionf_p1 thi return &ht->thinker; } -static inline thinker_t* LoadPolydisplaceThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadPolydisplaceThinker(save_t *save_p, actionf_p1 thinker) { polydisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -4149,7 +4149,7 @@ static inline thinker_t* LoadPolydisplaceThinker(save_t *save_p, actionf_p1 thin return &ht->thinker; } -static inline thinker_t* LoadPolyrotdisplaceThinker(save_t *save_p, actionf_p1 thinker) +FUNCINLINE static ATTRINLINE thinker_t *LoadPolyrotdisplaceThinker(save_t *save_p, actionf_p1 thinker) { polyrotdisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -4432,7 +4432,7 @@ static void P_NetUnArchiveThinkers(save_t *save_p) #define PD_FLAGS 0x01 #define PD_TRANS 0x02 -static inline void P_ArchivePolyObj(save_t *save_p, polyobj_t *po) +FUNCINLINE static ATTRINLINE void P_ArchivePolyObj(save_t *save_p, polyobj_t *po) { UINT8 diff = 0; P_WriteINT32(save_p, po->id); @@ -4454,7 +4454,7 @@ static inline void P_ArchivePolyObj(save_t *save_p, polyobj_t *po) P_WriteINT32(save_p, po->translucency); } -static inline void P_UnArchivePolyObj(save_t *save_p, polyobj_t *po) +FUNCINLINE static ATTRINLINE void P_UnArchivePolyObj(save_t *save_p, polyobj_t *po) { INT32 id; UINT32 angle; @@ -4489,7 +4489,7 @@ static inline void P_UnArchivePolyObj(save_t *save_p, polyobj_t *po) Polyobj_MoveOnLoad(po, angle, x, y); } -static inline void P_ArchivePolyObjects(save_t *save_p) +FUNCINLINE static ATTRINLINE void P_ArchivePolyObjects(save_t *save_p) { INT32 i; @@ -4502,7 +4502,7 @@ static inline void P_ArchivePolyObjects(save_t *save_p) P_ArchivePolyObj(save_p, &PolyObjects[i]); } -static inline void P_UnArchivePolyObjects(save_t *save_p) +FUNCINLINE static ATTRINLINE void P_UnArchivePolyObjects(save_t *save_p) { INT32 i, numSavedPolys; @@ -4518,7 +4518,7 @@ static inline void P_UnArchivePolyObjects(save_t *save_p) P_UnArchivePolyObj(save_p, &PolyObjects[i]); } -static inline void P_FinishMobjs(void) +FUNCINLINE static ATTRINLINE void P_FinishMobjs(void) { thinker_t *currentthinker; mobj_t *mobj; @@ -4633,7 +4633,7 @@ static void P_RelinkPointers(void) } } -static inline void P_NetArchiveSpecials(save_t *save_p) +FUNCINLINE static ATTRINLINE void P_NetArchiveSpecials(save_t *save_p) { size_t i, z; @@ -4719,7 +4719,7 @@ static void P_NetUnArchiveSpecials(save_t *save_p) // ======================================================================= // Misc // ======================================================================= -static inline void P_ArchiveMisc(save_t *save_p, INT16 mapnum) +FUNCINLINE static ATTRINLINE void P_ArchiveMisc(save_t *save_p, INT16 mapnum) { //lastmapsaved = mapnum; lastmaploaded = mapnum; @@ -4732,7 +4732,7 @@ static inline void P_ArchiveMisc(save_t *save_p, INT16 mapnum) P_WriteStringN(save_p, timeattackfolder, sizeof(timeattackfolder)); } -static inline void P_UnArchiveSPGame(save_t *save_p, INT16 mapoverride) +FUNCINLINE static ATTRINLINE void P_UnArchiveSPGame(save_t *save_p, INT16 mapoverride) { char testname[sizeof(timeattackfolder)]; @@ -4862,7 +4862,7 @@ static void P_NetArchiveMisc(save_t *save_p, boolean resending) } } -static inline boolean P_NetUnArchiveMisc(save_t *save_p, boolean reloading) +FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(save_t *save_p, boolean reloading) { INT32 i; @@ -4966,7 +4966,7 @@ static inline boolean P_NetUnArchiveMisc(save_t *save_p, boolean reloading) return true; } -static inline void P_NetArchiveEmblems(save_t *save_p) +FUNCINLINE static ATTRINLINE void P_NetArchiveEmblems(save_t *save_p) { gamedata_t *data = serverGamedata; INT32 i, j; @@ -5087,7 +5087,7 @@ static inline void P_NetArchiveEmblems(save_t *save_p) } } -static inline void P_NetUnArchiveEmblems(save_t *save_p) +FUNCINLINE static ATTRINLINE void P_NetUnArchiveEmblems(save_t *save_p) { gamedata_t *data = serverGamedata; INT32 i, j; @@ -5307,7 +5307,7 @@ static void P_NetUnArchiveSectorPortals(save_t *save_p) } } -static inline void P_ArchiveLuabanksAndConsistency(save_t *save_p) +FUNCINLINE static ATTRINLINE void P_ArchiveLuabanksAndConsistency(save_t *save_p) { UINT8 i, banksinuse = NUM_LUABANKS; @@ -5325,7 +5325,7 @@ static inline void P_ArchiveLuabanksAndConsistency(save_t *save_p) P_WriteUINT8(save_p, 0x1d); // consistency marker } -static inline boolean P_UnArchiveLuabanksAndConsistency(save_t *save_p) +FUNCINLINE static ATTRINLINE boolean P_UnArchiveLuabanksAndConsistency(save_t *save_p) { switch (P_ReadUINT8(save_p)) { diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index b2396e269..83e9437ad 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -23,6 +23,10 @@ /// \file /// \brief SRB2 system stuff for SDL +#ifdef __EMSCRIPTEN__ +#include +#endif + #include #ifdef _WIN32 @@ -79,7 +83,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #define HAVE_SDLCPUINFO #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#if defined (__linux__) || defined (__HAIKU__) +#if defined (__linux__) || defined (__HAIKU__) || defined (__EMSCRIPTEN__) #include #else #include @@ -103,6 +107,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #endif +#ifdef __EMSCRIPTEN__ +#undef HAVE_TERMIOS // do not read on /dev/tty, JavaScript alert() are blocking +#endif + #if defined(UNIXCOMMON) #include #endif @@ -111,9 +119,11 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include #include #ifndef __HAIKU__ // haiku's crash dialog is just objectively better +#ifndef __EMSCRIPTEN__ // WASM does not have a rell fork() #define NEWSIGNALHANDLER #endif #endif +#endif #ifndef NOMUMBLE #ifdef __linux__ // need -lrt @@ -145,12 +155,14 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if !defined (__EMSCRIPTEN__) #ifndef NOEXECINFO #include #endif #include #define UNIXBACKTRACE #endif +#endif // Locations to directly check for srb2.pk3 in const char *wadDefaultPaths[] = { @@ -967,8 +979,13 @@ void I_OutputMsg(const char *fmt, ...) } #endif +#ifdef __EMSCRIPTEN__ + fprintf(stdout, "%s", txt); +#else if (!framebuffer) fprintf(stderr, "%s", txt); +#endif + #ifdef HAVE_TERMIOS if (consolevent && txt[len-1] == '\n') { @@ -2295,6 +2312,12 @@ void I_StartupTimer(void) void I_Sleep(UINT32 ms) { +#if defined (__EMSCRIPTEN__) + if (emscripten_has_asyncify()) + { + return emscripten_sleep(ms); + } +#endif SDL_Delay(ms); } @@ -2440,10 +2463,8 @@ INT32 I_StartupSystem(void) SDL_version SDLlinked; SDL_VERSION(&SDLcompiled) SDL_GetVersion(&SDLlinked); -#ifdef HAVE_THREADS I_start_threads(); I_AddExitFunc(I_stop_threads); -#endif I_StartupConsole(); #ifdef NEWSIGNALHANDLER // This is useful when debugging. It lets GDB attach to @@ -2506,6 +2527,10 @@ void I_Quit(void) free(myargv); // Deallocate allocated memory death: W_Shutdown(); +#ifdef __EMSCRIPTEN__ + emscripten_cancel_main_loop(); + emscripten_force_exit(0); +#endif exit(0); } @@ -3218,7 +3243,13 @@ size_t I_GetFreeMem(size_t *total) #else // Guess 48 MB. if (total) + { +#if SDL_VERSION_ATLEAST(2,0,1) + *total = SDL_GetSystemRAM(); +#else *total = 48<<20; +#endif + } return 48<<20; #endif } diff --git a/src/sdl/i_threads.c b/src/sdl/i_threads.c index c05936072..24c528900 100644 --- a/src/sdl/i_threads.c +++ b/src/sdl/i_threads.c @@ -155,7 +155,7 @@ Worker ( return 0; } -void +int I_spawn_thread ( const char * name, I_thread_fn entry, @@ -164,10 +164,16 @@ I_spawn_thread ( Link link; Thread th; + if (! I_can_thread()) + return false; + th = malloc(sizeof *th); if (! th) - abort();/* this is pretty GNU of me */ + { + I_OutputMsg("Failed to make memory for Thread: %s", name); + return false; + } th->entry = entry; th->userdata = userdata; @@ -185,10 +191,30 @@ I_spawn_thread ( ); if (! th->thread) - abort(); + { + I_OutputMsg("I_spawn_thread failed to make thread %s: %s\n", name, SDL_GetError()); + } } } I_unlock_mutex(i_thread_pool_mutex); + + if (! th->thread) + { + free(th); + return false; + } + + return true; +} + +int +I_can_thread (void) +{ +#ifdef __EMSCRIPTEN_PTHREADS__ + return true; +#else + return SDL_ThreadID() != 0; +#endif } int @@ -204,6 +230,9 @@ I_start_threads (void) i_mutex_pool_mutex = SDL_CreateMutex(); i_cond_pool_mutex = SDL_CreateMutex(); + if (! I_can_thread()) + return; + if (!( i_thread_pool_mutex && i_mutex_pool_mutex && @@ -284,6 +313,9 @@ I_lock_mutex ( ){ SDL_mutex * mutex; + if (! I_can_thread()) + return; + mutex = Identity( &i_mutex_pool, i_mutex_pool_mutex, @@ -299,6 +331,9 @@ void I_unlock_mutex ( I_mutex id ){ + if (! I_can_thread()) + return; + if (SDL_UnlockMutex(id) == -1) abort(); } @@ -327,6 +362,9 @@ I_wake_one_cond ( ){ SDL_cond * cond; + if (! I_can_thread()) + return; + cond = Identity( &i_cond_pool, i_cond_pool_mutex, @@ -344,6 +382,9 @@ I_wake_all_cond ( ){ SDL_cond * cond; + if (! I_can_thread()) + return; + cond = Identity( &i_cond_pool, i_cond_pool_mutex, diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 82583ccb4..149efc1e2 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -20,6 +20,10 @@ /// \file /// \brief SRB2 graphics stuff for SDL +#ifdef __EMSCRIPTEN__ +#include +#endif + #include #include @@ -475,6 +479,35 @@ static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n")); } +static void TimingInfo(void) +{ +#ifdef __EMSCRIPTEN__ + int mode = -1, value = -1; + emscripten_get_main_loop_timing(&mode, &value); + CONS_Printf("\x82" "Currect Timing Mode\n"); + if (mode == -1) + { + CONS_Printf(" Unknown\n"); + } + else if (mode == EM_TIMING_SETTIMEOUT) + { + CONS_Printf(" everty %d ms\n", value); + } + else if (mode == EM_TIMING_RAF) + { + CONS_Printf(" every %d vsync\n", value); + } + else if (mode == EM_TIMING_SETIMMEDIATE) + { + CONS_Printf(" Unknown value %d\n", value); + } + else + { + CONS_Printf(" Unknown mode %d\n", mode); + } +#endif +} + static void VID_Command_Info_f (void) { #if 0 @@ -522,6 +555,7 @@ static void VID_Command_Info_f (void) SurfaceInfo(bufSurface, M_GetText("Current Engine Mode")); SurfaceInfo(vidSurface, M_GetText("Current Video Mode")); #endif + TimingInfo(); } static void VID_Command_ModeList_f(void) @@ -1832,7 +1866,11 @@ void I_StartupGraphics(void) I_ShutdownTTF(); #endif +#ifdef __EMSCRIPTEN__ + VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH*2, BASEVIDHEIGHT*2)); +#else VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT)); +#endif if (M_CheckParm("-nomousegrab")) mousegrabok = SDL_FALSE; @@ -1973,3 +2011,79 @@ UINT32 I_GetRefreshRate(void) // trouble querying mode over and over again. return refresh_rate; } + +#ifdef __EMSCRIPTEN__ +int EMSCRIPTEN_KEEPALIVE change_resolution(int x, int y) +{ + int newmode = -1; + + if ( x < BASEVIDWIDTH*1 && y < BASEVIDHEIGHT*1) + newmode = VID_GetModeForSize(BASEVIDWIDTH*1, BASEVIDHEIGHT*1); + else if (x < BASEVIDWIDTH*2 && y < BASEVIDHEIGHT*2) + newmode = VID_GetModeForSize(BASEVIDWIDTH*1, BASEVIDHEIGHT*1); + else if (x < BASEVIDWIDTH*3 && y < BASEVIDHEIGHT*3) + newmode = VID_GetModeForSize(BASEVIDWIDTH*2, BASEVIDHEIGHT*2); +#if 0 + else if (x < BASEVIDWIDTH*4 && y < BASEVIDHEIGHT*4) + newmode = VID_GetModeForSize(BASEVIDWIDTH*3, BASEVIDHEIGHT*3); + else if (x < BASEVIDWIDTH*5 && y < BASEVIDHEIGHT*5) + newmode = VID_GetModeForSize(BASEVIDWIDTH*4, BASEVIDHEIGHT*4); + else if (x < BASEVIDWIDTH*6 && y < BASEVIDHEIGHT*6) + newmode = VID_GetModeForSize(BASEVIDWIDTH*5, BASEVIDHEIGHT*5); + else + newmode = VID_GetModeForSize(BASEVIDWIDTH*6, BASEVIDHEIGHT*6); +#else + else + newmode = VID_GetModeForSize(BASEVIDWIDTH*2, BASEVIDHEIGHT*2); +#endif + + if (newmode != -1) + setmodeneeded = newmode; + + if (setmodeneeded) + return 1; + + return 0; +} + +void EMSCRIPTEN_KEEPALIVE inject_text(const char *text) +{ + event_t event; + size_t len = 0; + event.type = ev_text; + { + event.key = text[len]; + D_PostEvent(&event); + len++; + } while (text[len] != 0x00); +} + +void EMSCRIPTEN_KEEPALIVE inject_keycode(int key, int type) +{ + event_t event; + if (type == true) + { + event.type = ev_keyup; + } + else if (type == false) + { + event.type = ev_keydown; + } + else + { + return; + } + event.key = key; + if (event.key) D_PostEvent(&event); +} + +void EMSCRIPTEN_KEEPALIVE unlock_mouse(void) +{ + SDLforceUngrabMouse(); +} + +void EMSCRIPTEN_KEEPALIVE lock_mouse(void) +{ + SDLdoGrabMouse(); +} +#endif diff --git a/vcpkg.json b/vcpkg.json index 3b79ec83f..5bd5d45be 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -8,59 +8,53 @@ "name": "curl", "platform": "!wasm32" }, - "libgme", { - "name":"libopenmpt", - "platform": "!wasm32" + "name": "curl", + "default-features": false, + "features": [ + "mbedtls" + ], + "platform": "wasm32", + "version>=": "7.74.0#5" }, + "libgme", + "libopenmpt", "libpng", "miniupnpc", + { + "name": "sdl2", + "platform": "!linux" + }, { "name": "sdl2", "default-features": false, "features": [ - { - "name": "wayland", - "platform": "linux" - }, - { - "name": "x11", - "platform": "!windows" - } + "wayland", + "x11" ], - "platform": "!wasm32", + "platform": "linux", "version>=": "2.30.6#2" }, { "name": "sdl2-mixer-ext", "features": [ { - "name":"fluidsynth", + "name": "fluidsynth", "platform": "!static" }, { - "name":"libflac", - "platform": "!wasm32" + "name": "libflac", + "platform": "!emscripten" }, "libgme", "libmodplug", - { - "name":"libvorbis", - "platform": "!wasm32" - }, + "libvorbis", "libxmp", - { - "name":"mpg123", - "platform": "!wasm32" - }, - { - "name":"opusfile", - "platform": "!wasm32" - }, + "mpg123", + "opusfile", "pxtone", "timidity" ], - "platform": "!wasm32", "version>=": "2.6.0#0" }, "zlib"