From 50a34d85ddfe5769c8495bd7b37554c24630ef28 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 26 Dec 2022 21:06:46 -0600 Subject: [PATCH 01/50] 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/50] 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/50] 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/50] 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/50] 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 34817d9776b13879cd4201f36d06e6b45e012c36 Mon Sep 17 00:00:00 2001 From: SSNTails Date: Sun, 18 Feb 2024 22:38:34 -0500 Subject: [PATCH 06/50] 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 07/50] 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 08/50] 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 09/50] 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 10/50] 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 34cf7c1a018cd8fbf73c0686513c9f3a89c41b8c Mon Sep 17 00:00:00 2001 From: SSNTails Date: Wed, 13 Mar 2024 18:08:07 -0400 Subject: [PATCH 11/50] 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 12/50] 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 a58d9036bc48736d40c69fe9401747dbf083c90d Mon Sep 17 00:00:00 2001 From: SSNTails Date: Fri, 15 Mar 2024 14:28:44 -0400 Subject: [PATCH 13/50] 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 14/50] 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 15/50] 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 c3a8f452e2607ac502edba59ef45e63f62c6e1c9 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 20 Mar 2024 20:30:06 +0100 Subject: [PATCH 16/50] 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 fece34cef60bb3dd326b9292a93f4ce450d0639f Mon Sep 17 00:00:00 2001 From: Hanicef Date: Sat, 23 Mar 2024 13:05:29 +0100 Subject: [PATCH 17/50] 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 18/50] 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 19/50] 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 20/50] 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 21/50] 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 22/50] 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 23/50] 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 24/50] 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 25/50] 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 26/50] 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 27/50] 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 ccadfd8157e2b408c277232bc7c88e54e9f9c47b Mon Sep 17 00:00:00 2001 From: Refrag Date: Sun, 19 May 2024 09:08:00 +0200 Subject: [PATCH 28/50] 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 3a62ebbe3edbae3eacdadb0392a62412e25f089d Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sun, 19 May 2024 18:56:14 -0300 Subject: [PATCH 29/50] 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 30/50] 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 31/50] 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 6bf58ce8705111b1c7456edcf269e22e8ed6f1ee Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Mon, 20 May 2024 20:10:25 -0300 Subject: [PATCH 32/50] 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 33/50] 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 34/50] 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 35/50] 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 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 36/50] 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 37/50] 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 3b14531dc2d56b7a8d38ff3fccdada71f018b67d Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 26 May 2024 17:51:20 +0200 Subject: [PATCH 38/50] 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 39/50] 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 40/50] 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 41/50] 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 42/50] 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 43/50] 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 44/50] 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 45/50] 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 46/50] 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 1a02c7fd7381be22b5c862d916a3140029372074 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Mon, 3 Jun 2024 12:56:44 +0000 Subject: [PATCH 47/50] 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 48/50] 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 49/50] 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 50/50] 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)