From 50a34d85ddfe5769c8495bd7b37554c24630ef28 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 26 Dec 2022 21:06:46 -0600 Subject: [PATCH 01/74] Clean up the backtrace code and make it use write() more safely. --- src/sdl/i_system.c | 78 +++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index e328bedc2..076134d0a 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -258,68 +258,82 @@ SDL_bool framebuffer = SDL_FALSE; UINT8 keyboard_started = false; #ifdef UNIXBACKTRACE -#define STDERR_WRITE(string) if (fd != -1) I_OutputMsg("%s", string) -#define CRASHLOG_WRITE(string) if (fd != -1) write(fd, string, strlen(string)) -#define CRASHLOG_STDERR_WRITE(string) \ - if (fd != -1)\ - write(fd, string, strlen(string));\ - I_OutputMsg("%s", string) + +// NOTE: if written ends up ever being -1, all further writes end up being cancelled. +// i figure an error is a reason to stop writing... +#define WRITE_FILE(string) \ + sourcelen = strlen(string); \ + while (fd != -1 && (written != -1 && errno != EINTR) && written < sourcelen) \ + written = write(fd, string, sourcelen); + +#define WRITE_STDERR(string) \ + I_OutputMsg("%s", string); + +#define WRITE_ALL(string) \ + WRITE_FILE(string); \ + WRITE_STDERR(string); static void write_backtrace(INT32 signal) { int fd = -1; - size_t size; + ssize_t written = 0; + ssize_t sourcelen = 0; time_t rawtime; struct tm timeinfo; + size_t size; enum { BT_SIZE = 1024, STR_SIZE = 32 }; - void *array[BT_SIZE]; + void *funcptrs[BT_SIZE]; char timestr[STR_SIZE]; - const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n"; - const char *error2 = "(Or find crash-log.txt in your SRB2 directory.)\n"; // Shown only to stderr. + const char *filename = va("%s" PATHSEP "%s", srb2home, "crash-log.txt"); - fd = open(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR); + fd = open(filename, O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR); - if (fd == -1) - I_OutputMsg("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n"); + if (fd == -1) // File handle error + WRITE_STDERR("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n"); // Get the current time as a string. time(&rawtime); localtime_r(&rawtime, &timeinfo); strftime(timestr, STR_SIZE, "%a, %d %b %Y %T %z", &timeinfo); - CRASHLOG_WRITE("------------------------\n"); // Nice looking seperator + WRITE_FILE("------------------------\n"); // Nice looking seperator - CRASHLOG_STDERR_WRITE("\n"); // Newline to look nice for both outputs. - CRASHLOG_STDERR_WRITE(error); // "Oops, SRB2 crashed" message - STDERR_WRITE(error2); // Tell the user where the crash log is. + WRITE_ALL("\n"); // Newline to look nice for both outputs. + WRITE_ALL("An error occurred within SRB2! Send this stack trace to someone who can help!\n"); + + if (fd != -1) // If the crash log exists, + WRITE_STDERR("(Or find crash-log.txt in your SRB2 directory.)\n"); // tell the user where the crash log is. // Tell the log when we crashed. - CRASHLOG_WRITE("Time of crash: "); - CRASHLOG_WRITE(timestr); - CRASHLOG_WRITE("\n"); + WRITE_FILE("Time of crash: "); + WRITE_FILE(timestr); + WRITE_FILE("\n"); // Give the crash log the cause and a nice 'Backtrace:' thing // The signal is given to the user when the parent process sees we crashed. - CRASHLOG_WRITE("Cause: "); - CRASHLOG_WRITE(strsignal(signal)); - CRASHLOG_WRITE("\n"); // Newline for the signal name + WRITE_FILE("Cause: "); + WRITE_FILE(strsignal(signal)); + WRITE_FILE("\n"); // Newline for the signal name - CRASHLOG_STDERR_WRITE("\nBacktrace:\n"); + WRITE_ALL("\nBacktrace:\n"); // Flood the output and log with the backtrace - size = backtrace(array, BT_SIZE); - backtrace_symbols_fd(array, size, fd); - backtrace_symbols_fd(array, size, STDERR_FILENO); + size = backtrace(funcptrs, BT_SIZE); + backtrace_symbols_fd(funcptrs, size, fd); + backtrace_symbols_fd(funcptrs, size, STDERR_FILENO); - CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :) + WRITE_FILE("\n"); // Write another newline to the log so it looks nice :) - close(fd); + if (fd != -1) { + fsync(fd); // reaaaaally make sure we got that data written. + close(fd); + } } -#undef STDERR_WRITE -#undef CRASHLOG_WRITE -#undef CRASHLOG_STDERR_WRITE +#undef WRITE_FILE +#undef WRITE_STDERR +#undef WRITE_ALL #endif // UNIXBACKTRACE static void I_ReportSignal(int num, int coredumped) From c5e69fcf94c8e3296b567a56efb9aca66352564d Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 13 Apr 2023 01:19:12 -0500 Subject: [PATCH 02/74] Replace macros with static functions, rename size int to bt_size. --- src/sdl/i_system.c | 63 +++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 076134d0a..d4055ba26 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -259,28 +259,29 @@ UINT8 keyboard_started = false; #ifdef UNIXBACKTRACE -// NOTE: if written ends up ever being -1, all further writes end up being cancelled. -// i figure an error is a reason to stop writing... -#define WRITE_FILE(string) \ - sourcelen = strlen(string); \ - while (fd != -1 && (written != -1 && errno != EINTR) && written < sourcelen) \ +static void bt_write_file(int fd, const char *string) { + ssize_t written = 0; + ssize_t sourcelen = strlen(string); + + while (fd != -1 && (written != -1 && errno != EINTR) && written < sourcelen) written = write(fd, string, sourcelen); +} -#define WRITE_STDERR(string) \ - I_OutputMsg("%s", string); +static void bt_write_stderr(const char *string) { + bt_write_file(STDERR_FILENO, string); +} -#define WRITE_ALL(string) \ - WRITE_FILE(string); \ - WRITE_STDERR(string); +static void bt_write_all(int fd, const char *string) { + bt_write_file(fd, string); + bt_write_file(STDERR_FILENO, string); +} static void write_backtrace(INT32 signal) { int fd = -1; - ssize_t written = 0; - ssize_t sourcelen = 0; time_t rawtime; struct tm timeinfo; - size_t size; + size_t bt_size; enum { BT_SIZE = 1024, STR_SIZE = 32 }; void *funcptrs[BT_SIZE]; @@ -291,49 +292,47 @@ static void write_backtrace(INT32 signal) fd = open(filename, O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR); if (fd == -1) // File handle error - WRITE_STDERR("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n"); + bt_write_stderr("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n"); // Get the current time as a string. time(&rawtime); localtime_r(&rawtime, &timeinfo); strftime(timestr, STR_SIZE, "%a, %d %b %Y %T %z", &timeinfo); - WRITE_FILE("------------------------\n"); // Nice looking seperator + bt_write_file(fd, "------------------------\n"); // Nice looking seperator - WRITE_ALL("\n"); // Newline to look nice for both outputs. - WRITE_ALL("An error occurred within SRB2! Send this stack trace to someone who can help!\n"); + bt_write_all(fd, "\n"); // Newline to look nice for both outputs. + bt_write_all(fd, "An error occurred within SRB2! Send this stack trace to someone who can help!\n"); if (fd != -1) // If the crash log exists, - WRITE_STDERR("(Or find crash-log.txt in your SRB2 directory.)\n"); // tell the user where the crash log is. + bt_write_stderr("(Or find crash-log.txt in your SRB2 directory.)\n"); // tell the user where the crash log is. // Tell the log when we crashed. - WRITE_FILE("Time of crash: "); - WRITE_FILE(timestr); - WRITE_FILE("\n"); + bt_write_file(fd, "Time of crash: "); + bt_write_file(fd, timestr); + bt_write_file(fd, "\n"); // Give the crash log the cause and a nice 'Backtrace:' thing // The signal is given to the user when the parent process sees we crashed. - WRITE_FILE("Cause: "); - WRITE_FILE(strsignal(signal)); - WRITE_FILE("\n"); // Newline for the signal name + bt_write_file(fd, "Cause: "); + bt_write_file(fd, strsignal(signal)); + bt_write_file(fd, "\n"); // Newline for the signal name - WRITE_ALL("\nBacktrace:\n"); + bt_write_all(fd, "\nBacktrace:\n"); // Flood the output and log with the backtrace - size = backtrace(funcptrs, BT_SIZE); - backtrace_symbols_fd(funcptrs, size, fd); - backtrace_symbols_fd(funcptrs, size, STDERR_FILENO); + bt_size = backtrace(funcptrs, BT_SIZE); + backtrace_symbols_fd(funcptrs, bt_size, fd); + backtrace_symbols_fd(funcptrs, bt_size, STDERR_FILENO); - WRITE_FILE("\n"); // Write another newline to the log so it looks nice :) + bt_write_file(fd, "\n"); // Write another newline to the log so it looks nice :) if (fd != -1) { fsync(fd); // reaaaaally make sure we got that data written. close(fd); } } -#undef WRITE_FILE -#undef WRITE_STDERR -#undef WRITE_ALL + #endif // UNIXBACKTRACE static void I_ReportSignal(int num, int coredumped) From 5e2311c48db8c409e2571e8377e2f178fa4f7726 Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Tue, 2 Jan 2024 22:03:51 -0500 Subject: [PATCH 03/74] Update i_system.c removed CRASHLOG_STDERR_WRITE --- src/sdl/i_system.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 2307961d2..ca68d031a 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -339,14 +339,6 @@ static void write_backtrace(INT32 signal) bt_size = backtrace(funcptrs, BT_SIZE); backtrace_symbols_fd(funcptrs, bt_size, fd); backtrace_symbols_fd(funcptrs, bt_size, STDERR_FILENO); -#ifndef NOEXECINFO - CRASHLOG_STDERR_WRITE("\nBacktrace:\n"); - - // Flood the output and log with the backtrace - size = backtrace(array, BT_SIZE); - backtrace_symbols_fd(array, size, fd); - backtrace_symbols_fd(array, size, STDERR_FILENO); -#endif bt_write_file(fd, "\n"); // Write another newline to the log so it looks nice :) if (fd != -1) { From eae89efbb92574b325710c9a9f61cee313203f95 Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Tue, 2 Jan 2024 22:06:00 -0500 Subject: [PATCH 04/74] Update i_system.c remove unused size_t size remove unused void *array[BT_SIZE]; --- src/sdl/i_system.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index ca68d031a..6e6031f4e 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -288,18 +288,12 @@ static void bt_write_all(int fd, const char *string) { static void write_backtrace(INT32 signal) { int fd = -1; -#ifndef NOEXECINFO - size_t size; -#endif time_t rawtime; struct tm timeinfo; size_t bt_size; enum { BT_SIZE = 1024, STR_SIZE = 32 }; void *funcptrs[BT_SIZE]; -#ifndef NOEXECINFO - void *array[BT_SIZE]; -#endif char timestr[STR_SIZE]; const char *filename = va("%s" PATHSEP "%s", srb2home, "crash-log.txt"); From 4fddc8fec71d9c6fd4915895b00fb6b20f6d4622 Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Tue, 2 Jan 2024 22:23:52 -0500 Subject: [PATCH 05/74] Update i_system.c backtrace() doesn't exist in non-glibc systems --- src/sdl/i_system.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 6e6031f4e..bc21134da 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -290,10 +290,12 @@ static void write_backtrace(INT32 signal) int fd = -1; time_t rawtime; struct tm timeinfo; - size_t bt_size; enum { BT_SIZE = 1024, STR_SIZE = 32 }; +#ifndef NOEXECINFO void *funcptrs[BT_SIZE]; + size_t bt_size; +#endif char timestr[STR_SIZE]; const char *filename = va("%s" PATHSEP "%s", srb2home, "crash-log.txt"); @@ -327,12 +329,16 @@ static void write_backtrace(INT32 signal) bt_write_file(fd, strsignal(signal)); bt_write_file(fd, "\n"); // Newline for the signal name +#ifdef NOEXECINFO + bt_write_all(fd, "\nNo Backtrace support\n"); +#else bt_write_all(fd, "\nBacktrace:\n"); // Flood the output and log with the backtrace bt_size = backtrace(funcptrs, BT_SIZE); backtrace_symbols_fd(funcptrs, bt_size, fd); backtrace_symbols_fd(funcptrs, bt_size, STDERR_FILENO); +#endif bt_write_file(fd, "\n"); // Write another newline to the log so it looks nice :) if (fd != -1) { From e892cc1d4b7fcfa5abe9359f7506ca97e501504c Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 1 Feb 2024 18:57:55 +0100 Subject: [PATCH 06/74] Fix FOFs with transferline flag and many linedefs randomly crashing linenum could go out of bounds if you use more than 4 linedefs for such setup, hence making the game unable to retrieve textures and therefore crashing the games sometimes many thanks to indev for helping me figuring this one out c: --- src/hardware/hw_main.c | 4 ++-- src/r_segs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index be0c7ba62..faa5372f2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1631,7 +1631,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (rover->master->flags & ML_TFERLINE) { - size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; + size_t linenum = min(gl_curline->linedef-gl_backsector->lines[0], rover->master->frontsector->linecount); newline = rover->master->frontsector->lines[0] + linenum; side = &sides[newline->sidenum[0]]; do_texture_skew = newline->flags & ML_SKEWTD; @@ -1785,7 +1785,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (rover->master->flags & ML_TFERLINE) { - size_t linenum = gl_curline->linedef-gl_backsector->lines[0]; + size_t linenum = min(gl_curline->linedef-gl_backsector->lines[0], rover->master->frontsector->linecount); newline = rover->master->frontsector->lines[0] + linenum; side = &sides[newline->sidenum[0]]; } diff --git a/src/r_segs.c b/src/r_segs.c index 9340ca50c..b43f5e714 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -571,7 +571,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (pfloor->master->flags & ML_TFERLINE) { - size_t linenum = curline->linedef-backsector->lines[0]; + size_t linenum = min(curline->linedef-backsector->lines[0], pfloor->master->frontsector->linecount); line_t *newline = pfloor->master->frontsector->lines[0] + linenum; sidedef = &sides[newline->sidenum[0]]; do_texture_skew = newline->flags & ML_SKEWTD; From afa9b324080789d503fb4f39e6e210e95729be11 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 1 Feb 2024 19:13:13 +0100 Subject: [PATCH 07/74] compiler complains --- src/hardware/hw_main.c | 4 ++-- src/r_segs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index faa5372f2..8a1ad4f69 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1631,7 +1631,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (rover->master->flags & ML_TFERLINE) { - size_t linenum = min(gl_curline->linedef-gl_backsector->lines[0], rover->master->frontsector->linecount); + size_t linenum = min((size_t)(gl_curline->linedef-gl_backsector->lines[0]), rover->master->frontsector->linecount); newline = rover->master->frontsector->lines[0] + linenum; side = &sides[newline->sidenum[0]]; do_texture_skew = newline->flags & ML_SKEWTD; @@ -1785,7 +1785,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (rover->master->flags & ML_TFERLINE) { - size_t linenum = min(gl_curline->linedef-gl_backsector->lines[0], rover->master->frontsector->linecount); + size_t linenum = min((size_t)(gl_curline->linedef-gl_backsector->lines[0]), rover->master->frontsector->linecount); newline = rover->master->frontsector->lines[0] + linenum; side = &sides[newline->sidenum[0]]; } diff --git a/src/r_segs.c b/src/r_segs.c index b43f5e714..326b406f7 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -571,7 +571,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (pfloor->master->flags & ML_TFERLINE) { - size_t linenum = min(curline->linedef-backsector->lines[0], pfloor->master->frontsector->linecount); + size_t linenum = min((size_t)(curline->linedef-backsector->lines[0]), pfloor->master->frontsector->linecount); line_t *newline = pfloor->master->frontsector->lines[0] + linenum; sidedef = &sides[newline->sidenum[0]]; do_texture_skew = newline->flags & ML_SKEWTD; From 34817d9776b13879cd4201f36d06e6b45e012c36 Mon Sep 17 00:00:00 2001 From: SSNTails Date: Sun, 18 Feb 2024 22:38:34 -0500 Subject: [PATCH 08/74] Rollout rock handling with gravity boots --- src/p_map.c | 2 +- src/p_mobj.c | 8 ++++++++ src/p_user.c | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 7887c117d..b84fc7e27 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1043,7 +1043,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) if ((thing->flags & MF_PUSHABLE) // not carrying a player && (tmthing->player->powers[pw_carry] == CR_NONE) // player is not already riding something && !(tmthing->player->powers[pw_ignorelatch] & (1<<15)) - && ((tmthing->eflags & MFE_VERTICALFLIP) == (thing->eflags & MFE_VERTICALFLIP)) + && ((tmthing->eflags & MFE_VERTICALFLIP) == (thing->eflags & MFE_VERTICALFLIP) || tmthing->player->powers[pw_gravityboots]) && (P_MobjFlip(tmthing)*tmthing->momz <= 0) && ((!(tmthing->eflags & MFE_VERTICALFLIP) && abs(thing->z + thing->height - tmthing->z) < (thing->height>>2)) || (tmthing->eflags & MFE_VERTICALFLIP && abs(tmthing->z + tmthing->height - thing->z) < (thing->height>>2)))) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1dd766fc3..eac8dc3d7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1525,6 +1525,14 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_WATERDROP: case MT_CYBRAKDEMON: gravityadd >>= 1; + case MT_ROLLOUTROCK: + // If a player has gravity boots and its riding a rollout rock, the rock should copy the player's gravity + if (mo->tracer && mo->tracer->player && mo->tracer->player->powers[pw_gravityboots]) + { + gravityadd = -gravityadd; + mo->eflags ^= MFE_VERTICALFLIP; + } + break; default: break; } diff --git a/src/p_user.c b/src/p_user.c index 25a60cf34..9de234273 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1082,6 +1082,13 @@ void P_ResetPlayer(player_t *player) if (player->mo->tracer && !P_MobjWasRemoved(player->mo->tracer)) { player->mo->tracer->flags |= MF_PUSHABLE; + + // goose the mom a little bit to trigger gravity to process for a tic + if (player->mo->eflags & MFE_VERTICALFLIP) + player->mo->tracer->momz -= 1; + else + player->mo->tracer->momz += 1; + P_SetTarget(&player->mo->tracer->tracer, NULL); } P_SetTarget(&player->mo->tracer, NULL); @@ -4560,6 +4567,13 @@ void P_DoJump(player_t *player, boolean soundandstate, boolean allowflip) player->mo->momz += player->mo->tracer->momz; if (!P_IsObjectOnGround(player->mo->tracer)) P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true); + + // goose the mom a little bit to trigger gravity to process for a tic + if (player->mo->eflags & MFE_VERTICALFLIP) + player->mo->tracer->momz -= 1; + else + player->mo->tracer->momz += 1; + player->mo->tracer->flags |= MF_PUSHABLE; P_SetTarget(&player->mo->tracer->tracer, NULL); } From 372cbbc544e27b3689a0df8dbeddf5539dde83c3 Mon Sep 17 00:00:00 2001 From: SSNTails Date: Mon, 19 Feb 2024 08:08:12 -0500 Subject: [PATCH 09/74] missing 'break' --- src/p_mobj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index eac8dc3d7..cdd71ccc4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1525,6 +1525,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_WATERDROP: case MT_CYBRAKDEMON: gravityadd >>= 1; + break; case MT_ROLLOUTROCK: // If a player has gravity boots and its riding a rollout rock, the rock should copy the player's gravity if (mo->tracer && mo->tracer->player && mo->tracer->player->powers[pw_gravityboots]) From 716b9527bf9a0966154688818f5b8041b8351f8c Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 21 Feb 2024 14:38:11 -0500 Subject: [PATCH 10/74] Add a -allowdesync parameter that will allow individual demos to desync. Warning is still shown, but player position will not be modified. --- src/d_main.c | 4 ++-- src/f_finale.c | 1 + src/g_demo.c | 20 ++++++++++++-------- src/g_demo.h | 5 +++-- src/m_menu.c | 1 + src/netcode/d_netcmd.c | 4 +++- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 83cb425c9..2bd9546bb 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1664,10 +1664,10 @@ void D_SRB2Main(void) if (M_CheckParm("-playdemo")) { singledemo = true; // quit after one demo - G_DeferedPlayDemo(tmp); + G_DeferedPlayDemo(tmp, M_CheckParm("-allowdemodesync") != 0); } else - G_TimeDemo(tmp); + G_TimeDemo(tmp, M_CheckParm("-allowdemodesync") != 0); G_SetGamestate(GS_NULL); wipegamestate = GS_NULL; diff --git a/src/f_finale.c b/src/f_finale.c index edeb08820..001f06137 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -3513,6 +3513,7 @@ void F_TitleScreenTicker(boolean run) titledemo = true; demofileoverride = DFILE_OVERRIDE_NONE; + demoallowdesync = false; G_DoPlayDemo(dname); } } diff --git a/src/g_demo.c b/src/g_demo.c index f64f34168..a35498e92 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -51,6 +51,7 @@ boolean demorecording; boolean demoplayback; boolean titledemo; // Title Screen demo can be cancelled by any key demo_file_override_e demofileoverride; +boolean demoallowdesync = false; // Allow demo files to de-sync static UINT8 *demobuffer = NULL; static UINT8 *demo_p, *demotime_p; static UINT8 *demoend; @@ -660,11 +661,14 @@ void G_ConsGhostTic(void) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); demosynced = false; - P_UnsetThingPosition(testmo); - testmo->x = oldghost.x; - testmo->y = oldghost.y; - P_SetThingPosition(testmo); - testmo->z = oldghost.z; + if (!demoallowdesync) + { + P_UnsetThingPosition(testmo); + testmo->x = oldghost.x; + testmo->y = oldghost.y; + P_SetThingPosition(testmo); + testmo->z = oldghost.z; + } } if (*demo_p == DEMOMARKER) @@ -1975,7 +1979,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) // // G_PlayDemo // -void G_DeferedPlayDemo(const char *name) +void G_DeferedPlayDemo(const char *name, boolean allowdesync) { COM_BufAddText("playdemo \""); COM_BufAddText(name); @@ -2633,7 +2637,7 @@ void G_FreeGhosts(void) // static INT32 restorecv_vidwait; -void G_TimeDemo(const char *name) +void G_TimeDemo(const char *name, boolean allowdesync) { nodrawers = M_CheckParm("-nodraw"); noblit = M_CheckParm("-noblit"); @@ -2644,7 +2648,7 @@ void G_TimeDemo(const char *name) singletics = true; framecount = 0; demostarttime = I_GetTime(); - G_DeferedPlayDemo(name); + G_DeferedPlayDemo(name, allowdesync); } void G_DoPlayMetal(void) diff --git a/src/g_demo.h b/src/g_demo.h index e8c0c8d95..19fbc80e2 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -35,6 +35,7 @@ typedef enum } demo_file_override_e; extern demo_file_override_e demofileoverride; +extern boolean demoallowdesync; // Quit after playing a demo from cmdline. extern boolean singledemo; @@ -94,9 +95,9 @@ void G_WriteMetalTic(mobj_t *metal); void G_SaveMetal(UINT8 **buffer); void G_LoadMetal(UINT8 **buffer); -void G_DeferedPlayDemo(const char *demo); +void G_DeferedPlayDemo(const char *demo, boolean allowdesync); void G_DoPlayDemo(char *defdemoname); -void G_TimeDemo(const char *name); +void G_TimeDemo(const char *name, boolean allowdesync); void G_AddGhost(char *defdemoname); void G_FreeGhosts(void); void G_DoPlayMetal(void); diff --git a/src/m_menu.c b/src/m_menu.c index 3c6ef0fe3..b18515842 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10529,6 +10529,7 @@ static void M_StartTimeAttackReplay(INT32 choice) { M_ClearMenus(true); modeattacking = ATTACKING_RECORD; // set modeattacking before G_DoPlayDemo so the map loader knows + demoallowdesync = false; G_DoPlayDemo(ra_demoname); } } diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 66a30637f..bd3edc2b8 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -1596,6 +1596,8 @@ static void Command_Playdemo_f(void) demofileoverride = DFILE_OVERRIDE_SKIP; } + demoallowdesync = COM_CheckParm("-allowdesync"); + // Internal if no extension, external if one exists // If external, convert the file name to a path in SRB2's home directory if (FIL_CheckExtension(name)) @@ -1643,7 +1645,7 @@ static void Command_Timedemo_f(void) CONS_Printf(M_GetText("Timing demo '%s'.\n"), timedemo_name); - G_TimeDemo(timedemo_name); + G_TimeDemo(timedemo_name, COM_CheckParm("-allowdesync")); } // stop current demo From a407ff88999c7300a185e508d04a7005d491b631 Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 21 Feb 2024 16:22:00 -0500 Subject: [PATCH 11/74] Zwip Zwap Zapony's suggestion to use a consvar --- src/d_main.c | 4 ++-- src/f_finale.c | 1 - src/g_demo.c | 11 ++++++----- src/g_demo.h | 6 +++--- src/m_menu.c | 1 - src/netcode/d_netcmd.c | 5 ++--- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 2bd9546bb..83cb425c9 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1664,10 +1664,10 @@ void D_SRB2Main(void) if (M_CheckParm("-playdemo")) { singledemo = true; // quit after one demo - G_DeferedPlayDemo(tmp, M_CheckParm("-allowdemodesync") != 0); + G_DeferedPlayDemo(tmp); } else - G_TimeDemo(tmp, M_CheckParm("-allowdemodesync") != 0); + G_TimeDemo(tmp); G_SetGamestate(GS_NULL); wipegamestate = GS_NULL; diff --git a/src/f_finale.c b/src/f_finale.c index 001f06137..edeb08820 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -3513,7 +3513,6 @@ void F_TitleScreenTicker(boolean run) titledemo = true; demofileoverride = DFILE_OVERRIDE_NONE; - demoallowdesync = false; G_DoPlayDemo(dname); } } diff --git a/src/g_demo.c b/src/g_demo.c index a35498e92..ec3d223bd 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -51,7 +51,6 @@ boolean demorecording; boolean demoplayback; boolean titledemo; // Title Screen demo can be cancelled by any key demo_file_override_e demofileoverride; -boolean demoallowdesync = false; // Allow demo files to de-sync static UINT8 *demobuffer = NULL; static UINT8 *demo_p, *demotime_p; static UINT8 *demoend; @@ -68,6 +67,8 @@ static UINT8 *metalbuffer = NULL; static UINT8 *metal_p; static UINT16 metalversion; +consvar_t cv_resyncdemo = CVAR_INIT("resyncdemo", "On", 0, CV_OnOff, NULL); + // extra data stuff (events registered this frame while recording) static struct { UINT8 flags; // EZT flags @@ -661,7 +662,7 @@ void G_ConsGhostTic(void) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); demosynced = false; - if (!demoallowdesync) + if (cv_resyncdemo.value) { P_UnsetThingPosition(testmo); testmo->x = oldghost.x; @@ -1979,7 +1980,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) // // G_PlayDemo // -void G_DeferedPlayDemo(const char *name, boolean allowdesync) +void G_DeferedPlayDemo(const char *name) { COM_BufAddText("playdemo \""); COM_BufAddText(name); @@ -2637,7 +2638,7 @@ void G_FreeGhosts(void) // static INT32 restorecv_vidwait; -void G_TimeDemo(const char *name, boolean allowdesync) +void G_TimeDemo(const char *name) { nodrawers = M_CheckParm("-nodraw"); noblit = M_CheckParm("-noblit"); @@ -2648,7 +2649,7 @@ void G_TimeDemo(const char *name, boolean allowdesync) singletics = true; framecount = 0; demostarttime = I_GetTime(); - G_DeferedPlayDemo(name, allowdesync); + G_DeferedPlayDemo(name); } void G_DoPlayMetal(void) diff --git a/src/g_demo.h b/src/g_demo.h index 19fbc80e2..67f61f54d 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -35,7 +35,7 @@ typedef enum } demo_file_override_e; extern demo_file_override_e demofileoverride; -extern boolean demoallowdesync; +extern consvar_t cv_resyncdemo; // Quit after playing a demo from cmdline. extern boolean singledemo; @@ -95,9 +95,9 @@ void G_WriteMetalTic(mobj_t *metal); void G_SaveMetal(UINT8 **buffer); void G_LoadMetal(UINT8 **buffer); -void G_DeferedPlayDemo(const char *demo, boolean allowdesync); +void G_DeferedPlayDemo(const char *demo); void G_DoPlayDemo(char *defdemoname); -void G_TimeDemo(const char *name, boolean allowdesync); +void G_TimeDemo(const char *name); void G_AddGhost(char *defdemoname); void G_FreeGhosts(void); void G_DoPlayMetal(void); diff --git a/src/m_menu.c b/src/m_menu.c index b18515842..3c6ef0fe3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10529,7 +10529,6 @@ static void M_StartTimeAttackReplay(INT32 choice) { M_ClearMenus(true); modeattacking = ATTACKING_RECORD; // set modeattacking before G_DoPlayDemo so the map loader knows - demoallowdesync = false; G_DoPlayDemo(ra_demoname); } } diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index bd3edc2b8..f7aa2c6fa 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -675,6 +675,7 @@ void D_RegisterClientCommands(void) COM_AddCommand("timedemo", Command_Timedemo_f, 0); COM_AddCommand("stopdemo", Command_Stopdemo_f, COM_LUA); COM_AddCommand("playintro", Command_Playintro_f, COM_LUA); + CV_RegisterVar(&cv_resyncdemo); COM_AddCommand("resetcamera", Command_ResetCamera_f, COM_LUA); @@ -1596,8 +1597,6 @@ static void Command_Playdemo_f(void) demofileoverride = DFILE_OVERRIDE_SKIP; } - demoallowdesync = COM_CheckParm("-allowdesync"); - // Internal if no extension, external if one exists // If external, convert the file name to a path in SRB2's home directory if (FIL_CheckExtension(name)) @@ -1645,7 +1644,7 @@ static void Command_Timedemo_f(void) CONS_Printf(M_GetText("Timing demo '%s'.\n"), timedemo_name); - G_TimeDemo(timedemo_name, COM_CheckParm("-allowdesync")); + G_TimeDemo(timedemo_name); } // stop current demo From d43d5fb9e14ebf417077cd9e31be861a3939d7c5 Mon Sep 17 00:00:00 2001 From: SSNTails Date: Fri, 23 Feb 2024 15:23:39 -0500 Subject: [PATCH 12/74] Don't change drawangle while riding on a fan --- src/p_user.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 25a60cf34..1964a6b3e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12134,6 +12134,8 @@ void P_PlayerThink(player_t *player) case CR_DUSTDEVIL: player->drawangle += ANG20; break; + case CR_FAN: // Don't impact drawangle in any special way when on a fan + break; /* -- in case we wanted to have the camera freely movable during zoom tubes case CR_ZOOMTUBE:*/ case CR_ROPEHANG: From 02811b72f62e51a80a20c5816d2936e417cc7656 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Tue, 23 Jan 2024 22:43:25 +0100 Subject: [PATCH 13/74] Fix segfault when trying to spawn an MT_PLAYER from Lua --- src/lua_baselib.c | 4 ++-- src/p_local.h | 2 +- src/p_mobj.c | 18 ++++++++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e75a911ee..d6f125bbd 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -641,7 +641,7 @@ static int lib_pSpawnMobj(lua_State *L) NOHUD INLEVEL NOSPAWNNULL - LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ); + LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type, NULL), META_MOBJ); return 1; } @@ -657,7 +657,7 @@ static int lib_pSpawnMobjFromMobj(lua_State *L) NOSPAWNNULL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ); + LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type, NULL), META_MOBJ); return 1; } diff --git a/src/p_local.h b/src/p_local.h index 0bcd6da1d..7e4741ffd 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -328,7 +328,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(ffloor_t *rover); void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype); -mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type); +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...); mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type); mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z); diff --git a/src/p_mobj.c b/src/p_mobj.c index 55be8e54f..c6f437c9a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -14420,15 +14420,29 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration) // Spawns an object with offsets relative to the position of another object. // Scale, gravity flip, etc. is taken into account automatically. // -mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type) +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...) { + va_list args; mobj_t *newmobj; xofs = FixedMul(xofs, mobj->scale); yofs = FixedMul(yofs, mobj->scale); zofs = FixedMul(zofs, mobj->scale); - newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type); + if (type == MT_PLAYER) + { + player_t *player; + // MT_PLAYER requires an additional parameter for the player, so pass that forth. + va_start(args, type); + player = va_arg(args, player_t *); + va_end(args); + newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type, player); + } + else + { + newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type); + } + if (!newmobj) return NULL; From 259997d121c0bc32cbcc062fc52507f381a21668 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Wed, 24 Jan 2024 17:11:04 +0100 Subject: [PATCH 14/74] Remove varargs from P_SpawnMobjFromMobj --- src/lua_baselib.c | 2 +- src/p_local.h | 2 +- src/p_mobj.c | 16 ++-------------- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d6f125bbd..47ee3976d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -657,7 +657,7 @@ static int lib_pSpawnMobjFromMobj(lua_State *L) NOSPAWNNULL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type, NULL), META_MOBJ); + LUA_PushUserdata(L, P_SpawnMobjFromMobj(actor, x, y, z, type), META_MOBJ); return 1; } diff --git a/src/p_local.h b/src/p_local.h index 7e4741ffd..0bcd6da1d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -328,7 +328,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(ffloor_t *rover); void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype); -mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...); +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type); mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type); mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z); diff --git a/src/p_mobj.c b/src/p_mobj.c index c6f437c9a..3999c9476 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -14420,7 +14420,7 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration) // Spawns an object with offsets relative to the position of another object. // Scale, gravity flip, etc. is taken into account automatically. // -mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type, ...) +mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type) { va_list args; mobj_t *newmobj; @@ -14429,19 +14429,7 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo yofs = FixedMul(yofs, mobj->scale); zofs = FixedMul(zofs, mobj->scale); - if (type == MT_PLAYER) - { - player_t *player; - // MT_PLAYER requires an additional parameter for the player, so pass that forth. - va_start(args, type); - player = va_arg(args, player_t *); - va_end(args); - newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type, player); - } - else - { - newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type); - } + newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type, NULL); if (!newmobj) return NULL; From b3aa23bc214e3aee7accca87d820c7943f012c13 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Wed, 24 Jan 2024 16:13:34 +0000 Subject: [PATCH 15/74] Remove unused variable --- src/p_mobj.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 3999c9476..4bed833fb 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -14422,7 +14422,6 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration) // mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type) { - va_list args; mobj_t *newmobj; xofs = FixedMul(xofs, mobj->scale); From 51e912e87be2dac061565bddeb1b0e56e867d71b Mon Sep 17 00:00:00 2001 From: Hanicef Date: Tue, 5 Mar 2024 18:29:07 +0100 Subject: [PATCH 16/74] Fix segfault when passing NULL as player --- src/p_mobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4bed833fb..84884eef3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10886,7 +10886,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...) // when spawning MT_PLAYER, set mobj->player before calling MobjSpawn hook to prevent P_RemoveMobj from succeeding on player mobj. va_start(args, type); mobj->player = va_arg(args, player_t *); - mobj->player->mo = mobj; + if (mobj->player) + mobj->player->mo = mobj; va_end(args); } From 34cf7c1a018cd8fbf73c0686513c9f3a89c41b8c Mon Sep 17 00:00:00 2001 From: SSNTails Date: Wed, 13 Mar 2024 18:08:07 -0400 Subject: [PATCH 17/74] I don't think flipping the flag here is even needed... --- src/p_mobj.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index cdd71ccc4..27282fe52 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1529,10 +1529,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_ROLLOUTROCK: // If a player has gravity boots and its riding a rollout rock, the rock should copy the player's gravity if (mo->tracer && mo->tracer->player && mo->tracer->player->powers[pw_gravityboots]) - { gravityadd = -gravityadd; - mo->eflags ^= MFE_VERTICALFLIP; - } break; default: break; From cfc23648f5e66f300e652f75ecceeb3b32e8acd6 Mon Sep 17 00:00:00 2001 From: BarrelsOFun <161785144+BarrelsOFun@users.noreply.github.com> Date: Wed, 13 Mar 2024 19:58:24 -0700 Subject: [PATCH 18/74] Transform FlingRing instead of spawning new Ring --- src/p_enemy.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 4990db6fd..f9e643eb2 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4865,7 +4865,7 @@ void A_AttractChase(mobj_t *actor) else actor->flags2 &= ~MF2_DONTDRAW; - // Turn flingrings back into regular rings if attracted. + // Turn rings into flingrings if shield is lost or out of range if (actor->tracer && actor->tracer->player && !(actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC) && actor->info->reactiontime && actor->type != (mobjtype_t)actor->info->reactiontime) { @@ -4897,8 +4897,9 @@ void A_AttractChase(mobj_t *actor) // If a FlingRing gets attracted by a shield, change it into a normal ring. if (actor->type == (mobjtype_t)actor->info->reactiontime) { - P_SpawnMobj(actor->x, actor->y, actor->z, actor->info->painchance); - P_RemoveMobj(actor); + actor->type = mobjinfo[actor->type].painchance; // Become the regular version of the fling object. + actor->flags = mobjinfo[actor->type].flags; // Reset actor flags. + P_SetMobjState(actor, actor->info->spawnstate); // Go to regular object's spawn state. return; } From e44c751187345b5fdd7b331acf211f115839227b Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 14 Mar 2024 04:13:09 -0300 Subject: [PATCH 19/74] Fix #1215 --- src/r_segs.c | 80 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index e07ced86a..d68db60de 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -442,26 +442,75 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } // Loop through R_DrawMaskedColumn calls +static fixed_t repeatscroll = 0; + static void R_DrawRepeatMaskedColumn(column_t *col, unsigned lengthcol) { - while (sprtopscreen < sprbotscreen) { - R_DrawMaskedColumn(col, lengthcol); - if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow - sprtopscreen = INT32_MAX; - else - sprtopscreen += dc_texheight*spryscale; + fixed_t topscreen = sprtopscreen; + fixed_t bottomscreen = sprbotscreen; + + fixed_t texheight = dc_texheight*spryscale; + + fixed_t scroll = -repeatscroll; + if (scroll < 0) + { + scroll = -FixedMul((abs(scroll) % (dc_texheight*FRACUNIT)), spryscale); + bottomscreen += texheight; // Draw an extra time } + else if (scroll) + { + scroll = FixedMul(scroll % (dc_texheight*FRACUNIT), spryscale); + topscreen -= texheight; // Draw an extra time + } + + while (topscreen < bottomscreen) + { + sprtopscreen = topscreen + scroll; + + R_DrawMaskedColumn(col, lengthcol); + + if ((INT64)topscreen + (INT64)texheight > (INT64)INT32_MAX) // prevent overflow + break; + + topscreen += texheight; + } + + sprtopscreen = sprbotscreen; } static void R_DrawRepeatFlippedMaskedColumn(column_t *col, unsigned lengthcol) { - while (sprtopscreen < sprbotscreen) { - R_DrawFlippedMaskedColumn(col, lengthcol); - if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow - sprtopscreen = INT32_MAX; - else - sprtopscreen += dc_texheight*spryscale; + fixed_t topscreen = sprtopscreen; + fixed_t bottomscreen = sprbotscreen; + + fixed_t texheight = dc_texheight*spryscale; + + fixed_t scroll = -repeatscroll; + if (scroll < 0) + { + scroll = -FixedMul((abs(scroll) % (dc_texheight*FRACUNIT)), spryscale); + bottomscreen += texheight; // Draw an extra time } + else if (scroll) + { + scroll = FixedMul(scroll % (dc_texheight*FRACUNIT), spryscale); + topscreen -= texheight; // Draw an extra time + } + + while (topscreen < bottomscreen) + { + sprtopscreen = topscreen + scroll; + sprbotscreen = bottomscreen + scroll; + + R_DrawFlippedMaskedColumn(col, lengthcol); + + if ((INT64)topscreen + (INT64)texheight > (INT64)INT32_MAX) // prevent overflow + break; + + topscreen += texheight; + } + + sprtopscreen = sprbotscreen; } // Returns true if a fake floor is translucent. @@ -497,7 +546,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) sector_t tempsec; INT32 templight; INT32 i, p; - fixed_t offsetvalue; lightlist_t *light; r_lightlist_t *rlight; INT32 range; @@ -734,7 +782,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else dc_texturemid = FixedMul(*pfloor->topheight - viewz, wall_scaley); - offsetvalue = sidedef->rowoffset + sidedef->offsety_mid; + repeatscroll = sidedef->rowoffset + sidedef->offsety_mid; if (dont_peg_bottom) { @@ -744,7 +792,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_texturemid = FixedMul(left_bottom, wall_scaley); } else - offsetvalue -= FixedMul(*pfloor->topheight - *pfloor->bottomheight, wall_scaley); + repeatscroll -= FixedMul(*pfloor->topheight - *pfloor->bottomheight, wall_scaley); } if (skewslope) @@ -753,7 +801,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) ffloortextureslide = FixedMul(R_GetSlopeTextureSlide(skewslope, lineangle), wall_scaley); } - dc_texturemid += offsetvalue; + dc_texturemid += repeatscroll; // Texture must be cached R_CheckTextureCache(texnum); From a58d9036bc48736d40c69fe9401747dbf083c90d Mon Sep 17 00:00:00 2001 From: SSNTails Date: Fri, 15 Mar 2024 14:28:44 -0400 Subject: [PATCH 20/74] Restore MF2_OBJECTFLIP/MFE_VERTICALFLIP on rollout rock disconnect --- src/p_map.c | 4 ++++ src/p_user.c | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index b84fc7e27..088d55208 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1057,6 +1057,10 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) P_SetTarget(&tmthing->tracer, thing); if (!P_IsObjectOnGround(thing)) thing->momz += tmthing->momz; + + thing->extravalue1 = thing->flags2; + thing->extravalue2 = thing->eflags; + return CHECKTHING_COLLIDE; } } diff --git a/src/p_user.c b/src/p_user.c index 9de234273..417154b19 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1089,6 +1089,17 @@ void P_ResetPlayer(player_t *player) else player->mo->tracer->momz += 1; + // Restore MF2_OBJECTFLIP / MFE_VERTICALFLIP + if (player->mo->tracer->extravalue1 & MF2_OBJECTFLIP) + player->mo->tracer->flags2 |= MF2_OBJECTFLIP; + else + player->mo->tracer->flags2 &= ~MF2_OBJECTFLIP; + + if (player->mo->tracer->extravalue2 & MFE_VERTICALFLIP) + player->mo->tracer->eflags |= MFE_VERTICALFLIP; + else + player->mo->tracer->eflags &= ~MFE_VERTICALFLIP; + P_SetTarget(&player->mo->tracer->tracer, NULL); } P_SetTarget(&player->mo->tracer, NULL); @@ -4574,6 +4585,17 @@ void P_DoJump(player_t *player, boolean soundandstate, boolean allowflip) else player->mo->tracer->momz += 1; + // Restore MF2_OBJECTFLIP / MFE_VERTICALFLIP + if (player->mo->tracer->extravalue1 & MF2_OBJECTFLIP) + player->mo->tracer->flags2 |= MF2_OBJECTFLIP; + else + player->mo->tracer->flags2 &= ~MF2_OBJECTFLIP; + + if (player->mo->tracer->extravalue2 & MFE_VERTICALFLIP) + player->mo->tracer->eflags |= MFE_VERTICALFLIP; + else + player->mo->tracer->eflags &= ~MFE_VERTICALFLIP; + player->mo->tracer->flags |= MF_PUSHABLE; P_SetTarget(&player->mo->tracer->tracer, NULL); } From 2181dadb4cead6b3dbb8f63ada6446ee72202d90 Mon Sep 17 00:00:00 2001 From: SSNTails Date: Fri, 15 Mar 2024 16:39:37 -0400 Subject: [PATCH 21/74] Checking MFE_VERTICALFLIP matching is actually redundant.. --- src/p_map.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 088d55208..57883b448 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1043,7 +1043,6 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) if ((thing->flags & MF_PUSHABLE) // not carrying a player && (tmthing->player->powers[pw_carry] == CR_NONE) // player is not already riding something && !(tmthing->player->powers[pw_ignorelatch] & (1<<15)) - && ((tmthing->eflags & MFE_VERTICALFLIP) == (thing->eflags & MFE_VERTICALFLIP) || tmthing->player->powers[pw_gravityboots]) && (P_MobjFlip(tmthing)*tmthing->momz <= 0) && ((!(tmthing->eflags & MFE_VERTICALFLIP) && abs(thing->z + thing->height - tmthing->z) < (thing->height>>2)) || (tmthing->eflags & MFE_VERTICALFLIP && abs(tmthing->z + tmthing->height - thing->z) < (thing->height>>2)))) From b4ad0544225bef1c5b872af3e1b76991fd4d2a8b Mon Sep 17 00:00:00 2001 From: SSNTails Date: Sat, 16 Mar 2024 10:28:49 -0400 Subject: [PATCH 22/74] Zwip Zwap Zapony's suggestions --- src/p_enemy.c | 10 ++++++++-- src/p_map.c | 3 --- src/p_mobj.c | 5 ----- src/p_user.c | 26 ++------------------------ 4 files changed, 10 insertions(+), 34 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index a386d8ee9..6a52b6402 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -14799,12 +14799,18 @@ void A_RolloutRock(mobj_t *actor) if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health) actor->flags |= MF_PUSHABLE; + else if (actor->tracer->eflags & MFE_VERTICALFLIP) + { + actor->flags2 |= MF2_OBJECTFLIP; + actor->eflags |= MFE_VERTICALFLIP; + } else { - actor->flags2 = (actor->flags2 & ~MF2_OBJECTFLIP) | (actor->tracer->flags2 & MF2_OBJECTFLIP); - actor->eflags = (actor->eflags & ~MFE_VERTICALFLIP) | (actor->tracer->eflags & MFE_VERTICALFLIP); + actor->flags2 &= ~MF2_OBJECTFLIP; + actor->eflags &= ~MFE_VERTICALFLIP; } + actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves if (actor->eflags & MFE_JUSTHITFLOOR) diff --git a/src/p_map.c b/src/p_map.c index 57883b448..aa8ef17ec 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1057,9 +1057,6 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) if (!P_IsObjectOnGround(thing)) thing->momz += tmthing->momz; - thing->extravalue1 = thing->flags2; - thing->extravalue2 = thing->eflags; - return CHECKTHING_COLLIDE; } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 27282fe52..4c08c81da 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1526,11 +1526,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_CYBRAKDEMON: gravityadd >>= 1; break; - case MT_ROLLOUTROCK: - // If a player has gravity boots and its riding a rollout rock, the rock should copy the player's gravity - if (mo->tracer && mo->tracer->player && mo->tracer->player->powers[pw_gravityboots]) - gravityadd = -gravityadd; - break; default: break; } diff --git a/src/p_user.c b/src/p_user.c index 417154b19..707d420fc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1084,22 +1084,11 @@ void P_ResetPlayer(player_t *player) player->mo->tracer->flags |= MF_PUSHABLE; // goose the mom a little bit to trigger gravity to process for a tic - if (player->mo->eflags & MFE_VERTICALFLIP) + if (player->mo->tracer->eflags & MFE_VERTICALFLIP) player->mo->tracer->momz -= 1; else player->mo->tracer->momz += 1; - // Restore MF2_OBJECTFLIP / MFE_VERTICALFLIP - if (player->mo->tracer->extravalue1 & MF2_OBJECTFLIP) - player->mo->tracer->flags2 |= MF2_OBJECTFLIP; - else - player->mo->tracer->flags2 &= ~MF2_OBJECTFLIP; - - if (player->mo->tracer->extravalue2 & MFE_VERTICALFLIP) - player->mo->tracer->eflags |= MFE_VERTICALFLIP; - else - player->mo->tracer->eflags &= ~MFE_VERTICALFLIP; - P_SetTarget(&player->mo->tracer->tracer, NULL); } P_SetTarget(&player->mo->tracer, NULL); @@ -4580,22 +4569,11 @@ void P_DoJump(player_t *player, boolean soundandstate, boolean allowflip) P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true); // goose the mom a little bit to trigger gravity to process for a tic - if (player->mo->eflags & MFE_VERTICALFLIP) + if (player->mo->tracer->eflags & MFE_VERTICALFLIP) player->mo->tracer->momz -= 1; else player->mo->tracer->momz += 1; - // Restore MF2_OBJECTFLIP / MFE_VERTICALFLIP - if (player->mo->tracer->extravalue1 & MF2_OBJECTFLIP) - player->mo->tracer->flags2 |= MF2_OBJECTFLIP; - else - player->mo->tracer->flags2 &= ~MF2_OBJECTFLIP; - - if (player->mo->tracer->extravalue2 & MFE_VERTICALFLIP) - player->mo->tracer->eflags |= MFE_VERTICALFLIP; - else - player->mo->tracer->eflags &= ~MFE_VERTICALFLIP; - player->mo->tracer->flags |= MF_PUSHABLE; P_SetTarget(&player->mo->tracer->tracer, NULL); } From 8794e411bd57d9c5017ba38137770a586c558b06 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Wed, 20 Mar 2024 19:23:13 +0100 Subject: [PATCH 23/74] Don't traverse the entire HOME directory to find wads --- src/dedicated/i_system.c | 8 +++++++- src/sdl/i_system.c | 10 ++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 858dfaf20..b231080a8 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -1433,9 +1433,15 @@ static const char *locateWad(void) #ifndef NOHOME // find in $HOME - I_OutputMsg(",HOME"); + I_OutputMsg(",HOME/.srb2"); if ((envstr = I_GetEnv("HOME")) != NULL) + { + char *tmp = malloc(strlen(envstr) + sizeof("/.srb2")); + strcpy(tmp, envstr); + strcat(tmp, "/.srb2"); SEARCHWAD(envstr); + free(tmp); + } #endif // search paths diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 9f0fa0250..c6750ce74 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -3038,10 +3038,16 @@ static const char *locateWad(void) } #ifndef NOHOME - // find in $HOME - I_OutputMsg(",HOME"); + // find in $HOME/.srb2 + I_OutputMsg(",HOME/.srb2"); if ((envstr = I_GetEnv("HOME")) != NULL) + { + char *tmp = malloc(strlen(envstr) + sizeof("/.srb2")); + strcpy(tmp, envstr); + strcat(tmp, "/.srb2"); SEARCHWAD(envstr); + free(tmp); + } #endif // search paths From c3a8f452e2607ac502edba59ef45e63f62c6e1c9 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 20 Mar 2024 20:30:06 +0100 Subject: [PATCH 24/74] Fix equation slopes breaking with slopes farther than 32k FU away from the map center --- src/p_slopes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index e75d36ede..fd741398b 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -810,10 +810,10 @@ void P_InitSlopes(void) // Returns the height of the sloped plane at (x, y) as a fixed_t fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) { - fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) + - FixedMul(y - slope->o.y, slope->d.y); + fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) / 2 + + FixedMul(y - slope->o.y, slope->d.y) / 2; - return slope->o.z + FixedMul(dist, slope->zdelta); + return slope->o.z + FixedMul(dist, slope->zdelta) * 2; } // Like P_GetSlopeZAt but falls back to z if slope is NULL From 10365e943aacd35d7b1052cdc4543556b94ee6f8 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Wed, 20 Mar 2024 20:44:17 +0100 Subject: [PATCH 25/74] Use DEFAULTDIR instead of hardcoding .srb2 --- src/dedicated/i_system.c | 6 +++--- src/sdl/i_system.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index b231080a8..61b7a239a 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -1433,12 +1433,12 @@ static const char *locateWad(void) #ifndef NOHOME // find in $HOME - I_OutputMsg(",HOME/.srb2"); + I_OutputMsg(",HOME/" DEFAULTDIR); if ((envstr = I_GetEnv("HOME")) != NULL) { - char *tmp = malloc(strlen(envstr) + sizeof("/.srb2")); + char *tmp = malloc(strlen(envstr) + sizeof(DEFAULTDIR)); strcpy(tmp, envstr); - strcat(tmp, "/.srb2"); + strcat(tmp, DEFAULTDIR); SEARCHWAD(envstr); free(tmp); } diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index c6750ce74..64fcb2f2b 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -3038,13 +3038,13 @@ static const char *locateWad(void) } #ifndef NOHOME - // find in $HOME/.srb2 - I_OutputMsg(",HOME/.srb2"); + // find in $HOME + I_OutputMsg(",HOME/" DEFAULTDIR); if ((envstr = I_GetEnv("HOME")) != NULL) { - char *tmp = malloc(strlen(envstr) + sizeof("/.srb2")); + char *tmp = malloc(strlen(envstr) + sizeof(DEFAULTDIR)); strcpy(tmp, envstr); - strcat(tmp, "/.srb2"); + strcat(tmp, DEFAULTDIR); SEARCHWAD(envstr); free(tmp); } From d0dd329a8223c99ba84d70a59db3e977ca34e86e Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sat, 23 Mar 2024 13:01:21 +0100 Subject: [PATCH 26/74] Fix buffer overflow when loading addons through symlinks --- src/sdl/i_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 2d051888d..e151734f8 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2976,7 +2976,7 @@ static void pathonly(char *s) */ static const char *searchWad(const char *searchDir) { - static char tempsw[256] = ""; + static char tempsw[MAX_WADPATH] = ""; filestatus_t fstemp; strcpy(tempsw, WADKEYWORD1); From fece34cef60bb3dd326b9292a93f4ce450d0639f Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sat, 23 Mar 2024 13:05:29 +0100 Subject: [PATCH 27/74] Fix segfault when passing a long string to v.drawString --- src/lua_hudlib_drawlist.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index c518ba525..cb58e628e 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -180,7 +180,8 @@ static const char *CopyString(huddrawlist_h list, const char* str) const char *old_offset = list->strbuf; size_t i; if (list->strbuf_capacity == 0) list->strbuf_capacity = 256; - else list->strbuf_capacity *= 2; + while (list->strbuf_capacity <= list->strbuf_len + lenstr + 1) + list->strbuf_capacity *= 2; list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL); // align the string pointers to make sure old pointers don't point towards invalid addresses From 755adb0c46e0bb0dba1bb876fe155e962d9ca016 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sat, 30 Mar 2024 17:58:27 +0100 Subject: [PATCH 28/74] Fix vertical aim being off when using lack of perspective --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f533082f7..d764e2bb1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5221,7 +5221,7 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean if (cv_glshearing.value == 1 || (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))) { fixed_t fixedaiming = AIMINGTODY(aimingangle); - trans->viewaiming = FIXED_TO_FLOAT(fixedaiming); + trans->viewaiming = FIXED_TO_FLOAT(fixedaiming) * (vid.width / vid.height) / (BASEVIDWIDTH / BASEVIDHEIGHT); trans->shearing = true; gl_aimingangle = 0; } From de74137cae75de891194be808936893b82bd9a1e Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sat, 30 Mar 2024 21:10:09 +0100 Subject: [PATCH 29/74] Use float for calculating aspect ratio --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d764e2bb1..0771708eb 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5221,7 +5221,7 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean if (cv_glshearing.value == 1 || (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox))) { fixed_t fixedaiming = AIMINGTODY(aimingangle); - trans->viewaiming = FIXED_TO_FLOAT(fixedaiming) * (vid.width / vid.height) / (BASEVIDWIDTH / BASEVIDHEIGHT); + trans->viewaiming = FIXED_TO_FLOAT(fixedaiming) * ((float)vid.width / vid.height) / ((float)BASEVIDWIDTH / BASEVIDHEIGHT); trans->shearing = true; gl_aimingangle = 0; } From 2b9cfa8262b73e1ec1a935ee0dc4b318c649a394 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sun, 31 Mar 2024 18:27:57 +0200 Subject: [PATCH 30/74] Fix crash when spawning a BOT_2PAI on a dedicated server --- src/b_bot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/b_bot.c b/src/b_bot.c index af57d65ec..6229cb1d6 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -387,7 +387,8 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd) } // Bot AI isn't programmed in analog. - CV_SetValue(&cv_analog[1], false); + if (!dedicated) + CV_SetValue(&cv_analog[1], false); // Let Lua scripts build ticcmds if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd))) From 6c628db56a265115438cab865832455d12e42d5c Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Wed, 3 Apr 2024 00:54:35 -0400 Subject: [PATCH 31/74] 1st try around sorting the lumps by name --- src/filesrch.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/filesrch.c b/src/filesrch.c index 944e8447f..7ccf532c8 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -699,6 +699,13 @@ static void initdirpath(char *dirpath, size_t *dirpathindex, int depthleft) dirpathindex[depthleft]--; } +//sortdir by name? +static int lumpnamecompare( const void *A, const void *B ) +{ + return strcmp( (((lumpinfo_t *)A)->fullname), (((lumpinfo_t *)B)->fullname)); + +} + lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders) { DIR **dirhandle; @@ -889,6 +896,9 @@ lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders) free(dirpathindex); free(dirhandle); + //sort files and directories + qsort ( lumpinfo, numlumps, sizeof( lumpinfo_t ), lumpnamecompare ); + (*nlmp) = numlumps; return lumpinfo; } From aab11cd87385b399826e2d97dee47cf3b202a218 Mon Sep 17 00:00:00 2001 From: Logan Aerl Arias Date: Wed, 3 Apr 2024 18:42:36 -0400 Subject: [PATCH 32/74] reformat the compare func used in qsort --- src/d_main.c | 12 ++++++++---- src/filesrch.c | 8 +++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c139650d1..6ced36624 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1842,17 +1842,21 @@ static boolean check_top_dir(const char **path, const char *top) return true; } -static int cmp_strlen_desc(const void *a, const void *b) +static int cmp_strlen_desc(const void *A, const void *B) { - return ((int)strlen(*(const char*const*)b) - (int)strlen(*(const char*const*)a)); + const char *pA = A; + const char *pB = B; + size_t As = strlen(pA); + size_t Bs = strlen(pB); + return ((int)Bs - (int)As); } boolean D_IsPathAllowed(const char *path) { - const char *paths[] = { + char *paths[] = { srb2home, srb2path, - cv_addons_folder.string + cv_addons_folder.zstring }; const size_t n_paths = sizeof paths / sizeof *paths; diff --git a/src/filesrch.c b/src/filesrch.c index 7ccf532c8..3a729a9c8 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -700,9 +700,11 @@ static void initdirpath(char *dirpath, size_t *dirpathindex, int depthleft) } //sortdir by name? -static int lumpnamecompare( const void *A, const void *B ) +static int lumpnamecompare(const void *A, const void *B) { - return strcmp( (((lumpinfo_t *)A)->fullname), (((lumpinfo_t *)B)->fullname)); + const lumpinfo_t *pA = A; + const lumpinfo_t *pB = B; + return strcmp((pA->fullname), (pB->fullname)); } @@ -897,7 +899,7 @@ lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders) free(dirhandle); //sort files and directories - qsort ( lumpinfo, numlumps, sizeof( lumpinfo_t ), lumpnamecompare ); + qsort (lumpinfo, numlumps, sizeof(lumpinfo_t), lumpnamecompare); (*nlmp) = numlumps; return lumpinfo; From 92cccd682c53f212202bab2907652bd97f95fdc9 Mon Sep 17 00:00:00 2001 From: katsy Date: Wed, 17 Apr 2024 18:00:30 -0500 Subject: [PATCH 33/74] Fix automatic mode z-target bugs and crashes --- src/g_game.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 8d19c9e7c..ed9e88362 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1363,11 +1363,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL); if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0)) cmd->buttons |= BT_FIRENORMAL; - + // Toss flag button if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG)) cmd->buttons |= BT_TOSSFLAG; - + // Shield button axis = PlayerJoyAxis(ssplayer, JA_SHIELD); if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD) || (usejoystick && axis > 0)) @@ -1420,7 +1420,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) ticcmd_centerviewdown[forplayer] = true; } - else if (ticcmd_centerviewdown[forplayer]) + else if (ticcmd_centerviewdown[forplayer] || (leveltime < 5)) { if (controlstyle == CS_SIMPLE) { @@ -1435,6 +1435,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { if ( P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) || + (leveltime < 5) || + (player->playerstate != PST_LIVE) || + player->exiting || !ticcmd_ztargetfocus[forplayer]->health || (ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked ) @@ -1466,7 +1469,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]); newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating - if (player->mo && P_AproxDistance( + if (player->mo && R_PointToDist2(0, 0, player->mo->x - ticcmd_ztargetfocus[forplayer]->x, player->mo->y - ticcmd_ztargetfocus[forplayer]->y ) > 50*player->mo->scale) @@ -4018,7 +4021,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) INT32 i; INT16 newmapnum; boolean spec = G_IsSpecialStage(gamemap); - + // go to next level // newmapnum is 0-based, unlike gamemap if (nextmapoverride != 0) @@ -4122,7 +4125,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) if (spec && (!gottoken || ignoretokens) && !nextmapoverride) newmapnum = lastmap; // Exiting from a special stage? Go back to the game. Tails 08-11-2001 - + if (!(gametyperules & GTR_CAMPAIGN)) { if (cv_advancemap.value == 0) // Stay on same map. @@ -4130,7 +4133,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) else if (cv_advancemap.value == 2) // Go to random map. newmapnum = RandMap(G_TOLFlag(gametype_to_use), prevmap); } - + return newmapnum; } @@ -4140,7 +4143,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) static void G_DoCompleted(void) { INT32 i; - + tokenlist = 0; // Reset the list if (modeattacking && pausedelay) @@ -4168,7 +4171,7 @@ static void G_DoCompleted(void) //Get and set prevmap/nextmap prevmap = (INT16)(gamemap-1); nextmap = G_GetNextMap(false, false); - + automapactive = false; // We are committed to this map now. From f8650a17a0f5b6d31dbb462457378a2e96477d64 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sun, 28 Apr 2024 16:21:48 +0200 Subject: [PATCH 34/74] Fix aim in splitscreen --- src/hardware/hw_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0771708eb..376639878 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5222,6 +5222,8 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean { fixed_t fixedaiming = AIMINGTODY(aimingangle); trans->viewaiming = FIXED_TO_FLOAT(fixedaiming) * ((float)vid.width / vid.height) / ((float)BASEVIDWIDTH / BASEVIDHEIGHT); + if (splitscreen) + trans->viewaiming *= 2.125; // splitscreen adjusts fov with 0.8, so compensate (but only halfway, since splitscreen means only half the screen is used) trans->shearing = true; gl_aimingangle = 0; } From b0f5255a0d9e2fbd9949fabf0f0507e32b776d9f Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 28 Apr 2024 17:10:34 -0500 Subject: [PATCH 35/74] Removed thokked when hitting springs --- src/p_map.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index f97ddfa3c..f6f9c69b5 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -389,7 +389,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { INT32 pflags; UINT8 secondjump; - boolean washoming; if (spring->flags & MF_ENEMY) // Spring shells P_SetTarget(&spring->target, object); @@ -421,7 +420,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { boolean wasSpindashing = object->player->dashspeed > 0 && (object->player->charability2 == CA2_SPINDASH); - pflags = object->player->pflags & (PF_STARTJUMP | PF_JUMPED | PF_NOJUMPDAMAGE | PF_SPINNING | PF_THOKKED | PF_BOUNCING); // I still need these. + pflags = object->player->pflags & (PF_STARTJUMP | PF_JUMPED | PF_NOJUMPDAMAGE | PF_SPINNING | PF_BOUNCING); // I still need these. if (wasSpindashing) // Ensure we're in the rolling state, and not spindash. P_SetMobjState(object, S_PLAY_ROLL); @@ -433,7 +432,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } } secondjump = object->player->secondjump; - washoming = object->player->homing; P_ResetPlayer(object->player); if (spring->info->painchance == 1) // For all those ancient, SOC'd abilities. @@ -445,8 +443,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { object->player->pflags |= (pflags &~ PF_STARTJUMP); object->player->secondjump = secondjump; - if (washoming) - object->player->pflags &= ~PF_THOKKED; } else if (!vertispeed) { From c208921c4a65e6485c73066a28207978141da261 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Wed, 1 May 2024 17:26:02 +0200 Subject: [PATCH 36/74] Add tofixed lua function --- src/lua_baselib.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index f6b8f462b..dc6a26c81 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -345,6 +345,18 @@ static int lib_reserveLuabanks(lua_State *L) return 1; } +static int lib_tofixed(lua_State *L) +{ + const char *arg = luaL_checkstring(L, 1); + char *end; + float f = strtof(arg, &end); + if (*end != '\0') + lua_pushnil(L); + else + lua_pushnumber(L, FLOAT_TO_FIXED(f)); + return 1; +} + // M_MENU ////////////// @@ -4333,6 +4345,7 @@ static luaL_Reg lib[] = { {"userdataMetatable", lib_userdataMetatable}, {"IsPlayerAdmin", lib_isPlayerAdmin}, {"reserveLuabanks", lib_reserveLuabanks}, + {"tofixed", lib_tofixed}, // m_menu {"M_MoveColorAfter",lib_pMoveColorAfter}, From efced4e7637eacf803592e530149788c75c67c4d Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 3 May 2024 15:54:36 +0200 Subject: [PATCH 37/74] Allow less than 3 emerald shards instead of crashing --- src/p_setup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 41487d702..f6d9604d5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -831,13 +831,15 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) static void P_SpawnEmeraldHunt(void) { - INT32 emer[3], num[MAXHUNTEMERALDS], i, randomkey; + INT32 emer[3], num[MAXHUNTEMERALDS], i, amount, randomkey; fixed_t x, y, z; for (i = 0; i < numhuntemeralds; i++) num[i] = i; - for (i = 0; i < 3; i++) + amount = min(numhuntemeralds, 3); + + for (i = 0; i < amount; i++) { // generate random index, shuffle afterwards randomkey = P_RandomKey(numhuntemeralds--); From da3355a1536d212e58ced550bcfd5a56efd2f8af Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sat, 4 May 2024 03:39:41 -0300 Subject: [PATCH 38/74] Fix #1247 --- src/r_draw.c | 2 +- src/r_draw.h | 5 +- src/r_draw8.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++++ src/r_segs.c | 63 +++++++++++++----- src/r_things.c | 12 ++-- 5 files changed, 235 insertions(+), 23 deletions(-) diff --git a/src/r_draw.c b/src/r_draw.c index 86f7e488c..feb4693bb 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -74,7 +74,7 @@ UINT8 *dc_transmap; // one of the translucency tables UINT8 *dc_translation; struct r_lightlist_s *dc_lightlist = NULL; -INT32 dc_numlights = 0, dc_maxlights, dc_texheight; +INT32 dc_numlights = 0, dc_maxlights, dc_texheight, dc_postlength; // ========================================================================= // SPAN DRAWING CODE STUFF diff --git a/src/r_draw.h b/src/r_draw.h index 1a828312a..77588d7de 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -41,8 +41,7 @@ extern UINT8 *dc_translation; extern struct r_lightlist_s *dc_lightlist; extern INT32 dc_numlights, dc_maxlights; -//Fix TUTIFRUTI -extern INT32 dc_texheight; +extern INT32 dc_texheight, dc_postlength; // ----------------------- // SPAN DRAWING CODE STUFF @@ -154,8 +153,10 @@ void R_VideoErase(size_t ofs, INT32 count); // ----------------- void R_DrawColumn_8(void); +void R_DrawColumnClamped_8(void); void R_DrawShadeColumn_8(void); void R_DrawTranslucentColumn_8(void); +void R_DrawTranslucentColumnClamped_8(void); void R_DrawDropShadowColumn_8(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 99fb71e28..735127f88 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -100,6 +100,98 @@ void R_DrawColumn_8(void) } } +/** \brief The R_DrawColumnClamped_8 function + Same as R_DrawColumn_8, but prevents artifacts from showing up (caused by fixed-point imprecisions) +*/ +void R_DrawColumnClamped_8(void) +{ + INT32 count; + UINT8 *dest; + fixed_t frac; + fixed_t fracstep; + + count = dc_yh - dc_yl; + + if (count < 0) // Zero length, column does not exceed a pixel. + return; + +#ifdef RANGECHECK + if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + return; +#endif + + // Framebuffer destination address. + dest = &topleft[dc_yl*vid.width + dc_x]; + + count++; + + // Determine scaling, which is the only mapping to be done. + fracstep = dc_iscale; + frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep); + + // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. + // This is as fast as it gets. + { + const UINT8 *source = dc_source; + const lighttable_t *colormap = dc_colormap; + INT32 heightmask = dc_texheight-1; + INT32 idx; + if (dc_texheight & heightmask) // not a power of 2 -- killough + { + heightmask++; + heightmask <<= FRACBITS; + + if (frac < 0) + while ((frac += heightmask) < 0); + else + while (frac >= heightmask) + frac -= heightmask; + + do + { + // Re-map color indices from wall texture column + // using a lighting/special effects LUT. + // heightmask is the Tutti-Frutti fix + idx = frac>>FRACBITS; + if (idx >= 0 && idx < dc_postlength) + *dest = colormap[source[idx]]; + dest += vid.width; + + // Avoid overflow. + if (fracstep > 0x7FFFFFFF - frac) + frac += fracstep - heightmask; + else + frac += fracstep; + + while (frac >= heightmask) + frac -= heightmask; + } while (--count); + } + else + { + while ((count -= 2) >= 0) // texture height is a power of 2 + { + idx = (frac>>FRACBITS) & heightmask; + if (idx >= 0 && idx < dc_postlength) + *dest = colormap[source[idx]]; + dest += vid.width; + frac += fracstep; + idx = (frac>>FRACBITS) & heightmask; + if (idx >= 0 && idx < dc_postlength) + *dest = colormap[source[idx]]; + dest += vid.width; + frac += fracstep; + } + if (count & 1) + { + idx = (frac>>FRACBITS) & heightmask; + if (idx >= 0 && idx < dc_postlength) + *dest = colormap[source[idx]]; + } + } + } +} + /** \brief The R_DrawShadeColumn_8 function Experiment to make software go faster. Taken from the Boom source */ @@ -212,6 +304,90 @@ void R_DrawTranslucentColumn_8(void) } } +/** \brief The R_DrawTranslucentColumnClamped_8 function + Same as R_DrawTranslucentColumn_8, but prevents artifacts from showing up (caused by fixed-point imprecisions) +*/ +void R_DrawTranslucentColumnClamped_8(void) +{ + INT32 count; + UINT8 *dest; + fixed_t frac, fracstep; + + count = dc_yh - dc_yl + 1; + + if (count <= 0) // Zero length, column does not exceed a pixel. + return; + +#ifdef RANGECHECK + if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + I_Error("R_DrawTranslucentColumnClamped_8: %d to %d at %d", dc_yl, dc_yh, dc_x); +#endif + + dest = &topleft[dc_yl*vid.width + dc_x]; + + // Looks familiar. + fracstep = dc_iscale; + frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep); + + // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. + // This is as fast as it gets. + { + const UINT8 *source = dc_source; + const UINT8 *transmap = dc_transmap; + const lighttable_t *colormap = dc_colormap; + INT32 heightmask = dc_texheight - 1; + INT32 idx; + if (dc_texheight & heightmask) + { + heightmask++; + heightmask <<= FRACBITS; + + if (frac < 0) + while ((frac += heightmask) < 0) + ; + else + while (frac >= heightmask) + frac -= heightmask; + + do + { + // Re-map color indices from wall texture column + // using a lighting/special effects LUT. + // heightmask is the Tutti-Frutti fix + idx = frac>>FRACBITS; + if (idx >= 0 && idx < dc_postlength) + *dest = *(transmap + (colormap[source[idx]]<<8) + (*dest)); + dest += vid.width; + if ((frac += fracstep) >= heightmask) + frac -= heightmask; + } + while (--count); + } + else + { + while ((count -= 2) >= 0) // texture height is a power of 2 + { + idx = (frac>>FRACBITS)&heightmask; + if (idx >= 0 && idx < dc_postlength) + *dest = *(transmap + (colormap[source[idx]]<<8) + (*dest)); + dest += vid.width; + frac += fracstep; + idx = (frac>>FRACBITS)&heightmask; + if (idx >= 0 && idx < dc_postlength) + *dest = *(transmap + (colormap[source[idx]]<<8) + (*dest)); + dest += vid.width; + frac += fracstep; + } + if (count & 1) + { + idx = (frac>>FRACBITS)&heightmask; + if (idx >= 0 && idx < dc_postlength) + *dest = *(transmap + (colormap[source[idx]]<<8) + (*dest)); + } + } + } +} + // Hack: A cut-down copy of R_DrawTranslucentColumn_8 that does not read texture // data since something about calculating the texture reading address for drop shadows is broken. // dc_texturemid and dc_iscale get wrong values for drop shadows, however those are not strictly diff --git a/src/r_segs.c b/src/r_segs.c index e07ced86a..b7f9cd77b 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -515,6 +515,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t wall_scalex, wall_scaley; UINT8 vertflip; unsigned lengthcol; + boolean fog = false; + boolean fuzzy = false; void (*colfunc_2s) (column_t *, unsigned); @@ -528,8 +530,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; sidedef = R_GetFFloorSide(curline, pfloor); - colfunc = colfuncs[BASEDRAWFUNC]; - if (pfloor->master->flags & ML_TFERLINE) { line_t *newline = R_GetFFloorLine(curline, pfloor); @@ -547,7 +547,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (pfloor->fofflags & FOF_TRANSLUCENT) { - boolean fuzzy = true; + fuzzy = true; // Hacked up support for alpha value in software mode Tails 09-24-2002 // ...unhacked by toaster 04-01-2021, re-hacked a little by sphere 19-11-2021 @@ -560,17 +560,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else if (!(dc_transmap = R_GetTranslucencyTable(trans)) || trans == 0) fuzzy = false; // Opaque } - - if (fuzzy) - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; } else if (pfloor->fofflags & FOF_FOG) + { colfunc = colfuncs[COLDRAWFUNC_FOG]; + fog = true; + } range = max(ds->x2-ds->x1, 1); - //SoM: Moved these up here so they are available for my lightlist calculations - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; dc_numlights = 0; if (frontsector->numlights) @@ -673,9 +670,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // Get correct light level! if ((frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (pfloor->fofflags & FOF_FOG) + else if (fog) lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + else if (fuzzy) lightnum = LIGHTLEVELS-1; else lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) @@ -703,6 +700,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) vertflip = !vertflip; } + //SoM: Moved these up here so they are available for my lightlist calculations + // Lactozilla: Moved them back down + // This uses floating point math now, because the fixed-point imprecisions + // become more severe the bigger the texture is scaled. + double dwall_scaley = FixedToDouble(wall_scaley); + double scalestep = FixedToDouble(ds->scalestep) / dwall_scaley; + double yscale = (FixedToDouble(ds->scale1) + (x1 - ds->x1)*scalestep) / dwall_scaley; + thicksidecol = ffloortexturecolumn; wall_offsetx = ds->offsetx + sidedef->offsetx_mid; @@ -824,15 +829,41 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rlight->botheight += rlight->botheightstep; } } - spryscale += rw_scalestep; + yscale += scalestep; continue; } - dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley); - // Get data for the column col = R_GetColumn(texnum, ((thicksidecol[dc_x] + wall_offsetx) >> FRACBITS)); + spryscale = DoubleToFixed(yscale); + + // Eh. I tried fixing the scaling artifacts but it still wasn't perfect. + // So this checks if the column has gaps in it or not, and if it does, uses a version of the column drawers + // that prevents the artifacts from being visible. + // Note that if rendering fog then none of this matters because there's no texture mapping to be done + if (!fog) + { + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // Column has a single post and it matches the texture height, use regular column drawers + if (col->num_posts == 1 && col->posts[0].topdelta == 0 && col->posts[0].length == (unsigned)dc_texheight) + { + if (fuzzy) + colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + else + colfunc = colfuncs[BASEDRAWFUNC]; + } + else + { + // Otherwise use column drawers with extra checks + if (fuzzy) + colfunc = R_DrawTranslucentColumnClamped_8; + else + colfunc = R_DrawColumnClamped_8; + } + } + // SoM: New code does not rely on R_DrawColumnShadowed_8 which // will (hopefully) put less strain on the stack. if (dc_numlights) @@ -947,7 +978,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (windowtop < windowbottom) colfunc_2s (col, lengthcol); - spryscale += rw_scalestep; + yscale += scalestep; continue; } @@ -966,7 +997,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // draw the texture colfunc_2s (col, lengthcol); - spryscale += rw_scalestep; + yscale += scalestep; } colfunc = colfuncs[BASEDRAWFUNC]; diff --git a/src/r_things.c b/src/r_things.c index c46d81624..fb9757a9a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -839,8 +839,10 @@ void R_DrawMaskedColumn(column_t *column, unsigned lengthcol) { post_t *post = &column->posts[i]; + dc_postlength = post->length; + INT32 topscreen = sprtopscreen + spryscale*post->topdelta; - INT32 bottomscreen = topscreen + spryscale*post->length; + INT32 bottomscreen = topscreen + spryscale*dc_postlength; dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; dc_yh = (bottomscreen-1)>>FRACBITS; @@ -909,10 +911,12 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol) if (!post->length) continue; - topdelta = lengthcol-post->length-post->topdelta; + dc_postlength = post->length; + + topdelta = lengthcol-dc_postlength-post->topdelta; topscreen = sprtopscreen + spryscale*topdelta; - bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length - : sprbotscreen + spryscale*post->length; + bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*dc_postlength + : sprbotscreen + spryscale*dc_postlength; dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; dc_yh = (bottomscreen-1)>>FRACBITS; From b3418cd6859d7669e7bbbb812c4dfbc0ecc9d5bd Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 19 May 2024 01:29:54 -0300 Subject: [PATCH 39/74] Fix #523 --- src/p_maputl.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 242bc559e..e9ec71eec 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -500,6 +500,20 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) INT32 texnum = R_GetTextureNum(side->midtexture); // make sure the texture is actually valid if (texnum) { + fixed_t midopentop, midopenbottom; + + if (linedef->flags & ML_NOSKEW) + { + // Use the sector's actual heights if the midtexture is not skewed + midopentop = min(front->ceilingheight, back->ceilingheight); + midopenbottom = max(front->floorheight, back->floorheight); + } + else + { + midopentop = opentop; + midopenbottom = openbottom; + } + // Get the midtexture's height texheight = textures[texnum]->height << FRACBITS; @@ -522,13 +536,13 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) #endif { if (linedef->flags & ML_WRAPMIDTEX && !side->repeatcnt) { // "infinite" repeat - texbottom = openbottom + side->rowoffset + side->offsety_mid; - textop = opentop + side->rowoffset + side->offsety_mid; + texbottom = midopenbottom + side->rowoffset + side->offsety_mid; + textop = midopentop + side->rowoffset + side->offsety_mid; } else if (linedef->flags & ML_MIDPEG) { - texbottom = openbottom + side->rowoffset + side->offsety_mid; + texbottom = midopenbottom + side->rowoffset + side->offsety_mid; textop = texbottom + texheight*(side->repeatcnt+1); } else { - textop = opentop + side->rowoffset + side->offsety_mid; + textop = midopentop + side->rowoffset + side->offsety_mid; texbottom = textop - texheight*(side->repeatcnt+1); } } @@ -539,11 +553,17 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta2 = abs(thingtop - texmid); if (delta1 > delta2) { // Below - if (opentop > texbottom) + if (opentop > texbottom) { opentop = texbottom; + if (linedef->flags & ML_NOSKEW) + opentopslope = NULL; // Object is not actually on a slope + } } else { // Above - if (openbottom < textop) + if (openbottom < textop) { openbottom = textop; + if (linedef->flags & ML_NOSKEW) + openbottomslope = NULL; // Object is not actually on a slope + } } } } From ccadfd8157e2b408c277232bc7c88e54e9f9c47b Mon Sep 17 00:00:00 2001 From: Refrag Date: Sun, 19 May 2024 09:08:00 +0200 Subject: [PATCH 40/74] Fix mouse buttons not working in menus with alwaysgrabmouse on This commit fixes #1257 by reintroducing something left out in commit 9f116c7c9ef29b77e42df8ccae94087c81fc3285. From my testing, it looks look the behavior is the exact same regarding the lua hook script that the original commit was fixing (#879). --- src/sdl/i_video.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 76fe172fc..249be61f6 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -382,6 +382,8 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) static boolean ShouldIgnoreMouse(void) { + if (cv_alwaysgrabmouse.value) + return false; if (menuactive) return !M_MouseNeeded(); if (paused || con_destlines || chat_on) From 27e1ee710ca31c6c9873507a3535ea8bb41a88c1 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 19 May 2024 15:28:55 -0300 Subject: [PATCH 41/74] Fix #1248 --- src/p_maputl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 242bc559e..f00534d63 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -501,7 +501,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (texnum) { // Get the midtexture's height - texheight = textures[texnum]->height << FRACBITS; + texheight = FixedDiv(textureheight[texnum], abs(side->scaley_mid)); // Set texbottom and textop to the Z coordinates of the texture's boundaries #if 0 From 3a62ebbe3edbae3eacdadb0392a62412e25f089d Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 19 May 2024 18:56:14 -0300 Subject: [PATCH 42/74] Set correct slope for solid midtextures --- src/p_maputl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 242bc559e..18a15a928 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -539,11 +539,19 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta2 = abs(thingtop - texmid); if (delta1 > delta2) { // Below - if (opentop > texbottom) + if (opentop > texbottom) { opentop = texbottom; + if ((linedef->flags & ML_MIDPEG) != 0) { + opentopslope = openbottomslope; + } + } } else { // Above - if (openbottom < textop) + if (openbottom < textop) { openbottom = textop; + if ((linedef->flags & ML_MIDPEG) == 0) { + openbottomslope = opentopslope; + } + } } } } From e67e225ff2f796ba8cb78c9bacc5c91f052d5271 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 19 May 2024 20:40:40 -0300 Subject: [PATCH 43/74] Improve slope physics on solid middle textures --- src/p_local.h | 1 + src/p_map.c | 27 ++++++++-- src/p_maputl.c | 5 ++ src/p_maputl.h | 1 + src/p_mobj.c | 31 ++++++++---- src/p_mobj.h | 4 +- src/p_saveg.c | 9 +++- src/p_slopes.c | 130 +++++++++++++++++++++++++++++++++++++++++++------ src/p_slopes.h | 10 +++- src/p_user.c | 6 +-- 10 files changed, 189 insertions(+), 35 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 249c3cd4b..6a4aa241c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -399,6 +399,7 @@ extern camera_t *mapcampointer; extern fixed_t tmx; extern fixed_t tmy; extern pslope_t *tmfloorslope, *tmceilingslope; +extern line_t *tmfloorline, *tmceilingline; /* cphipps 2004/08/30 */ extern void P_MapStart(void); diff --git a/src/p_map.c b/src/p_map.c index f97ddfa3c..aeeeda056 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -55,6 +55,7 @@ mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) ffloor_t *tmfloorrover, *tmceilingrover; pslope_t *tmfloorslope, *tmceilingslope; +line_t *tmfloorline, *tmceilingline; // keep track of the line that lowers the ceiling, // so missiles don't explode against sky hack walls @@ -1760,6 +1761,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmfloorz = thing->z + thing->height; tmfloorrover = NULL; tmfloorslope = NULL; + tmfloorline = NULL; } return CHECKTHING_COLLIDE; } @@ -1779,6 +1781,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmfloorz = tmceilingz = topz; // block while in air tmceilingrover = NULL; tmceilingslope = NULL; + tmceilingline = NULL; tmfloorthing = thing; // needed for side collision collide = CHECKTHING_COLLIDE; @@ -1788,6 +1791,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmceilingz = topz; tmceilingrover = NULL; tmceilingslope = NULL; + tmceilingline = NULL; tmfloorthing = thing; // thing we may stand on collide = CHECKTHING_COLLIDE; @@ -1805,6 +1809,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmceilingz = thing->z; tmceilingrover = NULL; tmceilingslope = NULL; + tmceilingline = NULL; } return CHECKTHING_COLLIDE; } @@ -1824,6 +1829,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmfloorz = tmceilingz = topz; // block while in air tmfloorrover = NULL; tmfloorslope = NULL; + tmfloorline = NULL; tmfloorthing = thing; // needed for side collision collide = CHECKTHING_COLLIDE; @@ -1833,6 +1839,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmfloorz = topz; tmfloorrover = NULL; tmfloorslope = NULL; + tmfloorline = NULL; tmfloorthing = thing; // thing we may stand on collide = CHECKTHING_COLLIDE; @@ -2000,6 +2007,7 @@ static boolean PIT_CheckLine(line_t *ld) ceilingline = ld; tmceilingrover = openceilingrover; tmceilingslope = opentopslope; + tmceilingline = opentopline; } if (openbottom > tmfloorz) @@ -2007,6 +2015,7 @@ static boolean PIT_CheckLine(line_t *ld) tmfloorz = openbottom; tmfloorrover = openfloorrover; tmfloorslope = openbottomslope; + tmfloorline = openbottomline; } if (highceiling > tmdrpoffceilz) @@ -2057,6 +2066,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight; tmfloorrover = NULL; tmceilingrover = NULL; + tmfloorline = NULL; + tmceilingline = NULL; tmfloorslope = newsubsec->sector->f_slope; tmceilingslope = newsubsec->sector->c_slope; @@ -2642,6 +2653,8 @@ boolean PIT_PushableMoved(mobj_t *thing) ffloor_t *oldceilrover = tmceilingrover; pslope_t *oldfslope = tmfloorslope; pslope_t *oldcslope = tmceilingslope; + line_t *oldfline = tmfloorline; + line_t *oldcline = tmceilingline; // Move the player P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); @@ -2658,6 +2671,8 @@ boolean PIT_PushableMoved(mobj_t *thing) tmceilingrover = oldceilrover; tmfloorslope = oldfslope; tmceilingslope = oldcslope; + tmfloorline = oldfline; + tmceilingline = oldcline; thing->momz = stand->momz; } else @@ -2899,11 +2914,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) // Assign thing's standingslope if needed if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { if (!startingonground && tmfloorslope) - P_HandleSlopeLanding(thing, tmfloorslope); + P_HandleSlopeLanding(thing, tmfloorslope, tmfloorline); if (thing->momz <= 0) { thing->standingslope = tmfloorslope; + thing->standingline = tmfloorline; P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) @@ -2912,11 +2928,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) } else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { if (!startingonground && tmceilingslope) - P_HandleSlopeLanding(thing, tmceilingslope); + P_HandleSlopeLanding(thing, tmceilingslope, tmceilingline); if (thing->momz >= 0) { thing->standingslope = tmceilingslope; + thing->standingline = tmceilingline; P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) @@ -2924,8 +2941,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) } } } - else // don't set standingslope if you're not going to clip against it + else + { + // don't set standingslope or standingline if you're not going to clip against them thing->standingslope = NULL; + thing->standingline = NULL; + } thing->x = x; thing->y = y; diff --git a/src/p_maputl.c b/src/p_maputl.c index 18a15a928..7de5b5369 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -280,6 +280,7 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1) fixed_t opentop, openbottom, openrange, lowfloor, highceiling; pslope_t *opentopslope, *openbottomslope; ffloor_t *openfloorrover, *openceilingrover; +line_t *opentopline, *openbottomline; // P_CameraLineOpening // P_LineOpening, but for camera @@ -440,6 +441,8 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) I_Assert(back != NULL); openfloorrover = openceilingrover = NULL; + opentopline = openbottomline = NULL; + if (linedef->polyobj) { // set these defaults so that polyobjects don't interfere with collision above or below them @@ -544,6 +547,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if ((linedef->flags & ML_MIDPEG) != 0) { opentopslope = openbottomslope; } + opentopline = linedef; } } else { // Above if (openbottom < textop) { @@ -551,6 +555,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if ((linedef->flags & ML_MIDPEG) == 0) { openbottomslope = opentopslope; } + openbottomline = linedef; } } } diff --git a/src/p_maputl.h b/src/p_maputl.h index e894c08a2..ca29fc203 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -57,6 +57,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; extern pslope_t *opentopslope, *openbottomslope; extern ffloor_t *openfloorrover, *openceilingrover; +extern line_t *opentopline, *openbottomline; void P_LineOpening(line_t *plinedef, mobj_t *mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index 9cdd2628d..221149f70 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1672,6 +1672,7 @@ void P_XYMovement(mobj_t *mo) fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls boolean moved; pslope_t *oldslope = NULL; + line_t *oldstandingline = NULL; vector3_t slopemom = {0,0,0}; fixed_t predictedz = 0; @@ -1704,7 +1705,10 @@ void P_XYMovement(mobj_t *mo) oldy = mo->y; if (mo->flags & MF_NOCLIPHEIGHT) + { mo->standingslope = NULL; + mo->standingline = NULL; + } // adjust various things based on slope if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { @@ -1716,7 +1720,7 @@ void P_XYMovement(mobj_t *mo) slopemom.x = xmove; slopemom.y = ymove; slopemom.z = 0; - P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + P_QuantizeObjectMomentumToSlope(mo, &slopemom); xmove = slopemom.x; ymove = slopemom.y; @@ -1724,6 +1728,7 @@ void P_XYMovement(mobj_t *mo) predictedz = mo->z + slopemom.z; // We'll use this later... oldslope = mo->standingslope; + oldstandingline = mo->standingline; } } else if (P_IsObjectOnGround(mo) && !mo->momz) predictedz = mo->z; @@ -1799,12 +1804,16 @@ void P_XYMovement(mobj_t *mo) { // try to slide along it // Wall transfer part 1. pslope_t *transferslope = NULL; + line_t *transferline = NULL; fixed_t transfermomz = 0; if (oldslope && (P_MobjFlip(mo)*(predictedz - mo->z) > 0)) // Only for moving up (relative to gravity), otherwise there's a failed launch when going down slopes and hitting walls { + angle_t zangle; transferslope = ((mo->standingslope) ? mo->standingslope : oldslope); - if (((transferslope->zangle < ANGLE_180) ? transferslope->zangle : InvAngle(transferslope->zangle)) >= ANGLE_45) // Prevent some weird stuff going on on shallow slopes. - transfermomz = P_GetWallTransferMomZ(mo, transferslope); + transferline = ((mo->standingline) ? mo->standingline : oldstandingline); + zangle = P_GetStandingSlopeZAngle(transferslope, transferline); + if (((zangle < ANGLE_180) ? zangle : InvAngle(zangle)) >= ANGLE_45) // Prevent some weird stuff going on on shallow slopes. + transfermomz = P_GetWallTransferMomZ(mo, transferslope, transferline); } P_SlideMove(mo); @@ -1817,7 +1826,7 @@ void P_XYMovement(mobj_t *mo) { angle_t relation; // Scale transfer momentum based on how head-on it is to the slope. if (mo->momx || mo->momy) // "Guess" the angle of the wall you hit using new momentum - relation = transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy); + relation = P_GetStandingSlopeDirection(transferslope, transferline) - R_PointToAngle2(0, 0, mo->momx, mo->momy); else // Give it for free, I guess. relation = ANGLE_90; transfermomz = FixedMul(transfermomz, @@ -1826,6 +1835,7 @@ void P_XYMovement(mobj_t *mo) { mo->momz = transfermomz; mo->standingslope = NULL; + mo->standingline = NULL; if (player) { player->powers[pw_justlaunched] = 2; @@ -1875,7 +1885,7 @@ void P_XYMovement(mobj_t *mo) oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT)); if (mo->standingslope) - newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); + newangle = FixedMul((signed)P_GetObjectStandingSlopeZAngle(mo), FINECOSINE((moveangle - P_GetObjectStandingSlopeDirection(mo)) >> ANGLETOFINESHIFT)); else newangle = 0; @@ -1899,7 +1909,7 @@ void P_XYMovement(mobj_t *mo) } } else if (moved && mo->standingslope && predictedz) { angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); - angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); + angle_t newangle = FixedMul((signed)P_GetObjectStandingSlopeZAngle(mo), FINECOSINE((moveangle - P_GetObjectStandingSlopeDirection(mo)) >> ANGLETOFINESHIFT)); /*CONS_Printf("flat to angle %f - predicted z of %f\n", FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)), @@ -2432,8 +2442,9 @@ boolean P_ZMovement(mobj_t *mo) if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; + mo->standingline = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingline : tmfloorline; P_SetPitchRollFromSlope(mo, mo->standingslope); - P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); + P_ReverseQuantizeObjectMomentumToSlope(mo, &mom); } // hit the floor @@ -2579,7 +2590,7 @@ boolean P_ZMovement(mobj_t *mo) mom.z = tmfloorthing->momz; if (mo->standingslope) { // MT_STEAM will never have a standingslope, see above. - P_QuantizeMomentumToSlope(&mom, mo->standingslope); + P_QuantizeObjectMomentumToSlope(mo, &mom); } mo->momx = mom.x; @@ -2825,7 +2836,9 @@ void P_PlayerZMovement(mobj_t *mo) if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { // Handle landing on slope during Z movement - P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); + P_HandleSlopeLanding(mo, + (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope), + (mo->eflags & MFE_VERTICALFLIP ? tmceilingline : tmfloorline)); } if (P_MobjFlip(mo)*mo->momz < 0) // falling diff --git a/src/p_mobj.h b/src/p_mobj.h index 2f013a2f3..ae4c5a51d 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -412,7 +412,9 @@ typedef struct mobj_s INT32 cusval; INT32 cvmem; - struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) + struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) (it does) + + struct line_s *standingline; // The line that the object is standing on boolean resetinterp; // if true, some fields should not be interpolated (see R_InterpolateMobjState implementation) boolean colorized; // Whether the mobj uses the rainbow colormap diff --git a/src/p_saveg.c b/src/p_saveg.c index 5e4d6d076..675d68acd 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1746,7 +1746,8 @@ typedef enum MD2_DISPOFFSET = 1<<23, MD2_DRAWONLYFORPLAYER = 1<<24, MD2_DONTDRAWFORVIEWMOBJ = 1<<25, - MD2_TRANSLATION = 1<<26 + MD2_TRANSLATION = 1<<26, + MD2_STANDINGLINE = 1<<27 } mobj_diff2_t; typedef enum @@ -1953,6 +1954,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_CEILINGROVER; if (mobj->standingslope) diff2 |= MD2_SLOPE; + if (mobj->standingline) + diff2 |= MD2_STANDINGLINE; if (mobj->colorized) diff2 |= MD2_COLORIZED; if (mobj->mirrored) @@ -2125,6 +2128,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->hprev->mobjnum); if (diff2 & MD2_SLOPE) WRITEUINT16(save_p, mobj->standingslope->id); + if (diff2 & MD2_STANDINGLINE) + WRITEUINT32(save_p, SaveLine(mobj->standingline)); if (diff2 & MD2_COLORIZED) WRITEUINT8(save_p, mobj->colorized); if (diff2 & MD2_MIRRORED) @@ -3181,6 +3186,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_SLOPE) mobj->standingslope = P_SlopeById(READUINT16(save_p)); + if (diff2 & MD2_STANDINGLINE) + mobj->standingline = LoadLine(READUINT32(save_p)); if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); if (diff2 & MD2_MIRRORED) diff --git a/src/p_slopes.c b/src/p_slopes.c index e75d36ede..745be2eac 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -859,11 +859,10 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y) // When given a vector, rotates it and aligns it to a slope void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) { - vector3_t axis; // Fuck you, C90. - if (slope->flags & SL_NOPHYSICS) return; // No physics, no quantizing. + vector3_t axis; axis.x = -slope->d.y; axis.y = slope->d.x; axis.z = 0; @@ -877,9 +876,91 @@ void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) // When given a vector, rotates and aligns it to a flat surface (from being relative to a given slope) void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) { - slope->zangle = InvAngle(slope->zangle); - P_QuantizeMomentumToSlope(momentum, slope); - slope->zangle = InvAngle(slope->zangle); + if (slope->flags & SL_NOPHYSICS) + return; // No physics, no quantizing. + + vector3_t axis; + axis.x = -slope->d.y; + axis.y = slope->d.x; + axis.z = 0; + + FV3_Rotate(momentum, &axis, InvAngle(slope->zangle) >> ANGLETOFINESHIFT); +} + +angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line) +{ + angle_t zangle = slope->zangle; + + if (line) + { + zangle = R_PointToAngle2(0, P_GetSlopeZAt(slope, line->v1->x, line->v1->y), + R_PointToDist2(line->v1->x, line->v1->y, line->v2->x, line->v2->y), P_GetSlopeZAt(slope, line->v2->x, line->v2->y)); + } + + return zangle; +} + +angle_t P_GetStandingSlopeDirection(pslope_t *slope, line_t *line) +{ + angle_t xydirection = slope->xydirection; + + if (line) + { + xydirection = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); + } + + return xydirection; +} + +angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo) +{ + return P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline); +} + +angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo) +{ + return P_GetStandingSlopeDirection(mo->standingslope, mo->standingline); +} + +static void QuantizeMomentumToSlope(pslope_t *slope, line_t *line, vector3_t *momentum, boolean reverse) +{ + if (!slope || slope->flags & SL_NOPHYSICS) + return; + + angle_t zangle = P_GetStandingSlopeZAngle(slope, line); + + if (reverse) + zangle = InvAngle(zangle); + + vector3_t axis; + axis.z = 0; + + if (line) + { + fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy); + axis.x = FixedDiv(line->dy, len); + axis.y = -FixedDiv(line->dx, len); + } + else + { + axis.x = -slope->d.y; + axis.y = slope->d.x; + } + + FV3_Rotate(momentum, &axis, zangle >> ANGLETOFINESHIFT); +} + +// Given a vector of the object's momentum, rotates it and aligns it to the slope the object is standing on +void P_QuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum) +{ + QuantizeMomentumToSlope(mo->standingslope, mo->standingline, momentum, false); +} + +// Given a vector of the object's momentum, rotates and aligns it to a flat surface +// (from being relative to the slope the object is standing on) +void P_ReverseQuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum) +{ + QuantizeMomentumToSlope(mo->standingslope, mo->standingline, momentum, true); } // @@ -899,7 +980,7 @@ void P_SlopeLaunch(mobj_t *mo) slopemom.x = mo->momx; slopemom.y = mo->momy; slopemom.z = mo->momz*2; - P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + P_QuantizeObjectMomentumToSlope(mo, &slopemom); mo->momx = slopemom.x; mo->momy = slopemom.y; @@ -919,7 +1000,7 @@ void P_SlopeLaunch(mobj_t *mo) // It would be nice to have a single function that does everything necessary for slope-to-wall transfer. // However, it needs to be seperated out in P_XYMovement to take into account momentum before and after hitting the wall. // This just performs the necessary calculations for getting the base vertical momentum; the horizontal is already reasonably calculated by P_SlideMove. -fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope) +fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line) { vector3_t slopemom, axis; angle_t ang; @@ -927,18 +1008,30 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope) if (slope->flags & SL_NOPHYSICS) return 0; + angle_t zangle = P_GetStandingSlopeZAngle(slope, line); + // If there's physics, time for launching. // Doesn't kill the vertical momentum as much as P_SlopeLaunch does. - ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1); + ang = zangle + ANG15*((zangle > 0) ? 1 : -1); if (ang > ANGLE_90 && ang < ANGLE_180) - ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards + ang = ((zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards slopemom.x = mo->momx; slopemom.y = mo->momy; slopemom.z = 3*(mo->momz/2); - axis.x = -slope->d.y; - axis.y = slope->d.x; + if (line) + { + fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy); + axis.x = FixedDiv(line->dy, len); + axis.y = -FixedDiv(line->dx, len); + } + else + { + axis.x = -slope->d.y; + axis.y = slope->d.x; + } + axis.z = 0; FV3_Rotate(&slopemom, &axis, ang >> ANGLETOFINESHIFT); @@ -947,7 +1040,7 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope) } // Function to help handle landing on slopes -void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line) { vector3_t mom; // Ditto. if (slope->flags & SL_NOPHYSICS || (slope->normal.x == 0 && slope->normal.y == 0)) { // No physics, no need to make anything complicated. @@ -966,12 +1059,13 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) mom.y = thing->momy; mom.z = thing->momz*2; - P_ReverseQuantizeMomentumToSlope(&mom, slope); + QuantizeMomentumToSlope(slope, line, &mom, true); if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope thing->momx = mom.x; thing->momy = mom.y; thing->standingslope = slope; + thing->standingline = line; P_SetPitchRollFromSlope(thing, slope); if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); @@ -983,6 +1077,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) void P_ButteredSlope(mobj_t *mo) { fixed_t thrust; + angle_t zangle, xydirection; if (!mo->standingslope) return; @@ -1001,12 +1096,15 @@ void P_ButteredSlope(mobj_t *mo) return; // Allow the player to stand still on slopes below a certain steepness } - thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); + zangle = P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline); + xydirection = P_GetStandingSlopeDirection(mo->standingslope, mo->standingline); + + thrust = FINESINE(zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); if (mo->player && (mo->player->pflags & PF_SPINNING)) { fixed_t mult = 0; if (mo->momx || mo->momy) { - angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection; + angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - xydirection; if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0) angle ^= ANGLE_180; @@ -1027,5 +1125,5 @@ void P_ButteredSlope(mobj_t *mo) // ... and its friction against the ground for good measure (divided by original friction to keep behaviour for normal slopes the same). thrust = FixedMul(thrust, FixedDiv(mo->friction, ORIG_FRICTION)); - P_Thrust(mo, mo->standingslope->xydirection, thrust); + P_Thrust(mo, xydirection, thrust); } diff --git a/src/p_slopes.h b/src/p_slopes.h index fdc07f67e..f33053ac1 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -84,9 +84,15 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y); // Lots of physics-based bullshit void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); +void P_QuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum); +void P_ReverseQuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum); +angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line); +angle_t P_GetStandingSlopeDirection(pslope_t *slope, line_t *line); +angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo); +angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo); void P_SlopeLaunch(mobj_t *mo); -fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope); -void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); +fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line); +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line); void P_ButteredSlope(mobj_t *mo); pslope_t *P_MakeSlopeViaEquationConstants(const double a, const double b, const double c, const double d); diff --git a/src/p_user.c b/src/p_user.c index 7cd128cf0..1782c5386 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6257,15 +6257,15 @@ static void P_3dMovement(player_t *player) && player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) { // Factor thrust to slope, but only for the part pushing up it! // The rest is unaffected. - angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection; + angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-P_GetObjectStandingSlopeDirection(player->mo); if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) { - P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); + P_QuantizeObjectMomentumToSlope(player->mo, &totalthrust); } } else { // Direction goes up, so thrustangle needs to face away if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) { - P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); + P_QuantizeObjectMomentumToSlope(player->mo, &totalthrust); } } } From 3a09c475c71462f923a6a1c500901e450fa027b7 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 19 May 2024 22:53:00 -0300 Subject: [PATCH 44/74] Add comments --- src/p_slopes.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 745be2eac..1d53bfcf4 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -852,7 +852,6 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y) return light->slope ? P_GetSlopeZAt(light->slope, x, y) : light->height; } - // // P_QuantizeMomentumToSlope // @@ -887,6 +886,8 @@ void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) FV3_Rotate(momentum, &axis, InvAngle(slope->zangle) >> ANGLETOFINESHIFT); } +// Returns the angle of the slope plane. +// If line is provided, a new calculation is performed as if the slope were on the top or bottom of a solid midtexture. angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line) { angle_t zangle = slope->zangle; @@ -900,28 +901,23 @@ angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line) return zangle; } +// Returns the angle of the projected normal of slope plane. +// If line is provided, this simply returns the line's angle. angle_t P_GetStandingSlopeDirection(pslope_t *slope, line_t *line) { angle_t xydirection = slope->xydirection; if (line) { - xydirection = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); + xydirection = line->angle; } return xydirection; } -angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo) -{ - return P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline); -} - -angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo) -{ - return P_GetStandingSlopeDirection(mo->standingslope, mo->standingline); -} - +// When given a vector, rotates it and aligns it to either a slope, or a flat surface relative to the slope. +// If line is provided, this calculation is performed as if the slope were on the top or bottom of a solid midtexture. +// See also: P_QuantizeMomentumToSlope static void QuantizeMomentumToSlope(pslope_t *slope, line_t *line, vector3_t *momentum, boolean reverse) { if (!slope || slope->flags & SL_NOPHYSICS) @@ -963,6 +959,18 @@ void P_ReverseQuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum) QuantizeMomentumToSlope(mo->standingslope, mo->standingline, momentum, true); } +// Wrapper for P_GetStandingSlopeZAngle. +angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo) +{ + return P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline); +} + +// Wrapper for P_GetObjectStandingSlopeDirection. +angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo) +{ + return P_GetStandingSlopeDirection(mo->standingslope, mo->standingline); +} + // // P_SlopeLaunch // @@ -1042,7 +1050,6 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line) // Function to help handle landing on slopes void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line) { - vector3_t mom; // Ditto. if (slope->flags & SL_NOPHYSICS || (slope->normal.x == 0 && slope->normal.y == 0)) { // No physics, no need to make anything complicated. if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope { @@ -1055,6 +1062,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line) return; } + vector3_t mom; mom.x = thing->momx; mom.y = thing->momy; mom.z = thing->momz*2; From 4502e67f0f2c8bcfda5ddd35345fe2edac2ac696 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 20 May 2024 02:48:38 -0300 Subject: [PATCH 45/74] Ignore flats when loading patches --- src/console.c | 6 +- src/d_main.c | 4 +- src/f_finale.c | 8 +- src/hu_stuff.c | 2 +- src/m_menu.c | 10 +- src/st_stuff.c | 6 +- src/w_wad.c | 271 ++++++++++++++++++++++++++++++++++++++++++------- src/w_wad.h | 6 ++ 8 files changed, 256 insertions(+), 57 deletions(-) diff --git a/src/console.c b/src/console.c index 874fc2a4f..d3320fbfc 100644 --- a/src/console.c +++ b/src/console.c @@ -1730,12 +1730,12 @@ static void CON_DrawBackpic(void) // Get the lumpnum for CONSBACK, STARTUP (Only during game startup) or fallback into MISSING. if (con_startup) - piclump = W_CheckNumForName("STARTUP"); + piclump = W_CheckNumForPatchName("STARTUP"); else - piclump = W_CheckNumForName("CONSBACK"); + piclump = W_CheckNumForPatchName("CONSBACK"); if (piclump == LUMPERROR) - piclump = W_GetNumForName("MISSING"); + piclump = W_GetNumForPatchName("MISSING"); // Cache the patch. con_backpic = W_CachePatchNum(piclump, PU_PATCH); diff --git a/src/d_main.c b/src/d_main.c index c139650d1..afa10ae3c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -758,9 +758,9 @@ void D_SRB2Loop(void) /* Smells like a hack... Don't fade Sonic's ass into the title screen. */ if (gamestate != GS_TITLESCREEN) { - gstartuplumpnum = W_CheckNumForName("STARTUP"); + gstartuplumpnum = W_CheckNumForPatchName("STARTUP"); if (gstartuplumpnum == LUMPERROR) - gstartuplumpnum = W_GetNumForName("MISSING"); + gstartuplumpnum = W_GetNumForPatchName("MISSING"); V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(gstartuplumpnum, PU_PATCH)); } diff --git a/src/f_finale.c b/src/f_finale.c index 9ff50147e..810af4e82 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2336,7 +2336,7 @@ void F_SkyScroll(const char *patchname) } #define LOADTTGFX(arr, name, maxf) \ -lumpnum = W_CheckNumForName(name); \ +lumpnum = W_CheckNumForPatchName(name); \ if (lumpnum != LUMPERROR) \ { \ arr[0] = W_CachePatchName(name, PU_PATCH_LOWPRIORITY); \ @@ -2350,7 +2350,7 @@ else if (strlen(name) <= 6) \ { \ sprintf(&lumpname[cnt], "%.2hu", (UINT16)(i+1)); \ lumpname[8] = 0; \ - lumpnum = W_CheckNumForName(lumpname); \ + lumpnum = W_CheckNumForPatchName(lumpname); \ if (lumpnum != LUMPERROR) \ arr[i] = W_CachePatchName(lumpname, PU_PATCH_LOWPRIORITY); \ else \ @@ -4116,7 +4116,7 @@ static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *b // reuse: // cutnum -> promptnum // scenenum -> pagenum - lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); + lumpnum_t iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname); *pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; *rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); @@ -4508,7 +4508,7 @@ void F_TextPromptDrawer(void) if (!promptactive) return; - iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); + iconlump = W_CheckNumForPatchName(textprompts[cutnum]->page[scenenum].iconname); F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); // Draw gfx first diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 4e2f3d492..f8574a962 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -272,7 +272,7 @@ void HU_LoadFontCharacters(fontdef_t *font, const char *prefix) for (i = 0; i < FONTSIZE; i++, j++) { sprintf(buffer, "%.5s%.3d", prefix, j); - if (W_CheckNumForName(buffer) == LUMPERROR) + if (W_CheckNumForPatchName(buffer) == LUMPERROR) font->chars[i] = NULL; else font->chars[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); diff --git a/src/m_menu.c b/src/m_menu.c index 500113475..36b81b947 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4015,11 +4015,11 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv) lumpnum_t leftlump, rightlump, centerlump[2], cursorlump; patch_t *p; - leftlump = W_GetNumForName("M_THERML"); - rightlump = W_GetNumForName("M_THERMR"); - centerlump[0] = W_GetNumForName("M_THERMM"); - centerlump[1] = W_GetNumForName("M_THERMM"); - cursorlump = W_GetNumForName("M_THERMO"); + leftlump = W_CheckNumForPatchName("M_THERML"); + rightlump = W_CheckNumForPatchName("M_THERMR"); + centerlump[0] = W_CheckNumForPatchName("M_THERMM"); + centerlump[1] = W_CheckNumForPatchName("M_THERMM"); + cursorlump = W_CheckNumForPatchName("M_THERMO"); V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_PATCH)); xx += p->width - p->leftoffset; diff --git a/src/st_stuff.c b/src/st_stuff.c index 7df6f8848..e088a448c 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1269,19 +1269,19 @@ tic_t lt_exitticker = 0, lt_endtime = 0; // static void ST_cacheLevelTitle(void) { -#define SETPATCH(default, warning, custom, idx) \ +#define SETPATCH(def, warning, custom, idx) \ { \ lumpnum_t patlumpnum = LUMPERROR; \ if (mapheaderinfo[gamemap-1]->custom[0] != '\0') \ { \ - patlumpnum = W_CheckNumForName(mapheaderinfo[gamemap-1]->custom); \ + patlumpnum = W_CheckNumForPatchName(mapheaderinfo[gamemap-1]->custom); \ if (patlumpnum != LUMPERROR) \ lt_patches[idx] = (patch_t *)W_CachePatchNum(patlumpnum, PU_HUDGFX); \ } \ if (patlumpnum == LUMPERROR) \ { \ if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) \ - lt_patches[idx] = (patch_t *)W_CachePatchName(default, PU_HUDGFX); \ + lt_patches[idx] = (patch_t *)W_CachePatchName(def, PU_HUDGFX); \ else \ lt_patches[idx] = (patch_t *)W_CachePatchName(warning, PU_HUDGFX); \ } \ diff --git a/src/w_wad.c b/src/w_wad.c index 78d26f905..cc7cdc201 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -98,6 +98,7 @@ typedef struct lumpnum_cache_s { char lumpname[32]; lumpnum_t lumpnum; + UINT32 hash; } lumpnum_cache_t; static lumpnum_cache_t lumpnumcache[LUMPNUMCACHESIZE]; @@ -1475,6 +1476,63 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump) return INT16_MAX; } +static lumpnum_t CheckLumpInCache(const char *name, boolean longname) +{ + if (longname) + { + UINT32 hash = quickncasehash(name, 32); + + // Loop backwards so that we check most recent entries first + for (INT32 i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) + { + if (lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].hash == hash + && stricmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0) + { + lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1); + return lumpnumcache[lumpnumcacheindex].lumpnum; + } + } + } + else + { + UINT32 hash = quickncasehash(name, 8); + + // Loop backwards so that we check most recent entries first + for (INT32 i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) + { + if (lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].hash == hash + && lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8] == '\0' + && strnicmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0) + { + lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1); + return lumpnumcache[lumpnumcacheindex].lumpnum; + } + } + } + + return LUMPERROR; +} + +static void AddLumpToCache(lumpnum_t lumpnum, const char *name, boolean longname) +{ + if (longname && strlen(name) >= 32) + return; + + lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1); + memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32); + if (longname) + { + strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32); + lumpnumcache[lumpnumcacheindex].hash = quickncasehash(name, 32); + } + else + { + strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8); + lumpnumcache[lumpnumcacheindex].hash = quickncasehash(name, 8); + } + lumpnumcache[lumpnumcacheindex].lumpnum = lumpnum; +} + // // W_CheckNumForName // Returns LUMPERROR if name not found. @@ -1487,17 +1545,10 @@ lumpnum_t W_CheckNumForName(const char *name) if (!*name) // some doofus gave us an empty string? return LUMPERROR; - // Check the lumpnumcache first. Loop backwards so that we check - // most recent entries first - for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) - { - if (!lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8] - && strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0) - { - lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1); - return lumpnumcache[lumpnumcacheindex].lumpnum; - } - } + // Check the lumpnumcache first. + lumpnum_t cachenum = CheckLumpInCache(name, false); + if (cachenum != LUMPERROR) + return cachenum; // scan wad files backwards so patch lump files take precedence for (i = numwadfiles - 1; i >= 0; i--) @@ -1511,12 +1562,11 @@ lumpnum_t W_CheckNumForName(const char *name) else { // Update the cache. - lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1); - memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32); - strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8); - lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check; + lumpnum_t lumpnum = (i << 16) + check; - return lumpnumcache[lumpnumcacheindex].lumpnum; + AddLumpToCache(lumpnum, name, false); + + return lumpnum; } } @@ -1534,16 +1584,10 @@ lumpnum_t W_CheckNumForLongName(const char *name) if (!*name) // some doofus gave us an empty string? return LUMPERROR; - // Check the lumpnumcache first. Loop backwards so that we check - // most recent entries first - for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) - { - if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0) - { - lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1); - return lumpnumcache[lumpnumcacheindex].lumpnum; - } - } + // Check the lumpnumcache first. + lumpnum_t cachenum = CheckLumpInCache(name, true); + if (cachenum != LUMPERROR) + return cachenum; // scan wad files backwards so patch lump files take precedence for (i = numwadfiles - 1; i >= 0; i--) @@ -1556,16 +1600,12 @@ lumpnum_t W_CheckNumForLongName(const char *name) if (check == INT16_MAX) return LUMPERROR; else { - if (strlen(name) < 32) - { - // Update the cache. - lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1); - memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32); - strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32); - lumpnumcache[lumpnumcacheindex].lumpnum = (i << 16) + check; - } + // Update the cache. + lumpnum_t lumpnum = (i << 16) + check; - return (i << 16) + check; + AddLumpToCache(lumpnum, name, true); + + return lumpnum; } } @@ -1647,6 +1687,159 @@ lumpnum_t W_GetNumForLongName(const char *name) return i; } +// +// Same as W_CheckNumForNamePwad, but handles namespaces. +// +static UINT16 W_CheckNumForPatchNamePwad(const char *name, UINT16 wad, boolean longname) +{ + UINT16 i, start, end; + static char uname[8 + 1] = { 0 }; + UINT32 hash = 0; + lumpinfo_t *lump_p; + + if (!TestValidLump(wad,0)) + return INT16_MAX; + + if (!longname) + { + strlcpy(uname, name, sizeof uname); + strupr(uname); + hash = quickncasehash(uname, 8); + } + + // SRB2 doesn't have a specific namespace for graphics, which means someone can do weird things + // like placing graphics inside a namespace it doesn't make sense for them to be in, like Sounds/ or SOC/ + // So for now, this checks for lumps OUTSIDE of the flats namespace. + // When this situation changes, change the loops below to check for lumps INSIDE the namespaces to look in. + // TODO: cache namespace lump IDs + if (W_FileHasFolders(wadfiles[wad])) + { + start = W_CheckNumForFolderStartPK3("Flats/", wad, 0); + end = W_CheckNumForFolderEndPK3("Flats/", wad, start); + } + else + { + start = W_CheckNumForMarkerStartPwad("F_START", wad, 0); + end = W_CheckNumForNamePwad("F_END", wad, start); + if (end != INT16_MAX) + end++; + } + + lump_p = wadfiles[wad]->lumpinfo; + + if (start == INT16_MAX) + start = wadfiles[wad]->numlumps; + + for (i = 0; i < start; i++, lump_p++) + { + if ((!longname && lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1)) + || (longname && stricmp(lump_p->longname, name) == 0)) + return i; + } + + if (end != INT16_MAX && start < end) + { + lump_p = wadfiles[wad]->lumpinfo + end; + + for (i = end; i < wadfiles[wad]->numlumps; i++, lump_p++) + { + if ((!longname && lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1)) + || (longname && stricmp(lump_p->longname, name) == 0)) + return i; + } + } + + // not found. + return INT16_MAX; +} + +// +// W_CheckNumForPatchNameInternal +// Gets a lump number out of a patch name. Returns LUMPERROR if name not found. +// +static lumpnum_t W_CheckNumForPatchNameInternal(const char *name, boolean longname) +{ + INT32 i; + lumpnum_t check = INT16_MAX; + + if (!*name) // some doofus gave us an empty string? + return LUMPERROR; + + // Check the lumpnumcache first. + lumpnum_t cachenum = CheckLumpInCache(name, longname); + if (cachenum != LUMPERROR) + return cachenum; + + // scan wad files backwards so patch lump files take precedence + for (i = numwadfiles - 1; i >= 0; i--) + { + check = W_CheckNumForPatchNamePwad(name,(UINT16)i,longname); + if (check != INT16_MAX) + break; //found it + } + + if (check == INT16_MAX) return LUMPERROR; + else + { + // Update the cache. + lumpnum_t lumpnum = (i << 16) + check; + + AddLumpToCache(lumpnum, name, longname); + + return lumpnum; + } +} + +// +// W_CheckNumForPatchName +// Wrapper for W_CheckNumForPatchNameInternal(name, false). Returns LUMPERROR if name not found. +// +lumpnum_t W_CheckNumForPatchName(const char *name) +{ + return W_CheckNumForPatchNameInternal(name, false); +} + +// +// Like W_CheckNumForPatchName, but can find entries with long names. +// Wrapper for W_CheckNumForPatchNameInternal(name, true). Returns LUMPERROR if name not found. +// +lumpnum_t W_CheckNumForLongPatchName(const char *name) +{ + return W_CheckNumForPatchNameInternal(name, true); +} + +// +// W_GetNumForPatchName +// +// Calls W_CheckNumForPatchName, but bombs out if not found. +// +lumpnum_t W_GetNumForPatchName(const char *name) +{ + lumpnum_t i; + + i = W_CheckNumForPatchName(name); + + if (i == LUMPERROR) + I_Error("W_CheckNumForPatchName: %s not found!\n", name); + + return i; +} + +// +// Like W_GetNumForPatchName, but can find entries with long names +// +lumpnum_t W_GetNumForLongPatchName(const char *name) +{ + lumpnum_t i; + + i = W_CheckNumForLongPatchName(name); + + if (i == LUMPERROR) + I_Error("W_GetNumForLongPatchName: %s not found!\n", name); + + return i; +} + // // W_CheckNumForNameInBlock // Checks only in blocks from blockstart lump to blockend lump @@ -2291,10 +2484,10 @@ void *W_CachePatchName(const char *name, INT32 tag) { lumpnum_t num; - num = W_CheckNumForName(name); + num = W_CheckNumForPatchName(name); if (num == LUMPERROR) - return W_CachePatchNum(W_GetNumForName("MISSING"), tag); + return W_CachePatchNum(W_GetNumForPatchName("MISSING"), tag); return W_CachePatchNum(num, tag); } @@ -2302,10 +2495,10 @@ void *W_CachePatchLongName(const char *name, INT32 tag) { lumpnum_t num; - num = W_CheckNumForLongName(name); + num = W_CheckNumForLongPatchName(name); if (num == LUMPERROR) - return W_CachePatchNum(W_GetNumForLongName("MISSING"), tag); + return W_CachePatchNum(W_GetNumForLongPatchName("MISSING"), tag); return W_CachePatchNum(num, tag); } #ifndef NOMD5 diff --git a/src/w_wad.h b/src/w_wad.h index 80e0e32fd..3dcb9b6e8 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -193,6 +193,12 @@ lumpnum_t W_CheckNumForName(const char *name); lumpnum_t W_CheckNumForLongName(const char *name); lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR lumpnum_t W_GetNumForLongName(const char *name); + +lumpnum_t W_CheckNumForPatchName(const char *name); +lumpnum_t W_CheckNumForLongPatchName(const char *name); +lumpnum_t W_GetNumForPatchName(const char *name); // like W_CheckNumForPatchName but I_Error on LUMPERROR +lumpnum_t W_GetNumForLongPatchName(const char *name); + lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend); UINT8 W_LumpExists(const char *name); // Lua uses this. From 0186e5bce5d94665867ebb02b354063f9b3653cb Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 20 May 2024 02:54:45 -0300 Subject: [PATCH 46/74] Fix a mistake --- src/m_menu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 36b81b947..dd9d2fdbd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4015,11 +4015,11 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv) lumpnum_t leftlump, rightlump, centerlump[2], cursorlump; patch_t *p; - leftlump = W_CheckNumForPatchName("M_THERML"); - rightlump = W_CheckNumForPatchName("M_THERMR"); - centerlump[0] = W_CheckNumForPatchName("M_THERMM"); - centerlump[1] = W_CheckNumForPatchName("M_THERMM"); - cursorlump = W_CheckNumForPatchName("M_THERMO"); + leftlump = W_GetNumForPatchName("M_THERML"); + rightlump = W_GetNumForPatchName("M_THERMR"); + centerlump[0] = W_GetNumForPatchName("M_THERMM"); + centerlump[1] = W_GetNumForPatchName("M_THERMM"); + cursorlump = W_GetNumForPatchName("M_THERMO"); V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_PATCH)); xx += p->width - p->leftoffset; From 68264e7288c4db5b5797d806bab7df8dc22a8d17 Mon Sep 17 00:00:00 2001 From: Refrag Date: Wed, 15 May 2024 20:03:04 +0200 Subject: [PATCH 47/74] Fix buffer overflow when setting a NETVAR string CVar There was a possible buffer overflow if you tried setting a console var that had the CV_NETVAR and that was of the string type. The overflow would happen if you were trying to set the console variable while in a multiplayer / netgame state. This commit just increases the size of buf to account for everything that needs to be written to it. --- src/command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index a46cc98bc..7947048ed 100644 --- a/src/command.c +++ b/src/command.c @@ -1992,7 +1992,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth) if (var->flags & CV_NETVAR) { // send the value of the variable - UINT8 buf[128]; + UINT8 buf[512]; UINT8 *p = buf; // Loading from a config in a netgame? Set revert value. From 6bf58ce8705111b1c7456edcf269e22e8ed6f1ee Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 20 May 2024 20:10:25 -0300 Subject: [PATCH 48/74] Revert "Add comments" This reverts commit 3a09c475c71462f923a6a1c500901e450fa027b7. --- src/p_slopes.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 1d53bfcf4..745be2eac 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -852,6 +852,7 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y) return light->slope ? P_GetSlopeZAt(light->slope, x, y) : light->height; } + // // P_QuantizeMomentumToSlope // @@ -886,8 +887,6 @@ void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) FV3_Rotate(momentum, &axis, InvAngle(slope->zangle) >> ANGLETOFINESHIFT); } -// Returns the angle of the slope plane. -// If line is provided, a new calculation is performed as if the slope were on the top or bottom of a solid midtexture. angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line) { angle_t zangle = slope->zangle; @@ -901,23 +900,28 @@ angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line) return zangle; } -// Returns the angle of the projected normal of slope plane. -// If line is provided, this simply returns the line's angle. angle_t P_GetStandingSlopeDirection(pslope_t *slope, line_t *line) { angle_t xydirection = slope->xydirection; if (line) { - xydirection = line->angle; + xydirection = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); } return xydirection; } -// When given a vector, rotates it and aligns it to either a slope, or a flat surface relative to the slope. -// If line is provided, this calculation is performed as if the slope were on the top or bottom of a solid midtexture. -// See also: P_QuantizeMomentumToSlope +angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo) +{ + return P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline); +} + +angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo) +{ + return P_GetStandingSlopeDirection(mo->standingslope, mo->standingline); +} + static void QuantizeMomentumToSlope(pslope_t *slope, line_t *line, vector3_t *momentum, boolean reverse) { if (!slope || slope->flags & SL_NOPHYSICS) @@ -959,18 +963,6 @@ void P_ReverseQuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum) QuantizeMomentumToSlope(mo->standingslope, mo->standingline, momentum, true); } -// Wrapper for P_GetStandingSlopeZAngle. -angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo) -{ - return P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline); -} - -// Wrapper for P_GetObjectStandingSlopeDirection. -angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo) -{ - return P_GetStandingSlopeDirection(mo->standingslope, mo->standingline); -} - // // P_SlopeLaunch // @@ -1050,6 +1042,7 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line) // Function to help handle landing on slopes void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line) { + vector3_t mom; // Ditto. if (slope->flags & SL_NOPHYSICS || (slope->normal.x == 0 && slope->normal.y == 0)) { // No physics, no need to make anything complicated. if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope { @@ -1062,7 +1055,6 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line) return; } - vector3_t mom; mom.x = thing->momx; mom.y = thing->momy; mom.z = thing->momz*2; From 3d4c9eedf841dda8ad50b0d8fc028b3db89fdcc4 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 20 May 2024 20:10:34 -0300 Subject: [PATCH 49/74] Revert "Improve slope physics on solid middle textures" This reverts commit e67e225ff2f796ba8cb78c9bacc5c91f052d5271. --- src/p_local.h | 1 - src/p_map.c | 27 ++-------- src/p_maputl.c | 5 -- src/p_maputl.h | 1 - src/p_mobj.c | 31 ++++-------- src/p_mobj.h | 4 +- src/p_saveg.c | 9 +--- src/p_slopes.c | 130 ++++++------------------------------------------- src/p_slopes.h | 10 +--- src/p_user.c | 6 +-- 10 files changed, 35 insertions(+), 189 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 6a4aa241c..249c3cd4b 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -399,7 +399,6 @@ extern camera_t *mapcampointer; extern fixed_t tmx; extern fixed_t tmy; extern pslope_t *tmfloorslope, *tmceilingslope; -extern line_t *tmfloorline, *tmceilingline; /* cphipps 2004/08/30 */ extern void P_MapStart(void); diff --git a/src/p_map.c b/src/p_map.c index aeeeda056..f97ddfa3c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -55,7 +55,6 @@ mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) ffloor_t *tmfloorrover, *tmceilingrover; pslope_t *tmfloorslope, *tmceilingslope; -line_t *tmfloorline, *tmceilingline; // keep track of the line that lowers the ceiling, // so missiles don't explode against sky hack walls @@ -1761,7 +1760,6 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmfloorz = thing->z + thing->height; tmfloorrover = NULL; tmfloorslope = NULL; - tmfloorline = NULL; } return CHECKTHING_COLLIDE; } @@ -1781,7 +1779,6 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmfloorz = tmceilingz = topz; // block while in air tmceilingrover = NULL; tmceilingslope = NULL; - tmceilingline = NULL; tmfloorthing = thing; // needed for side collision collide = CHECKTHING_COLLIDE; @@ -1791,7 +1788,6 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmceilingz = topz; tmceilingrover = NULL; tmceilingslope = NULL; - tmceilingline = NULL; tmfloorthing = thing; // thing we may stand on collide = CHECKTHING_COLLIDE; @@ -1809,7 +1805,6 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmceilingz = thing->z; tmceilingrover = NULL; tmceilingslope = NULL; - tmceilingline = NULL; } return CHECKTHING_COLLIDE; } @@ -1829,7 +1824,6 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmfloorz = tmceilingz = topz; // block while in air tmfloorrover = NULL; tmfloorslope = NULL; - tmfloorline = NULL; tmfloorthing = thing; // needed for side collision collide = CHECKTHING_COLLIDE; @@ -1839,7 +1833,6 @@ static unsigned PIT_DoCheckThing(mobj_t *thing) tmfloorz = topz; tmfloorrover = NULL; tmfloorslope = NULL; - tmfloorline = NULL; tmfloorthing = thing; // thing we may stand on collide = CHECKTHING_COLLIDE; @@ -2007,7 +2000,6 @@ static boolean PIT_CheckLine(line_t *ld) ceilingline = ld; tmceilingrover = openceilingrover; tmceilingslope = opentopslope; - tmceilingline = opentopline; } if (openbottom > tmfloorz) @@ -2015,7 +2007,6 @@ static boolean PIT_CheckLine(line_t *ld) tmfloorz = openbottom; tmfloorrover = openfloorrover; tmfloorslope = openbottomslope; - tmfloorline = openbottomline; } if (highceiling > tmdrpoffceilz) @@ -2066,8 +2057,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight; tmfloorrover = NULL; tmceilingrover = NULL; - tmfloorline = NULL; - tmceilingline = NULL; tmfloorslope = newsubsec->sector->f_slope; tmceilingslope = newsubsec->sector->c_slope; @@ -2653,8 +2642,6 @@ boolean PIT_PushableMoved(mobj_t *thing) ffloor_t *oldceilrover = tmceilingrover; pslope_t *oldfslope = tmfloorslope; pslope_t *oldcslope = tmceilingslope; - line_t *oldfline = tmfloorline; - line_t *oldcline = tmceilingline; // Move the player P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); @@ -2671,8 +2658,6 @@ boolean PIT_PushableMoved(mobj_t *thing) tmceilingrover = oldceilrover; tmfloorslope = oldfslope; tmceilingslope = oldcslope; - tmfloorline = oldfline; - tmceilingline = oldcline; thing->momz = stand->momz; } else @@ -2914,12 +2899,11 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) // Assign thing's standingslope if needed if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { if (!startingonground && tmfloorslope) - P_HandleSlopeLanding(thing, tmfloorslope, tmfloorline); + P_HandleSlopeLanding(thing, tmfloorslope); if (thing->momz <= 0) { thing->standingslope = tmfloorslope; - thing->standingline = tmfloorline; P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) @@ -2928,12 +2912,11 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) } else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { if (!startingonground && tmceilingslope) - P_HandleSlopeLanding(thing, tmceilingslope, tmceilingline); + P_HandleSlopeLanding(thing, tmceilingslope); if (thing->momz >= 0) { thing->standingslope = tmceilingslope; - thing->standingline = tmceilingline; P_SetPitchRollFromSlope(thing, thing->standingslope); if (thing->momz == 0 && thing->player && !startingonground) @@ -2941,12 +2924,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) } } } - else - { - // don't set standingslope or standingline if you're not going to clip against them + else // don't set standingslope if you're not going to clip against it thing->standingslope = NULL; - thing->standingline = NULL; - } thing->x = x; thing->y = y; diff --git a/src/p_maputl.c b/src/p_maputl.c index 7de5b5369..18a15a928 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -280,7 +280,6 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1) fixed_t opentop, openbottom, openrange, lowfloor, highceiling; pslope_t *opentopslope, *openbottomslope; ffloor_t *openfloorrover, *openceilingrover; -line_t *opentopline, *openbottomline; // P_CameraLineOpening // P_LineOpening, but for camera @@ -441,8 +440,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) I_Assert(back != NULL); openfloorrover = openceilingrover = NULL; - opentopline = openbottomline = NULL; - if (linedef->polyobj) { // set these defaults so that polyobjects don't interfere with collision above or below them @@ -547,7 +544,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if ((linedef->flags & ML_MIDPEG) != 0) { opentopslope = openbottomslope; } - opentopline = linedef; } } else { // Above if (openbottom < textop) { @@ -555,7 +551,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if ((linedef->flags & ML_MIDPEG) == 0) { openbottomslope = opentopslope; } - openbottomline = linedef; } } } diff --git a/src/p_maputl.h b/src/p_maputl.h index ca29fc203..e894c08a2 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -57,7 +57,6 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; extern pslope_t *opentopslope, *openbottomslope; extern ffloor_t *openfloorrover, *openceilingrover; -extern line_t *opentopline, *openbottomline; void P_LineOpening(line_t *plinedef, mobj_t *mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index 221149f70..9cdd2628d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1672,7 +1672,6 @@ void P_XYMovement(mobj_t *mo) fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls boolean moved; pslope_t *oldslope = NULL; - line_t *oldstandingline = NULL; vector3_t slopemom = {0,0,0}; fixed_t predictedz = 0; @@ -1705,10 +1704,7 @@ void P_XYMovement(mobj_t *mo) oldy = mo->y; if (mo->flags & MF_NOCLIPHEIGHT) - { mo->standingslope = NULL; - mo->standingline = NULL; - } // adjust various things based on slope if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { @@ -1720,7 +1716,7 @@ void P_XYMovement(mobj_t *mo) slopemom.x = xmove; slopemom.y = ymove; slopemom.z = 0; - P_QuantizeObjectMomentumToSlope(mo, &slopemom); + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); xmove = slopemom.x; ymove = slopemom.y; @@ -1728,7 +1724,6 @@ void P_XYMovement(mobj_t *mo) predictedz = mo->z + slopemom.z; // We'll use this later... oldslope = mo->standingslope; - oldstandingline = mo->standingline; } } else if (P_IsObjectOnGround(mo) && !mo->momz) predictedz = mo->z; @@ -1804,16 +1799,12 @@ void P_XYMovement(mobj_t *mo) { // try to slide along it // Wall transfer part 1. pslope_t *transferslope = NULL; - line_t *transferline = NULL; fixed_t transfermomz = 0; if (oldslope && (P_MobjFlip(mo)*(predictedz - mo->z) > 0)) // Only for moving up (relative to gravity), otherwise there's a failed launch when going down slopes and hitting walls { - angle_t zangle; transferslope = ((mo->standingslope) ? mo->standingslope : oldslope); - transferline = ((mo->standingline) ? mo->standingline : oldstandingline); - zangle = P_GetStandingSlopeZAngle(transferslope, transferline); - if (((zangle < ANGLE_180) ? zangle : InvAngle(zangle)) >= ANGLE_45) // Prevent some weird stuff going on on shallow slopes. - transfermomz = P_GetWallTransferMomZ(mo, transferslope, transferline); + if (((transferslope->zangle < ANGLE_180) ? transferslope->zangle : InvAngle(transferslope->zangle)) >= ANGLE_45) // Prevent some weird stuff going on on shallow slopes. + transfermomz = P_GetWallTransferMomZ(mo, transferslope); } P_SlideMove(mo); @@ -1826,7 +1817,7 @@ void P_XYMovement(mobj_t *mo) { angle_t relation; // Scale transfer momentum based on how head-on it is to the slope. if (mo->momx || mo->momy) // "Guess" the angle of the wall you hit using new momentum - relation = P_GetStandingSlopeDirection(transferslope, transferline) - R_PointToAngle2(0, 0, mo->momx, mo->momy); + relation = transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy); else // Give it for free, I guess. relation = ANGLE_90; transfermomz = FixedMul(transfermomz, @@ -1835,7 +1826,6 @@ void P_XYMovement(mobj_t *mo) { mo->momz = transfermomz; mo->standingslope = NULL; - mo->standingline = NULL; if (player) { player->powers[pw_justlaunched] = 2; @@ -1885,7 +1875,7 @@ void P_XYMovement(mobj_t *mo) oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT)); if (mo->standingslope) - newangle = FixedMul((signed)P_GetObjectStandingSlopeZAngle(mo), FINECOSINE((moveangle - P_GetObjectStandingSlopeDirection(mo)) >> ANGLETOFINESHIFT)); + newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); else newangle = 0; @@ -1909,7 +1899,7 @@ void P_XYMovement(mobj_t *mo) } } else if (moved && mo->standingslope && predictedz) { angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); - angle_t newangle = FixedMul((signed)P_GetObjectStandingSlopeZAngle(mo), FINECOSINE((moveangle - P_GetObjectStandingSlopeDirection(mo)) >> ANGLETOFINESHIFT)); + angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); /*CONS_Printf("flat to angle %f - predicted z of %f\n", FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)), @@ -2442,9 +2432,8 @@ boolean P_ZMovement(mobj_t *mo) if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; - mo->standingline = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingline : tmfloorline; P_SetPitchRollFromSlope(mo, mo->standingslope); - P_ReverseQuantizeObjectMomentumToSlope(mo, &mom); + P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); } // hit the floor @@ -2590,7 +2579,7 @@ boolean P_ZMovement(mobj_t *mo) mom.z = tmfloorthing->momz; if (mo->standingslope) { // MT_STEAM will never have a standingslope, see above. - P_QuantizeObjectMomentumToSlope(mo, &mom); + P_QuantizeMomentumToSlope(&mom, mo->standingslope); } mo->momx = mom.x; @@ -2836,9 +2825,7 @@ void P_PlayerZMovement(mobj_t *mo) if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { // Handle landing on slope during Z movement - P_HandleSlopeLanding(mo, - (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope), - (mo->eflags & MFE_VERTICALFLIP ? tmceilingline : tmfloorline)); + P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); } if (P_MobjFlip(mo)*mo->momz < 0) // falling diff --git a/src/p_mobj.h b/src/p_mobj.h index ae4c5a51d..2f013a2f3 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -412,9 +412,7 @@ typedef struct mobj_s INT32 cusval; INT32 cvmem; - struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) (it does) - - struct line_s *standingline; // The line that the object is standing on + struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) boolean resetinterp; // if true, some fields should not be interpolated (see R_InterpolateMobjState implementation) boolean colorized; // Whether the mobj uses the rainbow colormap diff --git a/src/p_saveg.c b/src/p_saveg.c index 675d68acd..5e4d6d076 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1746,8 +1746,7 @@ typedef enum MD2_DISPOFFSET = 1<<23, MD2_DRAWONLYFORPLAYER = 1<<24, MD2_DONTDRAWFORVIEWMOBJ = 1<<25, - MD2_TRANSLATION = 1<<26, - MD2_STANDINGLINE = 1<<27 + MD2_TRANSLATION = 1<<26 } mobj_diff2_t; typedef enum @@ -1954,8 +1953,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_CEILINGROVER; if (mobj->standingslope) diff2 |= MD2_SLOPE; - if (mobj->standingline) - diff2 |= MD2_STANDINGLINE; if (mobj->colorized) diff2 |= MD2_COLORIZED; if (mobj->mirrored) @@ -2128,8 +2125,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->hprev->mobjnum); if (diff2 & MD2_SLOPE) WRITEUINT16(save_p, mobj->standingslope->id); - if (diff2 & MD2_STANDINGLINE) - WRITEUINT32(save_p, SaveLine(mobj->standingline)); if (diff2 & MD2_COLORIZED) WRITEUINT8(save_p, mobj->colorized); if (diff2 & MD2_MIRRORED) @@ -3186,8 +3181,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_SLOPE) mobj->standingslope = P_SlopeById(READUINT16(save_p)); - if (diff2 & MD2_STANDINGLINE) - mobj->standingline = LoadLine(READUINT32(save_p)); if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); if (diff2 & MD2_MIRRORED) diff --git a/src/p_slopes.c b/src/p_slopes.c index 745be2eac..e75d36ede 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -859,10 +859,11 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y) // When given a vector, rotates it and aligns it to a slope void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) { + vector3_t axis; // Fuck you, C90. + if (slope->flags & SL_NOPHYSICS) return; // No physics, no quantizing. - vector3_t axis; axis.x = -slope->d.y; axis.y = slope->d.x; axis.z = 0; @@ -876,91 +877,9 @@ void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) // When given a vector, rotates and aligns it to a flat surface (from being relative to a given slope) void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) { - if (slope->flags & SL_NOPHYSICS) - return; // No physics, no quantizing. - - vector3_t axis; - axis.x = -slope->d.y; - axis.y = slope->d.x; - axis.z = 0; - - FV3_Rotate(momentum, &axis, InvAngle(slope->zangle) >> ANGLETOFINESHIFT); -} - -angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line) -{ - angle_t zangle = slope->zangle; - - if (line) - { - zangle = R_PointToAngle2(0, P_GetSlopeZAt(slope, line->v1->x, line->v1->y), - R_PointToDist2(line->v1->x, line->v1->y, line->v2->x, line->v2->y), P_GetSlopeZAt(slope, line->v2->x, line->v2->y)); - } - - return zangle; -} - -angle_t P_GetStandingSlopeDirection(pslope_t *slope, line_t *line) -{ - angle_t xydirection = slope->xydirection; - - if (line) - { - xydirection = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); - } - - return xydirection; -} - -angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo) -{ - return P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline); -} - -angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo) -{ - return P_GetStandingSlopeDirection(mo->standingslope, mo->standingline); -} - -static void QuantizeMomentumToSlope(pslope_t *slope, line_t *line, vector3_t *momentum, boolean reverse) -{ - if (!slope || slope->flags & SL_NOPHYSICS) - return; - - angle_t zangle = P_GetStandingSlopeZAngle(slope, line); - - if (reverse) - zangle = InvAngle(zangle); - - vector3_t axis; - axis.z = 0; - - if (line) - { - fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy); - axis.x = FixedDiv(line->dy, len); - axis.y = -FixedDiv(line->dx, len); - } - else - { - axis.x = -slope->d.y; - axis.y = slope->d.x; - } - - FV3_Rotate(momentum, &axis, zangle >> ANGLETOFINESHIFT); -} - -// Given a vector of the object's momentum, rotates it and aligns it to the slope the object is standing on -void P_QuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum) -{ - QuantizeMomentumToSlope(mo->standingslope, mo->standingline, momentum, false); -} - -// Given a vector of the object's momentum, rotates and aligns it to a flat surface -// (from being relative to the slope the object is standing on) -void P_ReverseQuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum) -{ - QuantizeMomentumToSlope(mo->standingslope, mo->standingline, momentum, true); + slope->zangle = InvAngle(slope->zangle); + P_QuantizeMomentumToSlope(momentum, slope); + slope->zangle = InvAngle(slope->zangle); } // @@ -980,7 +899,7 @@ void P_SlopeLaunch(mobj_t *mo) slopemom.x = mo->momx; slopemom.y = mo->momy; slopemom.z = mo->momz*2; - P_QuantizeObjectMomentumToSlope(mo, &slopemom); + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); mo->momx = slopemom.x; mo->momy = slopemom.y; @@ -1000,7 +919,7 @@ void P_SlopeLaunch(mobj_t *mo) // It would be nice to have a single function that does everything necessary for slope-to-wall transfer. // However, it needs to be seperated out in P_XYMovement to take into account momentum before and after hitting the wall. // This just performs the necessary calculations for getting the base vertical momentum; the horizontal is already reasonably calculated by P_SlideMove. -fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line) +fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope) { vector3_t slopemom, axis; angle_t ang; @@ -1008,30 +927,18 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line) if (slope->flags & SL_NOPHYSICS) return 0; - angle_t zangle = P_GetStandingSlopeZAngle(slope, line); - // If there's physics, time for launching. // Doesn't kill the vertical momentum as much as P_SlopeLaunch does. - ang = zangle + ANG15*((zangle > 0) ? 1 : -1); + ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1); if (ang > ANGLE_90 && ang < ANGLE_180) - ang = ((zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards + ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards slopemom.x = mo->momx; slopemom.y = mo->momy; slopemom.z = 3*(mo->momz/2); - if (line) - { - fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy); - axis.x = FixedDiv(line->dy, len); - axis.y = -FixedDiv(line->dx, len); - } - else - { - axis.x = -slope->d.y; - axis.y = slope->d.x; - } - + axis.x = -slope->d.y; + axis.y = slope->d.x; axis.z = 0; FV3_Rotate(&slopemom, &axis, ang >> ANGLETOFINESHIFT); @@ -1040,7 +947,7 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line) } // Function to help handle landing on slopes -void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line) +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) { vector3_t mom; // Ditto. if (slope->flags & SL_NOPHYSICS || (slope->normal.x == 0 && slope->normal.y == 0)) { // No physics, no need to make anything complicated. @@ -1059,13 +966,12 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line) mom.y = thing->momy; mom.z = thing->momz*2; - QuantizeMomentumToSlope(slope, line, &mom, true); + P_ReverseQuantizeMomentumToSlope(&mom, slope); if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope thing->momx = mom.x; thing->momy = mom.y; thing->standingslope = slope; - thing->standingline = line; P_SetPitchRollFromSlope(thing, slope); if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); @@ -1077,7 +983,6 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line) void P_ButteredSlope(mobj_t *mo) { fixed_t thrust; - angle_t zangle, xydirection; if (!mo->standingslope) return; @@ -1096,15 +1001,12 @@ void P_ButteredSlope(mobj_t *mo) return; // Allow the player to stand still on slopes below a certain steepness } - zangle = P_GetStandingSlopeZAngle(mo->standingslope, mo->standingline); - xydirection = P_GetStandingSlopeDirection(mo->standingslope, mo->standingline); - - thrust = FINESINE(zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); + thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); if (mo->player && (mo->player->pflags & PF_SPINNING)) { fixed_t mult = 0; if (mo->momx || mo->momy) { - angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - xydirection; + angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection; if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0) angle ^= ANGLE_180; @@ -1125,5 +1027,5 @@ void P_ButteredSlope(mobj_t *mo) // ... and its friction against the ground for good measure (divided by original friction to keep behaviour for normal slopes the same). thrust = FixedMul(thrust, FixedDiv(mo->friction, ORIG_FRICTION)); - P_Thrust(mo, xydirection, thrust); + P_Thrust(mo, mo->standingslope->xydirection, thrust); } diff --git a/src/p_slopes.h b/src/p_slopes.h index f33053ac1..fdc07f67e 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -84,15 +84,9 @@ fixed_t P_GetLightZAt(const lightlist_t *light, fixed_t x, fixed_t y); // Lots of physics-based bullshit void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); -void P_QuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum); -void P_ReverseQuantizeObjectMomentumToSlope(mobj_t *mo, vector3_t *momentum); -angle_t P_GetStandingSlopeZAngle(pslope_t *slope, line_t *line); -angle_t P_GetStandingSlopeDirection(pslope_t *slope, line_t *line); -angle_t P_GetObjectStandingSlopeZAngle(mobj_t *mo); -angle_t P_GetObjectStandingSlopeDirection(mobj_t *mo); void P_SlopeLaunch(mobj_t *mo); -fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope, line_t *line); -void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope, line_t *line); +fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope); +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_ButteredSlope(mobj_t *mo); pslope_t *P_MakeSlopeViaEquationConstants(const double a, const double b, const double c, const double d); diff --git a/src/p_user.c b/src/p_user.c index 1782c5386..7cd128cf0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6257,15 +6257,15 @@ static void P_3dMovement(player_t *player) && player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) { // Factor thrust to slope, but only for the part pushing up it! // The rest is unaffected. - angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-P_GetObjectStandingSlopeDirection(player->mo); + angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection; if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) { - P_QuantizeObjectMomentumToSlope(player->mo, &totalthrust); + P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); } } else { // Direction goes up, so thrustangle needs to face away if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) { - P_QuantizeObjectMomentumToSlope(player->mo, &totalthrust); + P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); } } } From 3fb5907effb3814c77f39dd9b2c6e1f9b2a1dd2b Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 20 May 2024 20:08:47 -0300 Subject: [PATCH 50/74] Add slope data to lines --- src/p_maputl.c | 14 +++--- src/p_setup.c | 2 + src/p_slopes.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++- src/r_defs.h | 2 + 4 files changed, 137 insertions(+), 8 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index 18a15a928..3373a40c4 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -541,16 +541,18 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (delta1 > delta2) { // Below if (opentop > texbottom) { opentop = texbottom; - if ((linedef->flags & ML_MIDPEG) != 0) { - opentopslope = openbottomslope; - } + if (linedef->flags & ML_NOSKEW) + opentopslope = NULL; + else + opentopslope = linedef->midtexslope; } } else { // Above if (openbottom < textop) { openbottom = textop; - if ((linedef->flags & ML_MIDPEG) == 0) { - openbottomslope = opentopslope; - } + if (linedef->flags & ML_NOSKEW) + openbottomslope = NULL; + else + openbottomslope = linedef->midtexslope; } } } diff --git a/src/p_setup.c b/src/p_setup.c index 41487d702..3dd3d942c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1113,6 +1113,8 @@ static void P_InitializeLinedef(line_t *ld) ld->callcount = 0; ld->secportal = UINT32_MAX; + ld->midtexslope = NULL; + // cph 2006/09/30 - fix sidedef errors right away. // cph 2002/07/20 - these errors are fatal if not fixed, so apply them for (j = 0; j < 2; j++) diff --git a/src/p_slopes.c b/src/p_slopes.c index e75d36ede..d941c71f9 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -28,6 +28,8 @@ pslope_t *slopelist = NULL; UINT16 slopecount = 0; +static void P_UpdateMidtextureSlopesForSector(sector_t *sector); + // Calculate line normal void P_CalculateSlopeNormal(pslope_t *slope) { @@ -212,6 +214,9 @@ void T_DynamicSlopeLine (dynlineplanethink_t* th) slope->zangle = R_PointToAngle2(0, 0, th->extent, -zdelta); slope->moved = true; P_CalculateSlopeNormal(slope); + P_UpdateMidtextureSlopesForSector(srcline->frontsector); + if (srcline->backsector) + P_UpdateMidtextureSlopesForSector(srcline->backsector); } } @@ -232,6 +237,12 @@ void T_DynamicSlopeVert (dynvertexplanethink_t* th) } ReconfigureViaVertexes(th->slope, th->vex[0], th->vex[1], th->vex[2]); + + for (i = 0; i < 3; i++) + { + if (th->secs[i]) + P_UpdateMidtextureSlopesForSector(th->secs[i]); + } } static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent) @@ -758,6 +769,111 @@ pslope_t *P_MakeSlopeViaEquationConstants(const double a, const double b, const return ret; } +static pslope_t *P_GetReferenceSlopeForMidtexture(line_t *line) +{ + if (line->flags & ML_MIDPEG) + { + // Line has ML_MIDPEG, so use the floor slope + fixed_t frontheight = P_GetSectorFloorZAt(line->frontsector, line->v1->x, line->v1->y); + fixed_t backheight = P_GetSectorFloorZAt(line->backsector, line->v1->x, line->v1->y); + + if (frontheight > backheight) + { + return line->frontsector->f_slope; + } + else + { + return line->backsector->f_slope; + } + } + else + { + // Line does not have ML_MIDPEG, so use the ceiling slope + fixed_t frontheight = P_GetSectorCeilingZAt(line->frontsector, line->v1->x, line->v1->y); + fixed_t backheight = P_GetSectorCeilingZAt(line->backsector, line->v1->x, line->v1->y); + + if (frontheight < backheight) + { + return line->frontsector->c_slope; + } + else + { + return line->backsector->c_slope; + } + } + + return NULL; +} + +// Updates a slope for a solid midtexture based on the slope of the sector it's in. +static void P_UpdateSolidMidtextureSlope(line_t *line, pslope_t *ref) +{ + pslope_t *slope = line->midtexslope; + + if (ref == NULL) + return; + + // Set origin + vector3_t origin; + origin.x = line->v1->x; + origin.y = line->v1->y; + origin.z = P_GetSlopeZAt(ref, origin.x, origin.y); + FV3_Copy(&slope->o, &origin); + + // Get where the line ends + vector3_t point; + point.x = line->v2->x; + point.y = line->v2->y; + point.z = P_GetSlopeZAt(ref, point.x, point.y); + + // Get length of the line + fixed_t extent = R_PointToDist2(0, 0, line->dx, line->dy); + + // Precalculate variables + slope->zdelta = FixedDiv(origin.z - point.z, extent); + slope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + slope->xydirection = line->angle; + + // Precalculate the direction + vector2_t dir; + dir.x = FixedMul(FINECOSINE(slope->zangle >> ANGLETOFINESHIFT), FINECOSINE((slope->xydirection+ANGLE_180) >> ANGLETOFINESHIFT)); + dir.y = FixedMul(FINECOSINE(slope->zangle >> ANGLETOFINESHIFT), FINESINE((slope->xydirection+ANGLE_180) >> ANGLETOFINESHIFT)); + FV2_Copy(&slope->d, &dir); + + P_CalculateSlopeNormal(slope); + + // Calling P_CalculateSlopeVectors is not necessary. + slope->moved = true; +} + +// Goes through every line in the sector and updates the midtexture slope if it is present +static void P_UpdateMidtextureSlopesForSector(sector_t *sector) +{ + for (size_t i = 0; i < sector->linecount; i++) + { + if (sector->lines[i]->midtexslope != NULL) + P_UpdateSolidMidtextureSlope(sector->lines[i], P_GetReferenceSlopeForMidtexture(sector->lines[i])); + } +} + +// Creates a solid midtexture slope for the line if possible +static void P_CreateSolidMidtextureSlope(line_t *line) +{ + if (line->backsector == NULL) // Ignore single-sided lines (of course) + return; + + if ((line->flags & ML_MIDSOLID) == 0) // Ignore if the midtexture is not solid + return; + + pslope_t *ref = P_GetReferenceSlopeForMidtexture(line); + if (ref) + { + line->midtexslope = Slope_Add(0); + + P_UpdateSolidMidtextureSlope(line, ref); + } +} + /// Initializes and reads the slopes from the map data. void P_SpawnSlopes(const boolean fromsave) { size_t i; @@ -785,14 +901,21 @@ void P_SpawnSlopes(const boolean fromsave) { /// Copies slopes from tagged sectors via line specials. /// \note Doesn't actually copy, but instead they share the same pointers. + // Also, creates midtexture slopes. for (i = 0; i < numlines; i++) - switch (lines[i].special) + { + line_t *line = &lines[i]; + + switch (line->special) { case 720: - P_CopySectorSlope(&lines[i]); + P_CopySectorSlope(line); default: break; } + + P_CreateSolidMidtextureSlope(line); + } } /// Initializes slopes. diff --git a/src/r_defs.h b/src/r_defs.h index da4dd2d70..7a6f518ee 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -612,6 +612,8 @@ typedef struct line_s INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 UINT32 secportal; // transferred sector portal + + struct pslope_s *midtexslope; } line_t; typedef struct From 36395bfaac4b247234aa85c1f85780547d649bf0 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 20 May 2024 20:25:42 -0300 Subject: [PATCH 51/74] Copy the flags of the reference slope --- src/p_slopes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index d941c71f9..11327506e 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -868,7 +868,7 @@ static void P_CreateSolidMidtextureSlope(line_t *line) pslope_t *ref = P_GetReferenceSlopeForMidtexture(line); if (ref) { - line->midtexslope = Slope_Add(0); + line->midtexslope = Slope_Add(ref->flags & SL_NOPHYSICS); P_UpdateSolidMidtextureSlope(line, ref); } From 341139ea73ea419d506d583daf63c8028a6830df Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Wed, 22 May 2024 23:37:09 -0300 Subject: [PATCH 52/74] Scale the vertical offsets --- src/p_maputl.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index f00534d63..0bc22390b 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -500,8 +500,11 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) INT32 texnum = R_GetTextureNum(side->midtexture); // make sure the texture is actually valid if (texnum) { + fixed_t scaley = abs(side->scaley_mid); + fixed_t offsetvalue = FixedDiv(side->rowoffset + side->offsety_mid, scaley); + // Get the midtexture's height - texheight = FixedDiv(textureheight[texnum], abs(side->scaley_mid)); + texheight = FixedDiv(textureheight[texnum], scaley); // Set texbottom and textop to the Z coordinates of the texture's boundaries #if 0 @@ -509,26 +512,26 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // on non-solid polyobjects should NEVER happen in the future if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { if (linedef->flags & ML_WRAPMIDTEX && !side->repeatcnt) { // "infinite" repeat - texbottom = back->floorheight + side->rowoffset + side->offsety_mid; - textop = back->ceilingheight + side->rowoffset + side->offsety_mid; + texbottom = back->floorheight + offsetvalue; + textop = back->ceilingheight + offsetvalue; } else if (linedef->flags & ML_MIDTEX) { - texbottom = back->floorheight + side->rowoffset + side->offsety_mid; + texbottom = back->floorheight + offsetvalue; textop = texbottom + texheight*(side->repeatcnt+1); } else { - textop = back->ceilingheight + side->rowoffset + side->offsety_mid; + textop = back->ceilingheight + offsetvalue; texbottom = textop - texheight*(side->repeatcnt+1); } } else #endif { if (linedef->flags & ML_WRAPMIDTEX && !side->repeatcnt) { // "infinite" repeat - texbottom = openbottom + side->rowoffset + side->offsety_mid; - textop = opentop + side->rowoffset + side->offsety_mid; + texbottom = openbottom + offsetvalue; + textop = opentop + offsetvalue; } else if (linedef->flags & ML_MIDPEG) { - texbottom = openbottom + side->rowoffset + side->offsety_mid; + texbottom = openbottom + offsetvalue; textop = texbottom + texheight*(side->repeatcnt+1); } else { - textop = opentop + side->rowoffset + side->offsety_mid; + textop = opentop + offsetvalue; texbottom = textop - texheight*(side->repeatcnt+1); } } From 813c609c5fd932f5b0adb195a7cbba424f2907b1 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 23 May 2024 01:32:13 -0300 Subject: [PATCH 53/74] Fix repeatcnt data type mistake in UDMF specification --- doc/specs/udmf_srb2.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/specs/udmf_srb2.txt b/doc/specs/udmf_srb2.txt index b25ed1af3..d6d71a0d5 100644 --- a/doc/specs/udmf_srb2.txt +++ b/doc/specs/udmf_srb2.txt @@ -126,7 +126,7 @@ Sonic Robo Blast 2 defines the following standardized fields: texturebottom = ; // Lower texture. Default = "-". texturemiddle = ; // Middle texture. Default = "-". - repeatcnt = ; // Number of middle texture repetitions. Default = 0 + repeatcnt = ; // Number of middle texture repetitions. Default = 0. sector = ; // Sector index. No valid default. From 72f294292981a02cf2b700c4a68fa0c45b20978b Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sat, 25 May 2024 18:04:49 +0200 Subject: [PATCH 54/74] Fix players not rendering on team scoreboards --- src/hu_stuff.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 16c59d9cf..1c951475b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2015,13 +2015,13 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) greycheck = greycheckdef; supercheck = supercheckdef; - if (tab[i].color == skincolor_redteam) //red + if (players[tab[i].num].ctfteam == 1) //red { redplayers++; x = 14 + (BASEVIDWIDTH/2); y = (redplayers * 9) + 20; } - else if (tab[i].color == skincolor_blueteam) //blue + else if (players[tab[i].num].ctfteam == 2) //blue { blueplayers++; x = 14; @@ -2103,7 +2103,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) if (players[tab[i].num].spectator) continue; //ignore them. - if (tab[i].color == skincolor_redteam) //red + if (players[tab[i].num].ctfteam == 1) //red { if (redplayers++ > 8) { @@ -2111,7 +2111,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) break; // don't make more loops than we need to. } } - else if (tab[i].color == skincolor_blueteam) //blue + else if (players[tab[i].num].ctfteam == 2) //blue { if (blueplayers++ > 8) { @@ -2142,14 +2142,14 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) if (players[tab[i].num].spectator) continue; //ignore them. - if (tab[i].color == skincolor_redteam) //red + if (players[tab[i].num].ctfteam == 1) //red { if (redplayers++ > 8) continue; x = 32 + (BASEVIDWIDTH/2); y = (redplayers * 16) + 16; } - else if (tab[i].color == skincolor_blueteam) //blue + else if (players[tab[i].num].ctfteam == 2) //blue { if (blueplayers++ > 8) continue; From 92fc592966cd544d9a2cf3a6dd8fe87604f67981 Mon Sep 17 00:00:00 2001 From: kaldrum1 <116390251+kaldrum1@users.noreply.github.com> Date: Sat, 25 May 2024 20:08:43 -0700 Subject: [PATCH 55/74] fix spr2defaults probably --- src/hardware/hw_md2.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 0bb8de851..97864bf7b 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1099,13 +1099,13 @@ static modelspr2frames_t *HWR_GetModelSprite2Frames(md2_t *md2, UINT16 spr2) return NULL; } -static modelspr2frames_t *HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT16 spr2, player_t *player) +static UINT16 *HWR_GetModelSprite2Num(md2_t *md2, skin_t *skin, UINT16 spr2, player_t *player) { UINT16 super = 0; UINT8 i = 0; if (!md2 || !md2->model || !skin) - return HWR_GetModelSprite2Frames(md2, 0); + return 0; while (!HWR_GetModelSprite2Frames(md2, spr2) && spr2 != SPR2_STND @@ -1145,7 +1145,7 @@ static modelspr2frames_t *HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT16 s if (i >= 32) // probably an infinite loop... spr2 = 0; - return HWR_GetModelSprite2Frames(md2, spr2); + return spr2; } // Adjust texture coords of model to fit into a patch's max_s and max_t @@ -1269,6 +1269,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj)); const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj)); spritedef_t *sprdef; + UINT16 spr2 = 0; spriteframe_t *sprframe; INT32 mod; interpmobjstate_t interp; @@ -1438,13 +1439,17 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) frame = (spr->mobj->frame & FF_FRAMEMASK); if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - spr2frames = HWR_GetModelSprite2(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); + { + spr2 = HWR_GetModelSprite2Num(md2, spr->mobj->skin, spr->mobj->sprite2, spr->mobj->player); + spr2frames = HWR_GetModelSprite2Frames(md2, spr2); + } if (spr2frames) { + spritedef_t *defaultdef = P_GetSkinSpritedef(spr->mobj->skin, spr2); mod = spr2frames->numframes; #ifndef DONTHIDEDIFFANIMLENGTH // by default, different anim length is masked by the mod - if (mod > (INT32)sprdef->numframes) - mod = sprdef->numframes; + if (mod > (INT32)defaultdef->numframes) + mod = defaultdef->numframes; #endif if (!mod) mod = 1; From b7fdcdf2b2ba68bea3b2899d8702a6674eb8187f Mon Sep 17 00:00:00 2001 From: kaldrum1 <116390251+kaldrum1@users.noreply.github.com> Date: Sat, 25 May 2024 20:49:29 -0700 Subject: [PATCH 56/74] fix spr2defaults pretty sure --- src/hardware/hw_md2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 97864bf7b..0f466f051 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1093,13 +1093,13 @@ static modelspr2frames_t *HWR_GetModelSprite2Frames(md2_t *md2, UINT16 spr2) return &md2->model->superspr2frames[spr2]; } - if (md2->model->spr2frames) + if (md2->model->spr2frames[spr2].numframes) return &md2->model->spr2frames[spr2]; return NULL; } -static UINT16 *HWR_GetModelSprite2Num(md2_t *md2, skin_t *skin, UINT16 spr2, player_t *player) +static UINT16 HWR_GetModelSprite2Num(md2_t *md2, skin_t *skin, UINT16 spr2, player_t *player) { UINT16 super = 0; UINT8 i = 0; From 19500742d2179417b4441a97ff5ea592f0e8c237 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sun, 26 May 2024 13:00:16 +0200 Subject: [PATCH 57/74] Avoid updating IPv4 MS entry if it failed to register --- src/netcode/http-mserv.c | 44 +++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index b8c662a51..4a0804984 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -486,20 +486,23 @@ int HMS_unlist (void) { struct HMS_buffer *hms; - int ok; + int ok = 0; - hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token); + if (hms_server_token) + { + hms = HMS_connect(PROTO_V4, "servers/%s/unlist", hms_server_token); - if (! hms) - return 0; + if (! hms) + return 0; - curl_easy_setopt(hms->curl, CURLOPT_POST, 1); - curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDSIZE, 0); + curl_easy_setopt(hms->curl, CURLOPT_POST, 1); + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDSIZE, 0); - ok = HMS_do(hms); - HMS_end(hms); + ok = HMS_do(hms); + HMS_end(hms); - free(hms_server_token); + free(hms_server_token); + } #ifndef NO_IPV6 if (hms_server_token_ipv6 && hms_allow_ipv6) @@ -526,18 +529,13 @@ int HMS_update (void) { struct HMS_buffer *hms; - int ok; + int ok = 0; char post[256]; char *title; - hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token); - - if (! hms) - return 0; - - title = curl_easy_escape(hms->curl, cv_servername.string, 0); + title = curl_easy_escape(NULL, cv_servername.string, 0); snprintf(post, sizeof post, "title=%s", @@ -546,10 +544,18 @@ HMS_update (void) curl_free(title); - curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + if (hms_server_token) + { + hms = HMS_connect(PROTO_V4, "servers/%s/update", hms_server_token); - ok = HMS_do(hms); - HMS_end(hms); + if (! hms) + return 0; + + curl_easy_setopt(hms->curl, CURLOPT_POSTFIELDS, post); + + ok = HMS_do(hms); + HMS_end(hms); + } #ifndef NO_IPV6 if (hms_server_token_ipv6 && hms_allow_ipv6) From 3b14531dc2d56b7a8d38ff3fccdada71f018b67d Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 26 May 2024 17:51:20 +0200 Subject: [PATCH 58/74] Fix spriteinfo indexing --- src/lua_infolib.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index eeb1067a3..67b9fb82d 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -242,17 +242,12 @@ static int lib_getSpriteInfo(lua_State *L) UINT32 i = NUMSPRITES; lua_remove(L, 1); - if (lua_isstring(L, 1)) + if (lua_type(L, 1) == LUA_TSTRING) { const char *name = lua_tostring(L, 1); INT32 spr = R_GetSpriteNumByName(name); if (spr == NUMSPRITES) - { - char *check; - i = strtol(name, &check, 10); - if (check == name || *check != '\0') - return luaL_error(L, "unknown sprite name %s", name); - } + return luaL_error(L, "unknown sprite name %s", name); i = spr; } else From 1ba9ecf02794e3acfd8def53ef5dd219b1e173eb Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 26 May 2024 17:51:48 +0200 Subject: [PATCH 59/74] Add missing newline in console warning --- src/lua_infolib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 67b9fb82d..511c20031 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -1735,7 +1735,7 @@ static int lib_setSkinColor(lua_State *L) else if (i == 6 || (str && fastcmp(str,"accessible"))) { boolean v = lua_toboolean(L, 3); if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible) - CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); + CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.\n", cnum); else info->accessible = v; } @@ -1830,7 +1830,7 @@ static int skincolor_set(lua_State *L) else if (fastcmp(field,"accessible")) { boolean v = lua_toboolean(L, 3); if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible) - CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); + CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.\n", cnum); else info->accessible = v; } else From 712414817b946a82b60e2a66ed00cb69bc4aaf36 Mon Sep 17 00:00:00 2001 From: pastel Date: Tue, 28 May 2024 13:51:29 -0500 Subject: [PATCH 60/74] also fix ticcmd intro crash --- src/g_game.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index ed9e88362..bf369d111 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1386,6 +1386,13 @@ 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 + { + cmd->angleturn = ticcmd_oldangleturn[forplayer]; + cmd->aiming = G_ClipAimingPitch(myaiming); + return; + } + // Centerview can be a toggle in simple mode! { static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior @@ -1717,7 +1724,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 && gamestate == GS_LEVEL) + if (addedtogame) { INT16 extra = ticcmd_oldangleturn[forplayer] - player->oldrelangleturn; INT16 origangle = cmd->angleturn; From a2bba687ba73f29487648c26716763e57e1f4d74 Mon Sep 17 00:00:00 2001 From: SSNTails Date: Wed, 29 May 2024 17:19:49 -0400 Subject: [PATCH 61/74] Don't break automatic mode. --- src/p_user.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 1964a6b3e..6d3bcb168 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12134,8 +12134,6 @@ void P_PlayerThink(player_t *player) case CR_DUSTDEVIL: player->drawangle += ANG20; break; - case CR_FAN: // Don't impact drawangle in any special way when on a fan - break; /* -- in case we wanted to have the camera freely movable during zoom tubes case CR_ZOOMTUBE:*/ case CR_ROPEHANG: @@ -12146,7 +12144,8 @@ void P_PlayerThink(player_t *player) } /* FALLTHRU */ default: - player->drawangle = player->mo->angle; + if (player->powers[pw_carry] == CR_FAN && !(player->pflags & PF_DIRECTIONCHAR)) // Don't impact drawangle in any special way when on a fan + player->drawangle = player->mo->angle; break; } } From 19736fa55e5d789effd8657d3707e0a3f7c6f0ad Mon Sep 17 00:00:00 2001 From: SSNTails Date: Wed, 29 May 2024 21:18:36 -0400 Subject: [PATCH 62/74] possibly more valid...? --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 6d3bcb168..6d83a18e6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12144,7 +12144,7 @@ void P_PlayerThink(player_t *player) } /* FALLTHRU */ default: - if (player->powers[pw_carry] == CR_FAN && !(player->pflags & PF_DIRECTIONCHAR)) // Don't impact drawangle in any special way when on a fan + if (!(player->powers[pw_carry] == CR_FAN && (player->pflags & PF_DIRECTIONCHAR))) // Don't impact drawangle in any special way when on a fan player->drawangle = player->mo->angle; break; } From bd8684e3e0ef18691945e032bf9073871fae79f1 Mon Sep 17 00:00:00 2001 From: SSNTails Date: Wed, 29 May 2024 21:42:05 -0400 Subject: [PATCH 63/74] pastel's ideas --- src/p_user.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index f789de0d9..44d31ab44 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12129,6 +12129,10 @@ void P_PlayerThink(player_t *player) case CR_DUSTDEVIL: player->drawangle += ANG20; break; + case CR_FAN: + if (player->pflags & PF_ANALOGMODE) // Don't impact drawangle in any special way when on a fan + player->drawangle = player->mo->angle; + break; /* -- in case we wanted to have the camera freely movable during zoom tubes case CR_ZOOMTUBE:*/ case CR_ROPEHANG: @@ -12139,8 +12143,6 @@ void P_PlayerThink(player_t *player) } /* FALLTHRU */ default: - if (!(player->powers[pw_carry] == CR_FAN && (player->pflags & PF_DIRECTIONCHAR))) // Don't impact drawangle in any special way when on a fan - player->drawangle = player->mo->angle; break; } } From b453e6732d50727b0423e6a32eea086e3fd2849d Mon Sep 17 00:00:00 2001 From: SSNTails Date: Wed, 29 May 2024 21:43:09 -0400 Subject: [PATCH 64/74] pastel's ideas #2 --- src/p_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_user.c b/src/p_user.c index 44d31ab44..a995e87f9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12143,6 +12143,7 @@ void P_PlayerThink(player_t *player) } /* FALLTHRU */ default: + player->drawangle = player->mo->angle; break; } } From dd1ac23bdb6550d9c0db9528b577451b3001aee5 Mon Sep 17 00:00:00 2001 From: pastel Date: Fri, 31 May 2024 15:52:24 -0500 Subject: [PATCH 65/74] Update skin cvar from character select and compare against cvar when warping to map without character select --- src/d_main.c | 2 +- src/m_menu.c | 12 +++++++----- src/netcode/d_netcmd.c | 12 +++++++----- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c139650d1..d96ad9813 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -983,7 +983,7 @@ void D_StartTitle(void) emeralds = 0; memset(&luabanks, 0, sizeof(luabanks)); lastmaploaded = 0; - pickedchar = R_SkinAvailable(cv_defaultskin.string); + pickedchar = R_SkinAvailable(cv_skin.string); // In case someone exits out at the same time they start a time attack run, // reset modeattacking diff --git a/src/m_menu.c b/src/m_menu.c index 4d8ee17e8..798ab43df 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3674,7 +3674,7 @@ void M_StartControlPanel(void) { // Devmode unlocks Pandora's Box in the pause menu boolean pandora = ((M_SecretUnlocked(SECRET_PANDORA, serverGamedata) || cv_debug || devparm) && !marathonmode); - + if (gamestate != GS_LEVEL || ultimatemode) // intermission, so gray out stuff. { SPauseMenu[spause_pandora].status = (pandora) ? (IT_GRAYEDOUT) : (IT_DISABLED); @@ -4156,7 +4156,7 @@ static void M_DrawStaticBox(fixed_t x, fixed_t y, INT32 flags, fixed_t w, fixed_ temp = (gametic % temp) * h*2*FRACUNIT; // Which frame to draw V_DrawCroppedPatch(x*FRACUNIT, y*FRACUNIT, (w*FRACUNIT) / 160, (h*FRACUNIT) / 100, flags, patch, NULL, 0, temp, w*2*FRACUNIT, h*2*FRACUNIT); - + W_UnlockCachedPatch(patch); return; } @@ -9510,6 +9510,8 @@ static void M_ChoosePlayer(INT32 choice) //lastmapsaved = 0; gamecomplete = 0; + CV_StealthSet(&cv_skin, skins[skinnum]->name); + G_DeferedInitNew(ultmode, G_BuildMapName(startmap), skinnum, false, fromlevelselect); COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this @@ -10186,7 +10188,7 @@ void M_DrawNightsAttackMenu(void) skinnumber = 0; //Default to Sonic else skinnumber = (cv_chooseskin.value-1); - + spritedef_t *sprdef = &skins[skinnumber]->sprites[SPR2_NFLY]; //Make our patch the selected character's NFLY sprite spritetimer = FixedInt(ntsatkdrawtimer/2) % skins[skinnumber]->sprites[SPR2_NFLY].numframes; //Make the sprite timer cycle though all the frames at 2 tics per frame spriteframe_t *sprframe = &sprdef->spriteframes[spritetimer]; //Our animation frame is equal to the number on the timer @@ -10199,11 +10201,11 @@ void M_DrawNightsAttackMenu(void) color = skins[skinnumber]->supercolor+4; else //If you don't go super in NiGHTS or at all, use prefcolor color = skins[skinnumber]->prefcolor; - + angle_t fa = (FixedAngle(((FixedInt(ntsatkdrawtimer * 4)) % 360)<>ANGLETOFINESHIFT) & FINEMASK; V_DrawFixedPatch(270<highresscale, skins[skinnumber]->shieldscale), + FixedDiv(skins[skinnumber]->highresscale, skins[skinnumber]->shieldscale), (sprframe->flip & 1<<6) ? V_FLIP : 0, natksprite, R_GetTranslationColormap(TC_BLINK, color, GTC_CACHE)); diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index e073a863c..cab1d6072 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -1308,7 +1308,7 @@ static void SendNameAndColor(void) SetColorLocal(consoleplayer, cv_playercolor.value); - if (splitscreen) + if (splitscreen || (!pickedchar && stricmp(cv_skin.string, skins[consoleplayer]->name) != 0)) SetSkinLocal(consoleplayer, R_SkinAvailable(cv_skin.string)); else SetSkinLocal(consoleplayer, pickedchar); @@ -4608,7 +4608,7 @@ static void Command_ExitLevel_f(void) SendNetXCmd(XD_EXITLEVEL, NULL, 0); return; } - + // Allow exiting without cheating if at least one player beat the level // Consistent with just setting playersforexit to one if (splitscreen || multiplayer) @@ -4622,7 +4622,7 @@ static void Command_ExitLevel_f(void) continue; if (players[i].lives <= 0) continue; - + if ((players[i].pflags & PF_FINISHED) || players[i].exiting) { SendNetXCmd(XD_EXITLEVEL, NULL, 0); @@ -4630,7 +4630,7 @@ static void Command_ExitLevel_f(void) } } } - + // Only consider it a cheat if we're not allowed to go to the next map if (M_CampaignWarpIsCheat(gametype, G_GetNextMap(true, true) + 1, serverGamedata)) CONS_Alert(CONS_NOTICE, M_GetText("Cheats must be enabled to force exit to a locked level!\n")); @@ -4769,7 +4769,7 @@ static void Command_Cheats_f(void) G_SetUsedCheats(false); return; } - + if (usedCheats) CONS_Printf(M_GetText("Cheats are enabled, the game cannot be saved.\n")); else @@ -4941,6 +4941,8 @@ static boolean Skin2_CanChange(const char *valstr) */ static void Skin_OnChange(void) { + pickedchar = R_SkinAvailable(cv_skin.string); + if (!Playing()) return; From e2e879a7048b6f95e4771309f644148f61ba39c3 Mon Sep 17 00:00:00 2001 From: pastel Date: Fri, 31 May 2024 21:10:25 -0500 Subject: [PATCH 66/74] handle file loading correctly --- src/g_game.c | 14 +++++++------- src/m_menu.c | 8 ++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 8d19c9e7c..de95e9be3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1363,11 +1363,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL); if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0)) cmd->buttons |= BT_FIRENORMAL; - + // Toss flag button if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG)) cmd->buttons |= BT_TOSSFLAG; - + // Shield button axis = PlayerJoyAxis(ssplayer, JA_SHIELD); if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD) || (usejoystick && axis > 0)) @@ -4018,7 +4018,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) INT32 i; INT16 newmapnum; boolean spec = G_IsSpecialStage(gamemap); - + // go to next level // newmapnum is 0-based, unlike gamemap if (nextmapoverride != 0) @@ -4122,7 +4122,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) if (spec && (!gottoken || ignoretokens) && !nextmapoverride) newmapnum = lastmap; // Exiting from a special stage? Go back to the game. Tails 08-11-2001 - + if (!(gametyperules & GTR_CAMPAIGN)) { if (cv_advancemap.value == 0) // Stay on same map. @@ -4130,7 +4130,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) else if (cv_advancemap.value == 2) // Go to random map. newmapnum = RandMap(G_TOLFlag(gametype_to_use), prevmap); } - + return newmapnum; } @@ -4140,7 +4140,7 @@ INT16 G_GetNextMap(boolean ignoretokens, boolean silent) static void G_DoCompleted(void) { INT32 i; - + tokenlist = 0; // Reset the list if (modeattacking && pausedelay) @@ -4168,7 +4168,7 @@ static void G_DoCompleted(void) //Get and set prevmap/nextmap prevmap = (INT16)(gamemap-1); nextmap = G_GetNextMap(false, false); - + automapactive = false; // We are committed to this map now. diff --git a/src/m_menu.c b/src/m_menu.c index 798ab43df..a6deaae2f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7000,7 +7000,10 @@ static void M_LevelSelectWarp(INT32 choice) if (currentMenu == &SP_LevelSelectDef || currentMenu == &SP_PauseLevelSelectDef) { if (cursaveslot > 0) // do we have a save slot to load? + { + CV_StealthSet(&cv_skin, DEFAULTSKIN); // already handled by loadgame so we don't want this G_LoadGame((UINT32)cursaveslot, startmap); // reload from SP save data: this is needed to keep score/lives/continues from reverting to defaults + } else // no save slot, start new game but keep the current skin { M_ClearMenus(true); @@ -8649,9 +8652,14 @@ static void M_LoadSelect(INT32 choice) M_NewGame(); } else if (savegameinfo[saveSlotSelected-1].gamemap & 8192) // Completed + { M_LoadGameLevelSelect(0); + } else + { + CV_StealthSet(&cv_skin, DEFAULTSKIN); // already handled by loadgame so we don't want this G_LoadGame((UINT32)saveSlotSelected, 0); + } cursaveslot = saveSlotSelected; } From f8a7ba4a75dc7860a4fef942c6b6bc702c8f767d Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 2 Jun 2024 16:54:11 -0300 Subject: [PATCH 67/74] Prevent infinite loop in R_RenderThickSideRange --- src/r_segs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index d68db60de..d7296583c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -469,7 +469,7 @@ static void R_DrawRepeatMaskedColumn(column_t *col, unsigned lengthcol) R_DrawMaskedColumn(col, lengthcol); - if ((INT64)topscreen + (INT64)texheight > (INT64)INT32_MAX) // prevent overflow + if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow break; topscreen += texheight; @@ -504,7 +504,7 @@ static void R_DrawRepeatFlippedMaskedColumn(column_t *col, unsigned lengthcol) R_DrawFlippedMaskedColumn(col, lengthcol); - if ((INT64)topscreen + (INT64)texheight > (INT64)INT32_MAX) // prevent overflow + if ((INT64)sprtopscreen + (INT64)dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow break; topscreen += texheight; From 1a02c7fd7381be22b5c862d916a3140029372074 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Mon, 3 Jun 2024 12:56:44 +0000 Subject: [PATCH 68/74] Expose BASEVIDWIDTH and BASEVIDHEIGHT to Lua and SOC --- src/deh_tables.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index c7c7c6040..f113f6b19 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5804,6 +5804,10 @@ struct int_const_s const INT_CONST[] = { {"MB_SCROLLUP",MB_SCROLLUP}, {"MB_SCROLLDOWN",MB_SCROLLDOWN}, + // screen.h constants + {"BASEVIDWIDTH",BASEVIDWIDTH}, + {"BASEVIDHEIGHT",BASEVIDHEIGHT}, + {NULL,0} }; From 1f71ecdc800e048c506a0b393795c6f6d016f6f0 Mon Sep 17 00:00:00 2001 From: pastel Date: Mon, 3 Jun 2024 12:59:52 +0000 Subject: [PATCH 69/74] Fix forcecharacter regressions & crash (resolves #1262) --- src/m_menu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 4d8ee17e8..fded90750 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -263,7 +263,7 @@ static void M_ConfirmTeamScramble(INT32 choice); static void M_ConfirmTeamChange(INT32 choice); static void M_SecretsMenu(INT32 choice); static void M_SetupChoosePlayer(INT32 choice); -static UINT16 M_SetupChoosePlayerDirect(INT32 choice); +static INT32 M_SetupChoosePlayerDirect(INT32 choice); static void M_QuitSRB2(INT32 choice); menu_t SP_MainDef, OP_MainDef; menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef; @@ -3674,7 +3674,7 @@ void M_StartControlPanel(void) { // Devmode unlocks Pandora's Box in the pause menu boolean pandora = ((M_SecretUnlocked(SECRET_PANDORA, serverGamedata) || cv_debug || devparm) && !marathonmode); - + if (gamestate != GS_LEVEL || ultimatemode) // intermission, so gray out stuff. { SPauseMenu[spause_pandora].status = (pandora) ? (IT_GRAYEDOUT) : (IT_DISABLED); @@ -4156,7 +4156,7 @@ static void M_DrawStaticBox(fixed_t x, fixed_t y, INT32 flags, fixed_t w, fixed_ temp = (gametic % temp) * h*2*FRACUNIT; // Which frame to draw V_DrawCroppedPatch(x*FRACUNIT, y*FRACUNIT, (w*FRACUNIT) / 160, (h*FRACUNIT) / 100, flags, patch, NULL, 0, temp, w*2*FRACUNIT, h*2*FRACUNIT); - + W_UnlockCachedPatch(patch); return; } @@ -9072,7 +9072,7 @@ static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum) description[i].namepic = W_CachePatchName(description[i].nametag, PU_PATCH); } -static UINT16 M_SetupChoosePlayerDirect(INT32 choice) +static INT32 M_SetupChoosePlayerDirect(INT32 choice) { INT32 skinnum, botskinnum; UINT16 i; @@ -9161,7 +9161,7 @@ static UINT16 M_SetupChoosePlayerDirect(INT32 choice) static void M_SetupChoosePlayer(INT32 choice) { - UINT16 skinset = M_SetupChoosePlayerDirect(choice); + INT32 skinset = M_SetupChoosePlayerDirect(choice); if (skinset != MAXCHARACTERSLOTS) { M_ChoosePlayer(skinset); @@ -10186,7 +10186,7 @@ void M_DrawNightsAttackMenu(void) skinnumber = 0; //Default to Sonic else skinnumber = (cv_chooseskin.value-1); - + spritedef_t *sprdef = &skins[skinnumber]->sprites[SPR2_NFLY]; //Make our patch the selected character's NFLY sprite spritetimer = FixedInt(ntsatkdrawtimer/2) % skins[skinnumber]->sprites[SPR2_NFLY].numframes; //Make the sprite timer cycle though all the frames at 2 tics per frame spriteframe_t *sprframe = &sprdef->spriteframes[spritetimer]; //Our animation frame is equal to the number on the timer @@ -10199,11 +10199,11 @@ void M_DrawNightsAttackMenu(void) color = skins[skinnumber]->supercolor+4; else //If you don't go super in NiGHTS or at all, use prefcolor color = skins[skinnumber]->prefcolor; - + angle_t fa = (FixedAngle(((FixedInt(ntsatkdrawtimer * 4)) % 360)<>ANGLETOFINESHIFT) & FINEMASK; V_DrawFixedPatch(270<highresscale, skins[skinnumber]->shieldscale), + FixedDiv(skins[skinnumber]->highresscale, skins[skinnumber]->shieldscale), (sprframe->flip & 1<<6) ? V_FLIP : 0, natksprite, R_GetTranslationColormap(TC_BLINK, color, GTC_CACHE)); From b0d5828e79b9f698ad60639d63a18b49a9ff6c29 Mon Sep 17 00:00:00 2001 From: pastel Date: Mon, 3 Jun 2024 14:36:20 +0000 Subject: [PATCH 70/74] Fix tiny spindash math moment --- src/p_user.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 7cd128cf0..f15e8e194 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -915,7 +915,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->textvar = NTV_BONUSTIMEEND; // Score and grades player->finishedspheres = (INT16)(player->spheres); player->finishedrings = (INT16)(player->rings); - + // Add score to temp leaderboards player->lastmaretime = leveltime - player->marebegunat; G_AddTempNightsRecords(player, player->marescore, player->lastmaretime, (UINT8)(oldmare + 1)); @@ -2372,7 +2372,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) if (dorollstuff) { if ((player->charability2 == CA2_SPINDASH) && !((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_THOKKED) && !(player->charability == CA_THOK && player->secondjump) - && (player->cmd.buttons & BT_SPIN) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale))) + && (player->cmd.buttons & BT_SPIN) && (FixedHypot(player->mo->momx, player->mo->momy) >= (5*player->mo->scale))) player->pflags = (player->pflags|PF_SPINNING) & ~PF_THOKKED; else if (!(player->pflags & PF_STARTDASH)) player->pflags &= ~PF_SPINNING; @@ -4721,7 +4721,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) // Revving else if ((cmd->buttons & BT_SPIN) && (player->pflags & PF_STARTDASH)) { - if (player->speed > 5*player->mo->scale) + if (player->speed >= 5*player->mo->scale) { player->pflags &= ~PF_STARTDASH; P_SetMobjState(player->mo, S_PLAY_ROLL); @@ -4761,9 +4761,8 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (!player->spectator) S_StartSound(player->mo, sfx_spin); } - else // Catapult the player from a spindash rev! - if (onground && !(player->pflags & PF_SPINDOWN) && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING)) + else if (onground && !(player->pflags & PF_SPINDOWN) && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING)) { player->pflags &= ~PF_STARTDASH; if (player->powers[pw_carry] == CR_BRAKGOOP) @@ -8766,7 +8765,7 @@ void P_MovePlayer(player_t *player) if (!(player->mo->momz || player->mo->momx || player->mo->momy) && !(player->mo->eflags & MFE_GOOWATER) && player->panim == PA_IDLE && !(player->powers[pw_carry])) P_DoTeeter(player); - + // Toss a flag if (G_GametypeHasTeams() && (cmd->buttons & BT_TOSSFLAG) && !(player->powers[pw_super]) && !(player->tossdelay)) { From 4840310f1a428fac46a04689269c1d8a5aeb1080 Mon Sep 17 00:00:00 2001 From: pastel Date: Mon, 3 Jun 2024 14:47:27 +0000 Subject: [PATCH 71/74] Fix exitgame-ing a demo crashing the game (resolves #1237) --- src/g_demo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/g_demo.c b/src/g_demo.c index 0efba5a59..54b12f797 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -549,6 +549,9 @@ void G_ConsGhostTic(void) testmo = players[0].mo; + if (P_MobjWasRemoved(testmo)) + return; // No valid mobj exists, probably because of unexpected quit + // Grab ghost data. ziptic = READUINT8(demo_p); if (ziptic & GZT_XYZ) From f19ec6f676da79722b4c44a3c8b048ff97e6ecb7 Mon Sep 17 00:00:00 2001 From: SMS Alfredo Date: Mon, 3 Jun 2024 23:25:02 +0000 Subject: [PATCH 72/74] Fix shieldscale 0 bugs --- src/m_menu.c | 11 ++++++++--- src/p_mobj.c | 17 +++++++++++++++-- src/r_things.c | 4 ++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index e0c240fec..38165472e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10211,9 +10211,12 @@ void M_DrawNightsAttackMenu(void) color = skins[skinnumber]->prefcolor; angle_t fa = (FixedAngle(((FixedInt(ntsatkdrawtimer * 4)) % 360)<>ANGLETOFINESHIFT) & FINEMASK; + fixed_t scale = skins[skinnumber]->highresscale; + if (skins[skinnumber]->shieldscale) + scale = FixedDiv(scale, skins[skinnumber]->shieldscale); V_DrawFixedPatch(270<highresscale, skins[skinnumber]->shieldscale), + scale, (sprframe->flip & 1<<6) ? V_FLIP : 0, natksprite, R_GetTranslationColormap(TC_BLINK, color, GTC_CACHE)); @@ -12300,7 +12303,9 @@ static void M_DrawSetupMultiPlayerMenu(void) if (multi_frame >= sprdef->numframes) multi_frame = 0; - scale = FixedDiv(skins[setupm_fakeskin]->highresscale, skins[setupm_fakeskin]->shieldscale); + scale = skins[setupm_fakeskin]->highresscale; + if (skins[setupm_fakeskin]->shieldscale) + scale = FixedDiv(scale, skins[setupm_fakeskin]->shieldscale); #define chary (y+64) @@ -12333,7 +12338,7 @@ static void M_DrawSetupMultiPlayerMenu(void) V_DrawFixedPatch( x<highresscale, skins[setupm_fakeskin]->shieldscale), + scale, flags, patch, colormap); goto colordraw; diff --git a/src/p_mobj.c b/src/p_mobj.c index fbbae5a1e..4716042e3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6662,8 +6662,21 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) thing->flags |= MF_NOCLIPHEIGHT; thing->eflags = (thing->eflags & ~MFE_VERTICALFLIP)|(thing->target->eflags & MFE_VERTICALFLIP); - P_SetScale(thing, FixedMul(thing->target->scale, thing->target->player->shieldscale), true); - thing->old_scale = FixedMul(thing->target->old_scale, thing->target->player->shieldscale); + //Set the shield's scale based on shieldscale, hide it if we're too small! + fixed_t scale = FixedMul(thing->target->scale, thing->target->player->shieldscale); + if (scale < 1) { + P_SetScale(thing, thing->target->scale, true); + thing->old_scale = thing->target->old_scale; + + thing->flags2 |= (MF2_DONTDRAW|MF2_JUSTATTACKED); //Hide and indicate we're hidden + } else { + P_SetScale(thing, scale, true); + thing->old_scale = FixedMul(thing->target->old_scale, thing->target->player->shieldscale); + + //Only unhide if we were hidden by the above code + if (thing->flags2 & MF2_JUSTATTACKED) + thing->flags2 &= ~(MF2_DONTDRAW|MF2_JUSTATTACKED); + } #define NewMH(mobj) mobj->height // Ugly mobj-height and player-height defines, for the sake of prettier code #define NewPH(player) P_GetPlayerHeight(player) diff --git a/src/r_things.c b/src/r_things.c index fb9757a9a..dc9cab997 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1774,6 +1774,10 @@ static void R_ProjectSprite(mobj_t *thing) } this_scale = interp.scale; + + if (this_scale < 1) + return; + radius = interp.radius; // For drop shadows height = interp.height; // Ditto From 37270c871e39cef5cb3ee022f270921cd365d21f Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Tue, 4 Jun 2024 02:08:25 -0300 Subject: [PATCH 73/74] Raise TEXTMAP parser limits --- src/p_setup.c | 60 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index c4b4a35b3..e888ec5a5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1554,11 +1554,41 @@ static void P_LoadThings(UINT8 *data) } // Stores positions for relevant map data spread through a TEXTMAP. -UINT32 mapthingsPos[UINT16_MAX]; -UINT32 linesPos[UINT16_MAX]; -UINT32 sidesPos[UINT16_MAX]; -UINT32 vertexesPos[UINT16_MAX]; -UINT32 sectorsPos[UINT16_MAX]; +typedef struct textmap_block_s +{ + UINT32 *pos; + size_t capacity; +} textmap_block_t; + +static textmap_block_t mapthingBlocks; +static textmap_block_t linedefBlocks; +static textmap_block_t sidedefBlocks; +static textmap_block_t vertexBlocks; +static textmap_block_t sectorBlocks; + +static void TextmapStorePos(textmap_block_t *blocks, size_t *count) +{ + size_t locCount = (*count) + 1; + + if (blocks->pos == NULL) + { + // Initial capacity (half of the former one.) + blocks->capacity = UINT16_MAX / 2; + + Z_Calloc(sizeof(blocks->pos) * blocks->capacity, PU_LEVEL, &blocks->pos); + } + else if (locCount >= blocks->capacity) + { + // If we hit the list's capacity, make space for 1024 more blocks + blocks->capacity += 1024; + + Z_Realloc(blocks->pos, sizeof(blocks->pos) * blocks->capacity, PU_LEVEL, &blocks->pos); + } + + blocks->pos[locCount - 1] = M_TokenizerGetEndPos(); + + (*count) = locCount; +} // Determine total amount of map data in TEXTMAP. static boolean TextmapCount(size_t size) @@ -1602,15 +1632,15 @@ static boolean TextmapCount(size_t size) brackets++; // Check for valid fields. else if (fastcmp(tkn, "thing")) - mapthingsPos[nummapthings++] = M_TokenizerGetEndPos(); + TextmapStorePos(&mapthingBlocks, &nummapthings); else if (fastcmp(tkn, "linedef")) - linesPos[numlines++] = M_TokenizerGetEndPos(); + TextmapStorePos(&linedefBlocks, &numlines); else if (fastcmp(tkn, "sidedef")) - sidesPos[numsides++] = M_TokenizerGetEndPos(); + TextmapStorePos(&sidedefBlocks, &numsides); else if (fastcmp(tkn, "vertex")) - vertexesPos[numvertexes++] = M_TokenizerGetEndPos(); + TextmapStorePos(&vertexBlocks, &numvertexes); else if (fastcmp(tkn, "sector")) - sectorsPos[numsectors++] = M_TokenizerGetEndPos(); + TextmapStorePos(§orBlocks, &numsectors); else CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn); } @@ -2944,7 +2974,7 @@ static void P_LoadTextmap(void) vt->floorzset = vt->ceilingzset = false; vt->floorz = vt->ceilingz = 0; - TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); + TextmapParse(vertexBlocks.pos[i], i, ParseTextmapVertexParameter); if (vt->x == INT32_MAX) I_Error("P_LoadTextmap: vertex %s has no x value set!\n", sizeu1(i)); @@ -3001,7 +3031,7 @@ static void P_LoadTextmap(void) textmap_planefloor.defined = 0; textmap_planeceiling.defined = 0; - TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); + TextmapParse(sectorBlocks.pos[i], i, ParseTextmapSectorParameter); P_InitializeSector(sc); if (textmap_colormap.used) @@ -3050,7 +3080,7 @@ static void P_LoadTextmap(void) ld->sidenum[0] = NO_SIDEDEF; ld->sidenum[1] = NO_SIDEDEF; - TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); + TextmapParse(linedefBlocks.pos[i], i, ParseTextmapLinedefParameter); if (!ld->v1) I_Error("P_LoadTextmap: linedef %s has no v1 value set!\n", sizeu1(i)); @@ -3077,7 +3107,7 @@ static void P_LoadTextmap(void) sd->sector = NULL; sd->repeatcnt = 0; - TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); + TextmapParse(sidedefBlocks.pos[i], i, ParseTextmapSidedefParameter); if (!sd->sector) I_Error("P_LoadTextmap: sidedef %s has no sector value set!\n", sizeu1(i)); @@ -3101,7 +3131,7 @@ static void P_LoadTextmap(void) memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs)); mt->mobj = NULL; - TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter); + TextmapParse(mapthingBlocks.pos[i], i, ParseTextmapThingParameter); } } From b16c4df31c779bccd518fa5103b73b1b6f778165 Mon Sep 17 00:00:00 2001 From: Refrag Date: Mon, 20 May 2024 10:40:55 +0200 Subject: [PATCH 74/74] Ensure the servername fits into MAXSERVERNAME before setting it This commit adds a verification before setting the servername console variable. We now check that it fits within the MAXSERVERNAME length and we cancel setting it if it doesn't. Letting the servername be more than MAXSERVERNAME could lead to crashes when trying to edit the server name from the menu so, we now avoid those. --- src/netcode/mserv.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/netcode/mserv.c b/src/netcode/mserv.c index 3acacd24c..74ee120f9 100644 --- a/src/netcode/mserv.c +++ b/src/netcode/mserv.c @@ -50,6 +50,8 @@ static void Command_Listserv_f(void); #endif/*MASTERSERVER*/ +static boolean ServerName_CanChange (const char*); + static void Update_parameters (void); static void MasterServer_OnChange(void); @@ -61,7 +63,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = { }; consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ds.ms.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange); -consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters); +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); @@ -497,6 +499,15 @@ Set_api (const char *api) #endif/*MASTERSERVER*/ +static boolean ServerName_CanChange(const char* newvalue) +{ + if (strlen(newvalue) < MAXSERVERNAME) + return true; + + CONS_Alert(CONS_NOTICE, "The server name must be shorter than %d characters\n", MAXSERVERNAME); + return false; +} + static void Update_parameters (void) {