From 5568e445ed2211ea5cd931180661ee36c641aa3c Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Fri, 3 Jan 2020 16:21:08 -0300 Subject: [PATCH 001/220] Colored title cards --- src/st_stuff.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 9c4f0abd5..659ed8c2f 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1301,6 +1301,16 @@ void ST_drawTitleCard(void) INT32 ttlscroll = FixedInt(lt_scroll); INT32 zzticker; patch_t *actpat, *zigzag, *zztext; + UINT8 colornum; + const UINT8 *colormap; + stplyr = &players[consoleplayer]; + + if (stplyr) + colornum = stplyr->skincolor; + else + colornum = cv_playercolor.value; + + colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE); if (!G_IsTitleCardAvailable()) return; @@ -1340,16 +1350,16 @@ void ST_drawTitleCard(void) if (!splitscreen || (splitscreen && stplyr == &players[displayplayer])) { zzticker = lt_ticker; - V_DrawScaledPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag); - V_DrawScaledPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag); - V_DrawScaledPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext); - V_DrawScaledPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext); + V_DrawMappedPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap); + V_DrawMappedPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap); + V_DrawMappedPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap); + V_DrawMappedPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap); } if (actnum) { if (!splitscreen) - V_DrawScaledPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat); + V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum); } From 423d1af48d41e2595bd30ae6e219ee3b5205dc56 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Fri, 3 Jan 2020 16:39:39 -0300 Subject: [PATCH 002/220] I see trees of green --- src/st_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 659ed8c2f..708034c03 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1305,7 +1305,7 @@ void ST_drawTitleCard(void) const UINT8 *colormap; stplyr = &players[consoleplayer]; - if (stplyr) + if (stplyr->skincolor) colornum = stplyr->skincolor; else colornum = cv_playercolor.value; From 5d33ca42cfef4e57e38013815d9ae2d390244b2a Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sat, 11 Jan 2020 20:40:57 -0300 Subject: [PATCH 003/220] Expose colorization to mappers and SOC --- src/d_netcmd.c | 7 ++++--- src/d_player.h | 2 ++ src/dehacked.c | 6 +++++- src/info.h | 1 + src/p_enemy.c | 34 ++++++++++++++++++++++++++++++++++ src/p_setup.c | 4 ++++ src/p_spec.c | 39 +++++++++++++++++++++++++++++++++++++-- src/p_user.c | 13 ++++++++++++- 8 files changed, 99 insertions(+), 7 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 29e68143c..4bf592810 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1251,7 +1251,7 @@ static void SendNameAndColor(void) players[consoleplayer].skincolor = cv_playercolor.value; - if (players[consoleplayer].mo) + if (players[consoleplayer].mo && !players[consoleplayer].powers[pw_dye]) players[consoleplayer].mo->color = players[consoleplayer].skincolor; if (metalrecording) @@ -1363,8 +1363,9 @@ static void SendNameAndColor2(void) if (botingame) { players[secondplaya].skincolor = botcolor; - if (players[secondplaya].mo) + if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye]) players[secondplaya].mo->color = players[secondplaya].skincolor; + SetPlayerSkinByNum(secondplaya, botskin-1); return; } @@ -1377,7 +1378,7 @@ static void SendNameAndColor2(void) // don't use secondarydisplayplayer: the second player must be 1 players[secondplaya].skincolor = cv_playercolor2.value; - if (players[secondplaya].mo) + if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye]) players[secondplaya].mo->color = players[secondplaya].skincolor; if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player diff --git a/src/d_player.h b/src/d_player.h index 62f38193f..2344c9c85 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -278,6 +278,8 @@ typedef enum pw_nights_linkfreeze, pw_nocontrol, //for linedef exec 427 + + pw_dye, // for dyes NUMPOWERS } powertype_t; diff --git a/src/dehacked.c b/src/dehacked.c index 091371122..85a020936 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2918,6 +2918,7 @@ static actionpointer_t actionpointers[] = {{A_SetRandomTics}, "A_SETRANDOMTICS"}, {{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"}, {{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"}, + {{A_Dye}, "A_DYE"}, {{A_MoveRelative}, "A_MOVERELATIVE"}, {{A_MoveAbsolute}, "A_MOVEABSOLUTE"}, {{A_Thrust}, "A_THRUST"}, @@ -9129,7 +9130,10 @@ static const char *const POWERS_LIST[] = { "NIGHTS_LINKFREEZE", //for linedef exec 427 - "NOCONTROL" + "NOCONTROL", + + //for dyes + "DYE" }; static const char *const HUDITEMS_LIST[] = { diff --git a/src/info.h b/src/info.h index 324795d45..33f597e61 100644 --- a/src/info.h +++ b/src/info.h @@ -165,6 +165,7 @@ void A_SetTics(); void A_SetRandomTics(); void A_ChangeColorRelative(); void A_ChangeColorAbsolute(); +void A_Dye(); void A_MoveRelative(); void A_MoveAbsolute(); void A_Thrust(); diff --git a/src/p_enemy.c b/src/p_enemy.c index bd7b81d40..d8e75f7f2 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -191,6 +191,7 @@ void A_SetTics(mobj_t *actor); void A_SetRandomTics(mobj_t *actor); void A_ChangeColorRelative(mobj_t *actor); void A_ChangeColorAbsolute(mobj_t *actor); +void A_Dye(mobj_t *actor); void A_MoveRelative(mobj_t *actor); void A_MoveAbsolute(mobj_t *actor); void A_Thrust(mobj_t *actor); @@ -8949,6 +8950,39 @@ void A_ChangeColorAbsolute(mobj_t *actor) actor->color = (UINT8)locvar2; } +// Function: A_Dye +// +// Description: Colorizes an object. +// +// var1 = if (var1 > 0), dye your target instead of yourself +// var2 = if (var1 = 0), color value to dye +// +void A_Dye(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; +#ifdef HAVE_BLUA + if (LUA_CallAction("A_Dye", actor)) + return; +#endif + mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor); + UINT8 color = (UINT8)locvar2; + + // What if it's a player? + if (target->player) + { + target->player->powers[pw_dye] = color; + return; + } + + target->color = color; + + if (!color) + target->colorized = false; + else + target->colorized = true; +} + // Function: A_MoveRelative // // Description: Moves an object (wrapper for P_Thrust) diff --git a/src/p_setup.c b/src/p_setup.c index cfe141381..20dfc633b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1185,10 +1185,14 @@ static void P_LoadSidedefs(UINT8 *data) case 9: // Mace parameters case 14: // Bustable block parameters case 15: // Fan particle spawner parameters + case 334: // Trigger linedef executor: Object dye - Continuous + case 335: // Trigger linedef executor: Object dye - Each time + case 336: // Trigger linedef executor: Object dye - Once case 425: // Calls P_SetMobjState on calling mobj case 434: // Custom Power case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors case 461: // Spawns an object on the map based on texture offsets + case 463: // Colorizes an object { char process[8*3+1]; memset(process,0,8*3+1); diff --git a/src/p_spec.c b/src/p_spec.c index f2cb17e0e..8089896a7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2034,6 +2034,17 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (!(actor && actor->player && ((stricmp(triggerline->text, skins[actor->player->skin].name) == 0) ^ ((triggerline->flags & ML_NOCLIMB) == ML_NOCLIMB)))) return false; break; + case 334: // object dye - continuous + case 335: // object dye - each time + case 336: // object dye - once + { + INT32 triggercolor = (INT32)sides[triggerline->sidenum[0]].toptexture; + UINT8 color = (actor->player ? actor->player->powers[pw_dye] : actor->color); + boolean invert = (triggerline->flags & ML_NOCLIMB ? true : false); + + if (invert ^ (triggercolor != color)) + return false; + } default: break; } @@ -2167,6 +2178,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller || specialtype == 328 // Nights lap - Once || specialtype == 330 // Nights Bonus Time - Once || specialtype == 333 // Skin - Once + || specialtype == 336 // Dye - Once || specialtype == 399) // Level Load triggerline->special = 0; // Clear it out @@ -2208,7 +2220,8 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller) || lines[masterline].special == 310 // CTF Red team - Each time || lines[masterline].special == 312 // CTF Blue team - Each time || lines[masterline].special == 322 // Trigger on X calls - Each Time - || lines[masterline].special == 332)// Skin - Each time + || lines[masterline].special == 332 // Skin - Each time + || lines[masterline].special == 335)// Dye - Each time continue; if (lines[masterline].special < 300 @@ -4041,7 +4054,23 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } } break; - + + case 463: // Dye object + { + INT32 color = sides[line->sidenum[0]].toptexture; + + if (mo) + { + if (color < 0 || color > MAXSKINCOLORS) + return; + + var1 = 0; + var2 = color; + A_Dye(mo); + } + } + break; + #ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing @@ -7208,6 +7237,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 310: case 312: case 332: + case 335: sec = sides[*lines[i].sidenum].sector - sectors; P_AddEachTimeThinker(§ors[sec], &lines[i]); break; @@ -7260,6 +7290,11 @@ void P_SpawnSpecials(boolean fromnetsave) case 331: case 333: break; + + // Object dye executors + case 334: + case 336: + break; case 399: // Linedef execute on map load // This is handled in P_RunLevelLoadExecutors. diff --git a/src/p_user.c b/src/p_user.c index 2bd856481..aa632d365 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12270,7 +12270,18 @@ void P_PlayerThink(player_t *player) player->powers[pw_nocontrol]--; else player->powers[pw_nocontrol] = 0; - + + if (player->powers[pw_dye]) + { + player->mo->colorized = true; + player->mo->color = player->powers[pw_dye]; + } + else + { + player->mo->colorized = false; + player->mo->color = player->skincolor; + } + //pw_super acts as a timer now if (player->powers[pw_super] && (player->mo->state < &states[S_PLAY_SUPER_TRANS1] From 4221f08a7c82e6650ab48b6adad41ce22b39d260 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sat, 11 Jan 2020 21:35:19 -0300 Subject: [PATCH 004/220] toaster guidance --- src/p_user.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index aa632d365..0d96ced30 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12271,17 +12271,6 @@ void P_PlayerThink(player_t *player) else player->powers[pw_nocontrol] = 0; - if (player->powers[pw_dye]) - { - player->mo->colorized = true; - player->mo->color = player->powers[pw_dye]; - } - else - { - player->mo->colorized = false; - player->mo->color = player->skincolor; - } - //pw_super acts as a timer now if (player->powers[pw_super] && (player->mo->state < &states[S_PLAY_SUPER_TRANS1] @@ -12927,6 +12916,17 @@ void P_PlayerAfterThink(player_t *player) player->mo->flags2 |= MF2_DONTDRAW; player->mo->flags |= MF_NOGRAVITY; } + + if (player->powers[pw_dye]) + { + player->mo->colorized = true; + player->mo->color = player->powers[pw_dye]; + } + else + { + player->mo->colorized = false; + player->mo->color = player->skincolor; + } if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem)) { From 7b3cc02ddc3d78a3337defaeb5df375c197a1b64 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sat, 11 Jan 2020 21:38:10 -0300 Subject: [PATCH 005/220] Range check --- src/p_enemy.c | 7 +++++-- src/p_spec.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index d8e75f7f2..bfdd1b8de 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8954,8 +8954,8 @@ void A_ChangeColorAbsolute(mobj_t *actor) // // Description: Colorizes an object. // -// var1 = if (var1 > 0), dye your target instead of yourself -// var2 = if (var1 = 0), color value to dye +// var1 = if (var1 != 0), dye your target instead of yourself +// var2 = color value to dye // void A_Dye(mobj_t *actor) { @@ -8968,6 +8968,9 @@ void A_Dye(mobj_t *actor) mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor); UINT8 color = (UINT8)locvar2; + if (color >= MAXTRANSLATIONS) + return; + // What if it's a player? if (target->player) { diff --git a/src/p_spec.c b/src/p_spec.c index 8089896a7..c7558582a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4061,7 +4061,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (mo) { - if (color < 0 || color > MAXSKINCOLORS) + if (color < 0 || color >= MAXTRANSLATIONS) return; var1 = 0; From 0fa638eaf51b9f8b50b757d182e1c27a04dbf328 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Mon, 13 Jan 2020 19:12:02 -0300 Subject: [PATCH 006/220] Logistical problems --- src/p_enemy.c | 9 ++++----- src/p_user.c | 5 ----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index bfdd1b8de..21cf672a4 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8971,6 +8971,9 @@ void A_Dye(mobj_t *actor) if (color >= MAXTRANSLATIONS) return; + if (!color) + target->colorized = false; + // What if it's a player? if (target->player) { @@ -8979,11 +8982,7 @@ void A_Dye(mobj_t *actor) } target->color = color; - - if (!color) - target->colorized = false; - else - target->colorized = true; + target->colorized = true; } // Function: A_MoveRelative diff --git a/src/p_user.c b/src/p_user.c index 0d96ced30..45f4a4562 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12922,11 +12922,6 @@ void P_PlayerAfterThink(player_t *player) player->mo->colorized = true; player->mo->color = player->powers[pw_dye]; } - else - { - player->mo->colorized = false; - player->mo->color = player->skincolor; - } if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem)) { From fb19d25de175264742c7561d3098823c0d763341 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 14 Jan 2020 00:52:54 -0300 Subject: [PATCH 007/220] What --- src/p_enemy.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 21cf672a4..6b20862ed 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8973,7 +8973,9 @@ void A_Dye(mobj_t *actor) if (!color) target->colorized = false; - + else + target->colorized = true; + // What if it's a player? if (target->player) { @@ -8982,7 +8984,6 @@ void A_Dye(mobj_t *actor) } target->color = color; - target->colorized = true; } // Function: A_MoveRelative From 295f052f2decc703acd60d2b6f4c648bc0e40579 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Fri, 24 Jan 2020 01:03:38 -0300 Subject: [PATCH 008/220] I don't know how these even come up --- 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 45f4a4562..288f0dbb5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12916,7 +12916,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->flags2 |= MF2_DONTDRAW; player->mo->flags |= MF_NOGRAVITY; } - + if (player->powers[pw_dye]) { player->mo->colorized = true; From 0218f58f489e7ca00f1c8a6747f3837a1df95171 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 2 Feb 2020 15:08:22 -0800 Subject: [PATCH 009/220] userdataType can check light userdata too! --- src/lua_baselib.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 66bd30e32..7c53fa99a 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -220,10 +220,16 @@ static const char *GetUserdataUType(lua_State *L) // or players[0].powers -> "player_t.powers" static int lib_userdataType(lua_State *L) { + int type; lua_settop(L, 1); // pop everything except arg 1 (in case somebody decided to add more) - luaL_checktype(L, 1, LUA_TUSERDATA); - lua_pushstring(L, GetUserdataUType(L)); - return 1; + type = lua_type(L, 1); + if (type == LUA_TLIGHTUSERDATA || type == LUA_TUSERDATA) + { + lua_pushstring(L, GetUserdataUType(L)); + return 1; + } + else + return luaL_typerror(L, 1, "userdata"); } static int lib_isPlayerAdmin(lua_State *L) From deaf5cfa2895c21e50b10f7b0b3e4831729c4759 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 2 Feb 2020 15:19:19 -0800 Subject: [PATCH 010/220] LUA_PushLightUserdata takes the fun out of lib_cvFindVar --- src/lua_consolelib.c | 18 ++---------------- src/lua_script.c | 22 ++++++++++++++++++++++ src/lua_script.h | 1 + 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 48f2e20a8..62d59e582 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -431,22 +431,8 @@ static int lib_cvRegisterVar(lua_State *L) static int lib_cvFindVar(lua_State *L) { - consvar_t *cv; - if (( cv = CV_FindVar(luaL_checkstring(L,1)) )) - { - lua_settop(L,1);/* We only want one argument in the stack. */ - lua_pushlightuserdata(L, cv);/* Now the second value on stack. */ - luaL_getmetatable(L, META_CVAR); - /* - The metatable is the last value on the stack, so this - applies it to the second value, which is the cvar. - */ - lua_setmetatable(L,2); - lua_pushvalue(L,2); - return 1; - } - else - return 0; + LUA_PushLightUserdata(L, CV_FindVar(luaL_checkstring(L,1)), META_CVAR); + return 1; } // CONS_Printf for a single player diff --git a/src/lua_script.c b/src/lua_script.c index 2538fb711..9d0a80f90 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -568,6 +568,28 @@ fixed_t LUA_EvalMath(const char *word) return res; } +/* +LUA_PushUserdata but no userdata is created. +You can't invalidate it therefore. +*/ + +void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta) +{ + if (data) + { + lua_pushlightuserdata(L, data); + luaL_getmetatable(L, meta); + /* + The metatable is the last value on the stack, so this + applies it to the second value, which is the userdata. + */ + lua_setmetatable(L, -2); + lua_pushvalue(L, -1); + } + else + lua_pushnil(L); +} + // Takes a pointer, any pointer, and a metatable name // Creates a userdata for that pointer with the given metatable // Pushes it to the stack and stores it in the registry. diff --git a/src/lua_script.h b/src/lua_script.h index 8f27dcb4c..d54387175 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -46,6 +46,7 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump); void LUA_DumpFile(const char *filename); #endif fixed_t LUA_EvalMath(const char *word); +void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta); void LUA_PushUserdata(lua_State *L, void *data, const char *meta); void LUA_InvalidateUserdata(void *data); void LUA_InvalidateLevel(void); From 35f1a4b76c600526a53f4a154bda6cfaca65340b Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 2 Feb 2020 17:22:28 -0800 Subject: [PATCH 011/220] lua_pushvalue is unneeded --- src/lua_script.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lua_script.c b/src/lua_script.c index 9d0a80f90..02f78cd35 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -584,7 +584,6 @@ void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta) applies it to the second value, which is the userdata. */ lua_setmetatable(L, -2); - lua_pushvalue(L, -1); } else lua_pushnil(L); From 57a4545fdff6710782497601cd2223b4d3026afc Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 7 Feb 2020 00:01:20 -0600 Subject: [PATCH 012/220] PK3: Proper ignorance for file comments/extra data --- src/w_wad.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/w_wad.c b/src/w_wad.c index 1df2eacc7..00bdb7183 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -580,7 +580,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) return NULL; } - lump_p->position = zentry->offset + zentry->namelen + zentry->xtralen + sizeof(zlentry_t); + lump_p->position = zentry->offset + zentry->namelen + sizeof(zlentry_t); lump_p->disksize = zentry->compsize; lump_p->size = zentry->size; @@ -629,6 +629,15 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) lump_p->compression = CM_UNSUPPORTED; break; } + + // skip and ignore comments/extra fields + if (fseek(handle, zentry->xtralen + zentry->commlen, SEEK_CUR) != 0) + { + CONS_Alert(CONS_ERROR, "Central directory %d is corrupt (%02x%02x%02x%02x)\n", i, zentry->signature[0], zentry->signature[1], zentry->signature[2], zentry->signature[3]); + Z_Free(lumpinfo); + free(zentries); + return NULL; + } } free(zentries); From 8cb9d6f670c1982171f41d0a4ec715a6cd918c0c Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 7 Feb 2020 00:04:02 -0600 Subject: [PATCH 013/220] Uhhh do VerifyPk3 too --- src/w_wad.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/w_wad.c b/src/w_wad.c index 00bdb7183..9f36e5d2a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1819,6 +1819,10 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) } free(fullname); + + // skip and ignore comments/extra fields + if (fseek(fp, zentry->xtralen + zentry->commlen, SEEK_CUR) != 0) + return true; } return true; From c4ee113c710b6859cf837e9c0e8f1d7d694ed746 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 7 Feb 2020 00:53:56 -0800 Subject: [PATCH 014/220] Let MUSICDEF set loop point --- src/s_sound.c | 15 +++++++++++++++ src/s_sound.h | 1 + 2 files changed, 16 insertions(+) diff --git a/src/s_sound.c b/src/s_sound.c index d84e20ab4..0854d9b67 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1456,6 +1456,7 @@ musicdef_t soundtestsfx = { 0, // with no conditions 0, 0, + 0, false, NULL }; @@ -1651,6 +1652,8 @@ ReadMusicDefFields (UINT16 wadnum, int line, boolean fields, char *stoken, fixed_t bpmf = FLOAT_TO_FIXED(bpm); if (bpmf > 0) def->bpm = FixedDiv((60*TICRATE)<loop_ms = atoi(textline); } else { CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", @@ -2262,6 +2265,8 @@ static void S_UnloadMusic(void) static boolean S_PlayMusic(boolean looping, UINT32 fadeinms) { + musicdef_t *def; + if (S_MusicDisabled()) return false; @@ -2273,6 +2278,16 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms) return false; } + /* set loop point from MUSICDEF */ + for (def = musicdefstart; def; def = def->next) + { + if (strcasecmp(def->name, music_name) == 0) + { + S_SetMusicLoopPoint(def->loop_ms); + break; + } + } + S_InitMusicVolume(); // switch between digi and sequence volume if (S_MusicNotInFocus()) diff --git a/src/s_sound.h b/src/s_sound.h index 9a4cbe48b..c7ec7e5d1 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -208,6 +208,7 @@ typedef struct musicdef_s INT16 soundtestcond; // +ve for map, -ve for conditionset, 0 for already here tic_t stoppingtics; fixed_t bpm; + UINT32 loop_ms;/* override LOOPPOINT/LOOPMS */ boolean allowed; // question marks or listenable on sound test? struct musicdef_s *next; } musicdef_t; From 3d00596c6a53c3e20cee7a8ebfd4a7057987003b Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 7 Feb 2020 12:51:21 -0800 Subject: [PATCH 015/220] Don't override loop point if unset in MUSICDEF --- src/s_sound.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/s_sound.c b/src/s_sound.c index 0854d9b67..4a335bbe6 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2283,7 +2283,8 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms) { if (strcasecmp(def->name, music_name) == 0) { - S_SetMusicLoopPoint(def->loop_ms); + if (def->loop_ms) + S_SetMusicLoopPoint(def->loop_ms); break; } } From f7cf8e50f86824084307a71a6d3f146707e921ae Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 7 Feb 2020 18:43:20 -0600 Subject: [PATCH 016/220] Oops --- src/w_wad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 9f36e5d2a..3e8502b5e 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -633,7 +633,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) // skip and ignore comments/extra fields if (fseek(handle, zentry->xtralen + zentry->commlen, SEEK_CUR) != 0) { - CONS_Alert(CONS_ERROR, "Central directory %d is corrupt (%02x%02x%02x%02x)\n", i, zentry->signature[0], zentry->signature[1], zentry->signature[2], zentry->signature[3]); + CONS_Alert(CONS_ERROR, "Central directory is corrupt\n"); Z_Free(lumpinfo); free(zentries); return NULL; @@ -1821,7 +1821,7 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) free(fullname); // skip and ignore comments/extra fields - if (fseek(fp, zentry->xtralen + zentry->commlen, SEEK_CUR) != 0) + if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0) return true; } From ee9aa86ecd8ffdbcd7913193a02365e5a536df84 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 7 Feb 2020 18:46:46 -0600 Subject: [PATCH 017/220] Use the proper numbers to adjust lump's offset position --- src/w_wad.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/w_wad.c b/src/w_wad.c index 3e8502b5e..874b99cc7 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -529,6 +529,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) zend_t zend; zentry_t* zentries; zentry_t* zentry; + zlentry_t zlentry; UINT16 numlumps = *nlmp; lumpinfo_t* lumpinfo; @@ -580,7 +581,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) return NULL; } - lump_p->position = zentry->offset + zentry->namelen + sizeof(zlentry_t); + lump_p->position = zentry->offset; // NOT ACCURATE YET: we still need to read the local entry to find our true position lump_p->disksize = zentry->compsize; lump_p->size = zentry->size; @@ -642,6 +643,20 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) free(zentries); + // Adjust lump position values properly + for (i = 0, lump_p = lumpinfo; i < numlumps; i++, lump_p++) + { + // skip and ignore comments/extra fields + if ((fseek(handle, lump_p->position, SEEK_SET) != 0) || (fread(&zlentry, 1, sizeof(zlentry_t), handle) < sizeof(zlentry_t))) + { + CONS_Alert(CONS_ERROR, "Local headers for lump %s are corrupt\n", lump_p->name2); + Z_Free(lumpinfo); + return NULL; + } + + lump_p->position += sizeof(zlentry_t) + zlentry.namelen + zlentry.xtralen; + } + *nlmp = numlumps; return lumpinfo; } From fb7c4ab812a26ec3b1007cd5adbd9c300061cf38 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 7 Feb 2020 18:47:56 -0600 Subject: [PATCH 018/220] zentries is unnecessary --- src/w_wad.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 874b99cc7..9137c477f 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -527,8 +527,7 @@ typedef struct zlentry_s static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) { zend_t zend; - zentry_t* zentries; - zentry_t* zentry; + zentry_t zentry; zlentry_t zlentry; UINT16 numlumps = *nlmp; @@ -557,40 +556,36 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) numlumps = zend.entries; lump_p = lumpinfo = Z_Malloc(numlumps * sizeof (*lumpinfo), PU_STATIC, NULL); - zentry = zentries = malloc(numlumps * sizeof (*zentries)); fseek(handle, zend.cdiroffset, SEEK_SET); - for (i = 0; i < numlumps; i++, zentry++, lump_p++) + for (i = 0; i < numlumps; i++, lump_p++) { char* fullname; char* trimname; char* dotpos; - if (fread(zentry, 1, sizeof(zentry_t), handle) < sizeof(zentry_t)) + if (fread(&zentry, 1, sizeof(zentry_t), handle) < sizeof(zentry_t)) { CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", M_FileError(handle)); Z_Free(lumpinfo); - free(zentries); return NULL; } - if (memcmp(zentry->signature, pat_central, 4)) + if (memcmp(zentry.signature, pat_central, 4)) { CONS_Alert(CONS_ERROR, "Central directory is corrupt\n"); Z_Free(lumpinfo); - free(zentries); return NULL; } - lump_p->position = zentry->offset; // NOT ACCURATE YET: we still need to read the local entry to find our true position - lump_p->disksize = zentry->compsize; - lump_p->size = zentry->size; + lump_p->position = zentry.offset; // NOT ACCURATE YET: we still need to read the local entry to find our true position + lump_p->disksize = zentry.compsize; + lump_p->size = zentry.size; - fullname = malloc(zentry->namelen + 1); - if (fgets(fullname, zentry->namelen + 1, handle) != fullname) + fullname = malloc(zentry.namelen + 1); + if (fgets(fullname, zentry.namelen + 1, handle) != fullname) { CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", M_FileError(handle)); Z_Free(lumpinfo); - free(zentries); free(fullname); return NULL; } @@ -607,12 +602,12 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary? strncpy(lump_p->name, trimname, min(8, dotpos - trimname)); - lump_p->name2 = Z_Calloc(zentry->namelen + 1, PU_STATIC, NULL); - strncpy(lump_p->name2, fullname, zentry->namelen); + lump_p->name2 = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL); + strncpy(lump_p->name2, fullname, zentry.namelen); free(fullname); - switch(zentry->compression) + switch(zentry.compression) { case 0: lump_p->compression = CM_NOCOMPRESSION; @@ -632,17 +627,14 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) } // skip and ignore comments/extra fields - if (fseek(handle, zentry->xtralen + zentry->commlen, SEEK_CUR) != 0) + if (fseek(handle, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0) { CONS_Alert(CONS_ERROR, "Central directory is corrupt\n"); Z_Free(lumpinfo); - free(zentries); return NULL; } } - free(zentries); - // Adjust lump position values properly for (i = 0, lump_p = lumpinfo; i < numlumps; i++, lump_p++) { From 0a53f91820d116e23a2af9260074c5ab778308bc Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 7 Feb 2020 19:41:45 -0800 Subject: [PATCH 019/220] Don't skip the first directory entry of PK3 if it's a file Also puts the marker skipping in the WAD API. --- src/r_data.c | 20 ++++++-------------- src/r_things.c | 6 ++---- src/w_wad.c | 23 +++++++++++++++++++---- src/w_wad.h | 3 +++ 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index 5608fdbde..e94368288 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -716,14 +716,12 @@ Rloadflats (INT32 i, INT32 w) } else { - texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); + texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0); texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); } if (!( texstart == INT16_MAX || texend == INT16_MAX )) { - texstart++; // Do not count the first marker - // Work through each lump between the markers in the WAD. for (j = 0; j < (texend - texstart); j++) { @@ -836,7 +834,7 @@ Rloadtextures (INT32 i, INT32 w) } else { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); + texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0); texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); if (texturesLumpPos != INT16_MAX) @@ -845,8 +843,6 @@ Rloadtextures (INT32 i, INT32 w) if (!( texstart == INT16_MAX || texend == INT16_MAX )) { - texstart++; // Do not count the first marker - // Work through each lump between the markers in the WAD. for (j = 0; j < (texend - texstart); j++) { @@ -953,14 +949,12 @@ void R_LoadTextures(void) } else { - texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); + texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0); texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); } if (!( texstart == INT16_MAX || texend == INT16_MAX )) { - texstart++; // Do not count the first marker - // PK3s have subfolders, so we can't just make a simple sum if (wadfiles[w]->type == RET_PK3) { @@ -993,15 +987,13 @@ void R_LoadTextures(void) } else { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); + texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0); texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); } if (texstart == INT16_MAX || texend == INT16_MAX) continue; - texstart++; // Do not count the first marker - // PK3s have subfolders, so we can't just make a simple sum if (wadfiles[w]->type == RET_PK3) { @@ -1587,9 +1579,9 @@ lumpnum_t R_GetFlatNumForName(const char *name) switch (wadfiles[i]->type) { case RET_WAD: - if ((start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0)) == INT16_MAX) + if ((start = W_CheckNumForMarkerStartPwad("F_START", (UINT16)i, 0)) == INT16_MAX) { - if ((start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0)) == INT16_MAX) + if ((start = W_CheckNumForMarkerStartPwad("FF_START", (UINT16)i, 0)) == INT16_MAX) continue; else if ((end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start)) == INT16_MAX) continue; diff --git a/src/r_things.c b/src/r_things.c index 7f0f43281..75210d4ab 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -437,9 +437,9 @@ void R_AddSpriteDefs(UINT16 wadnum) switch (wadfiles[wadnum]->type) { case RET_WAD: - start = W_CheckNumForNamePwad("S_START", wadnum, 0); + start = W_CheckNumForMarkerStartPwad("S_START", wadnum, 0); if (start == INT16_MAX) - start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib. + start = W_CheckNumForMarkerStartPwad("SS_START", wadnum, 0); //deutex compatib. end = W_CheckNumForNamePwad("S_END",wadnum,start); if (end == INT16_MAX) @@ -461,8 +461,6 @@ void R_AddSpriteDefs(UINT16 wadnum) start = 0; //let say S_START is lump 0 } - else - start++; // just after S_START if (end == INT16_MAX || start >= end) { diff --git a/src/w_wad.c b/src/w_wad.c index 1df2eacc7..ea8a444b0 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -194,7 +194,6 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) if (posStart != INT16_MAX) { posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); - posStart++; // first "lump" will be "Lua/" folder itself, so ignore it for (; posStart < posEnd; posStart++) LUA_LoadLump(wadnum, posStart); } @@ -204,7 +203,6 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) { posEnd = W_CheckNumForFolderEndPK3("SOC/", wadnum, posStart); - posStart++; // first "lump" will be "SOC/" folder itself, so ignore it for(; posStart < posEnd; posStart++) { lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart]; @@ -912,15 +910,32 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) return INT16_MAX; } +UINT16 +W_CheckNumForMarkerStartPwad (const char *name, UINT16 wad, UINT16 startlump) +{ + UINT16 marker; + marker = W_CheckNumForNamePwad(name, wad, startlump); + if (marker != INT16_MAX) + marker++; // Do not count the first marker + return marker; +} + // Look for the first lump from a folder. UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump) { + size_t name_length; INT32 i; lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; + name_length = strlen(name); for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) { - if (strnicmp(name, lump_p->name2, strlen(name)) == 0) + if (strnicmp(name, lump_p->name2, name_length) == 0) + { + /* SLADE is special and puts a single directory entry. Skip that. */ + if (strlen(lump_p->name2) == name_length) + i++; break; + } } return i; } @@ -1023,7 +1038,7 @@ lumpnum_t W_CheckNumForMap(const char *name) else continue; // Now look for the specified map. - for (++lumpNum; lumpNum < end; lumpNum++) + for (; lumpNum < end; lumpNum++) if (!strnicmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8)) return (i<<16) + lumpNum; } diff --git a/src/w_wad.h b/src/w_wad.h index aca67c00f..e07ceaf2e 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -157,6 +157,9 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum); UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad +/* Find the first lump after F_START for instance. */ +UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlump); + UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump); From 934808ef6202ffb4eec2f3753fc98cd22c630bec Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 12 Feb 2020 14:16:23 -0500 Subject: [PATCH 020/220] BotRespawn hook Lets you force when and when not to respawn the bot --- src/b_bot.c | 15 +++++++++++++++ src/lua_hook.h | 2 ++ src/lua_hooklib.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/src/b_bot.c b/src/b_bot.c index f83aaa34c..3e8275bdd 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -463,6 +463,21 @@ boolean B_CheckRespawn(player_t *player) if (!sonic || sonic->health <= 0) return false; +#ifdef HAVE_BLUA + // B_RespawnBot doesn't do anything if the condition above this isn't met + { + UINT8 shouldForce = LUAh_BotRespawn(sonic, tails); + + if (P_MobjWasRemoved(sonic) || P_MobjWasRemoved(tails)) + return (shouldForce == 1); // mobj was removed + + if (shouldForce == 1) + return true; + else if (shouldForce == 2) + return false; + } +#endif + // Check if Sonic is busy first. // If he's doing any of these things, he probably doesn't want to see us. if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING) diff --git a/src/lua_hook.h b/src/lua_hook.h index 94d2239f7..4bacf573a 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -42,6 +42,7 @@ enum hook { hook_JumpSpinSpecial, hook_BotTiccmd, hook_BotAI, + hook_BotRespawn, hook_LinedefExecute, hook_PlayerMsg, hook_HurtMsg, @@ -92,6 +93,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 #define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air)) boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name +boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails); // Hook for B_CheckRespawn boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 306bf6839..5c6b97ce0 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -53,6 +53,7 @@ const char *const hookNames[hook_MAX+1] = { "JumpSpinSpecial", "BotTiccmd", "BotAI", + "BotRespawn", "LinedefExecute", "PlayerMsg", "HurtMsg", @@ -1122,6 +1123,51 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) return hooked; } +// Hook for B_CheckRespawn +boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails) +{ + hook_p hookp; + UINT8 shouldRespawn = 0; // 0 = default, 1 = force yes, 2 = force no. + if (!gL || !(hooksAvailable[hook_BotRespawn/8] & (1<<(hook_BotRespawn%8)))) + return false; + + lua_settop(gL, 0); + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_BotRespawn) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, sonic, META_MOBJ); + LUA_PushUserdata(gL, tails, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { + if (lua_toboolean(gL, -1)) + shouldRespawn = 1; // Force yes + else + shouldRespawn = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return shouldRespawn; +} + // Hook for linedef executors boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) { From 64b7a5e4d6d71e53a10e6cefef4ce04993230882 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Feb 2020 18:03:39 -0800 Subject: [PATCH 021/220] SF_NONIGHTSSUPER for disabling super colors in NiGHTS --- src/d_player.h | 1 + src/dehacked.c | 1 + src/p_user.c | 2 +- src/r_things.c | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index db55a9913..250410c3b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -48,6 +48,7 @@ typedef enum SF_FASTEDGE = 1<<12, // Faster edge teeter? SF_MULTIABILITY = 1<<13, // Revenge of Final Demo. SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS + SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER) // free up to and including 1<<31 } skinflags_t; diff --git a/src/dehacked.c b/src/dehacked.c index e7ff6e400..e48b1cb90 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9477,6 +9477,7 @@ struct { {"SF_FASTEDGE",SF_FASTEDGE}, {"SF_MULTIABILITY",SF_MULTIABILITY}, {"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION}, + {"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER}, // Dashmode constants {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, diff --git a/src/p_user.c b/src/p_user.c index 176b07d0a..5b88148d5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8040,7 +8040,7 @@ static void P_MovePlayer(player_t *player) && player->mo->state < &states[S_PLAY_NIGHTS_TRANS6]))) // Note the < instead of <= { skin_t *skin = ((skin_t *)(player->mo->skin)); - if (skin->flags & SF_SUPER) + if (( skin->flags & (SF_SUPER|SF_NONIGHTSSUPER) ) == SF_SUPER) { player->mo->color = skin->supercolor + ((player->nightstime == player->startedtime) diff --git a/src/r_things.c b/src/r_things.c index 7f0f43281..ae4ccb5a8 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -3463,6 +3463,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(DASHMODE) GETFLAG(FASTEDGE) GETFLAG(MULTIABILITY) + GETFLAG(NONIGHTSSUPER) #undef GETFLAG else // let's check if it's a sound, otherwise error out From 71319dce6b5cd1706c693942877149249e75b494 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Feb 2020 18:15:15 -0800 Subject: [PATCH 022/220] Revert "Update file hashes" This reverts commit 4281de3b89e4ace77bff9dca003feb26d9e4dbc5. --- src/config.h.in | 8 ++++---- src/d_main.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/config.h.in b/src/config.h.in index d4a613fdc..233cbdc53 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -26,12 +26,12 @@ #else /* Manually defined asset hashes for non-CMake builds - * Last updated 2020 / 02 / 09 - v2.2.1 - main assets + * Last updated 2019 / 12 / 06 - v2.2.0 - main assets * Last updated 20?? / ?? / ?? - v2.2.? - patch.pk3 */ -#define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28" -#define ASSET_HASH_ZONES_PK3 "89627822f5a5c7fb022d836b138144b2" -#define ASSET_HASH_PLAYER_DTA "129fa7d4b273a4b3dcacaa44eccead4f" +#define ASSET_HASH_SRB2_PK3 "51419a33b4982d840c6772c159ba7c0a" +#define ASSET_HASH_ZONES_PK3 "df74843919fd51af26a0baa8e21e4c19" +#define ASSET_HASH_PLAYER_DTA "56a247e074dd0dc794b6617efef1e918" #ifdef USE_PATCH_DTA #define ASSET_HASH_PATCH_PK3 "there is no patch.pk3, only zuul" #endif diff --git a/src/d_main.c b/src/d_main.c index 27f250017..dc9bfbfea 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1213,7 +1213,7 @@ void D_SRB2Main(void) #endif D_CleanFile(); -#ifndef DEVELOP // md5s last updated 09/02/20 (ddmmyy) +#ifndef DEVELOP // md5s last updated 06/12/19 (ddmmyy) // Check MD5s of autoloaded files W_VerifyFileMD5(0, ASSET_HASH_SRB2_PK3); // srb2.pk3 From e53a17bb528800c6a3ec7ec2fcc36c5c6f96ba20 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 17 Feb 2020 21:11:56 -0300 Subject: [PATCH 023/220] Rename stuff around --- src/android/i_video.c | 10 ++++------ src/djgppdos/i_video.c | 5 +---- src/djgppdos/vid_vesa.c | 6 ++---- src/dummy/i_video.c | 10 ++++------ src/i_video.h | 18 +++++++++++------- src/m_menu.c | 2 +- src/screen.c | 4 ++-- src/sdl/i_video.c | 39 +++++++++++++++++---------------------- src/win32/win_vid.c | 11 +++-------- 9 files changed, 45 insertions(+), 60 deletions(-) diff --git a/src/android/i_video.c b/src/android/i_video.c index b8bb4fefb..1909cd71a 100644 --- a/src/android/i_video.c +++ b/src/android/i_video.c @@ -19,10 +19,10 @@ boolean allow_fullscreen = false; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void I_StartupGraphics(void){} -void I_StartupHardwareGraphics(void){} - void I_ShutdownGraphics(void){} +void VID_StartupOpenGL(void){} + void I_SetPalette(RGBA_t *palette) { (void)palette; @@ -52,10 +52,8 @@ INT32 VID_SetMode(INT32 modenum) return 0; } -void VID_CheckRenderer(void) -{ - // .............. -} +void VID_CheckRenderer(void) {} +void VID_CheckGLLoaded(rendermode_t oldrender) {} const char *VID_GetModeName(INT32 modenum) { diff --git a/src/djgppdos/i_video.c b/src/djgppdos/i_video.c index 02c7a842b..f525b96ca 100644 --- a/src/djgppdos/i_video.c +++ b/src/djgppdos/i_video.c @@ -339,7 +339,4 @@ void I_StartupGraphics(void) } -void I_StartupHardwareGraphics(void) -{ - // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y -} +void VID_StartupOpenGL(void) {} diff --git a/src/djgppdos/vid_vesa.c b/src/djgppdos/vid_vesa.c index c8ce7dae5..61ed18e4b 100644 --- a/src/djgppdos/vid_vesa.c +++ b/src/djgppdos/vid_vesa.c @@ -378,10 +378,8 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette) return 1; } -void VID_CheckRenderer(void) -{ - // .............. -} +void VID_CheckRenderer(void) {} +void VID_CheckGLLoaded(rendermode_t oldrender) {} diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index fafeee000..56ead3672 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -11,10 +11,10 @@ boolean allow_fullscreen = false; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void I_StartupGraphics(void){} -void I_StartupHardwareGraphics(void){} - void I_ShutdownGraphics(void){} +void VID_StartupOpenGL(void){} + void I_SetPalette(RGBA_t *palette) { (void)palette; @@ -40,10 +40,8 @@ INT32 VID_SetMode(INT32 modenum) return 0; } -void VID_CheckRenderer(void) -{ - // .............. -} +void VID_CheckRenderer(void) {} +void VID_CheckGLLoaded(rendermode_t oldrender) {} const char *VID_GetModeName(INT32 modenum) { diff --git a/src/i_video.h b/src/i_video.h index 294b7ef84..2b40356ea 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -36,10 +36,10 @@ typedef enum */ extern rendermode_t rendermode; -/** \brief hardware renderer loaded +/** \brief OpenGL state 0 = never loaded, 1 = loaded successfully, -1 = failed loading */ -extern INT32 hwrenderloaded; +extern INT32 vid_opengl_state; /** \brief use highcolor modes if true */ @@ -49,11 +49,7 @@ extern boolean highcolor; */ void I_StartupGraphics(void); -/** \brief setup hardware mode -*/ -void I_StartupHardwareGraphics(void); - -/** \brief restore old video mode +/** \brief shutdown video mode */ void I_ShutdownGraphics(void); @@ -97,6 +93,14 @@ INT32 VID_SetMode(INT32 modenum); */ void VID_CheckRenderer(void); +/** \brief Load OpenGL mode +*/ +void VID_StartupOpenGL(void); + +/** \brief Checks if OpenGL loaded +*/ +void VID_CheckGLLoaded(rendermode_t oldrender); + /** \brief The VID_GetModeName function \param modenum video mode number diff --git a/src/m_menu.c b/src/m_menu.c index 0349ed3bc..82793ab9a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2093,7 +2093,7 @@ static void M_VideoOptions(INT32 choice) { (void)choice; #ifdef HWRENDER - if (hwrenderloaded == -1) + if (vid_opengl_state == -1) { OP_VideoOptionsMenu[op_video_renderer].status = (IT_TRANSTEXT | IT_PAIR); OP_VideoOptionsMenu[op_video_renderer].patch = "Renderer"; diff --git a/src/screen.c b/src/screen.c index 9c61f5689..828454a9b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -453,7 +453,7 @@ void SCR_ActuallyChangeRenderer(void) #ifdef HWRENDER // Well, it didn't even load anyway. - if ((hwrenderloaded == -1) && (setrenderneeded == render_opengl)) + if ((vid_opengl_state == -1) && (setrenderneeded == render_opengl)) { if (M_CheckParm("-nogl")) CONS_Alert(CONS_ERROR, "OpenGL rendering was disabled!\n"); @@ -478,7 +478,7 @@ void SCR_ChangeRenderer(void) { target_renderer = cv_renderer.value; #ifdef HWRENDER - if (M_CheckParm("-opengl") && (hwrenderloaded == 1)) + if (M_CheckParm("-opengl") && (vid_opengl_state == 1)) target_renderer = rendermode = render_opengl; else #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 1dbaf06bd..5d1baee74 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -104,7 +104,7 @@ static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff static consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; UINT8 graphics_started = 0; // Is used in console.c and screen.c -INT32 hwrenderloaded = 0; +INT32 vid_opengl_state = 0; // To disable fullscreen at startup; is set in VID_PrepareModeList boolean allow_fullscreen = false; @@ -1440,7 +1440,7 @@ static SDL_bool Impl_CreateContext(void) { // Renderer-specific stuff #ifdef HWRENDER - if ((rendermode == render_opengl) && (hwrenderloaded != -1)) + if ((rendermode == render_opengl) && (vid_opengl_state != -1)) { if (!sdlglcontext) sdlglcontext = SDL_GL_CreateContext(window); @@ -1473,10 +1473,10 @@ static SDL_bool Impl_CreateContext(void) return SDL_TRUE; } -#ifdef HWRENDER -static void VID_CheckGLLoaded(rendermode_t oldrender) +void VID_CheckGLLoaded(rendermode_t oldrender) { - if (hwrenderloaded == -1) // Well, it didn't work the first time anyway. +#ifdef HWRENDER + if (vid_opengl_state == -1) // Well, it didn't work the first time anyway. { rendermode = oldrender; if (chosenrendermode == render_opengl) // fallback to software @@ -1488,8 +1488,8 @@ static void VID_CheckGLLoaded(rendermode_t oldrender) setrenderneeded = 0; } } -} #endif +} void VID_CheckRenderer(void) { @@ -1499,11 +1499,6 @@ void VID_CheckRenderer(void) if (dedicated) return; -#ifdef HWRENDER - if (!graphics_started) - VID_CheckGLLoaded(oldrenderer); -#endif - if (setrenderneeded) { rendermode = setrenderneeded; @@ -1514,9 +1509,9 @@ void VID_CheckRenderer(void) { VID_CheckGLLoaded(oldrenderer); // Initialise OpenGL before calling SDLSetMode!!! - if (hwrenderloaded != 1) - I_StartupHardwareGraphics(); - else if (hwrenderloaded == -1) + if (vid_opengl_state != 1) + VID_StartupOpenGL(); + else if (vid_opengl_state == -1) rendererchanged = SDL_FALSE; } #endif @@ -1535,7 +1530,7 @@ void VID_CheckRenderer(void) bufSurface = NULL; } #ifdef HWRENDER - if (hwrenderloaded == 1) // Only if OpenGL ever loaded! + if (vid_opengl_state == 1) // Only if OpenGL ever loaded! HWR_FreeTextureCache(); #endif SCR_SetDrawFuncs(); @@ -1586,7 +1581,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) flags |= SDL_WINDOW_BORDERLESS; #ifdef HWRENDER - if (hwrenderloaded != -1) + if (vid_opengl_state != -1) flags |= SDL_WINDOW_OPENGL; #endif @@ -1722,9 +1717,9 @@ void I_StartupGraphics(void) VID_Command_ModeList_f(); #ifdef HWRENDER if (M_CheckParm("-nogl")) - hwrenderloaded = -1; // Don't call SDL_GL_LoadLibrary + vid_opengl_state = -1; // Don't call SDL_GL_LoadLibrary else - I_StartupHardwareGraphics(); + VID_StartupOpenGL(); #endif // Fury: we do window initialization after GL setup to allow @@ -1779,7 +1774,7 @@ void I_StartupGraphics(void) graphics_started = true; } -void I_StartupHardwareGraphics(void) +void VID_StartupOpenGL(void) { #ifdef HWRENDER static boolean glstartup = false; @@ -1817,12 +1812,12 @@ void I_StartupHardwareGraphics(void) if (HWD.pfnGetRenderVersion() != VERSION) { CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - hwrenderloaded = -1; + vid_opengl_state = -1; } else - hwrenderloaded = HWD.pfnInit(I_Error) ? 1 : -1; // let load the OpenGL library + vid_opengl_state = HWD.pfnInit(I_Error) ? 1 : -1; // let load the OpenGL library - if (hwrenderloaded == -1) + if (vid_opengl_state == -1) { rendermode = render_soft; setrenderneeded = 0; diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index d0aab92b3..4e7bab569 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -239,10 +239,7 @@ void I_StartupGraphics(void) if (!dedicated) graphics_started = true; } -void I_StartupHardwareGraphics(void) -{ - // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y -} +void VID_StartupOpenGL(void){} // ------------------ // I_ShutdownGraphics @@ -951,10 +948,8 @@ INT32 VID_SetMode(INT32 modenum) return 1; } -void VID_CheckRenderer(void) -{ - // .............. -} +void VID_CheckRenderer(void) {} +void VID_CheckGLLoaded(rendermode_t oldrender) {} // ======================================================================== // Free the video buffer of the last video mode, From bef6cb532b9d414eff831a40ae0321eb7a79b983 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 17 Feb 2020 21:58:32 -0300 Subject: [PATCH 024/220] Fix what !785 tried to fix, but correctly --- src/hardware/hw_main.c | 1 - src/sdl/i_video.c | 66 +++++++++++++++++++++++++++++++++--------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7e913c4c7..eed1b4644 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6611,7 +6611,6 @@ void HWR_Shutdown(void) CONS_Printf("HWR_Shutdown()\n"); HWR_FreeExtraSubsectors(); HWR_FreePolyPool(); - HWR_FreeMipmapCache(); HWR_FreeTextureCache(); HWD.pfnFlushScreenTextures(); } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5d1baee74..3c1e01384 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1493,7 +1493,8 @@ void VID_CheckGLLoaded(rendermode_t oldrender) void VID_CheckRenderer(void) { - SDL_bool rendererchanged = SDL_FALSE; + boolean rendererchanged = false; + boolean contextcreated = false; rendermode_t oldrenderer = rendermode; if (dedicated) @@ -1502,21 +1503,51 @@ void VID_CheckRenderer(void) if (setrenderneeded) { rendermode = setrenderneeded; - rendererchanged = SDL_TRUE; + rendererchanged = true; #ifdef HWRENDER if (rendermode == render_opengl) { VID_CheckGLLoaded(oldrenderer); + // Initialise OpenGL before calling SDLSetMode!!! - if (vid_opengl_state != 1) + // This is because SDLSetMode calls OglSdlSurface. + if (vid_opengl_state == 0) + { VID_StartupOpenGL(); + // Loaded successfully! + if (vid_opengl_state == 1) + { + // Destroy the current window, if it exists. + if (window) + { + SDL_DestroyWindow(window); + window = NULL; + } + + // Destroy the current window rendering context, if that also exists. + if (renderer) + { + SDL_DestroyRenderer(renderer); + renderer = NULL; + } + + // Create a new window. + Impl_CreateWindow(USE_FULLSCREEN); + + // From there, the OpenGL context was already created. + contextcreated = true; + } + } else if (vid_opengl_state == -1) - rendererchanged = SDL_FALSE; + rendererchanged = false; } #endif - Impl_CreateContext(); + if (!contextcreated) + Impl_CreateContext(); + + setrenderneeded = 0; } SDLSetMode(vid.width, vid.height, USE_FULLSCREEN, (rendererchanged ? SDL_FALSE : SDL_TRUE)); @@ -1529,15 +1560,22 @@ void VID_CheckRenderer(void) SDL_FreeSurface(bufSurface); bufSurface = NULL; } + + if (rendererchanged) + { #ifdef HWRENDER - if (vid_opengl_state == 1) // Only if OpenGL ever loaded! - HWR_FreeTextureCache(); + if (vid_opengl_state == 1) // Only if OpenGL ever loaded! + HWR_FreeTextureCache(); #endif - SCR_SetDrawFuncs(); + SCR_SetDrawFuncs(); + } } #ifdef HWRENDER else if (rendermode == render_opengl) - R_InitHardwareMode(); + { + if (rendererchanged) + R_InitHardwareMode(); + } #else (void)oldrenderer; #endif @@ -1581,7 +1619,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) flags |= SDL_WINDOW_BORDERLESS; #ifdef HWRENDER - if (vid_opengl_state != -1) + if (vid_opengl_state == 1) flags |= SDL_WINDOW_OPENGL; #endif @@ -1715,10 +1753,11 @@ void I_StartupGraphics(void) //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); + #ifdef HWRENDER if (M_CheckParm("-nogl")) - vid_opengl_state = -1; // Don't call SDL_GL_LoadLibrary - else + vid_opengl_state = -1; // Don't startup OpenGL + else if (chosenrendermode == render_opengl) VID_StartupOpenGL(); #endif @@ -1780,6 +1819,7 @@ void VID_StartupOpenGL(void) static boolean glstartup = false; if (!glstartup) { + CONS_Printf("VID_StartupOpenGL()...\n"); HWD.pfnInit = hwSym("Init",NULL); HWD.pfnFinishUpdate = NULL; HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); @@ -1811,7 +1851,7 @@ void VID_StartupOpenGL(void) // check gl renderer lib if (HWD.pfnGetRenderVersion() != VERSION) { - CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); + CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable!\nBe sure you have installed SRB2 properly.\n")); vid_opengl_state = -1; } else From d3abf5dcfa83b2935294bd49a28d6b1968b81050 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 17 Feb 2020 22:31:34 -0300 Subject: [PATCH 025/220] Set the palette :) --- src/sdl/i_video.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 3c1e01384..dc263f457 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1574,7 +1574,10 @@ void VID_CheckRenderer(void) else if (rendermode == render_opengl) { if (rendererchanged) + { R_InitHardwareMode(); + V_SetPalette(0); + } } #else (void)oldrenderer; From bd7b2fcb936e104bd3f63278cd743797efdbf70b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 17 Feb 2020 22:33:36 -0300 Subject: [PATCH 026/220] setrenderneeded is already cleared earlier --- src/d_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index d9f67675c..c4b445089 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1300,11 +1300,10 @@ void D_SRB2Main(void) // Set cv_renderer to the new render mode VID_CheckRenderer(); - SCR_ChangeRendererCVars(setrenderneeded); + SCR_ChangeRendererCVars(rendermode); - // check the renderer's state, and then clear setrenderneeded + // check the renderer's state D_CheckRendererState(); - setrenderneeded = 0; } wipegamestate = gamestate; From b1ad7787f44bec6a0000728e68f97ea0cbb46e98 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 18 Feb 2020 22:54:11 -0300 Subject: [PATCH 027/220] Standards 3 --- src/p_enemy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 6b20862ed..b7ccdb01b 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8961,13 +8961,13 @@ void A_Dye(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; + + mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor); + UINT8 color = (UINT8)locvar2; #ifdef HAVE_BLUA if (LUA_CallAction("A_Dye", actor)) return; #endif - mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor); - UINT8 color = (UINT8)locvar2; - if (color >= MAXTRANSLATIONS) return; From 2a93ddc2dd01264234f66bd7bb37d89ff340dde9 Mon Sep 17 00:00:00 2001 From: Snu Date: Thu, 20 Feb 2020 21:53:21 +0000 Subject: [PATCH 028/220] Change SKINCOLOR_SUPERGOLD1-5 --- src/r_draw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/r_draw.c b/src/r_draw.c index 743965cfb..60ff67680 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -229,11 +229,11 @@ const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = { {0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERORANGE4 {0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERORANGE5 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, // SKINCOLOR_SUPERGOLD1 - {0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, // SKINCOLOR_SUPERGOLD2 - {0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, // SKINCOLOR_SUPERGOLD3 - {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERGOLD4 - {0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERGOLD5 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48, 0x48, 0x48}, // SKINCOLOR_SUPERGOLD1 + {0x00, 0x50, 0x51, 0x52, 0x53, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x41, 0x41}, // SKINCOLOR_SUPERGOLD2 + {0x51, 0x52, 0x53, 0x53, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x43, 0x43}, // SKINCOLOR_SUPERGOLD3 + {0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46, 0x46}, // SKINCOLOR_SUPERGOLD4 + {0x48, 0x48, 0x49, 0x49, 0x49, 0x40, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x47}, // SKINCOLOR_SUPERGOLD5 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, // SKINCOLOR_SUPERPERIDOT1 {0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, // SKINCOLOR_SUPERPERIDOT2 From 4244480d6345148cd8d0e330e50494f9bf4114b8 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 14:43:41 -0800 Subject: [PATCH 029/220] Add patch_music.pk3 --- src/d_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_main.c b/src/d_main.c index 904ab3bf1..2792122e6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -963,6 +963,7 @@ static void IdentifyVersion(void) } MUSICTEST("music.dta") + MUSICTEST("patch_music.pk3") #ifdef DEVELOP // remove when music_new.dta is merged into music.dta MUSICTEST("music_new.dta") #endif From d1dcdf88c7ad407f43f0132e986ba5f2844903ca Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 23 Feb 2020 18:44:22 -0600 Subject: [PATCH 030/220] Fix MD2 rollangle in reverse gravity --- src/hardware/hw_md2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 5c3cd40a6..c9b78bc79 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1478,7 +1478,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) // rotation pivot p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2); - p.centery = FIXED_TO_FLOAT(spr->mobj->height/2); + p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2)); // rotation axis if (sprinfo->available) @@ -1490,6 +1490,9 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) p.rollflip = 1; else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left p.rollflip = -1; + + if (flip) + p.rollflip *= -1; } p.anglex = 0.0f; From 1848ce4b9785ba044496c92fb8f1f8594804c369 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 24 Feb 2020 10:02:36 -0600 Subject: [PATCH 031/220] Skip empty gametypes in level select menu --- src/m_menu.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 945ce3de0..b39fcc2bf 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5045,6 +5045,17 @@ static boolean M_SetNextMapOnPlatter(void) } #endif +static boolean M_GametypeHasLevels(INT32 gt) +{ + INT32 mapnum; + + for (mapnum = 0; mapnum < NUMMAPS; mapnum++) + if (M_CanShowLevelOnPlatter(mapnum, gt)) + return true; + + return false; +} + static INT32 M_CountRowsToShowOnPlatter(INT32 gt) { INT32 mapnum = 0, prevmapnum = 0, col = 0, rows = 0; @@ -5362,7 +5373,9 @@ static void M_HandleLevelPlatter(INT32 choice) case KEY_RIGHTARROW: if (levellistmode == LLM_CREATESERVER && !lsrow) { - CV_AddValue(&cv_newgametype, 1); + do + CV_AddValue(&cv_newgametype, 1); + while (!M_GametypeHasLevels(cv_newgametype.value)); S_StartSound(NULL,sfx_menu1); lscol = 0; @@ -5391,7 +5404,9 @@ static void M_HandleLevelPlatter(INT32 choice) case KEY_LEFTARROW: if (levellistmode == LLM_CREATESERVER && !lsrow) { - CV_AddValue(&cv_newgametype, -1); + do + CV_AddValue(&cv_newgametype, -1); + while (!M_GametypeHasLevels(cv_newgametype.value)); S_StartSound(NULL,sfx_menu1); lscol = 0; From 0df094021e35e4304e0e7b544cab1c2f5870e416 Mon Sep 17 00:00:00 2001 From: sphere Date: Mon, 24 Feb 2020 17:31:30 +0100 Subject: [PATCH 032/220] Allow emblem hints (and radar) in record attack. --- src/m_menu.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 403d3a036..622d740e2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -521,6 +521,8 @@ static menuitem_t MISC_AddonsMenu[] = // --------------------------------- static menuitem_t MAPauseMenu[] = { + {IT_CALL | IT_STRING, NULL, "Emblem Hints...", M_EmblemHints, 32}, + {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,48}, {IT_CALL | IT_STRING, NULL, "Retry", M_ModeAttackRetry, 56}, {IT_CALL | IT_STRING, NULL, "Abort", M_ModeAttackEndGame, 64}, @@ -528,6 +530,7 @@ static menuitem_t MAPauseMenu[] = typedef enum { + mapause_hints, mapause_continue, mapause_retry, mapause_abort @@ -729,9 +732,9 @@ static menuitem_t SR_SoundTestMenu[] = static menuitem_t SR_EmblemHintMenu[] = { - {IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10}, - {IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20}, - {IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SPauseDef, 30} + {IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10}, + {IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20}, + {IT_WHITESTRING|IT_CALL, NULL, "Back", M_GoBack, 30} }; // -------------------------------- @@ -7266,6 +7269,7 @@ static void M_EmblemHints(INT32 choice) SR_EmblemHintMenu[0].status = (local > NUMHINTS*2) ? (IT_STRING | IT_ARROWS) : (IT_DISABLED); SR_EmblemHintMenu[1].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET); hintpage = 1; + SR_EmblemHintDef.prevMenu = currentMenu; M_SetupNextMenu(&SR_EmblemHintDef); itemOn = 2; // always start on back. } From 1f8dbd1b8c64dd51736679c195c2b258e69a78e8 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 24 Feb 2020 11:44:27 -0600 Subject: [PATCH 033/220] Allow using lump names in ExecCfg --- src/dehacked.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index dea0289b9..38330606a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3889,7 +3889,26 @@ static void readmaincfg(MYFILE *f) value = atoi(word2); // used for numerical settings if (fastcmp(word, "EXECCFG")) - COM_BufAddText(va("exec %s\n", word2)); + { + if (strchr(word2, '.')) + COM_BufAddText(va("exec %s\n", word2)); + else + { + lumpnum_t lumpnum; + char newname[9]; + + strncpy(newname, word2, 8); + + newname[8] = '\0'; + + lumpnum = W_CheckNumForName(newname); + + if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0) + CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname); + else + COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE)); + } + } else if (fastcmp(word, "SPSTAGE_START")) { @@ -7477,7 +7496,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Got Flag Sign "S_GOTFLAG", - + // Finish flag "S_FINISHFLAG", From f8408f3c99c515efac228d33f689aa77bd3b2946 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 24 Feb 2020 11:44:45 -0600 Subject: [PATCH 034/220] Fix ExecCfg not working on files added via command line --- src/d_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 904ab3bf1..1af7857ee 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1152,6 +1152,12 @@ void D_SRB2Main(void) if (M_CheckParm("-password") && M_IsNextParm()) D_SetPassword(M_GetNextParm()); + CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); + Z_Init(); + + // Do this up here so that WADs loaded through the command line can use ExecCfg + COM_Init(); + // add any files specified on the command line with -file wadfile // to the wad list if (!(M_CheckParm("-connect") && !M_CheckParm("-server"))) @@ -1179,9 +1185,6 @@ void D_SRB2Main(void) if (M_CheckParm("-server") || dedicated) netgame = server = true; - CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); - Z_Init(); - // adapt tables to SRB2's needs, including extra slots for dehacked file support P_PatchInfoTables(); @@ -1253,7 +1256,6 @@ void D_SRB2Main(void) CONS_Printf("HU_Init(): Setting up heads up display.\n"); HU_Init(); - COM_Init(); CON_Init(); D_RegisterServerCommands(); From b66be478d991bb3038bb28b892ce7b059b235595 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 24 Feb 2020 11:45:22 -0600 Subject: [PATCH 035/220] Increase COM_BUF_SIZE The config file is starting to get close to the old max, so this should be enough headroom for a while... --- src/command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index d1eea6052..abe6bcedf 100644 --- a/src/command.c +++ b/src/command.c @@ -80,7 +80,7 @@ static boolean joyaxis2_default = false; static INT32 joyaxis_count = 0; static INT32 joyaxis2_count = 0; -#define COM_BUF_SIZE 8192 // command buffer size +#define COM_BUF_SIZE (32<<10) // command buffer size #define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases static INT32 com_wait; // one command per frame (for cmd sequences) From da122ca2fd195b6defdf4cc108f3e59e9fd313e4 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 24 Feb 2020 17:56:00 -0600 Subject: [PATCH 036/220] Fix missing menuname entries --- src/dehacked.c | 5 +++++ src/m_menu.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index dea0289b9..55a531347 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9209,6 +9209,7 @@ static const char *const MENUTYPES_LIST[] = { "MP_CONNECT", "MP_ROOM", "MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET + "MP_SERVER_OPTIONS", // Options "OP_MAIN", @@ -9218,10 +9219,14 @@ static const char *const MENUTYPES_LIST[] = { "OP_P1MOUSE", "OP_P1JOYSTICK", "OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2 + "OP_P1CAMERA", "OP_P2CONTROLS", "OP_P2MOUSE", "OP_P2JOYSTICK", + "OP_P2CAMERA", + + "OP_PLAYSTYLE", "OP_VIDEO", "OP_VIDEOMODE", diff --git a/src/m_menu.h b/src/m_menu.h index 18b681ff0..6cfa9ef71 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -30,6 +30,9 @@ #define MENUBITS 6 // Menu IDs sectioned by numeric places to signify hierarchy +/** + * IF YOU MODIFY THIS, MODIFY MENUTYPES_LIST[] IN dehacked.c TO MATCH. + */ typedef enum { MN_NONE, From 141df606c2109e97e14aa47f52dd381dba622192 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 24 Feb 2020 18:00:17 -0600 Subject: [PATCH 037/220] Use a named macro for menu hierarchy This _really_ needs to be a UINT8 array instead of all this bit-shifting nonsense that saves no space, but at least this way reading the menu structs doesn't make me want to die. --- src/m_menu.c | 126 +++++++++++++++++++++++++-------------------------- src/m_menu.h | 3 ++ 2 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 945ce3de0..53ad6b12c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1687,7 +1687,7 @@ static INT32 highlightflags, recommendedflags, warningflags; // Sky Room menu_t SR_PandoraDef = { - MN_SR_MAIN + (MN_SR_PANDORA << 6), + MTREE2(MN_SR_MAIN, MN_SR_PANDORA), "M_PANDRA", sizeof (SR_PandorasBox)/sizeof (menuitem_t), &SPauseDef, @@ -1701,12 +1701,12 @@ menu_t SR_PandoraDef = menu_t SR_MainDef = DEFAULTMENUSTYLE(MN_SR_MAIN, "M_SECRET", SR_MainMenu, &MainDef, 60, 40); menu_t SR_LevelSelectDef = MAPPLATTERMENUSTYLE( - MN_SR_MAIN + (MN_SR_LEVELSELECT << 6), + MTREE2(MN_SR_MAIN, MN_SR_LEVELSELECT), NULL, SR_LevelSelectMenu); menu_t SR_UnlockChecklistDef = { - MN_SR_MAIN + (MN_SR_UNLOCKCHECKLIST << 6), + MTREE2(MN_SR_MAIN, MN_SR_UNLOCKCHECKLIST), "M_SECRET", 1, &SR_MainDef, @@ -1719,7 +1719,7 @@ menu_t SR_UnlockChecklistDef = menu_t SR_SoundTestDef = { - MN_SR_MAIN + (MN_SR_SOUNDTEST << 6), + MTREE2(MN_SR_MAIN, MN_SR_SOUNDTEST), NULL, sizeof (SR_SoundTestMenu)/sizeof (menuitem_t), &SR_MainDef, @@ -1732,7 +1732,7 @@ menu_t SR_SoundTestDef = menu_t SR_EmblemHintDef = { - MN_SR_MAIN + (MN_SR_EMBLEMHINT << 6), + MTREE2(MN_SR_MAIN, MN_SR_EMBLEMHINT), NULL, sizeof (SR_EmblemHintMenu)/sizeof (menuitem_t), &SPauseDef, @@ -1759,7 +1759,7 @@ menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72); menu_t SP_LoadDef = { - MN_SP_MAIN + (MN_SP_LOAD << 6), + MTREE2(MN_SP_MAIN, MN_SP_LOAD), "M_PICKG", 1, &SP_MainDef, @@ -1771,12 +1771,12 @@ menu_t SP_LoadDef = }; menu_t SP_LevelSelectDef = MAPPLATTERMENUSTYLE( - MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12) + (MN_SP_LEVELSELECT << 18), + MTREE4(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER, MN_SP_LEVELSELECT), NULL, SP_LevelSelectMenu); menu_t SP_LevelStatsDef = { - MN_SP_MAIN + (MN_SP_LEVELSTATS << 6), + MTREE2(MN_SP_MAIN, MN_SP_LEVELSTATS), "M_STATS", 1, &SP_MainDef, @@ -1788,12 +1788,12 @@ menu_t SP_LevelStatsDef = }; menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE( - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_TIMEATTACK_LEVELSELECT << 12), + MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_TIMEATTACK_LEVELSELECT), "M_ATTACK", SP_TimeAttackLevelSelectMenu); static menu_t SP_TimeAttackDef = { - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6), + MTREE2(MN_SP_MAIN, MN_SP_TIMEATTACK), "M_ATTACK", sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t), &MainDef, // Doesn't matter. @@ -1805,7 +1805,7 @@ static menu_t SP_TimeAttackDef = }; static menu_t SP_ReplayDef = { - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_REPLAY << 12), + MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_REPLAY), "M_ATTACK", sizeof(SP_ReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, @@ -1817,7 +1817,7 @@ static menu_t SP_ReplayDef = }; static menu_t SP_GuestReplayDef = { - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GUESTREPLAY << 12), + MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GUESTREPLAY), "M_ATTACK", sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, @@ -1829,7 +1829,7 @@ static menu_t SP_GuestReplayDef = }; static menu_t SP_GhostDef = { - MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GHOST << 12), + MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GHOST), "M_ATTACK", sizeof(SP_GhostMenu)/sizeof(menuitem_t), &SP_TimeAttackDef, @@ -1841,12 +1841,12 @@ static menu_t SP_GhostDef = }; menu_t SP_NightsAttackLevelSelectDef = MAPPLATTERMENUSTYLE( - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_LEVELSELECT << 12), + MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_LEVELSELECT), "M_NIGHTS", SP_NightsAttackLevelSelectMenu); static menu_t SP_NightsAttackDef = { - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6), + MTREE2(MN_SP_MAIN, MN_SP_NIGHTSATTACK), "M_NIGHTS", sizeof (SP_NightsAttackMenu)/sizeof (menuitem_t), &MainDef, // Doesn't matter. @@ -1858,7 +1858,7 @@ static menu_t SP_NightsAttackDef = }; static menu_t SP_NightsReplayDef = { - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_REPLAY << 12), + MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_REPLAY), "M_NIGHTS", sizeof(SP_NightsReplayMenu)/sizeof(menuitem_t), &SP_NightsAttackDef, @@ -1870,7 +1870,7 @@ static menu_t SP_NightsReplayDef = }; static menu_t SP_NightsGuestReplayDef = { - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GUESTREPLAY << 12), + MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GUESTREPLAY), "M_NIGHTS", sizeof(SP_NightsGuestReplayMenu)/sizeof(menuitem_t), &SP_NightsAttackDef, @@ -1882,7 +1882,7 @@ static menu_t SP_NightsGuestReplayDef = }; static menu_t SP_NightsGhostDef = { - MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GHOST << 12), + MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GHOST), "M_NIGHTS", sizeof(SP_NightsGhostMenu)/sizeof(menuitem_t), &SP_NightsAttackDef, @@ -1896,7 +1896,7 @@ static menu_t SP_NightsGhostDef = menu_t SP_PlayerDef = { - MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12), + MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER), "M_PICKP", sizeof (SP_PlayerMenu)/sizeof (menuitem_t), &SP_MainDef, @@ -1911,7 +1911,7 @@ menu_t SP_PlayerDef = menu_t MP_SplitServerDef = { - MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6), + MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN), "M_MULTI", sizeof (MP_SplitServerMenu)/sizeof (menuitem_t), #ifndef NONET @@ -1943,7 +1943,7 @@ menu_t MP_MainDef = menu_t MP_ServerDef = { - MN_MP_MAIN + (MN_MP_SERVER << 6), + MTREE2(MN_MP_MAIN, MN_MP_SERVER), "M_MULTI", sizeof (MP_ServerMenu)/sizeof (menuitem_t), &MP_MainDef, @@ -1956,7 +1956,7 @@ menu_t MP_ServerDef = menu_t MP_ConnectDef = { - MN_MP_MAIN + (MN_MP_CONNECT << 6), + MTREE2(MN_MP_MAIN, MN_MP_CONNECT), "M_MULTI", sizeof (MP_ConnectMenu)/sizeof (menuitem_t), &MP_MainDef, @@ -1969,7 +1969,7 @@ menu_t MP_ConnectDef = menu_t MP_RoomDef = { - MN_MP_MAIN + (MN_MP_ROOM << 6), + MTREE2(MN_MP_MAIN, MN_MP_ROOM), "M_MULTI", sizeof (MP_RoomMenu)/sizeof (menuitem_t), &MP_ConnectDef, @@ -1984,9 +1984,9 @@ menu_t MP_RoomDef = menu_t MP_PlayerSetupDef = { #ifdef NONET - MN_MP_MAIN + (MN_MP_PLAYERSETUP << 6), + MTREE2(MN_MP_MAIN, MN_MP_PLAYERSETUP), #else - MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6) + (MN_MP_PLAYERSETUP << 12), + MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP), #endif "M_SPLAYR", sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), @@ -2002,12 +2002,13 @@ menu_t MP_PlayerSetupDef = menu_t OP_MainDef = DEFAULTMENUSTYLE( MN_OP_MAIN, "M_OPTTTL", OP_MainMenu, &MainDef, 50, 30); + menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE( - MN_OP_MAIN + (MN_OP_CHANGECONTROLS << 12), // second level (<<6) set on runtime + MTREE3(MN_OP_MAIN, 0, MN_OP_CHANGECONTROLS), // second level set on runtime OP_ChangeControlsMenu, &OP_MainDef); menu_t OP_P1ControlsDef = { - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6), + MTREE2(MN_OP_MAIN, MN_OP_P1CONTROLS), "M_CONTRO", sizeof(OP_P1ControlsMenu)/sizeof(menuitem_t), &OP_MainDef, @@ -2015,7 +2016,7 @@ menu_t OP_P1ControlsDef = { M_DrawControlsDefMenu, 50, 30, 0, NULL}; menu_t OP_P2ControlsDef = { - MN_OP_MAIN + (MN_OP_P2CONTROLS << 6), + MTREE2(MN_OP_MAIN, MN_OP_P2CONTROLS), "M_CONTRO", sizeof(OP_P2ControlsMenu)/sizeof(menuitem_t), &OP_MainDef, @@ -2024,20 +2025,22 @@ menu_t OP_P2ControlsDef = { 50, 30, 0, NULL}; menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1MOUSE << 12), + MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1MOUSE), "M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30); menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2MOUSE << 12), + MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2MOUSE), "M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 35, 30); + menu_t OP_Joystick1Def = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1JOYSTICK << 12), + MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1JOYSTICK), "M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 50, 30); menu_t OP_Joystick2Def = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2JOYSTICK << 12), + MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2JOYSTICK), "M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30); + menu_t OP_JoystickSetDef = { - MN_OP_MAIN + (MN_OP_JOYSTICKSET << MENUBITS*3), // second (<<6) and third level (<<12) set on runtime + MTREE4(MN_OP_MAIN, 0, 0, MN_OP_JOYSTICKSET), // second and third level set on runtime "M_CONTRO", sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t), &OP_Joystick1Def, @@ -2049,7 +2052,7 @@ menu_t OP_JoystickSetDef = }; menu_t OP_CameraOptionsDef = { - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1CAMERA << 12), + MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1CAMERA), "M_CONTRO", sizeof (OP_CameraOptionsMenu)/sizeof (menuitem_t), &OP_P1ControlsDef, @@ -2060,7 +2063,7 @@ menu_t OP_CameraOptionsDef = { NULL }; menu_t OP_Camera2OptionsDef = { - MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12), + MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2CAMERA), "M_CONTRO", sizeof (OP_Camera2OptionsMenu)/sizeof (menuitem_t), &OP_P2ControlsDef, @@ -2074,7 +2077,7 @@ menu_t OP_Camera2OptionsDef = { static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}}; menu_t OP_PlaystyleDef = { - MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_PLAYSTYLE << 12), + MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_PLAYSTYLE), ///@TODO the second level should be set in runtime NULL, 1, &OP_P1ControlsDef, @@ -2086,7 +2089,7 @@ menu_t OP_PlaystyleDef = { menu_t OP_VideoOptionsDef = { - MN_OP_MAIN + (MN_OP_VIDEO << 6), + MTREE2(MN_OP_MAIN, MN_OP_VIDEO), "M_VIDEO", sizeof (OP_VideoOptionsMenu)/sizeof (menuitem_t), &OP_MainDef, @@ -2098,7 +2101,7 @@ menu_t OP_VideoOptionsDef = }; menu_t OP_VideoModeDef = { - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_VIDEOMODE << 12), + MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_VIDEOMODE), "M_VIDEO", 1, &OP_VideoOptionsDef, @@ -2110,7 +2113,7 @@ menu_t OP_VideoModeDef = }; menu_t OP_ColorOptionsDef = { - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_COLOR << 12), + MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_COLOR), "M_VIDEO", sizeof (OP_ColorOptionsMenu)/sizeof (menuitem_t), &OP_VideoOptionsDef, @@ -2121,17 +2124,19 @@ menu_t OP_ColorOptionsDef = NULL }; menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_SOUND << 6), + MTREE2(MN_OP_MAIN, MN_OP_SOUND), "M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30); -menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30); +menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE( + MTREE2(MN_OP_MAIN, MN_OP_SOUND), + "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30); menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE( - MN_OP_MAIN + (MN_OP_SERVER << 6), + MTREE2(MN_OP_MAIN, MN_OP_SERVER), "M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30); menu_t OP_MonitorToggleDef = { - MN_OP_MAIN + (MN_OP_SERVER << 6) + (MN_OP_MONITORTOGGLE << 12), + MTREE3(MN_OP_MAIN, MN_OP_SOUND, MN_OP_MONITORTOGGLE), "M_SERVER", sizeof (OP_MonitorToggleMenu)/sizeof (menuitem_t), &OP_ServerOptionsDef, @@ -2152,16 +2157,16 @@ static void M_OpenGLOptionsMenu(void) } menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12), + MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL), "M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); #ifdef ALAM_LIGHTING menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_LIGHTING << 18), + MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_LIGHTING), "M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); #endif menu_t OP_OpenGLFogDef = { - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_FOG << 18), + MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_FOG), "M_VIDEO", sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t), &OP_OpenGLOptionsDef, @@ -2173,12 +2178,12 @@ menu_t OP_OpenGLFogDef = }; #endif menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_DATA << 6), + MTREE2(MN_OP_MAIN, MN_OP_DATA), "M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30); menu_t OP_ScreenshotOptionsDef = { - MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_SCREENSHOTS << 12), + MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_SCREENSHOTS), "M_DATA", sizeof (OP_ScreenshotOptionsMenu)/sizeof (menuitem_t), &OP_DataOptionsDef, @@ -2190,11 +2195,11 @@ menu_t OP_ScreenshotOptionsDef = }; menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ADDONS << 12), + MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ADDONS), "M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30); menu_t OP_EraseDataDef = DEFAULTMENUSTYLE( - MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ERASEDATA << 12), + MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ERASEDATA), "M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30); // ========================================================================== @@ -8844,16 +8849,11 @@ static void M_SetupChoosePlayer(INT32 choice) /* the menus suck -James */ if (currentMenu == &SP_LoadDef)/* from save states */ { - SP_PlayerDef.menuid = - MN_SP_MAIN + - ( MN_SP_LOAD << 6 ) + - ( MN_SP_PLAYER << 12 ); + SP_PlayerDef.menuid = MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER); } else/* from Secret level select */ { - SP_PlayerDef.menuid = - MN_SR_MAIN + - ( MN_SR_PLAYER << 6 ); + SP_PlayerDef.menuid = MTREE2(MN_SR_MAIN, MN_SR_PLAYER); } SP_PlayerDef.prevMenu = currentMenu; @@ -10747,9 +10747,9 @@ static void M_ServerOptions(INT32 choice) /* Disable fading because of different menu head. */ if (currentMenu == &OP_MainDef)/* from Options menu */ - OP_ServerOptionsDef.menuid = MN_OP_MAIN + ( MN_OP_SERVER << 6 ); + OP_ServerOptionsDef.menuid = MTREE2(MN_OP_MAIN, MN_OP_SERVER); else/* from Multiplayer menu */ - OP_ServerOptionsDef.menuid = MN_MP_MAIN + ( MN_MP_SERVER_OPTIONS << 6 ); + OP_ServerOptionsDef.menuid = MTREE2(MN_MP_MAIN, MN_MP_SERVER_OPTIONS); OP_ServerOptionsDef.prevMenu = currentMenu; M_SetupNextMenu(&OP_ServerOptionsDef); @@ -11666,8 +11666,8 @@ static void M_Setup1PControlsMenu(INT32 choice) OP_ChangeControlsMenu[27+3].status = IT_CALL|IT_STRING2; OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef; - OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) - OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine first level (<< 6) + OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level + OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine second level M_SetupNextMenu(&OP_ChangeControlsDef); } @@ -11697,8 +11697,8 @@ static void M_Setup2PControlsMenu(INT32 choice) OP_ChangeControlsMenu[27+3].status = IT_GRAYEDOUT2; OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef; - OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6) - OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine first level (<< 6) + OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level + OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine second level M_SetupNextMenu(&OP_ChangeControlsDef); } diff --git a/src/m_menu.h b/src/m_menu.h index 6cfa9ef71..47540acee 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -131,6 +131,9 @@ typedef enum MN_SPECIAL, NUMMENUTYPES, } menutype_t; // up to 63; MN_SPECIAL = 53 +#define MTREE2(a,b) (a | (b< Date: Mon, 24 Feb 2020 18:00:52 -0600 Subject: [PATCH 038/220] Fix menu enterwipes being overridden? --- src/d_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 904ab3bf1..a991bdbe3 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -312,7 +312,9 @@ static void D_Display(void) F_WipeStartScreen(); // Check for Mega Genesis fade wipestyleflags = WSF_FADEOUT; - if (F_TryColormapFade(31)) + if (wipegamestate == (gamestate_t)FORCEWIPE) + F_WipeColorFill(31); + else if (F_TryColormapFade(31)) wipetypepost = -1; // Don't run the fade below this one F_WipeEndScreen(); F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN); From 776951c6a897ac0a55e952aeb2963bea79504df3 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 3 Mar 2020 11:40:35 -0300 Subject: [PATCH 039/220] Never forget who your enemy is --- src/p_mobj.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index faee245d3..31abeb780 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9393,8 +9393,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16) { + var1 = mobj->info->speed; + var2 = 1; + // Home in on the target. - P_HomingAttack(mobj, mobj->tracer); + A_HomingChase(mobj); if (mobj->z < mobj->floorz) mobj->z = mobj->floorz; From 761ec3b6a4a2389d985ae8263fb65a3eb9a82fd7 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 1 Mar 2020 21:31:44 -0300 Subject: [PATCH 040/220] Separate PvP damage from non-friendly gametypes --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index a24f9bf03..8b9f74973 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3156,7 +3156,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou return false; // In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on - if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (G_PlatformGametype())) + if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (gametyperules & GTR_FRIENDLY)) { if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only { From 0d92bf3dd09cd4712a63fc79cc7520ed18556bf6 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 7 Mar 2020 21:41:52 -0600 Subject: [PATCH 041/220] Florida man fixes sectors with light level 256 blacking out OpenGL objects; mappers riot. Disclaimer: I'm not actually from Florida. --- src/hardware/hw_main.c | 17 ++++++++++------- src/hardware/hw_md2.c | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index efed9b602..5a5db90e8 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4186,7 +4186,10 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale { light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before - lightlevel = *thing->subsector->sector->lightlist[light].lightlevel; + if (*thing->subsector->sector->lightlist[light].lightlevel > 255) + lightlevel = 255; + else + lightlevel = *thing->subsector->sector->lightlist[light].lightlevel; if (*thing->subsector->sector->lightlist[light].extra_colormap) colormap = *thing->subsector->sector->lightlist[light].extra_colormap; @@ -4392,7 +4395,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (h <= temp) { if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *list[i-1].lightlevel; + lightlevel = *list[i-1].lightlevel > 255 ? 255 : *list[i-1].lightlevel; colormap = *list[i-1].extra_colormap; break; } @@ -4400,7 +4403,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) #else i = R_GetPlaneLight(sector, temp, false); if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *list[i].lightlevel; + lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel; colormap = *list[i].extra_colormap; #endif @@ -4416,7 +4419,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES)) { if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *list[i].lightlevel; + lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel; colormap = *list[i].extra_colormap; } @@ -4693,7 +4696,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) extracolormap_t *colormap = sector->extra_colormap; if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = sector->lightlevel; + lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel; if (colormap) Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); @@ -4790,7 +4793,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *sector->lightlist[light].lightlevel; + lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel; if (*sector->lightlist[light].extra_colormap) colormap = *sector->lightlist[light].extra_colormap; @@ -4798,7 +4801,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) else { if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = sector->lightlevel; + lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel; if (sector->extra_colormap) colormap = sector->extra_colormap; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 5c3cd40a6..2e3af4a4c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1221,7 +1221,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *sector->lightlist[light].lightlevel; + lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel; if (*sector->lightlist[light].extra_colormap) colormap = *sector->lightlist[light].extra_colormap; @@ -1229,7 +1229,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) else { if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = sector->lightlevel; + lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel; if (sector->extra_colormap) colormap = sector->extra_colormap; From cdba9ba03371adf3609010aa8896200018570cc7 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 7 Mar 2020 21:48:40 -0600 Subject: [PATCH 042/220] Fix spaces before someone yells at me for it --- src/hardware/hw_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5a5db90e8..bb3559696 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4186,10 +4186,10 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale { light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before - if (*thing->subsector->sector->lightlist[light].lightlevel > 255) - lightlevel = 255; - else - lightlevel = *thing->subsector->sector->lightlist[light].lightlevel; + if (*thing->subsector->sector->lightlist[light].lightlevel > 255) + lightlevel = 255; + else + lightlevel = *thing->subsector->sector->lightlist[light].lightlevel; if (*thing->subsector->sector->lightlist[light].extra_colormap) colormap = *thing->subsector->sector->lightlist[light].extra_colormap; From be338da3f695f94cce07a9aa4ae2e0e85701d8af Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 8 Mar 2020 14:06:18 -0300 Subject: [PATCH 043/220] I guess --- 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 9167d5345..1715224ae 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9422,7 +9422,7 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target if (enemy->health <= 0) // dead return false; - if (!((enemy->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (enemy->flags & MF_SHOOTABLE)) || (enemy->flags & MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag + if (source->player && (!((enemy->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (enemy->flags & MF_SHOOTABLE)) || (enemy->flags & MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE))) // allows if it has the flags desired XOR it has the invert aimable flag return false; if (enemy->flags2 & MF2_FRET) From bdab78152cb5288cdce2303cb6f65b99b6c22129 Mon Sep 17 00:00:00 2001 From: sphere Date: Fri, 13 Mar 2020 10:46:57 -0400 Subject: [PATCH 044/220] Check if emblem hints are actually unlocked. --- src/m_menu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/m_menu.c b/src/m_menu.c index 622d740e2..18f1f6c8e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3612,6 +3612,7 @@ void M_StartControlPanel(void) else if (modeattacking) { currentMenu = &MAPauseDef; + MAPauseMenu[mapause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); itemOn = mapause_continue; } else if (!(netgame || multiplayer)) // Single Player From c2cd9a71fad89d9b57759e6567437be8958625c1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Mar 2020 13:05:54 -0300 Subject: [PATCH 045/220] Fix con_backpic --- src/console.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/console.c b/src/console.c index f8fa1314a..e39c2f531 100644 --- a/src/console.c +++ b/src/console.c @@ -1553,13 +1553,28 @@ static void CON_DrawConsole(void) if (cons_backpic.value || con_forcepic) { patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); - int h; + int x, w, h; + w = (con_backpic->width * vid.dupx); + x = (vid.width / 2) - (w / 2); h = con_curlines/vid.dupy; - // Jimita: CON_DrawBackpic just called V_DrawScaledPatch - //V_DrawScaledPatch(0, 0, 0, con_backpic); - V_DrawCroppedPatch(0, 0, FRACUNIT, 0, con_backpic, + // Lactozilla: If the patch doesn't fill the entire screen, + // then fill the sides with a solid color. + if (x > 0) + { + column_t *column = (column_t *)((UINT8 *)(con_backpic) + LONG(con_backpic->columnofs[0])); + if (!column->topdelta) + { + UINT8 *source = (UINT8 *)(column) + 3; + INT32 color = (source[0] | V_NOSCALESTART); + // left side + V_DrawFill(0, 0, x, con_curlines, color); + // right side + V_DrawFill((x + w), 0, (vid.width - w), con_curlines, color); + } + } + V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, V_NOSCALESTART, con_backpic, 0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h); W_UnlockCachedPatch(con_backpic); From 1904e3b5e9e1491d59cfac9df2aac9f9196c3a40 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Mar 2020 15:23:13 -0300 Subject: [PATCH 046/220] Fix OpenGL --- src/console.c | 75 +++++++++++++++++++++++-------------- src/hardware/hw_draw.c | 4 +- src/w_wad.c | 85 ++++++++++++++++++++++++++---------------- src/w_wad.h | 11 +++++- 4 files changed, 110 insertions(+), 65 deletions(-) diff --git a/src/console.c b/src/console.c index e39c2f531..0f1ccbd33 100644 --- a/src/console.c +++ b/src/console.c @@ -97,6 +97,7 @@ static void CON_InputInit(void); static void CON_RecalcSize(void); static void CON_ChangeHeight(void); +static void CON_DrawBackpic(void); static void CONS_hudlines_Change(void); static void CONS_backcolor_Change(void); @@ -1530,6 +1531,51 @@ static void CON_DrawHudlines(void) con_clearlines = y; // this is handled by HU_Erase(); } +// Lactozilla: Draws the console's background picture. +static void CON_DrawBackpic(void) +{ + patch_t *con_backpic; + lumpnum_t piclump; + int x, w, h; + + // Get the lumpnum for CONSBACK, or fallback into MISSING. + piclump = W_CheckNumForName("CONSBACK"); + if (piclump == LUMPERROR) + piclump = W_GetNumForName("MISSING"); + + // Cache the Software patch. + con_backpic = W_CacheSoftwarePatchNum(piclump, PU_PATCH); + + // Center the backpic, and draw a vertically cropped patch. + w = (con_backpic->width * vid.dupx); + x = (vid.width / 2) - (w / 2); + h = con_curlines/vid.dupy; + + // If the patch doesn't fill the entire screen, + // then fill the sides with a solid color. + if (x > 0) + { + column_t *column = (column_t *)((UINT8 *)(con_backpic) + LONG(con_backpic->columnofs[0])); + if (!column->topdelta) + { + UINT8 *source = (UINT8 *)(column) + 3; + INT32 color = (source[0] | V_NOSCALESTART); + // left side + V_DrawFill(0, 0, x, con_curlines, color); + // right side + V_DrawFill((x + w), 0, (vid.width - w), con_curlines, color); + } + } + + // Cache the patch normally. + con_backpic = W_CachePatchNum(piclump, PU_PATCH); + V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, V_NOSCALESTART, con_backpic, + 0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h); + + // Unlock the cached patch. + W_UnlockCachedPatch(con_backpic); +} + // draw the console background, text, and prompt if enough place // static void CON_DrawConsole(void) @@ -1551,34 +1597,7 @@ static void CON_DrawConsole(void) // draw console background if (cons_backpic.value || con_forcepic) - { - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); - int x, w, h; - - w = (con_backpic->width * vid.dupx); - x = (vid.width / 2) - (w / 2); - h = con_curlines/vid.dupy; - - // Lactozilla: If the patch doesn't fill the entire screen, - // then fill the sides with a solid color. - if (x > 0) - { - column_t *column = (column_t *)((UINT8 *)(con_backpic) + LONG(con_backpic->columnofs[0])); - if (!column->topdelta) - { - UINT8 *source = (UINT8 *)(column) + 3; - INT32 color = (source[0] | V_NOSCALESTART); - // left side - V_DrawFill(0, 0, x, con_curlines, color); - // right side - V_DrawFill((x + w), 0, (vid.width - w), con_curlines, color); - } - } - V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, V_NOSCALESTART, con_backpic, - 0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h); - - W_UnlockCachedPatch(con_backpic); - } + CON_DrawBackpic(); else { // inu: no more width (was always 0 and vid.width) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 598a635aa..d01331765 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -291,7 +291,7 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { // Need to temporarily cache the real patch to get the colour of the top left pixel - patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); + patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); if (!column->topdelta) { @@ -450,7 +450,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { // Need to temporarily cache the real patch to get the colour of the top left pixel - patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); + patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); if (!column->topdelta) { diff --git a/src/w_wad.c b/src/w_wad.c index e96afd050..797f286d5 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1511,6 +1511,57 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // +void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) +{ + lumpcache_t *lumpcache = NULL; + + if (needpatchflush) + W_FlushCachedPatches(); + + if (!TestValidLump(wad, lump)) + return NULL; + + lumpcache = wadfiles[wad]->patchcache; + + if (!lumpcache[lump]) + { + size_t len = W_LumpLengthPwad(wad, lump); + void *ptr, *lumpdata; +#ifndef NO_PNG_LUMPS + void *srcdata = NULL; +#endif + + ptr = Z_Malloc(len, tag, &lumpcache[lump]); + lumpdata = Z_Malloc(len, tag, NULL); + + // read the lump in full + W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0); + +#ifndef NO_PNG_LUMPS + // lump is a png so convert it + if (R_IsLumpPNG((UINT8 *)lumpdata, len)) + { + size_t newlen; + srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen); + ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]); + M_Memcpy(ptr, srcdata, newlen); + Z_Free(srcdata); + } + else // just copy it into the patch cache +#endif + M_Memcpy(ptr, lumpdata, len); + } + else + Z_ChangeTag(lumpcache[lump], tag); + + return lumpcache[lump]; +} + +void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag) +{ + return W_CacheSoftwarePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag); +} + void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { #ifdef HWRENDER @@ -1528,39 +1579,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) if (rendermode == render_soft || rendermode == render_none) #endif { - lumpcache_t *lumpcache = wadfiles[wad]->patchcache; - if (!lumpcache[lump]) - { - size_t len = W_LumpLengthPwad(wad, lump); - void *ptr, *lumpdata; -#ifndef NO_PNG_LUMPS - void *srcdata = NULL; -#endif - - ptr = Z_Malloc(len, tag, &lumpcache[lump]); - lumpdata = Z_Malloc(len, tag, NULL); - - // read the lump in full - W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0); - -#ifndef NO_PNG_LUMPS - // lump is a png so convert it - if (R_IsLumpPNG((UINT8 *)lumpdata, len)) - { - size_t newlen; - srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen); - ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]); - M_Memcpy(ptr, srcdata, newlen); - Z_Free(srcdata); - } - else // just copy it into the patch cache -#endif - M_Memcpy(ptr, lumpdata, len); - } - else - Z_ChangeTag(lumpcache[lump], tag); - - return lumpcache[lump]; + return W_CacheSoftwarePatchNumPwad(wad, lump, tag); } #ifdef HWRENDER diff --git a/src/w_wad.h b/src/w_wad.h index d598d9b39..3fb0cb77e 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -191,8 +191,15 @@ boolean W_IsPatchCached(lumpnum_t lump, void *ptr); void *W_CacheLumpName(const char *name, INT32 tag); void *W_CachePatchName(const char *name, INT32 tag); -void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); // return a patch_t -void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t +// Returns either a Software patch, or an OpenGL patch. +// Performs any necessary conversions from PNG images. +void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); +void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); + +// Returns a Software patch. +// Performs any necessary conversions from PNG images. +void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); +void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag); void W_UnlockCachedPatch(void *patch); void W_FlushCachedPatches(void); From 725826a64b6d56a04b7fd17e1e1ef4c20243047d Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 18 Mar 2020 22:56:20 -0500 Subject: [PATCH 047/220] Avoid infinite loops if no maps are selectable (y tho) --- src/m_menu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index b39fcc2bf..3ebaedca2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5373,9 +5373,10 @@ static void M_HandleLevelPlatter(INT32 choice) case KEY_RIGHTARROW: if (levellistmode == LLM_CREATESERVER && !lsrow) { + INT32 startinggametype = cv_newgametype.value; do CV_AddValue(&cv_newgametype, 1); - while (!M_GametypeHasLevels(cv_newgametype.value)); + while (cv_newgametype.value != startinggametype && !M_GametypeHasLevels(cv_newgametype.value)); S_StartSound(NULL,sfx_menu1); lscol = 0; From 58c42eec292d6a38748d9a720ddb5e682344f628 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 19 Mar 2020 14:38:42 +0100 Subject: [PATCH 048/220] Simplify hook code --- src/lua_hooklib.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 20a7738e7..078732541 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -155,25 +155,13 @@ static int lib_addHook(lua_State *L) hook.s.skinname = NULL; if (lua_isstring(L, 2)) { // lowercase copy - const char *s = lua_tostring(L, 2); - char *p = hook.s.skinname = ZZ_Alloc(strlen(s)+1); - do { - *p = tolower(*s); - ++p; - } while(*(++s)); - *p = 0; + hook.s.skinname = Z_StrDup(lua_tostring(L, 2)); + strlwr(hook.s.skinname); } break; case hook_LinedefExecute: // Linedef executor functions - { // uppercase copy - const char *s = luaL_checkstring(L, 2); - char *p = hook.s.funcname = ZZ_Alloc(strlen(s)+1); - do { - *p = toupper(*s); - ++p; - } while(*(++s)); - *p = 0; - } + hook.s.skinname = Z_StrDup(luaL_checkstring(L, 2)); + strupr(hook.s.skinname); break; default: break; From 1d5d6ead651174a10f554e5a27ae0caa6511e2c6 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 19 Mar 2020 14:40:12 +0100 Subject: [PATCH 049/220] Fix misleading naming --- src/lua_hooklib.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 078732541..549d1a3ef 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -81,9 +81,7 @@ struct hook_s UINT16 id; union { mobjtype_t mt; - char *skinname; - char *musname; - char *funcname; + char *str; } s; boolean error; }; @@ -152,16 +150,16 @@ static int lib_addHook(lua_State *L) break; case hook_BotAI: case hook_ShouldJingleContinue: - hook.s.skinname = NULL; + hook.s.str = NULL; if (lua_isstring(L, 2)) { // lowercase copy - hook.s.skinname = Z_StrDup(lua_tostring(L, 2)); - strlwr(hook.s.skinname); + hook.s.str = Z_StrDup(lua_tostring(L, 2)); + strlwr(hook.s.str); } break; case hook_LinedefExecute: // Linedef executor functions - hook.s.skinname = Z_StrDup(luaL_checkstring(L, 2)); - strupr(hook.s.skinname); + hook.s.str = Z_StrDup(luaL_checkstring(L, 2)); + strupr(hook.s.str); break; default: break; @@ -1064,7 +1062,7 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_BotAI - || (hookp->s.skinname && strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name))) + || (hookp->s.str && strcmp(hookp->s.str, ((skin_t*)tails->skin)->name))) continue; if (lua_gettop(gL) == 0) @@ -1126,7 +1124,7 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next) { - if (strcmp(hookp->s.funcname, line->text)) + if (strcmp(hookp->s.str, line->text)) continue; if (lua_gettop(gL) == 0) @@ -1664,7 +1662,7 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type != hook_ShouldJingleContinue - || (hookp->s.musname && strcmp(hookp->s.musname, musname))) + || (hookp->s.str && strcmp(hookp->s.str, musname))) continue; if (lua_gettop(gL) == 0) From c1b50397ce665bd082fb45e1f8b24e85963d2ead Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 19 Mar 2020 14:40:35 +0100 Subject: [PATCH 050/220] Fix compiler warning --- src/p_user.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 345da85ef..15a75b3a5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1550,6 +1550,10 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname) int i; boolean result = false; +#ifndef HAVE_BLUA + (void)musname; +#endif + for (i = 0; i < MAXPLAYERS; i++) { if (!P_IsLocalPlayer(&players[i])) From dcb4ce8cb99380ff5c474681ceb2de8f8ba8083e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 19 Mar 2020 20:09:55 +0000 Subject: [PATCH 051/220] Created g_demo.c/.h, for the demo recording and playback code that formerly lived in g_game.c --- src/g_demo.c | 2501 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/g_demo.h | 85 ++ src/g_game.c | 2500 +------------------------------------------------ src/g_game.h | 65 +- 4 files changed, 2607 insertions(+), 2544 deletions(-) create mode 100644 src/g_demo.c create mode 100644 src/g_demo.h diff --git a/src/g_demo.c b/src/g_demo.c new file mode 100644 index 000000000..22cd34ad5 --- /dev/null +++ b/src/g_demo.c @@ -0,0 +1,2501 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file g_demo.c +/// \brief Demo recording and playback + +#include "doomdef.h" +#include "console.h" +#include "d_main.h" +#include "d_player.h" +#include "d_clisrv.h" +//#include "f_finale.h" +#include "p_setup.h" +#include "i_system.h" +#include "m_random.h" +#include "p_local.h" +#include "r_draw.h" +#include "r_main.h" +//#include "s_sound.h" +#include "g_game.h" +#include "g_demo.h" +#include "m_cheat.h" +#include "m_misc.h" +#include "m_menu.h" +#include "m_argv.h" +#include "hu_stuff.h" +#include "z_zone.h" +#include "i_video.h" +#include "byteptr.h" +#include "i_joy.h" +#include "r_local.h" +#include "r_skins.h" +#include "y_inter.h" +#include "v_video.h" +#include "lua_hook.h" +#include "md5.h" // demo checksums + +boolean timingdemo; // if true, exit with report on completion +boolean nodrawers; // for comparative timing purposes +boolean noblit; // for comparative timing purposes +tic_t demostarttime; // for comparative timing purposes + +static char demoname[64]; +boolean demorecording; +boolean demoplayback; +boolean titledemo; // Title Screen demo can be cancelled by any key +static UINT8 *demobuffer = NULL; +static UINT8 *demo_p, *demotime_p; +static UINT8 *demoend; +static UINT8 demoflags; +static UINT16 demoversion; +boolean singledemo; // quit after playing a demo from cmdline +boolean demo_start; // don't start playing demo right away +boolean demosynced = true; // console warning message + +boolean metalrecording; // recording as metal sonic +mobj_t *metalplayback; +static UINT8 *metalbuffer = NULL; +static UINT8 *metal_p; +static UINT16 metalversion; + +// extra data stuff (events registered this frame while recording) +static struct { + UINT8 flags; // EZT flags + + // EZT_COLOR + UINT8 color, lastcolor; + + // EZT_SCALE + fixed_t scale, lastscale; + + // EZT_HIT + UINT16 hits; + mobj_t **hitlist; +} ghostext; + +// Your naming conventions are stupid and useless. +// There is no conflict here. +typedef struct demoghost { + UINT8 checksum[16]; + UINT8 *buffer, *p, color, fadein; + UINT16 version; + mobj_t oldmo, *mo; + struct demoghost *next; +} demoghost; +demoghost *ghosts = NULL; + +// +// DEMO RECORDING +// + +#define DEMOVERSION 0x000c +#define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" + +#define DF_GHOST 0x01 // This demo contains ghost data too! +#define DF_RECORDATTACK 0x02 // This demo is from record attack and contains its final completion time, score, and rings! +#define DF_NIGHTSATTACK 0x04 // This demo is from NiGHTS attack and contains its time left, score, and mares! +#define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ??? +#define DF_ATTACKSHIFT 1 + +// For demos +#define ZT_FWD 0x01 +#define ZT_SIDE 0x02 +#define ZT_ANGLE 0x04 +#define ZT_BUTTONS 0x08 +#define ZT_AIMING 0x10 +#define DEMOMARKER 0x80 // demoend +#define METALDEATH 0x44 +#define METALSNICE 0x69 + +static ticcmd_t oldcmd; + +// For Metal Sonic and time attack ghosts +#define GZT_XYZ 0x01 +#define GZT_MOMXY 0x02 +#define GZT_MOMZ 0x04 +#define GZT_ANGLE 0x08 +#define GZT_FRAME 0x10 // Animation frame +#define GZT_SPR2 0x20 // Player animations +#define GZT_EXTRA 0x40 +#define GZT_FOLLOW 0x80 // Followmobj + +// GZT_EXTRA flags +#define EZT_THOK 0x01 // Spawned a thok object +#define EZT_SPIN 0x02 // Because one type of thok object apparently wasn't enough +#define EZT_REV 0x03 // And two types wasn't enough either yet +#define EZT_THOKMASK 0x03 +#define EZT_COLOR 0x04 // Changed color (Super transformation, Mario fireflowers/invulnerability, etc.) +#define EZT_FLIP 0x08 // Reversed gravity +#define EZT_SCALE 0x10 // Changed size +#define EZT_HIT 0x20 // Damaged a mobj +#define EZT_SPRITE 0x40 // Changed sprite set completely out of PLAY (NiGHTS, SOCs, whatever) +#define EZT_HEIGHT 0x80 // Changed height + +// GZT_FOLLOW flags +#define FZT_SPAWNED 0x01 // just been spawned +#define FZT_SKIN 0x02 // has skin +#define FZT_LINKDRAW 0x04 // has linkdraw (combine with spawned only) +#define FZT_COLORIZED 0x08 // colorized (ditto) +#define FZT_SCALE 0x10 // different scale to object +// spare FZT slots 0x20 to 0x80 + +static mobj_t oldmetal, oldghost; + +void G_SaveMetal(UINT8 **buffer) +{ + I_Assert(buffer != NULL && *buffer != NULL); + + WRITEUINT32(*buffer, metal_p - metalbuffer); +} + +void G_LoadMetal(UINT8 **buffer) +{ + I_Assert(buffer != NULL && *buffer != NULL); + + G_DoPlayMetal(); + metal_p = metalbuffer + READUINT32(*buffer); +} + + +void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) +{ + UINT8 ziptic; + (void)playernum; + + if (!demo_p || !demo_start) + return; + ziptic = READUINT8(demo_p); + + if (ziptic & ZT_FWD) + oldcmd.forwardmove = READSINT8(demo_p); + if (ziptic & ZT_SIDE) + oldcmd.sidemove = READSINT8(demo_p); + if (ziptic & ZT_ANGLE) + oldcmd.angleturn = READINT16(demo_p); + if (ziptic & ZT_BUTTONS) + oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT)); + if (ziptic & ZT_AIMING) + oldcmd.aiming = READINT16(demo_p); + + G_CopyTiccmd(cmd, &oldcmd, 1); + + if (!(demoflags & DF_GHOST) && *demo_p == DEMOMARKER) + { + // end of demo data stream + G_CheckDemoStatus(); + return; + } +} + +void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum) +{ + char ziptic = 0; + UINT8 *ziptic_p; + (void)playernum; + + if (!demo_p) + return; + ziptic_p = demo_p++; // the ziptic, written at the end of this function + + if (cmd->forwardmove != oldcmd.forwardmove) + { + WRITEUINT8(demo_p,cmd->forwardmove); + oldcmd.forwardmove = cmd->forwardmove; + ziptic |= ZT_FWD; + } + + if (cmd->sidemove != oldcmd.sidemove) + { + WRITEUINT8(demo_p,cmd->sidemove); + oldcmd.sidemove = cmd->sidemove; + ziptic |= ZT_SIDE; + } + + if (cmd->angleturn != oldcmd.angleturn) + { + WRITEINT16(demo_p,cmd->angleturn); + oldcmd.angleturn = cmd->angleturn; + ziptic |= ZT_ANGLE; + } + + if (cmd->buttons != oldcmd.buttons) + { + WRITEUINT16(demo_p,cmd->buttons); + oldcmd.buttons = cmd->buttons; + ziptic |= ZT_BUTTONS; + } + + if (cmd->aiming != oldcmd.aiming) + { + WRITEINT16(demo_p,cmd->aiming); + oldcmd.aiming = cmd->aiming; + ziptic |= ZT_AIMING; + } + + *ziptic_p = ziptic; + + // attention here for the ticcmd size! + // latest demos with mouse aiming byte in ticcmd + if (!(demoflags & DF_GHOST) && ziptic_p > demoend - 9) + { + G_CheckDemoStatus(); // no more space + return; + } +} + +void G_GhostAddThok(void) +{ + if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) + return; + ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_THOK; +} + +void G_GhostAddSpin(void) +{ + if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) + return; + ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_SPIN; +} + +void G_GhostAddRev(void) +{ + if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) + return; + ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_REV; +} + +void G_GhostAddFlip(void) +{ + if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) + return; + ghostext.flags |= EZT_FLIP; +} + +void G_GhostAddColor(ghostcolor_t color) +{ + if (!demorecording || !(demoflags & DF_GHOST)) + return; + if (ghostext.lastcolor == (UINT8)color) + { + ghostext.flags &= ~EZT_COLOR; + return; + } + ghostext.flags |= EZT_COLOR; + ghostext.color = (UINT8)color; +} + +void G_GhostAddScale(fixed_t scale) +{ + if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) + return; + if (ghostext.lastscale == scale) + { + ghostext.flags &= ~EZT_SCALE; + return; + } + ghostext.flags |= EZT_SCALE; + ghostext.scale = scale; +} + +void G_GhostAddHit(mobj_t *victim) +{ + if (!demorecording || !(demoflags & DF_GHOST)) + return; + ghostext.flags |= EZT_HIT; + ghostext.hits++; + ghostext.hitlist = Z_Realloc(ghostext.hitlist, ghostext.hits * sizeof(mobj_t *), PU_LEVEL, NULL); + ghostext.hitlist[ghostext.hits-1] = victim; +} + +void G_WriteGhostTic(mobj_t *ghost) +{ + char ziptic = 0; + UINT8 *ziptic_p; + UINT32 i; + fixed_t height; + + if (!demo_p) + return; + if (!(demoflags & DF_GHOST)) + return; // No ghost data to write. + + ziptic_p = demo_p++; // the ziptic, written at the end of this function + + #define MAXMOM (0xFFFF<<8) + + // GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic. + if (abs(ghost->x-oldghost.x) > MAXMOM + || abs(ghost->y-oldghost.y) > MAXMOM + || abs(ghost->z-oldghost.z) > MAXMOM) + { + oldghost.x = ghost->x; + oldghost.y = ghost->y; + oldghost.z = ghost->z; + ziptic |= GZT_XYZ; + WRITEFIXED(demo_p,oldghost.x); + WRITEFIXED(demo_p,oldghost.y); + WRITEFIXED(demo_p,oldghost.z); + } + else + { + // For moving normally: + // Store one full byte of movement, plus one byte of fractional movement. + INT16 momx = (INT16)((ghost->x-oldghost.x)>>8); + INT16 momy = (INT16)((ghost->y-oldghost.y)>>8); + if (momx != oldghost.momx + || momy != oldghost.momy) + { + oldghost.momx = momx; + oldghost.momy = momy; + ziptic |= GZT_MOMXY; + WRITEINT16(demo_p,momx); + WRITEINT16(demo_p,momy); + } + momx = (INT16)((ghost->z-oldghost.z)>>8); + if (momx != oldghost.momz) + { + oldghost.momz = momx; + ziptic |= GZT_MOMZ; + WRITEINT16(demo_p,momx); + } + + // This SHOULD set oldghost.x/y/z to match ghost->x/y/z + // but it keeps the fractional loss of one byte, + // so it will hopefully be made up for in future tics. + oldghost.x += oldghost.momx<<8; + oldghost.y += oldghost.momy<<8; + oldghost.z += oldghost.momz<<8; + } + + #undef MAXMOM + + // Only store the 8 most relevant bits of angle + // because exact values aren't too easy to discern to begin with when only 8 angles have different sprites + // and it does not affect this mode of movement at all anyway. + if (ghost->player && ghost->player->drawangle>>24 != oldghost.angle) + { + oldghost.angle = ghost->player->drawangle>>24; + ziptic |= GZT_ANGLE; + WRITEUINT8(demo_p,oldghost.angle); + } + + // Store the sprite frame. + if ((ghost->frame & FF_FRAMEMASK) != oldghost.frame) + { + oldghost.frame = (ghost->frame & FF_FRAMEMASK); + ziptic |= GZT_FRAME; + WRITEUINT8(demo_p,oldghost.frame); + } + + if (ghost->sprite == SPR_PLAY + && ghost->sprite2 != oldghost.sprite2) + { + oldghost.sprite2 = ghost->sprite2; + ziptic |= GZT_SPR2; + WRITEUINT8(demo_p,oldghost.sprite2); + } + + // Check for sprite set changes + if (ghost->sprite != oldghost.sprite) + { + oldghost.sprite = ghost->sprite; + ghostext.flags |= EZT_SPRITE; + } + + if ((height = FixedDiv(ghost->height, ghost->scale)) != oldghost.height) + { + oldghost.height = height; + ghostext.flags |= EZT_HEIGHT; + } + + if (ghostext.flags) + { + ziptic |= GZT_EXTRA; + + if (ghostext.color == ghostext.lastcolor) + ghostext.flags &= ~EZT_COLOR; + if (ghostext.scale == ghostext.lastscale) + ghostext.flags &= ~EZT_SCALE; + + WRITEUINT8(demo_p,ghostext.flags); + if (ghostext.flags & EZT_COLOR) + { + WRITEUINT8(demo_p,ghostext.color); + ghostext.lastcolor = ghostext.color; + } + if (ghostext.flags & EZT_SCALE) + { + WRITEFIXED(demo_p,ghostext.scale); + ghostext.lastscale = ghostext.scale; + } + if (ghostext.flags & EZT_HIT) + { + WRITEUINT16(demo_p,ghostext.hits); + for (i = 0; i < ghostext.hits; i++) + { + mobj_t *mo = ghostext.hitlist[i]; + //WRITEUINT32(demo_p,UINT32_MAX); // reserved for some method of determining exactly which mobj this is. (mobjnum doesn't work here.) + WRITEUINT32(demo_p,mo->type); + WRITEUINT16(demo_p,(UINT16)mo->health); + WRITEFIXED(demo_p,mo->x); + WRITEFIXED(demo_p,mo->y); + WRITEFIXED(demo_p,mo->z); + WRITEANGLE(demo_p,mo->angle); + } + Z_Free(ghostext.hitlist); + ghostext.hits = 0; + ghostext.hitlist = NULL; + } + if (ghostext.flags & EZT_SPRITE) + WRITEUINT16(demo_p,oldghost.sprite); + if (ghostext.flags & EZT_HEIGHT) + { + height >>= FRACBITS; + WRITEINT16(demo_p, height); + } + ghostext.flags = 0; + } + + if (ghost->player && ghost->player->followmobj && !(ghost->player->followmobj->sprite == SPR_NULL || (ghost->player->followmobj->flags2 & MF2_DONTDRAW))) // bloats tails runs but what can ya do + { + INT16 temp; + UINT8 *followtic_p = demo_p++; + UINT8 followtic = 0; + + ziptic |= GZT_FOLLOW; + + if (ghost->player->followmobj->skin) + followtic |= FZT_SKIN; + + if (!(oldghost.flags2 & MF2_AMBUSH)) + { + followtic |= FZT_SPAWNED; + WRITEINT16(demo_p,ghost->player->followmobj->info->height>>FRACBITS); + if (ghost->player->followmobj->flags2 & MF2_LINKDRAW) + followtic |= FZT_LINKDRAW; + if (ghost->player->followmobj->colorized) + followtic |= FZT_COLORIZED; + if (followtic & FZT_SKIN) + WRITEUINT8(demo_p,(UINT8)(((skin_t *)(ghost->player->followmobj->skin))-skins)); + oldghost.flags2 |= MF2_AMBUSH; + } + + if (ghost->player->followmobj->scale != ghost->scale) + { + followtic |= FZT_SCALE; + WRITEFIXED(demo_p,ghost->player->followmobj->scale); + } + + temp = (INT16)((ghost->player->followmobj->x-ghost->x)>>8); + WRITEINT16(demo_p,temp); + temp = (INT16)((ghost->player->followmobj->y-ghost->y)>>8); + WRITEINT16(demo_p,temp); + temp = (INT16)((ghost->player->followmobj->z-ghost->z)>>8); + WRITEINT16(demo_p,temp); + if (followtic & FZT_SKIN) + WRITEUINT8(demo_p,ghost->player->followmobj->sprite2); + WRITEUINT16(demo_p,ghost->player->followmobj->sprite); + WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK)); + WRITEUINT8(demo_p,ghost->player->followmobj->color); + + *followtic_p = followtic; + } + else + oldghost.flags2 &= ~MF2_AMBUSH; + + *ziptic_p = ziptic; + + // attention here for the ticcmd size! + // latest demos with mouse aiming byte in ticcmd + if (demo_p >= demoend - (13 + 9 + 9)) + { + G_CheckDemoStatus(); // no more space + return; + } +} + +// Uses ghost data to do consistency checks on your position. +// This fixes desynchronising demos when fighting eggman. +void G_ConsGhostTic(void) +{ + UINT8 ziptic; + UINT16 px,py,pz,gx,gy,gz; + mobj_t *testmo; + + if (!demo_p || !demo_start) + return; + if (!(demoflags & DF_GHOST)) + return; // No ghost data to use. + + testmo = players[0].mo; + + // Grab ghost data. + ziptic = READUINT8(demo_p); + if (ziptic & GZT_XYZ) + { + oldghost.x = READFIXED(demo_p); + oldghost.y = READFIXED(demo_p); + oldghost.z = READFIXED(demo_p); + } + else + { + if (ziptic & GZT_MOMXY) + { + oldghost.momx = READINT16(demo_p)<<8; + oldghost.momy = READINT16(demo_p)<<8; + } + if (ziptic & GZT_MOMZ) + oldghost.momz = READINT16(demo_p)<<8; + oldghost.x += oldghost.momx; + oldghost.y += oldghost.momy; + oldghost.z += oldghost.momz; + } + if (ziptic & GZT_ANGLE) + demo_p++; + if (ziptic & GZT_FRAME) + demo_p++; + if (ziptic & GZT_SPR2) + demo_p++; + + if (ziptic & GZT_EXTRA) + { // But wait, there's more! + UINT8 xziptic = READUINT8(demo_p); + if (xziptic & EZT_COLOR) + demo_p++; + if (xziptic & EZT_SCALE) + demo_p += sizeof(fixed_t); + if (xziptic & EZT_HIT) + { // Resync mob damage. + UINT16 i, count = READUINT16(demo_p); + thinker_t *th; + mobj_t *mobj; + + UINT32 type; + UINT16 health; + fixed_t x; + fixed_t y; + fixed_t z; + + for (i = 0; i < count; i++) + { + //demo_p += 4; // reserved. + type = READUINT32(demo_p); + health = READUINT16(demo_p); + x = READFIXED(demo_p); + y = READFIXED(demo_p); + z = READFIXED(demo_p); + demo_p += sizeof(angle_t); // angle, unnecessary for cons. + + mobj = NULL; + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + mobj = (mobj_t *)th; + if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z) + break; + } + if (th != &thlist[THINK_MOBJ] && mobj->health != health) // Wasn't damaged?! This is desync! Fix it! + { + if (demosynced) + CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); + demosynced = false; + P_DamageMobj(mobj, players[0].mo, players[0].mo, 1, 0); + } + } + } + if (xziptic & EZT_SPRITE) + demo_p += sizeof(UINT16); + if (xziptic & EZT_HEIGHT) + demo_p += sizeof(INT16); + } + + if (ziptic & GZT_FOLLOW) + { // Even more... + UINT8 followtic = READUINT8(demo_p); + if (followtic & FZT_SPAWNED) + { + demo_p += sizeof(INT16); + if (followtic & FZT_SKIN) + demo_p++; + } + if (followtic & FZT_SCALE) + demo_p += sizeof(fixed_t); + demo_p += sizeof(INT16); + demo_p += sizeof(INT16); + demo_p += sizeof(INT16); + if (followtic & FZT_SKIN) + demo_p++; + demo_p += sizeof(UINT16); + demo_p++; + demo_p++; + } + + // Re-synchronise + px = testmo->x>>FRACBITS; + py = testmo->y>>FRACBITS; + pz = testmo->z>>FRACBITS; + gx = oldghost.x>>FRACBITS; + gy = oldghost.y>>FRACBITS; + gz = oldghost.z>>FRACBITS; + + if (px != gx || py != gy || pz != gz) + { + if (demosynced) + 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 (*demo_p == DEMOMARKER) + { + // end of demo data stream + G_CheckDemoStatus(); + return; + } +} + +void G_GhostTicker(void) +{ + demoghost *g,*p; + for(g = ghosts, p = NULL; g; g = g->next) + { + // Skip normal demo data. + UINT8 ziptic = READUINT8(g->p); + UINT8 xziptic = 0; + if (ziptic & ZT_FWD) + g->p++; + if (ziptic & ZT_SIDE) + g->p++; + if (ziptic & ZT_ANGLE) + g->p += 2; + if (ziptic & ZT_BUTTONS) + g->p += 2; + if (ziptic & ZT_AIMING) + g->p += 2; + + // Grab ghost data. + ziptic = READUINT8(g->p); + if (ziptic & GZT_XYZ) + { + g->oldmo.x = READFIXED(g->p); + g->oldmo.y = READFIXED(g->p); + g->oldmo.z = READFIXED(g->p); + } + else + { + if (ziptic & GZT_MOMXY) + { + g->oldmo.momx = READINT16(g->p)<<8; + g->oldmo.momy = READINT16(g->p)<<8; + } + if (ziptic & GZT_MOMZ) + g->oldmo.momz = READINT16(g->p)<<8; + g->oldmo.x += g->oldmo.momx; + g->oldmo.y += g->oldmo.momy; + g->oldmo.z += g->oldmo.momz; + } + if (ziptic & GZT_ANGLE) + g->mo->angle = READUINT8(g->p)<<24; + if (ziptic & GZT_FRAME) + g->oldmo.frame = READUINT8(g->p); + if (ziptic & GZT_SPR2) + g->oldmo.sprite2 = READUINT8(g->p); + + // Update ghost + P_UnsetThingPosition(g->mo); + g->mo->x = g->oldmo.x; + g->mo->y = g->oldmo.y; + g->mo->z = g->oldmo.z; + P_SetThingPosition(g->mo); + g->mo->frame = g->oldmo.frame | tr_trans30<fadein) + { + g->mo->frame += (((--g->fadein)/6)<fadein is bad, and it's only set once, so... + g->mo->flags2 &= ~MF2_DONTDRAW; + } + g->mo->sprite2 = g->oldmo.sprite2; + + if (ziptic & GZT_EXTRA) + { // But wait, there's more! + xziptic = READUINT8(g->p); + if (xziptic & EZT_COLOR) + { + g->color = READUINT8(g->p); + switch(g->color) + { + default: + case GHC_RETURNSKIN: + g->mo->skin = g->oldmo.skin; + /* FALLTHRU */ + case GHC_NORMAL: // Go back to skin color + g->mo->color = g->oldmo.color; + break; + // Handled below + case GHC_SUPER: + case GHC_INVINCIBLE: + break; + case GHC_FIREFLOWER: // Fireflower + g->mo->color = SKINCOLOR_WHITE; + break; + case GHC_NIGHTSSKIN: // not actually a colour + g->mo->skin = &skins[DEFAULTNIGHTSSKIN]; + break; + } + } + if (xziptic & EZT_FLIP) + g->mo->eflags ^= MFE_VERTICALFLIP; + if (xziptic & EZT_SCALE) + { + g->mo->destscale = READFIXED(g->p); + if (g->mo->destscale != g->mo->scale) + P_SetScale(g->mo, g->mo->destscale); + } + if (xziptic & EZT_THOKMASK) + { // Let's only spawn ONE of these per frame, thanks. + mobj_t *mobj; + INT32 type = -1; + if (g->mo->skin) + { + skin_t *skin = (skin_t *)g->mo->skin; + switch (xziptic & EZT_THOKMASK) + { + case EZT_THOK: + type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; + break; + case EZT_SPIN: + type = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; + break; + case EZT_REV: + type = skin->revitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; + break; + } + } + if (type != MT_NULL) + { + if (type == MT_GHOST) + { + mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us + mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<mo, 0, 0, -FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK); + mobj->sprite = states[mobjinfo[type].spawnstate].sprite; + mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<color = g->mo->color; + mobj->skin = g->mo->skin; + P_SetScale(mobj, (mobj->destscale = g->mo->scale)); + + if (type == MT_THOK) // spintrail-specific modification for MT_THOK + { + mobj->frame = FF_TRANS80; + mobj->fuse = mobj->tics; + } + mobj->tics = -1; // nope. + } + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_UnsetThingPosition(mobj); + mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... + P_SetThingPosition(mobj); + if (!mobj->fuse) + mobj->fuse = 8; + P_SetTarget(&mobj->target, g->mo); + } + } + if (xziptic & EZT_HIT) + { // Spawn hit poofs for killing things! + UINT16 i, count = READUINT16(g->p), health; + UINT32 type; + fixed_t x,y,z; + angle_t angle; + mobj_t *poof; + for (i = 0; i < count; i++) + { + //g->p += 4; // reserved + type = READUINT32(g->p); + health = READUINT16(g->p); + x = READFIXED(g->p); + y = READFIXED(g->p); + z = READFIXED(g->p); + angle = READANGLE(g->p); + if (!(mobjinfo[type].flags & MF_SHOOTABLE) + || !(mobjinfo[type].flags & (MF_ENEMY|MF_MONITOR)) + || health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad. + continue; + poof = P_SpawnMobj(x, y, z, MT_GHOST); + poof->angle = angle; + poof->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... + poof->health = 0; + P_SetMobjStateNF(poof, S_XPLD1); + } + } + if (xziptic & EZT_SPRITE) + g->mo->sprite = READUINT16(g->p); + if (xziptic & EZT_HEIGHT) + { + fixed_t temp = READINT16(g->p)<mo->height = FixedMul(temp, g->mo->scale); + } + } + + // Tick ghost colors (Super and Mario Invincibility flashing) + switch(g->color) + { + case GHC_SUPER: // Super (P_DoSuperStuff) + if (g->mo->skin) + { + skin_t *skin = (skin_t *)g->mo->skin; + g->mo->color = skin->supercolor; + } + else + g->mo->color = SKINCOLOR_SUPERGOLD1; + g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); + break; + case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) + g->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours + break; + default: + break; + } + +#define follow g->mo->tracer + if (ziptic & GZT_FOLLOW) + { // Even more... + UINT8 followtic = READUINT8(g->p); + fixed_t temp; + if (followtic & FZT_SPAWNED) + { + if (follow) + P_RemoveMobj(follow); + P_SetTarget(&follow, P_SpawnMobjFromMobj(g->mo, 0, 0, 0, MT_GHOST)); + P_SetTarget(&follow->tracer, g->mo); + follow->tics = -1; + temp = READINT16(g->p)<height = FixedMul(follow->scale, temp); + + if (followtic & FZT_LINKDRAW) + follow->flags2 |= MF2_LINKDRAW; + + if (followtic & FZT_COLORIZED) + follow->colorized = true; + + if (followtic & FZT_SKIN) + follow->skin = &skins[READUINT8(g->p)]; + } + if (follow) + { + if (followtic & FZT_SCALE) + follow->destscale = READFIXED(g->p); + else + follow->destscale = g->mo->destscale; + if (follow->destscale != follow->scale) + P_SetScale(follow, follow->destscale); + + P_UnsetThingPosition(follow); + temp = READINT16(g->p)<<8; + follow->x = g->mo->x + temp; + temp = READINT16(g->p)<<8; + follow->y = g->mo->y + temp; + temp = READINT16(g->p)<<8; + follow->z = g->mo->z + temp; + P_SetThingPosition(follow); + if (followtic & FZT_SKIN) + follow->sprite2 = READUINT8(g->p); + else + follow->sprite2 = 0; + follow->sprite = READUINT16(g->p); + follow->frame = (READUINT8(g->p)) | (g->mo->frame & FF_TRANSMASK); + follow->angle = g->mo->angle; + follow->color = READUINT8(g->p); + + if (!(followtic & FZT_SPAWNED)) + { + if (xziptic & EZT_FLIP) + { + follow->flags2 ^= MF2_OBJECTFLIP; + follow->eflags ^= MFE_VERTICALFLIP; + } + } + } + } + else if (follow) + { + P_RemoveMobj(follow); + P_SetTarget(&follow, NULL); + } + // Demo ends after ghost data. + if (*g->p == DEMOMARKER) + { + g->mo->momx = g->mo->momy = g->mo->momz = 0; +#if 1 // freeze frame (maybe more useful for time attackers) + g->mo->colorized = true; + if (follow) + follow->colorized = true; +#else // dissapearing act + g->mo->fuse = TICRATE; + if (follow) + follow->fuse = TICRATE; +#endif + if (p) + p->next = g->next; + else + ghosts = g->next; + Z_Free(g); + continue; + } + p = g; +#undef follow + } +} + +void G_ReadMetalTic(mobj_t *metal) +{ + UINT8 ziptic; + UINT8 xziptic = 0; + + if (!metal_p) + return; + + if (!metal->health) + { + G_StopMetalDemo(); + return; + } + + switch (*metal_p) + { + case METALSNICE: + break; + case METALDEATH: + if (metal->tracer) + P_RemoveMobj(metal->tracer); + P_KillMobj(metal, NULL, NULL, 0); + /* FALLTHRU */ + case DEMOMARKER: + default: + // end of demo data stream + G_StopMetalDemo(); + return; + } + metal_p++; + + ziptic = READUINT8(metal_p); + + // Read changes from the tic + if (ziptic & GZT_XYZ) + { + P_TeleportMove(metal, READFIXED(metal_p), READFIXED(metal_p), READFIXED(metal_p)); + oldmetal.x = metal->x; + oldmetal.y = metal->y; + oldmetal.z = metal->z; + } + else + { + if (ziptic & GZT_MOMXY) + { + oldmetal.momx = READINT16(metal_p)<<8; + oldmetal.momy = READINT16(metal_p)<<8; + } + if (ziptic & GZT_MOMZ) + oldmetal.momz = READINT16(metal_p)<<8; + oldmetal.x += oldmetal.momx; + oldmetal.y += oldmetal.momy; + oldmetal.z += oldmetal.momz; + } + if (ziptic & GZT_ANGLE) + metal->angle = READUINT8(metal_p)<<24; + if (ziptic & GZT_FRAME) + oldmetal.frame = READUINT32(metal_p); + if (ziptic & GZT_SPR2) + oldmetal.sprite2 = READUINT8(metal_p); + + // Set movement, position, and angle + // oldmetal contains where you're supposed to be. + metal->momx = oldmetal.momx; + metal->momy = oldmetal.momy; + metal->momz = oldmetal.momz; + P_UnsetThingPosition(metal); + metal->x = oldmetal.x; + metal->y = oldmetal.y; + metal->z = oldmetal.z; + P_SetThingPosition(metal); + metal->frame = oldmetal.frame; + metal->sprite2 = oldmetal.sprite2; + + if (ziptic & GZT_EXTRA) + { // But wait, there's more! + xziptic = READUINT8(metal_p); + if (xziptic & EZT_FLIP) + { + metal->eflags ^= MFE_VERTICALFLIP; + metal->flags2 ^= MF2_OBJECTFLIP; + } + if (xziptic & EZT_SCALE) + { + metal->destscale = READFIXED(metal_p); + if (metal->destscale != metal->scale) + P_SetScale(metal, metal->destscale); + } + if (xziptic & EZT_THOKMASK) + { // Let's only spawn ONE of these per frame, thanks. + mobj_t *mobj; + INT32 type = -1; + if (metal->skin) + { + skin_t *skin = (skin_t *)metal->skin; + switch (xziptic & EZT_THOKMASK) + { + case EZT_THOK: + type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; + break; + case EZT_SPIN: + type = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; + break; + case EZT_REV: + type = skin->revitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; + break; + } + } + if (type != MT_NULL) + { + if (type == MT_GHOST) + { + mobj = P_SpawnGhostMobj(metal); // does a large portion of the work for us + } + else + { + mobj = P_SpawnMobjFromMobj(metal, 0, 0, -FixedDiv(FixedMul(metal->info->height, metal->scale) - metal->height,3*FRACUNIT), MT_THOK); + mobj->sprite = states[mobjinfo[type].spawnstate].sprite; + mobj->frame = states[mobjinfo[type].spawnstate].frame; + mobj->angle = metal->angle; + mobj->color = metal->color; + mobj->skin = metal->skin; + P_SetScale(mobj, (mobj->destscale = metal->scale)); + + if (type == MT_THOK) // spintrail-specific modification for MT_THOK + { + mobj->frame = FF_TRANS70; + mobj->fuse = mobj->tics; + } + mobj->tics = -1; // nope. + } + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z+mobj->height; + P_UnsetThingPosition(mobj); + mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... + P_SetThingPosition(mobj); + if (!mobj->fuse) + mobj->fuse = 8; + P_SetTarget(&mobj->target, metal); + } + } + if (xziptic & EZT_SPRITE) + metal->sprite = READUINT16(metal_p); + if (xziptic & EZT_HEIGHT) + { + fixed_t temp = READINT16(metal_p)<height = FixedMul(temp, metal->scale); + } + } + +#define follow metal->tracer + if (ziptic & GZT_FOLLOW) + { // Even more... + UINT8 followtic = READUINT8(metal_p); + fixed_t temp; + if (followtic & FZT_SPAWNED) + { + if (follow) + P_RemoveMobj(follow); + P_SetTarget(&follow, P_SpawnMobjFromMobj(metal, 0, 0, 0, MT_GHOST)); + P_SetTarget(&follow->tracer, metal); + follow->tics = -1; + temp = READINT16(metal_p)<height = FixedMul(follow->scale, temp); + + if (followtic & FZT_LINKDRAW) + follow->flags2 |= MF2_LINKDRAW; + + if (followtic & FZT_COLORIZED) + follow->colorized = true; + + if (followtic & FZT_SKIN) + follow->skin = &skins[READUINT8(metal_p)]; + } + if (follow) + { + if (followtic & FZT_SCALE) + follow->destscale = READFIXED(metal_p); + else + follow->destscale = metal->destscale; + if (follow->destscale != follow->scale) + P_SetScale(follow, follow->destscale); + + P_UnsetThingPosition(follow); + temp = READINT16(metal_p)<<8; + follow->x = metal->x + temp; + temp = READINT16(metal_p)<<8; + follow->y = metal->y + temp; + temp = READINT16(metal_p)<<8; + follow->z = metal->z + temp; + P_SetThingPosition(follow); + if (followtic & FZT_SKIN) + follow->sprite2 = READUINT8(metal_p); + else + follow->sprite2 = 0; + follow->sprite = READUINT16(metal_p); + follow->frame = READUINT32(metal_p); // NOT & FF_FRAMEMASK here, so 32 bits + follow->angle = metal->angle; + follow->color = READUINT8(metal_p); + + if (!(followtic & FZT_SPAWNED)) + { + if (xziptic & EZT_FLIP) + { + follow->flags2 ^= MF2_OBJECTFLIP; + follow->eflags ^= MFE_VERTICALFLIP; + } + } + } + } + else if (follow) + { + P_RemoveMobj(follow); + P_SetTarget(&follow, NULL); + } +#undef follow +} + +void G_WriteMetalTic(mobj_t *metal) +{ + UINT8 ziptic = 0; + UINT8 *ziptic_p; + fixed_t height; + + if (!demo_p) // demo_p will be NULL until the race start linedef executor is activated! + return; + + WRITEUINT8(demo_p, METALSNICE); + ziptic_p = demo_p++; // the ziptic, written at the end of this function + + #define MAXMOM (0xFFFF<<8) + + // GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic. + if (abs(metal->x-oldmetal.x) > MAXMOM + || abs(metal->y-oldmetal.y) > MAXMOM + || abs(metal->z-oldmetal.z) > MAXMOM) + { + oldmetal.x = metal->x; + oldmetal.y = metal->y; + oldmetal.z = metal->z; + ziptic |= GZT_XYZ; + WRITEFIXED(demo_p,oldmetal.x); + WRITEFIXED(demo_p,oldmetal.y); + WRITEFIXED(demo_p,oldmetal.z); + } + else + { + // For moving normally: + // Store one full byte of movement, plus one byte of fractional movement. + INT16 momx = (INT16)((metal->x-oldmetal.x)>>8); + INT16 momy = (INT16)((metal->y-oldmetal.y)>>8); + if (momx != oldmetal.momx + || momy != oldmetal.momy) + { + oldmetal.momx = momx; + oldmetal.momy = momy; + ziptic |= GZT_MOMXY; + WRITEINT16(demo_p,momx); + WRITEINT16(demo_p,momy); + } + momx = (INT16)((metal->z-oldmetal.z)>>8); + if (momx != oldmetal.momz) + { + oldmetal.momz = momx; + ziptic |= GZT_MOMZ; + WRITEINT16(demo_p,momx); + } + + // This SHOULD set oldmetal.x/y/z to match metal->x/y/z + // but it keeps the fractional loss of one byte, + // so it will hopefully be made up for in future tics. + oldmetal.x += oldmetal.momx<<8; + oldmetal.y += oldmetal.momy<<8; + oldmetal.z += oldmetal.momz<<8; + } + + #undef MAXMOM + + // Only store the 8 most relevant bits of angle + // because exact values aren't too easy to discern to begin with when only 8 angles have different sprites + // and it does not affect movement at all anyway. + if (metal->player && metal->player->drawangle>>24 != oldmetal.angle) + { + oldmetal.angle = metal->player->drawangle>>24; + ziptic |= GZT_ANGLE; + WRITEUINT8(demo_p,oldmetal.angle); + } + + // Store the sprite frame. + if ((metal->frame & FF_FRAMEMASK) != oldmetal.frame) + { + oldmetal.frame = metal->frame; // NOT & FF_FRAMEMASK here, so 32 bits + ziptic |= GZT_FRAME; + WRITEUINT32(demo_p,oldmetal.frame); + } + + if (metal->sprite == SPR_PLAY + && metal->sprite2 != oldmetal.sprite2) + { + oldmetal.sprite2 = metal->sprite2; + ziptic |= GZT_SPR2; + WRITEUINT8(demo_p,oldmetal.sprite2); + } + + // Check for sprite set changes + if (metal->sprite != oldmetal.sprite) + { + oldmetal.sprite = metal->sprite; + ghostext.flags |= EZT_SPRITE; + } + + if ((height = FixedDiv(metal->height, metal->scale)) != oldmetal.height) + { + oldmetal.height = height; + ghostext.flags |= EZT_HEIGHT; + } + + if (ghostext.flags & ~(EZT_COLOR|EZT_HIT)) // these two aren't handled by metal ever + { + ziptic |= GZT_EXTRA; + + if (ghostext.scale == ghostext.lastscale) + ghostext.flags &= ~EZT_SCALE; + + WRITEUINT8(demo_p,ghostext.flags); + if (ghostext.flags & EZT_SCALE) + { + WRITEFIXED(demo_p,ghostext.scale); + ghostext.lastscale = ghostext.scale; + } + if (ghostext.flags & EZT_SPRITE) + WRITEUINT16(demo_p,oldmetal.sprite); + if (ghostext.flags & EZT_HEIGHT) + { + height >>= FRACBITS; + WRITEINT16(demo_p, height); + } + ghostext.flags = 0; + } + + if (metal->player && metal->player->followmobj && !(metal->player->followmobj->sprite == SPR_NULL || (metal->player->followmobj->flags2 & MF2_DONTDRAW))) + { + INT16 temp; + UINT8 *followtic_p = demo_p++; + UINT8 followtic = 0; + + ziptic |= GZT_FOLLOW; + + if (metal->player->followmobj->skin) + followtic |= FZT_SKIN; + + if (!(oldmetal.flags2 & MF2_AMBUSH)) + { + followtic |= FZT_SPAWNED; + WRITEINT16(demo_p,metal->player->followmobj->info->height>>FRACBITS); + if (metal->player->followmobj->flags2 & MF2_LINKDRAW) + followtic |= FZT_LINKDRAW; + if (metal->player->followmobj->colorized) + followtic |= FZT_COLORIZED; + if (followtic & FZT_SKIN) + WRITEUINT8(demo_p,(UINT8)(((skin_t *)(metal->player->followmobj->skin))-skins)); + oldmetal.flags2 |= MF2_AMBUSH; + } + + if (metal->player->followmobj->scale != metal->scale) + { + followtic |= FZT_SCALE; + WRITEFIXED(demo_p,metal->player->followmobj->scale); + } + + temp = (INT16)((metal->player->followmobj->x-metal->x)>>8); + WRITEINT16(demo_p,temp); + temp = (INT16)((metal->player->followmobj->y-metal->y)>>8); + WRITEINT16(demo_p,temp); + temp = (INT16)((metal->player->followmobj->z-metal->z)>>8); + WRITEINT16(demo_p,temp); + if (followtic & FZT_SKIN) + WRITEUINT8(demo_p,metal->player->followmobj->sprite2); + WRITEUINT16(demo_p,metal->player->followmobj->sprite); + WRITEUINT32(demo_p,metal->player->followmobj->frame); // NOT & FF_FRAMEMASK here, so 32 bits + WRITEUINT8(demo_p,metal->player->followmobj->color); + + *followtic_p = followtic; + } + else + oldmetal.flags2 &= ~MF2_AMBUSH; + + *ziptic_p = ziptic; + + // attention here for the ticcmd size! + // latest demos with mouse aiming byte in ticcmd + if (demo_p >= demoend - 32) + { + G_StopMetalRecording(false); // no more space + return; + } +} + +// +// G_RecordDemo +// +void G_RecordDemo(const char *name) +{ + INT32 maxsize; + + strcpy(demoname, name); + strcat(demoname, ".lmp"); + maxsize = 1024*1024; + if (M_CheckParm("-maxdemo") && M_IsNextParm()) + maxsize = atoi(M_GetNextParm()) * 1024; +// if (demobuffer) +// free(demobuffer); + demo_p = NULL; + demobuffer = malloc(maxsize); + demoend = demobuffer + maxsize; + + demorecording = true; +} + +void G_RecordMetal(void) +{ + INT32 maxsize; + maxsize = 1024*1024; + if (M_CheckParm("-maxdemo") && M_IsNextParm()) + maxsize = atoi(M_GetNextParm()) * 1024; + demo_p = NULL; + demobuffer = malloc(maxsize); + demoend = demobuffer + maxsize; + metalrecording = true; +} + +void G_BeginRecording(void) +{ + UINT8 i; + char name[16]; + player_t *player = &players[consoleplayer]; + + if (demo_p) + return; + memset(name,0,sizeof(name)); + + demo_p = demobuffer; + demoflags = DF_GHOST|(modeattacking<>DF_ATTACKSHIFT) + { + case ATTACKING_NONE: // 0 + break; + case ATTACKING_RECORD: // 1 + demotime_p = demo_p; + WRITEUINT32(demo_p,UINT32_MAX); // time + WRITEUINT32(demo_p,0); // score + WRITEUINT16(demo_p,0); // rings + break; + case ATTACKING_NIGHTS: // 2 + demotime_p = demo_p; + WRITEUINT32(demo_p,UINT32_MAX); // time + WRITEUINT32(demo_p,0); // score + break; + default: // 3 + break; + } + + WRITEUINT32(demo_p,P_GetInitSeed()); + + // Name + for (i = 0; i < 16 && cv_playername.string[i]; i++) + name[i] = cv_playername.string[i]; + for (; i < 16; i++) + name[i] = '\0'; + M_Memcpy(demo_p,name,16); + demo_p += 16; + + // Skin + for (i = 0; i < 16 && cv_skin.string[i]; i++) + name[i] = cv_skin.string[i]; + for (; i < 16; i++) + name[i] = '\0'; + M_Memcpy(demo_p,name,16); + demo_p += 16; + + // Color + for (i = 0; i < 16 && cv_playercolor.string[i]; i++) + name[i] = cv_playercolor.string[i]; + for (; i < 16; i++) + name[i] = '\0'; + M_Memcpy(demo_p,name,16); + demo_p += 16; + + // Stats + WRITEUINT8(demo_p,player->charability); + WRITEUINT8(demo_p,player->charability2); + WRITEUINT8(demo_p,player->actionspd>>FRACBITS); + WRITEUINT8(demo_p,player->mindash>>FRACBITS); + WRITEUINT8(demo_p,player->maxdash>>FRACBITS); + WRITEUINT8(demo_p,player->normalspeed>>FRACBITS); + WRITEUINT8(demo_p,player->runspeed>>FRACBITS); + WRITEUINT8(demo_p,player->thrustfactor); + WRITEUINT8(demo_p,player->accelstart); + WRITEUINT8(demo_p,player->acceleration); + WRITEUINT8(demo_p,player->height>>FRACBITS); + WRITEUINT8(demo_p,player->spinheight>>FRACBITS); + WRITEUINT8(demo_p,player->camerascale>>FRACBITS); + WRITEUINT8(demo_p,player->shieldscale>>FRACBITS); + + // Trying to convert it back to % causes demo desync due to precision loss. + // Don't do it. + WRITEFIXED(demo_p, player->jumpfactor); + + // And mobjtype_t is best with UINT32 too... + WRITEUINT32(demo_p, player->followitem); + + // Save pflag data - see SendWeaponPref() + { + UINT8 buf = 0; + pflags_t pflags = 0; + if (cv_flipcam.value) + { + buf |= 0x01; + pflags |= PF_FLIPCAM; + } + if (cv_analog[0].value) + { + buf |= 0x02; + pflags |= PF_ANALOGMODE; + } + if (cv_directionchar[0].value) + { + buf |= 0x04; + pflags |= PF_DIRECTIONCHAR; + } + if (cv_autobrake.value) + { + buf |= 0x08; + pflags |= PF_AUTOBRAKE; + } + if (cv_usejoystick.value) + buf |= 0x10; + CV_SetValue(&cv_showinputjoy, !!(cv_usejoystick.value)); + + WRITEUINT8(demo_p,buf); + player->pflags = pflags; + } + + // Save netvar data + CV_SaveNetVars(&demo_p); + + memset(&oldcmd,0,sizeof(oldcmd)); + memset(&oldghost,0,sizeof(oldghost)); + memset(&ghostext,0,sizeof(ghostext)); + ghostext.lastcolor = ghostext.color = GHC_NORMAL; + ghostext.lastscale = ghostext.scale = FRACUNIT; + + if (player->mo) + { + oldghost.x = player->mo->x; + oldghost.y = player->mo->y; + oldghost.z = player->mo->z; + oldghost.angle = player->mo->angle>>24; + + // preticker started us gravity flipped + if (player->mo->eflags & MFE_VERTICALFLIP) + ghostext.flags |= EZT_FLIP; + } +} + +void G_BeginMetal(void) +{ + mobj_t *mo = players[consoleplayer].mo; + +#if 0 + if (demo_p) + return; +#endif + + demo_p = demobuffer; + + // Write header. + M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12; + WRITEUINT8(demo_p,VERSION); + WRITEUINT8(demo_p,SUBVERSION); + WRITEUINT16(demo_p,DEMOVERSION); + + // demo checksum + demo_p += 16; + + M_Memcpy(demo_p, "METL", 4); demo_p += 4; + + memset(&ghostext,0,sizeof(ghostext)); + ghostext.lastscale = ghostext.scale = FRACUNIT; + + // Set up our memory. + memset(&oldmetal,0,sizeof(oldmetal)); + oldmetal.x = mo->x; + oldmetal.y = mo->y; + oldmetal.z = mo->z; + oldmetal.angle = mo->angle>>24; +} + +void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings) +{ + if (!demorecording || !demotime_p) + return; + if (demoflags & DF_RECORDATTACK) + { + WRITEUINT32(demotime_p, ptime); + WRITEUINT32(demotime_p, pscore); + WRITEUINT16(demotime_p, prings); + demotime_p = NULL; + } + else if (demoflags & DF_NIGHTSATTACK) + { + WRITEUINT32(demotime_p, ptime); + WRITEUINT32(demotime_p, pscore); + demotime_p = NULL; + } +} + +// Returns bitfield: +// 1 == new demo has lower time +// 2 == new demo has higher score +// 4 == new demo has higher rings +UINT8 G_CmpDemoTime(char *oldname, char *newname) +{ + UINT8 *buffer,*p; + UINT8 flags; + UINT32 oldtime, newtime, oldscore, newscore; + UINT16 oldrings, newrings, oldversion; + size_t bufsize ATTRUNUSED; + UINT8 c; + UINT16 s ATTRUNUSED; + UINT8 aflags = 0; + + // load the new file + FIL_DefaultExtension(newname, ".lmp"); + bufsize = FIL_ReadFile(newname, &buffer); + I_Assert(bufsize != 0); + p = buffer; + + // read demo header + I_Assert(!memcmp(p, DEMOHEADER, 12)); + p += 12; // DEMOHEADER + c = READUINT8(p); // VERSION + I_Assert(c == VERSION); + c = READUINT8(p); // SUBVERSION + I_Assert(c == SUBVERSION); + s = READUINT16(p); + I_Assert(s == DEMOVERSION); + p += 16; // demo checksum + I_Assert(!memcmp(p, "PLAY", 4)); + p += 4; // PLAY + p += 2; // gamemap + p += 16; // map md5 + flags = READUINT8(p); // demoflags + + aflags = flags & (DF_RECORDATTACK|DF_NIGHTSATTACK); + I_Assert(aflags); + if (flags & DF_RECORDATTACK) + { + newtime = READUINT32(p); + newscore = READUINT32(p); + newrings = READUINT16(p); + } + else if (flags & DF_NIGHTSATTACK) + { + newtime = READUINT32(p); + newscore = READUINT32(p); + newrings = 0; + } + else // appease compiler + return 0; + + Z_Free(buffer); + + // load old file + FIL_DefaultExtension(oldname, ".lmp"); + if (!FIL_ReadFile(oldname, &buffer)) + { + CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), oldname); + return UINT8_MAX; + } + p = buffer; + + // read demo header + if (memcmp(p, DEMOHEADER, 12)) + { + CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname); + Z_Free(buffer); + return UINT8_MAX; + } p += 12; // DEMOHEADER + p++; // VERSION + p++; // SUBVERSION + oldversion = READUINT16(p); + switch(oldversion) // demoversion + { + case DEMOVERSION: // latest always supported + break; + // too old, cannot support. + default: + CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname); + Z_Free(buffer); + return UINT8_MAX; + } + p += 16; // demo checksum + if (memcmp(p, "PLAY", 4)) + { + CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname); + Z_Free(buffer); + return UINT8_MAX; + } p += 4; // "PLAY" + if (oldversion <= 0x0008) + p++; // gamemap + else + p += 2; // gamemap + p += 16; // mapmd5 + flags = READUINT8(p); + if (!(flags & aflags)) + { + CONS_Alert(CONS_NOTICE, M_GetText("File '%s' not from same game mode. It will be overwritten.\n"), oldname); + Z_Free(buffer); + return UINT8_MAX; + } + if (flags & DF_RECORDATTACK) + { + oldtime = READUINT32(p); + oldscore = READUINT32(p); + oldrings = READUINT16(p); + } + else if (flags & DF_NIGHTSATTACK) + { + oldtime = READUINT32(p); + oldscore = READUINT32(p); + oldrings = 0; + } + else // appease compiler + return UINT8_MAX; + + Z_Free(buffer); + + c = 0; + if (newtime < oldtime + || (newtime == oldtime && (newscore > oldscore || newrings > oldrings))) + c |= 1; // Better time + if (newscore > oldscore + || (newscore == oldscore && newtime < oldtime)) + c |= 1<<1; // Better score + if (newrings > oldrings + || (newrings == oldrings && newtime < oldtime)) + c |= 1<<2; // Better rings + return c; +} + +// +// G_PlayDemo +// +void G_DeferedPlayDemo(const char *name) +{ + COM_BufAddText("playdemo \""); + COM_BufAddText(name); + COM_BufAddText("\"\n"); +} + +// +// Start a demo from a .LMP file or from a wad resource +// +void G_DoPlayDemo(char *defdemoname) +{ + UINT8 i; + lumpnum_t l; + char skin[17],color[17],*n,*pdemoname; + UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration; + pflags_t pflags; + UINT32 randseed, followitem; + fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight; + char msg[1024]; + + skin[16] = '\0'; + color[16] = '\0'; + + n = defdemoname+strlen(defdemoname); + while (*n != '/' && *n != '\\' && n != defdemoname) + n--; + if (n != defdemoname) + n++; + pdemoname = ZZ_Alloc(strlen(n)+1); + strcpy(pdemoname,n); + + // Internal if no extension, external if one exists + if (FIL_CheckExtension(defdemoname)) + { + //FIL_DefaultExtension(defdemoname, ".lmp"); + if (!FIL_ReadFile(defdemoname, &demobuffer)) + { + snprintf(msg, 1024, M_GetText("Failed to read file '%s'.\n"), defdemoname); + CONS_Alert(CONS_ERROR, "%s", msg); + gameaction = ga_nothing; + M_StartMessage(msg, NULL, MM_NOTHING); + return; + } + demo_p = demobuffer; + } + // load demo resource from WAD + else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR) + { + snprintf(msg, 1024, M_GetText("Failed to read lump '%s'.\n"), defdemoname); + CONS_Alert(CONS_ERROR, "%s", msg); + gameaction = ga_nothing; + M_StartMessage(msg, NULL, MM_NOTHING); + return; + } + else // it's an internal demo + demobuffer = demo_p = W_CacheLumpNum(l, PU_STATIC); + + // read demo header + gameaction = ga_nothing; + demoplayback = true; + if (memcmp(demo_p, DEMOHEADER, 12)) + { + snprintf(msg, 1024, M_GetText("%s is not a SRB2 replay file.\n"), pdemoname); + CONS_Alert(CONS_ERROR, "%s", msg); + M_StartMessage(msg, NULL, MM_NOTHING); + Z_Free(pdemoname); + Z_Free(demobuffer); + demoplayback = false; + titledemo = false; + return; + } + demo_p += 12; // DEMOHEADER + + version = READUINT8(demo_p); + subversion = READUINT8(demo_p); + demoversion = READUINT16(demo_p); + switch(demoversion) + { + case DEMOVERSION: // latest always supported + break; + // too old, cannot support. + default: + snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname); + CONS_Alert(CONS_ERROR, "%s", msg); + M_StartMessage(msg, NULL, MM_NOTHING); + Z_Free(pdemoname); + Z_Free(demobuffer); + demoplayback = false; + titledemo = false; + return; + } + demo_p += 16; // demo checksum + if (memcmp(demo_p, "PLAY", 4)) + { + snprintf(msg, 1024, M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemoname); + CONS_Alert(CONS_ERROR, "%s", msg); + M_StartMessage(msg, NULL, MM_NOTHING); + Z_Free(pdemoname); + Z_Free(demobuffer); + demoplayback = false; + titledemo = false; + return; + } + demo_p += 4; // "PLAY" + gamemap = READINT16(demo_p); + demo_p += 16; // mapmd5 + + demoflags = READUINT8(demo_p); + modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT; + CON_ToggleOff(); + + hu_demoscore = 0; + hu_demotime = UINT32_MAX; + hu_demorings = 0; + + switch (modeattacking) + { + case ATTACKING_NONE: // 0 + break; + case ATTACKING_RECORD: // 1 + hu_demotime = READUINT32(demo_p); + hu_demoscore = READUINT32(demo_p); + hu_demorings = READUINT16(demo_p); + break; + case ATTACKING_NIGHTS: // 2 + hu_demotime = READUINT32(demo_p); + hu_demoscore = READUINT32(demo_p); + break; + default: // 3 + modeattacking = ATTACKING_NONE; + break; + } + + // Random seed + randseed = READUINT32(demo_p); + + // Player name + M_Memcpy(player_names[0],demo_p,16); + demo_p += 16; + + // Skin + M_Memcpy(skin,demo_p,16); + demo_p += 16; + + // Color + M_Memcpy(color,demo_p,16); + demo_p += 16; + + charability = READUINT8(demo_p); + charability2 = READUINT8(demo_p); + actionspd = (fixed_t)READUINT8(demo_p)<color = players[0].skincolor; + oldghost.x = players[0].mo->x; + oldghost.y = players[0].mo->y; + oldghost.z = players[0].mo->z; + } + + // Set saved attribute values + // No cheat checking here, because even if they ARE wrong... + // it would only break the replay if we clipped them. + players[0].camerascale = camerascale; + players[0].shieldscale = shieldscale; + players[0].charability = charability; + players[0].charability2 = charability2; + players[0].actionspd = actionspd; + players[0].mindash = mindash; + players[0].maxdash = maxdash; + players[0].normalspeed = normalspeed; + players[0].runspeed = runspeed; + players[0].thrustfactor = thrustfactor; + players[0].accelstart = accelstart; + players[0].acceleration = acceleration; + players[0].height = height; + players[0].spinheight = spinheight; + players[0].jumpfactor = jumpfactor; + players[0].followitem = followitem; + players[0].pflags = pflags; + + demo_start = true; +} + +void G_AddGhost(char *defdemoname) +{ + INT32 i; + lumpnum_t l; + char name[17],skin[17],color[17],*n,*pdemoname,md5[16]; + demoghost *gh; + UINT8 flags; + UINT8 *buffer,*p; + mapthing_t *mthing; + UINT16 count, ghostversion; + + name[16] = '\0'; + skin[16] = '\0'; + color[16] = '\0'; + + n = defdemoname+strlen(defdemoname); + while (*n != '/' && *n != '\\' && n != defdemoname) + n--; + if (n != defdemoname) + n++; + pdemoname = ZZ_Alloc(strlen(n)+1); + strcpy(pdemoname,n); + + // Internal if no extension, external if one exists + if (FIL_CheckExtension(defdemoname)) + { + //FIL_DefaultExtension(defdemoname, ".lmp"); + if (!FIL_ReadFileTag(defdemoname, &buffer, PU_LEVEL)) + { + CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), defdemoname); + Z_Free(pdemoname); + return; + } + p = buffer; + } + // load demo resource from WAD + else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR) + { + CONS_Alert(CONS_ERROR, M_GetText("Failed to read lump '%s'.\n"), defdemoname); + Z_Free(pdemoname); + return; + } + else // it's an internal demo + buffer = p = W_CacheLumpNum(l, PU_LEVEL); + + // read demo header + if (memcmp(p, DEMOHEADER, 12)) + { + CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Not a SRB2 replay.\n"), pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } p += 12; // DEMOHEADER + p++; // VERSION + p++; // SUBVERSION + ghostversion = READUINT16(p); + switch(ghostversion) + { + case DEMOVERSION: // latest always supported + break; + // too old, cannot support. + default: + CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } + M_Memcpy(md5, p, 16); p += 16; // demo checksum + for (gh = ghosts; gh; gh = gh->next) + if (!memcmp(md5, gh->checksum, 16)) // another ghost in the game already has this checksum? + { // Don't add another one, then! + CONS_Debug(DBG_SETUP, "Rejecting duplicate ghost %s (MD5 was matched)\n", pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } + if (memcmp(p, "PLAY", 4)) + { + CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo format unacceptable.\n"), pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } p += 4; // "PLAY" + if (ghostversion <= 0x0008) + p++; // gamemap + else + p += 2; // gamemap + p += 16; // mapmd5 (possibly check for consistency?) + flags = READUINT8(p); + if (!(flags & DF_GHOST)) + { + CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: No ghost data in this demo.\n"), pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } + switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) + { + case ATTACKING_NONE: // 0 + break; + case ATTACKING_RECORD: // 1 + p += 10; // demo time, score, and rings + break; + case ATTACKING_NIGHTS: // 2 + p += 8; // demo time left, score + break; + default: // 3 + break; + } + + p += 4; // random seed + + // Player name (TODO: Display this somehow if it doesn't match cv_playername!) + M_Memcpy(name, p,16); + p += 16; + + // Skin + M_Memcpy(skin, p,16); + p += 16; + + // Color + M_Memcpy(color, p,16); + p += 16; + + // Ghosts do not have a player structure to put this in. + p++; // charability + p++; // charability2 + p++; // actionspd + p++; // mindash + p++; // maxdash + p++; // normalspeed + p++; // runspeed + p++; // thrustfactor + p++; // accelstart + p++; // acceleration + p++; // height + p++; // spinheight + p++; // camerascale + p++; // shieldscale + p += 4; // jumpfactor + p += 4; // followitem + + p++; // pflag data + + // net var data + count = READUINT16(p); + while (count--) + { + p += 2; + SKIPSTRING(p); + p++; + } + + if (*p == DEMOMARKER) + { + CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Replay is empty.\n"), pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } + + gh = Z_Calloc(sizeof(demoghost), PU_LEVEL, NULL); + gh->next = ghosts; + gh->buffer = buffer; + M_Memcpy(gh->checksum, md5, 16); + gh->p = p; + + ghosts = gh; + + gh->version = ghostversion; + mthing = playerstarts[0]; + I_Assert(mthing); + { // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling. + fixed_t z,f,c; + fixed_t offset = mthing->z << FRACBITS; + gh->mo = P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST); + gh->mo->angle = FixedAngle(mthing->angle << FRACBITS); + f = gh->mo->floorz; + c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height; + if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) + { + z = c - offset; + if (z < f) + z = f; + } + else + { + z = f + offset; + if (z > c) + z = c; + } + gh->mo->z = z; + } + + gh->oldmo.x = gh->mo->x; + gh->oldmo.y = gh->mo->y; + gh->oldmo.z = gh->mo->z; + + // Set skin + gh->mo->skin = &skins[0]; + for (i = 0; i < numskins; i++) + if (!stricmp(skins[i].name,skin)) + { + gh->mo->skin = &skins[i]; + break; + } + gh->oldmo.skin = gh->mo->skin; + + // Set color + gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor; + for (i = 0; i < MAXSKINCOLORS; i++) + if (!stricmp(Color_Names[i],color)) + { + gh->mo->color = (UINT8)i; + break; + } + gh->oldmo.color = gh->mo->color; + + gh->mo->state = states+S_PLAY_STND; + gh->mo->sprite = gh->mo->state->sprite; + gh->mo->sprite2 = (gh->mo->state->frame & FF_FRAMEMASK); + //gh->mo->frame = tr_trans30<mo->flags2 |= MF2_DONTDRAW; + gh->fadein = (9-3)*6; // fade from invisible to trans30 over as close to 35 tics as possible + gh->mo->tics = -1; + + CONS_Printf(M_GetText("Added ghost %s from %s\n"), name, pdemoname); + Z_Free(pdemoname); +} + +// +// G_TimeDemo +// NOTE: name is a full filename for external demos +// +static INT32 restorecv_vidwait; + +void G_TimeDemo(const char *name) +{ + nodrawers = M_CheckParm("-nodraw"); + noblit = M_CheckParm("-noblit"); + restorecv_vidwait = cv_vidwait.value; + if (cv_vidwait.value) + CV_Set(&cv_vidwait, "0"); + timingdemo = true; + singletics = true; + framecount = 0; + demostarttime = I_GetTime(); + G_DeferedPlayDemo(name); +} + +void G_DoPlayMetal(void) +{ + lumpnum_t l; + mobj_t *mo = NULL; + thinker_t *th; + + // it's an internal demo + if ((l = W_CheckNumForName(va("%sMS",G_BuildMapName(gamemap)))) == LUMPERROR) + { + CONS_Alert(CONS_WARNING, M_GetText("No bot recording for this map.\n")); + return; + } + else + metalbuffer = metal_p = W_CacheLumpNum(l, PU_STATIC); + + // find metal sonic + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)th; + if (mo->type != MT_METALSONIC_RACE) + continue; + + break; + } + if (th == &thlist[THINK_MOBJ]) + { + CONS_Alert(CONS_ERROR, M_GetText("Failed to find bot entity.\n")); + Z_Free(metalbuffer); + return; + } + + // read demo header + metal_p += 12; // DEMOHEADER + metal_p++; // VERSION + metal_p++; // SUBVERSION + metalversion = READUINT16(metal_p); + switch(metalversion) + { + case DEMOVERSION: // latest always supported + break; + // too old, cannot support. + default: + CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n")); + Z_Free(metalbuffer); + return; + } + metal_p += 16; // demo checksum + if (memcmp(metal_p, "METL", 4)) + { + CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, wasn't recorded in Metal format.\n")); + Z_Free(metalbuffer); + return; + } metal_p += 4; // "METL" + + // read initial tic + memset(&oldmetal,0,sizeof(oldmetal)); + oldmetal.x = mo->x; + oldmetal.y = mo->y; + oldmetal.z = mo->z; + metalplayback = mo; +} + +void G_DoneLevelLoad(void) +{ + CONS_Printf(M_GetText("Loaded level in %f sec\n"), (double)(I_GetTime() - demostarttime) / TICRATE); + framecount = 0; + demostarttime = I_GetTime(); +} + +/* +=================== += += G_CheckDemoStatus += += Called after a death or level completion to allow demos to be cleaned up += Returns true if a new demo loop action will take place +=================== +*/ + +// Stops metal sonic's demo. Separate from other functions because metal + replays can coexist +void G_StopMetalDemo(void) +{ + + // Metal Sonic finishing doesn't end the game, dammit. + Z_Free(metalbuffer); + metalbuffer = NULL; + metalplayback = NULL; + metal_p = NULL; +} + +// Stops metal sonic recording. +ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) +{ + boolean saved = false; + if (demo_p) + { + UINT8 *p = demobuffer+16; // checksum position + if (kill) + WRITEUINT8(demo_p, METALDEATH); // add the metal death marker + else + WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker +#ifdef NOMD5 + { + UINT8 i; + for (i = 0; i < 16; i++, p++) + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. + } +#else + md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. +#endif + saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. + } + free(demobuffer); + metalrecording = false; + if (saved) + I_Error("Saved to %sMS.LMP", G_BuildMapName(gamemap)); + I_Error("Failed to save demo!"); +} + +// reset engine variable set for the demos +// called from stopdemo command, map command, and g_checkdemoStatus. +void G_StopDemo(void) +{ + Z_Free(demobuffer); + demobuffer = NULL; + demoplayback = false; + titledemo = false; + timingdemo = false; + singletics = false; + + if (gamestate == GS_INTERMISSION) + Y_EndIntermission(); // cleanup + + G_SetGamestate(GS_NULL); + wipegamestate = GS_NULL; + SV_StopServer(); + SV_ResetServer(); +} + +boolean G_CheckDemoStatus(void) +{ + boolean saved; + + while (ghosts) + { + demoghost *next = ghosts->next; + Z_Free(ghosts); + ghosts = next; + } + ghosts = NULL; + + + // DO NOT end metal sonic demos here + + if (timingdemo) + { + INT32 demotime; + double f1, f2; + demotime = I_GetTime() - demostarttime; + if (!demotime) + return true; + G_StopDemo(); + timingdemo = false; + f1 = (double)demotime; + f2 = (double)framecount*TICRATE; + + CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), + leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); + + // CSV-readable timedemo results, for external parsing + if (timedemo_csv) + { + FILE *f; + const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); + const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; + const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; + boolean headerrow = !FIL_FileExists(csvpath); + UINT8 procbits = 0; + + // Bitness + if (sizeof(void*) == 4) + procbits = 32; + else if (sizeof(void*) == 8) + procbits = 64; + + f = fopen(csvpath, "a+"); + + if (f) + { + if (headerrow) + fputs(header, f); + fprintf(f, rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + fclose(f); + CONS_Printf("Timedemo results saved to '%s'\n", csvpath); + } + else + { + // Just print the CSV output to console + CON_LogMessage(header); + CONS_Printf(rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + } + } + + if (restorecv_vidwait != cv_vidwait.value) + CV_SetValue(&cv_vidwait, restorecv_vidwait); + D_AdvanceDemo(); + return true; + } + + if (demoplayback) + { + if (singledemo) + I_Quit(); + G_StopDemo(); + + if (modeattacking) + M_EndModeAttackRun(); + else + D_AdvanceDemo(); + + return true; + } + + if (demorecording) + { + UINT8 *p = demobuffer+16; // checksum position +#ifdef NOMD5 + UINT8 i; + WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker + for (i = 0; i < 16; i++, p++) + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. +#else + WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker + md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. +#endif + saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. + free(demobuffer); + demorecording = false; + + if (modeattacking != ATTACKING_RECORD) + { + if (saved) + CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); + else + CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname); + } + return true; + } + + return false; +} diff --git a/src/g_demo.h b/src/g_demo.h new file mode 100644 index 000000000..89be6e343 --- /dev/null +++ b/src/g_demo.h @@ -0,0 +1,85 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2020 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file g_demo.h +/// \brief Demo recording and playback + +#ifndef __G_DEMO__ +#define __G_DEMO__ + +#include "doomdef.h" +#include "doomstat.h" +#include "d_event.h" + +// ====================================== +// DEMO playback/recording related stuff. +// ====================================== + +// demoplaying back and demo recording +extern boolean demoplayback, titledemo, demorecording, timingdemo; +extern tic_t demostarttime; + +// Quit after playing a demo from cmdline. +extern boolean singledemo; +extern boolean demo_start; +extern boolean demosynced; + +extern mobj_t *metalplayback; + +// Only called by startup code. +void G_RecordDemo(const char *name); +void G_RecordMetal(void); +void G_BeginRecording(void); +void G_BeginMetal(void); + +// Only called by shutdown code. +void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings); +UINT8 G_CmpDemoTime(char *oldname, char *newname); + +typedef enum +{ + GHC_NORMAL = 0, + GHC_SUPER, + GHC_FIREFLOWER, + GHC_INVINCIBLE, + GHC_NIGHTSSKIN, // not actually a colour + GHC_RETURNSKIN // ditto +} ghostcolor_t; + +// Record/playback tics +void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum); +void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum); +void G_GhostAddThok(void); +void G_GhostAddSpin(void); +void G_GhostAddRev(void); +void G_GhostAddColor(ghostcolor_t color); +void G_GhostAddFlip(void); +void G_GhostAddScale(fixed_t scale); +void G_GhostAddHit(mobj_t *victim); +void G_WriteGhostTic(mobj_t *ghost); +void G_ConsGhostTic(void); +void G_GhostTicker(void); +void G_ReadMetalTic(mobj_t *metal); +void G_WriteMetalTic(mobj_t *metal); +void G_SaveMetal(UINT8 **buffer); +void G_LoadMetal(UINT8 **buffer); + +void G_DeferedPlayDemo(const char *demo); +void G_DoPlayDemo(char *defdemoname); +void G_TimeDemo(const char *name); +void G_AddGhost(char *defdemoname); +void G_DoPlayMetal(void); +void G_DoneLevelLoad(void); +void G_StopMetalDemo(void); +ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill); +void G_StopDemo(void); +boolean G_CheckDemoStatus(void); + +#endif // __G_DEMO__ diff --git a/src/g_game.c b/src/g_game.c index 58f7795b6..fb70e2995 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -27,6 +27,7 @@ #include "r_main.h" #include "s_sound.h" #include "g_game.h" +#include "g_demo.h" #include "m_cheat.h" #include "m_misc.h" #include "m_menu.h" @@ -41,11 +42,9 @@ #include "r_skins.h" #include "y_inter.h" #include "v_video.h" -#include "dehacked.h" // get_number (for ghost thok) #include "lua_hook.h" #include "b_bot.h" #include "m_cond.h" // condition sets -#include "md5.h" // demo checksums #ifdef HAVE_BLUA #include "lua_hud.h" @@ -105,11 +104,6 @@ UINT8 numDemos = 0; UINT32 demoDelayTime = 15*TICRATE; UINT32 demoIdleTime = 3*TICRATE; -boolean timingdemo; // if true, exit with report on completion -boolean nodrawers; // for comparative timing purposes -boolean noblit; // for comparative timing purposes -tic_t demostarttime; // for comparative timing purposes - boolean netgame; // only true if packets are broadcast boolean multiplayer; boolean playeringame[MAXPLAYERS]; @@ -256,57 +250,12 @@ UINT32 timesBeaten; UINT32 timesBeatenWithEmeralds; UINT32 timesBeatenUltimate; -static char demoname[64]; -boolean demorecording; -boolean demoplayback; -boolean titledemo; // Title Screen demo can be cancelled by any key -static UINT8 *demobuffer = NULL; -static UINT8 *demo_p, *demotime_p; -static UINT8 *demoend; -static UINT8 demoflags; -static UINT16 demoversion; -boolean singledemo; // quit after playing a demo from cmdline -boolean demo_start; // don't start playing demo right away -boolean demosynced = true; // console warning message - -boolean metalrecording; // recording as metal sonic -mobj_t *metalplayback; -static UINT8 *metalbuffer = NULL; -static UINT8 *metal_p; -static UINT16 metalversion; - typedef struct joystickvector2_s { INT32 xaxis; INT32 yaxis; } joystickvector2_t; -// extra data stuff (events registered this frame while recording) -static struct { - UINT8 flags; // EZT flags - - // EZT_COLOR - UINT8 color, lastcolor; - - // EZT_SCALE - fixed_t scale, lastscale; - - // EZT_HIT - UINT16 hits; - mobj_t **hitlist; -} ghostext; - -// Your naming conventions are stupid and useless. -// There is no conflict here. -typedef struct demoghost { - UINT8 checksum[16]; - UINT8 *buffer, *p, color, fadein; - UINT16 version; - mobj_t oldmo, *mo; - struct demoghost *next; -} demoghost; -demoghost *ghosts = NULL; - boolean precache = true; // if true, load all graphics at start INT16 prevmap, nextmap; @@ -1102,8 +1051,6 @@ static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvect } } - - // // G_BuildTiccmd // Builds a ticcmd from all of the available inputs @@ -1723,6 +1670,25 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } } +ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) +{ + return M_Memcpy(dest, src, n*sizeof(*src)); +} + +ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) +{ + size_t i; + for (i = 0; i < n; i++) + { + dest[i].forwardmove = src[i].forwardmove; + dest[i].sidemove = src[i].sidemove; + dest[i].angleturn = SHORT(src[i].angleturn); + dest[i].aiming = (INT16)SHORT(src[i].aiming); + dest[i].buttons = (UINT16)SHORT(src[i].buttons); + } + return dest; +} + // User has designated that they want // analog ON, so tell the game to stop // fudging with it. @@ -4933,2432 +4899,6 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) return newmapnum; } -// -// DEMO RECORDING -// - -#define DEMOVERSION 0x000c -#define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" - -#define DF_GHOST 0x01 // This demo contains ghost data too! -#define DF_RECORDATTACK 0x02 // This demo is from record attack and contains its final completion time, score, and rings! -#define DF_NIGHTSATTACK 0x04 // This demo is from NiGHTS attack and contains its time left, score, and mares! -#define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ??? -#define DF_ATTACKSHIFT 1 - -// For demos -#define ZT_FWD 0x01 -#define ZT_SIDE 0x02 -#define ZT_ANGLE 0x04 -#define ZT_BUTTONS 0x08 -#define ZT_AIMING 0x10 -#define DEMOMARKER 0x80 // demoend -#define METALDEATH 0x44 -#define METALSNICE 0x69 - -static ticcmd_t oldcmd; - -// For Metal Sonic and time attack ghosts -#define GZT_XYZ 0x01 -#define GZT_MOMXY 0x02 -#define GZT_MOMZ 0x04 -#define GZT_ANGLE 0x08 -#define GZT_FRAME 0x10 // Animation frame -#define GZT_SPR2 0x20 // Player animations -#define GZT_EXTRA 0x40 -#define GZT_FOLLOW 0x80 // Followmobj - -// GZT_EXTRA flags -#define EZT_THOK 0x01 // Spawned a thok object -#define EZT_SPIN 0x02 // Because one type of thok object apparently wasn't enough -#define EZT_REV 0x03 // And two types wasn't enough either yet -#define EZT_THOKMASK 0x03 -#define EZT_COLOR 0x04 // Changed color (Super transformation, Mario fireflowers/invulnerability, etc.) -#define EZT_FLIP 0x08 // Reversed gravity -#define EZT_SCALE 0x10 // Changed size -#define EZT_HIT 0x20 // Damaged a mobj -#define EZT_SPRITE 0x40 // Changed sprite set completely out of PLAY (NiGHTS, SOCs, whatever) -#define EZT_HEIGHT 0x80 // Changed height - -// GZT_FOLLOW flags -#define FZT_SPAWNED 0x01 // just been spawned -#define FZT_SKIN 0x02 // has skin -#define FZT_LINKDRAW 0x04 // has linkdraw (combine with spawned only) -#define FZT_COLORIZED 0x08 // colorized (ditto) -#define FZT_SCALE 0x10 // different scale to object -// spare FZT slots 0x20 to 0x80 - -static mobj_t oldmetal, oldghost; - -void G_SaveMetal(UINT8 **buffer) -{ - I_Assert(buffer != NULL && *buffer != NULL); - - WRITEUINT32(*buffer, metal_p - metalbuffer); -} - -void G_LoadMetal(UINT8 **buffer) -{ - I_Assert(buffer != NULL && *buffer != NULL); - - G_DoPlayMetal(); - metal_p = metalbuffer + READUINT32(*buffer); -} - -ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) -{ - return M_Memcpy(dest, src, n*sizeof(*src)); -} - -ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) -{ - size_t i; - for (i = 0; i < n; i++) - { - dest[i].forwardmove = src[i].forwardmove; - dest[i].sidemove = src[i].sidemove; - dest[i].angleturn = SHORT(src[i].angleturn); - dest[i].aiming = (INT16)SHORT(src[i].aiming); - dest[i].buttons = (UINT16)SHORT(src[i].buttons); - } - return dest; -} - -void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) -{ - UINT8 ziptic; - (void)playernum; - - if (!demo_p || !demo_start) - return; - ziptic = READUINT8(demo_p); - - if (ziptic & ZT_FWD) - oldcmd.forwardmove = READSINT8(demo_p); - if (ziptic & ZT_SIDE) - oldcmd.sidemove = READSINT8(demo_p); - if (ziptic & ZT_ANGLE) - oldcmd.angleturn = READINT16(demo_p); - if (ziptic & ZT_BUTTONS) - oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT)); - if (ziptic & ZT_AIMING) - oldcmd.aiming = READINT16(demo_p); - - G_CopyTiccmd(cmd, &oldcmd, 1); - - if (!(demoflags & DF_GHOST) && *demo_p == DEMOMARKER) - { - // end of demo data stream - G_CheckDemoStatus(); - return; - } -} - -void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum) -{ - char ziptic = 0; - UINT8 *ziptic_p; - (void)playernum; - - if (!demo_p) - return; - ziptic_p = demo_p++; // the ziptic, written at the end of this function - - if (cmd->forwardmove != oldcmd.forwardmove) - { - WRITEUINT8(demo_p,cmd->forwardmove); - oldcmd.forwardmove = cmd->forwardmove; - ziptic |= ZT_FWD; - } - - if (cmd->sidemove != oldcmd.sidemove) - { - WRITEUINT8(demo_p,cmd->sidemove); - oldcmd.sidemove = cmd->sidemove; - ziptic |= ZT_SIDE; - } - - if (cmd->angleturn != oldcmd.angleturn) - { - WRITEINT16(demo_p,cmd->angleturn); - oldcmd.angleturn = cmd->angleturn; - ziptic |= ZT_ANGLE; - } - - if (cmd->buttons != oldcmd.buttons) - { - WRITEUINT16(demo_p,cmd->buttons); - oldcmd.buttons = cmd->buttons; - ziptic |= ZT_BUTTONS; - } - - if (cmd->aiming != oldcmd.aiming) - { - WRITEINT16(demo_p,cmd->aiming); - oldcmd.aiming = cmd->aiming; - ziptic |= ZT_AIMING; - } - - *ziptic_p = ziptic; - - // attention here for the ticcmd size! - // latest demos with mouse aiming byte in ticcmd - if (!(demoflags & DF_GHOST) && ziptic_p > demoend - 9) - { - G_CheckDemoStatus(); // no more space - return; - } -} - -void G_GhostAddThok(void) -{ - if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) - return; - ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_THOK; -} - -void G_GhostAddSpin(void) -{ - if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) - return; - ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_SPIN; -} - -void G_GhostAddRev(void) -{ - if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) - return; - ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_REV; -} - -void G_GhostAddFlip(void) -{ - if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) - return; - ghostext.flags |= EZT_FLIP; -} - -void G_GhostAddColor(ghostcolor_t color) -{ - if (!demorecording || !(demoflags & DF_GHOST)) - return; - if (ghostext.lastcolor == (UINT8)color) - { - ghostext.flags &= ~EZT_COLOR; - return; - } - ghostext.flags |= EZT_COLOR; - ghostext.color = (UINT8)color; -} - -void G_GhostAddScale(fixed_t scale) -{ - if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST))) - return; - if (ghostext.lastscale == scale) - { - ghostext.flags &= ~EZT_SCALE; - return; - } - ghostext.flags |= EZT_SCALE; - ghostext.scale = scale; -} - -void G_GhostAddHit(mobj_t *victim) -{ - if (!demorecording || !(demoflags & DF_GHOST)) - return; - ghostext.flags |= EZT_HIT; - ghostext.hits++; - ghostext.hitlist = Z_Realloc(ghostext.hitlist, ghostext.hits * sizeof(mobj_t *), PU_LEVEL, NULL); - ghostext.hitlist[ghostext.hits-1] = victim; -} - -void G_WriteGhostTic(mobj_t *ghost) -{ - char ziptic = 0; - UINT8 *ziptic_p; - UINT32 i; - fixed_t height; - - if (!demo_p) - return; - if (!(demoflags & DF_GHOST)) - return; // No ghost data to write. - - ziptic_p = demo_p++; // the ziptic, written at the end of this function - - #define MAXMOM (0xFFFF<<8) - - // GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic. - if (abs(ghost->x-oldghost.x) > MAXMOM - || abs(ghost->y-oldghost.y) > MAXMOM - || abs(ghost->z-oldghost.z) > MAXMOM) - { - oldghost.x = ghost->x; - oldghost.y = ghost->y; - oldghost.z = ghost->z; - ziptic |= GZT_XYZ; - WRITEFIXED(demo_p,oldghost.x); - WRITEFIXED(demo_p,oldghost.y); - WRITEFIXED(demo_p,oldghost.z); - } - else - { - // For moving normally: - // Store one full byte of movement, plus one byte of fractional movement. - INT16 momx = (INT16)((ghost->x-oldghost.x)>>8); - INT16 momy = (INT16)((ghost->y-oldghost.y)>>8); - if (momx != oldghost.momx - || momy != oldghost.momy) - { - oldghost.momx = momx; - oldghost.momy = momy; - ziptic |= GZT_MOMXY; - WRITEINT16(demo_p,momx); - WRITEINT16(demo_p,momy); - } - momx = (INT16)((ghost->z-oldghost.z)>>8); - if (momx != oldghost.momz) - { - oldghost.momz = momx; - ziptic |= GZT_MOMZ; - WRITEINT16(demo_p,momx); - } - - // This SHOULD set oldghost.x/y/z to match ghost->x/y/z - // but it keeps the fractional loss of one byte, - // so it will hopefully be made up for in future tics. - oldghost.x += oldghost.momx<<8; - oldghost.y += oldghost.momy<<8; - oldghost.z += oldghost.momz<<8; - } - - #undef MAXMOM - - // Only store the 8 most relevant bits of angle - // because exact values aren't too easy to discern to begin with when only 8 angles have different sprites - // and it does not affect this mode of movement at all anyway. - if (ghost->player && ghost->player->drawangle>>24 != oldghost.angle) - { - oldghost.angle = ghost->player->drawangle>>24; - ziptic |= GZT_ANGLE; - WRITEUINT8(demo_p,oldghost.angle); - } - - // Store the sprite frame. - if ((ghost->frame & FF_FRAMEMASK) != oldghost.frame) - { - oldghost.frame = (ghost->frame & FF_FRAMEMASK); - ziptic |= GZT_FRAME; - WRITEUINT8(demo_p,oldghost.frame); - } - - if (ghost->sprite == SPR_PLAY - && ghost->sprite2 != oldghost.sprite2) - { - oldghost.sprite2 = ghost->sprite2; - ziptic |= GZT_SPR2; - WRITEUINT8(demo_p,oldghost.sprite2); - } - - // Check for sprite set changes - if (ghost->sprite != oldghost.sprite) - { - oldghost.sprite = ghost->sprite; - ghostext.flags |= EZT_SPRITE; - } - - if ((height = FixedDiv(ghost->height, ghost->scale)) != oldghost.height) - { - oldghost.height = height; - ghostext.flags |= EZT_HEIGHT; - } - - if (ghostext.flags) - { - ziptic |= GZT_EXTRA; - - if (ghostext.color == ghostext.lastcolor) - ghostext.flags &= ~EZT_COLOR; - if (ghostext.scale == ghostext.lastscale) - ghostext.flags &= ~EZT_SCALE; - - WRITEUINT8(demo_p,ghostext.flags); - if (ghostext.flags & EZT_COLOR) - { - WRITEUINT8(demo_p,ghostext.color); - ghostext.lastcolor = ghostext.color; - } - if (ghostext.flags & EZT_SCALE) - { - WRITEFIXED(demo_p,ghostext.scale); - ghostext.lastscale = ghostext.scale; - } - if (ghostext.flags & EZT_HIT) - { - WRITEUINT16(demo_p,ghostext.hits); - for (i = 0; i < ghostext.hits; i++) - { - mobj_t *mo = ghostext.hitlist[i]; - //WRITEUINT32(demo_p,UINT32_MAX); // reserved for some method of determining exactly which mobj this is. (mobjnum doesn't work here.) - WRITEUINT32(demo_p,mo->type); - WRITEUINT16(demo_p,(UINT16)mo->health); - WRITEFIXED(demo_p,mo->x); - WRITEFIXED(demo_p,mo->y); - WRITEFIXED(demo_p,mo->z); - WRITEANGLE(demo_p,mo->angle); - } - Z_Free(ghostext.hitlist); - ghostext.hits = 0; - ghostext.hitlist = NULL; - } - if (ghostext.flags & EZT_SPRITE) - WRITEUINT16(demo_p,oldghost.sprite); - if (ghostext.flags & EZT_HEIGHT) - { - height >>= FRACBITS; - WRITEINT16(demo_p, height); - } - ghostext.flags = 0; - } - - if (ghost->player && ghost->player->followmobj && !(ghost->player->followmobj->sprite == SPR_NULL || (ghost->player->followmobj->flags2 & MF2_DONTDRAW))) // bloats tails runs but what can ya do - { - INT16 temp; - UINT8 *followtic_p = demo_p++; - UINT8 followtic = 0; - - ziptic |= GZT_FOLLOW; - - if (ghost->player->followmobj->skin) - followtic |= FZT_SKIN; - - if (!(oldghost.flags2 & MF2_AMBUSH)) - { - followtic |= FZT_SPAWNED; - WRITEINT16(demo_p,ghost->player->followmobj->info->height>>FRACBITS); - if (ghost->player->followmobj->flags2 & MF2_LINKDRAW) - followtic |= FZT_LINKDRAW; - if (ghost->player->followmobj->colorized) - followtic |= FZT_COLORIZED; - if (followtic & FZT_SKIN) - WRITEUINT8(demo_p,(UINT8)(((skin_t *)(ghost->player->followmobj->skin))-skins)); - oldghost.flags2 |= MF2_AMBUSH; - } - - if (ghost->player->followmobj->scale != ghost->scale) - { - followtic |= FZT_SCALE; - WRITEFIXED(demo_p,ghost->player->followmobj->scale); - } - - temp = (INT16)((ghost->player->followmobj->x-ghost->x)>>8); - WRITEINT16(demo_p,temp); - temp = (INT16)((ghost->player->followmobj->y-ghost->y)>>8); - WRITEINT16(demo_p,temp); - temp = (INT16)((ghost->player->followmobj->z-ghost->z)>>8); - WRITEINT16(demo_p,temp); - if (followtic & FZT_SKIN) - WRITEUINT8(demo_p,ghost->player->followmobj->sprite2); - WRITEUINT16(demo_p,ghost->player->followmobj->sprite); - WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK)); - WRITEUINT8(demo_p,ghost->player->followmobj->color); - - *followtic_p = followtic; - } - else - oldghost.flags2 &= ~MF2_AMBUSH; - - *ziptic_p = ziptic; - - // attention here for the ticcmd size! - // latest demos with mouse aiming byte in ticcmd - if (demo_p >= demoend - (13 + 9 + 9)) - { - G_CheckDemoStatus(); // no more space - return; - } -} - -// Uses ghost data to do consistency checks on your position. -// This fixes desynchronising demos when fighting eggman. -void G_ConsGhostTic(void) -{ - UINT8 ziptic; - UINT16 px,py,pz,gx,gy,gz; - mobj_t *testmo; - - if (!demo_p || !demo_start) - return; - if (!(demoflags & DF_GHOST)) - return; // No ghost data to use. - - testmo = players[0].mo; - - // Grab ghost data. - ziptic = READUINT8(demo_p); - if (ziptic & GZT_XYZ) - { - oldghost.x = READFIXED(demo_p); - oldghost.y = READFIXED(demo_p); - oldghost.z = READFIXED(demo_p); - } - else - { - if (ziptic & GZT_MOMXY) - { - oldghost.momx = READINT16(demo_p)<<8; - oldghost.momy = READINT16(demo_p)<<8; - } - if (ziptic & GZT_MOMZ) - oldghost.momz = READINT16(demo_p)<<8; - oldghost.x += oldghost.momx; - oldghost.y += oldghost.momy; - oldghost.z += oldghost.momz; - } - if (ziptic & GZT_ANGLE) - demo_p++; - if (ziptic & GZT_FRAME) - demo_p++; - if (ziptic & GZT_SPR2) - demo_p++; - - if (ziptic & GZT_EXTRA) - { // But wait, there's more! - UINT8 xziptic = READUINT8(demo_p); - if (xziptic & EZT_COLOR) - demo_p++; - if (xziptic & EZT_SCALE) - demo_p += sizeof(fixed_t); - if (xziptic & EZT_HIT) - { // Resync mob damage. - UINT16 i, count = READUINT16(demo_p); - thinker_t *th; - mobj_t *mobj; - - UINT32 type; - UINT16 health; - fixed_t x; - fixed_t y; - fixed_t z; - - for (i = 0; i < count; i++) - { - //demo_p += 4; // reserved. - type = READUINT32(demo_p); - health = READUINT16(demo_p); - x = READFIXED(demo_p); - y = READFIXED(demo_p); - z = READFIXED(demo_p); - demo_p += sizeof(angle_t); // angle, unnecessary for cons. - - mobj = NULL; - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - mobj = (mobj_t *)th; - if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z) - break; - } - if (th != &thlist[THINK_MOBJ] && mobj->health != health) // Wasn't damaged?! This is desync! Fix it! - { - if (demosynced) - CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); - demosynced = false; - P_DamageMobj(mobj, players[0].mo, players[0].mo, 1, 0); - } - } - } - if (xziptic & EZT_SPRITE) - demo_p += sizeof(UINT16); - if (xziptic & EZT_HEIGHT) - demo_p += sizeof(INT16); - } - - if (ziptic & GZT_FOLLOW) - { // Even more... - UINT8 followtic = READUINT8(demo_p); - if (followtic & FZT_SPAWNED) - { - demo_p += sizeof(INT16); - if (followtic & FZT_SKIN) - demo_p++; - } - if (followtic & FZT_SCALE) - demo_p += sizeof(fixed_t); - demo_p += sizeof(INT16); - demo_p += sizeof(INT16); - demo_p += sizeof(INT16); - if (followtic & FZT_SKIN) - demo_p++; - demo_p += sizeof(UINT16); - demo_p++; - demo_p++; - } - - // Re-synchronise - px = testmo->x>>FRACBITS; - py = testmo->y>>FRACBITS; - pz = testmo->z>>FRACBITS; - gx = oldghost.x>>FRACBITS; - gy = oldghost.y>>FRACBITS; - gz = oldghost.z>>FRACBITS; - - if (px != gx || py != gy || pz != gz) - { - if (demosynced) - 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 (*demo_p == DEMOMARKER) - { - // end of demo data stream - G_CheckDemoStatus(); - return; - } -} - -void G_GhostTicker(void) -{ - demoghost *g,*p; - for(g = ghosts, p = NULL; g; g = g->next) - { - // Skip normal demo data. - UINT8 ziptic = READUINT8(g->p); - UINT8 xziptic = 0; - if (ziptic & ZT_FWD) - g->p++; - if (ziptic & ZT_SIDE) - g->p++; - if (ziptic & ZT_ANGLE) - g->p += 2; - if (ziptic & ZT_BUTTONS) - g->p += 2; - if (ziptic & ZT_AIMING) - g->p += 2; - - // Grab ghost data. - ziptic = READUINT8(g->p); - if (ziptic & GZT_XYZ) - { - g->oldmo.x = READFIXED(g->p); - g->oldmo.y = READFIXED(g->p); - g->oldmo.z = READFIXED(g->p); - } - else - { - if (ziptic & GZT_MOMXY) - { - g->oldmo.momx = READINT16(g->p)<<8; - g->oldmo.momy = READINT16(g->p)<<8; - } - if (ziptic & GZT_MOMZ) - g->oldmo.momz = READINT16(g->p)<<8; - g->oldmo.x += g->oldmo.momx; - g->oldmo.y += g->oldmo.momy; - g->oldmo.z += g->oldmo.momz; - } - if (ziptic & GZT_ANGLE) - g->mo->angle = READUINT8(g->p)<<24; - if (ziptic & GZT_FRAME) - g->oldmo.frame = READUINT8(g->p); - if (ziptic & GZT_SPR2) - g->oldmo.sprite2 = READUINT8(g->p); - - // Update ghost - P_UnsetThingPosition(g->mo); - g->mo->x = g->oldmo.x; - g->mo->y = g->oldmo.y; - g->mo->z = g->oldmo.z; - P_SetThingPosition(g->mo); - g->mo->frame = g->oldmo.frame | tr_trans30<fadein) - { - g->mo->frame += (((--g->fadein)/6)<fadein is bad, and it's only set once, so... - g->mo->flags2 &= ~MF2_DONTDRAW; - } - g->mo->sprite2 = g->oldmo.sprite2; - - if (ziptic & GZT_EXTRA) - { // But wait, there's more! - xziptic = READUINT8(g->p); - if (xziptic & EZT_COLOR) - { - g->color = READUINT8(g->p); - switch(g->color) - { - default: - case GHC_RETURNSKIN: - g->mo->skin = g->oldmo.skin; - /* FALLTHRU */ - case GHC_NORMAL: // Go back to skin color - g->mo->color = g->oldmo.color; - break; - // Handled below - case GHC_SUPER: - case GHC_INVINCIBLE: - break; - case GHC_FIREFLOWER: // Fireflower - g->mo->color = SKINCOLOR_WHITE; - break; - case GHC_NIGHTSSKIN: // not actually a colour - g->mo->skin = &skins[DEFAULTNIGHTSSKIN]; - break; - } - } - if (xziptic & EZT_FLIP) - g->mo->eflags ^= MFE_VERTICALFLIP; - if (xziptic & EZT_SCALE) - { - g->mo->destscale = READFIXED(g->p); - if (g->mo->destscale != g->mo->scale) - P_SetScale(g->mo, g->mo->destscale); - } - if (xziptic & EZT_THOKMASK) - { // Let's only spawn ONE of these per frame, thanks. - mobj_t *mobj; - INT32 type = -1; - if (g->mo->skin) - { - skin_t *skin = (skin_t *)g->mo->skin; - switch (xziptic & EZT_THOKMASK) - { - case EZT_THOK: - type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; - break; - case EZT_SPIN: - type = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; - break; - case EZT_REV: - type = skin->revitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; - break; - } - } - if (type != MT_NULL) - { - if (type == MT_GHOST) - { - mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us - mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<mo, 0, 0, -FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK); - mobj->sprite = states[mobjinfo[type].spawnstate].sprite; - mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<color = g->mo->color; - mobj->skin = g->mo->skin; - P_SetScale(mobj, (mobj->destscale = g->mo->scale)); - - if (type == MT_THOK) // spintrail-specific modification for MT_THOK - { - mobj->frame = FF_TRANS80; - mobj->fuse = mobj->tics; - } - mobj->tics = -1; // nope. - } - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_UnsetThingPosition(mobj); - mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... - P_SetThingPosition(mobj); - if (!mobj->fuse) - mobj->fuse = 8; - P_SetTarget(&mobj->target, g->mo); - } - } - if (xziptic & EZT_HIT) - { // Spawn hit poofs for killing things! - UINT16 i, count = READUINT16(g->p), health; - UINT32 type; - fixed_t x,y,z; - angle_t angle; - mobj_t *poof; - for (i = 0; i < count; i++) - { - //g->p += 4; // reserved - type = READUINT32(g->p); - health = READUINT16(g->p); - x = READFIXED(g->p); - y = READFIXED(g->p); - z = READFIXED(g->p); - angle = READANGLE(g->p); - if (!(mobjinfo[type].flags & MF_SHOOTABLE) - || !(mobjinfo[type].flags & (MF_ENEMY|MF_MONITOR)) - || health != 0 || i >= 4) // only spawn for the first 4 hits per frame, to prevent ghosts from splode-spamming too bad. - continue; - poof = P_SpawnMobj(x, y, z, MT_GHOST); - poof->angle = angle; - poof->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... - poof->health = 0; - P_SetMobjStateNF(poof, S_XPLD1); - } - } - if (xziptic & EZT_SPRITE) - g->mo->sprite = READUINT16(g->p); - if (xziptic & EZT_HEIGHT) - { - fixed_t temp = READINT16(g->p)<mo->height = FixedMul(temp, g->mo->scale); - } - } - - // Tick ghost colors (Super and Mario Invincibility flashing) - switch(g->color) - { - case GHC_SUPER: // Super (P_DoSuperStuff) - if (g->mo->skin) - { - skin_t *skin = (skin_t *)g->mo->skin; - g->mo->color = skin->supercolor; - } - else - g->mo->color = SKINCOLOR_SUPERGOLD1; - g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); - break; - case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) - g->mo->color = (UINT8)(SKINCOLOR_RUBY + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RUBY))); // Passes through all saturated colours - break; - default: - break; - } - -#define follow g->mo->tracer - if (ziptic & GZT_FOLLOW) - { // Even more... - UINT8 followtic = READUINT8(g->p); - fixed_t temp; - if (followtic & FZT_SPAWNED) - { - if (follow) - P_RemoveMobj(follow); - P_SetTarget(&follow, P_SpawnMobjFromMobj(g->mo, 0, 0, 0, MT_GHOST)); - P_SetTarget(&follow->tracer, g->mo); - follow->tics = -1; - temp = READINT16(g->p)<height = FixedMul(follow->scale, temp); - - if (followtic & FZT_LINKDRAW) - follow->flags2 |= MF2_LINKDRAW; - - if (followtic & FZT_COLORIZED) - follow->colorized = true; - - if (followtic & FZT_SKIN) - follow->skin = &skins[READUINT8(g->p)]; - } - if (follow) - { - if (followtic & FZT_SCALE) - follow->destscale = READFIXED(g->p); - else - follow->destscale = g->mo->destscale; - if (follow->destscale != follow->scale) - P_SetScale(follow, follow->destscale); - - P_UnsetThingPosition(follow); - temp = READINT16(g->p)<<8; - follow->x = g->mo->x + temp; - temp = READINT16(g->p)<<8; - follow->y = g->mo->y + temp; - temp = READINT16(g->p)<<8; - follow->z = g->mo->z + temp; - P_SetThingPosition(follow); - if (followtic & FZT_SKIN) - follow->sprite2 = READUINT8(g->p); - else - follow->sprite2 = 0; - follow->sprite = READUINT16(g->p); - follow->frame = (READUINT8(g->p)) | (g->mo->frame & FF_TRANSMASK); - follow->angle = g->mo->angle; - follow->color = READUINT8(g->p); - - if (!(followtic & FZT_SPAWNED)) - { - if (xziptic & EZT_FLIP) - { - follow->flags2 ^= MF2_OBJECTFLIP; - follow->eflags ^= MFE_VERTICALFLIP; - } - } - } - } - else if (follow) - { - P_RemoveMobj(follow); - P_SetTarget(&follow, NULL); - } - // Demo ends after ghost data. - if (*g->p == DEMOMARKER) - { - g->mo->momx = g->mo->momy = g->mo->momz = 0; -#if 1 // freeze frame (maybe more useful for time attackers) - g->mo->colorized = true; - if (follow) - follow->colorized = true; -#else // dissapearing act - g->mo->fuse = TICRATE; - if (follow) - follow->fuse = TICRATE; -#endif - if (p) - p->next = g->next; - else - ghosts = g->next; - Z_Free(g); - continue; - } - p = g; -#undef follow - } -} - -void G_ReadMetalTic(mobj_t *metal) -{ - UINT8 ziptic; - UINT8 xziptic = 0; - - if (!metal_p) - return; - - if (!metal->health) - { - G_StopMetalDemo(); - return; - } - - switch (*metal_p) - { - case METALSNICE: - break; - case METALDEATH: - if (metal->tracer) - P_RemoveMobj(metal->tracer); - P_KillMobj(metal, NULL, NULL, 0); - /* FALLTHRU */ - case DEMOMARKER: - default: - // end of demo data stream - G_StopMetalDemo(); - return; - } - metal_p++; - - ziptic = READUINT8(metal_p); - - // Read changes from the tic - if (ziptic & GZT_XYZ) - { - P_TeleportMove(metal, READFIXED(metal_p), READFIXED(metal_p), READFIXED(metal_p)); - oldmetal.x = metal->x; - oldmetal.y = metal->y; - oldmetal.z = metal->z; - } - else - { - if (ziptic & GZT_MOMXY) - { - oldmetal.momx = READINT16(metal_p)<<8; - oldmetal.momy = READINT16(metal_p)<<8; - } - if (ziptic & GZT_MOMZ) - oldmetal.momz = READINT16(metal_p)<<8; - oldmetal.x += oldmetal.momx; - oldmetal.y += oldmetal.momy; - oldmetal.z += oldmetal.momz; - } - if (ziptic & GZT_ANGLE) - metal->angle = READUINT8(metal_p)<<24; - if (ziptic & GZT_FRAME) - oldmetal.frame = READUINT32(metal_p); - if (ziptic & GZT_SPR2) - oldmetal.sprite2 = READUINT8(metal_p); - - // Set movement, position, and angle - // oldmetal contains where you're supposed to be. - metal->momx = oldmetal.momx; - metal->momy = oldmetal.momy; - metal->momz = oldmetal.momz; - P_UnsetThingPosition(metal); - metal->x = oldmetal.x; - metal->y = oldmetal.y; - metal->z = oldmetal.z; - P_SetThingPosition(metal); - metal->frame = oldmetal.frame; - metal->sprite2 = oldmetal.sprite2; - - if (ziptic & GZT_EXTRA) - { // But wait, there's more! - xziptic = READUINT8(metal_p); - if (xziptic & EZT_FLIP) - { - metal->eflags ^= MFE_VERTICALFLIP; - metal->flags2 ^= MF2_OBJECTFLIP; - } - if (xziptic & EZT_SCALE) - { - metal->destscale = READFIXED(metal_p); - if (metal->destscale != metal->scale) - P_SetScale(metal, metal->destscale); - } - if (xziptic & EZT_THOKMASK) - { // Let's only spawn ONE of these per frame, thanks. - mobj_t *mobj; - INT32 type = -1; - if (metal->skin) - { - skin_t *skin = (skin_t *)metal->skin; - switch (xziptic & EZT_THOKMASK) - { - case EZT_THOK: - type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; - break; - case EZT_SPIN: - type = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; - break; - case EZT_REV: - type = skin->revitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; - break; - } - } - if (type != MT_NULL) - { - if (type == MT_GHOST) - { - mobj = P_SpawnGhostMobj(metal); // does a large portion of the work for us - } - else - { - mobj = P_SpawnMobjFromMobj(metal, 0, 0, -FixedDiv(FixedMul(metal->info->height, metal->scale) - metal->height,3*FRACUNIT), MT_THOK); - mobj->sprite = states[mobjinfo[type].spawnstate].sprite; - mobj->frame = states[mobjinfo[type].spawnstate].frame; - mobj->angle = metal->angle; - mobj->color = metal->color; - mobj->skin = metal->skin; - P_SetScale(mobj, (mobj->destscale = metal->scale)); - - if (type == MT_THOK) // spintrail-specific modification for MT_THOK - { - mobj->frame = FF_TRANS70; - mobj->fuse = mobj->tics; - } - mobj->tics = -1; // nope. - } - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_UnsetThingPosition(mobj); - mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up... - P_SetThingPosition(mobj); - if (!mobj->fuse) - mobj->fuse = 8; - P_SetTarget(&mobj->target, metal); - } - } - if (xziptic & EZT_SPRITE) - metal->sprite = READUINT16(metal_p); - if (xziptic & EZT_HEIGHT) - { - fixed_t temp = READINT16(metal_p)<height = FixedMul(temp, metal->scale); - } - } - -#define follow metal->tracer - if (ziptic & GZT_FOLLOW) - { // Even more... - UINT8 followtic = READUINT8(metal_p); - fixed_t temp; - if (followtic & FZT_SPAWNED) - { - if (follow) - P_RemoveMobj(follow); - P_SetTarget(&follow, P_SpawnMobjFromMobj(metal, 0, 0, 0, MT_GHOST)); - P_SetTarget(&follow->tracer, metal); - follow->tics = -1; - temp = READINT16(metal_p)<height = FixedMul(follow->scale, temp); - - if (followtic & FZT_LINKDRAW) - follow->flags2 |= MF2_LINKDRAW; - - if (followtic & FZT_COLORIZED) - follow->colorized = true; - - if (followtic & FZT_SKIN) - follow->skin = &skins[READUINT8(metal_p)]; - } - if (follow) - { - if (followtic & FZT_SCALE) - follow->destscale = READFIXED(metal_p); - else - follow->destscale = metal->destscale; - if (follow->destscale != follow->scale) - P_SetScale(follow, follow->destscale); - - P_UnsetThingPosition(follow); - temp = READINT16(metal_p)<<8; - follow->x = metal->x + temp; - temp = READINT16(metal_p)<<8; - follow->y = metal->y + temp; - temp = READINT16(metal_p)<<8; - follow->z = metal->z + temp; - P_SetThingPosition(follow); - if (followtic & FZT_SKIN) - follow->sprite2 = READUINT8(metal_p); - else - follow->sprite2 = 0; - follow->sprite = READUINT16(metal_p); - follow->frame = READUINT32(metal_p); // NOT & FF_FRAMEMASK here, so 32 bits - follow->angle = metal->angle; - follow->color = READUINT8(metal_p); - - if (!(followtic & FZT_SPAWNED)) - { - if (xziptic & EZT_FLIP) - { - follow->flags2 ^= MF2_OBJECTFLIP; - follow->eflags ^= MFE_VERTICALFLIP; - } - } - } - } - else if (follow) - { - P_RemoveMobj(follow); - P_SetTarget(&follow, NULL); - } -#undef follow -} - -void G_WriteMetalTic(mobj_t *metal) -{ - UINT8 ziptic = 0; - UINT8 *ziptic_p; - fixed_t height; - - if (!demo_p) // demo_p will be NULL until the race start linedef executor is activated! - return; - - WRITEUINT8(demo_p, METALSNICE); - ziptic_p = demo_p++; // the ziptic, written at the end of this function - - #define MAXMOM (0xFFFF<<8) - - // GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic. - if (abs(metal->x-oldmetal.x) > MAXMOM - || abs(metal->y-oldmetal.y) > MAXMOM - || abs(metal->z-oldmetal.z) > MAXMOM) - { - oldmetal.x = metal->x; - oldmetal.y = metal->y; - oldmetal.z = metal->z; - ziptic |= GZT_XYZ; - WRITEFIXED(demo_p,oldmetal.x); - WRITEFIXED(demo_p,oldmetal.y); - WRITEFIXED(demo_p,oldmetal.z); - } - else - { - // For moving normally: - // Store one full byte of movement, plus one byte of fractional movement. - INT16 momx = (INT16)((metal->x-oldmetal.x)>>8); - INT16 momy = (INT16)((metal->y-oldmetal.y)>>8); - if (momx != oldmetal.momx - || momy != oldmetal.momy) - { - oldmetal.momx = momx; - oldmetal.momy = momy; - ziptic |= GZT_MOMXY; - WRITEINT16(demo_p,momx); - WRITEINT16(demo_p,momy); - } - momx = (INT16)((metal->z-oldmetal.z)>>8); - if (momx != oldmetal.momz) - { - oldmetal.momz = momx; - ziptic |= GZT_MOMZ; - WRITEINT16(demo_p,momx); - } - - // This SHOULD set oldmetal.x/y/z to match metal->x/y/z - // but it keeps the fractional loss of one byte, - // so it will hopefully be made up for in future tics. - oldmetal.x += oldmetal.momx<<8; - oldmetal.y += oldmetal.momy<<8; - oldmetal.z += oldmetal.momz<<8; - } - - #undef MAXMOM - - // Only store the 8 most relevant bits of angle - // because exact values aren't too easy to discern to begin with when only 8 angles have different sprites - // and it does not affect movement at all anyway. - if (metal->player && metal->player->drawangle>>24 != oldmetal.angle) - { - oldmetal.angle = metal->player->drawangle>>24; - ziptic |= GZT_ANGLE; - WRITEUINT8(demo_p,oldmetal.angle); - } - - // Store the sprite frame. - if ((metal->frame & FF_FRAMEMASK) != oldmetal.frame) - { - oldmetal.frame = metal->frame; // NOT & FF_FRAMEMASK here, so 32 bits - ziptic |= GZT_FRAME; - WRITEUINT32(demo_p,oldmetal.frame); - } - - if (metal->sprite == SPR_PLAY - && metal->sprite2 != oldmetal.sprite2) - { - oldmetal.sprite2 = metal->sprite2; - ziptic |= GZT_SPR2; - WRITEUINT8(demo_p,oldmetal.sprite2); - } - - // Check for sprite set changes - if (metal->sprite != oldmetal.sprite) - { - oldmetal.sprite = metal->sprite; - ghostext.flags |= EZT_SPRITE; - } - - if ((height = FixedDiv(metal->height, metal->scale)) != oldmetal.height) - { - oldmetal.height = height; - ghostext.flags |= EZT_HEIGHT; - } - - if (ghostext.flags & ~(EZT_COLOR|EZT_HIT)) // these two aren't handled by metal ever - { - ziptic |= GZT_EXTRA; - - if (ghostext.scale == ghostext.lastscale) - ghostext.flags &= ~EZT_SCALE; - - WRITEUINT8(demo_p,ghostext.flags); - if (ghostext.flags & EZT_SCALE) - { - WRITEFIXED(demo_p,ghostext.scale); - ghostext.lastscale = ghostext.scale; - } - if (ghostext.flags & EZT_SPRITE) - WRITEUINT16(demo_p,oldmetal.sprite); - if (ghostext.flags & EZT_HEIGHT) - { - height >>= FRACBITS; - WRITEINT16(demo_p, height); - } - ghostext.flags = 0; - } - - if (metal->player && metal->player->followmobj && !(metal->player->followmobj->sprite == SPR_NULL || (metal->player->followmobj->flags2 & MF2_DONTDRAW))) - { - INT16 temp; - UINT8 *followtic_p = demo_p++; - UINT8 followtic = 0; - - ziptic |= GZT_FOLLOW; - - if (metal->player->followmobj->skin) - followtic |= FZT_SKIN; - - if (!(oldmetal.flags2 & MF2_AMBUSH)) - { - followtic |= FZT_SPAWNED; - WRITEINT16(demo_p,metal->player->followmobj->info->height>>FRACBITS); - if (metal->player->followmobj->flags2 & MF2_LINKDRAW) - followtic |= FZT_LINKDRAW; - if (metal->player->followmobj->colorized) - followtic |= FZT_COLORIZED; - if (followtic & FZT_SKIN) - WRITEUINT8(demo_p,(UINT8)(((skin_t *)(metal->player->followmobj->skin))-skins)); - oldmetal.flags2 |= MF2_AMBUSH; - } - - if (metal->player->followmobj->scale != metal->scale) - { - followtic |= FZT_SCALE; - WRITEFIXED(demo_p,metal->player->followmobj->scale); - } - - temp = (INT16)((metal->player->followmobj->x-metal->x)>>8); - WRITEINT16(demo_p,temp); - temp = (INT16)((metal->player->followmobj->y-metal->y)>>8); - WRITEINT16(demo_p,temp); - temp = (INT16)((metal->player->followmobj->z-metal->z)>>8); - WRITEINT16(demo_p,temp); - if (followtic & FZT_SKIN) - WRITEUINT8(demo_p,metal->player->followmobj->sprite2); - WRITEUINT16(demo_p,metal->player->followmobj->sprite); - WRITEUINT32(demo_p,metal->player->followmobj->frame); // NOT & FF_FRAMEMASK here, so 32 bits - WRITEUINT8(demo_p,metal->player->followmobj->color); - - *followtic_p = followtic; - } - else - oldmetal.flags2 &= ~MF2_AMBUSH; - - *ziptic_p = ziptic; - - // attention here for the ticcmd size! - // latest demos with mouse aiming byte in ticcmd - if (demo_p >= demoend - 32) - { - G_StopMetalRecording(false); // no more space - return; - } -} - -// -// G_RecordDemo -// -void G_RecordDemo(const char *name) -{ - INT32 maxsize; - - strcpy(demoname, name); - strcat(demoname, ".lmp"); - maxsize = 1024*1024; - if (M_CheckParm("-maxdemo") && M_IsNextParm()) - maxsize = atoi(M_GetNextParm()) * 1024; -// if (demobuffer) -// free(demobuffer); - demo_p = NULL; - demobuffer = malloc(maxsize); - demoend = demobuffer + maxsize; - - demorecording = true; -} - -void G_RecordMetal(void) -{ - INT32 maxsize; - maxsize = 1024*1024; - if (M_CheckParm("-maxdemo") && M_IsNextParm()) - maxsize = atoi(M_GetNextParm()) * 1024; - demo_p = NULL; - demobuffer = malloc(maxsize); - demoend = demobuffer + maxsize; - metalrecording = true; -} - -void G_BeginRecording(void) -{ - UINT8 i; - char name[16]; - player_t *player = &players[consoleplayer]; - - if (demo_p) - return; - memset(name,0,sizeof(name)); - - demo_p = demobuffer; - demoflags = DF_GHOST|(modeattacking<>DF_ATTACKSHIFT) - { - case ATTACKING_NONE: // 0 - break; - case ATTACKING_RECORD: // 1 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,0); // score - WRITEUINT16(demo_p,0); // rings - break; - case ATTACKING_NIGHTS: // 2 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,0); // score - break; - default: // 3 - break; - } - - WRITEUINT32(demo_p,P_GetInitSeed()); - - // Name - for (i = 0; i < 16 && cv_playername.string[i]; i++) - name[i] = cv_playername.string[i]; - for (; i < 16; i++) - name[i] = '\0'; - M_Memcpy(demo_p,name,16); - demo_p += 16; - - // Skin - for (i = 0; i < 16 && cv_skin.string[i]; i++) - name[i] = cv_skin.string[i]; - for (; i < 16; i++) - name[i] = '\0'; - M_Memcpy(demo_p,name,16); - demo_p += 16; - - // Color - for (i = 0; i < 16 && cv_playercolor.string[i]; i++) - name[i] = cv_playercolor.string[i]; - for (; i < 16; i++) - name[i] = '\0'; - M_Memcpy(demo_p,name,16); - demo_p += 16; - - // Stats - WRITEUINT8(demo_p,player->charability); - WRITEUINT8(demo_p,player->charability2); - WRITEUINT8(demo_p,player->actionspd>>FRACBITS); - WRITEUINT8(demo_p,player->mindash>>FRACBITS); - WRITEUINT8(demo_p,player->maxdash>>FRACBITS); - WRITEUINT8(demo_p,player->normalspeed>>FRACBITS); - WRITEUINT8(demo_p,player->runspeed>>FRACBITS); - WRITEUINT8(demo_p,player->thrustfactor); - WRITEUINT8(demo_p,player->accelstart); - WRITEUINT8(demo_p,player->acceleration); - WRITEUINT8(demo_p,player->height>>FRACBITS); - WRITEUINT8(demo_p,player->spinheight>>FRACBITS); - WRITEUINT8(demo_p,player->camerascale>>FRACBITS); - WRITEUINT8(demo_p,player->shieldscale>>FRACBITS); - - // Trying to convert it back to % causes demo desync due to precision loss. - // Don't do it. - WRITEFIXED(demo_p, player->jumpfactor); - - // And mobjtype_t is best with UINT32 too... - WRITEUINT32(demo_p, player->followitem); - - // Save pflag data - see SendWeaponPref() - { - UINT8 buf = 0; - pflags_t pflags = 0; - if (cv_flipcam.value) - { - buf |= 0x01; - pflags |= PF_FLIPCAM; - } - if (cv_analog[0].value) - { - buf |= 0x02; - pflags |= PF_ANALOGMODE; - } - if (cv_directionchar[0].value) - { - buf |= 0x04; - pflags |= PF_DIRECTIONCHAR; - } - if (cv_autobrake.value) - { - buf |= 0x08; - pflags |= PF_AUTOBRAKE; - } - if (cv_usejoystick.value) - buf |= 0x10; - CV_SetValue(&cv_showinputjoy, !!(cv_usejoystick.value)); - - WRITEUINT8(demo_p,buf); - player->pflags = pflags; - } - - // Save netvar data - CV_SaveNetVars(&demo_p); - - memset(&oldcmd,0,sizeof(oldcmd)); - memset(&oldghost,0,sizeof(oldghost)); - memset(&ghostext,0,sizeof(ghostext)); - ghostext.lastcolor = ghostext.color = GHC_NORMAL; - ghostext.lastscale = ghostext.scale = FRACUNIT; - - if (player->mo) - { - oldghost.x = player->mo->x; - oldghost.y = player->mo->y; - oldghost.z = player->mo->z; - oldghost.angle = player->mo->angle>>24; - - // preticker started us gravity flipped - if (player->mo->eflags & MFE_VERTICALFLIP) - ghostext.flags |= EZT_FLIP; - } -} - -void G_BeginMetal(void) -{ - mobj_t *mo = players[consoleplayer].mo; - -#if 0 - if (demo_p) - return; -#endif - - demo_p = demobuffer; - - // Write header. - M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12; - WRITEUINT8(demo_p,VERSION); - WRITEUINT8(demo_p,SUBVERSION); - WRITEUINT16(demo_p,DEMOVERSION); - - // demo checksum - demo_p += 16; - - M_Memcpy(demo_p, "METL", 4); demo_p += 4; - - memset(&ghostext,0,sizeof(ghostext)); - ghostext.lastscale = ghostext.scale = FRACUNIT; - - // Set up our memory. - memset(&oldmetal,0,sizeof(oldmetal)); - oldmetal.x = mo->x; - oldmetal.y = mo->y; - oldmetal.z = mo->z; - oldmetal.angle = mo->angle>>24; -} - -void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings) -{ - if (!demorecording || !demotime_p) - return; - if (demoflags & DF_RECORDATTACK) - { - WRITEUINT32(demotime_p, ptime); - WRITEUINT32(demotime_p, pscore); - WRITEUINT16(demotime_p, prings); - demotime_p = NULL; - } - else if (demoflags & DF_NIGHTSATTACK) - { - WRITEUINT32(demotime_p, ptime); - WRITEUINT32(demotime_p, pscore); - demotime_p = NULL; - } -} - -// Returns bitfield: -// 1 == new demo has lower time -// 2 == new demo has higher score -// 4 == new demo has higher rings -UINT8 G_CmpDemoTime(char *oldname, char *newname) -{ - UINT8 *buffer,*p; - UINT8 flags; - UINT32 oldtime, newtime, oldscore, newscore; - UINT16 oldrings, newrings, oldversion; - size_t bufsize ATTRUNUSED; - UINT8 c; - UINT16 s ATTRUNUSED; - UINT8 aflags = 0; - - // load the new file - FIL_DefaultExtension(newname, ".lmp"); - bufsize = FIL_ReadFile(newname, &buffer); - I_Assert(bufsize != 0); - p = buffer; - - // read demo header - I_Assert(!memcmp(p, DEMOHEADER, 12)); - p += 12; // DEMOHEADER - c = READUINT8(p); // VERSION - I_Assert(c == VERSION); - c = READUINT8(p); // SUBVERSION - I_Assert(c == SUBVERSION); - s = READUINT16(p); - I_Assert(s == DEMOVERSION); - p += 16; // demo checksum - I_Assert(!memcmp(p, "PLAY", 4)); - p += 4; // PLAY - p += 2; // gamemap - p += 16; // map md5 - flags = READUINT8(p); // demoflags - - aflags = flags & (DF_RECORDATTACK|DF_NIGHTSATTACK); - I_Assert(aflags); - if (flags & DF_RECORDATTACK) - { - newtime = READUINT32(p); - newscore = READUINT32(p); - newrings = READUINT16(p); - } - else if (flags & DF_NIGHTSATTACK) - { - newtime = READUINT32(p); - newscore = READUINT32(p); - newrings = 0; - } - else // appease compiler - return 0; - - Z_Free(buffer); - - // load old file - FIL_DefaultExtension(oldname, ".lmp"); - if (!FIL_ReadFile(oldname, &buffer)) - { - CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), oldname); - return UINT8_MAX; - } - p = buffer; - - // read demo header - if (memcmp(p, DEMOHEADER, 12)) - { - CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname); - Z_Free(buffer); - return UINT8_MAX; - } p += 12; // DEMOHEADER - p++; // VERSION - p++; // SUBVERSION - oldversion = READUINT16(p); - switch(oldversion) // demoversion - { - case DEMOVERSION: // latest always supported - break; - // too old, cannot support. - default: - CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname); - Z_Free(buffer); - return UINT8_MAX; - } - p += 16; // demo checksum - if (memcmp(p, "PLAY", 4)) - { - CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname); - Z_Free(buffer); - return UINT8_MAX; - } p += 4; // "PLAY" - if (oldversion <= 0x0008) - p++; // gamemap - else - p += 2; // gamemap - p += 16; // mapmd5 - flags = READUINT8(p); - if (!(flags & aflags)) - { - CONS_Alert(CONS_NOTICE, M_GetText("File '%s' not from same game mode. It will be overwritten.\n"), oldname); - Z_Free(buffer); - return UINT8_MAX; - } - if (flags & DF_RECORDATTACK) - { - oldtime = READUINT32(p); - oldscore = READUINT32(p); - oldrings = READUINT16(p); - } - else if (flags & DF_NIGHTSATTACK) - { - oldtime = READUINT32(p); - oldscore = READUINT32(p); - oldrings = 0; - } - else // appease compiler - return UINT8_MAX; - - Z_Free(buffer); - - c = 0; - if (newtime < oldtime - || (newtime == oldtime && (newscore > oldscore || newrings > oldrings))) - c |= 1; // Better time - if (newscore > oldscore - || (newscore == oldscore && newtime < oldtime)) - c |= 1<<1; // Better score - if (newrings > oldrings - || (newrings == oldrings && newtime < oldtime)) - c |= 1<<2; // Better rings - return c; -} - -// -// G_PlayDemo -// -void G_DeferedPlayDemo(const char *name) -{ - COM_BufAddText("playdemo \""); - COM_BufAddText(name); - COM_BufAddText("\"\n"); -} - -// -// Start a demo from a .LMP file or from a wad resource -// -void G_DoPlayDemo(char *defdemoname) -{ - UINT8 i; - lumpnum_t l; - char skin[17],color[17],*n,*pdemoname; - UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration; - pflags_t pflags; - UINT32 randseed, followitem; - fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight; - char msg[1024]; - - skin[16] = '\0'; - color[16] = '\0'; - - n = defdemoname+strlen(defdemoname); - while (*n != '/' && *n != '\\' && n != defdemoname) - n--; - if (n != defdemoname) - n++; - pdemoname = ZZ_Alloc(strlen(n)+1); - strcpy(pdemoname,n); - - // Internal if no extension, external if one exists - if (FIL_CheckExtension(defdemoname)) - { - //FIL_DefaultExtension(defdemoname, ".lmp"); - if (!FIL_ReadFile(defdemoname, &demobuffer)) - { - snprintf(msg, 1024, M_GetText("Failed to read file '%s'.\n"), defdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - gameaction = ga_nothing; - M_StartMessage(msg, NULL, MM_NOTHING); - return; - } - demo_p = demobuffer; - } - // load demo resource from WAD - else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR) - { - snprintf(msg, 1024, M_GetText("Failed to read lump '%s'.\n"), defdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - gameaction = ga_nothing; - M_StartMessage(msg, NULL, MM_NOTHING); - return; - } - else // it's an internal demo - demobuffer = demo_p = W_CacheLumpNum(l, PU_STATIC); - - // read demo header - gameaction = ga_nothing; - demoplayback = true; - if (memcmp(demo_p, DEMOHEADER, 12)) - { - snprintf(msg, 1024, M_GetText("%s is not a SRB2 replay file.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demoplayback = false; - titledemo = false; - return; - } - demo_p += 12; // DEMOHEADER - - version = READUINT8(demo_p); - subversion = READUINT8(demo_p); - demoversion = READUINT16(demo_p); - switch(demoversion) - { - case DEMOVERSION: // latest always supported - break; - // too old, cannot support. - default: - snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demoplayback = false; - titledemo = false; - return; - } - demo_p += 16; // demo checksum - if (memcmp(demo_p, "PLAY", 4)) - { - snprintf(msg, 1024, M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demoplayback = false; - titledemo = false; - return; - } - demo_p += 4; // "PLAY" - gamemap = READINT16(demo_p); - demo_p += 16; // mapmd5 - - demoflags = READUINT8(demo_p); - modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT; - CON_ToggleOff(); - - hu_demoscore = 0; - hu_demotime = UINT32_MAX; - hu_demorings = 0; - - switch (modeattacking) - { - case ATTACKING_NONE: // 0 - break; - case ATTACKING_RECORD: // 1 - hu_demotime = READUINT32(demo_p); - hu_demoscore = READUINT32(demo_p); - hu_demorings = READUINT16(demo_p); - break; - case ATTACKING_NIGHTS: // 2 - hu_demotime = READUINT32(demo_p); - hu_demoscore = READUINT32(demo_p); - break; - default: // 3 - modeattacking = ATTACKING_NONE; - break; - } - - // Random seed - randseed = READUINT32(demo_p); - - // Player name - M_Memcpy(player_names[0],demo_p,16); - demo_p += 16; - - // Skin - M_Memcpy(skin,demo_p,16); - demo_p += 16; - - // Color - M_Memcpy(color,demo_p,16); - demo_p += 16; - - charability = READUINT8(demo_p); - charability2 = READUINT8(demo_p); - actionspd = (fixed_t)READUINT8(demo_p)<color = players[0].skincolor; - oldghost.x = players[0].mo->x; - oldghost.y = players[0].mo->y; - oldghost.z = players[0].mo->z; - } - - // Set saved attribute values - // No cheat checking here, because even if they ARE wrong... - // it would only break the replay if we clipped them. - players[0].camerascale = camerascale; - players[0].shieldscale = shieldscale; - players[0].charability = charability; - players[0].charability2 = charability2; - players[0].actionspd = actionspd; - players[0].mindash = mindash; - players[0].maxdash = maxdash; - players[0].normalspeed = normalspeed; - players[0].runspeed = runspeed; - players[0].thrustfactor = thrustfactor; - players[0].accelstart = accelstart; - players[0].acceleration = acceleration; - players[0].height = height; - players[0].spinheight = spinheight; - players[0].jumpfactor = jumpfactor; - players[0].followitem = followitem; - players[0].pflags = pflags; - - demo_start = true; -} - -void G_AddGhost(char *defdemoname) -{ - INT32 i; - lumpnum_t l; - char name[17],skin[17],color[17],*n,*pdemoname,md5[16]; - demoghost *gh; - UINT8 flags; - UINT8 *buffer,*p; - mapthing_t *mthing; - UINT16 count, ghostversion; - - name[16] = '\0'; - skin[16] = '\0'; - color[16] = '\0'; - - n = defdemoname+strlen(defdemoname); - while (*n != '/' && *n != '\\' && n != defdemoname) - n--; - if (n != defdemoname) - n++; - pdemoname = ZZ_Alloc(strlen(n)+1); - strcpy(pdemoname,n); - - // Internal if no extension, external if one exists - if (FIL_CheckExtension(defdemoname)) - { - //FIL_DefaultExtension(defdemoname, ".lmp"); - if (!FIL_ReadFileTag(defdemoname, &buffer, PU_LEVEL)) - { - CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), defdemoname); - Z_Free(pdemoname); - return; - } - p = buffer; - } - // load demo resource from WAD - else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR) - { - CONS_Alert(CONS_ERROR, M_GetText("Failed to read lump '%s'.\n"), defdemoname); - Z_Free(pdemoname); - return; - } - else // it's an internal demo - buffer = p = W_CacheLumpNum(l, PU_LEVEL); - - // read demo header - if (memcmp(p, DEMOHEADER, 12)) - { - CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Not a SRB2 replay.\n"), pdemoname); - Z_Free(pdemoname); - Z_Free(buffer); - return; - } p += 12; // DEMOHEADER - p++; // VERSION - p++; // SUBVERSION - ghostversion = READUINT16(p); - switch(ghostversion) - { - case DEMOVERSION: // latest always supported - break; - // too old, cannot support. - default: - CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname); - Z_Free(pdemoname); - Z_Free(buffer); - return; - } - M_Memcpy(md5, p, 16); p += 16; // demo checksum - for (gh = ghosts; gh; gh = gh->next) - if (!memcmp(md5, gh->checksum, 16)) // another ghost in the game already has this checksum? - { // Don't add another one, then! - CONS_Debug(DBG_SETUP, "Rejecting duplicate ghost %s (MD5 was matched)\n", pdemoname); - Z_Free(pdemoname); - Z_Free(buffer); - return; - } - if (memcmp(p, "PLAY", 4)) - { - CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo format unacceptable.\n"), pdemoname); - Z_Free(pdemoname); - Z_Free(buffer); - return; - } p += 4; // "PLAY" - if (ghostversion <= 0x0008) - p++; // gamemap - else - p += 2; // gamemap - p += 16; // mapmd5 (possibly check for consistency?) - flags = READUINT8(p); - if (!(flags & DF_GHOST)) - { - CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: No ghost data in this demo.\n"), pdemoname); - Z_Free(pdemoname); - Z_Free(buffer); - return; - } - switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) - { - case ATTACKING_NONE: // 0 - break; - case ATTACKING_RECORD: // 1 - p += 10; // demo time, score, and rings - break; - case ATTACKING_NIGHTS: // 2 - p += 8; // demo time left, score - break; - default: // 3 - break; - } - - p += 4; // random seed - - // Player name (TODO: Display this somehow if it doesn't match cv_playername!) - M_Memcpy(name, p,16); - p += 16; - - // Skin - M_Memcpy(skin, p,16); - p += 16; - - // Color - M_Memcpy(color, p,16); - p += 16; - - // Ghosts do not have a player structure to put this in. - p++; // charability - p++; // charability2 - p++; // actionspd - p++; // mindash - p++; // maxdash - p++; // normalspeed - p++; // runspeed - p++; // thrustfactor - p++; // accelstart - p++; // acceleration - p++; // height - p++; // spinheight - p++; // camerascale - p++; // shieldscale - p += 4; // jumpfactor - p += 4; // followitem - - p++; // pflag data - - // net var data - count = READUINT16(p); - while (count--) - { - p += 2; - SKIPSTRING(p); - p++; - } - - if (*p == DEMOMARKER) - { - CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Replay is empty.\n"), pdemoname); - Z_Free(pdemoname); - Z_Free(buffer); - return; - } - - gh = Z_Calloc(sizeof(demoghost), PU_LEVEL, NULL); - gh->next = ghosts; - gh->buffer = buffer; - M_Memcpy(gh->checksum, md5, 16); - gh->p = p; - - ghosts = gh; - - gh->version = ghostversion; - mthing = playerstarts[0]; - I_Assert(mthing); - { // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling. - fixed_t z,f,c; - fixed_t offset = mthing->z << FRACBITS; - gh->mo = P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST); - gh->mo->angle = FixedAngle(mthing->angle << FRACBITS); - f = gh->mo->floorz; - c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height; - if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) - { - z = c - offset; - if (z < f) - z = f; - } - else - { - z = f + offset; - if (z > c) - z = c; - } - gh->mo->z = z; - } - - gh->oldmo.x = gh->mo->x; - gh->oldmo.y = gh->mo->y; - gh->oldmo.z = gh->mo->z; - - // Set skin - gh->mo->skin = &skins[0]; - for (i = 0; i < numskins; i++) - if (!stricmp(skins[i].name,skin)) - { - gh->mo->skin = &skins[i]; - break; - } - gh->oldmo.skin = gh->mo->skin; - - // Set color - gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor; - for (i = 0; i < MAXSKINCOLORS; i++) - if (!stricmp(Color_Names[i],color)) - { - gh->mo->color = (UINT8)i; - break; - } - gh->oldmo.color = gh->mo->color; - - gh->mo->state = states+S_PLAY_STND; - gh->mo->sprite = gh->mo->state->sprite; - gh->mo->sprite2 = (gh->mo->state->frame & FF_FRAMEMASK); - //gh->mo->frame = tr_trans30<mo->flags2 |= MF2_DONTDRAW; - gh->fadein = (9-3)*6; // fade from invisible to trans30 over as close to 35 tics as possible - gh->mo->tics = -1; - - CONS_Printf(M_GetText("Added ghost %s from %s\n"), name, pdemoname); - Z_Free(pdemoname); -} - -// -// G_TimeDemo -// NOTE: name is a full filename for external demos -// -static INT32 restorecv_vidwait; - -void G_TimeDemo(const char *name) -{ - nodrawers = M_CheckParm("-nodraw"); - noblit = M_CheckParm("-noblit"); - restorecv_vidwait = cv_vidwait.value; - if (cv_vidwait.value) - CV_Set(&cv_vidwait, "0"); - timingdemo = true; - singletics = true; - framecount = 0; - demostarttime = I_GetTime(); - G_DeferedPlayDemo(name); -} - -void G_DoPlayMetal(void) -{ - lumpnum_t l; - mobj_t *mo = NULL; - thinker_t *th; - - // it's an internal demo - if ((l = W_CheckNumForName(va("%sMS",G_BuildMapName(gamemap)))) == LUMPERROR) - { - CONS_Alert(CONS_WARNING, M_GetText("No bot recording for this map.\n")); - return; - } - else - metalbuffer = metal_p = W_CacheLumpNum(l, PU_STATIC); - - // find metal sonic - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo = (mobj_t *)th; - if (mo->type != MT_METALSONIC_RACE) - continue; - - break; - } - if (th == &thlist[THINK_MOBJ]) - { - CONS_Alert(CONS_ERROR, M_GetText("Failed to find bot entity.\n")); - Z_Free(metalbuffer); - return; - } - - // read demo header - metal_p += 12; // DEMOHEADER - metal_p++; // VERSION - metal_p++; // SUBVERSION - metalversion = READUINT16(metal_p); - switch(metalversion) - { - case DEMOVERSION: // latest always supported - break; - // too old, cannot support. - default: - CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n")); - Z_Free(metalbuffer); - return; - } - metal_p += 16; // demo checksum - if (memcmp(metal_p, "METL", 4)) - { - CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, wasn't recorded in Metal format.\n")); - Z_Free(metalbuffer); - return; - } metal_p += 4; // "METL" - - // read initial tic - memset(&oldmetal,0,sizeof(oldmetal)); - oldmetal.x = mo->x; - oldmetal.y = mo->y; - oldmetal.z = mo->z; - metalplayback = mo; -} - -void G_DoneLevelLoad(void) -{ - CONS_Printf(M_GetText("Loaded level in %f sec\n"), (double)(I_GetTime() - demostarttime) / TICRATE); - framecount = 0; - demostarttime = I_GetTime(); -} - -/* -=================== -= -= G_CheckDemoStatus -= -= Called after a death or level completion to allow demos to be cleaned up -= Returns true if a new demo loop action will take place -=================== -*/ - -// Stops metal sonic's demo. Separate from other functions because metal + replays can coexist -void G_StopMetalDemo(void) -{ - - // Metal Sonic finishing doesn't end the game, dammit. - Z_Free(metalbuffer); - metalbuffer = NULL; - metalplayback = NULL; - metal_p = NULL; -} - -// Stops metal sonic recording. -ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) -{ - boolean saved = false; - if (demo_p) - { - UINT8 *p = demobuffer+16; // checksum position - if (kill) - WRITEUINT8(demo_p, METALDEATH); // add the metal death marker - else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker -#ifdef NOMD5 - { - UINT8 i; - for (i = 0; i < 16; i++, p++) - *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. - } -#else - md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. -#endif - saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. - } - free(demobuffer); - metalrecording = false; - if (saved) - I_Error("Saved to %sMS.LMP", G_BuildMapName(gamemap)); - I_Error("Failed to save demo!"); -} - -// reset engine variable set for the demos -// called from stopdemo command, map command, and g_checkdemoStatus. -void G_StopDemo(void) -{ - Z_Free(demobuffer); - demobuffer = NULL; - demoplayback = false; - titledemo = false; - timingdemo = false; - singletics = false; - - if (gamestate == GS_INTERMISSION) - Y_EndIntermission(); // cleanup - - G_SetGamestate(GS_NULL); - wipegamestate = GS_NULL; - SV_StopServer(); - SV_ResetServer(); -} - -boolean G_CheckDemoStatus(void) -{ - boolean saved; - - while (ghosts) - { - demoghost *next = ghosts->next; - Z_Free(ghosts); - ghosts = next; - } - ghosts = NULL; - - - // DO NOT end metal sonic demos here - - if (timingdemo) - { - INT32 demotime; - double f1, f2; - demotime = I_GetTime() - demostarttime; - if (!demotime) - return true; - G_StopDemo(); - timingdemo = false; - f1 = (double)demotime; - f2 = (double)framecount*TICRATE; - - CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), - leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); - - // CSV-readable timedemo results, for external parsing - if (timedemo_csv) - { - FILE *f; - const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); - const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; - const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; - boolean headerrow = !FIL_FileExists(csvpath); - UINT8 procbits = 0; - - // Bitness - if (sizeof(void*) == 4) - procbits = 32; - else if (sizeof(void*) == 8) - procbits = 64; - - f = fopen(csvpath, "a+"); - - if (f) - { - if (headerrow) - fputs(header, f); - fprintf(f, rowformat, - timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); - fclose(f); - CONS_Printf("Timedemo results saved to '%s'\n", csvpath); - } - else - { - // Just print the CSV output to console - CON_LogMessage(header); - CONS_Printf(rowformat, - timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); - } - } - - if (restorecv_vidwait != cv_vidwait.value) - CV_SetValue(&cv_vidwait, restorecv_vidwait); - D_AdvanceDemo(); - return true; - } - - if (demoplayback) - { - if (singledemo) - I_Quit(); - G_StopDemo(); - - if (modeattacking) - M_EndModeAttackRun(); - else - D_AdvanceDemo(); - - return true; - } - - if (demorecording) - { - UINT8 *p = demobuffer+16; // checksum position -#ifdef NOMD5 - UINT8 i; - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - for (i = 0; i < 16; i++, p++) - *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. -#else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. -#endif - saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. - free(demobuffer); - demorecording = false; - - if (modeattacking != ATTACKING_RECORD) - { - if (saved) - CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); - else - CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname); - } - return true; - } - - return false; -} - // // G_SetGamestate // diff --git a/src/g_game.h b/src/g_game.h index c4c40d84b..b4216a001 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -17,6 +17,7 @@ #include "doomdef.h" #include "doomstat.h" #include "d_event.h" +#include "g_demo.h" extern char gamedatafilename[64]; extern char timeattackfolder[64]; @@ -31,21 +32,6 @@ extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; extern player_t players[MAXPLAYERS]; extern boolean playeringame[MAXPLAYERS]; -// ====================================== -// DEMO playback/recording related stuff. -// ====================================== - -// demoplaying back and demo recording -extern boolean demoplayback, titledemo, demorecording, timingdemo; -extern tic_t demostarttime; - -// Quit after playing a demo from cmdline. -extern boolean singledemo; -extern boolean demo_start; -extern boolean demosynced; - -extern mobj_t *metalplayback; - // gametic at level start extern tic_t levelstarttic; @@ -173,7 +159,6 @@ void G_DoLoadLevel(boolean resetplayer); void G_StartTitleCard(void); void G_PreLevelTitleCard(void); boolean G_IsTitleCardAvailable(void); -void G_DeferedPlayDemo(const char *demo); // Can be called by the startup code or M_Responder, calls P_SetupLevel. void G_LoadGame(UINT32 slot, INT16 mapoverride); @@ -184,54 +169,6 @@ void G_SaveGame(UINT32 slot); void G_SaveGameOver(UINT32 slot, boolean modifylives); -// Only called by startup code. -void G_RecordDemo(const char *name); -void G_RecordMetal(void); -void G_BeginRecording(void); -void G_BeginMetal(void); - -// Only called by shutdown code. -void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings); -UINT8 G_CmpDemoTime(char *oldname, char *newname); - -typedef enum -{ - GHC_NORMAL = 0, - GHC_SUPER, - GHC_FIREFLOWER, - GHC_INVINCIBLE, - GHC_NIGHTSSKIN, // not actually a colour - GHC_RETURNSKIN // ditto -} ghostcolor_t; - -// Record/playback tics -void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum); -void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum); -void G_GhostAddThok(void); -void G_GhostAddSpin(void); -void G_GhostAddRev(void); -void G_GhostAddColor(ghostcolor_t color); -void G_GhostAddFlip(void); -void G_GhostAddScale(fixed_t scale); -void G_GhostAddHit(mobj_t *victim); -void G_WriteGhostTic(mobj_t *ghost); -void G_ConsGhostTic(void); -void G_GhostTicker(void); -void G_ReadMetalTic(mobj_t *metal); -void G_WriteMetalTic(mobj_t *metal); -void G_SaveMetal(UINT8 **buffer); -void G_LoadMetal(UINT8 **buffer); - -void G_DoPlayDemo(char *defdemoname); -void G_TimeDemo(const char *name); -void G_AddGhost(char *defdemoname); -void G_DoPlayMetal(void); -void G_DoneLevelLoad(void); -void G_StopMetalDemo(void); -ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill); -void G_StopDemo(void); -boolean G_CheckDemoStatus(void); - extern UINT32 gametypedefaultrules[NUMGAMETYPES]; extern UINT32 gametypetol[NUMGAMETYPES]; extern INT16 gametyperankings[NUMGAMETYPES]; From 1a142340884f9a4216a845c7482e6acd2e0aecf4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 19 Mar 2020 20:13:39 +0000 Subject: [PATCH 052/220] update Makefile, CMakeLists.txt and MSVC project files --- src/CMakeLists.txt | 2 ++ src/Makefile | 1 + src/sdl/Srb2SDL-vc10.vcxproj | 2 ++ src/sdl/Srb2SDL-vc10.vcxproj.filters | 6 ++++++ 4 files changed, 11 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc4a6114e..e1e7689a6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,7 @@ set(SRB2_CORE_SOURCES f_finale.c f_wipe.c filesrch.c + g_demo.c g_game.c g_input.c hu_stuff.c @@ -71,6 +72,7 @@ set(SRB2_CORE_HEADERS f_finale.h fastcmp.h filesrch.h + g_demo.h g_game.h g_input.h g_state.h diff --git a/src/Makefile b/src/Makefile index 701f2cfda..43cf48905 100644 --- a/src/Makefile +++ b/src/Makefile @@ -424,6 +424,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/z_zone.o \ $(OBJDIR)/f_finale.o \ $(OBJDIR)/f_wipe.o \ + $(OBJDIR)/g_demo.o \ $(OBJDIR)/g_game.o \ $(OBJDIR)/g_input.o \ $(OBJDIR)/am_map.o \ diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 7e260f4c0..6335b3028 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -213,6 +213,7 @@ + @@ -364,6 +365,7 @@ + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index 21820551a..a226e8397 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -180,6 +180,9 @@ F_Frame + + G_Game + G_Game @@ -600,6 +603,9 @@ F_Frame + + G_Game + G_Game From dd76be16cbe6cfe075376fff1b358e1e57d305b2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 19 Mar 2020 20:42:51 +0000 Subject: [PATCH 053/220] Create G_FreeGhosts, for the benefit of G_DeferedInitNew (assuming it actually needs to do `ghosts = NULL;` at all) --- src/g_demo.c | 21 +++++++++++++-------- src/g_demo.h | 1 + src/g_game.c | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 22cd34ad5..9adafae54 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -2223,6 +2223,18 @@ void G_AddGhost(char *defdemoname) Z_Free(pdemoname); } +// Clean up all ghosts +void G_FreeGhosts(void) +{ + while (ghosts) + { + demoghost *next = ghosts->next; + Z_Free(ghosts); + ghosts = next; + } + ghosts = NULL; +} + // // G_TimeDemo // NOTE: name is a full filename for external demos @@ -2389,14 +2401,7 @@ boolean G_CheckDemoStatus(void) { boolean saved; - while (ghosts) - { - demoghost *next = ghosts->next; - Z_Free(ghosts); - ghosts = next; - } - ghosts = NULL; - + G_FreeGhosts(); // DO NOT end metal sonic demos here diff --git a/src/g_demo.h b/src/g_demo.h index 89be6e343..df25042c4 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -75,6 +75,7 @@ void G_DeferedPlayDemo(const char *demo); void G_DoPlayDemo(char *defdemoname); void G_TimeDemo(const char *name); void G_AddGhost(char *defdemoname); +void G_FreeGhosts(void); void G_DoPlayMetal(void); void G_DoneLevelLoad(void); void G_StopMetalDemo(void); diff --git a/src/g_game.c b/src/g_game.c index fb70e2995..e22961b9a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4490,7 +4490,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b if (demoplayback) COM_BufAddText("stopdemo\n"); - ghosts = NULL; + G_FreeGhosts(); // TODO: do we actually need to do this? // this leave the actual game if needed SV_StartSinglePlayerServer(); From 6610150bfeb11796cacad3d6453ab98030f1cd4b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 19 Mar 2020 20:43:56 +0000 Subject: [PATCH 054/220] We definitely don't need these files to compile! --- src/g_demo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 9adafae54..c589482b6 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -16,14 +16,12 @@ #include "d_main.h" #include "d_player.h" #include "d_clisrv.h" -//#include "f_finale.h" #include "p_setup.h" #include "i_system.h" #include "m_random.h" #include "p_local.h" #include "r_draw.h" #include "r_main.h" -//#include "s_sound.h" #include "g_game.h" #include "g_demo.h" #include "m_cheat.h" From 4236ae7c083f388d0c184c165a724ade3560f242 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 19 Mar 2020 21:10:23 +0000 Subject: [PATCH 055/220] We don't need m_cheat.h either in g_demo.c --- src/g_demo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/g_demo.c b/src/g_demo.c index c589482b6..199f7d68e 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -24,7 +24,6 @@ #include "r_main.h" #include "g_game.h" #include "g_demo.h" -#include "m_cheat.h" #include "m_misc.h" #include "m_menu.h" #include "m_argv.h" From 5eaa73b6ac8194a17a6af54f46fd7a2b7be46746 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Mar 2020 19:09:34 -0300 Subject: [PATCH 056/220] Fix lib_setSpriteInfo indexes being off-by-one --- src/lua_infolib.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 6760b4203..d099b24a9 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -389,10 +389,7 @@ static int lib_setSpriteInfo(lua_State *L) lua_Integer i = 0; const char *str = NULL; if (lua_isnumber(L, 2)) - { i = lua_tointeger(L, 2); - i++; // shift index in case of missing rotsprite support - } else str = luaL_checkstring(L, 2); From 78ec210896d2afffccbb17557510923f3ab8723f Mon Sep 17 00:00:00 2001 From: fickleheart Date: Thu, 19 Mar 2020 18:55:10 -0500 Subject: [PATCH 057/220] hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh --- src/m_menu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 3ebaedca2..6047bada9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5405,9 +5405,10 @@ static void M_HandleLevelPlatter(INT32 choice) case KEY_LEFTARROW: if (levellistmode == LLM_CREATESERVER && !lsrow) { + INT32 startinggametype = cv_newgametype.value; do CV_AddValue(&cv_newgametype, -1); - while (!M_GametypeHasLevels(cv_newgametype.value)); + while (cv_newgametype.value != startinggametype && !M_GametypeHasLevels(cv_newgametype.value)); S_StartSound(NULL,sfx_menu1); lscol = 0; From feb18208cbb6fbe0c380d96713af2278aa4119cb Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 21 Mar 2020 01:36:39 -0500 Subject: [PATCH 058/220] Add support for srb2:// URL handler (server links) --- src/d_main.c | 27 +++++++++++++++++++++++++-- src/i_tcp.c | 9 ++++++--- src/m_argv.c | 18 ++++++++++++++++++ src/m_argv.h | 3 +++ 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 3840e77a0..d954fa4d1 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -889,6 +889,29 @@ static void IdentifyVersion(void) char *srb2wad; const char *srb2waddir = NULL; + // URL handlers are opened by web browsers (at least Firefox) from the browser's working directory, not the game's stored directory, + // so chdir to that directory unless overridden. + if (M_GetUrlProtocolArg() != NULL && !M_CheckParm("-nochdir")) + { + size_t i; + + CONS_Printf("srb2:// connect links load game files from the SRB2 application's stored directory. Switching to "); + strlcpy(srb2path, myargv[0], sizeof(srb2path)); + + // Get just the directory, minus the EXE name + for (i = strlen(srb2path)-1; i > 0; i--) + { + if (srb2path[i] == '/' || srb2path[i] == '\\') + { + srb2path[i] = '\0'; + break; + } + } + + CONS_Printf("%s\n", srb2path); + chdir(srb2path); + } + #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) // change to the directory where 'srb2.pk3' is found srb2waddir = I_LocateWad(); @@ -1152,7 +1175,7 @@ void D_SRB2Main(void) // add any files specified on the command line with -file wadfile // to the wad list - if (!(M_CheckParm("-connect") && !M_CheckParm("-server"))) + if (!((M_GetUrlProtocolArg() || M_CheckParm("-connect")) && !M_CheckParm("-server"))) { if (M_CheckParm("-file")) { @@ -1187,7 +1210,7 @@ void D_SRB2Main(void) M_InitMenuPresTables(); // init title screen display params - if (M_CheckParm("-connect")) + if (M_GetUrlProtocolArg() || M_CheckParm("-connect")) F_InitMenuPresValues(); //---------------------------------------------------- READY TIME diff --git a/src/i_tcp.c b/src/i_tcp.c index 34cad1765..373ea1bd0 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -1423,6 +1423,7 @@ static void SOCK_ClearBans(void) boolean I_InitTcpNetwork(void) { char serverhostname[255]; + const char *urlparam = NULL; boolean ret = false; // initilize the OS's TCP/IP stack if (!I_InitTcpDriver()) @@ -1476,10 +1477,12 @@ boolean I_InitTcpNetwork(void) ret = true; } - else if (M_CheckParm("-connect")) + else if ((urlparam = M_GetUrlProtocolArg()) != NULL || M_CheckParm("-connect")) { - if (M_IsNextParm()) - strcpy(serverhostname, M_GetNextParm()); + if (urlparam != NULL) + strlcpy(serverhostname, urlparam, sizeof(serverhostname)); + else if (M_IsNextParm()) + strlcpy(serverhostname, M_GetNextParm(), sizeof(serverhostname)); else serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it diff --git a/src/m_argv.c b/src/m_argv.c index acb74cff4..d7d1f4463 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -34,6 +34,24 @@ boolean myargmalloc = false; */ static INT32 found; +/** \brief Parses a server URL (such as srb2://127.0.0.1) as may be passed to the game via a web browser, etc. + + \return the contents of the URL after the protocol (a server to join), or NULL if not found +*/ +const char *M_GetUrlProtocolArg(void) +{ + INT32 i; + + for (i = 1; i < myargc; i++) + { + if (!strnicmp(myargv[i], "srb2://", 7)) + { + return &myargv[i][7]; + } + } + + return NULL; +} /** \brief The M_CheckParm function diff --git a/src/m_argv.h b/src/m_argv.h index ca97d9b12..92770f4e9 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -21,6 +21,9 @@ extern INT32 myargc; extern char **myargv; extern boolean myargmalloc; +// Looks for an srb2:// (or similar) URL passed in as an argument and returns the IP to connect to if found. +const char *M_GetUrlProtocolArg(void); + // Returns the position of the given parameter in the arg list (0 if not found). INT32 M_CheckParm(const char *check); From 06f9246fd36b1dde74f0cd1d3248aa7aadb2ae97 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 21 Mar 2020 12:06:52 +0100 Subject: [PATCH 059/220] Updates and fixes for the ZB config --- extras/conf/SRB2-22.cfg | 109 +++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 35 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index ec318321d..5119c1234 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -435,7 +435,7 @@ sectortypes 112 = "Trigger Line Ex. (NiGHTS Mare)"; 128 = "Check for Linedef Executor on FOFs"; 144 = "Egg Capsule"; - 160 = "Special Stage Time/Rings Parameters"; + 160 = "Special Stage Time/Spheres Parameters"; 176 = "Custom Global Gravity"; 512 = "Wind/Current"; 1024 = "Conveyor Belt"; @@ -490,7 +490,7 @@ gen_sectortypes 112 = "Trigger Line Ex. (NiGHTS Mare)"; 128 = "Check for Linedef Executor on FOFs"; 144 = "Egg Capsule"; - 160 = "Special Stage Time/Rings Parameters"; + 160 = "Special Stage Time/Spheres Parameters"; 176 = "Custom Global Gravity"; } @@ -766,6 +766,7 @@ linedeftypes { title = "Parameters"; prefix = "(22)"; + flags32text = "[5] Render outer sides only"; flags64text = "[6] Trigger linedef executor"; flags128text = "[7] Intangible"; flags256text = "[8] Stopped by pushables"; @@ -788,7 +789,6 @@ linedeftypes { title = "Angular Displacement by Front Sector"; prefix = "(32)"; - flags8text = "[3] Set delay by backside sector"; flags64text = "[6] Don't turn players"; flags512text = "[9] Turn all objects"; } @@ -1136,7 +1136,6 @@ linedeftypes { title = "Goo Water, Translucent, No Sides"; prefix = "(125)"; - flags8text = "[3] Slope skew sides"; flags64text = "[6] Use two light levels"; flags512text = "[9] Use target light level"; flags1024text = "[10] Ripple effect"; @@ -1227,6 +1226,18 @@ linedeftypes 3dfloorflags = "19F"; } + 153 + { + title = "Dynamically Sinking Platform"; + prefix = "(153)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + 160 { title = "Floating, Bobbing"; @@ -1282,7 +1293,6 @@ linedeftypes title = "Rising Platform, Solid, Invisible"; prefix = "(193)"; flags2text = "[1] Sink when stepped on"; - flags8text = "[3] Slope skew sides"; flags32text = "[5] Only block player"; flags64text = "[6] Spindash to move"; flags128text = "[7] Only block non-players"; @@ -1488,16 +1498,22 @@ linedeftypes { title = "Mario Block"; prefix = "(250)"; + flags8text = "[3] Slope skew sides"; flags32text = "[5] Invisible block"; flags64text = "[6] Brick block"; 3dfloor = true; 3dfloorflags = "40019F"; + flags323dfloorflagsremove = "19E"; + flags643dfloorflagsadd = "200000"; } 251 { title = "Thwomp Block"; prefix = "(251)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; flags512text = "[9] Custom crushing sound"; flags1024text = "[10] Custom speed"; 3dfloor = true; @@ -1513,8 +1529,8 @@ linedeftypes flags512text = "[9] Shattered by pushables"; flags1024text = "[10] Trigger linedef executor"; 3dfloor = true; - 3dfloorflags = "8800019"; - flags643dfloorflagsadd = "200006"; + 3dfloorflags = "880001D"; + flags643dfloorflagsadd = "200002"; } 253 @@ -1525,7 +1541,7 @@ linedeftypes flags512text = "[9] Shattered by pushables"; flags1024text = "[10] Trigger linedef executor"; 3dfloor = true; - 3dfloorflags = "8801019"; + 3dfloorflags = "880101D"; } 254 @@ -1533,6 +1549,7 @@ linedeftypes title = "Bustable Block"; prefix = "(254)"; flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; flags64text = "[6] Strong characters only"; flags128text = "[7] Only block non-players"; flags512text = "[9] Shattered by pushables"; @@ -1593,6 +1610,7 @@ linedeftypes { title = "Custom FOF"; prefix = "(259)"; + flags8text = "[3] Slope skew sides"; flags32text = "[5] Only block player"; flags128text = "[7] Only block non-players"; flags512text = "[9] Shattered by pushables"; @@ -2161,6 +2179,14 @@ linedeftypes flags8text = "[3] Set delay by backside sector"; } + 449 + { + title = "Enable Bosses with Parameter"; + prefix = "(449)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Disable bosses"; + } + 457 { title = "Track Object's Angle"; @@ -2180,12 +2206,14 @@ linedeftypes { title = "Award Rings"; prefix = "(460)"; + flags8text = "[3] Set delay by backside sector"; } 461 { title = "Spawn Object"; prefix = "(461)"; + flags8text = "[3] Set delay by backside sector"; flags64text = "[6] Spawn inside a range"; } @@ -2193,6 +2221,7 @@ linedeftypes { title = "Stop Timer/Exit Stage in Record Attack"; prefix = "(462)"; + flags8text = "[3] Set delay by backside sector"; } } @@ -2206,7 +2235,7 @@ linedeftypes prefix = "(413)"; flags2text = "[1] Keep after death"; flags8text = "[3] Set delay by backside sector"; - flags32text = "[5] Seek to current song position"; + flags32text = "[5] Seek from current position"; flags64text = "[6] For everyone"; flags128text = "[7] Fade to custom volume"; flags512text = "[9] Don't loop"; @@ -2220,7 +2249,7 @@ linedeftypes flags2text = "[1] From calling sector"; flags8text = "[3] Set delay by backside sector"; flags64text = "[6] From nowhere for triggerer"; - flags512text = "[9] For everyone"; + flags512text = "[9] From nowhere for everyone"; flags1024text = "[10] From tagged sectors"; } @@ -2298,7 +2327,6 @@ linedeftypes flags8text = "[3] Set delay by backside sector"; } - 445 { title = "Make FOF Disappear/Reappear"; @@ -2325,8 +2353,8 @@ linedeftypes flags32text = "[5] Subtract Red value"; flags64text = "[6] Subtract Green value"; flags128text = "[7] Subtract Blue value"; - flags256text = "[8] Calc relative values"; - flags32768text = "[15] Use back side colormap"; + flags256text = "[8] Set relative to current"; + flags32768text = "[15] Use backside colormap"; } 448 @@ -2359,7 +2387,7 @@ linedeftypes prefix = "(452)"; flags8text = "[3] Set delay by backside sector"; flags64text = "[6] Do not handle FF_TRANS"; - flags256text = "[8] Set relative to current val"; + flags256text = "[8] Set relative to current"; } 453 @@ -2371,7 +2399,7 @@ linedeftypes flags32text = "[5] No collision during fade"; flags64text = "[6] Do not handle FF_TRANS"; flags128text = "[7] Do not handle lighting"; - flags256text = "[8] Set relative to current val"; + flags256text = "[8] Set relative to current"; flags512text = "[9] Speed = Tic Duration"; flags1024text = "[10] Override existing fade"; flags16384text = "[14] Do not handle collision"; @@ -2395,11 +2423,11 @@ linedeftypes flags32text = "[5] Subtract Red value"; flags64text = "[6] Subtract Green value"; flags128text = "[7] Subtract Blue value"; - flags256text = "[8] Calc relative values"; + flags256text = "[8] Set relative to current"; flags512text = "[9] Speed = Tic Duration"; flags1024text = "[10] Override existing fade"; flags16384text = "[14] Fade from invisible black"; - flags32768text = "[15] Use back side colormap"; + flags32768text = "[15] Use backside colormap"; } 456 @@ -2416,9 +2444,7 @@ linedeftypes flags2text = "[1] Close text prompt"; flags8text = "[3] Set delay by backside sector"; flags32text = "[5] Run executor tag on close"; - flags64text = "[6] For everyone"; - flags128text = "[7] Do not block controls"; - flags256text = "[8] Do not freeze time"; + flags128text = "[7] Don't disable controls"; flags32768text = "[15] Find prompt by name"; } } @@ -2524,7 +2550,7 @@ linedeftypes prefix = "(491)"; flags8text = "[3] Set delay by backside sector"; flags16text = "[4] Set raw alpha by Front X"; - flags256text = "[8] Calc relative values"; + flags256text = "[8] Set relative to current"; } 492 @@ -2534,7 +2560,7 @@ linedeftypes flags8text = "[3] Set delay by backside sector"; flags16text = "[4] Set raw alpha by Front X"; flags32text = "[5] No collision during fade"; - flags256text = "[8] Calc relative values"; + flags256text = "[8] Set relative to current"; flags512text = "[9] Speed = Tic Duration"; flags1024text = "[10] Override existing fade"; flags16384text = "[14] Do not handle collision"; @@ -2632,76 +2658,84 @@ linedeftypes { title = "Carry Objects on Floor"; prefix = "(520)"; + flags64text = "[6] Exclusive"; } 521 { title = "Carry Objects on Floor (Accelerative)"; prefix = "(521)"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 522 { title = "Carry Objects on Floor (Displacement)"; prefix = "(522)"; + flags64text = "[6] Exclusive"; } 523 { title = "Carry Objects on Ceiling"; prefix = "(523)"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 524 { title = "Carry Objects on Ceiling (Accelerative)"; prefix = "(524)"; + flags64text = "[6] Exclusive"; } 525 { title = "Carry Objects on Ceiling (Displacement)"; prefix = "(525)"; + flags64text = "[6] Exclusive"; } 530 { title = "Scroll Floor Texture and Carry Objects"; prefix = "(530)"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 531 { title = "Scroll Floor Texture and Carry Objects (Accelerative)"; prefix = "(531)"; + flags64text = "[6] Exclusive"; } 532 { title = "Scroll Floor Texture and Carry Objects (Displacement)"; prefix = "(532)"; + flags64text = "[6] Exclusive"; } 533 { title = "Scroll Ceiling Texture and Carry Objects"; prefix = "(533)"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 534 { title = "Scroll Ceiling Texture and Carry Objects (Accelerative)"; prefix = "(534)"; + flags64text = "[6] Exclusive"; } 535 { title = "Scroll Ceiling Texture and Carry Objects (Displacement)"; prefix = "(535)"; + flags64text = "[6] Exclusive"; } } @@ -2714,7 +2748,7 @@ linedeftypes title = "Wind"; prefix = "(541)"; flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 542 @@ -2722,7 +2756,7 @@ linedeftypes title = "Upwards Wind"; prefix = "(542)"; flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 543 @@ -2730,7 +2764,7 @@ linedeftypes title = "Downwards Wind"; prefix = "(543)"; flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 544 @@ -2738,7 +2772,7 @@ linedeftypes title = "Current"; prefix = "(544)"; flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 545 @@ -2746,7 +2780,7 @@ linedeftypes title = "Upwards Current"; prefix = "(545)"; flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 546 @@ -2754,13 +2788,14 @@ linedeftypes title = "Downwards Current"; prefix = "(546)"; flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; + flags64text = "[6] Exclusive"; } 547 { title = "Push/Pull"; prefix = "(547)"; + flags64text = "[6] Exclusive"; } } @@ -3897,9 +3932,10 @@ thingtypes title = "Monitors"; width = 18; height = 40; - flags1text = "[1] Run Linedef Executor on pop"; + flags1text = "[1] Run linedef executor on pop"; flags4text = "[4] Random (Strong)"; flags8text = "[8] Random (Weak)"; + angletext = "Tag"; 400 { @@ -4029,7 +4065,8 @@ thingtypes title = "Monitors (Respawning)"; width = 20; height = 44; - flags1text = "[1] Run Linedef Executor on pop"; + flags1text = "[1] Run linedef executor on pop"; + angletext = "Tag"; 431 { @@ -4126,6 +4163,7 @@ thingtypes width = 64; height = 128; angletext = "Angle/Order"; + parametertext = "Order"; } 520 { @@ -4558,6 +4596,7 @@ thingtypes sprite = "TOADA0"; width = 32; height = 16; + angletext = "Tag"; } 757 { @@ -5832,7 +5871,7 @@ thingtypes sprite = "CAPSA0"; width = 72; height = 144; - angletext = "Rings"; + angletext = "Spheres"; parametertext = "Mare"; } } From f32ab5918ec39181e238ebf5333499718f73e4b5 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 21 Mar 2020 07:47:29 -0500 Subject: [PATCH 060/220] Define SERVER_URL_PROTOCOL const for easy reconfiguration --- src/d_main.c | 2 +- src/doomdef.h | 3 +++ src/m_argv.c | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index d954fa4d1..ec63242b8 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -895,7 +895,7 @@ static void IdentifyVersion(void) { size_t i; - CONS_Printf("srb2:// connect links load game files from the SRB2 application's stored directory. Switching to "); + CONS_Printf("%s connect links load game files from the SRB2 application's stored directory. Switching to ", SERVER_URL_PROTOCOL); strlcpy(srb2path, myargv[0], sizeof(srb2path)); // Get just the directory, minus the EXE name diff --git a/src/doomdef.h b/src/doomdef.h index 71c885019..5a5c933e3 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -150,6 +150,9 @@ extern char logfilename[1024]; // Otherwise we can't force updates! #endif +/* A custom URL protocol for server links. */ +#define SERVER_URL_PROTOCOL "srb2://" + // Does this version require an added patch file? // Comment or uncomment this as necessary. #define USE_PATCH_DTA diff --git a/src/m_argv.c b/src/m_argv.c index d7d1f4463..7d43d96bc 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -41,12 +41,13 @@ static INT32 found; const char *M_GetUrlProtocolArg(void) { INT32 i; + const size_t len = strlen(SERVER_URL_PROTOCOL); for (i = 1; i < myargc; i++) { - if (!strnicmp(myargv[i], "srb2://", 7)) + if (strlen(myargv[i]) > len && !strnicmp(myargv[i], SERVER_URL_PROTOCOL, len)) { - return &myargv[i][7]; + return &myargv[i][len]; } } From d2c83e1cdae12e0cd02493a4e6f4786b93a5a471 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 21 Mar 2020 15:16:07 +0100 Subject: [PATCH 061/220] Add Object Special text for Star Post --- extras/conf/SRB2-22.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 5119c1234..0168cf210 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -4162,6 +4162,7 @@ thingtypes sprite = "STPTA0M0"; width = 64; height = 128; + flags4text = "[4] Respawn at center"; angletext = "Angle/Order"; parametertext = "Order"; } From c806d8a5e8c6572d0acabcb4e9f2e1ce1d243693 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 21 Mar 2020 20:17:28 +0100 Subject: [PATCH 062/220] Another ZB config fix --- extras/conf/SRB2-22.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 0168cf210..57805a528 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3442,8 +3442,8 @@ thingtypes sprite = "ESHIA1"; width = 16; height = 48; - flags1text = "[1] 90 degrees counter-clockwise"; - flags4text = "[4] 90 degrees clockwise"; + flags1text = "[1] 90 degrees clockwise"; + flags4text = "[4] 90 degrees counter-clockwise"; flags8text = "[8] Double speed"; } 115 From 6911097b56afc99f8a0ef3329bcf9f3bf0e89230 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 22 Mar 2020 07:50:57 +0100 Subject: [PATCH 063/220] Minor ZB config fix --- extras/conf/SRB2-22.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 57805a528..12287ec80 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -6313,7 +6313,7 @@ thingtypes sprite = "PUMKA0"; width = 16; height = 40; - flags1text = "Don't flicker"; + flags1text = "[1] Don't flicker"; } 2007 { @@ -6321,7 +6321,7 @@ thingtypes sprite = "PUMKB0"; width = 16; height = 40; - flags1text = "Don't flicker"; + flags1text = "[1] Don't flicker"; } 2008 { @@ -6329,7 +6329,7 @@ thingtypes sprite = "PUMKC0"; width = 16; height = 40; - flags1text = "Don't flicker"; + flags1text = "[1] Don't flicker"; } 2009 { From 48e8c9058a1ea98531e5887abd76cdbc13b550ac Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 22 Mar 2020 12:55:34 +0100 Subject: [PATCH 064/220] Add arrow to wall spike in ZB config --- extras/conf/SRB2-22.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 12287ec80..ec030b32f 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -4191,6 +4191,7 @@ thingtypes sprite = "WSPKALAR"; width = 16; height = 14; + arrow = 1; flags1text = "[1] Start retracted"; flags4text = "[4] Retractable"; flags8text = "[8] Intangible"; From deff1565dc5945f56d9e45478e684dd868d27856 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 22 Mar 2020 12:13:59 -0500 Subject: [PATCH 065/220] GL horizon lines --- src/hardware/hw_main.c | 172 ++++++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 80 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index efed9b602..a3a1ba692 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -20,6 +20,7 @@ #include "../doomstat.h" +#define HWRENDER #ifdef HWRENDER #include "hw_glob.h" #include "hw_light.h" @@ -469,7 +470,7 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this c // -----------------+ // HWR_RenderPlane : Render a floor or ceiling convex polygon // -----------------+ -static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, +static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap) { polyvertex_t * pv; @@ -493,8 +494,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; - (void)sector; ///@TODO remove shitty unused variable - // no convex poly were generated for this subsector if (!xsub->planepoly) return; @@ -593,8 +592,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight); // transform - v3d = planeVerts; - if (FOFsector != NULL) { if (!isceiling) // it's a floor @@ -637,46 +634,43 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); } - for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) - { - // Hurdler: add scrolling texture on floor/ceiling - if (texflat) - { - v3d->sow = (float)(pv->x / fflatwidth) + scrollx; - v3d->tow = -(float)(pv->y / fflatheight) + scrolly; - } - else - { - v3d->sow = (float)((pv->x / fflatwidth) - flatxref + scrollx); - v3d->tow = (float)(flatyref - (pv->y / fflatheight) + scrolly); - } +#define SETUP3DVERT(vert, vx, vy) {\ + /* Hurdler: add scrolling texture on floor/ceiling */\ + if (texflat)\ + {\ + vert->sow = (float)((vx) / fflatwidth) + scrollx;\ + vert->tow = -(float)((vy) / fflatheight) + scrolly;\ + }\ + else\ + {\ + vert->sow = (float)(((vx) / fflatwidth) - flatxref + scrollx);\ + vert->tow = (float)(flatyref - ((vy) / fflatheight) + scrolly);\ + }\ +\ + /* Need to rotate before translate */\ + if (angle) /* Only needs to be done if there's an altered angle */\ + {\ + tempxsow = FLOAT_TO_FIXED(vert->sow);\ + tempytow = FLOAT_TO_FIXED(vert->tow);\ + if (texflat)\ + tempytow = -tempytow;\ + vert->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));\ + vert->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));\ + }\ +\ + vert->x = (vx);\ + vert->y = height;\ + vert->z = (vy);\ +\ + if (slope)\ + {\ + fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)));\ + vert->y = FIXED_TO_FLOAT(fixedheight);\ + }\ +} - // Need to rotate before translate - if (angle) // Only needs to be done if there's an altered angle - { - tempxsow = FLOAT_TO_FIXED(v3d->sow); - tempytow = FLOAT_TO_FIXED(v3d->tow); - if (texflat) - tempytow = -tempytow; - v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - v3d->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); - } - - //v3d->sow = (float)(v3d->sow - flatxref + scrollx); - //v3d->tow = (float)(flatyref - v3d->tow + scrolly); - - v3d->x = pv->x; - v3d->y = height; - v3d->z = pv->y; - -#ifdef ESLOPE - if (slope) - { - fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED(pv->x), FLOAT_TO_FIXED(pv->y)); - v3d->y = FIXED_TO_FLOAT(fixedheight); - } -#endif - } + for (i = 0, v3d = planeVerts; i < nrPlaneVerts; i++,v3d++,pv++) + SETUP3DVERT(v3d, pv->x, pv->y); // only useful for flat coloured triangles //Surf.FlatColor = 0xff804020; @@ -687,38 +681,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = LightLevelToLum(lightlevel); // Don't take from the frontsector, or the game will crash -#if 0 // no colormap test - // colormap test - if (gr_frontsector) - { - sector_t *psector = gr_frontsector; - -#ifdef ESLOPE - if (slope) - fixedheight = P_GetZAt(slope, psector->soundorg.x, psector->soundorg.y); -#endif - - if (psector->ffloors) - { - ffloor_t *caster = psector->lightlist[R_GetPlaneLight(psector, fixedheight, false)].caster; - psector = caster ? §ors[caster->secnum] : psector; - - if (caster) - { - lightlevel = psector->lightlevel; - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = LightLevelToLum(lightlevel); - } - } - if (psector->extra_colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel,psector->extra_colormap->rgba,psector->extra_colormap->fadergba, false, true); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true); - } - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true); - -#endif // NOPE - if (planecolormap) { if (fogplane) @@ -744,6 +706,56 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags); + if (subsector) + { + // Horizon lines + FOutVector horizonpts[5]; + float dist, vx, vy; + const float renderdist = 60000.0f; // Well past the Z cutoff plane, but needed to fill out to that point at a wider angle + + seg_t *line = &segs[subsector->firstline]; + + for (i = 0; i < subsector->numlines; i++, line++) + { + if (!line->glseg && line->linedef->special == HORIZONSPECIAL && R_PointOnSegSide(dup_viewx, dup_viewy, line) == 0) + { + //SETUP3DVERT(horizonpts[1], FIXED_TO_FLOAT(line->v1->x), FIXED_TO_FLOAT(line->v1->y)); + //SETUP3DVERT(horizonpts[2], FIXED_TO_FLOAT(line->v2->x), FIXED_TO_FLOAT(line->v2->y)); + + // Left side + vx = ((polyvertex_t *)line->pv1)->x; + vy = ((polyvertex_t *)line->pv1)->y; + SETUP3DVERT((&horizonpts[1]), vx, vy); + + dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); + vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; + vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + SETUP3DVERT((&horizonpts[0]), vx, vy); + + // Right side + vx = ((polyvertex_t *)line->pv2)->x; + vy = ((polyvertex_t *)line->pv2)->y; + SETUP3DVERT((&horizonpts[2]), vx, vy); + + dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); + vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; + vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + SETUP3DVERT((&horizonpts[3]), vx, vy); + + // Midpoint for better filling + vx = (horizonpts[0].x + horizonpts[3].x)/2; + vy = (horizonpts[0].z + horizonpts[3].z)/2; + dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); + vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; + vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + SETUP3DVERT((&horizonpts[4]), vx, vy); + + // Draw + HWD.pfnDrawPolygon(&Surf, horizonpts, 5, PolyFlags); + } + } + } + #ifdef ALAM_LIGHTING // add here code for dynamic lighting on planes HWR_PlaneLighting(planeVerts, nrPlaneVerts); @@ -3561,7 +3573,7 @@ static void HWR_Subsector(size_t num) if (sub->validcount != validcount) { HWR_GetLevelFlat(&levelflats[gr_frontsector->floorpic]); - HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false, + HWR_RenderPlane(sub, &extrasubsectors[num], false, // Hack to make things continue to work around slopes. locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight, // We now return you to your regularly scheduled rendering. @@ -3583,7 +3595,7 @@ static void HWR_Subsector(size_t num) if (sub->validcount != validcount) { HWR_GetLevelFlat(&levelflats[gr_frontsector->ceilingpic]); - HWR_RenderPlane(NULL, &extrasubsectors[num], true, + HWR_RenderPlane(sub, &extrasubsectors[num], true, // Hack to make things continue to work around slopes. locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight, // We now return you to your regularly scheduled rendering. @@ -3677,7 +3689,7 @@ static void HWR_Subsector(size_t num) { HWR_GetLevelFlat(&levelflats[*rover->bottompic]); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); - HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic], + HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic], rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); } } @@ -3741,7 +3753,7 @@ static void HWR_Subsector(size_t num) { HWR_GetLevelFlat(&levelflats[*rover->toppic]); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); - HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic], + HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic], rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); } } From 14d6a012928443ba8699f1a2834800193bb70c1f Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 22 Mar 2020 12:20:26 -0500 Subject: [PATCH 066/220] Distort far edges to viewz for a flat horizon line --- src/hardware/hw_main.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a3a1ba692..253deb282 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -709,9 +709,10 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool if (subsector) { // Horizon lines - FOutVector horizonpts[5]; + FOutVector horizonpts[6]; float dist, vx, vy; - const float renderdist = 60000.0f; // Well past the Z cutoff plane, but needed to fill out to that point at a wider angle + const float renderdist = 30000.0f; // How far out to properly render the plane + const float farrenderdist = 32768.0f; // From here, raise plane to horizon level to fill in the line with some texture distortion seg_t *line = &segs[subsector->firstline]; @@ -742,16 +743,19 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; SETUP3DVERT((&horizonpts[3]), vx, vy); - // Midpoint for better filling - vx = (horizonpts[0].x + horizonpts[3].x)/2; - vy = (horizonpts[0].z + horizonpts[3].z)/2; - dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); - vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; - vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + // Horizon fills + vx = (horizonpts[0].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; + vy = (horizonpts[0].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; + SETUP3DVERT((&horizonpts[5]), vx, vy); + horizonpts[5].y = gr_viewz; + + vx = (horizonpts[3].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; + vy = (horizonpts[3].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; SETUP3DVERT((&horizonpts[4]), vx, vy); + horizonpts[4].y = gr_viewz; // Draw - HWD.pfnDrawPolygon(&Surf, horizonpts, 5, PolyFlags); + HWD.pfnDrawPolygon(&Surf, horizonpts, 6, PolyFlags); } } } From f9027ccaebcabed8b7b3de12b1c0efa0d098e22d Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 22 Mar 2020 12:52:17 -0500 Subject: [PATCH 067/220] Split horizon lines for minimal distortion --- src/hardware/hw_main.c | 78 ++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 253deb282..9a0805d57 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -20,7 +20,6 @@ #include "../doomstat.h" -#define HWRENDER #ifdef HWRENDER #include "hw_glob.h" #include "hw_light.h" @@ -711,6 +710,10 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool // Horizon lines FOutVector horizonpts[6]; float dist, vx, vy; + float x1, y1, xd, yd; + UINT8 numplanes, j; + vertex_t v; // For determining the closest distance from the line to the camera, to split render planes for minimum distortion; + const float renderdist = 30000.0f; // How far out to properly render the plane const float farrenderdist = 32768.0f; // From here, raise plane to horizon level to fill in the line with some texture distortion @@ -720,42 +723,57 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool { if (!line->glseg && line->linedef->special == HORIZONSPECIAL && R_PointOnSegSide(dup_viewx, dup_viewy, line) == 0) { - //SETUP3DVERT(horizonpts[1], FIXED_TO_FLOAT(line->v1->x), FIXED_TO_FLOAT(line->v1->y)); - //SETUP3DVERT(horizonpts[2], FIXED_TO_FLOAT(line->v2->x), FIXED_TO_FLOAT(line->v2->y)); + P_ClosestPointOnLine(viewx, viewy, line->linedef, &v); + dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y)); - // Left side - vx = ((polyvertex_t *)line->pv1)->x; - vy = ((polyvertex_t *)line->pv1)->y; - SETUP3DVERT((&horizonpts[1]), vx, vy); + x1 = ((polyvertex_t *)line->pv1)->x; + y1 = ((polyvertex_t *)line->pv1)->y; + xd = ((polyvertex_t *)line->pv2)->x - x1; + yd = ((polyvertex_t *)line->pv2)->y - y1; - dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); - vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; - vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; - SETUP3DVERT((&horizonpts[0]), vx, vy); + // Based on the seg length and the distance from the line, split horizon into multiple poly sets to reduce distortion + dist = sqrtf((xd*xd) + (yd*yd)) / dist / 16.0f; + if (dist > 100.0f) + numplanes = 100; + else + numplanes = (UINT8)dist + 1; - // Right side - vx = ((polyvertex_t *)line->pv2)->x; - vy = ((polyvertex_t *)line->pv2)->y; - SETUP3DVERT((&horizonpts[2]), vx, vy); + for (j = 0; j < numplanes; j++) + { + // Left side + vx = x1 + xd * j / numplanes; + vy = y1 + yd * j / numplanes; + SETUP3DVERT((&horizonpts[1]), vx, vy); - dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); - vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; - vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; - SETUP3DVERT((&horizonpts[3]), vx, vy); + dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); + vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; + vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + SETUP3DVERT((&horizonpts[0]), vx, vy); - // Horizon fills - vx = (horizonpts[0].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; - vy = (horizonpts[0].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; - SETUP3DVERT((&horizonpts[5]), vx, vy); - horizonpts[5].y = gr_viewz; + // Right side + vx = x1 + xd * (j+1) / numplanes; + vy = y1 + yd * (j+1) / numplanes; + SETUP3DVERT((&horizonpts[2]), vx, vy); - vx = (horizonpts[3].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; - vy = (horizonpts[3].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; - SETUP3DVERT((&horizonpts[4]), vx, vy); - horizonpts[4].y = gr_viewz; + dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); + vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; + vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + SETUP3DVERT((&horizonpts[3]), vx, vy); - // Draw - HWD.pfnDrawPolygon(&Surf, horizonpts, 6, PolyFlags); + // Horizon fills + vx = (horizonpts[0].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; + vy = (horizonpts[0].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; + SETUP3DVERT((&horizonpts[5]), vx, vy); + horizonpts[5].y = gr_viewz; + + vx = (horizonpts[3].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; + vy = (horizonpts[3].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; + SETUP3DVERT((&horizonpts[4]), vx, vy); + horizonpts[4].y = gr_viewz; + + // Draw + HWD.pfnDrawPolygon(&Surf, horizonpts, 6, PolyFlags); + } } } } From 719f29d27e828c14eb4454ddbceaa056a66c3217 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 23 Mar 2020 08:23:36 -0500 Subject: [PATCH 068/220] Reduce near renderdist to lessen visible texture distortion --- 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 9a0805d57..62464c951 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -714,7 +714,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool UINT8 numplanes, j; vertex_t v; // For determining the closest distance from the line to the camera, to split render planes for minimum distortion; - const float renderdist = 30000.0f; // How far out to properly render the plane + const float renderdist = 27000.0f; // How far out to properly render the plane const float farrenderdist = 32768.0f; // From here, raise plane to horizon level to fill in the line with some texture distortion seg_t *line = &segs[subsector->firstline]; From 99a5192872b6ad9d827985a38de4dc9411c08e38 Mon Sep 17 00:00:00 2001 From: sphere Date: Tue, 24 Mar 2020 16:10:30 +0100 Subject: [PATCH 069/220] Hide record/NiGHTS attack if there are no available maps for them. --- src/m_menu.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 6c22c6586..c6babc805 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7990,12 +7990,18 @@ static void M_CustomLevelSelect(INT32 choice) static void M_SinglePlayerMenu(INT32 choice) { (void)choice; - SP_MainMenu[sptutorial].status = - tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; - SP_MainMenu[sprecordattack].status = - (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; - SP_MainMenu[spnightsmode].status = - (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; + + if (M_GametypeHasLevels(LLM_RECORDATTACK)) + SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; + else + SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED; + + if (M_GametypeHasLevels(LLM_NIGHTSATTACK)) + SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; + else + SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED; + + SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; M_SetupNextMenu(&SP_MainDef); } From 60f7e35383e91d043dcc5c3e8e441faf9dc26d3d Mon Sep 17 00:00:00 2001 From: Sonic Edge Date: Tue, 24 Mar 2020 16:21:33 -0400 Subject: [PATCH 070/220] Character select in Nights mode. --- src/m_menu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 6c22c6586..259c2cb4c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -879,7 +879,8 @@ static menuitem_t SP_NightsAttackLevelSelectMenu[] = static menuitem_t SP_NightsAttackMenu[] = { {IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", &M_HandleTimeAttackLevelSelect, 52}, - {IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 62}, + {IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 62}, + {IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 72}, {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 100}, {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 110}, @@ -890,6 +891,7 @@ static menuitem_t SP_NightsAttackMenu[] = enum { nalevel, + nachar, narecords, naguest, From 92c74814cf20a9351f8bc36887378531155dbf6b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 25 Mar 2020 08:34:52 +0100 Subject: [PATCH 071/220] Standardize the behavior of FF_INVERTSIDES and FF_INVERTPLANES --- src/dehacked.c | 4 ++-- src/hardware/hw_main.c | 12 ++++++++---- src/p_sight.c | 4 ++-- src/p_spec.c | 2 +- src/r_bsp.c | 8 ++++---- src/r_defs.h | 4 ++-- src/r_segs.c | 28 ++++++++++++++++------------ 7 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c6cd0b9e5..20d23d680 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9648,11 +9648,11 @@ struct { {"FF_CUTEXTRA",FF_CUTEXTRA}, ///< Cuts out hidden translucent pixels. {"FF_CUTLEVEL",FF_CUTLEVEL}, ///< Cuts out all hidden pixels. {"FF_CUTSPRITES",FF_CUTSPRITES}, ///< Final step in making 3D water. - {"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Renders both planes all the time. + {"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Render inside and outside planes. {"FF_EXTRA",FF_EXTRA}, ///< Gets cut by ::FF_CUTEXTRA. {"FF_TRANSLUCENT",FF_TRANSLUCENT}, ///< See through! {"FF_FOG",FF_FOG}, ///< Fog "brush." - {"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Reverse the plane visibility rules. + {"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Only render inside planes. {"FF_ALLSIDES",FF_ALLSIDES}, ///< Render inside and outside sides. {"FF_INVERTSIDES",FF_INVERTSIDES}, ///< Only render inside sides. {"FF_DOUBLESHADOW",FF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light? diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c56f0ec06..51c6471ac 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1902,7 +1902,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { for (rover = gr_backsector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES) || (rover->flags & FF_INVERTSIDES)) + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES)) + continue; + if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES) continue; if (*rover->topheight < lowcut || *rover->bottomheight > highcut) continue; @@ -2042,7 +2044,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { for (rover = gr_frontsector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_ALLSIDES)) + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES)) + continue; + if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) continue; if (*rover->topheight < lowcut || *rover->bottomheight > highcut) continue; @@ -3427,7 +3431,7 @@ static void HWR_Subsector(size_t num) if (centerHeight <= locCeilingHeight && centerHeight >= locFloorHeight && - ((dup_viewz < cullHeight && !(rover->flags & FF_INVERTPLANES)) || + ((dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || (dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { if (rover->flags & FF_FOG) @@ -3488,7 +3492,7 @@ static void HWR_Subsector(size_t num) if (centerHeight >= locFloorHeight && centerHeight <= locCeilingHeight && - ((dup_viewz > cullHeight && !(rover->flags & FF_INVERTPLANES)) || + ((dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || (dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { if (rover->flags & FF_FOG) diff --git a/src/p_sight.c b/src/p_sight.c index c9083b99b..3d1ee9e60 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -495,7 +495,7 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) if (rover->flags & FF_SOLID) continue; // shortcut since neither mobj can be inside the 3dfloor - if (!(rover->flags & FF_INVERTPLANES)) + if (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)) { if (los.sightzstart >= topz1 && t2->z + t2->height < topz2) return false; // blocked by upper outside plane @@ -504,7 +504,7 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) return false; // blocked by lower outside plane } - if (rover->flags & FF_INVERTPLANES || rover->flags & FF_BOTHPLANES) + if (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES) { if (los.sightzstart < topz1 && t2->z >= topz2) return false; // blocked by upper inside plane diff --git a/src/p_spec.c b/src/p_spec.c index cd26dcf9e..dee816e47 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7069,7 +7069,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 202: // Fog - ffloorflags = FF_EXISTS|FF_RENDERALL|FF_FOG|FF_BOTHPLANES|FF_INVERTPLANES|FF_ALLSIDES|FF_INVERTSIDES|FF_CUTEXTRA|FF_EXTRA|FF_DOUBLESHADOW|FF_CUTSPRITES; + ffloorflags = FF_EXISTS|FF_RENDERALL|FF_FOG|FF_INVERTPLANES|FF_INVERTSIDES|FF_CUTEXTRA|FF_EXTRA|FF_DOUBLESHADOW|FF_CUTSPRITES; sec = sides[*lines[i].sidenum].sector - sectors; // SoM: Because it's fog, check for an extra colormap and set the fog flag... if (sectors[sec].extra_colormap) diff --git a/src/r_bsp.c b/src/r_bsp.c index 85113be43..77ab2a82f 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -955,8 +955,8 @@ static void R_Subsector(size_t num) *rover->bottomheight; if (planecenterz <= ceilingcenterz && planecenterz >= floorcenterz - && ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES)) - || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES)))) + && ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) + || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck); @@ -993,8 +993,8 @@ static void R_Subsector(size_t num) *rover->topheight; if (planecenterz >= floorcenterz && planecenterz <= ceilingcenterz - && ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES)) - || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES)))) + && ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) + || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck); diff --git a/src/r_defs.h b/src/r_defs.h index 0c6ff1d30..5f62ec058 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -130,11 +130,11 @@ typedef enum FF_CUTEXTRA = 0x100, ///< Cuts out hidden translucent pixels. FF_CUTLEVEL = 0x180, ///< Cuts out all hidden pixels. FF_CUTSPRITES = 0x200, ///< Final step in making 3D water. - FF_BOTHPLANES = 0x400, ///< Renders both planes all the time. + FF_BOTHPLANES = 0x400, ///< Render inside and outside planes. FF_EXTRA = 0x800, ///< Gets cut by ::FF_CUTEXTRA. FF_TRANSLUCENT = 0x1000, ///< See through! FF_FOG = 0x2000, ///< Fog "brush." - FF_INVERTPLANES = 0x4000, ///< Reverse the plane visibility rules. + FF_INVERTPLANES = 0x4000, ///< Only render inside planes. FF_ALLSIDES = 0x8000, ///< Render inside and outside sides. FF_INVERTSIDES = 0x10000, ///< Only render inside sides. FF_DOUBLESHADOW = 0x20000, ///< Make two lightlist entries to reset light? diff --git a/src/r_segs.c b/src/r_segs.c index d8f1981ee..d4b07ff13 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2165,7 +2165,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) continue; - if (rover->flags & FF_INVERTSIDES) + if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES) continue; if (rover->norender == leveltime) @@ -2220,7 +2220,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) continue; - if (!(rover->flags & FF_ALLSIDES)) + if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) continue; if (rover->norender == leveltime) @@ -2275,7 +2275,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) { for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES) continue; if (rover->norender == leveltime) continue; @@ -2295,7 +2297,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) { for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) continue; if (rover->norender == leveltime) continue; @@ -2620,8 +2624,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + ((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { //ffloor[i].slope = *rover->b_slope; ffloor[i].b_pos = roverleft; @@ -2643,8 +2647,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + ((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { //ffloor[i].slope = *rover->t_slope; ffloor[i].b_pos = roverleft; @@ -2677,8 +2681,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + ((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { //ffloor[i].slope = *rover->b_slope; ffloor[i].b_pos = roverleft; @@ -2700,8 +2704,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + ((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { //ffloor[i].slope = *rover->t_slope; ffloor[i].b_pos = roverleft; From ce2a1aa3b24108691d7ba58ca6945a8653f0d7c7 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 11 Jan 2020 16:24:00 +0000 Subject: [PATCH 072/220] Minor optimisations surrounding R_DrawFlippedMaskedColumn. * Replace the texheight parameter provided directly to it with a previously existing (now renamed) global used for the same purpose, so that it can be used as an interchangeable function pointer with R_DrawMaskedColumn. * Using the above, optimise R_DrawVisSprite to call a function pointer in a tighter loop rather than check SC_VFLIP each time around. * SHORT macro can involve repeated operations; calculate once and put in memory for both RANGECHECK and papersprite. * Remove irrelevant range check (already covered by existing range check immediately above) from R_DrawFlippedMaskedColumn and R_DrawMaskedColumn. * "Warning: avoiding a crash in %s %d" is a terrible error message, and it chips away at the tightness of the loop just for something most people will never see printed. Replace with a PARANOIA I_Error in case someone actively wants to go hunting for its cause. --- src/r_segs.c | 22 ++++++---------- src/r_things.c | 68 ++++++++++++++++++++++++-------------------------- src/r_things.h | 3 ++- 3 files changed, 41 insertions(+), 52 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 0233b1161..32a922147 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -240,14 +240,13 @@ static void R_DrawWallSplats(void) // way we don't have to store extra post_t info with each column for // multi-patch textures. They are not normally needed as multi-patch // textures don't have holes in it. At least not for now. -static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height static void R_Render2sidedMultiPatchColumn(column_t *column) { INT32 topscreen, bottomscreen; topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall - bottomscreen = topscreen + spryscale * column2s_length; + bottomscreen = topscreen + spryscale * lengthcol; dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; dc_yh = (bottomscreen-1)>>FRACBITS; @@ -279,13 +278,6 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) } } -// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value -// uses column2s_length for texture->height as above -static void R_DrawFlippedMaskedSegColumn(column_t *column) -{ - R_DrawFlippedMaskedColumn(column, column2s_length); -} - void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { size_t pindex; @@ -364,8 +356,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { if (textures[texnum]->flip & 2) // vertically flipped? { - colfunc_2s = R_DrawFlippedMaskedSegColumn; - column2s_length = textures[texnum]->height; + colfunc_2s = R_DrawFlippedMaskedColumn; + lengthcol = textures[texnum]->height; } else colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture @@ -373,7 +365,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) else { colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - column2s_length = textures[texnum]->height; + lengthcol = textures[texnum]->height; } // Setup lighting based on the presence/lack-of 3D floors. @@ -733,7 +725,7 @@ static void R_DrawRepeatMaskedColumn(column_t *col) static void R_DrawRepeatFlippedMaskedColumn(column_t *col) { do { - R_DrawFlippedMaskedColumn(col, column2s_length); + R_DrawFlippedMaskedColumn(col); sprtopscreen += dc_texheight*spryscale; } while (sprtopscreen < sprbotscreen); } @@ -1065,7 +1057,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (textures[texnum]->flip & 2) // vertically flipped? { colfunc_2s = R_DrawRepeatFlippedMaskedColumn; - column2s_length = textures[texnum]->height; + lengthcol = textures[texnum]->height; } else colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture @@ -1073,7 +1065,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else { colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) - column2s_length = textures[texnum]->height; + lengthcol = textures[texnum]->height; } #ifdef ESLOPE diff --git a/src/r_things.c b/src/r_things.c index 2fc44faf8..d2f3b4902 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -641,10 +641,10 @@ void R_DrawMaskedColumn(column_t *column) dc_yl = mceilingclip[dc_x]+1; if (dc_yl < 0) dc_yl = 0; - if (dc_yh >= vid.height) + if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop dc_yh = vid.height - 1; - if (dc_yl <= dc_yh && dc_yl < vid.height && dc_yh > 0) + if (dc_yl <= dc_yh && dc_yh > 0) { dc_source = (UINT8 *)column + 3; dc_texturemid = basetexturemid - (topdelta<length + 4); } @@ -671,7 +666,9 @@ void R_DrawMaskedColumn(column_t *column) dc_texturemid = basetexturemid; } -void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) +INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height + +void R_DrawFlippedMaskedColumn(column_t *column) { INT32 topscreen; INT32 bottomscreen; @@ -687,7 +684,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) if (topdelta <= prevdelta) topdelta += prevdelta; prevdelta = topdelta; - topdelta = texheight-column->length-topdelta; + topdelta = lengthcol-column->length-topdelta; topscreen = sprtopscreen + spryscale*topdelta; bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*column->length : sprbotscreen + spryscale*column->length; @@ -709,10 +706,10 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) dc_yl = mceilingclip[dc_x]+1; if (dc_yl < 0) dc_yl = 0; - if (dc_yh >= vid.height) + if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop dc_yh = vid.height - 1; - if (dc_yl <= dc_yh && dc_yl < vid.height && dc_yh > 0) + if (dc_yl <= dc_yh && dc_yh > 0) { dc_source = ZZ_Alloc(column->length); for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s) @@ -722,15 +719,10 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) // Still drawn by R_DrawColumn. if (ylookup[dc_yl]) colfunc(); - else if (colfunc == colfuncs[COLDRAWFUNC_BASE]) - { - static INT32 first = 1; - if (first) - { - CONS_Debug(DBG_RENDER, "WARNING: avoiding a crash in %s %d\n", __FILE__, __LINE__); - first = 0; - } - } +#ifdef PARANOIA + else + I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl); +#endif Z_Free(dc_source); } column = (column_t *)((UINT8 *)column + column->length + 4); @@ -746,7 +738,9 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) static void R_DrawVisSprite(vissprite_t *vis) { column_t *column; + void (*localcolfunc)(column_t *); INT32 texturecolumn; + INT32 pwidth; fixed_t frac; patch_t *patch = vis->patch; fixed_t this_scale = vis->mobj->scale; @@ -895,50 +889,52 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->x2 >= vid.width) vis->x2 = vid.width-1; + localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn; + lengthcol = patch->height; + // Split drawing loops for paper and non-paper to reduce conditional checks per sprite if (vis->scalestep) { - // Papersprite drawing loop + pwidth = SHORT(patch->width); + // Papersprite drawing loop for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep) { angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale; - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + if (texturecolumn < 0 || texturecolumn >= pwidth) continue; if (vis->xiscale < 0) // Flipped sprite - texturecolumn = SHORT(patch->width) - 1 - texturecolumn; + texturecolumn = pwidth - 1 - texturecolumn; sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); - if (vis->cut & SC_VFLIP) - R_DrawFlippedMaskedColumn(column, patch->height); - else - R_DrawMaskedColumn(column); + localcolfunc (column); } } else { +#ifdef RANGECHECK + pwidth = SHORT(patch->width); +#endif + // Non-paper drawing loop for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan) { #ifdef RANGECHECK texturecolumn = frac>>FRACBITS; - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + if (texturecolumn < 0 || texturecolumn >= pwidth) I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); #else column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); #endif - if (vis->cut & SC_VFLIP) - R_DrawFlippedMaskedColumn(column, patch->height); - else - R_DrawMaskedColumn(column); + localcolfunc (column); } } diff --git a/src/r_things.h b/src/r_things.h index 05d6fb27b..7a0fe3a60 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -44,9 +44,10 @@ extern fixed_t sprtopscreen; extern fixed_t sprbotscreen; extern fixed_t windowtop; extern fixed_t windowbottom; +extern INT32 lengthcol; void R_DrawMaskedColumn(column_t *column); -void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight); +void R_DrawFlippedMaskedColumn(column_t *column); // ---------------- // SPRITE RENDERING From da86c17ee112b833c6fe29192105e192be548656 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 26 Mar 2020 20:16:44 +0000 Subject: [PATCH 073/220] Disable continues outside of no-save/Ultimate by default, but allow SOC to re-enable them globally. Please look at the merge request description for a full explanation, since I know the vanilla team has been hashing this out and I don't want to add fuel to the fire without at least presenting a solid case. --- src/dehacked.c | 4 +++ src/doomstat.h | 2 ++ src/f_finale.c | 6 ++-- src/g_game.c | 4 ++- src/m_cheat.c | 6 ++++ src/m_menu.c | 84 +++++++++++++++++++++++++++++++++++++------------- src/m_menu.h | 2 +- src/p_inter.c | 5 ++- src/p_user.c | 6 ++-- src/y_inter.c | 2 +- 10 files changed, 90 insertions(+), 31 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 20d23d680..6d6fdf838 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4122,6 +4122,10 @@ static void readmaincfg(MYFILE *f) { maxXtraLife = (UINT8)get_number(word2); } + else if (fastcmp(word, "USECONTINUES")) + { + useContinues = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y'); + } else if (fastcmp(word, "GAMEDATA")) { diff --git a/src/doomstat.h b/src/doomstat.h index 893514b32..aedb120ff 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -575,6 +575,8 @@ extern UINT8 creditscutscene; extern UINT8 use1upSound; extern UINT8 maxXtraLife; // Max extra lives from rings +extern UINT8 useContinues; +#define continuesInSession (!multiplayer && (useContinues || ultimatemode || !(cursaveslot > 0))) extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations diff --git a/src/f_finale.c b/src/f_finale.c index 95535a7ea..825f646b0 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -3618,7 +3618,7 @@ void F_StartContinue(void) { I_Assert(!netgame && !multiplayer); - if (players[consoleplayer].continues <= 0) + if (continuesInSession && players[consoleplayer].continues <= 0) { Command_ExitGame_f(); return; @@ -3725,7 +3725,9 @@ void F_ContinueDrawer(void) } // Draw the continue markers! Show continues. - if (ncontinues > 10) + if (!continuesInSession) + ; + else if (ncontinues > 10) { if (!(continuetime & 1) || continuetime > 17) V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor); diff --git a/src/g_game.c b/src/g_game.c index 6dba6045a..92d71fbae 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -219,6 +219,7 @@ UINT8 ammoremovaltics = 2*TICRATE; UINT8 use1upSound = 0; UINT8 maxXtraLife = 2; // Max extra lives from rings +UINT8 useContinues = 0; // Set to 1 to enable continues outside of no-save scenarioes UINT8 introtoplay; UINT8 creditscutscene; @@ -3859,7 +3860,8 @@ static void G_DoContinued(void) I_Assert(!netgame && !multiplayer); I_Assert(pl->continues > 0); - pl->continues--; + if (pl->continues) + pl->continues--; // Reset score pl->score = 0; diff --git a/src/m_cheat.c b/src/m_cheat.c index 4a1a4fb58..f6fdb63e9 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -934,6 +934,12 @@ void Command_Setcontinues_f(void) REQUIRE_NOULTIMATE; REQUIRE_PANDORA; + if (!continuesInSession) + { + CONS_Printf(M_GetText("This session does not use continues.\n")); + return; + } + if (COM_Argc() > 1) { INT32 numcontinues = atoi(COM_Argv(1)); diff --git a/src/m_menu.c b/src/m_menu.c index f8240d403..a08b40909 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6724,6 +6724,7 @@ static void M_PandorasBox(INT32 choice) else CV_StealthSetValue(&cv_dummylives, max(players[consoleplayer].lives, 1)); CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues); + SR_PandorasBox[3].status = (continuesInSession) ? (IT_STRING | IT_CVAR) : (IT_GRAYEDOUT); SR_PandorasBox[6].status = (players[consoleplayer].charflags & SF_SUPER) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); SR_PandorasBox[7].status = (emeralds == ((EMERALD7)*2)-1) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); M_SetupNextMenu(&SR_PandoraDef); @@ -6740,7 +6741,7 @@ static boolean M_ExitPandorasBox(void) } if (cv_dummylives.value != players[consoleplayer].lives) COM_ImmedExecute(va("setlives %d", cv_dummylives.value)); - if (cv_dummycontinues.value != players[consoleplayer].continues) + if (continuesInSession && cv_dummycontinues.value != players[consoleplayer].continues) COM_ImmedExecute(va("setcontinues %d", cv_dummycontinues.value)); return true; } @@ -8251,9 +8252,19 @@ static void M_DrawLoadGameData(void) V_DrawRightAlignedThinString(x + 79, y, V_YELLOWMAP, savegameinfo[savetodraw].levelname); } - if ((savegameinfo[savetodraw].lives == -42) - || (savegameinfo[savetodraw].lives == -666)) + if (savegameinfo[savetodraw].lives == -42) + { + if (!useContinues) + V_DrawRightAlignedThinString(x + 80, y+1+60+16, V_GRAYMAP, "00000000"); continue; + } + + if (savegameinfo[savetodraw].lives == -666) + { + if (!useContinues) + V_DrawRightAlignedThinString(x + 80, y+1+60+16, V_REDMAP, "????????"); + continue; + } y += 64; @@ -8270,7 +8281,7 @@ static void M_DrawLoadGameData(void) y -= 4; - // character heads, lives, and continues + // character heads, lives, and continues/score { spritedef_t *sprdef; spriteframe_t *sprframe; @@ -8321,10 +8332,14 @@ skipbot: skipsign: y += 16; - tempx = x + 10; - if (savegameinfo[savetodraw].lives != INFLIVES - && savegameinfo[savetodraw].lives > 9) - tempx -= 4; + tempx = x; + if (useContinues) + { + tempx += 10; + if (savegameinfo[savetodraw].lives != INFLIVES + && savegameinfo[savetodraw].lives > 9) + tempx -= 4; + } if (!charskin) // shut up compiler goto skiplife; @@ -8354,22 +8369,45 @@ skiplife: else V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives)); - tempx = x + 47; - if (savegameinfo[savetodraw].continues > 9) - tempx -= 4; - - // continues - if (savegameinfo[savetodraw].continues > 0) + if (!useContinues) { - V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_PATCH)); - V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); - V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continues)); + INT32 workingscorenum = savegameinfo[savetodraw].continuescore; + char workingscorestr[11] = " 000000000\0"; + SINT8 j = 9; + // Change the above two lines if MAXSCORE ever changes from 8 digits long. + workingscorestr[0] = '\x86'; // done here instead of in initialiser 'cuz compiler complains + if (!workingscorenum) + j--; // just so ONE digit is not greyed out + else + { + while (workingscorenum) + { + workingscorestr[j--] = '0' + (workingscorenum % 10); + workingscorenum /= 10; + } + } + workingscorestr[j] = (savegameinfo[savetodraw].continuescore == MAXSCORE) ? '\x83' : '\x80'; + V_DrawRightAlignedThinString(x + 80, y+1, 0, workingscorestr); } else { - V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_PATCH)); - V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_PATCH)); - V_DrawString(tempx + 16, y, V_GRAYMAP, "0"); + tempx = x + 47; + if (savegameinfo[savetodraw].continuescore > 9) + tempx -= 4; + + // continues + if (savegameinfo[savetodraw].continuescore > 0) + { + V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_PATCH)); + V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); + V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continuescore)); + } + else + { + V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_PATCH)); + V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_PATCH)); + V_DrawString(tempx + 16, y, V_GRAYMAP, "0"); + } } } } @@ -8502,9 +8540,11 @@ static void M_ReadSavegameInfo(UINT32 slot) CHECKPOS savegameinfo[slot].lives = READSINT8(save_p); // lives CHECKPOS - (void)READINT32(save_p); // Score + savegameinfo[slot].continuescore = READINT32(save_p); // score CHECKPOS - savegameinfo[slot].continues = READINT32(save_p); // continues + fake = READINT32(save_p); // continues + if (useContinues) + savegameinfo[slot].continuescore = fake; // File end marker check CHECKPOS diff --git a/src/m_menu.h b/src/m_menu.h index e7270380d..eeda9cc58 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -397,7 +397,7 @@ typedef struct UINT8 numemeralds; UINT8 numgameovers; INT32 lives; - INT32 continues; + INT32 continuescore; INT32 gamemap; } saveinfo_t; diff --git a/src/p_inter.c b/src/p_inter.c index 67d197375..b568fb359 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -633,7 +633,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (ALL7EMERALDS(emeralds)) // Got all 7 { - if (!(netgame || multiplayer)) + if (continuesInSession) { player->continues += 1; player->gotcontinue = true; @@ -643,7 +643,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(toucher, sfx_chchng); } else + { + P_GiveCoopLives(player, 1, true); // if continues are disabled, a life is a reasonable substitute S_StartSound(toucher, sfx_chchng); + } } else { diff --git a/src/p_user.c b/src/p_user.c index 612e31cbc..5ceaa45fb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1388,7 +1388,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) // Continues are worthless in netgames. // If that stops being the case uncomment this. -/* if (!ultimatemode && players[i].marescore > 50000 +/* if (!ultimatemode && continuesInSession && players[i].marescore > 50000 && oldscore < 50000) { players[i].continues += 1; @@ -1408,7 +1408,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) else player->marescore = MAXSCORE; - if (!ultimatemode && !(netgame || multiplayer) && G_IsSpecialStage(gamemap) + if (!ultimatemode && continuesInSession && G_IsSpecialStage(gamemap) && player->marescore >= 50000 && oldscore < 50000) { player->continues += 1; @@ -9539,7 +9539,7 @@ static void P_DeathThink(player_t *player) // continue logic if (!(netgame || multiplayer) && player->lives <= 0) { - if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && player->continues > 0) + if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && (!continuesInSession || player->continues > 0)) G_UseContinue(); else if (player->deadtimer >= gameovertics) G_UseContinue(); // Even if we don't have one this handles ending the game diff --git a/src/y_inter.c b/src/y_inter.c index 94a289817..f1764a816 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -564,7 +564,7 @@ dontdrawbg: V_DrawTallNum(BASEVIDWIDTH + xoffset4 - 68, 125+yoffset, 0, data.spec.score); // Draw continues! - if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay + if (continuesInSession /* && (data.spec.continues & 0x80) */) // Always draw when continues are a thing { UINT8 continues = data.spec.continues & 0x7F; From 8130599a4f01378e67308c98570e43df80e1118c Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sat, 28 Mar 2020 15:23:15 +0100 Subject: [PATCH 074/220] Fix disconnected players being kicked for high ping --- src/d_clisrv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 71e32977a..92602d68a 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4855,7 +4855,8 @@ static inline void PingUpdate(void) { for (i = 1; i < MAXPLAYERS; i++) { - if (playeringame[i] && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value)) + if (playeringame[i] && !players[i].quittime + && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value)) { if (players[i].jointime > 30 * TICRATE) laggers[i] = true; @@ -4874,8 +4875,8 @@ static inline void PingUpdate(void) if (playeringame[i] && laggers[i]) { pingtimeout[i]++; + // ok your net has been bad for too long, you deserve to die. if (pingtimeout[i] > cv_pingtimeout.value) -// ok your net has been bad for too long, you deserve to die. { pingtimeout[i] = 0; SendKick(i, KICK_MSG_PING_HIGH | KICK_MSG_KEEP_BODY); From 2e27b3ea87cdc870774a1cbe068494d9a1df233d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 30 Mar 2020 19:58:46 +0100 Subject: [PATCH 075/220] Turn the fixed-float convert macros into inline functions, like those in GZDoom. The old macros get to be just the same as calling these inline functions. --- src/m_fixed.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/m_fixed.h b/src/m_fixed.h index 7fdb9ad0a..49e7cc096 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -38,8 +38,20 @@ typedef INT32 fixed_t; /*! \brief convert fixed_t into floating number */ -#define FIXED_TO_FLOAT(x) (((float)(x)) / ((float)FRACUNIT)) -#define FLOAT_TO_FIXED(f) (fixed_t)((f) * ((float)FRACUNIT)) + +FUNCMATH FUNCINLINE static inline float FixedToFloat(fixed_t x) +{ + return x / (float)FRACUNIT; +} + +FUNCMATH FUNCINLINE static inline fixed_t FloatToFixed(float f) +{ + return (fixed_t)(f * FRACUNIT); +} + +// for backwards compat +#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT)) +#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT)) #if defined (__WATCOMC__) && FRACBITS == 16 From befae492fe996ddedd4e9c6e0feaaa74a3b889bd Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 30 Mar 2020 20:25:56 +0100 Subject: [PATCH 076/220] use ATTRINLINE rather than inline to match some of the other functions in this file, though I'm told modern compilers ignore inlining info as they actually decide themselves now (though I could pretend we still support the older ones lol) --- src/m_fixed.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_fixed.h b/src/m_fixed.h index 49e7cc096..cc54c1aea 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -39,12 +39,12 @@ typedef INT32 fixed_t; \brief convert fixed_t into floating number */ -FUNCMATH FUNCINLINE static inline float FixedToFloat(fixed_t x) +FUNCMATH FUNCINLINE static ATTRINLINE float FixedToFloat(fixed_t x) { return x / (float)FRACUNIT; } -FUNCMATH FUNCINLINE static inline fixed_t FloatToFixed(float f) +FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f) { return (fixed_t)(f * FRACUNIT); } From ad12e29fda52e5b75c01f36fdecfdd1d65a3f4d5 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 30 Mar 2020 22:11:48 +0200 Subject: [PATCH 077/220] Fix allowjoin off affecting single player --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index aa5d4cb9a..56ce21c3d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1338,7 +1338,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; - if (FindRejoinerNum(node) != -1) + if (!node || FindRejoinerNum(node) != -1) netbuffer->u.serverinfo.refusereason = 0; else if (!cv_allownewplayer.value) netbuffer->u.serverinfo.refusereason = 1; From 3074880ac1c7e5259998fb3df4c1372d7d386d75 Mon Sep 17 00:00:00 2001 From: sphere Date: Thu, 2 Apr 2020 16:07:38 +0200 Subject: [PATCH 078/220] Actually check for available maps correctly. Whoops! --- src/m_menu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index c6babc805..a40aea89e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7991,12 +7991,14 @@ static void M_SinglePlayerMenu(INT32 choice) { (void)choice; - if (M_GametypeHasLevels(LLM_RECORDATTACK)) + levellistmode = LLM_RECORDATTACK; + if (M_PrepareLevelPlatter(-1, true)) SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; else SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED; - if (M_GametypeHasLevels(LLM_NIGHTSATTACK)) + levellistmode = LLM_NIGHTSATTACK; + if (M_PrepareLevelPlatter(-1, true)) SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; else SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED; From 806884a3f4cce2744cdf626982279e8ef3494f3f Mon Sep 17 00:00:00 2001 From: sphere Date: Thu, 2 Apr 2020 17:59:56 +0200 Subject: [PATCH 079/220] Use M_GametypeHasLevels again (properly this time) to save memory. --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index a40aea89e..4af94e77b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7992,13 +7992,13 @@ static void M_SinglePlayerMenu(INT32 choice) (void)choice; levellistmode = LLM_RECORDATTACK; - if (M_PrepareLevelPlatter(-1, true)) + if (M_GametypeHasLevels(-1)) SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; else SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED; levellistmode = LLM_NIGHTSATTACK; - if (M_PrepareLevelPlatter(-1, true)) + if (M_GametypeHasLevels(-1)) SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; else SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED; From dc25177457176814670975bf08eb7b36d20cc780 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 9 Apr 2020 17:30:53 -0700 Subject: [PATCH 080/220] You don't need to push the value twice, it's only used once --- src/lua_infolib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index b7902ef79..a82403097 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -1631,7 +1631,6 @@ int LUA_InfoLib(lua_State *L) lua_pushcfunction(L, lib_spriteinfolen); lua_setfield(L, -2, "__len"); lua_setmetatable(L, -2); - lua_pushvalue(L, -1); lua_setglobal(L, "spriteinfo"); luaL_newmetatable(L, META_LUABANKS); From 6845aca6e5cf2292b5586dbf01ea0be80c9225af Mon Sep 17 00:00:00 2001 From: fickleheart Date: Thu, 9 Apr 2020 20:52:23 -0500 Subject: [PATCH 081/220] Make chdir usage consistent with other source usage --- src/d_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 8519e6281..80f075cb1 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -909,7 +909,13 @@ static void IdentifyVersion(void) } CONS_Printf("%s\n", srb2path); - chdir(srb2path); + +#if defined (_WIN32) + SetCurrentDirectoryA(srb2path); +#else + if (chdir(srb2path) == -1) + I_OutputMsg("Couldn't change working directory\n"); +#endif } #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) From be07a23e5265aceea62f18acce09c1e7cdda31af Mon Sep 17 00:00:00 2001 From: fickleheart Date: Thu, 9 Apr 2020 20:56:27 -0500 Subject: [PATCH 082/220] Make a separate function instead of clogging up IdentifyVersion --- src/d_main.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 80f075cb1..a0672bb4e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -880,15 +880,10 @@ static inline void D_CleanFile(void) } } -// ========================================================================== -// Identify the SRB2 version, and IWAD file to use. -// ========================================================================== - -static void IdentifyVersion(void) +///\brief Checks if a netgame URL is being handled, and changes working directory to the EXE's if so. +/// Done because browsers (at least, Firefox on Windows) launch the game from the browser's directory, which causes problems. +static void ChangeDirForUrlHandler(void) { - char *srb2wad; - const char *srb2waddir = NULL; - // URL handlers are opened by web browsers (at least Firefox) from the browser's working directory, not the game's stored directory, // so chdir to that directory unless overridden. if (M_GetUrlProtocolArg() != NULL && !M_CheckParm("-nochdir")) @@ -917,6 +912,16 @@ static void IdentifyVersion(void) I_OutputMsg("Couldn't change working directory\n"); #endif } +} + +// ========================================================================== +// Identify the SRB2 version, and IWAD file to use. +// ========================================================================== + +static void IdentifyVersion(void) +{ + char *srb2wad; + const char *srb2waddir = NULL; #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) // change to the directory where 'srb2.pk3' is found @@ -1097,6 +1102,9 @@ void D_SRB2Main(void) // Test Dehacked lists DEH_Check(); + // Netgame URL special case: change working dir to EXE folder. + ChangeDirForUrlHandler(); + // identify the main IWAD file to use IdentifyVersion(); From 4214397679c70a7910c82126783b434f0d10343e Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 12 Apr 2020 17:05:18 -0700 Subject: [PATCH 083/220] Make the PACKETVERSION rule easier --- src/d_clisrv.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 10a1d714d..2ddebadba 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -20,12 +20,9 @@ #include "d_player.h" /* -The 'packet version' may be used with packets whose -format is expected to change between versions. - -This version is independent of the mod name, and standard -version and subversion. It should only account for the -basic fields of the packet, and change infrequently. +The 'packet version' is used to distinguish packet formats. +This version is independent of VERSION and SUBVERSION. Different +applications may follow different packet versions. */ #define PACKETVERSION 2 From 711c35970c0c467c3a78c87aa8a7c851c16e9614 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 13 Apr 2020 14:31:19 +0200 Subject: [PATCH 084/220] Refactor an unholy piece of code. --- src/p_floor.c | 132 ++++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 58 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index b8b40df3c..2923eeda0 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -48,13 +48,7 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus boolean flag; fixed_t lastpos; fixed_t destheight; // used to keep floors/ceilings from moving through each other - // Stuff used for mobj hacks. - INT32 secnum = -1; mobj_t *mo = NULL; - sector_t *sec = NULL; - ffloor_t *rover = NULL; - boolean sectorisffloor = false; - boolean sectorisquicksand = false; sector->moved = true; @@ -193,41 +187,37 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus break; } - // Hack for buggy mobjs to move by gravity with moving planes. + // If this is an FOF being checked, check all the affected sectors for moving mobjs. if (sector->tagline) - sectorisffloor = true; - - // Optimization condition. If the sector is not an FOF, declare sec as the main sector outside of the loop. - if (!sectorisffloor) - sec = sector; - - // Optimization condition. Only run the logic if there is any Things in the sector. - if (sectorisffloor || sec->thinglist) { - // If this is an FOF being checked, check all the affected sectors for moving mobjs. - while ((sectorisffloor ? (secnum = P_FindSectorFromLineTag(sector->tagline, secnum)) : (secnum = 1)) >= 0) - { - if (sectorisffloor) - { - // Get actual sector from the list of sectors. - sec = §ors[secnum]; + boolean sectorisquicksand = false; + sector_t *sec; + ffloor_t *rover; + INT32 secnum; - // Can't use P_InQuicksand because it will return the incorrect result - // because of checking for heights. - for (rover = sec->ffloors; rover; rover = rover->next) + while (secnum = P_FindSectorFromLineTag(sector->tagline, secnum) >= 0) + { + // Get actual sector from the list of sectors. + sec = §ors[secnum]; + + if (!sec->thinglist) + continue; + + // Can't use P_InQuicksand because it will return the incorrect result + // because of checking for heights. + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (rover->target == sec && (rover->flags & FF_QUICKSAND)) { - if (rover->target == sec && (rover->flags & FF_QUICKSAND)) - { - sectorisquicksand = true; - break; - } + sectorisquicksand = true; + break; } } for (mo = sec->thinglist; mo; mo = mo->snext) { // The object should be ready to move as defined by this function. - if (!P_MobjReadyToMove(mo, sec, sectorisffloor, sectorisquicksand)) + if (!P_MobjReadyToMove(mo, sec, true, sectorisquicksand)) continue; // The object should not be moving at all. @@ -237,39 +227,65 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus // These objects will be affected by this condition. switch (mo->type) { - case MT_GOOP: // Egg Slimer's goop objects - case MT_SPINFIRE: // Elemental Shield flame balls - case MT_SPIKE: // Floor Spike - // Is the object hang from the ceiling? - // In that case, swap the planes used. - // verticalflip inverts - if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP)) - { - if (sectorisffloor && !sectorisquicksand) - mo->z = mo->ceilingz - mo->height; - else - mo->z = mo->ceilingz = mo->subsector->sector->ceilingheight - mo->height; - } + case MT_GOOP: // Egg Slimer's goop objects + case MT_SPINFIRE: // Elemental Shield flame balls + case MT_SPIKE: // Floor Spike + // Is the object hang from the ceiling? + // In that case, swap the planes used. + // verticalflip inverts + if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP)) + { + if (!sectorisquicksand) + mo->z = mo->ceilingz - mo->height; else - { - if (sectorisffloor && !sectorisquicksand) - mo->z = mo->floorz; - else - mo->z = mo->floorz = mo->subsector->sector->floorheight; - } - break; - // Kill warnings... - default: - break; + mo->z = mo->ceilingz = mo->subsector->sector->ceilingheight - mo->height; + } + else + { + if (!sectorisquicksand) + mo->z = mo->floorz; + else + mo->z = mo->floorz = mo->subsector->sector->floorheight; + } + break; + default: + break; } } - - // Break from loop if there is no FOFs to check. - if (!sectorisffloor) - break; } } + // Only run the logic if there is any mobjs in the sector. + if (sector->thinglist) + for (mo = sector->thinglist; mo; mo = mo->snext) + { + // The object should be ready to move as defined by this function. + if (!P_MobjReadyToMove(mo, sector, false, false)) + continue; + + // The object should not be moving at all. + if (mo->momx || mo->momy || mo->momz) + continue; + + // These objects will be affected by this condition. + switch (mo->type) + { + case MT_GOOP: // Egg Slimer's goop objects + case MT_SPINFIRE: // Elemental Shield flame balls + case MT_SPIKE: // Floor Spike + // Is the object hang from the ceiling? + // In that case, swap the planes used. + // verticalflip inverts + if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP)) + mo->z = mo->ceilingz = mo->subsector->sector->ceilingheight - mo->height; + else + mo->z = mo->floorz = mo->subsector->sector->floorheight; + break; + default: + break; + } + } + return ok; } From 74bd23c275f5c57fc5a5f31659fb752e79acddcf Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 13 Apr 2020 15:17:53 +0200 Subject: [PATCH 085/220] Actually remove the entire code block in T_MovePlane(), and remove line_t.tagline as it served no other purpose. --- src/p_floor.c | 101 -------------------------------------------------- src/p_setup.c | 1 - src/p_spec.c | 2 - src/r_defs.h | 5 --- 4 files changed, 109 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 2923eeda0..078ee187b 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -48,8 +48,6 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus boolean flag; fixed_t lastpos; fixed_t destheight; // used to keep floors/ceilings from moving through each other - mobj_t *mo = NULL; - sector->moved = true; switch (floorOrCeiling) @@ -187,105 +185,6 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus break; } - // If this is an FOF being checked, check all the affected sectors for moving mobjs. - if (sector->tagline) - { - boolean sectorisquicksand = false; - sector_t *sec; - ffloor_t *rover; - INT32 secnum; - - while (secnum = P_FindSectorFromLineTag(sector->tagline, secnum) >= 0) - { - // Get actual sector from the list of sectors. - sec = §ors[secnum]; - - if (!sec->thinglist) - continue; - - // Can't use P_InQuicksand because it will return the incorrect result - // because of checking for heights. - for (rover = sec->ffloors; rover; rover = rover->next) - { - if (rover->target == sec && (rover->flags & FF_QUICKSAND)) - { - sectorisquicksand = true; - break; - } - } - - for (mo = sec->thinglist; mo; mo = mo->snext) - { - // The object should be ready to move as defined by this function. - if (!P_MobjReadyToMove(mo, sec, true, sectorisquicksand)) - continue; - - // The object should not be moving at all. - if (mo->momx || mo->momy || mo->momz) - continue; - - // These objects will be affected by this condition. - switch (mo->type) - { - case MT_GOOP: // Egg Slimer's goop objects - case MT_SPINFIRE: // Elemental Shield flame balls - case MT_SPIKE: // Floor Spike - // Is the object hang from the ceiling? - // In that case, swap the planes used. - // verticalflip inverts - if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP)) - { - if (!sectorisquicksand) - mo->z = mo->ceilingz - mo->height; - else - mo->z = mo->ceilingz = mo->subsector->sector->ceilingheight - mo->height; - } - else - { - if (!sectorisquicksand) - mo->z = mo->floorz; - else - mo->z = mo->floorz = mo->subsector->sector->floorheight; - } - break; - default: - break; - } - } - } - } - - // Only run the logic if there is any mobjs in the sector. - if (sector->thinglist) - for (mo = sector->thinglist; mo; mo = mo->snext) - { - // The object should be ready to move as defined by this function. - if (!P_MobjReadyToMove(mo, sector, false, false)) - continue; - - // The object should not be moving at all. - if (mo->momx || mo->momy || mo->momz) - continue; - - // These objects will be affected by this condition. - switch (mo->type) - { - case MT_GOOP: // Egg Slimer's goop objects - case MT_SPINFIRE: // Elemental Shield flame balls - case MT_SPIKE: // Floor Spike - // Is the object hang from the ceiling? - // In that case, swap the planes used. - // verticalflip inverts - if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP)) - mo->z = mo->ceilingz = mo->subsector->sector->ceilingheight - mo->height; - else - mo->z = mo->floorz = mo->subsector->sector->floorheight; - break; - default: - break; - } - } - return ok; } diff --git a/src/p_setup.c b/src/p_setup.c index 6c6ecbc5d..700113d85 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -872,7 +872,6 @@ static void P_InitializeSector(sector_t *ss) ss->linecount = 0; ss->lines = NULL; - ss->tagline = NULL; ss->ffloors = NULL; ss->attached = NULL; diff --git a/src/p_spec.c b/src/p_spec.c index 50b767535..ad22d1a54 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5772,8 +5772,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f sec2->floorheight = tempceiling; } - sec2->tagline = master; - if (sec2->numattached == 0) { sec2->attached = Z_Malloc(sizeof (*sec2->attached) * sec2->maxattached, PU_STATIC, NULL); diff --git a/src/r_defs.h b/src/r_defs.h index 5f62ec058..10c0721ac 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -328,11 +328,6 @@ typedef struct sector_s size_t linecount; struct line_s **lines; // [linecount] size - // Hack: store special line tagging to some sectors - // to efficiently help work around bugs by directly - // referencing the specific line that the problem happens in. - // (used in T_MovePlane mobj physics) - struct line_s *tagline; // Improved fake floor hack ffloor_t *ffloors; From 01c0797ba6965c110b37c385c02c3718d962bb90 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 13 Apr 2020 16:00:58 +0200 Subject: [PATCH 086/220] Remove now unused P_MobjReadyToMove(). --- src/p_floor.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 078ee187b..aa05c6af2 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -26,19 +26,6 @@ // FLOORS // ========================================================================== -// -// Mini-P_IsObjectOnGroundIn for T_MovePlane hack -// -static inline boolean P_MobjReadyToMove(mobj_t *mo, sector_t *sec, boolean sectorisffloor, boolean sectorisquicksand) -{ - if (sectorisquicksand) - return (mo->z > sec->floorheight && mo->z < sec->ceilingheight); - else if (!!(mo->flags & MF_SPAWNCEILING) ^ !!(mo->eflags & MFE_VERTICALFLIP)) - return ((sectorisffloor) ? (mo->z+mo->height != sec->floorheight) : (mo->z+mo->height != sec->ceilingheight)); - else - return ((sectorisffloor) ? (mo->z != sec->ceilingheight) : (mo->z != sec->floorheight)); -} - // // Move a plane (floor or ceiling) and check for crushing // From 01b28b66a6d47c604457561e01dd33ac7693ec84 Mon Sep 17 00:00:00 2001 From: sphere Date: Mon, 13 Apr 2020 17:10:25 +0200 Subject: [PATCH 087/220] Make linedef type 461 able to set object angle, using the line's angle. --- extras/conf/SRB2-22.cfg | 3 ++- src/p_spec.c | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index ec030b32f..a59771b2d 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -15,7 +15,7 @@ * Oogaland * Rob * Shadow Hog - * Spherallic + * sphere * SRB2-Playah * SSNTails * SteelT @@ -2214,6 +2214,7 @@ linedeftypes title = "Spawn Object"; prefix = "(461)"; flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] Use line angle for object"; flags64text = "[6] Spawn inside a range"; } diff --git a/src/p_spec.c b/src/p_spec.c index 50b767535..13280f3fe 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4027,7 +4027,11 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) mobj = P_SpawnMobj(x, y, z, type); if (mobj) + { + if (line->flags & ML_EFFECT1) + mobj->angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow. + } else CONS_Alert(CONS_ERROR,"Linedef Type %d - Spawn Object: Object did not spawn!\n", line->special); } From 778ef86fee107d820701ba16eabaaa9b0687321f Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 14 Apr 2020 10:31:07 +0200 Subject: [PATCH 088/220] Remove the bridge thinker code. --- src/p_floor.c | 472 -------------------------------------------------- src/p_saveg.c | 10 -- src/p_spec.c | 52 +----- src/p_spec.h | 1 - 4 files changed, 6 insertions(+), 529 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index b8b40df3c..b916014b2 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1275,478 +1275,6 @@ void T_FloatSector(levelspecthink_t *floater) } } -// -// T_BridgeThinker -// -// Kind of like T_RaiseSector, -// but spreads out across -// multiple FOFs at varying -// intensity. -// -void T_BridgeThinker(levelspecthink_t *bridge) -{ - msecnode_t *node; - mobj_t *thing; - sector_t *sector; - sector_t *controlsec = NULL; - INT32 i, k; - - INT16 j; - boolean playeronme = false; - fixed_t ceilingdestination = 0, floordestination = 0; - result_e res = 0; - -#define ORIGFLOORHEIGHT (bridge->vars[0]) -#define ORIGCEILINGHEIGHT (bridge->vars[1]) -#define BASESPEED (bridge->vars[2]) -#define CURSPEED (bridge->vars[3]) -#define STARTTAG ((INT16)bridge->vars[4]) -#define ENDTAG ((INT16)bridge->vars[5]) -#define DIRECTION (bridge->vars[8]) -#define SAGAMT (8*FRACUNIT) - fixed_t lowceilheight = ORIGCEILINGHEIGHT - SAGAMT; - fixed_t lowfloorheight = ORIGFLOORHEIGHT - SAGAMT; -#define LOWCEILINGHEIGHT (lowceilheight) -#define LOWFLOORHEIGHT (lowfloorheight) -#define STARTCONTROLTAG (ENDTAG + 1) -#define ENDCONTROLTAG (ENDTAG + (ENDTAG - STARTTAG) + 1) - - // Is someone standing on it? - for (j = STARTTAG; j <= ENDTAG; j++) - { - for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;) - { - sector = §ors[i]; - - // Nab the control sector that this sector belongs to. - k = P_FindSectorFromTag((INT16)(j + (ENDTAG-STARTTAG) + 1), -1); - - if (k == -1) - break; - - controlsec = §ors[k]; - - // Is a player standing on me? - for (node = sector->touching_thinglist; node; node = node->m_thinglist_next) - { - thing = node->m_thing; - - if (!thing->player) - continue; - - if (!(thing->z == controlsec->ceilingheight)) - continue; - - playeronme = true; - goto wegotit; // Just take the first one? - } - } - } -wegotit: - if (playeronme) - { - // Lower controlsec like a regular T_RaiseSector - // Set the heights of all the other control sectors to - // be a gradient of this height toward the edges - } - else - { - // Raise controlsec like a regular T_RaiseSector - // Set the heights of all the other control sectors to - // be a gradient of this height toward the edges. - } - - if (playeronme && controlsec) - { - INT32 dist; - - bridge->sector = controlsec; - CURSPEED = BASESPEED; - - { - // Translate tags to - 0 + range - /*so you have a number in [min, max]. - let range = max - min, subtract min - from your number to get [0, range]. - subtract range/2 to get [-range/2, range/2]. - take absolute value and get [0, range/2] where - lower number = closer to midpoint. divide by - range/2 to get [0, 1]. subtract that number - from 1 to get [0, 1] with higher number = closer - to midpoint. multiply this by max sag amount*/ - - INT32 midpoint = STARTCONTROLTAG + ((ENDCONTROLTAG-STARTCONTROLTAG) + 1)/2; -// INT32 tagstart = STARTTAG - midpoint; -// INT32 tagend = ENDTAG - midpoint; - -// CONS_Debug(DBG_GAMELOGIC, "tagstart is %d, tagend is %d\n", tagstart, tagend); - - // Sag is adjusted by how close you are to the center - dist = ((ENDCONTROLTAG - STARTCONTROLTAG))/2 - abs(bridge->sector->tag - midpoint); - -// CONS_Debug(DBG_GAMELOGIC, "Dist is %d\n", dist); - LOWCEILINGHEIGHT -= (SAGAMT) * dist; - LOWFLOORHEIGHT -= (SAGAMT) * dist; - } - - // go down - if (bridge->sector->ceilingheight <= LOWCEILINGHEIGHT) - { - bridge->sector->floorheight = LOWCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight); - bridge->sector->ceilingheight = LOWCEILINGHEIGHT; - bridge->sector->ceilspeed = 0; - bridge->sector->floorspeed = 0; - goto dorest; - } - - DIRECTION = -1; - ceilingdestination = LOWCEILINGHEIGHT; - floordestination = LOWFLOORHEIGHT; - - if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT) - < (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight)) - { - fixed_t origspeed = CURSPEED; - - // Slow down as you get closer to the bottom - CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5)); - - if (CURSPEED <= origspeed/16) - CURSPEED = origspeed/16; - else if (CURSPEED > origspeed) - CURSPEED = origspeed; - } - else - { - fixed_t origspeed = CURSPEED; - // Slow down as you get closer to the top - CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5)); - - if (CURSPEED <= origspeed/16) - CURSPEED = origspeed/16; - else if (CURSPEED > origspeed) - CURSPEED = origspeed; - } - -// CONS_Debug(DBG_GAMELOGIC, "Curspeed is %d\n", CURSPEED>>FRACBITS); - - res = T_MovePlane - ( - bridge->sector, // sector - CURSPEED, // speed - ceilingdestination, // dest - 0, // crush - 1, // floor or ceiling (1 for ceiling) - DIRECTION // direction - ); - - if (res == ok || res == pastdest) - T_MovePlane - ( - bridge->sector, // sector - CURSPEED, // speed - floordestination, // dest - 0, // crush - 0, // floor or ceiling (0 for floor) - DIRECTION // direction - ); - - bridge->sector->ceilspeed = 42; - bridge->sector->floorspeed = CURSPEED*DIRECTION; - - dorest: - // Adjust joined sector heights - { - sector_t *sourcesec = bridge->sector; - - INT32 divisor = sourcesec->tag - ENDTAG + 1; - fixed_t heightdiff = ORIGCEILINGHEIGHT - sourcesec->ceilingheight; - fixed_t interval; - INT32 plusplusme = 0; - - if (divisor > 0) - { - interval = heightdiff/divisor; - -// CONS_Debug(DBG_GAMELOGIC, "interval is %d\n", interval>>FRACBITS); - - // TODO: Use T_MovePlane - - for (j = (INT16)(ENDTAG+1); j <= sourcesec->tag; j++, plusplusme++) - { - for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;) - { - if (sectors[i].ceilingheight >= sourcesec->ceilingheight) - { - sectors[i].ceilingheight = ORIGCEILINGHEIGHT - (interval*plusplusme); - sectors[i].floorheight = ORIGFLOORHEIGHT - (interval*plusplusme); - } - else // Do the regular rise - { - bridge->sector = §ors[i]; - - CURSPEED = BASESPEED/2; - - // rise back up - if (bridge->sector->ceilingheight >= ORIGCEILINGHEIGHT) - { - bridge->sector->floorheight = ORIGCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight); - bridge->sector->ceilingheight = ORIGCEILINGHEIGHT; - bridge->sector->ceilspeed = 0; - bridge->sector->floorspeed = 0; - continue; - } - - DIRECTION = 1; - ceilingdestination = ORIGCEILINGHEIGHT; - floordestination = ORIGFLOORHEIGHT; - -// CONS_Debug(DBG_GAMELOGIC, "ceildest: %d, floordest: %d\n", ceilingdestination>>FRACBITS, floordestination>>FRACBITS); - - if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT) - < (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight)) - { - fixed_t origspeed = CURSPEED; - - // Slow down as you get closer to the bottom - CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5)); - - if (CURSPEED <= origspeed/16) - CURSPEED = origspeed/16; - else if (CURSPEED > origspeed) - CURSPEED = origspeed; - } - else - { - fixed_t origspeed = CURSPEED; - // Slow down as you get closer to the top - CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5)); - - if (CURSPEED <= origspeed/16) - CURSPEED = origspeed/16; - else if (CURSPEED > origspeed) - CURSPEED = origspeed; - } - - res = T_MovePlane - ( - bridge->sector, // sector - CURSPEED, // speed - ceilingdestination, // dest - 0, // crush - 1, // floor or ceiling (1 for ceiling) - DIRECTION // direction - ); - - if (res == ok || res == pastdest) - T_MovePlane - ( - bridge->sector, // sector - CURSPEED, // speed - floordestination, // dest - 0, // crush - 0, // floor or ceiling (0 for floor) - DIRECTION // direction - ); - - bridge->sector->ceilspeed = 42; - bridge->sector->floorspeed = CURSPEED*DIRECTION; - } - } - } - } - - // Now the other side - divisor = ENDTAG + (ENDTAG-STARTTAG) + 1; - divisor -= sourcesec->tag; - - if (divisor > 0) - { - interval = heightdiff/divisor; - plusplusme = 0; - -// CONS_Debug(DBG_GAMELOGIC, "interval2 is %d\n", interval>>FRACBITS); - - for (j = (INT16)(sourcesec->tag+1); j <= ENDTAG + (ENDTAG-STARTTAG) + 1; j++, plusplusme++) - { - for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;) - { - if (sectors[i].ceilingheight >= sourcesec->ceilingheight) - { - sectors[i].ceilingheight = sourcesec->ceilingheight + (interval*plusplusme); - sectors[i].floorheight = sourcesec->floorheight + (interval*plusplusme); - } - else // Do the regular rise - { - bridge->sector = §ors[i]; - - CURSPEED = BASESPEED/2; - - // rise back up - if (bridge->sector->ceilingheight >= ORIGCEILINGHEIGHT) - { - bridge->sector->floorheight = ORIGCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight); - bridge->sector->ceilingheight = ORIGCEILINGHEIGHT; - bridge->sector->ceilspeed = 0; - bridge->sector->floorspeed = 0; - continue; - } - - DIRECTION = 1; - ceilingdestination = ORIGCEILINGHEIGHT; - floordestination = ORIGFLOORHEIGHT; - -// CONS_Debug(DBG_GAMELOGIC, "ceildest: %d, floordest: %d\n", ceilingdestination>>FRACBITS, floordestination>>FRACBITS); - - if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT) - < (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight)) - { - fixed_t origspeed = CURSPEED; - - // Slow down as you get closer to the bottom - CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5)); - - if (CURSPEED <= origspeed/16) - CURSPEED = origspeed/16; - else if (CURSPEED > origspeed) - CURSPEED = origspeed; - } - else - { - fixed_t origspeed = CURSPEED; - // Slow down as you get closer to the top - CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5)); - - if (CURSPEED <= origspeed/16) - CURSPEED = origspeed/16; - else if (CURSPEED > origspeed) - CURSPEED = origspeed; - } - - res = T_MovePlane - ( - bridge->sector, // sector - CURSPEED, // speed - ceilingdestination, // dest - 0, // crush - 1, // floor or ceiling (1 for ceiling) - DIRECTION // direction - ); - - if (res == ok || res == pastdest) - T_MovePlane - ( - bridge->sector, // sector - CURSPEED, // speed - floordestination, // dest - 0, // crush - 0, // floor or ceiling (0 for floor) - DIRECTION // direction - ); - - bridge->sector->ceilspeed = 42; - bridge->sector->floorspeed = CURSPEED*DIRECTION; - } - } - } - } - } - - // for (i = -1; (i = P_FindSectorFromTag(bridge->sourceline->tag, i)) >= 0 ;) - // P_RecalcPrecipInSector(§ors[i]); - } - else - { - // Iterate control sectors - for (j = (INT16)(ENDTAG+1); j <= (ENDTAG+(ENDTAG-STARTTAG)+1); j++) - { - for (i = -1; (i = P_FindSectorFromTag(j, i)) >= 0 ;) - { - bridge->sector = §ors[i]; - - CURSPEED = BASESPEED/2; - - // rise back up - if (bridge->sector->ceilingheight >= ORIGCEILINGHEIGHT) - { - bridge->sector->floorheight = ORIGCEILINGHEIGHT - (bridge->sector->ceilingheight - bridge->sector->floorheight); - bridge->sector->ceilingheight = ORIGCEILINGHEIGHT; - bridge->sector->ceilspeed = 0; - bridge->sector->floorspeed = 0; - continue; - } - - DIRECTION = 1; - ceilingdestination = ORIGCEILINGHEIGHT; - floordestination = ORIGFLOORHEIGHT; - -// CONS_Debug(DBG_GAMELOGIC, "ceildest: %d, floordest: %d\n", ceilingdestination>>FRACBITS, floordestination>>FRACBITS); - - if ((bridge->sector->ceilingheight - LOWCEILINGHEIGHT) - < (ORIGCEILINGHEIGHT - bridge->sector->ceilingheight)) - { - fixed_t origspeed = CURSPEED; - - // Slow down as you get closer to the bottom - CURSPEED = FixedMul(CURSPEED,FixedDiv(bridge->sector->ceilingheight - LOWCEILINGHEIGHT, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5)); - - if (CURSPEED <= origspeed/16) - CURSPEED = origspeed/16; - else if (CURSPEED > origspeed) - CURSPEED = origspeed; - } - else - { - fixed_t origspeed = CURSPEED; - // Slow down as you get closer to the top - CURSPEED = FixedMul(CURSPEED,FixedDiv(ORIGCEILINGHEIGHT - bridge->sector->ceilingheight, (ORIGCEILINGHEIGHT - LOWCEILINGHEIGHT)>>5)); - - if (CURSPEED <= origspeed/16) - CURSPEED = origspeed/16; - else if (CURSPEED > origspeed) - CURSPEED = origspeed; - } - - res = T_MovePlane - ( - bridge->sector, // sector - CURSPEED, // speed - ceilingdestination, // dest - 0, // crush - 1, // floor or ceiling (1 for ceiling) - DIRECTION // direction - ); - - if (res == ok || res == pastdest) - T_MovePlane - ( - bridge->sector, // sector - CURSPEED, // speed - floordestination, // dest - 0, // crush - 0, // floor or ceiling (0 for floor) - DIRECTION // direction - ); - - bridge->sector->ceilspeed = 42; - bridge->sector->floorspeed = CURSPEED*DIRECTION; - } - } - // Update precip - } - -#undef SAGAMT -#undef LOWFLOORHEIGHT -#undef LOWCEILINGHEIGHT -#undef ORIGFLOORHEIGHT -#undef ORIGCEILINGHEIGHT -#undef BASESPEED -#undef CURSPEED -#undef STARTTAG -#undef ENDTAG -#undef DIRECTION -} - static mobj_t *SearchMarioNode(msecnode_t *node) { mobj_t *thing = NULL; diff --git a/src/p_saveg.c b/src/p_saveg.c index 716904432..259e58168 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1275,7 +1275,6 @@ typedef enum tc_marioblockchecker, tc_spikesector, tc_floatsector, - tc_bridgethinker, tc_crushceiling, tc_scroll, tc_friction, @@ -2291,11 +2290,6 @@ static void P_NetArchiveThinkers(void) SaveSpecialLevelThinker(th, tc_floatsector); continue; } - else if (th->function.acp1 == (actionf_p1)T_BridgeThinker) - { - SaveSpecialLevelThinker(th, tc_bridgethinker); - continue; - } else if (th->function.acp1 == (actionf_p1)T_LaserFlash) { SaveLaserThinker(th, tc_laserflash); @@ -3487,10 +3481,6 @@ static void P_NetUnArchiveThinkers(void) th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0); break; - case tc_bridgethinker: - th = LoadSpecialLevelThinker((actionf_p1)T_BridgeThinker, 3); - break; - case tc_laserflash: th = LoadLaserThinker((actionf_p1)T_LaserFlash); break; diff --git a/src/p_spec.c b/src/p_spec.c index 50b767535..8e56f2efe 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2041,7 +2041,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller INT32 triggercolor = (INT32)sides[triggerline->sidenum[0]].toptexture; UINT8 color = (actor->player ? actor->player->powers[pw_dye] : actor->color); boolean invert = (triggerline->flags & ML_NOCLIMB ? true : false); - + if (invert ^ (triggercolor != color)) return false; } @@ -4050,23 +4050,23 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } } break; - + case 463: // Dye object { INT32 color = sides[line->sidenum[0]].toptexture; - + if (mo) { if (color < 0 || color >= MAXTRANSLATIONS) return; - + var1 = 0; var2 = color; A_Dye(mo); } } break; - + #ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing @@ -5975,39 +5975,6 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline) floater->sourceline = sourceline; } -/** Adds a bridge thinker. - * Bridge thinkers cause a group of FOFs to behave like - * a bridge made up of pieces, that bows under weight. - * - * \param sec Control sector. - * \sa P_SpawnSpecials, T_BridgeThinker - * \author SSNTails - */ -/* -static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec) -{ - levelspecthink_t *bridge; - - // create an initialize new thinker - bridge = Z_Calloc(sizeof (*bridge), PU_LEVSPEC, NULL); - P_AddThinker(THINK_MAIN, &bridge->thinker); - - bridge->thinker.function.acp1 = (actionf_p1)T_BridgeThinker; - - bridge->sector = sec; - bridge->vars[0] = sourceline->frontsector->floorheight; - bridge->vars[1] = sourceline->frontsector->ceilingheight; - bridge->vars[2] = P_AproxDistance(sourceline->dx, sourceline->dy); // Speed - bridge->vars[2] = FixedDiv(bridge->vars[2], 16*FRACUNIT); - bridge->vars[3] = bridge->vars[2]; - - // Start tag and end tag are TARGET SECTORS, not CONTROL SECTORS - // Control sector tags should be End_Tag + (End_Tag - Start_Tag) - bridge->vars[4] = sourceline->tag; // Start tag - bridge->vars[5] = (sides[sourceline->sidenum[0]].textureoffset>>FRACBITS); // End tag -} -*/ - /** * Adds a plane displacement thinker. * Whenever the "control" sector moves, @@ -6753,13 +6720,6 @@ void P_SpawnSpecials(boolean fromnetsave) } break; - case 65: // Bridge Thinker - /* - // Disable this until it's working right! - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - P_AddBridgeThinker(&lines[i], §ors[s]);*/ - break; - case 66: // Displace floor by front sector for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); @@ -7287,7 +7247,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 331: case 333: break; - + // Object dye executors case 334: case 336: diff --git a/src/p_spec.h b/src/p_spec.h index 6377059b6..d756f1942 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -354,7 +354,6 @@ void T_StartCrumble(elevator_t *elevator); void T_MarioBlock(levelspecthink_t *block); void T_SpikeSector(levelspecthink_t *spikes); void T_FloatSector(levelspecthink_t *floater); -void T_BridgeThinker(levelspecthink_t *bridge); void T_MarioBlockChecker(levelspecthink_t *block); void T_ThwompSector(levelspecthink_t *thwomp); void T_NoEnemiesSector(levelspecthink_t *nobaddies); From 98481dc10b24f43d77b146dfcd42b87496c60827 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 14 Apr 2020 10:31:26 +0200 Subject: [PATCH 089/220] Remove the bridge thinker entry from the ZB configuration. --- extras/conf/SRB2-22.cfg | 6 ------ 1 file changed, 6 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index ec030b32f..b918cdb26 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -738,12 +738,6 @@ linedeftypes flags2text = "[1] Use control sector tag"; flags64text = "[6] No sound effect"; } - - 65 - { - title = "Bridge Thinker "; - prefix = "(65)"; - } } polyobject From d0c473c9ae817314f8860e084807e8d9f5db74ed Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 09:58:53 +0200 Subject: [PATCH 090/220] Make T_RaiseSector use its own thinker struct instead of levelspecthink_t --- src/p_floor.c | 130 +++++++++++++++++++++++++------------------------- src/p_saveg.c | 49 ++++++++++++++++++- src/p_spec.c | 79 ++++++++++-------------------- src/p_spec.h | 26 +++++++++- 4 files changed, 163 insertions(+), 121 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 7ab1dc1f6..d43900be7 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1847,7 +1847,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) // Rises up to its topmost position when a // player steps on it. Lowers otherwise. // -void T_RaiseSector(levelspecthink_t *raise) +void T_RaiseSector(raise_t *raise) { msecnode_t *node; mobj_t *thing; @@ -1877,7 +1877,7 @@ void T_RaiseSector(levelspecthink_t *raise) continue; // Option to require spindashing. - if (raise->vars[1] && !(thing->player->pflags & PF_STARTDASH)) + if (raise->flags & RF_SPINDASH && !(thing->player->pflags & PF_STARTDASH)) continue; if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector))) @@ -1888,43 +1888,43 @@ void T_RaiseSector(levelspecthink_t *raise) } } - if (raise->vars[9]) // Dynamically Sinking Platform^tm + if (raise->flags & RF_DYNAMIC) // Dynamically Sinking Platform^tm { #define shaketime 10 - if (raise->vars[11] > shaketime) // State: moving + if (raise->shaketimer > shaketime) // State: moving { if (playeronme) // If player is standing on the platform, accelerate { - raise->vars[10] += (FRACUNIT >> 5); + raise->extraspeed += (FRACUNIT >> 5); } else // otherwise, decelerate until inflection { - raise->vars[10] -= FRACUNIT >> 3; - if (raise->vars[10] <= 0) // inflection! + raise->extraspeed -= FRACUNIT >> 3; + if (raise->extraspeed <= 0) // inflection! { - raise->vars[10] = 0; - raise->vars[11] = 0; // allow the shake to occur again (fucks over players attempting to jump-cheese) + raise->extraspeed = 0; + raise->shaketimer = 0; // allow the shake to occur again (fucks over players attempting to jump-cheese) } } - active = raise->vars[10] > 0; + active = raise->extraspeed > 0; } else // State: shaking { - if (playeronme || raise->vars[11]) + if (playeronme || raise->shaketimer) { active = true; - if (++raise->vars[11] > shaketime) + if (++raise->shaketimer > shaketime) { if (playeronme) - raise->vars[10] = FRACUNIT >> 5; + raise->extraspeed = FRACUNIT >> 5; else - raise->vars[10] = FRACUNIT << 1; + raise->extraspeed = FRACUNIT << 1; } else { - raise->vars[10] = ((shaketime/2) - raise->vars[11]) << FRACBITS; - if (raise->vars[10] < -raise->vars[2]/2) - raise->vars[10] = -raise->vars[2]/2; + raise->extraspeed = ((shaketime/2) - raise->shaketimer) << FRACBITS; + if (raise->extraspeed < -raise->basespeed/2) + raise->extraspeed = -raise->basespeed/2; } } } @@ -1935,123 +1935,123 @@ void T_RaiseSector(levelspecthink_t *raise) if (active) { - raise->vars[3] = raise->vars[2]; + raise->speed = raise->basespeed; - if (raise->vars[0] == 1) + if (raise->flags & RF_REVERSE) { - if (raise->sector->ceilingheight <= raise->vars[7]) + if (raise->sector->ceilingheight <= raise->ceilingbottom) { - raise->sector->floorheight = raise->vars[7] - (raise->sector->ceilingheight - raise->sector->floorheight); - raise->sector->ceilingheight = raise->vars[7]; + raise->sector->floorheight = raise->ceilingbottom - (raise->sector->ceilingheight - raise->sector->floorheight); + raise->sector->ceilingheight = raise->ceilingbottom; raise->sector->ceilspeed = 0; raise->sector->floorspeed = 0; return; } - raise->vars[8] = -1; - ceilingdestination = raise->vars[7]; - floordestination = raise->vars[6]; + raise->direction = -1; + ceilingdestination = raise->ceilingbottom; + floordestination = raise->floorbottom; } else // elevateUp { - if (raise->sector->ceilingheight >= raise->vars[5]) + if (raise->sector->ceilingheight >= raise->ceilingtop) { - raise->sector->floorheight = raise->vars[5] - (raise->sector->ceilingheight - raise->sector->floorheight); - raise->sector->ceilingheight = raise->vars[5]; + raise->sector->floorheight = raise->ceilingtop - (raise->sector->ceilingheight - raise->sector->floorheight); + raise->sector->ceilingheight = raise->ceilingtop; raise->sector->ceilspeed = 0; raise->sector->floorspeed = 0; return; } - raise->vars[8] = 1; - ceilingdestination = raise->vars[5]; - floordestination = raise->vars[4]; + raise->direction = 1; + ceilingdestination = raise->ceilingtop; + floordestination = raise->floortop; } } else { - raise->vars[3] = raise->vars[2]/2; + raise->speed = raise->basespeed/2; - if (raise->vars[0] == 1) + if (raise->flags & RF_REVERSE) { - if (raise->sector->ceilingheight >= raise->vars[5]) + if (raise->sector->ceilingheight >= raise->ceilingtop) { - raise->sector->floorheight = raise->vars[5] - (raise->sector->ceilingheight - raise->sector->floorheight); - raise->sector->ceilingheight = raise->vars[5]; + raise->sector->floorheight = raise->ceilingtop - (raise->sector->ceilingheight - raise->sector->floorheight); + raise->sector->ceilingheight = raise->ceilingtop; raise->sector->ceilspeed = 0; raise->sector->floorspeed = 0; return; } - raise->vars[8] = 1; - ceilingdestination = raise->vars[5]; - floordestination = raise->vars[4]; + raise->direction = 1; + ceilingdestination = raise->ceilingtop; + floordestination = raise->floortop; } else // elevateUp { - if (raise->sector->ceilingheight <= raise->vars[7]) + if (raise->sector->ceilingheight <= raise->ceilingbottom) { - raise->sector->floorheight = raise->vars[7] - (raise->sector->ceilingheight - raise->sector->floorheight); - raise->sector->ceilingheight = raise->vars[7]; + raise->sector->floorheight = raise->ceilingbottom - (raise->sector->ceilingheight - raise->sector->floorheight); + raise->sector->ceilingheight = raise->ceilingbottom; raise->sector->ceilspeed = 0; raise->sector->floorspeed = 0; return; } - raise->vars[8] = -1; - ceilingdestination = raise->vars[7]; - floordestination = raise->vars[6]; + raise->direction = -1; + ceilingdestination = raise->ceilingbottom; + floordestination = raise->floorbottom; } } - if ((raise->sector->ceilingheight - raise->vars[7]) - < (raise->vars[5] - raise->sector->ceilingheight)) + if ((raise->sector->ceilingheight - raise->ceilingbottom) + < (raise->ceilingtop - raise->sector->ceilingheight)) { - fixed_t origspeed = raise->vars[3]; + fixed_t origspeed = raise->speed; // Slow down as you get closer to the bottom - raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->sector->ceilingheight - raise->vars[7], (raise->vars[5] - raise->vars[7])>>5)); + raise->speed = FixedMul(raise->speed,FixedDiv(raise->sector->ceilingheight - raise->ceilingbottom, (raise->ceilingtop - raise->ceilingbottom)>>5)); - if (raise->vars[3] <= origspeed/16) - raise->vars[3] = origspeed/16; - else if (raise->vars[3] > origspeed) - raise->vars[3] = origspeed; + if (raise->speed <= origspeed/16) + raise->speed = origspeed/16; + else if (raise->speed > origspeed) + raise->speed = origspeed; } else { - fixed_t origspeed = raise->vars[3]; + fixed_t origspeed = raise->speed; // Slow down as you get closer to the top - raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->vars[5] - raise->sector->ceilingheight, (raise->vars[5] - raise->vars[7])>>5)); + raise->speed = FixedMul(raise->speed,FixedDiv(raise->ceilingtop - raise->sector->ceilingheight, (raise->ceilingtop - raise->ceilingbottom)>>5)); - if (raise->vars[3] <= origspeed/16) - raise->vars[3] = origspeed/16; - else if (raise->vars[3] > origspeed) - raise->vars[3] = origspeed; + if (raise->speed <= origspeed/16) + raise->speed = origspeed/16; + else if (raise->speed > origspeed) + raise->speed = origspeed; } - raise->vars[3] += raise->vars[10]; + raise->speed += raise->extraspeed; res = T_MovePlane ( raise->sector, // sector - raise->vars[3], // speed + raise->speed, // speed ceilingdestination, // dest 0, // crush 1, // floor or ceiling (1 for ceiling) - raise->vars[8] // direction + raise->direction // direction ); if (res == ok || res == pastdest) T_MovePlane ( raise->sector, // sector - raise->vars[3], // speed + raise->speed, // speed floordestination, // dest 0, // crush 0, // floor or ceiling (0 for floor) - raise->vars[8] // direction + raise->direction // direction ); raise->sector->ceilspeed = 42; - raise->sector->floorspeed = raise->vars[3]*raise->vars[8]; + raise->sector->floorspeed = raise->speed*raise->direction; for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) P_RecalcPrecipInSector(§ors[i]); diff --git a/src/p_saveg.c b/src/p_saveg.c index 259e58168..114f30172 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1659,6 +1659,28 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); } +// SaveRaiseThinker +// +// Saves a raise_t thinker +// +static void SaveRaiseThinker(const thinker_t *th, const UINT8 type) +{ + const raise_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEFIXED(save_p, ht->floorbottom); + WRITEFIXED(save_p, ht->ceilingbottom); + WRITEFIXED(save_p, ht->floortop); + WRITEFIXED(save_p, ht->ceilingtop); + WRITEFIXED(save_p, ht->basespeed); + WRITEFIXED(save_p, ht->speed); + WRITEINT32(save_p, ht->direction); + WRITEFIXED(save_p, ht->extraspeed); + WRITEUINT8(save_p, ht->shaketimer); + WRITEUINT8(save_p, ht->flags); +} + // // SaveCeilingThinker // @@ -2237,7 +2259,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_RaiseSector) { - SaveSpecialLevelThinker(th, tc_raisesector); + SaveRaiseThinker(th, tc_raisesector); continue; } else if (th->function.acp1 == (actionf_p1)T_CameraScanner) @@ -2770,6 +2792,29 @@ static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeili return &ht->thinker; } +// LoadRaiseThinker +// +// Loads a raise_t from a save game +// +static thinker_t* LoadRaiseThinker(actionf_p1 thinker) +{ + raise_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sourceline = LoadLine(READUINT32(save_p)); + ht->sector = LoadSector(READUINT32(save_p)); + ht->floorbottom = READFIXED(save_p); + ht->ceilingbottom = READFIXED(save_p); + ht->floortop = READFIXED(save_p); + ht->ceilingtop = READFIXED(save_p); + ht->basespeed = READFIXED(save_p); + ht->speed = READFIXED(save_p); + ht->direction = READINT32(save_p); + ht->extraspeed = READFIXED(save_p); + ht->shaketimer = READUINT8(save_p); + ht->flags = READUINT8(save_p); + return &ht->thinker; +} + // // LoadCeilingThinker // @@ -3448,7 +3493,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_raisesector: - th = LoadSpecialLevelThinker((actionf_p1)T_RaiseSector, 0); + th = LoadRaiseThinker((actionf_p1)T_RaiseSector); break; /// \todo rewrite all the code that uses an elevator_t but isn't an elevator diff --git a/src/p_spec.c b/src/p_spec.c index e73c6ee9a..b0be41ae3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6042,83 +6042,56 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) */ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline) { - levelspecthink_t *raise; + raise_t *raise; raise = Z_Calloc(sizeof (*raise), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &raise->thinker); raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector; - if (sourceline->flags & ML_BLOCKMONSTERS) - raise->vars[0] = 1; - else - raise->vars[0] = 0; - - // set up the fields + raise->sourceline = sourceline; raise->sector = sec; - // Require a spindash to activate + raise->ceilingtop = P_FindHighestCeilingSurrounding(sec); + raise->floortop = raise->ceilingtop - (sec->ceilingheight - sec->floorheight); + raise->ceilingbottom = P_FindLowestCeilingSurrounding(sec); + raise->floorbottom = raise->ceilingbottom - (sec->ceilingheight - sec->floorheight); + + raise->basespeed = FixedDiv(P_AproxDistance(sourceline->dx, sourceline->dy), 4*FRACUNIT); + raise->speed = raise->basespeed; + + if (sourceline->flags & ML_BLOCKMONSTERS) + raise->flags |= RF_REVERSE; if (sourceline->flags & ML_NOCLIMB) - raise->vars[1] = 1; - else - raise->vars[1] = 0; - - raise->vars[2] = P_AproxDistance(sourceline->dx, sourceline->dy); - raise->vars[2] = FixedDiv(raise->vars[2], 4*FRACUNIT); - raise->vars[3] = raise->vars[2]; - - raise->vars[5] = P_FindHighestCeilingSurrounding(sec); - raise->vars[4] = raise->vars[5] - - (sec->ceilingheight - sec->floorheight); - - raise->vars[7] = P_FindLowestCeilingSurrounding(sec); - raise->vars[6] = raise->vars[7] - - (sec->ceilingheight - sec->floorheight); - - raise->sourceline = sourceline; + raise->flags |= RF_SPINDASH; } static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic) { - levelspecthink_t *airbob; + raise_t *airbob; airbob = Z_Calloc(sizeof (*airbob), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &airbob->thinker); airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector; - // set up the fields + airbob->sourceline = sourceline; airbob->sector = sec; - // Require a spindash to activate - if (sourceline->flags & ML_NOCLIMB) - airbob->vars[1] = 1; - else - airbob->vars[1] = 0; + airbob->ceilingtop = sec->ceilingheight; + airbob->floortop = airbob->ceilingtop - (sec->ceilingheight - sec->floorheight); + airbob->ceilingbottom = sec->ceilingheight - (noadjust ? 16*FRACUNIT : P_AproxDistance(sourceline->dx, sourceline->dy)); + airbob->floorbottom = airbob->ceilingbottom - (sec->ceilingheight - sec->floorheight); - airbob->vars[2] = FRACUNIT; - - if (noadjust) - airbob->vars[7] = airbob->sector->ceilingheight-16*FRACUNIT; - else - airbob->vars[7] = airbob->sector->ceilingheight - P_AproxDistance(sourceline->dx, sourceline->dy); - airbob->vars[6] = airbob->vars[7] - - (sec->ceilingheight - sec->floorheight); - - airbob->vars[3] = airbob->vars[2]; + airbob->basespeed = FRACUNIT; + airbob->speed = airbob->basespeed; if (sourceline->flags & ML_BLOCKMONSTERS) - airbob->vars[0] = 1; - else - airbob->vars[0] = 0; - - airbob->vars[5] = sec->ceilingheight; - airbob->vars[4] = airbob->vars[5] - - (sec->ceilingheight - sec->floorheight); - - airbob->vars[9] = dynamic ? 1 : 0; - - airbob->sourceline = sourceline; + airbob->flags |= RF_REVERSE; + if (sourceline->flags & ML_NOCLIMB) + airbob->flags |= RF_SPINDASH; + if (dynamic) + airbob->flags |= RF_DYNAMIC; } /** Adds a thwomp thinker. diff --git a/src/p_spec.h b/src/p_spec.h index d756f1942..1608728d9 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -320,6 +320,30 @@ typedef struct sector_t *sector; // Sector the thinker is from } levelspecthink_t; +typedef enum +{ + RF_REVERSE = 1, //Lower when stood on + RF_SPINDASH = 1<<1, //Require spindash to move + RF_DYNAMIC = 1<<2, //Dynamically sinking platform +} raiseflag_t; + +typedef struct +{ + thinker_t thinker; + line_t *sourceline; + sector_t *sector; + fixed_t floorbottom; + fixed_t ceilingbottom; + fixed_t floortop; + fixed_t ceilingtop; + fixed_t basespeed; + fixed_t speed; + INT32 direction; //1 = up, -1 = down + fixed_t extraspeed; //For dynamically sinking platform + UINT8 shaketimer; //For dynamically sinking platform + UINT8 flags; +} raise_t; + #define ELEVATORSPEED (FRACUNIT*4) #define FLOORSPEED (FRACUNIT) @@ -359,7 +383,7 @@ void T_ThwompSector(levelspecthink_t *thwomp); void T_NoEnemiesSector(levelspecthink_t *nobaddies); void T_EachTimeThinker(levelspecthink_t *eachtime); void T_CameraScanner(elevator_t *elevator); -void T_RaiseSector(levelspecthink_t *sraise); +void T_RaiseSector(raise_t *raise); typedef struct { From a41dbe2bae93cc4e62f3547c0f4b7ecd32ab82cb Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 10:19:02 +0200 Subject: [PATCH 091/220] Get rid of code duplication in T_RaiseSector --- src/p_floor.c | 116 ++++++++++++-------------------------------------- 1 file changed, 27 insertions(+), 89 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index d43900be7..03fa8629f 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1854,7 +1854,10 @@ void T_RaiseSector(raise_t *raise) sector_t *sector; INT32 i; boolean playeronme = false, active = false; + boolean moveUp; fixed_t ceilingdestination, floordestination; + fixed_t origspeed; + fixed_t distToNearestEndpoint; result_e res = 0; if (raise->sector->crumblestate >= 3 || raise->sector->ceilingdata) @@ -1933,99 +1936,34 @@ void T_RaiseSector(raise_t *raise) else // Air bobbing platform (not a Dynamically Sinking Platform^tm) active = playeronme; - if (active) + raise->speed = raise->basespeed; + if (!active) + raise->speed /= 2; + + moveUp = active ^ (raise->flags & RF_REVERSE); + ceilingdestination = moveUp ? raise->ceilingtop : raise->ceilingbottom; + floordestination = moveUp ? raise->floortop : raise->floorbottom; + + if ((moveUp && raise->sector->ceilingheight >= ceilingdestination) + || (!moveUp && raise->sector->ceilingheight <= ceilingdestination)) { - raise->speed = raise->basespeed; - - if (raise->flags & RF_REVERSE) - { - if (raise->sector->ceilingheight <= raise->ceilingbottom) - { - raise->sector->floorheight = raise->ceilingbottom - (raise->sector->ceilingheight - raise->sector->floorheight); - raise->sector->ceilingheight = raise->ceilingbottom; - raise->sector->ceilspeed = 0; - raise->sector->floorspeed = 0; - return; - } - - raise->direction = -1; - ceilingdestination = raise->ceilingbottom; - floordestination = raise->floorbottom; - } - else // elevateUp - { - if (raise->sector->ceilingheight >= raise->ceilingtop) - { - raise->sector->floorheight = raise->ceilingtop - (raise->sector->ceilingheight - raise->sector->floorheight); - raise->sector->ceilingheight = raise->ceilingtop; - raise->sector->ceilspeed = 0; - raise->sector->floorspeed = 0; - return; - } - - raise->direction = 1; - ceilingdestination = raise->ceilingtop; - floordestination = raise->floortop; - } + raise->sector->floorheight = ceilingdestination - (raise->sector->ceilingheight - raise->sector->floorheight); + raise->sector->ceilingheight = ceilingdestination; + raise->sector->ceilspeed = 0; + raise->sector->floorspeed = 0; + return; } - else - { - raise->speed = raise->basespeed/2; + raise->direction = moveUp ? 1 : -1; - if (raise->flags & RF_REVERSE) - { - if (raise->sector->ceilingheight >= raise->ceilingtop) - { - raise->sector->floorheight = raise->ceilingtop - (raise->sector->ceilingheight - raise->sector->floorheight); - raise->sector->ceilingheight = raise->ceilingtop; - raise->sector->ceilspeed = 0; - raise->sector->floorspeed = 0; - return; - } - raise->direction = 1; - ceilingdestination = raise->ceilingtop; - floordestination = raise->floortop; - } - else // elevateUp - { - if (raise->sector->ceilingheight <= raise->ceilingbottom) - { - raise->sector->floorheight = raise->ceilingbottom - (raise->sector->ceilingheight - raise->sector->floorheight); - raise->sector->ceilingheight = raise->ceilingbottom; - raise->sector->ceilspeed = 0; - raise->sector->floorspeed = 0; - return; - } - raise->direction = -1; - ceilingdestination = raise->ceilingbottom; - floordestination = raise->floorbottom; - } - } + origspeed = raise->speed; + // Speed up as you get closer to the middle, then slow down again + distToNearestEndpoint = min(raise->sector->ceilingheight - raise->ceilingbottom, raise->ceilingtop - raise->sector->ceilingheight); + raise->speed = FixedMul(raise->speed, FixedDiv(distToNearestEndpoint, (raise->ceilingtop - raise->ceilingbottom) >> 5)); - if ((raise->sector->ceilingheight - raise->ceilingbottom) - < (raise->ceilingtop - raise->sector->ceilingheight)) - { - fixed_t origspeed = raise->speed; - - // Slow down as you get closer to the bottom - raise->speed = FixedMul(raise->speed,FixedDiv(raise->sector->ceilingheight - raise->ceilingbottom, (raise->ceilingtop - raise->ceilingbottom)>>5)); - - if (raise->speed <= origspeed/16) - raise->speed = origspeed/16; - else if (raise->speed > origspeed) - raise->speed = origspeed; - } - else - { - fixed_t origspeed = raise->speed; - // Slow down as you get closer to the top - raise->speed = FixedMul(raise->speed,FixedDiv(raise->ceilingtop - raise->sector->ceilingheight, (raise->ceilingtop - raise->ceilingbottom)>>5)); - - if (raise->speed <= origspeed/16) - raise->speed = origspeed/16; - else if (raise->speed > origspeed) - raise->speed = origspeed; - } + if (raise->speed <= origspeed/16) + raise->speed = origspeed/16; + else if (raise->speed > origspeed) + raise->speed = origspeed; raise->speed += raise->extraspeed; From 63a901b714182cf5963ecfbad371e9d383517e36 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 11:11:36 +0200 Subject: [PATCH 092/220] -Remove superfluous variables from raise_t -Cleanup signatures of P_AddRaiseThinker and P_AddAirbob --- src/p_floor.c | 52 ++++++++++++++++++++++++------------------------ src/p_saveg.c | 8 -------- src/p_spec.c | 55 ++++++++++++++++++++++++--------------------------- src/p_spec.h | 4 ---- 4 files changed, 52 insertions(+), 67 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 03fa8629f..8b4b515fe 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1856,8 +1856,9 @@ void T_RaiseSector(raise_t *raise) boolean playeronme = false, active = false; boolean moveUp; fixed_t ceilingdestination, floordestination; - fixed_t origspeed; + fixed_t speed, origspeed; fixed_t distToNearestEndpoint; + INT32 direction; result_e res = 0; if (raise->sector->crumblestate >= 3 || raise->sector->ceilingdata) @@ -1936,60 +1937,59 @@ void T_RaiseSector(raise_t *raise) else // Air bobbing platform (not a Dynamically Sinking Platform^tm) active = playeronme; - raise->speed = raise->basespeed; - if (!active) - raise->speed /= 2; - moveUp = active ^ (raise->flags & RF_REVERSE); ceilingdestination = moveUp ? raise->ceilingtop : raise->ceilingbottom; - floordestination = moveUp ? raise->floortop : raise->floorbottom; + floordestination = ceilingdestination - (raise->sector->ceilingheight - raise->sector->floorheight); if ((moveUp && raise->sector->ceilingheight >= ceilingdestination) || (!moveUp && raise->sector->ceilingheight <= ceilingdestination)) { - raise->sector->floorheight = ceilingdestination - (raise->sector->ceilingheight - raise->sector->floorheight); + raise->sector->floorheight = floordestination; raise->sector->ceilingheight = ceilingdestination; raise->sector->ceilspeed = 0; raise->sector->floorspeed = 0; return; } - raise->direction = moveUp ? 1 : -1; + direction = moveUp ? 1 : -1; + + origspeed = raise->basespeed; + if (!active) + origspeed /= 2; - origspeed = raise->speed; // Speed up as you get closer to the middle, then slow down again distToNearestEndpoint = min(raise->sector->ceilingheight - raise->ceilingbottom, raise->ceilingtop - raise->sector->ceilingheight); - raise->speed = FixedMul(raise->speed, FixedDiv(distToNearestEndpoint, (raise->ceilingtop - raise->ceilingbottom) >> 5)); + speed = FixedMul(origspeed, FixedDiv(distToNearestEndpoint, (raise->ceilingtop - raise->ceilingbottom) >> 5)); - if (raise->speed <= origspeed/16) - raise->speed = origspeed/16; - else if (raise->speed > origspeed) - raise->speed = origspeed; + if (speed <= origspeed/16) + speed = origspeed/16; + else if (speed > origspeed) + speed = origspeed; - raise->speed += raise->extraspeed; + speed += raise->extraspeed; res = T_MovePlane ( - raise->sector, // sector - raise->speed, // speed + raise->sector, // sector + speed, // speed ceilingdestination, // dest - 0, // crush - 1, // floor or ceiling (1 for ceiling) - raise->direction // direction + 0, // crush + 1, // floor or ceiling (1 for ceiling) + direction // direction ); if (res == ok || res == pastdest) T_MovePlane ( - raise->sector, // sector - raise->speed, // speed + raise->sector, // sector + speed, // speed floordestination, // dest - 0, // crush - 0, // floor or ceiling (0 for floor) - raise->direction // direction + 0, // crush + 0, // floor or ceiling (0 for floor) + direction // direction ); raise->sector->ceilspeed = 42; - raise->sector->floorspeed = raise->speed*raise->direction; + raise->sector->floorspeed = speed*direction; for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) P_RecalcPrecipInSector(§ors[i]); diff --git a/src/p_saveg.c b/src/p_saveg.c index 114f30172..c93756983 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1669,13 +1669,9 @@ static void SaveRaiseThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, type); WRITEUINT32(save_p, SaveLine(ht->sourceline)); WRITEUINT32(save_p, SaveSector(ht->sector)); - WRITEFIXED(save_p, ht->floorbottom); WRITEFIXED(save_p, ht->ceilingbottom); - WRITEFIXED(save_p, ht->floortop); WRITEFIXED(save_p, ht->ceilingtop); WRITEFIXED(save_p, ht->basespeed); - WRITEFIXED(save_p, ht->speed); - WRITEINT32(save_p, ht->direction); WRITEFIXED(save_p, ht->extraspeed); WRITEUINT8(save_p, ht->shaketimer); WRITEUINT8(save_p, ht->flags); @@ -2802,13 +2798,9 @@ static thinker_t* LoadRaiseThinker(actionf_p1 thinker) ht->thinker.function.acp1 = thinker; ht->sourceline = LoadLine(READUINT32(save_p)); ht->sector = LoadSector(READUINT32(save_p)); - ht->floorbottom = READFIXED(save_p); ht->ceilingbottom = READFIXED(save_p); - ht->floortop = READFIXED(save_p); ht->ceilingtop = READFIXED(save_p); ht->basespeed = READFIXED(save_p); - ht->speed = READFIXED(save_p); - ht->direction = READINT32(save_p); ht->extraspeed = READFIXED(save_p); ht->shaketimer = READUINT8(save_p); ht->flags = READUINT8(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index b0be41ae3..ea86c88a4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6040,7 +6040,7 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) * \sa P_SpawnSpecials, T_RaiseSector * \author SSNTails */ -static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline) +static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower, boolean spindash) { raise_t *raise; @@ -6053,20 +6053,17 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline) raise->sector = sec; raise->ceilingtop = P_FindHighestCeilingSurrounding(sec); - raise->floortop = raise->ceilingtop - (sec->ceilingheight - sec->floorheight); raise->ceilingbottom = P_FindLowestCeilingSurrounding(sec); - raise->floorbottom = raise->ceilingbottom - (sec->ceilingheight - sec->floorheight); raise->basespeed = FixedDiv(P_AproxDistance(sourceline->dx, sourceline->dy), 4*FRACUNIT); - raise->speed = raise->basespeed; - if (sourceline->flags & ML_BLOCKMONSTERS) + if (lower) raise->flags |= RF_REVERSE; - if (sourceline->flags & ML_NOCLIMB) + if (spindash) raise->flags |= RF_SPINDASH; } -static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boolean dynamic) +static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean raise, boolean spindash, boolean dynamic) { raise_t *airbob; @@ -6079,16 +6076,15 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, boolean noadjust, boo airbob->sector = sec; airbob->ceilingtop = sec->ceilingheight; - airbob->floortop = airbob->ceilingtop - (sec->ceilingheight - sec->floorheight); - airbob->ceilingbottom = sec->ceilingheight - (noadjust ? 16*FRACUNIT : P_AproxDistance(sourceline->dx, sourceline->dy)); - airbob->floorbottom = airbob->ceilingbottom - (sec->ceilingheight - sec->floorheight); + airbob->ceilingbottom = sec->ceilingheight - speed; airbob->basespeed = FRACUNIT; - airbob->speed = airbob->basespeed; - if (sourceline->flags & ML_BLOCKMONSTERS) + airbob->flags = flags; + + if (!raise) airbob->flags |= RF_REVERSE; - if (sourceline->flags & ML_NOCLIMB) + if (spindash) airbob->flags |= RF_SPINDASH; if (dynamic) airbob->flags |= RF_DYNAMIC; @@ -6894,18 +6890,22 @@ void P_SpawnSpecials(boolean fromnetsave) case 150: // Air bobbing platform case 151: // Adjustable air bobbing platform + { + fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : P_AproxDistance(lines[i].dx, lines[i].dy); P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - lines[i].flags |= ML_BLOCKMONSTERS; - P_AddAirbob(lines[i].frontsector, lines + i, (lines[i].special != 151), false); + P_AddAirbob(lines[i].frontsector, lines + i, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); break; + } case 152: // Adjustable air bobbing platform in reverse + if (lines[i].flags & NOCLIMB) + raiseflags |= RF_SPINDASH; P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, true, false); + P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); break; case 153: // Dynamic Sinking Platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); lines[i].flags |= ML_BLOCKMONSTERS; - P_AddAirbob(lines[i].frontsector, lines + i, false, true); + P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); break; case 160: // Float/bob platform @@ -6955,15 +6955,13 @@ void P_SpawnSpecials(boolean fromnetsave) case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers); - lines[i].flags |= ML_BLOCKMONSTERS; - P_AddAirbob(lines[i].frontsector, lines + i, true, false); + P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 177: // Air bobbing platform that will crumble and bob on // the water when it falls and hits, then never return P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers); - lines[i].flags |= ML_BLOCKMONSTERS; - P_AddAirbob(lines[i].frontsector, lines + i, true, false); + P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 178: // Crumbling platform that will float when it hits water @@ -6976,28 +6974,27 @@ void P_SpawnSpecials(boolean fromnetsave) case 180: // Air bobbing platform that will crumble P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers); - lines[i].flags |= ML_BLOCKMONSTERS; - P_AddAirbob(lines[i].frontsector, lines + i, true, false); + P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 190: // Rising Platform FOF (solid, opaque, shadows) P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i]); + P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; case 191: // Rising Platform FOF (solid, opaque, no shadows) P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_CUTLEVEL, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i]); + P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; case 192: // Rising Platform TL block: FOF (solid, translucent) P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i]); + P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; case 193: // Rising Platform FOF (solid, invisible) P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_NOSHADE, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i]); + P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; case 194: // Rising Platform 'Platform' - You can jump up through it @@ -7007,7 +7004,7 @@ void P_SpawnSpecials(boolean fromnetsave) ffloorflags |= FF_NOSHADE; P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i]); + P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; case 195: // Rising Platform Translucent "platform" @@ -7017,7 +7014,7 @@ void P_SpawnSpecials(boolean fromnetsave) ffloorflags |= FF_NOSHADE; P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i]); + P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; case 200: // Double light effect diff --git a/src/p_spec.h b/src/p_spec.h index 1608728d9..eb61ad7bf 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -332,13 +332,9 @@ typedef struct thinker_t thinker; line_t *sourceline; sector_t *sector; - fixed_t floorbottom; fixed_t ceilingbottom; - fixed_t floortop; fixed_t ceilingtop; fixed_t basespeed; - fixed_t speed; - INT32 direction; //1 = up, -1 = down fixed_t extraspeed; //For dynamically sinking platform UINT8 shaketimer; //For dynamically sinking platform UINT8 flags; From 3e0a9c8718595daf124987a88b1220bc136f8937 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 11:13:13 +0200 Subject: [PATCH 093/220] Forgot to clean up some stuff --- src/p_spec.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index ea86c88a4..a72f56cc0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6076,12 +6076,10 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean airbob->sector = sec; airbob->ceilingtop = sec->ceilingheight; - airbob->ceilingbottom = sec->ceilingheight - speed; + airbob->ceilingbottom = sec->ceilingheight - dist; airbob->basespeed = FRACUNIT; - airbob->flags = flags; - if (!raise) airbob->flags |= RF_REVERSE; if (spindash) @@ -6897,8 +6895,6 @@ void P_SpawnSpecials(boolean fromnetsave) break; } case 152: // Adjustable air bobbing platform in reverse - if (lines[i].flags & NOCLIMB) - raiseflags |= RF_SPINDASH; P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); break; From 89539512f69f795f7a11c4d57dc5633aee9657f0 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 14:00:48 +0200 Subject: [PATCH 094/220] Make T_EachTimeThinker use its own struct --- src/p_floor.c | 45 ++++++++++----------------------------------- src/p_saveg.c | 41 +++++++++++++++++++++++++++++++++++++++-- src/p_spec.c | 11 +++++------ src/p_spec.h | 11 ++++++++++- 4 files changed, 64 insertions(+), 44 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 8b4b515fe..a5c358621 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1581,7 +1581,7 @@ static INT32 P_HavePlayersEnteredArea(boolean *curPlayers, boolean *oldPlayers, // // \sa P_AddEachTimeThinker // -void T_EachTimeThinker(levelspecthink_t *eachtime) +void T_EachTimeThinker(eachtime_t *eachtime) { size_t i, j; sector_t *sec = NULL; @@ -1604,19 +1604,10 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) for (i = 0; i < MAXPLAYERS; i++) { - if (i & 1) - { - oldPlayersInArea[i] = eachtime->vars[i/2] & 65535; - oldPlayersOnArea[i] = eachtime->var2s[i/2] & 65535; - eachtime->vars[i/2] = 0; - eachtime->var2s[i/2] = 0; - } - else - { - oldPlayersInArea[i] = eachtime->vars[i/2] >> 16; - oldPlayersOnArea[i] = eachtime->var2s[i/2] >> 16; - } - + oldPlayersInArea[i] = eachtime->playersInArea[i]; + oldPlayersOnArea[i] = eachtime->playersOnArea[i]; + eachtime->playersInArea[i] = false; + eachtime->playersOnArea[i] = false; playersInArea[i] = false; playersOnArea[i] = false; } @@ -1705,20 +1696,12 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) if (floortouch == true && P_IsObjectOnGroundIn(players[j].mo, targetsec)) { - if (j & 1) - eachtime->var2s[j/2] |= 1; - else - eachtime->var2s[j/2] |= 1 << 16; - + eachtime->playersOnArea[j] = true; playersOnArea[j] = true; } else { - if (j & 1) - eachtime->vars[j/2] |= 1; - else - eachtime->vars[j/2] |= 1 << 16; - + eachtime->playersInArea[j] = true; playersInArea[j] = true; } } @@ -1766,27 +1749,19 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec)) { - if (i & 1) - eachtime->var2s[i/2] |= 1; - else - eachtime->var2s[i/2] |= 1 << 16; - + eachtime->playersOnArea[i] = true; playersOnArea[i] = true; } else { - if (i & 1) - eachtime->vars[i/2] |= 1; - else - eachtime->vars[i/2] |= 1 << 16; - + eachtime->playersInArea[i] = true; playersInArea[i] = true; } } } } - if ((eachtime->sourceline->flags & ML_BOUNCY) == ML_BOUNCY) + if (eachtime->triggerOnExit) inAndOut = true; // Check if a new player entered. diff --git a/src/p_saveg.c b/src/p_saveg.c index c93756983..58fb7ad52 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1659,6 +1659,24 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); } +// SaveEachTimeThinker +// +// Loads a eachtime_t from a save game +// +static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type) +{ + const eachtime_t *ht = (const void *)th; + size_t i; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); + for (i = 0; i < MAXPLAYERS; i++) + { + WRITECHAR(save_p, ht->playersInArea[i]); + WRITECHAR(save_p, ht->playersOnArea[i]); + } + WRITECHAR(save_p, ht->triggerOnExit); +} + // SaveRaiseThinker // // Saves a raise_t thinker @@ -2250,7 +2268,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_EachTimeThinker) { - SaveSpecialLevelThinker(th, tc_eachtime); + SaveEachTimeThinker(th, tc_eachtime); continue; } else if (th->function.acp1 == (actionf_p1)T_RaiseSector) @@ -2788,6 +2806,25 @@ static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeili return &ht->thinker; } +// LoadEachTimeThinker +// +// Loads a eachtime_t from a save game +// +static thinker_t* LoadEachTimeThinker(actionf_p1 thinker) +{ + size_t i; + eachtime_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sourceline = LoadLine(READUINT32(save_p)); + for (i = 0; i < MAXPLAYERS; i++) + { + ht->playersInArea[i] = READCHAR(save_p); + ht->playersOnArea[i] = READCHAR(save_p); + } + ht->triggerOnExit = READCHAR(save_p); + return &ht->thinker; +} + // LoadRaiseThinker // // Loads a raise_t from a save game @@ -3481,7 +3518,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_eachtime: - th = LoadSpecialLevelThinker((actionf_p1)T_EachTimeThinker, 0); + th = LoadEachTimeThinker((actionf_p1)T_EachTimeThinker); break; case tc_raisesector: diff --git a/src/p_spec.c b/src/p_spec.c index a72f56cc0..7a99b1fad 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6160,14 +6160,13 @@ static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline) /** Adds a thinker for Each-Time linedef executors. A linedef executor is run * only when a player enters the area and doesn't run again until they re-enter. * - * \param sec Control sector that contains the lines of executors we will want to run. * \param sourceline Control linedef. * \sa P_SpawnSpecials, T_EachTimeThinker * \author SSNTails */ -static void P_AddEachTimeThinker(sector_t *sec, line_t *sourceline) +static void P_AddEachTimeThinker(line_t *sourceline) { - levelspecthink_t *eachtime; + eachtime_t *eachtime; // create and initialize new thinker eachtime = Z_Calloc(sizeof (*eachtime), PU_LEVSPEC, NULL); @@ -6175,8 +6174,8 @@ static void P_AddEachTimeThinker(sector_t *sec, line_t *sourceline) eachtime->thinker.function.acp1 = (actionf_p1)T_EachTimeThinker; - eachtime->sector = sec; eachtime->sourceline = sourceline; + eachtime->triggerOnExit = !!(sourceline->flags & ML_BOUNCY); } /** Adds a camera scanner. @@ -7160,7 +7159,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 332: case 335: sec = sides[*lines[i].sidenum].sector - sectors; - P_AddEachTimeThinker(§ors[sec], &lines[i]); + P_AddEachTimeThinker(&lines[i]); break; // No More Enemies Linedef Exec @@ -7192,7 +7191,7 @@ void P_SpawnSpecials(boolean fromnetsave) if (lines[i].special == 322) // Each time { sec = sides[*lines[i].sidenum].sector - sectors; - P_AddEachTimeThinker(§ors[sec], &lines[i]); + P_AddEachTimeThinker(&lines[i]); } break; diff --git a/src/p_spec.h b/src/p_spec.h index eb61ad7bf..8cccc96e4 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -320,6 +320,15 @@ typedef struct sector_t *sector; // Sector the thinker is from } levelspecthink_t; +typedef struct +{ + thinker_t thinker; + line_t *sourceline; // Source line of the thinker + boolean playersInArea[MAXPLAYERS]; + boolean playersOnArea[MAXPLAYERS]; + boolean triggerOnExit; +} eachtime_t; + typedef enum { RF_REVERSE = 1, //Lower when stood on @@ -377,7 +386,7 @@ void T_FloatSector(levelspecthink_t *floater); void T_MarioBlockChecker(levelspecthink_t *block); void T_ThwompSector(levelspecthink_t *thwomp); void T_NoEnemiesSector(levelspecthink_t *nobaddies); -void T_EachTimeThinker(levelspecthink_t *eachtime); +void T_EachTimeThinker(eachtime_t *eachtime); void T_CameraScanner(elevator_t *elevator); void T_RaiseSector(raise_t *raise); From 5a58b2d90e75db8e192478429d1a7eaddd7c4b3a Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 21:19:21 +0200 Subject: [PATCH 095/220] Refactor T_EachTimeThinker --- src/p_floor.c | 180 ++++++++++++++++---------------------------------- 1 file changed, 58 insertions(+), 122 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index a5c358621..2a0d09b65 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1547,30 +1547,40 @@ static boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec) return false; } -// -// P_HavePlayersEnteredArea -// -// Helper function for T_EachTimeThinker -// -static INT32 P_HavePlayersEnteredArea(boolean *curPlayers, boolean *oldPlayers, boolean inAndOut) +static boolean P_IsPlayerValid(size_t playernum) { - INT32 i; + if (!playeringame[playernum]) + return false; - // Easy check... nothing has changed - if (!memcmp(curPlayers, oldPlayers, sizeof(boolean)*MAXPLAYERS)) - return -1; + if (!players[playernum].mo) + return false; - // Otherwise, we have to check if any new players have entered - for (i = 0; i < MAXPLAYERS; i++) + if (players[playernum].mo->health <= 0) + return false; + + if (players[playernum].spectator) + return false; + + return true; +} + +static boolean P_IsMobjTouchingSector(mobj_t *mo, sector_t *sec) +{ + msecnode_t *node; + + if (mo->subsector->sector == sec) + return true; + + if (!(sec->flags & SF_TRIGGERSPECIAL_TOUCH)) + return false; + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) { - if (inAndOut && !curPlayers[i] && oldPlayers[i]) - return i; - - if (curPlayers[i] && !oldPlayers[i]) - return i; + if (node->m_sector == sec) + return true; } - return -1; + return false; } // @@ -1586,20 +1596,14 @@ void T_EachTimeThinker(eachtime_t *eachtime) size_t i, j; sector_t *sec = NULL; sector_t *targetsec = NULL; - //sector_t *usesec = NULL; INT32 secnum = -1; - INT32 affectPlayer = 0; boolean oldPlayersInArea[MAXPLAYERS]; - boolean playersInArea[MAXPLAYERS]; boolean oldPlayersOnArea[MAXPLAYERS]; - boolean playersOnArea[MAXPLAYERS]; boolean *oldPlayersArea; boolean *playersArea; boolean FOFsector = false; - boolean inAndOut = false; boolean floortouch = false; fixed_t bottomheight, topheight; - msecnode_t *node; ffloor_t *rover; for (i = 0; i < MAXPLAYERS; i++) @@ -1608,8 +1612,6 @@ void T_EachTimeThinker(eachtime_t *eachtime) oldPlayersOnArea[i] = eachtime->playersOnArea[i]; eachtime->playersInArea[i] = false; eachtime->playersOnArea[i] = false; - playersInArea[i] = false; - playersOnArea[i] = false; } while ((secnum = P_FindSectorFromLineTag(eachtime->sourceline, secnum)) >= 0) @@ -1654,35 +1656,10 @@ void T_EachTimeThinker(eachtime_t *eachtime) for (j = 0; j < MAXPLAYERS; j++) { - if (!playeringame[j]) + if (!P_IsPlayerValid(j)) continue; - if (!players[j].mo) - continue; - - if (players[j].mo->health <= 0) - continue; - - if ((netgame || multiplayer) && players[j].spectator) - continue; - - if (players[j].mo->subsector->sector == targetsec) - ; - else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH) - { - boolean insector = false; - for (node = players[j].mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (node->m_sector == targetsec) - { - insector = true; - break; - } - } - if (!insector) - continue; - } - else + if (!P_IsMobjTouchingSector(players[j].mo, targetsec)) continue; topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec); @@ -1694,16 +1671,10 @@ void T_EachTimeThinker(eachtime_t *eachtime) if (players[j].mo->z + players[j].mo->height < bottomheight) continue; - if (floortouch == true && P_IsObjectOnGroundIn(players[j].mo, targetsec)) - { + if (floortouch && P_IsObjectOnGroundIn(players[j].mo, targetsec)) eachtime->playersOnArea[j] = true; - playersOnArea[j] = true; - } else - { eachtime->playersInArea[j] = true; - playersInArea[j] = true; - } } } } @@ -1712,94 +1683,61 @@ void T_EachTimeThinker(eachtime_t *eachtime) { for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i]) + if (!P_IsPlayerValid(i)) continue; - if (!players[i].mo) - continue; - - if (players[i].mo->health <= 0) - continue; - - if ((netgame || multiplayer) && players[i].spectator) - continue; - - if (players[i].mo->subsector->sector == sec) - ; - else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH) - { - boolean insector = false; - for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (node->m_sector == sec) - { - insector = true; - break; - } - } - if (!insector) - continue; - } - else + if (!P_IsMobjTouchingSector(players[i].mo, sec)) continue; if (!(players[i].mo->subsector->sector == sec || P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec)) continue; - if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec)) - { + if (floortouch && P_IsObjectOnRealGround(players[i].mo, sec)) eachtime->playersOnArea[i] = true; - playersOnArea[i] = true; - } else - { eachtime->playersInArea[i] = true; - playersInArea[i] = true; - } } } } - if (eachtime->triggerOnExit) - inAndOut = true; - // Check if a new player entered. // If not, check if a player hit the floor. // If either condition is true, execute. - if (floortouch == true) + if (floortouch) { - playersArea = playersOnArea; + playersArea = eachtime->playersOnArea; oldPlayersArea = oldPlayersOnArea; } else { - playersArea = playersInArea; + playersArea = eachtime->playersInArea; oldPlayersArea = oldPlayersInArea; } - while ((affectPlayer = P_HavePlayersEnteredArea(playersArea, oldPlayersArea, inAndOut)) != -1) + // Easy check... nothing has changed + if (!memcmp(playersArea, oldPlayersArea, sizeof(boolean)*MAXPLAYERS)) + return; + + // If sector has an "all players" trigger type, all players need to be in area + if (GETSECSPECIAL(sec->special, 2) == 2 || GETSECSPECIAL(sec->special, 2) == 3) { - if (GETSECSPECIAL(sec->special, 2) == 2 || GETSECSPECIAL(sec->special, 2) == 3) + for (i = 0; i < MAXPLAYERS; i++) { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (!players[i].mo) - continue; - - if (players[i].mo->health <= 0) - continue; - - if ((netgame || multiplayer) && players[i].spectator) - continue; - - if (!playersArea[i]) - return; - } + if (P_IsPlayerValid(i) && playersArea[i]) + continue; } + } + + // Trigger for every player who has entered (and exited, if triggerOnExit) + for (i = 0; i < MAXPLAYERS; i++) + { + if (playersArea[i] == oldPlayersArea[i]) + continue; + + // If player has just left, check if still valid + if (!playersArea[i] && (!eachtime->triggerOnExit || !P_IsPlayerValid(i))) + continue; CONS_Debug(DBG_GAMELOGIC, "Trying to activate each time executor with tag %d\n", eachtime->sourceline->tag); @@ -1807,12 +1745,10 @@ void T_EachTimeThinker(eachtime_t *eachtime) // No more stupid hacks involving changing eachtime->sourceline's tag or special or whatever! // This should now run ONLY the stuff for eachtime->sourceline itself, instead of all trigger linedefs sharing the same tag. // Makes much more sense doing it this way, honestly. - P_RunTriggerLinedef(eachtime->sourceline, players[affectPlayer].mo, sec); + P_RunTriggerLinedef(eachtime->sourceline, players[i].mo, sec); if (!eachtime->sourceline->special) // this happens only for "Trigger on X calls" linedefs P_RemoveThinker(&eachtime->thinker); - - oldPlayersArea[affectPlayer]=playersArea[affectPlayer]; } } From 099ad6cf201fa9888271a523c7b67bf050f990fc Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 21:39:38 +0200 Subject: [PATCH 096/220] Remove sec assignments that have become superfluous --- src/p_spec.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 7a99b1fad..295be09e9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7158,7 +7158,6 @@ void P_SpawnSpecials(boolean fromnetsave) case 312: case 332: case 335: - sec = sides[*lines[i].sidenum].sector - sectors; P_AddEachTimeThinker(&lines[i]); break; @@ -7189,10 +7188,7 @@ void P_SpawnSpecials(boolean fromnetsave) else lines[i].callcount = sides[lines[i].sidenum[0]].textureoffset>>FRACBITS; if (lines[i].special == 322) // Each time - { - sec = sides[*lines[i].sidenum].sector - sectors; P_AddEachTimeThinker(&lines[i]); - } break; // NiGHTS trigger executors From 9b27d004e3462d3861934f1196bc322055593c86 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 22:54:35 +0200 Subject: [PATCH 097/220] Remove the spike thinker, which hasn't been necessary for a while now --- src/p_floor.c | 72 --------------------------------------------------- src/p_saveg.c | 10 ------- src/p_spec.c | 49 ++++------------------------------- src/p_spec.h | 1 - 4 files changed, 5 insertions(+), 127 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 2a0d09b65..52a348cb7 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1069,78 +1069,6 @@ void T_MarioBlock(levelspecthink_t *block) #undef low } -void T_SpikeSector(levelspecthink_t *spikes) -{ - mobj_t *thing; - msecnode_t *node; - boolean dothepain; - sector_t *affectsec; - - node = spikes->sector->touching_thinglist; // things touching this sector - - for (; node; node = node->m_thinglist_next) - { - thing = node->m_thing; - if (!thing->player) - continue; - - dothepain = false; - affectsec = §ors[spikes->vars[0]]; - - if (affectsec == spikes->sector) // Applied to an actual sector - { - fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, affectsec); - fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, affectsec); - - if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) - { - if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) - continue; - - if (thing->z == affectfloor) - dothepain = true; - } - - if (affectsec->flags & SF_FLIPSPECIAL_CEILING) - { - if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) - continue; - - if (thing->z + thing->height == affectceil) - dothepain = true; - } - } - else - { - fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, spikes->sector); - fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, spikes->sector); - if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) - { - if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) - continue; - - if (thing->z == affectceil) - dothepain = true; - } - - if (affectsec->flags & SF_FLIPSPECIAL_CEILING) - { - if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) - continue; - - if (thing->z + thing->height == affectfloor) - dothepain = true; - } - } - - if (dothepain) - { - P_DamageMobj(thing, NULL, NULL, 1, DMG_SPIKE); - break; - } - } -} - void T_FloatSector(levelspecthink_t *floater) { fixed_t cheeseheight; diff --git a/src/p_saveg.c b/src/p_saveg.c index 58fb7ad52..c9d4bb5fb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1273,7 +1273,6 @@ typedef enum tc_startcrumble, tc_marioblock, tc_marioblockchecker, - tc_spikesector, tc_floatsector, tc_crushceiling, tc_scroll, @@ -2316,11 +2315,6 @@ static void P_NetArchiveThinkers(void) SaveSpecialLevelThinker(th, tc_marioblockchecker); continue; } - else if (th->function.acp1 == (actionf_p1)T_SpikeSector) - { - SaveSpecialLevelThinker(th, tc_spikesector); - continue; - } else if (th->function.acp1 == (actionf_p1)T_FloatSector) { SaveSpecialLevelThinker(th, tc_floatsector); @@ -3547,10 +3541,6 @@ static void P_NetUnArchiveThinkers(void) th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0); break; - case tc_spikesector: - th = LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0); - break; - case tc_floatsector: th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0); break; diff --git a/src/p_spec.c b/src/p_spec.c index 295be09e9..2dcc21cbe 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -119,7 +119,6 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline); static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers); static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec); static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer); -static void P_AddSpikeThinker(sector_t *sec, INT32 referrer); static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse); @@ -4446,7 +4445,8 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers P_DamageMobj(player->mo, NULL, NULL, 1, DMG_ELECTRIC); break; case 5: // Spikes - // Don't do anything. In Soviet Russia, spikes find you. + if (roversector || P_MobjReadyToTrigger(player->mo, sector)) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPIKE); break; case 6: // Death Pit (Camera Mod) case 7: // Death Pit (No Camera Mod) @@ -5754,7 +5754,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f thinker_t *th; friction_t *f; pusher_t *p; - levelspecthink_t *lst; size_t sec2num; size_t i; @@ -5855,16 +5854,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f else if (th == &thlist[THINK_MAIN]) break; - // Should this FOF have spikeness? - if (th->function.acp1 == (actionf_p1)T_SpikeSector) - { - lst = (levelspecthink_t *)th; - - if (lst->sector == sec2) - P_AddSpikeThinker(sec, (INT32)sec2num); - } // Should this FOF have friction? - else if(th->function.acp1 == (actionf_p1)T_Friction) + if(th->function.acp1 == (actionf_p1)T_Friction) { f = (friction_t *)th; @@ -5928,28 +5919,6 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f // SPECIAL SPAWNING // -/** Adds a spike thinker. - * Sector type Section1:5 will result in this effect. - * - * \param sec Sector in which to add the thinker. - * \param referrer If != sec, then we're dealing with a FOF - * \sa P_SpawnSpecials, T_SpikeSector - * \author SSNTails - */ -static void P_AddSpikeThinker(sector_t *sec, INT32 referrer) -{ - levelspecthink_t *spikes; - - // create and initialize new thinker - spikes = Z_Calloc(sizeof (*spikes), PU_LEVSPEC, NULL); - P_AddThinker(THINK_MAIN, &spikes->thinker); - - spikes->thinker.function.acp1 = (actionf_p1)T_SpikeSector; - - spikes->sector = sec; - spikes->vars[0] = referrer; -} - /** Adds a float thinker. * Float thinkers cause solid 3Dfloors to float on water. * @@ -6401,10 +6370,6 @@ void P_SpawnSpecials(boolean fromnetsave) // Process Section 1 switch(GETSECSPECIAL(sector->special, 1)) { - case 5: // Spikes - P_AddSpikeThinker(sector, (INT32)(sector-sectors)); - break; - case 15: // Bouncy sector CheckForBouncySector = true; break; @@ -6450,9 +6415,7 @@ void P_SpawnSpecials(boolean fromnetsave) // Firstly, find out how many there are in each sector for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next) { - if (th->function.acp1 == (actionf_p1)T_SpikeSector) - secthinkers[((levelspecthink_t *)th)->sector - sectors].count++; - else if (th->function.acp1 == (actionf_p1)T_Friction) + if (th->function.acp1 == (actionf_p1)T_Friction) secthinkers[((friction_t *)th)->affectee].count++; else if (th->function.acp1 == (actionf_p1)T_Pusher) secthinkers[((pusher_t *)th)->affectee].count++; @@ -6472,9 +6435,7 @@ void P_SpawnSpecials(boolean fromnetsave) { size_t secnum = (size_t)-1; - if (th->function.acp1 == (actionf_p1)T_SpikeSector) - secnum = ((levelspecthink_t *)th)->sector - sectors; - else if (th->function.acp1 == (actionf_p1)T_Friction) + if (th->function.acp1 == (actionf_p1)T_Friction) secnum = ((friction_t *)th)->affectee; else if (th->function.acp1 == (actionf_p1)T_Pusher) secnum = ((pusher_t *)th)->affectee; diff --git a/src/p_spec.h b/src/p_spec.h index 8cccc96e4..79f6090fd 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -381,7 +381,6 @@ void T_ContinuousFalling(levelspecthink_t *faller); void T_BounceCheese(levelspecthink_t *bouncer); void T_StartCrumble(elevator_t *elevator); void T_MarioBlock(levelspecthink_t *block); -void T_SpikeSector(levelspecthink_t *spikes); void T_FloatSector(levelspecthink_t *floater); void T_MarioBlockChecker(levelspecthink_t *block); void T_ThwompSector(levelspecthink_t *thwomp); From 779b10681fa45f983513807ec67079d2e9e00f24 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 23:32:39 +0200 Subject: [PATCH 098/220] Refactoring in T_BounceCheese --- src/p_floor.c | 69 +++++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 52a348cb7..85304d779 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -682,11 +682,13 @@ void T_BounceCheese(levelspecthink_t *bouncer) #define low vars[2] #define ceilingwasheight vars[3] #define floorwasheight vars[4] + fixed_t sectorheight; fixed_t halfheight; fixed_t waterheight; fixed_t floorheight; sector_t *actionsector; INT32 i; + boolean remove; if (bouncer->sector->crumblestate == 4 || bouncer->sector->crumblestate == 1 || bouncer->sector->crumblestate == 2) // Oops! Crumbler says to remove yourself! @@ -706,43 +708,28 @@ void T_BounceCheese(levelspecthink_t *bouncer) actionsector = §ors[i]; actionsector->moved = true; - halfheight = abs(bouncer->sector->ceilingheight - bouncer->sector->floorheight) >> 1; + sectorheight = abs(bouncer->sector->ceilingheight - bouncer->sector->floorheight); + halfheight = sectorheight/2; waterheight = P_SectorCheckWater(actionsector, bouncer->sector); // sorts itself out if there's no suitable water in the sector - floorheight = P_FloorzAtPos(actionsector->soundorg.x, actionsector->soundorg.y, bouncer->sector->floorheight, halfheight << 1); + floorheight = P_FloorzAtPos(actionsector->soundorg.x, actionsector->soundorg.y, bouncer->sector->floorheight, sectorheight); + + remove = false; // Water level is up to the ceiling. if (waterheight > bouncer->sector->ceilingheight - halfheight && bouncer->sector->ceilingheight >= actionsector->ceilingheight) // Tails 01-08-2004 { bouncer->sector->ceilingheight = actionsector->ceilingheight; - bouncer->sector->floorheight = bouncer->sector->ceilingheight - (halfheight*2); - T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling - T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor - P_RecalcPrecipInSector(actionsector); - bouncer->sector->ceilingdata = NULL; - bouncer->sector->floordata = NULL; - bouncer->sector->floorspeed = 0; - bouncer->sector->ceilspeed = 0; - bouncer->sector->moved = true; - P_RemoveThinker(&bouncer->thinker); // remove bouncer from actives - return; + bouncer->sector->floorheight = actionsector->ceilingheight - sectorheight; + remove = true; } // Water level is too shallow. else if (waterheight < bouncer->sector->floorheight + halfheight && bouncer->sector->floorheight <= floorheight) { - bouncer->sector->ceilingheight = floorheight + (halfheight << 1); + bouncer->sector->ceilingheight = floorheight + sectorheight; bouncer->sector->floorheight = floorheight; - T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling - T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor - P_RecalcPrecipInSector(actionsector); - bouncer->sector->ceilingdata = NULL; - bouncer->sector->floordata = NULL; - bouncer->sector->floorspeed = 0; - bouncer->sector->ceilspeed = 0; - bouncer->sector->moved = true; - P_RemoveThinker(&bouncer->thinker); // remove bouncer from actives - return; + remove = true; } else { @@ -750,6 +737,20 @@ void T_BounceCheese(levelspecthink_t *bouncer) bouncer->floorwasheight = waterheight - halfheight; } + if (remove) + { + T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling + T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor + P_RecalcPrecipInSector(actionsector); + bouncer->sector->ceilingdata = NULL; + bouncer->sector->floordata = NULL; + bouncer->sector->floorspeed = 0; + bouncer->sector->ceilspeed = 0; + bouncer->sector->moved = true; + P_RemoveThinker(&bouncer->thinker); // remove bouncer from actives + return; + } + T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->ceilingheight - 70*FRACUNIT, 0, 1, -1); // move ceiling T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT, @@ -758,29 +759,15 @@ void T_BounceCheese(levelspecthink_t *bouncer) bouncer->sector->floorspeed = -bouncer->speed/2; bouncer->sector->ceilspeed = 42; - if (bouncer->sector->ceilingheight < bouncer->ceilingwasheight && bouncer->low == 0) // Down + if ((bouncer->sector->ceilingheight < bouncer->ceilingwasheight && bouncer->low == 0) // Down + || (bouncer->sector->ceilingheight > bouncer->ceilingwasheight && bouncer->low)) // Up { if (abs(bouncer->speed) < 6*FRACUNIT) bouncer->speed -= bouncer->speed/3; else bouncer->speed -= bouncer->speed/2; - bouncer->low = 1; - if (abs(bouncer->speed) > 6*FRACUNIT) - { - mobj_t *mp = (void *)&actionsector->soundorg; - actionsector->soundorg.z = bouncer->sector->floorheight; - S_StartSound(mp, sfx_splash); - } - } - else if (bouncer->sector->ceilingheight > bouncer->ceilingwasheight && bouncer->low) // Up - { - if (abs(bouncer->speed) < 6*FRACUNIT) - bouncer->speed -= bouncer->speed/3; - else - bouncer->speed -= bouncer->speed/2; - - bouncer->low = 0; + bouncer->low = bouncer->low ? 0 : 1; if (abs(bouncer->speed) > 6*FRACUNIT) { mobj_t *mp = (void *)&actionsector->soundorg; From fd598f315e2f4717aff233384e5744bfbf035f30 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 17 Apr 2020 23:54:37 +0200 Subject: [PATCH 099/220] Add an enum for crumblestate --- src/p_floor.c | 29 ++++++++++------------------- src/p_mobj.c | 2 +- src/p_setup.c | 2 +- src/p_spec.c | 2 +- src/p_user.c | 4 ++-- src/r_defs.h | 10 ++++++++++ 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 85304d779..0f1472810 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -690,10 +690,10 @@ void T_BounceCheese(levelspecthink_t *bouncer) INT32 i; boolean remove; - if (bouncer->sector->crumblestate == 4 || bouncer->sector->crumblestate == 1 - || bouncer->sector->crumblestate == 2) // Oops! Crumbler says to remove yourself! + if (bouncer->sector->crumblestate == CRUMBLE_RESTORE || bouncer->sector->crumblestate == CRUMBLE_WAIT + || bouncer->sector->crumblestate == CRUMBLE_ACTIVATED) // Oops! Crumbler says to remove yourself! { - bouncer->sector->crumblestate = 1; + bouncer->sector->crumblestate = CRUMBLE_WAIT; bouncer->sector->ceilingdata = NULL; bouncer->sector->ceilspeed = 0; bouncer->sector->floordata = NULL; @@ -817,15 +817,6 @@ void T_BounceCheese(levelspecthink_t *bouncer) // T_StartCrumble //////////////////////////////// ////////////////////////////////////////////////// // Crumbling platform Tails 03-11-2002 -// -// DEFINITION OF THE 'CRUMBLESTATE'S: -// -// 0 - No crumble thinker -// 1 - Don't float on water because this is supposed to wait for a crumble -// 2 - Crumble thinker activated, but hasn't fallen yet -// 3 - Crumble thinker is falling -// 4 - Crumble thinker is about to restore to original position -// void T_StartCrumble(elevator_t *elevator) { ffloor_t *rover; @@ -921,13 +912,13 @@ void T_StartCrumble(elevator_t *elevator) // so set this to let other thinkers know what is // about to happen. if (elevator->distance < 0 && elevator->distance > -3) - elevator->sector->crumblestate = 4; // makes T_BounceCheese remove itself + elevator->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself } if ((elevator->floordestheight == 0 && elevator->direction == -1) || (elevator->floordestheight == 1 && elevator->direction == 1)) // Down { - elevator->sector->crumblestate = 3; // Allow floating now. + elevator->sector->crumblestate = CRUMBLE_FALL; // Allow floating now. // Only fall like this if it isn't meant to float on water if (elevator->high != 42) @@ -976,7 +967,7 @@ void T_StartCrumble(elevator_t *elevator) } else // Up (restore to original position) { - elevator->sector->crumblestate = 1; + elevator->sector->crumblestate = CRUMBLE_WAIT; elevator->sector->ceilingheight = elevator->ceilingwasheight; elevator->sector->floorheight = elevator->floorwasheight; elevator->sector->floordata = NULL; @@ -1085,7 +1076,7 @@ void T_FloatSector(levelspecthink_t *floater) else if (floater->sector->ceilingheight == actionsector->ceilingheight && waterheight > cheeseheight) // too high ; // we have something to float in! Or we're for some reason above the ground, let's fall anyway - else if (floater->sector->crumblestate == 0 || floater->sector->crumblestate >= 3/* || floatanyway*/) + else if (floater->sector->crumblestate == CRUMBLE_NONE || floater->sector->crumblestate >= CRUMBLE_FALL/* || floatanyway*/) EV_BounceSector(floater->sector, FRACUNIT, floater->sourceline); P_RecalcPrecipInSector(actionsector); @@ -1687,7 +1678,7 @@ void T_RaiseSector(raise_t *raise) INT32 direction; result_e res = 0; - if (raise->sector->crumblestate >= 3 || raise->sector->ceilingdata) + if (raise->sector->crumblestate >= CRUMBLE_FALL || raise->sector->ceilingdata) return; for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) @@ -2489,7 +2480,7 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, if (sec->floordata) return 0; - if (sec->crumblestate > 1) + if (sec->crumblestate >= CRUMBLE_ACTIVATED) return 0; // create and initialize new elevator thinker @@ -2534,7 +2525,7 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, else elevator->high = 0; - elevator->sector->crumblestate = 2; + elevator->sector->crumblestate = CRUMBLE_ACTIVATED; for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 7e65c37ad..967e868ae 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1691,7 +1691,7 @@ static void P_PushableCheckBustables(mobj_t *mo) // Needs ML_EFFECT4 flag for pushables to break it if (!(rover->master->flags & ML_EFFECT4)) continue; - if (!rover->master->frontsector->crumblestate) + if (rover->master->frontsector->crumblestate == CRUMBLE_NONE) { topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL); diff --git a/src/p_setup.c b/src/p_setup.c index 700113d85..baccc294c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -866,7 +866,7 @@ static void P_InitializeSector(sector_t *ss) ss->camsec = -1; ss->floorlightsec = ss->ceilinglightsec = -1; - ss->crumblestate = 0; + ss->crumblestate = CRUMBLE_NONE; ss->touching_thinglist = NULL; diff --git a/src/p_spec.c b/src/p_spec.c index 2dcc21cbe..7d10a1152 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5902,7 +5902,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f } if ((flags & FF_CRUMBLE)) - sec2->crumblestate = 1; + sec2->crumblestate = CRUMBLE_WAIT; if ((flags & FF_FLOATBOB)) { diff --git a/src/p_user.c b/src/p_user.c index 994eb7007..3de69fbc5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2566,7 +2566,7 @@ static void P_CheckBustableBlocks(player_t *player) { if (!(rover->flags & FF_EXISTS)) continue; - if ((rover->flags & FF_BUSTUP)/* && !rover->master->frontsector->crumblestate*/) + if ((rover->flags & FF_BUSTUP)/* && rover->master->frontsector->crumblestate == CRUMBLE_NONE*/) { // If it's an FF_SHATTER, you can break it just by touching it. if (rover->flags & FF_SHATTER) @@ -12213,7 +12213,7 @@ void P_PlayerThink(player_t *player) player->powers[pw_nocontrol]--; else player->powers[pw_nocontrol] = 0; - + //pw_super acts as a timer now if (player->powers[pw_super] && (player->mo->state < &states[S_PLAY_SUPER_TRANS1] diff --git a/src/r_defs.h b/src/r_defs.h index 10c0721ac..4a8f5be34 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -277,6 +277,16 @@ typedef enum SF_INVERTPRECIP = 1<<4, } sectorflags_t; + +typedef enum +{ + CRUMBLE_NONE, // No crumble thinker + CRUMBLE_WAIT, // Don't float on water because this is supposed to wait for a crumble + CRUMBLE_ACTIVATED, // Crumble thinker activated, but hasn't fallen yet + CRUMBLE_FALL, // Crumble thinker is falling + CRUMBLE_RESTORE, // Crumble thinker is about to restore to original position +} crumblestate_t; + // // The SECTORS record, at runtime. // Stores things/mobjs. From cc0f686c9505606e75602ee6ecaca6466c796046 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 00:26:49 +0200 Subject: [PATCH 100/220] Refactor T_FloatSector --- src/p_floor.c | 43 ++++++++++++++++++++----------------------- src/p_saveg.c | 32 ++++++++++++++++++++++++++++++-- src/p_spec.c | 8 ++++---- src/p_spec.h | 10 +++++++++- 4 files changed, 63 insertions(+), 30 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 0f1472810..e787d1e13 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1047,40 +1047,37 @@ void T_MarioBlock(levelspecthink_t *block) #undef low } -void T_FloatSector(levelspecthink_t *floater) +void T_FloatSector(floatthink_t *floater) { fixed_t cheeseheight; + fixed_t waterheight; sector_t *actionsector; INT32 secnum; - cheeseheight = (floater->sector->ceilingheight + floater->sector->floorheight)>>1; - // Just find the first sector with the tag. // Doesn't work with multiple sectors that have different floor/ceiling heights. - secnum = P_FindSectorFromTag((INT16)floater->vars[0], -1); + secnum = P_FindSectorFromTag(floater->tag, -1); + if (secnum <= 0) + return; + actionsector = §ors[secnum]; - if (secnum > 0) - actionsector = §ors[secnum]; - else - actionsector = NULL; + cheeseheight = (floater->sector->ceilingheight + floater->sector->floorheight)>>1; - if (actionsector) - { - //boolean floatanyway = false; // Ignore the crumblestate setting. - fixed_t waterheight = P_SectorCheckWater(actionsector, floater->sector); // find the highest suitable water block around + //boolean floatanyway = false; // Ignore the crumblestate setting. + waterheight = P_SectorCheckWater(actionsector, floater->sector); // find the highest suitable water block around - if (waterheight == cheeseheight) // same height, no floating needed - ; - else if (floater->sector->floorheight == actionsector->floorheight && waterheight < cheeseheight) // too low - ; - else if (floater->sector->ceilingheight == actionsector->ceilingheight && waterheight > cheeseheight) // too high - ; - // we have something to float in! Or we're for some reason above the ground, let's fall anyway - else if (floater->sector->crumblestate == CRUMBLE_NONE || floater->sector->crumblestate >= CRUMBLE_FALL/* || floatanyway*/) - EV_BounceSector(floater->sector, FRACUNIT, floater->sourceline); + if (waterheight == cheeseheight) // same height, no floating needed + return; - P_RecalcPrecipInSector(actionsector); - } + if (floater->sector->floorheight == actionsector->floorheight && waterheight < cheeseheight) // too low + return; + + if (floater->sector->ceilingheight == actionsector->ceilingheight && waterheight > cheeseheight) // too high + return; + + // we have something to float in! Or we're for some reason above the ground, let's fall anyway + if (floater->sector->crumblestate == CRUMBLE_NONE || floater->sector->crumblestate >= CRUMBLE_FALL/* || floatanyway*/) + EV_BounceSector(floater->sector, FRACUNIT, floater->sourceline); } static mobj_t *SearchMarioNode(msecnode_t *node) diff --git a/src/p_saveg.c b/src/p_saveg.c index c9d4bb5fb..443480813 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1658,6 +1658,20 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); } +// +// SaveFloatThinker +// +// Saves a floatthink_t thinker +// +static void SaveFloatThinker(const thinker_t *th, const UINT8 type) +{ + const floatthink_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEINT16(save_p, ht->tag); +} + // SaveEachTimeThinker // // Loads a eachtime_t from a save game @@ -2317,7 +2331,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_FloatSector) { - SaveSpecialLevelThinker(th, tc_floatsector); + SaveFloatThinker(th, tc_floatsector); continue; } else if (th->function.acp1 == (actionf_p1)T_LaserFlash) @@ -2800,6 +2814,20 @@ static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeili return &ht->thinker; } +// LoadFloatThinker +// +// Loads a floatthink_t from a save game +// +static thinker_t* LoadFloatThinker(actionf_p1 thinker) +{ + floatthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sourceline = LoadLine(READUINT32(save_p)); + ht->sector = LoadSector(READUINT32(save_p)); + ht->tag = READINT16(save_p); + return &ht->thinker; +} + // LoadEachTimeThinker // // Loads a eachtime_t from a save game @@ -3542,7 +3570,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_floatsector: - th = LoadSpecialLevelThinker((actionf_p1)T_FloatSector, 0); + th = LoadFloatThinker((actionf_p1)T_FloatSector); break; case tc_laserflash: diff --git a/src/p_spec.c b/src/p_spec.c index 7d10a1152..54a6d88d6 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -114,7 +114,7 @@ static void P_ResetColormapFader(sector_t *sector); static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc, boolean ticbased, INT32 duration); static void P_AddBlockThinker(sector_t *sec, line_t *sourceline); -static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline); +static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline); //static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec); static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers); static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec); @@ -5927,9 +5927,9 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f * \sa P_SpawnSpecials, T_FloatSector * \author SSNTails */ -static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline) +static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline) { - levelspecthink_t *floater; + floatthink_t *floater; // create and initialize new thinker floater = Z_Calloc(sizeof (*floater), PU_LEVSPEC, NULL); @@ -5938,7 +5938,7 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline) floater->thinker.function.acp1 = (actionf_p1)T_FloatSector; floater->sector = sec; - floater->vars[0] = tag; + floater->tag = (INT16)tag; floater->sourceline = sourceline; } diff --git a/src/p_spec.h b/src/p_spec.h index 79f6090fd..78cf817ea 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -320,6 +320,14 @@ typedef struct sector_t *sector; // Sector the thinker is from } levelspecthink_t; +typedef struct +{ + thinker_t thinker; + line_t *sourceline; + sector_t *sector; + INT16 tag; +} floatthink_t; + typedef struct { thinker_t thinker; @@ -381,7 +389,7 @@ void T_ContinuousFalling(levelspecthink_t *faller); void T_BounceCheese(levelspecthink_t *bouncer); void T_StartCrumble(elevator_t *elevator); void T_MarioBlock(levelspecthink_t *block); -void T_FloatSector(levelspecthink_t *floater); +void T_FloatSector(floatthink_t *floater); void T_MarioBlockChecker(levelspecthink_t *block); void T_ThwompSector(levelspecthink_t *thwomp); void T_NoEnemiesSector(levelspecthink_t *nobaddies); From 70d262653eac26a01fe0f970f2f0a86af8b2d9a0 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 01:08:01 +0200 Subject: [PATCH 101/220] Refactor T_MovePlane a little bit --- src/p_ceilng.c | 16 ++- src/p_floor.c | 287 +++++++++++++++++++++++-------------------------- src/p_spec.h | 2 +- 3 files changed, 141 insertions(+), 164 deletions(-) diff --git a/src/p_ceilng.c b/src/p_ceilng.c index c65156b6f..31a4895ba 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -47,8 +47,7 @@ void T_MoveCeiling(ceiling_t *ceiling) case 0: // IN STASIS break; case 1: // UP - res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, - 1, ceiling->direction); + res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction); if (ceiling->type == bounceCeiling) { @@ -159,8 +158,7 @@ void T_MoveCeiling(ceiling_t *ceiling) break; case -1: // DOWN - res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, - ceiling->crush, 1, ceiling->direction); + res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction); if (ceiling->type == bounceCeiling) { @@ -314,11 +312,10 @@ void T_CrushCeiling(ceiling_t *ceiling) if (ceiling->type == crushBothOnce) { // Move the floor - T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, 0, -ceiling->direction); + T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, false, -ceiling->direction); } - res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, - false, 1, ceiling->direction); + res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction); if (res == pastdest) { @@ -357,11 +354,10 @@ void T_CrushCeiling(ceiling_t *ceiling) if (ceiling->type == crushBothOnce) { // Move the floor - T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, 0, -ceiling->direction); + T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, false, -ceiling->direction); } - res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, - ceiling->crush, 1, ceiling->direction); + res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction); if (res == pastdest) { diff --git a/src/p_floor.c b/src/p_floor.c index e787d1e13..83b22622f 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -30,146 +30,127 @@ // Move a plane (floor or ceiling) and check for crushing // result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush, - INT32 floorOrCeiling, INT32 direction) + boolean ceiling, INT32 direction) { - boolean flag; fixed_t lastpos; fixed_t destheight; // used to keep floors/ceilings from moving through each other sector->moved = true; - switch (floorOrCeiling) + if (ceiling) { - case 0: - // moving a floor - switch (direction) - { - case -1: - // Moving a floor down - if (sector->floorheight - speed < dest) + lastpos = sector->ceilingheight; + // moving a ceiling + switch (direction) + { + case -1: + // moving a ceiling down + // keep ceiling from moving through floors + destheight = (dest > sector->floorheight) ? dest : sector->floorheight; + if (sector->ceilingheight - speed < destheight) + { + sector->ceilingheight = destheight; + if (P_CheckSector(sector, crush)) { - lastpos = sector->floorheight; - sector->floorheight = dest; - flag = P_CheckSector(sector, crush); - if (flag && sector->numattached) - { - sector->floorheight = lastpos; - P_CheckSector(sector, crush); - } - return pastdest; + sector->ceilingheight = lastpos; + P_CheckSector(sector, crush); } - else + return pastdest; + } + else + { + // crushing is possible + sector->ceilingheight -= speed; + if (P_CheckSector(sector, crush)) { - lastpos = sector->floorheight; - sector->floorheight -= speed; - flag = P_CheckSector(sector, crush); - if (flag && sector->numattached) - { - sector->floorheight = lastpos; - P_CheckSector(sector, crush); - return crushed; - } + sector->ceilingheight = lastpos; + P_CheckSector(sector, crush); + return crushed; } - break; + } + break; - case 1: - // Moving a floor up - // keep floor from moving through ceilings - destheight = (dest < sector->ceilingheight) ? dest : sector->ceilingheight; - if (sector->floorheight + speed > destheight) + case 1: + // moving a ceiling up + if (sector->ceilingheight + speed > dest) + { + sector->ceilingheight = dest; + if (P_CheckSector(sector, crush) && sector->numattached) { - lastpos = sector->floorheight; - sector->floorheight = destheight; - flag = P_CheckSector(sector, crush); - if (flag) - { - sector->floorheight = lastpos; - P_CheckSector(sector, crush); - } - return pastdest; + sector->ceilingheight = lastpos; + P_CheckSector(sector, crush); } - else + return pastdest; + } + else + { + sector->ceilingheight += speed; + if (P_CheckSector(sector, crush) && sector->numattached) { - // crushing is possible - lastpos = sector->floorheight; - sector->floorheight += speed; - flag = P_CheckSector(sector, crush); - if (flag) - { - sector->floorheight = lastpos; - P_CheckSector(sector, crush); - return crushed; - } + sector->ceilingheight = lastpos; + P_CheckSector(sector, crush); + return crushed; } - break; - } - break; + } + break; + } + } + else + { + lastpos = sector->floorheight; + // moving a floor + switch (direction) + { + case -1: + // Moving a floor down + if (sector->floorheight - speed < dest) + { + sector->floorheight = dest; + if (P_CheckSector(sector, crush) && sector->numattached) + { + sector->floorheight = lastpos; + P_CheckSector(sector, crush); + } + return pastdest; + } + else + { + sector->floorheight -= speed; + if (P_CheckSector(sector, crush) && sector->numattached) + { + sector->floorheight = lastpos; + P_CheckSector(sector, crush); + return crushed; + } + } + break; - case 1: - // moving a ceiling - switch (direction) - { - case -1: - // moving a ceiling down - // keep ceiling from moving through floors - destheight = (dest > sector->floorheight) ? dest : sector->floorheight; - if (sector->ceilingheight - speed < destheight) + case 1: + // Moving a floor up + // keep floor from moving through ceilings + destheight = (dest < sector->ceilingheight) ? dest : sector->ceilingheight; + if (sector->floorheight + speed > destheight) + { + sector->floorheight = destheight; + if (P_CheckSector(sector, crush)) { - lastpos = sector->ceilingheight; - sector->ceilingheight = destheight; - flag = P_CheckSector(sector, crush); - - if (flag) - { - sector->ceilingheight = lastpos; - P_CheckSector(sector, crush); - } - return pastdest; + sector->floorheight = lastpos; + P_CheckSector(sector, crush); } - else + return pastdest; + } + else + { + // crushing is possible + sector->floorheight += speed; + if (P_CheckSector(sector, crush)) { - // crushing is possible - lastpos = sector->ceilingheight; - sector->ceilingheight -= speed; - flag = P_CheckSector(sector, crush); - - if (flag) - { - sector->ceilingheight = lastpos; - P_CheckSector(sector, crush); - return crushed; - } + sector->floorheight = lastpos; + P_CheckSector(sector, crush); + return crushed; } - break; - - case 1: - // moving a ceiling up - if (sector->ceilingheight + speed > dest) - { - lastpos = sector->ceilingheight; - sector->ceilingheight = dest; - flag = P_CheckSector(sector, crush); - if (flag && sector->numattached) - { - sector->ceilingheight = lastpos; - P_CheckSector(sector, crush); - } - return pastdest; - } - else - { - lastpos = sector->ceilingheight; - sector->ceilingheight += speed; - flag = P_CheckSector(sector, crush); - if (flag && sector->numattached) - { - sector->ceilingheight = lastpos; - P_CheckSector(sector, crush); - return crushed; - } - } - break; - } - break; + } + break; + } } return ok; @@ -192,7 +173,7 @@ void T_MoveFloor(floormove_t *movefloor) res = T_MovePlane(movefloor->sector, movefloor->speed, movefloor->floordestheight, - movefloor->crush, 0, movefloor->direction); + movefloor->crush, false, movefloor->direction); if (movefloor->type == bounceFloor) { @@ -385,7 +366,7 @@ void T_MoveElevator(elevator_t *elevator) elevator->speed, elevator->ceilingdestheight, elevator->distance, - 1, // move floor + true, // move ceiling elevator->direction ); @@ -395,7 +376,7 @@ void T_MoveElevator(elevator_t *elevator) elevator->speed, elevator->floordestheight, elevator->distance, - 0, // move ceiling + false, // move floor elevator->direction ); @@ -447,7 +428,7 @@ void T_MoveElevator(elevator_t *elevator) elevator->speed, elevator->floordestheight, elevator->distance, - 0, // move ceiling + false, // move floor elevator->direction ); @@ -459,7 +440,7 @@ void T_MoveElevator(elevator_t *elevator) elevator->speed, elevator->ceilingdestheight, elevator->distance, - 1, // move floor + true, // move ceiling elevator->direction ); } @@ -739,8 +720,8 @@ void T_BounceCheese(levelspecthink_t *bouncer) if (remove) { - T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling - T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor + T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, false, true, -1); // update things on ceiling + T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, false, false, -1); // update things on floor P_RecalcPrecipInSector(actionsector); bouncer->sector->ceilingdata = NULL; bouncer->sector->floordata = NULL; @@ -752,9 +733,9 @@ void T_BounceCheese(levelspecthink_t *bouncer) } T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->ceilingheight - - 70*FRACUNIT, 0, 1, -1); // move ceiling + 70*FRACUNIT, false, true, -1); // move ceiling T_MovePlane(bouncer->sector, bouncer->speed/2, bouncer->sector->floorheight - 70*FRACUNIT, - 0, 0, -1); // move floor + false, false, -1); // move floor bouncer->sector->floorspeed = -bouncer->speed/2; bouncer->sector->ceilspeed = 42; @@ -790,8 +771,8 @@ void T_BounceCheese(levelspecthink_t *bouncer) { bouncer->sector->floorheight = bouncer->floorwasheight; bouncer->sector->ceilingheight = bouncer->ceilingwasheight; - T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, 0, 1, -1); // update things on ceiling - T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, 0, 0, -1); // update things on floor + T_MovePlane(bouncer->sector, 0, bouncer->sector->ceilingheight, false, true, -1); // update things on ceiling + T_MovePlane(bouncer->sector, 0, bouncer->sector->floorheight, false, false, -1); // update things on floor bouncer->sector->ceilingdata = NULL; bouncer->sector->floordata = NULL; bouncer->sector->floorspeed = 0; @@ -940,8 +921,8 @@ void T_StartCrumble(elevator_t *elevator) elevator->sector, elevator->speed, dest, - 0, - 1, // move floor + false, + true, // move ceiling elevator->direction ); @@ -955,8 +936,8 @@ void T_StartCrumble(elevator_t *elevator) elevator->sector, elevator->speed, dest, - 0, - 0, // move ceiling + false, + false, // move floor elevator->direction ); @@ -1007,8 +988,8 @@ void T_MarioBlock(levelspecthink_t *block) block->sector, block->speed, block->sector->ceilingheight + 70*FRACUNIT * block->direction, - 0, - 1, // move floor + false, + true, // move ceiling block->direction ); @@ -1017,8 +998,8 @@ void T_MarioBlock(levelspecthink_t *block) block->sector, block->speed, block->sector->floorheight + 70*FRACUNIT * block->direction, - 0, - 0, // move ceiling + false, + false, // move floor block->direction ); @@ -1228,8 +1209,8 @@ void T_ThwompSector(levelspecthink_t *thwomp) thwomp->sector, // sector thwomp->speed, // speed thwomp->floorwasheight, // dest - 0, // crush - 0, // floor or ceiling (0 for floor) + false, // crush + false, // ceiling? thwomp->direction // direction ); @@ -1239,8 +1220,8 @@ void T_ThwompSector(levelspecthink_t *thwomp) thwomp->sector, // sector thwomp->speed, // speed thwomp->ceilingwasheight, // dest - 0, // crush - 1, // floor or ceiling (1 for ceiling) + false, // crush + true, // ceiling? thwomp->direction // direction ); @@ -1268,8 +1249,8 @@ void T_ThwompSector(levelspecthink_t *thwomp) thwomp->speed, // speed P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight, thwomp->sector->ceilingheight - thwomp->sector->floorheight), // dest - 0, // crush - 0, // floor or ceiling (0 for floor) + false, // crush + false, // ceiling? thwomp->direction // direction ); @@ -1283,8 +1264,8 @@ void T_ThwompSector(levelspecthink_t *thwomp) - (thwomp->sector->floorheight + thwomp->speed)) + (thwomp->sector->ceilingheight - (thwomp->sector->floorheight + thwomp->speed/2)), // dest - 0, // crush - 1, // floor or ceiling (1 for ceiling) + false, // crush + true, // ceiling? thwomp->direction // direction ); @@ -1786,8 +1767,8 @@ void T_RaiseSector(raise_t *raise) raise->sector, // sector speed, // speed ceilingdestination, // dest - 0, // crush - 1, // floor or ceiling (1 for ceiling) + false, // crush + true, // ceiling? direction // direction ); @@ -1797,8 +1778,8 @@ void T_RaiseSector(raise_t *raise) raise->sector, // sector speed, // speed floordestination, // dest - 0, // crush - 0, // floor or ceiling (0 for floor) + false, // crush + false, // ceiling? direction // direction ); @@ -1900,9 +1881,9 @@ void T_PlaneDisplace(planedisplace_t *pd) } if (pd->type == pd_floor || pd->type == pd_both) - T_MovePlane(target, INT32_MAX/2, target->floorheight+diff, 0, 0, direction); // move floor + T_MovePlane(target, INT32_MAX/2, target->floorheight+diff, false, false, direction); // move floor if (pd->type == pd_ceiling || pd->type == pd_both) - T_MovePlane(target, INT32_MAX/2, target->ceilingheight+diff, 0, 1, direction); // move ceiling + T_MovePlane(target, INT32_MAX/2, target->ceilingheight+diff, false, true, direction); // move ceiling pd->last_height = control->floorheight; } diff --git a/src/p_spec.h b/src/p_spec.h index 78cf817ea..279d59d7d 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -368,7 +368,7 @@ typedef enum } result_e; result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush, - INT32 floorOrCeiling, INT32 direction); + boolean ceiling, INT32 direction); INT32 EV_DoFloor(line_t *line, floor_e floortype); INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed); void EV_CrumbleChain(sector_t *sec, ffloor_t *rover); From 7e2f95c3f5caafc49b583046eac5d547e6e18e5b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 01:42:13 +0200 Subject: [PATCH 102/220] Refactor T_ContinuousFalling --- src/p_floor.c | 83 +++++++++------------------------------------------ src/p_saveg.c | 38 +++++++++++++++++++++-- src/p_spec.h | 15 ++++++++-- 3 files changed, 63 insertions(+), 73 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 83b22622f..4c6c7fa46 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -561,43 +561,18 @@ void T_MoveElevator(elevator_t *elevator) // // Useful for things like intermittent falling lava. // -void T_ContinuousFalling(levelspecthink_t *faller) +void T_ContinuousFalling(continuousfall_t *faller) { -#define speed vars[0] -#define direction vars[1] -#define floorwasheight vars[2] -#define ceilingwasheight vars[3] -#define floordestheight vars[4] -#define ceilingdestheight vars[5] - - if (faller->direction == -1) - { - faller->sector->ceilingheight -= faller->speed; - faller->sector->floorheight -= faller->speed; - } - else - { - faller->sector->ceilingheight += faller->speed; - faller->sector->floorheight += faller->speed; - } + faller->sector->ceilingheight += faller->speed*faller->direction; + faller->sector->floorheight += faller->speed*faller->direction; P_CheckSector(faller->sector, false); - if (faller->direction == -1) // Down + if ((faller->direction == -1 && faller->sector->ceilingheight <= faller->destheight) + || (faller->direction == 1 && faller->sector->floorheight >= faller->destheight)) { - if (faller->sector->ceilingheight <= faller->ceilingdestheight) // if destination height acheived - { - faller->sector->ceilingheight = faller->ceilingwasheight; - faller->sector->floorheight = faller->floorwasheight; - } - } - else // Up - { - if (faller->sector->floorheight >= faller->floordestheight) // if destination height acheived - { - faller->sector->ceilingheight = faller->ceilingwasheight; - faller->sector->floorheight = faller->floorwasheight; - } + faller->sector->ceilingheight = faller->ceilingstartheight; + faller->sector->floorheight = faller->floorstartheight; } P_CheckSector(faller->sector, false); // you might think this is irrelevant. you would be wrong @@ -605,12 +580,6 @@ void T_ContinuousFalling(levelspecthink_t *faller) faller->sector->floorspeed = faller->speed*faller->direction; faller->sector->ceilspeed = 42; faller->sector->moved = true; -#undef speed -#undef direction -#undef floorwasheight -#undef ceilingwasheight -#undef floordestheight -#undef ceilingdestheight } // @@ -2398,18 +2367,12 @@ INT32 EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline) } // For T_ContinuousFalling special -INT32 EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards) +void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards) { -#define speed vars[0] -#define direction vars[1] -#define floorwasheight vars[2] -#define ceilingwasheight vars[3] -#define floordestheight vars[4] -#define ceilingdestheight vars[5] - levelspecthink_t *faller; + continuousfall_t *faller; // workaround for when there is no back sector - if (backsector == NULL) + if (!backsector) backsector = sec; // create and initialize new thinker @@ -2421,29 +2384,11 @@ INT32 EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, bool faller->sector = sec; faller->speed = spd; - faller->floorwasheight = sec->floorheight; - faller->ceilingwasheight = sec->ceilingheight; + faller->floorstartheight = sec->floorheight; + faller->ceilingstartheight = sec->ceilingheight; - if (backwards) - { - faller->ceilingdestheight = backsector->ceilingheight; - faller->floordestheight = faller->ceilingdestheight; - faller->direction = 1; // Up! - } - else - { - faller->floordestheight = backsector->floorheight; - faller->ceilingdestheight = faller->floordestheight; - faller->direction = -1; - } - - return 1; -#undef speed -#undef direction -#undef floorwasheight -#undef ceilingwasheight -#undef floordestheight -#undef ceilingdestheight + faller->destheight = backwards ? backsector->ceilingheight : backsector->floorheight; + faller->direction = backwards ? 1 : -1; } // Some other 3dfloor special things Tails 03-11-2002 (Search p_mobj.c for description) diff --git a/src/p_saveg.c b/src/p_saveg.c index 443480813..025784d00 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1658,6 +1658,23 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); } +// +// SaveContinuousFallThinker +// +// Saves a continuousfall_t thinker +// +static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type) +{ + const continuousfall_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEFIXED(save_p, ht->speed); + WRITEINT32(save_p, ht->direction); + WRITEFIXED(save_p, ht->floorstartheight); + WRITEFIXED(save_p, ht->ceilingstartheight); + WRITEFIXED(save_p, ht->destheight); +} + // // SaveFloatThinker // @@ -2266,7 +2283,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_ContinuousFalling) { - SaveSpecialLevelThinker(th, tc_continuousfalling); + SaveContinuousFallThinker(th, tc_continuousfalling); continue; } else if (th->function.acp1 == (actionf_p1)T_ThwompSector) @@ -2814,6 +2831,23 @@ static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeili return &ht->thinker; } +// LoadContinuousFallThinker +// +// Loads a continuousfall_t from a save game +// +static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker) +{ + continuousfall_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sector = LoadSector(READUINT32(save_p)); + ht->speed = READFIXED(save_p); + ht->direction = READINT32(save_p); + ht->floorstartheight = READFIXED(save_p); + ht->ceilingstartheight = READFIXED(save_p); + ht->destheight = READFIXED(save_p); + return &ht->thinker; +} + // LoadFloatThinker // // Loads a floatthink_t from a save game @@ -3528,7 +3562,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_continuousfalling: - th = LoadSpecialLevelThinker((actionf_p1)T_ContinuousFalling, 3); + th = LoadContinuousFallThinker((actionf_p1)T_ContinuousFalling); break; case tc_thwomp: diff --git a/src/p_spec.h b/src/p_spec.h index 279d59d7d..db755b5c9 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -320,6 +320,17 @@ typedef struct sector_t *sector; // Sector the thinker is from } levelspecthink_t; +typedef struct +{ + thinker_t thinker; + sector_t *sector; + fixed_t speed; + INT32 direction; + fixed_t floorstartheight; + fixed_t ceilingstartheight; + fixed_t destheight; +} continuousfall_t; + typedef struct { thinker_t thinker; @@ -378,14 +389,14 @@ INT32 EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline); INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover, boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn); -INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards); +void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards); INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher); void T_MoveFloor(floormove_t *movefloor); void T_MoveElevator(elevator_t *elevator); -void T_ContinuousFalling(levelspecthink_t *faller); +void T_ContinuousFalling(continuousfall_t *faller); void T_BounceCheese(levelspecthink_t *bouncer); void T_StartCrumble(elevator_t *elevator); void T_MarioBlock(levelspecthink_t *block); From 003860597908c93ac7f905dc21d6db45862f4876 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 02:05:23 +0200 Subject: [PATCH 103/220] Make T_MarioBlock use its own thinker data structure --- src/p_floor.c | 55 +++++++++++++++++---------------------------------- src/p_saveg.c | 38 +++++++++++++++++++++++++++++++++-- src/p_spec.h | 15 ++++++++++++-- 3 files changed, 67 insertions(+), 41 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 4c6c7fa46..bef57014c 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -941,17 +941,10 @@ void T_StartCrumble(elevator_t *elevator) ////////////////////////////////////////////////// // Mario hits a block! // -void T_MarioBlock(levelspecthink_t *block) +void T_MarioBlock(mariothink_t *block) { INT32 i; -#define speed vars[1] -#define direction vars[2] -#define floorwasheight vars[3] -#define ceilingwasheight vars[4] -#define distance vars[5] -#define low vars[6] - T_MovePlane ( block->sector, @@ -972,12 +965,12 @@ void T_MarioBlock(levelspecthink_t *block) block->direction ); - if (block->sector->ceilingheight >= block->ceilingwasheight + 32*FRACUNIT) // Go back down now.. - block->direction = -block->direction; - else if (block->sector->ceilingheight <= block->ceilingwasheight) + if (block->sector->ceilingheight >= block->ceilingstartheight + 32*FRACUNIT) // Go back down now.. + block->direction *= -1; + else if (block->sector->ceilingheight <= block->ceilingstartheight) { - block->sector->ceilingheight = block->ceilingwasheight; - block->sector->floorheight = block->floorwasheight; + block->sector->ceilingheight = block->ceilingstartheight; + block->sector->floorheight = block->floorstartheight; P_RemoveThinker(&block->thinker); block->sector->floordata = NULL; block->sector->ceilingdata = NULL; @@ -986,15 +979,8 @@ void T_MarioBlock(levelspecthink_t *block) block->direction = 0; } - for (i = -1; (i = P_FindSectorFromTag((INT16)block->vars[0], i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(block->tag, i)) >= 0 ;) P_RecalcPrecipInSector(§ors[i]); - -#undef speed -#undef direction -#undef floorwasheight -#undef ceilingwasheight -#undef distance -#undef low } void T_FloatSector(floatthink_t *floater) @@ -2460,11 +2446,11 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, return 1; } -INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) +void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) { sector_t *roversec = rover->master->frontsector; fixed_t topheight = *rover->topheight; - levelspecthink_t *block; + mariothink_t *block; mobj_t *thing; fixed_t oldx = 0, oldy = 0, oldz = 0; @@ -2472,7 +2458,7 @@ INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) I_Assert(puncher->player != NULL); if (roversec->floordata || roversec->ceilingdata) - return 0; + return; if (!(rover->flags & FF_SOLID)) rover->flags |= (FF_SOLID|FF_RENDERALL|FF_CUTLEVEL); @@ -2480,8 +2466,9 @@ INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) // Find an item to pop out! thing = SearchMarioNode(roversec->touching_thinglist); - // Found something! - if (thing) + if (!thing) + S_StartSound(puncher, sfx_mario1); // "Thunk!" sound - puncher is "close enough". + else // Found something! { const boolean itsamonitor = (thing->flags & MF_MONITOR) == MF_MONITOR; // create and initialize new elevator thinker @@ -2494,13 +2481,11 @@ INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) // Set up the fields block->sector = roversec; - block->vars[0] = sector->tag; // actionsector - block->vars[1] = 4*FRACUNIT; // speed - block->vars[2] = 1; // Up // direction - block->vars[3] = block->sector->floorheight; // floorwasheight - block->vars[4] = block->sector->ceilingheight; // ceilingwasheight - block->vars[5] = FRACUNIT; // distance - block->vars[6] = 1; // low + block->speed = 4*FRACUNIT; + block->direction = 1; + block->floorstartheight = block->sector->floorheight; + block->ceilingstartheight = block->sector->ceilingheight; + block->tag = (INT16)sector->tag; if (itsamonitor) { @@ -2541,8 +2526,4 @@ INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) P_SetThingPosition(thing); } } - else - S_StartSound(puncher, sfx_mario1); // "Thunk!" sound - puncher is "close enough". - - return 1; } diff --git a/src/p_saveg.c b/src/p_saveg.c index 025784d00..e9d2e0836 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1675,6 +1675,23 @@ static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->destheight); } +// +// SaveMarioBlockThinker +// +// Saves a mariothink_t thinker +// +static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type) +{ + const mariothink_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEFIXED(save_p, ht->speed); + WRITEINT32(save_p, ht->direction); + WRITEFIXED(save_p, ht->floorstartheight); + WRITEFIXED(save_p, ht->ceilingstartheight); + WRITEINT16(save_p, ht->tag); +} + // // SaveFloatThinker // @@ -2338,7 +2355,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_MarioBlock) { - SaveSpecialLevelThinker(th, tc_marioblock); + SaveMarioBlockThinker(th, tc_marioblock); continue; } else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker) @@ -2848,6 +2865,23 @@ static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker) return &ht->thinker; } +// LoadMarioBlockThinker +// +// Loads a mariothink_t from a save game +// +static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) +{ + mariothink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sector = LoadSector(READUINT32(save_p)); + ht->speed = READFIXED(save_p); + ht->direction = READINT32(save_p); + ht->floorstartheight = READFIXED(save_p); + ht->ceilingstartheight = READFIXED(save_p); + ht->tag = READINT16(save_p); + return &ht->thinker; +} + // LoadFloatThinker // // Loads a floatthink_t from a save game @@ -3596,7 +3630,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_marioblock: - th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3); + th = LoadMarioBlockThinker((actionf_p1)T_MarioBlock); break; case tc_marioblockchecker: diff --git a/src/p_spec.h b/src/p_spec.h index db755b5c9..946b01bcf 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -331,6 +331,17 @@ typedef struct fixed_t destheight; } continuousfall_t; +typedef struct +{ + thinker_t thinker; + sector_t *sector; + fixed_t speed; + INT32 direction; + fixed_t floorstartheight; + fixed_t ceilingstartheight; + INT16 tag; +} mariothink_t; + typedef struct { thinker_t thinker; @@ -391,7 +402,7 @@ INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover, void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards); -INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher); +void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher); void T_MoveFloor(floormove_t *movefloor); @@ -399,7 +410,7 @@ void T_MoveElevator(elevator_t *elevator); void T_ContinuousFalling(continuousfall_t *faller); void T_BounceCheese(levelspecthink_t *bouncer); void T_StartCrumble(elevator_t *elevator); -void T_MarioBlock(levelspecthink_t *block); +void T_MarioBlock(mariothink_t *block); void T_FloatSector(floatthink_t *floater); void T_MarioBlockChecker(levelspecthink_t *block); void T_ThwompSector(levelspecthink_t *thwomp); From 29d33f0a931fd3e0908ecdc5291c0538a4c6af8b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 09:21:04 +0200 Subject: [PATCH 104/220] Refactor T_NoEnemiesSector --- src/p_floor.c | 61 +++++++++++++++++++++------------------------------ src/p_saveg.c | 28 +++++++++++++++++++++-- src/p_spec.c | 9 +++----- src/p_spec.h | 8 ++++++- 4 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index bef57014c..e46b0b4fb 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1281,21 +1281,37 @@ void T_ThwompSector(levelspecthink_t *thwomp) #undef ceilingwasheight } +static boolean T_SectorHasEnemies(sector_t *sec) +{ + msecnode_t *node = sec->touching_thinglist; // things touching this sector + mobj_t *mo; + while (node) + { + mo = node->m_thing; + + if ((mo->flags & (MF_ENEMY|MF_BOSS)) + && mo->health > 0 + && mo->z < sec->ceilingheight + && mo->z + mo->height > sec->floorheight) + return true; + + node = node->m_thinglist_next; + } + + return false; +} + // // T_NoEnemiesThinker // // Runs a linedef exec when no more MF_ENEMY/MF_BOSS objects with health are in the area // \sa P_AddNoEnemiesThinker // -void T_NoEnemiesSector(levelspecthink_t *nobaddies) +void T_NoEnemiesSector(noenemies_t *nobaddies) { size_t i; - fixed_t upperbound, lowerbound; sector_t *sec = NULL; - sector_t *targetsec = NULL; INT32 secnum = -1; - msecnode_t *node; - mobj_t *thing; boolean FOFsector = false; while ((secnum = P_FindSectorFromLineTag(nobaddies->sourceline, secnum)) >= 0) @@ -1316,40 +1332,13 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies) while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) { - targetsec = §ors[targetsecnum]; - - upperbound = targetsec->ceilingheight; - lowerbound = targetsec->floorheight; - node = targetsec->touching_thinglist; // things touching this sector - while (node) - { - thing = node->m_thing; - - if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0 - && thing->z < upperbound && thing->z+thing->height > lowerbound) - return; - - node = node->m_thinglist_next; - } - } - } - - if (!FOFsector) - { - upperbound = sec->ceilingheight; - lowerbound = sec->floorheight; - node = sec->touching_thinglist; // things touching this sector - while (node) - { - thing = node->m_thing; - - if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0 - && thing->z < upperbound && thing->z+thing->height > lowerbound) + if (T_SectorHasEnemies(§ors[targetsecnum])) return; - - node = node->m_thinglist_next; } } + + if (!FOFsector && T_SectorHasEnemies(sec)) + return; } CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", nobaddies->sourceline->tag); diff --git a/src/p_saveg.c b/src/p_saveg.c index e9d2e0836..afcd9867e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1658,6 +1658,18 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); } +// +// SaveNoEnemiesThinker +// +// Saves a noenemies_t thinker +// +static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type) +{ + const noenemies_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); +} + // // SaveContinuousFallThinker // @@ -2310,7 +2322,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_NoEnemiesSector) { - SaveSpecialLevelThinker(th, tc_noenemies); + SaveNoEnemiesThinker(th, tc_noenemies); continue; } else if (th->function.acp1 == (actionf_p1)T_EachTimeThinker) @@ -2848,6 +2860,18 @@ static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeili return &ht->thinker; } +// LoadNoEnemiesThinker +// +// Loads a noenemies_t from a save game +// +static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker) +{ + noenemies_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sourceline = LoadLine(READUINT32(save_p)); + return &ht->thinker; +} + // LoadContinuousFallThinker // // Loads a continuousfall_t from a save game @@ -3604,7 +3628,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_noenemies: - th = LoadSpecialLevelThinker((actionf_p1)T_NoEnemiesSector, 0); + th = LoadNoEnemiesThinker((actionf_p1)T_NoEnemiesSector); break; case tc_eachtime: diff --git a/src/p_spec.c b/src/p_spec.c index 54a6d88d6..6bcac18f9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6107,14 +6107,13 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin /** Adds a thinker which checks if any MF_ENEMY objects with health are in the defined area. * If not, a linedef executor is run once. * - * \param sec Control sector. * \param sourceline Control linedef. * \sa P_SpawnSpecials, T_NoEnemiesSector * \author SSNTails */ -static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline) +static inline void P_AddNoEnemiesThinker(line_t *sourceline) { - levelspecthink_t *nobaddies; + noenemies_t *nobaddies; // create and initialize new thinker nobaddies = Z_Calloc(sizeof (*nobaddies), PU_LEVSPEC, NULL); @@ -6122,7 +6121,6 @@ static inline void P_AddNoEnemiesThinker(sector_t *sec, line_t *sourceline) nobaddies->thinker.function.acp1 = (actionf_p1)T_NoEnemiesSector; - nobaddies->sector = sec; nobaddies->sourceline = sourceline; } @@ -7124,8 +7122,7 @@ void P_SpawnSpecials(boolean fromnetsave) // No More Enemies Linedef Exec case 313: - sec = sides[*lines[i].sidenum].sector - sectors; - P_AddNoEnemiesThinker(§ors[sec], &lines[i]); + P_AddNoEnemiesThinker(&lines[i]); break; // Pushable linedef executors (count # of pushables) diff --git a/src/p_spec.h b/src/p_spec.h index 946b01bcf..ef98be5c4 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -320,6 +320,12 @@ typedef struct sector_t *sector; // Sector the thinker is from } levelspecthink_t; +typedef struct +{ + thinker_t thinker; + line_t *sourceline; // Source line of the thinker +} noenemies_t; + typedef struct { thinker_t thinker; @@ -414,7 +420,7 @@ void T_MarioBlock(mariothink_t *block); void T_FloatSector(floatthink_t *floater); void T_MarioBlockChecker(levelspecthink_t *block); void T_ThwompSector(levelspecthink_t *thwomp); -void T_NoEnemiesSector(levelspecthink_t *nobaddies); +void T_NoEnemiesSector(noenemies_t *nobaddies); void T_EachTimeThinker(eachtime_t *eachtime); void T_CameraScanner(elevator_t *elevator); void T_RaiseSector(raise_t *raise); From 08f1e03e791c35dc70345130c61f6b532570abe3 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 10:26:03 +0200 Subject: [PATCH 105/220] Refactor T_ThwompSector --- src/p_floor.c | 273 ++++++++++++++++++++++---------------------------- src/p_saveg.c | 46 ++++++++- src/p_spec.c | 35 +++---- src/p_spec.h | 17 +++- 4 files changed, 196 insertions(+), 175 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index e46b0b4fb..774606563 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1104,164 +1104,74 @@ void T_MarioBlockChecker(levelspecthink_t *block) } } +static boolean P_IsPlayerValid(size_t playernum) +{ + if (!playeringame[playernum]) + return false; + + if (!players[playernum].mo) + return false; + + if (players[playernum].mo->health <= 0) + return false; + + if (players[playernum].spectator) + return false; + + return true; +} + // This is the Thwomp's 'brain'. It looks around for players nearby, and if // it finds any, **SMASH**!!! Muahahhaa.... -void T_ThwompSector(levelspecthink_t *thwomp) +void T_ThwompSector(thwomp_t *thwomp) { -#define speed vars[1] -#define direction vars[2] -#define distance vars[3] -#define floorwasheight vars[4] -#define ceilingwasheight vars[5] fixed_t thwompx, thwompy; sector_t *actionsector; ffloor_t *rover = NULL; INT32 secnum; + fixed_t speed; // If you just crashed down, wait a second before coming back up. - if (--thwomp->distance > 0) - { - sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].bottomtexture; + if (--thwomp->delay > 0) return; - } // Just find the first sector with the tag. // Doesn't work with multiple sectors that have different floor/ceiling heights. - secnum = P_FindSectorFromTag((INT16)thwomp->vars[0], -1); + secnum = P_FindSectorFromTag(thwomp->tag, -1); - if (secnum > 0) - { - actionsector = §ors[secnum]; - - // Look for thwomp FFloor - for (rover = actionsector->ffloors; rover; rover = rover->next) - { - if (rover->master == thwomp->sourceline) - break; - } - } - else + if (secnum <= 0) return; // Bad bad bad! + actionsector = §ors[secnum]; + + // Look for thwomp FOF + for (rover = actionsector->ffloors; rover; rover = rover->next) + { + if (rover->master == thwomp->sourceline) + break; + } + + if (!rover) + return; // Didn't find any FOFs, so bail out + thwompx = actionsector->soundorg.x; thwompy = actionsector->soundorg.y; - if (thwomp->direction > 0) // Moving back up.. + if (thwomp->direction == 0) // Not going anywhere, so look for players. { - result_e res = 0; - - // Set the texture from the lower one (normal) - sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].bottomtexture; - /// \note this should only have to be done once, but is already done repeatedly, above - - if (thwomp->sourceline->flags & ML_EFFECT5) - thwomp->speed = thwomp->sourceline->dx/8; - else - thwomp->speed = 2*FRACUNIT; - - res = T_MovePlane - ( - thwomp->sector, // sector - thwomp->speed, // speed - thwomp->floorwasheight, // dest - false, // crush - false, // ceiling? - thwomp->direction // direction - ); - - if (res == ok || res == pastdest) - T_MovePlane - ( - thwomp->sector, // sector - thwomp->speed, // speed - thwomp->ceilingwasheight, // dest - false, // crush - true, // ceiling? - thwomp->direction // direction - ); - - if (res == pastdest) - thwomp->direction = 0; // stop moving - - thwomp->sector->ceilspeed = 42; - thwomp->sector->floorspeed = thwomp->speed*thwomp->direction; - } - else if (thwomp->direction < 0) // Crashing down! - { - result_e res = 0; - - // Set the texture from the upper one (angry) - sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].toptexture; - - if (thwomp->sourceline->flags & ML_EFFECT5) - thwomp->speed = thwomp->sourceline->dy/8; - else - thwomp->speed = 10*FRACUNIT; - - res = T_MovePlane - ( - thwomp->sector, // sector - thwomp->speed, // speed - P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight, - thwomp->sector->ceilingheight - thwomp->sector->floorheight), // dest - false, // crush - false, // ceiling? - thwomp->direction // direction - ); - - if (res == ok || res == pastdest) - T_MovePlane - ( - thwomp->sector, // sector - thwomp->speed, // speed - P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight, - thwomp->sector->ceilingheight - - (thwomp->sector->floorheight + thwomp->speed)) - + (thwomp->sector->ceilingheight - - (thwomp->sector->floorheight + thwomp->speed/2)), // dest - false, // crush - true, // ceiling? - thwomp->direction // direction - ); - - if (res == pastdest) - { - mobj_t *mp = (void *)&actionsector->soundorg; - - if (!rover || (rover->flags & FF_EXISTS)) - { - if (thwomp->sourceline->flags & ML_EFFECT4) - S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS); - else - S_StartSound(mp, sfx_thwomp); - } - - thwomp->direction = 1; // start heading back up - thwomp->distance = TICRATE; // but only after a small delay - } - - thwomp->sector->ceilspeed = 42; - thwomp->sector->floorspeed = thwomp->speed*thwomp->direction; - } - else // Not going anywhere, so look for players. - { - if (!rover || (rover->flags & FF_EXISTS)) + if (rover->flags & FF_EXISTS) { UINT8 i; // scan the players to find victims! for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i]) - continue; - if (players[i].spectator) - continue; - if (!players[i].mo) - continue; - if (!players[i].mo->health) + if (!P_IsPlayerValid(i)) continue; + if (players[i].mo->z > thwomp->sector->ceilingheight) continue; - if (P_AproxDistance(thwompx - players[i].mo->x, thwompy - players[i].mo->y) > 96 * FRACUNIT) + + if (P_AproxDistance(thwompx - players[i].mo->x, thwompy - players[i].mo->y) > 96*FRACUNIT) continue; thwomp->direction = -1; @@ -1272,13 +1182,89 @@ void T_ThwompSector(levelspecthink_t *thwomp) thwomp->sector->ceilspeed = 0; thwomp->sector->floorspeed = 0; } + else + { + result_e res = 0; + + if (thwomp->direction > 0) //Moving back up.. + { + // Set the texture from the lower one (normal) + sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].bottomtexture; + + speed = thwomp->retractspeed; + + res = T_MovePlane + ( + thwomp->sector, // sector + speed, // speed + thwomp->floorstartheight, // dest + false, // crush + false, // ceiling? + thwomp->direction // direction + ); + + if (res == ok || res == pastdest) + T_MovePlane + ( + thwomp->sector, // sector + speed, // speed + thwomp->ceilingstartheight, // dest + false, // crush + true, // ceiling? + thwomp->direction // direction + ); + + if (res == pastdest) + thwomp->direction = 0; // stop moving + } + else // Crashing down! + { + // Set the texture from the upper one (angry) + sides[thwomp->sourceline->sidenum[0]].midtexture = sides[thwomp->sourceline->sidenum[0]].toptexture; + + speed = thwomp->crushspeed; + + res = T_MovePlane + ( + thwomp->sector, // sector + speed, // speed + P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight, + thwomp->sector->ceilingheight - thwomp->sector->floorheight), // dest + false, // crush + false, // ceiling? + thwomp->direction // direction + ); + + if (res == ok || res == pastdest) + T_MovePlane + ( + thwomp->sector, // sector + speed, // speed + P_FloorzAtPos(thwompx, thwompy, thwomp->sector->floorheight, + thwomp->sector->ceilingheight + - (thwomp->sector->floorheight + speed)) + + (thwomp->sector->ceilingheight + - (thwomp->sector->floorheight + speed/2)), // dest + false, // crush + true, // ceiling? + thwomp->direction // direction + ); + + if (res == pastdest) + { + if (rover->flags & FF_EXISTS) + S_StartSound((void *)&actionsector->soundorg, thwomp->sound); + + thwomp->direction = 1; // start heading back up + thwomp->delay = TICRATE; // but only after a small delay + } + } + + thwomp->sector->ceilspeed = 42; + thwomp->sector->floorspeed = speed*thwomp->direction; + } P_RecalcPrecipInSector(actionsector); -#undef speed -#undef direction -#undef distance -#undef floorwasheight -#undef ceilingwasheight } static boolean T_SectorHasEnemies(sector_t *sec) @@ -1375,23 +1361,6 @@ static boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec) return false; } -static boolean P_IsPlayerValid(size_t playernum) -{ - if (!playeringame[playernum]) - return false; - - if (!players[playernum].mo) - return false; - - if (players[playernum].mo->health <= 0) - return false; - - if (players[playernum].spectator) - return false; - - return true; -} - static boolean P_IsMobjTouchingSector(mobj_t *mo, sector_t *sec) { msecnode_t *node; diff --git a/src/p_saveg.c b/src/p_saveg.c index afcd9867e..888eb96ca 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1704,6 +1704,27 @@ static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type) WRITEINT16(save_p, ht->tag); } +// +// SaveThwompThinker +// +// Saves a thwomp_t thinker +// +static void SaveThwompThinker(const thinker_t *th, const UINT8 type) +{ + const thwomp_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEFIXED(save_p, ht->crushspeed); + WRITEFIXED(save_p, ht->retractspeed); + WRITEINT32(save_p, ht->direction); + WRITEFIXED(save_p, ht->floorstartheight); + WRITEFIXED(save_p, ht->ceilingstartheight); + WRITEINT32(save_p, ht->delay); + WRITEINT16(save_p, ht->tag); + WRITEUINT16(save_p, ht->sound); +} + // // SaveFloatThinker // @@ -2317,7 +2338,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_ThwompSector) { - SaveSpecialLevelThinker(th, tc_thwomp); + SaveThwompThinker(th, tc_thwomp); continue; } else if (th->function.acp1 == (actionf_p1)T_NoEnemiesSector) @@ -2906,6 +2927,27 @@ static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) return &ht->thinker; } +// LoadThwompThinker +// +// Loads a thwomp_t from a save game +// +static thinker_t* LoadThwompThinker(actionf_p1 thinker) +{ + thwomp_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sourceline = LoadLine(READUINT32(save_p)); + ht->sector = LoadSector(READUINT32(save_p)); + ht->crushspeed = READFIXED(save_p); + ht->retractspeed = READFIXED(save_p); + ht->direction = READINT32(save_p); + ht->floorstartheight = READFIXED(save_p); + ht->ceilingstartheight = READFIXED(save_p); + ht->delay = READINT32(save_p); + ht->tag = READINT16(save_p); + ht->sound = READUINT16(save_p); + return &ht->thinker; +} + // LoadFloatThinker // // Loads a floatthink_t from a save game @@ -3624,7 +3666,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_thwomp: - th = LoadSpecialLevelThinker((actionf_p1)T_ThwompSector, 3); + th = LoadThwompThinker((actionf_p1)T_ThwompSector); break; case tc_noenemies: diff --git a/src/p_spec.c b/src/p_spec.c index 6bcac18f9..921bcef26 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6068,12 +6068,7 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean */ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, line_t *sourceline) { -#define speed vars[1] -#define direction vars[2] -#define distance vars[3] -#define floorwasheight vars[4] -#define ceilingwasheight vars[5] - levelspecthink_t *thwomp; + thwomp_t *thwomp; // You *probably* already have a thwomp in this sector. If you've combined it with something // else that uses the floordata/ceilingdata, you must be weird. @@ -6087,21 +6082,21 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin thwomp->thinker.function.acp1 = (actionf_p1)T_ThwompSector; // set up the fields according to the type of elevator action - thwomp->sector = sec; - thwomp->vars[0] = actionsector->tag; - thwomp->floorwasheight = thwomp->sector->floorheight; - thwomp->ceilingwasheight = thwomp->sector->ceilingheight; - thwomp->direction = 0; - thwomp->distance = 1; thwomp->sourceline = sourceline; - thwomp->sector->floordata = thwomp; - thwomp->sector->ceilingdata = thwomp; - return; -#undef speed -#undef direction -#undef distance -#undef floorwasheight -#undef ceilingwasheight + thwomp->sector = sec; + thwomp->crushspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dy >> 3 : 10*FRACUNIT; + thwomp->retractspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dx >> 3 : 2*FRACUNIT; + thwomp->direction = 0; + thwomp->floorstartheight = sec->floorheight; + thwomp->ceilingstartheight = sec->ceilingheight; + thwomp->delay = 1; + thwomp->tag = actionsector->tag; + thwomp->sound = (sourceline->flags & ML_EFFECT4) ? sides[sourceline->sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; + + sec->floordata = thwomp; + sec->ceilingdata = thwomp; + // Start with 'resting' texture + sides[sourceline->sidenum[0]].midtexture = sides[sourceline->sidenum[0]].bottomtexture; } /** Adds a thinker which checks if any MF_ENEMY objects with health are in the defined area. diff --git a/src/p_spec.h b/src/p_spec.h index ef98be5c4..5e54b568f 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -348,6 +348,21 @@ typedef struct INT16 tag; } mariothink_t; +typedef struct +{ + thinker_t thinker; + line_t *sourceline; + sector_t *sector; + fixed_t crushspeed; + fixed_t retractspeed; + INT32 direction; + fixed_t floorstartheight; + fixed_t ceilingstartheight; + INT32 delay; + INT16 tag; + UINT16 sound; +} thwomp_t; + typedef struct { thinker_t thinker; @@ -419,7 +434,7 @@ void T_StartCrumble(elevator_t *elevator); void T_MarioBlock(mariothink_t *block); void T_FloatSector(floatthink_t *floater); void T_MarioBlockChecker(levelspecthink_t *block); -void T_ThwompSector(levelspecthink_t *thwomp); +void T_ThwompSector(thwomp_t *thwomp); void T_NoEnemiesSector(noenemies_t *nobaddies); void T_EachTimeThinker(eachtime_t *eachtime); void T_CameraScanner(elevator_t *elevator); From ab172673631e96a96c2f31ef32d4e54c160d1e35 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 10:45:21 +0200 Subject: [PATCH 106/220] Make T_BounceCheese use its own thinker struct --- src/p_floor.c | 28 ++++++---------------------- src/p_saveg.c | 40 ++++++++++++++++++++++++++++++++++++++-- src/p_spec.h | 14 +++++++++++++- 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 774606563..6e0599f70 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -625,13 +625,8 @@ static fixed_t P_SectorCheckWater(sector_t *analyzesector, ////////////////////////////////////////////////// // Bounces a floating cheese -void T_BounceCheese(levelspecthink_t *bouncer) +void T_BounceCheese(bouncecheese_t *bouncer) { -#define speed vars[0] -#define distance vars[1] -#define low vars[2] -#define ceilingwasheight vars[3] -#define floorwasheight vars[4] fixed_t sectorheight; fixed_t halfheight; fixed_t waterheight; @@ -709,7 +704,7 @@ void T_BounceCheese(levelspecthink_t *bouncer) bouncer->sector->floorspeed = -bouncer->speed/2; bouncer->sector->ceilspeed = 42; - if ((bouncer->sector->ceilingheight < bouncer->ceilingwasheight && bouncer->low == 0) // Down + if ((bouncer->sector->ceilingheight < bouncer->ceilingwasheight && !bouncer->low) // Down || (bouncer->sector->ceilingheight > bouncer->ceilingwasheight && bouncer->low)) // Up { if (abs(bouncer->speed) < 6*FRACUNIT) @@ -717,7 +712,7 @@ void T_BounceCheese(levelspecthink_t *bouncer) else bouncer->speed -= bouncer->speed/2; - bouncer->low = bouncer->low ? 0 : 1; + bouncer->low = !bouncer->low; if (abs(bouncer->speed) > 6*FRACUNIT) { mobj_t *mp = (void *)&actionsector->soundorg; @@ -756,11 +751,6 @@ void T_BounceCheese(levelspecthink_t *bouncer) if (actionsector) P_RecalcPrecipInSector(actionsector); } -#undef speed -#undef distance -#undef low -#undef ceilingwasheight -#undef floorwasheight } ////////////////////////////////////////////////// @@ -2283,10 +2273,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) // Used for bobbing platforms on the water INT32 EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline) { -#define speed vars[0] -#define distance vars[1] -#define low vars[2] - levelspecthink_t *bouncer; + bouncecheese_t *bouncer; // create and initialize new thinker if (sec->ceilingdata) // One at a time, ma'am. @@ -2298,16 +2285,13 @@ INT32 EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline) bouncer->thinker.function.acp1 = (actionf_p1)T_BounceCheese; // set up the fields according to the type of elevator action + bouncer->sourceline = sourceline; bouncer->sector = sec; bouncer->speed = momz/2; - bouncer->sourceline = sourceline; bouncer->distance = FRACUNIT; - bouncer->low = 1; + bouncer->low = true; return 1; -#undef speed -#undef distance -#undef low } // For T_ContinuousFalling special diff --git a/src/p_saveg.c b/src/p_saveg.c index 888eb96ca..48e910dcd 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1670,6 +1670,24 @@ static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveLine(ht->sourceline)); } +// +// SaveBounceCheeseThinker +// +// Saves a bouncecheese_t thinker +// +static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type) +{ + const bouncecheese_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEFIXED(save_p, ht->speed); + WRITEFIXED(save_p, ht->distance); + WRITEFIXED(save_p, ht->floorwasheight); + WRITEFIXED(save_p, ht->ceilingwasheight); + WRITECHAR(save_p, ht->low); +} + // // SaveContinuousFallThinker // @@ -2378,7 +2396,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_BounceCheese) { - SaveSpecialLevelThinker(th, tc_bouncecheese); + SaveBounceCheeseThinker(th, tc_bouncecheese); continue; } else if (th->function.acp1 == (actionf_p1)T_StartCrumble) @@ -2893,6 +2911,24 @@ static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker) return &ht->thinker; } +// LoadBounceCheeseThinker +// +// Loads a bouncecheese_t from a save game +// +static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker) +{ + bouncecheese_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sourceline = LoadLine(READUINT32(save_p)); + ht->sector = LoadSector(READUINT32(save_p)); + ht->speed = READFIXED(save_p); + ht->distance = READFIXED(save_p); + ht->floorwasheight = READFIXED(save_p); + ht->ceilingwasheight = READFIXED(save_p); + ht->low = READCHAR(save_p); + return &ht->thinker; +} + // LoadContinuousFallThinker // // Loads a continuousfall_t from a save game @@ -3688,7 +3724,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_bouncecheese: - th = LoadSpecialLevelThinker((actionf_p1)T_BounceCheese, 2); + th = LoadBounceCheeseThinker((actionf_p1)T_BounceCheese); break; case tc_startcrumble: diff --git a/src/p_spec.h b/src/p_spec.h index 5e54b568f..8897304af 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -337,6 +337,18 @@ typedef struct fixed_t destheight; } continuousfall_t; +typedef struct +{ + thinker_t thinker; + line_t *sourceline; + sector_t *sector; + fixed_t speed; + fixed_t distance; + fixed_t floorwasheight; + fixed_t ceilingwasheight; + boolean low; +} bouncecheese_t; + typedef struct { thinker_t thinker; @@ -429,7 +441,7 @@ void T_MoveFloor(floormove_t *movefloor); void T_MoveElevator(elevator_t *elevator); void T_ContinuousFalling(continuousfall_t *faller); -void T_BounceCheese(levelspecthink_t *bouncer); +void T_BounceCheese(bouncecheese_t *bouncer); void T_StartCrumble(elevator_t *elevator); void T_MarioBlock(mariothink_t *block); void T_FloatSector(floatthink_t *floater); From da594db3fcded48f85ed613a04ea415dc1c64d47 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 10:52:58 +0200 Subject: [PATCH 107/220] Remove return values from a few elevator functions that don't use them --- src/p_floor.c | 18 +++++------------- src/p_spec.h | 6 +++--- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 6e0599f70..eeb2a6b84 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1800,9 +1800,9 @@ void T_PlaneDisplace(planedisplace_t *pd) // (egg capsule button), P_PlayerInSpecialSector (buttons), // and P_SpawnSpecials (continuous floor movers and instant lower). // -INT32 EV_DoFloor(line_t *line, floor_e floortype) +void EV_DoFloor(line_t *line, floor_e floortype) { - INT32 rtn = 0, firstone = 1; + INT32 firstone = 1; INT32 secnum = -1; sector_t *sec; floormove_t *dofloor; @@ -1815,7 +1815,6 @@ INT32 EV_DoFloor(line_t *line, floor_e floortype) continue; // then don't add another one // new floor thinker - rtn = 1; dofloor = Z_Calloc(sizeof (*dofloor), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &dofloor->thinker); @@ -2005,8 +2004,6 @@ INT32 EV_DoFloor(line_t *line, floor_e floortype) firstone = 0; } - - return rtn; } // SoM: Boom elevator support. @@ -2019,10 +2016,9 @@ INT32 EV_DoFloor(line_t *line, floor_e floortype) // // jff 2/22/98 new type to move floor and ceiling in parallel // -INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) +void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) { INT32 secnum = -1; - INT32 rtn = 0; sector_t *sec; elevator_t *elevator; @@ -2036,7 +2032,6 @@ INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) continue; // create and initialize new elevator thinker - rtn = 1; elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &elevator->thinker); sec->floordata = elevator; @@ -2138,7 +2133,6 @@ INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) break; } } - return rtn; } void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) @@ -2271,13 +2265,13 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) } // Used for bobbing platforms on the water -INT32 EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline) +void EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline) { bouncecheese_t *bouncer; // create and initialize new thinker if (sec->ceilingdata) // One at a time, ma'am. - return 0; + return; bouncer = Z_Calloc(sizeof (*bouncer), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &bouncer->thinker); @@ -2290,8 +2284,6 @@ INT32 EV_BounceSector(sector_t *sec, fixed_t momz, line_t *sourceline) bouncer->speed = momz/2; bouncer->distance = FRACUNIT; bouncer->low = true; - - return 1; } // For T_ContinuousFalling special diff --git a/src/p_spec.h b/src/p_spec.h index 8897304af..2d535fd25 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -424,10 +424,10 @@ typedef enum result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush, boolean ceiling, INT32 direction); -INT32 EV_DoFloor(line_t *line, floor_e floortype); -INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed); +void EV_DoFloor(line_t *line, floor_e floortype); +void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed); void EV_CrumbleChain(sector_t *sec, ffloor_t *rover); -INT32 EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline); +void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline); // Some other special 3dfloor types INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover, From 54cbd66999f370cb296280b6dae27c46fdf3f5bd Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 11:05:58 +0200 Subject: [PATCH 108/220] Eradicate levelspecthink_t --- src/p_floor.c | 8 +---- src/p_saveg.c | 84 +++++++++++++++++---------------------------------- src/p_spec.c | 2 +- src/p_spec.h | 18 +++++------ 4 files changed, 38 insertions(+), 74 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index eeb2a6b84..179cf73c7 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1071,26 +1071,20 @@ static mobj_t *SearchMarioNode(msecnode_t *node) return thing; } -void T_MarioBlockChecker(levelspecthink_t *block) +void T_MarioBlockChecker(mariocheck_t *block) { line_t *masterline = block->sourceline; - if (block->vars[2] == 1) // Don't update the textures when the block's being bumped upwards. - return; if (SearchMarioNode(block->sector->touching_thinglist)) { sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; // Update textures if (masterline->backsector) - { block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->ceilingpic; // Update flats to be backside's ceiling - } } else { sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture; if (masterline->backsector) - { block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->floorpic; // Update flats to be backside's floor - } } } diff --git a/src/p_saveg.c b/src/p_saveg.c index 48e910dcd..0fef92d01 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1639,25 +1639,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->mobjnum); } -// -// SaveSpecialLevelThinker -// -// Saves a levelspecthink_t thinker -// -static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type) -{ - const levelspecthink_t *ht = (const void *)th; - size_t i; - WRITEUINT8(save_p, type); - for (i = 0; i < 16; i++) - { - WRITEFIXED(save_p, ht->vars[i]); //var[16] - WRITEFIXED(save_p, ht->var2s[i]); //var[16] - } - WRITEUINT32(save_p, SaveLine(ht->sourceline)); - WRITEUINT32(save_p, SaveSector(ht->sector)); -} - // // SaveNoEnemiesThinker // @@ -1722,6 +1703,19 @@ static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type) WRITEINT16(save_p, ht->tag); } +// +// SaveMarioCheckThinker +// +// Saves a mariocheck_t thinker +// +static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type) +{ + const mariocheck_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT32(save_p, SaveSector(ht->sector)); +} + // // SaveThwompThinker // @@ -2411,7 +2405,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker) { - SaveSpecialLevelThinker(th, tc_marioblockchecker); + SaveMarioCheckThinker(th, tc_marioblockchecker); continue; } else if (th->function.acp1 == (actionf_p1)T_FloatSector) @@ -2864,41 +2858,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) return &mobj->thinker; } -// -// LoadSpecialLevelThinker -// -// Loads a levelspecthink_t from a save game -// -// floorOrCeiling: -// 0 - Don't set -// 1 - Floor Only -// 2 - Ceiling Only -// 3 - Both -// -static thinker_t* LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling) -{ - levelspecthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); - size_t i; - ht->thinker.function.acp1 = thinker; - for (i = 0; i < 16; i++) - { - ht->vars[i] = READFIXED(save_p); //var[16] - ht->var2s[i] = READFIXED(save_p); //var[16] - } - ht->sourceline = LoadLine(READUINT32(save_p)); - ht->sector = LoadSector(READUINT32(save_p)); - - if (ht->sector) - { - if (floorOrCeiling & 2) - ht->sector->ceilingdata = ht; - if (floorOrCeiling & 1) - ht->sector->floordata = ht; - } - - return &ht->thinker; -} - // LoadNoEnemiesThinker // // Loads a noenemies_t from a save game @@ -2963,6 +2922,19 @@ static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) return &ht->thinker; } +// LoadMarioCheckThinker +// +// Loads a mariocheck_t from a save game +// +static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker) +{ + mariocheck_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->sourceline = LoadLine(READUINT32(save_p)); + ht->sector = LoadSector(READUINT32(save_p)); + return &ht->thinker; +} + // LoadThwompThinker // // Loads a thwomp_t from a save game @@ -3736,7 +3708,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_marioblockchecker: - th = LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0); + th = LoadMarioCheckThinker((actionf_p1)T_MarioBlockChecker); break; case tc_floatsector: diff --git a/src/p_spec.c b/src/p_spec.c index 921bcef26..728bacab1 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5983,7 +5983,7 @@ static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, */ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) { - levelspecthink_t *block; + mariocheck_t *block; // create and initialize new elevator thinker block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL); diff --git a/src/p_spec.h b/src/p_spec.h index 2d535fd25..e243e3a61 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -311,15 +311,6 @@ typedef struct line_t *sourceline; } elevator_t; -typedef struct -{ - thinker_t thinker; - fixed_t vars[16]; // Misc. variables - fixed_t var2s[16]; // Second misc variables buffer. - line_t *sourceline; // Source line of the thinker - sector_t *sector; // Sector the thinker is from -} levelspecthink_t; - typedef struct { thinker_t thinker; @@ -360,6 +351,13 @@ typedef struct INT16 tag; } mariothink_t; +typedef struct +{ + thinker_t thinker; + line_t *sourceline; + sector_t *sector; +} mariocheck_t; + typedef struct { thinker_t thinker; @@ -445,7 +443,7 @@ void T_BounceCheese(bouncecheese_t *bouncer); void T_StartCrumble(elevator_t *elevator); void T_MarioBlock(mariothink_t *block); void T_FloatSector(floatthink_t *floater); -void T_MarioBlockChecker(levelspecthink_t *block); +void T_MarioBlockChecker(mariocheck_t *block); void T_ThwompSector(thwomp_t *thwomp); void T_NoEnemiesSector(noenemies_t *nobaddies); void T_EachTimeThinker(eachtime_t *eachtime); From c031008eab4d44bf2c9113630c331b53e740b798 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 18 Apr 2020 15:17:25 +0200 Subject: [PATCH 109/220] Enable SF_TRIGGERSPECIAL_TOUCH for sectors with spike damage --- src/p_spec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 728bacab1..32e4f111c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6363,6 +6363,12 @@ void P_SpawnSpecials(boolean fromnetsave) // Process Section 1 switch(GETSECSPECIAL(sector->special, 1)) { + case 5: // Spikes + //Terrible hack to replace an even worse hack: + //Spike damage automatically sets SF_TRIGGERSPECIAL_TOUCH. + //Yes, this also affects other specials on the same sector. Sorry. + sector->flags |= SF_TRIGGERSPECIAL_TOUCH; + break; case 15: // Bouncy sector CheckForBouncySector = true; break; From f6e2c7063f77c399313b31e92a4278d2ba314cc4 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 20 Apr 2020 23:40:41 +0200 Subject: [PATCH 110/220] Rename lumpinfo_t.name2 to lumpinfo_t.fullname --- src/lua_script.c | 4 ++-- src/p_setup.c | 4 ++-- src/w_wad.c | 47 ++++++++++++++++++++++++----------------------- src/w_wad.h | 2 +- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 1bc89180e..7adf62fcc 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -441,9 +441,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump) else // If it's not a .lua file, copy the lump name in too. { lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump]; - len += 1 + strlen(lump_p->name2); // length of file name, '|', and lump name + len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name name = malloc(len+1); - sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2); + sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname); name[len] = '\0'; } diff --git a/src/p_setup.c b/src/p_setup.c index 700113d85..6396dbd90 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3777,12 +3777,12 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l { UINT16 numlumps = *pnumlumps; size_t i = *pi; - if (!stricmp(lumpinfo->name2, folName)) + if (!stricmp(lumpinfo->fullname, folName)) { lumpinfo++; *start = ++i; for (; i < numlumps; i++, lumpinfo++) - if (strnicmp(lumpinfo->name2, folName, strlen(folName))) + if (strnicmp(lumpinfo->fullname, folName, strlen(folName))) break; lumpinfo--; *end = i-- - *start; diff --git a/src/w_wad.c b/src/w_wad.c index 1008aca8f..45b1de086 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -117,7 +117,7 @@ void W_Shutdown(void) fclose(wadfiles[numwadfiles]->handle); Z_Free(wadfiles[numwadfiles]->filename); while (wadfiles[numwadfiles]->numlumps--) - Z_Free(wadfiles[numwadfiles]->lumpinfo[wadfiles[numwadfiles]->numlumps].name2); + Z_Free(wadfiles[numwadfiles]->lumpinfo[wadfiles[numwadfiles]->numlumps].fullname); Z_Free(wadfiles[numwadfiles]->lumpinfo); Z_Free(wadfiles[numwadfiles]); @@ -206,9 +206,9 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) for(; posStart < posEnd; posStart++) { lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart]; - size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name + size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name char *name = malloc(length + 1); - sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2); + sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname); name[length] = '\0'; CONS_Printf(M_GetText("Loading SOC from %s\n"), name); DEH_LoadDehackedLumpPwad(wadnum, posStart, mainfile); @@ -235,9 +235,9 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile) for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++) if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump { // shameless copy+paste of code from LUA_LoadLump - size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name + size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name char *name = malloc(length + 1); - sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2); + sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname); name[length] = '\0'; CONS_Printf(M_GetText("Loading SOC from %s\n"), name); @@ -340,9 +340,10 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const fseek(handle, 0, SEEK_SET); strcpy(lumpinfo->name, lumpname); // Allocate the lump's full name. - lumpinfo->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); - strcpy(lumpinfo->name2, lumpname); - lumpinfo->name2[8] = '\0'; + lumpinfo->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); + strcpy(lumpinfo->fullname, lumpname); + lumpinfo->fullname[8] = '\0'; + *numlumps = 1; return lumpinfo; } @@ -430,9 +431,9 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen memset(lump_p->name, 0x00, 9); strncpy(lump_p->name, fileinfo->name, 8); // Allocate the lump's full name. - lump_p->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); - strncpy(lump_p->name2, fileinfo->name, 8); - lump_p->name2[8] = '\0'; + lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); + strncpy(lump_p->fullname, fileinfo->name, 8); + lump_p->fullname[8] = '\0'; } free(fileinfov); *nlmp = numlumps; @@ -598,8 +599,8 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary? strncpy(lump_p->name, trimname, min(8, dotpos - trimname)); - lump_p->name2 = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL); - strncpy(lump_p->name2, fullname, zentry.namelen); + lump_p->fullname = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL); + strncpy(lump_p->fullname, fullname, zentry.namelen); free(fullname); @@ -637,7 +638,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) // skip and ignore comments/extra fields if ((fseek(handle, lump_p->position, SEEK_SET) != 0) || (fread(&zlentry, 1, sizeof(zlentry_t), handle) < sizeof(zlentry_t))) { - CONS_Alert(CONS_ERROR, "Local headers for lump %s are corrupt\n", lump_p->name2); + CONS_Alert(CONS_ERROR, "Local headers for lump %s are corrupt\n", lump_p->fullname); Z_Free(lumpinfo); return NULL; } @@ -947,10 +948,10 @@ UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlum name_length = strlen(name); for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) { - if (strnicmp(name, lump_p->name2, name_length) == 0) + if (strnicmp(name, lump_p->fullname, name_length) == 0) { /* SLADE is special and puts a single directory entry. Skip that. */ - if (strlen(lump_p->name2) == name_length) + if (strlen(lump_p->fullname) == name_length) i++; break; } @@ -967,7 +968,7 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump) lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) { - if (strnicmp(name, lump_p->name2, strlen(name))) + if (strnicmp(name, lump_p->fullname, strlen(name))) break; } return i; @@ -981,7 +982,7 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump) lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) { - if (!strnicmp(name, lump_p->name2, strlen(name))) + if (!strnicmp(name, lump_p->fullname, strlen(name))) { return i; } @@ -1151,7 +1152,7 @@ boolean W_IsLumpWad(lumpnum_t lumpnum) { if (wadfiles[WADFILENUM(lumpnum)]->type == RET_PK3) { - const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->name2; + const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->fullname; if (strlen(lumpfullName) < 4) return false; // can't possibly be a WAD can it? @@ -1169,7 +1170,7 @@ boolean W_IsLumpFolder(UINT16 wad, UINT16 lump) { if (wadfiles[wad]->type == RET_PK3) { - const char *name = wadfiles[wad]->lumpinfo[lump].name2; + const char *name = wadfiles[wad]->lumpinfo[lump].fullname; return (name[strlen(name)-1] == '/'); // folders end in '/' } @@ -1247,7 +1248,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si { size_t bytesread = fread(dest, 1, size, handle); if (R_IsLumpPNG((UINT8 *)dest, bytesread)) - W_ThrowPNGError(l->name2, wadfiles[wad]->filename); + W_ThrowPNGError(l->fullname, wadfiles[wad]->filename); return bytesread; } #else @@ -1289,7 +1290,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si Z_Free(decData); #ifdef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)dest, size)) - W_ThrowPNGError(l->name2, wadfiles[wad]->filename); + W_ThrowPNGError(l->fullname, wadfiles[wad]->filename); #endif return size; #else @@ -1352,7 +1353,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si #ifdef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)dest, size)) - W_ThrowPNGError(l->name2, wadfiles[wad]->filename); + W_ThrowPNGError(l->fullname, wadfiles[wad]->filename); #endif return size; } diff --git a/src/w_wad.h b/src/w_wad.h index d4455ba14..3cf9585a4 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -67,7 +67,7 @@ typedef struct unsigned long position; // filelump_t filepos unsigned long disksize; // filelump_t size char name[9]; // filelump_t name[] - char *name2; // Used by PK3s. Dynamically allocated name. + char *fullname; // Used by PK3s. Dynamically allocated name. size_t size; // real (uncompressed) size compmethod compression; // lump compression method } lumpinfo_t; From 29a94ee26aae3c45bd35463428bdcef9020b6734 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 21 Apr 2020 10:21:41 +0200 Subject: [PATCH 111/220] Add a longname field to lumpinfo_t --- src/w_wad.c | 32 ++++++++++++++++++++++++++------ src/w_wad.h | 7 ++++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 45b1de086..22856d155 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -114,13 +114,18 @@ void W_Shutdown(void) { while (numwadfiles--) { - fclose(wadfiles[numwadfiles]->handle); - Z_Free(wadfiles[numwadfiles]->filename); - while (wadfiles[numwadfiles]->numlumps--) - Z_Free(wadfiles[numwadfiles]->lumpinfo[wadfiles[numwadfiles]->numlumps].fullname); + wadfile_t *wad = wadfiles[numwadfiles]; - Z_Free(wadfiles[numwadfiles]->lumpinfo); - Z_Free(wadfiles[numwadfiles]); + fclose(wad->handle); + Z_Free(wad->filename); + while (wad->numlumps--) + { + Z_Free(wad->lumpinfo[wad->numlumps].longname); + Z_Free(wad->lumpinfo[wad->numlumps].fullname); + } + + Z_Free(wad->lumpinfo); + Z_Free(wad); } } @@ -339,6 +344,12 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const lumpinfo->size = ftell(handle); fseek(handle, 0, SEEK_SET); strcpy(lumpinfo->name, lumpname); + + // Allocate the lump's long name. + lumpinfo->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); + strcpy(lumpinfo->longname, lumpname); + lumpinfo->longname[8] = '\0'; + // Allocate the lump's full name. lumpinfo->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); strcpy(lumpinfo->fullname, lumpname); @@ -430,6 +441,12 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen lump_p->compression = CM_NOCOMPRESSION; memset(lump_p->name, 0x00, 9); strncpy(lump_p->name, fileinfo->name, 8); + + // Allocate the lump's long name. + lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); + strncpy(lump_p->longname, fileinfo->name, 8); + lump_p->longname[8] = '\0'; + // Allocate the lump's full name. lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); strncpy(lump_p->fullname, fileinfo->name, 8); @@ -599,6 +616,9 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary? strncpy(lump_p->name, trimname, min(8, dotpos - trimname)); + lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL); + strlcpy(lump_p->longname, trimname, dotpos - trimname + 1); + lump_p->fullname = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL); strncpy(lump_p->fullname, fullname, zentry.namelen); diff --git a/src/w_wad.h b/src/w_wad.h index 3cf9585a4..3af6148f4 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -66,9 +66,10 @@ typedef struct { unsigned long position; // filelump_t filepos unsigned long disksize; // filelump_t size - char name[9]; // filelump_t name[] - char *fullname; // Used by PK3s. Dynamically allocated name. - size_t size; // real (uncompressed) size + char name[9]; // filelump_t name[] e.g. "LongEntr" + char *longname; // e.g. "LongEntryName" + char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension" + size_t size; // real (uncompressed) size compmethod compression; // lump compression method } lumpinfo_t; From 0ddd2fea217949948d1b3bcf4525bd6bdf3827b2 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 21 Apr 2020 11:08:18 +0200 Subject: [PATCH 112/220] Let W_CheckNumForName(Pwad) find entries with long names --- src/w_wad.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 22856d155..f273753c8 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -92,7 +92,7 @@ typedef struct typedef struct lumpnum_cache_s { - char lumpname[8]; + char lumpname[32]; lumpnum_t lumpnum; } lumpnum_cache_t; @@ -922,16 +922,14 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum) UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) { UINT16 i; - static char uname[9]; - - memset(uname, 0x00, sizeof uname); - strncpy(uname, name, 8); - uname[8] = 0; - strupr(uname); + static char uname[256 + 1]; if (!TestValidLump(wad,0)) return INT16_MAX; + strlcpy(uname, name, sizeof uname); + strupr(uname); + // // scan forward // start at 'startlump', useful parameter when there are multiple @@ -941,7 +939,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) { lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) - if (memcmp(lump_p->name,uname,8) == 0) + if (!strcmp(lump_p->longname, uname)) return i; } @@ -1027,7 +1025,7 @@ lumpnum_t W_CheckNumForName(const char *name) // most recent entries first for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) { - if (strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0) + if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0) { lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1); return lumpnumcache[lumpnumcacheindex].lumpnum; @@ -1047,7 +1045,7 @@ lumpnum_t W_CheckNumForName(const char *name) { // Update the cache. lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1); - strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8); + strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32); lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check; return lumpnumcache[lumpnumcacheindex].lumpnum; From 64edd91dbd56de778695abb533590eac0f5df767 Mon Sep 17 00:00:00 2001 From: ZipperQR Date: Wed, 22 Apr 2020 00:59:12 +0300 Subject: [PATCH 113/220] Dust devil support --- src/d_player.h | 3 ++- src/dehacked.c | 1 + src/p_enemy.c | 5 ++++- src/p_user.c | 3 +++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 8697e9836..e5c7e7298 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -239,7 +239,8 @@ typedef enum CR_MACESPIN, CR_MINECART, CR_ROLLOUT, - CR_PTERABYTE + CR_PTERABYTE, + CR_DUSTDEVIL } carrytype_t; // pw_carry // Player powers. (don't edit this comment) diff --git a/src/dehacked.c b/src/dehacked.c index e9d029be0..15e5bb060 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9468,6 +9468,7 @@ struct { {"CR_MINECART",CR_MINECART}, {"CR_ROLLOUT",CR_ROLLOUT}, {"CR_PTERABYTE",CR_PTERABYTE}, + {"CR_DUSTDEVIL",CR_DUSTDEVIL}, // Ring weapons (ringweapons_t) // Useful for A_GiveWeapon diff --git a/src/p_enemy.c b/src/p_enemy.c index 2341be6d3..58f09cacb 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13311,8 +13311,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) P_ResetPlayer(player); A_PlayActiveSound(dustdevil); } + player->powers[pw_carry] = CR_DUSTDEVIL; player->powers[pw_nocontrol] = 2; - player->drawangle += ANG20; + P_SetTarget(&thing->tracer, dustdevil); P_SetPlayerMobjState(thing, S_PLAY_PAIN); if (dist > dragamount) @@ -13332,7 +13333,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) P_ResetPlayer(player); thing->z = dustdevil->z + dustdevil->height; thrust = 20 * FRACUNIT; + player->powers[pw_carry] = CR_NONE; player->powers[pw_nocontrol] = 0; + P_SetTarget(&thing->tracer, NULL); S_StartSound(thing, sfx_wdjump); P_SetPlayerMobjState(thing, S_PLAY_FALL); } diff --git a/src/p_user.c b/src/p_user.c index 1f46a2dff..28d2d6a5e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11950,6 +11950,9 @@ void P_PlayerThink(player_t *player) break; } /* FALLTHRU */ + case CR_DUSTDEVIL: + player->drawangle += ANG20; + break; default: player->drawangle = player->mo->angle; break; From 657ee8287e1a955d14797d7eb25568be857d2a07 Mon Sep 17 00:00:00 2001 From: Zipper Date: Wed, 22 Apr 2020 07:59:08 -0400 Subject: [PATCH 114/220] Update p_user.c --- src/p_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 28d2d6a5e..a656aef34 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11943,6 +11943,9 @@ void P_PlayerThink(player_t *player) break; /* -- in case we wanted to have the camera freely movable during zoom tubes case CR_ZOOMTUBE:*/ + case CR_DUSTDEVIL: + player->drawangle += ANG20; + break; case CR_ROPEHANG: if (player->mo->momx || player->mo->momy) { @@ -11950,9 +11953,6 @@ void P_PlayerThink(player_t *player) break; } /* FALLTHRU */ - case CR_DUSTDEVIL: - player->drawangle += ANG20; - break; default: player->drawangle = player->mo->angle; break; From 25affe6948acc3274c04a9f4a3e3df666d8a6fd5 Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 22 Apr 2020 18:58:40 +0200 Subject: [PATCH 115/220] Make emerald hunt shards spawn at correct heights, and add Float option. --- extras/conf/SRB2-22.cfg | 2 ++ src/p_mobj.c | 5 +++-- src/p_mobj.h | 3 +++ src/p_setup.c | 28 +++++++++++++++++++--------- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 585fa7857..ea783908a 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3900,6 +3900,8 @@ thingtypes { title = "Emerald Hunt Location"; sprite = "SHRDA0"; + flags8height = 24; + flags8text = "[8] Float"; } 321 { diff --git a/src/p_mobj.c b/src/p_mobj.c index 7e65c37ad..10f051891 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11616,7 +11616,7 @@ void P_MovePlayerToStarpost(INT32 playernum) mapthing_t *huntemeralds[MAXHUNTEMERALDS]; INT32 numhuntemeralds; -static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip) +fixed_t P_GetMobjSpawnHeight(mobjtype_t mobjtype, fixed_t x, fixed_t y, fixed_t offset, boolean flip) { const subsector_t *ss = R_PointInSubsector(x, y); @@ -11633,7 +11633,7 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, + offset; } -static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) +fixed_t P_GetMapThingSpawnHeight(mobjtype_t mobjtype, mapthing_t* mthing, fixed_t x, fixed_t y) { fixed_t offset = mthing->z << FRACBITS; boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); @@ -11673,6 +11673,7 @@ static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthin // Ring-like items, may float additional units with MTF_AMBUSH. case MT_SPIKEBALL: + case MT_EMERHUNT: case MT_EMERALDSPAWN: case MT_TOKEN: case MT_EMBLEM: diff --git a/src/p_mobj.h b/src/p_mobj.h index 5deb288e4..9e7e340a6 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -451,6 +451,9 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing); void P_MovePlayerToStarpost(INT32 playernum); void P_AfterPlayerSpawn(INT32 playernum); +fixed_t P_GetMobjSpawnHeight(mobjtype_t mobjtype, fixed_t x, fixed_t y, fixed_t offset, boolean flip); +fixed_t P_GetMapThingSpawnHeight(mobjtype_t mobjtype, mapthing_t* mthing, fixed_t x, fixed_t y); + mobj_t *P_SpawnMapThing(mapthing_t *mthing); void P_SpawnHoop(mapthing_t *mthing); void P_SetBonusTime(mobj_t *mobj); diff --git a/src/p_setup.c b/src/p_setup.c index 700113d85..50df3c01a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -695,6 +695,7 @@ static void P_SpawnEmeraldHunt(void) { INT32 emer1, emer2, emer3; INT32 timeout = 0; // keeps from getting stuck + fixed_t x, y, z; emer1 = emer2 = emer3 = 0; @@ -719,21 +720,30 @@ static void P_SpawnEmeraldHunt(void) //decrement spawn values to the actual number because zero is valid. if (emer1--) - P_SpawnMobj(huntemeralds[emer1]->x<y<z<x<y<x<y<z<x<y<x<y<z<x<y< Date: Wed, 22 Apr 2020 20:38:58 +0200 Subject: [PATCH 116/220] Fix a mistake with P_SpawnEmeraldHunt and make it more concise. --- src/p_setup.c | 45 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 50df3c01a..9bc334ff0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -691,58 +691,39 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) } #endif -static void P_SpawnEmeraldHunt(void) +static void P_SpawnEmeraldHunt(int amount) { - INT32 emer1, emer2, emer3; + INT32 emer[amount]; INT32 timeout = 0; // keeps from getting stuck fixed_t x, y, z; - emer1 = emer2 = emer3 = 0; - //increment spawn numbers because zero is valid. - emer1 = (P_RandomKey(numhuntemeralds)) + 1; + emer[0] = (P_RandomKey(numhuntemeralds)) + 1; while (timeout++ < 100) { - emer2 = (P_RandomKey(numhuntemeralds)) + 1; + emer[1] = (P_RandomKey(numhuntemeralds)) + 1; - if (emer2 != emer1) + if (emer[1] != emer[0]) break; } timeout = 0; while (timeout++ < 100) { - emer3 = (P_RandomKey(numhuntemeralds)) + 1; + emer[2] = (P_RandomKey(numhuntemeralds)) + 1; - if (emer3 != emer2 && emer3 != emer1) + if (emer[2] != emer[1] && emer[2] != emer[0]) break; } //decrement spawn values to the actual number because zero is valid. - if (emer1--) + for (int i = 0; i < amount; i++) { - x = huntemeralds[emer1]->x<y<x<y<x<y<x<y< Date: Wed, 22 Apr 2020 22:46:12 +0200 Subject: [PATCH 117/220] Make P_SpawnEmeraldHunt even more concise, using Fisher-Yates shuffle. --- src/p_setup.c | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 9bc334ff0..0e9c915fe 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -691,39 +691,28 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) } #endif -static void P_SpawnEmeraldHunt(int amount) +static void P_SpawnEmeraldHunt(void) { - INT32 emer[amount]; - INT32 timeout = 0; // keeps from getting stuck + INT32 emer[3], num[numhuntemeralds], randomkey; fixed_t x, y, z; - //increment spawn numbers because zero is valid. - emer[0] = (P_RandomKey(numhuntemeralds)) + 1; - while (timeout++ < 100) + for (int i = 0; i < numhuntemeralds; i++) + num[i] = i; + + for (int i = 0; i < 3; i++) { - emer[1] = (P_RandomKey(numhuntemeralds)) + 1; + // generate random index, shuffle afterwards + randomkey = P_RandomKey(numhuntemeralds--); + emer[i] = num[randomkey]; + num[randomkey] = num[numhuntemeralds]; + num[numhuntemeralds] = emer[i]; - if (emer[1] != emer[0]) - break; - } - - timeout = 0; - while (timeout++ < 100) - { - emer[2] = (P_RandomKey(numhuntemeralds)) + 1; - - if (emer[2] != emer[1] && emer[2] != emer[0]) - break; - } - - //decrement spawn values to the actual number because zero is valid. - for (int i = 0; i < amount; i++) - { - x = huntemeralds[emer[i]-1]->x<y<x<y< Date: Wed, 22 Apr 2020 23:10:43 +0200 Subject: [PATCH 118/220] Fix variable-length array definition, just in case. --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 0e9c915fe..7ee26d68b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -693,7 +693,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) static void P_SpawnEmeraldHunt(void) { - INT32 emer[3], num[numhuntemeralds], randomkey; + INT32 emer[3], num[MAXHUNTEMERALDS], randomkey; fixed_t x, y, z; for (int i = 0; i < numhuntemeralds; i++) From f85bfc87f5ffad7b65f21c28d41c10493d0c88e4 Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 22 Apr 2020 23:17:18 +0200 Subject: [PATCH 119/220] Move variable declarations outside of for loops. --- src/p_setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 7ee26d68b..86a30e326 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -693,13 +693,13 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) static void P_SpawnEmeraldHunt(void) { - INT32 emer[3], num[MAXHUNTEMERALDS], randomkey; + INT32 emer[3], num[MAXHUNTEMERALDS], i, randomkey; fixed_t x, y, z; - for (int i = 0; i < numhuntemeralds; i++) + for (i = 0; i < numhuntemeralds; i++) num[i] = i; - for (int i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { // generate random index, shuffle afterwards randomkey = P_RandomKey(numhuntemeralds--); From 67f511a55e5db11147853ce4edd0f6d89efe66db Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 22 Apr 2020 23:38:10 +0200 Subject: [PATCH 120/220] Restore carelessly removed const keywords. --- src/p_mobj.c | 4 ++-- src/p_mobj.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 10f051891..27cb0b456 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11616,7 +11616,7 @@ void P_MovePlayerToStarpost(INT32 playernum) mapthing_t *huntemeralds[MAXHUNTEMERALDS]; INT32 numhuntemeralds; -fixed_t P_GetMobjSpawnHeight(mobjtype_t mobjtype, fixed_t x, fixed_t y, fixed_t offset, boolean flip) +fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip) { const subsector_t *ss = R_PointInSubsector(x, y); @@ -11633,7 +11633,7 @@ fixed_t P_GetMobjSpawnHeight(mobjtype_t mobjtype, fixed_t x, fixed_t y, fixed_t + offset; } -fixed_t P_GetMapThingSpawnHeight(mobjtype_t mobjtype, mapthing_t* mthing, fixed_t x, fixed_t y) +fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) { fixed_t offset = mthing->z << FRACBITS; boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); diff --git a/src/p_mobj.h b/src/p_mobj.h index 9e7e340a6..eda7383df 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -451,8 +451,8 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing); void P_MovePlayerToStarpost(INT32 playernum); void P_AfterPlayerSpawn(INT32 playernum); -fixed_t P_GetMobjSpawnHeight(mobjtype_t mobjtype, fixed_t x, fixed_t y, fixed_t offset, boolean flip); -fixed_t P_GetMapThingSpawnHeight(mobjtype_t mobjtype, mapthing_t* mthing, fixed_t x, fixed_t y); +fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip); +fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y); mobj_t *P_SpawnMapThing(mapthing_t *mthing); void P_SpawnHoop(mapthing_t *mthing); From 9ec4ba38246c2841661da7c191f5f40e81be78da Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 24 Apr 2020 14:05:15 +0200 Subject: [PATCH 121/220] Add a minimum delay between connections --- src/d_clisrv.c | 22 ++++++++++++++++++++++ src/d_clisrv.h | 2 +- src/d_netcmd.c | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3603bb20d..f7755c148 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -85,6 +85,10 @@ tic_t jointimeout = (10*TICRATE); static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame? static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout? +// Incremented by cv_joindelay when a client joins, decremented each tic. +// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled. +static tic_t joindelay = 0; + UINT16 pingmeasurecount = 1; UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. @@ -3077,6 +3081,8 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}}; +consvar_t cv_joindelay = {"joindelay", "10", CV_SAVE, joindelay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}}; consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3164,6 +3170,8 @@ void SV_ResetServer(void) neededtic = maketic; tictoclear = maketic; + joindelay = 0; + for (i = 0; i < MAXNETNODES; i++) ResetNode(i); @@ -3613,6 +3621,9 @@ static void HandleConnect(SINT8 node) SV_SendRefuse(node, M_GetText("No players from\nthis node.")); else if (luafiletransfers) SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining.")); + else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE) + SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."), + (joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE)); else { #ifndef NONET @@ -3670,6 +3681,7 @@ static void HandleConnect(SINT8 node) DEBFILE("send savegame\n"); } SV_AddWaitingPlayers(names[0], names[1]); + joindelay += cv_joindelay.value * TICRATE; player_joining = true; } #else @@ -5038,12 +5050,21 @@ void NetUpdate(void) hu_resynching = true; } } + Net_AckTicker(); + // Handle timeouts to prevent definitive freezes from happenning if (server) + { for (i = 1; i < MAXNETNODES; i++) if (nodeingame[i] && freezetimeout[i] < I_GetTime()) Net_ConnectionTimeout(i); + + // In case the cvar value was lowered + if (joindelay) + joindelay = min(joindelay - 1, 3 * cv_joindelay.value * TICRATE); + } + nowtime /= NEWTICRATERATIO; if (nowtime > resptime) { @@ -5051,6 +5072,7 @@ void NetUpdate(void) M_Ticker(); CON_Ticker(); } + SV_FileSendTicker(); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 7e5061ff2..463240a2a 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -515,7 +515,7 @@ extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; extern tic_t servermaxping; -extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_rejointimeout; +extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout; extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1fd53499a..dfc7351f5 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -573,6 +573,7 @@ void D_RegisterServerCommands(void) // d_clisrv CV_RegisterVar(&cv_maxplayers); + CV_RegisterVar(&cv_joindelay); CV_RegisterVar(&cv_rejointimeout); CV_RegisterVar(&cv_resynchattempts); CV_RegisterVar(&cv_maxsend); From c90cc3b58f4999eeefac820d25f5b9065fa28938 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 24 Apr 2020 15:38:07 +0200 Subject: [PATCH 122/220] Add a menu option for the minimum join delay --- src/m_menu.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 1069f0f30..c5f10b2bd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1583,7 +1583,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_HEADER, NULL, "General", NULL, 0}, #ifndef NONET {IT_STRING | IT_CVAR | IT_CV_STRING, - NULL, "Server name", &cv_servername, 7}, + NULL, "Server name", &cv_servername, 7}, {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21}, {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31}, @@ -1628,8 +1628,9 @@ static menuitem_t OP_ServerOptionsMenu[] = #ifndef NONET {IT_HEADER, NULL, "Advanced", NULL, 225}, - {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, - {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 245}, + {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, + {IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 246}, + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 251}, #endif }; @@ -10822,7 +10823,8 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server - OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Attempts to resynchronise + OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Minimum delay between joins + OP_ServerOptionsMenu[37].status = IT_GRAYEDOUT; // Attempts to resynchronise } else { @@ -10834,6 +10836,7 @@ static void M_ServerOptions(INT32 choice) ? IT_GRAYEDOUT : (IT_STRING | IT_CVAR | IT_CV_STRING)); OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR; } #endif From 2419b65f793a45cb3552cb527614906cc052b64d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 24 Apr 2020 16:40:09 +0100 Subject: [PATCH 123/220] Sync crumblestate in netgames --- src/p_saveg.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/p_saveg.c b/src/p_saveg.c index 259e58168..cfa93ef2f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -755,6 +755,7 @@ static void P_NetUnArchiveColormaps(void) // diff3 flags #define SD_TAGLIST 0x01 #define SD_COLORMAP 0x02 +#define SD_CRUMBLESTATE 0x03 #define LD_FLAG 0x01 #define LD_SPECIAL 0x02 @@ -834,6 +835,8 @@ static void P_NetArchiveWorld(void) if (ss->extra_colormap != spawnss->extra_colormap) diff3 |= SD_COLORMAP; + if (ss->crumblestate) + diff3 |= SD_CRUMBLESTATE; // Check if any of the sector's FOFs differ from how they spawned if (ss->ffloors) @@ -901,6 +904,8 @@ static void P_NetArchiveWorld(void) if (diff3 & SD_COLORMAP) WRITEUINT32(put, CheckAddNetColormapToList(ss->extra_colormap)); // returns existing index if already added, or appends to net_colormaps and returns new index + if (diff3 & SD_CRUMBLESTATE) + WRITEINT32(put, ss->crumblestate); // Special case: save the stats of all modified ffloors along with their ffloor "number"s // we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed @@ -1105,6 +1110,8 @@ static void P_NetUnArchiveWorld(void) if (diff3 & SD_COLORMAP) sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get)); + if (diff3 & SD_CRUMBLESTATE) + sectors[i].crumblestate = READINT32(get); if (diff & SD_FFLOORS) { From 9df5d6e1e016ef36049687c1bd5df34c5940bb89 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 24 Apr 2020 16:53:54 +0100 Subject: [PATCH 124/220] These are flags! Serves me right for just rushing this out --- src/p_saveg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index cfa93ef2f..7093ea93d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -755,7 +755,7 @@ static void P_NetUnArchiveColormaps(void) // diff3 flags #define SD_TAGLIST 0x01 #define SD_COLORMAP 0x02 -#define SD_CRUMBLESTATE 0x03 +#define SD_CRUMBLESTATE 0x04 #define LD_FLAG 0x01 #define LD_SPECIAL 0x02 From e4f2c1dc70d89fc3ac1a3ae1af7f2f560f1a352c Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 24 Apr 2020 18:33:35 +0200 Subject: [PATCH 125/220] Fix mouse being grabbed in intermission and cutscenes --- src/sdl/i_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c042d141c..ec7bfc1c4 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -372,7 +372,9 @@ static boolean IgnoreMouse(void) return false; if (menuactive) return !M_MouseNeeded(); - if (paused || con_destlines || chat_on || gamestate != GS_LEVEL) + if (paused || con_destlines || chat_on) + return true; + if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION && gamestate != GS_CUTSCENE) return true; return false; } From 08a7fcbe8db5629a8dbd57602b8cd44dc9abe593 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 24 Apr 2020 20:26:57 +0100 Subject: [PATCH 126/220] Split off FOF archiving-related code into their own functions --- src/p_saveg.c | 173 +++++++++++++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 80 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index f6e31fc3a..15e11a27b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -772,6 +772,95 @@ static void P_NetUnArchiveColormaps(void) #define LD_S2BOTTEX 0x04 #define LD_S2MIDTEX 0x08 +#define FD_FLAGS 0x01 +#define FD_ALPHA 0x02 + +// Check if any of the sector's FOFs differ from how they spawned +static boolean CheckFFloorDiff(sector_t *ss) +{ + ffloor_t *rover; + + for (rover = ss->ffloors; rover; rover = rover->next) + { + if (rover->flags != rover->spawnflags + || rover->alpha != rover->spawnalpha) + { + return true; // we found an FOF that changed! + // don't bother checking for more, we do that later + } + } + return false; +} + +// Special case: save the stats of all modified ffloors along with their ffloor "number"s +// we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed +static void ArchiveFFloors(UINT8 *put, sector_t *ss) +{ + size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc + ffloor_t *rover; + UINT8 fflr_diff; + for (rover = ss->ffloors; rover; rover = rover->next) + { + fflr_diff = 0; // reset diff flags + if (rover->flags != rover->spawnflags) + fflr_diff |= FD_FLAGS; + if (rover->alpha != rover->spawnalpha) + fflr_diff |= FD_ALPHA; + + if (fflr_diff) + { + WRITEUINT16(put, j); // save ffloor "number" + WRITEUINT8(put, fflr_diff); + if (fflr_diff & FD_FLAGS) + WRITEUINT32(put, rover->flags); + if (fflr_diff & FD_ALPHA) + WRITEINT16(put, rover->alpha); + } + j++; + } + WRITEUINT16(put, 0xffff); +} + +static void UnArchiveFFloors(UINT8 *get, sector_t *ss) +{ + UINT16 j = 0; // number of current ffloor in loop + UINT16 fflr_i; // saved ffloor "number" of next modified ffloor + UINT16 fflr_diff; // saved ffloor diff + ffloor_t *rover; + + rover = ss->ffloors; + if (!rover) // it is assumed sectors[i].ffloors actually exists, but just in case... + I_Error("Sector does not have any ffloors!"); + + fflr_i = READUINT16(get); // get first modified ffloor's number ready + for (;;) // for some reason the usual for (rover = x; ...) thing doesn't work here? + { + if (fflr_i == 0xffff) // end of modified ffloors list, let's stop already + break; + // should NEVER need to be checked + //if (rover == NULL) + //break; + if (j != fflr_i) // this ffloor was not modified + { + j++; + rover = rover->next; + continue; + } + + fflr_diff = READUINT8(get); + + if (fflr_diff & FD_FLAGS) + rover->flags = READUINT32(get); + if (fflr_diff & FD_ALPHA) + rover->alpha = READINT16(get); + + fflr_i = READUINT16(get); // get next ffloor "number" ready + + j++; + rover = rover->next; + } +} + // // P_NetArchiveWorld // @@ -838,20 +927,8 @@ static void P_NetArchiveWorld(void) if (ss->crumblestate) diff3 |= SD_CRUMBLESTATE; - // Check if any of the sector's FOFs differ from how they spawned - if (ss->ffloors) - { - ffloor_t *rover; - for (rover = ss->ffloors; rover; rover = rover->next) - { - if (rover->flags != rover->spawnflags - || rover->alpha != rover->spawnalpha) - { - diff |= SD_FFLOORS; // we found an FOF that changed! - break; // don't bother checking for more, we do that later - } - } - } + if (ss->ffloors && CheckFFloorDiff(ss)) + diff |= SD_FFLOORS; if (diff3) diff2 |= SD_DIFF3; @@ -906,35 +983,8 @@ static void P_NetArchiveWorld(void) // returns existing index if already added, or appends to net_colormaps and returns new index if (diff3 & SD_CRUMBLESTATE) WRITEINT32(put, ss->crumblestate); - - // Special case: save the stats of all modified ffloors along with their ffloor "number"s - // we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed if (diff & SD_FFLOORS) - { - size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc - ffloor_t *rover; - UINT8 fflr_diff; - for (rover = ss->ffloors; rover; rover = rover->next) - { - fflr_diff = 0; // reset diff flags - if (rover->flags != rover->spawnflags) - fflr_diff |= 1; - if (rover->alpha != rover->spawnalpha) - fflr_diff |= 2; - - if (fflr_diff) - { - WRITEUINT16(put, j); // save ffloor "number" - WRITEUINT8(put, fflr_diff); - if (fflr_diff & 1) - WRITEUINT32(put, rover->flags); - if (fflr_diff & 2) - WRITEINT16(put, rover->alpha); - } - j++; - } - WRITEUINT16(put, 0xffff); - } + ArchiveFFloors(put, ss); } } @@ -1114,44 +1164,7 @@ static void P_NetUnArchiveWorld(void) sectors[i].crumblestate = READINT32(get); if (diff & SD_FFLOORS) - { - UINT16 j = 0; // number of current ffloor in loop - UINT16 fflr_i; // saved ffloor "number" of next modified ffloor - UINT16 fflr_diff; // saved ffloor diff - ffloor_t *rover; - - rover = sectors[i].ffloors; - if (!rover) // it is assumed sectors[i].ffloors actually exists, but just in case... - I_Error("Sector does not have any ffloors!"); - - fflr_i = READUINT16(get); // get first modified ffloor's number ready - for (;;) // for some reason the usual for (rover = x; ...) thing doesn't work here? - { - if (fflr_i == 0xffff) // end of modified ffloors list, let's stop already - break; - // should NEVER need to be checked - //if (rover == NULL) - //break; - if (j != fflr_i) // this ffloor was not modified - { - j++; - rover = rover->next; - continue; - } - - fflr_diff = READUINT8(get); - - if (fflr_diff & 1) - rover->flags = READUINT32(get); - if (fflr_diff & 2) - rover->alpha = READINT16(get); - - fflr_i = READUINT16(get); // get next ffloor "number" ready - - j++; - rover = rover->next; - } - } + UnArchiveFFloors(get, sectors[i]); } for (;;) From 2d45decbb0de5964f86c5dfc57f9167b17f3a71a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 24 Apr 2020 20:28:01 +0100 Subject: [PATCH 127/220] remove statsec and statline as they appear to be entirely unused --- src/p_saveg.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 15e11a27b..e5f6cc75d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -867,7 +867,6 @@ static void UnArchiveFFloors(UINT8 *get, sector_t *ss) static void P_NetArchiveWorld(void) { size_t i; - INT32 statsec = 0, statline = 0; const line_t *li = lines; const line_t *spawnli = spawnlines; const side_t *si; @@ -938,8 +937,6 @@ static void P_NetArchiveWorld(void) if (diff) { - statsec++; - WRITEUINT16(put, i); WRITEUINT8(put, diff); if (diff & SD_DIFF2) @@ -1033,7 +1030,6 @@ static void P_NetArchiveWorld(void) if (diff) { - statline++; WRITEINT16(put, i); WRITEUINT8(put, diff); if (diff & LD_DIFF2) From c1d2b8301b064b30ef1f4ac0e7f079fc61b313cb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 24 Apr 2020 20:40:50 +0100 Subject: [PATCH 128/220] split sector/lines archiving-related code into their own functions too --- src/p_saveg.c | 242 +++++++++++++++++++++++++++----------------------- 1 file changed, 133 insertions(+), 109 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index e5f6cc75d..860e3b86a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -861,28 +861,13 @@ static void UnArchiveFFloors(UINT8 *get, sector_t *ss) } } -// -// P_NetArchiveWorld -// -static void P_NetArchiveWorld(void) +static void ArchiveSectors(UINT8 *put) { size_t i; - const line_t *li = lines; - const line_t *spawnli = spawnlines; - const side_t *si; - const side_t *spawnsi; - UINT8 *put; - const sector_t *ss = sectors; const sector_t *spawnss = spawnsectors; UINT8 diff, diff2, diff3; - // initialize colormap vars because paranoia - ClearNetColormaps(); - - WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD); - put = save_p; - for (i = 0; i < numsectors; i++, ss++, spawnss++) { diff = diff2 = diff3 = 0; @@ -986,8 +971,90 @@ static void P_NetArchiveWorld(void) } WRITEUINT16(put, 0xffff); +} + +static void UnArchiveSectors(UINT8 *get) +{ + UINT16 i; + UINT8 diff, diff2, diff3; + for (;;) + { + i = READUINT16(get); + + if (i == 0xffff) + break; + + if (i > numsectors) + I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(numsectors)); + + diff = READUINT8(get); + if (diff & SD_DIFF2) + diff2 = READUINT8(get); + else + diff2 = 0; + if (diff2 & SD_DIFF3) + diff3 = READUINT8(get); + else + diff3 = 0; + + if (diff & SD_FLOORHT) + sectors[i].floorheight = READFIXED(get); + if (diff & SD_CEILHT) + sectors[i].ceilingheight = READFIXED(get); + if (diff & SD_FLOORPIC) + { + sectors[i].floorpic = P_AddLevelFlatRuntime((char *)get); + get += 8; + } + if (diff & SD_CEILPIC) + { + sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)get); + get += 8; + } + if (diff & SD_LIGHT) + sectors[i].lightlevel = READINT16(get); + if (diff & SD_SPECIAL) + sectors[i].special = READINT16(get); + + if (diff2 & SD_FXOFFS) + sectors[i].floor_xoffs = READFIXED(get); + if (diff2 & SD_FYOFFS) + sectors[i].floor_yoffs = READFIXED(get); + if (diff2 & SD_CXOFFS) + sectors[i].ceiling_xoffs = READFIXED(get); + if (diff2 & SD_CYOFFS) + sectors[i].ceiling_yoffs = READFIXED(get); + if (diff2 & SD_FLOORANG) + sectors[i].floorpic_angle = READANGLE(get); + if (diff2 & SD_CEILANG) + sectors[i].ceilingpic_angle = READANGLE(get); + if (diff2 & SD_TAG) + sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag + if (diff3 & SD_TAGLIST) + { + sectors[i].firsttag = READINT32(get); + sectors[i].nexttag = READINT32(get); + } + + if (diff3 & SD_COLORMAP) + sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get)); + if (diff3 & SD_CRUMBLESTATE) + sectors[i].crumblestate = READINT32(get); + + if (diff & SD_FFLOORS) + UnArchiveFFloors(get, sectors[i]); + } +} + +static void ArchiveLines(UINT8 *put) +{ + size_t i; + const line_t *li = lines; + const line_t *spawnli = spawnlines; + const side_t *si; + const side_t *spawnsi; + UINT8 diff, diff2, diff3; - // do lines for (i = 0; i < numlines; i++, spawnli++, li++) { diff = diff2 = diff3 = 0; @@ -1063,106 +1130,15 @@ static void P_NetArchiveWorld(void) } } WRITEUINT16(put, 0xffff); - R_ClearTextureNumCache(false); - - save_p = put; } -// -// P_NetUnArchiveWorld -// -static void P_NetUnArchiveWorld(void) +static void UnArchiveLines(UINT8 *get) { UINT16 i; line_t *li; side_t *si; - UINT8 *get; UINT8 diff, diff2, diff3; - if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD) - I_Error("Bad $$$.sav at archive block World"); - - // initialize colormap vars because paranoia - ClearNetColormaps(); - - // count the level's ffloors so that colormap loading can have an upper limit - for (i = 0; i < numsectors; i++) - { - ffloor_t *rover; - for (rover = sectors[i].ffloors; rover; rover = rover->next) - num_ffloors++; - } - - get = save_p; - - for (;;) - { - i = READUINT16(get); - - if (i == 0xffff) - break; - - if (i > numsectors) - I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(numsectors)); - - diff = READUINT8(get); - if (diff & SD_DIFF2) - diff2 = READUINT8(get); - else - diff2 = 0; - if (diff2 & SD_DIFF3) - diff3 = READUINT8(get); - else - diff3 = 0; - - if (diff & SD_FLOORHT) - sectors[i].floorheight = READFIXED(get); - if (diff & SD_CEILHT) - sectors[i].ceilingheight = READFIXED(get); - if (diff & SD_FLOORPIC) - { - sectors[i].floorpic = P_AddLevelFlatRuntime((char *)get); - get += 8; - } - if (diff & SD_CEILPIC) - { - sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)get); - get += 8; - } - if (diff & SD_LIGHT) - sectors[i].lightlevel = READINT16(get); - if (diff & SD_SPECIAL) - sectors[i].special = READINT16(get); - - if (diff2 & SD_FXOFFS) - sectors[i].floor_xoffs = READFIXED(get); - if (diff2 & SD_FYOFFS) - sectors[i].floor_yoffs = READFIXED(get); - if (diff2 & SD_CXOFFS) - sectors[i].ceiling_xoffs = READFIXED(get); - if (diff2 & SD_CYOFFS) - sectors[i].ceiling_yoffs = READFIXED(get); - if (diff2 & SD_FLOORANG) - sectors[i].floorpic_angle = READANGLE(get); - if (diff2 & SD_CEILANG) - sectors[i].ceilingpic_angle = READANGLE(get); - if (diff2 & SD_TAG) - sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag - if (diff3 & SD_TAGLIST) - { - sectors[i].firsttag = READINT32(get); - sectors[i].nexttag = READINT32(get); - } - - if (diff3 & SD_COLORMAP) - sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get)); - if (diff3 & SD_CRUMBLESTATE) - sectors[i].crumblestate = READINT32(get); - - if (diff & SD_FFLOORS) - UnArchiveFFloors(get, sectors[i]); - } - for (;;) { i = READUINT16(get); @@ -1209,6 +1185,54 @@ static void P_NetUnArchiveWorld(void) if (diff2 & LD_S2MIDTEX) si->midtexture = READINT32(get); } +} + +// +// P_NetArchiveWorld +// +static void P_NetArchiveWorld(void) +{ + UINT8 *put; + + // initialize colormap vars because paranoia + ClearNetColormaps(); + + WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD); + put = save_p; + + ArchiveSectors(put); + ArchiveLines(put); + R_ClearTextureNumCache(false); + + save_p = put; +} + +// +// P_NetUnArchiveWorld +// +static void P_NetUnArchiveWorld(void) +{ + UINT16 i; + UINT8 *get; + + if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD) + I_Error("Bad $$$.sav at archive block World"); + + // initialize colormap vars because paranoia + ClearNetColormaps(); + + // count the level's ffloors so that colormap loading can have an upper limit + for (i = 0; i < numsectors; i++) + { + ffloor_t *rover; + for (rover = sectors[i].ffloors; rover; rover = rover->next) + num_ffloors++; + } + + get = save_p; + + UnArchiveSectors(get); + UnArchiveLines(get); save_p = get; } From 1e61229cb7fe76961a89b18f85f49124b10ab0ef Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 24 Apr 2020 20:57:48 +0100 Subject: [PATCH 129/220] we don't actually need put/get pointers at all (plus with everything put into functions they wouldn't work properly anyway) --- src/p_saveg.c | 202 ++++++++++++++++++++++++-------------------------- 1 file changed, 96 insertions(+), 106 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 860e3b86a..e2bc9dd61 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -794,7 +794,7 @@ static boolean CheckFFloorDiff(sector_t *ss) // Special case: save the stats of all modified ffloors along with their ffloor "number"s // we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed -static void ArchiveFFloors(UINT8 *put, sector_t *ss) +static void ArchiveFFloors(sector_t *ss) { size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc ffloor_t *rover; @@ -809,19 +809,19 @@ static void ArchiveFFloors(UINT8 *put, sector_t *ss) if (fflr_diff) { - WRITEUINT16(put, j); // save ffloor "number" - WRITEUINT8(put, fflr_diff); + WRITEUINT16(save_p, j); // save ffloor "number" + WRITEUINT8(save_p, fflr_diff); if (fflr_diff & FD_FLAGS) - WRITEUINT32(put, rover->flags); + WRITEUINT32(save_p, rover->flags); if (fflr_diff & FD_ALPHA) - WRITEINT16(put, rover->alpha); + WRITEINT16(save_p, rover->alpha); } j++; } - WRITEUINT16(put, 0xffff); + WRITEUINT16(save_p, 0xffff); } -static void UnArchiveFFloors(UINT8 *get, sector_t *ss) +static void UnArchiveFFloors(sector_t *ss) { UINT16 j = 0; // number of current ffloor in loop UINT16 fflr_i; // saved ffloor "number" of next modified ffloor @@ -832,7 +832,7 @@ static void UnArchiveFFloors(UINT8 *get, sector_t *ss) if (!rover) // it is assumed sectors[i].ffloors actually exists, but just in case... I_Error("Sector does not have any ffloors!"); - fflr_i = READUINT16(get); // get first modified ffloor's number ready + fflr_i = READUINT16(save_p); // get first modified ffloor's number ready for (;;) // for some reason the usual for (rover = x; ...) thing doesn't work here? { if (fflr_i == 0xffff) // end of modified ffloors list, let's stop already @@ -847,21 +847,21 @@ static void UnArchiveFFloors(UINT8 *get, sector_t *ss) continue; } - fflr_diff = READUINT8(get); + fflr_diff = READUINT8(save_p); if (fflr_diff & FD_FLAGS) - rover->flags = READUINT32(get); + rover->flags = READUINT32(save_p); if (fflr_diff & FD_ALPHA) - rover->alpha = READINT16(get); + rover->alpha = READINT16(save_p); - fflr_i = READUINT16(get); // get next ffloor "number" ready + fflr_i = READUINT16(save_p); // get next ffloor "number" ready j++; rover = rover->next; } } -static void ArchiveSectors(UINT8 *put) +static void ArchiveSectors(void) { size_t i; const sector_t *ss = sectors; @@ -922,64 +922,64 @@ static void ArchiveSectors(UINT8 *put) if (diff) { - WRITEUINT16(put, i); - WRITEUINT8(put, diff); + WRITEUINT16(save_p, i); + WRITEUINT8(save_p, diff); if (diff & SD_DIFF2) - WRITEUINT8(put, diff2); + WRITEUINT8(save_p, diff2); if (diff2 & SD_DIFF3) - WRITEUINT8(put, diff3); + WRITEUINT8(save_p, diff3); if (diff & SD_FLOORHT) - WRITEFIXED(put, ss->floorheight); + WRITEFIXED(save_p, ss->floorheight); if (diff & SD_CEILHT) - WRITEFIXED(put, ss->ceilingheight); + WRITEFIXED(save_p, ss->ceilingheight); if (diff & SD_FLOORPIC) - WRITEMEM(put, levelflats[ss->floorpic].name, 8); + WRITEMEM(save_p, levelflats[ss->floorpic].name, 8); if (diff & SD_CEILPIC) - WRITEMEM(put, levelflats[ss->ceilingpic].name, 8); + WRITEMEM(save_p, levelflats[ss->ceilingpic].name, 8); if (diff & SD_LIGHT) - WRITEINT16(put, ss->lightlevel); + WRITEINT16(save_p, ss->lightlevel); if (diff & SD_SPECIAL) - WRITEINT16(put, ss->special); + WRITEINT16(save_p, ss->special); if (diff2 & SD_FXOFFS) - WRITEFIXED(put, ss->floor_xoffs); + WRITEFIXED(save_p, ss->floor_xoffs); if (diff2 & SD_FYOFFS) - WRITEFIXED(put, ss->floor_yoffs); + WRITEFIXED(save_p, ss->floor_yoffs); if (diff2 & SD_CXOFFS) - WRITEFIXED(put, ss->ceiling_xoffs); + WRITEFIXED(save_p, ss->ceiling_xoffs); if (diff2 & SD_CYOFFS) - WRITEFIXED(put, ss->ceiling_yoffs); + WRITEFIXED(save_p, ss->ceiling_yoffs); if (diff2 & SD_FLOORANG) - WRITEANGLE(put, ss->floorpic_angle); + WRITEANGLE(save_p, ss->floorpic_angle); if (diff2 & SD_CEILANG) - WRITEANGLE(put, ss->ceilingpic_angle); + WRITEANGLE(save_p, ss->ceilingpic_angle); if (diff2 & SD_TAG) // save only the tag - WRITEINT16(put, ss->tag); + WRITEINT16(save_p, ss->tag); if (diff3 & SD_TAGLIST) // save both firsttag and nexttag { // either of these could be changed even if tag isn't - WRITEINT32(put, ss->firsttag); - WRITEINT32(put, ss->nexttag); + WRITEINT32(save_p, ss->firsttag); + WRITEINT32(save_p, ss->nexttag); } if (diff3 & SD_COLORMAP) - WRITEUINT32(put, CheckAddNetColormapToList(ss->extra_colormap)); + WRITEUINT32(save_p, CheckAddNetColormapToList(ss->extra_colormap)); // returns existing index if already added, or appends to net_colormaps and returns new index if (diff3 & SD_CRUMBLESTATE) - WRITEINT32(put, ss->crumblestate); + WRITEINT32(save_p, ss->crumblestate); if (diff & SD_FFLOORS) - ArchiveFFloors(put, ss); + ArchiveFFloors(save_p, ss); } } - WRITEUINT16(put, 0xffff); + WRITEUINT16(save_p, 0xffff); } -static void UnArchiveSectors(UINT8 *get) +static void UnArchiveSectors(void) { UINT16 i; UINT8 diff, diff2, diff3; for (;;) { - i = READUINT16(get); + i = READUINT16(save_p); if (i == 0xffff) break; @@ -987,66 +987,66 @@ static void UnArchiveSectors(UINT8 *get) if (i > numsectors) I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(numsectors)); - diff = READUINT8(get); + diff = READUINT8(save_p); if (diff & SD_DIFF2) - diff2 = READUINT8(get); + diff2 = READUINT8(save_p); else diff2 = 0; if (diff2 & SD_DIFF3) - diff3 = READUINT8(get); + diff3 = READUINT8(save_p); else diff3 = 0; if (diff & SD_FLOORHT) - sectors[i].floorheight = READFIXED(get); + sectors[i].floorheight = READFIXED(save_p); if (diff & SD_CEILHT) - sectors[i].ceilingheight = READFIXED(get); + sectors[i].ceilingheight = READFIXED(save_p); if (diff & SD_FLOORPIC) { - sectors[i].floorpic = P_AddLevelFlatRuntime((char *)get); - get += 8; + sectors[i].floorpic = P_AddLevelFlatRuntime((char *)save_p); + save_p += 8; } if (diff & SD_CEILPIC) { - sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)get); - get += 8; + sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)save_p); + save_p += 8; } if (diff & SD_LIGHT) - sectors[i].lightlevel = READINT16(get); + sectors[i].lightlevel = READINT16(save_p); if (diff & SD_SPECIAL) - sectors[i].special = READINT16(get); + sectors[i].special = READINT16(save_p); if (diff2 & SD_FXOFFS) - sectors[i].floor_xoffs = READFIXED(get); + sectors[i].floor_xoffs = READFIXED(save_p); if (diff2 & SD_FYOFFS) - sectors[i].floor_yoffs = READFIXED(get); + sectors[i].floor_yoffs = READFIXED(save_p); if (diff2 & SD_CXOFFS) - sectors[i].ceiling_xoffs = READFIXED(get); + sectors[i].ceiling_xoffs = READFIXED(save_p); if (diff2 & SD_CYOFFS) - sectors[i].ceiling_yoffs = READFIXED(get); + sectors[i].ceiling_yoffs = READFIXED(save_p); if (diff2 & SD_FLOORANG) - sectors[i].floorpic_angle = READANGLE(get); + sectors[i].floorpic_angle = READANGLE(save_p); if (diff2 & SD_CEILANG) - sectors[i].ceilingpic_angle = READANGLE(get); + sectors[i].ceilingpic_angle = READANGLE(save_p); if (diff2 & SD_TAG) - sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag + sectors[i].tag = READINT16(save_p); // DON'T use P_ChangeSectorTag if (diff3 & SD_TAGLIST) { - sectors[i].firsttag = READINT32(get); - sectors[i].nexttag = READINT32(get); + sectors[i].firsttag = READINT32(save_p); + sectors[i].nexttag = READINT32(save_p); } if (diff3 & SD_COLORMAP) - sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get)); + sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(save_p)); if (diff3 & SD_CRUMBLESTATE) - sectors[i].crumblestate = READINT32(get); + sectors[i].crumblestate = READINT32(save_p); if (diff & SD_FFLOORS) - UnArchiveFFloors(get, sectors[i]); + UnArchiveFFloors(save_p, sectors[i]); } } -static void ArchiveLines(UINT8 *put) +static void ArchiveLines(void) { size_t i; const line_t *li = lines; @@ -1097,42 +1097,42 @@ static void ArchiveLines(UINT8 *put) if (diff) { - WRITEINT16(put, i); - WRITEUINT8(put, diff); + WRITEINT16(save_p, i); + WRITEUINT8(save_p, diff); if (diff & LD_DIFF2) - WRITEUINT8(put, diff2); + WRITEUINT8(save_p, diff2); if (diff & LD_FLAG) - WRITEINT16(put, li->flags); + WRITEINT16(save_p, li->flags); if (diff & LD_SPECIAL) - WRITEINT16(put, li->special); + WRITEINT16(save_p, li->special); if (diff & LD_CLLCOUNT) - WRITEINT16(put, li->callcount); + WRITEINT16(save_p, li->callcount); si = &sides[li->sidenum[0]]; if (diff & LD_S1TEXOFF) - WRITEFIXED(put, si->textureoffset); + WRITEFIXED(save_p, si->textureoffset); if (diff & LD_S1TOPTEX) - WRITEINT32(put, si->toptexture); + WRITEINT32(save_p, si->toptexture); if (diff & LD_S1BOTTEX) - WRITEINT32(put, si->bottomtexture); + WRITEINT32(save_p, si->bottomtexture); if (diff & LD_S1MIDTEX) - WRITEINT32(put, si->midtexture); + WRITEINT32(save_p, si->midtexture); si = &sides[li->sidenum[1]]; if (diff2 & LD_S2TEXOFF) - WRITEFIXED(put, si->textureoffset); + WRITEFIXED(save_p, si->textureoffset); if (diff2 & LD_S2TOPTEX) - WRITEINT32(put, si->toptexture); + WRITEINT32(save_p, si->toptexture); if (diff2 & LD_S2BOTTEX) - WRITEINT32(put, si->bottomtexture); + WRITEINT32(save_p, si->bottomtexture); if (diff2 & LD_S2MIDTEX) - WRITEINT32(put, si->midtexture); + WRITEINT32(save_p, si->midtexture); } } - WRITEUINT16(put, 0xffff); + WRITEUINT16(save_p, 0xffff); } -static void UnArchiveLines(UINT8 *get) +static void UnArchiveLines(void) { UINT16 i; line_t *li; @@ -1141,49 +1141,49 @@ static void UnArchiveLines(UINT8 *get) for (;;) { - i = READUINT16(get); + i = READUINT16(save_p); if (i == 0xffff) break; if (i > numlines) I_Error("Invalid line number %u from server", i); - diff = READUINT8(get); + diff = READUINT8(save_p); li = &lines[i]; if (diff & LD_DIFF2) - diff2 = READUINT8(get); + diff2 = READUINT8(save_p); else diff2 = 0; diff3 = 0; if (diff & LD_FLAG) - li->flags = READINT16(get); + li->flags = READINT16(save_p); if (diff & LD_SPECIAL) - li->special = READINT16(get); + li->special = READINT16(save_p); if (diff & LD_CLLCOUNT) - li->callcount = READINT16(get); + li->callcount = READINT16(save_p); si = &sides[li->sidenum[0]]; if (diff & LD_S1TEXOFF) - si->textureoffset = READFIXED(get); + si->textureoffset = READFIXED(save_p); if (diff & LD_S1TOPTEX) - si->toptexture = READINT32(get); + si->toptexture = READINT32(save_p); if (diff & LD_S1BOTTEX) - si->bottomtexture = READINT32(get); + si->bottomtexture = READINT32(save_p); if (diff & LD_S1MIDTEX) - si->midtexture = READINT32(get); + si->midtexture = READINT32(save_p); si = &sides[li->sidenum[1]]; if (diff2 & LD_S2TEXOFF) - si->textureoffset = READFIXED(get); + si->textureoffset = READFIXED(save_p); if (diff2 & LD_S2TOPTEX) - si->toptexture = READINT32(get); + si->toptexture = READINT32(save_p); if (diff2 & LD_S2BOTTEX) - si->bottomtexture = READINT32(get); + si->bottomtexture = READINT32(save_p); if (diff2 & LD_S2MIDTEX) - si->midtexture = READINT32(get); + si->midtexture = READINT32(save_p); } } @@ -1192,19 +1192,14 @@ static void UnArchiveLines(UINT8 *get) // static void P_NetArchiveWorld(void) { - UINT8 *put; - // initialize colormap vars because paranoia ClearNetColormaps(); WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD); - put = save_p; - ArchiveSectors(put); - ArchiveLines(put); + ArchiveSectors(); + ArchiveLines(); R_ClearTextureNumCache(false); - - save_p = put; } // @@ -1213,7 +1208,6 @@ static void P_NetArchiveWorld(void) static void P_NetUnArchiveWorld(void) { UINT16 i; - UINT8 *get; if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD) I_Error("Bad $$$.sav at archive block World"); @@ -1229,12 +1223,8 @@ static void P_NetUnArchiveWorld(void) num_ffloors++; } - get = save_p; - - UnArchiveSectors(get); - UnArchiveLines(get); - - save_p = get; + UnArchiveSectors(); + UnArchiveLines(); } // From e406a7bef5b029dc49b8861f89557644f8649c2c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 24 Apr 2020 20:58:38 +0100 Subject: [PATCH 130/220] no diff3 needed for line archiving --- src/p_saveg.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index e2bc9dd61..541b42426 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1053,11 +1053,11 @@ static void ArchiveLines(void) const line_t *spawnli = spawnlines; const side_t *si; const side_t *spawnsi; - UINT8 diff, diff2, diff3; + UINT8 diff, diff2; // no diff3 for (i = 0; i < numlines; i++, spawnli++, li++) { - diff = diff2 = diff3 = 0; + diff = diff2 = 0; if (li->special != spawnli->special) diff |= LD_SPECIAL; @@ -1137,7 +1137,7 @@ static void UnArchiveLines(void) UINT16 i; line_t *li; side_t *si; - UINT8 diff, diff2, diff3; + UINT8 diff, diff2; // no diff3 for (;;) { @@ -1156,8 +1156,6 @@ static void UnArchiveLines(void) else diff2 = 0; - diff3 = 0; - if (diff & LD_FLAG) li->flags = READINT16(save_p); if (diff & LD_SPECIAL) From 7dda5f6b946079925e86f83325c0889a16e842d3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 24 Apr 2020 22:29:41 +0100 Subject: [PATCH 131/220] created P_GetFFloorID to get an "ID" of an FOF in its target sector (an opposite to P_GetFFloorByID you could say!), rewrote floor/ceiling rover archiving code to use both P_GetFFloorID and P_GetFFloorByID --- src/p_saveg.c | 66 ++++++++------------------------------------------- src/p_spec.c | 31 +++++++++++++++++++++++- src/p_spec.h | 1 + 3 files changed, 41 insertions(+), 57 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 541b42426..e63409386 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1518,42 +1518,14 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (diff2 & MD2_FLOORROVER) { - ffloor_t *rover; - size_t i = 0; - UINT32 roverindex = 0; - - for (rover = mobj->floorrover->target->ffloors; rover; rover = rover->next) - { - if (rover == mobj->floorrover) - { - roverindex = i; - break; - } - i++; - } - - WRITEUINT32(save_p, (UINT32)(mobj->floorrover->target - sectors)); - WRITEUINT32(save_p, rover ? roverindex : i); // store max index to denote invalid ffloor ref + WRITEUINT32(save_p, SaveSector(mobj->floorrover->target)); + WRITEUINT16(save_p, P_GetFFloorID(mobj->floorrover)); } if (diff2 & MD2_CEILINGROVER) { - ffloor_t *rover; - size_t i = 0; - UINT32 roverindex = 0; - - for (rover = mobj->ceilingrover->target->ffloors; rover; rover = rover->next) - { - if (rover == mobj->ceilingrover) - { - roverindex = i; - break; - } - i++; - } - - WRITEUINT32(save_p, (UINT32)(mobj->ceilingrover->target - sectors)); - WRITEUINT32(save_p, rover ? roverindex : i); // store max index to denote invalid ffloor ref + WRITEUINT32(save_p, SaveSector(mobj->ceilingrover->target)); + WRITEUINT16(save_p, P_GetFFloorID(mobj->ceilingrover)); } if (diff & MD_SPAWNPOINT) @@ -2634,34 +2606,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff2 & MD2_FLOORROVER) { - size_t floor_sectornum = (size_t)READUINT32(save_p); - size_t floor_rovernum = (size_t)READUINT32(save_p); - ffloor_t *rover = NULL; - size_t rovernum = 0; - - for (rover = sectors[floor_sectornum].ffloors; rover; rover = rover->next) - { - if (rovernum == floor_rovernum) - break; - rovernum++; - } - floorrover = rover; + sector_t *sec = LoadSector(READUINT32(save_p)); + UINT16 id = READUINT16(save_p); + floorrover = P_GetFFloorByID(sec, id); } if (diff2 & MD2_CEILINGROVER) { - size_t ceiling_sectornum = (size_t)READUINT32(save_p); - size_t ceiling_rovernum = (size_t)READUINT32(save_p); - ffloor_t *rover = NULL; - size_t rovernum = 0; - - for (rover = sectors[ceiling_sectornum].ffloors; rover; rover = rover->next) - { - if (rovernum == ceiling_rovernum) - break; - rovernum++; - } - ceilingrover = rover; + sector_t *sec = LoadSector(READUINT32(save_p)); + UINT16 id = READUINT16(save_p); + ceilingrover = P_GetFFloorByID(sec, id); } if (diff & MD_SPAWNPOINT) diff --git a/src/p_spec.c b/src/p_spec.c index 6456cc514..96ae5522b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5678,6 +5678,35 @@ void P_UpdateSpecials(void) } } +// +// Floor over floors (FOFs), 3Dfloors, 3Dblocks, fake floors (ffloors), rovers, or whatever you want to call them +// + +/** Gets the ID number for a 3Dfloor in its target sector. + * + * \param fflr The 3Dfloor we want an ID for. + * \return ID of 3Dfloor in target sector. Note that the first FOF's ID is 0. UINT16_MAX is given if invalid. + * \sa P_GetFFloorByID + */ +UINT16 P_GetFFloorID(ffloor_t *fflr) +{ + ffloor_t *rover; + sector_t *sec; + UINT16 i = 0; + + if (!rover) + return UINT16_MAX; + + sec = rover->target; + + if (!sec->ffloors) + return UINT16_MAX; + for (rover = sec->ffloors; rover; rover = rover->next, i++) + if (rover == fflr) + return i; + return UINT16_MAX; +} + /** Gets a 3Dfloor by control sector. * * \param sec Target sector. @@ -5702,7 +5731,7 @@ static inline ffloor_t *P_GetFFloorBySec(sector_t *sec, sector_t *sec2) * \param sec Target sector. * \param id ID of 3Dfloor in target sector. Note that the first FOF's ID is 0. * \return Pointer to found 3Dfloor, or NULL. - * \sa P_GetFFloorBySec + * \sa P_GetFFloorBySec, P_GetFFloorID */ ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id) { diff --git a/src/p_spec.h b/src/p_spec.h index e243e3a61..8e778b9ed 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -74,6 +74,7 @@ void P_RunDeNightserizeExecutors(mobj_t *actor); void P_RunNightsLapExecutors(mobj_t *actor); void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres); +UINT16 P_GetFFloorID(ffloor_t *fflr); ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id); // From 49cceda15bce75c0c54301c8747e413ee3f436e0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 24 Apr 2020 22:43:23 +0100 Subject: [PATCH 132/220] Do the same with writing ARCH_FFLOOR values in Lua archiving code (reading was already dealt with years ago) --- src/lua_script.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 7adf62fcc..6b7b122f0 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1010,16 +1010,8 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) if (!rover) WRITEUINT8(save_p, ARCH_NULL); else { - ffloor_t *r2; - UINT16 i = 0; - // search for id - for (r2 = rover->target->ffloors; r2; r2 = r2->next) - { - if (r2 == rover) - break; - i++; - } - if (!r2) + UINT16 i = P_GetFFloorID(rover); + if (i == UINT16_MAX) // invalid ID WRITEUINT8(save_p, ARCH_NULL); else { From 3cd8f62ae984120989c7b6685550112aa674b397 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 25 Apr 2020 08:18:48 +0200 Subject: [PATCH 133/220] Remove a line I overlooked in the thinker cleanup branch --- src/p_spec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 6456cc514..826260d3a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6863,7 +6863,6 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 153: // Dynamic Sinking Platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - lines[i].flags |= ML_BLOCKMONSTERS; P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); break; From 049a7db877ce52b08981137ea435f2cb3c3df361 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 25 Apr 2020 16:52:11 +0100 Subject: [PATCH 134/220] whoops --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 96ae5522b..f15741479 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5694,7 +5694,7 @@ UINT16 P_GetFFloorID(ffloor_t *fflr) sector_t *sec; UINT16 i = 0; - if (!rover) + if (!fflr) return UINT16_MAX; sec = rover->target; From 7034e2537a9db7024b26dc85b78a93c8fe1eb728 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 25 Apr 2020 16:53:52 +0100 Subject: [PATCH 135/220] whoops the sequel --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index f15741479..e84619c7f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5697,7 +5697,7 @@ UINT16 P_GetFFloorID(ffloor_t *fflr) if (!fflr) return UINT16_MAX; - sec = rover->target; + sec = fflr->target; if (!sec->ffloors) return UINT16_MAX; From 212358dbba7f2e5e47ac12c3a3d6f705ba027d60 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 26 Apr 2020 00:39:52 +0200 Subject: [PATCH 136/220] Restore old entry searching functions and add alternate versions for long names --- src/lua_hudlib.c | 6 +-- src/w_wad.c | 120 +++++++++++++++++++++++++++++++++++++++++++++-- src/w_wad.h | 4 ++ 3 files changed, 124 insertions(+), 6 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 818e760c9..703b924bb 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -412,9 +412,9 @@ static int libd_cachePatch(lua_State *L) HUDONLY luapat = patchinfohead; - lumpnum = W_CheckNumForName(luaL_checkstring(L, 1)); + lumpnum = W_CheckNumForLongName(luaL_checkstring(L, 1)); if (lumpnum == LUMPERROR) - lumpnum = W_GetNumForName("MISSING"); + lumpnum = W_GetNumForLongName("MISSING"); for (i = 0; i < numluapatches; i++) { @@ -454,7 +454,7 @@ static int libd_cachePatch(lua_State *L) numluapatches++; #else HUDONLY - LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); + LUA_PushUserdata(L, W_CachePatchLongName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); #endif return 1; } diff --git a/src/w_wad.c b/src/w_wad.c index f273753c8..a81132354 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -920,6 +920,40 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum) // 'startlump' is the lump number to start the search // UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) +{ + UINT16 i; + static char uname[8 + 1]; + + if (!TestValidLump(wad,0)) + return INT16_MAX; + + strlcpy(uname, name, sizeof uname); + strupr(uname); + + // + // scan forward + // start at 'startlump', useful parameter when there are multiple + // resources with the same name + // + if (startlump < wadfiles[wad]->numlumps) + { + lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; + for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) + if (!strncmp(lump_p->name, uname, sizeof(uname) - 1)) + return i; + } + + // not found. + return INT16_MAX; +} + +// +// Like W_CheckNumForNamePwad, but can find entries with long names +// +// Should be the only version, but that's not possible until we fix +// all the instances of non null-terminated strings in the codebase... +// +UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump) { UINT16 i; static char uname[256 + 1]; @@ -1025,7 +1059,8 @@ lumpnum_t W_CheckNumForName(const char *name) // most recent entries first for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) { - if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0) + if (!lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8] + && strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0) { lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1); return lumpnumcache[lumpnumcacheindex].lumpnum; @@ -1045,13 +1080,63 @@ lumpnum_t W_CheckNumForName(const char *name) { // Update the cache. lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1); - strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32); + memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32); + strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8); lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check; return lumpnumcache[lumpnumcacheindex].lumpnum; } } +// +// Like W_CheckNumForName, but can find entries with long names +// +// Should be the only version, but that's not possible until we fix +// all the instances of non null-terminated strings in the codebase... +// +lumpnum_t W_CheckNumForLongName(const char *name) +{ + INT32 i; + lumpnum_t check = INT16_MAX; + + if (!*name) // some doofus gave us an empty string? + return LUMPERROR; + + // Check the lumpnumcache first. Loop backwards so that we check + // most recent entries first + for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--) + { + if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0) + { + lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1); + return lumpnumcache[lumpnumcacheindex].lumpnum; + } + } + + // scan wad files backwards so patch lump files take precedence + for (i = numwadfiles - 1; i >= 0; i--) + { + check = W_CheckNumForLongNamePwad(name,(UINT16)i,0); + if (check != INT16_MAX) + break; //found it + } + + if (check == INT16_MAX) return LUMPERROR; + else + { + if (strlen(name) < 32) + { + // Update the cache. + lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1); + memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32); + strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32); + lumpnumcache[lumpnumcacheindex].lumpnum = (i << 16) + check; + } + + return (i << 16) + check; + } +} + // Look for valid map data through all added files in descendant order. // Get a map marker for WADs, and a standalone WAD file lump inside PK3s. // TODO: Make it search through cache first, maybe...? @@ -1100,6 +1185,24 @@ lumpnum_t W_GetNumForName(const char *name) return i; } +// +// Like W_GetNumForName, but can find entries with long names +// +// Should be the only version, but that's not possible until we fix +// all the instances of non null-terminated strings in the codebase... +// +lumpnum_t W_GetNumForLongName(const char *name) +{ + lumpnum_t i; + + i = W_CheckNumForLongName(name); + + if (i == LUMPERROR) + I_Error("W_GetNumForLongName: %s not found!\n", name); + + return i; +} + // // W_CheckNumForNameInBlock // Checks only in blocks from blockstart lump to blockend lump @@ -1139,7 +1242,7 @@ UINT8 W_LumpExists(const char *name) { lumpinfo_t *lump_p = wadfiles[i]->lumpinfo; for (j = 0; j < wadfiles[i]->numlumps; ++j, ++lump_p) - if (fastcmp(lump_p->name,name)) + if (fastcmp(lump_p->longname, name)) return true; } return false; @@ -1680,6 +1783,17 @@ void *W_CachePatchName(const char *name, INT32 tag) return W_CachePatchNum(W_GetNumForName("MISSING"), tag); return W_CachePatchNum(num, tag); } + +void *W_CachePatchLongName(const char *name, INT32 tag) +{ + lumpnum_t num; + + num = W_CheckNumForLongName(name); + + if (num == LUMPERROR) + return W_CachePatchNum(W_GetNumForLongName("MISSING"), tag); + return W_CachePatchNum(num, tag); +} #ifndef NOMD5 #define MD5_LEN 16 diff --git a/src/w_wad.h b/src/w_wad.h index 3af6148f4..88b542fca 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -156,6 +156,7 @@ const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump); const char *W_CheckNameForNum(lumpnum_t lumpnum); UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad +UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump); /* Find the first lump after F_START for instance. */ UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlump); @@ -166,7 +167,9 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump) lumpnum_t W_CheckNumForMap(const char *name); lumpnum_t W_CheckNumForName(const char *name); +lumpnum_t W_CheckNumForLongName(const char *name); lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR +lumpnum_t W_GetNumForLongName(const char *name); lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend); UINT8 W_LumpExists(const char *name); // Lua uses this. @@ -194,6 +197,7 @@ boolean W_IsPatchCached(lumpnum_t lump, void *ptr); void *W_CacheLumpName(const char *name, INT32 tag); void *W_CachePatchName(const char *name, INT32 tag); +void *W_CachePatchLongName(const char *name, INT32 tag); // Returns either a Software patch, or an OpenGL patch. // Performs any necessary conversions from PNG images. From 2e27f32d3e3c7de727867fa0c25f75f0c9ebe698 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 26 Apr 2020 00:42:17 +0200 Subject: [PATCH 137/220] Replace a few instance of strncpy with strlcpy --- src/dehacked.c | 6 ++---- src/f_finale.c | 4 ++-- src/m_menu.c | 14 +++++++------- src/m_menu.h | 2 +- src/p_setup.c | 4 +--- src/r_data.c | 5 ++--- src/v_video.c | 2 +- src/w_wad.c | 8 +++----- src/y_inter.c | 5 ++--- 9 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e9d029be0..fbd42dee1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -419,7 +419,7 @@ static void readPlayer(MYFILE *f, INT32 num) if (fastcmp(word, "PICNAME")) { SLOTFOUND - strncpy(description[num].picname, word2, 8); + strlcpy(description[num].picname, word2, sizeof(description->picname)); } // new character select else if (fastcmp(word, "DISPLAYNAME")) @@ -3889,9 +3889,7 @@ static void readmaincfg(MYFILE *f) lumpnum_t lumpnum; char newname[9]; - strncpy(newname, word2, 8); - - newname[8] = '\0'; + strlcpy(newname, word2, sizeof(newname)); lumpnum = W_CheckNumForName(newname); diff --git a/src/f_finale.c b/src/f_finale.c index 825f646b0..abef1da69 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2338,7 +2338,7 @@ void F_InitMenuPresValues(void) activeMenuId = MainDef.menuid; // Set defaults for presentation values - strncpy(curbgname, "TITLESKY", 9); + strlcpy(curbgname, "TITLESKY", sizeof(curbgname)); curfadevalue = 16; curbgcolor = -1; curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; @@ -2348,7 +2348,7 @@ void F_InitMenuPresValues(void) curhidepics = hidetitlepics; curttmode = ttmode; curttscale = ttscale; - strncpy(curttname, ttname, 9); + strlcpy(curttname, ttname, sizeof(curttname)); curttx = ttx; curtty = tty; curttloop = ttloop; diff --git a/src/m_menu.c b/src/m_menu.c index 1069f0f30..e510f582a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2615,7 +2615,7 @@ static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval, } else if (menupres[menutype].bgname[0]) { - strncpy(curbgname, menupres[menutype].bgname, 8); + strlcpy(curbgname, menupres[menutype].bgname, sizeof(curbgname)); curbgxspeed = menupres[menutype].titlescrollxspeed != INT32_MAX ? menupres[menutype].titlescrollxspeed : titlescrollxspeed; curbgyspeed = menupres[menutype].titlescrollyspeed != INT32_MAX ? menupres[menutype].titlescrollyspeed : titlescrollyspeed; return true; @@ -2628,7 +2628,7 @@ static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval, curbghide = true; else { - strncpy(curbgname, defaultname, 9); + strlcpy(curbgname, defaultname, sizeof(curbgname)); curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; curbgyspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollyspeed; } @@ -2767,7 +2767,7 @@ void M_ChangeMenuMusic(const char *defaultmusname, boolean defaultmuslooping) void M_SetMenuCurBackground(const char *defaultname) { char name[9]; - strncpy(name, defaultname, 8); + strlcpy(name, defaultname, 9); M_IterateMenuTree(MIT_SetCurBackground, &name); } @@ -2820,7 +2820,7 @@ static void M_HandleMenuPresState(menu_t *newMenu) activeMenuId = newMenu ? newMenu->menuid : 0; // Set defaults for presentation values - strncpy(curbgname, "TITLESKY", 9); + strlcpy(curbgname, "TITLESKY", sizeof(curbgname)); curfadevalue = 16; curhidepics = hidetitlepics; curbgcolor = -1; @@ -5785,7 +5785,7 @@ static void M_DrawLevelPlatterMenu(void) { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); // Draw and animate foreground - if (!strncmp("RECATKBG", curbgname, 8)) + if (!strcmp("RECATKBG", curbgname)) M_DrawRecordAttackForeground(); } @@ -6033,7 +6033,7 @@ static void M_DrawMessageMenu(void) else { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); - if (!strncmp("RECATKBG", curbgname, 8)) + if (!strcmp("RECATKBG", curbgname)) M_DrawRecordAttackForeground(); } } @@ -9583,7 +9583,7 @@ void M_DrawTimeAttackMenu(void) { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); // Draw and animate foreground - if (!strncmp("RECATKBG", curbgname, 8)) + if (!strcmp("RECATKBG", curbgname)) M_DrawRecordAttackForeground(); } if (curfadevalue) diff --git a/src/m_menu.h b/src/m_menu.h index eeda9cc58..0658f38da 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -340,7 +340,7 @@ typedef struct { boolean used; char notes[441]; - char picname[8]; + char picname[9]; char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 patch_t *charpic; UINT8 prev; diff --git a/src/p_setup.c b/src/p_setup.c index 8c73b85e6..61a49d958 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2883,9 +2883,7 @@ static void P_RunLevelScript(const char *scriptname) lumpnum_t lumpnum; char newname[9]; - strncpy(newname, scriptname, 8); - - newname[8] = '\0'; + strlcpy(newname, scriptname, sizeof(newname)); lumpnum = W_CheckNumForName(newname); diff --git a/src/r_data.c b/src/r_data.c index 831e75bef..c542bbd98 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -2603,7 +2603,7 @@ INT32 R_CheckTextureNumForName(const char *name) return 0; for (i = 0; i < tidcachelen; i++) - if (!strncasecmp(tidcache[i].name, name, 8)) + if (!strcasecmp(tidcache[i].name, name)) return tidcache[i].id; // Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier @@ -2613,8 +2613,7 @@ INT32 R_CheckTextureNumForName(const char *name) { tidcachelen++; Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache); - strncpy(tidcache[tidcachelen-1].name, name, 8); - tidcache[tidcachelen-1].name[8] = '\0'; + strlcpy(tidcache[tidcachelen-1].name, name, sizeof(tidcache->name)); #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name); #endif diff --git a/src/v_video.c b/src/v_video.c index 2d1014c23..e03d0a60d 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -391,7 +391,7 @@ const char *R_GetPalname(UINT16 num) if (num > 0 && num <= 10000) snprintf(newpal, 8, "PAL%04u", num-1); - strncpy(palname, newpal, 8); + strlcpy(palname, newpal, sizeof(palname)); return palname; } diff --git a/src/w_wad.c b/src/w_wad.c index a81132354..267f06198 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -440,17 +440,15 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen else lump_p->compression = CM_NOCOMPRESSION; memset(lump_p->name, 0x00, 9); - strncpy(lump_p->name, fileinfo->name, 8); + strlcpy(lump_p->name, fileinfo->name, 9); // Allocate the lump's long name. lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); - strncpy(lump_p->longname, fileinfo->name, 8); - lump_p->longname[8] = '\0'; + strlcpy(lump_p->longname, fileinfo->name, 9); // Allocate the lump's full name. lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); - strncpy(lump_p->fullname, fileinfo->name, 8); - lump_p->fullname[8] = '\0'; + strlcpy(lump_p->fullname, fileinfo->name, 9); } free(fileinfov); *nlmp = numlumps; diff --git a/src/y_inter.c b/src/y_inter.c index f1764a816..ce57bef9e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1740,9 +1740,8 @@ static void Y_CalculateCompetitionWinners(void) data.competition.monitors[data.competition.numplayers] = monitors[winner]; data.competition.scores[data.competition.numplayers] = scores[winner]; - strncpy(tempname, player_names[winner], 8); - tempname[8] = '\0'; - strncpy(data.competition.name[data.competition.numplayers], tempname, 9); + strlcpy(tempname, player_names[winner], 9); + strlcpy(data.competition.name[data.competition.numplayers], tempname, 9); data.competition.color[data.competition.numplayers] = &players[winner].skincolor; data.competition.character[data.competition.numplayers] = &players[winner].skin; From 295ed303af137464c995efe165d8767d22f89859 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 26 Apr 2020 11:55:10 +0200 Subject: [PATCH 138/220] Make T_StartCrumble use its own thinker data structure --- src/p_floor.c | 175 +++++++++++++++++++++++++------------------------- src/p_map.c | 4 +- src/p_saveg.c | 59 ++++++++++++++++- src/p_spec.h | 20 +++++- 4 files changed, 164 insertions(+), 94 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 179cf73c7..d0fef319c 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -757,7 +757,7 @@ void T_BounceCheese(bouncecheese_t *bouncer) // T_StartCrumble //////////////////////////////// ////////////////////////////////////////////////// // Crumbling platform Tails 03-11-2002 -void T_StartCrumble(elevator_t *elevator) +void T_StartCrumble(crumble_t *crumble) { ffloor_t *rover; sector_t *sector; @@ -765,42 +765,42 @@ void T_StartCrumble(elevator_t *elevator) // Once done, the no-return thinker just sits there, // constantly 'returning'... kind of an oxymoron, isn't it? - if (((elevator->floordestheight == 1 && elevator->direction == -1) - || (elevator->floordestheight == 0 && elevator->direction == 1)) - && elevator->type == elevateContinuous) // No return crumbler + if (((crumble->floordestheight == 1 && crumble->direction == -1) + || (crumble->floordestheight == 0 && crumble->direction == 1)) + && crumble->type == elevateContinuous) // No return crumbler { - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; return; } - if (elevator->distance != 0) + if (crumble->distance != 0) { - if (elevator->distance > 0) // Count down the timer + if (crumble->distance > 0) // Count down the timer { - elevator->distance--; - if (elevator->distance <= 0) - elevator->distance = -15*TICRATE; // Timer until platform returns to original position. + crumble->distance--; + if (crumble->distance <= 0) + crumble->distance = -15*TICRATE; // Timer until platform returns to original position. else { // Timer isn't up yet, so just keep waiting. - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; return; } } - else if (++elevator->distance == 0) // Reposition back to original spot + else if (++crumble->distance == 0) // Reposition back to original spot { - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { sector = §ors[i]; for (rover = sector->ffloors; rover; rover = rover->next) { if (rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB - && rover->master == elevator->sourceline) + && rover->master == crumble->sourceline) { - rover->alpha = elevator->origspeed; + rover->alpha = crumble->origspeed; if (rover->alpha == 0xff) rover->flags &= ~FF_TRANSLUCENT; @@ -809,39 +809,39 @@ void T_StartCrumble(elevator_t *elevator) } // Up! - if (elevator->floordestheight == 1) - elevator->direction = -1; + if (crumble->floordestheight == 1) + crumble->direction = -1; else - elevator->direction = 1; + crumble->direction = 1; - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; return; } // Flash to indicate that the platform is about to return. - if (elevator->distance > -224 && (leveltime % ((abs(elevator->distance)/8) + 1) == 0)) + if (crumble->distance > -224 && (leveltime % ((abs(crumble->distance)/8) + 1) == 0)) { - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { sector = §ors[i]; for (rover = sector->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_NORETURN) && rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB - && rover->master == elevator->sourceline) + && rover->master == crumble->sourceline) { - if (rover->alpha == elevator->origspeed) + if (rover->alpha == crumble->origspeed) { rover->flags |= FF_TRANSLUCENT; rover->alpha = 0x00; } else { - if (elevator->origspeed == 0xff) + if (crumble->origspeed == 0xff) rover->flags &= ~FF_TRANSLUCENT; - rover->alpha = elevator->origspeed; + rover->alpha = crumble->origspeed; } } } @@ -851,74 +851,74 @@ void T_StartCrumble(elevator_t *elevator) // We're about to go back to the original position, // so set this to let other thinkers know what is // about to happen. - if (elevator->distance < 0 && elevator->distance > -3) - elevator->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself + if (crumble->distance < 0 && crumble->distance > -3) + crumble->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself } - if ((elevator->floordestheight == 0 && elevator->direction == -1) - || (elevator->floordestheight == 1 && elevator->direction == 1)) // Down + if ((crumble->floordestheight == 0 && crumble->direction == -1) + || (crumble->floordestheight == 1 && crumble->direction == 1)) // Down { - elevator->sector->crumblestate = CRUMBLE_FALL; // Allow floating now. + crumble->sector->crumblestate = CRUMBLE_FALL; // Allow floating now. // Only fall like this if it isn't meant to float on water - if (elevator->high != 42) + if (crumble->high != 42) { - elevator->speed += gravity; // Gain more and more speed + crumble->speed += gravity; // Gain more and more speed - if ((elevator->floordestheight == 0 && !(elevator->sector->ceilingheight < -16384*FRACUNIT)) - || (elevator->floordestheight == 1 && !(elevator->sector->ceilingheight > 16384*FRACUNIT))) + if ((crumble->floordestheight == 0 && !(crumble->sector->ceilingheight < -16384*FRACUNIT)) + || (crumble->floordestheight == 1 && !(crumble->sector->ceilingheight > 16384*FRACUNIT))) { fixed_t dest; - if (elevator->floordestheight == 1) - dest = elevator->sector->ceilingheight + (elevator->speed*2); + if (crumble->floordestheight == 1) + dest = crumble->sector->ceilingheight + (crumble->speed*2); else - dest = elevator->sector->ceilingheight - (elevator->speed*2); + dest = crumble->sector->ceilingheight - (crumble->speed*2); T_MovePlane //jff 4/7/98 reverse order of ceiling/floor ( - elevator->sector, - elevator->speed, + crumble->sector, + crumble->speed, dest, false, true, // move ceiling - elevator->direction + crumble->direction ); - if (elevator->floordestheight == 1) - dest = elevator->sector->floorheight + (elevator->speed*2); + if (crumble->floordestheight == 1) + dest = crumble->sector->floorheight + (crumble->speed*2); else - dest = elevator->sector->floorheight - (elevator->speed*2); + dest = crumble->sector->floorheight - (crumble->speed*2); T_MovePlane ( - elevator->sector, - elevator->speed, + crumble->sector, + crumble->speed, dest, false, false, // move floor - elevator->direction + crumble->direction ); - elevator->sector->ceilspeed = 42; - elevator->sector->floorspeed = elevator->speed*elevator->direction; + crumble->sector->ceilspeed = 42; + crumble->sector->floorspeed = crumble->speed*crumble->direction; } } } else // Up (restore to original position) { - elevator->sector->crumblestate = CRUMBLE_WAIT; - elevator->sector->ceilingheight = elevator->ceilingwasheight; - elevator->sector->floorheight = elevator->floorwasheight; - elevator->sector->floordata = NULL; - elevator->sector->ceilingdata = NULL; - elevator->sector->ceilspeed = 0; - elevator->sector->floorspeed = 0; - elevator->sector->moved = true; - P_RemoveThinker(&elevator->thinker); + crumble->sector->crumblestate = CRUMBLE_WAIT; + crumble->sector->ceilingheight = crumble->ceilingwasheight; + crumble->sector->floorheight = crumble->floorwasheight; + crumble->sector->floordata = NULL; + crumble->sector->ceilingdata = NULL; + crumble->sector->ceilspeed = 0; + crumble->sector->floorspeed = 0; + crumble->sector->moved = true; + P_RemoveThinker(&crumble->thinker); } - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { sector = §ors[i]; sector->moved = true; @@ -2309,7 +2309,7 @@ void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boole INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn) { - elevator_t *elevator; + crumble_t *crumble; sector_t *foundsec; INT32 i; @@ -2320,55 +2320,54 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, if (sec->crumblestate >= CRUMBLE_ACTIVATED) return 0; - // create and initialize new elevator thinker - elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); - P_AddThinker(THINK_MAIN, &elevator->thinker); - elevator->thinker.function.acp1 = (actionf_p1)T_StartCrumble; + // create and initialize new crumble thinker + crumble = Z_Calloc(sizeof (*crumble), PU_LEVSPEC, NULL); + P_AddThinker(THINK_MAIN, &crumble->thinker); + crumble->thinker.function.acp1 = (actionf_p1)T_StartCrumble; // Does this crumbler return? if (crumblereturn) - elevator->type = elevateBounce; + crumble->type = elevateBounce; else - elevator->type = elevateContinuous; + crumble->type = elevateContinuous; - // set up the fields according to the type of elevator action - elevator->sector = sec; - elevator->speed = 0; + // set up the fields + crumble->sector = sec; + crumble->speed = 0; if (player && player->mo && (player->mo->eflags & MFE_VERTICALFLIP)) { - elevator->direction = 1; // Up - elevator->floordestheight = 1; + crumble->direction = 1; // Up + crumble->floordestheight = 1; } else { - elevator->direction = -1; // Down - elevator->floordestheight = 0; + crumble->direction = -1; // Down + crumble->floordestheight = 0; } - elevator->floorwasheight = elevator->sector->floorheight; - elevator->ceilingwasheight = elevator->sector->ceilingheight; - elevator->distance = TICRATE; // Used for delay time - elevator->low = 0; - elevator->player = player; - elevator->origspeed = origalpha; + crumble->floorwasheight = crumble->sector->floorheight; + crumble->ceilingwasheight = crumble->sector->ceilingheight; + crumble->distance = TICRATE; // Used for delay time + crumble->player = player; + crumble->origspeed = origalpha; - elevator->sourceline = rover->master; + crumble->sourceline = rover->master; - sec->floordata = elevator; + sec->floordata = crumble; if (floating) - elevator->high = 42; + crumble->high = 42; else - elevator->high = 0; + crumble->high = 0; - elevator->sector->crumblestate = CRUMBLE_ACTIVATED; + crumble->sector->crumblestate = CRUMBLE_ACTIVATED; - for (i = -1; (i = P_FindSectorFromTag(elevator->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { foundsec = §ors[i]; - P_SpawnMobj(foundsec->soundorg.x, foundsec->soundorg.y, elevator->direction == 1 ? elevator->sector->floorheight : elevator->sector->ceilingheight, MT_CRUMBLEOBJ); + P_SpawnMobj(foundsec->soundorg.x, foundsec->soundorg.y, crumble->direction == 1 ? crumble->sector->floorheight : crumble->sector->ceilingheight, MT_CRUMBLEOBJ); } return 1; diff --git a/src/p_map.c b/src/p_map.c index accc52836..2b6623f71 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4223,14 +4223,14 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) { //If the thing was crushed by a crumbling FOF, reward the player who made it crumble! thinker_t *think; - elevator_t *crumbler; + crumble_t *crumbler; for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) { if (think->function.acp1 != (actionf_p1)T_StartCrumble) continue; - crumbler = (elevator_t *)think; + crumbler = (crumble_t *)think; if (crumbler->player && crumbler->player->mo && crumbler->player->mo != thing diff --git a/src/p_saveg.c b/src/p_saveg.c index f6e31fc3a..5032cfc75 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1930,6 +1930,30 @@ static void SaveElevatorThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveLine(ht->sourceline)); } +// +// SaveCrumbleThinker +// +// Saves a crumble_t thinker +// +static void SaveCrumbleThinker(const thinker_t *th, const UINT8 type) +{ + const crumble_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEUINT8(save_p, ht->type); + WRITEUINT32(save_p, SaveSector(ht->sector)); + WRITEUINT32(save_p, SaveSector(ht->actionsector)); + WRITEINT32(save_p, ht->direction); + WRITEFIXED(save_p, ht->floordestheight); + WRITEFIXED(save_p, ht->speed); + WRITEFIXED(save_p, ht->origspeed); + WRITEFIXED(save_p, ht->high); + WRITEFIXED(save_p, ht->distance); + WRITEFIXED(save_p, ht->floorwasheight); + WRITEFIXED(save_p, ht->ceilingwasheight); + WRITEUINT32(save_p, SavePlayer(ht->player)); // was dummy + WRITEUINT32(save_p, SaveLine(ht->sourceline)); +} + // // SaveScrollThinker // @@ -2377,7 +2401,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_CameraScanner) { - SaveElevatorThinker(th, tc_camerascanner); + SaveCrumbleThinker(th, tc_camerascanner); continue; } else if (th->function.acp1 == (actionf_p1)T_Scroll) @@ -3142,7 +3166,7 @@ static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) return &ht->thinker; } // -// LoadElevatorThinker +// +vatorThinker // // Loads a elevator_t from a save game // @@ -3179,6 +3203,35 @@ static thinker_t* LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) return &ht->thinker; } +// +// LoadCrumbleThinker +// +// Loads a crumble_t from a save game +// +static thinker_t* LoadCrumbleThinker(actionf_p1 thinker) +{ + crumble_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->type = READUINT8(save_p); + ht->sector = LoadSector(READUINT32(save_p)); + ht->actionsector = LoadSector(READUINT32(save_p)); + ht->direction = READINT32(save_p); + ht->floordestheight = READFIXED(save_p); + ht->speed = READFIXED(save_p); + ht->origspeed = READFIXED(save_p); + ht->high = READFIXED(save_p); + ht->distance = READFIXED(save_p); + ht->floorwasheight = READFIXED(save_p); + ht->ceilingwasheight = READFIXED(save_p); + ht->player = LoadPlayer(READUINT32(save_p)); // was dummy + ht->sourceline = LoadLine(READUINT32(save_p)); + + if (ht->sector) + ht->sector->floordata = ht; + + return &ht->thinker; +} + // // LoadScrollThinker // @@ -3707,7 +3760,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_startcrumble: - th = LoadElevatorThinker((actionf_p1)T_StartCrumble, 1); + th = LoadCrumbleThinker((actionf_p1)T_StartCrumble); break; case tc_marioblock: diff --git a/src/p_spec.h b/src/p_spec.h index e243e3a61..7e2a97ce9 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -311,6 +311,24 @@ typedef struct line_t *sourceline; } elevator_t; +typedef struct +{ + thinker_t thinker; + elevator_e type; + sector_t *sector; + sector_t *actionsector; // The sector the rover action is taking place in. + INT32 direction; + fixed_t floordestheight; + fixed_t speed; + fixed_t origspeed; + fixed_t high; + fixed_t distance; + fixed_t floorwasheight; // Height the floor WAS at + fixed_t ceilingwasheight; // Height the ceiling WAS at + player_t *player; // Player who initiated the thinker (used for airbob) + line_t *sourceline; +} crumble_t; + typedef struct { thinker_t thinker; @@ -440,7 +458,7 @@ void T_MoveFloor(floormove_t *movefloor); void T_MoveElevator(elevator_t *elevator); void T_ContinuousFalling(continuousfall_t *faller); void T_BounceCheese(bouncecheese_t *bouncer); -void T_StartCrumble(elevator_t *elevator); +void T_StartCrumble(crumble_t *crumble); void T_MarioBlock(mariothink_t *block); void T_FloatSector(floatthink_t *floater); void T_MarioBlockChecker(mariocheck_t *block); From 554de0e0f52730a66ec5e05613aaba5c80b68688 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 26 Apr 2020 16:51:14 +0200 Subject: [PATCH 139/220] T_StartCrumble refactoring, part 1 --- src/p_floor.c | 139 +++++++++++++++++++++++--------------------------- src/p_map.c | 4 +- src/p_saveg.c | 24 ++++----- src/p_spec.h | 19 ++++--- 4 files changed, 88 insertions(+), 98 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index d0fef319c..220202d07 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -765,22 +765,21 @@ void T_StartCrumble(crumble_t *crumble) // Once done, the no-return thinker just sits there, // constantly 'returning'... kind of an oxymoron, isn't it? - if (((crumble->floordestheight == 1 && crumble->direction == -1) - || (crumble->floordestheight == 0 && crumble->direction == 1)) - && crumble->type == elevateContinuous) // No return crumbler + if ((((crumble->flags & CF_REVERSE) && crumble->direction == -1) + || (!(crumble->flags & CF_REVERSE) && crumble->direction == 1)) + && !(crumble->flags & CF_RETURN)) { crumble->sector->ceilspeed = 0; crumble->sector->floorspeed = 0; return; } - if (crumble->distance != 0) + if (crumble->timer != 0) { - if (crumble->distance > 0) // Count down the timer + if (crumble->timer > 0) // Count down the timer { - crumble->distance--; - if (crumble->distance <= 0) - crumble->distance = -15*TICRATE; // Timer until platform returns to original position. + if (--crumble->timer <= 0) + crumble->timer = -15*TICRATE; // Timer until platform returns to original position. else { // Timer isn't up yet, so just keep waiting. @@ -789,7 +788,7 @@ void T_StartCrumble(crumble_t *crumble) return; } } - else if (++crumble->distance == 0) // Reposition back to original spot + else if (++crumble->timer == 0) // Reposition back to original spot { for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { @@ -797,19 +796,24 @@ void T_StartCrumble(crumble_t *crumble) for (rover = sector->ffloors; rover; rover = rover->next) { - if (rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB - && rover->master == crumble->sourceline) - { - rover->alpha = crumble->origspeed; + if (!(rover->flags & FF_CRUMBLE)) + continue; - if (rover->alpha == 0xff) - rover->flags &= ~FF_TRANSLUCENT; - } + if (!(rover->flags & FF_FLOATBOB)) + continue; + + if (rover->master != crumble->sourceline) + continue; + + rover->alpha = crumble->origalpha; + + if (rover->alpha == 0xff) + rover->flags &= ~FF_TRANSLUCENT; } } // Up! - if (crumble->floordestheight == 1) + if (crumble->flags & CF_REVERSE) crumble->direction = -1; else crumble->direction = 1; @@ -820,7 +824,7 @@ void T_StartCrumble(crumble_t *crumble) } // Flash to indicate that the platform is about to return. - if (crumble->distance > -224 && (leveltime % ((abs(crumble->distance)/8) + 1) == 0)) + if (crumble->timer > -224 && (leveltime % ((abs(crumble->timer)/8) + 1) == 0)) { for (i = -1; (i = P_FindSectorFromTag(crumble->sourceline->tag, i)) >= 0 ;) { @@ -828,21 +832,29 @@ void T_StartCrumble(crumble_t *crumble) for (rover = sector->ffloors; rover; rover = rover->next) { - if (!(rover->flags & FF_NORETURN) && rover->flags & FF_CRUMBLE && rover->flags & FF_FLOATBOB - && rover->master == crumble->sourceline) - { - if (rover->alpha == crumble->origspeed) - { - rover->flags |= FF_TRANSLUCENT; - rover->alpha = 0x00; - } - else - { - if (crumble->origspeed == 0xff) - rover->flags &= ~FF_TRANSLUCENT; + if (rover->flags & FF_NORETURN) + continue; - rover->alpha = crumble->origspeed; - } + if (!(rover->flags & FF_CRUMBLE)) + continue; + + if (!(rover->flags & FF_FLOATBOB)) + continue; + + if (rover->master != crumble->sourceline) + continue; + + if (rover->alpha == crumble->origalpha) + { + rover->flags |= FF_TRANSLUCENT; + rover->alpha = 0x00; + } + else + { + rover->alpha = crumble->origalpha; + + if (rover->alpha == 0xff) + rover->flags &= ~FF_TRANSLUCENT; } } } @@ -851,53 +863,41 @@ void T_StartCrumble(crumble_t *crumble) // We're about to go back to the original position, // so set this to let other thinkers know what is // about to happen. - if (crumble->distance < 0 && crumble->distance > -3) + if (crumble->timer < 0 && crumble->timer > -3) crumble->sector->crumblestate = CRUMBLE_RESTORE; // makes T_BounceCheese remove itself } - if ((crumble->floordestheight == 0 && crumble->direction == -1) - || (crumble->floordestheight == 1 && crumble->direction == 1)) // Down + if ((!(crumble->flags & CF_REVERSE) && crumble->direction == -1) + || ((crumble->flags & CF_REVERSE) && crumble->direction == 1)) // Down { crumble->sector->crumblestate = CRUMBLE_FALL; // Allow floating now. // Only fall like this if it isn't meant to float on water - if (crumble->high != 42) + if (!(crumble->flags & CF_FLOATBOB)) { crumble->speed += gravity; // Gain more and more speed - if ((crumble->floordestheight == 0 && !(crumble->sector->ceilingheight < -16384*FRACUNIT)) - || (crumble->floordestheight == 1 && !(crumble->sector->ceilingheight > 16384*FRACUNIT))) + if ((!(crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight >= -16384*FRACUNIT) + || ((crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight <= 16384*FRACUNIT)) { - fixed_t dest; - - if (crumble->floordestheight == 1) - dest = crumble->sector->ceilingheight + (crumble->speed*2); - else - dest = crumble->sector->ceilingheight - (crumble->speed*2); - T_MovePlane //jff 4/7/98 reverse order of ceiling/floor ( crumble->sector, crumble->speed, - dest, + crumble->sector->ceilingheight + crumble->direction*crumble->speed*2, false, true, // move ceiling crumble->direction ); - if (crumble->floordestheight == 1) - dest = crumble->sector->floorheight + (crumble->speed*2); - else - dest = crumble->sector->floorheight - (crumble->speed*2); - - T_MovePlane - ( - crumble->sector, - crumble->speed, - dest, - false, - false, // move floor - crumble->direction + T_MovePlane + ( + crumble->sector, + crumble->speed, + crumble->sector->floorheight + crumble->direction*crumble->speed*2, + false, + false, // move floor + crumble->direction ); crumble->sector->ceilspeed = 42; @@ -2325,12 +2325,6 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, P_AddThinker(THINK_MAIN, &crumble->thinker); crumble->thinker.function.acp1 = (actionf_p1)T_StartCrumble; - // Does this crumbler return? - if (crumblereturn) - crumble->type = elevateBounce; - else - crumble->type = elevateContinuous; - // set up the fields crumble->sector = sec; crumble->speed = 0; @@ -2338,28 +2332,25 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, if (player && player->mo && (player->mo->eflags & MFE_VERTICALFLIP)) { crumble->direction = 1; // Up - crumble->floordestheight = 1; + crumble->flags |= CF_REVERSE; } else - { crumble->direction = -1; // Down - crumble->floordestheight = 0; - } crumble->floorwasheight = crumble->sector->floorheight; crumble->ceilingwasheight = crumble->sector->ceilingheight; - crumble->distance = TICRATE; // Used for delay time + crumble->timer = TICRATE; crumble->player = player; - crumble->origspeed = origalpha; + crumble->origalpha = origalpha; crumble->sourceline = rover->master; sec->floordata = crumble; + if (crumblereturn) + crumble->flags |= CF_RETURN; if (floating) - crumble->high = 42; - else - crumble->high = 0; + crumble->flags |= CF_FLOATBOB; crumble->sector->crumblestate = CRUMBLE_ACTIVATED; diff --git a/src/p_map.c b/src/p_map.c index 2b6623f71..0c21e3e69 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4235,9 +4235,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) if (crumbler->player && crumbler->player->mo && crumbler->player->mo != thing && crumbler->actionsector == thing->subsector->sector - && crumbler->sector == rover->master->frontsector - && (crumbler->type == elevateBounce - || crumbler->type == elevateContinuous)) + && crumbler->sector == rover->master->frontsector) { killer = crumbler->player->mo; } diff --git a/src/p_saveg.c b/src/p_saveg.c index 5032cfc75..c4830b995 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1939,19 +1939,17 @@ static void SaveCrumbleThinker(const thinker_t *th, const UINT8 type) { const crumble_t *ht = (const void *)th; WRITEUINT8(save_p, type); - WRITEUINT8(save_p, ht->type); + WRITEUINT32(save_p, SaveLine(ht->sourceline)); WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEUINT32(save_p, SaveSector(ht->actionsector)); + WRITEUINT32(save_p, SavePlayer(ht->player)); // was dummy WRITEINT32(save_p, ht->direction); - WRITEFIXED(save_p, ht->floordestheight); + WRITEINT32(save_p, ht->origalpha); + WRITEINT32(save_p, ht->timer); WRITEFIXED(save_p, ht->speed); - WRITEFIXED(save_p, ht->origspeed); - WRITEFIXED(save_p, ht->high); - WRITEFIXED(save_p, ht->distance); WRITEFIXED(save_p, ht->floorwasheight); WRITEFIXED(save_p, ht->ceilingwasheight); - WRITEUINT32(save_p, SavePlayer(ht->player)); // was dummy - WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT8(save_p, ht->flags); } // @@ -3212,19 +3210,17 @@ static thinker_t* LoadCrumbleThinker(actionf_p1 thinker) { crumble_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; - ht->type = READUINT8(save_p); + ht->sourceline = LoadLine(READUINT32(save_p)); ht->sector = LoadSector(READUINT32(save_p)); ht->actionsector = LoadSector(READUINT32(save_p)); + ht->player = LoadPlayer(READUINT32(save_p)); ht->direction = READINT32(save_p); - ht->floordestheight = READFIXED(save_p); + ht->origalpha = READINT32(save_p); + ht->timer = READINT32(save_p); ht->speed = READFIXED(save_p); - ht->origspeed = READFIXED(save_p); - ht->high = READFIXED(save_p); - ht->distance = READFIXED(save_p); ht->floorwasheight = READFIXED(save_p); ht->ceilingwasheight = READFIXED(save_p); - ht->player = LoadPlayer(READUINT32(save_p)); // was dummy - ht->sourceline = LoadLine(READUINT32(save_p)); + ht->flags = READUINT8(save_p); if (ht->sector) ht->sector->floordata = ht; diff --git a/src/p_spec.h b/src/p_spec.h index 7e2a97ce9..c26cb4523 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -311,22 +311,27 @@ typedef struct line_t *sourceline; } elevator_t; +typedef enum +{ + CF_RETURN = 1, // Return after crumbling + CF_FLOATBOB = 1<<1, // Float on water + CF_REVERSE = 1<<2, // Reverse gravity +} crumbleflag_t; + typedef struct { thinker_t thinker; - elevator_e type; + line_t *sourceline; sector_t *sector; sector_t *actionsector; // The sector the rover action is taking place in. + player_t *player; // Player who initiated the thinker (used for airbob) INT32 direction; - fixed_t floordestheight; + INT32 origalpha; + INT32 timer; fixed_t speed; - fixed_t origspeed; - fixed_t high; - fixed_t distance; fixed_t floorwasheight; // Height the floor WAS at fixed_t ceilingwasheight; // Height the ceiling WAS at - player_t *player; // Player who initiated the thinker (used for airbob) - line_t *sourceline; + UINT8 flags; } crumble_t; typedef struct From f4282718dc3a22f5e2f7c1d0356ce3e2289bc232 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 26 Apr 2020 18:31:39 +0200 Subject: [PATCH 140/220] Accidentally changed the wrong SaveElevatorThinker call to SaveCrumbleThinker --- src/p_saveg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index c4830b995..74f94590c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2399,7 +2399,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_CameraScanner) { - SaveCrumbleThinker(th, tc_camerascanner); + SaveElevatorThinker(th, tc_camerascanner); continue; } else if (th->function.acp1 == (actionf_p1)T_Scroll) @@ -2424,7 +2424,7 @@ static void P_NetArchiveThinkers(void) } else if (th->function.acp1 == (actionf_p1)T_StartCrumble) { - SaveElevatorThinker(th, tc_startcrumble); + SaveCrumbleThinker(th, tc_startcrumble); continue; } else if (th->function.acp1 == (actionf_p1)T_MarioBlock) From 82bf72f5e1dba7997d4e7be49d190b14b0098950 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 26 Apr 2020 18:38:45 +0200 Subject: [PATCH 141/220] Remove obsolete stuff from elevator_t --- src/p_saveg.c | 18 ++++++------------ src/p_spec.h | 1 - 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 74f94590c..c04a9ee2d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1926,7 +1926,6 @@ static void SaveElevatorThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->delaytimer); WRITEFIXED(save_p, ht->floorwasheight); WRITEFIXED(save_p, ht->ceilingwasheight); - WRITEUINT32(save_p, SavePlayer(ht->player)); // was dummy WRITEUINT32(save_p, SaveLine(ht->sourceline)); } @@ -3168,7 +3167,7 @@ static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) // // Loads a elevator_t from a save game // -static thinker_t* LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) +static thinker_t* LoadElevatorThinker(actionf_p1 thinker, boolean setplanedata) { elevator_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; @@ -3187,15 +3186,12 @@ static thinker_t* LoadElevatorThinker(actionf_p1 thinker, UINT8 floorOrCeiling) ht->delaytimer = READFIXED(save_p); ht->floorwasheight = READFIXED(save_p); ht->ceilingwasheight = READFIXED(save_p); - ht->player = LoadPlayer(READUINT32(save_p)); // was dummy ht->sourceline = LoadLine(READUINT32(save_p)); - if (ht->sector) + if (ht->sector && setplanedata) { - if (floorOrCeiling & 2) - ht->sector->ceilingdata = ht; - if (floorOrCeiling & 1) - ht->sector->floordata = ht; + ht->sector->ceilingdata = ht; + ht->sector->floordata = ht; } return &ht->thinker; @@ -3722,7 +3718,7 @@ static void P_NetUnArchiveThinkers(void) break; case tc_elevator: - th = LoadElevatorThinker((actionf_p1)T_MoveElevator, 3); + th = LoadElevatorThinker((actionf_p1)T_MoveElevator, true); break; case tc_continuousfalling: @@ -3745,10 +3741,8 @@ static void P_NetUnArchiveThinkers(void) th = LoadRaiseThinker((actionf_p1)T_RaiseSector); break; - /// \todo rewrite all the code that uses an elevator_t but isn't an elevator - /// \note working on it! case tc_camerascanner: - th = LoadElevatorThinker((actionf_p1)T_CameraScanner, 0); + th = LoadElevatorThinker((actionf_p1)T_CameraScanner, false); break; case tc_bouncecheese: diff --git a/src/p_spec.h b/src/p_spec.h index c26cb4523..f7785125a 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -307,7 +307,6 @@ typedef struct fixed_t delaytimer; fixed_t floorwasheight; // Height the floor WAS at fixed_t ceilingwasheight; // Height the ceiling WAS at - player_t *player; // Player who initiated the thinker (used for airbob) line_t *sourceline; } elevator_t; From fb1746e95b2a2a2647d8ca2997b655a2d0278f88 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 26 Apr 2020 18:42:31 +0200 Subject: [PATCH 142/220] Deprecate the camera scanner effect and print a warning when it's used --- src/p_spec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 826260d3a..57795f2bf 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6156,6 +6156,8 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto { elevator_t *elevator; // Why not? LOL + CONS_Alert(CONS_WARNING, M_GetText("Detected a camera scanner effect (linedef type 5). This effect is deprecated and will be removed in the future!\n")); + // create and initialize new elevator thinker elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &elevator->thinker); From c026b707cea12bb1c46ca3ea8af2b888dae6fe57 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 26 Apr 2020 18:54:03 +0200 Subject: [PATCH 143/220] Make new thinker loading functions set floordata/ceilingdata where necessary --- src/p_saveg.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/p_saveg.c b/src/p_saveg.c index f6e31fc3a..c5724c15c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2892,6 +2892,10 @@ static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker) ht->floorwasheight = READFIXED(save_p); ht->ceilingwasheight = READFIXED(save_p); ht->low = READCHAR(save_p); + + if (ht->sector) + ht->sector->ceilingdata = ht; + return &ht->thinker; } @@ -2909,6 +2913,13 @@ static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker) ht->floorstartheight = READFIXED(save_p); ht->ceilingstartheight = READFIXED(save_p); ht->destheight = READFIXED(save_p); + + if (ht->sector) + { + ht->sector->ceilingdata = ht; + ht->sector->floordata = ht; + } + return &ht->thinker; } @@ -2926,6 +2937,13 @@ static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) ht->floorstartheight = READFIXED(save_p); ht->ceilingstartheight = READFIXED(save_p); ht->tag = READINT16(save_p); + + if (ht->sector) + { + ht->sector->ceilingdata = ht; + ht->sector->floordata = ht; + } + return &ht->thinker; } @@ -2960,6 +2978,13 @@ static thinker_t* LoadThwompThinker(actionf_p1 thinker) ht->delay = READINT32(save_p); ht->tag = READINT16(save_p); ht->sound = READUINT16(save_p); + + if (ht->sector) + { + ht->sector->ceilingdata = ht; + ht->sector->floordata = ht; + } + return &ht->thinker; } From e0f9b82544df2d9cd248a663108ffbb70f188e08 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 26 Apr 2020 18:46:43 -0400 Subject: [PATCH 144/220] Fix window icon being reset when switching renderers on non-Windows platforms --- src/sdl/i_video.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c042d141c..d9c08eca7 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -217,7 +217,6 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool else { Impl_CreateWindow(fullscreen); - Impl_SetWindowIcon(); wasfullscreen = fullscreen; SDL_SetWindowSize(window, width, height); if (fullscreen) @@ -1630,12 +1629,15 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); + if (window == NULL) { CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError()); return SDL_FALSE; } + Impl_SetWindowIcon(); + return Impl_CreateContext(); } @@ -1652,12 +1654,8 @@ static void Impl_SetWindowName(const char *title) static void Impl_SetWindowIcon(void) { - if (window == NULL || icoSurface == NULL) - { - return; - } - //SDL2STUB(); // Monster Iestyn: why is this stubbed? - SDL_SetWindowIcon(window, icoSurface); + if (window && icoSurface) + SDL_SetWindowIcon(window, icoSurface); } static void Impl_VideoSetupSDLBuffer(void) @@ -1764,6 +1762,11 @@ void I_StartupGraphics(void) VID_StartupOpenGL(); #endif + // Window icon +#ifdef HAVE_IMAGE + icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); +#endif + // Fury: we do window initialization after GL setup to allow // SDL_GL_LoadLibrary to work well on Windows @@ -1782,11 +1785,6 @@ void I_StartupGraphics(void) #ifdef HAVE_TTF I_ShutdownTTF(); #endif - // Window icon -#ifdef HAVE_IMAGE - icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); -#endif - Impl_SetWindowIcon(); VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT)); From 2f9cccf2870a7cab7588c02ba96d78bfc477591a Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 27 Apr 2020 11:19:07 +0200 Subject: [PATCH 145/220] Make P_AddRaiseThinker more configurable via function parameters (needed for UDMF) --- src/p_spec.c | 56 +++++++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 826260d3a..c2fe59ee3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6013,7 +6013,7 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) * \sa P_SpawnSpecials, T_RaiseSector * \author SSNTails */ -static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower, boolean spindash) +static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, fixed_t speed, fixed_t ceilingtop, fixed_t ceilingbottom, boolean lower, boolean spindash) { raise_t *raise; @@ -6025,10 +6025,10 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, boolean lower, raise->sourceline = sourceline; raise->sector = sec; - raise->ceilingtop = P_FindHighestCeilingSurrounding(sec); - raise->ceilingbottom = P_FindLowestCeilingSurrounding(sec); + raise->ceilingtop = ceilingtop; + raise->ceilingbottom = ceilingbottom; - raise->basespeed = FixedDiv(P_AproxDistance(sourceline->dx, sourceline->dy), 4*FRACUNIT); + raise->basespeed = speed; if (lower) raise->flags |= RF_REVERSE; @@ -6936,44 +6936,32 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 190: // Rising Platform FOF (solid, opaque, shadows) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 191: // Rising Platform FOF (solid, opaque, no shadows) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_CUTLEVEL, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 192: // Rising Platform TL block: FOF (solid, translucent) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_NOSHADE|FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 193: // Rising Platform FOF (solid, invisible) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_NOSHADE, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 194: // Rising Platform 'Platform' - You can jump up through it - // If line has no-climb set, don't give it shadows, otherwise do - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_PLATFORM|FF_BOTHPLANES|FF_ALLSIDES; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_NOSHADE; - - P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); - break; - case 195: // Rising Platform Translucent "platform" - // If line has no-climb set, don't give it shadows, otherwise do - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_PLATFORM|FF_TRANSLUCENT|FF_BOTHPLANES|FF_ALLSIDES|FF_EXTRA|FF_CUTEXTRA; - if (lines[i].flags & ML_NOCLIMB) - ffloorflags |= FF_NOSHADE; + { + fixed_t speed = FixedDiv(P_AproxDistance(lines[i].dx, lines[i].dy), 4*FRACUNIT); + fixed_t ceilingtop = P_FindHighestCeilingSurrounding(lines[i].frontsector); + fixed_t ceilingbottom = P_FindLowestCeilingSurrounding(lines[i].frontsector); + ffloorflags = FF_EXISTS|FF_SOLID; + if (lines[i].special != 193) + ffloorflags |= FF_RENDERALL; + if (lines[i].special <= 191) + ffloorflags |= FF_CUTLEVEL; + if (lines[i].special == 192 || lines[i].special == 195) + ffloorflags |= FF_TRANSLUCENT|FF_EXTRA|FF_CUTEXTRA; + if (lines[i].special >= 194) + ffloorflags |= FF_PLATFORM|FF_BOTHPLANES|FF_ALLSIDES; + if (lines[i].special != 190 && (lines[i].special <= 193 || lines[i].flags & ML_NOCLIMB)) + ffloorflags |= FF_NOSHADE; P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); + + P_AddRaiseThinker(lines[i].frontsector, &lines[i], speed, ceilingtop, ceilingbottom, !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; + } case 200: // Double light effect P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers); From 556c2a8c185c269b7eab56182b9f28311df9e710 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 27 Apr 2020 12:54:08 +0200 Subject: [PATCH 146/220] Store tag instead of sourceline in raise thinker --- src/p_floor.c | 4 ++-- src/p_saveg.c | 4 ++-- src/p_spec.c | 24 +++++++++++------------- src/p_spec.h | 2 +- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 179cf73c7..97b3af4cc 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1556,7 +1556,7 @@ void T_RaiseSector(raise_t *raise) if (raise->sector->crumblestate >= CRUMBLE_FALL || raise->sector->ceilingdata) return; - for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;) { sector = §ors[i]; @@ -1683,7 +1683,7 @@ void T_RaiseSector(raise_t *raise) raise->sector->ceilspeed = 42; raise->sector->floorspeed = speed*direction; - for (i = -1; (i = P_FindSectorFromTag(raise->sourceline->tag, i)) >= 0 ;) + for (i = -1; (i = P_FindSectorFromTag(raise->tag, i)) >= 0 ;) P_RecalcPrecipInSector(§ors[i]); } diff --git a/src/p_saveg.c b/src/p_saveg.c index f6e31fc3a..27f60684a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1784,7 +1784,7 @@ static void SaveRaiseThinker(const thinker_t *th, const UINT8 type) { const raise_t *ht = (const void *)th; WRITEUINT8(save_p, type); - WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEINT16(save_p, ht->tag); WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEFIXED(save_p, ht->ceilingbottom); WRITEFIXED(save_p, ht->ceilingtop); @@ -3004,7 +3004,7 @@ static thinker_t* LoadRaiseThinker(actionf_p1 thinker) { raise_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; - ht->sourceline = LoadLine(READUINT32(save_p)); + ht->tag = READINT16(save_p); ht->sector = LoadSector(READUINT32(save_p)); ht->ceilingbottom = READFIXED(save_p); ht->ceilingtop = READFIXED(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index c2fe59ee3..a870bf681 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6008,12 +6008,10 @@ static void P_AddBlockThinker(sector_t *sec, line_t *sourceline) * there already. * * \param sec Control sector. - * \param actionsector Target sector. - * \param sourceline Control linedef. * \sa P_SpawnSpecials, T_RaiseSector * \author SSNTails */ -static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, fixed_t speed, fixed_t ceilingtop, fixed_t ceilingbottom, boolean lower, boolean spindash) +static void P_AddRaiseThinker(sector_t *sec, INT16 tag, fixed_t speed, fixed_t ceilingtop, fixed_t ceilingbottom, boolean lower, boolean spindash) { raise_t *raise; @@ -6022,7 +6020,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, fixed_t speed, raise->thinker.function.acp1 = (actionf_p1)T_RaiseSector; - raise->sourceline = sourceline; + raise->tag = tag; raise->sector = sec; raise->ceilingtop = ceilingtop; @@ -6036,7 +6034,7 @@ static void P_AddRaiseThinker(sector_t *sec, line_t *sourceline, fixed_t speed, raise->flags |= RF_SPINDASH; } -static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean raise, boolean spindash, boolean dynamic) +static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, boolean spindash, boolean dynamic) { raise_t *airbob; @@ -6045,7 +6043,7 @@ static void P_AddAirbob(sector_t *sec, line_t *sourceline, fixed_t dist, boolean airbob->thinker.function.acp1 = (actionf_p1)T_RaiseSector; - airbob->sourceline = sourceline; + airbob->tag = tag; airbob->sector = sec; airbob->ceilingtop = sec->ceilingheight; @@ -6854,16 +6852,16 @@ void P_SpawnSpecials(boolean fromnetsave) { fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : P_AproxDistance(lines[i].dx, lines[i].dy); P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); break; } case 152: // Adjustable air bobbing platform in reverse P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); break; case 153: // Dynamic Sinking Platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); + P_AddAirbob(lines[i].frontsector, lines[i].tag, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); break; case 160: // Float/bob platform @@ -6913,13 +6911,13 @@ void P_SpawnSpecials(boolean fromnetsave) case 176: // Air bobbing platform that will crumble and bob on the water when it falls and hits P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB|FF_CRUMBLE, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 177: // Air bobbing platform that will crumble and bob on // the water when it falls and hits, then never return P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_FLOATBOB|FF_CRUMBLE|FF_NORETURN, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 178: // Crumbling platform that will float when it hits water @@ -6932,7 +6930,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 180: // Air bobbing platform that will crumble P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_CRUMBLE, secthinkers); - P_AddAirbob(lines[i].frontsector, lines + i, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, lines[i].tag, 16*FRACUNIT, false, !!(lines[i].flags & ML_NOCLIMB), false); break; case 190: // Rising Platform FOF (solid, opaque, shadows) @@ -6959,7 +6957,7 @@ void P_SpawnSpecials(boolean fromnetsave) ffloorflags |= FF_NOSHADE; P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); - P_AddRaiseThinker(lines[i].frontsector, &lines[i], speed, ceilingtop, ceilingbottom, !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); + P_AddRaiseThinker(lines[i].frontsector, lines[i].tag, speed, ceilingtop, ceilingbottom, !!(lines[i].flags & ML_BLOCKMONSTERS), !!(lines[i].flags & ML_NOCLIMB)); break; } diff --git a/src/p_spec.h b/src/p_spec.h index e243e3a61..d81726b14 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -400,7 +400,7 @@ typedef enum typedef struct { thinker_t thinker; - line_t *sourceline; + INT16 tag; sector_t *sector; fixed_t ceilingbottom; fixed_t ceilingtop; From 630af5d225f796a61ac77224e7822e138a091164 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 27 Apr 2020 13:01:31 +0200 Subject: [PATCH 147/220] Pass thwomp settings to P_AddThwompThinker --- src/p_spec.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index a870bf681..19bbdf57e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6063,12 +6063,10 @@ static void P_AddAirbob(sector_t *sec, INT16 tag, fixed_t dist, boolean raise, b * Even thwomps need to think! * * \param sec Control sector. - * \param actionsector Target sector. - * \param sourceline Control linedef. * \sa P_SpawnSpecials, T_ThwompSector * \author SSNTails */ -static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, line_t *sourceline) +static inline void P_AddThwompThinker(sector_t *sec, INT16 tag, line_t *sourceline, fixed_t crushspeed, fixed_t retractspeed, UINT16 sound) { thwomp_t *thwomp; @@ -6086,14 +6084,14 @@ static inline void P_AddThwompThinker(sector_t *sec, sector_t *actionsector, lin // set up the fields according to the type of elevator action thwomp->sourceline = sourceline; thwomp->sector = sec; - thwomp->crushspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dy >> 3 : 10*FRACUNIT; - thwomp->retractspeed = (sourceline->flags & ML_EFFECT5) ? sourceline->dx >> 3 : 2*FRACUNIT; + thwomp->crushspeed = crushspeed; + thwomp->retractspeed = retractspeed; thwomp->direction = 0; thwomp->floorstartheight = sec->floorheight; thwomp->ceilingstartheight = sec->ceilingheight; thwomp->delay = 1; - thwomp->tag = actionsector->tag; - thwomp->sound = (sourceline->flags & ML_EFFECT4) ? sides[sourceline->sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; + thwomp->tag = tag; + thwomp->sound = sound; sec->floordata = thwomp; sec->ceilingdata = thwomp; @@ -7015,14 +7013,20 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 251: // A THWOMP! + { + fixed_t crushspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dy >> 3 : 10*FRACUNIT; + fixed_t retractspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dx >> 3 : 2*FRACUNIT; + UINT16 sound = (lines[i].flags & ML_EFFECT4) ? sides[lines[i].sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; + sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) { - P_AddThwompThinker(§ors[sec], §ors[s], &lines[i]); + P_AddThwompThinker(§ors[sec], lines[i].tag, &lines[i], crushspeed, retractspeed, sound); P_AddFakeFloor(§ors[s], §ors[sec], lines + i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); } break; + } case 252: // Shatter block (breaks when touched) ffloorflags = FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER; From 4f3d8378355b4b2fefc37fe67362cebff152dfef Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 27 Apr 2020 13:09:57 +0200 Subject: [PATCH 148/220] Store "no bosses" setting for lasers in thinker instead of checking sourceline. --- src/p_saveg.c | 2 ++ src/p_spec.c | 10 +++++----- src/p_spec.h | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 27f60684a..6f96cbf0c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2003,6 +2003,7 @@ static void SaveLaserThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEUINT32(save_p, SaveSector(ht->sec)); WRITEUINT32(save_p, SaveLine(ht->sourceline)); + WRITEUINT8(save_p, ht->nobosses); } // @@ -3257,6 +3258,7 @@ static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) ht->sector = LoadSector(READUINT32(save_p)); ht->sec = LoadSector(READUINT32(save_p)); ht->sourceline = LoadLine(READUINT32(save_p)); + ht->nobosses = READUINT8(save_p); for (rover = ht->sector->ffloors; rover; rover = rover->next) if (rover->secnum == (size_t)(ht->sec - sectors) && rover->master == ht->sourceline) diff --git a/src/p_spec.c b/src/p_spec.c index 19bbdf57e..17b4d047e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6206,8 +6206,7 @@ void T_LaserFlash(laserthink_t *flash) { thing = node->m_thing; - if ((fflr->master->flags & ML_EFFECT1) - && thing->flags & MF_BOSS) + if (flash->nobosses && thing->flags & MF_BOSS) continue; // Don't hurt bosses // Don't endlessly kill egg guard shields (or anything else for that matter) @@ -6236,7 +6235,7 @@ void T_LaserFlash(laserthink_t *flash) * \sa T_LaserFlash * \author SSNTails */ -static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *line, thinkerlist_t *secthinkers) +static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *line, thinkerlist_t *secthinkers, boolean nobosses) { laserthink_t *flash; ffloor_t *fflr = P_AddFakeFloor(sec, sec2, line, laserflags, secthinkers); @@ -6253,6 +6252,7 @@ static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *lin flash->sector = sec; // For finding mobjs flash->sec = sec2; flash->sourceline = line; + flash->nobosses = nobosses; } // @@ -7068,8 +7068,8 @@ void P_SpawnSpecials(boolean fromnetsave) sec = sides[*lines[i].sidenum].sector - sectors; // No longer totally disrupts netgames - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - EV_AddLaserThinker(§ors[s], §ors[sec], lines + i, secthinkers); + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) + EV_AddLaserThinker(§ors[s], §ors[sec], lines + i, secthinkers, !!(lines[i].flags & ML_EFFECT1)); break; case 259: // Custom FOF diff --git a/src/p_spec.h b/src/p_spec.h index d81726b14..53e0076ef 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -108,6 +108,7 @@ typedef struct sector_t *sector; ///< Sector in which the effect takes place. sector_t *sec; line_t *sourceline; + UINT8 nobosses; } laserthink_t; /** Strobe light action structure.. From 0a0812bc57c3dedaa48c0cdb2749f78cd04eb1e9 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 27 Apr 2020 14:31:37 +0200 Subject: [PATCH 149/220] Remove P_FindSectorFromLineTag --- src/p_ceilng.c | 4 +- src/p_floor.c | 12 ++--- src/p_slopes.c | 2 +- src/p_spec.c | 128 +++++++++++++++++++------------------------------ src/p_spec.h | 1 - 5 files changed, 58 insertions(+), 89 deletions(-) diff --git a/src/p_ceilng.c b/src/p_ceilng.c index 31a4895ba..3c3c507cd 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -395,7 +395,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) sector_t *sec; ceiling_t *ceiling; - while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0) { sec = §ors[secnum]; @@ -615,7 +615,7 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type) sector_t *sec; ceiling_t *ceiling; - while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0) { sec = §ors[secnum]; diff --git a/src/p_floor.c b/src/p_floor.c index 97b3af4cc..a4b71d78d 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1284,7 +1284,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) INT32 secnum = -1; boolean FOFsector = false; - while ((secnum = P_FindSectorFromLineTag(nobaddies->sourceline, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(nobaddies->sourceline->tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -1300,7 +1300,7 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) FOFsector = true; - while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) + while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0) { if (T_SectorHasEnemies(§ors[targetsecnum])) return; @@ -1395,7 +1395,7 @@ void T_EachTimeThinker(eachtime_t *eachtime) eachtime->playersOnArea[i] = false; } - while ((secnum = P_FindSectorFromLineTag(eachtime->sourceline, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(eachtime->sourceline->tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -1418,7 +1418,7 @@ void T_EachTimeThinker(eachtime_t *eachtime) FOFsector = true; - while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0) + while ((targetsecnum = P_FindSectorFromTag(sec->lines[i]->tag, targetsecnum)) >= 0) { targetsec = §ors[targetsecnum]; @@ -1801,7 +1801,7 @@ void EV_DoFloor(line_t *line, floor_e floortype) sector_t *sec; floormove_t *dofloor; - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -2017,7 +2017,7 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) elevator_t *elevator; // act on all sectors with the same tag as the triggering linedef - while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0) { sec = §ors[secnum]; diff --git a/src/p_slopes.c b/src/p_slopes.c index 4b5838077..92b40f70f 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -566,7 +566,7 @@ void P_CopySectorSlope(line_t *line) int i, special = line->special; // Check for copy linedefs - for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) + for (i = -1; (i = P_FindSectorFromTag(line->tag, i)) >= 0;) { sector_t *srcsec = sectors + i; diff --git a/src/p_spec.c b/src/p_spec.c index 17b4d047e..7074ca4a6 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -987,42 +987,12 @@ static sector_t *P_FindModelCeilingSector(fixed_t ceildestheight, INT32 secnum) } #endif -/** Searches the tag lists for the next sector tagged to a line. - * - * \param line Tagged line used as a reference. - * \param start -1 to start at the beginning, or the result of a previous call - * to keep searching. - * \return Number of the next tagged sector found. - * \sa P_FindSectorFromTag, P_FindLineFromLineTag - */ -INT32 P_FindSectorFromLineTag(line_t *line, INT32 start) -{ - if (line->tag == -1) - { - start++; - - if (start >= (INT32)numsectors) - return -1; - - return start; - } - else - { - start = start >= 0 ? sectors[start].nexttag : - sectors[(unsigned)line->tag % numsectors].firsttag; - while (start >= 0 && sectors[start].tag != line->tag) - start = sectors[start].nexttag; - return start; - } -} - /** Searches the tag lists for the next sector with a given tag. * * \param tag Tag number to look for. * \param start -1 to start anew, or the result of a previous call to keep * searching. * \return Number of the next tagged sector found. - * \sa P_FindSectorFromLineTag */ INT32 P_FindSectorFromTag(INT16 tag, INT32 start) { @@ -1051,7 +1021,7 @@ INT32 P_FindSectorFromTag(INT16 tag, INT32 start) * \param start -1 to start anew, or the result of a previous call to keep * searching. * \return Number of the next tagged line found. - * \sa P_FindSectorFromLineTag + * \sa P_FindSectorFromTag */ static INT32 P_FindLineFromLineTag(const line_t *line, INT32 start) { @@ -2500,7 +2470,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) newceilinglightsec = line->frontsector->ceilinglightsec; // act on all sectors with the same tag as the triggering linedef - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (sectors[secnum].lightingdata) { @@ -2555,7 +2525,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 409: // Change tagged sectors' tag // (formerly "Change calling sectors' tag", but behavior was changed) { - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) P_ChangeSectorTag(secnum,(INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS)); break; } @@ -2565,7 +2535,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 411: // Stop floor/ceiling movement in tagged sector(s) - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (sectors[secnum].floordata) { @@ -2635,7 +2605,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } else { - if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + if ((secnum = P_FindSectorFromTag(line->tag, -1)) < 0) return; dest = P_GetObjectTypeInSectorNum(MT_TELEPORTMAN, secnum); @@ -2750,7 +2720,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Additionally play the sound from tagged sectors' soundorgs sector_t *sec; - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { sec = §ors[secnum]; S_StartSound(&sec->soundorg, sfxnum); @@ -2865,7 +2835,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 416: // Spawn adjustable fire flicker - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2899,7 +2869,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 417: // Spawn adjustable glowing light - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2933,7 +2903,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 418: // Spawn adjustable strobe flash (unsynchronized) - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2967,7 +2937,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 419: // Spawn adjustable strobe flash (synchronized) - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -3015,7 +2985,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 421: // Stop lighting effect in tagged sectors - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) if (sectors[secnum].lightingdata) { P_RemoveThinker(&((elevator_t *)sectors[secnum].lightingdata)->thinker); @@ -3030,7 +3000,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if ((!mo || !mo->player) && !titlemapinaction) // only players have views, and title screens return; - if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + if ((secnum = P_FindSectorFromTag(line->tag, -1)) < 0) return; altview = P_GetObjectTypeInSectorNum(MT_ALTVIEWMAN, secnum); @@ -3349,7 +3319,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (line->sidenum[1] != 0xffff) state = (statenum_t)sides[line->sidenum[1]].toptexture; - while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) + while ((secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0) { boolean tryagain; sec = sectors + secnum; @@ -3504,7 +3474,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Except it is activated by linedef executor, not level load // This could even override existing colormaps I believe // -- Monster Iestyn 14/06/18 - for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;) + for (secnum = -1; (secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0 ;) { P_ResetColormapFader(§ors[secnum]); @@ -3832,7 +3802,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } case 455: // Fade colormap - for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;) + for (secnum = -1; (secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0 ;) { extracolormap_t *source_exc, *dest_exc, *exc; INT32 speed = (INT32)((line->flags & ML_DONTPEGBOTTOM) || !sides[line->sidenum[0]].rowoffset) && line->sidenum[1] != 0xFFFF ? @@ -3921,7 +3891,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 456: // Stop fade colormap - for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;) + for (secnum = -1; (secnum = P_FindSectorFromTag(line->tag, secnum)) >= 0 ;) P_ResetColormapFader(§ors[secnum]); break; @@ -3935,7 +3905,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) boolean persist = (line->flags & ML_EFFECT2); mobj_t *anchormo; - if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + if ((secnum = P_FindSectorFromTag(line->tag, -1)) < 0) return; anchormo = P_GetObjectTypeInSectorNum(MT_ANGLEMAN, secnum); @@ -6473,7 +6443,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 1: // Definable gravity per sector sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) { sectors[s].gravity = §ors[sec].floorheight; // This allows it to change in realtime! @@ -6497,7 +6467,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 5: // Change camera info sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddCameraScanner(§ors[sec], §ors[s], R_PointToAngle2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y)); break; @@ -6524,7 +6494,7 @@ void P_SpawnSpecials(boolean fromnetsave) P_ApplyFlatAlignment(lines + i, lines[i].frontsector, flatangle, xoffs, yoffs); else { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0;) P_ApplyFlatAlignment(lines + i, sectors + s, flatangle, xoffs, yoffs); } } @@ -6535,7 +6505,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 8: // Sector Parameters - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) { if (lines[i].flags & ML_NOCLIMB) { @@ -6563,7 +6533,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 10: // Vertical culling plane for sprites and FOFs sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].cullheight = &lines[i]; // This allows it to change in realtime! break; @@ -6624,13 +6594,13 @@ void P_SpawnSpecials(boolean fromnetsave) case 63: // support for drawn heights coming from different sector sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].heightsec = (INT32)sec; break; case 64: // Appearing/Disappearing FOF option if (lines[i].flags & ML_BLOCKMONSTERS) { // Find FOFs by control sector tag - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) for (j = 0; (unsigned)j < sectors[s].linecount; j++) if (sectors[s].lines[j]->special >= 100 && sectors[s].lines[j]->special < 300) Add_MasterDisappearer(abs(lines[i].dx>>FRACBITS), abs(lines[i].dy>>FRACBITS), abs(sides[lines[i].sidenum[0]].sector->floorheight>>FRACBITS), (INT32)(sectors[s].lines[j]-lines), (INT32)i); @@ -6645,15 +6615,15 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 66: // Displace floor by front sector - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 67: // Displace ceiling by front sector - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 68: // Displace both floor AND ceiling by front sector - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; @@ -7255,46 +7225,46 @@ void P_SpawnSpecials(boolean fromnetsave) case 600: // floor lighting independently (e.g. lava) sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].floorlightsec = (INT32)sec; break; case 601: // ceiling lighting independently sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].ceilinglightsec = (INT32)sec; break; case 602: // Adjustable pulsating light sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableGlowingLight(§ors[sec], §ors[s], P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 603: // Adjustable flickering light sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableFireFlicker(§ors[sec], §ors[s], P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 604: // Adjustable Blinking Light (unsynchronized) sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, false); break; case 605: // Adjustable Blinking Light (synchronized) sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, true); break; case 606: // HACK! Copy colormaps. Just plain colormaps. - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = sides[lines[i].sidenum[0]].colormap_data; break; @@ -7349,7 +7319,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker INT32 s; size_t sec = sides[*lines[line].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines+line, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[line].tag, s)) >= 0 ;) P_AddFakeFloor(§ors[s], §ors[sec], lines+line, ffloorflags, secthinkers); } @@ -7711,7 +7681,7 @@ static void P_SpawnScrollers(void) case 513: // scroll effect ceiling case 533: // scroll and carry objects on ceiling - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 533) break; @@ -7720,13 +7690,13 @@ static void P_SpawnScrollers(void) case 523: // carry objects on ceiling dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; case 510: // scroll effect floor case 530: // scroll and carry objects on floor - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 530) break; @@ -7735,14 +7705,14 @@ static void P_SpawnScrollers(void) case 520: // carry objects on floor dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; // scroll wall according to linedef // (same direction and speed as scrolling floors) case 502: - for (s = -1; (s = P_FindLineFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) if (s != (INT32)i) Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); break; @@ -7812,7 +7782,7 @@ void T_Disappear(disappear_t *d) ffloor_t *rover; register INT32 s; - for (s = -1; (s = P_FindSectorFromLineTag(&lines[d->affectee], s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(lines[d->affectee].tag, s)) >= 0 ;) { for (rover = sectors[s].ffloors; rover; rover = rover->next) { @@ -8569,7 +8539,7 @@ static void P_SpawnFriction(void) else movefactor = FRACUNIT; - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Friction(friction, movefactor, s, -1); } } @@ -9104,15 +9074,15 @@ static void P_SpawnPushers(void) switch (l->special) { case 541: // wind - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_wind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 544: // current - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_current, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 547: // push/pull - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) { thing = P_GetPushThing(s); if (thing) // No MT_P* means no effect @@ -9120,19 +9090,19 @@ static void P_SpawnPushers(void) } break; case 545: // current up - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_upcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 546: // current down - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_downcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 542: // wind up - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_upwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 543: // wind down - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) + for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) Add_Pusher(p_downwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; } diff --git a/src/p_spec.h b/src/p_spec.h index 53e0076ef..98541d3e5 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -55,7 +55,6 @@ fixed_t P_FindNextLowestFloor(sector_t *sec, fixed_t currentheight); fixed_t P_FindLowestCeilingSurrounding(sector_t *sec); fixed_t P_FindHighestCeilingSurrounding(sector_t *sec); -INT32 P_FindSectorFromLineTag(line_t *line, INT32 start); INT32 P_FindSectorFromTag(INT16 tag, INT32 start); INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start); From 4cec927bbb35d4d006c4fa1cc9954985a1ab5370 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 27 Apr 2020 14:34:42 +0200 Subject: [PATCH 150/220] Replace P_FindLineFromLineTag with P_FindLineFromTag --- src/p_spec.c | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 7074ca4a6..f9e0a4040 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1015,42 +1015,12 @@ INT32 P_FindSectorFromTag(INT16 tag, INT32 start) } } -/** Searches the tag lists for the next line tagged to a line. - * - * \param line Tagged line used as a reference. - * \param start -1 to start anew, or the result of a previous call to keep - * searching. - * \return Number of the next tagged line found. - * \sa P_FindSectorFromTag - */ -static INT32 P_FindLineFromLineTag(const line_t *line, INT32 start) -{ - if (line->tag == -1) - { - start++; - - if (start >= (INT32)numlines) - return -1; - - return start; - } - else - { - start = start >= 0 ? lines[start].nexttag : - lines[(unsigned)line->tag % numlines].firsttag; - while (start >= 0 && lines[start].tag != line->tag) - start = lines[start].nexttag; - return start; - } -} -#if 0 /** Searches the tag lists for the next line with a given tag and special. * * \param tag Tag number. * \param start -1 to start anew, or the result of a previous call to keep * searching. * \return Number of next suitable line found. - * \sa P_FindLineFromLineTag * \author Graue */ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) @@ -1059,7 +1029,7 @@ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) { start++; - if (start >= numlines) + if (start >= (INT32)numlines) return -1; return start; @@ -1073,7 +1043,7 @@ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) return start; } } -#endif + // // P_FindSpecialLineFromTag // @@ -6605,7 +6575,7 @@ void P_SpawnSpecials(boolean fromnetsave) if (sectors[s].lines[j]->special >= 100 && sectors[s].lines[j]->special < 300) Add_MasterDisappearer(abs(lines[i].dx>>FRACBITS), abs(lines[i].dy>>FRACBITS), abs(sides[lines[i].sidenum[0]].sector->floorheight>>FRACBITS), (INT32)(sectors[s].lines[j]-lines), (INT32)i); } else // Find FOFs by effect sector tag - for (s = -1; (s = P_FindLineFromLineTag(lines + i, s)) >= 0 ;) + for (s = -1; (s = P_FindLineFromTag(lines[i].tag, s)) >= 0 ;) { if ((size_t)s == i) continue; From 2e3c110534c4a3fe655d05bce4897c39dc3a7521 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 28 Apr 2020 22:19:44 +0200 Subject: [PATCH 151/220] Optimise string archiving and allow for longer strings --- src/lua_script.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 7adf62fcc..d8dee37f6 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -732,7 +732,8 @@ enum ARCH_NULL=0, ARCH_BOOLEAN, ARCH_SIGNED, - ARCH_STRING, + ARCH_SMALLSTRING, + ARCH_LARGESTRING, ARCH_TABLE, ARCH_MOBJINFO, @@ -829,10 +830,9 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) } case LUA_TSTRING: { - UINT16 len = (UINT16)lua_objlen(gL, myindex); // get length of string, including embedded zeros + UINT32 len = (UINT32)lua_objlen(gL, myindex); // get length of string, including embedded zeros const char *s = lua_tostring(gL, myindex); - UINT16 i = 0; - WRITEUINT8(save_p, ARCH_STRING); + UINT32 i = 0; // if you're wondering why we're writing a string to save_p this way, // it turns out that Lua can have embedded zeros ('\0') in the strings, // so we can't use WRITESTRING as that cuts off when it finds a '\0'. @@ -840,7 +840,16 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) // fixing the awful crashes previously encountered for reading strings longer than 1024 // (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?) // -- Monster Iestyn 05/08/18 - WRITEUINT16(save_p, len); // save size of string + if (len < 255) + { + WRITEUINT8(save_p, ARCH_SMALLSTRING); + WRITEUINT8(save_p, len); // save size of string + } + else + { + WRITEUINT8(save_p, ARCH_LARGESTRING); + WRITEUINT32(save_p, len); // save size of string + } while (i < len) WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros break; @@ -1184,15 +1193,21 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_SIGNED: lua_pushinteger(gL, READFIXED(save_p)); break; - case ARCH_STRING: + case ARCH_SMALLSTRING: + case ARCH_LARGESTRING: { - UINT16 len = READUINT16(save_p); // length of string, including embedded zeros + UINT32 len; char *value; - UINT16 i = 0; + UINT32 i = 0; + // See my comments in the ArchiveValue function; // it's much the same for reading strings as writing them! // (i.e. we can't use READSTRING either) // -- Monster Iestyn 05/08/18 + if (type == ARCH_SMALLSTRING) + len = READUINT8(save_p); // length of string, including embedded zeros + else + len = READUINT32(save_p); // length of string, including embedded zeros value = malloc(len); // make temp buffer of size len // now read the actual string while (i < len) From 3e8fb8db25c022ba2c3b4d887c26e05844f9c0c9 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 28 Apr 2020 23:11:28 +0200 Subject: [PATCH 152/220] Optimise boolean archiving --- src/lua_script.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index d8dee37f6..05ad4700f 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -730,7 +730,8 @@ void LUA_InvalidatePlayer(player_t *player) enum { ARCH_NULL=0, - ARCH_BOOLEAN, + ARCH_TRUE, + ARCH_FALSE, ARCH_SIGNED, ARCH_SMALLSTRING, ARCH_LARGESTRING, @@ -818,8 +819,7 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) WRITEUINT8(save_p, ARCH_NULL); return 2; case LUA_TBOOLEAN: - WRITEUINT8(save_p, ARCH_BOOLEAN); - WRITEUINT8(save_p, lua_toboolean(gL, myindex)); + WRITEUINT8(save_p, lua_toboolean(gL, myindex) ? ARCH_TRUE : ARCH_FALSE); break; case LUA_TNUMBER: { @@ -1187,8 +1187,12 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_NULL: lua_pushnil(gL); break; - case ARCH_BOOLEAN: - lua_pushboolean(gL, READUINT8(save_p)); + case ARCH_TRUE: + lua_pushboolean(gL, true); + break; + case ARCH_FALSE: + lua_pushboolean(gL, false); + break; break; case ARCH_SIGNED: lua_pushinteger(gL, READFIXED(save_p)); From ae05f11c458601fe6c279ae5abcd2197518e3c28 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 28 Apr 2020 23:12:02 +0200 Subject: [PATCH 153/220] Optimise number archiving --- src/lua_script.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 05ad4700f..98c35e91f 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -732,7 +732,9 @@ enum ARCH_NULL=0, ARCH_TRUE, ARCH_FALSE, - ARCH_SIGNED, + ARCH_INT8, + ARCH_INT16, + ARCH_INT32, ARCH_SMALLSTRING, ARCH_LARGESTRING, ARCH_TABLE, @@ -824,8 +826,21 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) case LUA_TNUMBER: { lua_Integer number = lua_tointeger(gL, myindex); - WRITEUINT8(save_p, ARCH_SIGNED); - WRITEFIXED(save_p, number); + if (number >= INT8_MIN && number <= INT8_MAX) + { + WRITEUINT8(save_p, ARCH_INT8); + WRITESINT8(save_p, number); + } + else if (number >= INT16_MIN && number <= INT16_MAX) + { + WRITEUINT8(save_p, ARCH_INT16); + WRITEINT16(save_p, number); + } + else + { + WRITEUINT8(save_p, ARCH_INT32); + WRITEFIXED(save_p, number); + } break; } case LUA_TSTRING: @@ -1193,8 +1208,13 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_FALSE: lua_pushboolean(gL, false); break; + case ARCH_INT8: + lua_pushinteger(gL, READSINT8(save_p)); break; - case ARCH_SIGNED: + case ARCH_INT16: + lua_pushinteger(gL, READINT16(save_p)); + break; + case ARCH_INT32: lua_pushinteger(gL, READFIXED(save_p)); break; case ARCH_SMALLSTRING: From 9b3917cd729895c0f0e2db8792d3b721222afef4 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 29 Apr 2020 10:55:49 +0200 Subject: [PATCH 154/220] Revert "Replace a few instance of strncpy with strlcpy" This reverts commit 2e27f32d3e3c7de727867fa0c25f75f0c9ebe698. --- src/dehacked.c | 6 ++++-- src/f_finale.c | 4 ++-- src/m_menu.c | 14 +++++++------- src/m_menu.h | 2 +- src/p_setup.c | 4 +++- src/r_data.c | 5 +++-- src/v_video.c | 2 +- src/w_wad.c | 8 +++++--- src/y_inter.c | 5 +++-- 9 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index fbd42dee1..e9d029be0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -419,7 +419,7 @@ static void readPlayer(MYFILE *f, INT32 num) if (fastcmp(word, "PICNAME")) { SLOTFOUND - strlcpy(description[num].picname, word2, sizeof(description->picname)); + strncpy(description[num].picname, word2, 8); } // new character select else if (fastcmp(word, "DISPLAYNAME")) @@ -3889,7 +3889,9 @@ static void readmaincfg(MYFILE *f) lumpnum_t lumpnum; char newname[9]; - strlcpy(newname, word2, sizeof(newname)); + strncpy(newname, word2, 8); + + newname[8] = '\0'; lumpnum = W_CheckNumForName(newname); diff --git a/src/f_finale.c b/src/f_finale.c index abef1da69..825f646b0 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2338,7 +2338,7 @@ void F_InitMenuPresValues(void) activeMenuId = MainDef.menuid; // Set defaults for presentation values - strlcpy(curbgname, "TITLESKY", sizeof(curbgname)); + strncpy(curbgname, "TITLESKY", 9); curfadevalue = 16; curbgcolor = -1; curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; @@ -2348,7 +2348,7 @@ void F_InitMenuPresValues(void) curhidepics = hidetitlepics; curttmode = ttmode; curttscale = ttscale; - strlcpy(curttname, ttname, sizeof(curttname)); + strncpy(curttname, ttname, 9); curttx = ttx; curtty = tty; curttloop = ttloop; diff --git a/src/m_menu.c b/src/m_menu.c index e510f582a..1069f0f30 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2615,7 +2615,7 @@ static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval, } else if (menupres[menutype].bgname[0]) { - strlcpy(curbgname, menupres[menutype].bgname, sizeof(curbgname)); + strncpy(curbgname, menupres[menutype].bgname, 8); curbgxspeed = menupres[menutype].titlescrollxspeed != INT32_MAX ? menupres[menutype].titlescrollxspeed : titlescrollxspeed; curbgyspeed = menupres[menutype].titlescrollyspeed != INT32_MAX ? menupres[menutype].titlescrollyspeed : titlescrollyspeed; return true; @@ -2628,7 +2628,7 @@ static boolean MIT_SetCurBackground(UINT32 menutype, INT32 level, INT32 *retval, curbghide = true; else { - strlcpy(curbgname, defaultname, sizeof(curbgname)); + strncpy(curbgname, defaultname, 9); curbgxspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollxspeed; curbgyspeed = (gamestate == GS_TIMEATTACK) ? 0 : titlescrollyspeed; } @@ -2767,7 +2767,7 @@ void M_ChangeMenuMusic(const char *defaultmusname, boolean defaultmuslooping) void M_SetMenuCurBackground(const char *defaultname) { char name[9]; - strlcpy(name, defaultname, 9); + strncpy(name, defaultname, 8); M_IterateMenuTree(MIT_SetCurBackground, &name); } @@ -2820,7 +2820,7 @@ static void M_HandleMenuPresState(menu_t *newMenu) activeMenuId = newMenu ? newMenu->menuid : 0; // Set defaults for presentation values - strlcpy(curbgname, "TITLESKY", sizeof(curbgname)); + strncpy(curbgname, "TITLESKY", 9); curfadevalue = 16; curhidepics = hidetitlepics; curbgcolor = -1; @@ -5785,7 +5785,7 @@ static void M_DrawLevelPlatterMenu(void) { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); // Draw and animate foreground - if (!strcmp("RECATKBG", curbgname)) + if (!strncmp("RECATKBG", curbgname, 8)) M_DrawRecordAttackForeground(); } @@ -6033,7 +6033,7 @@ static void M_DrawMessageMenu(void) else { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); - if (!strcmp("RECATKBG", curbgname)) + if (!strncmp("RECATKBG", curbgname, 8)) M_DrawRecordAttackForeground(); } } @@ -9583,7 +9583,7 @@ void M_DrawTimeAttackMenu(void) { F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); // Draw and animate foreground - if (!strcmp("RECATKBG", curbgname)) + if (!strncmp("RECATKBG", curbgname, 8)) M_DrawRecordAttackForeground(); } if (curfadevalue) diff --git a/src/m_menu.h b/src/m_menu.h index 0658f38da..eeda9cc58 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -340,7 +340,7 @@ typedef struct { boolean used; char notes[441]; - char picname[9]; + char picname[8]; char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 patch_t *charpic; UINT8 prev; diff --git a/src/p_setup.c b/src/p_setup.c index 61a49d958..8c73b85e6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2883,7 +2883,9 @@ static void P_RunLevelScript(const char *scriptname) lumpnum_t lumpnum; char newname[9]; - strlcpy(newname, scriptname, sizeof(newname)); + strncpy(newname, scriptname, 8); + + newname[8] = '\0'; lumpnum = W_CheckNumForName(newname); diff --git a/src/r_data.c b/src/r_data.c index c542bbd98..831e75bef 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -2603,7 +2603,7 @@ INT32 R_CheckTextureNumForName(const char *name) return 0; for (i = 0; i < tidcachelen; i++) - if (!strcasecmp(tidcache[i].name, name)) + if (!strncasecmp(tidcache[i].name, name, 8)) return tidcache[i].id; // Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier @@ -2613,7 +2613,8 @@ INT32 R_CheckTextureNumForName(const char *name) { tidcachelen++; Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache); - strlcpy(tidcache[tidcachelen-1].name, name, sizeof(tidcache->name)); + strncpy(tidcache[tidcachelen-1].name, name, 8); + tidcache[tidcachelen-1].name[8] = '\0'; #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name); #endif diff --git a/src/v_video.c b/src/v_video.c index e03d0a60d..2d1014c23 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -391,7 +391,7 @@ const char *R_GetPalname(UINT16 num) if (num > 0 && num <= 10000) snprintf(newpal, 8, "PAL%04u", num-1); - strlcpy(palname, newpal, sizeof(palname)); + strncpy(palname, newpal, 8); return palname; } diff --git a/src/w_wad.c b/src/w_wad.c index 267f06198..a81132354 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -440,15 +440,17 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen else lump_p->compression = CM_NOCOMPRESSION; memset(lump_p->name, 0x00, 9); - strlcpy(lump_p->name, fileinfo->name, 9); + strncpy(lump_p->name, fileinfo->name, 8); // Allocate the lump's long name. lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); - strlcpy(lump_p->longname, fileinfo->name, 9); + strncpy(lump_p->longname, fileinfo->name, 8); + lump_p->longname[8] = '\0'; // Allocate the lump's full name. lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); - strlcpy(lump_p->fullname, fileinfo->name, 9); + strncpy(lump_p->fullname, fileinfo->name, 8); + lump_p->fullname[8] = '\0'; } free(fileinfov); *nlmp = numlumps; diff --git a/src/y_inter.c b/src/y_inter.c index ce57bef9e..f1764a816 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1740,8 +1740,9 @@ static void Y_CalculateCompetitionWinners(void) data.competition.monitors[data.competition.numplayers] = monitors[winner]; data.competition.scores[data.competition.numplayers] = scores[winner]; - strlcpy(tempname, player_names[winner], 9); - strlcpy(data.competition.name[data.competition.numplayers], tempname, 9); + strncpy(tempname, player_names[winner], 8); + tempname[8] = '\0'; + strncpy(data.competition.name[data.competition.numplayers], tempname, 9); data.competition.color[data.competition.numplayers] = &players[winner].skincolor; data.competition.character[data.competition.numplayers] = &players[winner].skin; From d89d2505bb64c82c5e5192149aed0e5066006a3e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 29 Apr 2020 14:45:52 +0100 Subject: [PATCH 155/220] Whoops the third --- src/p_saveg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index e63409386..239fa47df 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -966,7 +966,7 @@ static void ArchiveSectors(void) if (diff3 & SD_CRUMBLESTATE) WRITEINT32(save_p, ss->crumblestate); if (diff & SD_FFLOORS) - ArchiveFFloors(save_p, ss); + ArchiveFFloors(ss); } } @@ -1042,7 +1042,7 @@ static void UnArchiveSectors(void) sectors[i].crumblestate = READINT32(save_p); if (diff & SD_FFLOORS) - UnArchiveFFloors(save_p, sectors[i]); + UnArchiveFFloors(sectors[i]); } } From 2f0bf3860f1ba456c9b2f5ef3d975fd19c2289d5 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 29 Apr 2020 15:24:28 +0100 Subject: [PATCH 156/220] Don't discard const, added missing & --- src/p_saveg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 239fa47df..aee160859 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -776,7 +776,7 @@ static void P_NetUnArchiveColormaps(void) #define FD_ALPHA 0x02 // Check if any of the sector's FOFs differ from how they spawned -static boolean CheckFFloorDiff(sector_t *ss) +static boolean CheckFFloorDiff(const sector_t *ss) { ffloor_t *rover; @@ -794,7 +794,7 @@ static boolean CheckFFloorDiff(sector_t *ss) // Special case: save the stats of all modified ffloors along with their ffloor "number"s // we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed -static void ArchiveFFloors(sector_t *ss) +static void ArchiveFFloors(const sector_t *ss) { size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc ffloor_t *rover; @@ -821,7 +821,7 @@ static void ArchiveFFloors(sector_t *ss) WRITEUINT16(save_p, 0xffff); } -static void UnArchiveFFloors(sector_t *ss) +static void UnArchiveFFloors(const sector_t *ss) { UINT16 j = 0; // number of current ffloor in loop UINT16 fflr_i; // saved ffloor "number" of next modified ffloor @@ -1042,7 +1042,7 @@ static void UnArchiveSectors(void) sectors[i].crumblestate = READINT32(save_p); if (diff & SD_FFLOORS) - UnArchiveFFloors(sectors[i]); + UnArchiveFFloors(§ors[i]); } } From f9b831c00b25b02873d2fef7964267c1f89287e5 Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 1 May 2020 06:34:30 +0800 Subject: [PATCH 157/220] Restore jump-related pflags properly during twinspin --- src/p_user.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index b2f40fe70..2b8744e64 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5006,6 +5006,15 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range) player->pflags |= PF_THOKKED; } +static inline void P_DoTwinSpin(player_t *player) +{ + player->pflags &= ~PF_NOJUMPDAMAGE; + player->pflags |= P_GetJumpFlags(player) | PF_THOKKED; + S_StartSound(player->mo, sfx_s3k42); + player->mo->frame = 0; + P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); +} + // // P_DoJumpStuff // @@ -5176,12 +5185,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; case CA_TWINSPIN: if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_USEDOWN)) || player->charflags & SF_MULTIABILITY)) - { - player->pflags |= PF_THOKKED; - S_StartSound(player->mo, sfx_s3k42); - player->mo->frame = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); - } + P_DoTwinSpin(player); break; default: break; @@ -5438,12 +5442,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; case CA_TWINSPIN: if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY) - { - player->pflags |= PF_THOKKED; - S_StartSound(player->mo, sfx_s3k42); - player->mo->frame = 0; - P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); - } + P_DoTwinSpin(player); break; default: break; From be0959fa904889ae65532d2afec21b58f73eb1b8 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 1 May 2020 11:25:32 +0200 Subject: [PATCH 158/220] Remove bogus comments from p_saveg.c --- src/p_saveg.c | 397 +------------------------------------------------- 1 file changed, 5 insertions(+), 392 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index c04a9ee2d..2f84e97ef 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -59,9 +59,6 @@ typedef enum DRONE = 0x80, } player_saveflags; -// -// P_ArchivePlayer -// static inline void P_ArchivePlayer(void) { const player_t *player = &players[consoleplayer]; @@ -77,9 +74,6 @@ static inline void P_ArchivePlayer(void) WRITEINT32(save_p, player->continues); } -// -// P_UnArchivePlayer -// static inline void P_UnArchivePlayer(void) { INT16 skininfo = READUINT16(save_p); @@ -92,9 +86,6 @@ static inline void P_UnArchivePlayer(void) savedata.continues = READINT32(save_p); } -// -// P_NetArchivePlayers -// static void P_NetArchivePlayers(void) { INT32 i, j; @@ -300,9 +291,6 @@ static void P_NetArchivePlayers(void) } } -// -// P_NetUnArchivePlayers -// static void P_NetUnArchivePlayers(void) { INT32 i, j; @@ -772,9 +760,6 @@ static void P_NetUnArchiveColormaps(void) #define LD_S2BOTTEX 0x04 #define LD_S2MIDTEX 0x08 -// -// P_NetArchiveWorld -// static void P_NetArchiveWorld(void) { size_t i; @@ -1022,9 +1007,6 @@ static void P_NetArchiveWorld(void) save_p = put; } -// -// P_NetUnArchiveWorld -// static void P_NetUnArchiveWorld(void) { UINT16 i; @@ -1341,11 +1323,6 @@ static UINT32 SaveSlope(const pslope_t *slope) return 0xFFFFFFFF; } -// -// SaveMobjThinker -// -// Saves a mobj_t thinker -// static void SaveMobjThinker(const thinker_t *th, const UINT8 type) { const mobj_t *mobj = (const mobj_t *)th; @@ -1646,11 +1623,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->mobjnum); } -// -// SaveNoEnemiesThinker -// -// Saves a noenemies_t thinker -// static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type) { const noenemies_t *ht = (const void *)th; @@ -1658,11 +1630,6 @@ static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveLine(ht->sourceline)); } -// -// SaveBounceCheeseThinker -// -// Saves a bouncecheese_t thinker -// static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type) { const bouncecheese_t *ht = (const void *)th; @@ -1676,11 +1643,6 @@ static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type) WRITECHAR(save_p, ht->low); } -// -// SaveContinuousFallThinker -// -// Saves a continuousfall_t thinker -// static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type) { const continuousfall_t *ht = (const void *)th; @@ -1693,11 +1655,6 @@ static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->destheight); } -// -// SaveMarioBlockThinker -// -// Saves a mariothink_t thinker -// static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type) { const mariothink_t *ht = (const void *)th; @@ -1710,11 +1667,6 @@ static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type) WRITEINT16(save_p, ht->tag); } -// -// SaveMarioCheckThinker -// -// Saves a mariocheck_t thinker -// static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type) { const mariocheck_t *ht = (const void *)th; @@ -1723,11 +1675,6 @@ static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveSector(ht->sector)); } -// -// SaveThwompThinker -// -// Saves a thwomp_t thinker -// static void SaveThwompThinker(const thinker_t *th, const UINT8 type) { const thwomp_t *ht = (const void *)th; @@ -1744,11 +1691,6 @@ static void SaveThwompThinker(const thinker_t *th, const UINT8 type) WRITEUINT16(save_p, ht->sound); } -// -// SaveFloatThinker -// -// Saves a floatthink_t thinker -// static void SaveFloatThinker(const thinker_t *th, const UINT8 type) { const floatthink_t *ht = (const void *)th; @@ -1758,10 +1700,6 @@ static void SaveFloatThinker(const thinker_t *th, const UINT8 type) WRITEINT16(save_p, ht->tag); } -// SaveEachTimeThinker -// -// Loads a eachtime_t from a save game -// static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type) { const eachtime_t *ht = (const void *)th; @@ -1776,10 +1714,6 @@ static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type) WRITECHAR(save_p, ht->triggerOnExit); } -// SaveRaiseThinker -// -// Saves a raise_t thinker -// static void SaveRaiseThinker(const thinker_t *th, const UINT8 type) { const raise_t *ht = (const void *)th; @@ -1794,11 +1728,6 @@ static void SaveRaiseThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->flags); } -// -// SaveCeilingThinker -// -// Saves a ceiling_t thinker -// static void SaveCeilingThinker(const thinker_t *th, const UINT8 type) { const ceiling_t *ht = (const void *)th; @@ -1820,11 +1749,6 @@ static void SaveCeilingThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->sourceline); } -// -// SaveFloormoveThinker -// -// Saves a floormove_t thinker -// static void SaveFloormoveThinker(const thinker_t *th, const UINT8 type) { const floormove_t *ht = (const void *)th; @@ -1841,11 +1765,6 @@ static void SaveFloormoveThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, ht->delaytimer); } -// -// SaveLightflashThinker -// -// Saves a lightflash_t thinker -// static void SaveLightflashThinker(const thinker_t *th, const UINT8 type) { const lightflash_t *ht = (const void *)th; @@ -1855,11 +1774,6 @@ static void SaveLightflashThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->minlight); } -// -// SaveStrobeThinker -// -// Saves a strobe_t thinker -// static void SaveStrobeThinker(const thinker_t *th, const UINT8 type) { const strobe_t *ht = (const void *)th; @@ -1872,11 +1786,6 @@ static void SaveStrobeThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->brighttime); } -// -// SaveGlowThinker -// -// Saves a glow_t thinker -// static void SaveGlowThinker(const thinker_t *th, const UINT8 type) { const glow_t *ht = (const void *)th; @@ -1887,11 +1796,7 @@ static void SaveGlowThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->direction); WRITEINT32(save_p, ht->speed); } -// -// SaveFireflickerThinker -// -// Saves a fireflicker_t thinker -// + static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type) { const fireflicker_t *ht = (const void *)th; @@ -1902,11 +1807,7 @@ static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->maxlight); WRITEINT32(save_p, ht->minlight); } -// -// SaveElevatorThinker -// -// Saves a elevator_t thinker -// + static void SaveElevatorThinker(const thinker_t *th, const UINT8 type) { const elevator_t *ht = (const void *)th; @@ -1929,11 +1830,6 @@ static void SaveElevatorThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveLine(ht->sourceline)); } -// -// SaveCrumbleThinker -// -// Saves a crumble_t thinker -// static void SaveCrumbleThinker(const thinker_t *th, const UINT8 type) { const crumble_t *ht = (const void *)th; @@ -1951,11 +1847,6 @@ static void SaveCrumbleThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->flags); } -// -// SaveScrollThinker -// -// Saves a scroll_t thinker -// static inline void SaveScrollThinker(const thinker_t *th, const UINT8 type) { const scroll_t *ht = (const void *)th; @@ -1972,11 +1863,6 @@ static inline void SaveScrollThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->type); } -// -// SaveFrictionThinker -// -// Saves a friction_t thinker -// static inline void SaveFrictionThinker(const thinker_t *th, const UINT8 type) { const friction_t *ht = (const void *)th; @@ -1988,11 +1874,6 @@ static inline void SaveFrictionThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->roverfriction); } -// -// SavePusherThinker -// -// Saves a pusher_t thinker -// static inline void SavePusherThinker(const thinker_t *th, const UINT8 type) { const pusher_t *ht = (const void *)th; @@ -2012,11 +1893,6 @@ static inline void SavePusherThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->slider); } -// -// SaveLaserThinker -// -// Saves a laserthink_t thinker -// static void SaveLaserThinker(const thinker_t *th, const UINT8 type) { const laserthink_t *ht = (const void *)th; @@ -2026,11 +1902,6 @@ static void SaveLaserThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, SaveLine(ht->sourceline)); } -// -// SaveLightlevelThinker -// -// Saves a lightlevel_t thinker -// static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type) { const lightlevel_t *ht = (const void *)th; @@ -2043,11 +1914,6 @@ static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -// -// SaveExecutorThinker -// -// Saves a executor_t thinker -// static void SaveExecutorThinker(const thinker_t *th, const UINT8 type) { const executor_t *ht = (const void *)th; @@ -2058,11 +1924,6 @@ static void SaveExecutorThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -// -// SaveDisappearThinker -// -// Saves a disappear_t thinker -// static void SaveDisappearThinker(const thinker_t *th, const UINT8 type) { const disappear_t *ht = (const void *)th; @@ -2076,11 +1937,6 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->exists); } -// -// SaveFadeThinker -// -// Saves a fade_t thinker -// static void SaveFadeThinker(const thinker_t *th, const UINT8 type) { const fade_t *ht = (const void *)th; @@ -2104,11 +1960,6 @@ static void SaveFadeThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->exactalpha); } -// -// SaveFadeColormapThinker -// -// Saves a fadecolormap_t thinker -// static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type) { const fadecolormap_t *ht = (const void *)th; @@ -2121,11 +1972,6 @@ static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->timer); } -// -// SavePlaneDisplaceThinker -// -// Saves a planedisplace_t thinker -// static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) { const planedisplace_t *ht = (const void *)th; @@ -2137,7 +1983,6 @@ static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->type); } -/// Save a dynamic slope thinker. static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type) { const dynplanethink_t* ht = (const void*)th; @@ -2153,12 +1998,6 @@ static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type } #ifdef POLYOBJECTS - -// -// SavePolyrotateThinker -// -// Saves a polyrotate_t thinker -// static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type) { const polyrotate_t *ht = (const void *)th; @@ -2168,11 +2007,6 @@ static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->distance); } -// -// SavePolymoveThinker -// -// Saves a polymovet_t thinker -// static void SavePolymoveThinker(const thinker_t *th, const UINT8 type) { const polymove_t *ht = (const void *)th; @@ -2185,11 +2019,6 @@ static void SavePolymoveThinker(const thinker_t *th, const UINT8 type) WRITEANGLE(save_p, ht->angle); } -// -// SavePolywaypointThinker -// -// Saves a polywaypoint_t thinker -// static void SavePolywaypointThinker(const thinker_t *th, UINT8 type) { const polywaypoint_t *ht = (const void *)th; @@ -2209,11 +2038,6 @@ static void SavePolywaypointThinker(const thinker_t *th, UINT8 type) WRITEUINT32(save_p, SaveMobjnum(ht->target)); } -// -// SavePolyslidedoorThinker -// -// Saves a polyslidedoor_t thinker -// static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type) { const polyslidedoor_t *ht = (const void *)th; @@ -2233,11 +2057,6 @@ static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, ht->closing); } -// -// SavePolyswingdoorThinker -// -// Saves a polyswingdoor_t thinker -// static void SavePolyswingdoorThinker(const thinker_t *th, const UINT8 type) { const polyswingdoor_t *ht = (const void *)th; @@ -2287,25 +2106,8 @@ static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->duration); WRITEINT32(save_p, ht->timer); } - #endif -/* -// -// SaveWhatThinker -// -// Saves a what_t thinker -// -static inline void SaveWhatThinker(const thinker_t *th, const UINT8 type) -{ - const what_t *ht = (const void *)th; - WRITEUINT8(save_p, type); -} -*/ -// -// P_NetArchiveThinkers -// -// static void P_NetArchiveThinkers(void) { const thinker_t *th; @@ -2605,11 +2407,6 @@ static inline pslope_t *LoadSlope(UINT32 slopeid) return NULL; } -// -// LoadMobjThinker -// -// Loads a mobj_t from a save game -// static thinker_t* LoadMobjThinker(actionf_p1 thinker) { thinker_t *next; @@ -2886,10 +2683,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) return &mobj->thinker; } -// LoadNoEnemiesThinker -// -// Loads a noenemies_t from a save game -// static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker) { noenemies_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2898,10 +2691,6 @@ static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadBounceCheeseThinker -// -// Loads a bouncecheese_t from a save game -// static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker) { bouncecheese_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2916,10 +2705,6 @@ static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadContinuousFallThinker -// -// Loads a continuousfall_t from a save game -// static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker) { continuousfall_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2933,10 +2718,6 @@ static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadMarioBlockThinker -// -// Loads a mariothink_t from a save game -// static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) { mariothink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2950,10 +2731,6 @@ static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadMarioCheckThinker -// -// Loads a mariocheck_t from a save game -// static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker) { mariocheck_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2963,10 +2740,6 @@ static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadThwompThinker -// -// Loads a thwomp_t from a save game -// static thinker_t* LoadThwompThinker(actionf_p1 thinker) { thwomp_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2984,10 +2757,6 @@ static thinker_t* LoadThwompThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadFloatThinker -// -// Loads a floatthink_t from a save game -// static thinker_t* LoadFloatThinker(actionf_p1 thinker) { floatthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -2998,10 +2767,6 @@ static thinker_t* LoadFloatThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadEachTimeThinker -// -// Loads a eachtime_t from a save game -// static thinker_t* LoadEachTimeThinker(actionf_p1 thinker) { size_t i; @@ -3017,10 +2782,6 @@ static thinker_t* LoadEachTimeThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadRaiseThinker -// -// Loads a raise_t from a save game -// static thinker_t* LoadRaiseThinker(actionf_p1 thinker) { raise_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3036,11 +2797,6 @@ static thinker_t* LoadRaiseThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadCeilingThinker -// -// Loads a ceiling_t from a save game -// static thinker_t* LoadCeilingThinker(actionf_p1 thinker) { ceiling_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3065,11 +2821,6 @@ static thinker_t* LoadCeilingThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadFloormoveThinker -// -// Loads a floormove_t from a save game -// static thinker_t* LoadFloormoveThinker(actionf_p1 thinker) { floormove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3089,11 +2840,6 @@ static thinker_t* LoadFloormoveThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadLightflashThinker -// -// Loads a lightflash_t from a save game -// static thinker_t* LoadLightflashThinker(actionf_p1 thinker) { lightflash_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3106,11 +2852,6 @@ static thinker_t* LoadLightflashThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadStrobeThinker -// -// Loads a strobe_t from a save game -// static thinker_t* LoadStrobeThinker(actionf_p1 thinker) { strobe_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3126,11 +2867,6 @@ static thinker_t* LoadStrobeThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadGlowThinker -// -// Loads a glow_t from a save game -// static thinker_t* LoadGlowThinker(actionf_p1 thinker) { glow_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3144,11 +2880,7 @@ static thinker_t* LoadGlowThinker(actionf_p1 thinker) ht->sector->lightingdata = ht; return &ht->thinker; } -// -// LoadFireflickerThinker -// -// Loads a fireflicker_t from a save game -// + static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) { fireflicker_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3162,11 +2894,7 @@ static thinker_t* LoadFireflickerThinker(actionf_p1 thinker) ht->sector->lightingdata = ht; return &ht->thinker; } -// -// +vatorThinker -// -// Loads a elevator_t from a save game -// + static thinker_t* LoadElevatorThinker(actionf_p1 thinker, boolean setplanedata) { elevator_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3197,11 +2925,6 @@ static thinker_t* LoadElevatorThinker(actionf_p1 thinker, boolean setplanedata) return &ht->thinker; } -// -// LoadCrumbleThinker -// -// Loads a crumble_t from a save game -// static thinker_t* LoadCrumbleThinker(actionf_p1 thinker) { crumble_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3224,11 +2947,6 @@ static thinker_t* LoadCrumbleThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadScrollThinker -// -// Loads a scroll_t from a save game -// static thinker_t* LoadScrollThinker(actionf_p1 thinker) { scroll_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3246,11 +2964,6 @@ static thinker_t* LoadScrollThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadFrictionThinker -// -// Loads a friction_t from a save game -// static inline thinker_t* LoadFrictionThinker(actionf_p1 thinker) { friction_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3263,11 +2976,6 @@ static inline thinker_t* LoadFrictionThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPusherThinker -// -// Loads a pusher_t from a save game -// static thinker_t* LoadPusherThinker(actionf_p1 thinker) { pusher_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3289,11 +2997,6 @@ static thinker_t* LoadPusherThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadLaserThinker -// -// Loads a laserthink_t from a save game -// static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) { laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3309,11 +3012,6 @@ static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadLightlevelThinker -// -// Loads a lightlevel_t from a save game -// static inline thinker_t* LoadLightlevelThinker(actionf_p1 thinker) { lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3329,11 +3027,6 @@ static inline thinker_t* LoadLightlevelThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadExecutorThinker -// -// Loads a executor_t from a save game -// static inline thinker_t* LoadExecutorThinker(actionf_p1 thinker) { executor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3345,11 +3038,6 @@ static inline thinker_t* LoadExecutorThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadDisappearThinker -// -// Loads a disappear_t thinker -// static inline thinker_t* LoadDisappearThinker(actionf_p1 thinker) { disappear_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3364,11 +3052,6 @@ static inline thinker_t* LoadDisappearThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadFadeThinker -// -// Loads a fade_t thinker -// static inline thinker_t* LoadFadeThinker(actionf_p1 thinker) { sector_t *ss; @@ -3411,10 +3094,6 @@ static inline thinker_t* LoadFadeThinker(actionf_p1 thinker) return &ht->thinker; } -// LoadFadeColormapThinker -// -// Loads a fadecolormap_t from a save game -// static inline thinker_t* LoadFadeColormapThinker(actionf_p1 thinker) { fadecolormap_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3430,11 +3109,6 @@ static inline thinker_t* LoadFadeColormapThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPlaneDisplaceThinker -// -// Loads a planedisplace_t thinker -// static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker) { planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3448,7 +3122,6 @@ static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker) return &ht->thinker; } -/// Save a dynamic slope thinker. static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker) { dynplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL); @@ -3464,12 +3137,6 @@ static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker) } #ifdef POLYOBJECTS - -// -// LoadPolyrotateThinker -// -// Loads a polyrotate_t thinker -// static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker) { polyrotate_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3480,11 +3147,6 @@ static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolymoveThinker -// -// Loads a polymovet_t thinker -// static thinker_t* LoadPolymoveThinker(actionf_p1 thinker) { polymove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3498,11 +3160,6 @@ static thinker_t* LoadPolymoveThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolywaypointThinker -// -// Loads a polywaypoint_t thinker -// static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker) { polywaypoint_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3523,11 +3180,6 @@ static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolyslidedoorThinker -// -// loads a polyslidedoor_t thinker -// static inline thinker_t* LoadPolyslidedoorThinker(actionf_p1 thinker) { polyslidedoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3548,11 +3200,6 @@ static inline thinker_t* LoadPolyslidedoorThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolyswingdoorThinker -// -// Loads a polyswingdoor_t thinker -// static inline thinker_t* LoadPolyswingdoorThinker(actionf_p1 thinker) { polyswingdoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3568,11 +3215,6 @@ static inline thinker_t* LoadPolyswingdoorThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolydisplaceThinker -// -// Loads a polydisplace_t thinker -// static inline thinker_t* LoadPolydisplaceThinker(actionf_p1 thinker) { polydisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3597,11 +3239,6 @@ static inline thinker_t* LoadPolyrotdisplaceThinker(actionf_p1 thinker) return &ht->thinker; } -// -// LoadPolyfadeThinker -// -// Loads a polyfadet_t thinker -// static thinker_t* LoadPolyfadeThinker(actionf_p1 thinker) { polyfade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3618,22 +3255,6 @@ static thinker_t* LoadPolyfadeThinker(actionf_p1 thinker) } #endif -/* -// -// LoadWhatThinker -// -// load a what_t thinker -// -static inline void LoadWhatThinker(actionf_p1 thinker) -{ - what_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); - ht->thinker.function.acp1 = thinker; -} -*/ - -// -// P_NetUnArchiveThinkers -// static void P_NetUnArchiveThinkers(void) { thinker_t *currentthinker; @@ -3982,9 +3603,7 @@ static inline void P_UnArchivePolyObjects(void) P_UnArchivePolyObj(&PolyObjects[i]); } #endif -// -// P_FinishMobjs -// + static inline void P_FinishMobjs(void) { thinker_t *currentthinker; @@ -4093,9 +3712,6 @@ static void P_RelinkPointers(void) } } -// -// P_NetArchiveSpecials -// static inline void P_NetArchiveSpecials(void) { size_t i, z; @@ -4136,9 +3752,6 @@ static inline void P_NetArchiveSpecials(void) WRITEUINT8(save_p, 0x00); } -// -// P_NetUnArchiveSpecials -// static void P_NetUnArchiveSpecials(void) { size_t i; From dd645d88eaaa525f6f5ef97e576293b3a877921b Mon Sep 17 00:00:00 2001 From: Zipper Date: Fri, 1 May 2020 08:25:37 -0400 Subject: [PATCH 159/220] Update p_user.c --- src/p_user.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index a656aef34..69c38f79d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12720,6 +12720,18 @@ void P_PlayerAfterThink(player_t *player) } break; } + case CR_DUSTDEVIL: + { + mobj_t *mo = player->mo, *dustdevil = player->mo->tracer; + + if (abs(mo->x - dustdevil->x) > dustdevil->radius || abs(mo->y - dustdevil->y) > dustdevil->radius){ + P_SetTarget(&player->mo->tracer, NULL); + player->powers[pw_carry] = CR_NONE; + break; + } + + break; + } case CR_ROLLOUT: { mobj_t *mo = player->mo, *rock = player->mo->tracer; From c1304e019d9744c3877efa0ee59795df16681663 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 09:15:34 +0200 Subject: [PATCH 160/220] Clean up Thwomp spawning code --- src/p_spec.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index cebab0902..937015253 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6988,14 +6988,8 @@ void P_SpawnSpecials(boolean fromnetsave) fixed_t crushspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dy >> 3 : 10*FRACUNIT; fixed_t retractspeed = (lines[i].flags & ML_EFFECT5) ? lines[i].dx >> 3 : 2*FRACUNIT; UINT16 sound = (lines[i].flags & ML_EFFECT4) ? sides[lines[i].sidenum[0]].textureoffset >> FRACBITS : sfx_thwomp; - - sec = sides[*lines[i].sidenum].sector - sectors; - for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) - { - P_AddThwompThinker(§ors[sec], lines[i].tag, &lines[i], crushspeed, retractspeed, sound); - P_AddFakeFloor(§ors[s], §ors[sec], lines + i, - FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - } + P_AddThwompThinker(lines[i].frontsector, lines[i].tag, &lines[i], crushspeed, retractspeed, sound); + P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); break; } From 2a392651564981c88f6eaac5110a97165a083022 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 10:03:16 +0200 Subject: [PATCH 161/220] Make the laser thinker find the FOF itself instead of storing it in the thinker struct --- src/p_saveg.c | 11 +---- src/p_spec.c | 120 +++++++++++++++++++++++--------------------------- src/p_spec.h | 4 +- 3 files changed, 57 insertions(+), 78 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index e8c6593fa..54ffc7cbb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1890,8 +1890,7 @@ static void SaveLaserThinker(const thinker_t *th, const UINT8 type) { const laserthink_t *ht = (const void *)th; WRITEUINT8(save_p, type); - WRITEUINT32(save_p, SaveSector(ht->sector)); - WRITEUINT32(save_p, SaveSector(ht->sec)); + WRITEINT16(save_p, ht->tag); WRITEUINT32(save_p, SaveLine(ht->sourceline)); WRITEUINT8(save_p, ht->nobosses); } @@ -3001,16 +3000,10 @@ static thinker_t* LoadPusherThinker(actionf_p1 thinker) static inline thinker_t* LoadLaserThinker(actionf_p1 thinker) { laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); - ffloor_t *rover = NULL; ht->thinker.function.acp1 = thinker; - ht->sector = LoadSector(READUINT32(save_p)); - ht->sec = LoadSector(READUINT32(save_p)); + ht->tag = READINT16(save_p); ht->sourceline = LoadLine(READUINT32(save_p)); ht->nobosses = READUINT8(save_p); - for (rover = ht->sector->ffloors; rover; rover = rover->next) - if (rover->secnum == (size_t)(ht->sec - sectors) - && rover->master == ht->sourceline) - ht->ffloor = rover; return &ht->thinker; } diff --git a/src/p_spec.c b/src/p_spec.c index 937015253..0ce3df57b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6136,92 +6136,83 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto elevator->distance = FixedInt(AngleFixed(angle)); } -static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT; - /** Flashes a laser block. * * \param flash Thinker structure for this laser. - * \sa EV_AddLaserThinker + * \sa P_AddLaserThinker * \author SSNTails */ void T_LaserFlash(laserthink_t *flash) { msecnode_t *node; mobj_t *thing; - sector_t *sourcesec; - ffloor_t *fflr = flash->ffloor; - sector_t *sector = flash->sector; + INT32 s; + ffloor_t *fflr; + sector_t *sector; + sector_t *sourcesec = flash->sourceline->frontsector; fixed_t top, bottom; - if (!fflr || !(fflr->flags & FF_EXISTS)) - return; - - if (leveltime & 2) - //fflr->flags |= FF_RENDERALL; - fflr->alpha = 0xB0; - else - //fflr->flags &= ~FF_RENDERALL; - fflr->alpha = 0x90; - - sourcesec = fflr->master->frontsector; // Less to type! - - top = (*fflr->t_slope) ? P_GetZAt(*fflr->t_slope, sector->soundorg.x, sector->soundorg.y) - : *fflr->topheight; - bottom = (*fflr->b_slope) ? P_GetZAt(*fflr->b_slope, sector->soundorg.x, sector->soundorg.y) - : *fflr->bottomheight; - sector->soundorg.z = (top + bottom)/2; - S_StartSound(§or->soundorg, sfx_laser); - - // Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough* - for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_thinglist_next) + for (s = -1; (s = P_FindSectorFromTag(flash->tag, s)) >= 0 ;) { - thing = node->m_thing; + sector = §ors[s]; + for (fflr = sector->ffloors; fflr; fflr = fflr->next) + { + if (fflr->master != flash->sourceline) + continue; - if (flash->nobosses && thing->flags & MF_BOSS) - continue; // Don't hurt bosses + if (!(fflr->flags & FF_EXISTS)) + break; - // Don't endlessly kill egg guard shields (or anything else for that matter) - if (thing->health <= 0) - continue; + if (leveltime & 2) + //fflr->flags |= FF_RENDERALL; + fflr->alpha = 0xB0; + else + //fflr->flags &= ~FF_RENDERALL; + fflr->alpha = 0x90; - top = P_GetSpecialTopZ(thing, sourcesec, sector); - bottom = P_GetSpecialBottomZ(thing, sourcesec, sector); + top = (*fflr->t_slope) ? P_GetZAt(*fflr->t_slope, sector->soundorg.x, sector->soundorg.y) : *fflr->topheight; + bottom = (*fflr->b_slope) ? P_GetZAt(*fflr->b_slope, sector->soundorg.x, sector->soundorg.y) : *fflr->bottomheight; + sector->soundorg.z = (top + bottom)/2; + S_StartSound(§or->soundorg, sfx_laser); - if (thing->z >= top - || thing->z + thing->height <= bottom) - continue; + // Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough* + for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_thinglist_next) + { + thing = node->m_thing; - if (thing->flags & MF_SHOOTABLE) - P_DamageMobj(thing, NULL, NULL, 1, 0); - else if (thing->type == MT_EGGSHIELD) - P_KillMobj(thing, NULL, NULL, 0); + if (flash->nobosses && thing->flags & MF_BOSS) + continue; // Don't hurt bosses + + // Don't endlessly kill egg guard shields (or anything else for that matter) + if (thing->health <= 0) + continue; + + top = P_GetSpecialTopZ(thing, sourcesec, sector); + bottom = P_GetSpecialBottomZ(thing, sourcesec, sector); + + if (thing->z >= top + || thing->z + thing->height <= bottom) + continue; + + if (thing->flags & MF_SHOOTABLE) + P_DamageMobj(thing, NULL, NULL, 1, 0); + else if (thing->type == MT_EGGSHIELD) + P_KillMobj(thing, NULL, NULL, 0); + } + + break; + } } } -/** Adds a laser thinker to a 3Dfloor. - * - * \param fflr 3Dfloor to turn into a laser block. - * \param sector Target sector. - * \param secthkiners Lists of thinkers sorted by sector. May be NULL. - * \sa T_LaserFlash - * \author SSNTails - */ -static inline void EV_AddLaserThinker(sector_t *sec, sector_t *sec2, line_t *line, thinkerlist_t *secthinkers, boolean nobosses) +static inline void P_AddLaserThinker(INT16 tag, line_t *line, boolean nobosses) { - laserthink_t *flash; - ffloor_t *fflr = P_AddFakeFloor(sec, sec2, line, laserflags, secthinkers); - - if (!fflr) - return; - - flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); + laserthink_t *flash = Z_Calloc(sizeof (*flash), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &flash->thinker); flash->thinker.function.acp1 = (actionf_p1)T_LaserFlash; - flash->ffloor = fflr; - flash->sector = sec; // For finding mobjs - flash->sec = sec2; + flash->tag = tag; flash->sourceline = line; flash->nobosses = nobosses; } @@ -7030,11 +7021,8 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 258: // Laser block - sec = sides[*lines[i].sidenum].sector - sectors; - - // No longer totally disrupts netgames - for (s = -1; (s = P_FindSectorFromTag(lines[i].tag, s)) >= 0 ;) - EV_AddLaserThinker(§ors[s], §ors[sec], lines + i, secthinkers, !!(lines[i].flags & ML_EFFECT1)); + P_AddLaserThinker(lines[i].tag, lines + i, !!(lines[i].flags & ML_EFFECT1)); + P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT, secthinkers); break; case 259: // Custom FOF diff --git a/src/p_spec.h b/src/p_spec.h index 0228f8a02..596d8171d 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -104,9 +104,7 @@ typedef struct typedef struct { thinker_t thinker; ///< Thinker structure for laser. - ffloor_t *ffloor; ///< 3Dfloor that is a laser. - sector_t *sector; ///< Sector in which the effect takes place. - sector_t *sec; + INT16 tag; line_t *sourceline; UINT8 nobosses; } laserthink_t; From 485a4e50356d81ce6a72af60ac83da0135b01fb4 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 2 May 2020 12:08:31 +0200 Subject: [PATCH 162/220] Remove POLYOBJECTS and POLYOBJECTS_PLANES defines --- src/doomdef.h | 3 - src/hardware/hw_bsp.c | 2 - src/hardware/hw_main.c | 47 +++-------- src/lua_blockmaplib.c | 4 - src/p_map.c | 4 - src/p_maputl.c | 164 ++++++++++++++++++------------------- src/p_mobj.c | 3 - src/p_polyobj.c | 8 -- src/p_polyobj.h | 4 - src/p_saveg.c | 16 ---- src/p_setup.c | 8 -- src/p_sight.c | 11 --- src/p_spec.c | 9 --- src/p_user.c | 26 +----- src/r_bsp.c | 52 +++--------- src/r_bsp.h | 2 - src/r_defs.h | 10 --- src/r_plane.c | 178 +++++++++++++++++++---------------------- src/r_plane.h | 10 +-- src/r_segs.c | 92 ++++++++++----------- src/r_things.c | 5 -- 21 files changed, 230 insertions(+), 428 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index f9828a442..a91142e9d 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -578,9 +578,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Dumps the contents of a network save game upon consistency failure for debugging. //#define DUMPCONSISTENCY -/// Polyobject fake flat code -#define POLYOBJECTS_PLANES - /// See name of player in your crosshair #define SEENAMES diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 6f3dd9fbd..ebb74f653 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -887,12 +887,10 @@ static void AdjustSegs(void) float distv1,distv2,tmp; nearv1 = nearv2 = MYMAX; -#ifdef POLYOBJECTS // Don't touch polyobject segs. We'll compensate // for this when we go about drawing them. if (lseg->polyseg) continue; -#endif if (p) { for (j = 0; j < p->numpts; j++) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7fca7cd91..50c76fb5a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1602,7 +1602,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // heights of the polygon, and h & l, are the final (clipped) // poly coords. -#ifdef POLYOBJECTS // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, // you must use the linedef's backsector to be correct // From CB @@ -1612,7 +1611,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) popenbottom = back->floorheight; } else -#endif { popentop = min(worldtop, worldhigh); popenbottom = max(worldbottom, worldlow); @@ -1642,7 +1640,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) polybottom = polytop - textureheight[gr_midtexture]*repeats; } // CB -#ifdef POLYOBJECTS // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, // you must use the linedef's backsector to be correct if (gr_curline->polyseg) @@ -1650,7 +1647,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) lowcut = polybottom; highcut = polytop; } -#endif else { // The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector @@ -1780,7 +1776,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) break; } -#ifdef POLYOBJECTS if (gr_curline->polyseg && gr_curline->polyseg->translucency > 0) { if (gr_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn @@ -1791,7 +1786,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) else blendmode = HWR_TranstableToAlpha(gr_curline->polyseg->translucency, &Surf); } -#endif if (gr_frontsector->numlights) { @@ -2587,10 +2581,8 @@ static void HWR_AddLine(seg_t * line) static sector_t tempsec; fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t -#ifdef POLYOBJECTS if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; -#endif gr_curline = line; @@ -2717,13 +2709,10 @@ static void HWR_AddLine(seg_t * line) if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then { - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - !line->sidedef->midtexture - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || (gr_frontsector->tag == gr_backsector->tag))) + if (!line->polyseg && + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) return; // line is empty, don't even bother // treat like wide open window instead HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D @@ -2759,13 +2748,10 @@ static void HWR_AddLine(seg_t * line) if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then { - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - !line->sidedef->midtexture - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || (gr_frontsector->tag == gr_backsector->tag))) + if (!line->polyseg && + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) return; // line is empty, don't even bother goto clippass; // treat like wide open window instead @@ -2957,8 +2943,6 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) #endif } -#ifdef POLYOBJECTS - // // HWR_AddPolyObjectSegs // @@ -3001,7 +2985,6 @@ static inline void HWR_AddPolyObjectSegs(void) Z_Free(gr_fakeline); } -#ifdef POLYOBJECTS_PLANES static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) @@ -3256,8 +3239,6 @@ static void HWR_AddPolyObjectPlanes(void) } } } -#endif -#endif // -----------------+ // HWR_Subsector : Determine floor/ceiling planes. @@ -3585,7 +3566,6 @@ static void HWR_Subsector(size_t num) #endif #endif //doplanes -#ifdef POLYOBJECTS // Draw all the polyobjects in this subsector if (sub->polyList) { @@ -3606,15 +3586,12 @@ static void HWR_Subsector(size_t num) // Draw polyobject lines. HWR_AddPolyObjectSegs(); -#ifdef POLYOBJECTS_PLANES if (sub->validcount != validcount) // This validcount situation seems to let us know that the floors have already been drawn. { // Draw polyobject planes HWR_AddPolyObjectPlanes(); } -#endif } -#endif // Hurder ici se passe les choses INT32�essantes! // on vient de tracer le sol et le plafond @@ -3637,14 +3614,8 @@ static void HWR_Subsector(size_t num) while (count--) { - if (!line->glseg -#ifdef POLYOBJECTS - && !line->polyseg // ignore segs that belong to polyobjects -#endif - ) - { + if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects HWR_AddLine(line); - } line++; } } diff --git a/src/lua_blockmaplib.c b/src/lua_blockmaplib.c index bc8d20e8e..5aae73284 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -80,9 +80,7 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th { INT32 offset; const INT32 *list; // Big blockmap -#ifdef POLYOBJECTS polymaplink_t *plink; // haleyjd 02/22/06 -#endif line_t *ld; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) @@ -90,7 +88,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th offset = y*bmapwidth + x; -#ifdef POLYOBJECTS // haleyjd 02/22/06: consider polyobject lines plink = polyblocklinks[offset]; @@ -133,7 +130,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th } plink = (polymaplink_t *)(plink->link.next); } -#endif offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; diff --git a/src/p_map.c b/src/p_map.c index 0c21e3e69..0fade4847 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2157,7 +2157,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) BMBOUNDFIX(xl, xh, yl, yh); -#ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { validcount++; @@ -2229,7 +2228,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) } } } -#endif // tmfloorthing is set when tmfloorz comes from a thing's top tmfloorthing = NULL; @@ -2387,7 +2385,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) BMBOUNDFIX(xl, xh, yl, yh); -#ifdef POLYOBJECTS // Check polyobjects and see if tmfloorz/tmceilingz need to be altered { validcount++; @@ -2458,7 +2455,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) } } } -#endif // check lines for (bx = xl; bx <= xh; bx++) diff --git a/src/p_maputl.c b/src/p_maputl.c index bfca72eda..b0289db36 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -451,7 +451,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) I_Assert(back != NULL); openfloorrover = openceilingrover = NULL; -#ifdef POLYOBJECTS if (linedef->polyobj) { // set these defaults so that polyobjects don't interfere with collision above or below them @@ -462,7 +461,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) opentopslope = openbottomslope = NULL; } else -#endif { // Set open and high/low values here fixed_t frontheight, backheight; @@ -517,7 +515,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) texheight = textures[texnum]->height << FRACBITS; // Set texbottom and textop to the Z coordinates of the texture's boundaries -#if 0 // #ifdef POLYOBJECTS +#if 0 // don't remove this code unless solid midtextures // on non-solid polyobjects should NEVER happen in the future if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { @@ -560,7 +558,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) } } } -#ifdef POLYOBJECTS if (linedef->polyobj) { // Treat polyobj's backsector like a 3D Floor @@ -597,94 +594,95 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // otherwise don't do anything special, pretend there's nothing else there } else -#endif - // Check for fake floors in the sector. - if (front->ffloors || back->ffloors) { - ffloor_t *rover; - fixed_t delta1, delta2; - - // Check for frontsector's fake floors - for (rover = front->ffloors; rover; rover = rover->next) + // Check for fake floors in the sector. + if (front->ffloors || back->ffloors) { - fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) - continue; + ffloor_t *rover; + fixed_t delta1, delta2; - if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) - ; - else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) - || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) - continue; - - topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef); - bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef); - - delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); - delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - - if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF + // Check for frontsector's fake floors + for (rover = front->ffloors; rover; rover = rover->next) { - if (bottomheight < opentop) { - opentop = bottomheight; - opentopslope = *rover->b_slope; - openceilingrover = rover; + fixed_t topheight, bottomheight; + if (!(rover->flags & FF_EXISTS)) + continue; + + if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) + ; + else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) + || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) + continue; + + topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef); + + delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + + if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF + { + if (bottomheight < opentop) { + opentop = bottomheight; + opentopslope = *rover->b_slope; + openceilingrover = rover; + } + else if (bottomheight < highceiling) + highceiling = bottomheight; + } + + if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + { + if (topheight > openbottom) { + openbottom = topheight; + openbottomslope = *rover->t_slope; + openfloorrover = rover; + } + else if (topheight > lowfloor) + lowfloor = topheight; } - else if (bottomheight < highceiling) - highceiling = bottomheight; } - if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + // Check for backsectors fake floors + for (rover = back->ffloors; rover; rover = rover->next) { - if (topheight > openbottom) { - openbottom = topheight; - openbottomslope = *rover->t_slope; - openfloorrover = rover; + fixed_t topheight, bottomheight; + if (!(rover->flags & FF_EXISTS)) + continue; + + if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) + ; + else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) + || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) + continue; + + topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef); + + delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + + if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF + { + if (bottomheight < opentop) { + opentop = bottomheight; + opentopslope = *rover->b_slope; + openceilingrover = rover; + } + else if (bottomheight < highceiling) + highceiling = bottomheight; } - else if (topheight > lowfloor) - lowfloor = topheight; - } - } - // Check for backsectors fake floors - for (rover = back->ffloors; rover; rover = rover->next) - { - fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS)) - continue; - - if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover))) - ; - else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) - || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) - continue; - - topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef); - bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef); - - delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); - delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - - if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF - { - if (bottomheight < opentop) { - opentop = bottomheight; - opentopslope = *rover->b_slope; - openceilingrover = rover; + if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + { + if (topheight > openbottom) { + openbottom = topheight; + openbottomslope = *rover->t_slope; + openfloorrover = rover; + } + else if (topheight > lowfloor) + lowfloor = topheight; } - else if (bottomheight < highceiling) - highceiling = bottomheight; - } - - if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF - { - if (topheight > openbottom) { - openbottom = topheight; - openbottomslope = *rover->t_slope; - openfloorrover = rover; - } - else if (topheight > lowfloor) - lowfloor = topheight; } } } @@ -934,9 +932,7 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) { INT32 offset; const INT32 *list; // Big blockmap -#ifdef POLYOBJECTS polymaplink_t *plink; // haleyjd 02/22/06 -#endif line_t *ld; if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) @@ -944,7 +940,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) offset = y*bmapwidth + x; -#ifdef POLYOBJECTS // haleyjd 02/22/06: consider polyobject lines plink = polyblocklinks[offset]; @@ -968,7 +963,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *)) } plink = (polymaplink_t *)(plink->link.next); } -#endif offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x]; diff --git a/src/p_mobj.c b/src/p_mobj.c index 29fe1a57c..c78ec4a53 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2895,7 +2895,6 @@ static void P_PlayerZMovement(mobj_t *mo) mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack { -#ifdef POLYOBJECTS // Check if we're on a polyobject // that triggers a linedef executor. msecnode_t *node; @@ -2955,8 +2954,6 @@ static void P_PlayerZMovement(mobj_t *mo) } if (!stopmovecut) -#endif - // Cut momentum in half when you hit the ground and // aren't pressing any controls. if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 7e1ff1f49..0431707ac 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -28,12 +28,6 @@ #include "r_state.h" #include "r_defs.h" - -#define POLYOBJECTS - - -#ifdef POLYOBJECTS - /* Theory behind Polyobjects: @@ -3152,6 +3146,4 @@ INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) return 1; } -#endif // ifdef POLYOBJECTS - // EOF diff --git a/src/p_polyobj.h b/src/p_polyobj.h index d56701d2d..7dfc90ce9 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -18,8 +18,6 @@ #include "p_mobj.h" #include "r_defs.h" -// haleyjd: temporary define -#ifdef POLYOBJECTS // // Defines // @@ -353,8 +351,6 @@ extern polyobj_t *PolyObjects; extern INT32 numPolyObjects; extern polymaplink_t **polyblocklinks; // polyobject blockmap -#endif // ifdef POLYOBJECTS - #endif // EOF diff --git a/src/p_saveg.c b/src/p_saveg.c index e8c6593fa..34bd3724b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1300,7 +1300,6 @@ typedef enum tc_planedisplace, tc_dynslopeline, tc_dynslopevert, -#ifdef POLYOBJECTS tc_polyrotate, // haleyjd 03/26/06: polyobjects tc_polymove, tc_polywaypoint, @@ -1310,7 +1309,6 @@ typedef enum tc_polydisplace, tc_polyrotdisplace, tc_polyfade, -#endif tc_end } specials_e; @@ -1991,7 +1989,6 @@ static inline void SaveDynamicSlopeThinker(const thinker_t *th, const UINT8 type WRITEMEM(save_p, ht->vex, sizeof(ht->vex)); } -#ifdef POLYOBJECTS static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type) { const polyrotate_t *ht = (const void *)th; @@ -2100,7 +2097,6 @@ static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->duration); WRITEINT32(save_p, ht->timer); } -#endif static void P_NetArchiveThinkers(void) { @@ -2272,7 +2268,6 @@ static void P_NetArchiveThinkers(void) SavePlaneDisplaceThinker(th, tc_planedisplace); continue; } -#ifdef POLYOBJECTS else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate) { SavePolyrotatetThinker(th, tc_polyrotate); @@ -2318,7 +2313,6 @@ static void P_NetArchiveThinkers(void) SavePolyfadeThinker(th, tc_polyfade); continue; } -#endif else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeLine) { SaveDynamicSlopeThinker(th, tc_dynslopeline); @@ -3138,7 +3132,6 @@ static inline thinker_t* LoadDynamicSlopeThinker(actionf_p1 thinker) return &ht->thinker; } -#ifdef POLYOBJECTS static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker) { polyrotate_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); @@ -3255,7 +3248,6 @@ static thinker_t* LoadPolyfadeThinker(actionf_p1 thinker) ht->timer = READINT32(save_p); return &ht->thinker; } -#endif static void P_NetUnArchiveThinkers(void) { @@ -3416,7 +3408,6 @@ static void P_NetUnArchiveThinkers(void) case tc_planedisplace: th = LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace); break; -#ifdef POLYOBJECTS case tc_polyrotate: th = LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate); break; @@ -3453,7 +3444,6 @@ static void P_NetUnArchiveThinkers(void) case tc_polyfade: th = LoadPolyfadeThinker((actionf_p1)T_PolyObjFade); break; -#endif case tc_dynslopeline: th = LoadDynamicSlopeThinker((actionf_p1)T_DynamicSlopeLine); @@ -3515,7 +3505,6 @@ static void P_NetUnArchiveThinkers(void) // // haleyjd 03/26/06: PolyObject saving code // -#ifdef POLYOBJECTS #define PD_FLAGS 0x01 #define PD_TRANS 0x02 @@ -3604,7 +3593,6 @@ static inline void P_UnArchivePolyObjects(void) for (i = 0; i < numSavedPolys; ++i) P_UnArchivePolyObj(&PolyObjects[i]); } -#endif static inline void P_FinishMobjs(void) { @@ -4078,9 +4066,7 @@ void P_SaveNetGame(void) if (gamestate == GS_LEVEL) { P_NetArchiveWorld(); -#ifdef POLYOBJECTS P_ArchivePolyObjects(); -#endif P_NetArchiveThinkers(); P_NetArchiveSpecials(); P_NetArchiveColormaps(); @@ -4118,9 +4104,7 @@ boolean P_LoadNetGame(void) if (gamestate == GS_LEVEL) { P_NetUnArchiveWorld(); -#ifdef POLYOBJECTS P_UnArchivePolyObjects(); -#endif P_NetUnArchiveThinkers(); P_NetUnArchiveSpecials(); P_NetUnArchiveColormaps(); diff --git a/src/p_setup.c b/src/p_setup.c index 8c73b85e6..b3b618e51 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -953,9 +953,7 @@ static void P_InitializeLinedef(line_t *ld) ld->splats = NULL; #endif ld->firsttag = ld->nexttag = -1; -#ifdef POLYOBJECTS ld->polyobj = NULL; -#endif ld->text = NULL; ld->callcount = 0; @@ -1869,10 +1867,8 @@ static void P_InitializeSeg(seg_t *seg) seg->numlights = 0; seg->rlights = NULL; -#ifdef POLYOBJECTS seg->polyseg = NULL; seg->dontrenderme = false; -#endif } static void P_LoadSegs(UINT8 *data) @@ -2235,11 +2231,9 @@ static boolean P_LoadBlockMap(UINT8 *data, size_t count) blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blockmap = blockmaplump+4; -#ifdef POLYOBJECTS // haleyjd 2/22/06: setup polyobject blockmap count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); -#endif return true; } @@ -2490,11 +2484,9 @@ static void P_CreateBlockMap(void) blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blockmap = blockmaplump + 4; -#ifdef POLYOBJECTS // haleyjd 2/22/06: setup polyobject blockmap count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); -#endif } } diff --git a/src/p_sight.c b/src/p_sight.c index 3d1ee9e60..3e44281d0 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -100,7 +100,6 @@ static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1) return frac; } -#ifdef POLYOBJECTS static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) { size_t i; @@ -169,7 +168,6 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los) return true; } -#endif // // P_CrossSubsector @@ -180,9 +178,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) { seg_t *seg; INT32 count; -#ifdef POLYOBJECTS polyobj_t *po; // haleyjd 02/23/06 -#endif #ifdef RANGECHECK if (num >= numsubsectors) @@ -192,7 +188,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) // haleyjd 02/23/06: this assignment should be after the above check seg = segs + subsectors[num].firstline; -#ifdef POLYOBJECTS // haleyjd 02/23/06: check polyobject lines if ((po = subsectors[num].polyList)) { @@ -207,7 +202,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) po = (polyobj_t *)(po->link.next); } } -#endif for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines { @@ -413,15 +407,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) // killough 11/98: shortcut for melee situations // same subsector? obviously visible -#ifndef POLYOBJECTS - if (t1->subsector == t2->subsector) - return true; -#else // haleyjd 02/23/06: can't do this if there are polyobjects in the subsec if (!t1->subsector->polyList && t1->subsector == t2->subsector) return true; -#endif // An unobstructed LOS is possible. // Now look from eyes of t1 to any part of t2. diff --git a/src/p_spec.c b/src/p_spec.c index cebab0902..c93846438 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1076,9 +1076,6 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) } } -// haleyjd: temporary define -#ifdef POLYOBJECTS - // // PolyDoor // @@ -1401,8 +1398,6 @@ static boolean PolyRotDisplace(line_t *line) return EV_DoPolyObjRotDisplace(&pdd); } -#endif // ifdef POLYOBJECTS - /** Changes a sector's tag. * Used by the linedef executor tag changer and by crumblers. * @@ -4010,7 +4005,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } break; -#ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing PolyDoor(line); @@ -4040,7 +4034,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 492: PolyFade(line); break; -#endif default: break; @@ -7281,7 +7274,6 @@ void P_SpawnSpecials(boolean fromnetsave) Z_Free(secthinkers); -#ifdef POLYOBJECTS // haleyjd 02/20/06: spawn polyobjects Polyobj_InitLevel(); @@ -7302,7 +7294,6 @@ void P_SpawnSpecials(boolean fromnetsave) break; } } -#endif P_RunLevelLoadExecutors(); } diff --git a/src/p_user.c b/src/p_user.c index b2f40fe70..36a1054c6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3847,7 +3847,6 @@ static void P_DoTeeter(player_t *player) BMBOUNDFIX(xl, xh, yl, yh); // Polyobjects -#ifdef POLYOBJECTS validcount++; for (by = yl; by <= yh; by++) @@ -3941,7 +3940,6 @@ static void P_DoTeeter(player_t *player) plink = (polymaplink_t *)(plink->link.next); } } -#endif if (teeter) // only bother with objects as a last resort if you were already teetering { mobj_t *oldtmthing = tmthing; @@ -5702,11 +5700,7 @@ static void P_2dMovement(player_t *player) } else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt player->cmomx = player->cmomy = 0; - else if (player->onconveyor != 2 && player->onconveyor != 4 -#ifdef POLYOBJECTS - && player->onconveyor != 1 -#endif - ) + else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1) player->cmomx = player->cmomy = 0; player->rmomx = player->mo->momx - player->cmomx; @@ -5901,11 +5895,7 @@ static void P_3dMovement(player_t *player) } else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt player->cmomx = player->cmomy = 0; - else if (player->onconveyor != 2 && player->onconveyor != 4 -#ifdef POLYOBJECTS - && player->onconveyor != 1 -#endif - ) + else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1) player->cmomx = player->cmomy = 0; player->rmomx = player->mo->momx - player->cmomx; @@ -10235,7 +10225,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } -#ifdef POLYOBJECTS // Check polyobjects and see if floorz/ceilingz need to be altered { INT32 xl, xh, yl, yh, bx, by; @@ -10314,7 +10303,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } } -#endif // crushed camera if (myceilingz <= myfloorz + thiscam->height && !resetcalled && !cameranoclip) @@ -11725,10 +11713,8 @@ void P_PlayerThink(player_t *player) P_MobjCheckWater(player->mo); #ifndef SECTORSPECIALSAFTERTHINK -#ifdef POLYOBJECTS if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo)) -#endif - player->onconveyor = 0; + player->onconveyor = 0; // check special sectors : damage & secrets if (!player->spectator) @@ -12086,12 +12072,10 @@ void P_PlayerThink(player_t *player) // it lasts for one tic. player->pflags &= ~PF_FULLSTASIS; -#ifdef POLYOBJECTS if (player->onconveyor == 1) player->onconveyor = 3; else if (player->onconveyor == 3) player->cmomy = player->cmomx = 0; -#endif P_DoSuperStuff(player); P_CheckSneakerAndLivesTimer(player); @@ -12424,10 +12408,8 @@ void P_PlayerAfterThink(player_t *player) cmd = &player->cmd; #ifdef SECTORSPECIALSAFTERTHINK -#ifdef POLYOBJECTS if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo)) -#endif - player->onconveyor = 0; + player->onconveyor = 0; // check special sectors : damage & secrets if (!player->spectator) diff --git a/src/r_bsp.c b/src/r_bsp.c index 77ab2a82f..3bd023dbf 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -354,9 +354,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) { return ( -#ifdef POLYOBJECTS !line->polyseg && -#endif back->ceilingpic == front->ceilingpic && back->floorpic == front->floorpic && back->f_slope == front->f_slope @@ -482,13 +480,10 @@ static void R_AddLine(seg_t *line) if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then { - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - !line->sidedef->midtexture - && ((!frontsector->ffloors && !backsector->ffloors) - || (frontsector->tag == backsector->tag))) + if (!line->polyseg && + !line->sidedef->midtexture + && ((!frontsector->ffloors && !backsector->ffloors) + || (frontsector->tag == backsector->tag))) return; // line is empty, don't even bother goto clippass; // treat like wide open window instead @@ -654,8 +649,6 @@ static boolean R_CheckBBox(const fixed_t *bspcoord) return true; } -#ifdef POLYOBJECTS - size_t numpolys; // number of polyobjects in current subsector size_t num_po_ptrs; // number of polyobject pointers allocated polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers @@ -819,7 +812,6 @@ static void R_AddPolyObjects(subsector_t *sub) R_AddLine(po_ptrs[i]->segs[j]); } } -#endif // // R_Subsector @@ -896,11 +888,7 @@ static void R_Subsector(size_t num) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL -#ifdef POLYOBJECTS_PLANES - , NULL -#endif - , frontsector->f_slope); + frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope); } else floorplane = NULL; @@ -911,11 +899,7 @@ static void R_Subsector(size_t num) { ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, - ceilingcolormap, NULL -#ifdef POLYOBJECTS_PLANES - , NULL -#endif - , frontsector->c_slope); + ceilingcolormap, NULL, NULL, frontsector->c_slope); } else ceilingplane = NULL; @@ -963,11 +947,7 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, - *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover -#ifdef POLYOBJECTS_PLANES - , NULL -#endif - , *rover->b_slope); + *rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope); ffloor[numffloors].slope = *rover->b_slope; @@ -1000,11 +980,7 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, - *frontsector->lightlist[light].extra_colormap, rover -#ifdef POLYOBJECTS_PLANES - , NULL -#endif - , *rover->t_slope); + *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope); ffloor[numffloors].slope = *rover->t_slope; @@ -1019,7 +995,6 @@ static void R_Subsector(size_t num) } } -#ifdef POLYOBJECTS_PLANES // Polyobjects have planes, too! if (sub->polyList) { @@ -1085,7 +1060,6 @@ static void R_Subsector(size_t num) po = (polyobj_t *)(po->link.next); } } -#endif #ifdef FLOORSPLATS if (sub->splats) @@ -1108,21 +1082,15 @@ static void R_Subsector(size_t num) firstseg = NULL; -#ifdef POLYOBJECTS // haleyjd 02/19/06: draw polyobjects before static lines if (sub->polyList) R_AddPolyObjects(sub); -#endif while (count--) { // CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime); - if (!line->glseg -#ifdef POLYOBJECTS - && !line->polyseg // ignore segs that belong to polyobjects -#endif - ) - R_AddLine(line); + if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects + R_AddLine(line); line++; curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */ } diff --git a/src/r_bsp.h b/src/r_bsp.h index 1562b79f6..e2da8ebaf 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -40,13 +40,11 @@ void R_PortalClearClipSegs(INT32 start, INT32 end); void R_ClearDrawSegs(void); void R_RenderBSPNode(INT32 bspnum); -#ifdef POLYOBJECTS void R_SortPolyObjects(subsector_t *sub); extern size_t numpolys; // number of polyobjects in current subsector extern size_t num_po_ptrs; // number of polyobject pointers allocated extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers -#endif sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back); diff --git a/src/r_defs.h b/src/r_defs.h index 4a8f5be34..a36568192 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -28,8 +28,6 @@ #include "m_aatree.h" #endif -#define POLYOBJECTS - // // ClipWallSegment // Clips the given range of columns @@ -107,9 +105,7 @@ typedef struct fixed_t z; ///< Z coordinate. } degenmobj_t; -#ifdef POLYOBJECTS #include "p_polyobj.h" -#endif // Store fake planes in a resizable array insted of just by // heightsec. Allows for multiple fake planes. @@ -434,9 +430,7 @@ typedef struct line_s void *splats; // wallsplat_t list #endif INT32 firsttag, nexttag; // improves searches for tags. -#ifdef POLYOBJECTS polyobj_t *polyobj; // Belongs to a polyobject? -#endif char *text; // a concatenation of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 @@ -479,9 +473,7 @@ typedef struct subsector_s sector_t *sector; INT16 numlines; UINT16 firstline; -#ifdef POLYOBJECTS struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects -#endif #if 1//#ifdef FLOORSPLATS void *splats; // floorsplat_t list #endif @@ -584,10 +576,8 @@ typedef struct seg_s // Why slow things down by calculating lightlists for every thick side? size_t numlights; r_lightlist_t *rlights; -#ifdef POLYOBJECTS polyobj_t *polyseg; boolean dontrenderme; -#endif boolean glseg; } seg_t; diff --git a/src/r_plane.c b/src/r_plane.c index ca5aa758e..9b5a94340 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -337,11 +337,7 @@ static visplane_t *new_visplane(unsigned hash) // visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, - ffloor_t *pfloor -#ifdef POLYOBJECTS_PLANES - , polyobj_t *polyobj -#endif - , pslope_t *slope) + ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope) { visplane_t *check; unsigned hash; @@ -361,7 +357,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, } } -#ifdef POLYOBJECTS_PLANES if (polyobj) { if (polyobj->angle != 0) @@ -376,7 +371,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, yoff += polyobj->centerPt.y; } } -#endif // This appears to fix the Nimbus Ruins sky bug. if (picnum == skyflatnum && pfloor) @@ -390,12 +384,10 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, for (check = visplanes[hash]; check; check = check->next) { -#ifdef POLYOBJECTS_PLANES if (check->polyobj && pfloor) continue; if (polyobj != check->polyobj) continue; -#endif if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel && xoff == check->xoffs && yoff == check->yoffs @@ -426,9 +418,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, check->viewz = viewz; check->viewangle = viewangle; check->plangle = plangle; -#ifdef POLYOBJECTS_PLANES check->polyobj = polyobj; -#endif check->slope = slope; memset(check->top, 0xff, sizeof (check->top)); @@ -496,9 +486,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) new_pl->viewz = pl->viewz; new_pl->viewangle = pl->viewangle; new_pl->plangle = pl->plangle; -#ifdef POLYOBJECTS_PLANES new_pl->polyobj = pl->polyobj; -#endif new_pl->slope = pl->slope; pl = new_pl; pl->minx = start; @@ -523,11 +511,9 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) // INT32 unionl, unionh; // INT32 x; -#ifdef POLYOBJECTS_PLANES // Don't expand polyobject planes here - we do that on our own. if (pl->polyobj) return; -#endif if (pl->minx > start) pl->minx = start; if (pl->maxx < stop) pl->maxx = stop; @@ -603,11 +589,7 @@ void R_DrawPlanes(void) { for (pl = visplanes[i]; pl; pl = pl->next) { - if (pl->ffloor != NULL -#ifdef POLYOBJECTS_PLANES - || pl->polyobj != NULL -#endif - ) + if (pl->ffloor != NULL || pl->polyobj != NULL) continue; R_DrawSinglePlane(pl); @@ -961,7 +943,6 @@ void R_DrawSinglePlane(visplane_t *pl) #endif spanfunc = spanfuncs[BASEDRAWFUNC]; -#ifdef POLYOBJECTS_PLANES if (pl->polyobj && pl->polyobj->translucency != 0) { spanfunctype = SPANDRAWFUNC_TRANS; @@ -979,95 +960,98 @@ void R_DrawSinglePlane(visplane_t *pl) else light = LIGHTLEVELS-1; - } else -#endif - if (pl->ffloor) + } + else { - // Don't draw planes that shouldn't be drawn. - for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next) + if (pl->ffloor) { - if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA)) + // Don't draw planes that shouldn't be drawn. + for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next) { - if (pl->ffloor->flags & FF_EXTRA) + if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA)) { - // The plane is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) - && pl->height < *rover->topheight - && pl->height > *rover->bottomheight) - return; + if (pl->ffloor->flags & FF_EXTRA) + { + // The plane is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) + && pl->height < *rover->topheight + && pl->height > *rover->bottomheight) + return; + } } } - } - if (pl->ffloor->flags & FF_TRANSLUCENT) - { - spanfunctype = SPANDRAWFUNC_TRANS; - - // Hacked up support for alpha value in software mode Tails 09-24-2002 - if (pl->ffloor->alpha < 12) - return; // Don't even draw it - else if (pl->ffloor->alpha < 38) - ds_transmap = transtables + ((tr_trans90-1)<ffloor->alpha < 64) - ds_transmap = transtables + ((tr_trans80-1)<ffloor->alpha < 89) - ds_transmap = transtables + ((tr_trans70-1)<ffloor->alpha < 115) - ds_transmap = transtables + ((tr_trans60-1)<ffloor->alpha < 140) - ds_transmap = transtables + ((tr_trans50-1)<ffloor->alpha < 166) - ds_transmap = transtables + ((tr_trans40-1)<ffloor->alpha < 192) - ds_transmap = transtables + ((tr_trans30-1)<ffloor->alpha < 217) - ds_transmap = transtables + ((tr_trans20-1)<ffloor->alpha < 243) - ds_transmap = transtables + ((tr_trans10-1)<extra_colormap && (pl->extra_colormap->flags & CMF_FOG))) - light = (pl->lightlevel >> LIGHTSEGSHIFT); - else - light = LIGHTLEVELS-1; - } - else if (pl->ffloor->flags & FF_FOG) - { - spanfunctype = SPANDRAWFUNC_FOG; - light = (pl->lightlevel >> LIGHTSEGSHIFT); - } - else light = (pl->lightlevel >> LIGHTSEGSHIFT); - -#ifndef NOWATER - if (pl->ffloor->flags & FF_RIPPLE) - { - INT32 top, bottom; - - itswater = true; - if (spanfunctype == SPANDRAWFUNC_TRANS) + if (pl->ffloor->flags & FF_TRANSLUCENT) { - spanfunctype = SPANDRAWFUNC_WATER; + spanfunctype = SPANDRAWFUNC_TRANS; - // Copy the current scene, ugh - top = pl->high-8; - bottom = pl->low+8; + // Hacked up support for alpha value in software mode Tails 09-24-2002 + if (pl->ffloor->alpha < 12) + return; // Don't even draw it + else if (pl->ffloor->alpha < 38) + ds_transmap = transtables + ((tr_trans90-1)<ffloor->alpha < 64) + ds_transmap = transtables + ((tr_trans80-1)<ffloor->alpha < 89) + ds_transmap = transtables + ((tr_trans70-1)<ffloor->alpha < 115) + ds_transmap = transtables + ((tr_trans60-1)<ffloor->alpha < 140) + ds_transmap = transtables + ((tr_trans50-1)<ffloor->alpha < 166) + ds_transmap = transtables + ((tr_trans40-1)<ffloor->alpha < 192) + ds_transmap = transtables + ((tr_trans30-1)<ffloor->alpha < 217) + ds_transmap = transtables + ((tr_trans20-1)<ffloor->alpha < 243) + ds_transmap = transtables + ((tr_trans10-1)< vid.height) - bottom = vid.height; - - // Only copy the part of the screen we need - VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width), - vid.width, bottom-top, - vid.width, vid.width); + if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG))) + light = (pl->lightlevel >> LIGHTSEGSHIFT); + else + light = LIGHTLEVELS-1; } + else if (pl->ffloor->flags & FF_FOG) + { + spanfunctype = SPANDRAWFUNC_FOG; + light = (pl->lightlevel >> LIGHTSEGSHIFT); + } + else light = (pl->lightlevel >> LIGHTSEGSHIFT); + + #ifndef NOWATER + if (pl->ffloor->flags & FF_RIPPLE) + { + INT32 top, bottom; + + itswater = true; + if (spanfunctype == SPANDRAWFUNC_TRANS) + { + spanfunctype = SPANDRAWFUNC_WATER; + + // Copy the current scene, ugh + top = pl->high-8; + bottom = pl->low+8; + + if (top < 0) + top = 0; + if (bottom > vid.height) + bottom = vid.height; + + // Only copy the part of the screen we need + VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width), + vid.width, bottom-top, + vid.width, vid.width); + } + } + #endif } -#endif + else + light = (pl->lightlevel >> LIGHTSEGSHIFT); } - else light = (pl->lightlevel >> LIGHTSEGSHIFT); if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later && viewangle != pl->viewangle+pl->plangle) diff --git a/src/r_plane.h b/src/r_plane.h index a1a5b7a78..67fa19f38 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -47,9 +47,7 @@ typedef struct visplane_s fixed_t xoffs, yoffs; // Scrolling flats. struct ffloor_s *ffloor; -#ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; -#endif pslope_t *slope; } visplane_t; @@ -80,11 +78,7 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, - extracolormap_t *planecolormap, ffloor_t *ffloor -#ifdef POLYOBJECTS_PLANES - , polyobj_t *polyobj -#endif - , pslope_t *slope); + extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_PlaneBounds(visplane_t *plane); @@ -112,9 +106,7 @@ typedef struct planemgr_s struct pslope_s *slope; struct ffloor_s *ffloor; -#ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; -#endif } visffloor_t; extern visffloor_t ffloor[MAXFFLOORS]; diff --git a/src/r_segs.c b/src/r_segs.c index b6b4ca44c..6a838be79 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -610,7 +610,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // draw the texture col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); -//#ifdef POLYOBJECTS_PLANES #if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) { @@ -1309,10 +1308,8 @@ static void R_RenderSegLoop (void) for (i = 0; i < numffloors; i++) { -#ifdef POLYOBJECTS_PLANES if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg)) continue; -#endif if (ffloor[i].height < viewz) { @@ -1325,18 +1322,19 @@ static void R_RenderSegLoop (void) if (bottom_w > bottom) bottom_w = bottom; -#ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red - if (ffloor[i].polyobj && top_w >= bottom_w) { + if (ffloor[i].polyobj && top_w >= bottom_w) + { ffloor[i].plane->top[rw_x] = 0xFFFF; ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 - } else -#endif - - if (top_w <= bottom_w) + } + else { - ffloor[i].plane->top[rw_x] = (INT16)top_w; - ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + if (top_w <= bottom_w) + { + ffloor[i].plane->top[rw_x] = (INT16)top_w; + ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + } } } else if (ffloor[i].height > viewz) @@ -1350,18 +1348,19 @@ static void R_RenderSegLoop (void) if (bottom_w > bottom) bottom_w = bottom; -#ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red - if (ffloor[i].polyobj && top_w >= bottom_w) { + if (ffloor[i].polyobj && top_w >= bottom_w) + { ffloor[i].plane->top[rw_x] = 0xFFFF; ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 - } else -#endif - - if (top_w <= bottom_w) + } + else { - ffloor[i].plane->top[rw_x] = (INT16)top_w; - ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + if (top_w <= bottom_w) + { + ffloor[i].plane->top[rw_x] = (INT16)top_w; + ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + } } } } @@ -1818,10 +1817,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) { for (i = 0; i < numffloors; i++) { -#ifdef POLYOBJECTS_PLANES if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) continue; -#endif if (ffloor[i].slope) { ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; @@ -2328,33 +2325,40 @@ void R_StoreWallRange(INT32 start, INT32 stop) maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) -#ifdef POLYOBJECTS - if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up + if (curline->polyseg) + { // use REAL front and back floors please, so midtexture rendering isn't mucked up rw_midtextureslide = rw_midtexturebackslide = 0; if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; else rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; - } else -#endif - // Set midtexture starting height - if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing - rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; - else - rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + } + else + { + // Set midtexture starting height + if (linedef->flags & ML_EFFECT2) + { // Ignore slopes when texturing + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - rw_midtexturemid = worldbottom; - rw_midtextureslide = floorfrontslide; - rw_midtextureback = worldlow; - rw_midtexturebackslide = floorbackslide; - } else { - rw_midtexturemid = worldtop; - rw_midtextureslide = ceilingfrontslide; - rw_midtextureback = worldhigh; - rw_midtexturebackslide = ceilingbackslide; + } + else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + { + rw_midtexturemid = worldbottom; + rw_midtextureslide = floorfrontslide; + rw_midtextureback = worldlow; + rw_midtexturebackslide = floorbackslide; + } + else + { + rw_midtexturemid = worldtop; + rw_midtextureslide = ceilingfrontslide; + rw_midtextureback = worldhigh; + rw_midtexturebackslide = ceilingbackslide; + } } rw_midtexturemid += sidedef->rowoffset; rw_midtextureback += sidedef->rowoffset; @@ -2711,7 +2715,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } } -#ifdef POLYOBJECTS_PLANES if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) { while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; @@ -2750,7 +2753,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) i++; } } -#endif numbackffloors = i; } @@ -2804,7 +2806,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (i = 0; i < numffloors; i++) R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1); } -#ifdef POLYOBJECTS_PLANES // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red if (curline->polyseg) { @@ -2819,7 +2820,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].plane->maxx = rw_stopx - 1; } } -#endif } #ifdef WALLSPLATS diff --git a/src/r_things.c b/src/r_things.c index b4ffd4408..361cb1961 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1140,7 +1140,6 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) } #if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. -//#ifdef POLYOBJECTS // Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz if (thing->type == MT_RING) { @@ -2271,7 +2270,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps entry->ffloor = ds->thicksides[i]; } } -#ifdef POLYOBJECTS_PLANES // Check for a polyobject plane, but only if this is a front line if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) { plane = ds->curline->polyseg->visplane; @@ -2287,7 +2285,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } ds->curline->polyseg->visplane = NULL; } -#endif if (ds->maskedtexturecol) { entry = R_CreateDrawNode(head); @@ -2335,7 +2332,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (tempskip) return; -#ifdef POLYOBJECTS_PLANES // find all the remaining polyobject planes and add them on the end of the list // probably this is a terrible idea if we wanted them to be sorted properly // but it works getting them in for now @@ -2356,7 +2352,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps // note: no seg is set, for what should be obvious reasons PolyObjects[i].visplane = NULL; } -#endif // No vissprites in this mask? if (mask->vissprites[1] - mask->vissprites[0] == 0) From 1528f2aef8814e3841cf9e20d63d3fe9a7894008 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 2 May 2020 17:13:16 +0100 Subject: [PATCH 163/220] Fix drop shadow and rotsprite code to use SHORT() --- src/hardware/hw_main.c | 14 +++++++------- src/r_patch.c | 14 ++++++++++---- src/r_things.c | 30 +++++++++++++++--------------- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index be03ba083..927bad34c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4158,7 +4158,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale HWR_GetPatch(gpatch); scalemul = FixedMul(FRACUNIT - floordiff/640, scale); - scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); + scalemul = FixedMul(scalemul, (thing->radius*2) / SHORT(gpatch->height)); fscale = FIXED_TO_FLOAT(scalemul); fx = FIXED_TO_FLOAT(thing->x); @@ -4170,9 +4170,9 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale // 0--1 if (thing && fabsf(fscale - 1.0f) > 1.0E-36f) - offset = (gpatch->height/2) * fscale; + offset = (SHORT(gpatch->height)/2) * fscale; else - offset = (float)(gpatch->height/2); + offset = (float)(SHORT(gpatch->height)/2); shadowVerts[0].x = shadowVerts[3].x = fx - offset; shadowVerts[2].x = shadowVerts[1].x = fx + offset; @@ -5551,10 +5551,10 @@ static void HWR_ProjectSprite(mobj_t *thing) rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) { - spr_width = rotsprite->width << FRACBITS; - spr_height = rotsprite->height << FRACBITS; - spr_offset = rotsprite->leftoffset << FRACBITS; - spr_topoffset = rotsprite->topoffset << FRACBITS; + spr_width = SHORT(rotsprite->width) << FRACBITS; + spr_height = SHORT(rotsprite->height) << FRACBITS; + spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS; + spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS; // flip -> rotate, not rotate -> flip flip = 0; } diff --git a/src/r_patch.c b/src/r_patch.c index 9e31d4d19..ad4b3329a 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1231,9 +1231,9 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp if (!R_CheckIfPatch(lump)) return; - width = patch->width; - height = patch->height; - leftoffset = patch->leftoffset; + width = SHORT(patch->width); + height = SHORT(patch->height); + leftoffset = SHORT(patch->leftoffset); // rotation pivot px = SPRITE_XCENTER; @@ -1348,7 +1348,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp newpatch = R_MaskedFlatToPatch(rawdst, newwidth, newheight, 0, 0, &size); { newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px); - newpatch->topoffset = (newpatch->height / 2) + (patch->topoffset - py); + newpatch->topoffset = (newpatch->height / 2) + (SHORT(patch->topoffset) - py); } //BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer @@ -1358,6 +1358,12 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp // P_PrecacheLevel if (devparm) spritememory += size; + // convert everything to little-endian, for big-endian support + newpatch->width = SHORT(newpatch->width); + newpatch->height = SHORT(newpatch->height); + newpatch->leftoffset = SHORT(newpatch->leftoffset); + newpatch->topoffset = SHORT(newpatch->topoffset); + #ifdef HWRENDER if (rendermode == render_opengl) { diff --git a/src/r_things.c b/src/r_things.c index d2f3b4902..1956e1e7d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -890,7 +890,7 @@ static void R_DrawVisSprite(vissprite_t *vis) vis->x2 = vid.width-1; localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn; - lengthcol = patch->height; + lengthcol = SHORT(patch->height); // Split drawing loops for paper and non-paper to reduce conditional checks per sprite if (vis->scalestep) @@ -1235,8 +1235,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, yscale = FixedDiv(projectiony, tz); shadowxscale = FixedMul(thing->radius*2, scalemul); shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz)); - shadowyscale = min(shadowyscale, shadowxscale) / patch->height; - shadowxscale /= patch->width; + shadowyscale = min(shadowyscale, shadowxscale) / SHORT(patch->height); + shadowxscale /= SHORT(patch->width); shadowskew = 0; if (floorslope) @@ -1251,24 +1251,24 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); if (viewz < floorz) - shadowyscale += FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + shadowyscale += FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); else - shadowyscale -= FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + shadowyscale -= FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope); shadowyscale = abs(shadowyscale); shadowskew = xslope; } - tx -= patch->width * shadowxscale/2; + tx -= SHORT(patch->width) * shadowxscale/2; x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; if (x1 >= viewwidth) return; - tx += patch->width * shadowxscale; + tx += SHORT(patch->width) * shadowxscale; x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; if (x2 < 0 || x2 <= x1) return; - if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes? + if (shadowyscale < FRACUNIT/SHORT(patch->height)) return; // fix some crashes? shadow = R_NewVisSprite(); shadow->patch = patch; @@ -1283,8 +1283,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->dispoffset = vis->dispoffset - 5; shadow->gx = thing->x; shadow->gy = thing->y; - shadow->gzt = shadow->pz + shadow->patch->height * shadowyscale / 2; - shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale; + shadow->gzt = shadow->pz + SHORT(patch->height) * shadowyscale / 2; + shadow->gz = shadow->gzt - SHORT(patch->height) * shadowyscale; shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale); @@ -1305,7 +1305,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->startfrac = 0; //shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2); - shadow->xiscale = (patch->width<xiscale = (SHORT(patch->width)<x1 > x1) shadow->startfrac += shadow->xiscale*(shadow->x1-x1); @@ -1534,10 +1534,10 @@ static void R_ProjectSprite(mobj_t *thing) rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) { - spr_width = rotsprite->width << FRACBITS; - spr_height = rotsprite->height << FRACBITS; - spr_offset = rotsprite->leftoffset << FRACBITS; - spr_topoffset = rotsprite->topoffset << FRACBITS; + spr_width = SHORT(rotsprite->width) << FRACBITS; + spr_height = SHORT(rotsprite->height) << FRACBITS; + spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS; + spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS; // flip -> rotate, not rotate -> flip flip = 0; } From 887c25e04757c7e6af4f5c40a666842485da5394 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 2 May 2020 17:39:55 -0400 Subject: [PATCH 164/220] Remove inline keyword from P_DoTwinSpin function The compiler doesn't like this and will give you a "inlining failed in call to 'P_DoTwinSpin': call is unlikely and code size would grow" error --- 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 4991c3065..9df71587d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5004,7 +5004,7 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range) player->pflags |= PF_THOKKED; } -static inline void P_DoTwinSpin(player_t *player) +static void P_DoTwinSpin(player_t *player) { player->pflags &= ~PF_NOJUMPDAMAGE; player->pflags |= P_GetJumpFlags(player) | PF_THOKKED; From 0d7c49e7e4c9da6e84f6d5d182940bf49f178e1f Mon Sep 17 00:00:00 2001 From: ZipperQR Date: Sun, 3 May 2020 13:59:00 +0300 Subject: [PATCH 165/220] no message --- src/p_enemy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 58f09cacb..e83e4cd4f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13288,8 +13288,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) if (!player) return true; - if (abs(thing->x - dustdevil->x) > dustdevil->radius || abs(thing->y - dustdevil->y) > dustdevil->radius) + if (abs(thing->x - dustdevil->x) > dustdevil->radius || abs(thing->y - dustdevil->y) > dustdevil->radius){ return true; + } if (thing->z + thing->height >= dustdevil->z && dustdevil->z + dustdevil->height >= thing->z) { fixed_t pos = thing->z - dustdevil->z; From dd50990e85199f80d93ed19d2b419d9b944096b3 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 3 May 2020 15:22:13 +0200 Subject: [PATCH 166/220] Add "trigger egg capsule" linedef executor --- extras/conf/SRB2-22.cfg | 8 ++++++++ src/p_spec.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index ea783908a..75563e505 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -2218,6 +2218,13 @@ linedeftypes prefix = "(462)"; flags8text = "[3] Set delay by backside sector"; } + + 464 + { + title = "Trigger Egg Capsule"; + prefix = "(464)"; + flags64text = "[6] Don't end level"; + } } linedefexecmisc @@ -3704,6 +3711,7 @@ thingtypes width = 8; height = 16; sprite = "internal:capsule"; + angletext = "Tag"; } 292 { diff --git a/src/p_spec.c b/src/p_spec.c index cebab0902..e7a600875 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4010,6 +4010,47 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } break; + case 464: // Trigger Egg Capsule + { + thinker_t *th; + mobj_t *mo2; + + // Find the center of the Eggtrap and release all the pretty animals! + // The chimps are my friends.. heeheeheheehehee..... - LouisJM + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo2 = (mobj_t *)th; + + if (mo2->type != MT_EGGTRAP) + continue; + + if (!mo2->spawnpoint) + continue; + + if (mo2->spawnpoint->angle != line->tag) + continue; + + P_KillMobj(mo2, NULL, mo, 0); + } + + if (!(line->flags & ML_NOCLIMB)) + { + INT32 i; + + // Mark all players with the time to exit thingy! + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + P_DoPlayerExit(&players[i]); + } + } + } + break; + #ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing From 1b66d1f936521262f33406095ae3d4f139b474f3 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 3 May 2020 15:57:18 +0200 Subject: [PATCH 167/220] Add object dye linedef executors to ZB config --- extras/conf/SRB2-22.cfg | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index ea783908a..1c1d11809 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -1908,6 +1908,27 @@ linedeftypes prefix = "(333)"; } + 334 + { + title = "Object Dye - Continuous"; + flags64text = "[6] Disable for this color"; + prefix = "(334)"; + } + + 335 + { + title = "Object Dye - Each Time"; + flags64text = "[6] Disable for this color"; + prefix = "(335)"; + } + + 336 + { + title = "Object Dye - Once"; + flags64text = "[6] Disable for this color"; + prefix = "(336)"; + } + 399 { title = "Level Load"; @@ -2218,6 +2239,12 @@ linedeftypes prefix = "(462)"; flags8text = "[3] Set delay by backside sector"; } + + 463 + { + title = "Dye Object"; + prefix = "(463)"; + } } linedefexecmisc From 4b87bee759ce8e67069228688b7a32fab8f3c4b6 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 3 May 2020 17:56:49 +0200 Subject: [PATCH 168/220] Add level header options for setting special stage time and spheres requirements --- src/dehacked.c | 4 ++++ src/doomstat.h | 2 ++ src/lua_maplib.c | 4 ++++ src/p_setup.c | 2 ++ src/p_spec.c | 4 ++-- 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e9d029be0..c05a8f444 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1863,6 +1863,10 @@ static void readlevelheader(MYFILE *f, INT32 num) } else if (fastcmp(word, "STARTRINGS")) mapheaderinfo[num-1]->startrings = (UINT16)i; + else if (fastcmp(word, "SPECIALSTAGETIME")) + mapheaderinfo[num-1]->sstimer = i; + else if (fastcmp(word, "SPECIALSTAGESPHERES")) + mapheaderinfo[num-1]->ssspheres = i; else deh_warning("Level header %d: unknown word '%s'", num, word); } diff --git a/src/doomstat.h b/src/doomstat.h index aedb120ff..e6a227a42 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -319,6 +319,8 @@ typedef struct char selectheading[22]; ///< Level select heading. Allows for controllable grouping. UINT16 startrings; ///< Number of rings players start with. + INT32 sstimer; ///< Timer for special stages. + UINT32 ssspheres; ///< Sphere requirement in special stages. // Title card. char ltzzpatch[8]; ///< Zig zag patch. diff --git a/src/lua_maplib.c b/src/lua_maplib.c index d851c820e..1737216e3 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2082,6 +2082,10 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->menuflags); else if (fastcmp(field,"startrings")) lua_pushinteger(L, header->startrings); + else if (fastcmp(field, "sstimer")) + lua_pushinteger(L, header->sstimer); + else if (fastcmp(field, "ssspheres")) + lua_pushinteger(L, header->ssspheres); // TODO add support for reading numGradedMares and grades else { // Read custom vars now diff --git a/src/p_setup.c b/src/p_setup.c index b3b618e51..1d1826a53 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -218,6 +218,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->nextlevel = (INT16)(i + 1); mapheaderinfo[num]->startrings = 0; + mapheaderinfo[num]->sstimer = 90; + mapheaderinfo[num]->ssspheres = 1; mapheaderinfo[num]->keywords[0] = '\0'; snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); mapheaderinfo[num]->musname[6] = 0; diff --git a/src/p_spec.c b/src/p_spec.c index c93846438..fafe2cdf3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6249,8 +6249,8 @@ void P_InitSpecials(void) gravity = FRACUNIT/2; // Defaults in case levels don't have them set. - sstimer = 90*TICRATE + 6; - ssspheres = 1; + sstimer = mapheaderinfo[gamemap-1]->sstimer*TICRATE + 6; + ssspheres = mapheaderinfo[gamemap-1]->ssspheres; CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false; From 700b340827cbe8da1bee2afa423d3666be4fad5f Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 3 May 2020 18:33:18 +0200 Subject: [PATCH 169/220] Allow map-wide gravity to be set via level header --- src/dehacked.c | 2 ++ src/doomstat.h | 3 ++- src/lua_maplib.c | 2 ++ src/p_setup.c | 1 + src/p_spec.c | 2 +- 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c05a8f444..268f9943c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1867,6 +1867,8 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->sstimer = i; else if (fastcmp(word, "SPECIALSTAGESPHERES")) mapheaderinfo[num-1]->ssspheres = i; + else if (fastcmp(word, "GRAVITY")) + mapheaderinfo[num-1]->gravity = FLOAT_TO_FIXED(atof(word2)); else deh_warning("Level header %d: unknown word '%s'", num, word); } diff --git a/src/doomstat.h b/src/doomstat.h index e6a227a42..1ec03a86c 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -320,7 +320,8 @@ typedef struct char selectheading[22]; ///< Level select heading. Allows for controllable grouping. UINT16 startrings; ///< Number of rings players start with. INT32 sstimer; ///< Timer for special stages. - UINT32 ssspheres; ///< Sphere requirement in special stages. + UINT32 ssspheres; ///< Sphere requirement in special stages. + fixed_t gravity; ///< Map-wide gravity. // Title card. char ltzzpatch[8]; ///< Zig zag patch. diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 1737216e3..ece42b8d3 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2086,6 +2086,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->sstimer); else if (fastcmp(field, "ssspheres")) lua_pushinteger(L, header->ssspheres); + else if (fastcmp(field, "gravity")) + lua_pushfixed(L, header->gravity); // TODO add support for reading numGradedMares and grades else { // Read custom vars now diff --git a/src/p_setup.c b/src/p_setup.c index 1d1826a53..b4a5f2c3c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -220,6 +220,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->startrings = 0; mapheaderinfo[num]->sstimer = 90; mapheaderinfo[num]->ssspheres = 1; + mapheaderinfo[num]->gravity = FRACUNIT/2; mapheaderinfo[num]->keywords[0] = '\0'; snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); mapheaderinfo[num]->musname[6] = 0; diff --git a/src/p_spec.c b/src/p_spec.c index fafe2cdf3..2e5b1f44b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6246,7 +6246,7 @@ static void P_RunLevelLoadExecutors(void) void P_InitSpecials(void) { // Set the default gravity. Custom gravity overrides this setting. - gravity = FRACUNIT/2; + gravity = mapheaderinfo[gamemap-1]->gravity; // Defaults in case levels don't have them set. sstimer = mapheaderinfo[gamemap-1]->sstimer*TICRATE + 6; From 5de11441a195591b1f619fd42133c76051467372 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 3 May 2020 23:47:26 +0200 Subject: [PATCH 170/220] Remove "explicitly include line in polyobject" code which has never worked --- src/p_polyobj.c | 106 ++---------------------------------------------- src/p_polyobj.h | 1 - 2 files changed, 3 insertions(+), 104 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 0431707ac..9173aa12a 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -490,84 +490,6 @@ newseg: CONS_Debug(DBG_POLYOBJ, "Polyobject %d is not closed\n", po->id); } -/* -// structure used to store segs during explicit search process -typedef struct segitem_s -{ - seg_t *seg; - INT32 num; -} segitem_t; - -// -// Polyobj_segCompare -// -// Callback for qsort that compares two segitems. -// -static int Polyobj_segCompare(const void *s1, const void *s2) -{ - const segitem_t *si1 = s1; - const segitem_t *si2 = s2; - - return si2->num - si1->num; -} - -// -// Polyobj_findExplicit -// -// Searches for segs to put into a polyobject in an explicitly provided order. -// -static void Polyobj_findExplicit(polyobj_t *po) -{ - // temporary dynamic seg array - segitem_t *segitems = NULL; - size_t numSegItems = 0; - size_t numSegItemsAlloc = 0; - - size_t i; - - // first loop: save off all segs with polyobject's id number - for (i = 0; i < numsegs; ++i) - { - INT32 polyID, parentID; - - if (segs[i].linedef->special != POLYOBJ_EXPLICIT_LINE) - continue; - - Polyobj_GetInfo(segs[i].linedef->tag, &polyID, &parentID, NULL); - - if (polyID == po->id && parentID > 0) - { - if (numSegItems >= numSegItemsAlloc) - { - numSegItemsAlloc = numSegItemsAlloc ? numSegItemsAlloc*2 : 4; - segitems = Z_Realloc(segitems, numSegItemsAlloc*sizeof(segitem_t), PU_STATIC, NULL); - } - segitems[numSegItems].seg = &segs[i]; - segitems[numSegItems].num = parentID; - ++numSegItems; - } - } - - // make sure array isn't empty - if (numSegItems == 0) - { - po->isBad = true; - CONS_Debug(DBG_POLYOBJ, "Polyobject %d is empty\n", po->id); - return; - } - - // sort the array if necessary - if (numSegItems >= 2) - qsort(segitems, numSegItems, sizeof(segitem_t), Polyobj_segCompare); - - // second loop: put the sorted segs into the polyobject - for (i = 0; i < numSegItems; ++i) - Polyobj_addSeg(po, segitems[i].seg); - - // free the temporary array - Z_Free(segitems); -}*/ - // Setup functions // @@ -598,9 +520,9 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) po->thrust = FRACUNIT; po->spawnflags = po->flags = 0; - // 1. Search segs for "line start" special with tag matching this - // polyobject's id number. If found, iterate through segs which - // share common vertices and record them into the polyobject. + // Search segs for "line start" special with tag matching this + // polyobject's id number. If found, iterate through segs which + // share common vertices and record them into the polyobject. for (i = 0; i < numsegs; ++i) { seg_t *seg = &segs[i]; @@ -639,29 +561,7 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) if (po->isBad) return; - /* - // 2. If no such line existed in the first step, look for a seg with the - // "explicit" special with tag matching this polyobject's id number. If - // found, continue to search for all such lines, storing them in a - // temporary list of segs which is then copied into the polyobject in - // sorted order. - if (po->segCount == 0) - { - UINT16 parent; - Polyobj_findExplicit(po); - // if an error occurred above, quit processing this object - if (po->isBad) - return; - - Polyobj_GetInfo(po->segs[0]->linedef->tag, NULL, NULL, &parent); - po->parent = parent; - if (po->parent == po->id) // do not allow a self-reference - po->parent = -1; - // TODO: sound sequence is in args[3] - }*/ - // make sure array isn't empty - // since Polyobj_findExplicit is disabled currently, we have to do things here instead now! if (po->segCount == 0) { po->isBad = true; diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 7dfc90ce9..fd660761e 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -29,7 +29,6 @@ #define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE #define POLYOBJ_START_LINE 20 -#define POLYOBJ_EXPLICIT_LINE 21 #define POLYINFO_SPECIALNUM 22 typedef enum From b82c3c2089fd5a2f0459229f335495bbd6056363 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 3 May 2020 23:55:23 +0200 Subject: [PATCH 171/220] Clean up Polyobj_GetInfo --- src/p_polyobj.c | 38 +++++++++++++++++--------------------- src/p_polyobj.h | 1 - 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 9173aa12a..2cde29da4 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -230,36 +230,38 @@ boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox) // Finds the 'polyobject settings' linedef for a polyobject // the polyobject's id should be set as its tag // -void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans) +static void Polyobj_GetInfo(polyobj_t *po) { - INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, poid, -1); + INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, po->id, -1); if (i == -1) return; // no extra settings to apply, let's leave it - if (parentID) - *parentID = lines[i].frontsector->special; + po->parent = lines[i].frontsector->special; + if (po->parent == po->id) // do not allow a self-reference + po->parent = -1; - if (potrans) - *potrans = (lines[i].frontsector->floorheight>>FRACBITS) / 100; + po->translucency = (lines[i].frontsector->floorheight>>FRACBITS) / 100; + + po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; if (lines[i].flags & ML_EFFECT1) - *poflags |= POF_ONESIDE; + po->flags |= POF_ONESIDE; if (lines[i].flags & ML_EFFECT2) - *poflags &= ~POF_SOLID; + po->flags &= ~POF_SOLID; if (lines[i].flags & ML_EFFECT3) - *poflags |= POF_PUSHABLESTOP; + po->flags |= POF_PUSHABLESTOP; if (lines[i].flags & ML_EFFECT4) - *poflags |= POF_RENDERPLANES; + po->flags |= POF_RENDERPLANES; /*if (lines[i].flags & ML_EFFECT5) - *poflags &= ~POF_CLIPPLANES;*/ + po->flags &= ~POF_CLIPPLANES;*/ if (lines[i].flags & ML_NOCLIMB) // Has a linedef executor - *poflags |= POF_LDEXEC; + po->flags |= POF_LDEXEC; } // Reallocating array maintenance @@ -526,8 +528,6 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) for (i = 0; i < numsegs; ++i) { seg_t *seg = &segs[i]; - INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; - INT32 parentID = 0, potrans = 0; if (seg->glseg) continue; @@ -541,17 +541,13 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) if (seg->linedef->tag != po->id) continue; - Polyobj_GetInfo(po->id, &poflags, &parentID, &potrans); // apply extra settings if they exist! + Polyobj_GetInfo(po); // apply extra settings if they exist! // save original flags and translucency to reference later for netgames! - po->spawnflags = po->flags = poflags; - po->spawntrans = po->translucency = potrans; + po->spawnflags = po->flags; + po->spawntrans = po->translucency; Polyobj_findSegs(po, seg); - po->parent = parentID; - if (po->parent == po->id) // do not allow a self-reference - po->parent = -1; - // TODO: sound sequence is in args[2] break; } diff --git a/src/p_polyobj.h b/src/p_polyobj.h index fd660761e..4f022013f 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -319,7 +319,6 @@ boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y); boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo); boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo); boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox); -void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans); // thinkers (needed in p_saveg.c) void T_PolyObjRotate(polyrotate_t *); From 8ae635c7ba13ae9b3fbc7394acd91852a9d6c045 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 4 May 2020 00:17:05 +0200 Subject: [PATCH 172/220] Purge uninformative comments --- src/p_polyobj.c | 151 ++---------------------------------------------- 1 file changed, 4 insertions(+), 147 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 2cde29da4..69b002242 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -140,11 +140,6 @@ FUNCINLINE static ATTRINLINE void Polyobj_vecSub2(vertex_t *dst, vertex_t *v1, v dst->y = v1->y - v2->y; } -// -// P_PointInsidePolyobj -// -// Returns TRUE if the XY point is inside the polyobject -// boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y) { size_t i; @@ -158,11 +153,6 @@ boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y) return true; } -// -// P_MobjTouchingPolyobj -// -// Returns TRUE if the mobj is touching the edge of a polyobject -// boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo) { fixed_t mbbox[4]; @@ -182,11 +172,6 @@ boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo) return false; } -// -// P_MobjInsidePolyobj -// -// Returns TRUE if the mobj is inside the polyobject -// boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo) { fixed_t mbbox[4]; @@ -206,11 +191,6 @@ boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo) return true; } -// -// P_BBoxInsidePolyobj -// -// Returns TRUE if the bbox is inside the polyobject -// boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox) { size_t i; @@ -224,12 +204,8 @@ boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox) return true; } -// -// Polyobj_GetInfo -// // Finds the 'polyobject settings' linedef for a polyobject // the polyobject's id should be set as its tag -// static void Polyobj_GetInfo(polyobj_t *po) { INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, po->id, -1); @@ -266,15 +242,11 @@ static void Polyobj_GetInfo(polyobj_t *po) // Reallocating array maintenance -// -// Polyobj_addVertex -// // Adds a vertex to a polyobject's reallocating vertex arrays, provided // that such a vertex isn't already in the array. Each vertex must only // be translated once during polyobject movement. Keeping track of them // this way results in much more clear and efficient code than what // Hexen used. -// static void Polyobj_addVertex(polyobj_t *po, vertex_t *v) { size_t i; @@ -310,14 +282,10 @@ static void Polyobj_addVertex(polyobj_t *po, vertex_t *v) po->numVertices++; } -// -// Polyobj_addLine -// // Adds a linedef to a polyobject's reallocating linedefs array, provided // that such a linedef isn't already in the array. Each linedef must only // be adjusted once during polyobject movement. Keeping track of them // this way provides the same benefits as for vertices. -// static void Polyobj_addLine(polyobj_t *po, line_t *l) { size_t i; @@ -342,14 +310,10 @@ static void Polyobj_addLine(polyobj_t *po, line_t *l) po->lines[po->numLines++] = l; } -// -// Polyobj_addSeg -// // Adds a single seg to a polyobject's reallocating seg pointer array. // Most polyobjects will have between 4 and 16 segs, so the array size // begins much smaller than usual. Calls Polyobj_addVertex and Polyobj_addLine // to add those respective structures for this seg, as well. -// static void Polyobj_addSeg(polyobj_t *po, seg_t *seg) { if (po->segCount >= po->numSegsAlloc) @@ -375,14 +339,10 @@ static void Polyobj_addSeg(polyobj_t *po, seg_t *seg) // Seg-finding functions -// -// Polyobj_findSegs -// // This method adds segs to a polyobject by following segs from vertex to // vertex. The process stops when the original starting point is reached // or if a particular search ends unexpectedly (ie, the polyobject is not // closed). -// static void Polyobj_findSegs(polyobj_t *po, seg_t *seg) { fixed_t startx, starty; @@ -494,11 +454,6 @@ newseg: // Setup functions -// -// Polyobj_spawnPolyObj -// -// Sets up a Polyobject. -// static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) { size_t i; @@ -586,12 +541,8 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) static void Polyobj_attachToSubsec(polyobj_t *po); -// -// Polyobj_moveToSpawnSpot -// // Translates the polyobject's vertices with respect to the difference between // the anchor and spawn spots. Updates linedef bounding boxes as well. -// static void Polyobj_moveToSpawnSpot(mapthing_t *anchor) { polyobj_t *po; @@ -638,11 +589,7 @@ static void Polyobj_moveToSpawnSpot(mapthing_t *anchor) Polyobj_attachToSubsec(po); } -// -// Polyobj_attachToSubsec -// // Attaches a polyobject to its appropriate subsector. -// static void Polyobj_attachToSubsec(polyobj_t *po) { subsector_t *ss; @@ -677,11 +624,7 @@ static void Polyobj_attachToSubsec(polyobj_t *po) po->attached = true; } -// -// Polyobj_removeFromSubsec -// // Removes a polyobject from the subsector to which it is attached. -// static void Polyobj_removeFromSubsec(polyobj_t *po) { if (po->attached) @@ -693,11 +636,7 @@ static void Polyobj_removeFromSubsec(polyobj_t *po) // Blockmap Functions -// -// Polyobj_getLink -// // Retrieves a polymaplink object from the free list or creates a new one. -// static polymaplink_t *Polyobj_getLink(void) { polymaplink_t *l; @@ -716,11 +655,7 @@ static polymaplink_t *Polyobj_getLink(void) return l; } -// -// Polyobj_putLink -// // Puts a polymaplink object into the free list. -// static void Polyobj_putLink(polymaplink_t *l) { memset(l, 0, sizeof(*l)); @@ -728,14 +663,10 @@ static void Polyobj_putLink(polymaplink_t *l) bmap_freelist = l; } -// -// Polyobj_linkToBlockmap -// // Inserts a polyobject into the polyobject blockmap. Unlike, mobj_t's, // polyobjects need to be linked into every blockmap cell which their // bounding box intersects. This ensures the accurate level of clipping // which is present with linedefs but absent from most mobj interactions. -// static void Polyobj_linkToBlockmap(polyobj_t *po) { fixed_t *blockbox = po->blockbox; @@ -780,12 +711,8 @@ static void Polyobj_linkToBlockmap(polyobj_t *po) po->linked = true; } -// -// Polyobj_removeFromBlockmap -// // Unlinks a polyobject from all blockmap cells it intersects and returns // its polymaplink objects to the free list. -// static void Polyobj_removeFromBlockmap(polyobj_t *po) { polymaplink_t *rover; @@ -824,13 +751,9 @@ static void Polyobj_removeFromBlockmap(polyobj_t *po) // Movement functions -// -// Polyobj_untouched -// // A version of Lee's routine from p_maputl.c that accepts an mobj pointer // argument instead of using tmthing. Returns true if the line isn't contacted // and false otherwise. -// static inline boolean Polyobj_untouched(line_t *ld, mobj_t *mo) { fixed_t x, y, ptmbbox[4]; @@ -843,13 +766,9 @@ static inline boolean Polyobj_untouched(line_t *ld, mobj_t *mo) P_BoxOnLineSide(ptmbbox, ld) != -1; } -// -// Polyobj_pushThing -// // Inflicts thrust and possibly damage on a thing which has been found to be // blocking the motion of a polyobject. The default thrust amount is only one // unit, but the motion of the polyobject can be used to change this. -// static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo) { angle_t lineangle; @@ -884,11 +803,7 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo) } } -// -// Polyobj_slideThing -// // Moves an object resting on top of a polyobject by (x, y). Template function to make alteration easier. -// static void Polyobj_slideThing(mobj_t *mo, fixed_t dx, fixed_t dy) { if (mo->player) { // Finally this doesn't suck eggs -fickle @@ -936,11 +851,7 @@ static void Polyobj_slideThing(mobj_t *mo, fixed_t dx, fixed_t dy) P_TryMove(mo, mo->x+dx, mo->y+dy, true); } -// -// Polyobj_carryThings -// // Causes objects resting on top of the polyobject to 'ride' with its movement. -// static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) { static INT32 pomovecount = 0; @@ -992,12 +903,8 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy) } } -// -// Polyobj_clipThings -// // Checks for things that are in the way of a polyobject line move. // Returns true if something was hit. -// static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) { INT32 hitflags = 0; @@ -1059,11 +966,8 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line) return hitflags; } -// -// Polyobj_moveXY -// + // Moves a polyobject on the x-y plane. -// static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs) { size_t i; @@ -1119,14 +1023,10 @@ static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean check return !(hitflags & 2); } -// -// Polyobj_rotatePoint -// // Rotates a point and then translates it relative to point c. // The formula for this can be found here: // http://www.inversereality.org/tutorials/graphics%20programming/2dtransformations.html // It is, of course, just a vector-matrix multiplication. -// static inline void Polyobj_rotatePoint(vertex_t *v, const vertex_t *c, angle_t ang) { vertex_t tmp = *v; @@ -1138,12 +1038,8 @@ static inline void Polyobj_rotatePoint(vertex_t *v, const vertex_t *c, angle_t a v->y += c->y; } -// -// Polyobj_rotateLine -// // Taken from P_LoadLineDefs; simply updates the linedef's dx, dy, slopetype, // and bounding box to be consistent with its vertices. -// static void Polyobj_rotateLine(line_t *ld) { vertex_t *v1, *v2; @@ -1183,11 +1079,7 @@ static void Polyobj_rotateLine(line_t *ld) } } -// -// Polyobj_rotateThings -// // Causes objects resting on top of the rotating polyobject to 'ride' with its movement. -// static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, UINT8 turnthings) { static INT32 pomovecount = 10000; @@ -1263,11 +1155,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, } } -// -// Polyobj_rotate -// // Rotates a polyobject around its start point. -// static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs) { size_t i; @@ -1341,12 +1229,8 @@ static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, bo // Global Functions // -// -// Polyobj_GetForNum -// // Retrieves a polyobject by its numeric id using hashing. // Returns NULL if no such polyobject exists. -// polyobj_t *Polyobj_GetForNum(INT32 id) { INT32 curidx = PolyObjects[id % numPolyObjects].first; @@ -1357,12 +1241,9 @@ polyobj_t *Polyobj_GetForNum(INT32 id) return curidx == numPolyObjects ? NULL : &PolyObjects[curidx]; } -// -// Polyobj_GetParent -// + // Retrieves the parenting polyobject if one exists. Returns NULL // otherwise. -// #if 0 //unused function static polyobj_t *Polyobj_GetParent(polyobj_t *po) { @@ -1370,12 +1251,8 @@ static polyobj_t *Polyobj_GetParent(polyobj_t *po) } #endif -// -// Polyobj_GetChild -// // Iteratively retrieves the children POs of a parent, // sorta like P_FindSectorSpecialFromTag. -// static polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start) { for (; *start < numPolyObjects; (*start)++) @@ -1394,12 +1271,8 @@ typedef struct mobjqitem_s mobj_t *mo; } mobjqitem_t; -// -// Polyobj_InitLevel -// // Called at the beginning of each map after all other line and thing // processing is finished. -// void Polyobj_InitLevel(void) { thinker_t *th; @@ -1518,9 +1391,6 @@ void Polyobj_InitLevel(void) M_QueueFree(&anchorqueue); } -// -// Polyobj_MoveOnLoad -// // Called when a savegame is being loaded. Rotates and translates an // existing polyobject to its position when the game was saved. // @@ -1545,11 +1415,7 @@ void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y) // Thinker Functions -// -// T_PolyObjRotate -// // Thinker function for PolyObject rotation. -// void T_PolyObjRotate(polyrotate_t *th) { polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); @@ -1610,11 +1476,7 @@ void T_PolyObjRotate(polyrotate_t *th) } } -// -// Polyobj_componentSpeed -// // Calculates the speed components from the desired resultant velocity. -// FUNCINLINE static ATTRINLINE void Polyobj_componentSpeed(INT32 resVel, INT32 angle, fixed_t *xVel, fixed_t *yVel) { @@ -1695,11 +1557,6 @@ void T_PolyObjMove(polymove_t *th) } } -// -// T_PolyObjWaypoint -// -// Kinda like 'Zoom Tubes for PolyObjects' -// void T_PolyObjWaypoint(polywaypoint_t *th) { mobj_t *mo2; @@ -2193,7 +2050,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th) } } -// T_PolyObjDisplace: shift a polyobject based on a control sector's heights. +// Shift a polyobject based on a control sector's heights. void T_PolyObjDisplace(polydisplace_t *th) { polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); @@ -2233,7 +2090,7 @@ void T_PolyObjDisplace(polydisplace_t *th) th->oldHeights = newheights; } -// T_PolyObjRotDisplace: rotate a polyobject based on a control sector's heights. +// Rotate a polyobject based on a control sector's heights. void T_PolyObjRotDisplace(polyrotdisplace_t *th) { polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); From 02c347ada269131bfc61f9eeeb98180112b7f96b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 4 May 2020 01:28:21 +0200 Subject: [PATCH 173/220] Refactor Polyobj_findSegs --- src/p_polyobj.c | 126 +++++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 59 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 69b002242..5c71e356a 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -356,25 +356,29 @@ static void Polyobj_findSegs(polyobj_t *po, seg_t *seg) // Find backfacings for (s = 0; s < numsegs; s++) { + size_t r; + if (segs[s].glseg) continue; - if (segs[s].linedef == seg->linedef - && segs[s].side == 1) + + if (segs[s].linedef != seg->linedef) + continue; + + if (segs[s].side != 1) + continue; + + for (r = 0; r < po->segCount; r++) { - size_t r; - for (r = 0; r < po->segCount; r++) - { - if (po->segs[r] == &segs[s]) - break; - } - - if (r != po->segCount) - continue; - - segs[s].dontrenderme = true; - - Polyobj_addSeg(po, &segs[s]); + if (po->segs[r] == &segs[s]) + break; } + + if (r != po->segCount) + continue; + + segs[s].dontrenderme = true; + + Polyobj_addSeg(po, &segs[s]); } } @@ -394,56 +398,60 @@ newseg: // seg's ending vertex. for (i = 0; i < numsegs; ++i) { + size_t q; + if (segs[i].glseg) continue; if (segs[i].side != 0) // needs to be frontfacing continue; - if (segs[i].v1->x == seg->v2->x && segs[i].v1->y == seg->v2->y) + if (segs[i].v1->x != seg->v2->x) + continue; + if (segs[i].v1->y != seg->v2->y) + continue; + + // Make sure you didn't already add this seg... + for (q = 0; q < po->segCount; q++) { - // Make sure you didn't already add this seg... - size_t q; - for (q = 0; q < po->segCount; q++) - { - if (po->segs[q] == &segs[i]) - break; - } - - if (q != po->segCount) - continue; - - // add the new seg and recurse - Polyobj_addSeg(po, &segs[i]); - seg = &segs[i]; - - if (!(po->flags & POF_ONESIDE)) - { - // Find backfacings - for (q = 0; q < numsegs; q++) - { - if (segs[q].glseg) - continue; - - if (segs[q].linedef == segs[i].linedef - && segs[q].side == 1) - { - size_t r; - for (r=0; r < po->segCount; r++) - { - if (po->segs[r] == &segs[q]) - break; - } - - if (r != po->segCount) - continue; - - segs[q].dontrenderme = true; - Polyobj_addSeg(po, &segs[q]); - } - } - } - - goto newseg; + if (po->segs[q] == &segs[i]) + break; } + + if (q != po->segCount) + continue; + + // add the new seg and recurse + Polyobj_addSeg(po, &segs[i]); + seg = &segs[i]; + + if (!(po->flags & POF_ONESIDE)) + { + // Find backfacings + for (q = 0; q < numsegs; q++) + { + size_t r; + + if (segs[q].glseg) + continue; + if (segs[q].linedef != segs[i].linedef) + continue; + if (segs[q].side != 1) + continue; + + for (r = 0; r < po->segCount; r++) + { + if (po->segs[r] == &segs[q]) + break; + } + + if (r != po->segCount) + continue; + + segs[q].dontrenderme = true; + Polyobj_addSeg(po, &segs[q]); + } + } + + goto newseg; } // error: if we reach here, the seg search never found another seg to From 482adc6124fb574fa9e366ea9ea66d966d35b981 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 4 May 2020 09:54:32 +0200 Subject: [PATCH 174/220] Pass parameters to EV_DoPolyObjFlag in a struct and not via the line --- src/p_polyobj.c | 16 ++++++++-------- src/p_polyobj.h | 10 +++++++++- src/p_spec.c | 9 ++++++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 5c71e356a..be751e153 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -2691,7 +2691,7 @@ void T_PolyObjFlag(polymove_t *th) Polyobj_attachToSubsec(po); // relink to subsector } -INT32 EV_DoPolyObjFlag(line_t *pfdata) +INT32 EV_DoPolyObjFlag(polyflagdata_t *pfdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2699,9 +2699,9 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) size_t i; INT32 start; - if (!(po = Polyobj_GetForNum(pfdata->tag))) + if (!(po = Polyobj_GetForNum(pfdata->polyObjNum))) { - CONS_Debug(DBG_POLYOBJ, "EV_DoPolyFlag: bad polyobj %d\n", pfdata->tag); + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyFlag: bad polyobj %d\n", pfdata->polyObjNum); return 0; } @@ -2724,11 +2724,11 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) po->thinker = &th->thinker; // set fields - th->polyObjNum = pfdata->tag; + th->polyObjNum = pfdata->polyObjNum; th->distance = 0; - th->speed = P_AproxDistance(pfdata->dx, pfdata->dy)>>FRACBITS; - th->angle = R_PointToAngle2(pfdata->v1->x, pfdata->v1->y, pfdata->v2->x, pfdata->v2->y)>>ANGLETOFINESHIFT; - th->momx = sides[pfdata->sidenum[0]].textureoffset>>FRACBITS; + th->speed = pfdata->speed; + th->angle = pfdata->angle; + th->momx = pfdata->momx; // save current positions for (i = 0; i < po->numVertices; ++i) @@ -2740,7 +2740,7 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) start = 0; while ((po = Polyobj_GetChild(oldpo, &start))) { - pfdata->tag = po->id; + pfdata->polyObjNum = po->id; EV_DoPolyObjFlag(pfdata); } diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 4f022013f..4ba2b469c 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -298,6 +298,14 @@ typedef struct polyrotdisplacedata_s UINT8 turnobjs; } polyrotdisplacedata_t; +typedef struct polyflagdata_s +{ + INT32 polyObjNum; + INT32 speed; + UINT32 angle; + fixed_t momx; +} polyflagdata_t; + typedef struct polyfadedata_s { INT32 polyObjNum; @@ -337,7 +345,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *); INT32 EV_DoPolyObjRotate(polyrotdata_t *); INT32 EV_DoPolyObjDisplace(polydisplacedata_t *); INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *); -INT32 EV_DoPolyObjFlag(struct line_s *); +INT32 EV_DoPolyObjFlag(polyflagdata_t *); INT32 EV_DoPolyObjFade(polyfadedata_t *); diff --git a/src/p_spec.c b/src/p_spec.c index c93846438..6355b7717 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7282,8 +7282,15 @@ void P_SpawnSpecials(boolean fromnetsave) switch (lines[i].special) { case 30: // Polyobj_Flag - EV_DoPolyObjFlag(&lines[i]); + { + polyflagdata_t pfd; + pfd.polyObjNum = lines[i].tag; + pfd.speed = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + pfd.angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y) >> ANGLETOFINESHIFT; + pfd.momx = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + EV_DoPolyObjFlag(&pfd); break; + } case 31: // Polyobj_Displace PolyDisplace(&lines[i]); From 2be775e74ce867380a344f0bcf3bf86a65db4f51 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 4 May 2020 09:58:27 +0200 Subject: [PATCH 175/220] Move parameter parsing for EV_DoPolyObjFlag into its own function --- src/p_spec.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 6355b7717..091f0faff 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1352,6 +1352,19 @@ static boolean PolyRotate(line_t *line) return EV_DoPolyObjRotate(&prd); } +// Parses arguments for polyobject flag waving special +static boolean PolyFlag(line_t *line) +{ + polyflagdata_t pfd; + + pfd.polyObjNum = line->tag; + pfd.speed = P_AproxDistance(line->dx, line->dy) >> FRACBITS; + pfd.angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y) >> ANGLETOFINESHIFT; + pfd.momx = sides[line->sidenum[0]].textureoffset >> FRACBITS; + + return EV_DoPolyObjFlag(&pfd); +} + // // PolyDisplace // @@ -7282,15 +7295,8 @@ void P_SpawnSpecials(boolean fromnetsave) switch (lines[i].special) { case 30: // Polyobj_Flag - { - polyflagdata_t pfd; - pfd.polyObjNum = lines[i].tag; - pfd.speed = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; - pfd.angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y) >> ANGLETOFINESHIFT; - pfd.momx = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; - EV_DoPolyObjFlag(&pfd); + PolyFlag(&lines[i]); break; - } case 31: // Polyobj_Displace PolyDisplace(&lines[i]); From 78a700f5fa905916acc1745c814d178145bc3fa4 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 4 May 2020 10:01:44 +0200 Subject: [PATCH 176/220] Remove non-descriptive comments --- src/p_spec.c | 44 +++----------------------------------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 091f0faff..1d9c2b143 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1044,9 +1044,6 @@ static INT32 P_FindLineFromTag(INT32 tag, INT32 start) } } -// -// P_FindSpecialLineFromTag -// INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) { if (tag == -1) @@ -1076,11 +1073,8 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) } } -// -// PolyDoor -// + // Parses arguments for parameterized polyobject door types -// static boolean PolyDoor(line_t *line) { polydoordata_t pdd; @@ -1117,11 +1111,7 @@ static boolean PolyDoor(line_t *line) return EV_DoPolyDoor(&pdd); } -// -// PolyMove -// // Parses arguments for parameterized polyobject move specials -// static boolean PolyMove(line_t *line) { polymovedata_t pmd; @@ -1136,12 +1126,8 @@ static boolean PolyMove(line_t *line) return EV_DoPolyObjMove(&pmd); } -// -// PolyInvisible -// // Makes a polyobject invisible and intangible // If NOCLIMB is ticked, the polyobject will still be tangible, just not visible. -// static void PolyInvisible(line_t *line) { INT32 polyObjNum = line->tag; @@ -1164,12 +1150,8 @@ static void PolyInvisible(line_t *line) po->flags &= ~POF_RENDERALL; } -// -// PolyVisible -// // Makes a polyobject visible and tangible // If NOCLIMB is ticked, the polyobject will not be tangible, just visible. -// static void PolyVisible(line_t *line) { INT32 polyObjNum = line->tag; @@ -1192,12 +1174,9 @@ static void PolyVisible(line_t *line) po->flags |= (po->spawnflags & POF_RENDERALL); } -// -// PolyTranslucency -// + // Sets the translucency of a polyobject // Frontsector floor / 100 = translevel -// static void PolyTranslucency(line_t *line) { INT32 polyObjNum = line->tag; @@ -1234,11 +1213,7 @@ static void PolyTranslucency(line_t *line) : max(min(line->frontsector->floorheight>>FRACBITS, 1000), 0) / 100); } -// -// PolyFade -// // Makes a polyobject translucency fade and applies tangibility -// static boolean PolyFade(line_t *line) { INT32 polyObjNum = line->tag; @@ -1303,11 +1278,7 @@ static boolean PolyFade(line_t *line) return EV_DoPolyObjFade(&pfd); } -// -// PolyWaypoint -// // Parses arguments for parameterized polyobject waypoint movement -// static boolean PolyWaypoint(line_t *line) { polywaypointdata_t pwd; @@ -1323,11 +1294,7 @@ static boolean PolyWaypoint(line_t *line) return EV_DoPolyObjWaypoint(&pwd); } -// -// PolyRotate -// // Parses arguments for parameterized polyobject rotate specials -// static boolean PolyRotate(line_t *line) { polyrotdata_t prd; @@ -1365,11 +1332,7 @@ static boolean PolyFlag(line_t *line) return EV_DoPolyObjFlag(&pfd); } -// -// PolyDisplace -// // Parses arguments for parameterized polyobject move-by-sector-heights specials -// static boolean PolyDisplace(line_t *line) { polydisplacedata_t pdd; @@ -1384,8 +1347,7 @@ static boolean PolyDisplace(line_t *line) } -/** Similar to PolyDisplace(). - */ +// Parses arguments for parameterized polyobject rotate-by-sector-heights specials static boolean PolyRotDisplace(line_t *line) { polyrotdisplacedata_t pdd; From e3ddb413aa2c6378a2014a79db3cea9398a8063b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 4 May 2020 10:07:38 +0200 Subject: [PATCH 177/220] Make PolyObject special functions return boolean instead of INT32 --- src/p_polyobj.c | 80 ++++++++++++++++++++++++------------------------- src/p_polyobj.h | 16 +++++----- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index be751e153..e35a124cd 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -2144,7 +2144,7 @@ static inline INT32 Polyobj_AngSpeed(INT32 speed) // Linedef Handlers -INT32 EV_DoPolyObjRotate(polyrotdata_t *prdata) +boolean EV_DoPolyObjRotate(polyrotdata_t *prdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2154,16 +2154,16 @@ INT32 EV_DoPolyObjRotate(polyrotdata_t *prdata) if (!(po = Polyobj_GetForNum(prdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // check for override if this polyobj already has a thinker if (po->thinker && !prdata->overRide) - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polyrotate_t), PU_LEVSPEC, NULL); @@ -2206,10 +2206,10 @@ INT32 EV_DoPolyObjRotate(polyrotdata_t *prdata) } // action was successful - return 1; + return true; } -INT32 EV_DoPolyObjMove(polymovedata_t *pmdata) +boolean EV_DoPolyObjMove(polymovedata_t *pmdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2219,16 +2219,16 @@ INT32 EV_DoPolyObjMove(polymovedata_t *pmdata) if (!(po = Polyobj_GetForNum(pmdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjMove: bad polyobj %d\n", pmdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // check for override if this polyobj already has a thinker if (po->thinker && !pmdata->overRide) - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polymove_t), PU_LEVSPEC, NULL); @@ -2265,10 +2265,10 @@ INT32 EV_DoPolyObjMove(polymovedata_t *pmdata) } // action was successful - return 1; + return true; } -INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) +boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) { polyobj_t *po; polywaypoint_t *th; @@ -2281,15 +2281,15 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) if (!(po = Polyobj_GetForNum(pwdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: bad polyobj %d\n", pwdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; if (po->thinker) // Don't crowd out another thinker. - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polywaypoint_t), PU_LEVSPEC, NULL); @@ -2356,7 +2356,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: Missing starting waypoint!\n"); po->thinker = NULL; P_RemoveThinker(&th->thinker); - return 0; + return false; } // Hotfix to not crash on single-waypoint sequences -Red @@ -2419,7 +2419,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: Missing target waypoint!\n"); po->thinker = NULL; P_RemoveThinker(&th->thinker); - return 0; + return false; } // Set pointnum @@ -2430,7 +2430,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) // We don't deal with the mirror crap here, we'll // handle that in the T_Thinker function. - return 1; + return true; } static void Polyobj_doSlideDoor(polyobj_t *po, polydoordata_t *doordata) @@ -2522,20 +2522,20 @@ static void Polyobj_doSwingDoor(polyobj_t *po, polydoordata_t *doordata) Polyobj_doSwingDoor(po, doordata); } -INT32 EV_DoPolyDoor(polydoordata_t *doordata) +boolean EV_DoPolyDoor(polydoordata_t *doordata) { polyobj_t *po; if (!(po = Polyobj_GetForNum(doordata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyDoor: bad polyobj %d\n", doordata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects; // polyobject doors don't allow action overrides if (po->isBad || po->thinker) - return 0; + return false; switch (doordata->doorType) { @@ -2547,13 +2547,13 @@ INT32 EV_DoPolyDoor(polydoordata_t *doordata) break; default: CONS_Debug(DBG_POLYOBJ, "EV_DoPolyDoor: unknown door type %d", doordata->doorType); - return 0; + return false; } - return 1; + return true; } -INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata) +boolean EV_DoPolyObjDisplace(polydisplacedata_t *prdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2563,12 +2563,12 @@ INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata) if (!(po = Polyobj_GetForNum(prdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polydisplace_t), PU_LEVSPEC, NULL); @@ -2596,10 +2596,10 @@ INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata) } // action was successful - return 1; + return true; } -INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) +boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2609,12 +2609,12 @@ INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) if (!(po = Polyobj_GetForNum(prdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // create a new thinker th = Z_Malloc(sizeof(polyrotdisplace_t), PU_LEVSPEC, NULL); @@ -2642,7 +2642,7 @@ INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata) } // action was successful - return 1; + return true; } void T_PolyObjFlag(polymove_t *th) @@ -2691,7 +2691,7 @@ void T_PolyObjFlag(polymove_t *th) Polyobj_attachToSubsec(po); // relink to subsector } -INT32 EV_DoPolyObjFlag(polyflagdata_t *pfdata) +boolean EV_DoPolyObjFlag(polyflagdata_t *pfdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2702,19 +2702,19 @@ INT32 EV_DoPolyObjFlag(polyflagdata_t *pfdata) if (!(po = Polyobj_GetForNum(pfdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyFlag: bad polyobj %d\n", pfdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects, // polyobject doors don't allow action overrides if (po->isBad || po->thinker) - return 0; + return false; // Must have even # of vertices if (po->numVertices & 1) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyFlag: Polyobject has odd # of vertices!\n"); - return 0; + return false; } // create a new thinker @@ -2745,7 +2745,7 @@ INT32 EV_DoPolyObjFlag(polyflagdata_t *pfdata) } // action was successful - return 1; + return true; } void T_PolyObjFade(polyfade_t *th) @@ -2843,7 +2843,7 @@ void T_PolyObjFade(polyfade_t *th) } } -INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) +boolean EV_DoPolyObjFade(polyfadedata_t *pfdata) { polyobj_t *po; polyobj_t *oldpo; @@ -2853,16 +2853,16 @@ INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) if (!(po = Polyobj_GetForNum(pfdata->polyObjNum))) { CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjFade: bad polyobj %d\n", pfdata->polyObjNum); - return 0; + return false; } // don't allow line actions to affect bad polyobjects if (po->isBad) - return 0; + return false; // already equal, nothing to do if (po->translucency == pfdata->destvalue) - return 1; + return true; if (po->thinker && po->thinker->function.acp1 == (actionf_p1)T_PolyObjFade) P_RemoveThinker(po->thinker); @@ -2904,7 +2904,7 @@ INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) } // action was successful - return 1; + return true; } // EOF diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 4ba2b469c..68aff4bf1 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -339,14 +339,14 @@ void T_PolyObjRotDisplace (polyrotdisplace_t *); void T_PolyObjFlag (polymove_t *); void T_PolyObjFade (polyfade_t *); -INT32 EV_DoPolyDoor(polydoordata_t *); -INT32 EV_DoPolyObjMove(polymovedata_t *); -INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *); -INT32 EV_DoPolyObjRotate(polyrotdata_t *); -INT32 EV_DoPolyObjDisplace(polydisplacedata_t *); -INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *); -INT32 EV_DoPolyObjFlag(polyflagdata_t *); -INT32 EV_DoPolyObjFade(polyfadedata_t *); +boolean EV_DoPolyDoor(polydoordata_t *); +boolean EV_DoPolyObjMove(polymovedata_t *); +boolean EV_DoPolyObjWaypoint(polywaypointdata_t *); +boolean EV_DoPolyObjRotate(polyrotdata_t *); +boolean EV_DoPolyObjDisplace(polydisplacedata_t *); +boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *); +boolean EV_DoPolyObjFlag(polyflagdata_t *); +boolean EV_DoPolyObjFade(polyfadedata_t *); // From 248df41a2fc603b19ddd67e26d667ec13c0cc7cf Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 4 May 2020 10:29:35 +0200 Subject: [PATCH 178/220] Simplify set/fade polyobject translucency code --- src/p_spec.c | 58 ++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 1d9c2b143..430b6077c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1181,6 +1181,7 @@ static void PolyTranslucency(line_t *line) { INT32 polyObjNum = line->tag; polyobj_t *po; + INT32 value; if (!(po = Polyobj_GetForNum(polyObjNum))) { @@ -1192,25 +1193,19 @@ static void PolyTranslucency(line_t *line) if (po->isBad) return; - // if DONTPEGBOTTOM, specify raw translucency value in Front X Offset - // else, take it out of 1000. If Front X Offset is specified, use that. Else, use floorheight. + // If Front X Offset is specified, use that. Else, use floorheight. + value = (sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : line->frontsector->floorheight) >> FRACBITS; + + // If DONTPEGBOTTOM, specify raw translucency value. Else, take it out of 1000. + if (!(line->flags & ML_DONTPEGBOTTOM)) + value /= 100; + if (line->flags & ML_EFFECT3) // relative calc - po->translucency = max(min(po->translucency + ((line->flags & ML_DONTPEGBOTTOM) ? - (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS) - : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS)) - : (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), -1000) / 100 - : max(min(line->frontsector->floorheight>>FRACBITS, 1000), -1000) / 100)), - NUMTRANSMAPS), 0); + po->translucency += value; else - po->translucency = (line->flags & ML_DONTPEGBOTTOM) ? - (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0) - : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), 0)) - : (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), 0) / 100 - : max(min(line->frontsector->floorheight>>FRACBITS, 1000), 0) / 100); + po->translucency = value; + + po->translucency = max(min(po->translucency, NUMTRANSMAPS), 0); } // Makes a polyobject translucency fade and applies tangibility @@ -1219,6 +1214,7 @@ static boolean PolyFade(line_t *line) INT32 polyObjNum = line->tag; polyobj_t *po; polyfadedata_t pfd; + INT32 value; if (!(po = Polyobj_GetForNum(polyObjNum))) { @@ -1241,25 +1237,19 @@ static boolean PolyFade(line_t *line) pfd.polyObjNum = polyObjNum; - // if DONTPEGBOTTOM, specify raw translucency value in Front X Offset - // else, take it out of 1000. If Front X Offset is specified, use that. Else, use floorheight. + // If Front X Offset is specified, use that. Else, use floorheight. + value = (sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : line->frontsector->floorheight) >> FRACBITS; + + // If DONTPEGBOTTOM, specify raw translucency value. Else, take it out of 1000. + if (!(line->flags & ML_DONTPEGBOTTOM)) + value /= 100; + if (line->flags & ML_EFFECT3) // relative calc - pfd.destvalue = max(min(po->translucency + ((line->flags & ML_DONTPEGBOTTOM) ? - (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS) - : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS)) - : (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), -1000) / 100 - : max(min(line->frontsector->floorheight>>FRACBITS, 1000), -1000) / 100)), - NUMTRANSMAPS), 0); + pfd.destvalue = po->translucency + value; else - pfd.destvalue = (line->flags & ML_DONTPEGBOTTOM) ? - (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0) - : max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), 0)) - : (sides[line->sidenum[0]].textureoffset ? - max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), 0) / 100 - : max(min(line->frontsector->floorheight>>FRACBITS, 1000), 0) / 100); + pfd.destvalue = value; + + pfd.destvalue = max(min(pfd.destvalue, NUMTRANSMAPS), 0); // already equal, nothing to do if (po->translucency == pfd.destvalue) From de100b076a5843f695325dab5bf56c53d6a22072 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 4 May 2020 19:47:39 +0200 Subject: [PATCH 179/220] PolyObject: Allow translucency to be set via X offset --- src/p_polyobj.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index e35a124cd..13f7decf9 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -217,7 +217,11 @@ static void Polyobj_GetInfo(polyobj_t *po) if (po->parent == po->id) // do not allow a self-reference po->parent = -1; - po->translucency = (lines[i].frontsector->floorheight>>FRACBITS) / 100; + po->translucency = (lines[i].flags & ML_DONTPEGTOP) + ? (sides[lines[i].sidenum[0]].textureoffset>>FRACBITS) + : ((lines[i].frontsector->floorheight>>FRACBITS) / 100); + + po->translucency = max(min(po->translucency, NUMTRANSMAPS), 0); po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; From 41efc0786dee6d33692856cdfab5f329ba9638b1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 4 May 2020 19:55:25 +0200 Subject: [PATCH 180/220] Add new PolyObject flag to ZB config --- extras/conf/SRB2-22.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 1c1d11809..11206e75a 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -760,6 +760,7 @@ linedeftypes { title = "Parameters"; prefix = "(22)"; + flags8text = "[3] Set translucency by X offset"; flags32text = "[5] Render outer sides only"; flags64text = "[6] Trigger linedef executor"; flags128text = "[7] Intangible"; From 5282f01a533fcb084e2e4ff6d176b6179c52377c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 5 May 2020 08:40:59 +0200 Subject: [PATCH 181/220] Fix PolyObject flags not being applied when there is no parameter line --- src/p_polyobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 13f7decf9..cd63f4509 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -210,6 +210,8 @@ static void Polyobj_GetInfo(polyobj_t *po) { INT32 i = P_FindSpecialLineFromTag(POLYINFO_SPECIALNUM, po->id, -1); + po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; + if (i == -1) return; // no extra settings to apply, let's leave it @@ -223,8 +225,6 @@ static void Polyobj_GetInfo(polyobj_t *po) po->translucency = max(min(po->translucency, NUMTRANSMAPS), 0); - po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; - if (lines[i].flags & ML_EFFECT1) po->flags |= POF_ONESIDE; From 2d6c9a94f43bba89bf7843ab1ff743fa5f7952a5 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 5 May 2020 14:05:19 +0200 Subject: [PATCH 182/220] Fix compiler warning --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f7755c148..43321d92d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5062,7 +5062,7 @@ void NetUpdate(void) // In case the cvar value was lowered if (joindelay) - joindelay = min(joindelay - 1, 3 * cv_joindelay.value * TICRATE); + joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE); } nowtime /= NEWTICRATERATIO; From 92c900f28468e058fbcd17701ff88967b6c0a83b Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 4 May 2020 00:35:57 +0800 Subject: [PATCH 183/220] New GFZ3 laser --- src/dehacked.c | 5 ++++- src/info.c | 13 ++++++++----- src/info.h | 5 ++++- src/p_enemy.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e9d029be0..daf578007 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6224,7 +6224,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ROCKET", - "S_LASER", + "S_LASER1", + "S_LASER2", + "S_LASERFLASH", + "S_LASERSPARK", "S_TORPEDO", diff --git a/src/info.c b/src/info.c index bd6ccb527..2944c53b1 100644 --- a/src/info.c +++ b/src/info.c @@ -2058,7 +2058,10 @@ state_t states[NUMSTATES] = {SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET - {SPR_MISL, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LASER + {SPR_MISL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_NULL}, // S_LASER1 + {SPR_MISL, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_NULL}, // S_LASER2 + {SPR_MISL, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_NULL}, // S_LASERFLASH + {SPR_MISL, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_LASERSPARK}, // S_LASERSPARK {SPR_TORP, 0, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_TORPEDO}, // S_TORPEDO @@ -9628,17 +9631,17 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_LASER -1, // doomednum - S_LASER, // spawnstate + S_LASER1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_rlaunc, // seesound 8, // reactiontime sfx_None, // attacksound - S_NULL, // painstate + S_LASERSPARK, // painstate 0, // painchance sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate + S_LASERFLASH, // meleestate + S_LASER2, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound diff --git a/src/info.h b/src/info.h index 586209ff9..1d1400aba 100644 --- a/src/info.h +++ b/src/info.h @@ -2219,7 +2219,10 @@ typedef enum state S_ROCKET, - S_LASER, + S_LASER1, + S_LASER2, + S_LASERFLASH, + S_LASERSPARK, S_TORPEDO, diff --git a/src/p_enemy.c b/src/p_enemy.c index 2341be6d3..ec7445f9f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2990,6 +2990,19 @@ void A_Boss1Laser(mobj_t *actor) angle_t angle; mobj_t *point; tic_t dur; + static const UINT8 LASERCOLORS[] = + { + SKINCOLOR_SUPERRED3, + SKINCOLOR_SUPERRED4, + SKINCOLOR_SUPERRED5, + SKINCOLOR_FLAME, + SKINCOLOR_RED, + SKINCOLOR_RED, + SKINCOLOR_FLAME, + SKINCOLOR_SUPERRED5, + SKINCOLOR_SUPERRED4, + SKINCOLOR_SUPERRED3, + }; if (LUA_CallAction("A_Boss1Laser", actor)) return; @@ -3064,7 +3077,7 @@ void A_Boss1Laser(mobj_t *actor) point = P_SpawnMobj(x, y, z, locvar1); P_SetTarget(&point->target, actor); point->angle = actor->angle; - speed = point->radius*2; + speed = point->radius; point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed); point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed)); point->momy = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINESINE(point->angle>>ANGLETOFINESHIFT), speed)); @@ -3073,10 +3086,26 @@ void A_Boss1Laser(mobj_t *actor) { mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type); mo->angle = point->angle; + mo->color = LASERCOLORS[((UINT8)(i - 3*leveltime) >> 2) % sizeof(LASERCOLORS)]; // codeing P_UnsetThingPosition(mo); mo->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; P_SetThingPosition(mo); + if (leveltime & 1 && mo->info->missilestate) + { + P_SetMobjState(mo, mo->info->missilestate); + if (mo->info->meleestate) + { + mobk_t *mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_PARTICLE); + mo2->flags2 |= MF2_LINKDRAW; + P_SetTarget(&mo2->tracer, actor); + P_SetMobjState(mo2, mo->info->meleestate); + } + } + + if (leveltime % 4 == 0) + P_SpawnGhostMobj(mo); + x = point->x, y = point->y, z = point->z; if (P_RailThinker(point)) break; @@ -3085,6 +3114,20 @@ void A_Boss1Laser(mobj_t *actor) floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_EGGMOBILE_FIRE].height); if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1) { + for (i = 0; point->info->painstate && i < 3; i++) + { + mobj_t *spark = P_SpawnMobj(x, y, floorz+1, MT_PARTICLE); + spark->flags &= ~MF_NOGRAVITY; + spark->angle = FixedAngle(P_RandomKey(360)*FRACUNIT); + spark->rollangle = FixedAngle(P_RandomKey(360)*FRACUNIT); + spark->color = LASERCOLORS[P_RandomKey(sizeof(LASERCOLORS)/sizeof(UINT8))]; + spark->colorized = true; + spark->fuse = 12; + spark->destscale = point->scale >> 3; + P_SetObjectMomZ(spark, 8*FRACUNIT, true); + P_InstaThrust(spark, spark->angle, 6*FRACUNIT); + P_SetMobjState(spark, point->info->painstate); + } point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE); P_SetTarget(&point->target, actor); point->destscale = 3*FRACUNIT; From 63cb58a10a97c9a68e17781122027dcd58f82ec9 Mon Sep 17 00:00:00 2001 From: lachwright Date: Wed, 6 May 2020 09:03:03 +0800 Subject: [PATCH 184/220] Update new GFZ3 laser --- src/dehacked.c | 10 ++++- src/hardware/hw_light.c | 2 + src/info.c | 27 ++++++++----- src/info.h | 12 +++++- src/p_enemy.c | 89 +++++++++++++++++++++++++++++++---------- src/p_mobj.c | 7 +--- src/sounds.c | 2 +- 7 files changed, 106 insertions(+), 43 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index daf578007..32339fe87 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3027,6 +3027,7 @@ static actionpointer_t actionpointers[] = {{A_DragonbomberSpawn}, "A_DRAGONBOMERSPAWN"}, {{A_DragonWing}, "A_DRAGONWING"}, {{A_DragonSegment}, "A_DRAGONSEGMENT"}, + {{A_ChangeHeight}, "A_CHANGEHEIGHT"}, {{NULL}, "NONE"}, // This NULL entry must be the last in the list @@ -6224,10 +6225,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ROCKET", - "S_LASER1", + "S_LASER", "S_LASER2", "S_LASERFLASH", - "S_LASERSPARK", + + "S_LASERFLAME1", + "S_LASERFLAME2", + "S_LASERFLAME3", + "S_LASERFLAME4", + "S_LASERFLAME5", "S_TORPEDO", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index c5af8d6d3..3d1316a2f 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -298,6 +298,8 @@ light_t *t_lspr[NUMSPRITES] = // Projectiles &lspr[NOLIGHT], // SPR_MISL + &lspr[SMALLREDBALL_L], // SPR_LASR + &lspr[REDSHINE_L], // SPR_LASF &lspr[NOLIGHT], // SPR_TORP &lspr[NOLIGHT], // SPR_ENRG &lspr[NOLIGHT], // SPR_MINE diff --git a/src/info.c b/src/info.c index 2944c53b1..ccb03ab1a 100644 --- a/src/info.c +++ b/src/info.c @@ -187,6 +187,8 @@ char sprnames[NUMSPRITES + 1][5] = // Projectiles "MISL", + "LASR", // GFZ3 laser + "LASF", // GFZ3 laser flames "TORP", // Torpedo "ENRG", // Energy ball "MINE", // Skim mine @@ -2058,10 +2060,15 @@ state_t states[NUMSTATES] = {SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET - {SPR_MISL, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_NULL}, // S_LASER1 - {SPR_MISL, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_NULL}, // S_LASER2 - {SPR_MISL, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_NULL}, // S_LASERFLASH - {SPR_MISL, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_LASERSPARK}, // S_LASERSPARK + {SPR_LASR, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_NULL}, // S_LASER + {SPR_LASR, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_NULL}, // S_LASER2 + {SPR_LASR, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_NULL}, // S_LASERFLASH + + {SPR_LASF, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_LASERFLAME2}, // S_LASERFLAME1 + {SPR_LASF, FF_FULLBRIGHT|1, 1, {A_ChangeHeight}, 52*FRACUNIT, 3, S_LASERFLAME3}, // S_LASERFLAME2 + {SPR_LASF, FF_FULLBRIGHT|2, 0, {A_ChangeHeight}, 12*FRACUNIT, 3, S_LASERFLAME4}, // S_LASERFLAME3 + {SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|2, 4, {NULL}, 1, 2, S_LASERFLAME5}, // S_LASERFLAME4 + {SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|4, 28, {NULL}, 2, 2, S_NULL}, // S_LASERFLAME5 {SPR_TORP, 0, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_TORPEDO}, // S_TORPEDO @@ -5668,15 +5675,15 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_EGGMOBILE_FIRE -1, // doomednum - S_SPINFIRE1, // spawnstate + S_LASERFLAME1, // spawnstate 1, // spawnhealth S_NULL, // seestate - sfx_None, // seesound + sfx_s3kc2s, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_None, // painsound + sfx_s3k8d, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate @@ -5684,7 +5691,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 8*FRACUNIT, // radius - 14*FRACUNIT, // height + 28*FRACUNIT, // height 0, // display offset DMG_FIRE, // mass 1, // damage @@ -9631,13 +9638,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_LASER -1, // doomednum - S_LASER1, // spawnstate + S_LASER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_rlaunc, // seesound 8, // reactiontime sfx_None, // attacksound - S_LASERSPARK, // painstate + S_NULL, // painstate 0, // painchance sfx_None, // painsound S_LASERFLASH, // meleestate diff --git a/src/info.h b/src/info.h index 1d1400aba..79af9bbbb 100644 --- a/src/info.h +++ b/src/info.h @@ -284,6 +284,7 @@ void A_RolloutRock(); void A_DragonbomberSpawn(); void A_DragonWing(); void A_DragonSegment(); +void A_ChangeHeight(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 512 @@ -451,6 +452,8 @@ typedef enum sprite // Projectiles SPR_MISL, + SPR_LASR, // GFZ3 laser + SPR_LASF, // GFZ3 laser flames SPR_TORP, // Torpedo SPR_ENRG, // Energy ball SPR_MINE, // Skim mine @@ -2219,10 +2222,15 @@ typedef enum state S_ROCKET, - S_LASER1, + S_LASER, S_LASER2, S_LASERFLASH, - S_LASERSPARK, + + S_LASERFLAME1, + S_LASERFLAME2, + S_LASERFLAME3, + S_LASERFLAME4, + S_LASERFLAME5, S_TORPEDO, diff --git a/src/p_enemy.c b/src/p_enemy.c index ec7445f9f..9fc7734d6 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -312,6 +312,7 @@ void A_RolloutRock(mobj_t *actor); void A_DragonbomberSpawn(mobj_t *actor); void A_DragonWing(mobj_t *actor); void A_DragonSegment(mobj_t *actor); +void A_ChangeHeight(mobj_t *actor); //for p_enemy.c @@ -3086,24 +3087,24 @@ void A_Boss1Laser(mobj_t *actor) { mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type); mo->angle = point->angle; - mo->color = LASERCOLORS[((UINT8)(i - 3*leveltime) >> 2) % sizeof(LASERCOLORS)]; // codeing + mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing P_UnsetThingPosition(mo); mo->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; P_SetThingPosition(mo); - if (leveltime & 1 && mo->info->missilestate) + if (dur & 1 && mo->info->missilestate) { P_SetMobjState(mo, mo->info->missilestate); if (mo->info->meleestate) { - mobk_t *mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_PARTICLE); + mobj_t *mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_PARTICLE); mo2->flags2 |= MF2_LINKDRAW; P_SetTarget(&mo2->tracer, actor); P_SetMobjState(mo2, mo->info->meleestate); } } - if (leveltime % 4 == 0) + if (dur == 1) P_SpawnGhostMobj(mo); x = point->x, y = point->y, z = point->z; @@ -3111,28 +3112,32 @@ void A_Boss1Laser(mobj_t *actor) break; } + x += point->momx; + y += point->momy; floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_EGGMOBILE_FIRE].height); - if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1) + if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1) { - for (i = 0; point->info->painstate && i < 3; i++) - { - mobj_t *spark = P_SpawnMobj(x, y, floorz+1, MT_PARTICLE); - spark->flags &= ~MF_NOGRAVITY; - spark->angle = FixedAngle(P_RandomKey(360)*FRACUNIT); - spark->rollangle = FixedAngle(P_RandomKey(360)*FRACUNIT); - spark->color = LASERCOLORS[P_RandomKey(sizeof(LASERCOLORS)/sizeof(UINT8))]; - spark->colorized = true; - spark->fuse = 12; - spark->destscale = point->scale >> 3; - P_SetObjectMomZ(spark, 8*FRACUNIT, true); - P_InstaThrust(spark, spark->angle, 6*FRACUNIT); - P_SetMobjState(spark, point->info->painstate); - } point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE); + point->angle = actor->angle; + point->destscale = actor->scale*3; + P_SetScale(point, point->destscale); P_SetTarget(&point->target, actor); - point->destscale = 3*FRACUNIT; - point->scalespeed = FRACUNIT>>2; - point->fuse = TICRATE; + P_MobjCheckWater(point); + if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) + { + for (i = 0; i < 2; i++) + { + UINT8 size = 3; + mobj_t *steam = P_SpawnMobj(x, y, point->watertop - size*mobjinfo[MT_DUST].height, MT_DUST); + P_SetScale(steam, size*actor->scale); + P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true); + P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed()); + if (point->info->painsound) + S_StartSound(steam, point->info->painsound); + } + } + else if (point->info->seesound) + S_StartSound(point, point->info->seesound); } if (dur > 1) @@ -14452,3 +14457,43 @@ void A_DragonSegment(mobj_t *actor) actor->angle = hangle; P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist); } + +// Function: A_ChangeHeight +// +// Description: Changes the actor's height by var1 +// +// var1 = height +// var2 = +// &1: height is absolute +// &2: scale with actor's scale +// +void A_ChangeHeight(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + fixed_t height = locvar1; + boolean reverse; + + if (LUA_CallAction("A_ChangeHeight", actor)) + return; + + reverse = (actor->eflags & MFE_VERTICALFLIP) || (actor->flags2 & MF2_OBJECTFLIP); + + if (locvar2 & 2) + height = FixedMul(height, actor->scale); + + P_UnsetThingPosition(actor); + if (locvar2 & 1) + { + if (reverse) + actor->z += actor->height - locvar1; + actor->height = locvar1; + } + else + { + if (reverse) + actor->z -= locvar1; + actor->height += locvar1; + } + P_SetThingPosition(actor); +} \ No newline at end of file diff --git a/src/p_mobj.c b/src/p_mobj.c index c78ec4a53..02be9dcef 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7056,8 +7056,7 @@ static void P_MobjScaleThink(mobj_t *mobj) fixed_t oldheight = mobj->height; UINT8 correctionType = 0; // Don't correct Z position, just gain height - if ((mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz)) - && mobj->type != MT_EGGMOBILE_FIRE) + if (mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz)) correctionType = 1; // Correct Z position by centering else if (mobj->eflags & MFE_VERTICALFLIP) correctionType = 2; // Correct Z position by moving down @@ -7078,10 +7077,6 @@ static void P_MobjScaleThink(mobj_t *mobj) /// \todo Lua hook for "reached destscale"? switch (mobj->type) { - case MT_EGGMOBILE_FIRE: - mobj->destscale = FRACUNIT; - mobj->scalespeed = FRACUNIT>>4; - break; default: break; } diff --git a/src/sounds.c b/src/sounds.c index ca943c2d0..9894fd13e 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -527,7 +527,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boing"}, {"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful hit"}, {"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Humming power"}, - {"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "/"}, {"s3k8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Accelerating"}, {"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Opening"}, {"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"}, From d0376e284a8ea93f3016001faba38068599a7047 Mon Sep 17 00:00:00 2001 From: ZipperQR Date: Wed, 6 May 2020 16:22:04 +0300 Subject: [PATCH 185/220] S_StopSoundByID Lua support --- src/lua_baselib.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 74938739c..da1f4e600 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2458,6 +2458,21 @@ static int lib_sStopSound(lua_State *L) return 0; } +static int lib_sStopSoundByID(lua_State *L) +{ + void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + //NOHUD + if (!origin) + return LUA_ErrInvalid(L, "mobj_t"); + + sfxenum_t sound_id = luaL_checkinteger(L, 2); + if (sound_id >= NUMSFX) + return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1); + + S_StopSoundByID(origin, sound_id); + return 0; +} + static int lib_sChangeMusic(lua_State *L) { #ifdef MUSICSLOT_COMPATIBILITY @@ -3253,6 +3268,7 @@ static luaL_Reg lib[] = { {"S_StartSound",lib_sStartSound}, {"S_StartSoundAtVolume",lib_sStartSoundAtVolume}, {"S_StopSound",lib_sStopSound}, + {"S_StopSoundByID",lib_sStopSoundByID}, {"S_ChangeMusic",lib_sChangeMusic}, {"S_SpeedMusic",lib_sSpeedMusic}, {"S_StopMusic",lib_sStopMusic}, From 87f7100d2e50522c914762fe9c252a42d7bfc5da Mon Sep 17 00:00:00 2001 From: Zipper Date: Wed, 6 May 2020 09:30:15 -0400 Subject: [PATCH 186/220] Update p_user.c --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 69c38f79d..5770ae5d4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11941,11 +11941,11 @@ void P_PlayerThink(player_t *player) factor = 4; } break; - /* -- in case we wanted to have the camera freely movable during zoom tubes - case CR_ZOOMTUBE:*/ case CR_DUSTDEVIL: player->drawangle += ANG20; break; + /* -- in case we wanted to have the camera freely movable during zoom tubes + case CR_ZOOMTUBE:*/ case CR_ROPEHANG: if (player->mo->momx || player->mo->momy) { From 38232ce07ec09e44058bdc74d6d7dd4e122cdf88 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Wed, 6 May 2020 18:35:54 -0400 Subject: [PATCH 187/220] fix build errors in public master --- src/s_sound.c | 2 +- src/w_wad.c | 4 ++++ src/win32/win_sys.c | 4 +++- src/win32/win_vid.c | 6 +++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 8e9461d78..7cd025786 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1672,7 +1672,7 @@ void S_LoadMusicDefs(UINT16 wadnum) char *lf; char *stoken; - size_t nlf; + size_t nlf = 0xFFFFFFFF; size_t ncr; musicdef_t *def = NULL; diff --git a/src/w_wad.c b/src/w_wad.c index 797f286d5..ea0a82fe9 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -76,6 +76,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...); //int vsnprintf(char *str, size_t n, const char *fmt, va_list ap); #endif +#ifdef _DEBUG +#include "console.h" +#endif + #ifndef O_BINARY #define O_BINARY 0 #endif diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index 42733c309..f9d66be7f 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -3199,7 +3199,7 @@ INT32 I_GetKey(void) // ----------------- #define DI_KEYBOARD_BUFFERSIZE 32 // number of data elements in keyboard buffer -void I_StartupKeyboard(void) +static void I_StartupKeyboard(void) { DIPROPDWORD dip; @@ -3435,6 +3435,8 @@ INT32 I_StartupSystem(void) // some 'more global than globals' things to initialize here ? graphics_started = keyboard_started = sound_started = cdaudio_started = false; + I_StartupKeyboard(); + #ifdef NDEBUG #ifdef BUGTRAP diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index 4e7bab569..5fa219586 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -56,6 +56,7 @@ static consvar_t cv_stretch = {"stretch", "On", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, static consvar_t cv_ontop = {"ontop", "Never", 0, CV_NeverOnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; boolean highcolor; +int vid_opengl_state = 0; static BOOL bDIBMode; // means we are using DIB instead of DirectDraw surfaces static LPBITMAPINFO bmiMain = NULL; @@ -949,7 +950,10 @@ INT32 VID_SetMode(INT32 modenum) } void VID_CheckRenderer(void) {} -void VID_CheckGLLoaded(rendermode_t oldrender) {} +void VID_CheckGLLoaded(rendermode_t oldrender) +{ + (void)oldrender; +} // ======================================================================== // Free the video buffer of the last video mode, From 3a1988fc014449d6870e6bf32220472107c78867 Mon Sep 17 00:00:00 2001 From: lachwright Date: Thu, 7 May 2020 22:47:34 +0800 Subject: [PATCH 188/220] Fix knockback scaling --- src/info.c | 8 ++++---- src/p_enemy.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/info.c b/src/info.c index ccb03ab1a..98cdce44d 100644 --- a/src/info.c +++ b/src/info.c @@ -2065,8 +2065,8 @@ state_t states[NUMSTATES] = {SPR_LASR, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_NULL}, // S_LASERFLASH {SPR_LASF, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_LASERFLAME2}, // S_LASERFLAME1 - {SPR_LASF, FF_FULLBRIGHT|1, 1, {A_ChangeHeight}, 52*FRACUNIT, 3, S_LASERFLAME3}, // S_LASERFLAME2 - {SPR_LASF, FF_FULLBRIGHT|2, 0, {A_ChangeHeight}, 12*FRACUNIT, 3, S_LASERFLAME4}, // S_LASERFLAME3 + {SPR_LASF, FF_FULLBRIGHT|1, 1, {A_ChangeHeight}, 156*FRACUNIT, 3, S_LASERFLAME3}, // S_LASERFLAME2 + {SPR_LASF, FF_FULLBRIGHT|2, 0, {A_ChangeHeight}, 32*FRACUNIT, 3, S_LASERFLAME4}, // S_LASERFLAME3 {SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|2, 4, {NULL}, 1, 2, S_LASERFLAME5}, // S_LASERFLAME4 {SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|4, 28, {NULL}, 2, 2, S_NULL}, // S_LASERFLAME5 @@ -5690,8 +5690,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8*FRACUNIT, // radius - 28*FRACUNIT, // height + 24*FRACUNIT, // radius + 84*FRACUNIT, // height 0, // display offset DMG_FIRE, // mass 1, // damage diff --git a/src/p_enemy.c b/src/p_enemy.c index 9fc7734d6..ba162fba6 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3119,7 +3119,7 @@ void A_Boss1Laser(mobj_t *actor) { point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE); point->angle = actor->angle; - point->destscale = actor->scale*3; + point->destscale = actor->scale; P_SetScale(point, point->destscale); P_SetTarget(&point->target, actor); P_MobjCheckWater(point); From 36b400387e8c2b67c0d3a0c764cadb8e65a2424e Mon Sep 17 00:00:00 2001 From: lachwright Date: Thu, 7 May 2020 23:24:33 +0800 Subject: [PATCH 189/220] Remove MF_NOBLOCKMAP from MT_LASER so Silver can find it --- src/info.c | 2 +- src/p_enemy.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index 98cdce44d..c64f669ee 100644 --- a/src/info.c +++ b/src/info.c @@ -9659,7 +9659,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 20, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags + MF_MISSILE|MF_NOGRAVITY, // flags S_NULL // raisestate }, diff --git a/src/p_enemy.c b/src/p_enemy.c index ba162fba6..a6dff3b59 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3089,7 +3089,7 @@ void A_Boss1Laser(mobj_t *actor) mo->angle = point->angle; mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing P_UnsetThingPosition(mo); - mo->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; + mo->flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY; P_SetThingPosition(mo); if (dur & 1 && mo->info->missilestate) From 9d21d790a4d741af02c793a0140b22754154246a Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 8 May 2020 02:58:56 +0800 Subject: [PATCH 190/220] Prevent laser sprites clipping into walls/off ledges --- src/info.c | 2 +- src/p_enemy.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index c64f669ee..d443e035d 100644 --- a/src/info.c +++ b/src/info.c @@ -5696,7 +5696,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = DMG_FIRE, // mass 1, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_FIRE, // flags + MF_NOGRAVITY|MF_FIRE|MF_PAIN, // flags S_NULL // raisestate }, diff --git a/src/p_enemy.c b/src/p_enemy.c index a6dff3b59..6b092fb61 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3117,7 +3117,7 @@ void A_Boss1Laser(mobj_t *actor) floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_EGGMOBILE_FIRE].height); if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1) { - point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE); + point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE); point->angle = actor->angle; point->destscale = actor->scale; P_SetScale(point, point->destscale); @@ -3136,8 +3136,20 @@ void A_Boss1Laser(mobj_t *actor) S_StartSound(steam, point->info->painsound); } } - else if (point->info->seesound) - S_StartSound(point, point->info->seesound); + else + { + fixed_t distx = P_ReturnThrustX(point, point->angle, point->radius); + fixed_t disty = P_ReturnThrustY(point, point->angle, point->radius); + if (P_TryMove(point, point->x + distx, point->y + disty, false) // prevents the sprite from clipping into the wall or dangling off ledges + && P_TryMove(point, point->x - 2*distx, point->y - 2*disty, false) + && P_TryMove(point, point->x + distx, point->y + disty, false)) + { + if (point->info->seesound) + S_StartSound(point, point->info->seesound); + } + else + P_RemoveMobj(point); + } } if (dur > 1) From 650f44566f5e8e2298b331cd5c14fcd252d11250 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 7 May 2020 21:59:39 +0200 Subject: [PATCH 191/220] Fixed a typo --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index ac72eec15..feac4dea0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7710,7 +7710,7 @@ static void P_SpawnScrollers(void) // scroll wall according to linedef // (same direction and speed as scrolling floors) case 502: - for (s = -1; (s = P_FindSectorFromTag(l->tag, s)) >= 0 ;) + for (s = -1; (s = P_FindLineFromTag(l->tag, s)) >= 0 ;) if (s != (INT32)i) Add_Scroller(sc_side, dx, dy, control, lines[s].sidenum[0], accel, 0); break; From 426925c5fce4ddcebc300d7a42b88a89d96fa9a0 Mon Sep 17 00:00:00 2001 From: Lachlan Date: Fri, 8 May 2020 04:07:00 +0800 Subject: [PATCH 192/220] Play the 1-up sound when 1upsound is set to sound --- src/p_user.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index c34d37264..22379d469 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -395,7 +395,7 @@ void P_GiveFinishFlags(player_t *player) mobj_t* flag = P_SpawnMobjFromMobj(player->mo, xoffs, yoffs, 0, MT_FINISHFLAG); flag->angle = angle; angle += FixedAngle(120*FRACUNIT); - + P_SetTarget(&flag->target, player->mo); } } @@ -1492,17 +1492,10 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if (use1upSound) + if (use1upSound || cv_1upsound.value) S_StartSound(NULL, sfx_oneup); else if (mariomode) S_StartSound(NULL, sfx_marioa); - else if (cv_1upsound.value) - { - if (S_sfx[sfx_oneup].lumpnum != LUMPERROR) - S_StartSound(NULL, sfx_oneup); - else - S_StartSound(NULL, sfx_chchng);/* at least play something! */ - } else { P_PlayJingle(player, JT_1UP); From c55d6dbc9f856706af3d9969f5238492ea5ad25e Mon Sep 17 00:00:00 2001 From: sphere Date: Fri, 8 May 2020 15:40:50 +0200 Subject: [PATCH 193/220] Make showfps save to config, and add a compact option. --- src/screen.c | 14 ++++++++++---- src/v_video.c | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/screen.c b/src/screen.c index 6e5fd54cd..73c6b9ba0 100644 --- a/src/screen.c +++ b/src/screen.c @@ -538,10 +538,16 @@ void SCR_DisplayTicRate(void) if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP; else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP; - V_DrawString(vid.width-(72*vid.dupx), h, - V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:"); - V_DrawString(vid.width-(40*vid.dupx), h, - ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE)); + if (cv_ticrate.value == 2) // compact counter + V_DrawString(vid.width-(16*vid.dupx), h, + ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d", totaltics)); + else if (cv_ticrate.value == 1) // full counter + { + V_DrawString(vid.width-(72*vid.dupx), h, + V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:"); + V_DrawString(vid.width-(40*vid.dupx), h, + ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE)); + } lasttic = ontic; } diff --git a/src/v_video.c b/src/v_video.c index 2d1014c23..3ce0e79f5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -42,7 +42,8 @@ UINT8 *screens[5]; // screens[3] = fade screen start // screens[4] = fade screen end, postimage tempoarary buffer -consvar_t cv_ticrate = {"showfps", "No", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t ticrate_cons_t[] = {{0, "No"}, {1, "Full"}, {2, "Compact"}, {0, NULL}}; +consvar_t cv_ticrate = {"showfps", "No", CV_SAVE, ticrate_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static void CV_palette_OnChange(void); From ab7987d1cf34fd5d30ce82385bf1c81caf1cb2d3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 May 2020 16:59:09 -0300 Subject: [PATCH 194/220] Fix OpenGL only recording the first frame of unoptimized GIFs --- src/m_anigif.c | 57 +++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index ce2ca20b9..1b71a09bc 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -490,29 +490,28 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by static UINT8 *gifframe_data = NULL; static size_t gifframe_size = 8192; +// +// GIF_rgbconvert +// converts an RGB frame to a frame with a palette. +// #ifdef HWRENDER -static void hwrconvert(void) +static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr) { - UINT8 *linear = HWR_GetScreenshot(); - UINT8 *dest = screens[2]; UINT8 r, g, b; - INT32 x, y; - size_t i = 0; + size_t src = 0, dest = 0; + size_t size = (vid.width * vid.height * 3); InitColorLUT(gif_framepalette); - for (y = 0; y < vid.height; y++) + while (src < size) { - for (x = 0; x < vid.width; x++, i += 3) - { - r = (UINT8)linear[i]; - g = (UINT8)linear[i + 1]; - b = (UINT8)linear[i + 2]; - dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; - } + r = (UINT8)linear[src]; + g = (UINT8)linear[src + 1]; + b = (UINT8)linear[src + 2]; + scr[dest] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; + src += (3 * scrbuf_downscaleamt); + dest += scrbuf_downscaleamt; } - - free(linear); } #endif @@ -556,7 +555,11 @@ static void GIF_framewrite(void) I_ReadScreen(movie_screen); #ifdef HWRENDER else if (rendermode == render_opengl) - hwrconvert(); + { + UINT8 *linear = HWR_GetScreenshot(); + GIF_rgbconvert(linear, movie_screen); + free(linear); + } #endif } else @@ -565,18 +568,20 @@ static void GIF_framewrite(void) blitw = vid.width; blith = vid.height; - if (gif_frames == 0) - { - if (rendermode == render_soft) - I_ReadScreen(movie_screen); #ifdef HWRENDER - else if (rendermode == render_opengl) - { - hwrconvert(); - VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); - } -#endif + // Copy the current OpenGL frame into the base screen + if (rendermode == render_opengl) + { + UINT8 *linear = HWR_GetScreenshot(); + GIF_rgbconvert(linear, screens[0]); + free(linear); } +#endif + + // Copy the first frame into the movie screen + // OpenGL already does the same above. + if (gif_frames == 0 && rendermode == render_soft) + I_ReadScreen(movie_screen); movie_screen = screens[0]; } From baee6a1d57cafddb7d6a4a839507ca8d469e7661 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 10 May 2020 16:02:23 +0100 Subject: [PATCH 195/220] Update version number to 2.2.3 in all the usual files, also updated MODVERSION --- CMakeLists.txt | 2 +- appveyor.yml | 2 +- src/doomdef.h | 8 ++++---- src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index abec11087..85f469a9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # Version change is fine. project(SRB2 - VERSION 2.2.2 + VERSION 2.2.3 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) diff --git a/appveyor.yml b/appveyor.yml index a28935f63..8d370301d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.2.2.{branch}-{build} +version: 2.2.3.{branch}-{build} os: MinGW environment: diff --git a/src/doomdef.h b/src/doomdef.h index a91142e9d..16f3d4783 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -143,9 +143,9 @@ extern char logfilename[1024]; // we use comprevision and compbranch instead. #else #define VERSION 202 // Game version -#define SUBVERSION 2 // more precise version number -#define VERSIONSTRING "v2.2.2" -#define VERSIONSTRINGW L"v2.2.2" +#define SUBVERSION 3 // more precise version number +#define VERSIONSTRING "v2.2.3" +#define VERSIONSTRINGW L"v2.2.3" // Hey! If you change this, add 1 to the MODVERSION below! // Otherwise we can't force updates! #endif @@ -213,7 +213,7 @@ extern char logfilename[1024]; // it's only for detection of the version the player is using so the MS can alert them of an update. // Only set it higher, not lower, obviously. // Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1". -#define MODVERSION 42 +#define MODVERSION 43 // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. // Increment MINOREXECVERSION whenever a config change is needed that does not correspond diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index 182220265..1ed28bd14 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -1219,7 +1219,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.2.2; + CURRENT_PROJECT_VERSION = 2.2.3; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1231,7 +1231,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.2.2; + CURRENT_PROJECT_VERSION = 2.2.3; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( From 3ce4c1b789bfde579d3cc911d527a4afb231f191 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 10 May 2020 16:47:01 +0100 Subject: [PATCH 196/220] Fix logging on Mac These fixes were suggested by Sveciaost on #mac-users on Discord --- src/sdl/i_main.c | 10 +++++----- src/sdl/i_system.c | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 5d0009927..3eded734f 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -27,7 +27,7 @@ #include #endif -#ifdef __unix__ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #include #endif @@ -142,7 +142,7 @@ int main(int argc, char **argv) const char *reldir; int left; boolean fileabs; -#ifdef __unix__ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) const char *link; #endif @@ -201,7 +201,7 @@ int main(int argc, char **argv) M_PathParts(logdir) - 1, M_PathParts(logfilename) - 1, 0755); -#ifdef __unix__ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) logstream = fopen(logfilename, "w"); #ifdef DEFAULTDIR if (logdir) @@ -214,9 +214,9 @@ int main(int argc, char **argv) { I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno)); } -#else/*__unix__*/ +#else/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ logstream = fopen("latest-log.txt", "wt+"); -#endif/*__unix__*/ +#endif/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/ } //I_OutputMsg("I_StartupSystem() ...\n"); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a86af316e..d2ed62516 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2484,7 +2484,7 @@ void I_RemoveExitFunc(void (*func)()) } } -#ifndef __unix__ +#if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)) static void Shittycopyerror(const char *name) { I_OutputMsg( @@ -2524,7 +2524,7 @@ static void Shittylogcopy(void) Shittycopyerror(logfilename); } } -#endif/*__unix__*/ +#endif/*!(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON))*/ // // Closes down everything. This includes restoring the initial @@ -2548,7 +2548,7 @@ void I_ShutdownSystem(void) if (logstream) { I_OutputMsg("I_ShutdownSystem(): end of logstream.\n"); -#ifndef __unix__ +#if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)) Shittylogcopy(); #endif fclose(logstream); From b7af502ed46df9a3adbc2b2a992b7bd17689256c Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 11 May 2020 00:16:01 +0800 Subject: [PATCH 197/220] Update MD5 hashes for player.dta and patch.pk3 --- src/config.h.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/config.h.in b/src/config.h.in index 4926f9a06..18320f96b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -28,12 +28,13 @@ /* Manually defined asset hashes for non-CMake builds * Last updated 2020 / 02 / 15 - v2.2.1 - main assets * Last updated 2020 / 02 / 22 - v2.2.2 - patch.pk3 + * Last updated 2020 / 05 / 10 - v2.2.3 - player.dta & patch.pk3 */ #define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28" #define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead" -#define ASSET_HASH_PLAYER_DTA "ad49e07b17cc662f1ad70c454910b4ae" +#define ASSET_HASH_PLAYER_DTA "8a4507ddf9bc0682c09174400f26ad65" #ifdef USE_PATCH_DTA -#define ASSET_HASH_PATCH_PK3 "ee54330ecb743314c5f962af4db731ff" +#define ASSET_HASH_PATCH_PK3 "d56064ff33a0a4a17d38512cbcb5613d" #endif #endif From 197da95a232da92e61f88ee27c754e8671a6624f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 10 May 2020 20:09:08 +0100 Subject: [PATCH 198/220] Last minute OpenGL fix: don't check flippedness in HWR_RotateSpritePolyToAim if the mobj is actually a precipmobj! precipmobj_t does not have eflags, so P_MobjFlip checking it would actually be accessing memory addresses beyond the end of the struct --- src/hardware/hw_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 565076b95..69da6655a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4019,7 +4019,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale } // This is expecting a pointer to an array containing 4 wallVerts for a sprite -static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts) +static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts, const boolean precip) { if (cv_grspritebillboarding.value && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) @@ -4027,7 +4027,7 @@ static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts { float basey = FIXED_TO_FLOAT(spr->mobj->z); float lowy = wallVerts[0].y; - if (P_MobjFlip(spr->mobj) == -1) + if (!precip && P_MobjFlip(spr->mobj) == -1) // precip doesn't have eflags so they can't flip { basey = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); } @@ -4140,7 +4140,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) } // Let dispoffset work first since this adjust each vertex - HWR_RotateSpritePolyToAim(spr, baseWallVerts); + HWR_RotateSpritePolyToAim(spr, baseWallVerts, false); realtop = top = baseWallVerts[3].y; realbot = bot = baseWallVerts[0].y; @@ -4419,7 +4419,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) } // Let dispoffset work first since this adjust each vertex - HWR_RotateSpritePolyToAim(spr, wallVerts); + HWR_RotateSpritePolyToAim(spr, wallVerts, false); // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. // sprite lighting by modulating the RGB components @@ -4503,7 +4503,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) wallVerts[1].z = wallVerts[2].z = spr->z2; // Let dispoffset work first since this adjust each vertex - HWR_RotateSpritePolyToAim(spr, wallVerts); + HWR_RotateSpritePolyToAim(spr, wallVerts, true); wallVerts[0].sow = wallVerts[3].sow = 0; wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; From 61dfee7e133cfb9d4f3748ab1a02a79267bea6ff Mon Sep 17 00:00:00 2001 From: sphere Date: Mon, 11 May 2020 01:33:34 +0200 Subject: [PATCH 199/220] Don't show the FPS counter during startup. --- src/screen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/screen.c b/src/screen.c index 73c6b9ba0..e01d1a81a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -526,6 +526,9 @@ void SCR_DisplayTicRate(void) INT32 ticcntcolor = 0; const INT32 h = vid.height-(8*vid.dupy); + if (gamestate == GS_NULL) + return; + for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) fpsgraph[i % TICRATE] = false; From 6b4ee94e383fa77d17849233280c11d98693bf0a Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 10 May 2020 19:40:28 -0700 Subject: [PATCH 200/220] Use camera angle, not mobj angle, when comparing Angle Anchor --- src/p_mobj.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 02be9dcef..78e0ccd41 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8252,6 +8252,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) // See Linedef Exec 457 (Track mobj angle to point) static void P_TracerAngleThink(mobj_t *mobj) { + angle_t looking; angle_t ang; if (!mobj->tracer) @@ -8266,7 +8267,12 @@ static void P_TracerAngleThink(mobj_t *mobj) // mobj->cvval - Allowable failure delay // mobj->cvmem - Failure timer - ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); + if (mobj->player) + looking = ( mobj->player->cmd.angleturn << 16 );/* fixes CS_LMAOGALOG */ + else + looking = mobj->angle; + + ang = looking - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); // \todo account for distance between mobj and tracer // Because closer mobjs can be facing beyond the angle tolerance From 7257fc730a5658e8d5409ae2a4f78d76d6adf6bf Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 10 May 2020 19:59:56 -0700 Subject: [PATCH 201/220] Remove instances of HAVE_BLUA that actually disable Lua now --- src/b_bot.c | 2 -- src/p_enemy.c | 4 +--- src/p_user.c | 4 ---- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index 9a4c20c17..4397938c1 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -459,7 +459,6 @@ boolean B_CheckRespawn(player_t *player) if (!sonic || sonic->health <= 0) return false; -#ifdef HAVE_BLUA // B_RespawnBot doesn't do anything if the condition above this isn't met { UINT8 shouldForce = LUAh_BotRespawn(sonic, tails); @@ -472,7 +471,6 @@ boolean B_CheckRespawn(player_t *player) else if (shouldForce == 2) return false; } -#endif // Check if Sonic is busy first. // If he's doing any of these things, he probably doesn't want to see us. diff --git a/src/p_enemy.c b/src/p_enemy.c index 6b092fb61..246ca1321 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8848,10 +8848,8 @@ void A_Dye(mobj_t *actor) mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor); UINT8 color = (UINT8)locvar2; -#ifdef HAVE_BLUA if (LUA_CallAction("A_Dye", actor)) return; -#endif if (color >= MAXTRANSLATIONS) return; @@ -14508,4 +14506,4 @@ void A_ChangeHeight(mobj_t *actor) actor->height += locvar1; } P_SetThingPosition(actor); -} \ No newline at end of file +} diff --git a/src/p_user.c b/src/p_user.c index 63103f3c2..02417ccff 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1541,10 +1541,6 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname) int i; boolean result = false; -#ifndef HAVE_BLUA - (void)musname; -#endif - for (i = 0; i < MAXPLAYERS; i++) { if (!P_IsLocalPlayer(&players[i])) From 334ad93c56f7d3d2a0a93e03643d84b267f6cda8 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Mon, 11 May 2020 19:57:20 +0200 Subject: [PATCH 202/220] Fix splitscreen Title Card act name regression This fixes act names not being shown on player 2's view --- src/st_stuff.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 6e365dc68..b6226d085 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1333,13 +1333,12 @@ void ST_drawTitleCard(void) patch_t *actpat, *zigzag, *zztext; UINT8 colornum; const UINT8 *colormap; - stplyr = &players[consoleplayer]; - - if (stplyr->skincolor) - colornum = stplyr->skincolor; + + if (players[consoleplayer].skincolor) + colornum = players[consoleplayer].skincolor; else colornum = cv_playercolor.value; - + colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE); if (!G_IsTitleCardAvailable()) From c52c8e0282beda74c2d2076fb5f1471e13b21c47 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 11 May 2020 14:37:53 -0700 Subject: [PATCH 203/220] Update version names, SUBVERSION, MODVERSION --- CMakeLists.txt | 2 +- appveyor.yml | 2 +- src/doomdef.h | 8 ++++---- src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85f469a9f..1e46f5dc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # Version change is fine. project(SRB2 - VERSION 2.2.3 + VERSION 2.2.4 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) diff --git a/appveyor.yml b/appveyor.yml index 8d370301d..5d599a516 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.2.3.{branch}-{build} +version: 2.2.4.{branch}-{build} os: MinGW environment: diff --git a/src/doomdef.h b/src/doomdef.h index 16f3d4783..6112881fb 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -143,9 +143,9 @@ extern char logfilename[1024]; // we use comprevision and compbranch instead. #else #define VERSION 202 // Game version -#define SUBVERSION 3 // more precise version number -#define VERSIONSTRING "v2.2.3" -#define VERSIONSTRINGW L"v2.2.3" +#define SUBVERSION 4 // more precise version number +#define VERSIONSTRING "v2.2.4" +#define VERSIONSTRINGW L"v2.2.4" // Hey! If you change this, add 1 to the MODVERSION below! // Otherwise we can't force updates! #endif @@ -213,7 +213,7 @@ extern char logfilename[1024]; // it's only for detection of the version the player is using so the MS can alert them of an update. // Only set it higher, not lower, obviously. // Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1". -#define MODVERSION 43 +#define MODVERSION 44 // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. // Increment MINOREXECVERSION whenever a config change is needed that does not correspond diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index 1ed28bd14..745513eeb 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -1219,7 +1219,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.2.3; + CURRENT_PROJECT_VERSION = 2.2.4; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1231,7 +1231,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.2.3; + CURRENT_PROJECT_VERSION = 2.2.4; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( From a645f3a44f07f177f768f33eae14def482c7be7e Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 11 May 2020 14:40:28 -0700 Subject: [PATCH 204/220] Update patch.pk3 asset hash --- src/config.h.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config.h.in b/src/config.h.in index 18320f96b..3b2579965 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -29,12 +29,13 @@ * Last updated 2020 / 02 / 15 - v2.2.1 - main assets * Last updated 2020 / 02 / 22 - v2.2.2 - patch.pk3 * Last updated 2020 / 05 / 10 - v2.2.3 - player.dta & patch.pk3 + * Last updated 2020 / 05 / 11 - v2.2.4 - patch.pk3 */ #define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28" #define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead" #define ASSET_HASH_PLAYER_DTA "8a4507ddf9bc0682c09174400f26ad65" #ifdef USE_PATCH_DTA -#define ASSET_HASH_PATCH_PK3 "d56064ff33a0a4a17d38512cbcb5613d" +#define ASSET_HASH_PATCH_PK3 "bbbf6af3b20349612ee06e0b55979a76" #endif #endif From 0c4f983eb5f589087f40de0c8a3237f594fb5bba Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Mon, 11 May 2020 23:48:35 +0200 Subject: [PATCH 205/220] Fix crash with rollout rock --- src/p_user.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 02417ccff..f5c8caf72 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4429,13 +4429,16 @@ void P_DoJump(player_t *player, boolean soundandstate) else if (player->powers[pw_carry] == CR_ROLLOUT) { player->mo->momz = 9*FRACUNIT; - if (P_MobjFlip(player->mo->tracer)*player->mo->tracer->momz > 0) - player->mo->momz += player->mo->tracer->momz; - if (!P_IsObjectOnGround(player->mo->tracer)) - P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true); + if (player->mo->tracer) + { + if (P_MobjFlip(player->mo->tracer)*player->mo->tracer->momz > 0) + player->mo->momz += player->mo->tracer->momz; + if (!P_IsObjectOnGround(player->mo->tracer)) + P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true); + player->mo->tracer->flags |= MF_PUSHABLE; + P_SetTarget(&player->mo->tracer->tracer, NULL); + } player->powers[pw_carry] = CR_NONE; - player->mo->tracer->flags |= MF_PUSHABLE; - P_SetTarget(&player->mo->tracer->tracer, NULL); P_SetTarget(&player->mo->tracer, NULL); } else if (player->mo->eflags & MFE_GOOWATER) From 69c11a8220477e64348f1fb5b47f0e86df324ea1 Mon Sep 17 00:00:00 2001 From: sphere Date: Thu, 30 Apr 2020 16:01:03 +0200 Subject: [PATCH 206/220] Support act numbers up to 99 and draw both digits individually. --- src/dehacked.c | 2 +- src/hu_stuff.c | 4 ++-- src/hu_stuff.h | 2 +- src/st_stuff.c | 9 +++++++-- src/v_video.c | 30 +++++++++++++++++++++++------- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index a6c73e0b4..a71bfe055 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1557,7 +1557,7 @@ static void readlevelheader(MYFILE *f, INT32 num) } else if (fastcmp(word, "ACT")) { - if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19 + if (i >= 0 && i <= 99) // 0 for no act number mapheaderinfo[num-1]->actnum = (UINT8)i; else deh_warning("Level header %d: invalid act number %d", num, i); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 6aa5a4510..3ff9db2b6 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -68,7 +68,7 @@ patch_t *nightsnum[10]; // 0-9 // Level title and credits fonts patch_t *lt_font[LT_FONTSIZE]; patch_t *cred_font[CRED_FONTSIZE]; -patch_t *ttlnum[20]; // act numbers (0-19) +patch_t *ttlnum[10]; // act numbers (0-9) // Name tag fonts patch_t *ntb_font[NT_FONTSIZE]; @@ -243,7 +243,7 @@ void HU_LoadGraphics(void) tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX); // cache act numbers for level titles - for (i = 0; i < 20; i++) + for (i = 0; i < 10; i++) { sprintf(buffer, "TTL%.2d", i); ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 9e3c66747..63d85f1b8 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -85,7 +85,7 @@ extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE]; extern patch_t *ntb_font[NT_FONTSIZE]; extern patch_t *nto_font[NT_FONTSIZE]; -extern patch_t *ttlnum[20]; +extern patch_t *ttlnum[10]; extern patch_t *emeraldpics[3][8]; extern patch_t *rflagico; extern patch_t *bflagico; diff --git a/src/st_stuff.c b/src/st_stuff.c index b6226d085..26f2c1774 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1325,7 +1325,7 @@ void ST_drawTitleCard(void) { char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *subttl = mapheaderinfo[gamemap-1]->subttl; - INT32 actnum = mapheaderinfo[gamemap-1]->actnum; + UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; INT32 lvlttlxpos, ttlnumxpos, zonexpos; INT32 subttlxpos = BASEVIDWIDTH/2; INT32 ttlscroll = FixedInt(lt_scroll); @@ -1382,7 +1382,12 @@ void ST_drawTitleCard(void) if (actnum) { if (!splitscreen) - V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); + { + if (actnum > 9) + V_DrawMappedPatch(ttlnumxpos + (V_LevelActNumWidth(actnum)/4) + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); + else + V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); + } V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum); } diff --git a/src/v_video.c b/src/v_video.c index 3ce0e79f5..e8d121f9a 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2952,13 +2952,19 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits) } // Draw an act number for a level title -// Todo: actually draw two-digit numbers as two act num patches -void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num) +void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num) { - if (num < 0 || num > 19) + if (num < 0 || num > 99) return; // not supported - V_DrawScaledPatch(x, y, flags, ttlnum[num]); + while (num > 0) + { + if (num > 9) + V_DrawScaledPatch(x + (V_LevelActNumWidth(num) - V_LevelActNumWidth(num%10)), y, flags, ttlnum[num%10]); + else + V_DrawScaledPatch(x, y, flags, ttlnum[num]); + num = num/10; + } } // Write a string using the credit font @@ -3340,12 +3346,22 @@ INT32 V_LevelNameHeight(const char *string) // For ST_drawTitleCard // Returns the width of the act num patch -INT32 V_LevelActNumWidth(INT32 num) +INT32 V_LevelActNumWidth(UINT8 num) { - if (num < 0 || num > 19) + SHORT result = 0; + if (num > 99) return 0; // not a valid number - return SHORT(ttlnum[num]->width); + if (num == 0) + return SHORT(ttlnum[num]->width); + + while (num > 0) + { + result = result + SHORT(ttlnum[num%10]->width); + num = num/10; + } + + return result; } // From 0287c6956e03ed8a5e690b4aea1a0b53086127d2 Mon Sep 17 00:00:00 2001 From: sphere Date: Thu, 30 Apr 2020 17:12:52 +0200 Subject: [PATCH 207/220] Fix some errors and add some comments. Also, actnum is not an INT32. --- src/d_clisrv.c | 2 +- src/g_game.c | 2 +- src/m_menu.c | 2 +- src/st_stuff.c | 2 +- src/v_video.c | 18 ++++++++---------- src/v_video.h | 4 ++-- src/y_inter.c | 2 +- 7 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 43321d92d..ed0b8e528 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1690,7 +1690,7 @@ static void CL_LoadReceivedSavegame(void) // load a base level if (P_LoadNetGame()) { - const INT32 actnum = mapheaderinfo[gamemap-1]->actnum; + const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, "")) { diff --git a/src/g_game.c b/src/g_game.c index 92d71fbae..5bcf9f580 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4629,7 +4629,7 @@ char *G_BuildMapTitle(INT32 mapnum) { size_t len = 1; const char *zonetext = NULL; - const INT32 actnum = mapheaderinfo[mapnum-1]->actnum; + const UINT8 actnum = mapheaderinfo[mapnum-1]->actnum; len += strlen(mapheaderinfo[mapnum-1]->lvlttl); if (!(mapheaderinfo[mapnum-1]->levelflags & LF_NOZONE)) diff --git a/src/m_menu.c b/src/m_menu.c index 2977b432f..c221571c8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5186,7 +5186,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) { if (M_CanShowLevelOnPlatter(mapnum, gt)) { - const INT32 actnum = mapheaderinfo[mapnum]->actnum; + const UINT8 actnum = mapheaderinfo[mapnum]->actnum; const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl)); const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON); diff --git a/src/st_stuff.c b/src/st_stuff.c index 26f2c1774..9d819b147 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1383,7 +1383,7 @@ void ST_drawTitleCard(void) { if (!splitscreen) { - if (actnum > 9) + if (actnum > 9) // slightly offset the act diamond for two-digit act numbers V_DrawMappedPatch(ttlnumxpos + (V_LevelActNumWidth(actnum)/4) + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); else V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap); diff --git a/src/v_video.c b/src/v_video.c index e8d121f9a..e17df995b 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2954,12 +2954,12 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits) // Draw an act number for a level title void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num) { - if (num < 0 || num > 99) + if (num > 99) return; // not supported while (num > 0) { - if (num > 9) + if (num > 9) // if there are two digits, draw second digit first V_DrawScaledPatch(x + (V_LevelActNumWidth(num) - V_LevelActNumWidth(num%10)), y, flags, ttlnum[num%10]); else V_DrawScaledPatch(x, y, flags, ttlnum[num]); @@ -3345,19 +3345,17 @@ INT32 V_LevelNameHeight(const char *string) } // For ST_drawTitleCard -// Returns the width of the act num patch -INT32 V_LevelActNumWidth(UINT8 num) +// Returns the width of the act num patch(es) +INT16 V_LevelActNumWidth(UINT8 num) { - SHORT result = 0; - if (num > 99) - return 0; // not a valid number + INT16 result = 0; if (num == 0) - return SHORT(ttlnum[num]->width); + result = ttlnum[num]->width; - while (num > 0) + while (num > 0 && num <= 99) { - result = result + SHORT(ttlnum[num%10]->width); + result = result + ttlnum[num%10]->width; num = num/10; } diff --git a/src/v_video.h b/src/v_video.h index ed623a57f..664fa8995 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -238,12 +238,12 @@ void V_DrawRightAlignedSmallThinStringAtFixed(fixed_t x, fixed_t y, INT32 option // Draw tall nums, used for menu, HUD, intermission void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num); void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits); -void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num); +void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num); // Find string width from lt_font chars INT32 V_LevelNameWidth(const char *string); INT32 V_LevelNameHeight(const char *string); -INT32 V_LevelActNumWidth(INT32 num); // act number width +INT16 V_LevelActNumWidth(UINT8 num); // act number width void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string); INT32 V_CreditStringWidth(const char *string); diff --git a/src/y_inter.c b/src/y_inter.c index f1764a816..a2628832f 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -73,7 +73,7 @@ typedef union UINT32 score, total; // fake score, total UINT32 tics; // time - INT32 actnum; // act number being displayed + UINT8 actnum; // act number being displayed patch_t *ptotal; // TOTAL UINT8 gotlife; // Number of extra lives obtained } coop; From 4eb5f09c6f6fada395a94d69eb5e599ba69a017f Mon Sep 17 00:00:00 2001 From: sphere Date: Thu, 30 Apr 2020 23:41:06 +0200 Subject: [PATCH 208/220] Restore SHORT(). --- src/v_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index e17df995b..1e550fe9d 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -3351,11 +3351,11 @@ INT16 V_LevelActNumWidth(UINT8 num) INT16 result = 0; if (num == 0) - result = ttlnum[num]->width; + result = SHORT(ttlnum[num]->width); while (num > 0 && num <= 99) { - result = result + ttlnum[num%10]->width; + result = result + SHORT(ttlnum[num%10]->width); num = num/10; } From 89cd756cd83e4a03a34d1f16da18142d8167d889 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 12 May 2020 18:37:15 +0100 Subject: [PATCH 209/220] make savegamename in doomdef.h an extern, put the actual definition in d_main.c --- src/d_main.c | 2 ++ src/doomdef.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 07e15aec4..07a7ecf91 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -125,6 +125,8 @@ boolean advancedemo; INT32 debugload = 0; #endif +char savegamename[256]; + char srb2home[256] = "."; char srb2path[256] = "."; boolean usehome = true; diff --git a/src/doomdef.h b/src/doomdef.h index 6112881fb..4b425dc72 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -458,7 +458,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG; // Things that used to be in dstrings.h #define SAVEGAMENAME "srb2sav" -char savegamename[256]; +extern char savegamename[256]; // m_misc.h #ifdef GETTEXT From dab212dc56936dd92a935d0c81003ff1d35ee2ee Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 12 May 2020 18:40:51 +0100 Subject: [PATCH 210/220] turn all non-extern variables in s_sound.h into externs (and put their real definitions in the .c file) --- src/s_sound.c | 5 +++++ src/s_sound.h | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index d108363eb..5ed9fd83a 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -134,6 +134,7 @@ consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_Y consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef HAVE_OPENMPT +openmpt_module *openmpt_mhandle = NULL; static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}}; consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -1910,6 +1911,10 @@ UINT32 S_GetMusicPosition(void) /// In this section: mazmazz doesn't know how to do dynamic arrays or struct pointers! /// ------------------------ +char music_stack_nextmusname[7]; +boolean music_stack_noposition = false; +UINT32 music_stack_fadeout = 0; +UINT32 music_stack_fadein = 0; static musicstack_t *music_stacks = NULL; static musicstack_t *last_music_stack = NULL; diff --git a/src/s_sound.h b/src/s_sound.h index 119722af4..3334fcb69 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -22,7 +22,7 @@ #ifdef HAVE_OPENMPT #include "libopenmpt/libopenmpt.h" -openmpt_module *openmpt_mhandle; +extern openmpt_module *openmpt_mhandle; #endif // mask used to indicate sound origin is player item pickup @@ -262,10 +262,10 @@ typedef struct musicstack_s struct musicstack_s *next; } musicstack_t; -char music_stack_nextmusname[7]; -boolean music_stack_noposition; -UINT32 music_stack_fadeout; -UINT32 music_stack_fadein; +extern char music_stack_nextmusname[7]; +extern boolean music_stack_noposition; +extern UINT32 music_stack_fadeout; +extern UINT32 music_stack_fadein; void S_SetStackAdjustmentStart(void); void S_AdjustMusicStackTics(void); @@ -333,7 +333,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum); #ifdef MUSICSLOT_COMPATIBILITY // For compatibility with code/scripts relying on older versions // This is a list of all the "special" slot names and their associated numbers -const char *compat_special_music_slots[16]; +extern const char *compat_special_music_slots[16]; #endif #endif From 064f4bcf349e9600552a0b99bd0fbfb3cbcf0958 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 12 May 2020 18:42:16 +0100 Subject: [PATCH 211/220] added missing extern keyword for ms_RoomId in mserv.h (the definition is already in the .c file in this case) --- src/mserv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mserv.h b/src/mserv.h index 6d91da643..5f9b8da5f 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -68,7 +68,7 @@ extern consvar_t cv_masterserver, cv_servername; // < 0 to not connect (usually -1) (offline mode) // == 0 to show all rooms, not a valid hosting room // anything else is whatever room the MS assigns to that number (online mode) -INT16 ms_RoomId; +extern INT16 ms_RoomId; const char *GetMasterServerPort(void); const char *GetMasterServerIP(void); From 8c88c3dbb4479f09f65df9dec3c8ef5ef09792e3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 12 May 2020 18:43:49 +0100 Subject: [PATCH 212/220] added missing extern keyword for ntemprecords in doomstat.h (definition is in g_game.c) --- src/doomstat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomstat.h b/src/doomstat.h index 1ec03a86c..0c2f1e975 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -545,7 +545,7 @@ extern recorddata_t *mainrecords[NUMMAPS]; extern UINT8 mapvisited[NUMMAPS]; // Temporary holding place for nights data for the current map -nightsdata_t ntemprecords; +extern nightsdata_t ntemprecords; extern UINT32 token; ///< Number of tokens collected in a level extern UINT32 tokenlist; ///< List of tokens collected From 6a9543b1c251bc802f1be9380cfa4faa3887614c Mon Sep 17 00:00:00 2001 From: ZipperQR Date: Thu, 14 May 2020 03:35:46 +0300 Subject: [PATCH 213/220] no message --- src/p_enemy.c | 3 +-- src/p_user.c | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index e83e4cd4f..58f09cacb 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13288,9 +13288,8 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) if (!player) return true; - if (abs(thing->x - dustdevil->x) > dustdevil->radius || abs(thing->y - dustdevil->y) > dustdevil->radius){ + if (abs(thing->x - dustdevil->x) > dustdevil->radius || abs(thing->y - dustdevil->y) > dustdevil->radius) return true; - } if (thing->z + thing->height >= dustdevil->z && dustdevil->z + dustdevil->height >= thing->z) { fixed_t pos = thing->z - dustdevil->z; diff --git a/src/p_user.c b/src/p_user.c index 5770ae5d4..726177ff9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12724,7 +12724,8 @@ void P_PlayerAfterThink(player_t *player) { mobj_t *mo = player->mo, *dustdevil = player->mo->tracer; - if (abs(mo->x - dustdevil->x) > dustdevil->radius || abs(mo->y - dustdevil->y) > dustdevil->radius){ + if (abs(mo->x - dustdevil->x) > dustdevil->radius || abs(mo->y - dustdevil->y) > dustdevil->radius) + { P_SetTarget(&player->mo->tracer, NULL); player->powers[pw_carry] = CR_NONE; break; From ee520b4a0d2c462ba2c5f0b3c922c0b713635ea9 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 14 May 2020 20:57:21 +0100 Subject: [PATCH 214/220] split significant chunks of G_CheckDemoStatus into their own smaller functions, also give writing demo checksums its own little function --- src/g_demo.c | 182 ++++++++++++++++++++++++++------------------------- 1 file changed, 93 insertions(+), 89 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 30bc8ca48..a901e8dea 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -2332,6 +2332,38 @@ void G_DoneLevelLoad(void) =================== */ +// Writes the demo's checksum, or just random garbage if you can't do that for some reason. +static void WriteDemoChecksum(void) +{ + UINT8 *p = demobuffer+16; // checksum position +#ifdef NOMD5 + UINT8 i; + for (i = 0; i < 16; i++, p++) + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. +#else + md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. +#endif +} + +// Stops recording a demo. +static void G_StopDemoRecording(void) +{ + boolean saved = false; + WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker + WriteDemoChecksum(); + saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. + free(demobuffer); + demorecording = false; + + if (modeattacking != ATTACKING_RECORD) + { + if (saved) + CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); + else + CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname); + } +} + // Stops metal sonic's demo. Separate from other functions because metal + replays can coexist void G_StopMetalDemo(void) { @@ -2349,20 +2381,8 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) boolean saved = false; if (demo_p) { - UINT8 *p = demobuffer+16; // checksum position - if (kill) - WRITEUINT8(demo_p, METALDEATH); // add the metal death marker - else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker -#ifdef NOMD5 - { - UINT8 i; - for (i = 0; i < 16; i++, p++) - *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. - } -#else - md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. -#endif + WRITEUINT8(demo_p, (kill) ? METALDEATH : DEMOMARKER); // add the demo end (or metal death) marker + WriteDemoChecksum(); saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. } free(demobuffer); @@ -2372,6 +2392,63 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) I_Error("Failed to save demo!"); } +// Stops timing a demo. +static void G_StopTimingDemo(void) +{ + INT32 demotime; + double f1, f2; + demotime = I_GetTime() - demostarttime; + if (!demotime) + return; + G_StopDemo(); + timingdemo = false; + f1 = (double)demotime; + f2 = (double)framecount*TICRATE; + + CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), + leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); + + // CSV-readable timedemo results, for external parsing + if (timedemo_csv) + { + FILE *f; + const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); + const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; + const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; + boolean headerrow = !FIL_FileExists(csvpath); + UINT8 procbits = 0; + + // Bitness + if (sizeof(void*) == 4) + procbits = 32; + else if (sizeof(void*) == 8) + procbits = 64; + + f = fopen(csvpath, "a+"); + + if (f) + { + if (headerrow) + fputs(header, f); + fprintf(f, rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + fclose(f); + CONS_Printf("Timedemo results saved to '%s'\n", csvpath); + } + else + { + // Just print the CSV output to console + CON_LogMessage(header); + CONS_Printf(rowformat, + timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); + } + } + + if (restorecv_vidwait != cv_vidwait.value) + CV_SetValue(&cv_vidwait, restorecv_vidwait); + D_AdvanceDemo(); +} + // reset engine variable set for the demos // called from stopdemo command, map command, and g_checkdemoStatus. void G_StopDemo(void) @@ -2394,66 +2471,13 @@ void G_StopDemo(void) boolean G_CheckDemoStatus(void) { - boolean saved; - G_FreeGhosts(); // DO NOT end metal sonic demos here if (timingdemo) { - INT32 demotime; - double f1, f2; - demotime = I_GetTime() - demostarttime; - if (!demotime) - return true; - G_StopDemo(); - timingdemo = false; - f1 = (double)demotime; - f2 = (double)framecount*TICRATE; - - CONS_Printf(M_GetText("timed %u gametics in %d realtics - %u frames\n%f seconds, %f avg fps\n"), - leveltime,demotime,(UINT32)framecount,f1/TICRATE,f2/f1); - - // CSV-readable timedemo results, for external parsing - if (timedemo_csv) - { - FILE *f; - const char *csvpath = va("%s"PATHSEP"%s", srb2home, "timedemo.csv"); - const char *header = "id,demoname,seconds,avgfps,leveltime,demotime,framecount,ticrate,rendermode,vidmode,vidwidth,vidheight,procbits\n"; - const char *rowformat = "\"%s\",\"%s\",%f,%f,%u,%d,%u,%u,%u,%u,%u,%u,%u\n"; - boolean headerrow = !FIL_FileExists(csvpath); - UINT8 procbits = 0; - - // Bitness - if (sizeof(void*) == 4) - procbits = 32; - else if (sizeof(void*) == 8) - procbits = 64; - - f = fopen(csvpath, "a+"); - - if (f) - { - if (headerrow) - fputs(header, f); - fprintf(f, rowformat, - timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); - fclose(f); - CONS_Printf("Timedemo results saved to '%s'\n", csvpath); - } - else - { - // Just print the CSV output to console - CON_LogMessage(header); - CONS_Printf(rowformat, - timedemo_csv_id,timedemo_name,f1/TICRATE,f2/f1,leveltime,demotime,(UINT32)framecount,TICRATE,rendermode,vid.modenum,vid.width,vid.height,procbits); - } - } - - if (restorecv_vidwait != cv_vidwait.value) - CV_SetValue(&cv_vidwait, restorecv_vidwait); - D_AdvanceDemo(); + G_StopTimingDemo(); return true; } @@ -2473,27 +2497,7 @@ boolean G_CheckDemoStatus(void) if (demorecording) { - UINT8 *p = demobuffer+16; // checksum position -#ifdef NOMD5 - UINT8 i; - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - for (i = 0; i < 16; i++, p++) - *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. -#else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - md5_buffer((char *)p+16, demo_p - (p+16), p); // make a checksum of everything after the checksum in the file. -#endif - saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. - free(demobuffer); - demorecording = false; - - if (modeattacking != ATTACKING_RECORD) - { - if (saved) - CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); - else - CONS_Alert(CONS_WARNING, M_GetText("Demo %s not saved\n"), demoname); - } + G_StopDemoRecording(); return true; } From dd3c7aa0af1d2d947a2b4ee5706a30f615306642 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 15 May 2020 15:58:20 -0300 Subject: [PATCH 215/220] Fix colormap mipmap memory leak on the character select in OpenGL --- src/m_menu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 2977b432f..75c0650c7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9095,7 +9095,7 @@ static void M_DrawSetupChoosePlayerMenu(void) col = Color_Opposite[charskin->prefcolor - 1][0]; // Make the translation colormap - colormap = R_GetTranslationColormap(TC_DEFAULT, col, 0); + colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_CACHE); // Don't render the title map hidetitlemap = true; @@ -9171,8 +9171,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(TC_DEFAULT, curtextcolor, 0), - R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, curtextcolor, GTC_CACHE), + R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, GTC_CACHE), curtext ); } @@ -9204,8 +9204,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, 0), - R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, GTC_CACHE), + R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, GTC_CACHE), prevtext ); } @@ -9234,8 +9234,8 @@ static void M_DrawSetupChoosePlayerMenu(void) { V_DrawNameTag( x, y, V_CENTERNAMETAG, FRACUNIT, - R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, 0), - R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, 0), + R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, GTC_CACHE), + R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, GTC_CACHE), nexttext ); } From 00ac9deb5b8b6443343279570a33afe5ae0e38ee Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 15 May 2020 16:17:31 -0300 Subject: [PATCH 216/220] Fix missing sprite column --- src/r_main.c | 2 +- src/r_things.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index 9a3d98870..e47bb06e3 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1388,7 +1388,7 @@ void R_RenderPlayerView(player_t *player) else { portalclipstart = 0; - portalclipend = viewwidth-1; + portalclipend = viewwidth; R_ClearClipSegs(); } R_ClearDrawSegs(); diff --git a/src/r_things.c b/src/r_things.c index 61bd17cb9..31326ef72 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1688,7 +1688,7 @@ static void R_ProjectSprite(mobj_t *thing) // PORTAL SPRITE CLIPPING if (portalrender && portalclipline) { - if (x2 < portalclipstart || x1 > portalclipend) + if (x2 < portalclipstart || x1 >= portalclipend) return; if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) @@ -1958,7 +1958,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // PORTAL SPRITE CLIPPING if (portalrender && portalclipline) { - if (x2 < portalclipstart || x1 > portalclipend) + if (x2 < portalclipstart || x1 >= portalclipend) return; if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) From 69c86c63b3cf12c5253f724729ec628383419f06 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 15 May 2020 23:05:29 -0400 Subject: [PATCH 217/220] Fix A_SpinSpin not being usable in Lua or SOC due to an error --- src/dehacked.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 83654d520..d78a0d6c6 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2813,7 +2813,7 @@ static actionpointer_t actionpointers[] = {{A_ThrownRing}, "A_THROWNRING"}, {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, - {{A_SignSpin}, "S_SIGNSPIN"}, + {{A_SignSpin}, "A_SIGNSPIN"}, {{A_SignPlayer}, "A_SIGNPLAYER"}, {{A_OverlayThink}, "A_OVERLAYTHINK"}, {{A_JetChase}, "A_JETCHASE"}, From 20e4d5ab9e0f8353400939dd92a5e9a433530dbf Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 16 May 2020 16:14:47 +0100 Subject: [PATCH 218/220] lib_sStopSoundByID: fixed mixed declaration and code compiler warning --- src/lua_baselib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index da1f4e600..fb76b1ec8 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2461,11 +2461,10 @@ static int lib_sStopSound(lua_State *L) static int lib_sStopSoundByID(lua_State *L) { void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + sfxenum_t sound_id = luaL_checkinteger(L, 2); //NOHUD if (!origin) return LUA_ErrInvalid(L, "mobj_t"); - - sfxenum_t sound_id = luaL_checkinteger(L, 2); if (sound_id >= NUMSFX) return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1); From bf11e3a361be9e6128c8949fe9039ba0aebbcb31 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sat, 16 May 2020 23:22:33 +0200 Subject: [PATCH 219/220] Add missing packet name --- src/d_net.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_net.c b/src/d_net.c index 1db75f3da..a6768d75d 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -811,6 +811,7 @@ static const char *packettypename[NUMPACKETTYPE] = "CLIENTJOIN", "NODETIMEOUT", "RESYNCHING", + "LOGIN", "PING" }; From 4cd5d760666856b6d82fe90393ff5823b92fdcee Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 17 May 2020 14:18:27 +0200 Subject: [PATCH 220/220] Remove linedef type 21 from ZB config (somehow I forgot to do that) --- extras/conf/SRB2-22.cfg | 6 ------ 1 file changed, 6 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 5dd7a1c5b..7b1b678f2 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -750,12 +750,6 @@ linedeftypes prefix = "(20)"; } - 21 - { - title = "Explicitly Include Line "; - prefix = "(21)"; - } - 22 { title = "Parameters";