From 7ff1d5877d0eb355dbb457758f82d8388179b038 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 1 Feb 2024 18:16:24 +0100 Subject: [PATCH 01/38] Replace glBuild2DMipmaps with GL_GENERATE_MIPMAPS Quote "gluBuild2DMipmaps. Never use this." gluBuild2DMipmaps was causing massive stutters on many maps on windows this replaces it with GL_GENERATE_MIPMAP and removes glBuild2DMipmaps completely https://www.khronos.org/opengl/wiki/Common_Mistakes --- src/hardware/r_opengl/r_opengl.c | 18 ++++++++---------- src/hardware/r_opengl/r_opengl.h | 1 + src/sdl/ogl_sdl.c | 5 +++++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index ea831e41d..932cfbaff 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -77,6 +77,7 @@ static GLint min_filter = GL_LINEAR; static GLint mag_filter = GL_LINEAR; static GLint anisotropic_filter = 0; static boolean model_lighting = false; +boolean supportMipMap = false; const GLubyte *gl_version = NULL; const GLubyte *gl_renderer = NULL; @@ -397,9 +398,6 @@ static PFNglCopyTexImage2D pglCopyTexImage2D; typedef void (APIENTRY * PFNglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); static PFNglCopyTexSubImage2D pglCopyTexSubImage2D; #endif -/* GLU functions */ -typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data); -static PFNgluBuild2DMipmaps pgluBuild2DMipmaps; /* 1.3 functions for multitexturing */ typedef void (APIENTRY *PFNglActiveTexture) (GLenum); @@ -907,9 +905,6 @@ void SetupGLFunc4(void) pglUniform3fv = GetGLFunc("glUniform3fv"); pglGetUniformLocation = GetGLFunc("glGetUniformLocation"); #endif - - // GLU - pgluBuild2DMipmaps = GetGLFunc("gluBuild2DMipmaps"); } EXPORT boolean HWRAPI(CompileShaders) (void) @@ -1887,7 +1882,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); if (MipMap) { - pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); if (pTexInfo->flags & TF_TRANSPARENT) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff @@ -1908,7 +1904,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); if (MipMap) { - pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); if (pTexInfo->flags & TF_TRANSPARENT) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff @@ -1928,7 +1925,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) { if (MipMap) { - pgluBuild2DMipmaps(GL_TEXTURE_2D, textureformatGL, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); // Control the mipmap level of detail pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail if (pTexInfo->flags & TF_TRANSPARENT) @@ -2463,7 +2461,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) mag_filter = GL_LINEAR; min_filter = GL_NEAREST; } - if (!pgluBuild2DMipmaps) + if (!supportMipMap) { MipMap = GL_FALSE; min_filter = GL_LINEAR; diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index f44e0818b..8e4784c65 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -126,6 +126,7 @@ extern GLint screen_width; extern GLint screen_height; extern GLbyte screen_depth; extern GLint maximumAnisotropy; +extern boolean supportMipMap; /** \brief OpenGL flags for video driver */ diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index db0538195..81b1314e0 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -189,6 +189,11 @@ boolean OglSdlSurface(INT32 w, INT32 h) else maximumAnisotropy = 1; + if (atof((const char*)gl_version) >= 1.4) + supportMipMap = true; + else + supportMipMap = false; + SetupGLFunc4(); glanisotropicmode_cons_t[1].value = maximumAnisotropy; From 30e7bd90a430cc2f37670f7e826949fb91b1481e Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 1 Feb 2024 21:03:28 +0100 Subject: [PATCH 02/38] Better Opengl version check somehow forgor about vendor information in the version string lmao --- src/sdl/ogl_sdl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 81b1314e0..9b6678401 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -155,6 +155,7 @@ boolean OglSdlSurface(INT32 w, INT32 h) { INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; static boolean first_init = false; + static int majorGL = 0, minorGL = 0; oglflags = 0; @@ -189,7 +190,8 @@ boolean OglSdlSurface(INT32 w, INT32 h) else maximumAnisotropy = 1; - if (atof((const char*)gl_version) >= 1.4) + if (sscanf((const char*)gl_version, "%d.%d", &majorGL, &minorGL) + && (!(majorGL == 1 && minorGL <= 3))) supportMipMap = true; else supportMipMap = false; From 338088104e6a16ddbba5e5f32811a4dbaaf64cef Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 1 Feb 2024 22:10:38 +0100 Subject: [PATCH 03/38] Remove GLU library loading code hope i didnt forger smth X) --- src/hardware/r_opengl/ogl_win.c | 12 +-------- src/hardware/r_opengl/r_opengl.h | 1 - src/sdl/i_video.c | 2 -- src/sdl/ogl_sdl.c | 46 -------------------------------- src/sdl/ogl_sdl.h | 2 -- 5 files changed, 1 insertion(+), 62 deletions(-) diff --git a/src/hardware/r_opengl/ogl_win.c b/src/hardware/r_opengl/ogl_win.c index c9bf60144..ec8fc9bdb 100644 --- a/src/hardware/r_opengl/ogl_win.c +++ b/src/hardware/r_opengl/ogl_win.c @@ -117,7 +117,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module #define pwglDeleteContext wglDeleteContext; #define pwglMakeCurrent wglMakeCurrent; #else -static HMODULE OGL32, GLU32; +static HMODULE OGL32; typedef void *(WINAPI *PFNwglGetProcAddress) (const char *); static PFNwglGetProcAddress pwglGetProcAddress; typedef HGLRC (WINAPI *PFNwglCreateContext) (HDC hdc); @@ -132,13 +132,6 @@ static PFNwglMakeCurrent pwglMakeCurrent; void *GetGLFunc(const char *proc) { void *func = NULL; - if (strncmp(proc, "glu", 3) == 0) - { - if (GLU32) - func = GetProcAddress(GLU32, proc); - else - return NULL; - } if (pwglGetProcAddress) func = pwglGetProcAddress(proc); if (!func) @@ -155,8 +148,6 @@ boolean LoadGL(void) if (!OGL32) return 0; - GLU32 = LoadLibrary("GLU32.DLL"); - pwglGetProcAddress = GetGLFunc("wglGetProcAddress"); pwglCreateContext = GetGLFunc("wglCreateContext"); pwglDeleteContext = GetGLFunc("wglDeleteContext"); @@ -528,7 +519,6 @@ EXPORT void HWRAPI(Shutdown) (void) ReleaseDC(hWnd, hDC); hDC = NULL; } - FreeLibrary(GLU32); FreeLibrary(OGL32); GL_DBG_Printf ("HWRAPI Shutdown(DONE)\n"); } diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index 8e4784c65..fefe43ae7 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -35,7 +35,6 @@ #else #include -#include #ifdef STATIC_OPENGL // Because of the 1.3 functions, you'll need GLext to compile it if static #define GL_GLEXT_PROTOTYPES diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d3a602c05..6fccf3a17 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -2026,8 +2026,6 @@ void I_ShutdownGraphics(void) I_OutputMsg("shut down\n"); #ifdef HWRENDER - if (GLUhandle) - hwClose(GLUhandle); if (sdlglcontext) { SDL_GL_DeleteContext(sdlglcontext); diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 9b6678401..b47c09833 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -70,18 +70,10 @@ PFNglGetString pglGetString; /** \brief SDL video display surface */ INT32 oglflags = 0; -void *GLUhandle = NULL; SDL_GLContext sdlglcontext = 0; void *GetGLFunc(const char *proc) { - if (strncmp(proc, "glu", 3) == 0) - { - if (GLUhandle) - return hwSym(proc, GLUhandle); - else - return NULL; - } return SDL_GL_GetProcAddress(proc); } @@ -89,7 +81,6 @@ boolean LoadGL(void) { #ifndef STATIC_OPENGL const char *OGLLibname = NULL; - const char *GLULibname = NULL; if (M_CheckParm("-OGLlib") && M_IsNextParm()) OGLLibname = M_GetNextParm(); @@ -102,43 +93,6 @@ boolean LoadGL(void) CONS_Printf("If you know what is the OpenGL library's name, use -OGLlib\n"); return 0; } - -#if 0 - GLULibname = "/proc/self/exe"; -#elif defined (_WIN32) - GLULibname = "GLU32.DLL"; -#elif defined (__MACH__) - GLULibname = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"; -#elif defined (macintos) - GLULibname = "OpenGLLibrary"; -#elif defined (__unix__) - GLULibname = "libGLU.so.1"; -#elif defined (__HAIKU__) - GLULibname = "libGLU.so"; -#else - GLULibname = NULL; -#endif - - if (M_CheckParm("-GLUlib") && M_IsNextParm()) - GLULibname = M_GetNextParm(); - - if (GLULibname) - { - GLUhandle = hwOpen(GLULibname); - if (GLUhandle) - return SetupGLfunc(); - else - { - CONS_Alert(CONS_ERROR, "Could not load GLU Library: %s\n", GLULibname); - if (!M_CheckParm ("-GLUlib")) - CONS_Alert(CONS_ERROR, "If you know what is the GLU library's name, use -GLUlib\n"); - } - } - else - { - CONS_Alert(CONS_ERROR, "Could not load GLU Library\n"); - CONS_Alert(CONS_ERROR, "If you know what is the GLU library's name, use -GLUlib\n"); - } #endif return SetupGLfunc(); } diff --git a/src/sdl/ogl_sdl.h b/src/sdl/ogl_sdl.h index bd1d699ff..87df5e5e6 100644 --- a/src/sdl/ogl_sdl.h +++ b/src/sdl/ogl_sdl.h @@ -19,8 +19,6 @@ #include "../v_video.h" -extern void *GLUhandle; - boolean OglSdlSurface(INT32 w, INT32 h); void OglSdlFinishUpdate(boolean vidwait); From 64df78228794a27612dbb848ade690804b41db3c Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sun, 19 May 2024 12:20:03 +0200 Subject: [PATCH 04/38] Refactor TTY input handling --- src/dedicated/i_system.c | 78 ++++++++++++++-------------------------- src/sdl/i_system.c | 78 ++++++++++++++-------------------------- 2 files changed, 52 insertions(+), 104 deletions(-) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 858dfaf20..29a3e9511 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -705,10 +705,9 @@ typedef struct static feild_t tty_con; -// when printing general stuff to stdout stderr (Sys_Printf) -// we need to disable the tty console stuff -// this increments so we can recursively disable -static INT32 ttycon_hide = 0; +// lock to prevent clearing partial lines, since not everything +// printed ends on a newline. +static boolean ttycon_ateol = true; // some key codes that the terminal may be using // TTimo NOTE: I'm not sure how relevant this is static INT32 tty_erase; @@ -736,63 +735,31 @@ static inline void tty_FlushIn(void) // TTimo NOTE: it seems on some terminals just sending '\b' is not enough // so for now, in any case we send "\b \b" .. yeah well .. // (there may be a way to find out if '\b' alone would work though) +// Hanicef NOTE: using \b this way is unreliable because of terminal state, +// it's better to use \r to reset the cursor to the beginning of the +// line and clear from there. static void tty_Back(void) { - char key; - ssize_t d; - key = '\b'; - d = write(STDOUT_FILENO, &key, 1); - key = ' '; - d = write(STDOUT_FILENO, &key, 1); - key = '\b'; - d = write(STDOUT_FILENO, &key, 1); - (void)d; + write(STDOUT_FILENO, "\r", 1); + if (tty_con.cursor>0) + { + write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); + } + write(STDOUT_FILENO, " \b", 2); } static void tty_Clear(void) { size_t i; + write(STDOUT_FILENO, "\r", 1); if (tty_con.cursor>0) { for (i=0; i0); - ttycon_hide--; - if (ttycon_hide == 0 && tty_con.cursor) - { - for (i=0; i0) + { + write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); + } + write(STDOUT_FILENO, " \b", 2); } static void tty_Clear(void) { size_t i; + write(STDOUT_FILENO, "\r", 1); if (tty_con.cursor>0) { for (i=0; i0); - ttycon_hide--; - if (ttycon_hide == 0 && tty_con.cursor) - { - for (i=0; i Date: Sun, 16 Jun 2024 15:00:51 +0200 Subject: [PATCH 05/38] Add CVar for changing room ID --- src/d_main.c | 2 +- src/m_menu.c | 4 ++-- src/netcode/mserv.c | 16 +++++++++++++++- src/netcode/mserv.h | 1 + 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 3a3a0b26a..9935dcaa1 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1600,7 +1600,7 @@ void D_SRB2Main(void) { if (!M_IsNextParm()) I_Error("usage: -room \nCheck the Master Server's webpage for room ID numbers.\n"); - ms_RoomId = atoi(M_GetNextParm()); + CV_SetValue(&cv_masterserver_room_id, atoi(M_GetNextParm())); #ifdef UPDATE_ALERT GetMODVersion_Console(); diff --git a/src/m_menu.c b/src/m_menu.c index 38165472e..d3df61b65 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -11524,10 +11524,10 @@ static void M_ChooseRoom(INT32 choice) #endif if (choice == 0) - ms_RoomId = -1; + CV_SetValue(&cv_masterserver_room_id, 0); else { - ms_RoomId = roomIds[choice-1]; + CV_SetValue(&cv_masterserver_room_id, roomIds[choice-1]); menuRoomIndex = choice - 1; } diff --git a/src/netcode/mserv.c b/src/netcode/mserv.c index 74ee120f9..db0f640d7 100644 --- a/src/netcode/mserv.c +++ b/src/netcode/mserv.c @@ -55,6 +55,7 @@ static boolean ServerName_CanChange (const char*); static void Update_parameters (void); static void MasterServer_OnChange(void); +static void RoomId_OnChange(void); static CV_PossibleValue_t masterserver_update_rate_cons_t[] = { {2, "MIN"}, @@ -66,8 +67,9 @@ consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ds.ms.srb2.org/M consvar_t cv_servername = CVAR_INIT_WITH_CALLBACKS ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters, ServerName_CanChange); consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters); +consvar_t cv_masterserver_room_id = CVAR_INIT ("masterserver_room_id", "0", CV_CALL, CV_Unsigned, RoomId_OnChange); -INT16 ms_RoomId = -1; +INT16 ms_RoomId = 0; #if defined (MASTERSERVER) && defined (HAVE_THREADS) int ms_QueryId; @@ -92,6 +94,7 @@ void AddMServCommands(void) { CV_RegisterVar(&cv_masterserver); CV_RegisterVar(&cv_masterserver_update_rate); + CV_RegisterVar(&cv_masterserver_room_id); CV_RegisterVar(&cv_masterserver_timeout); CV_RegisterVar(&cv_masterserver_debug); CV_RegisterVar(&cv_masterserver_token); @@ -534,6 +537,17 @@ Update_parameters (void) #endif/*MASTERSERVER*/ } +static void RoomId_OnChange(void) +{ + if (ms_RoomId != cv_masterserver_room_id.value) + { + UnregisterServer(); + ms_RoomId = cv_masterserver_room_id.value; + if (Online()) + RegisterServer(); + } +} + static void MasterServer_OnChange(void) { #ifdef MASTERSERVER diff --git a/src/netcode/mserv.h b/src/netcode/mserv.h index 0bc8c8e6b..419c11a89 100644 --- a/src/netcode/mserv.h +++ b/src/netcode/mserv.h @@ -66,6 +66,7 @@ typedef struct extern consvar_t cv_masterserver, cv_servername; extern consvar_t cv_masterserver_update_rate; +extern consvar_t cv_masterserver_room_id; extern consvar_t cv_masterserver_timeout; extern consvar_t cv_masterserver_debug; extern consvar_t cv_masterserver_token; From 7cd96a6b2ea836ccfb71a5d521982ed4db7db085 Mon Sep 17 00:00:00 2001 From: StarManiaKG Date: Tue, 18 Jun 2024 17:07:19 -0400 Subject: [PATCH 06/38] Add actual multiplayer automap support --- src/am_map.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/am_map.c b/src/am_map.c index df3a45cff..36b62f2f9 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -1076,6 +1076,9 @@ static inline void AM_drawPlayers(void) if (!playeringame[i] || players[i].spectator) continue; + if (!players[i].mo) + continue; + p = &players[i]; if (p->skincolor > 0) color = R_GetTranslationColormap(TC_DEFAULT, p->skincolor, GTC_CACHE)[GREENS + 8]; From eefcca6259e4ecac9738c70833a0623f547aabd1 Mon Sep 17 00:00:00 2001 From: kaldrum1 <116390251+kaldrum1@users.noreply.github.com> Date: Mon, 8 Jul 2024 15:27:42 -0700 Subject: [PATCH 07/38] adjust interpolation duration based on speed, allow anim_duration to be used as a lua override to hardcoded values --- src/hardware/hw_md2.c | 90 +++++++++++++++++++++++++++++++++++++++++-- src/p_mobj.c | 4 ++ 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 2616d4085..fc8047c6c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1193,6 +1193,90 @@ static void adjustTextureCoords(model_t *model, patch_t *patch) model->max_t = gpatch->max_t; } +static INT32 GetAnimDuration(mobj_t *mobj) //part of p_mobj's setplayermobjstate logic, used to make sure that anim durations are actually correct when the speed gets adjusted on players +{ + player_t *player = mobj->player; + INT32 tics = mobj->state->tics; + + if (!(mobj->frame & FF_ANIMATE) && mobj->anim_duration) //set manually by something through lua + return mobj->anim_duration; + + if (!player && mobj->type == MT_TAILSOVERLAY) //so tails overlays interpolate properly + player = mobj->tracer->player; + if (player) + { + if (player->panim == PA_EDGE && (player->charflags & SF_FASTEDGE)) + tics = 2; + else if (player->powers[pw_tailsfly] && (!(player->mo->eflags & MFE_UNDERWATER) || (mobj->type == MT_PLAYER))) //tailsoverlay does not get adjusted from these rules when underwater + { + if (player->fly1 > 0) + tics = 1; + else if (!(player->mo->eflags & MFE_UNDERWATER)) + tics = 2; + else + tics = 4; + } + else if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST)) + { + fixed_t speed;// = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); + if (player->panim == PA_FALL) + { + speed = FixedDiv(abs(mobj->momz), mobj->scale); + if (speed < 10<panim == PA_ABILITY2 && player->charability2 == CA2_SPINDASH) + { + fixed_t step = (player->maxdash - player->mindash)/4; + speed = (player->dashspeed - player->mindash); + if (speed > 3*step) + tics = 1; + else if (speed > step) + tics = 2; + else + tics = 3; + } + else + { + speed = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); + if (player->panim == PA_ROLL || player->panim == PA_JUMP) + { + if (speed > 16<charability == CA_FLOAT || player->charability == CA_SLOWFALL) && player->secondjump == 1) || player->powers[pw_super]) // Only if on the ground or superflying. + { + if (player->panim == PA_WALK) + { + if (speed > 12< 6<panim == PA_RUN) || (player->panim == PA_DASH)) + { + if (speed > 52<mobj->state->tics; + float durs = GetAnimDuration(spr->mobj); float tics = (float)spr->mobj->tics; const boolean papersprite = (R_ThingIsPaperSprite(spr->mobj) && !R_ThingIsFloorSprite(spr->mobj)); const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj)); @@ -1287,8 +1371,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } // Apparently people don't like jump frames like that, so back it goes - //if (tics > durs) - //durs = tics; + if (tics > durs) + durs = tics; // Make linkdraw objects use their tracer's alpha value fixed_t newalpha = spr->mobj->alpha; diff --git a/src/p_mobj.c b/src/p_mobj.c index 1ec09ab85..92133c1dc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -96,11 +96,15 @@ static void P_SetupStateAnimation(mobj_t *mobj, state_t *st) animlength = st->var1; if (!(st->frame & FF_ANIMATE)) + { + mobj->anim_duration = 0; return; + } if (animlength <= 0 || st->var2 == 0) { mobj->frame &= ~FF_ANIMATE; + mobj->anim_duration = 0; return; // Crash/stupidity prevention } From 147aa123f926ef03f6e3bc1f737d19b8a9e65508 Mon Sep 17 00:00:00 2001 From: kaldrum1 <116390251+kaldrum1@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:14:11 -0700 Subject: [PATCH 08/38] fix crash when tails tails dont have a tails to be the tail of --- src/hardware/hw_md2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index fc8047c6c..88aa4f430 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1201,7 +1201,7 @@ static INT32 GetAnimDuration(mobj_t *mobj) //part of p_mobj's setplayermobjstate if (!(mobj->frame & FF_ANIMATE) && mobj->anim_duration) //set manually by something through lua return mobj->anim_duration; - if (!player && mobj->type == MT_TAILSOVERLAY) //so tails overlays interpolate properly + if (!player && mobj->type == MT_TAILSOVERLAY && mobj->tracer) //so tails overlays interpolate properly player = mobj->tracer->player; if (player) { @@ -1691,7 +1691,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf); } } - return true; } From 455ffec1e4c2c3d7981d0b42534b2fa3b195d5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 7 Oct 2024 15:48:42 +0200 Subject: [PATCH 09/38] Check for empty string before printing in console --- src/dedicated/i_system.c | 5 ++++- src/sdl/i_system.c | 22 +++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 29a3e9511..e95ea3417 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -1035,6 +1035,9 @@ void I_OutputMsg(const char *fmt, ...) va_start(argptr,fmt); len = vsnprintf(NULL, 0, fmt, argptr); va_end(argptr); + if (len == 0) + return; + txt = malloc(len+1); va_start(argptr,fmt); vsprintf(txt, fmt, argptr); @@ -1134,7 +1137,7 @@ void I_OutputMsg(const char *fmt, ...) if (!framebuffer) fprintf(stderr, "%s", txt); #ifdef HAVE_TERMIOS - if (consolevent && txt[strlen(txt)-1] == '\n') + if (consolevent && txt[len-1] == '\n') { write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); ttycon_ateol = true; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 8227cd52c..3eb70373b 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -840,9 +840,16 @@ static void I_RegisterChildSignals(void) void I_OutputMsg(const char *fmt, ...) { size_t len; - char txt[8192]; + char *txt; va_list argptr; + va_start(argptr,fmt); + len = vsnprintf(NULL, 0, fmt, argptr); + va_end(argptr); + if (len == 0) + return; + + txt = malloc(len+1); va_start(argptr,fmt); vsprintf(txt, fmt, argptr); va_end(argptr); @@ -876,7 +883,10 @@ void I_OutputMsg(const char *fmt, ...) DWORD bytesWritten; if (co == INVALID_HANDLE_VALUE) + { + free(txt); return; + } if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten)) { @@ -892,11 +902,16 @@ void I_OutputMsg(const char *fmt, ...) if (oldLength > 0) { LPVOID blank = malloc(oldLength); - if (!blank) return; + if (!blank) + { + free(txt); + return; + } memset(blank, ' ', oldLength); // Blank out. oldLines = malloc(oldLength*sizeof(TCHAR)); if (!oldLines) { + free(txt); free(blank); return; } @@ -941,7 +956,7 @@ void I_OutputMsg(const char *fmt, ...) if (!framebuffer) fprintf(stderr, "%s", txt); #ifdef HAVE_TERMIOS - if (consolevent && txt[strlen(txt)-1] == '\n') + if (consolevent && txt[len-1] == '\n') { write(STDOUT_FILENO, tty_con.buffer, tty_con.cursor); ttycon_ateol = true; @@ -953,6 +968,7 @@ void I_OutputMsg(const char *fmt, ...) fflush(stderr); #endif + free(txt); } // From 22ce859e65da2a0770d6966e0c1a3f32192cb54d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 13 Oct 2024 14:06:45 +0200 Subject: [PATCH 10/38] Fix BootMap not having any effect when loaded from the addon menu --- src/deh_soc.c | 2 ++ src/dehacked.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index c0e646f60..a2be99fa0 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -3549,6 +3549,8 @@ void readmaincfg(MYFILE *f) char *tmp; INT32 value; + bootmap = 0; // reset bootmap so we don't warp to the wrong map if another maincfg had set this before + do { if (myfgets(s, MAXLINELEN, f)) diff --git a/src/dehacked.c b/src/dehacked.c index 2050a117f..8743a482e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -587,7 +587,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) if (gamestate == GS_TITLESCREEN) { - if (introchanged) + if (bootmap) + { + menuactive = false; + D_MapChange(bootmap, gametype, ultimatemode, true, 0, false, false); + } + else if (introchanged) { menuactive = false; I_UpdateMouseGrab(); From 0b2202e5cbc9f1139598e88cd68345bddf6d5000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 13 Oct 2024 16:50:41 +0200 Subject: [PATCH 11/38] Fix bootmap not resetting properly after reload --- src/deh_soc.c | 2 -- src/dehacked.c | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index a2be99fa0..c0e646f60 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -3549,8 +3549,6 @@ void readmaincfg(MYFILE *f) char *tmp; INT32 value; - bootmap = 0; // reset bootmap so we don't warp to the wrong map if another maincfg had set this before - do { if (myfgets(s, MAXLINELEN, f)) diff --git a/src/dehacked.c b/src/dehacked.c index 8743a482e..505c7ed1f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -196,6 +196,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) deh_num_warning = 0; + bootmap = 0; gamedataadded = titlechanged = introchanged = false; // it doesn't test the version of SRB2 and version of dehacked file From 0dac4ed492fd78d801f939a8fef27fcf7a7c3655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 13 Oct 2024 17:47:56 +0200 Subject: [PATCH 12/38] Fix (hopufully) all remaining edge cases --- src/deh_soc.c | 1 + src/dehacked.c | 6 +++--- src/dehacked.h | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index c0e646f60..80a5358c0 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -3925,6 +3925,7 @@ void readmaincfg(MYFILE *f) value = get_number(word2); bootmap = (INT16)value; + bootmapchanged = true; //titlechanged = true; } else if (fastcmp(word, "STARTCHAR")) diff --git a/src/dehacked.c b/src/dehacked.c index 505c7ed1f..473e77e55 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -20,6 +20,7 @@ boolean deh_loaded = false; boolean gamedataadded = false; boolean titlechanged = false; boolean introchanged = false; +boolean bootmapchanged = false; static int dbg_line; static INT32 deh_num_warning = 0; @@ -196,8 +197,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) deh_num_warning = 0; - bootmap = 0; - gamedataadded = titlechanged = introchanged = false; + gamedataadded = titlechanged = introchanged = bootmapchanged = false; // it doesn't test the version of SRB2 and version of dehacked file dbg_line = -1; // start at -1 so the first line is 0. @@ -588,7 +588,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) if (gamestate == GS_TITLESCREEN) { - if (bootmap) + if (bootmapchanged && bootmap) { menuactive = false; D_MapChange(bootmap, gametype, ultimatemode, true, 0, false, false); diff --git a/src/dehacked.h b/src/dehacked.h index d985b14b0..e7b9b4656 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -39,6 +39,7 @@ extern boolean deh_loaded; extern boolean gamedataadded; extern boolean titlechanged; extern boolean introchanged; +extern boolean bootmapchanged; #define MAX_ACTION_RECURSION 30 extern const char *luaactions[MAX_ACTION_RECURSION]; From 0a611b0f09b5a3108c1cf4ed806a1df0a7f645e7 Mon Sep 17 00:00:00 2001 From: Jordan Christiansen Date: Wed, 6 Nov 2024 19:59:58 -0600 Subject: [PATCH 13/38] Convert waddir to an absolute path Since we change directories to the waddir, if waddir is a relative path, it will be invalidated after changing directories. Converting it to an absolute path means we can change directories without messing anything up. Fixes #1310 --- src/dedicated/i_system.c | 2 ++ src/sdl/i_system.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 23c0149ca..91cc18d9f 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -1453,8 +1453,10 @@ const char *I_LocateWad(void) { // change to the directory where we found srb2.pk3 #if defined (_WIN32) + waddir = _fullpath(NULL, waddir, MAX_PATH); SetCurrentDirectoryA(waddir); #else + waddir = realpath(waddir, NULL); if (chdir(waddir) == -1) I_OutputMsg("Couldn't change working directory\n"); #endif diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 9fe50a6a2..d8fb4346b 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -3087,8 +3087,10 @@ const char *I_LocateWad(void) { // change to the directory where we found srb2.pk3 #if defined (_WIN32) + waddir = _fullpath(NULL, waddir, MAX_PATH); SetCurrentDirectoryA(waddir); #else + waddir = realpath(waddir, NULL); if (chdir(waddir) == -1) I_OutputMsg("Couldn't change working directory\n"); #endif From e215d233768bfebb8b0b94f1a2a2a6c496c89096 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Tue, 17 Dec 2024 20:26:17 +0100 Subject: [PATCH 14/38] Update outdated __HAIKU__ ifdefs --- src/dedicated/i_system.c | 21 +++++++++------------ src/sdl/i_system.c | 19 ++++++++----------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 23c0149ca..87a8a8033 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -65,9 +65,9 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #pragma warning(default : 4214 4244) #endif -#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) -#if defined (__linux__) -#include +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__linux__) || defined (__HAIKU__) +#include #else #include #include @@ -81,7 +81,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #endif -#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) +#if defined (__linux__) || defined (UNIXCOMMON) #ifndef NOTERMIOS #include #include // ioctl @@ -96,8 +96,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__)) #include #include +#ifndef __HAIKU__ // haiku's crash dialog is just objectively better #define NEWSIGNALHANDLER #endif +#endif #ifndef NOMUMBLE #ifdef __linux__ // need -lrt @@ -374,7 +376,7 @@ void I_Sleep(UINT32 ms) void I_SleepDuration(precise_t duration) { -#if defined(__linux__) || defined(__FreeBSD__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) UINT64 precision = I_GetPrecisePrecision(); struct timespec ts = { .tv_sec = duration / precision, @@ -1226,18 +1228,13 @@ void I_ShutdownSystem(void) void I_GetDiskFreeSpace(INT64* freespace) { #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#if defined (SOLARIS) || defined (__HAIKU__) - *freespace = INT32_MAX; - return; -#else // Both Linux and BSD have this, apparently. - struct statfs stfs; - if (statfs(srb2home, &stfs) == -1) + struct statvfs stfs; + if (statvfs(srb2home, &stfs) == -1) { *freespace = INT32_MAX; return; } *freespace = stfs.f_bavail * stfs.f_bsize; -#endif #elif defined (_WIN32) static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; static boolean testwin95 = false; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 07088b957..f787bbfbd 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -78,9 +78,9 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include "SDL_cpuinfo.h" #define HAVE_SDLCPUINFO -#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) -#if defined (__linux__) -#include +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__linux__) || defined (__HAIKU__) +#include #else #include #include @@ -94,7 +94,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #endif -#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (__HAIKU__)) +#if defined (__linux__) || defined (UNIXCOMMON) #ifndef NOTERMIOS #include #include // ioctl @@ -109,8 +109,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__)) #include #include +#ifndef __HAIKU__ // haiku's crash dialog is just objectively better #define NEWSIGNALHANDLER #endif +#endif #ifndef NOMUMBLE #ifdef __linux__ // need -lrt @@ -2754,18 +2756,13 @@ void I_ShutdownSystem(void) void I_GetDiskFreeSpace(INT64 *freespace) { #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#if defined (SOLARIS) || defined (__HAIKU__) - *freespace = INT32_MAX; - return; -#else // Both Linux and BSD have this, apparently. - struct statfs stfs; - if (statfs(srb2home, &stfs) == -1) + struct statvfs stfs; + if (statvfs(srb2home, &stfs) == -1) { *freespace = INT32_MAX; return; } *freespace = stfs.f_bavail * stfs.f_bsize; -#endif #elif defined (_WIN32) static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; static boolean testwin95 = false; From f7b0e771debcf020596c1a2bdb58027dbb881f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 17 Dec 2024 20:43:09 +0100 Subject: [PATCH 15/38] Fix FreeBSD build --- src/dedicated/i_system.c | 1 + src/sdl/i_system.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 87a8a8033..02cb22a4f 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -69,6 +69,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #if defined (__linux__) || defined (__HAIKU__) #include #else +#include #include #include /*For meminfo*/ diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index f787bbfbd..77660f469 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -82,6 +82,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #if defined (__linux__) || defined (__HAIKU__) #include #else +#include #include #include /*For meminfo*/ From 493190675398fbd9455bfd1915434cbbf4c53970 Mon Sep 17 00:00:00 2001 From: Fancy2209 <4370-Fancy2209@users.noreply.git.do.srb2.org> Date: Wed, 18 Dec 2024 18:51:58 +0000 Subject: [PATCH 16/38] Fix CMake not finding OpenMPT on Haiku --- cmake/Modules/Findlibopenmpt.cmake | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cmake/Modules/Findlibopenmpt.cmake b/cmake/Modules/Findlibopenmpt.cmake index d7de22134..96cc31026 100644 --- a/cmake/Modules/Findlibopenmpt.cmake +++ b/cmake/Modules/Findlibopenmpt.cmake @@ -1,14 +1,16 @@ include(LibFindMacros) -libfind_pkg_check_modules(libopenmpt_PKGCONF openmpt) +libfind_pkg_check_modules(libopenmpt_PKGCONF openmpt libopenmpt) find_path(libopenmpt_INCLUDE_DIR NAMES libopenmpt.h PATHS ${libopenmpt_PKGCONF_INCLUDE_DIRS} - "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include/libopenmpt" - "/usr/include/libopenmpt" - "/usr/local/include/libopenmpt" + "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include" + "/usr/include" + "/usr/local/include" + PATH_SUFFIXES ++ libopenmpt ) find_library(libopenmpt_LIBRARY From 102ba86869b0da2308397aca362addfd3fbea77f Mon Sep 17 00:00:00 2001 From: pastel Date: Thu, 19 Dec 2024 14:11:01 -0600 Subject: [PATCH 17/38] Correctly force Sonic in the tutorial --- src/m_menu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/m_menu.c b/src/m_menu.c index 63a702474..88a69b5a5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8511,6 +8511,7 @@ static void M_StartTutorial(INT32 choice) gamecomplete = 0; cursaveslot = 0; maplistoption = 0; + CV_StealthSet(&cv_skin, DEFAULTSKIN); // tutorial accounts for sonic only G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false); } From 468cef704fcb38363d7cbaf68518d5f468169d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Fri, 20 Dec 2024 17:36:38 +0100 Subject: [PATCH 18/38] Fix some components of ticcmd being blocked in IntermissionThinker --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 175e757ec..ca02ac7e3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1384,7 +1384,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (PLAYERINPUTDOWN(ssplayer, GC_SPIN) || (usejoystick && axis > 0)) cmd->buttons |= BT_SPIN; - if (gamestate != GS_LEVEL) // not in a level, don't build anything else + if (gamestate == GS_INTRO) // prevent crash in intro { cmd->angleturn = ticcmd_oldangleturn[forplayer]; cmd->aiming = G_ClipAimingPitch(myaiming); From 5093e9eb8eda42209d11c28c1f51f249da7a1280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Fri, 20 Dec 2024 18:04:49 +0100 Subject: [PATCH 19/38] Re-add gamestate check alongside addedtogame --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index ca02ac7e3..894063585 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1722,7 +1722,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // At this point, cmd doesn't contain the final angle yet, // So we need to temporarily transform it so Lua scripters // don't need to handle it differently than in other hooks. - if (addedtogame) + if (addedtogame && gamestate == GS_LEVEL) { INT16 extra = ticcmd_oldangleturn[forplayer] - player->oldrelangleturn; INT16 origangle = cmd->angleturn; From bc0735c02724f28050665814734869efda994ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 21 Dec 2024 12:33:00 +0100 Subject: [PATCH 20/38] Fix segfault due to leftover ztargetfocus when switching maps --- src/g_game.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 175e757ec..6f02fde3c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1867,6 +1867,10 @@ void G_DoLoadLevel(boolean resetplayer) if (gamestate == GS_INTERMISSION) Y_EndIntermission(); + // clear the target on map change, since the object will be invalidated + P_SetTarget(&ticcmd_ztargetfocus[0], NULL); + P_SetTarget(&ticcmd_ztargetfocus[1], NULL); + // cleanup if (titlemapinaction == TITLEMAP_LOADING) { From 90a23b8a8487a7f641521d2f0c3785ace0998b9b Mon Sep 17 00:00:00 2001 From: pastel Date: Sun, 22 Dec 2024 11:19:12 -0600 Subject: [PATCH 21/38] Increase ps_samplesize default value to 100 --- src/netcode/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 630999cd0..8376f26b9 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -391,7 +391,7 @@ static CV_PossibleValue_t perfstats_cons_t[] = { consvar_t cv_perfstats = CVAR_INIT ("perfstats", "Off", CV_CALL, perfstats_cons_t, PS_PerfStats_OnChange); static CV_PossibleValue_t ps_samplesize_cons_t[] = { {1, "MIN"}, {1000, "MAX"}, {0, NULL}}; -consvar_t cv_ps_samplesize = CVAR_INIT ("ps_samplesize", "1", CV_CALL, ps_samplesize_cons_t, PS_SampleSize_OnChange); +consvar_t cv_ps_samplesize = CVAR_INIT ("ps_samplesize", "175", CV_CALL, ps_samplesize_cons_t, PS_SampleSize_OnChange); static CV_PossibleValue_t ps_descriptor_cons_t[] = { {1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}}; consvar_t cv_ps_descriptor = CVAR_INIT ("ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL); From f27b2900d2b714ada30c7db9b67437b23e5a5351 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 23 Dec 2024 23:27:41 -0300 Subject: [PATCH 22/38] Fix plane offsets overflow in the software renderer --- src/r_plane.c | 57 ++++++++++++++++++++++++++++++-------------------- src/r_plane.h | 4 ++-- src/r_splats.c | 2 +- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 7642a4dd6..a0de048ea 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -83,7 +83,7 @@ static fixed_t planeheight; fixed_t yslopetab[MAXVIDHEIGHT*16]; fixed_t *yslope; -static fixed_t xoffs, yoffs; +static INT64 xoffs, yoffs; static dvector3_t slope_origin, slope_u, slope_v; static dvector3_t slope_lightu, slope_lightv; @@ -376,19 +376,25 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li visplane_t *check; unsigned hash; + float offset_xd = FixedToFloat(xoff) / FixedToFloat(xscale ? xscale : 1); + float offset_yd = FixedToFloat(yoff) / FixedToFloat(yscale ? yscale : 1); + + INT64 offset_x = offset_xd * FRACUNIT; + INT64 offset_y = offset_yd * FRACUNIT; + if (!slope) // Don't mess with this right now if a slope is involved { - xoff += FixedMul(viewx, xscale); - yoff -= FixedMul(viewy, yscale); + offset_x += viewx; + offset_y -= viewy; if (plangle != 0) { // Add the view offset, rotated by the plane angle. float ang = ANG2RAD(plangle); - float x = FixedToFloat(xoff); - float y = FixedToFloat(yoff); - xoff = FloatToFixed(x * cos(ang) + y * sin(ang)); - yoff = FloatToFixed(-x * sin(ang) + y * cos(ang)); + float x = offset_x / (float)FRACUNIT; + float y = offset_y / (float)FRACUNIT; + offset_x = (x * cos(ang) + y * sin(ang)) * FRACUNIT; + offset_y = (-x * sin(ang) + y * cos(ang)) * FRACUNIT; } } @@ -399,16 +405,19 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li float ang = ANG2RAD(polyobj->angle); float x = FixedToFloat(polyobj->centerPt.x); float y = FixedToFloat(polyobj->centerPt.y); - xoff -= FloatToFixed(x * cos(ang) + y * sin(ang)); - yoff -= FloatToFixed(x * sin(ang) - y * cos(ang)); + offset_x -= (x * cos(ang) + y * sin(ang)) * FRACUNIT; + offset_y -= (x * sin(ang) - y * cos(ang)) * FRACUNIT; } else { - xoff -= polyobj->centerPt.x; - yoff += polyobj->centerPt.y; + offset_x -= polyobj->centerPt.x; + offset_y += polyobj->centerPt.y; } } + offset_x = ((INT64)offset_x * xscale) / FRACUNIT; + offset_y = ((INT64)offset_y * yscale) / FRACUNIT; + // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) { @@ -423,7 +432,7 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li { if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel - && xoff == check->xoffs && yoff == check->yoffs + && offset_x == check->xoffs && offset_y == check->yoffs && xscale == check->xscale && yscale == check->yscale && planecolormap == check->extra_colormap && check->viewx == viewx && check->viewy == viewy && check->viewz == viewz @@ -449,8 +458,8 @@ visplane_t *R_FindPlane(sector_t *sector, fixed_t height, INT32 picnum, INT32 li check->lightlevel = lightlevel; check->minx = vid.width; check->maxx = -1; - check->xoffs = xoff; - check->yoffs = yoff; + check->xoffs = offset_x; + check->yoffs = offset_y; check->xscale = xscale; check->yscale = yscale; check->extra_colormap = planecolormap; @@ -658,13 +667,13 @@ static void R_DrawSkyPlane(visplane_t *pl) } // Returns the height of the sloped plane at (x, y) as a double -static double R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) +static double R_GetSlopeZAt(const pslope_t *slope, INT64 x, INT64 y) { // If you want to reimplement this using just the equation constants, use this instead: // (d + a*x + b*y) * -(1.0 / c) - double px = FixedToDouble(x) - slope->dorigin.x; - double py = FixedToDouble(y) - slope->dorigin.y; + double px = (x / (double)FRACUNIT) - slope->dorigin.x; + double py = (y / (double)FRACUNIT) - slope->dorigin.y; double dist = (px * slope->dnormdir.x) + (py * slope->dnormdir.y); @@ -672,10 +681,10 @@ static double R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) } // Sets the texture origin vector of the sloped plane. -static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle) +static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, INT64 xoff, INT64 yoff, fixed_t angle) { - INT64 vx = (INT64)xpos + (INT64)xoff; - INT64 vy = (INT64)ypos - (INT64)yoff; + INT64 vx = (INT64)xpos + xoff; + INT64 vy = (INT64)ypos - yoff; float vxf = vx / (float)FRACUNIT; float vyf = vy / (float)FRACUNIT; @@ -702,7 +711,7 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, slope->moved = false; } - R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); + R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, (INT64)xoff, (INT64)yoff, angle); height = R_GetSlopeZAt(slope, xpos, ypos); zeroheight = height - FixedToDouble(zpos); @@ -735,7 +744,7 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, } // This function calculates all of the vectors necessary for drawing a sloped and scaled plane. -void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) +void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, INT64 xoff, INT64 yoff, angle_t angle, angle_t plangle) { double height, z_at_xy; float ang; @@ -836,9 +845,11 @@ static void CalcSlopePlaneVectors(visplane_t *pl, fixed_t xoff, fixed_t yoff) { if (!ds_fog && (pl->xscale != FRACUNIT || pl->yscale != FRACUNIT)) { + float offset_x = FixedToFloat(xoff) / FixedToFloat(pl->xscale ? pl->xscale : 1); + float offset_y = FixedToFloat(yoff) / FixedToFloat(pl->yscale ? pl->yscale : 1); R_SetScaledSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, FixedDiv(FRACUNIT, pl->xscale), FixedDiv(FRACUNIT, pl->yscale), - FixedDiv(xoff, pl->xscale), FixedDiv(yoff, pl->yscale), pl->viewangle, pl->plangle); + (INT64)(offset_x * FRACUNIT), (INT64)(offset_y * FRACUNIT), pl->viewangle, pl->plangle); } else R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); diff --git a/src/r_plane.h b/src/r_plane.h index 69620f25e..cd9477501 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -48,7 +48,7 @@ typedef struct visplane_s UINT16 padbottomstart, bottom[MAXVIDWIDTH], padbottomend; INT32 high, low; // R_PlaneBounds should set these. - fixed_t xoffs, yoffs; // Scrolling flats. + INT64 xoffs, yoffs; // Scrolling flats. fixed_t xscale, yscale; sector_t *sector; @@ -85,7 +85,7 @@ void R_DrawSinglePlane(visplane_t *pl); // Calculates the slope vectors needed for tilted span drawing. void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); -void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); +void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, INT64 xoff, INT64 yoff, angle_t angle, angle_t plangle); typedef struct planemgr_s { diff --git a/src/r_splats.c b/src/r_splats.c index 813c4b243..ce35a35b4 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -381,7 +381,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (pSplat->slope) { - R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); + R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, (INT64)pSplat->xscale, (INT64)pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); } else if (!ds_solidcolor) { From be7c2d9dd31feb33558c72799ef77faf2fcafb76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 29 Dec 2024 12:57:42 +0100 Subject: [PATCH 23/38] Reset target focus in P_LoadLevel instead --- src/g_game.c | 4 ---- src/p_setup.c | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 6f02fde3c..175e757ec 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1867,10 +1867,6 @@ void G_DoLoadLevel(boolean resetplayer) if (gamestate == GS_INTERMISSION) Y_EndIntermission(); - // clear the target on map change, since the object will be invalidated - P_SetTarget(&ticcmd_ztargetfocus[0], NULL); - P_SetTarget(&ticcmd_ztargetfocus[1], NULL); - // cleanup if (titlemapinaction == TITLEMAP_LOADING) { diff --git a/src/p_setup.c b/src/p_setup.c index 93286219d..a62e287ac 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7853,6 +7853,10 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) maptol = mapheaderinfo[gamemap-1]->typeoflevel; gametyperules = gametypedefaultrules[gametype]; + // clear the target on map change, since the object will be invalidated + P_SetTarget(&ticcmd_ztargetfocus[0], NULL); + P_SetTarget(&ticcmd_ztargetfocus[1], NULL); + CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer From 4fdb2f6b0888c165ae70a46f8e2d5cb59a090a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 29 Dec 2024 13:42:36 +0100 Subject: [PATCH 24/38] Fix segfault when switching perfstats screen before sampling is done --- src/m_perfstats.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 0a52b0125..33a774acf 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -453,7 +453,7 @@ static int PS_DrawPerfRows(int x, int y, int color, perfstatrow_t *rows) return draw_y; } -static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boolean frame_metric, boolean set_user) +static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boolean frame_metric) { int index = frame_metric ? ps_frame_index : ps_tick_index; @@ -461,7 +461,7 @@ static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boo { // allocate history table int value_size = time_metric ? sizeof(precise_t) : sizeof(INT32); - void** memory_user = set_user ? &metric->history : NULL; + void** memory_user = &metric->history; metric->history = Z_Calloc(value_size * cv_ps_samplesize.value, PU_PERFSTATS, memory_user); @@ -491,7 +491,7 @@ static void PS_UpdateRowHistories(perfstatrow_t *rows, boolean frame_metric) for (row = rows; row->lores_label; row++) { if (PS_IsRowValid(row)) - PS_UpdateMetricHistory(row->metric, !!(row->flags & PS_TIME), frame_metric, true); + PS_UpdateMetricHistory(row->metric, !!(row->flags & PS_TIME), frame_metric); } } @@ -649,17 +649,17 @@ void PS_UpdateTickStats(void) if (cv_perfstats.value == 3) { for (i = 0; i < thinkframe_hooks_length; i++) - PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false, false); + PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false); } else if (cv_perfstats.value == 4) { for (i = 0; i < prethinkframe_hooks_length; i++) - PS_UpdateMetricHistory(&prethinkframe_hooks[i].time_taken, true, false, false); + PS_UpdateMetricHistory(&prethinkframe_hooks[i].time_taken, true, false); } else if (cv_perfstats.value == 5) { for (i = 0; i < postthinkframe_hooks_length; i++) - PS_UpdateMetricHistory(&postthinkframe_hooks[i].time_taken, true, false, false); + PS_UpdateMetricHistory(&postthinkframe_hooks[i].time_taken, true, false); } } if (cv_perfstats.value) From 91d1c11617c75f71eaad1c823902d9872caafd78 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 30 Dec 2024 00:03:41 +0100 Subject: [PATCH 25/38] Fix io.open() crashing the client sometimes --- src/netcode/d_netfil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index adec1a0e4..362979b0c 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -606,7 +606,7 @@ void AddLuaFileTransfer(const char *filename, const char *mode) prevnext = &((*prevnext)->next); // Allocate file transfer information and append it to the transfer list - filetransfer = malloc(sizeof(luafiletransfer_t)); + filetransfer = calloc(1, sizeof(luafiletransfer_t)); if (!filetransfer) I_Error("AddLuaFileTransfer: Out of memory\n"); *prevnext = filetransfer; From 770ee7b53cc5c3d5c451c430e8a95667757f708a Mon Sep 17 00:00:00 2001 From: Hanicef Date: Fri, 16 Feb 2024 18:04:55 +0100 Subject: [PATCH 26/38] Put HTTP downloading on a background thread --- src/netcode/client_connection.c | 5 +- src/netcode/d_netfil.c | 139 +++++++++++++++++--------------- src/netcode/d_netfil.h | 1 + 3 files changed, 77 insertions(+), 68 deletions(-) diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c index 917e32b59..c740d53a6 100644 --- a/src/netcode/client_connection.c +++ b/src/netcode/client_connection.c @@ -546,6 +546,7 @@ static void AbortConnection(void) { Snake_Free(&snake); + CURLAbortFile(); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -1062,10 +1063,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic } } - // Rusty TODO: multithread - if (filedownload.http_running) - CURLGetFile(); - if (waitmore) break; // exit the case diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index 362979b0c..ee1f7a9b2 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -1672,6 +1672,8 @@ boolean CURLPrepareFile(const char* url, int dfilenum) filedownload.current = dfilenum; filedownload.http_running = true; + I_spawn_thread("http-download", (I_thread_fn)CURLGetFile, NULL); + return true; } @@ -1680,95 +1682,103 @@ boolean CURLPrepareFile(const char* url, int dfilenum) return false; } +void CURLAbortFile(void) +{ + filedownload.http_running = false; +} + void CURLGetFile(void) { CURLMcode mc; /* return code used by curl_multi_wait() */ CURLcode easyres; /* Return from easy interface */ - int numfds; CURLMsg *m; /* for picking up messages with the transfer status */ CURL *e; int msgs_left; /* how many messages are left */ const char *easy_handle_error; + boolean running = true; - if (curl_runninghandles) + while (running && filedownload.http_running) { - curl_multi_perform(multi_handle, &curl_runninghandles); - - /* wait for activity, timeout or "nothing" */ - mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds); - - if (mc != CURLM_OK) + if (curl_runninghandles) { - CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc); - return; + curl_multi_perform(multi_handle, &curl_runninghandles); + + /* 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); + continue; + } + curl_curfile->currentsize = curl_dlnow; + curl_curfile->totalsize = curl_dltotal; } - curl_curfile->currentsize = curl_dlnow; - curl_curfile->totalsize = curl_dltotal; - } - /* See how the transfers went */ - while ((m = curl_multi_info_read(multi_handle, &msgs_left))) - { - if (m && (m->msg == CURLMSG_DONE)) + /* See how the transfers went */ + while ((m = curl_multi_info_read(multi_handle, &msgs_left))) { - e = m->easy_handle; - easyres = m->data.result; - - char *filename = Z_StrDup(curl_realname); - nameonly(filename); - - if (easyres != CURLE_OK) + if (m && (m->msg == CURLMSG_DONE)) { - long response_code = 0; + running = false; + e = m->easy_handle; + easyres = m->data.result; - if (easyres == CURLE_HTTP_RETURNED_ERROR) - curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code); + char *filename = Z_StrDup(curl_realname); + nameonly(filename); - if (response_code == 404) - curl_curfile->failed = FDOWNLOAD_FAIL_NOTFOUND; - else - curl_curfile->failed = FDOWNLOAD_FAIL_OTHER; - - easy_handle_error = (response_code) ? va("HTTP response code %ld", response_code) : curl_easy_strerror(easyres); - curl_curfile->status = FS_FALLBACK; - curl_curfile->currentsize = curl_origfilesize; - curl_curfile->totalsize = curl_origtotalfilesize; - filedownload.http_failed = true; - fclose(curl_curfile->file); - remove(curl_curfile->filename); - CONS_Alert(CONS_ERROR, M_GetText("Failed to download addon \"%s\" (%s)\n"), filename, easy_handle_error); - } - else - { - fclose(curl_curfile->file); - - CONS_Printf(M_GetText("Finished download of \"%s\"\n"), filename); - - if (checkfilemd5(curl_curfile->filename, curl_curfile->md5sum) == FS_MD5SUMBAD) + if (easyres != CURLE_OK) { - CONS_Alert(CONS_WARNING, M_GetText("File \"%s\" does not match the version used by the server\n"), filename); + long response_code = 0; + + if (easyres == CURLE_HTTP_RETURNED_ERROR) + curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code); + + if (response_code == 404) + curl_curfile->failed = FDOWNLOAD_FAIL_NOTFOUND; + else + curl_curfile->failed = FDOWNLOAD_FAIL_OTHER; + + easy_handle_error = (response_code) ? va("HTTP response code %ld", response_code) : curl_easy_strerror(easyres); curl_curfile->status = FS_FALLBACK; - curl_curfile->failed = FDOWNLOAD_FAIL_MD5SUMBAD; + curl_curfile->currentsize = curl_origfilesize; + curl_curfile->totalsize = curl_origtotalfilesize; filedownload.http_failed = true; + fclose(curl_curfile->file); + remove(curl_curfile->filename); + CONS_Alert(CONS_ERROR, M_GetText("Failed to download addon \"%s\" (%s)\n"), filename, easy_handle_error); } else { - filedownload.completednum++; - filedownload.completedsize += curl_curfile->totalsize; - curl_curfile->status = FS_FOUND; + fclose(curl_curfile->file); + + CONS_Printf(M_GetText("Finished download of \"%s\"\n"), filename); + + if (checkfilemd5(curl_curfile->filename, curl_curfile->md5sum) == FS_MD5SUMBAD) + { + CONS_Alert(CONS_WARNING, M_GetText("File \"%s\" does not match the version used by the server\n"), filename); + curl_curfile->status = FS_FALLBACK; + curl_curfile->failed = FDOWNLOAD_FAIL_MD5SUMBAD; + filedownload.http_failed = true; + } + else + { + filedownload.completednum++; + filedownload.completedsize += curl_curfile->totalsize; + curl_curfile->status = FS_FOUND; + } } + + Z_Free(filename); + + curl_curfile->file = NULL; + filedownload.remaining--; + curl_multi_remove_handle(multi_handle, e); + curl_easy_cleanup(e); + + if (!filedownload.remaining) + break; } - - Z_Free(filename); - - curl_curfile->file = NULL; - filedownload.http_running = false; - filedownload.remaining--; - curl_multi_remove_handle(multi_handle, e); - curl_easy_cleanup(e); - - if (!filedownload.remaining) - break; } } @@ -1777,6 +1787,7 @@ void CURLGetFile(void) curl_multi_cleanup(multi_handle); curl_global_cleanup(); } + filedownload.http_running = false; } HTTP_login * diff --git a/src/netcode/d_netfil.h b/src/netcode/d_netfil.h index 4039b5e2d..9f29d18bb 100644 --- a/src/netcode/d_netfil.h +++ b/src/netcode/d_netfil.h @@ -140,6 +140,7 @@ boolean CL_SendFileRequest(void); void PT_RequestFile(SINT8 node); boolean CURLPrepareFile(const char* url, int dfilenum); +void CURLAbortFile(void); void CURLGetFile(void); HTTP_login * CURLGetLogin (const char *url, HTTP_login ***return_prev_next); From c04dd70a433edb19055d7d1e8b50fcbb954a9465 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Fri, 16 Feb 2024 18:38:40 +0100 Subject: [PATCH 27/38] Avoid double initialization of CURL --- src/netcode/d_netfil.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index ee1f7a9b2..da3a8727b 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -1609,11 +1609,13 @@ boolean CURLPrepareFile(const char* url, int dfilenum) I_Error("Attempted to download files in -nodownload mode"); #endif - curl_global_init(CURL_GLOBAL_ALL); + if (!multi_handle) + { + curl_global_init(CURL_GLOBAL_ALL); + multi_handle = curl_multi_init(); + } http_handle = curl_easy_init(); - multi_handle = curl_multi_init(); - if (http_handle && multi_handle) { I_mkdir(downloaddir, 0755); @@ -1782,10 +1784,11 @@ void CURLGetFile(void) } } - if (!filedownload.remaining) + if (!filedownload.remaining || !filedownload.http_running) { curl_multi_cleanup(multi_handle); curl_global_cleanup(); + multi_handle = NULL; } filedownload.http_running = false; } From 93d48ca97e59fc045b566f320d5c5bed5e0771fb Mon Sep 17 00:00:00 2001 From: Hanicef Date: Mon, 30 Dec 2024 17:12:56 +0100 Subject: [PATCH 28/38] Fix segfault when aborting HTTP download --- src/netcode/d_netfil.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index da3a8727b..313905f43 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -95,6 +95,7 @@ static filetran_t transfer[MAXNETNODES]; INT32 fileneedednum; // Number of files needed to join the server fileneeded_t *fileneeded; // List of needed files static tic_t lasttimeackpacketsent = 0; +static I_mutex downloadmutex; char downloaddir[512] = "DOWNLOAD"; // For resuming failed downloads @@ -1687,10 +1688,15 @@ boolean CURLPrepareFile(const char* url, int dfilenum) void CURLAbortFile(void) { filedownload.http_running = false; + + // lock and unlock to wait for the download thread to exit + I_lock_mutex(&downloadmutex); + I_unlock_mutex(downloadmutex); } void CURLGetFile(void) { + I_lock_mutex(&downloadmutex); CURLMcode mc; /* return code used by curl_multi_wait() */ CURLcode easyres; /* Return from easy interface */ CURLMsg *m; /* for picking up messages with the transfer status */ @@ -1791,6 +1797,7 @@ void CURLGetFile(void) multi_handle = NULL; } filedownload.http_running = false; + I_unlock_mutex(downloadmutex); } HTTP_login * From 9eecedf3ae292f4cf4fcd2ab3330f9be0a22b251 Mon Sep 17 00:00:00 2001 From: pastel Date: Tue, 31 Dec 2024 14:05:51 -0600 Subject: [PATCH 29/38] Fix being unable to use CTRL keyboard shortcuts on menu input fields --- src/m_menu.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 88a69b5a5..15442cf17 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3399,6 +3399,13 @@ boolean M_Responder(event_t *ev) // Handle menuitems which need a specific key handling if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER) { + // block text input if ctrl is held, to allow using ctrl+c ctrl+v and ctrl+x + if (ctrldown) + { + routine(ch); + return true; + } + // ignore ev_keydown events if the key maps to a character, since // the ev_text event will follow immediately after in that case. if (ev->type == ev_keydown && ((ch >= 32 && ch <= 127) || (ch >= KEY_KEYPAD7 && ch <= KEY_KPADDEL))) @@ -12116,8 +12123,7 @@ static void M_HandleConnectIP(INT32 choice) if ( ctrldown ) { switch (choice) { - case 'v': - case 'V': // ctrl+v, pasting + case 'v': // ctrl+v, pasting { const char *paste = I_ClipboardPaste(); @@ -12130,8 +12136,7 @@ static void M_HandleConnectIP(INT32 choice) break; } case KEY_INS: - case 'c': - case 'C': // ctrl+c, ctrl+insert, copying + case 'c': // ctrl+c, ctrl+insert, copying if (l != 0) // Don't replace the clipboard without any text { I_ClipboardCopy(setupm_ip, l); @@ -12139,8 +12144,7 @@ static void M_HandleConnectIP(INT32 choice) } break; - case 'x': - case 'X': // ctrl+x, cutting + case 'x': // ctrl+x, cutting if (l != 0) // Don't replace the clipboard without any text { I_ClipboardCopy(setupm_ip, l); From f3f3fafdc4f19f7289801614ee779cabf2f92a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 4 Jan 2025 18:27:11 +0100 Subject: [PATCH 30/38] Fix buffer overflow when reading string from R_TextureNameForNum into Lua --- src/lua_baselib.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 19775eb8a..18ae53405 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3181,17 +3181,25 @@ static int lib_rTextureNumForName(lua_State *L) static int lib_rCheckTextureNameForNum(lua_State *L) { + char s[9]; INT32 num = (INT32)luaL_checkinteger(L, 1); //HUDSAFE - lua_pushstring(L, R_CheckTextureNameForNum(num)); + + M_Memcpy(s, R_CheckTextureNameForNum(num), 8); + s[8] = '\0'; + lua_pushstring(L, s); return 1; } static int lib_rTextureNameForNum(lua_State *L) { + char s[9]; INT32 num = (INT32)luaL_checkinteger(L, 1); //HUDSAFE - lua_pushstring(L, R_TextureNameForNum(num)); + + M_Memcpy(s, R_TextureNameForNum(num), 8); + s[8] = '\0'; + lua_pushstring(L, s); return 1; } From c00d139e556c7231aeb5ed61cd4c9999866f5a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 4 Jan 2025 20:12:00 +0100 Subject: [PATCH 31/38] Further improve sleep accuracy on UNIX systems --- src/sdl/i_system.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 07088b957..4d62c4287 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2309,13 +2309,21 @@ void I_SleepDuration(precise_t duration) { #if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) UINT64 precision = I_GetPrecisePrecision(); - struct timespec ts = { - .tv_sec = duration / precision, - .tv_nsec = duration * 1000000000 / precision % 1000000000, - }; - int status; - do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); - while (status == EINTR); + precise_t dest = I_GetPreciseTime() + duration; + if (duration > 100000) + { + duration -= 100000; // 0.1 ms slack + struct timespec ts = { + .tv_sec = duration / precision, + .tv_nsec = duration * 1000000000 / precision % 1000000000, + }; + int status; + do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); + while (status == EINTR); + } + + // busy-wait the rest + while (((INT64)dest - (INT64)I_GetPreciseTime()) > 0); #elif defined (MIN_SLEEP_DURATION_MS) UINT64 precision = I_GetPrecisePrecision(); INT32 sleepvalue = cv_sleep.value; From d20552c49d9fd6a2075ebd7d46b0b133c69f1dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 5 Jan 2025 15:58:18 +0100 Subject: [PATCH 32/38] Adjust slack based on precision --- src/sdl/i_system.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 4d62c4287..18a5cb46d 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2310,9 +2310,9 @@ void I_SleepDuration(precise_t duration) #if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) UINT64 precision = I_GetPrecisePrecision(); precise_t dest = I_GetPreciseTime() + duration; - if (duration > 100000) + if (duration * 100000 / precision > 1) { - duration -= 100000; // 0.1 ms slack + duration -= (precision / 10000); // 0.1 ms slack struct timespec ts = { .tv_sec = duration / precision, .tv_nsec = duration * 1000000000 / precision % 1000000000, From 1da55066d43ed6a0cb666999c20316bef463024b Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sun, 5 Jan 2025 19:18:57 +0100 Subject: [PATCH 33/38] Slight optimization --- src/sdl/i_system.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 18a5cb46d..f32d97e22 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2310,9 +2310,10 @@ void I_SleepDuration(precise_t duration) #if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) UINT64 precision = I_GetPrecisePrecision(); precise_t dest = I_GetPreciseTime() + duration; - if (duration * 100000 / precision > 1) + precise_t slack = (precision / 10000); // 0.1 ms slack + if (duration > slack) { - duration -= (precision / 10000); // 0.1 ms slack + duration -= slack; struct timespec ts = { .tv_sec = duration / precision, .tv_nsec = duration * 1000000000 / precision % 1000000000, From fb80091ac322c8a41bf8b983499596b5eec356b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 6 Jan 2025 09:49:04 +0100 Subject: [PATCH 34/38] Double slack time for busy-wait --- src/dedicated/i_system.c | 23 ++++++++++++++++------- src/sdl/i_system.c | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 23c0149ca..79cdd9bb6 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -376,13 +376,22 @@ void I_SleepDuration(precise_t duration) { #if defined(__linux__) || defined(__FreeBSD__) UINT64 precision = I_GetPrecisePrecision(); - struct timespec ts = { - .tv_sec = duration / precision, - .tv_nsec = duration * 1000000000 / precision % 1000000000, - }; - int status; - do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); - while (status == EINTR); + precise_t dest = I_GetPreciseTime() + duration; + precise_t slack = (precision / 5000); // 0.2 ms slack + if (duration > slack) + { + duration -= slack; + struct timespec ts = { + .tv_sec = duration / precision, + .tv_nsec = duration * 1000000000 / precision % 1000000000, + }; + int status; + do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts); + while (status == EINTR); + } + + // busy-wait the rest + while (((INT64)dest - (INT64)I_GetPreciseTime()) > 0); #else UINT64 precision = I_GetPrecisePrecision(); INT32 sleepvalue = cv_sleep.value; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index f32d97e22..f78f74d57 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2310,7 +2310,7 @@ void I_SleepDuration(precise_t duration) #if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) UINT64 precision = I_GetPrecisePrecision(); precise_t dest = I_GetPreciseTime() + duration; - precise_t slack = (precision / 10000); // 0.1 ms slack + precise_t slack = (precision / 5000); // 0.2 ms slack if (duration > slack) { duration -= slack; From ddc1c63fc637030576f8d45d27fe8ba5f836baa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?chromaticpipe=20=E2=80=8E?= Date: Wed, 8 Jan 2025 22:31:20 +0000 Subject: [PATCH 35/38] register slope contrast cvar so it actually works --- src/hardware/hw_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index da8965454..e426bcddd 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5794,6 +5794,7 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glskydome); CV_RegisterVar(&cv_glspritebillboarding); CV_RegisterVar(&cv_glfakecontrast); + CV_RegisterVar(&cv_glslopecontrast); CV_RegisterVar(&cv_glshearing); CV_RegisterVar(&cv_glshaders); From 3b1711c02820cf0c65faf5b81ff38ad608e411f7 Mon Sep 17 00:00:00 2001 From: "Spectrum (Jonathan Dove)" <763-spectrumuk2@users.noreply.git.do.srb2.org> Date: Fri, 10 Jan 2025 03:02:30 +0000 Subject: [PATCH 36/38] Extra resolutions --- src/sdl/i_video.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 36bfd380f..68e65a975 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -87,7 +87,7 @@ #endif // maximum number of windowed modes (see windowedModes[][]) -#define MAXWINMODES (18) +#define MAXWINMODES (21) /** \brief */ @@ -157,7 +157,9 @@ static INT32 windowedModes[MAXWINMODES][2] = {1920,1080}, // 1.66 {1680,1050}, // 1.60,5.25 {1600,1200}, // 1.33 + {1600,1000}, // 1.60,5.00 {1600, 900}, // 1.66 + {1536, 864}, // 1.66,4.80 {1366, 768}, // 1.66 {1440, 900}, // 1.60,4.50 {1280,1024}, // 1.33? @@ -166,6 +168,7 @@ static INT32 windowedModes[MAXWINMODES][2] = {1280, 720}, // 1.66 {1152, 864}, // 1.33,3.60 {1024, 768}, // 1.33,3.20 + { 960, 600}, // 1.60,3.00 { 800, 600}, // 1.33,2.50 { 640, 480}, // 1.33,2.00 { 640, 400}, // 1.60,2.00 From 819ecb0152262f346fc0f9f87df7b6e26f2e6b07 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Fri, 10 Jan 2025 03:37:58 +0000 Subject: [PATCH 37/38] Fix issues with custom pause menu binds --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 15442cf17..afc45fcf0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3318,7 +3318,7 @@ boolean M_Responder(event_t *ev) if (ch == -1) return false; - else if (ch == gamecontrol[GC_SYSTEMMENU][0] || ch == gamecontrol[GC_SYSTEMMENU][1]) // allow remappable ESC key + else if (ev->type != ev_text && (ch == gamecontrol[GC_SYSTEMMENU][0] || ch == gamecontrol[GC_SYSTEMMENU][1])) // allow remappable ESC key ch = KEY_ESCAPE; // F-Keys @@ -3436,7 +3436,7 @@ boolean M_Responder(event_t *ev) { // dirty hack: for customising controls, I want only buttons/keys, not moves if (ev->type == ev_mouse || ev->type == ev_mouse2 || ev->type == ev_joystick - || ev->type == ev_joystick2) + || ev->type == ev_joystick2 || ev->type == ev_text) return true; if (routine) { From 1bb51b0ed3e89211a41d57974fcd49ce8ab0e470 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sat, 11 Jan 2025 13:12:08 +0000 Subject: [PATCH 38/38] Revert "Merge branch 'slopecontrast-fix' into 'next'" This reverts merge request !2585 --- src/hardware/hw_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e426bcddd..da8965454 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5794,7 +5794,6 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glskydome); CV_RegisterVar(&cv_glspritebillboarding); CV_RegisterVar(&cv_glfakecontrast); - CV_RegisterVar(&cv_glslopecontrast); CV_RegisterVar(&cv_glshearing); CV_RegisterVar(&cv_glshaders);