From b0cbc8ab2a59cd863c5c59f7593215fc1cd316a0 Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Wed, 2 Mar 2016 23:47:06 -0600 Subject: [PATCH 001/264] Lua slope manipulation stuff! Warning: Incomplete. Very prone to crashing and I might not have handled some things properly. Use with caution. --- src/dehacked.c | 6 ++ src/lua_libs.h | 1 + src/lua_maplib.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++- src/p_slopes.c | 2 +- src/p_slopes.h | 1 + 5 files changed, 220 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index d6a1881e6..d8847fd38 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7230,6 +7230,12 @@ struct { {"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. + // Slope flags + {"SL_NOPHYSICS",SL_NOPHYSICS}, // Don't do momentum adjustment with this slope + {"SL_NODYNAMIC",SL_NODYNAMIC}, // Slope will never need to move during the level, so don't fuss with recalculating it + {"SL_ANCHORVERTEX",SL_ANCHORVERTEX},// Slope is using a Slope Vertex Thing to anchor its position + {"SL_VERTEXSLOPE",SL_VERTEXSLOPE}, // Slope is built from three Slope Vertex Things + // Angles {"ANG1",ANG1>>16}, {"ANG2",ANG2>>16}, diff --git a/src/lua_libs.h b/src/lua_libs.h index d19ad8857..893f56683 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -38,6 +38,7 @@ extern lua_State *gL; #define META_SUBSECTOR "SUBSECTOR_T*" #define META_SECTOR "SECTOR_T*" #define META_FFLOOR "FFLOOR_T*" +#define META_SLOPE "PSLOPE_T*" #define META_MAPHEADER "MAPHEADER_T*" #define META_CVAR "CONSVAR_T*" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 16d05dacd..a6ebf1abe 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -16,6 +16,8 @@ #include "p_local.h" #include "p_setup.h" #include "z_zone.h" +#include "p_slopes.h" +#include "r_main.h" #include "lua_script.h" #include "lua_libs.h" @@ -37,7 +39,10 @@ enum sector_e { sector_thinglist, sector_heightsec, sector_camsec, - sector_ffloors + sector_ffloors, + sector_fslope, + sector_cslope, + sector_hasslope }; static const char *const sector_opt[] = { @@ -53,6 +58,9 @@ static const char *const sector_opt[] = { "heightsec", "camsec", "ffloors", + "f_slope", + "c_slope", + "hasslope", NULL}; enum subsector_e { @@ -158,6 +166,8 @@ enum ffloor_e { ffloor_toplightlevel, ffloor_bottomheight, ffloor_bottompic, + ffloor_tslope, + ffloor_bslope, ffloor_sector, ffloor_flags, ffloor_master, @@ -174,6 +184,8 @@ static const char *const ffloor_opt[] = { "toplightlevel", "bottomheight", "bottompic", + "t_slope", + "b_slope", "sector", // secnum pushed as control sector userdata "flags", "master", // control linedef @@ -183,6 +195,32 @@ static const char *const ffloor_opt[] = { "alpha", NULL}; +enum slope_e { + slope_valid = 0, + slope_o, + slope_d, + slope_zdelta, + slope_normal, + slope_zangle, + slope_xydirection, + slope_sourceline, + slope_refpos, + slope_flags +}; + +static const char *const slope_opt[] = { + "valid", + "o", + "d", + "zdelta", + "normal", + "zangle", + "xydirection", + "sourceline", + "refpos", + "flags", + NULL}; + static const char *const array_opt[] ={"iterate",NULL}; static const char *const valid_opt[] ={"valid",NULL}; @@ -330,6 +368,15 @@ static int sector_get(lua_State *L) LUA_PushUserdata(L, sector->ffloors, META_FFLOOR); lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function return 1; + case sector_fslope: // f_slope + LUA_PushUserdata(L, sector->f_slope, META_SLOPE); + return 1; + case sector_cslope: // c_slope + LUA_PushUserdata(L, sector->c_slope, META_SLOPE); + return 1; + case sector_hasslope: // hasslope + lua_pushboolean(L, sector->hasslope); + return 1; } return 0; } @@ -392,6 +439,9 @@ static int sector_set(lua_State *L) case sector_heightsec: // heightsec case sector_camsec: // camsec case sector_ffloors: // ffloors + case sector_fslope: // f_slope + case sector_cslope: // c_slope + case sector_hasslope: // hasslope default: return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); case sector_floorheight: { // floorheight @@ -1026,6 +1076,12 @@ static int ffloor_get(lua_State *L) lua_pushlstring(L, levelflat->name, 8); return 1; } + case ffloor_tslope: + LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE); + return 1; + case ffloor_bslope: + LUA_PushUserdata(L, *ffloor->b_slope, META_SLOPE); + return 1; case ffloor_sector: LUA_PushUserdata(L, §ors[ffloor->secnum], META_SECTOR); return 1; @@ -1065,6 +1121,8 @@ static int ffloor_set(lua_State *L) switch(field) { case ffloor_valid: // valid + case ffloor_tslope: // t_slope + case ffloor_bslope: // b_slope case ffloor_sector: // sector case ffloor_master: // master case ffloor_target: // target @@ -1125,6 +1183,150 @@ static int ffloor_set(lua_State *L) return 0; } +static int slope_get(lua_State *L) +{ + pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); + enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt); + + if (!slope) + { + if (field == slope_valid) { + lua_pushboolean(L, 0); + return 1; + } + return luaL_error(L, "accessed pslope_t doesn't exist anymore."); + } + + switch(field) + { + case slope_valid: // valid + lua_pushboolean(L, 1); + return 1; + case slope_o: // o + lua_createtable(L, 0, 3); + lua_pushfixed(L, slope->o.x); + lua_setfield(L, -2, "x"); + lua_pushfixed(L, slope->o.y); + lua_setfield(L, -2, "y"); + lua_pushfixed(L, slope->o.z); + lua_setfield(L, -2, "z"); + return 1; + case slope_d: // d + lua_createtable(L, 0, 2); + lua_pushfixed(L, slope->o.x); + lua_setfield(L, -2, "x"); + lua_pushfixed(L, slope->o.y); + lua_setfield(L, -2, "y"); + return 1; + case slope_zdelta: // zdelta + lua_pushfixed(L, slope->zdelta); + return 1; + case slope_normal: // normal + lua_createtable(L, 0, 2); + lua_pushfixed(L, slope->o.x); + lua_setfield(L, -2, "x"); + lua_pushfixed(L, slope->o.y); + lua_setfield(L, -2, "y"); + return 1; + case slope_zangle: // zangle + lua_pushangle(L, slope->zangle); + return 1; + case slope_xydirection: // xydirection + lua_pushangle(L, slope->xydirection); + return 1; + case slope_sourceline: // source linedef + LUA_PushUserdata(L, slope->sourceline, META_LINE); + return 1; + case slope_refpos: // refpos + lua_pushinteger(L, slope->refpos); + return 1; + case slope_flags: // flags + lua_pushinteger(L, slope->flags); + return 1; + } + return 0; +} + +static int slope_set(lua_State *L) +{ + pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); + enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt); + + if (!slope) + return luaL_error(L, "accessed pslope_t doesn't exist anymore."); + + if (hud_running) + return luaL_error(L, "Do not alter pslope_t in HUD rendering code!"); + + switch(field) // todo: reorganize this shit + { + case slope_valid: // valid + case slope_sourceline: // sourceline + case slope_d: // d + case slope_flags: // flags + case slope_normal: // normal + case slope_refpos: // refpos + default: + return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]); + case slope_o: { // o + luaL_checktype(L, 3, LUA_TTABLE); + + lua_getfield(L, 3, "x"); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_rawgeti(L, 3, 1); + } + if (!lua_isnil(L, -1)) + slope->o.x = luaL_checkfixed(L, -1); + else + slope->o.x = 0; + lua_pop(L, 1); + + lua_getfield(L, 3, "y"); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_rawgeti(L, 3, 2); + } + if (!lua_isnil(L, -1)) + slope->o.y = luaL_checkfixed(L, -1); + else + slope->o.y = 0; + lua_pop(L, 1); + + lua_getfield(L, 3, "z"); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_rawgeti(L, 3, 3); + } + if (!lua_isnil(L, -1)) + slope->o.z = luaL_checkfixed(L, -1); + else + slope->o.z = 0; + lua_pop(L, 1); + break; + } + case slope_zdelta: { // zdelta, this is temp until i figure out wtf to do + slope->zdelta = luaL_checkfixed(L, 3); + slope->zangle = R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta); + P_CalculateSlopeNormal(slope); + break; + } + case slope_zangle: // zangle + slope->zangle = luaL_checkangle(L, 3); + slope->zdelta = FINETANGENT(slope->zangle); + P_CalculateSlopeNormal(slope); + break; + case slope_xydirection: // xydirection + slope->xydirection = luaL_checkangle(L, 3); + P_CalculateSlopeNormal(slope); + break; + } + return 0; +} + static int lib_getMapheaderinfo(lua_State *L) { // i -> mapheaderinfo[i-1] @@ -1293,6 +1495,14 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); + luaL_newmetatable(L, META_SLOPE); + lua_pushcfunction(L, slope_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, slope_set); + lua_setfield(L, -2, "__newindex"); + lua_pop(L, 1); + luaL_newmetatable(L, META_MAPHEADER); lua_pushcfunction(L, mapheaderinfo_get); lua_setfield(L, -2, "__index"); diff --git a/src/p_slopes.c b/src/p_slopes.c index 2d55cf194..b51b2a4dc 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -46,7 +46,7 @@ static pslope_t *slopelist = NULL; static UINT16 slopecount = 0; // Calculate line normal -static void P_CalculateSlopeNormal(pslope_t *slope) { +void P_CalculateSlopeNormal(pslope_t *slope) { slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT); slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x); slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); diff --git a/src/p_slopes.h b/src/p_slopes.h index 8d82632ff..7898302e0 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -29,6 +29,7 @@ #define P_SLOPES_H__ #ifdef ESLOPE +void P_CalculateSlopeNormal(pslope_t *slope); void P_ResetDynamicSlopes(void); void P_RunDynamicSlopes(void); // P_SpawnSlope_Line From b3d842e8590938de3e4ac6cfea61a7df3023f4cc Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 3 Mar 2016 14:43:42 +0000 Subject: [PATCH 002/264] Fix accidental copy+paste of o to d and normal in slope_get code --- src/lua_maplib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index a6ebf1abe..218f26e1b 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1213,9 +1213,9 @@ static int slope_get(lua_State *L) return 1; case slope_d: // d lua_createtable(L, 0, 2); - lua_pushfixed(L, slope->o.x); + lua_pushfixed(L, slope->d.x); lua_setfield(L, -2, "x"); - lua_pushfixed(L, slope->o.y); + lua_pushfixed(L, slope->d.y); lua_setfield(L, -2, "y"); return 1; case slope_zdelta: // zdelta @@ -1223,9 +1223,9 @@ static int slope_get(lua_State *L) return 1; case slope_normal: // normal lua_createtable(L, 0, 2); - lua_pushfixed(L, slope->o.x); + lua_pushfixed(L, slope->normal.x); lua_setfield(L, -2, "x"); - lua_pushfixed(L, slope->o.y); + lua_pushfixed(L, slope->normal.y); lua_setfield(L, -2, "y"); return 1; case slope_zangle: // zangle From ad0069676a4cbc1201dbf3bfef35f28052df303b Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Thu, 3 Mar 2016 20:47:05 -0600 Subject: [PATCH 003/264] slope->normal is vector3_t, not vector2_t --- src/lua_maplib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 218f26e1b..f584ce4c3 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1222,11 +1222,13 @@ static int slope_get(lua_State *L) lua_pushfixed(L, slope->zdelta); return 1; case slope_normal: // normal - lua_createtable(L, 0, 2); + lua_createtable(L, 0, 3); lua_pushfixed(L, slope->normal.x); lua_setfield(L, -2, "x"); lua_pushfixed(L, slope->normal.y); lua_setfield(L, -2, "y"); + lua_pushfixed(L, slope->normal.z); + lua_setfield(L, -2, "z"); return 1; case slope_zangle: // zangle lua_pushangle(L, slope->zangle); From cb62f08364d4d53e51d4770198e2b65b3547e62b Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Thu, 20 Oct 2016 22:23:50 -0400 Subject: [PATCH 004/264] "PlayerQuit" hook --- src/lua_hook.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua_hook.h b/src/lua_hook.h index 804d99e12..240fdaece 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -43,6 +43,7 @@ enum hook { hook_PlayerMsg, hook_HurtMsg, hook_PlayerSpawn, + hook_PlayerQuit, hook_MAX // last hook }; @@ -77,5 +78,6 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook 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); // Hook for hurt messages #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer +boolean LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting #endif From cfb2feff8ef4344130bed3456937ecb9609c593a Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Thu, 20 Oct 2016 22:25:11 -0400 Subject: [PATCH 005/264] "PlayerQuit" hook --- src/lua_hooklib.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 1b9652571..be3f8b0e1 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -54,6 +54,7 @@ const char *const hookNames[hook_MAX+1] = { "PlayerMsg", "HurtMsg", "PlayerSpawn", + "PlayerQuit", NULL }; @@ -798,4 +799,41 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) // stack: tables } +boolean LUAh_PlayerQuit(player_t *plr, int reason) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8)))) + return false; + + lua_settop(gL, 0); + + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_PlayerQuit) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit + lua_pushinteger(gL, reason); // Reason for quitting + } + 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_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return hooked; +} + #endif From 89e8766b77f0176e9680522cd4a9b325a2e1b33c Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Thu, 20 Oct 2016 22:30:11 -0400 Subject: [PATCH 006/264] "PlayerQuit" hook --- src/d_clisrv.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c0f81ba32..973564a9b 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2208,7 +2208,7 @@ void CL_ClearPlayer(INT32 playernum) // // Removes a player from the current game // -static void CL_RemovePlayer(INT32 playernum) +static void CL_RemovePlayer(INT32 playernum, INT32 reason) { // Sanity check: exceptional cases (i.e. c-fails) can cause multiple // kick commands to be issued for the same player. @@ -2262,6 +2262,10 @@ static void CL_RemovePlayer(INT32 playernum) } } } + +#ifdef HAVE_BLUA + LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting +#endif // Reset player data CL_ClearPlayer(playernum); @@ -2513,6 +2517,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) INT32 pnum, msg; XBOXSTATIC char buf[3 + MAX_REASONLENGTH]; char *reason = buf; + INT32 kickreason = 1; pnum = READUINT8(*p); msg = READUINT8(*p); @@ -2593,14 +2598,17 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) { case KICK_MSG_GO_AWAY: CONS_Printf(M_GetText("has been kicked (Go away)\n")); + kickreason = 1; break; #ifdef NEWPING case KICK_MSG_PING_HIGH: CONS_Printf(M_GetText("left the game (Broke ping limit)\n")); + kickreason = 2; break; #endif case KICK_MSG_CON_FAIL: CONS_Printf(M_GetText("left the game (Synch failure)\n")); + kickreason = 3; if (M_CheckParm("-consisdump")) // Helps debugging some problems { @@ -2637,21 +2645,26 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) break; case KICK_MSG_TIMEOUT: CONS_Printf(M_GetText("left the game (Connection timeout)\n")); + kickreason = 4; break; case KICK_MSG_PLAYER_QUIT: if (netgame) // not splitscreen/bots CONS_Printf(M_GetText("left the game\n")); + kickreason = 6; break; case KICK_MSG_BANNED: CONS_Printf(M_GetText("has been banned (Don't come back)\n")); + kickreason = 5; break; case KICK_MSG_CUSTOM_KICK: READSTRINGN(*p, reason, MAX_REASONLENGTH+1); CONS_Printf(M_GetText("has been kicked (%s)\n"), reason); + kickreason = 1; break; case KICK_MSG_CUSTOM_BAN: READSTRINGN(*p, reason, MAX_REASONLENGTH+1); CONS_Printf(M_GetText("has been banned (%s)\n"), reason); + kickreason = 5; break; } @@ -2679,7 +2692,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING); } else - CL_RemovePlayer(pnum); + CL_RemovePlayer(pnum, kickreason); } consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; From fcf2fe79e00dae735cf383ce04422a6548fe4288 Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Thu, 20 Oct 2016 23:25:47 -0400 Subject: [PATCH 007/264] Oops; PlayerQuit isn't a boolean! --- src/lua_hook.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 240fdaece..94b934f32 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -78,6 +78,6 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook 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); // Hook for hurt messages #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer -boolean LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting +void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting #endif From defc7c164545eeae8db8f81de5c8ca46eff9af14 Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Thu, 20 Oct 2016 23:26:41 -0400 Subject: [PATCH 008/264] Oops; PlayerQuit isn't a boolean! --- src/lua_hooklib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index be3f8b0e1..5ac77da97 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -799,12 +799,12 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) // stack: tables } -boolean LUAh_PlayerQuit(player_t *plr, int reason) +void LUAh_PlayerQuit(player_t *plr, int reason) { hook_p hookp; boolean hooked = false; if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8)))) - return false; + return; lua_settop(gL, 0); From 673315265107da0740372f2ba1917cb89396c208 Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Fri, 21 Oct 2016 16:16:54 -0400 Subject: [PATCH 009/264] No more magic numbers --- src/d_clisrv.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 973564a9b..cfe0c1cdd 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2517,7 +2517,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) INT32 pnum, msg; XBOXSTATIC char buf[3 + MAX_REASONLENGTH]; char *reason = buf; - INT32 kickreason = 1; + kickreason_t kickreason = KR_KICK; pnum = READUINT8(*p); msg = READUINT8(*p); @@ -2598,17 +2598,17 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) { case KICK_MSG_GO_AWAY: CONS_Printf(M_GetText("has been kicked (Go away)\n")); - kickreason = 1; + kickreason = KR_KICK; break; #ifdef NEWPING case KICK_MSG_PING_HIGH: CONS_Printf(M_GetText("left the game (Broke ping limit)\n")); - kickreason = 2; + kickreason = KR_PINGLIMIT; break; #endif case KICK_MSG_CON_FAIL: CONS_Printf(M_GetText("left the game (Synch failure)\n")); - kickreason = 3; + kickreason = KR_SYNCH; if (M_CheckParm("-consisdump")) // Helps debugging some problems { @@ -2645,26 +2645,26 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) break; case KICK_MSG_TIMEOUT: CONS_Printf(M_GetText("left the game (Connection timeout)\n")); - kickreason = 4; + kickreason = KR_TIMEOUT; break; case KICK_MSG_PLAYER_QUIT: if (netgame) // not splitscreen/bots CONS_Printf(M_GetText("left the game\n")); - kickreason = 6; + kickreason = KR_LEAVE; break; case KICK_MSG_BANNED: CONS_Printf(M_GetText("has been banned (Don't come back)\n")); - kickreason = 5; + kickreason = KR_BAN; break; case KICK_MSG_CUSTOM_KICK: READSTRINGN(*p, reason, MAX_REASONLENGTH+1); CONS_Printf(M_GetText("has been kicked (%s)\n"), reason); - kickreason = 1; + kickreason = KR_KICK; break; case KICK_MSG_CUSTOM_BAN: READSTRINGN(*p, reason, MAX_REASONLENGTH+1); CONS_Printf(M_GetText("has been banned (%s)\n"), reason); - kickreason = 5; + kickreason = KR_BAN; break; } From c38457f23c70509cef3fd131e380332c2e43ab4f Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Fri, 21 Oct 2016 16:25:07 -0400 Subject: [PATCH 010/264] No more magic numbers --- src/d_clisrv.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 14b590926..cd726d9b3 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -436,6 +436,17 @@ extern consvar_t cv_playbackspeed; #define KICK_MSG_CUSTOM_KICK 7 #define KICK_MSG_CUSTOM_BAN 8 +typedef enum +{ + KR_KICK = 1, //Kicked by server + KR_PINGLIMIT = 2, //Broke Ping Limit + KR_SYNCH = 3, //Synch Failure + KR_TIMEOUT = 4, //Connection Timeout + KR_BAN = 5, //Banned by server + KR_LEAVE = 6, //Quit the game + +} kickreason_t; + extern boolean server; extern boolean dedicated; // for dedicated server extern UINT16 software_MAXPACKETLENGTH; From b5988e082cd012555e532d7c0a25b73818ec6566 Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Fri, 21 Oct 2016 16:27:15 -0400 Subject: [PATCH 011/264] No more magic numbers --- src/dehacked.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index f03dd73b4..62a7ad811 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -31,6 +31,7 @@ #include "fastcmp.h" #include "lua_script.h" #include "lua_hook.h" +#include "d_clisrv.h" #include "m_cond.h" @@ -7392,6 +7393,14 @@ struct { {"V_CHARCOLORSHIFT",V_CHARCOLORSHIFT}, {"V_ALPHASHIFT",V_ALPHASHIFT}, + + //Kick Reasons + {"KR_KICK",KR_KICK}, + {"KR_PINGLIMIT",KR_PINGLIMIT}, + {"KR_SYNCH",KR_SYNCH}, + {"KR_TIMEOUT",KR_TIMEOUT}, + {"KR_BAN",KR_BAN}, + {"KR_LEAVE",KR_LEAVE}, #endif {NULL,0} From b1ce5896aa97509268589cbcba26431c08f8adf9 Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Tue, 8 Nov 2016 10:30:01 -0500 Subject: [PATCH 012/264] Remove boolean remnants --- src/lua_hooklib.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 5ac77da97..16f8c55d3 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -802,7 +802,6 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) void LUAh_PlayerQuit(player_t *plr, int reason) { hook_p hookp; - boolean hooked = false; if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8)))) return; @@ -811,29 +810,16 @@ void LUAh_PlayerQuit(player_t *plr, int reason) for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerQuit) { - if (lua_gettop(gL) == 0) - { - LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit - lua_pushinteger(gL, reason); // Reason for quitting - } + LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit + lua_pushinteger(gL, reason); // Reason for quitting 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_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); + LUA_Call(gL, 2); } lua_settop(gL, 0); - return hooked; } #endif From d788cb7676e8832147d9e6ae911b10005987a85c Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Fri, 25 Nov 2016 15:20:41 -0500 Subject: [PATCH 013/264] Keeping the lua_gettop(gL) thing, otherwise the player/reason values will be pushed once to the stack each for every hook. Thanks MonsterIestyn! --- src/lua_hooklib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 16f8c55d3..7c10b7e38 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -810,7 +810,11 @@ void LUAh_PlayerQuit(player_t *plr, int reason) for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerQuit) { - LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit + lua_pushinteger(gL, reason); // Reason for quitting + } lua_pushinteger(gL, reason); // Reason for quitting lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); From dd13df230831debbfb08a447800ea8cc18bd4abf Mon Sep 17 00:00:00 2001 From: Prisima the Fox Date: Sat, 3 Dec 2016 18:18:16 -0500 Subject: [PATCH 014/264] Whoops, didn't see the duplicate line. --- src/lua_hooklib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 7c10b7e38..273264d7d 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -815,7 +815,6 @@ void LUAh_PlayerQuit(player_t *plr, int reason) LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit lua_pushinteger(gL, reason); // Reason for quitting } - lua_pushinteger(gL, reason); // Reason for quitting lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); lua_pushvalue(gL, -3); From a7dc20e7d2d53dad20f41884f382bfedf8f1d44e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 29 Aug 2016 22:42:06 +0100 Subject: [PATCH 015/264] Upper Unpegged on an FOF's control linedef now enables skewing of walls with respect to slopes Skewing direction is decided per in-level wall by the Lower Unpegged flag on in-level linedefs themselves, since they already decide the stuff for FOF wall pegging as it is. That is unless Transfer Line is involved which moves everything to the control sector linedefs instead... --- src/r_segs.c | 73 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 502ff3304..fff98dbf2 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -743,6 +743,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // Render FOF sides kinda like normal sides, with the frac and step and everything // NOTE: INT64 instead of fixed_t because overflow concerns INT64 top_frac, top_step, bottom_frac, bottom_step; + // skew FOF walls with slopes? + boolean slopeskew = false; + fixed_t ffloortextureslide = 0; + INT32 oldx = -1; + fixed_t left_top, left_bottom; // needed here for slope skewing + pslope_t *skewslope = NULL; #endif void (*colfunc_2s) (column_t *); @@ -966,21 +972,68 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) mceilingclip = ds->sprtopclip; dc_texheight = textureheight[texnum]>>FRACBITS; +#ifdef ESLOPE + // calculate both left ends + if (*pfloor->t_slope) + left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_bottom = *pfloor->bottomheight - viewz; + dc_texturemid = left_top; + skewslope = *pfloor->t_slope; // skew using top slope by default +#else dc_texturemid = *pfloor->topheight - viewz; +#endif if (newline) { offsetvalue = sides[newline->sidenum[0]].rowoffset; if (newline->flags & ML_DONTPEGBOTTOM) +#ifdef ESLOPE + { + dc_texturemid = left_bottom; + skewslope = *pfloor->b_slope; // skew using bottom slope + } +#else offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; +#endif +#ifdef ESLOPE + if (newline->flags & ML_DONTPEGTOP) + slopeskew = true; +#endif } else { offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; if (curline->linedef->flags & ML_DONTPEGBOTTOM) +#ifdef ESLOPE + { + dc_texturemid = left_bottom; + skewslope = *pfloor->b_slope; // skew using bottom slope + } +#else offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; +#endif +#ifdef ESLOPE + if (pfloor->master->flags & ML_DONTPEGTOP) // use control linedef's flags + slopeskew = true; +#endif } +#ifdef ESLOPE + if (slopeskew) + { + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + + if (skewslope) + ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); + } +#endif + dc_texturemid += offsetvalue; // Texture must be cached before setting colfunc_2s, @@ -999,23 +1052,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #ifdef ESLOPE // Set heights according to plane, or slope, whichever { - fixed_t left_top, right_top, left_bottom, right_bottom; + fixed_t right_top, right_bottom; + // calculate right ends now if (*pfloor->t_slope) - { - left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - } else - left_top = right_top = *pfloor->topheight - viewz; + right_top = *pfloor->topheight - viewz; if (*pfloor->b_slope) - { - left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - } else - left_bottom = right_bottom = *pfloor->bottomheight - viewz; + right_bottom = *pfloor->bottomheight - viewz; // using INT64 to avoid 32bit overflow top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); @@ -1039,6 +1087,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { if (maskedtexturecol[dc_x] != INT16_MAX) { +#ifdef ESLOPE + if (ffloortextureslide) { // skew FOF walls + if (oldx != -1) + dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< Date: Mon, 29 Aug 2016 23:21:57 +0100 Subject: [PATCH 016/264] If NOT skewing FOF walls, make sure dc_texturemid reverts to using unsloped FOF topheight/bottomheight rather than actual left side top/bottom heights --- src/r_segs.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index fff98dbf2..0d3a6430e 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -983,45 +983,45 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; else left_bottom = *pfloor->bottomheight - viewz; - dc_texturemid = left_top; skewslope = *pfloor->t_slope; // skew using top slope by default -#else - dc_texturemid = *pfloor->topheight - viewz; + if (newline && newline->flags & ML_DONTPEGTOP) + slopeskew = true; + else if (pfloor->master->flags & ML_DONTPEGTOP) + slopeskew = true; + + if (slopeskew) + dc_texturemid = left_top; + else #endif + dc_texturemid = *pfloor->topheight - viewz; if (newline) { offsetvalue = sides[newline->sidenum[0]].rowoffset; if (newline->flags & ML_DONTPEGBOTTOM) -#ifdef ESLOPE { - dc_texturemid = left_bottom; - skewslope = *pfloor->b_slope; // skew using bottom slope - } -#else - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; -#endif #ifdef ESLOPE - if (newline->flags & ML_DONTPEGTOP) - slopeskew = true; + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else #endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } } else { offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; if (curline->linedef->flags & ML_DONTPEGBOTTOM) -#ifdef ESLOPE { - dc_texturemid = left_bottom; - skewslope = *pfloor->b_slope; // skew using bottom slope - } -#else - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; -#endif #ifdef ESLOPE - if (pfloor->master->flags & ML_DONTPEGTOP) // use control linedef's flags - slopeskew = true; + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else #endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } } #ifdef ESLOPE From 40cb22a130be5dc06b22a280b44588430f5a8610 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 29 Aug 2016 23:24:59 +0100 Subject: [PATCH 017/264] probably best if we did this instead actually --- src/r_segs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 0d3a6430e..b997c2a88 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -984,8 +984,11 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else left_bottom = *pfloor->bottomheight - viewz; skewslope = *pfloor->t_slope; // skew using top slope by default - if (newline && newline->flags & ML_DONTPEGTOP) - slopeskew = true; + if (newline) + { + if (newline->flags & ML_DONTPEGTOP) + slopeskew = true; + } else if (pfloor->master->flags & ML_DONTPEGTOP) slopeskew = true; From 0b88c364bca99887530e6d00db3b4c8f56c0a43b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Aug 2018 18:01:54 +0100 Subject: [PATCH 018/264] Add "Tutorial" to the 1P menu, above "Start Game". It doesn't actually do anything yet, mind! Also, change said menu's def to start at "Start Game" when entering it for the first time. --- src/m_menu.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index f99f5d860..50850ecee 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -731,6 +731,7 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { + {IT_STRING, NULL, "Tutorial", NULL, 84}, {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108}, @@ -739,6 +740,7 @@ static menuitem_t SP_MainMenu[] = enum { + sptutorial, sploadgame, sprecordattack, spnightsmode, @@ -1554,7 +1556,18 @@ menu_t SR_EmblemHintDef = }; // Single Player -menu_t SP_MainDef = CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72); +menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72); +{ + NULL, + sizeof(SP_MainMenu)/sizeof(menuitem_t), + &MainDef, + SP_MainMenu, + M_DrawCenteredMenu, + BASEVIDWIDTH/2, 72, + 1, // start at "Start Game" on first entry + NULL +}; + menu_t SP_LoadDef = { "M_PICKG", From 51b8d6e01a512f758b8ebc0e933a959b140e1057 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Aug 2018 21:17:52 +0100 Subject: [PATCH 019/264] Make "Tutorial" warp directly to MAPZ0 (not configurable yet) --- src/m_menu.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 50850ecee..f8324ab7e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -273,6 +273,7 @@ menu_t SP_MainDef, OP_MainDef; menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef; // Single Player +static void M_StartTutorial(INT32 choice); static void M_LoadGame(INT32 choice); static void M_TimeAttackLevelSelect(INT32 choice); static void M_TimeAttack(INT32 choice); @@ -731,7 +732,7 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { - {IT_STRING, NULL, "Tutorial", NULL, 84}, + {IT_STRING, NULL, "Tutorial", M_StartTutorial, 84}, {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108}, @@ -6131,6 +6132,22 @@ static void M_LoadGameLevelSelect(INT32 choice) M_SetupNextMenu(&SP_LevelSelectDef); } +static INT32 tutorialmap = 1000; // MAPZ0, temporary value + +// Starts up the tutorial immediately (tbh I wasn't sure where else to put this) +static void M_StartTutorial(INT32 choice) +{ + (void)choice; + if (!tutorialmap) + return; // no map to go to, don't bother + + emeralds = 0; + M_ClearMenus(true); + gamecomplete = false; + cursaveslot = 0; + G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false); +} + // ============== // LOAD GAME MENU // ============== From 0da21244c0b0f36da86509916aaee66c6966cf07 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 12 Aug 2018 14:30:49 +0100 Subject: [PATCH 020/264] Added "Tutorialmap" MainCfg option for SOC --- src/dehacked.c | 13 +++++++++++++ src/doomstat.h | 2 ++ src/g_game.c | 2 ++ src/m_menu.c | 2 -- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index fb0f958c3..28c86f56e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2863,6 +2863,19 @@ static void readmaincfg(MYFILE *f) startchar = (INT16)value; char_on = -1; } + else if (fastcmp(word, "TUTORIALMAP")) + { + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. + + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + value = M_MapNumber(word2[0], word2[1]); + else + value = get_number(word2); + + tutorialmap = (INT16)value; + } else deh_warning("Maincfg: unknown word '%s'", word); } diff --git a/src/doomstat.h b/src/doomstat.h index 24b9e5753..18ae04584 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -132,6 +132,8 @@ extern INT16 titlemap; extern boolean hidetitlepics; extern INT16 bootmap; //bootmap for loading a map on startup +extern INT16 tutorialmap; // map to load for tutorial + extern boolean looptitle; // CTF colors. diff --git a/src/g_game.c b/src/g_game.c index 52358a8b9..da6f1bbd1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -127,6 +127,8 @@ INT16 titlemap = 0; boolean hidetitlepics = false; INT16 bootmap; //bootmap for loading a map on startup +INT16 tutorialmap = 0; // map to load for tutorial + boolean looptitle = false; UINT8 skincolor_redteam = SKINCOLOR_RED; diff --git a/src/m_menu.c b/src/m_menu.c index f8324ab7e..ec7215d46 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6132,8 +6132,6 @@ static void M_LoadGameLevelSelect(INT32 choice) M_SetupNextMenu(&SP_LevelSelectDef); } -static INT32 tutorialmap = 1000; // MAPZ0, temporary value - // Starts up the tutorial immediately (tbh I wasn't sure where else to put this) static void M_StartTutorial(INT32 choice) { From aba9bd13bbfaa52754a6b54fcc5bf6523c73958a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 4 Sep 2018 16:58:49 +0100 Subject: [PATCH 021/264] Add "tutorialmode" var to help the game know when we're in a tutorial or not, add placeholder for tutorial HUD to test it works --- src/d_main.c | 3 +++ src/d_netcmd.c | 2 ++ src/doomstat.h | 1 + src/g_game.c | 1 + src/m_menu.c | 2 ++ src/st_stuff.c | 11 +++++++++++ 6 files changed, 20 insertions(+) diff --git a/src/d_main.c b/src/d_main.c index 95af1f754..c6dd9dc46 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -714,6 +714,9 @@ void D_StartTitle(void) // reset modeattacking modeattacking = ATTACKING_NONE; + // The title screen is obviously not a tutorial! (Unless I'm mistaken) + tutorialmode = false; + // empty maptol so mario/etc sounds don't play in sound test when they shouldn't maptol = 0; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f9f960a70..e96d98f11 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1815,6 +1815,8 @@ static void Command_Map_f(void) else fromlevelselect = ((netgame || multiplayer) && ((gametype == newgametype) && (newgametype == GT_COOP))); + tutorialmode = false; // warping takes us out of tutorial mode + D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect); } diff --git a/src/doomstat.h b/src/doomstat.h index 1f78710e2..9a3bff7c0 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -133,6 +133,7 @@ extern boolean hidetitlepics; extern INT16 bootmap; //bootmap for loading a map on startup extern INT16 tutorialmap; // map to load for tutorial +extern boolean tutorialmode; // are we in a tutorial right now? extern boolean looptitle; diff --git a/src/g_game.c b/src/g_game.c index 4b2877f95..38289bcb2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -128,6 +128,7 @@ boolean hidetitlepics = false; INT16 bootmap; //bootmap for loading a map on startup INT16 tutorialmap = 0; // map to load for tutorial +boolean tutorialmode = false; // are we in a tutorial right now? boolean looptitle = false; diff --git a/src/m_menu.c b/src/m_menu.c index 103e629de..41fb1319d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6139,6 +6139,8 @@ static void M_StartTutorial(INT32 choice) if (!tutorialmap) return; // no map to go to, don't bother + tutorialmode = true; // turn on tutorial mode + emeralds = 0; M_ClearMenus(true); gamecomplete = false; diff --git a/src/st_stuff.c b/src/st_stuff.c index fa13e008a..246bae8bc 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2465,6 +2465,13 @@ static void ST_overlayDrawer(void) ST_drawDebugInfo(); } +static void ST_drawTutorial(void) +{ + // Nothing, ...yet + // Except this for now, just to check it works + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); +} + void ST_Drawer(void) { #ifdef SEENAMES @@ -2538,4 +2545,8 @@ void ST_Drawer(void) ST_overlayDrawer(); } } + + // Draw tutorial text over everything else + if (tutorialmode) + ST_drawTutorial(); } From bffaafd61ed98eb31e357b5c2a9c9a188528318b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 4 Sep 2018 19:21:58 +0100 Subject: [PATCH 022/264] Add V_DrawTutorialBack for drawing a console-like background box, add Lorem ipsum as filler test --- src/st_stuff.c | 8 +++++++- src/v_video.c | 19 +++++++++++++++++++ src/v_video.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 246bae8bc..1adc6596c 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2467,9 +2467,15 @@ static void ST_overlayDrawer(void) static void ST_drawTutorial(void) { + INT32 charheight = 8; + INT32 y = BASEVIDHEIGHT - ((charheight * 4) + (charheight/2)*5); + INT32 i; // Nothing, ...yet // Except this for now, just to check it works - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); + //V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); + V_DrawTutorialBack(); + for (i = 0; i < 4; i++, y += 12) + V_DrawString(0, y, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"); } void ST_Drawer(void) diff --git a/src/v_video.c b/src/v_video.c index 765965ffd..05401ce56 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1480,6 +1480,25 @@ void V_DrawFadeConsBack(INT32 plines) *buf = consolebgmap[*buf]; } +// Very similar to F_DrawFadeConsBack, except we draw from the middle(-ish) of the screen to the bottom. +void V_DrawTutorialBack(void) +{ + INT32 charheight = 8*vid.dupy; + UINT8 *deststop, *buf; + +#ifdef HWRENDER + if (rendermode != render_soft) // no support for OpenGL yet + return; +#endif + + // heavily simplified -- we don't need to know x or y position, + // just the start and stop positions + deststop = screens[0] + vid.rowbytes * vid.height; + buf = deststop - vid.rowbytes * ((charheight * 4) + (charheight/2)*5); // 4 lines of space plus gaps between and some leeway + for (; buf < deststop; ++buf) + *buf = consolebgmap[*buf]; +} + // Gets string colormap, used for 0x80 color codes // static const UINT8 *V_GetStringColormap(INT32 colorflags) diff --git a/src/v_video.h b/src/v_video.h index 6113d08ec..850206816 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -158,6 +158,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); void V_DrawFadeScreen(UINT16 color, UINT8 strength); void V_DrawFadeConsBack(INT32 plines); +void V_DrawTutorialBack(void); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); From 16c7c264a5b099e880b4469e044466e602775ca1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 4 Sep 2018 19:52:50 +0100 Subject: [PATCH 023/264] Wrap the text and snap to bottom --- src/st_stuff.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 1adc6596c..d4c710e97 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2468,14 +2468,16 @@ static void ST_overlayDrawer(void) static void ST_drawTutorial(void) { INT32 charheight = 8; - INT32 y = BASEVIDHEIGHT - ((charheight * 4) + (charheight/2)*5); - INT32 i; + INT32 y = BASEVIDHEIGHT - ((charheight * 4) + (charheight/2)*4); + char *test; + //INT32 i; // Nothing, ...yet // Except this for now, just to check it works //V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); V_DrawTutorialBack(); - for (i = 0; i < 4; i++, y += 12) - V_DrawString(0, y, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"); + //for (i = 0; i < 4; i++, y += 12) + test = V_WordWrap(4, BASEVIDWIDTH-4, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"); + V_DrawString(4, y, V_SNAPTOBOTTOM, test); } void ST_Drawer(void) From d26ba2ee5451bb53bf15384b1ad7af12ecd665ff Mon Sep 17 00:00:00 2001 From: PrisimaTheFox Date: Sun, 9 Sep 2018 23:16:28 -0500 Subject: [PATCH 024/264] Update m_anigif.c More accurate GIF delay. --- src/m_anigif.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 2540665ad..5c7cfbd68 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -492,7 +492,9 @@ static void GIF_framewrite(void) // screen regions are handled in GIF_lzw { - UINT16 delay = 3; // todo + int d1 = (int)((100.0/NEWTICRATE)*gif_frames); + int d2 = (int)((100.0/NEWTICRATE)*(gif_frames-1)); + UINT16 delay = d1-d2; INT32 startline; WRITEMEM(p, gifframe_gchead, 4); From 4ada0b0a9e42f5b3b71cf509bc66f7881104b4aa Mon Sep 17 00:00:00 2001 From: PrisimaTheFox Date: Sun, 9 Sep 2018 23:33:51 -0500 Subject: [PATCH 025/264] Update m_anigif.c Remember gif_frames starts at 0 --- src/m_anigif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 5c7cfbd68..d46d889bb 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -492,8 +492,8 @@ static void GIF_framewrite(void) // screen regions are handled in GIF_lzw { - int d1 = (int)((100.0/NEWTICRATE)*gif_frames); - int d2 = (int)((100.0/NEWTICRATE)*(gif_frames-1)); + int d1 = (int)((100.0/NEWTICRATE)*gif_frames+1); + int d2 = (int)((100.0/NEWTICRATE)*(gif_frames)); UINT16 delay = d1-d2; INT32 startline; From f8834b02019b03c9bead2414a28f790d6ce933f9 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 25 Mar 2018 19:07:21 -0400 Subject: [PATCH 026/264] MT_NIGHTSBUMPER Spawn: Don't reset mthing->options (cherry picked from commit dc9fd6f02ed4b681ed4982d119672f07cc91e585) --- src/p_mobj.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 5f85474c6..1e2fe4f8f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9194,9 +9194,6 @@ ML_NOCLIMB : Direction not controllable // the bumper in 30 degree increments. mobj->threshold = (mthing->options & 15) % 12; // It loops over, etc P_SetMobjState(mobj, mobj->info->spawnstate+mobj->threshold); - - // you can shut up now, OBJECTFLIP. And all of the other options, for that matter. - mthing->options &= ~0xF; break; case MT_EGGCAPSULE: if (mthing->angle <= 0) From b666fa3131ec391f85dfc1cc56de047ebaf53ec2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 25 Mar 2018 19:42:46 -0400 Subject: [PATCH 027/264] P_SpawnMapThing: Ignore MTF_ flags if MT_NIGHTSBUMPER (cherry picked from commit d85f108997bfeca3e0b1731c1aad70617456400b) --- src/p_mobj.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1e2fe4f8f..a146027b9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9381,6 +9381,14 @@ ML_NOCLIMB : Direction not controllable } } + // ignore MTF_ flags and return early + if (i == MT_NIGHTSBUMPER) + { + mobj->angle = FixedAngle(mthing->angle*FRACUNIT); + mthing->mobj = mobj; + return; + } + mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if ((mthing->options & MTF_AMBUSH) From b59aa2710433ca89744f4f9a91eb1e0dba727c6f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 09:37:02 -0400 Subject: [PATCH 028/264] Loose ends other targets (cherry picked from commit 9a5fc5f66a31baf713c6f32f7a696b933da6907b) --- src/android/i_sound.c | 22 ++++----- src/djgppdos/i_sound.c | 28 +---------- src/dummy/i_sound.c | 15 ++---- src/sdl/sdl_sound.c | 6 +-- src/win32/win_main.c | 4 +- src/win32/win_snd.c | 106 +++++++++++++++++++++-------------------- 6 files changed, 74 insertions(+), 107 deletions(-) diff --git a/src/android/i_sound.c b/src/android/i_sound.c index ecf96f2f0..1011dbb6a 100644 --- a/src/android/i_sound.c +++ b/src/android/i_sound.c @@ -64,12 +64,12 @@ void I_InitMusic(void){} void I_ShutdownMusic(void){} -void I_PauseSong(INT32 handle) +void I_PauseSong(void) { (void)handle; } -void I_ResumeSong(INT32 handle) +void I_ResumeSong(void) { (void)handle; } @@ -80,23 +80,19 @@ void I_ResumeSong(INT32 handle) UINT8 midimusic_started = 0; -void I_InitMIDIMusic(void){} - -void I_ShutdownMIDIMusic(void){} - -void I_SetMIDIMusicVolume(INT32 volume) -{ - (void)volume; -} - -INT32 I_RegisterSong(void *data, size_t len) +boolean I_LoadSong(char *data, size_t len) { (void)data; (void)len; return -1; } -boolean I_PlaySong(INT32 handle, INT32 looping) +void I_SetMIDIMusicVolume(INT32 volume) +{ + (void)volume; +} + +boolean I_PlaySong(boolean looping) { (void)handle; (void)looping; diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c index 88fc807f4..105e8d67a 100644 --- a/src/djgppdos/i_sound.c +++ b/src/djgppdos/i_sound.c @@ -408,31 +408,7 @@ void I_ShutdownMIDIMusic(void) music_started=false; } -void I_InitDigMusic(void) -{ -// CONS_Printf("Digital music not yet supported under DOS.\n"); -} - -void I_ShutdownDigMusic(void) -{ -// CONS_Printf("Digital music not yet supported under DOS.\n"); -} - -void I_InitMusic(void) -{ - if (!nodigimusic) - I_InitDigMusic(); - if (!nomidimusic) - I_InitMIDIMusic(); -} - -void I_ShutdownMusic(void) -{ - I_ShutdownMIDIMusic(); - I_ShutdownDigMusic(); -} - -boolean I_PlaySong(INT32 handle, INT32 looping) +boolean I_PlaySong(boolean looping) { handle = 0; if (nomidimusic) @@ -495,7 +471,7 @@ void I_UnRegisterSong(INT32 handle) //destroy_midi(currsong); } -INT32 I_RegisterSong(void *data, size_t len) +boolean I_LoadSong(char *data, size_t len) { int e = len; //Alam: For error if (nomidimusic) diff --git a/src/dummy/i_sound.c b/src/dummy/i_sound.c index 51dbb610d..2f6f0001c 100644 --- a/src/dummy/i_sound.c +++ b/src/dummy/i_sound.c @@ -70,7 +70,7 @@ void I_PauseSong(INT32 handle) (void)handle; } -void I_ResumeSong(INT32 handle) +void I_ResumeSong(void) { (void)handle; } @@ -79,23 +79,14 @@ void I_ResumeSong(INT32 handle) // MIDI I/O // -void I_InitMIDIMusic(void){} - -void I_ShutdownMIDIMusic(void){} - -void I_SetMIDIMusicVolume(UINT8 volume) -{ - (void)volume; -} - -INT32 I_RegisterSong(void *data, size_t len) +boolean I_LoadSong(char *data, size_t len) { (void)data; (void)len; return -1; } -boolean I_PlaySong(INT32 handle, boolean looping) +boolean I_PlaySong(boolean looping) { (void)handle; (void)looping; diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 6c70c163b..c714f675b 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1605,7 +1605,7 @@ static void I_PauseGME(void) #endif } -void I_PauseSong(INT32 handle) +void I_PauseSong(void) { (void)handle; I_PauseGME(); @@ -1625,7 +1625,7 @@ static void I_ResumeGME(void) #endif } -void I_ResumeSong(INT32 handle) +void I_ResumeSong(void) { (void)handle; I_ResumeGME(); @@ -1669,7 +1669,7 @@ void I_UnRegisterSong(INT32 handle) #endif } -INT32 I_RegisterSong(void *data, size_t len) +boolean I_LoadSong(char *data, size_t len) { #ifdef HAVE_MIXER if (nomidimusic || !musicStarted) diff --git a/src/win32/win_main.c b/src/win32/win_main.c index 6c774f557..bfe620a43 100644 --- a/src/win32/win_main.c +++ b/src/win32/win_main.c @@ -110,9 +110,9 @@ static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPAR // pause music when alt-tab if (appActive && !paused) - I_ResumeSong(0); + I_ResumeSong(); else if (!paused) - I_PauseSong(0); + I_PauseSong(); { HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); DWORD mode; diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index f168f1fe3..18c88d267 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -456,14 +456,14 @@ void I_ShutdownMusic(void) I_ShutdownMIDIMusic(); } -void I_PauseSong(INT32 handle) +void I_PauseSong(void) { UNREFERENCED_PARAMETER(handle); if (music_stream) FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, true)); } -void I_ResumeSong(INT32 handle) +void I_ResumeSong(void) { UNREFERENCED_PARAMETER(handle); if (music_stream) @@ -644,60 +644,64 @@ boolean I_StartDigSong(const char *musicname, boolean looping) current_track = 0; // Try to find a loop point in streaming music formats (ogg, mp3) - if (looping) - { - FMOD_RESULT e; - FMOD_TAG tag; - unsigned int loopstart, loopend; + FMOD_RESULT e; + FMOD_TAG tag; + unsigned int loopstart, loopend; - // A proper LOOPPOINT is its own tag, stupid. - e = FMOD_Sound_GetTag(music_stream, "LOOPPOINT", 0, &tag); - if (e != FMOD_ERR_TAGNOTFOUND) + // A proper LOOPPOINT is its own tag, stupid. + e = FMOD_Sound_GetTag(music_stream, "LOOPPOINT", 0, &tag); + if (e != FMOD_ERR_TAGNOTFOUND) + { + FMR(e); + loopstart = atoi((char *)tag.data); // assumed to be a string data tag. + FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM)); + if (loopstart > 0) + FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM)); + return true; + } + + // todo + // if(music type == MIDI) + // { + // FMR(FMOD_Sound_SetMode(music_stream, FMOD_LOOP_NORMAL)); + // return true; + // } + + // Use LOOPMS for time in miliseconds. + e = FMOD_Sound_GetTag(music_stream, "LOOPMS", 0, &tag); + if (e != FMOD_ERR_TAGNOTFOUND) + { + FMR(e); + loopstart = atoi((char *)tag.data); // assumed to be a string data tag. + FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_MS, &loopend, FMOD_TIMEUNIT_PCM)); + if (loopstart > 0) + FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_MS, loopend, FMOD_TIMEUNIT_PCM)); + return true; + } + + // Try to fetch it from the COMMENT tag, like A.J. Freda + e = FMOD_Sound_GetTag(music_stream, "COMMENT", 0, &tag); + if (e != FMOD_ERR_TAGNOTFOUND) + { + char *loopText; + // Handle any errors that arose, first + FMR(e); + // Figure out where the number starts + loopText = strstr((char *)tag.data,"LOOPPOINT="); + if (loopText != NULL) { - FMR(e); - loopstart = atoi((char *)tag.data); // assumed to be a string data tag. + // Skip the "LOOPPOINT=" part. + loopText += 10; + // Convert it to our looppoint + // FMOD seems to ensure the tag is properly NULL-terminated. + // atoi will stop when it reaches anything that's not a number. + loopstart = atoi(loopText); + // Now do the rest like above FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM)); if (loopstart > 0) FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM)); - return true; - } - - // Use LOOPMS for time in miliseconds. - e = FMOD_Sound_GetTag(music_stream, "LOOPMS", 0, &tag); - if (e != FMOD_ERR_TAGNOTFOUND) - { - FMR(e); - loopstart = atoi((char *)tag.data); // assumed to be a string data tag. - FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_MS, &loopend, FMOD_TIMEUNIT_PCM)); - if (loopstart > 0) - FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_MS, loopend, FMOD_TIMEUNIT_PCM)); - return true; - } - - // Try to fetch it from the COMMENT tag, like A.J. Freda - e = FMOD_Sound_GetTag(music_stream, "COMMENT", 0, &tag); - if (e != FMOD_ERR_TAGNOTFOUND) - { - char *loopText; - // Handle any errors that arose, first - FMR(e); - // Figure out where the number starts - loopText = strstr((char *)tag.data,"LOOPPOINT="); - if (loopText != NULL) - { - // Skip the "LOOPPOINT=" part. - loopText += 10; - // Convert it to our looppoint - // FMOD seems to ensure the tag is properly NULL-terminated. - // atoi will stop when it reaches anything that's not a number. - loopstart = atoi(loopText); - // Now do the rest like above - FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM)); - if (loopstart > 0) - FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM)); - } - return true; } + return true; } // No special loop point, but we're playing so it's all good. @@ -825,7 +829,7 @@ void I_SetMIDIMusicVolume(UINT8 volume) FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, volume / 31.0)); } -INT32 I_RegisterSong(void *data, size_t len) +boolean I_PlaySong(boolean looping) { FMOD_CREATESOUNDEXINFO fmt; memset(&fmt, 0, sizeof(FMOD_CREATESOUNDEXINFO)); From 06b73679414f3c52755ee407833b0d965f0ab761 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 10:18:38 -0400 Subject: [PATCH 029/264] Added I_GetMusicType and removed midimode variable * Revised S_PlayMusic arguments * Now music plays again! (cherry picked from commit 55f3803e4b9f8104c90cc6c769d54121e5bac0b8) --- src/i_sound.h | 18 +++++++++++++++ src/s_sound.c | 16 +++++++------ src/sdl/mixer_sound.c | 54 +++++++++++++++++++++++++++++++++---------- 3 files changed, 69 insertions(+), 19 deletions(-) diff --git a/src/i_sound.h b/src/i_sound.h index 084479ee1..0fe62d5eb 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -18,6 +18,21 @@ #include "sounds.h" #include "command.h" +// copied from SDL mixer, plus GME +typedef enum { + MU_NONE, + MU_CMD, + MU_WAV, + MU_MOD, + MU_MID, + MU_OGG, + MU_MP3, + MU_MP3_MAD_UNUSED, // use MU_MP3 instead + MU_FLAC, + MU_MODPLUG_UNUSED, // use MU_MOD instead + MU_GME +} musictype_t; + /** \brief Sound subsystem runing and waiting */ extern UINT8 sound_started; @@ -108,6 +123,9 @@ void I_SetSfxVolume(UINT8 volume); // // MUSIC I/O // + +musictype_t I_GetMusicType(void); + /** \brief Init the music systems */ void I_InitMusic(void); diff --git a/src/s_sound.c b/src/s_sound.c index 76ee4c649..279f0dc6d 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1227,7 +1227,7 @@ static boolean S_MIDIMusic(const char *mname, boolean looping) return true; } -static boolean S_DigMusic(const char *mname, boolean looping) +static boolean S_PlayMusic(boolean looping) { if (nodigimusic || digital_disabled) return false; // try midi @@ -1235,11 +1235,6 @@ static boolean S_DigMusic(const char *mname, boolean looping) if (!I_StartDigSong(mname, looping)) return false; - strncpy(music_name, mname, 7); - music_name[6] = 0; - music_lumpnum = LUMPERROR; - music_data = NULL; - music_handle = 0; return true; } @@ -1262,11 +1257,18 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) if (strncmp(music_name, mmusic, 6)) { S_StopMusic(); // shutdown old music - if (!S_DigMusic(mmusic, looping) && !S_MIDIMusic(mmusic, looping)) + + if (!S_LoadMusic(mmusic)) { CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic); return; } + + if (!S_PlayMusic(looping)) + { + CONS_Alert(CONS_ERROR, "Music cannot be played!\n"); + return; + } } I_SetSongTrack(mflags & MUSIC_TRACKMASK); } diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 5211efe0a..0888d5d31 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -62,7 +62,6 @@ UINT8 sound_started = false; -static boolean midimode; static Mix_Music *music; static UINT8 music_volume, midi_volume, sfx_volume; static float loop_point; @@ -87,7 +86,6 @@ void I_StartupSound(void) return; } - midimode = false; music = NULL; music_volume = midi_volume = sfx_volume = 0; @@ -436,6 +434,25 @@ void I_SetSfxVolume(UINT8 volume) // Music // +musictype_t I_GetMusicType(void) +{ +#ifdef HAVE_LIBGME + if (gme) + return MU_GME; + else +#endif + if (!music) + return MU_NONE; + else if (Mix_GetMusicType(music) == MUS_MID) + return MU_MID; + else if (Mix_GetMusicType(music) == MUS_MOD || Mix_GetMusicType(music) == MUS_MODPLUG_UNUSED) + return MU_MOD; + else if (Mix_GetMusicType(music) == MUS_MP3 || Mix_GetMusicType(music) == MUS_MP3_MAD_UNUSED) + return MU_MP3; + else + return (musictype_t)Mix_GetMusicType(music); +} + // Music hooks static void music_loop(void) { @@ -470,8 +487,19 @@ FUNCMATH void I_InitMusic(void) void I_ShutdownMusic(void) { - I_ShutdownDigMusic(); - I_ShutdownMIDIMusic(); +#ifdef HAVE_LIBGME + if (gme) + { + Mix_HookMusic(NULL, NULL); + gme_delete(gme); + gme = NULL; + } +#endif + if (!music) + return; + Mix_HookMusicFinished(NULL); + Mix_FreeMusic(music); + music = NULL; } void I_PauseSong(INT32 handle) @@ -492,7 +520,15 @@ void I_ResumeSong(INT32 handle) // Digital Music // -void I_InitDigMusic(void) +void I_SetDigMusicVolume(UINT8 volume) +{ + music_volume = volume; + if (I_GetMusicType() == MU_MID || !music) + return; + Mix_VolumeMusic((UINT32)volume*128/31); +} + +boolean I_SetSongSpeed(float speed) { #ifdef HAVE_LIBGME gme = NULL; @@ -691,8 +727,6 @@ boolean I_StartDigSong(const char *musicname, boolean looping) void I_StopDigSong(void) { - if (midimode) - return; #ifdef HAVE_LIBGME if (gme) { @@ -791,7 +825,7 @@ void I_SetMIDIMusicVolume(UINT8 volume) midi_volume = 31; //midi_volume = volume; - if (!midimode || !music) + if (I_GetMusicType() != MU_MID || !music) return; Mix_VolumeMusic((UINT32)midi_volume*128/31); } @@ -834,10 +868,6 @@ void I_StopSong(INT32 handle) void I_UnRegisterSong(INT32 handle) { - if (!midimode || !music) - return; - - (void)handle; Mix_FreeMusic(music); music = NULL; } From 46b53e8baeede0df6c75d93697301a027aeb8a70 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 10:19:04 -0400 Subject: [PATCH 030/264] Added I_GetMusicType and removed midimode variable: other targets (cherry picked from commit 14b393ab16736bb44dab6fd4a90b7bdd8ff782e0) --- src/android/i_sound.c | 24 ++---- src/djgppdos/i_sound.c | 33 ++++----- src/dummy/i_sound.c | 31 ++++---- src/sdl/sdl_sound.c | 98 +++++++++++-------------- src/win32/win_snd.c | 162 +++++++++++++++++++---------------------- 5 files changed, 155 insertions(+), 193 deletions(-) diff --git a/src/android/i_sound.c b/src/android/i_sound.c index 1011dbb6a..c3fc038e5 100644 --- a/src/android/i_sound.c +++ b/src/android/i_sound.c @@ -60,6 +60,11 @@ void I_SetSfxVolume(INT32 volume) // UINT8 music_started = 0; +musictype_t I_GetMusicType(void) +{ + return MU_NONE; +} + void I_InitMusic(void){} void I_ShutdownMusic(void){} @@ -99,12 +104,12 @@ boolean I_PlaySong(boolean looping) return false; } -void I_StopSong(INT32 handle) +void I_StopSong(void) { (void)handle; } -void I_UnRegisterSong(INT32 handle) +void I_UnloadSong(void) { (void)handle; } @@ -115,19 +120,6 @@ void I_UnRegisterSong(INT32 handle) UINT8 digmusic_started = 0; -void I_InitDigMusic(void){} - -void I_ShutdownDigMusic(void){} - -boolean I_StartDigSong(const char *musicname, INT32 looping) -{ - (void)musicname; - (void)looping; - return false; -} - -void I_StopDigSong(void){} - void I_SetDigMusicVolume(INT32 volume) { (void)volume; @@ -137,4 +129,4 @@ boolean I_SetSongSpeed(float speed) { (void)speed; return false; -} +} \ No newline at end of file diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c index 105e8d67a..4c8ceb20c 100644 --- a/src/djgppdos/i_sound.c +++ b/src/djgppdos/i_sound.c @@ -322,6 +322,13 @@ static int islooping=0; static int musicdies=-1; UINT8 music_started=0; +musictype_t I_GetMusicType(void) +{ + if (currsong) + return MU_MID; + else + return MU_NONE; +} /* load_midi_mem: * Loads a standard MIDI file from memory, returning a pointer to @@ -389,7 +396,7 @@ static MIDI *load_midi_mem(char *mempointer,int *e) return midi; } -void I_InitMIDIMusic(void) +void I_InitMusic(void) { if (nomidimusic) return; @@ -398,12 +405,12 @@ void I_InitMIDIMusic(void) music_started = true; } -void I_ShutdownMIDIMusic(void) +void I_ShutdownMusic(void) { if ( !music_started ) return; - I_StopSong(1); + I_StopSong(); music_started=false; } @@ -439,7 +446,7 @@ void I_ResumeSong (INT32 handle) midi_resume(); } -void I_StopSong(INT32 handle) +void I_StopSong(void) { handle = 0; if (nomidimusic) @@ -462,7 +469,7 @@ int I_QrySongPlaying(int handle) } #endif -void I_UnRegisterSong(INT32 handle) +void I_UnloadSong(void) { handle = 0; if (nomidimusic) @@ -496,20 +503,6 @@ boolean I_LoadSong(char *data, size_t len) return 1; } -/// \todo Add OGG/MP3 support for dos -boolean I_StartDigSong(const char *musicname, INT32 looping) -{ - musicname = NULL; - looping = 0; - //CONS_Printf("I_StartDigSong: Not yet supported under DOS.\n"); - return false; -} - -void I_StopDigSong(void) -{ -// CONS_Printf("I_StopDigSong: Not yet supported under DOS.\n"); -} - void I_SetDigMusicVolume(INT32 volume) { volume = 0; @@ -524,4 +517,4 @@ boolean I_SetSongSpeed(float speed) { (void)speed; return false; -} +} \ No newline at end of file diff --git a/src/dummy/i_sound.c b/src/dummy/i_sound.c index 2f6f0001c..60cf51f73 100644 --- a/src/dummy/i_sound.c +++ b/src/dummy/i_sound.c @@ -61,11 +61,21 @@ void I_SetSfxVolume(UINT8 volume) // MUSIC I/O // +musictype_t I_GetMusicType(void) +{ + return MU_NONE; +} + void I_InitMusic(void){} void I_ShutdownMusic(void){} -void I_PauseSong(INT32 handle) +void I_SetMIDIMusicVolume(UINT8 volume) +{ + (void)volume; +} + +void I_PauseSong(void) { (void)handle; } @@ -93,12 +103,12 @@ boolean I_PlaySong(boolean looping) return false; } -void I_StopSong(INT32 handle) +void I_StopSong(void) { (void)handle; } -void I_UnRegisterSong(INT32 handle) +void I_UnloadSong(void) { (void)handle; } @@ -107,19 +117,6 @@ void I_UnRegisterSong(INT32 handle) // DIGMUSIC I/O // -void I_InitDigMusic(void){} - -void I_ShutdownDigMusic(void){} - -boolean I_StartDigSong(const char *musicname, boolean looping) -{ - (void)musicname; - (void)looping; - return false; -} - -void I_StopDigSong(void){} - void I_SetDigMusicVolume(UINT8 volume) { (void)volume; @@ -135,4 +132,4 @@ boolean I_SetSongTrack(int track) { (void)track; return false; -} +} \ No newline at end of file diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index c714f675b..b729d4d89 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1313,10 +1313,27 @@ void I_StartupSound(void) // MUSIC API. // -void I_ShutdownMIDIMusic(void) +musictype_t I_GetMusicType(void) { - nomidimusic = false; - if (nodigimusic) I_ShutdownMusic(); +#ifdef HAVE_MIXER +#ifdef HAVE_LIBGME + if (gme) + return MU_GME; + else +#endif + if (!music) + return MU_NONE; + else if (Mix_GetMusicType(music) == MUS_MID) + return MU_MID; + else if (Mix_GetMusicType(music) == MUS_MOD || Mix_GetMusicType(music) == MUS_MODPLUG_UNUSED) + return MU_MOD; + else if (Mix_GetMusicType(music) == MUS_MP3 || Mix_GetMusicType(music) == MUS_MP3_MAD_UNUSED) + return MU_MP3; + else + return (musictype_t)Mix_GetMusicType(music); +#else + return MU_NONE +#endif } #ifdef HAVE_LIBGME @@ -1330,12 +1347,6 @@ static void I_ShutdownGMEMusic(void) } #endif -void I_ShutdownDigMusic(void) -{ - nodigimusic = false; - if (nomidimusic) I_ShutdownMusic(); -} - #ifdef HAVE_MIXER static boolean LoadSong(void *data, size_t lumplength, size_t selectpos) { @@ -1436,8 +1447,8 @@ void I_ShutdownMusic(void) CONS_Printf("%s", M_GetText("I_ShutdownMusic: ")); - I_UnRegisterSong(0); - I_StopDigSong(); + I_UnloadSong(); + I_StopSong(); Mix_CloseAudio(); #ifdef MIX_INIT Mix_Quit(); @@ -1450,16 +1461,6 @@ void I_ShutdownMusic(void) #endif } -void I_InitMIDIMusic(void) -{ - if (nodigimusic) I_InitMusic(); -} - -void I_InitDigMusic(void) -{ - if (nomidimusic) I_InitMusic(); -} - void I_InitMusic(void) { #ifdef HAVE_MIXER @@ -1639,17 +1640,29 @@ void I_ResumeSong(void) #endif } -void I_StopSong(INT32 handle) +void I_StopSong(void) { - (void)handle; + I_StopGME(); #ifdef HAVE_MIXER - if (nomidimusic || !musicStarted) + if (nodigimusic) return; - Mix_FadeOutMusic(MIDIfade); + +#ifdef MIXER_POS + if (canlooping) + Mix_HookMusicFinished(NULL); #endif + + Mix_HaltMusic(); + while (Mix_PlayingMusic()) + ; + + if (music[1]) + Mix_FreeMusic(music[1]); + music[1] = NULL; + LoadSong(NULL, 0, 1); } -void I_UnRegisterSong(INT32 handle) +void I_UnloadSong(void) { #ifdef HAVE_MIXER @@ -1714,7 +1727,7 @@ static void I_CleanupGME(void *userdata) static boolean I_StartGMESong(const char *musicname, boolean looping) { #ifdef HAVE_LIBGME - XBOXSTATIC char filename[9]; + char filename[9]; void *data; lumpnum_t lumpnum; size_t lumplength; @@ -1769,7 +1782,7 @@ static boolean I_StartGMESong(const char *musicname, boolean looping) boolean I_StartDigSong(const char *musicname, boolean looping) { #ifdef HAVE_MIXER - XBOXSTATIC char filename[9]; + char filename[9]; void *data; lumpnum_t lumpnum; size_t lumplength; @@ -1786,7 +1799,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) lumpnum = W_CheckNumForName(filename); - I_StopDigSong(); + I_StopSong(); if (lumpnum == LUMPERROR) { @@ -1811,7 +1824,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) { size_t scan; const char *dataum = data; - XBOXSTATIC char looplength[64]; + char looplength[64]; UINT32 loopstart = 0; UINT8 newcount = 0; @@ -1938,29 +1951,6 @@ static void I_StopGME(void) #endif } -void I_StopDigSong(void) -{ - I_StopGME(); -#ifdef HAVE_MIXER - if (nodigimusic) - return; - -#ifdef MIXER_POS - if (canlooping) - Mix_HookMusicFinished(NULL); -#endif - - Mix_HaltMusic(); - while (Mix_PlayingMusic()) - ; - - if (music[1]) - Mix_FreeMusic(music[1]); - music[1] = NULL; - LoadSong(NULL, 0, 1); -#endif -} - void I_SetDigMusicVolume(UINT8 volume) { I_SetMIDIMusicVolume(volume); @@ -1995,4 +1985,4 @@ static void SDLCALL I_FinishMusic(void) if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); } #endif -#endif //HAVE_SDL +#endif //HAVE_SDL \ No newline at end of file diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index 18c88d267..295d68680 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -22,12 +22,10 @@ #define HAVE_ZLIB #ifndef _MSC_VER -#ifndef _WII #ifndef _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE #endif #endif -#endif #ifndef _LFS64_LARGEFILE #define _LFS64_LARGEFILE @@ -44,7 +42,6 @@ static FMOD_SYSTEM *fsys; static FMOD_SOUND *music_stream; static FMOD_CHANNEL *music_channel; -static boolean midimode; static UINT8 music_volume, midi_volume, sfx_volume; static INT32 current_track; @@ -446,14 +443,48 @@ void I_SetSfxVolume(UINT8 volume) // MUSIC // +musictype_t I_GetMusicType(void) +{ +#ifdef HAVE_LIBGME + if (gme) + return MU_GME; +#endif + + if (!music_stream) + return MU_NONE; + + FMOD_SOUND_TYPE type; + if (FMOD_Sound_GetFormat(music_stream, &type, NULL, NULL, NULL) == FMOD_OK) + { + switch(type) + { + case FMOD_SOUND_TYPE_WAV: + return MU_WAV; + case FMOD_SOUND_TYPE_MOD: + return MU_MOD; + case FMOD_SOUND_TYPE_MID: + return MU_MID; + case FMOD_SOUND_TYPE_OGGVORBIS: + return MU_OGG; + case FMOD_SOUND_TYPE_MP3: + return MU_MP3; + case FMOD_SOUND_TYPE_FLAC: + return MU_FLAC; + default: + return MU_NONE; + } + } + else + return MU_NONE; +} + void I_InitMusic(void) { } void I_ShutdownMusic(void) { - I_ShutdownDigMusic(); - I_ShutdownMIDIMusic(); + I_StopSong(); } void I_PauseSong(void) @@ -470,17 +501,7 @@ void I_ResumeSong(void) FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, false)); } -void I_InitDigMusic(void) -{ -} - -void I_ShutdownDigMusic(void) -{ - if (!midimode) - I_StopDigSong(); -} - -boolean I_StartDigSong(const char *musicname, boolean looping) +boolean I_LoadSong(char *data, size_t len) { char *data; size_t len; @@ -492,10 +513,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) lumpnum = W_CheckNumForName(va("D_%s",musicname)); if (lumpnum == LUMPERROR) return false; - midimode = true; } - else - midimode = false; data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC); len = W_LumpLength(lumpnum); @@ -605,8 +623,6 @@ boolean I_StartDigSong(const char *musicname, boolean looping) { gme_equalizer_t gmeq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; Z_Free(data); // We don't need this anymore. - gme_start_track(gme, 0); - current_track = 0; gme_set_equalizer(gme,&gmeq); fmt.format = FMOD_SOUND_FORMAT_PCM16; fmt.defaultfrequency = 44100; @@ -616,32 +632,21 @@ boolean I_StartDigSong(const char *musicname, boolean looping) fmt.pcmreadcallback = GMEReadCallback; fmt.userdata = gme; FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER | (looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream)); - FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); - FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); - FMR(FMOD_Channel_SetPriority(music_channel, 0)); return true; } #endif fmt.length = len; + + FMOD_RESULT e = FMOD_System_CreateStream(fsys, data, FMOD_OPENMEMORY_POINT|(looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream); + if (e != FMOD_OK) { - FMOD_RESULT e = FMOD_System_CreateStream(fsys, data, FMOD_OPENMEMORY_POINT|(looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream); - if (e != FMOD_OK) - { - if (e == FMOD_ERR_FORMAT) - CONS_Alert(CONS_WARNING, "Failed to play music lump %s due to invalid format.\n", W_CheckNameForNum(lumpnum)); - else - FMR(e); - return false; - } + if (e == FMOD_ERR_FORMAT) + CONS_Alert(CONS_WARNING, "Failed to play music lump %s due to invalid format.\n", W_CheckNameForNum(lumpnum)); + else + FMR(e); + return false; } - FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); - if (midimode) - FMR(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0)); - else - FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); - FMR(FMOD_Channel_SetPriority(music_channel, 0)); - current_track = 0; // Try to find a loop point in streaming music formats (ogg, mp3) FMOD_RESULT e; @@ -704,28 +709,15 @@ boolean I_StartDigSong(const char *musicname, boolean looping) return true; } - // No special loop point, but we're playing so it's all good. + // No special loop point return true; } -void I_StopDigSong(void) -{ - if (music_stream) - FMR(FMOD_Sound_Release(music_stream)); - music_stream = NULL; -#ifdef HAVE_LIBGME - if (gme) - gme_delete(gme); - gme = NULL; -#endif - current_track = -1; -} - void I_SetDigMusicVolume(UINT8 volume) { // volume is 0 to 31. music_volume = volume; - if (!midimode && music_stream) + if (I_GetMusicType() != MU_MID && music_stream) FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, volume / 31.0)); } @@ -811,57 +803,55 @@ boolean I_SetSongTrack(INT32 track) // Fuck MIDI. ... Okay fine, you can have your silly D_-only mode. // -void I_InitMIDIMusic(void) -{ -} - -void I_ShutdownMIDIMusic(void) -{ - if (midimode) - I_StopSong(0); -} - void I_SetMIDIMusicVolume(UINT8 volume) { // volume is 0 to 31. midi_volume = volume; - if (midimode && music_stream) + if (I_GetMusicType() != MU_MID && music_stream) FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, volume / 31.0)); } boolean I_PlaySong(boolean looping) { - FMOD_CREATESOUNDEXINFO fmt; - memset(&fmt, 0, sizeof(FMOD_CREATESOUNDEXINFO)); - fmt.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); - fmt.length = len; - FMR(FMOD_System_CreateStream(fsys, (char *)data, FMOD_OPENMEMORY_POINT, &fmt, &music_stream)); - return 1337; -} - -boolean I_PlaySong(INT32 handle, boolean looping) -{ - if (1337 == handle) +#ifdef HAVE_LIBGME + if (gme) { - midimode = true; - if (looping) - FMR(FMOD_Sound_SetMode(music_stream, FMOD_LOOP_NORMAL)); + gme_start_track(gme, 0); + current_track = 0; FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); - FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0)); - FMR_MUSIC(FMOD_Channel_SetPriority(music_channel, 0)); + FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); + FMR(FMOD_Channel_SetPriority(music_channel, 0)); + return true; } +#endif + + FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); + if (I_GetMusicType() != MU_MID) + FMR(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0)); + else + FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); + FMR(FMOD_Channel_SetPriority(music_channel, 0)); + current_track = 0; + return true; } -void I_StopSong(INT32 handle) +void I_StopSong(void) { - I_UnRegisterSong(handle); +#ifdef HAVE_LIBGME + if (gme) + gme_delete(gme); + gme = NULL; +#endif + current_track = -1; + + I_UnloadSong(); } -void I_UnRegisterSong(INT32 handle) +void I_UnloadSong(void) { UNREFERENCED_PARAMETER(handle); if (music_stream) FMR(FMOD_Sound_Release(music_stream)); music_stream = NULL; -} +} \ No newline at end of file From a7ed7b2c90e5dcc2b342adca4227a33a1432d38d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 11:51:23 -0400 Subject: [PATCH 031/264] Consolidate I_SetDigMusicVolume and I_SetMIDIMusicVolume into one method * In s_sound, they are merged to one method as well, but there are still two separate digvolume and seqvolume variables * Simplified Dig/MidiMusicDisabled in s_sound * Method reordering (cherry picked from commit 701cc5a7dd1dfead87a42ec7558c9fa6a1deb193) --- src/d_netcmd.c | 4 +- src/i_sound.h | 47 ++----- src/s_sound.c | 161 +++++++++++++++-------- src/s_sound.h | 28 +++- src/sdl/mixer_sound.c | 298 +++++++++++++++--------------------------- 5 files changed, 242 insertions(+), 296 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index bf26ca61a..ab3201c5c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3963,11 +3963,9 @@ static void Command_RestartAudio_f(void) // These must be called or no sound and music until manually set. I_SetSfxVolume(cv_soundvolume.value); - I_SetDigMusicVolume(cv_digmusicvolume.value); - I_SetMIDIMusicVolume(cv_midimusicvolume.value); + S_SetMusicVolume(cv_digmusicvolume.value, cv_midimusicvolume.value); if (Playing()) // Gotta make sure the player is in a level P_RestoreMusic(&players[consoleplayer]); - } /** Quits a game and returns to the title screen. diff --git a/src/i_sound.h b/src/i_sound.h index 0fe62d5eb..1d4d6ff72 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -140,7 +140,7 @@ void I_ShutdownMusic(void); \return void */ -void I_PauseSong(INT32 handle); +void I_PauseSong(void); /** \brief RESUME game handling @@ -148,20 +148,12 @@ void I_PauseSong(INT32 handle); \return void */ -void I_ResumeSong(INT32 handle); +void I_ResumeSong(void); // // MIDI I/O // -/** \brief Startup the MIDI music system -*/ -void I_InitMIDIMusic(void); - -/** \brief Shutdown the MIDI music system -*/ -void I_ShutdownMIDIMusic(void); - /** \brief The I_SetMIDIMusicVolume function \param volume volume to set at @@ -179,7 +171,7 @@ void I_SetMIDIMusicVolume(UINT8 volume); \todo Remove this */ -INT32 I_RegisterSong(void *data, size_t len); +boolean I_LoadSong(char *data, size_t len); /** \brief Called by anything that wishes to start music @@ -190,7 +182,7 @@ INT32 I_RegisterSong(void *data, size_t len); \todo pass music name, not handle */ -boolean I_PlaySong(INT32 handle, boolean looping); +boolean I_PlaySong(boolean looping); /** \brief Stops a song over 3 seconds @@ -199,46 +191,25 @@ boolean I_PlaySong(INT32 handle, boolean looping); /todo drop handle */ -void I_StopSong(INT32 handle); +void I_StopSong(void); -/** \brief See ::I_RegisterSong, then think backwards +/** \brief See ::I_LoadSong, then think backwards \param handle song handle - \sa I_RegisterSong + \sa I_LoadSong \todo remove midi handle */ -void I_UnRegisterSong(INT32 handle); +void I_UnloadSong(void); // // DIGMUSIC I/O // -/** \brief Startup the music system -*/ -void I_InitDigMusic(void); - -/** \brief Shutdown the music system -*/ -void I_ShutdownDigMusic(void); - boolean I_SetSongSpeed(float speed); boolean I_SetSongTrack(INT32 track); -/** \brief The I_StartDigSong function - - \param musicname music lump name - \param looping if true, loop the song - - \return if true, song playing -*/ -boolean I_StartDigSong(const char *musicname, boolean looping); - -/** \brief stop non-MIDI song -*/ -void I_StopDigSong(void); - /** \brief The I_SetDigMusicVolume function \param volume volume to set at @@ -297,4 +268,4 @@ void I_PlayCD(UINT8 track, UINT8 looping); */ boolean I_SetVolumeCD(INT32 volume); -#endif +#endif \ No newline at end of file diff --git a/src/s_sound.c b/src/s_sound.c index 279f0dc6d..a1c53acd2 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1180,28 +1180,71 @@ const char *compat_special_music_slots[16] = #define music_playing (music_name[0]) // String is empty if no music is playing static char music_name[7]; // up to 6-character name -static lumpnum_t music_lumpnum; // lump number of music (used??) -static void *music_data; // music raw data -static INT32 music_handle; // once registered, the handle for the music +static boolean mus_paused = 0; // whether songs are mus_paused -static boolean mus_paused = 0; // whether songs are mus_paused +/// ------------------------ +/// Music Status +/// ------------------------ -static boolean S_MIDIMusic(const char *mname, boolean looping) +boolean S_DigMusicDisabled() +{ + return (nodigimusic || digital_disabled); +} + +boolean S_MIDIMusicDisabled() +{ + return (nomidimusic || music_disabled); +} + +boolean S_MusicDisabled() +{ + return ( + (nodigimusic && nomidimusic) || + (music_disabled && digital_disabled) || + (nodigimusic && music_disabled) || + (nomidimusic && digital_disabled) + ); +} + +/// ------------------------ +/// Music Properties +/// ------------------------ + +boolean S_SpeedMusic(float speed) +{ + return I_SetSongSpeed(speed); +} + +/// ------------------------ +/// Music Routines +/// ------------------------ + +static boolean S_LoadMusic(const char *mname) { lumpnum_t mlumpnum; void *mdata; - INT32 mhandle; - if (nomidimusic || music_disabled) - return false; // didn't search. - - if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR) + if (S_MusicDisabled()) return false; - mlumpnum = W_GetNumForName(va("d_%s", mname)); + + if (S_DigMusicDisabled()) + { + if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR) + return false; + mlumpnum = W_GetNumForName(va("d_%s", mname)); + } + else + { + if (W_CheckNumForName(va("o_%s", mname)) != LUMPERROR) + mlumpnum = W_GetNumForName(va("o_%s", mname)); + else if (W_CheckNumForName(va("d_%s", mname)) != LUMPERROR) + mlumpnum = W_GetNumForName(va("d_%s", mname)); + else + return false; + } // load & register it mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC); - mhandle = I_RegisterSong(mdata, W_LumpLength(mlumpnum)); #ifdef MUSSERV if (msg_id != -1) @@ -1215,16 +1258,20 @@ static boolean S_MIDIMusic(const char *mname, boolean looping) } #endif - // play it - if (!I_PlaySong(mhandle, looping)) + if (I_LoadSong(mdata, W_LumpLength(mlumpnum))) + { + strncpy(music_name, mname, 7); + music_name[6] = 0; + return true; + } + else return false; +} - strncpy(music_name, mname, 7); - music_name[6] = 0; - music_lumpnum = mlumpnum; - music_data = mdata; - music_handle = mhandle; - return true; +static void S_UnloadMusic(void) +{ + I_UnloadSong(); + music_name[0] = 0; } static boolean S_PlayMusic(boolean looping) @@ -1232,9 +1279,13 @@ static boolean S_PlayMusic(boolean looping) if (nodigimusic || digital_disabled) return false; // try midi - if (!I_StartDigSong(mname, looping)) + if (!I_PlaySong(looping)) + { + S_UnloadMusic(); return false; + } + S_InitMusicVolume(); // switch between digi and sequence volume return true; } @@ -1244,7 +1295,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) S_ClearSfx(); #endif - if ((nomidimusic || music_disabled) && (nodigimusic || digital_disabled)) + if (S_MusicDisabled()) return; // No Music (empty string) @@ -1273,60 +1324,55 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) I_SetSongTrack(mflags & MUSIC_TRACKMASK); } -boolean S_SpeedMusic(float speed) -{ - return I_SetSongSpeed(speed); -} - void S_StopMusic(void) { if (!music_playing) return; if (mus_paused) - I_ResumeSong(music_handle); - - if (!nodigimusic) - I_StopDigSong(); + I_ResumeSong(); S_SpeedMusic(1.0f); - I_StopSong(music_handle); - I_UnRegisterSong(music_handle); + I_StopSong(); + I_UnloadSong(); #ifndef HAVE_SDL //SDL uses RWOPS Z_ChangeTag(music_data, PU_CACHE); #endif - music_data = NULL; music_name[0] = 0; } -void S_SetDigMusicVolume(INT32 volume) +void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) { - if (volume < 0 || volume > 31) - CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n"); + if (digvolume < 0) + digvolume = cv_digmusicvolume.value; + if (seqvolume < 0) + seqvolume = cv_midimusicvolume.value; - CV_SetValue(&cv_digmusicvolume, volume&31); + if (digvolume < 0 || digvolume > 31) + CONS_Alert(CONS_WARNING, "digmusicvolume should be between 0-31\n"); + CV_SetValue(&cv_digmusicvolume, digvolume&31); actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var -#ifdef DJGPPDOS - I_SetDigMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this. -#endif - I_SetDigMusicVolume(volume&31); -} - -void S_SetMIDIMusicVolume(INT32 volume) -{ - if (volume < 0 || volume > 31) - CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n"); - - CV_SetValue(&cv_midimusicvolume, volume&0x1f); + if (digvolume < 0 || digvolume > 31) + CONS_Alert(CONS_WARNING, "midimusicvolume should be between 0-31\n"); + CV_SetValue(&cv_midimusicvolume, seqvolume&31); actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var #ifdef DJGPPDOS - I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this. + digvolume = seqvolume = 31; #endif - I_SetMIDIMusicVolume(volume&0x1f); + + switch(I_GetMusicType()) + { + case MU_MID: + case MU_MOD: + case MU_GME: + I_SetMusicVolume(seqvolume&31); + default: + I_SetMusicVolume(digvolume&31); + } } /// ------------------------ @@ -1346,8 +1392,7 @@ void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume) return; S_SetSfxVolume(sfxVolume); - S_SetDigMusicVolume(digMusicVolume); - S_SetMIDIMusicVolume(midiMusicVolume); + S_SetMusicVolume(digMusicVolume, midiMusicVolume); SetChannelsNum(); @@ -1403,11 +1448,11 @@ void S_Start(void) void S_PauseAudio(void) { if (!nodigimusic) - I_PauseSong(0); + I_PauseSong(); if (music_playing && !mus_paused) { - I_PauseSong(music_handle); + I_PauseSong(); mus_paused = true; } @@ -1422,11 +1467,11 @@ void S_PauseAudio(void) void S_ResumeAudio(void) { if (!nodigimusic) - I_ResumeSong(0); + I_ResumeSong(); else if (music_playing && mus_paused) { - I_ResumeSong(music_handle); + I_ResumeSong(); mus_paused = false; } diff --git a/src/s_sound.h b/src/s_sound.h index 39ec769a6..bce3ab8bb 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -97,6 +97,25 @@ void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume); // Stop sound for thing at void S_StopSound(void *origin); +// +// Music Status +// + +boolean S_DigMusicDisabled(); +boolean S_MIDIMusicDisabled(); +boolean S_MusicDisabled(); + +// +// Music Properties +// + +// Set Speed of Music +boolean S_SpeedMusic(float speed); + +// +// Music Routines +// + // Start music track, arbitrary, given its name, and set whether looping // note: music flags 12 bits for tracknum (gme, other formats with more than one track) // 13-15 aren't used yet @@ -104,9 +123,6 @@ void S_StopSound(void *origin); #define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b) void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping); -// Set Speed of Music -boolean S_SpeedMusic(float speed); - // Stops the music. void S_StopMusic(void); @@ -121,9 +137,11 @@ void S_UpdateSounds(void); FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2); -void S_SetDigMusicVolume(INT32 volume); -void S_SetMIDIMusicVolume(INT32 volume); void S_SetSfxVolume(INT32 volume); +void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume); +#define S_SetDigMusicVolume(a) S_SetMusicVolume(a,-1) +#define S_SetMIDIMusicVolume(a) S_SetMusicVolume(-1,a) +#define S_InitMusicVolume() S_SetMusicVolume(-1,-1) INT32 S_OriginPlaying(void *origin); INT32 S_IdPlaying(sfxenum_t id); diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 0888d5d31..457f74f95 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -483,6 +483,10 @@ static void mix_gme(void *udata, Uint8 *stream, int len) FUNCMATH void I_InitMusic(void) { +#ifdef HAVE_LIBGME + gme = NULL; + current_track = -1; +#endif } void I_ShutdownMusic(void) @@ -502,16 +506,14 @@ void I_ShutdownMusic(void) music = NULL; } -void I_PauseSong(INT32 handle) +void I_PauseSong(void) { - (void)handle; Mix_PauseMusic(); songpaused = true; } -void I_ResumeSong(INT32 handle) +void I_ResumeSong(void) { - (void)handle; Mix_ResumeMusic(); songpaused = false; } @@ -520,59 +522,66 @@ void I_ResumeSong(INT32 handle) // Digital Music // -void I_SetDigMusicVolume(UINT8 volume) -{ - music_volume = volume; - if (I_GetMusicType() == MU_MID || !music) - return; - Mix_VolumeMusic((UINT32)volume*128/31); -} - boolean I_SetSongSpeed(float speed) { -#ifdef HAVE_LIBGME - gme = NULL; - current_track = -1; -#endif -} - -void I_ShutdownDigMusic(void) -{ - if (midimode) - return; + if (speed > 250.0f) + speed = 250.0f; //limit speed up to 250x #ifdef HAVE_LIBGME if (gme) { - Mix_HookMusic(NULL, NULL); - gme_delete(gme); - gme = NULL; + SDL_LockAudio(); + gme_set_tempo(gme, speed); + SDL_UnlockAudio(); + return true; } +#else + (void)speed; #endif - if (!music) - return; - Mix_HookMusicFinished(NULL); - Mix_FreeMusic(music); - music = NULL; + return false; } -boolean I_StartDigSong(const char *musicname, boolean looping) +boolean I_SetSongTrack(int track) { - char *data; - size_t len; - lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname)); +#ifdef HAVE_LIBGME + if (current_track == track) + return false; + // If the specified track is within the number of tracks playing, then change it + if (gme) + { + SDL_LockAudio(); + if (track >= 0 + && track < gme_track_count(gme)) + { + gme_err_t gme_e = gme_start_track(gme, track); + if (gme_e != NULL) + { + CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); + return false; + } + current_track = track; + SDL_UnlockAudio(); + return true; + } + SDL_UnlockAudio(); + return false; + } +#endif + (void)track; + return false; +} + +// +// MIDI Music +// + +boolean I_LoadSong(char *data, size_t len) +{ I_Assert(!music); #ifdef HAVE_LIBGME I_Assert(!gme); #endif - if (lumpnum == LUMPERROR) - return false; - midimode = false; - - data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC); - len = W_LumpLength(lumpnum); - #ifdef HAVE_LIBGME if ((UINT8)data[0] == 0x1F && (UINT8)data[1] == 0x8B) @@ -663,8 +672,6 @@ boolean I_StartDigSong(const char *musicname, boolean looping) else if (!gme_open_data(data, len, &gme, 44100)) { gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - gme_start_track(gme, 0); - current_track = 0; gme_set_equalizer(gme, &eq); Mix_HookMusic(mix_gme, gme); return true; @@ -675,48 +682,62 @@ boolean I_StartDigSong(const char *musicname, boolean looping) if (!music) { CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); - return true; + return false; } // Find the OGG loop point. loop_point = 0.0f; - if (looping) + + const char *key1 = "LOOP"; + const char *key2 = "POINT="; + const char *key3 = "MS="; + const size_t key1len = strlen(key1); + const size_t key2len = strlen(key2); + const size_t key3len = strlen(key3); + char *p = data; + while ((UINT32)(p - data) < len) { - const char *key1 = "LOOP"; - const char *key2 = "POINT="; - const char *key3 = "MS="; - const size_t key1len = strlen(key1); - const size_t key2len = strlen(key2); - const size_t key3len = strlen(key3); - char *p = data; - while ((UINT32)(p - data) < len) + if (strncmp(p++, key1, key1len)) + continue; + p += key1len-1; // skip OOP (the L was skipped in strncmp) + if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=? { - if (strncmp(p++, key1, key1len)) - continue; - p += key1len-1; // skip OOP (the L was skipped in strncmp) - if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=? - { - p += key2len; // skip POINT= - loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count. - // because SDL_Mixer is USELESS and can't even tell us - // something simple like the frequency of the streaming music, - // we are unfortunately forced to assume that ALL MUSIC is 44100hz. - // This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly. - } - else if (!strncmp(p, key3, key3len)) // is it LOOPMS=? - { - p += key3len; // skip MS= - loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds. - // Everything that uses LOOPMS will work perfectly with SDL_Mixer. - } - // Neither?! Continue searching. + p += key2len; // skip POINT= + loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count. + // because SDL_Mixer is USELESS and can't even tell us + // something simple like the frequency of the streaming music, + // we are unfortunately forced to assume that ALL MUSIC is 44100hz. + // This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly. } + else if (!strncmp(p, key3, key3len)) // is it LOOPMS=? + { + p += key3len; // skip MS= + loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds. + // Everything that uses LOOPMS will work perfectly with SDL_Mixer. + } + // Neither?! Continue searching. } + return true; +} + +boolean I_PlaySong(boolean looping) +{ + if (!music) + return false; +#ifdef HAVE_GME + if (gme) + { + gme_start_track(gme, 0); + current_track = 0; + return true; + } +#endif + if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1) { CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); - return true; + return false; } Mix_VolumeMusic((UINT32)music_volume*128/31); @@ -725,7 +746,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) return true; } -void I_StopDigSong(void) +void I_StopSong(void) { #ifdef HAVE_LIBGME if (gme) @@ -744,132 +765,25 @@ void I_StopDigSong(void) music = NULL; } -void I_SetDigMusicVolume(UINT8 volume) +void I_SetMusicVolume(UINT8 volume) { - music_volume = volume; - if (midimode || !music) - return; - Mix_VolumeMusic((UINT32)volume*128/31); -} - -boolean I_SetSongSpeed(float speed) -{ - if (speed > 250.0f) - speed = 250.0f; //limit speed up to 250x -#ifdef HAVE_LIBGME - if (gme) - { - SDL_LockAudio(); - gme_set_tempo(gme, speed); - SDL_UnlockAudio(); - return true; - } -#else - (void)speed; -#endif - return false; -} - -boolean I_SetSongTrack(int track) -{ -#ifdef HAVE_LIBGME - if (current_track == track) - return false; - - // If the specified track is within the number of tracks playing, then change it - if (gme) - { - SDL_LockAudio(); - if (track >= 0 - && track < gme_track_count(gme)) - { - gme_err_t gme_e = gme_start_track(gme, track); - if (gme_e != NULL) - { - CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); - return false; - } - current_track = track; - SDL_UnlockAudio(); - return true; - } - SDL_UnlockAudio(); - return false; - } -#endif - (void)track; - return false; -} - -// -// MIDI Music -// - -FUNCMATH void I_InitMIDIMusic(void) -{ -} - -void I_ShutdownMIDIMusic(void) -{ - if (!midimode || !music) - return; - Mix_FreeMusic(music); - music = NULL; -} - -void I_SetMIDIMusicVolume(UINT8 volume) -{ - // HACK: Until we stop using native MIDI, - // disable volume changes - (void)volume; - midi_volume = 31; - //midi_volume = volume; - - if (I_GetMusicType() != MU_MID || !music) - return; - Mix_VolumeMusic((UINT32)midi_volume*128/31); -} - -INT32 I_RegisterSong(void *data, size_t len) -{ - music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE); if (!music) - { - CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); - return -1; - } - return 1337; -} - -boolean I_PlaySong(INT32 handle, boolean looping) -{ - (void)handle; - - midimode = true; - - if (Mix_PlayMusic(music, looping ? -1 : 0) == -1) - { - CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); - return false; - } - - Mix_VolumeMusic((UINT32)midi_volume*128/31); - return true; -} - -void I_StopSong(INT32 handle) -{ - if (!midimode || !music) return; - (void)handle; - Mix_HaltMusic(); + if (I_GetMusicType() == MU_MID) + // HACK: Until we stop using native MIDI, + // disable volume changes + music_volume = 31; + else + music_volume = volume; + + Mix_VolumeMusic((UINT32)music_volume*128/31); } -void I_UnRegisterSong(INT32 handle) +void I_UnloadSong(void) { Mix_FreeMusic(music); music = NULL; } -#endif +#endif \ No newline at end of file From e58a8f4fe18609531a5eb06e1d1b302b6cf6c197 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 11:54:58 -0400 Subject: [PATCH 032/264] Consolidate I_SetDigMusicVolume and I_SetMIDIMusicVolume other targets (cherry picked from commit 9fb9386f84b3739fe765a78bcb9683eb7e98bc36) --- src/android/i_sound.c | 7 +------ src/djgppdos/i_sound.c | 12 +----------- src/dummy/i_sound.c | 7 +------ src/sdl/sdl_sound.c | 7 +------ src/win32/win_snd.c | 22 ++++++++++------------ 5 files changed, 14 insertions(+), 41 deletions(-) diff --git a/src/android/i_sound.c b/src/android/i_sound.c index c3fc038e5..80b90d2f7 100644 --- a/src/android/i_sound.c +++ b/src/android/i_sound.c @@ -92,7 +92,7 @@ boolean I_LoadSong(char *data, size_t len) return -1; } -void I_SetMIDIMusicVolume(INT32 volume) +void I_SetMusicVolume(INT32 volume) { (void)volume; } @@ -120,11 +120,6 @@ void I_UnloadSong(void) UINT8 digmusic_started = 0; -void I_SetDigMusicVolume(INT32 volume) -{ - (void)volume; -} - boolean I_SetSongSpeed(float speed) { (void)speed; diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c index 4c8ceb20c..e66bf8e23 100644 --- a/src/djgppdos/i_sound.c +++ b/src/djgppdos/i_sound.c @@ -140,7 +140,7 @@ void I_SetSfxVolume(INT32 volume) set_volume (Volset(volume),-1); } -void I_SetMIDIMusicVolume(INT32 volume) +void I_SetMusicVolume(INT32 volume) { if (nomidimusic) return; @@ -503,16 +503,6 @@ boolean I_LoadSong(char *data, size_t len) return 1; } -void I_SetDigMusicVolume(INT32 volume) -{ - volume = 0; - if (nodigimusic) - return; - - // Now set volume on output device. -// CONS_Printf("Digital music not yet supported under DOS.\n"); -} - boolean I_SetSongSpeed(float speed) { (void)speed; diff --git a/src/dummy/i_sound.c b/src/dummy/i_sound.c index 60cf51f73..f82bf00da 100644 --- a/src/dummy/i_sound.c +++ b/src/dummy/i_sound.c @@ -70,7 +70,7 @@ void I_InitMusic(void){} void I_ShutdownMusic(void){} -void I_SetMIDIMusicVolume(UINT8 volume) +void I_SetMusicVolume(UINT8 volume) { (void)volume; } @@ -117,11 +117,6 @@ void I_UnloadSong(void) // DIGMUSIC I/O // -void I_SetDigMusicVolume(UINT8 volume) -{ - (void)volume; -} - boolean I_SetSongSpeed(float speed) { (void)speed; diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index b729d4d89..5f92cde10 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1702,7 +1702,7 @@ boolean I_LoadSong(char *data, size_t len) return false; } -void I_SetMIDIMusicVolume(UINT8 volume) +void I_SetMusicVolume(UINT8 volume) { #ifdef HAVE_MIXER if ((nomidimusic && nodigimusic) || !musicStarted) @@ -1951,11 +1951,6 @@ static void I_StopGME(void) #endif } -void I_SetDigMusicVolume(UINT8 volume) -{ - I_SetMIDIMusicVolume(volume); -} - boolean I_SetSongSpeed(float speed) { diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index 295d68680..bfa43d087 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -713,14 +713,6 @@ boolean I_LoadSong(char *data, size_t len) return true; } -void I_SetDigMusicVolume(UINT8 volume) -{ - // volume is 0 to 31. - music_volume = volume; - if (I_GetMusicType() != MU_MID && music_stream) - FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, volume / 31.0)); -} - boolean I_SetSongSpeed(float speed) { FMOD_RESULT e; @@ -803,12 +795,18 @@ boolean I_SetSongTrack(INT32 track) // Fuck MIDI. ... Okay fine, you can have your silly D_-only mode. // -void I_SetMIDIMusicVolume(UINT8 volume) +void I_SetMusicVolume(UINT8 volume) { + if (!music_stream) + return; + // volume is 0 to 31. - midi_volume = volume; - if (I_GetMusicType() != MU_MID && music_stream) - FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, volume / 31.0)); + if (I_GetMusicType() == MU_MID) + music_volume = 31; // windows bug hack + else + music_volume = volume; + + FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); } boolean I_PlaySong(boolean looping) From 011a043dbaaa5706be45f3e900a3d2f031239217 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 12:30:47 -0400 Subject: [PATCH 033/264] Refactoring, music statues * S_Init -> S_InitSfxChannels because it did mostly SFX anyway * S_MusicPlaying, S_MusicPaused, S_MusicName, S_MusicExists new status methods * I_MusicPlaying, I_MusicPaused (cherry picked from commit f5f0b5e76c2fd405c8cc895dde653c5ed2652622) --- src/d_main.c | 4 +- src/i_sound.h | 2 + src/m_menu.c | 6 +- src/s_sound.c | 182 +++++++++++++++++++++--------------------- src/s_sound.h | 17 ++-- src/sdl/mixer_sound.c | 10 +++ 6 files changed, 121 insertions(+), 100 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index df3398752..f2da8586c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1217,7 +1217,7 @@ void D_SRB2Main(void) } else { - CONS_Printf("S_Init(): Setting up sound.\n"); + CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n"); } if (M_CheckParm("-nosound")) nosound = true; @@ -1232,7 +1232,7 @@ void D_SRB2Main(void) } I_StartupSound(); I_InitMusic(); - S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); + S_InitSfxChannels(cv_soundvolume.value); CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); diff --git a/src/i_sound.h b/src/i_sound.h index 1d4d6ff72..901e6c284 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -125,6 +125,8 @@ void I_SetSfxVolume(UINT8 volume); // musictype_t I_GetMusicType(void); +boolean I_MusicPlaying(void); +boolean I_MusicPaused(void); /** \brief Init the music systems */ diff --git a/src/m_menu.c b/src/m_menu.c index 79ac6800b..82242c0c1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6955,7 +6955,7 @@ static void M_ToggleSFX(void) nosound = false; I_StartupSound(); if (nosound) return; - S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); + S_InitSfxChannels(cv_soundvolume.value); M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING); } else @@ -6981,7 +6981,7 @@ static void M_ToggleDigital(void) nodigimusic = false; I_InitDigMusic(); if (nodigimusic) return; - S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); + S_InitSfxChannels(cv_soundvolume.value); S_StopMusic(); S_ChangeMusicInternal("lclear", false); M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); @@ -7009,7 +7009,7 @@ static void M_ToggleMIDI(void) nomidimusic = false; I_InitMIDIMusic(); if (nomidimusic) return; - S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); + S_InitSfxChannels(cv_soundvolume.value); S_ChangeMusicInternal("lclear", false); M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); } diff --git a/src/s_sound.c b/src/s_sound.c index a1c53acd2..e035c4192 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1151,6 +1151,43 @@ void S_StartSoundName(void *mo, const char *soundname) S_StartSound(mo, soundnum); } +// +// Initializes sound stuff, including volume +// Sets channels, SFX volume, +// allocates channel buffer, sets S_sfx lookup. +// +void S_InitSfxChannels(INT32 sfxVolume) +{ + INT32 i; + + if (dedicated) + return; + + S_SetSfxVolume(sfxVolume); + + SetChannelsNum(); + + // Note that sounds have not been cached (yet). + for (i = 1; i < NUMSFX; i++) + { + S_sfx[i].usefulness = -1; // for I_GetSfx() + S_sfx[i].lumpnum = LUMPERROR; + } + + // precache sounds if requested by cmdline, or precachesound var true + if (!nosound && (M_CheckParm("-precachesound") || precachesound.value)) + { + // Initialize external data (all sounds) at start, keep static. + CONS_Printf(M_GetText("Loading sounds... ")); + + for (i = 1; i < NUMSFX; i++) + if (S_sfx[i].name) + S_sfx[i].data = I_GetSfx(&S_sfx[i]); + + CONS_Printf(M_GetText(" pre-cached all sound data\n")); + } +} + /// ------------------------ /// Music /// ------------------------ @@ -1177,10 +1214,7 @@ const char *compat_special_music_slots[16] = }; #endif -#define music_playing (music_name[0]) // String is empty if no music is playing - static char music_name[7]; // up to 6-character name -static boolean mus_paused = 0; // whether songs are mus_paused /// ------------------------ /// Music Status @@ -1206,6 +1240,29 @@ boolean S_MusicDisabled() ); } +boolean S_MusicPlaying(void) +{ + return I_MusicPlaying(); +} + +boolean S_MusicPaused(void) +{ + return I_MusicPaused(); +} + +const char *S_MusicName(void) +{ + return music_name; +} + +boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi) +{ + return ( + (checkDigi ? W_CheckNumForName(va("O_%s", mname)) != LUMPERROR : false) + || (checkMIDI ? W_CheckNumForName(va("D_%s", mname)) != LUMPERROR : false) + ); +} + /// ------------------------ /// Music Properties /// ------------------------ @@ -1229,15 +1286,15 @@ static boolean S_LoadMusic(const char *mname) if (S_DigMusicDisabled()) { - if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR) + if (!S_MIDIExists(mname)) return false; mlumpnum = W_GetNumForName(va("d_%s", mname)); } else { - if (W_CheckNumForName(va("o_%s", mname)) != LUMPERROR) + if (S_DigExists(mname)) mlumpnum = W_GetNumForName(va("o_%s", mname)); - else if (W_CheckNumForName(va("d_%s", mname)) != LUMPERROR) + else if (S_MIDIExists(mname)) mlumpnum = W_GetNumForName(va("d_%s", mname)); else return false; @@ -1326,10 +1383,10 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) void S_StopMusic(void) { - if (!music_playing) + if (!I_MusicPlaying()) return; - if (mus_paused) + if (I_MusicPaused()) I_ResumeSong(); S_SpeedMusic(1.0f); @@ -1343,6 +1400,31 @@ void S_StopMusic(void) music_name[0] = 0; } +// +// Stop and resume music, during game PAUSE. +// +void S_PauseAudio(void) +{ + if (I_MusicPlaying() && !I_MusicPaused()) + I_PauseSong(); + + // pause cd music +#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) + I_PauseCD(); +#else + I_StopCD(); +#endif +} + +void S_ResumeAudio(void) +{ + if (I_MusicPlaying() && I_MusicPaused()) + I_ResumeSong(); + + // resume cd music + I_ResumeCD(); +} + void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) { if (digvolume < 0) @@ -1355,7 +1437,7 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) CV_SetValue(&cv_digmusicvolume, digvolume&31); actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var - if (digvolume < 0 || digvolume > 31) + if (seqvolume < 0 || seqvolume > 31) CONS_Alert(CONS_WARNING, "midimusicvolume should be between 0-31\n"); CV_SetValue(&cv_midimusicvolume, seqvolume&31); actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var @@ -1375,52 +1457,11 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) } } + /// ------------------------ /// Init & Others /// ------------------------ -// -// Initializes sound stuff, including volume -// Sets channels, SFX and music volume, -// allocates channel buffer, sets S_sfx lookup. -// -void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume) -{ - INT32 i; - - if (dedicated) - return; - - S_SetSfxVolume(sfxVolume); - S_SetMusicVolume(digMusicVolume, midiMusicVolume); - - SetChannelsNum(); - - // no sounds are playing, and they are not mus_paused - mus_paused = 0; - - // Note that sounds have not been cached (yet). - for (i = 1; i < NUMSFX; i++) - { - S_sfx[i].usefulness = -1; // for I_GetSfx() - S_sfx[i].lumpnum = LUMPERROR; - } - - // precache sounds if requested by cmdline, or precachesound var true - if (!nosound && (M_CheckParm("-precachesound") || precachesound.value)) - { - // Initialize external data (all sounds) at start, keep static. - CONS_Printf(M_GetText("Loading sounds... ")); - - for (i = 1; i < NUMSFX; i++) - if (S_sfx[i].name) - S_sfx[i].data = I_GetSfx(&S_sfx[i]); - - CONS_Printf(M_GetText(" pre-cached all sound data\n")); - } -} - - // // Per level startup code. // Kills playing sounds at start of level, @@ -1435,46 +1476,7 @@ void S_Start(void) mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK); } - mus_paused = 0; - if (cv_resetmusic.value) S_StopMusic(); S_ChangeMusic(mapmusname, mapmusflags, true); } - -// -// Stop and resume music, during game PAUSE. -// -void S_PauseAudio(void) -{ - if (!nodigimusic) - I_PauseSong(); - - if (music_playing && !mus_paused) - { - I_PauseSong(); - mus_paused = true; - } - - // pause cd music -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) - I_PauseCD(); -#else - I_StopCD(); -#endif -} - -void S_ResumeAudio(void) -{ - if (!nodigimusic) - I_ResumeSong(); - else - if (music_playing && mus_paused) - { - I_ResumeSong(); - mus_paused = false; - } - - // resume cd music - I_ResumeCD(); -} diff --git a/src/s_sound.h b/src/s_sound.h index bce3ab8bb..9a3f2805c 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -69,9 +69,9 @@ void S_RegisterSoundStuff(void); // // Initializes sound stuff, including volume -// Sets channels, SFX and music volume, allocates channel buffer, sets S_sfx lookup. +// Sets channels, SFX, allocates channel buffer, sets S_sfx lookup. // -void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume); +void S_InitSfxChannels(INT32 sfxVolume); // // Per level startup code. @@ -101,9 +101,16 @@ void S_StopSound(void *origin); // Music Status // -boolean S_DigMusicDisabled(); -boolean S_MIDIMusicDisabled(); -boolean S_MusicDisabled(); +boolean S_DigMusicDisabled(void); +boolean S_MIDIMusicDisabled(void); +boolean S_MusicDisabled(void); +boolean S_MusicPlaying(void); +boolean S_MusicPaused(void); +const char *S_MusicName(void); +boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi); +#define S_DigExists(a) S_MusicExists(a, false, true) +#define S_MIDIExists(a) S_MusicExists(a, true, false) + // // Music Properties diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 457f74f95..1384f1da0 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -453,6 +453,16 @@ musictype_t I_GetMusicType(void) return (musictype_t)Mix_GetMusicType(music); } +boolean I_MusicPlaying(void) +{ + return (boolean)music; +} + +boolean I_MusicPaused(void) +{ + return songpaused; +} + // Music hooks static void music_loop(void) { From 44557d9c9d6b6ea3df722987bf778f847193db90 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 12:31:01 -0400 Subject: [PATCH 034/264] I_MusicPlaying, I_MusicPaused other targets (cherry picked from commit d5ec38815968e267aceb59a48a6cb6d3292c0b69) --- src/android/i_sound.c | 10 ++++++++++ src/djgppdos/i_sound.c | 17 +++++++++++++++-- src/dummy/i_sound.c | 10 ++++++++++ src/sdl/sdl_sound.c | 10 ++++++++++ src/win32/win_snd.c | 13 +++++++++++++ 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/android/i_sound.c b/src/android/i_sound.c index 80b90d2f7..1cbc53fab 100644 --- a/src/android/i_sound.c +++ b/src/android/i_sound.c @@ -65,6 +65,16 @@ musictype_t I_GetMusicType(void) return MU_NONE; } +boolean I_MusicPlaying(void) +{ + return false; +} + +boolean I_MusicPaused(void) +{ + return false; +} + void I_InitMusic(void){} void I_ShutdownMusic(void){} diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c index e66bf8e23..6e351b523 100644 --- a/src/djgppdos/i_sound.c +++ b/src/djgppdos/i_sound.c @@ -321,6 +321,7 @@ static MIDI* currsong; //im assuming only 1 song will be played at once static int islooping=0; static int musicdies=-1; UINT8 music_started=0; +boolean songpaused=false; musictype_t I_GetMusicType(void) { @@ -330,6 +331,16 @@ musictype_t I_GetMusicType(void) return MU_NONE; } +boolean I_MusicPlaying() +{ + return (boolean)currsong; +} + +boolean I_MusicPaused() +{ + return songpaused; +} + /* load_midi_mem: * Loads a standard MIDI file from memory, returning a pointer to * a MIDI structure, * or NULL on error. @@ -403,6 +414,7 @@ void I_InitMusic(void) I_AddExitFunc(I_ShutdownMusic); music_started = true; + songpaused = false; } void I_ShutdownMusic(void) @@ -433,8 +445,8 @@ void I_PauseSong (INT32 handle) handle = 0; if (nomidimusic) return; - midi_pause(); + songpaused = true; } void I_ResumeSong (INT32 handle) @@ -442,8 +454,8 @@ void I_ResumeSong (INT32 handle) handle = 0; if (nomidimusic) return; - midi_resume(); + songpaused = false; } void I_StopSong(void) @@ -455,6 +467,7 @@ void I_StopSong(void) islooping = 0; musicdies = 0; stop_midi(); + songpaused = false; } // Is the song playing? diff --git a/src/dummy/i_sound.c b/src/dummy/i_sound.c index f82bf00da..ca90a7da3 100644 --- a/src/dummy/i_sound.c +++ b/src/dummy/i_sound.c @@ -66,6 +66,16 @@ musictype_t I_GetMusicType(void) return MU_NONE; } +boolean I_MusicPlaying(void) +{ + return false; +} + +boolean I_MusicPaused(void) +{ + return false; +} + void I_InitMusic(void){} void I_ShutdownMusic(void){} diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 5f92cde10..d8d3e0a95 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1336,6 +1336,16 @@ musictype_t I_GetMusicType(void) #endif } +boolean I_MusicPlaying(void) +{ + return music_started; +} + +boolean I_MusicPaused(void) +{ + return Mix_PausedMusic(); +} + #ifdef HAVE_LIBGME static void I_ShutdownGMEMusic(void) { diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index bfa43d087..c6a74d999 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -478,6 +478,19 @@ musictype_t I_GetMusicType(void) return MU_NONE; } +boolean I_MusicPlaying(void) +{ + return (boolean)music_stream; +} + +boolean I_MusicPaused(void) +{ + boolean fmpaused = false; + if (music_stream) + FMOD_Channel_GetPaused(music_channel, &fmpaused); + return fmpaused; +} + void I_InitMusic(void) { } From a414ccf24ae6b59b1945cb0b9177bfaebbfb334e Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 12:42:15 -0400 Subject: [PATCH 035/264] nodigimusic nomusic nosound -> digital_disabled midi_disabled sound_disabled (cherry picked from commit 07738fb0bcf640a4349337373f451fe68e024b2a) --- src/d_main.c | 26 ++++++++++----------- src/doomstat.h | 5 +--- src/m_menu.c | 62 ++++++++++++++++++++------------------------------ src/p_mobj.c | 2 +- src/s_sound.c | 27 +++++++++------------- 5 files changed, 51 insertions(+), 71 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index f2da8586c..ed1b44684 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -122,17 +122,17 @@ postimg_t postimgtype2 = postimg_none; INT32 postimgparam2; #ifdef _XBOX -boolean nomidimusic = true, nosound = true; -boolean nodigimusic = true; +boolean midi_disabled = true, sound_disabled = true; +boolean digital_disabled = true; #else -boolean nomidimusic = false, nosound = false; -boolean nodigimusic = false; // No fmod-based music +boolean midi_disabled = false, sound_disabled = false; +boolean digital_disabled = false; // No fmod-based music #endif // These variables are only true if -// the respective sound system is initialized -// and active, but no sounds/music should play. -boolean music_disabled = false; +// whether the respective sound system is disabled +// or they're init'ed, but the player just toggled them +boolean midi_disabled = false; boolean sound_disabled = false; boolean digital_disabled = false; @@ -1212,23 +1212,23 @@ void D_SRB2Main(void) // setting up sound if (dedicated) { - nosound = true; - nomidimusic = nodigimusic = true; + sound_disabled = true; + midi_disabled = digital_disabled = true; } else { CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n"); } if (M_CheckParm("-nosound")) - nosound = true; + sound_disabled = true; if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic - nomidimusic = nodigimusic = true; + midi_disabled = digital_disabled = true; else { if (M_CheckParm("-nomidimusic")) - nomidimusic = true; ; // WARNING: DOS version initmusic in I_StartupSound + midi_disabled = true; ; // WARNING: DOS version initmusic in I_StartupSound if (M_CheckParm("-nodigmusic")) - nodigimusic = true; // WARNING: DOS version initmusic in I_StartupSound + digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound } I_StartupSound(); I_InitMusic(); diff --git a/src/doomstat.h b/src/doomstat.h index 8072a1552..27bd3fa19 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -85,10 +85,7 @@ extern boolean fromlevelselect; // Internal parameters for sound rendering. // ======================================== -extern boolean nomidimusic; // defined in d_main.c -extern boolean nosound; -extern boolean nodigimusic; -extern boolean music_disabled; +extern boolean midi_disabled; extern boolean sound_disabled; extern boolean digital_disabled; diff --git a/src/m_menu.c b/src/m_menu.c index 82242c0c1..7a5e78a7b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6950,11 +6950,11 @@ static void M_ChangeControl(INT32 choice) // Toggles sound systems in-game. static void M_ToggleSFX(void) { - if (nosound) + if (sound_disabled) { - nosound = false; + sound_disabled = false; I_StartupSound(); - if (nosound) return; + if (sound_disabled) return; S_InitSfxChannels(cv_soundvolume.value); M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING); } @@ -6976,56 +6976,44 @@ static void M_ToggleSFX(void) static void M_ToggleDigital(void) { - if (nodigimusic) + if (digital_disabled) { - nodigimusic = false; - I_InitDigMusic(); - if (nodigimusic) return; - S_InitSfxChannels(cv_soundvolume.value); + digital_disabled = false; + I_InitMusic(); + if (digital_disabled) return; S_StopMusic(); - S_ChangeMusicInternal("lclear", false); + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("lclear", false); M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); } else { - if (digital_disabled) - { - digital_disabled = false; - M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); - } - else - { - digital_disabled = true; - S_StopMusic(); - M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING); - } + digital_disabled = true; + S_StopMusic(); + M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING); } } static void M_ToggleMIDI(void) { - if (nomidimusic) + if (midi_disabled) { - nomidimusic = false; - I_InitMIDIMusic(); - if (nomidimusic) return; - S_InitSfxChannels(cv_soundvolume.value); - S_ChangeMusicInternal("lclear", false); + midi_disabled = false; + I_InitMusic(); + if (midi_disabled) return; + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("lclear", false); M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); } else { - if (music_disabled) - { - music_disabled = false; - M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); - } - else - { - music_disabled = true; - S_StopMusic(); - M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING); - } + midi_disabled = true; + S_StopMusic(); + M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING); } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 5f85474c6..a55e5de26 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8228,7 +8228,7 @@ void P_PrecipitationEffects(void) if (!playeringame[displayplayer] || !players[displayplayer].mo) return; - if (nosound || sound_disabled) + if (sound_disabled) return; // Sound off? D'aw, no fun. if (players[displayplayer].mo->subsector->sector->ceilingpic == skyflatnum) diff --git a/src/s_sound.c b/src/s_sound.c index e035c4192..d1993bc87 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -226,7 +226,7 @@ void S_RegisterSoundStuff(void) { if (dedicated) { - nosound = true; + sound_disabled = true; return; } @@ -400,7 +400,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) mobj_t *listenmobj = players[displayplayer].mo; mobj_t *listenmobj2 = NULL; - if (sound_disabled || !sound_started || nosound) + if (sound_disabled || !sound_started) return; // Don't want a sound? Okay then... @@ -716,7 +716,7 @@ void S_UpdateSounds(void) return; } - if (dedicated || nosound) + if (dedicated || sound_disabled) return; if (players[displayplayer].awayviewtics) @@ -1175,7 +1175,7 @@ void S_InitSfxChannels(INT32 sfxVolume) } // precache sounds if requested by cmdline, or precachesound var true - if (!nosound && (M_CheckParm("-precachesound") || precachesound.value)) + if (!sound_disabled && (M_CheckParm("-precachesound") || precachesound.value)) { // Initialize external data (all sounds) at start, keep static. CONS_Printf(M_GetText("Loading sounds... ")); @@ -1220,24 +1220,19 @@ static char music_name[7]; // up to 6-character name /// Music Status /// ------------------------ -boolean S_DigMusicDisabled() +boolean S_DigMusicDisabled(void) { - return (nodigimusic || digital_disabled); + return digital_disabled; } -boolean S_MIDIMusicDisabled() +boolean S_MIDIMusicDisabled(void) { - return (nomidimusic || music_disabled); + return midi_disabled; } -boolean S_MusicDisabled() +boolean S_MusicDisabled(void) { - return ( - (nodigimusic && nomidimusic) || - (music_disabled && digital_disabled) || - (nodigimusic && music_disabled) || - (nomidimusic && digital_disabled) - ); + return (midi_disabled && digital_disabled); } boolean S_MusicPlaying(void) @@ -1333,7 +1328,7 @@ static void S_UnloadMusic(void) static boolean S_PlayMusic(boolean looping) { - if (nodigimusic || digital_disabled) + if (S_DigMusicDisabled()) return false; // try midi if (!I_PlaySong(looping)) From 17cf310b84ebeaa096b2172f55bb9a2fb5494e08 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 12:43:38 -0400 Subject: [PATCH 036/264] nodigimusic nomusic nosound refactor other targets (cherry picked from commit 86f151db654beb14e8d6893cdff2adaa965e8e4b) --- src/djgppdos/i_sound.c | 38 +++++++++++++++++----------------- src/hardware/hw3sound.c | 2 +- src/sdl/sdl_sound.c | 46 ++++++++++++++++++++--------------------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c index 6e351b523..d998016a2 100644 --- a/src/djgppdos/i_sound.c +++ b/src/djgppdos/i_sound.c @@ -134,7 +134,7 @@ FUNCINLINE static ATTRINLINE int Volset(int vol) void I_SetSfxVolume(INT32 volume) { - if (nosound) + if (sound_disabled) return; set_volume (Volset(volume),-1); @@ -142,7 +142,7 @@ void I_SetSfxVolume(INT32 volume) void I_SetMusicVolume(INT32 volume) { - if (nomidimusic) + if (midi_disabled) return; // Now set volume on output device. @@ -169,7 +169,7 @@ INT32 I_StartSound ( sfxenum_t id, { int voice; - if (nosound) + if (sound_disabled) return 0; // UNUSED @@ -190,7 +190,7 @@ void I_StopSound (INT32 handle) // an setting the channel to zero. int voice=handle & (VIRTUAL_VOICES-1); - if (nosound) + if (sound_disabled) return; if (voice_check(voice)==S_sfx[handle>>VOICESSHIFT].data) @@ -199,7 +199,7 @@ void I_StopSound (INT32 handle) INT32 I_SoundIsPlaying(INT32 handle) { - if (nosound) + if (sound_disabled) return FALSE; if (voice_check(handle & (VIRTUAL_VOICES-1))==S_sfx[handle>>VOICESSHIFT].data) @@ -229,7 +229,7 @@ void I_UpdateSoundParams( INT32 handle, int voice=handle & (VIRTUAL_VOICES-1); int numsfx=handle>>VOICESSHIFT; - if (nosound) + if (sound_disabled) return; if (voice_check(voice)==S_sfx[numsfx].data) @@ -270,17 +270,17 @@ void I_StartupSound(void) char err[255]; #endif - if (nosound) + if (sound_disabled) sfxcard=DIGI_NONE; else sfxcard=DIGI_AUTODETECT; - if (nomidimusic) + if (midi_disabled) midicard=MIDI_NONE; else midicard=MIDI_AUTODETECT; //DetectMusicCard(); - nodigimusic=true; //Alam: No OGG/MP3/IT/MOD support + digital_disabled=true; //Alam: No OGG/MP3/IT/MOD support // Secure and configure sound device first. CONS_Printf("I_StartupSound: "); @@ -293,8 +293,8 @@ void I_StartupSound(void) { sprintf (err,"Sound init error : %s\n",allegro_error); CONS_Error (err); - nosound=true; - nomidimusic=true; + sound_disabled=true; + midi_disabled=true; } else { @@ -409,7 +409,7 @@ static MIDI *load_midi_mem(char *mempointer,int *e) void I_InitMusic(void) { - if (nomidimusic) + if (midi_disabled) return; I_AddExitFunc(I_ShutdownMusic); @@ -430,7 +430,7 @@ void I_ShutdownMusic(void) boolean I_PlaySong(boolean looping) { handle = 0; - if (nomidimusic) + if (midi_disabled) return false; islooping = looping; @@ -443,7 +443,7 @@ boolean I_PlaySong(boolean looping) void I_PauseSong (INT32 handle) { handle = 0; - if (nomidimusic) + if (midi_disabled) return; midi_pause(); songpaused = true; @@ -452,7 +452,7 @@ void I_PauseSong (INT32 handle) void I_ResumeSong (INT32 handle) { handle = 0; - if (nomidimusic) + if (midi_disabled) return; midi_resume(); songpaused = false; @@ -461,7 +461,7 @@ void I_ResumeSong (INT32 handle) void I_StopSong(void) { handle = 0; - if (nomidimusic) + if (midi_disabled) return; islooping = 0; @@ -474,7 +474,7 @@ void I_StopSong(void) #if 0 int I_QrySongPlaying(int handle) { - if (nomidimusic) + if (midi_disabled) return 0; //return islooping || musicdies > gametic; @@ -485,7 +485,7 @@ int I_QrySongPlaying(int handle) void I_UnloadSong(void) { handle = 0; - if (nomidimusic) + if (midi_disabled) return; //destroy_midi(currsong); @@ -494,7 +494,7 @@ void I_UnloadSong(void) boolean I_LoadSong(char *data, size_t len) { int e = len; //Alam: For error - if (nomidimusic) + if (midi_disabled) return 0; if (memcmp(data,"MThd",4)==0) // support mid file in WAD !!! diff --git a/src/hardware/hw3sound.c b/src/hardware/hw3sound.c index c68430921..f7c6e1da0 100644 --- a/src/hardware/hw3sound.c +++ b/src/hardware/hw3sound.c @@ -361,7 +361,7 @@ INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, chan if (splitscreen) listenmobj2 = players[secondarydisplayplayer].mo; - if (nosound) + if (sound_disabled) return -1; sfx = &S_sfx[sfx_id]; diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index d8d3e0a95..cf54d7d05 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -194,8 +194,8 @@ static srb2audio_t localdata; static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio callback { if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); - else if (nosound) return; - else if (nomidimusic && nodigimusic + else if (sound_disabled) return; + else if (midi_disabled && digital_disabled #ifdef HW3SOUND && hws_mode == HWS_DEFAULT_MODE #endif @@ -208,8 +208,8 @@ static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio call static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio callback { if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); - else if (nosound) return; - else if (nomidimusic && nodigimusic + else if (sound_disabled) return; + else if (midi_disabled && digital_disabled #ifdef HW3SOUND && hws_mode == HWS_DEFAULT_MODE #endif @@ -493,7 +493,7 @@ static inline void I_SetChannels(void) INT32 *steptablemid = steptable + 128; - if (nosound) + if (sound_disabled) return; // This table provides step widths for pitch parameters. @@ -609,7 +609,7 @@ INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priori (void)priority; (void)pitch; - if (nosound) + if (sound_disabled) return 0; if (S_sfx[id].data == NULL) return -1; @@ -1136,7 +1136,7 @@ static INT32 Init3DSDriver(const char *soName) void I_ShutdownSound(void) { - if (nosound || !sound_started) + if (sound_disabled || !sound_started) return; CONS_Printf("I_ShutdownSound: "); @@ -1150,7 +1150,7 @@ void I_ShutdownSound(void) } #endif - if (nomidimusic && nodigimusic) + if (midi_disabled && digital_disabled) SDL_CloseAudio(); CONS_Printf("%s", M_GetText("shut down\n")); sound_started = false; @@ -1170,7 +1170,7 @@ void I_StartupSound(void) const char *sdrv_name = NULL; #endif #ifndef HAVE_MIXER - nomidimusic = nodigimusic = true; + midi_disabled = digital_disabled = true; #endif memset(channels, 0, sizeof (channels)); //Alam: Clean it @@ -1213,7 +1213,7 @@ void I_StartupSound(void) audio.samples /= 2; } - if (nosound) + if (sound_disabled) return; #ifdef HW3SOUND @@ -1261,7 +1261,7 @@ void I_StartupSound(void) { snddev_t snddev; - //nosound = true; + //sound_disabled = true; //I_AddExitFunc(I_ShutdownSound); snddev.bps = 16; snddev.sample_rate = audio.freq; @@ -1288,7 +1288,7 @@ void I_StartupSound(void) if (!musicStarted && SDL_OpenAudio(&audio, &audio) < 0) { CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n")); - nosound = true; + sound_disabled = true; return; } else @@ -1452,7 +1452,7 @@ static boolean LoadSong(void *data, size_t lumplength, size_t selectpos) void I_ShutdownMusic(void) { #ifdef HAVE_MIXER - if ((nomidimusic && nodigimusic) || !musicStarted) + if ((midi_disabled && digital_disabled) || !musicStarted) return; CONS_Printf("%s", M_GetText("I_ShutdownMusic: ")); @@ -1543,7 +1543,7 @@ void I_InitMusic(void) if (Mix_OpenAudio(audio.freq, audio.format, audio.channels, audio.samples) < 0) //open_music(&audio) { CONS_Printf(M_GetText(" Unable to open music: %s\n"), Mix_GetError()); - nomidimusic = nodigimusic = true; + midi_disabled = digital_disabled = true; if (sound_started #ifdef HW3SOUND && hws_mode == HWS_DEFAULT_MODE @@ -1553,7 +1553,7 @@ void I_InitMusic(void) if (SDL_OpenAudio(&audio, NULL) < 0) //retry { CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n")); - nosound = true; + sound_disabled = true; sound_started = false; } else @@ -1588,7 +1588,7 @@ boolean I_PlaySong(INT32 handle, boolean looping) { (void)handle; #ifdef HAVE_MIXER - if (nomidimusic || !musicStarted || !music[handle]) + if (midi_disabled || !musicStarted || !music[handle]) return false; #ifdef MIXER_POS @@ -1621,7 +1621,7 @@ void I_PauseSong(void) (void)handle; I_PauseGME(); #ifdef HAVE_MIXER - if ((nomidimusic && nodigimusic) || !musicStarted) + if ((midi_disabled && digital_disabled) || !musicStarted) return; Mix_PauseMusic(); @@ -1641,7 +1641,7 @@ void I_ResumeSong(void) (void)handle; I_ResumeGME(); #ifdef HAVE_MIXER - if ((nomidimusic && nodigimusic) || !musicStarted) + if ((midi_disabled && digital_disabled) || !musicStarted) return; Mix_VolumeMusic(musicvol); @@ -1654,7 +1654,7 @@ void I_StopSong(void) { I_StopGME(); #ifdef HAVE_MIXER - if (nodigimusic) + if (digital_disabled) return; #ifdef MIXER_POS @@ -1676,7 +1676,7 @@ void I_UnloadSong(void) { #ifdef HAVE_MIXER - if (nomidimusic || !musicStarted) + if (midi_disabled || !musicStarted) return; Mix_HaltMusic(); @@ -1695,7 +1695,7 @@ void I_UnloadSong(void) boolean I_LoadSong(char *data, size_t len) { #ifdef HAVE_MIXER - if (nomidimusic || !musicStarted) + if (midi_disabled || !musicStarted) return false; if (!LoadSong(data, len, 0)) @@ -1715,7 +1715,7 @@ boolean I_LoadSong(char *data, size_t len) void I_SetMusicVolume(UINT8 volume) { #ifdef HAVE_MIXER - if ((nomidimusic && nodigimusic) || !musicStarted) + if ((midi_disabled && digital_disabled) || !musicStarted) return; if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); @@ -1802,7 +1802,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) return true; #ifdef HAVE_MIXER - if (nodigimusic) + if (digital_disabled) return false; snprintf(filename, sizeof filename, "o_%s", musicname); From 7e7899ae831e2203e0cf28b09b8178e66037c554 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 12:51:45 -0400 Subject: [PATCH 037/264] Toggle Digi/MIDI music in menu accurately; add S_MusicType (cherry picked from commit 4aa100aa575cc7fc14a743085222c806ba2c714a) --- src/m_menu.c | 6 ++++-- src/s_sound.c | 36 +++++++++++++++++++++--------------- src/s_sound.h | 2 ++ 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7a5e78a7b..2c82bf84f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6991,7 +6991,8 @@ static void M_ToggleDigital(void) else { digital_disabled = true; - S_StopMusic(); + if (S_MusicType() != MU_MID) + S_StopMusic(); M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING); } } @@ -7012,7 +7013,8 @@ static void M_ToggleMIDI(void) else { midi_disabled = true; - S_StopMusic(); + if (S_MusicType() == MU_MID) + S_StopMusic(); M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING); } } diff --git a/src/s_sound.c b/src/s_sound.c index d1993bc87..54ffffc4c 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1245,6 +1245,11 @@ boolean S_MusicPaused(void) return I_MusicPaused(); } +musictype_t S_MusicType(void) +{ + return I_GetMusicType(); +} + const char *S_MusicName(void) { return music_name; @@ -1279,20 +1284,24 @@ static boolean S_LoadMusic(const char *mname) if (S_MusicDisabled()) return false; - if (S_DigMusicDisabled()) - { - if (!S_MIDIExists(mname)) - return false; + if (!S_DigMusicDisabled() && S_DigExists(mname)) + mlumpnum = W_GetNumForName(va("o_%s", mname)); + else if (!S_MIDIMusicDisabled() && S_MIDIExists(mname)) mlumpnum = W_GetNumForName(va("d_%s", mname)); + else if (S_DigMusicDisabled() && S_DigExists(mname)) + { + CONS_Alert(CONS_NOTICE, "Digital music is disabled!\n"); + return false; + } + else if (S_MIDIMusicDisabled() && S_MIDIExists(mname)) + { + CONS_Alert(CONS_NOTICE, "MIDI music is disabled!\n"); + return false; } else { - if (S_DigExists(mname)) - mlumpnum = W_GetNumForName(va("o_%s", mname)); - else if (S_MIDIExists(mname)) - mlumpnum = W_GetNumForName(va("d_%s", mname)); - else - return false; + CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mname); + return false; } // load & register it @@ -1328,8 +1337,8 @@ static void S_UnloadMusic(void) static boolean S_PlayMusic(boolean looping) { - if (S_DigMusicDisabled()) - return false; // try midi + if (S_MusicDisabled()) + return false; if (!I_PlaySong(looping)) { @@ -1362,10 +1371,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) S_StopMusic(); // shutdown old music if (!S_LoadMusic(mmusic)) - { - CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic); return; - } if (!S_PlayMusic(looping)) { diff --git a/src/s_sound.h b/src/s_sound.h index 9a3f2805c..a0ac6c158 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -14,6 +14,7 @@ #ifndef __S_SOUND__ #define __S_SOUND__ +#include "i_sound.h" // musictype_t #include "sounds.h" #include "m_fixed.h" #include "command.h" @@ -106,6 +107,7 @@ boolean S_MIDIMusicDisabled(void); boolean S_MusicDisabled(void); boolean S_MusicPlaying(void); boolean S_MusicPaused(void); +musictype_t S_MusicType(void); const char *S_MusicName(void); boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi); #define S_DigExists(a) S_MusicExists(a, false, true) From 8c78d86c3641675e6c5803afab052cf91055af03 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 16:46:40 -0400 Subject: [PATCH 038/264] Play the opposite type music (Digital/MIDI) when toggling between them in menu * S_MusicInfo method to retrieve name, flags, and looping (cherry picked from commit f6ec93198f0dcfa1d053cca88172c3e3c7ba310c) --- src/m_menu.c | 38 ++++++++++++++++++++++++++++++++++++-- src/s_sound.c | 19 +++++++++++++++++-- src/s_sound.h | 2 +- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 2c82bf84f..6a6875aad 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6992,7 +6992,24 @@ static void M_ToggleDigital(void) { digital_disabled = true; if (S_MusicType() != MU_MID) - S_StopMusic(); + { + if (midi_disabled) + S_StopMusic(); + else + { + char mmusic[7]; + UINT16 mflags; + boolean looping; + + if (S_MusicInfo(mmusic, &mflags, &looping) && S_MIDIExists(mmusic)) + { + S_StopMusic(); + S_ChangeMusic(mmusic, mflags, looping); + } + else + S_StopMusic(); + } + } M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING); } } @@ -7014,7 +7031,24 @@ static void M_ToggleMIDI(void) { midi_disabled = true; if (S_MusicType() == MU_MID) - S_StopMusic(); + { + if (digital_disabled) + S_StopMusic(); + else + { + char mmusic[7]; + UINT16 mflags; + boolean looping; + + if (S_MusicInfo(mmusic, &mflags, &looping) && S_DigExists(mmusic)) + { + S_StopMusic(); + S_ChangeMusic(mmusic, mflags, looping); + } + else + S_StopMusic(); + } + } M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING); } } diff --git a/src/s_sound.c b/src/s_sound.c index 54ffffc4c..32d9c7b06 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1215,6 +1215,8 @@ const char *compat_special_music_slots[16] = #endif static char music_name[7]; // up to 6-character name +static UINT16 music_flags; +static boolean music_looping; /// ------------------------ /// Music Status @@ -1250,9 +1252,17 @@ musictype_t S_MusicType(void) return I_GetMusicType(); } -const char *S_MusicName(void) +boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping) { - return music_name; + if (!I_MusicPlaying()) + return false; + + strncpy(mname, music_name, 7); + mname[6] = 0; + *mflags = music_flags; + *looping = music_looping; + + return (boolean)mname[0]; } boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi) @@ -1333,6 +1343,8 @@ static void S_UnloadMusic(void) { I_UnloadSong(); music_name[0] = 0; + music_flags = 0; + music_looping = false; } static boolean S_PlayMusic(boolean looping) @@ -1373,6 +1385,9 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) if (!S_LoadMusic(mmusic)) return; + music_flags = mflags; + music_looping = looping; + if (!S_PlayMusic(looping)) { CONS_Alert(CONS_ERROR, "Music cannot be played!\n"); diff --git a/src/s_sound.h b/src/s_sound.h index a0ac6c158..a2d51a59b 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -108,7 +108,7 @@ boolean S_MusicDisabled(void); boolean S_MusicPlaying(void); boolean S_MusicPaused(void); musictype_t S_MusicType(void); -const char *S_MusicName(void); +boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping); boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi); #define S_DigExists(a) S_MusicExists(a, false, true) #define S_MIDIExists(a) S_MusicExists(a, true, false) From 5bac836d4c805e37c1bf7d9d75cfa23c0933538f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 17:05:37 -0400 Subject: [PATCH 039/264] Minor refactoring and reordering * I_GetMusicType() -> I_MusicType() * Wrap MIDI volume hack in #ifdef _WIN32 (cherry picked from commit a7d51bf81030c228937a8e759f8f43b85817fce6) --- src/i_sound.h | 89 ++++++++-------- src/s_sound.c | 8 +- src/sdl/mixer_sound.c | 238 +++++++++++++++++++++++------------------- 3 files changed, 174 insertions(+), 161 deletions(-) diff --git a/src/i_sound.h b/src/i_sound.h index 901e6c284..15126d695 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -66,9 +66,9 @@ void I_StartupSound(void); */ void I_ShutdownSound(void); -// -// SFX I/O -// +/// ------------------------ +/// SFX I/O +/// ------------------------ /** \brief Starts a sound in a particular sound channel. \param id sfxid @@ -120,13 +120,9 @@ void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch); */ void I_SetSfxVolume(UINT8 volume); -// -// MUSIC I/O -// - -musictype_t I_GetMusicType(void); -boolean I_MusicPlaying(void); -boolean I_MusicPaused(void); +/// ------------------------ +// MUSIC SYSTEM +/// ------------------------ /** \brief Init the music systems */ @@ -136,33 +132,23 @@ void I_InitMusic(void); */ void I_ShutdownMusic(void); -/** \brief PAUSE game handling. +/// ------------------------ +// MUSIC PROPERTIES +/// ------------------------ - \param handle song handle +musictype_t I_MusicType(void); +boolean I_MusicPlaying(void); +boolean I_MusicPaused(void); - \return void -*/ -void I_PauseSong(void); +/// ------------------------ +// MUSIC EFFECTS +/// ------------------------ -/** \brief RESUME game handling +boolean I_SetSongSpeed(float speed); - \param handle song handle - - \return void -*/ -void I_ResumeSong(void); - -// -// MIDI I/O -// - -/** \brief The I_SetMIDIMusicVolume function - - \param volume volume to set at - - \return void -*/ -void I_SetMIDIMusicVolume(UINT8 volume); +/// ------------------------ +// MUSIC PLAYBACK +/// ------------------------ /** \brief Registers a song handle to song data. @@ -175,6 +161,15 @@ void I_SetMIDIMusicVolume(UINT8 volume); */ boolean I_LoadSong(char *data, size_t len); +/** \brief See ::I_LoadSong, then think backwards + + \param handle song handle + + \sa I_LoadSong + \todo remove midi handle +*/ +void I_UnloadSong(void); + /** \brief Called by anything that wishes to start music \param handle Song handle @@ -195,35 +190,35 @@ boolean I_PlaySong(boolean looping); */ void I_StopSong(void); -/** \brief See ::I_LoadSong, then think backwards +/** \brief PAUSE game handling. \param handle song handle - \sa I_LoadSong - \todo remove midi handle + \return void */ -void I_UnloadSong(void); +void I_PauseSong(void); -// -// DIGMUSIC I/O -// +/** \brief RESUME game handling -boolean I_SetSongSpeed(float speed); + \param handle song handle -boolean I_SetSongTrack(INT32 track); + \return void +*/ +void I_ResumeSong(void); -/** \brief The I_SetDigMusicVolume function +/** \brief The I_SetMusicVolume function \param volume volume to set at \return void */ -void I_SetDigMusicVolume(UINT8 volume); +void I_SetMusicVolume(UINT8 volume); -// -// CD MUSIC I/O -// +boolean I_SetSongTrack(INT32 track); +/// ------------------------ +// CD MUSIC I/O +/// ------------------------ /** \brief cd music interface */ diff --git a/src/s_sound.c b/src/s_sound.c index 32d9c7b06..bd6022dfb 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1249,7 +1249,7 @@ boolean S_MusicPaused(void) musictype_t S_MusicType(void) { - return I_GetMusicType(); + return I_MusicType(); } boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping) @@ -1274,7 +1274,7 @@ boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi) } /// ------------------------ -/// Music Properties +/// Music Effects /// ------------------------ boolean S_SpeedMusic(float speed) @@ -1283,7 +1283,7 @@ boolean S_SpeedMusic(float speed) } /// ------------------------ -/// Music Routines +/// Music Playback /// ------------------------ static boolean S_LoadMusic(const char *mname) @@ -1462,7 +1462,7 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) digvolume = seqvolume = 31; #endif - switch(I_GetMusicType()) + switch(I_MusicType()) { case MU_MID: case MU_MOD: diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 1384f1da0..9c46625fc 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -72,6 +72,10 @@ static Music_Emu *gme; static INT32 current_track; #endif +/// ------------------------ +/// Audio System +/// ------------------------ + void I_StartupSound(void) { I_Assert(!sound_started); @@ -128,6 +132,10 @@ FUNCMATH void I_UpdateSound(void) { } +/// ------------------------ +/// SFX +/// ------------------------ + // this is as fast as I can possibly make it. // sorry. more asm needed. static Mix_Chunk *ds2chunk(void *stream) @@ -430,11 +438,72 @@ void I_SetSfxVolume(UINT8 volume) sfx_volume = volume; } -// -// Music -// +/// ------------------------ +/// Music Hooks +/// ------------------------ -musictype_t I_GetMusicType(void) +static void music_loop(void) +{ + Mix_PlayMusic(music, 0); + Mix_SetMusicPosition(loop_point); +} + +#ifdef HAVE_LIBGME +static void mix_gme(void *udata, Uint8 *stream, int len) +{ + int i; + short *p; + + (void)udata; + + // no gme? no music. + if (!gme || gme_track_ended(gme) || songpaused) + return; + + // play gme into stream + gme_play(gme, len/2, (short *)stream); + + // apply volume to stream + for (i = 0, p = (short *)stream; i < len/2; i++, p++) + *p = ((INT32)*p) * music_volume*2 / 42; +} +#endif + + +/// ------------------------ +/// Music System +/// ------------------------ + +FUNCMATH void I_InitMusic(void) +{ +#ifdef HAVE_LIBGME + gme = NULL; + current_track = -1; +#endif +} + +void I_ShutdownMusic(void) +{ +#ifdef HAVE_LIBGME + if (gme) + { + Mix_HookMusic(NULL, NULL); + gme_delete(gme); + gme = NULL; + } +#endif + if (!music) + return; + Mix_HookMusicFinished(NULL); + Mix_FreeMusic(music); + music = NULL; +} + +/// ------------------------ +/// Music Properties +/// ------------------------ + +musictype_t I_MusicType(void) { #ifdef HAVE_LIBGME if (gme) @@ -463,74 +532,9 @@ boolean I_MusicPaused(void) return songpaused; } -// Music hooks -static void music_loop(void) -{ - Mix_PlayMusic(music, 0); - Mix_SetMusicPosition(loop_point); -} - -#ifdef HAVE_LIBGME -static void mix_gme(void *udata, Uint8 *stream, int len) -{ - int i; - short *p; - - (void)udata; - - // no gme? no music. - if (!gme || gme_track_ended(gme) || songpaused) - return; - - // play gme into stream - gme_play(gme, len/2, (short *)stream); - - // apply volume to stream - for (i = 0, p = (short *)stream; i < len/2; i++, p++) - *p = ((INT32)*p) * music_volume*2 / 42; -} -#endif - -FUNCMATH void I_InitMusic(void) -{ -#ifdef HAVE_LIBGME - gme = NULL; - current_track = -1; -#endif -} - -void I_ShutdownMusic(void) -{ -#ifdef HAVE_LIBGME - if (gme) - { - Mix_HookMusic(NULL, NULL); - gme_delete(gme); - gme = NULL; - } -#endif - if (!music) - return; - Mix_HookMusicFinished(NULL); - Mix_FreeMusic(music); - music = NULL; -} - -void I_PauseSong(void) -{ - Mix_PauseMusic(); - songpaused = true; -} - -void I_ResumeSong(void) -{ - Mix_ResumeMusic(); - songpaused = false; -} - -// -// Digital Music -// +/// ------------------------ +/// Music Effects +/// ------------------------ boolean I_SetSongSpeed(float speed) { @@ -550,40 +554,9 @@ boolean I_SetSongSpeed(float speed) return false; } -boolean I_SetSongTrack(int track) -{ -#ifdef HAVE_LIBGME - if (current_track == track) - return false; - - // If the specified track is within the number of tracks playing, then change it - if (gme) - { - SDL_LockAudio(); - if (track >= 0 - && track < gme_track_count(gme)) - { - gme_err_t gme_e = gme_start_track(gme, track); - if (gme_e != NULL) - { - CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); - return false; - } - current_track = track; - SDL_UnlockAudio(); - return true; - } - SDL_UnlockAudio(); - return false; - } -#endif - (void)track; - return false; -} - -// -// MIDI Music -// +/// ------------------------ +/// Music Playback +/// ------------------------ boolean I_LoadSong(char *data, size_t len) { @@ -731,6 +704,12 @@ boolean I_LoadSong(char *data, size_t len) return true; } +void I_UnloadSong(void) +{ + Mix_FreeMusic(music); + music = NULL; +} + boolean I_PlaySong(boolean looping) { if (!music) @@ -775,25 +754,64 @@ void I_StopSong(void) music = NULL; } +void I_PauseSong(void) +{ + Mix_PauseMusic(); + songpaused = true; +} + +void I_ResumeSong(void) +{ + Mix_ResumeMusic(); + songpaused = false; +} + void I_SetMusicVolume(UINT8 volume) { if (!music) return; - if (I_GetMusicType() == MU_MID) +#ifdef _WIN32 + if (I_MusicType() == MU_MID) // HACK: Until we stop using native MIDI, // disable volume changes music_volume = 31; else +#endif music_volume = volume; Mix_VolumeMusic((UINT32)music_volume*128/31); } -void I_UnloadSong(void) +boolean I_SetSongTrack(int track) { - Mix_FreeMusic(music); - music = NULL; +#ifdef HAVE_LIBGME + if (current_track == track) + return false; + + // If the specified track is within the number of tracks playing, then change it + if (gme) + { + SDL_LockAudio(); + if (track >= 0 + && track < gme_track_count(gme)) + { + gme_err_t gme_e = gme_start_track(gme, track); + if (gme_e != NULL) + { + CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); + return false; + } + current_track = track; + SDL_UnlockAudio(); + return true; + } + SDL_UnlockAudio(); + return false; + } +#endif + (void)track; + return false; } #endif \ No newline at end of file From d535c14fc6b8d5fb25af05075c6804aaae68270c Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 17:05:47 -0400 Subject: [PATCH 040/264] Refactoring and reordering other targets (cherry picked from commit cf065e106f68fb8af3b0568eba188c8235b1656e) --- src/android/i_sound.c | 66 ++++++------ src/djgppdos/i_sound.c | 198 +++++++++++++++++++--------------- src/dummy/i_sound.c | 64 +++++------ src/sdl/sdl_sound.c | 237 +++++++++++++++++++++++------------------ src/win32/win_snd.c | 218 +++++++++++++++++++------------------ 5 files changed, 428 insertions(+), 355 deletions(-) diff --git a/src/android/i_sound.c b/src/android/i_sound.c index 1cbc53fab..bf54c9ff0 100644 --- a/src/android/i_sound.c +++ b/src/android/i_sound.c @@ -55,12 +55,22 @@ void I_SetSfxVolume(INT32 volume) (void)volume; } -// -// MUSIC I/O -// -UINT8 music_started = 0; +/// ------------------------ +// MUSIC SYSTEM +/// ------------------------ -musictype_t I_GetMusicType(void) +UINT8 music_started = 0; +UINT8 digmusic_started = 0; + +void I_InitMusic(void){} + +void I_ShutdownMusic(void){} + +/// ------------------------ +// MUSIC PROPERTIES +/// ------------------------ + +musictype_t I_MusicType(void) { return MU_NONE; } @@ -75,23 +85,19 @@ boolean I_MusicPaused(void) return false; } -void I_InitMusic(void){} +/// ------------------------ +// MUSIC EFFECTS +/// ------------------------ -void I_ShutdownMusic(void){} - -void I_PauseSong(void) +boolean I_SetSongSpeed(float speed) { - (void)handle; + (void)speed; + return false; } -void I_ResumeSong(void) -{ - (void)handle; -} - -// -// MIDI I/O -// +/// ------------------------ +// MUSIC PLAYBACK +/// ------------------------ UINT8 midimusic_started = 0; @@ -102,9 +108,9 @@ boolean I_LoadSong(char *data, size_t len) return -1; } -void I_SetMusicVolume(INT32 volume) +void I_UnloadSong() { - (void)volume; + } boolean I_PlaySong(boolean looping) @@ -119,19 +125,17 @@ void I_StopSong(void) (void)handle; } -void I_UnloadSong(void) +void I_PauseSong(void) { (void)handle; } -// -// DIGMUSIC I/O -// - -UINT8 digmusic_started = 0; - -boolean I_SetSongSpeed(float speed) +void I_ResumeSong(void) { - (void)speed; - return false; -} \ No newline at end of file + (void)handle; +} + +void I_SetMusicVolume(INT32 volume) +{ + (void)volume; +} diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c index d998016a2..339b469d3 100644 --- a/src/djgppdos/i_sound.c +++ b/src/djgppdos/i_sound.c @@ -140,15 +140,6 @@ void I_SetSfxVolume(INT32 volume) set_volume (Volset(volume),-1); } -void I_SetMusicVolume(INT32 volume) -{ - if (midi_disabled) - return; - - // Now set volume on output device. - set_volume (-1, Volset(volume)); -} - // // Starting a sound means adding it // to the current list of active sounds @@ -323,23 +314,9 @@ static int musicdies=-1; UINT8 music_started=0; boolean songpaused=false; -musictype_t I_GetMusicType(void) -{ - if (currsong) - return MU_MID; - else - return MU_NONE; -} - -boolean I_MusicPlaying() -{ - return (boolean)currsong; -} - -boolean I_MusicPaused() -{ - return songpaused; -} +/// ------------------------ +// MUSIC SYSTEM +/// ------------------------ /* load_midi_mem: * Loads a standard MIDI file from memory, returning a pointer to @@ -427,69 +404,41 @@ void I_ShutdownMusic(void) music_started=false; } -boolean I_PlaySong(boolean looping) -{ - handle = 0; - if (midi_disabled) - return false; +/// ------------------------ +// MUSIC PROPERTIES +/// ------------------------ - islooping = looping; - musicdies = gametic + NEWTICRATE*30; - if (play_midi(currsong,looping)==0) - return true; +musictype_t I_MusicType(void) +{ + if (currsong) + return MU_MID; + else + return MU_NONE; +} + +boolean I_MusicPlaying() +{ + return (boolean)currsong; +} + +boolean I_MusicPaused() +{ + return songpaused; +} + +/// ------------------------ +// MUSIC EFFECTS +/// ------------------------ + +boolean I_SetSongSpeed(float speed) +{ + (void)speed; return false; } -void I_PauseSong (INT32 handle) -{ - handle = 0; - if (midi_disabled) - return; - midi_pause(); - songpaused = true; -} - -void I_ResumeSong (INT32 handle) -{ - handle = 0; - if (midi_disabled) - return; - midi_resume(); - songpaused = false; -} - -void I_StopSong(void) -{ - handle = 0; - if (midi_disabled) - return; - - islooping = 0; - musicdies = 0; - stop_midi(); - songpaused = false; -} - -// Is the song playing? -#if 0 -int I_QrySongPlaying(int handle) -{ - if (midi_disabled) - return 0; - - //return islooping || musicdies > gametic; - return (midi_pos==-1); -} -#endif - -void I_UnloadSong(void) -{ - handle = 0; - if (midi_disabled) - return; - - //destroy_midi(currsong); -} +/// ------------------------ +// MUSIC PLAYBACK +/// ------------------------ boolean I_LoadSong(char *data, size_t len) { @@ -516,8 +465,81 @@ boolean I_LoadSong(char *data, size_t len) return 1; } -boolean I_SetSongSpeed(float speed) +void I_UnloadSong(void) { - (void)speed; + handle = 0; + if (midi_disabled) + return; + + //destroy_midi(currsong); +} + +boolean I_PlaySong(boolean looping) +{ + handle = 0; + if (midi_disabled) + return false; + + islooping = looping; + musicdies = gametic + NEWTICRATE*30; + if (play_midi(currsong,looping)==0) + return true; return false; -} \ No newline at end of file +} + +void I_StopSong(void) +{ + handle = 0; + if (midi_disabled) + return; + + islooping = 0; + musicdies = 0; + stop_midi(); + songpaused = false; +} + +void I_PauseSong (INT32 handle) +{ + handle = 0; + if (midi_disabled) + return; + midi_pause(); + songpaused = true; +} + +void I_ResumeSong (INT32 handle) +{ + handle = 0; + if (midi_disabled) + return; + midi_resume(); + songpaused = false; +} + +void I_SetMusicVolume(INT32 volume) +{ + if (midi_disabled) + return; + + // Now set volume on output device. + set_volume (-1, Volset(volume)); +} + +boolean I_SetSongTrack(INT32 track) +{ + (void)track; + return false; +} + +// Is the song playing? +#if 0 +int I_QrySongPlaying(int handle) +{ + if (midi_disabled) + return 0; + + //return islooping || musicdies > gametic; + return (midi_pos==-1); +} +#endif diff --git a/src/dummy/i_sound.c b/src/dummy/i_sound.c index ca90a7da3..fb325c59e 100644 --- a/src/dummy/i_sound.c +++ b/src/dummy/i_sound.c @@ -57,11 +57,19 @@ void I_SetSfxVolume(UINT8 volume) (void)volume; } -// -// MUSIC I/O -// +/// ------------------------ +// MUSIC SYSTEM +/// ------------------------ -musictype_t I_GetMusicType(void) +void I_InitMusic(void){} + +void I_ShutdownMusic(void){} + +/// ------------------------ +// MUSIC PROPERTIES +/// ------------------------ + +musictype_t I_MusicType(void) { return MU_NONE; } @@ -76,28 +84,19 @@ boolean I_MusicPaused(void) return false; } -void I_InitMusic(void){} +/// ------------------------ +// MUSIC EFFECTS +/// ------------------------ -void I_ShutdownMusic(void){} - -void I_SetMusicVolume(UINT8 volume) +boolean I_SetSongSpeed(float speed) { - (void)volume; + (void)speed; + return false; } -void I_PauseSong(void) -{ - (void)handle; -} - -void I_ResumeSong(void) -{ - (void)handle; -} - -// -// MIDI I/O -// +/// ------------------------ +// MUSIC PLAYBACK +/// ------------------------ boolean I_LoadSong(char *data, size_t len) { @@ -106,6 +105,11 @@ boolean I_LoadSong(char *data, size_t len) return -1; } +void I_UnloadSong(void) +{ + (void)handle; +} + boolean I_PlaySong(boolean looping) { (void)handle; @@ -118,19 +122,19 @@ void I_StopSong(void) (void)handle; } -void I_UnloadSong(void) +void I_PauseSong(void) { (void)handle; } -// -// DIGMUSIC I/O -// - -boolean I_SetSongSpeed(float speed) +void I_ResumeSong(void) { - (void)speed; - return false; + (void)handle; +} + +void I_SetMusicVolume(UINT8 volume) +{ + (void)volume; } boolean I_SetSongTrack(int track) diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index cf54d7d05..6a79220c2 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1313,7 +1313,7 @@ void I_StartupSound(void) // MUSIC API. // -musictype_t I_GetMusicType(void) +musictype_t I_MusicType(void) { #ifdef HAVE_MIXER #ifdef HAVE_LIBGME @@ -1448,28 +1448,9 @@ static boolean LoadSong(void *data, size_t lumplength, size_t selectpos) } #endif - -void I_ShutdownMusic(void) -{ -#ifdef HAVE_MIXER - if ((midi_disabled && digital_disabled) || !musicStarted) - return; - - CONS_Printf("%s", M_GetText("I_ShutdownMusic: ")); - - I_UnloadSong(); - I_StopSong(); - Mix_CloseAudio(); -#ifdef MIX_INIT - Mix_Quit(); -#endif - CONS_Printf("%s", M_GetText("shut down\n")); - musicStarted = SDL_FALSE; - if (Msc_Mutex) - SDL_DestroyMutex(Msc_Mutex); - Msc_Mutex = NULL; -#endif -} +/// ------------------------ +// MUSIC SYSTEM +/// ------------------------ void I_InitMusic(void) { @@ -1584,11 +1565,106 @@ void I_InitMusic(void) #endif } -boolean I_PlaySong(INT32 handle, boolean looping) +void I_ShutdownMusic(void) { - (void)handle; #ifdef HAVE_MIXER - if (midi_disabled || !musicStarted || !music[handle]) + if ((midi_disabled && digital_disabled) || !musicStarted) + return; + + CONS_Printf("%s", M_GetText("I_ShutdownMusic: ")); + + I_UnloadSong(); + I_StopSong(); + Mix_CloseAudio(); +#ifdef MIX_INIT + Mix_Quit(); +#endif + CONS_Printf("%s", M_GetText("shut down\n")); + musicStarted = SDL_FALSE; + if (Msc_Mutex) + SDL_DestroyMutex(Msc_Mutex); + Msc_Mutex = NULL; +#endif +} + +/// ------------------------ +// MUSIC PROPERTIES +/// ------------------------ + +musictype_t I_MusicType(void) +{ + return MU_NONE; +} + +boolean I_MusicPlaying(void) +{ + return false; +} + +boolean I_MusicPaused(void) +{ + return false; +} + +/// ------------------------ +// MUSIC EFFECTS +/// ------------------------ + +boolean I_SetSongSpeed(float speed) +{ + (void)speed; + return false; +} + +/// ------------------------ +// MUSIC PLAYBACK +// \todo Merge Digital and MIDI +/// ------------------------ + +boolean I_LoadSong(char *data, size_t len) +{ +#ifdef HAVE_MIXER + if (midi_disabled || !musicStarted) + return false; + + if (!LoadSong(data, len, 0)) + return false; + + if (music[0]) + return true; + + CONS_Printf(M_GetText("Couldn't load MIDI: %s\n"), Mix_GetError()); +#else + (void)len; + (void)data; +#endif + return false; +} + +void I_UnloadSong(void) +{ +#ifdef HAVE_MIXER + + if (midi_disabled || !musicStarted) + return; + + Mix_HaltMusic(); + while (Mix_PlayingMusic()) + ; + + if (music[handle]) + Mix_FreeMusic(music[handle]); + music[handle] = NULL; + LoadSong(NULL, 0, handle); +#else + (void)handle; +#endif +} + +boolean I_PlaySong(boolean looping) +{ +#ifdef HAVE_MIXER + if (!musicStarted || !music[handle]) return false; #ifdef MIXER_POS @@ -1609,6 +1685,28 @@ boolean I_PlaySong(INT32 handle, boolean looping) return false; } +void I_StopSong(void) +{ + I_StopGME(); +#ifdef HAVE_MIXER + if (digital_disabled) + return; + +#ifdef MIXER_POS + if (canlooping) + Mix_HookMusicFinished(NULL); +#endif + + Mix_HaltMusic(); + while (Mix_PlayingMusic()) + ; + + if (music[1]) + Mix_FreeMusic(music[1]); + music[1] = NULL; + LoadSong(NULL, 0, 1); +} + static void I_PauseGME(void) { #ifdef HAVE_LIBGME @@ -1650,68 +1748,6 @@ void I_ResumeSong(void) #endif } -void I_StopSong(void) -{ - I_StopGME(); -#ifdef HAVE_MIXER - if (digital_disabled) - return; - -#ifdef MIXER_POS - if (canlooping) - Mix_HookMusicFinished(NULL); -#endif - - Mix_HaltMusic(); - while (Mix_PlayingMusic()) - ; - - if (music[1]) - Mix_FreeMusic(music[1]); - music[1] = NULL; - LoadSong(NULL, 0, 1); -} - -void I_UnloadSong(void) -{ -#ifdef HAVE_MIXER - - if (midi_disabled || !musicStarted) - return; - - Mix_HaltMusic(); - while (Mix_PlayingMusic()) - ; - - if (music[handle]) - Mix_FreeMusic(music[handle]); - music[handle] = NULL; - LoadSong(NULL, 0, handle); -#else - (void)handle; -#endif -} - -boolean I_LoadSong(char *data, size_t len) -{ -#ifdef HAVE_MIXER - if (midi_disabled || !musicStarted) - return false; - - if (!LoadSong(data, len, 0)) - return false; - - if (music[0]) - return true; - - CONS_Printf(M_GetText("Couldn't load MIDI: %s\n"), Mix_GetError()); -#else - (void)len; - (void)data; -#endif - return false; -} - void I_SetMusicVolume(UINT8 volume) { #ifdef HAVE_MIXER @@ -1727,6 +1763,18 @@ void I_SetMusicVolume(UINT8 volume) #endif } +boolean I_SetSongTrack(int track) +{ + (void)track; + return false; +} + +/// ------------------------ +// MUSIC LOADING AND CLEANUP +// \todo Split logic between loading and playing, +// then move to Playback section +/// ------------------------ + #ifdef HAVE_LIBGME static void I_CleanupGME(void *userdata) { @@ -1961,19 +2009,6 @@ static void I_StopGME(void) #endif } -boolean I_SetSongSpeed(float speed) -{ - - (void)speed; - return false; -} - -boolean I_SetSongTrack(int track) -{ - (void)track; - return false; -} - #ifdef MIXER_POS static void SDLCALL I_FinishMusic(void) { diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index c6a74d999..3dbe6c572 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -439,11 +439,24 @@ void I_SetSfxVolume(UINT8 volume) sfx_volume = volume; } -// -// MUSIC -// +/// ------------------------ +// MUSIC SYSTEM +/// ------------------------ -musictype_t I_GetMusicType(void) +void I_InitMusic(void) +{ +} + +void I_ShutdownMusic(void) +{ + I_StopSong(); +} + +/// ------------------------ +// MUSIC PROPERTIES +/// ------------------------ + +musictype_t I_MusicType(void) { #ifdef HAVE_LIBGME if (gme) @@ -491,28 +504,46 @@ boolean I_MusicPaused(void) return fmpaused; } -void I_InitMusic(void) +/// ------------------------ +// MUSIC EFFECTS +/// ------------------------ + +boolean I_SetSongSpeed(float speed) { + FMOD_RESULT e; + float frequency; + if (!music_stream) + return false; + if (speed > 250.0f) + speed = 250.0f; //limit speed up to 250x + +#ifdef HAVE_LIBGME + // Try to set GME speed + if (gme) + { + gme_set_tempo(gme, speed); + return true; + } +#endif + + // Try to set Mod/Midi speed + e = FMOD_Sound_SetMusicSpeed(music_stream, speed); + + if (e == FMOD_ERR_FORMAT) + { + // Just change pitch instead for Ogg/etc. + FMR(FMOD_Sound_GetDefaults(music_stream, &frequency, NULL, NULL, NULL)); + FMR_MUSIC(FMOD_Channel_SetFrequency(music_channel, speed*frequency)); + } + else + FMR_MUSIC(e); + + return true; } -void I_ShutdownMusic(void) -{ - I_StopSong(); -} - -void I_PauseSong(void) -{ - UNREFERENCED_PARAMETER(handle); - if (music_stream) - FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, true)); -} - -void I_ResumeSong(void) -{ - UNREFERENCED_PARAMETER(handle); - if (music_stream) - FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, false)); -} +/// ------------------------ +// MUSIC PLAYBACK +/// ------------------------ boolean I_LoadSong(char *data, size_t len) { @@ -726,39 +757,79 @@ boolean I_LoadSong(char *data, size_t len) return true; } -boolean I_SetSongSpeed(float speed) +void I_UnloadSong(void) { - FMOD_RESULT e; - float frequency; - if (!music_stream) - return false; - if (speed > 250.0f) - speed = 250.0f; //limit speed up to 250x + UNREFERENCED_PARAMETER(handle); + if (music_stream) + FMR(FMOD_Sound_Release(music_stream)); + music_stream = NULL; +} +boolean I_PlaySong(boolean looping) +{ #ifdef HAVE_LIBGME - // Try to set GME speed if (gme) { - gme_set_tempo(gme, speed); + gme_start_track(gme, 0); + current_track = 0; + FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); + FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); + FMR(FMOD_Channel_SetPriority(music_channel, 0)); return true; } #endif - // Try to set Mod/Midi speed - e = FMOD_Sound_SetMusicSpeed(music_stream, speed); - - if (e == FMOD_ERR_FORMAT) - { - // Just change pitch instead for Ogg/etc. - FMR(FMOD_Sound_GetDefaults(music_stream, &frequency, NULL, NULL, NULL)); - FMR_MUSIC(FMOD_Channel_SetFrequency(music_channel, speed*frequency)); - } + FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); + if (I_MusicType() != MU_MID) + FMR(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0)); else - FMR_MUSIC(e); + FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); + FMR(FMOD_Channel_SetPriority(music_channel, 0)); + current_track = 0; return true; } +void I_StopSong(void) +{ +#ifdef HAVE_LIBGME + if (gme) + gme_delete(gme); + gme = NULL; +#endif + current_track = -1; + + I_UnloadSong(); +} + +void I_PauseSong(void) +{ + UNREFERENCED_PARAMETER(handle); + if (music_stream) + FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, true)); +} + +void I_ResumeSong(void) +{ + UNREFERENCED_PARAMETER(handle); + if (music_stream) + FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, false)); +} + +void I_SetMusicVolume(UINT8 volume) +{ + if (!music_stream) + return; + + // volume is 0 to 31. + if (I_MusicType() == MU_MID) + music_volume = 31; // windows bug hack + else + music_volume = volume; + + FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); +} + boolean I_SetSongTrack(INT32 track) { if (track != current_track) // If the track's already playing, then why bother? @@ -803,66 +874,3 @@ boolean I_SetSongTrack(INT32 track) } return false; } - -// -// Fuck MIDI. ... Okay fine, you can have your silly D_-only mode. -// - -void I_SetMusicVolume(UINT8 volume) -{ - if (!music_stream) - return; - - // volume is 0 to 31. - if (I_GetMusicType() == MU_MID) - music_volume = 31; // windows bug hack - else - music_volume = volume; - - FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); -} - -boolean I_PlaySong(boolean looping) -{ -#ifdef HAVE_LIBGME - if (gme) - { - gme_start_track(gme, 0); - current_track = 0; - FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); - FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); - FMR(FMOD_Channel_SetPriority(music_channel, 0)); - return true; - } -#endif - - FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); - if (I_GetMusicType() != MU_MID) - FMR(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0)); - else - FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); - FMR(FMOD_Channel_SetPriority(music_channel, 0)); - current_track = 0; - - return true; -} - -void I_StopSong(void) -{ -#ifdef HAVE_LIBGME - if (gme) - gme_delete(gme); - gme = NULL; -#endif - current_track = -1; - - I_UnloadSong(); -} - -void I_UnloadSong(void) -{ - UNREFERENCED_PARAMETER(handle); - if (music_stream) - FMR(FMOD_Sound_Release(music_stream)); - music_stream = NULL; -} \ No newline at end of file From eacf0ba00bc88eeff112b29fbf18f0a8d6ba2b52 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 20:14:46 -0400 Subject: [PATCH 041/264] Refactor I_MusicType MusicPlaying and MusicPaused -> I_SongType ... (cherry picked from commit 4b82de9e540d6dc0651bbe8db8e5e15cba39f650) --- src/i_sound.h | 6 +++--- src/s_sound.c | 18 +++++++++--------- src/sdl/mixer_sound.c | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/i_sound.h b/src/i_sound.h index 15126d695..1be970d2e 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -136,9 +136,9 @@ void I_ShutdownMusic(void); // MUSIC PROPERTIES /// ------------------------ -musictype_t I_MusicType(void); -boolean I_MusicPlaying(void); -boolean I_MusicPaused(void); +musictype_t I_SongType(void); +boolean I_SongPlaying(void); +boolean I_SongPaused(void); /// ------------------------ // MUSIC EFFECTS diff --git a/src/s_sound.c b/src/s_sound.c index bd6022dfb..723401fb2 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1239,22 +1239,22 @@ boolean S_MusicDisabled(void) boolean S_MusicPlaying(void) { - return I_MusicPlaying(); + return I_SongPlaying(); } boolean S_MusicPaused(void) { - return I_MusicPaused(); + return I_SongPaused(); } musictype_t S_MusicType(void) { - return I_MusicType(); + return I_SongType(); } boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping) { - if (!I_MusicPlaying()) + if (!I_SongPlaying()) return false; strncpy(mname, music_name, 7); @@ -1399,10 +1399,10 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) void S_StopMusic(void) { - if (!I_MusicPlaying()) + if (!I_SongPlaying()) return; - if (I_MusicPaused()) + if (I_SongPaused()) I_ResumeSong(); S_SpeedMusic(1.0f); @@ -1421,7 +1421,7 @@ void S_StopMusic(void) // void S_PauseAudio(void) { - if (I_MusicPlaying() && !I_MusicPaused()) + if (I_SongPlaying() && !I_SongPaused()) I_PauseSong(); // pause cd music @@ -1434,7 +1434,7 @@ void S_PauseAudio(void) void S_ResumeAudio(void) { - if (I_MusicPlaying() && I_MusicPaused()) + if (I_SongPlaying() && I_SongPaused()) I_ResumeSong(); // resume cd music @@ -1462,7 +1462,7 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) digvolume = seqvolume = 31; #endif - switch(I_MusicType()) + switch(I_SongType()) { case MU_MID: case MU_MOD: diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 9c46625fc..521bcd033 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -503,7 +503,7 @@ void I_ShutdownMusic(void) /// Music Properties /// ------------------------ -musictype_t I_MusicType(void) +musictype_t I_SongType(void) { #ifdef HAVE_LIBGME if (gme) @@ -522,12 +522,12 @@ musictype_t I_MusicType(void) return (musictype_t)Mix_GetMusicType(music); } -boolean I_MusicPlaying(void) +boolean I_SongPlaying(void) { return (boolean)music; } -boolean I_MusicPaused(void) +boolean I_SongPaused(void) { return songpaused; } @@ -772,7 +772,7 @@ void I_SetMusicVolume(UINT8 volume) return; #ifdef _WIN32 - if (I_MusicType() == MU_MID) + if (I_SongType() == MU_MID) // HACK: Until we stop using native MIDI, // disable volume changes music_volume = 31; From 4d61f00b865033a36af0ad246189345a4fa776f8 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 23 Aug 2018 20:14:56 -0400 Subject: [PATCH 042/264] Refactor I_MusicType MusicPlaying and MusicPaused other targets (cherry picked from commit 9e6eebeb8d6b4119d87e9678bb6b0687e3dc5217) --- src/android/i_sound.c | 6 +++--- src/djgppdos/i_sound.c | 6 +++--- src/dummy/i_sound.c | 6 +++--- src/sdl/mixer_sound.c | 4 ++-- src/sdl/sdl_sound.c | 12 ++++++------ src/win32/win_snd.c | 10 +++++----- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/android/i_sound.c b/src/android/i_sound.c index bf54c9ff0..1d16e4df3 100644 --- a/src/android/i_sound.c +++ b/src/android/i_sound.c @@ -70,17 +70,17 @@ void I_ShutdownMusic(void){} // MUSIC PROPERTIES /// ------------------------ -musictype_t I_MusicType(void) +musictype_t I_SongType(void) { return MU_NONE; } -boolean I_MusicPlaying(void) +boolean I_SongPlaying(void) { return false; } -boolean I_MusicPaused(void) +boolean I_SongPaused(void) { return false; } diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c index 339b469d3..5403aef17 100644 --- a/src/djgppdos/i_sound.c +++ b/src/djgppdos/i_sound.c @@ -408,7 +408,7 @@ void I_ShutdownMusic(void) // MUSIC PROPERTIES /// ------------------------ -musictype_t I_MusicType(void) +musictype_t I_SongType(void) { if (currsong) return MU_MID; @@ -416,12 +416,12 @@ musictype_t I_MusicType(void) return MU_NONE; } -boolean I_MusicPlaying() +boolean I_SongPlaying() { return (boolean)currsong; } -boolean I_MusicPaused() +boolean I_SongPaused() { return songpaused; } diff --git a/src/dummy/i_sound.c b/src/dummy/i_sound.c index fb325c59e..4bace7a41 100644 --- a/src/dummy/i_sound.c +++ b/src/dummy/i_sound.c @@ -69,17 +69,17 @@ void I_ShutdownMusic(void){} // MUSIC PROPERTIES /// ------------------------ -musictype_t I_MusicType(void) +musictype_t I_SongType(void) { return MU_NONE; } -boolean I_MusicPlaying(void) +boolean I_SongPlaying(void) { return false; } -boolean I_MusicPaused(void) +boolean I_SongPaused(void) { return false; } diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 521bcd033..9b84a1247 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -63,7 +63,7 @@ UINT8 sound_started = false; static Mix_Music *music; -static UINT8 music_volume, midi_volume, sfx_volume; +static UINT8 music_volume, sfx_volume; static float loop_point; static boolean songpaused; @@ -91,7 +91,7 @@ void I_StartupSound(void) } music = NULL; - music_volume = midi_volume = sfx_volume = 0; + music_volume = sfx_volume = 0; #if SDL_MIXER_VERSION_ATLEAST(1,2,11) Mix_Init(MIX_INIT_FLAC|MIX_INIT_MOD|MIX_INIT_MP3|MIX_INIT_OGG); diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 6a79220c2..887726ebb 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1313,7 +1313,7 @@ void I_StartupSound(void) // MUSIC API. // -musictype_t I_MusicType(void) +musictype_t I_SongType(void) { #ifdef HAVE_MIXER #ifdef HAVE_LIBGME @@ -1336,12 +1336,12 @@ musictype_t I_MusicType(void) #endif } -boolean I_MusicPlaying(void) +boolean I_SongPlaying(void) { return music_started; } -boolean I_MusicPaused(void) +boolean I_SongPaused(void) { return Mix_PausedMusic(); } @@ -1591,17 +1591,17 @@ void I_ShutdownMusic(void) // MUSIC PROPERTIES /// ------------------------ -musictype_t I_MusicType(void) +musictype_t I_SongType(void) { return MU_NONE; } -boolean I_MusicPlaying(void) +boolean I_SongPlaying(void) { return false; } -boolean I_MusicPaused(void) +boolean I_SongPaused(void) { return false; } diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index 3dbe6c572..2960ff7d2 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -456,7 +456,7 @@ void I_ShutdownMusic(void) // MUSIC PROPERTIES /// ------------------------ -musictype_t I_MusicType(void) +musictype_t I_SongType(void) { #ifdef HAVE_LIBGME if (gme) @@ -491,12 +491,12 @@ musictype_t I_MusicType(void) return MU_NONE; } -boolean I_MusicPlaying(void) +boolean I_SongPlaying(void) { return (boolean)music_stream; } -boolean I_MusicPaused(void) +boolean I_SongPaused(void) { boolean fmpaused = false; if (music_stream) @@ -780,7 +780,7 @@ boolean I_PlaySong(boolean looping) #endif FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); - if (I_MusicType() != MU_MID) + if (I_SongType() != MU_MID) FMR(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0)); else FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); @@ -822,7 +822,7 @@ void I_SetMusicVolume(UINT8 volume) return; // volume is 0 to 31. - if (I_MusicType() == MU_MID) + if (I_SongType() == MU_MID) music_volume = 31; // windows bug hack else music_volume = volume; From b0c47e2fb12a234a1fa5c41eab54a5b72e734a43 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 24 Aug 2018 13:12:14 -0400 Subject: [PATCH 043/264] GME fix: play song in I_PlaySong, not I_LoadSong (cherry picked from commit 5f21bf230d9716b7cc5b52e4bf3591ebe01e9f3a) --- src/sdl/mixer_sound.c | 8 ++++---- src/win32/win_snd.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 9b84a1247..ca22724b6 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -656,7 +656,6 @@ boolean I_LoadSong(char *data, size_t len) { gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; gme_set_equalizer(gme, &eq); - Mix_HookMusic(mix_gme, gme); return true; } #endif @@ -712,16 +711,17 @@ void I_UnloadSong(void) boolean I_PlaySong(boolean looping) { - if (!music) - return false; -#ifdef HAVE_GME +#ifdef HAVE_LIBGME if (gme) { gme_start_track(gme, 0); current_track = 0; + Mix_HookMusic(mix_gme, gme); return true; } #endif + else if (!music) + return false; if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1) { diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index 2960ff7d2..2e05c4f72 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -675,7 +675,6 @@ boolean I_LoadSong(char *data, size_t len) fmt.decodebuffersize = (44100 * 2) / 35; fmt.pcmreadcallback = GMEReadCallback; fmt.userdata = gme; - FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER | (looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream)); return true; } #endif @@ -772,6 +771,7 @@ boolean I_PlaySong(boolean looping) { gme_start_track(gme, 0); current_track = 0; + FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER | (looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream)); FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); FMR(FMOD_Channel_SetPriority(music_channel, 0)); From 2fbe206ecb6c978f088f7398e970ecbad8b4b90b Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 24 Aug 2018 13:41:26 -0400 Subject: [PATCH 044/264] A word (cherry picked from commit fb6f8c8a0752c229f5b7369729437c8fecb54d45) --- src/sdl/mixer_sound.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index ca22724b6..927065924 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -719,8 +719,9 @@ boolean I_PlaySong(boolean looping) Mix_HookMusic(mix_gme, gme); return true; } + else #endif - else if (!music) + if (!music) return false; if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1) From 5f22b7d973002eb873551dff56a07a034c564a61 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 24 Aug 2018 18:01:57 -0400 Subject: [PATCH 045/264] Volume fixes # Conflicts: # src/sdl/mixer_sound.c (cherry picked from commit d39b7011c5b12e5b7abe3e493971e003469a1f3d) --- src/s_sound.c | 6 ++++-- src/sdl/mixer_sound.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 723401fb2..6b632687b 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1465,11 +1465,13 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) switch(I_SongType()) { case MU_MID: - case MU_MOD: - case MU_GME: + //case MU_MOD: + //case MU_GME: I_SetMusicVolume(seqvolume&31); + break; default: I_SetMusicVolume(digvolume&31); + break; } } diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 927065924..49905efd7 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -769,7 +769,7 @@ void I_ResumeSong(void) void I_SetMusicVolume(UINT8 volume) { - if (!music) + if (!I_SongPlaying()) return; #ifdef _WIN32 From d94f7e3cb095b14bad42dc14e39fc40848ed86ee Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 24 Aug 2018 18:02:46 -0400 Subject: [PATCH 046/264] Stub I_UnloadSong because we already unload in I_StopMusic * Stop-gap for now. Ideally the logic would be in the respective places. # Conflicts: # src/sdl/mixer_sound.c (cherry picked from commit eae5d3333f5001512c82f22f2b1433a955b3a6c3) --- src/sdl/mixer_sound.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 49905efd7..676bfc4db 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -705,8 +705,11 @@ boolean I_LoadSong(char *data, size_t len) void I_UnloadSong(void) { - Mix_FreeMusic(music); - music = NULL; + // \todo unhook looper + //var_cleanup(); + //Mix_FreeMusic(music); + //music = NULL; + I_StopSong(); } boolean I_PlaySong(boolean looping) From 8541963c613cfaaff38feef1e00b00a0d5c9ddbc Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 24 Aug 2018 18:00:18 -0400 Subject: [PATCH 047/264] I_SongPlaying detect GME properly (cherry picked from commit e88d1477616ca66472ecb50d371e37dc79c77c0f) --- src/sdl/mixer_sound.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 676bfc4db..dd00d78f7 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -524,7 +524,12 @@ musictype_t I_SongType(void) boolean I_SongPlaying(void) { - return (boolean)music; + return ( +#ifdef HAVE_LIBGME + (I_SongType() == MU_GME && gme) || +#endif + (boolean)music + ); } boolean I_SongPaused(void) From fac7d19637dd29e09622493281744fbfaa045dc0 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 25 Aug 2018 21:42:39 -0400 Subject: [PATCH 048/264] Case-insensitive music_name comparison (cherry picked from commit a7ae059949b320723727aea4468a370bc63c3910) --- src/s_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_sound.c b/src/s_sound.c index 6b632687b..53b8a9628 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1378,7 +1378,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) return; } - if (strncmp(music_name, mmusic, 6)) + if (strnicmp(music_name, newmusic, 6)) { S_StopMusic(); // shutdown old music From 4b1bc53db13198c4746102cff6a0a90eab2e4d88 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 10:58:41 -0400 Subject: [PATCH 049/264] Compile fixes --- src/d_main.c | 11 ++++------- src/s_sound.c | 2 +- src/sdl/i_video.c | 4 ++-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index ed1b44684..9d2e1bccc 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -121,20 +121,17 @@ INT32 postimgparam; postimg_t postimgtype2 = postimg_none; INT32 postimgparam2; +// These variables are only true if +// whether the respective sound system is disabled +// or they're init'ed, but the player just toggled them #ifdef _XBOX boolean midi_disabled = true, sound_disabled = true; boolean digital_disabled = true; #else -boolean midi_disabled = false, sound_disabled = false; -boolean digital_disabled = false; // No fmod-based music -#endif - -// These variables are only true if -// whether the respective sound system is disabled -// or they're init'ed, but the player just toggled them boolean midi_disabled = false; boolean sound_disabled = false; boolean digital_disabled = false; +#endif boolean advancedemo; #ifdef DEBUGFILE diff --git a/src/s_sound.c b/src/s_sound.c index 53b8a9628..969d9fdee 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1378,7 +1378,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) return; } - if (strnicmp(music_name, newmusic, 6)) + if (strnicmp(music_name, mmusic, 6)) { S_StopMusic(); // shutdown old music diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index ce84e86a6..30ef1b27b 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -566,7 +566,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) // Tell game we got focus back, resume music if necessary window_notinfocus = false; if (!paused) - I_ResumeSong(0); //resume it + I_ResumeSong(); //resume it if (!firsttimeonmouse) { @@ -578,7 +578,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) { // Tell game we lost focus, pause music window_notinfocus = true; - I_PauseSong(0); + I_PauseSong(); if (!disable_mouse) { From 691de18fbbe502fe15fa30854a09c028897cc312 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 11:10:38 -0400 Subject: [PATCH 050/264] Menu sound toggle fixes (and add starpost sfx to menu) --- src/m_menu.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 6a6875aad..63794c529 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6954,23 +6954,15 @@ static void M_ToggleSFX(void) { sound_disabled = false; I_StartupSound(); - if (sound_disabled) return; S_InitSfxChannels(cv_soundvolume.value); + S_StartSound(NULL, sfx_strpst); M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING); } else { - if (sound_disabled) - { - sound_disabled = false; - M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING); - } - else - { - sound_disabled = true; - S_StopSounds(); - M_StartMessage(M_GetText("SFX Disabled\n"), NULL, MM_NOTHING); - } + sound_disabled = true; + S_StopSounds(); + M_StartMessage(M_GetText("SFX Disabled\n"), NULL, MM_NOTHING); } } @@ -6980,7 +6972,6 @@ static void M_ToggleDigital(void) { digital_disabled = false; I_InitMusic(); - if (digital_disabled) return; S_StopMusic(); if (Playing()) P_RestoreMusic(&players[consoleplayer]); @@ -7020,7 +7011,6 @@ static void M_ToggleMIDI(void) { midi_disabled = false; I_InitMusic(); - if (midi_disabled) return; if (Playing()) P_RestoreMusic(&players[consoleplayer]); else From 8e05de17f07e599ebb0e3030cb6d74a0b1f76e02 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 12:29:58 -0400 Subject: [PATCH 051/264] Bring back music_data handle, for srb2dd --- src/s_sound.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/s_sound.c b/src/s_sound.c index 969d9fdee..13b8beac1 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1215,6 +1215,7 @@ const char *compat_special_music_slots[16] = #endif static char music_name[7]; // up to 6-character name +static void *music_data; static UINT16 music_flags; static boolean music_looping; @@ -1333,6 +1334,7 @@ static boolean S_LoadMusic(const char *mname) { strncpy(music_name, mname, 7); music_name[6] = 0; + music_data = mdata; return true; } else @@ -1343,6 +1345,10 @@ static void S_UnloadMusic(void) { I_UnloadSong(); music_name[0] = 0; +#ifndef HAVE_SDL //SDL uses RWOPS + Z_ChangeTag(music_data, PU_CACHE); +#endif + music_data = NULL; music_flags = 0; music_looping = false; } From e72610a3dc0e7e1d18deb6375daa8bd5ef1e420f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 12:47:33 -0400 Subject: [PATCH 052/264] Separate StopMusic and UnloadMusic --- src/s_sound.c | 12 ++++------- src/sdl/mixer_sound.c | 50 ++++++++++++++++++------------------------- 2 files changed, 25 insertions(+), 37 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 13b8beac1..2b8e8e721 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1344,11 +1344,13 @@ static boolean S_LoadMusic(const char *mname) static void S_UnloadMusic(void) { I_UnloadSong(); - music_name[0] = 0; + #ifndef HAVE_SDL //SDL uses RWOPS Z_ChangeTag(music_data, PU_CACHE); #endif music_data = NULL; + + music_name[0] = 0; music_flags = 0; music_looping = false; } @@ -1413,13 +1415,7 @@ void S_StopMusic(void) S_SpeedMusic(1.0f); I_StopSong(); - I_UnloadSong(); - -#ifndef HAVE_SDL //SDL uses RWOPS - Z_ChangeTag(music_data, PU_CACHE); -#endif - - music_name[0] = 0; + S_UnloadMusic(); // for now, stopping also means you unload the song } // diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index dd00d78f7..99a379ea2 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -484,19 +484,7 @@ FUNCMATH void I_InitMusic(void) void I_ShutdownMusic(void) { -#ifdef HAVE_LIBGME - if (gme) - { - Mix_HookMusic(NULL, NULL); - gme_delete(gme); - gme = NULL; - } -#endif - if (!music) - return; - Mix_HookMusicFinished(NULL); - Mix_FreeMusic(music); - music = NULL; + I_UnloadSong(); } /// ------------------------ @@ -565,10 +553,8 @@ boolean I_SetSongSpeed(float speed) boolean I_LoadSong(char *data, size_t len) { - I_Assert(!music); -#ifdef HAVE_LIBGME - I_Assert(!gme); -#endif + if (music || gme) + I_UnloadSong(); #ifdef HAVE_LIBGME if ((UINT8)data[0] == 0x1F @@ -710,11 +696,20 @@ boolean I_LoadSong(char *data, size_t len) void I_UnloadSong(void) { - // \todo unhook looper - //var_cleanup(); - //Mix_FreeMusic(music); - //music = NULL; I_StopSong(); + +#ifdef HAVE_LIBGME + if (gme) + { + gme_delete(gme); + gme = NULL; + } +#endif + if (music) + { + Mix_FreeMusic(music); + music = NULL; + } } boolean I_PlaySong(boolean looping) @@ -750,17 +745,14 @@ void I_StopSong(void) if (gme) { Mix_HookMusic(NULL, NULL); - gme_delete(gme); - gme = NULL; current_track = -1; - return; } #endif - if (!music) - return; - Mix_HookMusicFinished(NULL); - Mix_FreeMusic(music); - music = NULL; + if (music) + { + Mix_HookMusicFinished(NULL); + Mix_HaltMusic(); + } } void I_PauseSong(void) From 0999b0f8a8044eae0d8109ba3f0df102bb32c246 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 13:24:15 -0400 Subject: [PATCH 053/264] srb2dd music cleanup fixes --- src/win32/win_cd.c | 2 +- src/win32/win_snd.c | 76 +++++++++++++++++---------------------------- 2 files changed, 29 insertions(+), 49 deletions(-) diff --git a/src/win32/win_cd.c b/src/win32/win_cd.c index f6c430748..2586b8440 100644 --- a/src/win32/win_cd.c +++ b/src/win32/win_cd.c @@ -471,7 +471,7 @@ void I_PlayCD(UINT8 nTrack, UINT8 bLooping) //faB: stop MIDI music, MIDI music will restart if volume is upped later cv_digmusicvolume.value = 0; cv_midimusicvolume.value = 0; - I_StopSong (0); + I_StopSong(); //faB: I don't use the notify message, I'm trying to minimize the delay mciPlay.dwCallback = (DWORD)((size_t)hWndMain); diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index 2e05c4f72..36a5904a5 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -475,11 +475,11 @@ musictype_t I_SongType(void) return MU_WAV; case FMOD_SOUND_TYPE_MOD: return MU_MOD; - case FMOD_SOUND_TYPE_MID: + case FMOD_SOUND_TYPE_MIDI: return MU_MID; case FMOD_SOUND_TYPE_OGGVORBIS: return MU_OGG; - case FMOD_SOUND_TYPE_MP3: + case FMOD_SOUND_TYPE_MPEG: return MU_MP3; case FMOD_SOUND_TYPE_FLAC: return MU_FLAC; @@ -547,20 +547,13 @@ boolean I_SetSongSpeed(float speed) boolean I_LoadSong(char *data, size_t len) { - char *data; - size_t len; FMOD_CREATESOUNDEXINFO fmt; - lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname)); + FMOD_RESULT e; + FMOD_TAG tag; + unsigned int loopstart, loopend; - if (lumpnum == LUMPERROR) - { - lumpnum = W_CheckNumForName(va("D_%s",musicname)); - if (lumpnum == LUMPERROR) - return false; - } - - data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC); - len = W_LumpLength(lumpnum); + if (gme || music_stream) + I_UnloadSong(); memset(&fmt, 0, sizeof(FMOD_CREATESOUNDEXINFO)); fmt.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); @@ -595,8 +588,6 @@ boolean I_LoadSong(char *data, size_t len) gme_equalizer_t gmeq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around Z_Free(data); // We don't need this, either. - gme_start_track(gme, 0); - current_track = 0; gme_set_equalizer(gme,&gmeq); fmt.format = FMOD_SOUND_FORMAT_PCM16; fmt.defaultfrequency = 44100; @@ -605,10 +596,7 @@ boolean I_LoadSong(char *data, size_t len) fmt.decodebuffersize = (44100 * 2) / 35; fmt.pcmreadcallback = GMEReadCallback; fmt.userdata = gme; - FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER | (looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream)); - FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); - FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); - FMR(FMOD_Channel_SetPriority(music_channel, 0)); + FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER, &fmt, &music_stream)); return true; } } @@ -675,26 +663,24 @@ boolean I_LoadSong(char *data, size_t len) fmt.decodebuffersize = (44100 * 2) / 35; fmt.pcmreadcallback = GMEReadCallback; fmt.userdata = gme; + FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER, &fmt, &music_stream)); return true; } #endif fmt.length = len; - FMOD_RESULT e = FMOD_System_CreateStream(fsys, data, FMOD_OPENMEMORY_POINT|(looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream); + e = FMOD_System_CreateStream(fsys, data, FMOD_OPENMEMORY_POINT, &fmt, &music_stream); if (e != FMOD_OK) { if (e == FMOD_ERR_FORMAT) - CONS_Alert(CONS_WARNING, "Failed to play music lump %s due to invalid format.\n", W_CheckNameForNum(lumpnum)); + CONS_Alert(CONS_WARNING, "Failed to play music lump due to invalid format.\n"); else FMR(e); return false; } // Try to find a loop point in streaming music formats (ogg, mp3) - FMOD_RESULT e; - FMOD_TAG tag; - unsigned int loopstart, loopend; // A proper LOOPPOINT is its own tag, stupid. e = FMOD_Sound_GetTag(music_stream, "LOOPPOINT", 0, &tag); @@ -708,13 +694,6 @@ boolean I_LoadSong(char *data, size_t len) return true; } - // todo - // if(music type == MIDI) - // { - // FMR(FMOD_Sound_SetMode(music_stream, FMOD_LOOP_NORMAL)); - // return true; - // } - // Use LOOPMS for time in miliseconds. e = FMOD_Sound_GetTag(music_stream, "LOOPMS", 0, &tag); if (e != FMOD_ERR_TAGNOTFOUND) @@ -758,10 +737,19 @@ boolean I_LoadSong(char *data, size_t len) void I_UnloadSong(void) { - UNREFERENCED_PARAMETER(handle); + I_StopSong(); +#ifdef HAVE_LIBGME + if (gme) + { + gme_delete(gme); + gme = NULL; + } +#endif if (music_stream) + { FMR(FMOD_Sound_Release(music_stream)); - music_stream = NULL; + music_stream = NULL; + } } boolean I_PlaySong(boolean looping) @@ -771,7 +759,6 @@ boolean I_PlaySong(boolean looping) { gme_start_track(gme, 0); current_track = 0; - FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER | (looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream)); FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0)); FMR(FMOD_Channel_SetPriority(music_channel, 0)); @@ -779,6 +766,7 @@ boolean I_PlaySong(boolean looping) } #endif + FMR(FMOD_Sound_SetMode(music_stream, (looping ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF))); FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel)); if (I_SongType() != MU_MID) FMR(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0)); @@ -792,33 +780,25 @@ boolean I_PlaySong(boolean looping) void I_StopSong(void) { -#ifdef HAVE_LIBGME - if (gme) - gme_delete(gme); - gme = NULL; -#endif - current_track = -1; - - I_UnloadSong(); + if (music_channel) + FMR_MUSIC(FMOD_Channel_Stop(music_channel)); } void I_PauseSong(void) { - UNREFERENCED_PARAMETER(handle); - if (music_stream) + if (music_channel) FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, true)); } void I_ResumeSong(void) { - UNREFERENCED_PARAMETER(handle); - if (music_stream) + if (music_channel) FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, false)); } void I_SetMusicVolume(UINT8 volume) { - if (!music_stream) + if (!music_channel) return; // volume is 0 to 31. From cb4e075137857a391005cfb12c25b294c4e96031 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 13:36:01 -0400 Subject: [PATCH 054/264] I_InitMusic SDL2: Don't unload GME indiscriminately --- src/sdl/mixer_sound.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 99a379ea2..f39d375ef 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -476,10 +476,6 @@ static void mix_gme(void *udata, Uint8 *stream, int len) FUNCMATH void I_InitMusic(void) { -#ifdef HAVE_LIBGME - gme = NULL; - current_track = -1; -#endif } void I_ShutdownMusic(void) From 76be77b93a2a655cd28983c1709fe058c5878859 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 14:52:24 -0400 Subject: [PATCH 055/264] Rip out SDL Mixer code from sdl_sound.c because superfluous * Mixer code has been in mixer_sound.c; this file is not invoked unless compiling with NOMIXER=1 * Remove everything under #ifdef HAVE_MIXER because this is never triggered * Comment out #ifdef HAVE_LIBGME because we don't support playing music anyway (but theoretically, it could have worked separately from Mixer) * Stub new music calls --- src/sdl/sdl_sound.c | 611 +++----------------------------------------- 1 file changed, 42 insertions(+), 569 deletions(-) diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 887726ebb..e29ac080b 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -989,7 +989,7 @@ FUNCINLINE static ATTRINLINE void I_UpdateStream16M(Uint8 *stream, int len) if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); } -#ifdef HAVE_LIBGME +#if 0 //#ifdef HAVE_LIBGME static void I_UpdateSteamGME(Music_Emu *emu, INT16 *stream, int len, UINT8 looping) { #define GME_BUFFER_LEN 44100*2048 @@ -1049,14 +1049,16 @@ static void SDLCALL I_UpdateStream(void *userdata, Uint8 *stream, int len) else if (audio.channels == 2 && audio.format == AUDIO_S16SYS) { I_UpdateStream16S(stream, len); -#ifdef HAVE_LIBGME - if (userdata) - { - srb2audio_t *sa_userdata = userdata; - if (!sa_userdata->gme_pause) - I_UpdateSteamGME(sa_userdata->gme_emu, (INT16 *)stream, len/4, sa_userdata->gme_loop); - } -#endif + + // Crashes! But no matter; this build doesn't play music anyway... +// #ifdef HAVE_LIBGME +// if (userdata) +// { +// srb2audio_t *sa_userdata = userdata; +// if (!sa_userdata->gme_pause) +// I_UpdateSteamGME(sa_userdata->gme_emu, (INT16 *)stream, len/4, sa_userdata->gme_loop); +// } +// #endif } } @@ -1313,40 +1315,11 @@ void I_StartupSound(void) // MUSIC API. // -musictype_t I_SongType(void) -{ -#ifdef HAVE_MIXER -#ifdef HAVE_LIBGME - if (gme) - return MU_GME; - else -#endif - if (!music) - return MU_NONE; - else if (Mix_GetMusicType(music) == MUS_MID) - return MU_MID; - else if (Mix_GetMusicType(music) == MUS_MOD || Mix_GetMusicType(music) == MUS_MODPLUG_UNUSED) - return MU_MOD; - else if (Mix_GetMusicType(music) == MUS_MP3 || Mix_GetMusicType(music) == MUS_MP3_MAD_UNUSED) - return MU_MP3; - else - return (musictype_t)Mix_GetMusicType(music); -#else - return MU_NONE -#endif -} +/// ------------------------ +// MUSIC SYSTEM +/// ------------------------ -boolean I_SongPlaying(void) -{ - return music_started; -} - -boolean I_SongPaused(void) -{ - return Mix_PausedMusic(); -} - -#ifdef HAVE_LIBGME +#if 0 //#ifdef HAVE_LIBGME static void I_ShutdownGMEMusic(void) { Snd_LockAudio(); @@ -1357,235 +1330,14 @@ static void I_ShutdownGMEMusic(void) } #endif -#ifdef HAVE_MIXER -static boolean LoadSong(void *data, size_t lumplength, size_t selectpos) -{ - FILE *midfile; - const char *tempname; -#ifdef USE_RWOPS - if (canuseRW) - { - SDL_RWops *SDLRW; - void *olddata = Smidi[selectpos]; //quick shortcut to set - - Z_Free(olddata); //free old memory - Smidi[selectpos] = NULL; - - if (!data) - return olddata != NULL; //was there old data? - - SDLRW = SDL_RWFromConstMem(data, (int)lumplength); //new RWops from Z_zone - if (!SDLRW) //ERROR while making RWops! - { - CONS_Printf(M_GetText("Couldn't load music lump: %s\n"), SDL_GetError()); - Z_Free(data); - return false; - } - - music[selectpos] = Mix_LoadMUS_RW(SDLRW); // new Mix_Chuck from RWops - if (music[selectpos]) - Smidi[selectpos] = data; //all done - else //ERROR while making Mix_Chuck - { - CONS_Printf(M_GetText("Couldn't load music data: %s\n"), Mix_GetError()); - Z_Free(data); - SDL_RWclose(SDLRW); - Smidi[selectpos] = NULL; - } - return true; - } -#endif - tempname = va("%s/%s", MIDI_PATH, fmidi[selectpos]); - - if (!data) - { - if (FIL_FileExists(tempname)) - return unlink(tempname)+1; -#ifdef MIDI_PATH2 - else if (FIL_FileExists(tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos]))) - return unlink(tempname)+1; -#endif - else - return false; - } - - midfile = fopen(tempname, "wb"); - -#ifdef MIDI_PATH2 - if (!midfile) - { - tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos]); - midfile = fopen(tempname, "wb"); - } -#endif - - if (!midfile) - { - CONS_Printf(M_GetText("Couldn't open file %s to write music in\n"), tempname); - Z_Free(data); - return false; - } - - if (fwrite(data, lumplength, 1, midfile) == 0) - { - CONS_Printf(M_GetText("Couldn't write music into file %s because %s\n"), tempname, strerror(ferror(midfile))); - Z_Free(data); - fclose(midfile); - return false; - } - - fclose(midfile); - - Z_Free(data); - - music[selectpos] = Mix_LoadMUS(tempname); - if (!music[selectpos]) //ERROR while making Mix_Chuck - { - CONS_Printf(M_GetText("Couldn't load music file %s: %s\n"), tempname, Mix_GetError()); - return false; - } - return true; -} -#endif - -/// ------------------------ -// MUSIC SYSTEM -/// ------------------------ - void I_InitMusic(void) { -#ifdef HAVE_MIXER - char ad[100]; - SDL_version MIXcompiled; - const SDL_version *MIXlinked; -#ifdef MIXER_INIT - const int mixstart = MIX_INIT_OGG; - int mixflags; -#endif -#endif -#ifdef HAVE_LIBGME +#if 0 //#ifdef HAVE_LIBGME I_AddExitFunc(I_ShutdownGMEMusic); #endif - -#ifdef HAVE_MIXER - MIX_VERSION(&MIXcompiled) - MIXlinked = Mix_Linked_Version(); - I_OutputMsg("Compiled for SDL_mixer version: %d.%d.%d\n", - MIXcompiled.major, MIXcompiled.minor, MIXcompiled.patch); -#ifdef MIXER_POS - if (MIXlinked->major == 1 && MIXlinked->minor == 2 && MIXlinked->patch < 7) - canlooping = SDL_FALSE; -#endif -#ifdef USE_RWOPS - if (M_CheckParm("-noRW")) - canuseRW = SDL_FALSE; -#endif - I_OutputMsg("Linked with SDL_mixer version: %d.%d.%d\n", - MIXlinked->major, MIXlinked->minor, MIXlinked->patch); - if (audio.freq < 44100 && !M_CheckParm ("-freq")) //I want atleast 44Khz - { - audio.samples = (Uint16)(audio.samples*(INT32)(44100/audio.freq)); - audio.freq = 44100; //Alam: to keep it around the same XX ms - } - - if (sound_started -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) - { - I_OutputMsg("Temp Shutdown of SDL Audio System"); - SDL_CloseAudio(); - I_OutputMsg(" Done\n"); - } - - CONS_Printf("%s", M_GetText("I_InitMusic:")); - -#ifdef MIXER_INIT - mixflags = Mix_Init(mixstart); - if ((mixstart & MIX_INIT_FLAC) != (mixflags & MIX_INIT_FLAC)) - { - CONS_Printf("%s", M_GetText(" Unable to load FLAC support\n")); - } - if ((mixstart & MIX_INIT_MOD ) != (mixflags & MIX_INIT_MOD )) - { - CONS_Printf("%s", M_GetText(" Unable to load MOD support\n")); - } - if ((mixstart & MIX_INIT_MP3 ) != (mixflags & MIX_INIT_MP3 )) - { - CONS_Printf("%s", M_GetText(" Unable to load MP3 support\n")); - } - if ((mixstart & MIX_INIT_OGG ) != (mixflags & MIX_INIT_OGG )) - { - CONS_Printf("%s", M_GetText(" Unable to load OGG support\n")); - } -#endif - - if (Mix_OpenAudio(audio.freq, audio.format, audio.channels, audio.samples) < 0) //open_music(&audio) - { - CONS_Printf(M_GetText(" Unable to open music: %s\n"), Mix_GetError()); - midi_disabled = digital_disabled = true; - if (sound_started -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) - { - if (SDL_OpenAudio(&audio, NULL) < 0) //retry - { - CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n")); - sound_disabled = true; - sound_started = false; - } - else - { - CONS_Printf(M_GetText(" Starting with audio driver : %s\n"), SDL_AudioDriverName(ad, (int)sizeof ad)); - } - } - return; - } - else - CONS_Printf(M_GetText(" Starting up with audio driver : %s with SDL_Mixer\n"), SDL_AudioDriverName(ad, (int)sizeof ad)); - - samplecount = audio.samples; - CV_SetValue(&cv_samplerate, audio.freq); - if (sound_started -#ifdef HW3SOUND - && hws_mode == HWS_DEFAULT_MODE -#endif - ) - I_OutputMsg(" Reconfigured SDL Audio System"); - else I_OutputMsg(" Configured SDL_Mixer System"); - I_OutputMsg(" with %d samples/slice at %ikhz(%dms buffer)\n", samplecount, audio.freq/1000, (INT32) ((audio.samples * 1000.0f) / audio.freq)); - Mix_SetPostMix(audio.callback, audio.userdata); // after mixing music, add sound effects - Mix_Resume(-1); - CONS_Printf("%s", M_GetText("Music initialized\n")); - musicStarted = SDL_TRUE; - Msc_Mutex = SDL_CreateMutex(); -#endif } -void I_ShutdownMusic(void) -{ -#ifdef HAVE_MIXER - if ((midi_disabled && digital_disabled) || !musicStarted) - return; - - CONS_Printf("%s", M_GetText("I_ShutdownMusic: ")); - - I_UnloadSong(); - I_StopSong(); - Mix_CloseAudio(); -#ifdef MIX_INIT - Mix_Quit(); -#endif - CONS_Printf("%s", M_GetText("shut down\n")); - musicStarted = SDL_FALSE; - if (Msc_Mutex) - SDL_DestroyMutex(Msc_Mutex); - Msc_Mutex = NULL; -#endif -} +void I_ShutdownMusic(void) { } /// ------------------------ // MUSIC PROPERTIES @@ -1618,149 +1370,64 @@ boolean I_SetSongSpeed(float speed) /// ------------------------ // MUSIC PLAYBACK -// \todo Merge Digital and MIDI /// ------------------------ +#if 0 //#ifdef HAVE_LIBGME +static void I_StopGME(void) +{ + Snd_LockAudio(); + gme_seek(localdata.gme_emu, 0); + Snd_UnlockAudio(); +} + +static void I_PauseGME(void) +{ + localdata.gme_pause = true; +} + +static void I_ResumeGME(void) +{ + localdata.gme_pause = false; +} +#endif + boolean I_LoadSong(char *data, size_t len) { -#ifdef HAVE_MIXER - if (midi_disabled || !musicStarted) - return false; - - if (!LoadSong(data, len, 0)) - return false; - - if (music[0]) - return true; - - CONS_Printf(M_GetText("Couldn't load MIDI: %s\n"), Mix_GetError()); -#else - (void)len; - (void)data; -#endif return false; } -void I_UnloadSong(void) -{ -#ifdef HAVE_MIXER - - if (midi_disabled || !musicStarted) - return; - - Mix_HaltMusic(); - while (Mix_PlayingMusic()) - ; - - if (music[handle]) - Mix_FreeMusic(music[handle]); - music[handle] = NULL; - LoadSong(NULL, 0, handle); -#else - (void)handle; -#endif -} +void I_UnloadSong(void) { } boolean I_PlaySong(boolean looping) { -#ifdef HAVE_MIXER - if (!musicStarted || !music[handle]) - return false; - -#ifdef MIXER_POS - if (canlooping) - Mix_HookMusicFinished(NULL); -#endif - - if (Mix_FadeInMusic(music[handle], looping ? -1 : 0, MIDIfade) == -1) - CONS_Printf(M_GetText("Couldn't play song because %s\n"), Mix_GetError()); - else - { - Mix_VolumeMusic(musicvol); - return true; - } -#else (void)looping; -#endif return false; } void I_StopSong(void) { +#if 0 //#ifdef HAVE_LIBGME I_StopGME(); -#ifdef HAVE_MIXER - if (digital_disabled) - return; - -#ifdef MIXER_POS - if (canlooping) - Mix_HookMusicFinished(NULL); -#endif - - Mix_HaltMusic(); - while (Mix_PlayingMusic()) - ; - - if (music[1]) - Mix_FreeMusic(music[1]); - music[1] = NULL; - LoadSong(NULL, 0, 1); -} - -static void I_PauseGME(void) -{ -#ifdef HAVE_LIBGME - localdata.gme_pause = true; #endif } void I_PauseSong(void) { - (void)handle; +#if 0 //#ifdef HAVE_LIBGME I_PauseGME(); -#ifdef HAVE_MIXER - if ((midi_disabled && digital_disabled) || !musicStarted) - return; - - Mix_PauseMusic(); - //I_StopSong(handle); -#endif -} - -static void I_ResumeGME(void) -{ -#ifdef HAVE_LIBGME - localdata.gme_pause = false; #endif } void I_ResumeSong(void) { - (void)handle; +#if 0 I_ResumeGME(); -#ifdef HAVE_MIXER - if ((midi_disabled && digital_disabled) || !musicStarted) - return; - - Mix_VolumeMusic(musicvol); - Mix_ResumeMusic(); - //I_PlaySong(handle, true); #endif } void I_SetMusicVolume(UINT8 volume) { -#ifdef HAVE_MIXER - if ((midi_disabled && digital_disabled) || !musicStarted) - return; - - if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); - musicvol = volume * 2; - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); - Mix_VolumeMusic(musicvol); -#else (void)volume; -#endif } boolean I_SetSongTrack(int track) @@ -1775,16 +1442,14 @@ boolean I_SetSongTrack(int track) // then move to Playback section /// ------------------------ -#ifdef HAVE_LIBGME +#if 0 //#ifdef HAVE_LIBGME static void I_CleanupGME(void *userdata) { Z_Free(userdata); } -#endif static boolean I_StartGMESong(const char *musicname, boolean looping) { -#ifdef HAVE_LIBGME char filename[9]; void *data; lumpnum_t lumpnum; @@ -1830,199 +1495,7 @@ static boolean I_StartGMESong(const char *musicname, boolean looping) Snd_UnlockAudio(); return true; -#else - (void)musicname; - (void)looping; -#endif - return false; -} - -boolean I_StartDigSong(const char *musicname, boolean looping) -{ -#ifdef HAVE_MIXER - char filename[9]; - void *data; - lumpnum_t lumpnum; - size_t lumplength; -#endif - - if(I_StartGMESong(musicname, looping)) - return true; - -#ifdef HAVE_MIXER - if (digital_disabled) - return false; - - snprintf(filename, sizeof filename, "o_%s", musicname); - - lumpnum = W_CheckNumForName(filename); - - I_StopSong(); - - if (lumpnum == LUMPERROR) - { - // Alam_GBC: like in win32/win_snd.c: Graue 02-29-2004: don't worry about missing music, there might still be a MIDI - //I_OutputMsg("Music lump %s not found!\n", filename); - return false; // No music found. Oh well! - } - else - lumplength = W_LumpLength(lumpnum); - - data = W_CacheLumpNum(lumpnum, PU_MUSIC); - - if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); - -#ifdef MIXER_POS - if (canlooping && (loopingDig = looping) == SDL_TRUE && strcmp(data, "OggS") == 0) - looping = false; // Only on looping Ogg files, will we will do our own looping - - // Scan the Ogg Vorbis file for the COMMENT= field for a custom - // loop point - if (!looping && loopingDig) - { - size_t scan; - const char *dataum = data; - char looplength[64]; - UINT32 loopstart = 0; - UINT8 newcount = 0; - - Mix_HookMusicFinished(I_FinishMusic); - - for (scan = 0; scan < lumplength; scan++) - { - if (*dataum++ == 'C'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'M'){ - if (*dataum++ == 'M'){ - if (*dataum++ == 'E'){ - if (*dataum++ == 'N'){ - if (*dataum++ == 'T'){ - if (*dataum++ == '='){ - if (*dataum++ == 'L'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'P'){ - if (*dataum++ == 'P'){ - if (*dataum++ == 'O'){ - if (*dataum++ == 'I'){ - if (*dataum++ == 'N'){ - if (*dataum++ == 'T'){ - if (*dataum++ == '=') - { - - while (*dataum != 1 && newcount != 63) - looplength[newcount++] = *dataum++; - - looplength[newcount] = '\0'; - - loopstart = atoi(looplength); - - } - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - else - dataum--;} - } - - if (loopstart > 0) - { - loopstartDig = (double)((44.1l+loopstart) / 44100.0l); //8 PCM chucks off and PCM to secs -//#ifdef PARANOIA - //I_OutputMsg("I_StartDigSong: setting looping point to %ul PCMs(%f seconds)\n", loopstart, loopstartDig); -//#endif - } - else - { - looping = true; // loopingDig true, but couldn't find start loop point - } - } - else - loopstartDig = 0.0l; -#else - if (looping && strcmp(data, "OggS") == 0) - I_OutputMsg("I_StartDigSong: SRB2 was not compiled with looping music support(no Mix_FadeInMusicPos)\n"); -#endif - - if (!LoadSong(data, lumplength, 1)) - { - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); - return false; - } - - // Note: LoadSong() frees the data. Let's make sure - // we don't try to use the data again. - data = NULL; - - if (Mix_FadeInMusic(music[1], looping ? -1 : 0, Digfade) == -1) - { - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); - I_OutputMsg("I_StartDigSong: Couldn't play song %s because %s\n", musicname, Mix_GetError()); - return false; - } - Mix_VolumeMusic(musicvol); - - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); - return true; -#else - (void)looping; - (void)musicname; - return false; -#endif -} - -static void I_StopGME(void) -{ -#ifdef HAVE_LIBGME - Snd_LockAudio(); - gme_seek(localdata.gme_emu, 0); - Snd_UnlockAudio(); -#endif -} - -#ifdef MIXER_POS -static void SDLCALL I_FinishMusic(void) -{ - if (!music[1]) - return; - else if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); -// I_OutputMsg("I_FinishMusic: Loopping song to %g seconds\n", loopstartDig); - - if (Mix_FadeInMusicPos(music[1], loopstartDig ? 0 : -1, Digfade, loopstartDig) == 0) - Mix_VolumeMusic(musicvol); - else - I_OutputMsg("I_FinishMusic: Couldn't loop song because %s\n", Mix_GetError()); - - if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); } #endif + #endif //HAVE_SDL \ No newline at end of file From b330dc23946ecfae91301ababebbfddc97560c7e Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 16:39:10 -0400 Subject: [PATCH 056/264] Don't call I_StartupSound in SFX toggle * Mixer: make I_StartupSound return early if already set up * Restartaudio: Add StopSFX call --- src/d_netcmd.c | 1 + src/m_menu.c | 1 - src/sdl/mixer_sound.c | 5 ++++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ab3201c5c..a58aff3fe 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3955,6 +3955,7 @@ static void Command_RestartAudio_f(void) return; S_StopMusic(); + S_StopSounds(); I_ShutdownMusic(); I_ShutdownSound(); I_StartupSound(); diff --git a/src/m_menu.c b/src/m_menu.c index 63794c529..c9adbfb9c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6953,7 +6953,6 @@ static void M_ToggleSFX(void) if (sound_disabled) { sound_disabled = false; - I_StartupSound(); S_InitSfxChannels(cv_soundvolume.value); S_StartSound(NULL, sfx_strpst); M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING); diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index f39d375ef..72217482f 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -82,7 +82,10 @@ void I_StartupSound(void) // EE inits audio first so we're following along. if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO) - CONS_Printf("SDL Audio already started\n"); + { + CONS_Debug(DBG_DETAILED, "SDL Audio already started\n"); + return; + } else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError()); From fdbe3e80f6eac3659093a79f8dabfb92df0b1c10 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 17:07:13 -0400 Subject: [PATCH 057/264] Fix compile errors on buildbots * Check SDL Mixer 2.0.3 for MUS_MODPLUG_UNUSED, MUS_MP3_MAD_UNUSED * Mixed D+C in I_LoadSong --- src/sdl/mixer_sound.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 72217482f..d496aa666 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -501,9 +501,17 @@ musictype_t I_SongType(void) return MU_NONE; else if (Mix_GetMusicType(music) == MUS_MID) return MU_MID; - else if (Mix_GetMusicType(music) == MUS_MOD || Mix_GetMusicType(music) == MUS_MODPLUG_UNUSED) + else if (Mix_GetMusicType(music) == MUS_MOD +#if SDL_MIXER_VERSION_ATLEAST(2,0,3) + || Mix_GetMusicType(music) == MUS_MODPLUG_UNUSED +#endif + ) return MU_MOD; - else if (Mix_GetMusicType(music) == MUS_MP3 || Mix_GetMusicType(music) == MUS_MP3_MAD_UNUSED) + else if (Mix_GetMusicType(music) == MUS_MP3 +#if SDL_MIXER_VERSION_ATLEAST(2,0,3) + || Mix_GetMusicType(music) == MUS_MP3_MAD_UNUSED +#endif + ) return MU_MP3; else return (musictype_t)Mix_GetMusicType(music); @@ -552,6 +560,14 @@ boolean I_SetSongSpeed(float speed) boolean I_LoadSong(char *data, size_t len) { + const char *key1 = "LOOP"; + const char *key2 = "POINT="; + const char *key3 = "MS="; + const size_t key1len = strlen(key1); + const size_t key2len = strlen(key2); + const size_t key3len = strlen(key3); + char *p = data; + if (music || gme) I_UnloadSong(); @@ -660,13 +676,6 @@ boolean I_LoadSong(char *data, size_t len) // Find the OGG loop point. loop_point = 0.0f; - const char *key1 = "LOOP"; - const char *key2 = "POINT="; - const char *key3 = "MS="; - const size_t key1len = strlen(key1); - const size_t key2len = strlen(key2); - const size_t key3len = strlen(key3); - char *p = data; while ((UINT32)(p - data) < len) { if (strncmp(p++, key1, key1len)) From 17ec5d80220b472fe827e5e87b5c05f083a3cd24 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 17:27:00 -0400 Subject: [PATCH 058/264] Mixer: Better MODPLUG/MP3_MAD defines (cherry picked from commit 5b724e18b5268b0492b3f8b8980aadd2dd41e235) --- src/sdl/mixer_sound.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index d496aa666..e46da2755 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -34,6 +34,12 @@ (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) #endif +// thanks alam for making the buildbots happy! +#if SDL_MIXER_VERSION_ATLEAST(2,0,3) +#define MUS_MP3_MAD MUS_MP3_MAD_UNUSED +#define MUS_MODPLUG MUS_MODPLUG_UNUSED +#endif + #ifdef HAVE_LIBGME #include "gme/gme.h" #define GME_TREBLE 5.0 @@ -501,17 +507,9 @@ musictype_t I_SongType(void) return MU_NONE; else if (Mix_GetMusicType(music) == MUS_MID) return MU_MID; - else if (Mix_GetMusicType(music) == MUS_MOD -#if SDL_MIXER_VERSION_ATLEAST(2,0,3) - || Mix_GetMusicType(music) == MUS_MODPLUG_UNUSED -#endif - ) + else if (Mix_GetMusicType(music) == MUS_MOD || Mix_GetMusicType(music) == MUS_MODPLUG) return MU_MOD; - else if (Mix_GetMusicType(music) == MUS_MP3 -#if SDL_MIXER_VERSION_ATLEAST(2,0,3) - || Mix_GetMusicType(music) == MUS_MP3_MAD_UNUSED -#endif - ) + else if (Mix_GetMusicType(music) == MUS_MP3 || Mix_GetMusicType(music) == MUS_MP3_MAD) return MU_MP3; else return (musictype_t)Mix_GetMusicType(music); From 9a5eb024590d5b98afa878a6ebd49eef4fcb28ed Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 14 Sep 2018 17:47:04 -0400 Subject: [PATCH 059/264] Fix Windows buildbot for MP3_MAD/MODPLUG define (the header we use is 2.0.2) --- src/sdl/mixer_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index e46da2755..7d11c32c6 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -35,7 +35,7 @@ #endif // thanks alam for making the buildbots happy! -#if SDL_MIXER_VERSION_ATLEAST(2,0,3) +#if SDL_MIXER_VERSION_ATLEAST(2,0,2) #define MUS_MP3_MAD MUS_MP3_MAD_UNUSED #define MUS_MODPLUG MUS_MODPLUG_UNUSED #endif From 40a8c9c1ee4fc30e82a8ce3d84d309152a07a5a2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 15 Sep 2018 00:34:55 -0400 Subject: [PATCH 060/264] Mixer: HAVE_LIBGME ifdef in I_LoadSong --- src/sdl/mixer_sound.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 7d11c32c6..87f8fd671 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -566,7 +566,11 @@ boolean I_LoadSong(char *data, size_t len) const size_t key3len = strlen(key3); char *p = data; - if (music || gme) + if (music +#ifdef HAVE_LIBGME + || gme +#endif + ) I_UnloadSong(); #ifdef HAVE_LIBGME From 1b7b1f3f796eb08385f86e817b4486ec3a25361a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 16 Sep 2018 20:25:07 +0100 Subject: [PATCH 061/264] Fix order of operations messups by adding brackets --- src/m_anigif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index d46d889bb..e2af70095 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -492,7 +492,7 @@ static void GIF_framewrite(void) // screen regions are handled in GIF_lzw { - int d1 = (int)((100.0/NEWTICRATE)*gif_frames+1); + int d1 = (int)((100.0/NEWTICRATE)*(gif_frames+1)); int d2 = (int)((100.0/NEWTICRATE)*(gif_frames)); UINT16 delay = d1-d2; INT32 startline; From 34e403afcb501ae5e456dc292b8a3632a7e5fab9 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 18 Sep 2018 08:32:34 -0400 Subject: [PATCH 062/264] S_ChangeMusic: More specific load/play fail messages --- src/s_sound.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/s_sound.c b/src/s_sound.c index 2b8e8e721..ea129a109 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1391,14 +1391,17 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) S_StopMusic(); // shutdown old music if (!S_LoadMusic(mmusic)) + { + CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded!\n", mmusic); return; + } music_flags = mflags; music_looping = looping; if (!S_PlayMusic(looping)) { - CONS_Alert(CONS_ERROR, "Music cannot be played!\n"); + CONS_Alert(CONS_ERROR, "Music %.6s could not be played!\n", mmusic); return; } } From 24938473a5ae66616b17c9c8d3e4b8c0a7961775 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 19 Sep 2018 17:49:03 -0400 Subject: [PATCH 063/264] Linedef exec FOF specials: Move logic into for (rover =...) block so procedure happens on every FOF match --- src/p_spec.c | 238 +++++++++++++++++++++++++++------------------------ 1 file changed, 125 insertions(+), 113 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index d152b59c1..e63ec4a92 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3090,7 +3090,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover; // FOF that we are going to crumble + ffloor_t *rover, *foundrover; // FOF that we are going to crumble for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -3105,16 +3105,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) for (rover = sec->ffloors; rover; rover = rover->next) { if (rover->master->frontsector->tag == foftag) - break; + { + foundrover = rover; // for debug, "Can't find a FOF" message below + + EV_CrumbleChain(sec, rover); + } } - if (!rover) + if (!foundrover) { CONS_Debug(DBG_GAMELOGIC, "Line type 436 Executor: Can't find a FOF control sector with tag %d\n", foftag); return; } - - EV_CrumbleChain(sec, rover); } } break; @@ -3274,7 +3276,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible (or not visible) in - ffloor_t *rover; // FOF to vanish/un-vanish + ffloor_t *rover, *foundrover; // FOF to vanish/un-vanish ffloortype_e oldflags; // store FOF's old flags for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) @@ -3290,26 +3292,28 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) for (rover = sec->ffloors; rover; rover = rover->next) { if (rover->master->frontsector->tag == foftag) - break; + { + foundrover = rover; // for debug, "Can't find a FOF" message below + + oldflags = rover->flags; + + // Abracadabra! + if (line->flags & ML_NOCLIMB) + rover->flags |= FF_EXISTS; + else + rover->flags &= ~FF_EXISTS; + + // if flags changed, reset sector's light list + if (rover->flags != oldflags) + sec->moved = true; + } } - if (!rover) + if (!foundrover) { CONS_Debug(DBG_GAMELOGIC, "Line type 445 Executor: Can't find a FOF control sector with tag %d\n", foftag); return; } - - oldflags = rover->flags; - - // Abracadabra! - if (line->flags & ML_NOCLIMB) - rover->flags |= FF_EXISTS; - else - rover->flags &= ~FF_EXISTS; - - // if flags changed, reset sector's light list - if (rover->flags != oldflags) - sec->moved = true; } } break; @@ -3319,7 +3323,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover; // FOF that we are going to make fall down + ffloor_t *rover, *foundrover; // FOF that we are going to make fall down player_t *player = NULL; // player that caused FOF to fall boolean respawn = true; // should the fallen FOF respawn? @@ -3342,19 +3346,21 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) for (rover = sec->ffloors; rover; rover = rover->next) { if (rover->master->frontsector->tag == foftag) - break; + { + foundrover = rover; // for debug, "Can't find a FOF" message below + + if (line->flags & ML_BLOCKMONSTERS) // FOF flags determine respawn ability instead? + respawn = !(rover->flags & FF_NORETURN) ^ !!(line->flags & ML_NOCLIMB); // no climb inverts + + EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, respawn); + } } - if (!rover) + if (!foundrover) { CONS_Debug(DBG_GAMELOGIC, "Line type 446 Executor: Can't find a FOF control sector with tag %d\n", foftag); return; } - - if (line->flags & ML_BLOCKMONSTERS) // FOF flags determine respawn ability instead? - respawn = !(rover->flags & FF_NORETURN) ^ !!(line->flags & ML_NOCLIMB); // no climb inverts - - EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, respawn); } } break; @@ -3486,7 +3492,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover; // FOF that we are going to operate + ffloor_t *rover, *foundrover; // FOF that we are going to operate for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -3501,38 +3507,40 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) for (rover = sec->ffloors; rover; rover = rover->next) { if (rover->master->frontsector->tag == foftag) - break; + { + foundrover = rover; // for debug, "Can't find a FOF" message below + + // If fading an invisible FOF whose render flags we did not yet set, + // initialize its alpha to 1 + // for relative alpha calc + if (!(line->flags & ML_NOCLIMB) && // do translucent + (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE + !(rover->spawnflags & FF_RENDERSIDES) && + !(rover->spawnflags & FF_RENDERPLANES) && + !(rover->flags & FF_RENDERALL)) + rover->alpha = 1; + + P_RemoveFakeFloorFader(rover); + P_FadeFakeFloor(rover, + rover->alpha, + max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)), + 0, // set alpha immediately + false, NULL, // tic-based logic + false, // do not handle FF_EXISTS + !(line->flags & ML_NOCLIMB), // handle FF_TRANSLUCENT + false, // do not handle lighting + false, // do not handle colormap + false, // do not handle collision + false, // do not do ghost fade (no collision during fade) + true); // use exact alpha values (for opengl) + } } - if (!rover) + if (!foundrover) { CONS_Debug(DBG_GAMELOGIC, "Line type 452 Executor: Can't find a FOF control sector with tag %d\n", foftag); return; } - - // If fading an invisible FOF whose render flags we did not yet set, - // initialize its alpha to 1 - // for relative alpha calc - if (!(line->flags & ML_NOCLIMB) && // do translucent - (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE - !(rover->spawnflags & FF_RENDERSIDES) && - !(rover->spawnflags & FF_RENDERPLANES) && - !(rover->flags & FF_RENDERALL)) - rover->alpha = 1; - - P_RemoveFakeFloorFader(rover); - P_FadeFakeFloor(rover, - rover->alpha, - max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)), - 0, // set alpha immediately - false, NULL, // tic-based logic - false, // do not handle FF_EXISTS - !(line->flags & ML_NOCLIMB), // handle FF_TRANSLUCENT - false, // do not handle lighting - false, // do not handle colormap - false, // do not handle collision - false, // do not do ghost fade (no collision during fade) - true); // use exact alpha values (for opengl) } break; } @@ -3546,7 +3554,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover; // FOF that we are going to operate + ffloor_t *rover, *foundrover; // FOF that we are going to operate size_t j = 0; // sec->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) @@ -3562,64 +3570,66 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) for (rover = sec->ffloors; rover; rover = rover->next) { if (rover->master->frontsector->tag == foftag) - break; + { + foundrover = rover; // for debug, "Can't find a FOF" message below + + // Prevent continuous execs from interfering on an existing fade + if (!(line->flags & ML_EFFECT5) + && rover->fadingdata) + //&& ((fade_t*)rover->fadingdata)->timer > (ticbased ? 2 : speed*2)) + { + CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Fade FOF thinker already exists, timer: %d\n", ((fade_t*)rover->fadingdata)->timer); + continue; + } + + if (speed > 0) + P_AddFakeFloorFader(rover, secnum, j, + destvalue, + speed, + (line->flags & ML_EFFECT4), // tic-based logic + (line->flags & ML_EFFECT3), // Relative destvalue + !(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS + !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT + !(line->flags & ML_EFFECT2), // do not handle lighting + !(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags) + !(line->flags & ML_BOUNCY), // do not handle collision + (line->flags & ML_EFFECT1), // do ghost fade (no collision during fade) + (line->flags & ML_TFERLINE)); // use exact alpha values (for opengl) + else + { + // If fading an invisible FOF whose render flags we did not yet set, + // initialize its alpha to 1 + // for relative alpha calc + if (!(line->flags & ML_NOCLIMB) && // do translucent + (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE + !(rover->spawnflags & FF_RENDERSIDES) && + !(rover->spawnflags & FF_RENDERPLANES) && + !(rover->flags & FF_RENDERALL)) + rover->alpha = 1; + + P_RemoveFakeFloorFader(rover); + P_FadeFakeFloor(rover, + rover->alpha, + max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)), + 0, // set alpha immediately + false, NULL, // tic-based logic + !(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS + !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT + !(line->flags & ML_EFFECT2), // do not handle lighting + !(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags) + !(line->flags & ML_BOUNCY), // do not handle collision + (line->flags & ML_EFFECT1), // do ghost fade (no collision during fade) + (line->flags & ML_TFERLINE)); // use exact alpha values (for opengl) + } + } j++; } - if (!rover) + if (!foundrover) { CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Can't find a FOF control sector with tag %d\n", foftag); return; } - - // Prevent continuous execs from interfering on an existing fade - if (!(line->flags & ML_EFFECT5) - && rover->fadingdata) - //&& ((fade_t*)rover->fadingdata)->timer > (ticbased ? 2 : speed*2)) - { - CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Fade FOF thinker already exists, timer: %d\n", ((fade_t*)rover->fadingdata)->timer); - continue; - } - - if (speed > 0) - P_AddFakeFloorFader(rover, secnum, j, - destvalue, - speed, - (line->flags & ML_EFFECT4), // tic-based logic - (line->flags & ML_EFFECT3), // Relative destvalue - !(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS - !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT - !(line->flags & ML_EFFECT2), // do not handle lighting - !(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags) - !(line->flags & ML_BOUNCY), // do not handle collision - (line->flags & ML_EFFECT1), // do ghost fade (no collision during fade) - (line->flags & ML_TFERLINE)); // use exact alpha values (for opengl) - else - { - // If fading an invisible FOF whose render flags we did not yet set, - // initialize its alpha to 1 - // for relative alpha calc - if (!(line->flags & ML_NOCLIMB) && // do translucent - (rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE - !(rover->spawnflags & FF_RENDERSIDES) && - !(rover->spawnflags & FF_RENDERPLANES) && - !(rover->flags & FF_RENDERALL)) - rover->alpha = 1; - - P_RemoveFakeFloorFader(rover); - P_FadeFakeFloor(rover, - rover->alpha, - max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)), - 0, // set alpha immediately - false, NULL, // tic-based logic - !(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS - !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT - !(line->flags & ML_EFFECT2), // do not handle lighting - !(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags) - !(line->flags & ML_BOUNCY), // do not handle collision - (line->flags & ML_EFFECT1), // do ghost fade (no collision during fade) - (line->flags & ML_TFERLINE)); // use exact alpha values (for opengl) - } } break; } @@ -3629,7 +3639,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover; // FOF that we are going to operate + ffloor_t *rover, *foundrover; // FOF that we are going to operate for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -3644,17 +3654,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) for (rover = sec->ffloors; rover; rover = rover->next) { if (rover->master->frontsector->tag == foftag) - break; + { + foundrover = rover; // for debug, "Can't find a FOF" message below + + P_ResetFakeFloorFader(rover, NULL, + !(line->flags & ML_BLOCKMONSTERS)); // do not finalize collision flags + } } - if (!rover) + if (!foundrover) { CONS_Debug(DBG_GAMELOGIC, "Line type 454 Executor: Can't find a FOF control sector with tag %d\n", foftag); return; } - - P_ResetFakeFloorFader(rover, NULL, - !(line->flags & ML_BLOCKMONSTERS)); // do not finalize collision flags } break; } From 5e1b4272c1c835b2d6cb074b5c00acc2dd26a5bb Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 19 Sep 2018 17:50:05 -0400 Subject: [PATCH 064/264] Initialize foundrover to NULL (for debug checking) --- src/p_spec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index e63ec4a92..dfc75a4e3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3090,7 +3090,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover; // FOF that we are going to crumble + ffloor_t *rover, *foundrover = NULL; // FOF that we are going to crumble for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -3276,7 +3276,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible (or not visible) in - ffloor_t *rover, *foundrover; // FOF to vanish/un-vanish + ffloor_t *rover, *foundrover = NULL; // FOF to vanish/un-vanish ffloortype_e oldflags; // store FOF's old flags for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) @@ -3323,7 +3323,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover; // FOF that we are going to make fall down + ffloor_t *rover, *foundrover = NULL; // FOF that we are going to make fall down player_t *player = NULL; // player that caused FOF to fall boolean respawn = true; // should the fallen FOF respawn? @@ -3492,7 +3492,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover; // FOF that we are going to operate + ffloor_t *rover, *foundrover = NULL; // FOF that we are going to operate for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -3554,7 +3554,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover; // FOF that we are going to operate + ffloor_t *rover, *foundrover = NULL; // FOF that we are going to operate size_t j = 0; // sec->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) @@ -3639,7 +3639,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover; // FOF that we are going to operate + ffloor_t *rover, *foundrover = NULL; // FOF that we are going to operate for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { From 31343be41be36f219630ff02001750ed9b6b3c51 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 19 Sep 2018 20:11:30 -0400 Subject: [PATCH 065/264] foundrover ffloor_t -> boolean --- src/p_spec.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index dfc75a4e3..2f6558175 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3090,7 +3090,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover = NULL; // FOF that we are going to crumble + ffloor_t *rover; // FOF that we are going to crumble + boolean foundrover = false; // for debug, "Can't find a FOF" message for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -3106,7 +3107,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { if (rover->master->frontsector->tag == foftag) { - foundrover = rover; // for debug, "Can't find a FOF" message below + foundrover = true; EV_CrumbleChain(sec, rover); } @@ -3276,7 +3277,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible (or not visible) in - ffloor_t *rover, *foundrover = NULL; // FOF to vanish/un-vanish + ffloor_t *rover; // FOF to vanish/un-vanish + boolean foundrover = false; // for debug, "Can't find a FOF" message ffloortype_e oldflags; // store FOF's old flags for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) @@ -3293,7 +3295,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { if (rover->master->frontsector->tag == foftag) { - foundrover = rover; // for debug, "Can't find a FOF" message below + foundrover = true; oldflags = rover->flags; @@ -3323,7 +3325,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover = NULL; // FOF that we are going to make fall down + ffloor_t *rover; // FOF that we are going to make fall down + boolean foundrover = false; // for debug, "Can't find a FOF" message player_t *player = NULL; // player that caused FOF to fall boolean respawn = true; // should the fallen FOF respawn? @@ -3347,7 +3350,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { if (rover->master->frontsector->tag == foftag) { - foundrover = rover; // for debug, "Can't find a FOF" message below + foundrover = true; if (line->flags & ML_BLOCKMONSTERS) // FOF flags determine respawn ability instead? respawn = !(rover->flags & FF_NORETURN) ^ !!(line->flags & ML_NOCLIMB); // no climb inverts @@ -3492,7 +3495,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover = NULL; // FOF that we are going to operate + ffloor_t *rover; // FOF that we are going to operate + boolean foundrover = false; // for debug, "Can't find a FOF" message for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -3508,7 +3512,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { if (rover->master->frontsector->tag == foftag) { - foundrover = rover; // for debug, "Can't find a FOF" message below + foundrover = true; // If fading an invisible FOF whose render flags we did not yet set, // initialize its alpha to 1 @@ -3554,7 +3558,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover = NULL; // FOF that we are going to operate + ffloor_t *rover; // FOF that we are going to operate + boolean foundrover = false; // for debug, "Can't find a FOF" message size_t j = 0; // sec->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) @@ -3571,7 +3576,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { if (rover->master->frontsector->tag == foftag) { - foundrover = rover; // for debug, "Can't find a FOF" message below + foundrover = true; // Prevent continuous execs from interfering on an existing fade if (!(line->flags & ML_EFFECT5) @@ -3639,7 +3644,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in - ffloor_t *rover, *foundrover = NULL; // FOF that we are going to operate + ffloor_t *rover; // FOF that we are going to operate + boolean foundrover = false; // for debug, "Can't find a FOF" message for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -3655,7 +3661,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { if (rover->master->frontsector->tag == foftag) { - foundrover = rover; // for debug, "Can't find a FOF" message below + foundrover = true; P_ResetFakeFloorFader(rover, NULL, !(line->flags & ML_BLOCKMONSTERS)); // do not finalize collision flags From a53f036149a4ff1d7c9371f9f082fbfe5b65a5b7 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 20 Sep 2018 18:26:59 -0400 Subject: [PATCH 066/264] Use MemAvailable instead --- src/sdl/i_system.c | 49 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index e86a39cab..984f6dd22 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -124,6 +124,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include "macosx/mac_resources.h" #endif +#ifndef errno +#include +#endif + // Locations for searching the srb2.srb #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" @@ -2712,9 +2716,31 @@ const char *I_LocateWad(void) #ifdef __linux__ #define MEMINFO_FILE "/proc/meminfo" #define MEMTOTAL "MemTotal:" +#define MEMAVAILABLE "MemAvailable:" #define MEMFREE "MemFree:" +#define CACHED "Cached:" +#define BUFFERS "Buffers:" +#define SHMEM "Shmem:" #endif +/* Parse the contents of /proc/meminfo (in buf), return value of "name" + * (example: MemTotal) */ +static long get_entry(const char* name, const char* buf) +{ + char* hit = strstr(buf, name); + if (hit == NULL) { + return -1; + } + + errno = 0; + long val = strtol(hit + strlen(name), NULL, 10); + if (errno != 0) { + CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno)); + return -1; + } + return val; +} + // quick fix for compil UINT32 I_GetFreeMem(UINT32 *total) { @@ -2809,7 +2835,17 @@ UINT32 I_GetFreeMem(UINT32 *total) memTag += sizeof (MEMTOTAL); totalKBytes = atoi(memTag); - if ((memTag = strstr(buf, MEMFREE)) == NULL) + if ((memTag = strstr(buf, MEMAVAILABLE)) == NULL) + { + Cached = get_entry(CACHED, buf); + MemFree = get_entry(MEMFREE, buf); + Buffers = get_entry(BUFFERS, buf); + Shmem = get_entry(SHMEM, buf); + MemAvailable = Cached + MemFree + Buffers - Shmem; + guessed = true; + } + + if (MemAvailable == -1 && guessed) { // Error if (total) @@ -2817,8 +2853,15 @@ UINT32 I_GetFreeMem(UINT32 *total) return 0; } - memTag += sizeof (MEMFREE); - freeKBytes = atoi(memTag); + if (guessed) + { + freeKBytes = MemAvailable; + } + else + { + memTag += sizeof (MEMAVAILABLE); + freeKBytes = atoi(memTag); + } if (total) *total = totalKBytes << 10; From 378495cb2b8337c37b6bfefc3f510cf9b6117e61 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 20 Sep 2018 18:33:50 -0400 Subject: [PATCH 067/264] Add some stuff --- src/sdl/i_system.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 984f6dd22..3610a534d 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2810,6 +2810,12 @@ UINT32 I_GetFreeMem(UINT32 *total) UINT32 totalKBytes; INT32 n; INT32 meminfo_fd = -1; + long Cached; + long MemFree; + long Buffers; + long Shmem; + long MemAvailable = -1; + boolean guessed = false; // Stupid way to verify if the amount was guessed or not. meminfo_fd = open(MEMINFO_FILE, O_RDONLY); n = read(meminfo_fd, buf, 1023); From be74b4e58b93974bc56a7f96f3f175b541b04230 Mon Sep 17 00:00:00 2001 From: Steel Date: Fri, 21 Sep 2018 07:16:54 -0400 Subject: [PATCH 068/264] Fix up errors with buildbots --- src/sdl/i_system.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 3610a534d..e9e1ae92d 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1,6 +1,6 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- -// +- // // Copyright (C) 1993-1996 by id Software, Inc. // Portions Copyright (C) 1998-2000 by DooM Legacy Team. // @@ -2095,7 +2095,6 @@ INT32 I_StartupSystem(void) return 0; } - // // I_Quit // @@ -2721,25 +2720,26 @@ const char *I_LocateWad(void) #define CACHED "Cached:" #define BUFFERS "Buffers:" #define SHMEM "Shmem:" -#endif /* Parse the contents of /proc/meminfo (in buf), return value of "name" * (example: MemTotal) */ static long get_entry(const char* name, const char* buf) { + long val; char* hit = strstr(buf, name); if (hit == NULL) { return -1; } errno = 0; - long val = strtol(hit + strlen(name), NULL, 10); + val = strtol(hit + strlen(name), NULL, 10); if (errno != 0) { CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno)); return -1; } return val; } +#endif // quick fix for compil UINT32 I_GetFreeMem(UINT32 *total) From af58ba9ae3fa661ea406bca3b134ae2ac6b76a2c Mon Sep 17 00:00:00 2001 From: Steel Date: Fri, 21 Sep 2018 07:21:49 -0400 Subject: [PATCH 069/264] Remove this that somehow slipped in. --- src/sdl/i_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index e9e1ae92d..b7326b066 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1,6 +1,6 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- -- // +// // Copyright (C) 1993-1996 by id Software, Inc. // Portions Copyright (C) 1998-2000 by DooM Legacy Team. // From 68ec8119096c3744e25115337fd03ea3e124df2a Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 21 Sep 2018 11:26:08 -0400 Subject: [PATCH 070/264] Rearrange the code. Thanks again MonsterIestyn! --- src/sdl/i_system.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index b7326b066..05d9e092f 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2815,7 +2815,6 @@ UINT32 I_GetFreeMem(UINT32 *total) long Buffers; long Shmem; long MemAvailable = -1; - boolean guessed = false; // Stupid way to verify if the amount was guessed or not. meminfo_fd = open(MEMINFO_FILE, O_RDONLY); n = read(meminfo_fd, buf, 1023); @@ -2848,26 +2847,21 @@ UINT32 I_GetFreeMem(UINT32 *total) Buffers = get_entry(BUFFERS, buf); Shmem = get_entry(SHMEM, buf); MemAvailable = Cached + MemFree + Buffers - Shmem; - guessed = true; - } - if (MemAvailable == -1 && guessed) - { - // Error - if (total) - *total = 0L; - return 0; - } - - if (guessed) - { + if (MemAvailable == -1) + { + // Error + if (total) + *total = 0L; + return 0; + } freeKBytes = MemAvailable; - } - else - { + } + else + { memTag += sizeof (MEMAVAILABLE); freeKBytes = atoi(memTag); - } + } if (total) *total = totalKBytes << 10; From f88708bb75810e5ef089b5cf5246d3a2f9154d02 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 21 Sep 2018 12:05:52 -0400 Subject: [PATCH 071/264] Fix the weird indentation --- src/sdl/i_system.c | 76 +++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 05d9e092f..f92cd4b6e 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1683,7 +1683,7 @@ static void I_ShutdownMouse2(void) EscapeCommFunction(mouse2filehandle, CLRRTS); PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT | - PURGE_TXCLEAR | PURGE_RXCLEAR); + PURGE_TXCLEAR | PURGE_RXCLEAR); CloseHandle(mouse2filehandle); @@ -1876,11 +1876,11 @@ void I_StartupMouse2(void) { // COM file handle mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ | GENERIC_WRITE, - 0, // exclusive access - NULL, // no security attrs - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); + 0, // exclusive access + NULL, // no security attrs + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); if (mouse2filehandle == INVALID_HANDLE_VALUE) { INT32 e = GetLastError(); @@ -1900,7 +1900,7 @@ void I_StartupMouse2(void) // purge buffers PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT - | PURGE_TXCLEAR | PURGE_RXCLEAR); + | PURGE_TXCLEAR | PURGE_RXCLEAR); // setup port to 1200 7N1 dcb.DCBlength = sizeof (DCB); @@ -2029,7 +2029,7 @@ static void I_ShutdownTimer(void) tic_t I_GetTime (void) { static Uint32 basetime = 0; - Uint32 ticks = SDL_GetTicks(); + Uint32 ticks = SDL_GetTicks(); if (!basetime) basetime = ticks; @@ -2373,7 +2373,7 @@ void I_GetDiskFreeSpace(INT64 *freespace) { DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters; GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, - &NumberOfFreeClusters, &TotalNumberOfClusters); + &NumberOfFreeClusters, &TotalNumberOfClusters); *freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters; } #else // Dummy for platform independent; 1GB should be enough @@ -2595,22 +2595,22 @@ static const char *locateWad(void) #ifdef CMAKECONFIG #ifndef NDEBUG - I_OutputMsg(","CMAKE_ASSETS_DIR); - strcpy(returnWadPath, CMAKE_ASSETS_DIR); - if (isWadPathOk(returnWadPath)) - { - return returnWadPath; - } + I_OutputMsg(","CMAKE_ASSETS_DIR); + strcpy(returnWadPath, CMAKE_ASSETS_DIR); + if (isWadPathOk(returnWadPath)) + { + return returnWadPath; + } #endif #endif #ifdef __APPLE__ - OSX_GetResourcesPath(returnWadPath); - I_OutputMsg(",%s", returnWadPath); - if (isWadPathOk(returnWadPath)) - { - return returnWadPath; - } + OSX_GetResourcesPath(returnWadPath); + I_OutputMsg(",%s", returnWadPath); + if (isWadPathOk(returnWadPath)) + { + return returnWadPath; + } #endif // examine default dirs @@ -2725,19 +2725,19 @@ const char *I_LocateWad(void) * (example: MemTotal) */ static long get_entry(const char* name, const char* buf) { - long val; - char* hit = strstr(buf, name); - if (hit == NULL) { - return -1; - } + long val; + char* hit = strstr(buf, name); + if (hit == NULL) { + return -1; + } - errno = 0; - val = strtol(hit + strlen(name), NULL, 10); - if (errno != 0) { - CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno)); - return -1; - } - return val; + errno = 0; + val = strtol(hit + strlen(name), NULL, 10); + if (errno != 0) { + CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno)); + return -1; + } + return val; } #endif @@ -2850,18 +2850,18 @@ UINT32 I_GetFreeMem(UINT32 *total) if (MemAvailable == -1) { - // Error + // Error if (total) *total = 0L; return 0; } freeKBytes = MemAvailable; - } - else - { + } + else + { memTag += sizeof (MEMAVAILABLE); freeKBytes = atoi(memTag); - } + } if (total) *total = totalKBytes << 10; From 872e2f82c154359ac5f8e33e5c9ffeeef5a84017 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 28 Sep 2018 17:02:02 +0100 Subject: [PATCH 072/264] Redo OpenGL skewing support, so that it now itself supports the lower unpegged effect for FOFs in OpenGL! --- src/hardware/hw_main.c | 46 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d7c73415a..92925c9bf 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2183,6 +2183,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) else if (drawtextured) { fixed_t texturevpeg; + boolean attachtobottom = false; +#ifdef ESLOPE + boolean slopeskew = false; // skew FOF walls with slopes? +#endif // Wow, how was this missing from OpenGL for so long? // ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software @@ -2190,24 +2194,50 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (newline) { texturevpeg = sides[newline->sidenum[0]].rowoffset; - if (newline->flags & ML_DONTPEGBOTTOM) - texturevpeg -= *rover->topheight - *rover->bottomheight; + attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM); +#ifdef ESLOPE + slopeskew = !!(newline->flags & ML_DONTPEGTOP); +#endif } else { texturevpeg = sides[rover->master->sidenum[0]].rowoffset; - if (gr_linedef->flags & ML_DONTPEGBOTTOM) - texturevpeg -= *rover->topheight - *rover->bottomheight; + attachtobottom = !!(gr_linedef->flags & ML_DONTPEGBOTTOM); +#ifdef ESLOPE + slopeskew = !!(rover->master->flags & ML_DONTPEGTOP); +#endif } grTex = HWR_GetTexture(texnum); #ifdef ESLOPE - wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY; - wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY; - wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY; - wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY; + if (!slopeskew) // no skewing + { + if (attachtobottom) + texturevpeg -= *rover->topheight - *rover->bottomheight; + wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY; + wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY; + wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY; + wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY; + } + else + { + if (!attachtobottom) // skew by top + { + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; + wallVerts[1].t = (hS - lS + texturevpeg) * grTex->scaleY; + } + else // skew by bottom + { + wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY; + wallVerts[3].t = wallVerts[0].t - (h - l) * grTex->scaleY; + wallVerts[2].t = wallVerts[1].t - (hS - lS) * grTex->scaleY; + } + } #else + if (attachtobottom) + texturevpeg -= *rover->topheight - *rover->bottomheight; wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY; #endif From 800b3bb2407f793730b88f2b6c70c583f3a2f8a8 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 30 Sep 2018 22:18:48 +0100 Subject: [PATCH 073/264] Move player + player mobj existence checks to top of P_MoveChaseCamera. This is the only place it makes sense to even check them tbh. While I'm at it, let's also use the "mo" variable instead of player->mo throughout the function (to be consistent) --- src/p_user.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index da8e19caa..91b5feb85 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7853,7 +7853,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall subsector_t *newsubsec; fixed_t f1, f2; - cameranoclip = (player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) || (player->mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!! + // We probably shouldn't move the camera if there is no player or player mobj somehow + if (!player || !player->mo) + return true; + + mo = player->mo; + + cameranoclip = (player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!! if (!(player->climbing || (player->pflags & PF_NIGHTSMODE) || player->playerstate == PST_DEAD)) { @@ -7874,7 +7880,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall else if (player == &players[secondarydisplayplayer]) focusangle = localangle2; else - focusangle = player->mo->angle; + focusangle = mo->angle; if (thiscam == &camera) camrotate = cv_cam_rotate.value; else if (thiscam == &camera2) @@ -7886,17 +7892,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall return true; } - if (!player || !player->mo) - return true; - - mo = player->mo; - thiscam->radius = FixedMul(20*FRACUNIT, mo->scale); thiscam->height = FixedMul(16*FRACUNIT, mo->scale); - if (!mo) - return true; - // Don't run while respawning from a starpost // Inu 4/8/13 Why not?! // if (leveltime > 0 && timeinmap <= 0) @@ -7904,7 +7902,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player->pflags & PF_NIGHTSMODE) { - focusangle = player->mo->angle; + focusangle = mo->angle; focusaiming = 0; } else if (player == &players[consoleplayer]) @@ -7919,7 +7917,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } else { - focusangle = player->mo->angle; + focusangle = mo->angle; focusaiming = player->aiming; } @@ -7966,12 +7964,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall angle = R_PointToAngle2(player->axis1->x, player->axis1->y, player->axis2->x, player->axis2->y); angle += ANGLE_90; } - else if (player->mo->target) + else if (mo->target) { - if (player->mo->target->flags & MF_AMBUSH) - angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y); + if (mo->target->flags & MF_AMBUSH) + angle = R_PointToAngle2(mo->target->x, mo->target->y, mo->x, mo->y); else - angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->target->x, player->mo->target->y); + angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y); } } else if (P_AnalogMove(player)) // Analog @@ -8066,7 +8064,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (twodlevel || (mo->flags2 & MF2_TWOD)) { // Camera doesn't ALWAYS need to move, only when running... - if (abs(player->mo->momx) > 10) + if (abs(mo->momx) > 10) { // Move the camera all smooth-like, not jerk it around... if (mo->momx > 0) @@ -8384,13 +8382,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall vy = thiscam->y; } - if (P_AproxDistance(vx - player->mo->x, vy - player->mo->y) < FixedMul(48*FRACUNIT, mo->scale)) - player->mo->flags2 |= MF2_SHADOW; + if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale)) + mo->flags2 |= MF2_SHADOW; else - player->mo->flags2 &= ~MF2_SHADOW; + mo->flags2 &= ~MF2_SHADOW; } else - player->mo->flags2 &= ~MF2_SHADOW; + mo->flags2 &= ~MF2_SHADOW; /* if (!resetcalled && (player->pflags & PF_NIGHTSMODE && player->exiting)) { From 79f5f4885c70e373cd6d4afc275c2141aa545736 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 4 Oct 2018 19:47:19 -0400 Subject: [PATCH 074/264] Split zlib and libpng --- src/Makefile | 22 +++++++++++++++------- src/sdl/mixer_sound.c | 17 ++++++++--------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/Makefile b/src/Makefile index dd250b0bc..7a67c3f02 100644 --- a/src/Makefile +++ b/src/Makefile @@ -66,6 +66,7 @@ # Compile without 3D sound support, add 'NOHS=1' # Compile with GDBstubs, add 'RDB=1' # Compile without PNG, add 'NOPNG=1' +# Compile without zlib, add 'NOZLIB=1' # # Addon for SDL: # To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config' @@ -119,6 +120,7 @@ include Makefile.cfg ifdef DUMMY NOPNG=1 +NOZLIB=1 NONET=1 NOHW=1 NOHS=1 @@ -199,6 +201,7 @@ endif ifdef NDS NOPNG=1 +NOZLIB=1 NONET=1 #NOHW=1 NOHS=1 @@ -325,13 +328,6 @@ LIBS+=$(PNG_LDFLAGS) CFLAGS+=$(PNG_CFLAGS) endif -ZLIB_PKGCONFIG?=zlib -ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags) -ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) - -LIBS+=$(ZLIB_LDFLAGS) -CFLAGS+=$(ZLIB_CFLAGS) - ifdef HAVE_LIBGME OPTS+=-DHAVE_LIBGME @@ -343,6 +339,18 @@ LIBS+=$(LIBGME_LDFLAGS) CFLAGS+=$(LIBGME_CFLAGS) endif +ifndef NOZLIB +OPTS+=-DHAVE_ZLIB +ZLIB_PKGCONFIG?=zlib +ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags) +ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) + +LIBS+=$(ZLIB_LDFLAGS) +CFLAGS+=$(ZLIB_CFLAGS) +else +NOPNG=1 +endif + ifdef STATIC LIBS:=-static $(LIBS) endif diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 5211efe0a..362d7f264 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -38,9 +38,6 @@ #include "gme/gme.h" #define GME_TREBLE 5.0 #define GME_BASS 1.0 -#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng - -#define HAVE_ZLIB #ifndef _MSC_VER #ifndef _LARGEFILE64_SOURCE @@ -56,10 +53,13 @@ #define _FILE_OFFSET_BITS 0 #endif -#include "zlib.h" #endif #endif +#ifdef HAVE_ZLIB +#include "zlib.h" +#endif + UINT8 sound_started = false; static boolean midimode; @@ -361,7 +361,7 @@ void *I_GetSfx(sfxinfo_t *sfx) } Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up #else - //CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); + return NULL; // No zlib support #endif } // Try to read it as a GME sound @@ -621,7 +621,8 @@ boolean I_StartDigSong(const char *musicname, boolean looping) } Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up #else - //CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); + CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); + return true; #endif } else if (!gme_open_data(data, len, &gme, 44100)) @@ -840,6 +841,4 @@ void I_UnRegisterSong(INT32 handle) (void)handle; Mix_FreeMusic(music); music = NULL; -} - -#endif +} \ No newline at end of file From 49cb1ffe9fb578f8abb29a3f45355ded6211dc03 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 4 Oct 2018 22:38:59 -0400 Subject: [PATCH 075/264] Restore deleted endif --- src/sdl/mixer_sound.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 362d7f264..d1083518a 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -51,8 +51,6 @@ #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 0 -#endif - #endif #endif @@ -841,4 +839,6 @@ void I_UnRegisterSong(INT32 handle) (void)handle; Mix_FreeMusic(music); music = NULL; -} \ No newline at end of file +} + +#endif \ No newline at end of file From fc5d969642f57f54c12acd137355473f14d84acd Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 4 Oct 2018 22:44:26 -0400 Subject: [PATCH 076/264] Fix DD compiling --- src/win32/win_snd.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index f168f1fe3..c030eec5c 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -17,9 +17,6 @@ #include "gme/gme.h" #define GME_TREBLE 5.0 #define GME_BASS 1.0 -#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng - -#define HAVE_ZLIB #ifndef _MSC_VER #ifndef _WII From b812a6a4abdf705d65c6f204291ec6645fe5d729 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 4 Oct 2018 22:56:11 -0400 Subject: [PATCH 077/264] Really fix DD compiling this time. --- src/win32/win_snd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index c030eec5c..bc04bd6df 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -34,6 +34,7 @@ #define _FILE_OFFSET_BITS 0 #endif +#ifdef HAVE_ZLIB #include "zlib.h" #endif #endif From 1ec601af6b989f7ebdc0fa89f4bc2452977ae209 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 5 Oct 2018 22:42:36 +0100 Subject: [PATCH 078/264] Draw a star for continues if invalid skin numbers are somehow supplied --- src/v_video.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index aa2852c01..802a4d388 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -653,14 +653,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ // void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor) { - if (skins[skinnum].flags & SF_HIRES -#ifdef HWRENDER -// || (rendermode != render_soft && rendermode != render_none) -#endif - ) - V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE)); + if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES)) + V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE)); // Draw a star else - { + { // Find front angle of the first waiting frame of the character's actual sprites spriteframe_t *sprframe = &skins[skinnum].spritedef.spriteframes[2 & FF_FRAMEMASK]; patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE); From 725a65c1f7eff77e5632b6a7d7fdb11c47ee0c3f Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 6 Oct 2018 21:44:40 +0100 Subject: [PATCH 079/264] Call SDL_RWclose after an SDL_RWFromMem call to close the RWops. --- src/sdl/mixer_sound.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 5211efe0a..e835a55ce 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -387,7 +387,15 @@ void *I_GetSfx(sfxinfo_t *sfx) #endif // Try to load it as a WAVE or OGG using Mixer. - return Mix_LoadWAV_RW(SDL_RWFromMem(lump, sfx->length), 1); + SDL_RWops *rw = SDL_RWFromMem(lump, sfx->length); + if (rw != NULL) + { + Mix_Chunk *chunk = Mix_LoadWAV_RW(rw, 1); + SDL_RWclose(rw); + return chunk; + } + + return NULL; // haven't been able to get anything } void I_FreeSfx(sfxinfo_t *sfx) @@ -635,7 +643,12 @@ boolean I_StartDigSong(const char *musicname, boolean looping) } #endif - music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE); + SDL_RWops *rw = SDL_RWFromMem(data, len); + if (rw != NULL) + { + music = Mix_LoadMUS_RW(rw, SDL_FALSE); + SDL_RWclose(rw); + } if (!music) { CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); @@ -798,7 +811,12 @@ void I_SetMIDIMusicVolume(UINT8 volume) INT32 I_RegisterSong(void *data, size_t len) { - music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE); + SDL_RWops *rw = SDL_RWFromMem(data, len); + if (rw != NULL) + { + music = Mix_LoadMUS_RW(rw, SDL_FALSE); + SDL_RWclose(rw); + } if (!music) { CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); From 7b417b573c61eeaeb325366196d78ace780f1b5a Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 6 Oct 2018 23:59:39 +0100 Subject: [PATCH 080/264] Mix_QuickLoad_RAW sets a flag in the Mix_Chunk so that Mix_FreeChunk doesn't actually Free the sound. Checks for the flag when freeing, and if it's 0, we free the data manually after Mix_FreeChunk. I went back to Z_Malloc and Z_Free for this because they still work after this. --- src/sdl/mixer_sound.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index e835a55ce..15f1595ce 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -178,7 +178,7 @@ static Mix_Chunk *ds2chunk(void *stream) return NULL; // would and/or did wrap, can't store. break; } - sound = malloc(newsamples<<2); // samples * frequency shift * bytes per sample * channels + sound = Z_Malloc(newsamples<<2, PU_SOUND, 0); // samples * frequency shift * bytes per sample * channels s = (SINT8 *)stream; d = (INT16 *)sound; @@ -401,7 +401,22 @@ void *I_GetSfx(sfxinfo_t *sfx) void I_FreeSfx(sfxinfo_t *sfx) { if (sfx->data) + { + Mix_Chunk *chunk = (Mix_Chunk*)sfx->data; + UINT8 *abufdata = NULL; + if (chunk->allocated == 0) + { + // We allocated the data in this chunk, so get the abuf from mixer, then let it free the chunk, THEN we free the data + // I believe this should ensure the sound is not playing when we free it + abufdata = chunk->abuf; + } Mix_FreeChunk(sfx->data); + if (abufdata) + { + // I'm going to assume we used Z_Malloc to allocate this data. + Z_Free(abufdata); + } + } sfx->data = NULL; sfx->lumpnum = LUMPERROR; } From d072dd27254596c7c8925b4f6d08c151e57535f2 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 7 Oct 2018 00:22:23 +0100 Subject: [PATCH 081/264] I think that should be NULL, not 0 actually. --- src/sdl/mixer_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 15f1595ce..9fef16460 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -178,7 +178,7 @@ static Mix_Chunk *ds2chunk(void *stream) return NULL; // would and/or did wrap, can't store. break; } - sound = Z_Malloc(newsamples<<2, PU_SOUND, 0); // samples * frequency shift * bytes per sample * channels + sound = Z_Malloc(newsamples<<2, PU_SOUND, NULL); // samples * frequency shift * bytes per sample * channels s = (SINT8 *)stream; d = (INT16 *)sound; From 02597e0bf923c76cb1aed2bd15c285371bdd71ff Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 7 Oct 2018 09:26:18 +0100 Subject: [PATCH 082/264] Fix compiler warnings. --- src/sdl/mixer_sound.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 9fef16460..ed15fcdaa 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -246,6 +246,7 @@ void *I_GetSfx(sfxinfo_t *sfx) { void *lump; Mix_Chunk *chunk; + SDL_RWops *rw; #ifdef HAVE_LIBGME Music_Emu *emu; gme_info_t *info; @@ -387,10 +388,10 @@ void *I_GetSfx(sfxinfo_t *sfx) #endif // Try to load it as a WAVE or OGG using Mixer. - SDL_RWops *rw = SDL_RWFromMem(lump, sfx->length); + rw = SDL_RWFromMem(lump, sfx->length); if (rw != NULL) { - Mix_Chunk *chunk = Mix_LoadWAV_RW(rw, 1); + chunk = Mix_LoadWAV_RW(rw, 1); SDL_RWclose(rw); return chunk; } @@ -547,6 +548,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) char *data; size_t len; lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname)); + SDL_RWops *rw; I_Assert(!music); #ifdef HAVE_LIBGME @@ -658,7 +660,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) } #endif - SDL_RWops *rw = SDL_RWFromMem(data, len); + rw = SDL_RWFromMem(data, len); if (rw != NULL) { music = Mix_LoadMUS_RW(rw, SDL_FALSE); From fb6c3298702e76ee8a167264cc7dc0e86936f862 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 7 Oct 2018 10:37:45 +0100 Subject: [PATCH 083/264] Fix the crashing bug hopefully A value of 1 in freesrc for Mix_LoadWAV_RW and Mix_LoadMus_RW calls SDL_RWclose on the RWops anyway. For Mix_LoadWAV_RW the RWops is freed right after the data is loaded (because it makes a copy of the data in memory) For Mix_LoadMUS_RW the RWops is freed when Mix_FreeMusic is called (because the data is not a copy) So setting 1 on freesrc doesn't actually free the RWops immediately on Mix_LoadMus_RW *unless* it failed to load any music. --- src/sdl/mixer_sound.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index ed15fcdaa..53a767dfb 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -392,7 +392,6 @@ void *I_GetSfx(sfxinfo_t *sfx) if (rw != NULL) { chunk = Mix_LoadWAV_RW(rw, 1); - SDL_RWclose(rw); return chunk; } @@ -663,8 +662,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) rw = SDL_RWFromMem(data, len); if (rw != NULL) { - music = Mix_LoadMUS_RW(rw, SDL_FALSE); - SDL_RWclose(rw); + music = Mix_LoadMUS_RW(rw, 1); } if (!music) { @@ -831,8 +829,7 @@ INT32 I_RegisterSong(void *data, size_t len) SDL_RWops *rw = SDL_RWFromMem(data, len); if (rw != NULL) { - music = Mix_LoadMUS_RW(rw, SDL_FALSE); - SDL_RWclose(rw); + music = Mix_LoadMUS_RW(rw, 1); } if (!music) { From b1e02467bfc009d1b08d83a12181fde87869bae0 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 7 Oct 2018 15:00:58 +0100 Subject: [PATCH 084/264] Weather is already run client-side. What if we ran it render-side, for major performance gains? This commit will answer all your questions - and more! --- src/hardware/hw_main.c | 22 ++++++++++++++++++---- src/p_mobj.c | 37 ++++++++++++++++++++----------------- src/p_mobj.h | 4 ++++ src/p_saveg.c | 6 ++---- src/p_spec.c | 34 ++++++++++------------------------ src/p_tick.c | 24 ++++++++++++------------ src/r_things.c | 23 +++++++++++++++++++---- 7 files changed, 85 insertions(+), 65 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d7c73415a..871a6a493 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5140,8 +5140,10 @@ static void HWR_AddSprites(sector_t *sec) approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); - if (approx_dist <= limit_dist) - HWR_ProjectSprite(thing); + if (approx_dist > limit_dist) + continue; + + HWR_ProjectSprite(thing); } } else @@ -5163,8 +5165,10 @@ static void HWR_AddSprites(sector_t *sec) approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); - if (approx_dist <= limit_dist) - HWR_ProjectPrecipitationSprite(precipthing); + if (approx_dist > limit_dist) + continue; + + HWR_ProjectPrecipitationSprite(precipthing); } } else @@ -5449,6 +5453,16 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) x1 = tr_x + x1 * rightcos; x2 = tr_x - x2 * rightcos; + // okay, we can't return now... this is a hack, but weather isn't networked, so it should be ok + if (!(thing->precipflags & PCF_THUNK)) + { + if (thing->precipflags & PCF_RAIN) + P_RainThinker(thing); + else + P_SnowThinker(thing); + thing->precipflags |= PCF_THUNK; + } + // // store information in a vissprite // diff --git a/src/p_mobj.c b/src/p_mobj.c index 5f85474c6..bb9483d18 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3840,7 +3840,8 @@ void P_RecalcPrecipInSector(sector_t *sector) // void P_NullPrecipThinker(precipmobj_t *mobj) { - (void)mobj; + //(void)mobj; + mobj->precipflags &= ~PCF_THUNK; } void P_SnowThinker(precipmobj_t *mobj) @@ -3860,25 +3861,26 @@ void P_RainThinker(precipmobj_t *mobj) { // cycle through states, // calling action functions at transitions - if (mobj->tics > 0 && --mobj->tics == 0) - { - // you can cycle through multiple states in a tic - if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate)) - return; // freed itself - } + if (mobj->tics <= 0) + return; + + if (--mobj->tics) + return; + + if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate)) + return; + + if (mobj->state != &states[S_RAINRETURN]) + return; + + mobj->z = mobj->ceilingz; + P_SetPrecipMobjState(mobj, S_RAIN1); - if (mobj->state == &states[S_RAINRETURN]) - { - mobj->z = mobj->ceilingz; - P_SetPrecipMobjState(mobj, S_RAIN1); - } return; } // adjust height - mobj->z += mobj->momz; - - if (mobj->z <= mobj->floorz) + if ((mobj->z += mobj->momz) <= mobj->floorz) { // no splashes on sky or bottomless pits if (mobj->precipflags & PCF_PIT) @@ -7926,14 +7928,15 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); - mo->thinker.function.acp1 = (actionf_p1)P_RainThinker; + mo->precipflags |= PCF_RAIN; + //mo->thinker.function.acp1 = (actionf_p1)P_RainThinker; return mo; } static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); - mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker; + //mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker; return mo; } diff --git a/src/p_mobj.h b/src/p_mobj.h index 79cffae89..620028d81 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -252,6 +252,10 @@ typedef enum { PCF_FOF = 4, // Above MOVING FOF (this means we need to keep floorz up to date...) PCF_MOVINGFOF = 8, + // Is rain. + PCF_RAIN = 16, + // Ran the thinker this tic. + PCF_THUNK = 32, } precipflag_t; // Map Object definition. typedef struct mobj_s diff --git a/src/p_saveg.c b/src/p_saveg.c index d1ec8e5ab..17d28302e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1661,8 +1661,7 @@ static void P_NetArchiveThinkers(void) for (th = thinkercap.next; th != &thinkercap; th = th->next) { if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed - || th->function.acp1 == (actionf_p1)P_RainThinker - || th->function.acp1 == (actionf_p1)P_SnowThinker)) + || th->function.acp1 == (actionf_p1)P_NullPrecipThinker)) numsaved++; if (th->function.acp1 == (actionf_p1)P_MobjThinker) @@ -1671,8 +1670,7 @@ static void P_NetArchiveThinkers(void) continue; } #ifdef PARANOIA - else if (th->function.acp1 == (actionf_p1)P_RainThinker - || th->function.acp1 == (actionf_p1)P_SnowThinker); + else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker); #endif else if (th->function.acp1 == (actionf_p1)T_MoveCeiling) { diff --git a/src/p_spec.c b/src/p_spec.c index c62c3b209..ff6691a99 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2039,8 +2039,7 @@ void P_SwitchWeather(INT32 weathernum) for (think = thinkercap.next; think != &thinkercap; think = think->next) { - if ((think->function.acp1 != (actionf_p1)P_SnowThinker) - && (think->function.acp1 != (actionf_p1)P_RainThinker)) + if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker precipmobj = (precipmobj_t *)think; @@ -2056,14 +2055,12 @@ void P_SwitchWeather(INT32 weathernum) for (think = thinkercap.next; think != &thinkercap; think = think->next) { + if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) + continue; // not a precipmobj thinker + precipmobj = (precipmobj_t *)think; + if (swap == PRECIP_RAIN) // Snow To Rain { - if (!(think->function.acp1 == (actionf_p1)P_SnowThinker - || think->function.acp1 == (actionf_p1)P_NullPrecipThinker)) - continue; // not a precipmobj thinker - - precipmobj = (precipmobj_t *)think; - precipmobj->flags = mobjinfo[MT_RAIN].flags; st = &states[mobjinfo[MT_RAIN].spawnstate]; precipmobj->state = st; @@ -2074,18 +2071,13 @@ void P_SwitchWeather(INT32 weathernum) precipmobj->precipflags &= ~PCF_INVISIBLE; - think->function.acp1 = (actionf_p1)P_RainThinker; + precipmobj->precipflags |= PCF_RAIN; + //think->function.acp1 = (actionf_p1)P_RainThinker; } else if (swap == PRECIP_SNOW) // Rain To Snow { INT32 z; - if (!(think->function.acp1 == (actionf_p1)P_RainThinker - || think->function.acp1 == (actionf_p1)P_NullPrecipThinker)) - continue; // not a precipmobj thinker - - precipmobj = (precipmobj_t *)think; - precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; z = M_RandomByte(); @@ -2103,19 +2095,13 @@ void P_SwitchWeather(INT32 weathernum) precipmobj->frame = st->frame; precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed; - precipmobj->precipflags &= ~PCF_INVISIBLE; + precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_RAIN); - think->function.acp1 = (actionf_p1)P_SnowThinker; + //think->function.acp1 = (actionf_p1)P_SnowThinker; } else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse. { - if (!(think->function.acp1 == (actionf_p1)P_RainThinker - || think->function.acp1 == (actionf_p1)P_SnowThinker)) - continue; - - precipmobj = (precipmobj_t *)think; - - think->function.acp1 = (actionf_p1)P_NullPrecipThinker; + //think->function.acp1 = (actionf_p1)P_NullPrecipThinker; precipmobj->precipflags |= PCF_INVISIBLE; } diff --git a/src/p_tick.c b/src/p_tick.c index f4bc59323..5ba747078 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -56,12 +56,12 @@ void Command_Numthinkers_f(void) CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n")); CONS_Printf( "\t1: P_MobjThinker\n" - "\t2: P_RainThinker\n" - "\t3: P_SnowThinker\n" - "\t4: P_NullPrecipThinker\n" - "\t5: T_Friction\n" - "\t6: T_Pusher\n" - "\t7: P_RemoveThinkerDelayed\n"); + /*"\t2: P_RainThinker\n" + "\t3: P_SnowThinker\n"*/ + "\t2: P_NullPrecipThinker\n" + "\t3: T_Friction\n" + "\t4: T_Pusher\n" + "\t5: P_RemoveThinkerDelayed\n"); return; } @@ -73,27 +73,27 @@ void Command_Numthinkers_f(void) action = (actionf_p1)P_MobjThinker; CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker"); break; - case 2: + /*case 2: action = (actionf_p1)P_RainThinker; CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker"); break; case 3: action = (actionf_p1)P_SnowThinker; CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker"); - break; - case 4: + break;*/ + case 2: action = (actionf_p1)P_NullPrecipThinker; CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker"); break; - case 5: + case 3: action = (actionf_p1)T_Friction; CONS_Printf(M_GetText("Number of %s: "), "T_Friction"); break; - case 6: + case 4: action = (actionf_p1)T_Pusher; CONS_Printf(M_GetText("Number of %s: "), "T_Pusher"); break; - case 7: + case 5: action = (actionf_p1)P_RemoveThinkerDelayed; CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed"); break; diff --git a/src/r_things.c b/src/r_things.c index 0b1764167..910a52b30 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1451,6 +1451,17 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) return; } + // okay, we can't return now except for vertical clipping... this is a hack, but weather isn't networked, so it should be ok + if (!(thing->precipflags & PCF_THUNK)) + { + if (thing->precipflags & PCF_RAIN) + P_RainThinker(thing); + else + P_SnowThinker(thing); + thing->precipflags |= PCF_THUNK; + } + + //SoM: 3/17/2000: Disregard sprites that are out of view.. gzt = thing->z + spritecachedinfo[lump].topoffset; gz = gzt - spritecachedinfo[lump].height; @@ -1569,8 +1580,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); - if (approx_dist <= limit_dist) - R_ProjectSprite(thing); + if (approx_dist > limit_dist) + continue; + + R_ProjectSprite(thing); } } else @@ -1591,8 +1604,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); - if (approx_dist <= limit_dist) - R_ProjectPrecipitationSprite(precipthing); + if (approx_dist > limit_dist) + continue; + + R_ProjectPrecipitationSprite(precipthing); } } else From def090c9f0245c148d2313c30c4ef398578d1738 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 7 Oct 2018 14:45:03 -0400 Subject: [PATCH 085/264] Move the ifdef --- src/sdl/mixer_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index d1083518a..1b0974b17 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -52,11 +52,11 @@ #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 0 #endif -#endif #ifdef HAVE_ZLIB #include "zlib.h" #endif +#endif UINT8 sound_started = false; From 232a7ae7b713c5c5854d0d0205a4fbd5dea9ee47 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 7 Oct 2018 14:52:25 -0400 Subject: [PATCH 086/264] Change order of the ifdef --- src/sdl/mixer_sound.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 1b0974b17..c4d2a8b08 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -39,6 +39,7 @@ #define GME_TREBLE 5.0 #define GME_BASS 1.0 +#ifdef HAVE_ZLIB #ifndef _MSC_VER #ifndef _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE @@ -53,10 +54,9 @@ #define _FILE_OFFSET_BITS 0 #endif -#ifdef HAVE_ZLIB #include "zlib.h" -#endif -#endif +#endif // HAVE_ZLIB +#endif // HAVE_LIBGME UINT8 sound_started = false; From 027e6e8e3c91777efa302c63ab5eab23e315925d Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 7 Oct 2018 15:00:48 -0400 Subject: [PATCH 087/264] Change win_snd.c also --- src/win32/win_snd.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index bc04bd6df..58644457a 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -18,13 +18,12 @@ #define GME_TREBLE 5.0 #define GME_BASS 1.0 +#ifdef HAVE_ZLIB #ifndef _MSC_VER -#ifndef _WII #ifndef _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE #endif #endif -#endif #ifndef _LFS64_LARGEFILE #define _LFS64_LARGEFILE @@ -34,10 +33,9 @@ #define _FILE_OFFSET_BITS 0 #endif -#ifdef HAVE_ZLIB #include "zlib.h" -#endif -#endif +#endif // HAVE_ZLIB +#endif // HAVE_LIBGME static FMOD_SYSTEM *fsys; static FMOD_SOUND *music_stream; From 1324e0bfcd945651a90c339042523d4f35e89a24 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 8 Oct 2018 18:50:17 +0100 Subject: [PATCH 088/264] * Fix a memory leak regarding implementation of SOC_ (improperly copypasted code from LUA_LoadLump!!) * Optimise the repeated strlen usage into a single call, which is stored for later. --- src/lua_script.c | 12 +++++++----- src/w_wad.c | 15 ++++++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index ce96878bf..1c1b01f6c 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -182,19 +182,21 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump) { MYFILE f; char *name; + size_t len; f.wad = wad; f.size = W_LumpLengthPwad(wad, lump); f.data = Z_Malloc(f.size, PU_LUA, NULL); W_ReadLumpPwad(wad, lump, f.data); f.curpos = f.data; - name = malloc(strlen(wadfiles[wad]->filename)+10); + len = strlen(wadfiles[wad]->filename); + name = malloc(len+10); strcpy(name, wadfiles[wad]->filename); - if (!fasticmp(&name[strlen(name) - 4], ".lua")) { + if (!fasticmp(&name[len - 4], ".lua")) { // If it's not a .lua file, copy the lump name in too. - name[strlen(wadfiles[wad]->filename)] = '|'; - M_Memcpy(name+strlen(wadfiles[wad]->filename)+1, wadfiles[wad]->lumpinfo[lump].name, 8); - name[strlen(wadfiles[wad]->filename)+9] = '\0'; + name[len] = '|'; + M_Memcpy(name+len+1, wadfiles[wad]->lumpinfo[lump].name, 8); + name[len+9] = '\0'; } LUA_LoadFile(&f, name); diff --git a/src/w_wad.c b/src/w_wad.c index 3a8285593..3f0082a16 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -194,16 +194,21 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum) 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 - char *name = malloc(strlen(wadfiles[wadnum]->filename)+10); + size_t len = strlen(wadfiles[wadnum]->filename); + char *name = malloc(len+10); + strcpy(name, wadfiles[wadnum]->filename); - if (!fasticmp(&name[strlen(name) - 4], ".soc")) { + if (!fasticmp(&name[len - 4], ".soc")) { // If it's not a .soc file, copy the lump name in too. - name[strlen(wadfiles[wadnum]->filename)] = '|'; - M_Memcpy(name+strlen(wadfiles[wadnum]->filename)+1, lump_p->name, 8); - name[strlen(wadfiles[wadnum]->filename)+9] = '\0'; + name[len] = '|'; + M_Memcpy(name+len+1, lump_p->name, 8); + name[len+9] = '\0'; } + CONS_Printf(M_GetText("Loading SOC from %s\n"), name); DEH_LoadDehackedLumpPwad(wadnum, lump); + + free(name); } else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG { From 497314fdc44551a46395f41cd579d845d92b270e Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 9 Oct 2018 19:43:18 +0100 Subject: [PATCH 089/264] Tiny fix so that joystick2 being closed can let the JoystickSubSystem close before game close. No memory leak here, just a very tiny thing I noticed. --- src/sdl/i_system.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index f92cd4b6e..7b14f1f18 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1154,6 +1154,7 @@ static void I_ShutdownJoystick2(void) D_PostEvent(&event); } + joystick2_started = 0; JoyReset(&JoyInfo2); if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) { From 77e85394d8fe59d70b96085f64062118ea261986 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 10 Oct 2018 14:59:44 +0100 Subject: [PATCH 090/264] Change when and specifically what colormap[] is applied to in R_Draw2sMultiPatchTranslucentColumn_8 --- src/r_draw8.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index 76eb58c0d..bda146546 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -261,7 +261,7 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) val = source[frac>>FRACBITS]; if (val != TRANSPARENTPIXEL) - *dest = colormap[*(transmap + (val<<8) + (*dest))]; + *dest = *(transmap + (colormap[val]<<8) + (*dest)); dest += vid.width; @@ -281,12 +281,12 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[*(transmap + (val<<8) + (*dest))]; + *dest = *(transmap + (colormap[val]<<8) + (*dest)); dest += vid.width; frac += fracstep; val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[*(transmap + (val<<8) + (*dest))]; + *dest = *(transmap + (colormap[val]<<8) + (*dest)); dest += vid.width; frac += fracstep; } @@ -294,7 +294,7 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[*(transmap + (val<<8) + (*dest))]; + *dest = *(transmap + (colormap[val]<<8) + (*dest)); } } } From b9b0a8110c307bdf8457fa66a83a193ad0008461 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 16 Nov 2016 18:43:25 +0000 Subject: [PATCH 091/264] Add R_Draw2sMultiPatchTranslucentColumn_8, for columns of multi-patch textures used as midtextures on two-sided linedefs with both transparency AND translucency ...that was a mouthful --- src/r_draw.h | 1 + src/r_draw8.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/r_segs.c | 2 ++ src/screen.c | 2 ++ src/screen.h | 1 + 5 files changed, 103 insertions(+) diff --git a/src/r_draw.h b/src/r_draw.h index 6d85bd6a5..9cf7e9d54 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -161,6 +161,7 @@ void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); void R_DrawTranslucentSpan_8(void); void R_Draw2sMultiPatchColumn_8(void); +void R_Draw2sMultiPatchTranslucentColumn_8(void); void R_DrawFogSpan_8(void); void R_DrawFogColumn_8(void); void R_DrawColumnShadowed_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 800f28b6b..e5dbe7071 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -203,6 +203,103 @@ void R_Draw2sMultiPatchColumn_8(void) } } +void R_Draw2sMultiPatchTranslucentColumn_8(void) +{ + INT32 count; + register UINT8 *dest; + register fixed_t frac; + fixed_t fracstep; + + count = dc_yh - dc_yl; + + if (count < 0) // Zero length, column does not exceed a pixel. + return; + +#ifdef RANGECHECK + if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) + return; +#endif + + // Framebuffer destination address. + // Use ylookup LUT to avoid multiply with ScreenWidth. + // Use columnofs LUT for subwindows? + + //dest = ylookup[dc_yl] + columnofs[dc_x]; + dest = &topleft[dc_yl*vid.width + dc_x]; + + count++; + + // Determine scaling, which is the only mapping to be done. + fracstep = dc_iscale; + //frac = dc_texturemid + (dc_yl - centery)*fracstep; + frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + + // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. + // This is as fast as it gets. + { + register const UINT8 *source = dc_source; + register const UINT8 *transmap = dc_transmap; + register const lighttable_t *colormap = dc_colormap; + register INT32 heightmask = dc_texheight-1; + register UINT8 val; + if (dc_texheight & heightmask) // not a power of 2 -- killough + { + heightmask++; + heightmask <<= FRACBITS; + + if (frac < 0) + while ((frac += heightmask) < 0); + else + while (frac >= heightmask) + frac -= heightmask; + + do + { + // Re-map color indices from wall texture column + // using a lighting/special effects LUT. + // heightmask is the Tutti-Frutti fix + val = source[frac>>FRACBITS]; + + if (val != TRANSPARENTPIXEL) + *dest = colormap[*(transmap + (val<<8) + (*dest))]; + + dest += vid.width; + + // Avoid overflow. + if (fracstep > 0x7FFFFFFF - frac) + frac += fracstep - heightmask; + else + frac += fracstep; + + while (frac >= heightmask) + frac -= heightmask; + } while (--count); + } + else + { + while ((count -= 2) >= 0) // texture height is a power of 2 + { + val = source[(frac>>FRACBITS) & heightmask]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[*(transmap + (val<<8) + (*dest))]; + dest += vid.width; + frac += fracstep; + val = source[(frac>>FRACBITS) & heightmask]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[*(transmap + (val<<8) + (*dest))]; + dest += vid.width; + frac += fracstep; + } + if (count & 1) + { + val = source[(frac>>FRACBITS) & heightmask]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[*(transmap + (val<<8) + (*dest))]; + } + } + } +} + /** \brief The R_DrawShadeColumn_8 function Experiment to make software go faster. Taken from the Boom source */ diff --git a/src/r_segs.c b/src/r_segs.c index 502ff3304..40184bddf 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -271,6 +271,8 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) if (colfunc == wallcolfunc) twosmultipatchfunc(); + else if (colfunc == fuzzcolfunc) + twosmultipatchtransfunc(); else colfunc(); } diff --git a/src/screen.c b/src/screen.c index 2780edb60..58c38993b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -49,6 +49,7 @@ void (*splatfunc)(void); // span drawer w/ transparency void (*basespanfunc)(void); // default span func for color mode void (*transtransfunc)(void); // translucent translated column drawer void (*twosmultipatchfunc)(void); // for cols with transparent pixels +void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND translucency // ------------------ // global video state @@ -127,6 +128,7 @@ void SCR_SetMode(void) fuzzcolfunc = R_DrawTranslucentColumn_8; walldrawerfunc = R_DrawWallColumn_8; twosmultipatchfunc = R_Draw2sMultiPatchColumn_8; + twosmultipatchtransfunc = R_Draw2sMultiPatchTranslucentColumn_8; #ifdef RUSEASM if (R_ASM) { diff --git a/src/screen.h b/src/screen.h index 2dff4590e..a61de7f92 100644 --- a/src/screen.h +++ b/src/screen.h @@ -136,6 +136,7 @@ extern void (*basespanfunc)(void); extern void (*splatfunc)(void); extern void (*transtransfunc)(void); extern void (*twosmultipatchfunc)(void); +extern void (*twosmultipatchtransfunc)(void); // ----- // CPUID From 72ab305bf4672edc9ead8a1004fcf1ab1f7b7cd5 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 10 Oct 2018 14:59:44 +0100 Subject: [PATCH 092/264] Change when and specifically what colormap[] is applied to in R_Draw2sMultiPatchTranslucentColumn_8 --- src/r_draw8.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index e5dbe7071..f9c5b7ada 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -261,7 +261,7 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) val = source[frac>>FRACBITS]; if (val != TRANSPARENTPIXEL) - *dest = colormap[*(transmap + (val<<8) + (*dest))]; + *dest = *(transmap + (colormap[val]<<8) + (*dest)); dest += vid.width; @@ -281,12 +281,12 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[*(transmap + (val<<8) + (*dest))]; + *dest = *(transmap + (colormap[val]<<8) + (*dest)); dest += vid.width; frac += fracstep; val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[*(transmap + (val<<8) + (*dest))]; + *dest = *(transmap + (colormap[val]<<8) + (*dest)); dest += vid.width; frac += fracstep; } @@ -294,7 +294,7 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[*(transmap + (val<<8) + (*dest))]; + *dest = *(transmap + (colormap[val]<<8) + (*dest)); } } } From 4b7af892e1b7ddda002d3d5a3867a19b4d502285 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 14 Apr 2017 17:45:27 +0100 Subject: [PATCH 093/264] Moved most of d_netcmd.h's 2P mouse consvar externs to the files with their 1P counterparts --- src/d_netcmd.h | 5 ----- src/g_game.h | 1 + src/g_input.h | 1 + 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index d8fae72f7..8a15136c0 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -40,11 +40,6 @@ extern consvar_t cv_usemouse2; #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) extern consvar_t cv_mouse2opt; #endif -extern consvar_t cv_invertmouse2; -extern consvar_t cv_alwaysfreelook2; -extern consvar_t cv_mousemove2; -extern consvar_t cv_mousesens2; -extern consvar_t cv_mouseysens2; // normally in p_mobj but the .h is not read extern consvar_t cv_itemrespawntime; diff --git a/src/g_game.h b/src/g_game.h index ada82404c..448d2855e 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -56,6 +56,7 @@ extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; +extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_fireaxis2,cv_firenaxis2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; diff --git a/src/g_input.h b/src/g_input.h index d65339321..2f86e5928 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -126,6 +126,7 @@ typedef enum // mouse values are used once extern consvar_t cv_mousesens, cv_mouseysens; +extern consvar_t cv_mousesens2, cv_mouseysens2; extern INT32 mousex, mousey; extern INT32 mlooky; //mousey with mlookSensitivity From e2a4c59e2190a92acb00921d783a43f484e39253 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 14 Apr 2017 18:02:35 +0100 Subject: [PATCH 094/264] cv_controlperkey probably belongs in g_input.h too --- src/d_netcmd.h | 1 - src/g_input.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 8a15136c0..08cdfd2ee 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -32,7 +32,6 @@ extern consvar_t cv_joyport2; #endif extern consvar_t cv_joyscale; extern consvar_t cv_joyscale2; -extern consvar_t cv_controlperkey; // splitscreen with second mouse extern consvar_t cv_mouse2port; diff --git a/src/g_input.h b/src/g_input.h index 2f86e5928..f42ad89d8 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -127,6 +127,7 @@ typedef enum // mouse values are used once extern consvar_t cv_mousesens, cv_mouseysens; extern consvar_t cv_mousesens2, cv_mouseysens2; +extern consvar_t cv_controlperkey; extern INT32 mousex, mousey; extern INT32 mlooky; //mousey with mlookSensitivity From 933508db89376993f49ec8e074e8c5afd5edec90 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 14 Apr 2017 18:14:15 +0100 Subject: [PATCH 095/264] Moved screenshot/movie consvar externs to m_misc.h --- src/d_netcmd.h | 12 +----------- src/m_misc.h | 7 +++++++ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 08cdfd2ee..2731ca7fb 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -115,17 +115,7 @@ extern consvar_t cv_maxping; extern consvar_t cv_skipmapcheck; -extern consvar_t cv_sleep, cv_screenshot_option, cv_screenshot_folder; - -extern consvar_t cv_moviemode; - -extern consvar_t cv_zlib_level, cv_zlib_memory, cv_zlib_strategy; - -extern consvar_t cv_zlib_window_bits, cv_zlib_levela, cv_zlib_memorya; - -extern consvar_t cv_zlib_strategya, cv_zlib_window_bitsa; - -extern consvar_t cv_apng_delay; +extern consvar_t cv_sleep; typedef enum { diff --git a/src/m_misc.h b/src/m_misc.h index dc540dc16..5bd7401e1 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -19,6 +19,7 @@ #include "tables.h" #include "d_event.h" // Screenshot responder +#include "command.h" typedef enum { MM_OFF = 0, @@ -28,6 +29,12 @@ typedef enum { } moviemode_t; extern moviemode_t moviemode; +extern consvar_t cv_screenshot_option, cv_screenshot_folder; +extern consvar_t cv_moviemode; +extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits; +extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa; +extern consvar_t cv_apng_delay; + void M_StartMovie(void); void M_SaveFrame(void); void M_StopMovie(void); From 0ad0f8afc451d172fb36f8f2b1a0e14021bbcd18 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 14 Apr 2017 19:00:46 +0100 Subject: [PATCH 096/264] Move analog consvars to g_game.h --- src/d_netcmd.h | 3 --- src/g_game.h | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 2731ca7fb..40c806a33 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -71,9 +71,6 @@ extern consvar_t cv_autobalance; extern consvar_t cv_teamscramble; extern consvar_t cv_scrambleonchange; -extern consvar_t cv_useranalog, cv_useranalog2; -extern consvar_t cv_analog, cv_analog2; - extern consvar_t cv_netstat; #ifdef WALLSPLATS extern consvar_t cv_splats; diff --git a/src/g_game.h b/src/g_game.h index 448d2855e..ba4142695 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -57,6 +57,8 @@ extern INT16 rw_maximums[NUM_WEAPONS]; extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2; +extern consvar_t cv_useranalog, cv_useranalog2; +extern consvar_t cv_analog, cv_analog2; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_fireaxis,cv_firenaxis; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_fireaxis2,cv_firenaxis2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; From 38ec0cc50aa595f22e6e1f5ee19352cd42da355d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 14 Apr 2017 19:56:51 +0100 Subject: [PATCH 097/264] These convar externs aren't moving files, I'm just shifting them up to live with their relatives --- src/d_netcmd.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 40c806a33..e03089482 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -20,6 +20,12 @@ // console vars extern consvar_t cv_playername; extern consvar_t cv_playercolor; +extern consvar_t cv_skin; +// secondary splitscreen player +extern consvar_t cv_playername2; +extern consvar_t cv_playercolor2; +extern consvar_t cv_skin2; + #ifdef SEENAMES extern consvar_t cv_seenames, cv_allowseenames; #endif @@ -47,13 +53,6 @@ extern consvar_t cv_itemrespawn; extern consvar_t cv_flagtime; extern consvar_t cv_suddendeath; -extern consvar_t cv_skin; - -// secondary splitscreen player -extern consvar_t cv_playername2; -extern consvar_t cv_playercolor2; -extern consvar_t cv_skin2; - extern consvar_t cv_touchtag; extern consvar_t cv_hidetime; From a4419abfdc21d0d0ec69e3d73528a4c9bb68205e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 25 Jan 2017 19:36:32 +0000 Subject: [PATCH 098/264] debugfile is only used by DEBUGFILE code, no need to declare/define it for anything else --- src/d_net.c | 2 ++ src/doomstat.h | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_net.c b/src/d_net.c index 643c41ac9..8de5cf088 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -49,7 +49,9 @@ doomcom_t *doomcom = NULL; /// \brief network packet data, points inside doomcom doomdata_t *netbuffer = NULL; +#ifdef DEBUGFILE FILE *debugfile = NULL; // put some net info in a file during the game +#endif #define MAXREBOUND 8 static doomdata_t reboundstore[MAXREBOUND]; diff --git a/src/doomstat.h b/src/doomstat.h index 8072a1552..341cc70a9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -445,19 +445,17 @@ extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF #if defined (macintosh) #define DEBFILE(msg) I_OutputMsg(msg) -extern FILE *debugfile; #else #define DEBUGFILE #ifdef DEBUGFILE #define DEBFILE(msg) { if (debugfile) { fputs(msg, debugfile); fflush(debugfile); } } -extern FILE *debugfile; #else #define DEBFILE(msg) {} -extern FILE *debugfile; #endif #endif #ifdef DEBUGFILE +extern FILE *debugfile; extern INT32 debugload; #endif From 61a29bed853a737f79fb5aac2c1ceb4ddd758aeb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Feb 2017 22:41:15 +0000 Subject: [PATCH 099/264] Remove unused sscount variable (it's only set to 0 in software, and only ++'d in OpenGL, what kind of sense does that make?) --- src/hardware/hw_bsp.c | 2 -- src/hardware/hw_main.c | 1 - src/r_main.c | 5 ----- src/r_state.h | 3 --- 4 files changed, 11 deletions(-) diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 17eb8761c..a32609fc8 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -564,8 +564,6 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly) subsector_t *sub; seg_t *lseg; - sscount++; - sub = &subsectors[num]; count = sub->numlines; lseg = &segs[sub->firstline]; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 871a6a493..ecb70a0f9 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3264,7 +3264,6 @@ static void HWR_Subsector(size_t num) if (num < numsubsectors) { - sscount++; // subsector sub = &subsectors[num]; // sector diff --git a/src/r_main.c b/src/r_main.c index f2a0c8894..6c92983f4 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -60,7 +60,6 @@ fixed_t projectiony; // aspect ratio // just for profiling purposes size_t framecount; -size_t sscount; size_t loopcount; fixed_t viewx, viewy, viewz; @@ -964,8 +963,6 @@ void R_SkyboxFrame(player_t *player) viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - sscount = 0; - // recalc necessary stuff for mouseaiming // slopes are already calculated for the full possible view (which is 4*viewheight). @@ -1089,8 +1086,6 @@ void R_SetupFrame(player_t *player, boolean skybox) viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - sscount = 0; - // recalc necessary stuff for mouseaiming // slopes are already calculated for the full possible view (which is 4*viewheight). diff --git a/src/r_state.h b/src/r_state.h index 49d0457b2..ac3e1fa42 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -108,7 +108,4 @@ extern angle_t rw_normalangle; // angle to line origin extern angle_t rw_angle1; -// Segs count? -extern size_t sscount; - #endif From 07dd527e7e58e06ce621e80357bef7ae91424f76 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Feb 2017 22:56:08 +0000 Subject: [PATCH 100/264] Removed unused function prototypes in d_main.h Also corrected what appears to be a typo in some comments above? --- src/d_main.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/d_main.h b/src/d_main.h index 6dc273b15..d73b19d1f 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -34,7 +34,7 @@ void D_SRB2Loop(void) FUNCNORETURN; // D_SRB2Main() // Not a globally visible function, just included for source reference, // calls all startup code, parses command line options. -// If not overrided by user input, calls N_AdvanceDemo. +// If not overrided by user input, calls D_AdvanceDemo. // void D_SRB2Main(void); @@ -51,9 +51,6 @@ const char *D_Home(void); // // BASE LEVEL // -void D_PageTicker(void); -// pagename is lumpname of a 320x200 patch to fill the screen -void D_PageDrawer(const char *pagename); void D_AdvanceDemo(void); void D_StartTitle(void); From 91b2f5e570b1b3783b54ca014a11ed07d0570ef4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Feb 2017 23:24:12 +0000 Subject: [PATCH 101/264] "t" is not needed to take out fencepost cases from viewangletox --- src/r_main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index 6c92983f4..d1cd71b3f 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -491,9 +491,6 @@ static void R_InitTextureMapping(void) // Take out the fencepost cases from viewangletox. for (i = 0; i < FINEANGLES/2; i++) { - t = FixedMul(FINETANGENT(i), focallength); - t = centerx - t; - if (viewangletox[i] == -1) viewangletox[i] = 0; else if (viewangletox[i] == viewwidth+1) From 49c5a6f7e474ff6aa30a726ae7cbcf9e224fb533 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Feb 2017 23:28:42 +0000 Subject: [PATCH 102/264] Remove unused "runcount" variable from p_local.h --- src/p_local.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_local.h b/src/p_local.h index 1fd7ada04..b82bcf0ec 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -68,7 +68,6 @@ // both the head and tail of the thinker list extern thinker_t thinkercap; -extern INT32 runcount; void P_InitThinkers(void); void P_AddThinker(thinker_t *thinker); From ef78c942f798e0d736cc84de8b912889d9232fbc Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 15 Feb 2017 21:16:56 +0000 Subject: [PATCH 103/264] Remove unused ObjectPlace_OnChange prototype (from when Objectplace was a consvar, which it is not anymore) --- src/d_netcmd.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index d8fae72f7..023bbd094 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -212,7 +212,6 @@ void Command_ExitGame_f(void); void Command_Retry_f(void); void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); -void ObjectPlace_OnChange(void); void ItemFinder_OnChange(void); void D_SetPassword(const char *pw); From 9c464742b7d0b10b35ef27dcdad2e72d33e4f8da Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 22 Feb 2017 21:07:29 +0000 Subject: [PATCH 104/264] Remove "playerdeadview" variable; it's not been used for its stated purpose for who knows how long now Besides rankings popping up when you die just sounds weird anyway, maybe I'm just used to SRB2 not doing it I guess --- src/d_clisrv.c | 2 -- src/d_main.c | 1 - src/f_finale.c | 6 ------ src/g_game.c | 1 - src/hu_stuff.h | 3 --- src/p_user.c | 9 --------- 6 files changed, 22 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 6e22dde23..950038237 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1568,8 +1568,6 @@ static void CL_LoadReceivedSavegame(void) automapactive = false; // load a base level - playerdeadview = false; - if (P_LoadNetGame()) { const INT32 actnum = mapheaderinfo[gamemap-1]->actnum; diff --git a/src/d_main.c b/src/d_main.c index df3398752..f807e3070 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -720,7 +720,6 @@ void D_StartTitle(void) maptol = 0; gameaction = ga_nothing; - playerdeadview = false; displayplayer = consoleplayer = 0; //demosequence = -1; gametype = GT_COOP; diff --git a/src/f_finale.c b/src/f_finale.c index a8b27bb80..fb1387c11 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -442,7 +442,6 @@ void F_StartIntro(void) G_SetGamestate(GS_INTRO); gameaction = ga_nothing; - playerdeadview = false; paused = false; CON_ToggleOff(); CON_ClearHUD(); @@ -1130,7 +1129,6 @@ void F_StartCredits(void) } gameaction = ga_nothing; - playerdeadview = false; paused = false; CON_ToggleOff(); CON_ClearHUD(); @@ -1277,7 +1275,6 @@ void F_StartGameEvaluation(void) G_SaveGame((UINT32)cursaveslot); gameaction = ga_nothing; - playerdeadview = false; paused = false; CON_ToggleOff(); CON_ClearHUD(); @@ -1388,7 +1385,6 @@ void F_StartGameEnd(void) G_SetGamestate(GS_GAMEEND); gameaction = ga_nothing; - playerdeadview = false; paused = false; CON_ToggleOff(); CON_ClearHUD(); @@ -1591,7 +1587,6 @@ void F_StartContinue(void) gameaction = ga_nothing; keypressed = false; - playerdeadview = false; paused = false; CON_ToggleOff(); CON_ClearHUD(); @@ -1760,7 +1755,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset G_SetGamestate(GS_CUTSCENE); gameaction = ga_nothing; - playerdeadview = false; paused = false; CON_ToggleOff(); diff --git a/src/g_game.c b/src/g_game.c index 4f1c49b42..0e8c14f6a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3616,7 +3616,6 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean mapmusflags |= MUSIC_RELOADRESET; ultimatemode = pultmode; - playerdeadview = false; automapactive = false; imcontinuing = false; diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 7b22f33f1..5356ba8ac 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -78,9 +78,6 @@ extern boolean chat_on; // set true whenever the tab rankings are being shown for any reason extern boolean hu_showscores; -// P_DeathThink sets this true to show scores while dead, in multiplayer -extern boolean playerdeadview; - // init heads up data at game startup. void HU_Init(void); diff --git a/src/p_user.c b/src/p_user.c index 7abf85347..7e206930d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8648,8 +8648,6 @@ void P_DoPityCheck(player_t *player) // P_PlayerThink // -boolean playerdeadview; // show match/chaos/tag/capture the flag rankings while in death view - void P_PlayerThink(player_t *player) { ticcmd_t *cmd; @@ -8838,10 +8836,6 @@ void P_PlayerThink(player_t *player) if (player->playerstate == PST_DEAD) { player->mo->flags2 &= ~MF2_SHADOW; - // show the multiplayer rankings while dead - if (player == &players[displayplayer]) - playerdeadview = true; - P_DeathThink(player); return; @@ -8862,9 +8856,6 @@ void P_PlayerThink(player_t *player) player->lives = cv_startinglives.value; } - if (player == &players[displayplayer]) - playerdeadview = false; - if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) { cmd->buttons &= BT_USE; // Remove all buttons except BT_USE From c1d5c711a940fc2e66cbfe53571be01f8bee9420 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 19 Apr 2017 20:00:19 +0100 Subject: [PATCH 105/264] Be gone ye old texture hack --- src/r_data.c | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index f2c9b1466..ee9144b72 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -472,40 +472,22 @@ void R_LoadTextures(void) } else { - UINT16 patchcount = 1; //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); - if (SHORT(patchlump->width) == 64 - && SHORT(patchlump->height) == 64) - { // 64x64 patch - const column_t *column; - for (k = 0; k < SHORT(patchlump->width); k++) - { // Find use of transparency. - column = (const column_t *)((const UINT8 *)patchlump + LONG(patchlump->columnofs[k])); - if (column->length != SHORT(patchlump->height)) - break; - } - if (k == SHORT(patchlump->width)) - patchcount = 2; // No transparency? 64x128 texture. - } - texture = textures[i] = Z_Calloc(sizeof(texture_t) + (sizeof(texpatch_t) * patchcount), PU_STATIC, NULL); + texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); // Set texture properties. M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name)); texture->width = SHORT(patchlump->width); - texture->height = SHORT(patchlump->height)*patchcount; - texture->patchcount = patchcount; + texture->height = SHORT(patchlump->height); + texture->patchcount = 1; texture->holes = false; // Allocate information for the texture's patches. - for (k = 0; k < patchcount; k++) - { - patch = &texture->patches[k]; + patch = &texture->patches[0]; - patch->originx = 0; - patch->originy = (INT16)(k*patchlump->height); - patch->wad = (UINT16)w; - patch->lump = texstart + j; - } + patch->originx = patch->originy = 0; + patch->wad = (UINT16)w; + patch->lump = texstart + j; Z_Unlock(patchlump); From 31f3f8b8e787f41e4c22ac2d84130f0a02861912 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 18 May 2017 16:54:58 +0100 Subject: [PATCH 106/264] Moved Y_EndGame from y_inter.c/h to g_game.c/h, renamed it to G_EndGame --- src/f_finale.c | 4 ++-- src/g_game.c | 34 +++++++++++++++++++++++++++++++++- src/g_game.h | 1 + src/y_inter.c | 33 +-------------------------------- src/y_inter.h | 1 - 5 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index a8b27bb80..0a4486928 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1733,7 +1733,7 @@ static void F_AdvanceToNextScene(void) void F_EndCutScene(void) { - cutsceneover = true; // do this first, just in case Y_EndGame or something wants to turn it back false later + cutsceneover = true; // do this first, just in case G_EndGame or something wants to turn it back false later if (runningprecutscene) { if (server) @@ -1748,7 +1748,7 @@ void F_EndCutScene(void) else if (nextmap < 1100-1) G_NextLevel(); else - Y_EndGame(); + G_EndGame(); } } diff --git a/src/g_game.c b/src/g_game.c index 4f1c49b42..25730ce7d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2911,7 +2911,7 @@ void G_AfterIntermission(void) if (nextmap < 1100-1) G_NextLevel(); else - Y_EndGame(); + G_EndGame(); } } @@ -2997,6 +2997,38 @@ static void G_DoContinued(void) gameaction = ga_nothing; } +// +// G_EndGame (formerly Y_EndGame) +// Franky this function fits better in g_game.c than it does in y_inter.c +// +// ...Gee, (why) end the game? +// Because Y_FollowIntermission and F_EndCutscene would +// both do this exact same thing *in different ways* otherwise, +// which made it so that you could only unlock Ultimate mode +// if you had a cutscene after the final level and crap like that. +// This function simplifies it so only one place has to be updated +// when something new is added. +void G_EndGame(void) +{ + // Only do evaluation and credits in coop games. + if (gametype == GT_COOP) + { + if (nextmap == 1102-1) // end game with credits + { + F_StartCredits(); + return; + } + if (nextmap == 1101-1) // end game with evaluation + { + F_StartGameEvaluation(); + return; + } + } + + // 1100 or competitive multiplayer, so go back to title screen. + D_StartTitle(); +} + // // G_LoadGameSettings // diff --git a/src/g_game.h b/src/g_game.h index ada82404c..196ba2ea1 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -171,6 +171,7 @@ void G_NextLevel(void); void G_Continue(void); void G_UseContinue(void); void G_AfterIntermission(void); +void G_EndGame(void); // moved from y_inter.c/h and renamed void G_Ticker(boolean run); boolean G_Responder(event_t *ev); diff --git a/src/y_inter.c b/src/y_inter.c index e7df165bf..37c597305 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1794,37 +1794,6 @@ void Y_EndIntermission(void) usebuffer = false; } -// -// Y_EndGame -// -// Why end the game? -// Because Y_FollowIntermission and F_EndCutscene would -// both do this exact same thing *in different ways* otherwise, -// which made it so that you could only unlock Ultimate mode -// if you had a cutscene after the final level and crap like that. -// This function simplifies it so only one place has to be updated -// when something new is added. -void Y_EndGame(void) -{ - // Only do evaluation and credits in coop games. - if (gametype == GT_COOP) - { - if (nextmap == 1102-1) // end game with credits - { - F_StartCredits(); - return; - } - if (nextmap == 1101-1) // end game with evaluation - { - F_StartGameEvaluation(); - return; - } - } - - // 1100 or competitive multiplayer, so go back to title screen. - D_StartTitle(); -} - // // Y_FollowIntermission // @@ -1850,7 +1819,7 @@ static void Y_FollowIntermission(void) return; } - Y_EndGame(); + G_EndGame(); } #define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL diff --git a/src/y_inter.h b/src/y_inter.h index 9fe95fcc4..26f7dc390 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -15,7 +15,6 @@ void Y_IntermissionDrawer(void); void Y_Ticker(void); void Y_StartIntermission(void); void Y_EndIntermission(void); -void Y_EndGame(void); typedef enum { From 2bb7df5f49d90ac9f8c4d80ec5bbfeb11c9a064e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 18 May 2017 17:10:44 +0100 Subject: [PATCH 107/264] G_ExitLevel tweak: Use HU_ClearCEcho() instead of HU_DoCEcho(""), the latter causes an empty line to appear in log.txt --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 25730ce7d..d145fcbef 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2615,7 +2615,7 @@ void G_ExitLevel(void) CONS_Printf(M_GetText("The round has ended.\n")); // Remove CEcho text on round end. - HU_DoCEcho(""); + HU_ClearCEcho(); } } From feceaf6d30144e19ef64e773705b637b242c7b05 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 18 May 2017 17:23:19 +0100 Subject: [PATCH 108/264] Removed all code in Y_FollowIntermission that's already handled in G_AfterIntermission Only real difference here is that CEcho messages will always be cleared when going to credits/evaluation, but that's hardly a loss tbh. --- src/g_game.c | 4 ++-- src/y_inter.c | 19 ++++--------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index d145fcbef..b8df32f90 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2999,10 +2999,10 @@ static void G_DoContinued(void) // // G_EndGame (formerly Y_EndGame) -// Franky this function fits better in g_game.c than it does in y_inter.c +// Frankly this function fits better in g_game.c than it does in y_inter.c // // ...Gee, (why) end the game? -// Because Y_FollowIntermission and F_EndCutscene would +// Because G_AfterIntermission and F_EndCutscene would // both do this exact same thing *in different ways* otherwise, // which made it so that you could only unlock Ultimate mode // if you had a cutscene after the final level and crap like that. diff --git a/src/y_inter.c b/src/y_inter.c index 37c597305..9d41caf36 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1805,21 +1805,10 @@ static void Y_FollowIntermission(void) return; } - if (nextmap < 1100-1) - { - // normal level - G_AfterIntermission(); - return; - } - - // Start a custom cutscene if there is one. - if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking) - { - F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); - return; - } - - G_EndGame(); + // This handles whether to play a post-level cutscene, end the game, + // or simply go to the next level. + // No need to duplicate the code here! + G_AfterIntermission(); } #define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL From b3faed190b4838ee88f88d75524ad228b690f195 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 11 Oct 2018 16:29:43 -0400 Subject: [PATCH 109/264] Move commands and console variable into s_sound.c --- src/d_netcmd.c | 95 ------------------------------------------------ src/d_netcmd.h | 6 +--- src/s_sound.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/s_sound.h | 1 + 4 files changed, 100 insertions(+), 100 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index bf26ca61a..a8e02bab6 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -128,8 +128,6 @@ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void); static void Command_Playintro_f(void); static void Command_Displayplayer_f(void); -static void Command_Tunes_f(void); -static void Command_RestartAudio_f(void); static void Command_ExitLevel_f(void); static void Command_Showmap_f(void); @@ -319,7 +317,6 @@ consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display -consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}}; consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, @@ -668,9 +665,6 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_ghost_guest); COM_AddCommand("displayplayer", Command_Displayplayer_f); - COM_AddCommand("tunes", Command_Tunes_f); - COM_AddCommand("restartaudio", Command_RestartAudio_f); - CV_RegisterVar(&cv_resetmusic); // FIXME: not to be here.. but needs be done for config loading CV_RegisterVar(&cv_usegamma); @@ -3881,95 +3875,6 @@ static void Command_Displayplayer_f(void) CONS_Printf(M_GetText("Displayplayer is %d\n"), displayplayer); } -static void Command_Tunes_f(void) -{ - const char *tunearg; - UINT16 tunenum, track = 0; - const size_t argc = COM_Argc(); - - if (argc < 2) //tunes slot ... - { - CONS_Printf("tunes [track] [speed] / <-show> / <-default> / <-none>:\n"); - CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n")); - CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n")); - CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n")); - CONS_Printf(M_GetText("* With \"-default\", returns to the default music for the map.\n")); - CONS_Printf(M_GetText("* With \"-none\", any music playing will be stopped.\n")); - return; - } - - tunearg = COM_Argv(1); - tunenum = (UINT16)atoi(tunearg); - track = 0; - - if (!strcasecmp(tunearg, "-show")) - { - CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"), - mapmusname, (mapmusflags & MUSIC_TRACKMASK)); - return; - } - if (!strcasecmp(tunearg, "-none")) - { - S_StopMusic(); - return; - } - else if (!strcasecmp(tunearg, "-default")) - { - tunearg = mapheaderinfo[gamemap-1]->musname; - track = mapheaderinfo[gamemap-1]->mustrack; - } - else if (!tunearg[2] && toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z') - tunenum = (UINT16)M_MapNumber(tunearg[0], tunearg[1]); - - if (tunenum && tunenum >= 1036) - { - CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n")); - return; - } - if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case - CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n")); - - if (argc > 2) - track = (UINT16)atoi(COM_Argv(2))-1; - - if (tunenum) - snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum)); - else - strncpy(mapmusname, tunearg, 7); - mapmusname[6] = 0; - mapmusflags = (track & MUSIC_TRACKMASK); - - S_ChangeMusic(mapmusname, mapmusflags, true); - - if (argc > 3) - { - float speed = (float)atof(COM_Argv(3)); - if (speed > 0.0f) - S_SpeedMusic(speed); - } -} - -static void Command_RestartAudio_f(void) -{ - if (dedicated) // No point in doing anything if game is a dedicated server. - return; - - S_StopMusic(); - I_ShutdownMusic(); - I_ShutdownSound(); - I_StartupSound(); - I_InitMusic(); - -// These must be called or no sound and music until manually set. - - I_SetSfxVolume(cv_soundvolume.value); - I_SetDigMusicVolume(cv_digmusicvolume.value); - I_SetMIDIMusicVolume(cv_midimusicvolume.value); - if (Playing()) // Gotta make sure the player is in a level - P_RestoreMusic(&players[consoleplayer]); - -} - /** Quits a game and returns to the title screen. * */ diff --git a/src/d_netcmd.h b/src/d_netcmd.h index d8fae72f7..7427252de 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -109,8 +109,6 @@ extern consvar_t cv_startinglives; // for F_finale.c extern consvar_t cv_rollingdemos; -extern consvar_t cv_resetmusic; - extern consvar_t cv_ringslinger, cv_soundtest; extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes; @@ -219,6 +217,4 @@ void D_SetPassword(const char *pw); // used for the player setup menu UINT8 CanChangeSkin(INT32 playernum); -#endif - - +#endif \ No newline at end of file diff --git a/src/s_sound.c b/src/s_sound.c index 76ee4c649..33c614051 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -36,6 +36,7 @@ extern INT32 msg_id; #include "d_main.h" #include "r_sky.h" // skyflatnum #include "p_local.h" // camera info +#include "m_misc.h" // for tunes command #ifdef HW3SOUND // 3D Sound Interface @@ -46,6 +47,8 @@ static INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, I CV_PossibleValue_t soundvolume_cons_t[] = {{0, "MIN"}, {31, "MAX"}, {0, NULL}}; static void SetChannelsNum(void); +static void Command_Tunes_f(void); +static void Command_RestartAudio_f(void); // commands for music and sound servers #ifdef MUSSERV @@ -89,6 +92,7 @@ consvar_t cv_numChannels = {"snd_channels", "32", CV_SAVE|CV_CALL, CV_Unsigned, #endif static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; #define S_MAX_VOLUME 127 @@ -243,6 +247,11 @@ void S_RegisterSoundStuff(void) #endif CV_RegisterVar(&surround); CV_RegisterVar(&cv_samplerate); + CV_RegisterVar(&cv_resetmusic); + + COM_AddCommand("tunes", Command_Tunes_f); + COM_AddCommand("restartaudio", Command_RestartAudio_f); + #if defined (macintosh) && !defined (HAVE_SDL) // mp3 playlist stuff { @@ -1431,3 +1440,92 @@ void S_ResumeAudio(void) // resume cd music I_ResumeCD(); } + +static void Command_Tunes_f(void) +{ + const char *tunearg; + UINT16 tunenum, track = 0; + const size_t argc = COM_Argc(); + + if (argc < 2) //tunes slot ... + { + CONS_Printf("tunes [track] [speed] / <-show> / <-default> / <-none>:\n"); + CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n")); + CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n")); + CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n")); + CONS_Printf(M_GetText("* With \"-default\", returns to the default music for the map.\n")); + CONS_Printf(M_GetText("* With \"-none\", any music playing will be stopped.\n")); + return; + } + + tunearg = COM_Argv(1); + tunenum = (UINT16)atoi(tunearg); + track = 0; + + if (!strcasecmp(tunearg, "-show")) + { + CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"), + mapmusname, (mapmusflags & MUSIC_TRACKMASK)); + return; + } + if (!strcasecmp(tunearg, "-none")) + { + S_StopMusic(); + return; + } + else if (!strcasecmp(tunearg, "-default")) + { + tunearg = mapheaderinfo[gamemap-1]->musname; + track = mapheaderinfo[gamemap-1]->mustrack; + } + else if (!tunearg[2] && toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z') + tunenum = (UINT16)M_MapNumber(tunearg[0], tunearg[1]); + + if (tunenum && tunenum >= 1036) + { + CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n")); + return; + } + if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case + CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n")); + + if (argc > 2) + track = (UINT16)atoi(COM_Argv(2))-1; + + if (tunenum) + snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum)); + else + strncpy(mapmusname, tunearg, 7); + mapmusname[6] = 0; + mapmusflags = (track & MUSIC_TRACKMASK); + + S_ChangeMusic(mapmusname, mapmusflags, true); + + if (argc > 3) + { + float speed = (float)atof(COM_Argv(3)); + if (speed > 0.0f) + S_SpeedMusic(speed); + } +} + +static void Command_RestartAudio_f(void) +{ + if (dedicated) // No point in doing anything if game is a dedicated server. + return; + + S_StopMusic(); + I_ShutdownMusic(); + I_ShutdownSound(); + I_StartupSound(); + I_InitMusic(); + +// These must be called or no sound and music until manually set. + + I_SetSfxVolume(cv_soundvolume.value); + I_SetDigMusicVolume(cv_digmusicvolume.value); + I_SetMIDIMusicVolume(cv_midimusicvolume.value); + if (Playing()) // Gotta make sure the player is in a level + P_RestoreMusic(&players[consoleplayer]); + +} \ No newline at end of file diff --git a/src/s_sound.h b/src/s_sound.h index 39ec769a6..083815e15 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -25,6 +25,7 @@ extern consvar_t stereoreverse; extern consvar_t cv_soundvolume, cv_digmusicvolume, cv_midimusicvolume; extern consvar_t cv_numChannels; +extern consvar_t cv_resetmusic; #ifdef SNDSERV extern consvar_t sndserver_cmd, sndserver_arg; From 8ab4915b5bf83cc336e0666301b84e41807623e8 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 11 Oct 2018 21:44:25 +0100 Subject: [PATCH 110/264] Whoops these should be L not gL here (not that it makes much difference normally though) --- src/dehacked.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index f6288f487..6c39fc197 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8869,17 +8869,17 @@ static int lib_getActionName(lua_State *L) { lua_settop(L, 1); // set top of stack to 1 (removing any extra args, which there shouldn't be) // get the name for this action, if possible. - lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS); - lua_pushnil(gL); + lua_getfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS); + lua_pushnil(L); // Lua stack at this point: // 1 ... -2 -1 // arg ... LREG_ACTIONS nil - while (lua_next(gL, -2)) + while (lua_next(L, -2)) { // Lua stack at this point: // 1 ... -3 -2 -1 // arg ... LREG_ACTIONS "A_ACTION" function - if (lua_rawequal(gL, -1, 1)) // is this the same as the arg? + if (lua_rawequal(L, -1, 1)) // is this the same as the arg? { // make sure the key (i.e. "A_ACTION") is a string first // (note: we don't use lua_isstring because it also returns true for numbers) @@ -8888,12 +8888,12 @@ static int lib_getActionName(lua_State *L) lua_pushvalue(L, -2); // push "A_ACTION" string to top of stack return 1; } - lua_pop(gL, 2); // pop the name and function + lua_pop(L, 2); // pop the name and function break; // probably should have succeeded but we didn't, so end the loop } - lua_pop(gL, 1); + lua_pop(L, 1); } - lua_pop(gL, 1); // pop LREG_ACTIONS + lua_pop(L, 1); // pop LREG_ACTIONS return 0; // return nothing (don't error) } From 450b536147b6bf36f879ee0a5ae9164d32f15c72 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 11 Oct 2018 20:11:37 -0400 Subject: [PATCH 111/264] Remove the condition in restartaudio command. No longer needed as S_RegisterSoundStuff will return early if in dedicated mode. --- src/s_sound.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 33c614051..a79e56ce5 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1511,9 +1511,6 @@ static void Command_Tunes_f(void) static void Command_RestartAudio_f(void) { - if (dedicated) // No point in doing anything if game is a dedicated server. - return; - S_StopMusic(); I_ShutdownMusic(); I_ShutdownSound(); @@ -1527,5 +1524,4 @@ static void Command_RestartAudio_f(void) I_SetMIDIMusicVolume(cv_midimusicvolume.value); if (Playing()) // Gotta make sure the player is in a level P_RestoreMusic(&players[consoleplayer]); - } \ No newline at end of file From 6184f91dd3bd82164282c7379d457ffcea5e5a8c Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 13 Oct 2018 23:01:11 +0100 Subject: [PATCH 112/264] Add an int to I_PlaySound to tell an interface which channel number SRB2 is using. I've voided this out on other sound interfaces than SDL Mixer ones because I'm both not sure whether they need it, and not sure how to make them work with it if they do. --- src/djgppdos/i_sound.c | 4 +++- src/dummy/i_sound.c | 3 ++- src/i_sound.h | 2 +- src/nds/i_sound.c | 3 ++- src/s_sound.c | 4 ++-- src/sdl/mixer_sound.c | 4 ++-- src/sdl/sdl_sound.c | 3 ++- src/sdl12/mixer_sound.c | 4 ++-- src/sdl12/sdl_sound.c | 3 ++- src/win32/win_snd.c | 3 ++- src/win32ce/win_snd.c | 4 +++- 11 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c index 88fc807f4..f1e2ad2bf 100644 --- a/src/djgppdos/i_sound.c +++ b/src/djgppdos/i_sound.c @@ -165,9 +165,11 @@ INT32 I_StartSound ( sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, - INT32 priority ) + INT32 priority + INT32 channel) { int voice; + (void)channel; if (nosound) return 0; diff --git a/src/dummy/i_sound.c b/src/dummy/i_sound.c index 51dbb610d..143da186c 100644 --- a/src/dummy/i_sound.c +++ b/src/dummy/i_sound.c @@ -23,13 +23,14 @@ void I_UpdateSound(void){}; // SFX I/O // -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) { (void)id; (void)vol; (void)sep; (void)pitch; (void)priority; + (void)channel; return -1; } diff --git a/src/i_sound.h b/src/i_sound.h index 084479ee1..098c9be17 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -64,7 +64,7 @@ void I_ShutdownSound(void); \return sfx handle */ -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority); +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel); /** \brief Stops a sound channel. diff --git a/src/nds/i_sound.c b/src/nds/i_sound.c index 8dea4ad7d..a17c7f66a 100644 --- a/src/nds/i_sound.c +++ b/src/nds/i_sound.c @@ -21,13 +21,14 @@ void I_ShutdownSound(void){} // SFX I/O // -INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority) +INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority, INT32 channel) { (void)id; (void)vol; (void)sep; (void)pitch; (void)priority; + (void)channel; return -1; } diff --git a/src/s_sound.c b/src/s_sound.c index 76ee4c649..3b35b36f6 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -529,7 +529,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) // Assigns the handle to one of the channels in the // mix/output buffer. - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority); + channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); } dontplay: @@ -579,7 +579,7 @@ dontplay: // Assigns the handle to one of the channels in the // mix/output buffer. - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority); + channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); } void S_StartSound(const void *origin, sfxenum_t sfx_id) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index cfdb32303..4b4ad3e62 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -419,10 +419,10 @@ void I_FreeSfx(sfxinfo_t *sfx) sfx->lumpnum = LUMPERROR; } -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) { UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 - INT32 handle = Mix_PlayChannel(-1, S_sfx[id].data, 0); + INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0); Mix_Volume(handle, volume); Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff)); (void)pitch; // Mixer can't handle pitch diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 6c70c163b..a7c8383a3 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -604,10 +604,11 @@ void I_FreeSfx(sfxinfo_t * sfx) // Pitching (that is, increased speed of playback) // is set, but currently not used by mixing. // -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) { (void)priority; (void)pitch; + (void)channel; if (nosound) return 0; diff --git a/src/sdl12/mixer_sound.c b/src/sdl12/mixer_sound.c index 542a67169..daf09ab91 100644 --- a/src/sdl12/mixer_sound.c +++ b/src/sdl12/mixer_sound.c @@ -376,10 +376,10 @@ void I_FreeSfx(sfxinfo_t *sfx) sfx->data = NULL; } -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) { UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 - INT32 handle = Mix_PlayChannel(-1, S_sfx[id].data, 0); + INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0); Mix_Volume(handle, volume); Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff)); (void)pitch; // Mixer can't handle pitch diff --git a/src/sdl12/sdl_sound.c b/src/sdl12/sdl_sound.c index 6ba83104e..01a27153e 100644 --- a/src/sdl12/sdl_sound.c +++ b/src/sdl12/sdl_sound.c @@ -621,10 +621,11 @@ void I_FreeSfx(sfxinfo_t * sfx) // Pitching (that is, increased speed of playback) // is set, but currently not used by mixing. // -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) { (void)priority; (void)pitch; + (void)channel; if (nosound) return 0; diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c index 58644457a..e50a4737e 100644 --- a/src/win32/win_snd.c +++ b/src/win32/win_snd.c @@ -353,12 +353,13 @@ void I_FreeSfx(sfxinfo_t *sfx) sfx->data = NULL; } -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) { FMOD_SOUND *sound; FMOD_CHANNEL *chan; INT32 i; float frequency; + (void)channel; sound = (FMOD_SOUND *)S_sfx[id].data; I_Assert(sound != NULL); diff --git a/src/win32ce/win_snd.c b/src/win32ce/win_snd.c index f9c652178..a58bbc3ce 100644 --- a/src/win32ce/win_snd.c +++ b/src/win32ce/win_snd.c @@ -538,7 +538,8 @@ INT32 I_StartSound (sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, - INT32 priority) + INT32 priority + INT32 channel) { HRESULT hr; LPDIRECTSOUNDBUFFER dsbuffer; @@ -549,6 +550,7 @@ INT32 I_StartSound (sfxenum_t id, #ifdef SURROUND LPDIRECTSOUNDBUFFER dssurround; #endif + (void)channel; if (nosound) return -1; From 3886888b3014da650aa2ae5bd843b8ef7dcea28f Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 14 Oct 2018 10:14:07 +0100 Subject: [PATCH 113/264] Fix missing commas and missed interface --- src/android/i_sound.c | 3 ++- src/djgppdos/i_sound.c | 2 +- src/win32ce/win_snd.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/android/i_sound.c b/src/android/i_sound.c index ecf96f2f0..77f8e6a55 100644 --- a/src/android/i_sound.c +++ b/src/android/i_sound.c @@ -21,13 +21,14 @@ void I_ShutdownSound(void){} // SFX I/O // -INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority) +INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority, INT32 channel) { (void)id; (void)vol; (void)sep; (void)pitch; (void)priority; + (void)channel; return -1; } diff --git a/src/djgppdos/i_sound.c b/src/djgppdos/i_sound.c index f1e2ad2bf..ec6f4412f 100644 --- a/src/djgppdos/i_sound.c +++ b/src/djgppdos/i_sound.c @@ -165,7 +165,7 @@ INT32 I_StartSound ( sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, - INT32 priority + INT32 priority, INT32 channel) { int voice; diff --git a/src/win32ce/win_snd.c b/src/win32ce/win_snd.c index a58bbc3ce..14ce4add4 100644 --- a/src/win32ce/win_snd.c +++ b/src/win32ce/win_snd.c @@ -538,7 +538,7 @@ INT32 I_StartSound (sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, - INT32 priority + INT32 priority, INT32 channel) { HRESULT hr; From 7d612011949d117f568f99c6012084bb6056f67a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 20 Oct 2018 12:54:40 +0100 Subject: [PATCH 114/264] Fix slipup from when the smashing spikeballs from HHZ were hardcoded --- src/info.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index 728fb13c0..3140bd7de 100644 --- a/src/info.c +++ b/src/info.c @@ -3458,8 +3458,8 @@ state_t states[NUMSTATES] = {SPR_FMCE, 0, 20, {NULL}, 0, 0, S_SMASHSPIKE_EASE1}, // S_SMASHSPIKE_FLOAT {SPR_FMCE, 0, 4, {A_ZThrust}, 4, (1<<16)|1, S_SMASHSPIKE_EASE2}, // S_SMASHSPIKE_EASE1 - {SPR_FMCE, 0, 4, {A_ZThrust}, 0, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_EASE1 - {SPR_FMCE, 0, 2, {A_ZThrust}, -6, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_FALL + {SPR_FMCE, 0, 4, {A_ZThrust}, 0, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_EASE2 + {SPR_FMCE, 0, 2, {A_ZThrust}, -6, 1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_FALL {SPR_FMCE, 1, 2, {A_MultiShotDist}, (MT_DUST<<16)|10, -48, S_SMASHSPIKE_STOMP2}, // S_SMASHSPIKE_STOMP1 {SPR_FMCE, 2, 14, {NULL}, 0, 0, S_SMASHSPIKE_RISE1}, // S_SMASHSPIKE_STOMP2 {SPR_FMCE, 1, 2, {NULL}, 0, 0, S_SMASHSPIKE_RISE2}, // S_SMASHSPIKE_RISE1 From 61fa7026a107e30688bf836e0fc7c6a7c9f77861 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 20 Oct 2018 19:00:37 +0100 Subject: [PATCH 115/264] add vector2 and vector3 userdata types to simplify getting a slope's o/d/normal --- src/lua_libs.h | 2 ++ src/lua_maplib.c | 82 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/lua_libs.h b/src/lua_libs.h index bf7fe03e9..a9c82bce2 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -39,6 +39,8 @@ extern lua_State *gL; #define META_SECTOR "SECTOR_T*" #define META_FFLOOR "FFLOOR_T*" #define META_SLOPE "PSLOPE_T*" +#define META_VECTOR2 "VECTOR2_T" +#define META_VECTOR3 "VECTOR3_T" #define META_MAPHEADER "MAPHEADER_T*" #define META_CVAR "CONSVAR_T*" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 7a94060e5..e769a00dc 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -223,6 +223,19 @@ static const char *const slope_opt[] = { "flags", NULL}; +// shared by both vector2_t and vector3_t +enum vector_e { + vector_x = 0, + vector_y, + vector_z +}; + +static const char *const vector_opt[] = { + "x", + "y", + "z", + NULL}; + static const char *const array_opt[] ={"iterate",NULL}; static const char *const valid_opt[] ={"valid",NULL}; @@ -1232,32 +1245,16 @@ static int slope_get(lua_State *L) lua_pushboolean(L, 1); return 1; case slope_o: // o - lua_createtable(L, 0, 3); - lua_pushfixed(L, slope->o.x); - lua_setfield(L, -2, "x"); - lua_pushfixed(L, slope->o.y); - lua_setfield(L, -2, "y"); - lua_pushfixed(L, slope->o.z); - lua_setfield(L, -2, "z"); + LUA_PushUserdata(L, &slope->o, META_VECTOR3); return 1; case slope_d: // d - lua_createtable(L, 0, 2); - lua_pushfixed(L, slope->d.x); - lua_setfield(L, -2, "x"); - lua_pushfixed(L, slope->d.y); - lua_setfield(L, -2, "y"); + LUA_PushUserdata(L, &slope->d, META_VECTOR2); return 1; case slope_zdelta: // zdelta lua_pushfixed(L, slope->zdelta); return 1; case slope_normal: // normal - lua_createtable(L, 0, 3); - lua_pushfixed(L, slope->normal.x); - lua_setfield(L, -2, "x"); - lua_pushfixed(L, slope->normal.y); - lua_setfield(L, -2, "y"); - lua_pushfixed(L, slope->normal.z); - lua_setfield(L, -2, "z"); + LUA_PushUserdata(L, &slope->normal, META_VECTOR3); return 1; case slope_zangle: // zangle lua_pushangle(L, slope->zangle); @@ -1358,6 +1355,43 @@ static int slope_set(lua_State *L) return 0; } +static int vector2_get(lua_State *L) +{ + vector2_t *vec = *((vector2_t **)luaL_checkudata(L, 1, META_VECTOR2)); + enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt); + + if (!vec) + return luaL_error(L, "accessed vector2_t doesn't exist anymore."); + + switch(field) + { + case vector_x: lua_pushfixed(L, vec->x); return 1; + case vector_y: lua_pushfixed(L, vec->y); return 1; + default: break; + } + + return 0; +} + +static int vector3_get(lua_State *L) +{ + vector3_t *vec = *((vector3_t **)luaL_checkudata(L, 1, META_VECTOR3)); + enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt); + + if (!vec) + return luaL_error(L, "accessed vector3_t doesn't exist anymore."); + + switch(field) + { + case vector_x: lua_pushfixed(L, vec->x); return 1; + case vector_y: lua_pushfixed(L, vec->y); return 1; + case vector_z: lua_pushfixed(L, vec->z); return 1; + default: break; + } + + return 0; +} + static int lib_getMapheaderinfo(lua_State *L) { // i -> mapheaderinfo[i-1] @@ -1542,6 +1576,16 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); + luaL_newmetatable(L, META_VECTOR2); + lua_pushcfunction(L, vector2_get); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); + + luaL_newmetatable(L, META_VECTOR3); + lua_pushcfunction(L, vector3_get); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); + luaL_newmetatable(L, META_MAPHEADER); lua_pushcfunction(L, mapheaderinfo_get); lua_setfield(L, -2, "__index"); From 4edeeb69539267dce61e9841c564632dc6cad20d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 20 Oct 2018 21:08:59 +0100 Subject: [PATCH 116/264] Add P_GetZAt to Lua --- src/lua_baselib.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e8e8fd020..f60756f1c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -14,6 +14,9 @@ #ifdef HAVE_BLUA #include "p_local.h" #include "p_setup.h" // So we can have P_SetupLevelSky +#ifdef ESLOPE +#include "p_slopes.h" // P_GetZAt +#endif #include "z_zone.h" #include "r_main.h" #include "r_things.h" @@ -1547,6 +1550,24 @@ static int lib_evCrumbleChain(lua_State *L) return 0; } +#ifdef ESLOPE +// P_SLOPES +//////////// + +static int lib_pGetZAt(lua_State *L) +{ + pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + //HUDSAFE + if (!slope) + return LUA_ErrInvalid(L, "pslope_t"); + + lua_pushfixed(L, P_GetZAt(slope, x, y)); + return 1; +} +#endif + // R_DEFS //////////// @@ -2113,6 +2134,11 @@ static luaL_Reg lib[] = { {"P_StartQuake",lib_pStartQuake}, {"EV_CrumbleChain",lib_evCrumbleChain}, +#ifdef ESLOPE + // p_slopes + {"P_GetZAt",lib_pGetZAt}, +#endif + // r_defs {"R_PointToAngle",lib_rPointToAngle}, {"R_PointToAngle2",lib_rPointToAngle2}, From 9296aaa28c720057b4b0752c82256701ee0ae6ac Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 20 Oct 2018 23:36:06 +0100 Subject: [PATCH 117/264] zangle should be shifted down by ANGLETOFINESHIFT if we're to use FINETANGENT on it --- src/lua_maplib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index e769a00dc..7635ded1c 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1344,7 +1344,7 @@ static int slope_set(lua_State *L) } case slope_zangle: // zangle slope->zangle = luaL_checkangle(L, 3); - slope->zdelta = FINETANGENT(slope->zangle); + slope->zdelta = FINETANGENT(slope->zangle>>ANGLETOFINESHIFT); P_CalculateSlopeNormal(slope); break; case slope_xydirection: // xydirection From 2ec4f2024f784af6bc5562cbd0e5f62d5d722d1a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 21 Oct 2018 15:00:07 +0100 Subject: [PATCH 118/264] Added support for pslope_t userdata variables in Lua archive/unarchive code --- src/lua_script.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/lua_script.c b/src/lua_script.c index ddfbf5c70..0440efd58 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -22,6 +22,9 @@ #include "byteptr.h" #include "p_saveg.h" #include "p_local.h" +#ifdef ESLOPE +#include "p_slopes.h" // for P_SlopeById +#endif #ifdef LUA_ALLOW_BYTECODE #include "d_netfil.h" // for LUA_DumpFile #endif @@ -457,6 +460,9 @@ enum ARCH_SIDE, ARCH_SUBSECTOR, ARCH_SECTOR, +#ifdef ESLOPE + ARCH_SLOPE, +#endif ARCH_MAPHEADER, ARCH_TEND=0xFF, @@ -476,6 +482,9 @@ static const struct { {META_SIDE, ARCH_SIDE}, {META_SUBSECTOR,ARCH_SUBSECTOR}, {META_SECTOR, ARCH_SECTOR}, +#ifdef ESLOPE + {META_SLOPE, ARCH_SLOPE}, +#endif {META_MAPHEADER, ARCH_MAPHEADER}, {NULL, ARCH_NULL} }; @@ -680,6 +689,19 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) } break; } +#ifdef ESLOPE + case ARCH_SLOPE: + { + pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex)); + if (!slope) + WRITEUINT8(save_p, ARCH_NULL); + else { + WRITEUINT8(save_p, ARCH_SLOPE); + WRITEUINT16(save_p, slope->id); + } + break; + } +#endif case ARCH_MAPHEADER: { mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex)); @@ -884,6 +906,11 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_SECTOR: LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR); break; +#ifdef ESLOPE + case ARCH_SLOPE: + LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE); + break; +#endif case ARCH_MAPHEADER: LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_MAPHEADER); break; From efff869e6e1e15b616f425ba84ce4d339e7052e3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 21 Oct 2018 15:12:51 +0100 Subject: [PATCH 119/264] Add mobj.standingslope to Lua --- src/lua_mobjlib.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 6bb1388fc..05091f126 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -80,7 +80,12 @@ enum mobj_e { mobj_extravalue1, mobj_extravalue2, mobj_cusval, +#ifdef ESLOPE + mobj_cvmem, + mobj_standingslope +#else mobj_cvmem +#endif }; static const char *const mobj_opt[] = { @@ -140,6 +145,9 @@ static const char *const mobj_opt[] = { "extravalue2", "cusval", "cvmem", +#ifdef ESLOPE + "standingslope", +#endif NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) @@ -343,6 +351,11 @@ static int mobj_get(lua_State *L) case mobj_cvmem: lua_pushinteger(L, mo->cvmem); break; +#ifdef ESLOPE + case mobj_standingslope: + LUA_PushUserdata(L, mo->standingslope, META_SLOPE); + break; +#endif default: // extra custom variables in Lua memory lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -634,6 +647,10 @@ static int mobj_set(lua_State *L) case mobj_cvmem: mo->cvmem = luaL_checkinteger(L, 3); break; +#ifdef ESLOPE + case mobj_standingslope: + return NOSET; +#endif default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); From 87afae9cf598922543e36df9efb16230bee36006 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 21 Oct 2018 15:15:54 +0100 Subject: [PATCH 120/264] Fix unarchiving of mapheader_t userdata Lua variables --- src/lua_script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_script.c b/src/lua_script.c index 1c1b01f6c..9b87f0c29 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -853,7 +853,7 @@ static UINT8 UnArchiveValue(int TABLESINDEX) LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR); break; case ARCH_MAPHEADER: - LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_MAPHEADER); + LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER); break; case ARCH_TEND: return 1; From e15ed742c124f556ebebd4983e9f09136fa7cca3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 21 Oct 2018 16:27:54 +0100 Subject: [PATCH 121/264] add ESLOPE ifdef checks around all the Lua slope support code that was there before I was involved --- src/dehacked.c | 2 ++ src/lua_libs.h | 2 ++ src/lua_maplib.c | 24 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 251b0532a..d470c7fa9 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7261,11 +7261,13 @@ struct { {"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. +#ifdef ESLOPE // Slope flags {"SL_NOPHYSICS",SL_NOPHYSICS}, // Don't do momentum adjustment with this slope {"SL_NODYNAMIC",SL_NODYNAMIC}, // Slope will never need to move during the level, so don't fuss with recalculating it {"SL_ANCHORVERTEX",SL_ANCHORVERTEX},// Slope is using a Slope Vertex Thing to anchor its position {"SL_VERTEXSLOPE",SL_VERTEXSLOPE}, // Slope is built from three Slope Vertex Things +#endif // Angles {"ANG1",ANG1}, diff --git a/src/lua_libs.h b/src/lua_libs.h index a9c82bce2..15d988ef6 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -38,9 +38,11 @@ extern lua_State *gL; #define META_SUBSECTOR "SUBSECTOR_T*" #define META_SECTOR "SECTOR_T*" #define META_FFLOOR "FFLOOR_T*" +#ifdef ESLOPE #define META_SLOPE "PSLOPE_T*" #define META_VECTOR2 "VECTOR2_T" #define META_VECTOR3 "VECTOR3_T" +#endif #define META_MAPHEADER "MAPHEADER_T*" #define META_CVAR "CONSVAR_T*" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 7635ded1c..d83634291 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -40,10 +40,14 @@ enum sector_e { sector_heightsec, sector_camsec, sector_lines, +#ifdef ESLOPE sector_ffloors, sector_fslope, sector_cslope, sector_hasslope +#else + sector_ffloors +#endif }; static const char *const sector_opt[] = { @@ -60,9 +64,11 @@ static const char *const sector_opt[] = { "camsec", "lines", "ffloors", +#ifdef ESLOPE "f_slope", "c_slope", "hasslope", +#endif NULL}; enum subsector_e { @@ -168,8 +174,10 @@ enum ffloor_e { ffloor_toplightlevel, ffloor_bottomheight, ffloor_bottompic, +#ifdef ESLOPE ffloor_tslope, ffloor_bslope, +#endif ffloor_sector, ffloor_flags, ffloor_master, @@ -186,8 +194,10 @@ static const char *const ffloor_opt[] = { "toplightlevel", "bottomheight", "bottompic", +#ifdef ESLOPE "t_slope", "b_slope", +#endif "sector", // secnum pushed as control sector userdata "flags", "master", // control linedef @@ -197,6 +207,7 @@ static const char *const ffloor_opt[] = { "alpha", NULL}; +#ifdef ESLOPE enum slope_e { slope_valid = 0, slope_o, @@ -235,6 +246,7 @@ static const char *const vector_opt[] = { "y", "z", NULL}; +#endif static const char *const array_opt[] ={"iterate",NULL}; static const char *const valid_opt[] ={"valid",NULL}; @@ -450,6 +462,7 @@ static int sector_get(lua_State *L) LUA_PushUserdata(L, sector->ffloors, META_FFLOOR); lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function return 1; +#ifdef ESLOPE case sector_fslope: // f_slope LUA_PushUserdata(L, sector->f_slope, META_SLOPE); return 1; @@ -459,6 +472,7 @@ static int sector_get(lua_State *L) case sector_hasslope: // hasslope lua_pushboolean(L, sector->hasslope); return 1; +#endif } return 0; } @@ -481,9 +495,11 @@ static int sector_set(lua_State *L) case sector_heightsec: // heightsec case sector_camsec: // camsec case sector_ffloors: // ffloors +#ifdef ESLOPE case sector_fslope: // f_slope case sector_cslope: // c_slope case sector_hasslope: // hasslope +#endif default: return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); case sector_floorheight: { // floorheight @@ -1118,12 +1134,14 @@ static int ffloor_get(lua_State *L) lua_pushlstring(L, levelflat->name, 8); return 1; } +#ifdef ESLOPE case ffloor_tslope: LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE); return 1; case ffloor_bslope: LUA_PushUserdata(L, *ffloor->b_slope, META_SLOPE); return 1; +#endif case ffloor_sector: LUA_PushUserdata(L, §ors[ffloor->secnum], META_SECTOR); return 1; @@ -1163,8 +1181,10 @@ static int ffloor_set(lua_State *L) switch(field) { case ffloor_valid: // valid +#ifdef ESLOPE case ffloor_tslope: // t_slope case ffloor_bslope: // b_slope +#endif case ffloor_sector: // sector case ffloor_master: // master case ffloor_target: // target @@ -1225,6 +1245,7 @@ static int ffloor_set(lua_State *L) return 0; } +#ifdef ESLOPE static int slope_get(lua_State *L) { pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); @@ -1391,6 +1412,7 @@ static int vector3_get(lua_State *L) return 0; } +#endif static int lib_getMapheaderinfo(lua_State *L) { @@ -1568,6 +1590,7 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); +#ifdef ESLOPE luaL_newmetatable(L, META_SLOPE); lua_pushcfunction(L, slope_get); lua_setfield(L, -2, "__index"); @@ -1585,6 +1608,7 @@ int LUA_MapLib(lua_State *L) lua_pushcfunction(L, vector3_get); lua_setfield(L, -2, "__index"); lua_pop(L, 1); +#endif luaL_newmetatable(L, META_MAPHEADER); lua_pushcfunction(L, mapheaderinfo_get); From 3ec8743c1bbdec71ecaa7d4d4cd41a3f00f1516c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 21 Oct 2018 17:32:53 +0100 Subject: [PATCH 122/264] Fix up the ability to edit slope zdelta and zangle with Lua (zangle is untested as of writing) --- src/lua_maplib.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index d83634291..975ea1cb1 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1359,15 +1359,19 @@ static int slope_set(lua_State *L) } case slope_zdelta: { // zdelta, this is temp until i figure out wtf to do slope->zdelta = luaL_checkfixed(L, 3); - slope->zangle = R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta); + slope->zangle = R_PointToAngle2(0, 0, FRACUNIT, -slope->zdelta); P_CalculateSlopeNormal(slope); break; } - case slope_zangle: // zangle - slope->zangle = luaL_checkangle(L, 3); - slope->zdelta = FINETANGENT(slope->zangle>>ANGLETOFINESHIFT); + case slope_zangle: { // zangle + angle_t zangle = luaL_checkangle(L, 3); + if (zangle == ANGLE_90 || zangle == ANGLE_270) + return luaL_error(L, "invalid zangle for slope!"); + slope->zangle = zangle; + slope->zdelta = -FINETANGENT(((slope->zangle+ANGLE_90)>>ANGLETOFINESHIFT) & 4095); P_CalculateSlopeNormal(slope); break; + } case slope_xydirection: // xydirection slope->xydirection = luaL_checkangle(L, 3); P_CalculateSlopeNormal(slope); From 772004d3fd8032f6397b43221227af488e82cfd4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 21 Oct 2018 18:25:13 +0100 Subject: [PATCH 123/264] Fix editing slope xydirection with Lua --- src/lua_maplib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 975ea1cb1..2ccb3b5f7 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1374,6 +1374,8 @@ static int slope_set(lua_State *L) } case slope_xydirection: // xydirection slope->xydirection = luaL_checkangle(L, 3); + slope->d.x = -FINECOSINE((slope->xydirection>>ANGLETOFINESHIFT) & FINEMASK); + slope->d.y = -FINESINE((slope->xydirection>>ANGLETOFINESHIFT) & FINEMASK); P_CalculateSlopeNormal(slope); break; } From e95b54e64f2cbb13b79ac46b13b8e104f17f5517 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 21 Oct 2018 20:35:14 +0100 Subject: [PATCH 124/264] missed this ESLOPE-needed area from a few commits ago apparently :V --- src/lua_maplib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 2ccb3b5f7..b59c3c178 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -16,7 +16,9 @@ #include "p_local.h" #include "p_setup.h" #include "z_zone.h" +#ifdef ESLOPE #include "p_slopes.h" +#endif #include "r_main.h" #include "lua_script.h" From ab38e6cebb7765e1fe0ce846e2a30deab285e7d2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 13 Oct 2018 20:44:01 +0100 Subject: [PATCH 125/264] Creating a quick get_WSAErrorStr function to act as a wrapper for FormatMessageA so we can string-ify Winsock errors properly Untested! --- src/i_tcp.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/i_tcp.c b/src/i_tcp.c index 6488e9845..9febd56f0 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -262,6 +262,28 @@ static void wattcp_outch(char s) } #endif +#ifdef USE_WINSOCK +// stupid microsoft makes things complicated +static inline char *get_WSAErrorStr(int e) +{ + char *buf = NULL; + + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + (DWORD)e, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&buf, + 0, NULL); + + return buf; +} +#undef strerror +#define strerror get_WSAErrorStr +#endif + #ifdef USE_WINSOCK2 #define inet_ntop inet_ntopA #define HAVE_NTOP From 3b39a25adec80437e56f8a6d886d220786a889f6 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 27 Oct 2018 15:49:04 +0100 Subject: [PATCH 126/264] Save the result of errno (aka WSAGetLastError() for WinSock) as soon as possible, to prevent anything in SOCK_GetNodeAddress resetting the value to 0 while trying to print the message for the error itself! --- src/i_tcp.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 9febd56f0..6a2127866 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -781,9 +781,13 @@ static void SOCK_Send(void) &clientaddress[doomcom->remotenode].any, d); } - if (c == ERRSOCKET && errno != ECONNREFUSED && errno != EWOULDBLOCK) - I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode, - SOCK_GetNodeAddress(doomcom->remotenode), errno, strerror(errno)); + if (c == ERRSOCKET) + { + int e = errno; // save error code so it can't be modified later + if (e != ECONNREFUSED && e != EWOULDBLOCK) + I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode, + SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e)); + } } #endif From e4e76f83c3e6c4de8ac467667df7daf05d2d9582 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 27 Oct 2018 16:09:14 +0100 Subject: [PATCH 127/264] Use temporary buffer with a max size of 255 bytes instead of having Microsoft's FormatMessageA alloc one for us. Also, provide a fallback message in case no message was available for some reason --- src/i_tcp.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 6a2127866..c054b3a4a 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -266,17 +266,22 @@ static void wattcp_outch(char s) // stupid microsoft makes things complicated static inline char *get_WSAErrorStr(int e) { - char *buf = NULL; + char buf[256]; // allow up to 255 bytes + + buf[0] = '\0'; FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&buf, - 0, NULL); + (LPTSTR)buf, + sizeof (buf), + NULL); + + if (!buf[0]) // provide a fallback error message if no message is available for some reason + sprintf(buf, "Unknown error"); return buf; } From bb3d850bbfaf9fe9c333e1c0c4a79706ec878c8c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 27 Oct 2018 16:27:00 +0100 Subject: [PATCH 128/264] static the buffer, forgot to do this earlier --- src/i_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index c054b3a4a..43dba4aa3 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -266,7 +266,7 @@ static void wattcp_outch(char s) // stupid microsoft makes things complicated static inline char *get_WSAErrorStr(int e) { - char buf[256]; // allow up to 255 bytes + static char buf[256]; // allow up to 255 bytes buf[0] = '\0'; From 9fb301ecb587ed933f300cc9b65f23f8072e9d57 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 27 Oct 2018 16:47:56 +0100 Subject: [PATCH 129/264] don't bother with inlining the function, on second thoughts --- src/i_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 43dba4aa3..0728c7aac 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -264,7 +264,7 @@ static void wattcp_outch(char s) #ifdef USE_WINSOCK // stupid microsoft makes things complicated -static inline char *get_WSAErrorStr(int e) +static char *get_WSAErrorStr(int e) { static char buf[256]; // allow up to 255 bytes From 29d8e34d03f0508cc75aa887a73d724b79837db6 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Sep 2016 22:14:51 +0100 Subject: [PATCH 130/264] Call V_DoPostProcessor only in software mode (it cancels itself in OGL anyway) --- src/d_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 170532675..78e370cc3 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -417,10 +417,13 @@ static void D_Display(void) } // Image postprocessing effect - if (postimgtype) - V_DoPostProcessor(0, postimgtype, postimgparam); - if (postimgtype2) - V_DoPostProcessor(1, postimgtype2, postimgparam2); + if (rendermode == render_soft) + { + if (postimgtype) + V_DoPostProcessor(0, postimgtype, postimgparam); + if (postimgtype2) + V_DoPostProcessor(1, postimgtype2, postimgparam2); + } } if (lastdraw) From b150e842fc4920b9298219ededd21f931c9de7f4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 5 Nov 2016 20:40:48 +0000 Subject: [PATCH 131/264] Add MD2_INDENT and MD2_VERSION so we can cleanly check that it's a valid MD2 from magic number/version --- src/hardware/hw_md2.c | 4 ++-- src/hardware/hw_md2.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 756d5a098..42f2afb28 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -304,8 +304,8 @@ static md2_model_t *md2_readModel(const char *filename) // initialize model and read header if (fread(&model->header, sizeof (model->header), 1, file) != 1 - || model->header.magic != - (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')) + || model->header.magic != MD2_IDENT + || model->header.version != MD2_VERSION) { fclose(file); free(model); diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 5a7e6d2b3..299d12400 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -23,6 +23,11 @@ #include "hw_glob.h" +// magic number "IDP2" or 844121161 +#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I') +// model version +#define MD2_VERSION 8 + #define MD2_MAX_TRIANGLES 8192 #define MD2_MAX_VERTICES 4096 #define MD2_MAX_TEXCOORDS 4096 From 67a29225585bb2b978009d86ac3825021708d3bf Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 5 Nov 2016 20:51:48 +0000 Subject: [PATCH 132/264] Ensure file is closed whenever MD2 reading errors happen --- src/hardware/hw_md2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 42f2afb28..cb33562d8 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -319,6 +319,7 @@ static md2_model_t *md2_readModel(const char *filename) { \ CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \ md2_freeModel (model); \ + fclose(file); \ return 0; \ } @@ -340,6 +341,7 @@ static md2_model_t *md2_readModel(const char *filename) fread(model->skins, sizeof (md2_skin_t), model->header.numSkins, file)) { md2_freeModel (model); + fclose(file); return 0; } } @@ -353,6 +355,7 @@ static md2_model_t *md2_readModel(const char *filename) fread(model->texCoords, sizeof (md2_textureCoordinate_t), model->header.numTexCoords, file)) { md2_freeModel (model); + fclose(file); return 0; } } @@ -366,6 +369,7 @@ static md2_model_t *md2_readModel(const char *filename) fread(model->triangles, sizeof (md2_triangle_t), model->header.numTriangles, file)) { md2_freeModel (model); + fclose(file); return 0; } } @@ -378,6 +382,7 @@ static md2_model_t *md2_readModel(const char *filename) if (!model->frames) { md2_freeModel (model); + fclose(file); return 0; } @@ -391,6 +396,7 @@ static md2_model_t *md2_readModel(const char *filename) fread(frame, 1, model->header.frameSize, file)) { md2_freeModel (model); + fclose(file); return 0; } @@ -416,6 +422,7 @@ static md2_model_t *md2_readModel(const char *filename) fread(model->glCommandBuffer, sizeof (INT32), model->header.numGlCommands, file)) { md2_freeModel (model); + fclose(file); return 0; } } From 787d5b598dd9e681b1896d2f99cfb59a5c9fcc3c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 3 Jun 2017 21:40:41 +0100 Subject: [PATCH 133/264] gr_correcttricks fix: don't check if top/bottom textures are missing for sloped sectors, just ignore and cancel the hack This fixes GFZ2's mysterious flying flats at the ramp to the big room --- src/hardware/hw_trick.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/hardware/hw_trick.c b/src/hardware/hw_trick.c index e9ba19efb..7a92859f8 100644 --- a/src/hardware/hw_trick.c +++ b/src/hardware/hw_trick.c @@ -507,6 +507,14 @@ static boolean areToptexturesMissing(sector_t *thisSector) if (!frontSector || !backSector) continue; +#ifdef ESLOPE + if (frontSector->c_slope || backSector->c_slope) // the slope's height can be completely different from original ceiling height + { + nomiss++; + break; + } +#endif + sider = &sides[thisElem->line->sidenum[0]]; sidel = &sides[thisElem->line->sidenum[1]]; @@ -555,6 +563,14 @@ static boolean areBottomtexturesMissing(sector_t *thisSector) if (frontSector == NULL || backSector == NULL) continue; +#ifdef ESLOPE + if (frontSector->f_slope || backSector->f_slope) // the slope's height can be completely different from original floor height + { + nomiss++; + break; + } +#endif + sider = &sides[thisElem->line->sidenum[0]]; sidel = &sides[thisElem->line->sidenum[1]]; From 2107aab666b8147571ae5d63824412130a5cf50f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 26 Jun 2017 10:51:19 +0100 Subject: [PATCH 134/264] Moved my added slope checks in hw_trick.c to isCeilingFloating/isFloorFloating I also optimised those two functions while I was there (why keep a "floating" variable when setting it to false guarantees the functions return false?) --- src/hardware/hw_trick.c | 86 ++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 58 deletions(-) diff --git a/src/hardware/hw_trick.c b/src/hardware/hw_trick.c index 7a92859f8..44c07a6b5 100644 --- a/src/hardware/hw_trick.c +++ b/src/hardware/hw_trick.c @@ -507,14 +507,6 @@ static boolean areToptexturesMissing(sector_t *thisSector) if (!frontSector || !backSector) continue; -#ifdef ESLOPE - if (frontSector->c_slope || backSector->c_slope) // the slope's height can be completely different from original ceiling height - { - nomiss++; - break; - } -#endif - sider = &sides[thisElem->line->sidenum[0]]; sidel = &sides[thisElem->line->sidenum[1]]; @@ -563,14 +555,6 @@ static boolean areBottomtexturesMissing(sector_t *thisSector) if (frontSector == NULL || backSector == NULL) continue; -#ifdef ESLOPE - if (frontSector->f_slope || backSector->f_slope) // the slope's height can be completely different from original floor height - { - nomiss++; - break; - } -#endif - sider = &sides[thisElem->line->sidenum[0]]; sidel = &sides[thisElem->line->sidenum[1]]; @@ -603,15 +587,14 @@ static boolean areBottomtexturesMissing(sector_t *thisSector) static boolean isCeilingFloating(sector_t *thisSector) { sector_t *adjSector, *refSector = NULL, *frontSector, *backSector; - boolean floating = true; linechain_t *thisElem, *nextElem; if (!thisSector) return false; - nextElem = thisSector->sectorLines; + nextElem = thisSector->sectorLines; - while (NULL != nextElem) // walk through chain + while (nextElem) // walk through chain { thisElem = nextElem; nextElem = thisElem->next; @@ -625,10 +608,12 @@ static boolean isCeilingFloating(sector_t *thisSector) adjSector = frontSector; if (!adjSector) // assume floating sectors have surrounding sectors - { - floating = false; - break; - } + return false; + +#ifdef ESLOPE + if (adjSector->c_slope) // Don't bother with slopes + return false; +#endif if (!refSector) { @@ -637,23 +622,15 @@ static boolean isCeilingFloating(sector_t *thisSector) } // if adjacent sector has same height or more than one adjacent sector exists -> stop - if (thisSector->ceilingheight == adjSector->ceilingheight || - refSector != adjSector) - { - floating = false; - break; - } + if (thisSector->ceilingheight == adjSector->ceilingheight || refSector != adjSector) + return false; } // now check for walltextures - if (floating) - { - if (!areToptexturesMissing(thisSector)) - { - floating = false; - } - } - return floating; + if (!areToptexturesMissing(thisSector)) + return false; + + return true; } // @@ -663,7 +640,6 @@ static boolean isCeilingFloating(sector_t *thisSector) static boolean isFloorFloating(sector_t *thisSector) { sector_t *adjSector, *refSector = NULL, *frontSector, *backSector; - boolean floating = true; linechain_t *thisElem, *nextElem; if (!thisSector) @@ -684,36 +660,30 @@ static boolean isFloorFloating(sector_t *thisSector) else adjSector = frontSector; - if (NULL == adjSector) // assume floating sectors have surrounding sectors - { - floating = false; - break; - } + if (!adjSector) // assume floating sectors have surrounding sectors + return false; - if (NULL == refSector) +#ifdef ESLOPE + if (adjSector->f_slope) // Don't bother with slopes + return false; +#endif + + if (!refSector) { refSector = adjSector; continue; } // if adjacent sector has same height or more than one adjacent sector exists -> stop - if (thisSector->floorheight == adjSector->floorheight || - refSector != adjSector) - { - floating = false; - break; - } + if (thisSector->floorheight == adjSector->floorheight || refSector != adjSector) + return false; } // now check for walltextures - if (floating) - { - if (!areBottomtexturesMissing(thisSector)) - { - floating = false; - } - } - return floating; + if (!areBottomtexturesMissing(thisSector)) + return false; + + return true; } // From 1cf2ce63c061f5288b088120c981e45ea613c399 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 26 Jun 2017 11:12:26 +0100 Subject: [PATCH 135/264] More optimising and otherwise fixing bizarre formatting in hw_trick.c --- src/hardware/hw_trick.c | 56 +++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/src/hardware/hw_trick.c b/src/hardware/hw_trick.c index 44c07a6b5..97d86b944 100644 --- a/src/hardware/hw_trick.c +++ b/src/hardware/hw_trick.c @@ -107,17 +107,17 @@ static void releaseLineChains(void) for (i = 0; i < numsectors; i++) { - sector = §ors[i]; - nextElem = sector->sectorLines; + sector = §ors[i]; + nextElem = sector->sectorLines; - while (nextElem) - { - thisElem = nextElem; - nextElem = thisElem->next; - free(thisElem); - } + while (nextElem) + { + thisElem = nextElem; + nextElem = thisElem->next; + free(thisElem); + } - sector->sectorLines = NULL; + sector->sectorLines = NULL; } } @@ -397,7 +397,7 @@ static void sortStacklist(sector_t *sector) i = 0; finished = true; - while (NULL != *(list+i+1)) + while (*(list+i+1)) { sec1 = *(list+i); sec2 = *(list+i+1); @@ -438,7 +438,7 @@ static double calcLineoutLength(sector_t *sector) double length = 0.0L; chain = sector->sectorLines; - while (NULL != chain) // sum up lengths of all lines + while (chain) // sum up lengths of all lines { length += lineLength(chain->line); chain = chain->next; @@ -454,7 +454,7 @@ static void calcLineouts(sector_t *sector) size_t secCount = 0; sector_t *encSector = *(sector->stackList); - while (NULL != encSector) + while (encSector) { if (encSector->lineoutLength < 0.0L) // if length has not yet been calculated { @@ -552,7 +552,7 @@ static boolean areBottomtexturesMissing(sector_t *thisSector) if (frontSector == backSector) // skip damn renderer tricks here continue; - if (frontSector == NULL || backSector == NULL) + if (!frontSector || !backSector) continue; sider = &sides[thisElem->line->sidenum[0]]; @@ -645,7 +645,7 @@ static boolean isFloorFloating(sector_t *thisSector) if (!thisSector) return false; - nextElem = thisSector->sectorLines; + nextElem = thisSector->sectorLines; while (nextElem) // walk through chain { @@ -693,14 +693,12 @@ static fixed_t estimateCeilHeight(sector_t *thisSector) { sector_t *adjSector; - if (!thisSector || - !thisSector->sectorLines || - !thisSector->sectorLines->line) + if (!thisSector || !thisSector->sectorLines || !thisSector->sectorLines->line) return 0; adjSector = thisSector->sectorLines->line->frontsector; if (adjSector == thisSector) - adjSector = thisSector->sectorLines->line->backsector; + adjSector = thisSector->sectorLines->line->backsector; if (!adjSector) return 0; @@ -715,17 +713,15 @@ static fixed_t estimateFloorHeight(sector_t *thisSector) { sector_t *adjSector; - if (!thisSector || - !thisSector->sectorLines || - !thisSector->sectorLines->line) - return 0; + if (!thisSector || !thisSector->sectorLines || !thisSector->sectorLines->line) + return 0; adjSector = thisSector->sectorLines->line->frontsector; if (adjSector == thisSector) - adjSector = thisSector->sectorLines->line->backsector; + adjSector = thisSector->sectorLines->line->backsector; - if (NULL == adjSector) - return 0; + if (!adjSector) + return 0; return adjSector->floorheight; } @@ -831,18 +827,12 @@ void HWR_CorrectSWTricks(void) // correct height of floating sectors if (isCeilingFloating(floatSector)) { - fixed_t corrheight; - - corrheight = estimateCeilHeight(floatSector); - floatSector->virtualCeilingheight = corrheight; + floatSector->virtualCeilingheight = estimateCeilHeight(floatSector); floatSector->virtualCeiling = true; } if (isFloorFloating(floatSector)) { - fixed_t corrheight; - - corrheight = estimateFloorHeight(floatSector); - floatSector->virtualFloorheight = corrheight; + floatSector->virtualFloorheight = estimateFloorHeight(floatSector); floatSector->virtualFloor = true; } } From 90cfa5ef16d9e283cf4b23be70d9ad3f7a6f41f7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 7 Nov 2016 21:55:56 +0000 Subject: [PATCH 136/264] Make new pv1/pv2 seg pointers, so AdjustSeg doesn't modify the v1/v2 pointers directly anymore Yes I know they're void * in r_defs.h's seg_t definition, it's quicker than trying to figure out if including hardware/hw_glob.h is a good idea or not --- src/hardware/hw_bsp.c | 12 ++++---- src/hardware/hw_main.c | 64 +++++++++++++++++++++--------------------- src/p_setup.c | 1 + src/r_defs.h | 3 ++ 4 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index a32609fc8..97baec66c 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -914,7 +914,7 @@ static void AdjustSegs(void) } if (nearv1 <= NEARDIST*NEARDIST) // share vertice with segs - lseg->v1 = (vertex_t *)&(p->pts[v1found]); + lseg->pv1 = &(p->pts[v1found]); else { // BP: here we can do better, using PointInSeg and compute @@ -925,24 +925,24 @@ static void AdjustSegs(void) polyvertex_t *pv = HWR_AllocVertex(); pv->x = FIXED_TO_FLOAT(lseg->v1->x); pv->y = FIXED_TO_FLOAT(lseg->v1->y); - lseg->v1 = (vertex_t *)pv; + lseg->pv1 = pv; } if (nearv2 <= NEARDIST*NEARDIST) - lseg->v2 = (vertex_t *)&(p->pts[v2found]); + lseg->pv2 = &(p->pts[v2found]); else { polyvertex_t *pv = HWR_AllocVertex(); pv->x = FIXED_TO_FLOAT(lseg->v2->x); pv->y = FIXED_TO_FLOAT(lseg->v2->y); - lseg->v2 = (vertex_t *)pv; + lseg->pv2 = pv; } // recompute length { float x,y; - x = ((polyvertex_t *)lseg->v2)->x - ((polyvertex_t *)lseg->v1)->x + x = ((polyvertex_t *)lseg->pv2)->x - ((polyvertex_t *)lseg->pv1)->x + FIXED_TO_FLOAT(FRACUNIT/2); - y = ((polyvertex_t *)lseg->v2)->y - ((polyvertex_t *)lseg->v1)->y + y = ((polyvertex_t *)lseg->pv2)->y - ((polyvertex_t *)lseg->pv1)->y + FIXED_TO_FLOAT(FRACUNIT/2); lseg->flength = (float)hypot(x, y); // BP: debug see this kind of segs diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index ecb70a0f9..85ddff082 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -856,11 +856,11 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) M_ClearBox(segbbox); M_AddToBox(segbbox, - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x), - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y)); + FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x), + FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y)); M_AddToBox(segbbox, - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x), - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y)); + FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x), + FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y)); splat = (wallsplat_t *)gr_curline->linedef->splats; for (; splat; splat = splat->next) @@ -1367,10 +1367,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) gr_sidedef = gr_curline->sidedef; gr_linedef = gr_curline->linedef; - vs.x = ((polyvertex_t *)gr_curline->v1)->x; - vs.y = ((polyvertex_t *)gr_curline->v1)->y; - ve.x = ((polyvertex_t *)gr_curline->v2)->x; - ve.y = ((polyvertex_t *)gr_curline->v2)->y; + vs.x = ((polyvertex_t *)gr_curline->pv1)->x; + vs.y = ((polyvertex_t *)gr_curline->pv1)->y; + ve.x = ((polyvertex_t *)gr_curline->pv2)->x; + ve.y = ((polyvertex_t *)gr_curline->pv2)->y; #ifdef ESLOPE v1x = FLOAT_TO_FIXED(vs.x); @@ -2456,7 +2456,7 @@ static void HWR_ClipSolidWallSegment(INT32 first, INT32 last) } else { - highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2); + highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); HWR_StoreWallRange(0, highfrac); } // Now adjust the clip size. @@ -2480,8 +2480,8 @@ static void HWR_ClipSolidWallSegment(INT32 first, INT32 last) } else { - lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2); - highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2); + lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); + highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); HWR_StoreWallRange(lowfrac, highfrac); } next++; @@ -2515,7 +2515,7 @@ static void HWR_ClipSolidWallSegment(INT32 first, INT32 last) } else { - lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2); + lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); HWR_StoreWallRange(lowfrac, 1); } } @@ -2578,8 +2578,8 @@ static void HWR_ClipPassWallSegment(INT32 first, INT32 last) else { highfrac = HWR_ClipViewSegment(min(start->first + 1, - start->last), (polyvertex_t *)gr_curline->v1, - (polyvertex_t *)gr_curline->v2); + start->last), (polyvertex_t *)gr_curline->pv1, + (polyvertex_t *)gr_curline->pv2); HWR_StoreWallRange(0, highfrac); } } @@ -2598,8 +2598,8 @@ static void HWR_ClipPassWallSegment(INT32 first, INT32 last) } else { - lowfrac = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2); - highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2); + lowfrac = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); + highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); HWR_StoreWallRange(lowfrac, highfrac); } start++; @@ -2629,8 +2629,8 @@ static void HWR_ClipPassWallSegment(INT32 first, INT32 last) else { lowfrac = HWR_ClipViewSegment(max(start->last - 1, - start->first), (polyvertex_t *)gr_curline->v1, - (polyvertex_t *)gr_curline->v2); + start->first), (polyvertex_t *)gr_curline->pv1, + (polyvertex_t *)gr_curline->pv2); HWR_StoreWallRange(lowfrac, 1); } } @@ -2691,10 +2691,10 @@ static void HWR_AddLine(seg_t * line) gr_curline = line; // OPTIMIZE: quickly reject orthogonal back sides. - angle1 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x), - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y)); - angle2 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x), - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y)); + angle1 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x), + FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y)); + angle2 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x), + FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y)); // Clip to view edges. span = angle1 - angle2; @@ -2736,8 +2736,8 @@ static void HWR_AddLine(seg_t * line) float fx1,fx2,fy1,fy2; //BP: test with a better projection than viewangletox[R_PointToAngle(angle)] // do not enable this at release 4 mul and 2 div - fx1 = ((polyvertex_t *)(line->v1))->x-gr_viewx; - fy1 = ((polyvertex_t *)(line->v1))->y-gr_viewy; + fx1 = ((polyvertex_t *)(line->pv1))->x-gr_viewx; + fy1 = ((polyvertex_t *)(line->pv1))->y-gr_viewy; fy2 = (fx1 * gr_viewcos + fy1 * gr_viewsin); if (fy2 < 0) // the point is back @@ -2745,8 +2745,8 @@ static void HWR_AddLine(seg_t * line) else fx1 = gr_windowcenterx + (fx1 * gr_viewsin - fy1 * gr_viewcos) * gr_centerx / fy2; - fx2 = ((polyvertex_t *)(line->v2))->x-gr_viewx; - fy2 = ((polyvertex_t *)(line->v2))->y-gr_viewy; + fx2 = ((polyvertex_t *)(line->pv2))->x-gr_viewx; + fy2 = ((polyvertex_t *)(line->pv2))->y-gr_viewy; fy1 = (fx2 * gr_viewcos + fy2 * gr_viewsin); if (fy1 < 0) // the point is back @@ -2789,10 +2789,10 @@ static void HWR_AddLine(seg_t * line) fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends - v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x); - v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y); - v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x); - v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y); + v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x); + v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y); + v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); + v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); #define SLOPEPARAMS(slope, end1, end2, normalheight) \ if (slope) { \ end1 = P_GetZAt(slope, v1x, v1y); \ @@ -2987,8 +2987,8 @@ static inline void HWR_AddPolyObjectSegs(void) pv2->x = FIXED_TO_FLOAT(gr_fakeline->v2->x); pv2->y = FIXED_TO_FLOAT(gr_fakeline->v2->y); - gr_fakeline->v1 = (vertex_t *)pv1; - gr_fakeline->v2 = (vertex_t *)pv2; + gr_fakeline->pv1 = pv1; + gr_fakeline->pv2 = pv2; HWR_AddLine(gr_fakeline); } diff --git a/src/p_setup.c b/src/p_setup.c index 17a6797f4..f00781a5d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -451,6 +451,7 @@ static void P_LoadSegs(lumpnum_t lumpnum) //Hurdler: 04/12/2000: for now, only used in hardware mode li->lightmaps = NULL; // list of static lightmap for this seg } + li->pv1 = li->pv2 = NULL; #endif li->angle = (SHORT(ml->angle))< Date: Wed, 21 Dec 2016 22:10:27 +0000 Subject: [PATCH 137/264] Hack to make sure even (extra)subsectors without planepolys have segs adjusted this fixes a crash in (old) GFZ2 at the ramp as a result of creating pv1/pv2. This probably means before pv1/pv2 there could have been some silly typecasting from vertex_t to polyvertex_t to get fixed vertex coords and such... --- src/hardware/hw_bsp.c | 44 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 97baec66c..fa5bce308 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -878,8 +878,8 @@ static void AdjustSegs(void) count = subsectors[i].numlines; lseg = &segs[subsectors[i].firstline]; p = extrasubsectors[i].planepoly; - if (!p) - continue; + //if (!p) + //continue; for (; count--; lseg++) { float distv1,distv2,tmp; @@ -892,27 +892,29 @@ static void AdjustSegs(void) continue; #endif - for (j = 0; j < p->numpts; j++) - { - distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x); - tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y); - distv1 = distv1*distv1+tmp*tmp; - if (distv1 <= nearv1) + if (p) { + for (j = 0; j < p->numpts; j++) { - v1found = j; - nearv1 = distv1; - } - // the same with v2 - distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x); - tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y); - distv2 = distv2*distv2+tmp*tmp; - if (distv2 <= nearv2) - { - v2found = j; - nearv2 = distv2; + distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x); + tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y); + distv1 = distv1*distv1+tmp*tmp; + if (distv1 <= nearv1) + { + v1found = j; + nearv1 = distv1; + } + // the same with v2 + distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x); + tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y); + distv2 = distv2*distv2+tmp*tmp; + if (distv2 <= nearv2) + { + v2found = j; + nearv2 = distv2; + } } } - if (nearv1 <= NEARDIST*NEARDIST) + if (p && nearv1 <= NEARDIST*NEARDIST) // share vertice with segs lseg->pv1 = &(p->pts[v1found]); else @@ -927,7 +929,7 @@ static void AdjustSegs(void) pv->y = FIXED_TO_FLOAT(lseg->v1->y); lseg->pv1 = pv; } - if (nearv2 <= NEARDIST*NEARDIST) + if (p && nearv2 <= NEARDIST*NEARDIST) lseg->pv2 = &(p->pts[v2found]); else { From 3d88ee9d55385f5281108f90a4fea63ce4a8ad2e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 21 Dec 2016 22:31:09 +0000 Subject: [PATCH 138/264] Added missing checks in HWR_AddLine from the software version, move v** vars to the top since R_PointToAngle calls use the same values anyway --- src/hardware/hw_main.c | 49 ++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 85ddff082..d4b2832f8 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2685,16 +2685,21 @@ static void HWR_AddLine(seg_t * line) // SoM: Backsector needs to be run through R_FakeFlat static sector_t tempsec; + fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t + if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; gr_curline = line; + v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x); + v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y); + v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); + v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); + // OPTIMIZE: quickly reject orthogonal back sides. - angle1 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x), - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y)); - angle2 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x), - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y)); + angle1 = R_PointToAngle(v1x, v1y); + angle2 = R_PointToAngle(v2x, v2y); // Clip to view edges. span = angle1 - angle2; @@ -2785,14 +2790,9 @@ static void HWR_AddLine(seg_t * line) #ifdef ESLOPE if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope) { - fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends - v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x); - v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y); - v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); - v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); #define SLOPEPARAMS(slope, end1, end2, normalheight) \ if (slope) { \ end1 = P_GetZAt(slope, v1x, v1y); \ @@ -2813,6 +2813,13 @@ static void HWR_AddLine(seg_t * line) goto clipsolid; } + // Check for automap fix. + if (backc1 <= backf1 && backc2 <= backf2 + && ((backc1 >= frontc1 && backc2 >= frontc2) || gr_curline->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 >= frontf2) || gr_curline->sidedef->bottomtexture) + && (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)) + goto clipsolid; + // Window. if (backc1 != frontc1 || backc2 != frontc2 || backf1 != frontf1 || backf2 != frontf2) @@ -2828,6 +2835,13 @@ static void HWR_AddLine(seg_t * line) gr_backsector->floorheight >= gr_frontsector->ceilingheight) goto clipsolid; + // Check for automap fix. + if (gr_backsector->ceilingheight <= gr_backsector->floorheight + && ((gr_backsector->ceilingheight >= gr_frontsector->ceilingheight) || gr_curline->sidedef->toptexture) + && ((gr_backsector->floorheight <= gr_backsector->floorheight) || gr_curline->sidedef->bottomtexture) + && (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)) + goto clipsolid; + // Window. if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight || gr_backsector->floorheight != gr_frontsector->floorheight) @@ -2849,8 +2863,21 @@ static void HWR_AddLine(seg_t * line) && gr_backsector->c_slope == gr_frontsector->c_slope #endif && gr_backsector->lightlevel == gr_frontsector->lightlevel - && gr_curline->sidedef->midtexture == 0 - && !gr_backsector->ffloors && !gr_frontsector->ffloors) + && !gr_curline->sidedef->midtexture + // Check offsets too! + && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs + && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs + && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle + && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs + && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs + && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle + // Consider altered lighting. + && gr_backsector->floorlightsec == gr_frontsector->floorlightsec + && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec + // Consider colormaps + && gr_backsector->extra_colormap == gr_frontsector->extra_colormap + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || gr_frontsector->tag == gr_backsector->tag)) // SoM: For 3D sides... Boris, would you like to take a // crack at rendering 3D sides? You would need to add the // above check and add code to HWR_StoreWallRange... From aebcf3520b8814b11b694b571cb7c4352ced637b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 12 Jan 2017 21:43:37 +0000 Subject: [PATCH 139/264] Remove pointless drawtextured variable and redundant fake planes checks (R_FakeFlat would already have made gr_frontsector/backsector something else if they were) --- src/hardware/hw_main.c | 98 ++++++++---------------------------------- 1 file changed, 19 insertions(+), 79 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d4b2832f8..7e8152583 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -323,9 +323,6 @@ static angle_t gr_xtoviewangle[MAXVIDWIDTH+1]; // test change fov when looking up/down but bsp projection messup :( //#define NOCRAPPYMLOOK -/// \note crappy -#define drawtextured true - // base values set at SetViewSize static float gr_basecentery; @@ -1378,44 +1375,21 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) v2x = FLOAT_TO_FIXED(ve.x); v2y = FLOAT_TO_FIXED(ve.y); #endif - - if (gr_frontsector->heightsec != -1) - { #ifdef ESLOPE - worldtop = worldtopslope = sectors[gr_frontsector->heightsec].ceilingheight; - worldbottom = worldbottomslope = sectors[gr_frontsector->heightsec].floorheight; -#else - worldtop = sectors[gr_frontsector->heightsec].ceilingheight; - worldbottom = sectors[gr_frontsector->heightsec].floorheight; -#endif - } - else - { -#ifdef ESLOPE - if (gr_frontsector->c_slope) - { - worldtop = P_GetZAt(gr_frontsector->c_slope, v1x, v1y); - worldtopslope = P_GetZAt(gr_frontsector->c_slope, v2x, v2y); - } - else - { - worldtop = worldtopslope = gr_frontsector->ceilingheight; - } - if (gr_frontsector->f_slope) - { - worldbottom = P_GetZAt(gr_frontsector->f_slope, v1x, v1y); - worldbottomslope = P_GetZAt(gr_frontsector->f_slope, v2x, v2y); - } - else - { - worldbottom = worldbottomslope = gr_frontsector->floorheight; - } +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, v1x, v1y); \ + end2 = P_GetZAt(slope, v2x, v2y); \ + } else \ + end1 = end2 = normalheight; + + SLOPEPARAMS(gr_frontsector->c_slope, worldtop, worldtopslope, gr_frontsector->ceilingheight) + SLOPEPARAMS(gr_frontsector->f_slope, worldbottom, worldbottomslope, gr_frontsector->floorheight) #else - worldtop = gr_frontsector->ceilingheight; - worldbottom = gr_frontsector->floorheight; + worldtop = gr_frontsector->ceilingheight; + worldbottom = gr_frontsector->floorheight; #endif - } // remember vertices ordering // 3--2 @@ -1430,7 +1404,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) wallVerts[2].z = wallVerts[1].z = ve.y; wallVerts[0].w = wallVerts[1].w = wallVerts[2].w = wallVerts[3].w = 1.0f; - if (drawtextured) { // x offset the texture fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset; @@ -1459,43 +1432,15 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { INT32 gr_toptexture, gr_bottomtexture; // two sided line - if (gr_backsector->heightsec != -1) - { -#ifdef ESLOPE - worldhigh = worldhighslope = sectors[gr_backsector->heightsec].ceilingheight; - worldlow = worldlowslope = sectors[gr_backsector->heightsec].floorheight; -#else - worldhigh = sectors[gr_backsector->heightsec].ceilingheight; - worldlow = sectors[gr_backsector->heightsec].floorheight; -#endif - } - else - { -#ifdef ESLOPE - if (gr_backsector->c_slope) - { - worldhigh = P_GetZAt(gr_backsector->c_slope, v1x, v1y); - worldhighslope = P_GetZAt(gr_backsector->c_slope, v2x, v2y); - } - else - { - worldhigh = worldhighslope = gr_backsector->ceilingheight; - } - if (gr_backsector->f_slope) - { - worldlow = P_GetZAt(gr_backsector->f_slope, v1x, v1y); - worldlowslope = P_GetZAt(gr_backsector->f_slope, v2x, v2y); - } - else - { - worldlow = worldlowslope = gr_backsector->floorheight; - } +#ifdef ESLOPE + SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight) + SLOPEPARAMS(gr_backsector->f_slope, worldlow, worldlowslope, gr_backsector->floorheight) +#undef SLOPEPARAMS #else - worldhigh = gr_backsector->ceilingheight; - worldlow = gr_backsector->floorheight; + worldhigh = gr_backsector->ceilingheight; + worldlow = gr_backsector->floorheight; #endif - } // hack to allow height changes in outdoor areas // This is what gets rid of the upper textures if there should be sky @@ -1519,7 +1464,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) worldhigh < worldtop ) && gr_toptexture) { - if (drawtextured) { fixed_t texturevpegtop; // top @@ -1600,7 +1544,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif worldlow > worldbottom) && gr_bottomtexture) //only if VISIBLE!!! { - if (drawtextured) { fixed_t texturevpegbottom = 0; // bottom @@ -1792,7 +1735,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) h = min(highcut, polytop); l = max(polybottom, lowcut); - if (drawtextured) { // PEGGING #ifdef ESLOPE @@ -1848,7 +1790,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) h = min(highcut, polytop); l = max(polybottom, lowcut); - if (drawtextured) { // PEGGING if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) @@ -2039,7 +1980,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); if (gr_midtexture) { - if (drawtextured) { fixed_t texturevpeg; // PEGGING @@ -2180,7 +2120,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = 0; } - else if (drawtextured) + else { fixed_t texturevpeg; @@ -2316,7 +2256,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = 0; } - else if (drawtextured) + else { grTex = HWR_GetTexture(texnum); From 32077897b6af08a28e1fe28b9a2b9ef14393672f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 27 Oct 2018 19:58:51 +0100 Subject: [PATCH 140/264] Removed all remaining traces of VID_X11 code in hw_drv.h and hw_data.h, the macro is no longer used by Linux etc versions of SRB2. Unlike the rest of the commits in this branch (as of writing), I didn't make this commit between 1 and 2 years ago, I made it right now ;) --- src/hardware/hw_data.h | 4 ---- src/hardware/hw_drv.h | 15 --------------- 2 files changed, 19 deletions(-) diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index d76fcc1c8..4bbc578ed 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -26,10 +26,6 @@ #include #endif -#if defined (VID_X11) && !defined (HAVE_SDL) -#include -#endif - #include "../doomdef.h" //THIS MUST DISAPPEAR!!! #include "hw_glide.h" diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index a5ac82001..e2fa90eb0 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -32,10 +32,6 @@ // STANDARD DLL EXPORTS // ========================================================================== -#ifdef HAVE_SDL -#undef VID_X11 -#endif - EXPORT boolean HWRAPI(Init) (I_Error_t ErrorFunction); #ifndef HAVE_SDL EXPORT void HWRAPI(Shutdown) (void); @@ -43,9 +39,6 @@ EXPORT void HWRAPI(Shutdown) (void); #ifdef _WINDOWS EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes); #endif -#ifdef VID_X11 -EXPORT Window HWRAPI(HookXwin) (Display *, INT32, INT32, boolean); -#endif #if defined (PURESDL) || defined (macintosh) EXPORT void HWRAPI(SetPalette) (INT32 *, RGBA_t *gamma); #else @@ -71,10 +64,6 @@ EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); EXPORT INT32 HWRAPI(GetRenderVersion) (void); -#ifdef VID_X11 // ifdef to be removed as soon as windoze supports that as well -// metzgermeister: added for Voodoo detection -EXPORT char *HWRAPI(GetRenderer) (void); -#endif #ifdef SHUFFLE #define SCREENVERTS 10 EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); @@ -115,10 +104,6 @@ struct hwdriver_s #ifdef _WINDOWS GetModeList pfnGetModeList; #endif -#ifdef VID_X11 - HookXwin pfnHookXwin; - GetRenderer pfnGetRenderer; -#endif #ifndef HAVE_SDL Shutdown pfnShutdown; #endif From 834a5e6b3530a5ed3cc89b3528b8f35ea8689b55 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 29 Oct 2018 12:06:22 +0000 Subject: [PATCH 141/264] V_DrawFixedPatch: Tinker with the left/top offsets code so that V_OFFSET can support V_FLIP --- src/v_video.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index 802a4d388..0d80dc50e 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -406,22 +406,35 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t colfrac = FixedDiv(FRACUNIT, fdup); rowfrac = FixedDiv(FRACUNIT, fdup); - if (scrn & V_OFFSET) // Crosshair shit + // So it turns out offsets aren't scaled in V_NOSCALESTART unless V_OFFSET is applied ...poo, that's terrible + // For now let's just at least give V_OFFSET the ability to support V_FLIP + // I'll probably make a better fix for 2.2 where I don't have to worry about breaking existing support for stuff + // -- Monster Iestyn 29/10/18 { - y -= FixedMul((SHORT(patch->topoffset)*dupy)<leftoffset)*dupx)<topoffset)<width) - SHORT(patch->leftoffset))<width) - SHORT(patch->leftoffset))<leftoffset)<leftoffset)<topoffset)< Date: Mon, 29 Oct 2018 12:36:09 +0000 Subject: [PATCH 142/264] Make V_OFFSET no thing without V_NOSCALESTART, to remove any potential glitches with using it on its own --- src/v_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index 0d80dc50e..b5abd009b 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -426,7 +426,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t // TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!? offsety = FixedMul(SHORT(patch->topoffset)< Date: Mon, 29 Oct 2018 13:29:16 +0000 Subject: [PATCH 143/264] HWR_DrawFixedPatch: Add V_OFFSET support for V_FLIP in hardware code as well, also add missing SHORTs for gpatch fields --- src/hardware/hw_draw.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 84081dd25..ad41c68d0 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -179,18 +179,29 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, dupx = dupy = (dupx < dupy ? dupx : dupy); fscale = FIXED_TO_FLOAT(pscale); - if (option & V_OFFSET) + // See my comments in v_video.c's V_DrawFixedPatch + // -- Monster Iestyn 29/10/18 { - cx -= (float)gpatch->leftoffset * dupx * fscale; - cy -= (float)gpatch->topoffset * dupy * fscale; - } - else - { - cy -= (float)gpatch->topoffset * fscale; + float offsetx = 0.0f, offsety = 0.0f; + + // left offset if (option & V_FLIP) - cx -= ((float)gpatch->width - (float)gpatch->leftoffset) * fscale; + offsetx = (float)(SHORT(gpatch->width) - SHORT(gpatch->leftoffset)) * fscale; else - cx -= (float)gpatch->leftoffset * fscale; + offsetx = (float)SHORT(gpatch->leftoffset) * fscale; + + // top offset + // TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!? + offsety = (float)SHORT(patch->topoffset) * fscale; + + if ((option & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs + { + offsetx *= dupx; + offsety *= dupy; + } + + cx -= offsetx; + cy -= offsety; } if (option & V_SPLITSCREEN) @@ -237,13 +248,13 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (pscale != FRACUNIT) { - fwidth = (float)gpatch->width * fscale * dupx; - fheight = (float)gpatch->height * fscale * dupy; + fwidth = (float)SHORT(gpatch->width) * fscale * dupx; + fheight = (float)SHORT(gpatch->height) * fscale * dupy; } else { - fwidth = (float)gpatch->width * dupx; - fheight = (float)gpatch->height * dupy; + fwidth = (float)SHORT(gpatch->width) * dupx; + fheight = (float)SHORT(gpatch->height) * dupy; } // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1 From b022ff02a5859dd597cc67c40367085fee40ac4c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 29 Oct 2018 13:34:54 +0000 Subject: [PATCH 144/264] add missing SHORTs in HWR_DrawPatch and HWR_DrawCroppedPatch as well --- src/hardware/hw_draw.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index ad41c68d0..ffd156862 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -112,10 +112,10 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) if (option & V_NOSCALESTART) sdupx = sdupy = 2.0f; - v[0].x = v[3].x = (x*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1; - v[2].x = v[1].x = (x*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; - v[0].y = v[1].y = 1-(y*sdupy-gpatch->topoffset*pdupy)/vid.height; - v[2].y = v[3].y = 1-(y*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height; + v[0].x = v[3].x = (x*sdupx-SHORT(gpatch->leftoffset)*pdupx)/vid.width - 1; + v[2].x = v[1].x = (x*sdupx+(SHORT(gpatch->width)-SHORT(gpatch->leftoffset))*pdupx)/vid.width - 1; + v[0].y = v[1].y = 1-(y*sdupy-SHORT(gpatch->topoffset)*pdupy)/vid.height; + v[2].y = v[3].y = 1-(y*sdupy+(SHORT(gpatch->height)-SHORT(gpatch->topoffset))*pdupy)/vid.height; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; @@ -352,8 +352,8 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal dupx = dupy = (dupx < dupy ? dupx : dupy); fscale = FIXED_TO_FLOAT(pscale); - cy -= (float)gpatch->topoffset * fscale; - cx -= (float)gpatch->leftoffset * fscale; + cy -= (float)SHORT(gpatch->topoffset) * fscale; + cx -= (float)SHORT(gpatch->leftoffset) * fscale; if (!(option & V_NOSCALESTART)) { @@ -403,11 +403,11 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal if (fheight > h - sy) fheight = h - sy; - if (fwidth > gpatch->width) - fwidth = gpatch->width; + if (fwidth > SHORT(gpatch->width)) + fwidth = SHORT(gpatch->width); - if (fheight > gpatch->height) - fheight = gpatch->height; + if (fheight > SHORT(gpatch->height)) + fheight = SHORT(gpatch->height); if (pscale != FRACUNIT) { @@ -437,10 +437,10 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = ((sx)/(float)gpatch->width )*gpatch->max_s; - v[2].sow = v[1].sow = ((w )/(float)gpatch->width )*gpatch->max_s; - v[0].tow = v[1].tow = ((sy)/(float)gpatch->height)*gpatch->max_t; - v[2].tow = v[3].tow = ((h )/(float)gpatch->height)*gpatch->max_t; + v[0].sow = v[3].sow = ((sx)/(float)SHORT(gpatch->width) )*gpatch->max_s; + v[2].sow = v[1].sow = ((w )/(float)SHORT(gpatch->width) )*gpatch->max_s; + v[0].tow = v[1].tow = ((sy)/(float)SHORT(gpatch->height))*gpatch->max_t; + v[2].tow = v[3].tow = ((h )/(float)SHORT(gpatch->height))*gpatch->max_t; flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; From 2fa0896fd020ef2eb83a42561344fe888df06588 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 30 Oct 2018 13:44:01 +0000 Subject: [PATCH 145/264] Fix an error I made in HWR_DrawFixedPatch --- src/hardware/hw_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index ffd156862..33f5e0318 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -192,7 +192,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, // top offset // TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!? - offsety = (float)SHORT(patch->topoffset) * fscale; + offsety = (float)SHORT(gpatch->topoffset) * fscale; if ((option & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs { From 22e8dd1f9da40d0447531f848ae4cbbdd18b869c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 30 Oct 2018 14:22:21 +0000 Subject: [PATCH 146/264] now that V_FLIP's effects are always supported in V_DrawFixedPatch, there's no need for the "flip" variable anymore --- src/v_video.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index b5abd009b..933ec0f05 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -331,7 +331,6 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t { UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t); UINT32 alphalevel = 0; - boolean flip = false; fixed_t col, ofs, colfrac, rowfrac, fdup; INT32 dupx, dupy; @@ -415,10 +414,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t // left offset if (scrn & V_FLIP) - { - flip = true; offsetx = FixedMul((SHORT(patch->width) - SHORT(patch->leftoffset))<leftoffset)<>FRACBITS) < SHORT(patch->width); col += colfrac, ++offx, desttop++) { INT32 topdelta, prevdelta = -1; - if (flip) // offx is measured from right edge instead of left + if (scrn & V_FLIP) // offx is measured from right edge instead of left { if (x+pwidth-offx < 0) // don't draw off the left of the screen (WRAP PREVENTION) break; @@ -534,7 +530,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t prevdelta = topdelta; source = (const UINT8 *)(column) + 3; dest = desttop; - if (flip) + if (scrn & V_FLIP) dest = deststart + (destend - desttop); dest += FixedInt(FixedMul(topdelta< Date: Tue, 30 Oct 2018 19:40:59 +0100 Subject: [PATCH 147/264] Small hud library additions --- src/lua_hudlib.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 60cbbe501..893534960 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -560,6 +560,15 @@ static int libd_renderer(lua_State *L) return 1; } +// 30/10/18 Lat': Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int +// Could as well be thrown in global vars for ease of access but I guess it makes sense for it to be a HUD fn +static int libd_getlocaltransflag(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, (10-cv_translucenthud.value)*V_10TRANS); // A bit weird that it's called "translucenthud" yet 10 is fully opaque :V + return 1; +} + static luaL_Reg lib_draw[] = { {"patchExists", libd_patchExists}, {"cachePatch", libd_cachePatch}, @@ -576,6 +585,7 @@ static luaL_Reg lib_draw[] = { {"dupx", libd_dupx}, {"dupy", libd_dupy}, {"renderer", libd_renderer}, + {"localTransFlag", libd_getlocaltransflag}, {NULL, NULL} }; @@ -599,6 +609,20 @@ static int lib_huddisable(lua_State *L) return 0; } +// 30/10/18: Lat': How come this wasn't here before? +static int lib_hudenabled(lua_State *L) +{ + enum hud option = luaL_checkoption(L, 1, NULL, hud_disable_options); + lua_settop(L, 2); + if (!gL || hud_enabled[option/8] & (1<<(option%8))) + lua_pushboolean(L, true); + else + lua_pushboolean(L, false); + + return 1; +} + + // add a HUD element for rendering static int lib_hudadd(lua_State *L) { @@ -623,6 +647,7 @@ static int lib_hudadd(lua_State *L) static luaL_Reg lib_hud[] = { {"enable", lib_hudenable}, {"disable", lib_huddisable}, + {"enabled", lib_hudenabled}, {"add", lib_hudadd}, {NULL, NULL} }; From 799d8d2749250218bd557d09c9727df3658f7a9f Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Tue, 30 Oct 2018 22:29:28 +0100 Subject: [PATCH 148/264] remove gL check --- src/lua_hudlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 893534960..2ba6c8a60 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -614,7 +614,7 @@ static int lib_hudenabled(lua_State *L) { enum hud option = luaL_checkoption(L, 1, NULL, hud_disable_options); lua_settop(L, 2); - if (!gL || hud_enabled[option/8] & (1<<(option%8))) + if (hud_enabled[option/8] & (1<<(option%8))) lua_pushboolean(L, true); else lua_pushboolean(L, false); From 68414585469fbb4e1c739253e9561b430dcaf0eb Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Tue, 30 Oct 2018 22:51:05 +0100 Subject: [PATCH 149/264] got rid of the settop as well --- src/lua_hudlib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 2ba6c8a60..bc9423bea 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -613,7 +613,6 @@ static int lib_huddisable(lua_State *L) static int lib_hudenabled(lua_State *L) { enum hud option = luaL_checkoption(L, 1, NULL, hud_disable_options); - lua_settop(L, 2); if (hud_enabled[option/8] & (1<<(option%8))) lua_pushboolean(L, true); else From e9ea1b47d5ec8f2d04452426341aa9c13e00ce2d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 31 Oct 2018 19:26:29 +0000 Subject: [PATCH 150/264] Fix the game crashing if you put params with no "=" for some reason in some of the SOC blocks, just stop going through the lines if that happens --- src/dehacked.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 365241084..97e1965eb 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1035,7 +1035,10 @@ static void readlevelheader(MYFILE *f, INT32 num) // Get the part before the " = " tmp = strchr(s, '='); - *(tmp-1) = '\0'; + if (tmp) + *(tmp-1) = '\0'; + else + break; strupr(word); // Now get the part after @@ -1616,7 +1619,10 @@ static void readhuditem(MYFILE *f, INT32 num) // Get the part before the " = " tmp = strchr(s, '='); - *(tmp-1) = '\0'; + if (tmp) + *(tmp-1) = '\0'; + else + break; strupr(word); // Now get the part after @@ -2118,7 +2124,10 @@ static void reademblemdata(MYFILE *f, INT32 num) // Get the part before the " = " tmp = strchr(s, '='); - *(tmp-1) = '\0'; + if (tmp) + *(tmp-1) = '\0'; + else + break; strupr(word); // Now get the part after @@ -2258,7 +2267,10 @@ static void readextraemblemdata(MYFILE *f, INT32 num) // Get the part before the " = " tmp = strchr(s, '='); - *(tmp-1) = '\0'; + if (tmp) + *(tmp-1) = '\0'; + else + break; strupr(word); // Now get the part after @@ -2342,7 +2354,10 @@ static void readunlockable(MYFILE *f, INT32 num) // Get the part before the " = " tmp = strchr(s, '='); - *(tmp-1) = '\0'; + if (tmp) + *(tmp-1) = '\0'; + else + break; strupr(word); // Now get the part after @@ -2629,7 +2644,10 @@ static void readconditionset(MYFILE *f, UINT8 setnum) // Get the part before the " = " tmp = strchr(s, '='); - *(tmp-1) = '\0'; + if (tmp) + *(tmp-1) = '\0'; + else + break; strupr(word); // Now get the part after @@ -2874,7 +2892,10 @@ static void readmaincfg(MYFILE *f) // Get the part before the " = " tmp = strchr(s, '='); - *(tmp-1) = '\0'; + if (tmp) + *(tmp-1) = '\0'; + else + break; strupr(word); // Now get the part after @@ -3113,7 +3134,10 @@ static void readwipes(MYFILE *f) // Get the part before the " = " tmp = strchr(s, '='); - *(tmp-1) = '\0'; + if (tmp) + *(tmp-1) = '\0'; + else + break; strupr(word); // Now get the part after From 5a0cfc10f44206bedf1c764c112ac84f21772b20 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 1 Nov 2018 14:47:19 -0400 Subject: [PATCH 151/264] Update copyright info on some files --- src/sdl/i_system.c | 3 +++ src/sdl/i_video.c | 2 ++ src/sdl/mixer_sound.c | 8 ++++++++ src/sdl12/mixer_sound.c | 8 ++++++++ 4 files changed, 21 insertions(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 7b14f1f18..0ec8a980e 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1,8 +1,11 @@ // Emacs style mode select -*- C++ -*- +// +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // // Copyright (C) 1993-1996 by id Software, Inc. // Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 2014-2018 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 30ef1b27b..c0ec99883 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1,8 +1,10 @@ // Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // // Copyright (C) 1993-1996 by id Software, Inc. // Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 2014-2018 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 4d86d7a3c..bbd1fcee4 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1,3 +1,11 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2014-2018 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 /// \brief SDL Mixer interface for sound diff --git a/src/sdl12/mixer_sound.c b/src/sdl12/mixer_sound.c index daf09ab91..dcae19b05 100644 --- a/src/sdl12/mixer_sound.c +++ b/src/sdl12/mixer_sound.c @@ -1,3 +1,11 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2008-2018 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 /// \brief SDL Mixer interface for sound From 0f37411e2bda94bd496f6fbbe6edd1a1d43dbc32 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 2 Nov 2018 20:48:12 +0000 Subject: [PATCH 152/264] Make sure handles of files opened by W_LoadWadFile are closed if we abort loading the files for whatever reason. ESPECIALLY if the file is already loaded in SRB2, that's just silly. --- src/w_wad.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/w_wad.c b/src/w_wad.c index 3f0082a16..3789eab55 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -381,6 +381,8 @@ UINT16 W_LoadWadFile(const char *filename) if (fread(&header, 1, sizeof header, handle) < sizeof header) { CONS_Alert(CONS_ERROR, M_GetText("Can't read wad header from %s because %s\n"), filename, strerror(ferror(handle))); + if (handle) + fclose(handle); return INT16_MAX; } @@ -391,6 +393,8 @@ UINT16 W_LoadWadFile(const char *filename) && memcmp(header.identification, "SDLL", 4) != 0) { CONS_Alert(CONS_ERROR, M_GetText("%s does not have a valid WAD header\n"), filename); + if (handle) + fclose(handle); return INT16_MAX; } @@ -405,6 +409,8 @@ UINT16 W_LoadWadFile(const char *filename) { CONS_Alert(CONS_ERROR, M_GetText("Wadfile directory in %s is corrupted (%s)\n"), filename, strerror(ferror(handle))); free(fileinfov); + if (handle) + fclose(handle); return INT16_MAX; } @@ -462,6 +468,8 @@ UINT16 W_LoadWadFile(const char *filename) if (!memcmp(wadfiles[i]->md5sum, md5sum, 16)) { CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename); + if (handle) + fclose(handle); return INT16_MAX; } } From 15020ae01d1819e27af1a39f5eed434f8dd8cf71 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 10:57:43 -0400 Subject: [PATCH 153/264] Removed TextPrompt-specific code for `text-prompt` branch --- src/st_stuff.c | 19 ------------------- src/v_video.c | 19 ------------------- src/v_video.h | 1 - 3 files changed, 39 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index d4c710e97..fa13e008a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2465,21 +2465,6 @@ static void ST_overlayDrawer(void) ST_drawDebugInfo(); } -static void ST_drawTutorial(void) -{ - INT32 charheight = 8; - INT32 y = BASEVIDHEIGHT - ((charheight * 4) + (charheight/2)*4); - char *test; - //INT32 i; - // Nothing, ...yet - // Except this for now, just to check it works - //V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Tutorial placeholder"); - V_DrawTutorialBack(); - //for (i = 0; i < 4; i++, y += 12) - test = V_WordWrap(4, BASEVIDWIDTH-4, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum"); - V_DrawString(4, y, V_SNAPTOBOTTOM, test); -} - void ST_Drawer(void) { #ifdef SEENAMES @@ -2553,8 +2538,4 @@ void ST_Drawer(void) ST_overlayDrawer(); } } - - // Draw tutorial text over everything else - if (tutorialmode) - ST_drawTutorial(); } diff --git a/src/v_video.c b/src/v_video.c index 05401ce56..765965ffd 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1480,25 +1480,6 @@ void V_DrawFadeConsBack(INT32 plines) *buf = consolebgmap[*buf]; } -// Very similar to F_DrawFadeConsBack, except we draw from the middle(-ish) of the screen to the bottom. -void V_DrawTutorialBack(void) -{ - INT32 charheight = 8*vid.dupy; - UINT8 *deststop, *buf; - -#ifdef HWRENDER - if (rendermode != render_soft) // no support for OpenGL yet - return; -#endif - - // heavily simplified -- we don't need to know x or y position, - // just the start and stop positions - deststop = screens[0] + vid.rowbytes * vid.height; - buf = deststop - vid.rowbytes * ((charheight * 4) + (charheight/2)*5); // 4 lines of space plus gaps between and some leeway - for (; buf < deststop; ++buf) - *buf = consolebgmap[*buf]; -} - // Gets string colormap, used for 0x80 color codes // static const UINT8 *V_GetStringColormap(INT32 colorflags) diff --git a/src/v_video.h b/src/v_video.h index 850206816..6113d08ec 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -158,7 +158,6 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); void V_DrawFadeScreen(UINT16 color, UINT8 strength); void V_DrawFadeConsBack(INT32 plines); -void V_DrawTutorialBack(void); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); From cf6a6991cbd9f1710bef5ac70739a1efa4745ab2 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 16:28:25 -0500 Subject: [PATCH 154/264] Trigger line exec by whether mobj is facing its tracer * MFE_TRACERANGLE * Thing 758 MT_ANGLEMAN * mobj thinker behavior * Line Exec 457/458 Enable/Disable --- src/dehacked.c | 1 + src/info.c | 27 +++++++++++++++++++++++++++ src/info.h | 1 + src/p_mobj.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/p_mobj.h | 3 +++ src/p_spec.c | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 107 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 6c39fc197..9ccefa9ce 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6937,6 +6937,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_PULL", "MT_GHOST", "MT_OVERLAY", + "MT_ANGLEMAN", "MT_POLYANCHOR", "MT_POLYSPAWN", "MT_POLYSPAWNCRUSH", diff --git a/src/info.c b/src/info.c index 3140bd7de..72abcede1 100644 --- a/src/info.c +++ b/src/info.c @@ -17814,6 +17814,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_ANGLEMAN + 758, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8, // radius + 8, // height + 0, // display offset + 10, // mass + 0, // damage + sfx_None, // activesound + MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + { // MT_POLYANCHOR 760, // doomednum S_INVISIBLE, // spawnstate diff --git a/src/info.h b/src/info.h index b757deec0..c9de82541 100644 --- a/src/info.h +++ b/src/info.h @@ -4305,6 +4305,7 @@ typedef enum mobj_type MT_PULL, MT_GHOST, MT_OVERLAY, + MT_ANGLEMAN, MT_POLYANCHOR, MT_POLYSPAWN, MT_POLYSPAWNCRUSH, diff --git a/src/p_mobj.c b/src/p_mobj.c index 717bb92b6..45a26cbc5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7435,6 +7435,46 @@ void P_MobjThinker(mobj_t *mobj) if ((mobj->flags & MF_ENEMY) && (mobj->state->nextstate == mobj->info->spawnstate && mobj->tics == 1)) mobj->flags2 &= ~MF2_FRET; + // Angle-to-tracer to trigger a linedef exec + // See Linedef Exec 457 (Track mobj angle to point) + if ((mobj->eflags & MFE_TRACERANGLE) && mobj->tracer && mobj->extravalue2) + { + // mobj->lastlook - Don't disable behavior after first failure + // mobj->extravalue1 - Angle tolerance + // mobj->extravalue2 - Exec tag upon failure + // mobj->cvval - Allowable failure delay + // mobj->cvmem - Failure timer + + angle_t ang = mobj->angle - 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 + // yet tracer is still in the camera view + + // failure state: mobj is not facing tracer + // Reasaonable defaults: ANGLE_67h, ANGLE_292h + if (ang >= mobj->extravalue1 && ang <= ANGLE_MAX - mobj->extravalue1) + { + if (mobj->cvmem) + mobj->cvmem--; + else + { + P_LinedefExecute(mobj->extravalue2, mobj, NULL); + + if (mobj->lastlook) + mobj->cvmem = mobj->cusval; // reset timer for next failure + else + { + // disable after first failure + mobj->eflags &= ~MFE_TRACERANGLE; + mobj->lastlook = mobj->extravalue1 = mobj->extravalue2 = mobj->cvmem = mobj->cusval = 0; + } + } + } + else + mobj->cvmem = mobj->cusval; // reset failure timer + } + switch (mobj->type) { case MT_WALLSPIKEBASE: diff --git a/src/p_mobj.h b/src/p_mobj.h index 5c0408e1b..b80080674 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -239,6 +239,9 @@ typedef enum MFE_SPRUNG = 1<<8, // Platform movement MFE_APPLYPMOMZ = 1<<9, + // Compute and trigger on mobj angle relative to tracer + // See Linedef Exec 457 (Track mobj angle to point) + MFE_TRACERANGLE = 1<<10, // free: to and including 1<<15 } mobjeflag_t; diff --git a/src/p_spec.c b/src/p_spec.c index 9f9e80ecc..6bf20283e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3757,6 +3757,41 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) P_ResetColormapFader(§ors[secnum]); break; + case 457: // Track mobj angle to point + if (mo) + { + INT32 failureangle = min(max(abs(sides[line->sidenum[0]].textureoffset>>FRACBITS), 0), 360) * ANG1; + INT32 failuredelay = abs(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT32 failureexectag = line->sidenum[1] != 0xffff ? + (INT32)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; + boolean persist = (line->flags & ML_EFFECT2); + mobj_t *anchormo; + + if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0) + return; + + anchormo = P_GetObjectTypeInSectorNum(MT_ANGLEMAN, secnum); + if (!anchormo) + return; + + mo->eflags |= MFE_TRACERANGLE; + P_SetTarget(&mo->tracer, anchormo); + mo->lastlook = persist; // don't disable behavior after first failure + mo->extravalue1 = failureangle; // angle to exceed for failure state + mo->extravalue2 = failureexectag; // exec tag for failure state (angle is not within range) + mo->cusval = mo->cvmem = failuredelay; // cusval = tics to allow failure before line trigger; cvmem = decrement timer + } + break; + + case 458: // Stop tracking mobj angle to point + if (mo) + { + mo->eflags &= ~MFE_TRACERANGLE; + P_SetTarget(&mo->tracer, NULL); + mo->lastlook = mo->cvmem = mo->cusval = mo->extravalue1 = mo->extravalue2 = 0; + } + break; + #ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing From 4fc335a26b16b7290dc274181264436ff4799d67 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 16:48:18 -0500 Subject: [PATCH 155/264] Line 458: Only do disable operation if MFE_TRACERANGLE is set --- 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 6bf20283e..965e0cbe0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3784,7 +3784,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 458: // Stop tracking mobj angle to point - if (mo) + if (mo && (mo->eflags & MFE_TRACERANGLE)) { mo->eflags &= ~MFE_TRACERANGLE; P_SetTarget(&mo->tracer, NULL); From eaf89cf7b919422d0b033c54a53297026fcfd9bc Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 17:34:00 -0500 Subject: [PATCH 156/264] TRACERANGLE: Run exec *after* resetting mobj values --- src/p_mobj.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 45a26cbc5..c9cacb444 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7459,7 +7459,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->cvmem--; else { - P_LinedefExecute(mobj->extravalue2, mobj, NULL); + INT32 exectag = mobj->extravalue2; // remember this before we erase the values if (mobj->lastlook) mobj->cvmem = mobj->cusval; // reset timer for next failure @@ -7469,6 +7469,8 @@ void P_MobjThinker(mobj_t *mobj) mobj->eflags &= ~MFE_TRACERANGLE; mobj->lastlook = mobj->extravalue1 = mobj->extravalue2 = mobj->cvmem = mobj->cusval = 0; } + + P_LinedefExecute(exectag, mobj, NULL); } } else From b7c6661c76db66d4158875c60bdf37525b080d86 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 20:16:33 -0500 Subject: [PATCH 157/264] Add MTF_EXTRA flag to monitors, to run linedef exec by Angle (Tag + 16384) upon pop --- src/p_enemy.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index 8088c20a8..15608f57f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3324,6 +3324,11 @@ void A_MonitorPop(mobj_t *actor) newmobj->sprite = SPR_TV1P; } } + + // Run a linedef executor immediately upon popping + // You may want to delay your effects by 18 tics to sync with the reward giving + if (actor->spawnpoint && (actor->spawnpoint->options & MTF_EXTRA) && (actor->spawnpoint->angle & 16384)) + P_LinedefExecute((actor->spawnpoint->angle & 16383), actor->target, NULL); } // Function: A_GoldMonitorPop From 77447492ecf02bf3b487c9a24bf624b270b80ab5 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 4 Sep 2018 19:21:58 +0100 Subject: [PATCH 158/264] Add V_DrawTutorialBack for drawing a console-like background box, add Lorem ipsum as filler test --- src/v_video.c | 19 +++++++++++++++++++ src/v_video.h | 1 + 2 files changed, 20 insertions(+) diff --git a/src/v_video.c b/src/v_video.c index 2f84d4c7e..06f96a605 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1480,6 +1480,25 @@ void V_DrawFadeConsBack(INT32 plines) *buf = consolebgmap[*buf]; } +// Very similar to F_DrawFadeConsBack, except we draw from the middle(-ish) of the screen to the bottom. +void V_DrawTutorialBack(void) +{ + INT32 charheight = 8*vid.dupy; + UINT8 *deststop, *buf; + +#ifdef HWRENDER + if (rendermode != render_soft) // no support for OpenGL yet + return; +#endif + + // heavily simplified -- we don't need to know x or y position, + // just the start and stop positions + deststop = screens[0] + vid.rowbytes * vid.height; + buf = deststop - vid.rowbytes * ((charheight * 4) + (charheight/2)*5); // 4 lines of space plus gaps between and some leeway + for (; buf < deststop; ++buf) + *buf = consolebgmap[*buf]; +} + // Gets string colormap, used for 0x80 color codes // static const UINT8 *V_GetStringColormap(INT32 colorflags) diff --git a/src/v_video.h b/src/v_video.h index 6113d08ec..850206816 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -158,6 +158,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); void V_DrawFadeScreen(UINT16 color, UINT8 strength); void V_DrawFadeConsBack(INT32 plines); +void V_DrawTutorialBack(void); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); From 95c68c331a79e1837efc41e208c87d0079deaa1f Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 01:27:32 -0400 Subject: [PATCH 159/264] TextPrompt/Page freeslots; SOC Prompt/Page parsing --- src/dehacked.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++ src/doomstat.h | 22 +++++ src/g_game.c | 1 + 3 files changed, 245 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 6c39fc197..9f48b5f57 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1545,6 +1545,218 @@ static void readcutscene(MYFILE *f, INT32 num) Z_Free(s); } +static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) +{ + char *s = Z_Calloc(MAXLINELEN, PU_STATIC, NULL); + char *word; + char *word2; + INT32 i; + UINT16 usi; + + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + word = strtok(s, " "); + if (word) + strupr(word); + else + break; + + if (fastcmp(word, "PAGETEXT")) + { + char *pagetext = NULL; + char *buffer; + const int bufferlen = 4096; + + for (i = 0; i < MAXLINELEN; i++) + { + if (s[i] == '=') + { + pagetext = &s[i+2]; + break; + } + } + + if (!pagetext) + { + Z_Free(textprompts[num]->page[pagenum].text); + textprompts[num]->page[pagenum].text = NULL; + continue; + } + + for (i = 0; i < MAXLINELEN; i++) + { + if (s[i] == '\0') + { + s[i] = '\n'; + s[i+1] = '\0'; + break; + } + } + + buffer = Z_Malloc(4096, PU_STATIC, NULL); + strcpy(buffer, pagetext); + + strcat(buffer, + myhashfgets(pagetext, bufferlen + - strlen(buffer) - 1, f)); + + // A text prompt overwriting another one... + Z_Free(textprompts[num]->page[pagenum].text); + + textprompts[num]->page[pagenum].text = Z_StrDup(buffer); + + Z_Free(buffer); + + continue; + } + + word2 = strtok(NULL, " = "); + if (word2) + strupr(word2); + else + break; + + if (word2[strlen(word2)-1] == '\n') + word2[strlen(word2)-1] = '\0'; + i = atoi(word2); + usi = (UINT16)i; + + + if (fastcmp(word, "NAME")) + strncpy(textprompts[num]->page[pagenum].name, word2, 32); + else if (fastcmp(word, "ICON")) + strncpy(textprompts[num]->page[pagenum].iconname, word2, 8); + else if (fastcmp(word, "ICONALIGN")) + textprompts[num]->page[pagenum].rightside = (i || word2[0] == 'R'); + else if (fastcmp(word, "LINES")) + textprompts[num]->page[pagenum].lines = usi; + else if (fastcmp(word, "BACKCOLOR")) + { + UINT8 backcolor; + if (usi == 0 || fastcmp(word2, "WHITE")) backcolor = 0; + else if (usi == 1 || fastcmp(word2, "GRAY") || fastcmp(word2, "GREY")) backcolor = 1; + else if (usi == 2 || fastcmp(word2, "BROWN")) backcolor = 2; + else if (usi == 3 || fastcmp(word2, "RED")) backcolor = 3; + else if (usi == 4 || fastcmp(word2, "ORANGE")) backcolor = 4; + else if (usi == 5 || fastcmp(word2, "YELLOW")) backcolor = 5; + else if (usi == 6 || fastcmp(word2, "GREEN")) backcolor = 6; + else if (usi == 7 || fastcmp(word2, "BLUE")) backcolor = 7; + else if (usi == 8 || fastcmp(word2, "PURPLE")) backcolor = 8; + else if (usi == 9 || fastcmp(word2, "MAGENTA")) backcolor = 9; + else if (usi == 10 || fastcmp(word2, "AQUA")) backcolor = 10; + else if (usi < 0) backcolor = UINT8_MAX; // CONS_BACKCOLOR user-configured + else backcolor = 11; // default green + textprompts[num]->page[pagenum].backcolor = backcolor; + } + else if (fastcmp(word, "ALIGN")) + { + UINT8 align = 0; // left + if (usi == 1 || word2[0] == 'R') align = 1; + else if (usi == 2 || word2[0] == 'C' || word2[0] == 'M') align = 2; + textprompts[num]->page[pagenum].align = align; + } + else if (fastcmp(word, "VERTICALALIGN")) + { + UINT8 align = 0; // top + if (usi == 1 || word2[0] == 'B') align = 1; + else if (usi == 2 || word2[0] == 'C' || word2[0] == 'M') align = 2; + textprompts[num]->page[pagenum].verticalalign = align; + } + else if (fastcmp(word, "TEXTSPEED")) + textprompts[num]->page[pagenum].textspeed = min(max(0, usi), 15); + else if (fastcmp(word, "TEXTSFX")) + textprompts[num]->page[pagenum].textsfx = get_number(word2); + else if (fastcmp(word, "METAPAGE")) + { + if (usi <= textprompts[num]->numpages) + { + strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[usi].name, 32); + strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[usi].iconname, 8); + textprompts[num]->page[pagenum].rightside = textprompts[num]->page[usi].rightside; + textprompts[num]->page[pagenum].lines = textprompts[num]->page[usi].lines; + textprompts[num]->page[pagenum].backcolor = textprompts[num]->page[usi].backcolor; + textprompts[num]->page[pagenum].align = textprompts[num]->page[usi].align; + textprompts[num]->page[pagenum].verticalalign = textprompts[num]->page[usi].verticalalign; + textprompts[num]->page[pagenum].textspeed = textprompts[num]->page[usi].textspeed; + textprompts[num]->page[pagenum].textsfx = textprompts[num]->page[usi].textsfx; + } + } + else + deh_warning("PromptPage %d: unknown word '%s'", num, word); + } + } while (!myfeof(f)); // finish when the line is empty + + Z_Free(s); +} + +static void readtextprompt(MYFILE *f, INT32 num) +{ + char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word; + char *word2; + char *tmp; + INT32 value; + + // Allocate memory for this prompt if we don't yet have any + if (!textprompts[num]) + textprompts[num] = Z_Calloc(sizeof (textprompt_t), PU_STATIC, NULL); + + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + tmp = strchr(s, '#'); + if (tmp) + *tmp = '\0'; + if (s == tmp) + continue; // Skip comment lines, but don't break. + + word = strtok(s, " "); + if (word) + strupr(word); + else + break; + + word2 = strtok(NULL, " "); + if (word2) + value = atoi(word2); + else + { + deh_warning("No value for token %s", word); + continue; + } + + if (fastcmp(word, "NUMPAGES")) + { + textprompts[num]->numpages = value; + } + else if (fastcmp(word, "PAGE")) + { + if (1 <= value && value <= 128) + { + textprompts[num]->page[value - 1].backcolor = UINT8_MAX; // non-zero default + readtextpromptpage(f, num, value - 1); + } + else + deh_warning("Page number %d out of range (1 - 128)", value); + + } + else + deh_warning("Prompt %d: unknown word '%s', Page expected.", num, word); + } + } while (!myfeof(f)); // finish when the line is empty + + Z_Free(s); +} + static void readhuditem(MYFILE *f, INT32 num) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -3214,6 +3426,16 @@ static void DEH_LoadDehackedFile(MYFILE *f) ignorelines(f); } } + else if (fastcmp(word, "PROMPT")) + { + if (i > 0 && i < 257) + readtextprompt(f, i - 1); + else + { + deh_warning("Prompt number %d out of range (1 - 256)", i); + ignorelines(f); + } + } else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE")) { if (i == 0 && word2[0] != '0') // If word2 isn't a number diff --git a/src/doomstat.h b/src/doomstat.h index 7678c86b7..d737ef451 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -166,6 +166,28 @@ typedef struct extern cutscene_t *cutscenes[128]; +typedef struct +{ + char name[32]; // narrator name + char iconname[8]; // narrator icon lump + boolean rightside; // narrator side, false = left, true = right + UINT8 lines; // # of lines to show. If name is specified, name takes one of the lines. If 0, defaults to 4. + UINT8 backcolor; // see CON_SetupBackColormap: 0-10, 11 for default, UINT8_MAX for user-defined (CONS_BACKCOLOR) + UINT8 align; // text alignment, 0 = left, 1 = right, 2 = center + UINT8 verticalalign; // vertical text alignment, 0 = top, 1 = bottom, 2 = middle + UINT8 textspeed; // text speed 0-15, makes it slower. See f_finale.c F_WriteText + sfxenum_t textsfx; // sfx_ id for printing text + char *text; +} textpage_t; + +typedef struct +{ + textpage_t page[128]; // 128 pages per prompt. + INT32 numpages; // Number of pages in this prompt +} textprompt_t; + +extern textprompt_t *textprompts[256]; + // For the Custom Exit linedef. extern INT16 nextmapoverride; extern boolean skipstats; diff --git a/src/g_game.c b/src/g_game.c index 0a392fa85..df8e0fd79 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -138,6 +138,7 @@ tic_t countdowntimer = 0; boolean countdowntimeup = false; cutscene_t *cutscenes[128]; +textprompt_t *textprompts[256]; INT16 nextmapoverride; boolean skipstats; From ef241b4521fb4ece6eae1f6e46756adebbb5194c Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 04:38:16 -0400 Subject: [PATCH 160/264] Broken attempt at supporting linebreaks for PageText, like cutscenes --- src/dehacked.c | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 9f48b5f57..963285cff 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -146,7 +146,7 @@ char *myfgets(char *buf, size_t bufsize, MYFILE *f) return buf; } -static char *myhashfgets(char *buf, size_t bufsize, MYFILE *f) +static char *myhashfgets(char *buf, size_t bufsize, MYFILE *f, boolean trim) { size_t i = 0; if (myfeof(f)) @@ -165,11 +165,34 @@ static char *myhashfgets(char *buf, size_t bufsize, MYFILE *f) if (c == '\n') // Ensure debug line is right... dbg_line++; if (c == '#') + { + if (i > 0) + i--; // don't include the hash in our string break; + } } - i++; - buf[i] = '\0'; + // HACK: BS code to make sure i doesn't wrap past 0 + // and put the terminator char AFTER the first non-whitespace char + // OR at position 0 if the first char is whitespace OR a hash + if (trim) // trailing whitespace only + { + if (i > 0) + i--; // current char may be '#', so skip that + while (i < bufsize && i > 0 && !myfeof(f)) + { + char c = buf[i]; + if (i > 0) + i--; + if ((c != '\r' && c != '\n' && c != ' ') || i == 0) + break; + } + if (buf[i] != '\r' && buf[i] != '\n' && buf[i] != ' ' && buf[i] != '#') + i++; // put the null character after the first non-whitespace char + } + + buf[i] = '\0'; + CONS_Printf("%s", buf); return buf; } @@ -352,7 +375,7 @@ static void readPlayer(MYFILE *f, INT32 num) if (playertext) { strcpy(description[num].notes, playertext); - strcat(description[num].notes, myhashfgets(playertext, sizeof (description[num].notes), f)); + strcat(description[num].notes, myhashfgets(playertext, sizeof (description[num].notes), f, false)); } else strcpy(description[num].notes, ""); @@ -1368,7 +1391,7 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) strcat(buffer, myhashfgets(scenetext, bufferlen - - strlen(buffer) - 1, f)); + - strlen(buffer) - 1, f, false)); // A cutscene overwriting another one... Z_Free(cutscenes[num]->scene[scenenum].text); @@ -1603,7 +1626,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) strcat(buffer, myhashfgets(pagetext, bufferlen - - strlen(buffer) - 1, f)); + - strlen(buffer) - 1, f, true)); // A text prompt overwriting another one... Z_Free(textprompts[num]->page[pagenum].text); @@ -1628,7 +1651,16 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) if (fastcmp(word, "NAME")) - strncpy(textprompts[num]->page[pagenum].name, word2, 32); + { + // HACK: Add yellow control char now + // so the drawing function doesn't call it repeatedly + char name[32]; + name[0] = '\x82'; // color yellow + name[1] = 0; + strncat(name, word2, 31); + name[31] = 0; + strncpy(textprompts[num]->page[pagenum].name, name, 32); + } else if (fastcmp(word, "ICON")) strncpy(textprompts[num]->page[pagenum].iconname, word2, 8); else if (fastcmp(word, "ICONALIGN")) From a3d000a37ecf21c93994252e1d4370cc9eb35161 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 05:04:09 -0400 Subject: [PATCH 161/264] Kind of support line breaks with PAGETEXT. Can't trim trailing whitespace yet. --- src/dehacked.c | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 963285cff..b439f43de 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -146,7 +146,7 @@ char *myfgets(char *buf, size_t bufsize, MYFILE *f) return buf; } -static char *myhashfgets(char *buf, size_t bufsize, MYFILE *f, boolean trim) +static char *myhashfgets(char *buf, size_t bufsize, MYFILE *f) { size_t i = 0; if (myfeof(f)) @@ -166,33 +166,15 @@ static char *myhashfgets(char *buf, size_t bufsize, MYFILE *f, boolean trim) dbg_line++; if (c == '#') { - if (i > 0) - i--; // don't include the hash in our string + if (i > 0) // don't let i wrap past 0 + i--; // don't include hash char in string break; } } - - // HACK: BS code to make sure i doesn't wrap past 0 - // and put the terminator char AFTER the first non-whitespace char - // OR at position 0 if the first char is whitespace OR a hash - if (trim) // trailing whitespace only - { - if (i > 0) - i--; // current char may be '#', so skip that - while (i < bufsize && i > 0 && !myfeof(f)) - { - char c = buf[i]; - if (i > 0) - i--; - if ((c != '\r' && c != '\n' && c != ' ') || i == 0) - break; - } - if (buf[i] != '\r' && buf[i] != '\n' && buf[i] != ' ' && buf[i] != '#') - i++; // put the null character after the first non-whitespace char - } - + if (buf[i] != '#') // don't include hash char in string + i++; buf[i] = '\0'; - CONS_Printf("%s", buf); + return buf; } @@ -375,7 +357,7 @@ static void readPlayer(MYFILE *f, INT32 num) if (playertext) { strcpy(description[num].notes, playertext); - strcat(description[num].notes, myhashfgets(playertext, sizeof (description[num].notes), f, false)); + strcat(description[num].notes, myhashfgets(playertext, sizeof (description[num].notes), f)); } else strcpy(description[num].notes, ""); @@ -1391,7 +1373,7 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) strcat(buffer, myhashfgets(scenetext, bufferlen - - strlen(buffer) - 1, f, false)); + - strlen(buffer) - 1, f)); // A cutscene overwriting another one... Z_Free(cutscenes[num]->scene[scenenum].text); @@ -1624,9 +1606,12 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) buffer = Z_Malloc(4096, PU_STATIC, NULL); strcpy(buffer, pagetext); + // \todo trim trailing whitespace before the # + // and also support # at the end of a PAGETEXT with no line break + strcat(buffer, myhashfgets(pagetext, bufferlen - - strlen(buffer) - 1, f, true)); + - strlen(buffer) - 1, f)); // A text prompt overwriting another one... Z_Free(textprompts[num]->page[pagenum].text); From cbcb6a0d6c7d072540931043603ebbf853e33832 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 05:05:15 -0400 Subject: [PATCH 162/264] Text prompt features: Name, Icon, IconAlign, Lines --- src/st_stuff.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/v_video.c | 7 ++++--- src/v_video.h | 2 +- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index fa13e008a..2a9d25cc7 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2465,6 +2465,49 @@ static void ST_overlayDrawer(void) ST_drawDebugInfo(); } +static void ST_drawTutorial(INT32 promptnum, INT32 pagenum) +{ + lumpnum_t iconlump = W_CheckNumForName(textprompts[promptnum]->page[pagenum].iconname); + UINT8 pagelines = textprompts[promptnum]->page[pagenum].lines ? textprompts[promptnum]->page[pagenum].lines : 4; + + // Vertical calculations + INT32 boxh = pagelines*2; + INT32 texth = textprompts[promptnum]->page[pagenum].name[0] ? (pagelines-1)*2 : pagelines*2; // name takes up first line if it exists + INT32 texty = BASEVIDHEIGHT - ((texth * 4) + (texth/2)*4); + INT32 namey = BASEVIDHEIGHT - ((boxh * 4) + (boxh/2)*4); + + // Horizontal calculations + // Shift text to the right if we have a character icon on the left side + // Add 4 margin against icon + INT32 textx = iconlump != LUMPERROR && !textprompts[promptnum]->page[pagenum].rightside ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; + INT32 textr = textprompts[promptnum]->page[pagenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; + + // Data + patch_t *patch; + char *text; + + // Draw background + V_DrawTutorialBack(boxh); + + // Draw narrator icon + if (iconlump != LUMPERROR) + { + INT32 iconx = textprompts[promptnum]->page[pagenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4; + patch = W_CachePatchName(textprompts[promptnum]->page[pagenum].iconname, PU_CACHE); + V_DrawFixedPatch(iconx<width), 0, patch, NULL); + W_UnlockCachedPatch(patch); + } + + // Draw text + // \todo Char-by-char printing, see f_finale.c F_WriteText + text = V_WordWrap(textx, textr, 0, textprompts[promptnum]->page[pagenum].text); + V_DrawString(textx, texty, V_SNAPTOBOTTOM, text); + + // Draw name + if (textprompts[promptnum]->page[pagenum].name[0]) + V_DrawString(textx, namey, V_SNAPTOBOTTOM, textprompts[promptnum]->page[pagenum].name); +} + void ST_Drawer(void) { #ifdef SEENAMES @@ -2538,4 +2581,8 @@ void ST_Drawer(void) ST_overlayDrawer(); } } + + // Draw tutorial text over everything else + //if (tutorialmode) + ST_drawTutorial(0, 0); } diff --git a/src/v_video.c b/src/v_video.c index 06f96a605..a628b1a8b 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1481,11 +1481,12 @@ void V_DrawFadeConsBack(INT32 plines) } // Very similar to F_DrawFadeConsBack, except we draw from the middle(-ish) of the screen to the bottom. -void V_DrawTutorialBack(void) +void V_DrawTutorialBack(INT32 boxheight) { - INT32 charheight = 8*vid.dupy; UINT8 *deststop, *buf; + boxheight *= vid.dupy; + #ifdef HWRENDER if (rendermode != render_soft) // no support for OpenGL yet return; @@ -1494,7 +1495,7 @@ void V_DrawTutorialBack(void) // heavily simplified -- we don't need to know x or y position, // just the start and stop positions deststop = screens[0] + vid.rowbytes * vid.height; - buf = deststop - vid.rowbytes * ((charheight * 4) + (charheight/2)*5); // 4 lines of space plus gaps between and some leeway + buf = deststop - vid.rowbytes * ((boxheight * 4) + (boxheight/2)*5); // 4 lines of space plus gaps between and some leeway for (; buf < deststop; ++buf) *buf = consolebgmap[*buf]; } diff --git a/src/v_video.h b/src/v_video.h index 850206816..ee958c2fa 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -158,7 +158,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); void V_DrawFadeScreen(UINT16 color, UINT8 strength); void V_DrawFadeConsBack(INT32 plines); -void V_DrawTutorialBack(void); +void V_DrawTutorialBack(INT32 boxheight); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); From 63e5cfecffd2cc3266cbce002ce6b9ddc722d9ba Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 05:06:18 -0400 Subject: [PATCH 163/264] Linedef Exec 449 Control Text Prompt - beginnings --- src/p_spec.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 9f9e80ecc..571e6277f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3455,6 +3455,29 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } break; + case 449: // Control Text Prompt +#if 0 + // console player only unless NOCLIMB is set + if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) + { + INT32 promptnum = abs(sides[line->sidenum[0]].textureoffset>>FRACBITS); + INT32 pagenum = abs(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT32 postexectag = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; + INT32 closedelay = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].rowoffset>>FRACBITS) : 0; + + boolean blockcontrols = !(line->flags & ML_BLOCKMONSTERS); + boolean closetextprompt = (line->flags & ML_EFFECT2); + boolean runpostexec = (line->flags & ML_EFFECT1); + boolean freezethinkers = (line->flags & ML_TFERLINE); + + // if (closetextprompt && !promptnum) + // P_CloseTextPromptEx(closedelay, runpostexec ? postexectag : 0, mo); + // else + // P_ControlTextPromptEx(promptnum, pagenum, closetextprompt ? closedelay : 0, runpostexec ? postexectag : 0, mo, blockcontrols, freezethinkers); + } +#endif + break; + case 450: // Execute Linedef Executor - for recursion P_LinedefExecute(line->tag, mo, NULL); break; From edcdf79b60d23ad4dc97377a40674c6a988bbe82 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 09:13:17 -0400 Subject: [PATCH 164/264] Text prompt: Fix V_DrawFixedPatch call for non-green resos --- 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 2a9d25cc7..ce5042971 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2494,7 +2494,7 @@ static void ST_drawTutorial(INT32 promptnum, INT32 pagenum) { INT32 iconx = textprompts[promptnum]->page[pagenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4; patch = W_CachePatchName(textprompts[promptnum]->page[pagenum].iconname, PU_CACHE); - V_DrawFixedPatch(iconx<width), 0, patch, NULL); + V_DrawFixedPatch(iconx<width), V_SNAPTOBOTTOM, patch, NULL); W_UnlockCachedPatch(patch); } From 1855359ac0a167091a1ad5dd70ef64361564f618 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 10:54:30 -0400 Subject: [PATCH 165/264] Moved TextPrompt logic to f_finale.c * Added basic TextPrompt ticker and drawer functions * Added chevron animation --- src/d_main.c | 1 + src/f_finale.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/f_finale.h | 5 +++ src/g_game.c | 1 + src/st_stuff.c | 47 -------------------------- 5 files changed, 99 insertions(+), 47 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 6cd6aaba6..6f9d46f36 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -424,6 +424,7 @@ static void D_Display(void) if (gamestate == GS_LEVEL) { ST_Drawer(); + F_TextPromptDrawer(); HU_Drawer(); } else diff --git a/src/f_finale.c b/src/f_finale.c index 151889c4c..c25dd9eca 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -48,6 +48,7 @@ static INT32 timetonext; // Delay between screen changes static INT32 continuetime; // Short delay when continuing static tic_t animtimer; // Used for some animation timings +static INT16 skullAnimCounter; // Chevron animation static INT32 roidtics; // Asteroid spinning static INT32 deplete; @@ -78,6 +79,8 @@ static patch_t *ttspop7; static void F_SkyScroll(INT32 scrollspeed); +static boolean promptactive = false; + // // CUTSCENE TEXT WRITING // @@ -2015,3 +2018,92 @@ boolean F_CutsceneResponder(event_t *event) return false; } + +void F_EndTextPrompt(void) +{ + promptactive = false; +} + +void F_StartTextPrompt(INT32 promptnum, INT32 pagenum) +{ + // We share vars, so no starting text prompts over cutscenes or title screens! + keypressed = false; + finalecount = 0; + timetonext = 0; + animtimer = 0; + stoptimer = 0; + skullAnimCounter = 0; + + cutnum = promptnum; + scenenum = pagenum; + promptactive = true; +} + +void F_TextPromptDrawer(void) +{ + // reuse: + // cutnum -> promptnum + // scenenum -> pagenum + + if (!promptactive) + return; + + lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); + UINT8 pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; + + // Vertical calculations + INT32 boxh = pagelines*2; + INT32 texth = textprompts[cutnum]->page[scenenum].name[0] ? (pagelines-1)*2 : pagelines*2; // name takes up first line if it exists + INT32 texty = BASEVIDHEIGHT - ((texth * 4) + (texth/2)*4); + INT32 namey = BASEVIDHEIGHT - ((boxh * 4) + (boxh/2)*4); + INT32 chevrony = BASEVIDHEIGHT - (((1*2) * 4) + ((1*2)/2)*4); // force on last line + + // Horizontal calculations + // Shift text to the right if we have a character icon on the left side + // Add 4 margin against icon + INT32 textx = iconlump != LUMPERROR && !textprompts[cutnum]->page[scenenum].rightside ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; + INT32 textr = textprompts[cutnum]->page[scenenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; + + // Data + patch_t *patch; + char *text; + + // Draw background + V_DrawTutorialBack(boxh); + + // Draw narrator icon + if (iconlump != LUMPERROR) + { + INT32 iconx = textprompts[cutnum]->page[scenenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4; + patch = W_CachePatchName(textprompts[cutnum]->page[scenenum].iconname, PU_CACHE); + V_DrawFixedPatch(iconx<width), V_SNAPTOBOTTOM, patch, NULL); + W_UnlockCachedPatch(patch); + } + + // Draw text + // \todo Char-by-char printing, see f_finale.c F_WriteText + text = V_WordWrap(textx, textr, 0, textprompts[cutnum]->page[scenenum].text); + V_DrawString(textx, texty, V_SNAPTOBOTTOM, text); + + // Draw name + // Don't use V_YELLOWMAP here so that the name color can be changed with control codes + if (textprompts[cutnum]->page[scenenum].name[0]) + V_DrawString(textx, namey, V_SNAPTOBOTTOM, textprompts[cutnum]->page[scenenum].name); + + // Draw chevron + V_DrawString(textr-8, chevrony + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); // down arrow +} + +void F_TextPromptTicker(void) +{ + if (!promptactive) + return; + + // advance animation + finalecount++; + cutscene_boostspeed = 0; + + // for the chevron + if (--skullAnimCounter <= 0) + skullAnimCounter = 8; +} diff --git a/src/f_finale.h b/src/f_finale.h index aadc64ad0..eb5872fca 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -33,6 +33,7 @@ void F_IntroTicker(void); void F_TitleScreenTicker(boolean run); void F_CutsceneTicker(void); void F_TitleDemoTicker(void); +void F_TextPromptTicker(void); // Called by main loop. FUNCMATH void F_GameEndDrawer(void); @@ -50,6 +51,10 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset void F_CutsceneDrawer(void); void F_EndCutScene(void); +void F_StartTextPrompt(INT32 promptnum, INT32 pagenum); +void F_TextPromptDrawer(void); +void F_EndTextPrompt(void); + void F_StartGameEnd(void); void F_StartIntro(void); void F_StartTitleScreen(void); diff --git a/src/g_game.c b/src/g_game.c index df8e0fd79..d72a1961b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1934,6 +1934,7 @@ void G_Ticker(boolean run) F_TitleDemoTicker(); P_Ticker(run); // tic the game ST_Ticker(); + F_TextPromptTicker(); AM_Ticker(); HU_Ticker(); break; diff --git a/src/st_stuff.c b/src/st_stuff.c index ce5042971..fa13e008a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2465,49 +2465,6 @@ static void ST_overlayDrawer(void) ST_drawDebugInfo(); } -static void ST_drawTutorial(INT32 promptnum, INT32 pagenum) -{ - lumpnum_t iconlump = W_CheckNumForName(textprompts[promptnum]->page[pagenum].iconname); - UINT8 pagelines = textprompts[promptnum]->page[pagenum].lines ? textprompts[promptnum]->page[pagenum].lines : 4; - - // Vertical calculations - INT32 boxh = pagelines*2; - INT32 texth = textprompts[promptnum]->page[pagenum].name[0] ? (pagelines-1)*2 : pagelines*2; // name takes up first line if it exists - INT32 texty = BASEVIDHEIGHT - ((texth * 4) + (texth/2)*4); - INT32 namey = BASEVIDHEIGHT - ((boxh * 4) + (boxh/2)*4); - - // Horizontal calculations - // Shift text to the right if we have a character icon on the left side - // Add 4 margin against icon - INT32 textx = iconlump != LUMPERROR && !textprompts[promptnum]->page[pagenum].rightside ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; - INT32 textr = textprompts[promptnum]->page[pagenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; - - // Data - patch_t *patch; - char *text; - - // Draw background - V_DrawTutorialBack(boxh); - - // Draw narrator icon - if (iconlump != LUMPERROR) - { - INT32 iconx = textprompts[promptnum]->page[pagenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4; - patch = W_CachePatchName(textprompts[promptnum]->page[pagenum].iconname, PU_CACHE); - V_DrawFixedPatch(iconx<width), V_SNAPTOBOTTOM, patch, NULL); - W_UnlockCachedPatch(patch); - } - - // Draw text - // \todo Char-by-char printing, see f_finale.c F_WriteText - text = V_WordWrap(textx, textr, 0, textprompts[promptnum]->page[pagenum].text); - V_DrawString(textx, texty, V_SNAPTOBOTTOM, text); - - // Draw name - if (textprompts[promptnum]->page[pagenum].name[0]) - V_DrawString(textx, namey, V_SNAPTOBOTTOM, textprompts[promptnum]->page[pagenum].name); -} - void ST_Drawer(void) { #ifdef SEENAMES @@ -2581,8 +2538,4 @@ void ST_Drawer(void) ST_overlayDrawer(); } } - - // Draw tutorial text over everything else - //if (tutorialmode) - ST_drawTutorial(0, 0); } From 7778507a703679e20ae1f0f5fcbbbfac15a43f46 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 10:54:47 -0400 Subject: [PATCH 166/264] Basic TextPrompt line action implemented --- src/p_spec.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 571e6277f..8f93b84a1 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -35,6 +35,7 @@ #include "m_misc.h" #include "m_cond.h" //unlock triggers #include "lua_hook.h" // LUAh_LinedefExecute +#include "f_finale.h" // control text prompt #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -3456,26 +3457,33 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 449: // Control Text Prompt -#if 0 // console player only unless NOCLIMB is set if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) { - INT32 promptnum = abs(sides[line->sidenum[0]].textureoffset>>FRACBITS); - INT32 pagenum = abs(sides[line->sidenum[0]].rowoffset>>FRACBITS); + INT32 promptnum = max(0, (sides[line->sidenum[0]].textureoffset>>FRACBITS)-1); + INT32 pagenum = max(0, (sides[line->sidenum[0]].rowoffset>>FRACBITS)-1); + + boolean closetextprompt = (line->flags & ML_EFFECT2); + + if (closetextprompt) + F_EndTextPrompt(); + else + F_StartTextPrompt(promptnum, pagenum); +#if 0 + INT32 postexectag = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; INT32 closedelay = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].rowoffset>>FRACBITS) : 0; boolean blockcontrols = !(line->flags & ML_BLOCKMONSTERS); - boolean closetextprompt = (line->flags & ML_EFFECT2); boolean runpostexec = (line->flags & ML_EFFECT1); boolean freezethinkers = (line->flags & ML_TFERLINE); // if (closetextprompt && !promptnum) - // P_CloseTextPromptEx(closedelay, runpostexec ? postexectag : 0, mo); + // F_EndTextPrompt(closedelay, runpostexec ? postexectag : 0, mo); // else - // P_ControlTextPromptEx(promptnum, pagenum, closetextprompt ? closedelay : 0, runpostexec ? postexectag : 0, mo, blockcontrols, freezethinkers); - } + // F_StartTextPrompt(promptnum, pagenum, closetextprompt ? closedelay : 0, runpostexec ? postexectag : 0, mo, blockcontrols, freezethinkers); #endif + } break; case 450: // Execute Linedef Executor - for recursion From 5f1052729c5db69c51bb6abc75919564e4ea4f86 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 11:12:27 -0400 Subject: [PATCH 167/264] Line 449 param rearranging --- src/p_spec.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 8f93b84a1..2771c85f7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3463,7 +3463,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT32 promptnum = max(0, (sides[line->sidenum[0]].textureoffset>>FRACBITS)-1); INT32 pagenum = max(0, (sides[line->sidenum[0]].rowoffset>>FRACBITS)-1); - boolean closetextprompt = (line->flags & ML_EFFECT2); + boolean closetextprompt = (line->flags & ML_BLOCKMONSTERS); if (closetextprompt) F_EndTextPrompt(); @@ -3474,9 +3474,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT32 postexectag = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; INT32 closedelay = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].rowoffset>>FRACBITS) : 0; - boolean blockcontrols = !(line->flags & ML_BLOCKMONSTERS); boolean runpostexec = (line->flags & ML_EFFECT1); - boolean freezethinkers = (line->flags & ML_TFERLINE); + boolean blockcontrols = !(line->flags & ML_EFFECT2); + boolean freezetimer = !(line->flags & ML_EFFECT3); + boolean freezethinkers = (line->flags & ML_EFFECT4); // if (closetextprompt && !promptnum) // F_EndTextPrompt(closedelay, runpostexec ? postexectag : 0, mo); From 971151ab836590126e7c6ba5e957fe03c5d01252 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 13:06:05 -0400 Subject: [PATCH 168/264] Fixes: MetaPage, AdvanceToNextPage, center/scale icons, button handling --- src/dehacked.c | 25 +++++++----- src/doomstat.h | 2 + src/f_finale.c | 107 +++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 116 insertions(+), 18 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b439f43de..2b466fab7 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1690,19 +1690,24 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].textsfx = get_number(word2); else if (fastcmp(word, "METAPAGE")) { - if (usi <= textprompts[num]->numpages) + if (usi && usi <= textprompts[num]->numpages) { - strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[usi].name, 32); - strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[usi].iconname, 8); - textprompts[num]->page[pagenum].rightside = textprompts[num]->page[usi].rightside; - textprompts[num]->page[pagenum].lines = textprompts[num]->page[usi].lines; - textprompts[num]->page[pagenum].backcolor = textprompts[num]->page[usi].backcolor; - textprompts[num]->page[pagenum].align = textprompts[num]->page[usi].align; - textprompts[num]->page[pagenum].verticalalign = textprompts[num]->page[usi].verticalalign; - textprompts[num]->page[pagenum].textspeed = textprompts[num]->page[usi].textspeed; - textprompts[num]->page[pagenum].textsfx = textprompts[num]->page[usi].textsfx; + UINT8 metapagenum = usi - 1; + strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, 32); + strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, 8); + textprompts[num]->page[pagenum].rightside = textprompts[num]->page[metapagenum].rightside; + textprompts[num]->page[pagenum].lines = textprompts[num]->page[metapagenum].lines; + textprompts[num]->page[pagenum].backcolor = textprompts[num]->page[metapagenum].backcolor; + textprompts[num]->page[pagenum].align = textprompts[num]->page[metapagenum].align; + textprompts[num]->page[pagenum].verticalalign = textprompts[num]->page[metapagenum].verticalalign; + textprompts[num]->page[pagenum].textspeed = textprompts[num]->page[metapagenum].textspeed; + textprompts[num]->page[pagenum].textsfx = textprompts[num]->page[metapagenum].textsfx; } } + else if (fastcmp(word, "NEXTPROMPT")) + textprompts[num]->page[pagenum].nextprompt = usi; + else if (fastcmp(word, "NEXTPAGE")) + textprompts[num]->page[pagenum].nextpage = usi; else deh_warning("PromptPage %d: unknown word '%s'", num, word); } diff --git a/src/doomstat.h b/src/doomstat.h index d737ef451..eaa19e3d6 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -177,6 +177,8 @@ typedef struct UINT8 verticalalign; // vertical text alignment, 0 = top, 1 = bottom, 2 = middle UINT8 textspeed; // text speed 0-15, makes it slower. See f_finale.c F_WriteText sfxenum_t textsfx; // sfx_ id for printing text + UINT8 nextprompt; // next prompt to jump to, one-based. 0 = current prompt + UINT8 nextpage; // next page to jump to, one-based. 0 = next page within prompt->numpages char *text; } textpage_t; diff --git a/src/f_finale.c b/src/f_finale.c index c25dd9eca..baaad10b0 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2019,6 +2019,47 @@ boolean F_CutsceneResponder(event_t *event) return false; } +// ================== +// TEXT PROMPTS +// ================== + +static void F_AdvanceToNextPage(void) +{ + UINT8 nextprompt = textprompts[cutnum]->page[scenenum].nextprompt, + nextpage = textprompts[cutnum]->page[scenenum].nextpage, + oldcutnum = cutnum; + + // determine next prompt + if (nextprompt) + { + if (textprompts[nextprompt-1]) + cutnum = nextprompt-1; + else + cutnum = INT32_MAX; + } + + // determine next page + if (nextpage) + { + scenenum = nextpage-1; + if (scenenum > textprompts[cutnum]->numpages-1) + scenenum = INT32_MAX; + } + else + { + if (cutnum != oldcutnum) + scenenum = 0; + else if (scenenum < textprompts[cutnum]->numpages-1) + scenenum++; + else + scenenum = INT32_MAX; + } + + // close the prompt if either num is invalid + if (cutnum == INT32_MAX || scenenum == INT32_MAX) + F_EndTextPrompt(); +} + void F_EndTextPrompt(void) { promptactive = false; @@ -2034,9 +2075,9 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum) stoptimer = 0; skullAnimCounter = 0; - cutnum = promptnum; - scenenum = pagenum; - promptactive = true; + cutnum = (textprompts[promptnum]) ? promptnum : INT32_MAX; + scenenum = (pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX; + promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX); } void F_TextPromptDrawer(void) @@ -2050,6 +2091,7 @@ void F_TextPromptDrawer(void) lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); UINT8 pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; + boolean rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); // Vertical calculations INT32 boxh = pagelines*2; @@ -2061,8 +2103,8 @@ void F_TextPromptDrawer(void) // Horizontal calculations // Shift text to the right if we have a character icon on the left side // Add 4 margin against icon - INT32 textx = iconlump != LUMPERROR && !textprompts[cutnum]->page[scenenum].rightside ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; - INT32 textr = textprompts[cutnum]->page[scenenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; + INT32 textx = (iconlump != LUMPERROR && !rightside) ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; + INT32 textr = rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; // Data patch_t *patch; @@ -2074,9 +2116,33 @@ void F_TextPromptDrawer(void) // Draw narrator icon if (iconlump != LUMPERROR) { - INT32 iconx = textprompts[cutnum]->page[scenenum].rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4; + INT32 iconx, icony, scale, scaledsize; patch = W_CachePatchName(textprompts[cutnum]->page[scenenum].iconname, PU_CACHE); - V_DrawFixedPatch(iconx<width), V_SNAPTOBOTTOM, patch, NULL); + + // scale and center + if (patch->width > patch->height) + { + scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->width); + scaledsize = FixedMul(patch->height, scale); + iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS; + icony = ((namey-4) << FRACBITS) + FixedDiv(BASEVIDHEIGHT - namey + 4 - scaledsize, 2); // account for 4 margin + } + else if (patch->height > patch->width) + { + scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->height); + scaledsize = FixedMul(patch->width, scale); + iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS; + icony = namey << FRACBITS; + iconx += FixedDiv(FixedMul(patch->height, scale) - scaledsize, 2); + } + else + { + scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->width); + iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS; + icony = namey << FRACBITS; + } + + V_DrawFixedPatch(iconx, icony, scale, V_SNAPTOBOTTOM, patch, NULL); W_UnlockCachedPatch(patch); } @@ -2091,11 +2157,13 @@ void F_TextPromptDrawer(void) V_DrawString(textx, namey, V_SNAPTOBOTTOM, textprompts[cutnum]->page[scenenum].name); // Draw chevron - V_DrawString(textr-8, chevrony + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); // down arrow + V_DrawString(textr-8, chevrony + (skullAnimCounter/5), (V_SNAPTOBOTTOM|V_YELLOWMAP), "\x1B"); // down arrow } void F_TextPromptTicker(void) { + INT32 i; + if (!promptactive) return; @@ -2106,4 +2174,27 @@ void F_TextPromptTicker(void) // for the chevron if (--skullAnimCounter <= 0) skullAnimCounter = 8; + + // button handling + for (i = 0; i < MAXPLAYERS; i++) + { + if (netgame && i != serverplayer && i != adminplayer) + continue; + + if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP)) + { + if (keypressed) + return; + + cutscene_boostspeed = 1; + if (timetonext) + timetonext = 2; + F_AdvanceToNextPage(); + keypressed = true; // prevent repeat events + } + else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP)) + keypressed = false; + + break; + } } From 57d9e0aef6c1e61a03bfb4ecc16d43628aa9916b Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 14:43:19 -0400 Subject: [PATCH 169/264] TextPrompt: Implement player blocked controls and post-close run line --- src/f_finale.c | 69 +++++++++++++++++++++++++++++++++++++------------- src/f_finale.h | 2 +- src/p_spec.c | 22 +++++----------- 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index baaad10b0..b30160b87 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -79,7 +79,13 @@ static patch_t *ttspop7; static void F_SkyScroll(INT32 scrollspeed); +// +// PROMPT STATE +// static boolean promptactive = false; +static mobj_t *promptmo; +static INT16 promptpostexectag; +static boolean promptblockcontrols; // // CUTSCENE TEXT WRITING @@ -2063,9 +2069,20 @@ static void F_AdvanceToNextPage(void) void F_EndTextPrompt(void) { promptactive = false; + + // \todo net safety, maybe loop all player thinkers? + if (promptpostexectag) + P_LinedefExecute(promptpostexectag, promptmo, NULL); + + // \todo reset blocked controls and frozen realtime? + + P_SetTarget(&promptmo, NULL); // \todo tmthing crash upon teleporting? see test map + + // \todo if !promptactive, block player jumping if BT_JUMP is set + // so player does not immediately jump upon prompt close } -void F_StartTextPrompt(INT32 promptnum, INT32 pagenum) +void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime) { // We share vars, so no starting text prompts over cutscenes or title screens! keypressed = false; @@ -2075,6 +2092,13 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum) stoptimer = 0; skullAnimCounter = 0; + // Set up state + P_SetTarget(&promptmo, mo); //promptmo = mo; + promptpostexectag = postexectag; + promptblockcontrols = blockcontrols; + (void)freezerealtime; // \todo freeze player->realtime, maybe this needs to cycle through player thinkers + + // Initialize current prompt and scene cutnum = (textprompts[promptnum]) ? promptnum : INT32_MAX; scenenum = (pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX; promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX); @@ -2157,7 +2181,8 @@ void F_TextPromptDrawer(void) V_DrawString(textx, namey, V_SNAPTOBOTTOM, textprompts[cutnum]->page[scenenum].name); // Draw chevron - V_DrawString(textr-8, chevrony + (skullAnimCounter/5), (V_SNAPTOBOTTOM|V_YELLOWMAP), "\x1B"); // down arrow + if (promptblockcontrols) // \todo if !CloseTimer + V_DrawString(textr-8, chevrony + (skullAnimCounter/5), (V_SNAPTOBOTTOM|V_YELLOWMAP), "\x1B"); // down arrow } void F_TextPromptTicker(void) @@ -2176,25 +2201,35 @@ void F_TextPromptTicker(void) skullAnimCounter = 8; // button handling - for (i = 0; i < MAXPLAYERS; i++) + if (promptblockcontrols) { - if (netgame && i != serverplayer && i != adminplayer) - continue; + // \todo loop through all players that have a text prompt + if (promptmo && promptmo->player) + promptmo->player->powers[pw_nocontrol] = 1; - if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP)) + for (i = 0; i < MAXPLAYERS; i++) { - if (keypressed) - return; + if (netgame && i != serverplayer && i != adminplayer) + continue; - cutscene_boostspeed = 1; - if (timetonext) - timetonext = 2; - F_AdvanceToNextPage(); - keypressed = true; // prevent repeat events + if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP)) + { + if (keypressed) + return; + + cutscene_boostspeed = 1; + if (timetonext) + timetonext = 2; + F_AdvanceToNextPage(); + keypressed = true; // prevent repeat events + + if (promptactive) + S_StartSound(NULL, sfx_menu1); + } + else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP)) + keypressed = false; + + break; } - else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP)) - keypressed = false; - - break; } } diff --git a/src/f_finale.h b/src/f_finale.h index eb5872fca..66b608e21 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -51,7 +51,7 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset void F_CutsceneDrawer(void); void F_EndCutScene(void); -void F_StartTextPrompt(INT32 promptnum, INT32 pagenum); +void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime); void F_TextPromptDrawer(void); void F_EndTextPrompt(void); diff --git a/src/p_spec.c b/src/p_spec.c index 2771c85f7..cd4dd76cf 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3462,28 +3462,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { INT32 promptnum = max(0, (sides[line->sidenum[0]].textureoffset>>FRACBITS)-1); INT32 pagenum = max(0, (sides[line->sidenum[0]].rowoffset>>FRACBITS)-1); + INT32 postexectag = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; boolean closetextprompt = (line->flags & ML_BLOCKMONSTERS); + boolean runpostexec = (line->flags & ML_EFFECT1); + boolean blockcontrols = !(line->flags & ML_EFFECT2); + boolean freezerealtime = !(line->flags & ML_EFFECT3); + //boolean freezethinkers = (line->flags & ML_EFFECT4); if (closetextprompt) F_EndTextPrompt(); else - F_StartTextPrompt(promptnum, pagenum); -#if 0 - - INT32 postexectag = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; - INT32 closedelay = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].rowoffset>>FRACBITS) : 0; - - boolean runpostexec = (line->flags & ML_EFFECT1); - boolean blockcontrols = !(line->flags & ML_EFFECT2); - boolean freezetimer = !(line->flags & ML_EFFECT3); - boolean freezethinkers = (line->flags & ML_EFFECT4); - - // if (closetextprompt && !promptnum) - // F_EndTextPrompt(closedelay, runpostexec ? postexectag : 0, mo); - // else - // F_StartTextPrompt(promptnum, pagenum, closetextprompt ? closedelay : 0, runpostexec ? postexectag : 0, mo, blockcontrols, freezethinkers); -#endif + F_StartTextPrompt(promptnum, pagenum, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime); } break; From 98d532f119e1a52b1193952c68fe1b3dffe00f00 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 15:07:02 -0400 Subject: [PATCH 170/264] EndTextPrompt: Fix tmthing crash with P_LinedefExecute --- src/f_finale.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index b30160b87..8d578c61f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2072,11 +2072,15 @@ void F_EndTextPrompt(void) // \todo net safety, maybe loop all player thinkers? if (promptpostexectag) + { + P_MapStart(); P_LinedefExecute(promptpostexectag, promptmo, NULL); + P_MapEnd(); + } - // \todo reset blocked controls and frozen realtime? + // \todo reset frozen realtime? - P_SetTarget(&promptmo, NULL); // \todo tmthing crash upon teleporting? see test map + P_SetTarget(&promptmo, NULL); // \todo if !promptactive, block player jumping if BT_JUMP is set // so player does not immediately jump upon prompt close @@ -2093,7 +2097,7 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex skullAnimCounter = 0; // Set up state - P_SetTarget(&promptmo, mo); //promptmo = mo; + P_SetTarget(&promptmo, mo); promptpostexectag = postexectag; promptblockcontrols = blockcontrols; (void)freezerealtime; // \todo freeze player->realtime, maybe this needs to cycle through player thinkers From d327f82e854ed62f532f5c40d7878bc5ad1f069a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 3 Nov 2018 21:13:44 +0000 Subject: [PATCH 171/264] Fix errors found when compiling --- src/dehacked.c | 26 +++++++++++++------------- src/f_finale.c | 45 +++++++++++++++++++++++++-------------------- src/f_finale.h | 1 + 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 2b466fab7..725a30b4e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1655,18 +1655,18 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) else if (fastcmp(word, "BACKCOLOR")) { UINT8 backcolor; - if (usi == 0 || fastcmp(word2, "WHITE")) backcolor = 0; - else if (usi == 1 || fastcmp(word2, "GRAY") || fastcmp(word2, "GREY")) backcolor = 1; - else if (usi == 2 || fastcmp(word2, "BROWN")) backcolor = 2; - else if (usi == 3 || fastcmp(word2, "RED")) backcolor = 3; - else if (usi == 4 || fastcmp(word2, "ORANGE")) backcolor = 4; - else if (usi == 5 || fastcmp(word2, "YELLOW")) backcolor = 5; - else if (usi == 6 || fastcmp(word2, "GREEN")) backcolor = 6; - else if (usi == 7 || fastcmp(word2, "BLUE")) backcolor = 7; - else if (usi == 8 || fastcmp(word2, "PURPLE")) backcolor = 8; - else if (usi == 9 || fastcmp(word2, "MAGENTA")) backcolor = 9; - else if (usi == 10 || fastcmp(word2, "AQUA")) backcolor = 10; - else if (usi < 0) backcolor = UINT8_MAX; // CONS_BACKCOLOR user-configured + if (i == 0 || fastcmp(word2, "WHITE")) backcolor = 0; + else if (i == 1 || fastcmp(word2, "GRAY") || fastcmp(word2, "GREY")) backcolor = 1; + else if (i == 2 || fastcmp(word2, "BROWN")) backcolor = 2; + else if (i == 3 || fastcmp(word2, "RED")) backcolor = 3; + else if (i == 4 || fastcmp(word2, "ORANGE")) backcolor = 4; + else if (i == 5 || fastcmp(word2, "YELLOW")) backcolor = 5; + else if (i == 6 || fastcmp(word2, "GREEN")) backcolor = 6; + else if (i == 7 || fastcmp(word2, "BLUE")) backcolor = 7; + else if (i == 8 || fastcmp(word2, "PURPLE")) backcolor = 8; + else if (i == 9 || fastcmp(word2, "MAGENTA")) backcolor = 9; + else if (i == 10 || fastcmp(word2, "AQUA")) backcolor = 10; + else if (i < 0) backcolor = UINT8_MAX; // CONS_BACKCOLOR user-configured else backcolor = 11; // default green textprompts[num]->page[pagenum].backcolor = backcolor; } @@ -1685,7 +1685,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].verticalalign = align; } else if (fastcmp(word, "TEXTSPEED")) - textprompts[num]->page[pagenum].textspeed = min(max(0, usi), 15); + textprompts[num]->page[pagenum].textspeed = min(max(0, i), 15); else if (fastcmp(word, "TEXTSFX")) textprompts[num]->page[pagenum].textsfx = get_number(word2); else if (fastcmp(word, "METAPAGE")) diff --git a/src/f_finale.c b/src/f_finale.c index 8d578c61f..5f6d8ce42 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2113,31 +2113,36 @@ void F_TextPromptDrawer(void) // reuse: // cutnum -> promptnum // scenenum -> pagenum - - if (!promptactive) - return; - - lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); - UINT8 pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; - boolean rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); - - // Vertical calculations - INT32 boxh = pagelines*2; - INT32 texth = textprompts[cutnum]->page[scenenum].name[0] ? (pagelines-1)*2 : pagelines*2; // name takes up first line if it exists - INT32 texty = BASEVIDHEIGHT - ((texth * 4) + (texth/2)*4); - INT32 namey = BASEVIDHEIGHT - ((boxh * 4) + (boxh/2)*4); - INT32 chevrony = BASEVIDHEIGHT - (((1*2) * 4) + ((1*2)/2)*4); // force on last line - - // Horizontal calculations - // Shift text to the right if we have a character icon on the left side - // Add 4 margin against icon - INT32 textx = (iconlump != LUMPERROR && !rightside) ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; - INT32 textr = rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; + lumpnum_t iconlump; + UINT8 pagelines; + boolean rightside; + INT32 boxh, texth, texty, namey, chevrony; + INT32 textx, textr; // Data patch_t *patch; char *text; + if (!promptactive) + return; + + iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); + pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; + rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); + + // Vertical calculations + boxh = pagelines*2; + texth = textprompts[cutnum]->page[scenenum].name[0] ? (pagelines-1)*2 : pagelines*2; // name takes up first line if it exists + texty = BASEVIDHEIGHT - ((texth * 4) + (texth/2)*4); + namey = BASEVIDHEIGHT - ((boxh * 4) + (boxh/2)*4); + chevrony = BASEVIDHEIGHT - (((1*2) * 4) + ((1*2)/2)*4); // force on last line + + // Horizontal calculations + // Shift text to the right if we have a character icon on the left side + // Add 4 margin against icon + textx = (iconlump != LUMPERROR && !rightside) ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; + textr = rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; + // Draw background V_DrawTutorialBack(boxh); diff --git a/src/f_finale.h b/src/f_finale.h index 66b608e21..dfee247fb 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -17,6 +17,7 @@ #include "doomtype.h" #include "d_event.h" +#include "p_mobj.h" // // FINALE From 444462732b24a13c2142523bca7ac05e4d2b62e7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 3 Nov 2018 21:14:17 +0000 Subject: [PATCH 172/264] added HWR_DrawTutorialBack for OpenGL --- src/hardware/hw_draw.c | 26 ++++++++++++++++++++++++++ src/hardware/hw_main.h | 1 + src/v_video.c | 20 +++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 02608892e..6d4467439 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -705,6 +705,32 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height) HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } +// Very similar to HWR_DrawConsoleBack, except we draw from the middle(-ish) of the screen to the bottom. +void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight) +{ + FOutVector v[4]; + FSurfaceInfo Surf; + INT32 height = (boxheight * 4) + (boxheight/2)*5; // 4 lines of space plus gaps between and some leeway + + // setup some neat-o translucency effect + + v[0].x = v[3].x = -1.0f; + v[2].x = v[1].x = 1.0f; + v[0].y = v[1].y = -1.0f; + v[2].y = v[3].y = -1.0f+((height<<1)/(float)vid.height); + v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; + + v[0].sow = v[3].sow = 0.0f; + v[2].sow = v[1].sow = 1.0f; + v[0].tow = v[1].tow = 1.0f; + v[2].tow = v[3].tow = 0.0f; + + Surf.FlatColor.rgba = UINT2RGBA(color); + Surf.FlatColor.s.alpha = 0x80; + + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); +} + // ========================================================================== // R_DRAW.C STUFF diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 1ae2d8fc3..f25720d1e 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -35,6 +35,7 @@ void HWR_clearAutomap(void); void HWR_drawAMline(const fline_t *fl, INT32 color); void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength); void HWR_DrawConsoleBack(UINT32 color, INT32 height); +void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight); void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player); void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); void HWR_DrawViewBorder(INT32 clearlines); diff --git a/src/v_video.c b/src/v_video.c index a628b1a8b..f8d0b392c 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1488,8 +1488,26 @@ void V_DrawTutorialBack(INT32 boxheight) boxheight *= vid.dupy; #ifdef HWRENDER - if (rendermode != render_soft) // no support for OpenGL yet + if (rendermode != render_soft && rendermode != render_none) + { + UINT32 hwcolor; + switch (cons_backcolor.value) + { + case 0: hwcolor = 0xffffff00; break; // White + case 1: hwcolor = 0x80808000; break; // Gray + case 2: hwcolor = 0x40201000; break; // Brown + case 3: hwcolor = 0xff000000; break; // Red + case 4: hwcolor = 0xff800000; break; // Orange + case 5: hwcolor = 0x80800000; break; // Yellow + case 6: hwcolor = 0x00800000; break; // Green + case 7: hwcolor = 0x0000ff00; break; // Blue + case 8: hwcolor = 0x4080ff00; break; // Cyan + // Default green + default: hwcolor = 0x00800000; break; + } + HWR_DrawTutorialBack(hwcolor, boxheight); return; + } #endif // heavily simplified -- we don't need to know x or y position, From 0a766dc93b53a587c6fa022135e767000b670e54 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 20:01:39 -0400 Subject: [PATCH 173/264] Implemented progressive text printing for TextPrompt --- src/f_finale.c | 107 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 27 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 5f6d8ce42..29789c539 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -86,6 +86,7 @@ static boolean promptactive = false; static mobj_t *promptmo; static INT16 promptpostexectag; static boolean promptblockcontrols; +static char *promptpagetext = NULL; // // CUTSCENE TEXT WRITING @@ -2029,6 +2030,52 @@ boolean F_CutsceneResponder(event_t *event) // TEXT PROMPTS // ================== +static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *boxh, INT32 *texth, INT32 *texty, INT32 *namey, INT32 *chevrony, INT32 *textx, INT32 *textr) +{ + // reuse: + // cutnum -> promptnum + // scenenum -> pagenum + lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); + + *pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; + *rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); + + // Vertical calculations + *boxh = *pagelines*2; + *texth = textprompts[cutnum]->page[scenenum].name[0] ? (*pagelines-1)*2 : *pagelines*2; // name takes up first line if it exists + *texty = BASEVIDHEIGHT - ((*texth * 4) + (*texth/2)*4); + *namey = BASEVIDHEIGHT - ((*boxh * 4) + (*boxh/2)*4); + *chevrony = BASEVIDHEIGHT - (((1*2) * 4) + ((1*2)/2)*4); // force on last line + + // Horizontal calculations + // Shift text to the right if we have a character icon on the left side + // Add 4 margin against icon + *textx = (iconlump != LUMPERROR && !*rightside) ? ((*boxh * 4) + (*boxh/2)*4) + 4 : 4; + *textr = *rightside ? BASEVIDWIDTH - (((*boxh * 4) + (*boxh/2)*4) + 4) : BASEVIDWIDTH-4; +} + +static void F_PreparePageText(char *pagetext) +{ + UINT8 pagelines; + boolean rightside; + INT32 boxh, texth, texty, namey, chevrony; + INT32 textx, textr; + + F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); + + if (promptpagetext) + Z_Free(promptpagetext); + promptpagetext = V_WordWrap(textx, textr, 0, pagetext); + + F_NewCutscene(promptpagetext); + cutscene_textspeed = TICRATE/4; // \todo configurable speed by SOC + cutscene_textcount = 0; // no delay in beginning + cutscene_boostspeed = 0; // don't print 8 characters to start + + // \todo update control hot strings on re-config + // and somehow don't reset cutscene text counters +} + static void F_AdvanceToNextPage(void) { UINT8 nextprompt = textprompts[cutnum]->page[scenenum].nextprompt, @@ -2064,12 +2111,20 @@ static void F_AdvanceToNextPage(void) // close the prompt if either num is invalid if (cutnum == INT32_MAX || scenenum == INT32_MAX) F_EndTextPrompt(); + else + { + timetonext = 1; // on page-mode, delay before boosting // \todo timed mode set by SOC, enable different behavior for a legitimate timer + F_PreparePageText(textprompts[cutnum]->page[scenenum].text); + } } void F_EndTextPrompt(void) { promptactive = false; + if (promptmo && promptmo->player && promptblockcontrols) + promptmo->reactiontime = TICRATE/4; // prevent jumping right away // \todo account freeze realtime for this + // \todo net safety, maybe loop all player thinkers? if (promptpostexectag) { @@ -2106,6 +2161,12 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex cutnum = (textprompts[promptnum]) ? promptnum : INT32_MAX; scenenum = (pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX; promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX); + + if (promptactive) + { + timetonext = 1; // on page-mode, delay before boosting // \todo timed mode set by SOC, enable different behavior for a legitimate timer + F_PreparePageText(textprompts[cutnum]->page[scenenum].text); + } } void F_TextPromptDrawer(void) @@ -2121,27 +2182,12 @@ void F_TextPromptDrawer(void) // Data patch_t *patch; - char *text; if (!promptactive) return; iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname); - pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4; - rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside); - - // Vertical calculations - boxh = pagelines*2; - texth = textprompts[cutnum]->page[scenenum].name[0] ? (pagelines-1)*2 : pagelines*2; // name takes up first line if it exists - texty = BASEVIDHEIGHT - ((texth * 4) + (texth/2)*4); - namey = BASEVIDHEIGHT - ((boxh * 4) + (boxh/2)*4); - chevrony = BASEVIDHEIGHT - (((1*2) * 4) + ((1*2)/2)*4); // force on last line - - // Horizontal calculations - // Shift text to the right if we have a character icon on the left side - // Add 4 margin against icon - textx = (iconlump != LUMPERROR && !rightside) ? ((boxh * 4) + (boxh/2)*4) + 4 : 4; - textr = rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4) + 4) : BASEVIDWIDTH-4; + F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); // Draw background V_DrawTutorialBack(boxh); @@ -2181,8 +2227,7 @@ void F_TextPromptDrawer(void) // Draw text // \todo Char-by-char printing, see f_finale.c F_WriteText - text = V_WordWrap(textx, textr, 0, textprompts[cutnum]->page[scenenum].text); - V_DrawString(textx, texty, V_SNAPTOBOTTOM, text); + V_DrawString(textx, texty, V_SNAPTOBOTTOM, cutscene_disptext); // Draw name // Don't use V_YELLOWMAP here so that the name color can be changed with control codes @@ -2190,7 +2235,7 @@ void F_TextPromptDrawer(void) V_DrawString(textx, namey, V_SNAPTOBOTTOM, textprompts[cutnum]->page[scenenum].name); // Draw chevron - if (promptblockcontrols) // \todo if !CloseTimer + if (promptblockcontrols && !timetonext) // \todo if !CloseTimer V_DrawString(textr-8, chevrony + (skullAnimCounter/5), (V_SNAPTOBOTTOM|V_YELLOWMAP), "\x1B"); // down arrow } @@ -2223,17 +2268,21 @@ void F_TextPromptTicker(void) if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP)) { + if (timetonext > 1) + timetonext--; + else if (cutscene_baseptr) // don't set boost if we just reset the string + cutscene_boostspeed = 1; // only after a slight delay + if (keypressed) - return; + break; - cutscene_boostspeed = 1; - if (timetonext) - timetonext = 2; - F_AdvanceToNextPage(); + if (!timetonext) // is 0 when finished generating text + { + F_AdvanceToNextPage(); + if (promptactive) + S_StartSound(NULL, sfx_menu1); + } keypressed = true; // prevent repeat events - - if (promptactive) - S_StartSound(NULL, sfx_menu1); } else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP)) keypressed = false; @@ -2241,4 +2290,8 @@ void F_TextPromptTicker(void) break; } } + + // generate letter-by-letter text + if (!F_WriteText()) + timetonext = 0; } From 73ae27334899f3b737f9779b2cd4ef6e7faf21e3 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 21:53:17 -0400 Subject: [PATCH 174/264] Implemented auto-advancing TextPrompts * Fixed TextSpeed * New TimeToNext * Other bugs --- src/dehacked.c | 4 +- src/doomstat.h | 3 +- src/f_finale.c | 119 ++++++++++++++++++++++++++++++------------------- 3 files changed, 78 insertions(+), 48 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 725a30b4e..9f819a665 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1685,7 +1685,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].verticalalign = align; } else if (fastcmp(word, "TEXTSPEED")) - textprompts[num]->page[pagenum].textspeed = min(max(0, i), 15); + textprompts[num]->page[pagenum].textspeed = get_number(word2); else if (fastcmp(word, "TEXTSFX")) textprompts[num]->page[pagenum].textsfx = get_number(word2); else if (fastcmp(word, "METAPAGE")) @@ -1708,6 +1708,8 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].nextprompt = usi; else if (fastcmp(word, "NEXTPAGE")) textprompts[num]->page[pagenum].nextpage = usi; + else if (fastcmp(word, "TIMETONEXT")) + textprompts[num]->page[pagenum].timetonext = get_number(word2); else deh_warning("PromptPage %d: unknown word '%s'", num, word); } diff --git a/src/doomstat.h b/src/doomstat.h index eaa19e3d6..73758a6a6 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -175,10 +175,11 @@ typedef struct UINT8 backcolor; // see CON_SetupBackColormap: 0-10, 11 for default, UINT8_MAX for user-defined (CONS_BACKCOLOR) UINT8 align; // text alignment, 0 = left, 1 = right, 2 = center UINT8 verticalalign; // vertical text alignment, 0 = top, 1 = bottom, 2 = middle - UINT8 textspeed; // text speed 0-15, makes it slower. See f_finale.c F_WriteText + UINT8 textspeed; // text speed, delay in tics between characters. sfxenum_t textsfx; // sfx_ id for printing text UINT8 nextprompt; // next prompt to jump to, one-based. 0 = current prompt UINT8 nextpage; // next page to jump to, one-based. 0 = next page within prompt->numpages + INT32 timetonext; // time in tics to jump to next page automatically. 0 = don't jump automatically char *text; } textpage_t; diff --git a/src/f_finale.c b/src/f_finale.c index 29789c539..05a77cedd 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2068,7 +2068,7 @@ static void F_PreparePageText(char *pagetext) promptpagetext = V_WordWrap(textx, textr, 0, pagetext); F_NewCutscene(promptpagetext); - cutscene_textspeed = TICRATE/4; // \todo configurable speed by SOC + cutscene_textspeed = textprompts[cutnum]->page[scenenum].textspeed ? textprompts[cutnum]->page[scenenum].textspeed : TICRATE/5; cutscene_textcount = 0; // no delay in beginning cutscene_boostspeed = 0; // don't print 8 characters to start @@ -2113,17 +2113,22 @@ static void F_AdvanceToNextPage(void) F_EndTextPrompt(); else { - timetonext = 1; // on page-mode, delay before boosting // \todo timed mode set by SOC, enable different behavior for a legitimate timer + // on page mode, number of tics before allowing boost + // on timer mode, number of tics until page advances + timetonext = textprompts[cutnum]->page[scenenum].timetonext ? textprompts[cutnum]->page[scenenum].timetonext : TICRATE/10; F_PreparePageText(textprompts[cutnum]->page[scenenum].text); } } void F_EndTextPrompt(void) { - promptactive = false; + if (promptactive) { + if (promptmo && promptmo->player && promptblockcontrols) + promptmo->reactiontime = TICRATE/4; // prevent jumping right away // \todo account freeze realtime for this) + // \todo reset frozen realtime? + } - if (promptmo && promptmo->player && promptblockcontrols) - promptmo->reactiontime = TICRATE/4; // prevent jumping right away // \todo account freeze realtime for this + promptactive = false; // \todo net safety, maybe loop all player thinkers? if (promptpostexectag) @@ -2132,13 +2137,6 @@ void F_EndTextPrompt(void) P_LinedefExecute(promptpostexectag, promptmo, NULL); P_MapEnd(); } - - // \todo reset frozen realtime? - - P_SetTarget(&promptmo, NULL); - - // \todo if !promptactive, block player jumping if BT_JUMP is set - // so player does not immediately jump upon prompt close } void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime) @@ -2152,21 +2150,25 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex skullAnimCounter = 0; // Set up state - P_SetTarget(&promptmo, mo); + promptmo = mo; promptpostexectag = postexectag; promptblockcontrols = blockcontrols; (void)freezerealtime; // \todo freeze player->realtime, maybe this needs to cycle through player thinkers // Initialize current prompt and scene cutnum = (textprompts[promptnum]) ? promptnum : INT32_MAX; - scenenum = (pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX; + scenenum = (cutnum != INT32_MAX && pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX; promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX); if (promptactive) { - timetonext = 1; // on page-mode, delay before boosting // \todo timed mode set by SOC, enable different behavior for a legitimate timer + // on page mode, number of tics before allowing boost + // on timer mode, number of tics until page advances + timetonext = textprompts[cutnum]->page[scenenum].timetonext ? textprompts[cutnum]->page[scenenum].timetonext : TICRATE/10; F_PreparePageText(textprompts[cutnum]->page[scenenum].text); } + else + F_EndTextPrompt(); // run the post-effects immediately } void F_TextPromptDrawer(void) @@ -2255,43 +2257,68 @@ void F_TextPromptTicker(void) skullAnimCounter = 8; // button handling - if (promptblockcontrols) + if (textprompts[cutnum]->page[scenenum].timetonext) { - // \todo loop through all players that have a text prompt - if (promptmo && promptmo->player) - promptmo->player->powers[pw_nocontrol] = 1; - - for (i = 0; i < MAXPLAYERS; i++) + if (promptblockcontrols) // same procedure as below, just without the button handling { - if (netgame && i != serverplayer && i != adminplayer) - continue; - - if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP)) + for (i = 0; i < MAXPLAYERS; i++) { - if (timetonext > 1) - timetonext--; - else if (cutscene_baseptr) // don't set boost if we just reset the string - cutscene_boostspeed = 1; // only after a slight delay + if (netgame && i != serverplayer && i != adminplayer) + continue; - if (keypressed) - break; - - if (!timetonext) // is 0 when finished generating text - { - F_AdvanceToNextPage(); - if (promptactive) - S_StartSound(NULL, sfx_menu1); - } - keypressed = true; // prevent repeat events + players[i].powers[pw_nocontrol] = 1; + break; } - else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP)) - keypressed = false; - - break; } + + if (timetonext >= 1) + timetonext--; + + if (!timetonext) + F_AdvanceToNextPage(); + + F_WriteText(); + } + else + { + if (promptblockcontrols) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (netgame && i != serverplayer && i != adminplayer) + continue; + + players[i].powers[pw_nocontrol] = 1; + + if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP)) + { + if (timetonext > 1) + timetonext--; + else if (cutscene_baseptr) // don't set boost if we just reset the string + cutscene_boostspeed = 1; // only after a slight delay + + if (keypressed) + break; + + if (!timetonext) // is 0 when finished generating text + { + F_AdvanceToNextPage(); + if (promptactive) + S_StartSound(NULL, sfx_menu1); + } + keypressed = true; // prevent repeat events + } + else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP)) + keypressed = false; + + break; + } + } + + // generate letter-by-letter text + if (!F_WriteText()) + timetonext = !promptblockcontrols; // never show the chevron if we can't toggle pages } - // generate letter-by-letter text - if (!F_WriteText()) - timetonext = 0; + } From 1ca8fca602ad376019b747ea88a2161c7f82e6ca Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 21:53:21 -0400 Subject: [PATCH 175/264] Changed Line 449 post exec tag to line tag --- 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 cd4dd76cf..e2c73a5a5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3462,7 +3462,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { INT32 promptnum = max(0, (sides[line->sidenum[0]].textureoffset>>FRACBITS)-1); INT32 pagenum = max(0, (sides[line->sidenum[0]].rowoffset>>FRACBITS)-1); - INT32 postexectag = (line->sidenum[1] != 0xFFFF) ? abs(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0; + INT32 postexectag = line->tag; boolean closetextprompt = (line->flags & ML_BLOCKMONSTERS); boolean runpostexec = (line->flags & ML_EFFECT1); From 6356a6cf2ed19173009c121515d3cd6476805042 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 3 Nov 2018 22:57:39 -0400 Subject: [PATCH 176/264] Lowercase font for body text; added ICONFLIP parameter --- src/dehacked.c | 3 +++ src/doomstat.h | 1 + src/f_finale.c | 9 ++++++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 9f819a665..7a89cadcf 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1650,6 +1650,8 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) strncpy(textprompts[num]->page[pagenum].iconname, word2, 8); else if (fastcmp(word, "ICONALIGN")) textprompts[num]->page[pagenum].rightside = (i || word2[0] == 'R'); + else if (fastcmp(word, "ICONFLIP")) + textprompts[num]->page[pagenum].iconflip = (i || word2[0] == 'T' || word2[0] == 'Y'); else if (fastcmp(word, "LINES")) textprompts[num]->page[pagenum].lines = usi; else if (fastcmp(word, "BACKCOLOR")) @@ -1696,6 +1698,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, 32); strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, 8); textprompts[num]->page[pagenum].rightside = textprompts[num]->page[metapagenum].rightside; + textprompts[num]->page[pagenum].iconflip = textprompts[num]->page[metapagenum].iconflip; textprompts[num]->page[pagenum].lines = textprompts[num]->page[metapagenum].lines; textprompts[num]->page[pagenum].backcolor = textprompts[num]->page[metapagenum].backcolor; textprompts[num]->page[pagenum].align = textprompts[num]->page[metapagenum].align; diff --git a/src/doomstat.h b/src/doomstat.h index 73758a6a6..7bcf59946 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -171,6 +171,7 @@ typedef struct char name[32]; // narrator name char iconname[8]; // narrator icon lump boolean rightside; // narrator side, false = left, true = right + boolean iconflip; // narrator flip icon horizontally UINT8 lines; // # of lines to show. If name is specified, name takes one of the lines. If 0, defaults to 4. UINT8 backcolor; // see CON_SetupBackColormap: 0-10, 11 for default, UINT8_MAX for user-defined (CONS_BACKCOLOR) UINT8 align; // text alignment, 0 = left, 1 = right, 2 = center diff --git a/src/f_finale.c b/src/f_finale.c index 05a77cedd..1fae49e9d 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2223,18 +2223,21 @@ void F_TextPromptDrawer(void) icony = namey << FRACBITS; } - V_DrawFixedPatch(iconx, icony, scale, V_SNAPTOBOTTOM, patch, NULL); + if (textprompts[cutnum]->page[scenenum].iconflip) + iconx += FixedMul(patch->width, scale) << FRACBITS; + + V_DrawFixedPatch(iconx, icony, scale, (V_SNAPTOBOTTOM|(textprompts[cutnum]->page[scenenum].iconflip ? V_FLIP : 0)), patch, NULL); W_UnlockCachedPatch(patch); } // Draw text // \todo Char-by-char printing, see f_finale.c F_WriteText - V_DrawString(textx, texty, V_SNAPTOBOTTOM, cutscene_disptext); + V_DrawString(textx, texty, (V_SNAPTOBOTTOM|V_ALLOWLOWERCASE), cutscene_disptext); // Draw name // Don't use V_YELLOWMAP here so that the name color can be changed with control codes if (textprompts[cutnum]->page[scenenum].name[0]) - V_DrawString(textx, namey, V_SNAPTOBOTTOM, textprompts[cutnum]->page[scenenum].name); + V_DrawString(textx, namey, (V_SNAPTOBOTTOM|V_ALLOWLOWERCASE), textprompts[cutnum]->page[scenenum].name); // Draw chevron if (promptblockcontrols && !timetonext) // \todo if !CloseTimer From 722da815ea8b1ddb326f0abbace0590e102f7dae Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 16:45:29 -0500 Subject: [PATCH 177/264] Move Line 449 to Line 459; allow post exec tag by either Back X offset or line tag --- src/p_spec.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index e2c73a5a5..edf9174d6 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3456,27 +3456,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } break; - case 449: // Control Text Prompt - // console player only unless NOCLIMB is set - if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) - { - INT32 promptnum = max(0, (sides[line->sidenum[0]].textureoffset>>FRACBITS)-1); - INT32 pagenum = max(0, (sides[line->sidenum[0]].rowoffset>>FRACBITS)-1); - INT32 postexectag = line->tag; - - boolean closetextprompt = (line->flags & ML_BLOCKMONSTERS); - boolean runpostexec = (line->flags & ML_EFFECT1); - boolean blockcontrols = !(line->flags & ML_EFFECT2); - boolean freezerealtime = !(line->flags & ML_EFFECT3); - //boolean freezethinkers = (line->flags & ML_EFFECT4); - - if (closetextprompt) - F_EndTextPrompt(); - else - F_StartTextPrompt(promptnum, pagenum, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime); - } - break; - case 450: // Execute Linedef Executor - for recursion P_LinedefExecute(line->tag, mo, NULL); break; @@ -3779,6 +3758,27 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) P_ResetColormapFader(§ors[secnum]); break; + case 459: // Control Text Prompt + // console player only unless NOCLIMB is set + if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) + { + INT32 promptnum = max(0, (sides[line->sidenum[0]].textureoffset>>FRACBITS)-1); + INT32 pagenum = max(0, (sides[line->sidenum[0]].rowoffset>>FRACBITS)-1); + INT32 postexectag = abs((line->sidenum[1] != 0xFFFF) ? sides[line->sidenum[1]].textureoffset>>FRACBITS : line->tag); + + boolean closetextprompt = (line->flags & ML_BLOCKMONSTERS); + boolean runpostexec = (line->flags & ML_EFFECT1); + boolean blockcontrols = !(line->flags & ML_EFFECT2); + boolean freezerealtime = !(line->flags & ML_EFFECT3); + //boolean freezethinkers = (line->flags & ML_EFFECT4); + + if (closetextprompt) + F_EndTextPrompt(); + else + F_StartTextPrompt(promptnum, pagenum, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime); + } + break; + #ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing From c16c59fd739b394464350947c397b062ee52a617 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 21:14:22 -0500 Subject: [PATCH 178/264] Support underscores -> spaces in TextPrompt name --- src/dehacked.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 7a89cadcf..dcd61bd31 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1637,6 +1637,8 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) if (fastcmp(word, "NAME")) { + INT32 i; + // HACK: Add yellow control char now // so the drawing function doesn't call it repeatedly char name[32]; @@ -1644,6 +1646,14 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) name[1] = 0; strncat(name, word2, 31); name[31] = 0; + + // Replace _ with ' ' + for (i = 0; i < 32 && name[i]; i++) + { + if (name[i] == '_') + name[i] = ' '; + } + strncpy(textprompts[num]->page[pagenum].name, name, 32); } else if (fastcmp(word, "ICON")) From 96e9b4143a7a63a35fa877b8212e4e06c221bad4 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 22:09:54 -0500 Subject: [PATCH 179/264] Pause TextPrompt when game is paused --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 1fae49e9d..6ba9132cf 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2248,7 +2248,7 @@ void F_TextPromptTicker(void) { INT32 i; - if (!promptactive) + if (!promptactive || paused || P_AutoPause()) return; // advance animation From 311cb2781805668cbffb15b242d37527805ba032 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Nov 2018 22:22:47 -0500 Subject: [PATCH 180/264] Close text prompt upon level load --- src/f_finale.c | 15 ++++++++------- src/f_finale.h | 2 +- src/p_setup.c | 3 +++ src/p_spec.c | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 6ba9132cf..8a6a8ce0c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2110,7 +2110,7 @@ static void F_AdvanceToNextPage(void) // close the prompt if either num is invalid if (cutnum == INT32_MAX || scenenum == INT32_MAX) - F_EndTextPrompt(); + F_EndTextPrompt(false, false); else { // on page mode, number of tics before allowing boost @@ -2120,18 +2120,19 @@ static void F_AdvanceToNextPage(void) } } -void F_EndTextPrompt(void) +void F_EndTextPrompt(boolean forceexec, boolean noexec) { - if (promptactive) { + boolean promptwasactive = promptactive; + promptactive = false; + + if (promptwasactive) { if (promptmo && promptmo->player && promptblockcontrols) promptmo->reactiontime = TICRATE/4; // prevent jumping right away // \todo account freeze realtime for this) // \todo reset frozen realtime? } - promptactive = false; - // \todo net safety, maybe loop all player thinkers? - if (promptpostexectag) + if ((promptwasactive || forceexec) && !noexec && promptpostexectag) { P_MapStart(); P_LinedefExecute(promptpostexectag, promptmo, NULL); @@ -2168,7 +2169,7 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex F_PreparePageText(textprompts[cutnum]->page[scenenum].text); } else - F_EndTextPrompt(); // run the post-effects immediately + F_EndTextPrompt(true, false); // run the post-effects immediately } void F_TextPromptDrawer(void) diff --git a/src/f_finale.h b/src/f_finale.h index dfee247fb..8ce7ac22e 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -54,7 +54,7 @@ void F_EndCutScene(void); void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime); void F_TextPromptDrawer(void); -void F_EndTextPrompt(void); +void F_EndTextPrompt(boolean forceexec, boolean noexec); void F_StartGameEnd(void); void F_StartIntro(void); diff --git a/src/p_setup.c b/src/p_setup.c index eb25c51c8..b2dfedb4e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2753,6 +2753,9 @@ boolean P_SetupLevel(boolean skipprecip) I_UpdateNoVsync(); } + // Close text prompt before freeing the old level + F_EndTextPrompt(false, true); + #ifdef HAVE_BLUA LUA_InvalidateLevel(); #endif diff --git a/src/p_spec.c b/src/p_spec.c index edf9174d6..42153b4bf 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3773,7 +3773,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) //boolean freezethinkers = (line->flags & ML_EFFECT4); if (closetextprompt) - F_EndTextPrompt(); + F_EndTextPrompt(false, false); else F_StartTextPrompt(promptnum, pagenum, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime); } From eb204b6cc44a7d3bf9f16859274b186b2ad41847 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Mon, 5 Nov 2018 07:41:02 -0500 Subject: [PATCH 181/264] Add exec to GoldMonitorPop; transfer Angle tag to mobj->lastlook for Lua compat --- src/p_enemy.c | 9 +++++++-- src/p_mobj.c | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 15608f57f..6fee7d2f0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3327,8 +3327,8 @@ void A_MonitorPop(mobj_t *actor) // Run a linedef executor immediately upon popping // You may want to delay your effects by 18 tics to sync with the reward giving - if (actor->spawnpoint && (actor->spawnpoint->options & MTF_EXTRA) && (actor->spawnpoint->angle & 16384)) - P_LinedefExecute((actor->spawnpoint->angle & 16383), actor->target, NULL); + if (actor->spawnpoint && actor->lastlook) + P_LinedefExecute(actor->lastlook, actor->target, NULL); } // Function: A_GoldMonitorPop @@ -3412,6 +3412,11 @@ void A_GoldMonitorPop(mobj_t *actor) newmobj->sprite = SPR_TV1P; } } + + // Run a linedef executor immediately upon popping + // You may want to delay your effects by 18 tics to sync with the reward giving + if (actor->spawnpoint && actor->lastlook) + P_LinedefExecute(actor->lastlook, actor->target, NULL); } // Function: A_GoldMonitorRestore diff --git a/src/p_mobj.c b/src/p_mobj.c index 717bb92b6..2450fb801 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10894,6 +10894,16 @@ ML_EFFECT4 : Don't clip inside the ground mobj->flags2 |= MF2_OBJECTFLIP; } + // Extra functionality + if (mthing->options & MTF_EXTRA) + { + if (mobj->flags & MF_MONITOR && (mthing->angle & 16384)) + { + // Store line exec tag to run upon popping + mobj->lastlook = (mthing->angle & 16383); + } + } + // Final set of not being able to draw nightsitems. if (mobj->flags & MF_NIGHTSITEM) mobj->flags2 |= MF2_DONTDRAW; From 1cc8619c9e155a06f39821473c84b25ff11b0fac Mon Sep 17 00:00:00 2001 From: MPC Date: Mon, 5 Nov 2018 20:40:51 -0200 Subject: [PATCH 182/264] Minor remote viewpoint bugfixes. --- src/p_mobj.c | 5 +++-- src/p_user.c | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2a29c32ad..e94c4ff89 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3506,14 +3506,15 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP) postimg = postimg_flip; - else if (player->awayviewtics) + else if (player->awayviewtics && player->awayviewmobj != NULL) // Camera must obviously exist { camera_t dummycam; dummycam.subsector = player->awayviewmobj->subsector; dummycam.x = player->awayviewmobj->x; dummycam.y = player->awayviewmobj->y; dummycam.z = player->awayviewmobj->z; - dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT + //dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT + dummycam.height = 0; // Why? Remote viewpoint cameras have no height. // Are we in water? if (P_CameraCheckWater(&dummycam)) postimg = postimg_water; diff --git a/src/p_user.c b/src/p_user.c index 7e206930d..34191cdf7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8365,16 +8365,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall // Make player translucent if camera is too close (only in single player). if (!(multiplayer || netgame) && !splitscreen) { - fixed_t vx = 0, vy = 0; - if (player->awayviewtics) { + fixed_t vx = thiscam->x, vy = thiscam->y; + if (player->awayviewtics && player->awayviewmobj != NULL) // Camera must obviously exist + { vx = player->awayviewmobj->x; vy = player->awayviewmobj->y; } - else - { - vx = thiscam->x; - vy = thiscam->y; - } if (P_AproxDistance(vx - player->mo->x, vy - player->mo->y) < FixedMul(48*FRACUNIT, mo->scale)) player->mo->flags2 |= MF2_SHADOW; @@ -8710,8 +8706,9 @@ void P_PlayerThink(player_t *player) if (player->flashcount) player->flashcount--; - if (player->awayviewtics) - player->awayviewtics--; + // By the time P_MoveChaseCamera is called, this might be zero. Do not do it here. + //if (player->awayviewtics) + // player->awayviewtics--; /// \note do this in the cheat code if (player->pflags & PF_NOCLIP) @@ -9489,6 +9486,9 @@ void P_PlayerAfterThink(player_t *player) } } + if (player->awayviewtics) + player->awayviewtics--; + // spectator invisibility and nogravity. if ((netgame || multiplayer) && player->spectator) { From a3bc7ddfa0bca4d52b8de2a7151095ecc6968e04 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Tue, 6 Nov 2018 18:09:45 -0600 Subject: [PATCH 183/264] Add Lua Ultimate Mode global variable so people can use it. --- src/dehacked.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 97e1965eb..212715dd3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8217,6 +8217,9 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"maptol")) { lua_pushinteger(L, maptol); return 1; + } else if (fastcmp(word,"ultimatemode")) { + lua_pushboolean(L, ultimatemode != 0); + return 1; } else if (fastcmp(word,"mariomode")) { lua_pushboolean(L, mariomode != 0); return 1; From f66979ba1a3f2b2ea8bb07bc7c31e09094c6e1ec Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 7 Nov 2018 21:00:38 +0000 Subject: [PATCH 184/264] P_NullPrecipThinker no longer should have FUNCMATH (though I'm not sure if it should have had it in the first place anyway) --- src/p_mobj.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.h b/src/p_mobj.h index 620028d81..56d9b6dae 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -445,7 +445,7 @@ boolean P_SupermanLook4Players(mobj_t *actor); void P_DestroyRobots(void); void P_SnowThinker(precipmobj_t *mobj); void P_RainThinker(precipmobj_t *mobj); -FUNCMATH void P_NullPrecipThinker(precipmobj_t *mobj); +void P_NullPrecipThinker(precipmobj_t *mobj); void P_RemovePrecipMobj(precipmobj_t *mobj); void P_SetScale(mobj_t *mobj, fixed_t newscale); void P_XYMovement(mobj_t *mo); From 4a4e07e1385ddb1c707e431e6be928cc16a1c724 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 7 Nov 2018 21:21:36 +0000 Subject: [PATCH 185/264] D_PostEvent_end is only used by Allegro (used by the DOS port) to help timers work, so check for PC_DOS in preprocessor code. Also remove FUNCMATH from said function. --- src/d_main.c | 2 +- src/d_main.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 170532675..037aeccf9 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -170,7 +170,7 @@ void D_PostEvent(const event_t *ev) eventhead = (eventhead+1) & (MAXEVENTS-1); } // just for lock this function -#ifndef DOXYGEN +#if defined (PC_DOS) && !defined (DOXYGEN) void D_PostEvent_end(void) {}; #endif diff --git a/src/d_main.h b/src/d_main.h index d73b19d1f..4c9c99ea5 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -40,8 +40,8 @@ void D_SRB2Main(void); // Called by IO functions when input is detected. void D_PostEvent(const event_t *ev); -#ifndef DOXYGEN -FUNCMATH void D_PostEvent_end(void); // delimiter for locking memory +#if defined (PC_DOS) && !defined (DOXYGEN) +void D_PostEvent_end(void); // delimiter for locking memory #endif void D_ProcessEvents(void); From b3e8a1ed88961acad8d45a59c3003af08ccb6b5c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 7 Nov 2018 21:37:42 +0000 Subject: [PATCH 186/264] HU_Start should not have FUNCMATH, it has side effects --- src/hu_stuff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 5356ba8ac..a5c81e6e7 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -84,7 +84,7 @@ void HU_Init(void); void HU_LoadGraphics(void); // reset heads up when consoleplayer respawns. -FUNCMATH void HU_Start(void); +void HU_Start(void); boolean HU_Responder(event_t *ev); From c47f0045d6a60b41faceff3edd17be58b244c601 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 7 Nov 2018 21:45:27 +0000 Subject: [PATCH 187/264] ST_Ticker also should not have FUNCMATH, as it also has side effects --- src/st_stuff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st_stuff.h b/src/st_stuff.h index c11559d2b..6fafca404 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -24,7 +24,7 @@ // // Called by main loop. -FUNCMATH void ST_Ticker(void); +void ST_Ticker(void); // Called by main loop. void ST_Drawer(void); From 0bdbdd1b1ed1ffbb15b99664d037fd5f83b7ad12 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 16:26:55 +0000 Subject: [PATCH 188/264] Remove FUNCMATH from functions with a void return value or args, or examine variables other than their args (which could be modified) --- src/dehacked.c | 2 +- src/f_finale.c | 1 + src/f_finale.h | 2 +- src/r_plane.h | 2 +- src/r_splats.h | 4 ---- src/screen.c | 4 ---- src/sdl/i_cdmus.c | 14 +++++++------- src/sdl/i_system.c | 16 ++++++++-------- src/sdl/i_video.c | 6 +++--- src/sdl/mixer_sound.c | 4 ++-- src/sdl/sdl_sound.c | 2 +- src/sdl12/sdl_sound.c | 2 +- 12 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b7e874b16..2fed963f8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7769,7 +7769,7 @@ fixed_t get_number(const char *word) #endif } -void FUNCMATH DEH_Check(void) +void DEH_Check(void) { #if defined(_DEBUG) || defined(PARANOIA) const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*); diff --git a/src/f_finale.c b/src/f_finale.c index fb1387c11..a50e4a5be 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1401,6 +1401,7 @@ void F_StartGameEnd(void) // void F_GameEndDrawer(void) { + // this function does nothing } // diff --git a/src/f_finale.h b/src/f_finale.h index 1f23643be..8ee02bdf3 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -35,7 +35,7 @@ void F_CutsceneTicker(void); void F_TitleDemoTicker(void); // Called by main loop. -FUNCMATH void F_GameEndDrawer(void); +void F_GameEndDrawer(void); void F_IntroDrawer(void); void F_TitleScreenDrawer(void); diff --git a/src/r_plane.h b/src/r_plane.h index 16c8c12a4..dff58669a 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -87,7 +87,7 @@ extern lighttable_t **planezlight; extern fixed_t *yslope; extern fixed_t distscale[MAXVIDWIDTH]; -FUNCMATH void R_InitPlanes(void); +void R_InitPlanes(void); void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_ClearPlanes(void); diff --git a/src/r_splats.h b/src/r_splats.h index c0ba6881c..349d8fa7a 100644 --- a/src/r_splats.h +++ b/src/r_splats.h @@ -63,11 +63,7 @@ typedef struct floorsplat_s fixed_t P_SegLength(seg_t *seg); // call at P_SetupLevel() -#if !(defined (WALLSPLATS) || defined (FLOORSPLATS)) -FUNCMATH void R_ClearLevelSplats(void); -#else void R_ClearLevelSplats(void); -#endif #ifdef WALLSPLATS void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, fixed_t top, diff --git a/src/screen.c b/src/screen.c index 58c38993b..fdd8eb7bd 100644 --- a/src/screen.c +++ b/src/screen.c @@ -71,11 +71,7 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL #endif consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#ifdef DIRECTFULLSCREEN -static FUNCMATH void SCR_ChangeFullscreen (void); -#else static void SCR_ChangeFullscreen (void); -#endif consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/sdl/i_cdmus.c b/src/sdl/i_cdmus.c index 3105f5122..5d086e73a 100644 --- a/src/sdl/i_cdmus.c +++ b/src/sdl/i_cdmus.c @@ -12,19 +12,19 @@ consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NUL consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -FUNCMATH void I_InitCD(void){} +void I_InitCD(void){} -FUNCMATH void I_StopCD(void){} +void I_StopCD(void){} -FUNCMATH void I_PauseCD(void){} +void I_PauseCD(void){} -FUNCMATH void I_ResumeCD(void){} +void I_ResumeCD(void){} -FUNCMATH void I_ShutdownCD(void){} +void I_ShutdownCD(void){} -FUNCMATH void I_UpdateCD(void){} +void I_UpdateCD(void){} -FUNCMATH void I_PlayCD(UINT8 track, UINT8 looping) +void I_PlayCD(UINT8 track, UINT8 looping) { (void)track; (void)looping; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 7b14f1f18..9a2baf31c 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1927,14 +1927,14 @@ void I_StartupMouse2(void) // // I_Tactile // -FUNCMATH void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) +void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) { // UNUSED. (void)pFFType; (void)FFEffect; } -FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) +void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) { // UNUSED. (void)pFFType; @@ -1945,7 +1945,7 @@ FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) */ static ticcmd_t emptycmd; -FUNCMATH ticcmd_t *I_BaseTiccmd(void) +ticcmd_t *I_BaseTiccmd(void) { return &emptycmd; } @@ -1954,7 +1954,7 @@ FUNCMATH ticcmd_t *I_BaseTiccmd(void) */ static ticcmd_t emptycmd2; -FUNCMATH ticcmd_t *I_BaseTiccmd2(void) +ticcmd_t *I_BaseTiccmd2(void) { return &emptycmd2; } @@ -2048,7 +2048,7 @@ tic_t I_GetTime (void) // //I_StartupTimer // -FUNCMATH void I_StartupTimer(void) +void I_StartupTimer(void) { #ifdef _WIN32 // for win2k time bug @@ -2147,11 +2147,11 @@ void I_WaitVBL(INT32 count) SDL_Delay(count); } -FUNCMATH void I_BeginRead(void) +void I_BeginRead(void) { } -FUNCMATH void I_EndRead(void) +void I_EndRead(void) { } @@ -2939,5 +2939,5 @@ const CPUInfoFlags *I_CPUInfo(void) } // note CPUAFFINITY code used to reside here -FUNCMATH void I_RegisterSysCommands(void) {} +void I_RegisterSysCommands(void) {} #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 30ef1b27b..db88f452a 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1053,7 +1053,7 @@ void I_SetPalette(RGBA_t *palette) } // return number of fullscreen + X11 modes -FUNCMATH INT32 VID_NumModes(void) +INT32 VID_NumModes(void) { if (USE_FULLSCREEN && numVidModes != -1) return numVidModes - firstEntry; @@ -1061,7 +1061,7 @@ FUNCMATH INT32 VID_NumModes(void) return MAXWINMODES; } -FUNCMATH const char *VID_GetModeName(INT32 modeNum) +const char *VID_GetModeName(INT32 modeNum) { #if 0 if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes @@ -1091,7 +1091,7 @@ FUNCMATH const char *VID_GetModeName(INT32 modeNum) return &vidModeName[modeNum][0]; } -FUNCMATH INT32 VID_GetModeForSize(INT32 w, INT32 h) +INT32 VID_GetModeForSize(INT32 w, INT32 h) { int i; for (i = 0; i < MAXWINMODES; i++) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 4d86d7a3c..f36f08695 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -135,7 +135,7 @@ void I_ShutdownSound(void) #endif } -FUNCMATH void I_UpdateSound(void) +void I_UpdateSound(void) { } @@ -504,7 +504,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len) /// Music System /// ------------------------ -FUNCMATH void I_InitMusic(void) +void I_InitMusic(void) { } diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 9f8a3e29d..f4796cd80 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -219,7 +219,7 @@ static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio #endif } -FUNCMATH static inline Uint16 Snd_LowerRate(Uint16 sr) +static inline Uint16 Snd_LowerRate(Uint16 sr) { if (sr <= audio.freq) // already lowered rate? return sr; // good then diff --git a/src/sdl12/sdl_sound.c b/src/sdl12/sdl_sound.c index 01a27153e..ed1afd8e2 100644 --- a/src/sdl12/sdl_sound.c +++ b/src/sdl12/sdl_sound.c @@ -236,7 +236,7 @@ static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio #endif } -FUNCMATH static inline Uint16 Snd_LowerRate(Uint16 sr) +static inline Uint16 Snd_LowerRate(Uint16 sr) { if (sr <= audio.freq) // already lowered rate? return sr; // good then From 5c61c405514206b6e7b8b46f5322920519efa5f1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 16:31:20 +0000 Subject: [PATCH 189/264] Clean up doomtype.h a bit, add indenting and comments to make some preprocessor code more readable --- src/doomtype.h | 129 +++++++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 59 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index a711b466d..3631eb518 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -44,12 +44,13 @@ typedef long ssize_t; /* Older Visual C++ headers don't have the Win64-compatible typedefs... */ -#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) -#define DWORD_PTR DWORD -#endif - -#if ((_MSC_VER <= 1200) && (!defined(PDWORD_PTR))) -#define PDWORD_PTR PDWORD +#if (_MSC_VER <= 1200) + #ifndef DWORD_PTR + #define DWORD_PTR DWORD + #endif + #ifndef PDWORD_PTR + #define PDWORD_PTR PDWORD + #endif #endif #elif defined (_arch_dreamcast) // KOS Dreamcast #include @@ -102,7 +103,7 @@ typedef long ssize_t; #ifdef _MSC_VER #if (_MSC_VER <= 1800) // MSVC 2013 and back #define snprintf _snprintf -#if (_MSC_VER <= 1200) // MSVC 2012 and back +#if (_MSC_VER <= 1200) // MSVC 6.0 and back #define vsnprintf _vsnprintf #endif #endif @@ -185,7 +186,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz); //faB: clean that up !! #if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward - #include "stdbool.h" + #include "stdbool.h" #elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) #define false FALSE // use windows types #define true TRUE @@ -275,58 +276,68 @@ typedef UINT32 tic_t; #endif #ifdef __GNUC__ // __attribute__ ((X)) -#define FUNCNORETURN __attribute__ ((noreturn)) -#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__) -#include "inttypes.h" -#if 0 //defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0 -#define FUNCPRINTF __attribute__ ((format(gnu_printf, 1, 2))) -#define FUNCDEBUG __attribute__ ((format(gnu_printf, 2, 3))) -#define FUNCIERROR __attribute__ ((format(gnu_printf, 1, 2),noreturn)) -#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -#define FUNCPRINTF __attribute__ ((format(ms_printf, 1, 2))) -#define FUNCDEBUG __attribute__ ((format(ms_printf, 2, 3))) -#define FUNCIERROR __attribute__ ((format(ms_printf, 1, 2),noreturn)) -#else -#define FUNCPRINTF __attribute__ ((format(printf, 1, 2))) -#define FUNCDEBUG __attribute__ ((format(printf, 2, 3))) -#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn)) -#endif -#else -#define FUNCPRINTF __attribute__ ((format(printf, 1, 2))) -#define FUNCDEBUG __attribute__ ((format(printf, 2, 3))) -#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn)) -#endif -#ifndef FUNCIERROR -#define FUNCIERROR __attribute__ ((noreturn)) -#endif -#define FUNCMATH __attribute__((const)) -#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -#define FUNCDEAD __attribute__ ((deprecated)) -#define FUNCINLINE __attribute__((always_inline)) -#define FUNCNONNULL __attribute__((nonnull)) -#endif -#define FUNCNOINLINE __attribute__((noinline)) -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -#ifdef __i386__ // i386 only -#define FUNCTARGET(X) __attribute__ ((__target__ (X))) -#endif -#endif -#if defined (__MINGW32__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -#define ATTRPACK __attribute__((packed, gcc_struct)) -#else -#define ATTRPACK __attribute__((packed)) -#endif -#define ATTRUNUSED __attribute__((unused)) -#ifdef _XBOX -#define FILESTAMP I_OutputMsg("%s:%d\n",__FILE__,__LINE__); -#define XBOXSTATIC static -#endif + #define FUNCNORETURN __attribute__ ((noreturn)) + + #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__) // MinGW, >= GCC 4.1 + #include "inttypes.h" + #if 0 //defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0 + #define FUNCPRINTF __attribute__ ((format(gnu_printf, 1, 2))) + #define FUNCDEBUG __attribute__ ((format(gnu_printf, 2, 3))) + #define FUNCIERROR __attribute__ ((format(gnu_printf, 1, 2),noreturn)) + #elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4 + #define FUNCPRINTF __attribute__ ((format(ms_printf, 1, 2))) + #define FUNCDEBUG __attribute__ ((format(ms_printf, 2, 3))) + #define FUNCIERROR __attribute__ ((format(ms_printf, 1, 2),noreturn)) + #else + #define FUNCPRINTF __attribute__ ((format(printf, 1, 2))) + #define FUNCDEBUG __attribute__ ((format(printf, 2, 3))) + #define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn)) + #endif + #else + #define FUNCPRINTF __attribute__ ((format(printf, 1, 2))) + #define FUNCDEBUG __attribute__ ((format(printf, 2, 3))) + #define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn)) + #endif + + #ifndef FUNCIERROR + #define FUNCIERROR __attribute__ ((noreturn)) + #endif + + #define FUNCMATH __attribute__((const)) + + #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) // >= GCC 3.1 + #define FUNCDEAD __attribute__ ((deprecated)) + #define FUNCINLINE __attribute__((always_inline)) + #define FUNCNONNULL __attribute__((nonnull)) + #endif + + #define FUNCNOINLINE __attribute__((noinline)) + + #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4 + #ifdef __i386__ // i386 only + #define FUNCTARGET(X) __attribute__ ((__target__ (X))) + #endif + #endif + + #if defined (__MINGW32__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) // MinGW, >= GCC 3.4 + #define ATTRPACK __attribute__((packed, gcc_struct)) + #else + #define ATTRPACK __attribute__((packed)) + #endif + + #define ATTRUNUSED __attribute__((unused)) + + // Xbox-only macros + #ifdef _XBOX + #define FILESTAMP I_OutputMsg("%s:%d\n",__FILE__,__LINE__); + #define XBOXSTATIC static + #endif #elif defined (_MSC_VER) -#define ATTRNORETURN __declspec(noreturn) -#define ATTRINLINE __forceinline -#if _MSC_VER > 1200 -#define ATTRNOINLINE __declspec(noinline) -#endif + #define ATTRNORETURN __declspec(noreturn) + #define ATTRINLINE __forceinline + #if _MSC_VER > 1200 // >= MSVC 6.0 + #define ATTRNOINLINE __declspec(noinline) + #endif #endif #ifndef FUNCPRINTF From fd20bbb54e5882f43f006bcf60f653455f55ab11 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 17:05:35 +0000 Subject: [PATCH 190/264] More doomtype.h cleaning up: * Move the misc types in the file to bottom, so that ATTRPACK at least is usable for RGBA_t * Include endian.h, so that UINT2RGBA can be defined correctly for big endian builds * Add more comments to make clear the main sections of the file --- src/doomtype.h | 77 ++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index 3631eb518..67c279aa9 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -98,6 +98,8 @@ typedef long ssize_t; #define NOIPX #endif +/* Strings and some misc platform specific stuff */ + #if defined (_MSC_VER) || defined (__OS2__) // Microsoft VisualC++ #ifdef _MSC_VER @@ -179,6 +181,8 @@ size_t strlcpy(char *dst, const char *src, size_t siz); // not the number of bytes in the buffer. #define STRBUFCPY(dst,src) strlcpy(dst, src, sizeof dst) +/* Boolean type definition */ + // \note __BYTEBOOL__ used to be set above if "macintosh" was defined, // if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now? #ifndef __BYTEBOOL__ @@ -241,39 +245,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz); #define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ #endif -union FColorRGBA -{ - UINT32 rgba; - struct - { - UINT8 red; - UINT8 green; - UINT8 blue; - UINT8 alpha; - } s; -} ATTRPACK; -typedef union FColorRGBA RGBA_t; - -typedef enum -{ - postimg_none, - postimg_water, - postimg_motion, - postimg_flip, - postimg_heat -} postimg_t; - -typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num) -#define LUMPERROR UINT32_MAX - -typedef UINT32 tic_t; -#define INFTICS UINT32_MAX - -#ifdef _BIG_ENDIAN -#define UINT2RGBA(a) a -#else -#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24) -#endif +/* Compiler-specific attributes and other macros */ #ifdef __GNUC__ // __attribute__ ((X)) #define FUNCNORETURN __attribute__ ((noreturn)) @@ -391,4 +363,43 @@ typedef UINT32 tic_t; #ifndef FILESTAMP #define FILESTAMP #endif + +/* Miscellaneous types that don't fit anywhere else (Can this be changed?) */ + +union FColorRGBA +{ + UINT32 rgba; + struct + { + UINT8 red; + UINT8 green; + UINT8 blue; + UINT8 alpha; + } s; +} ATTRPACK; +typedef union FColorRGBA RGBA_t; + +typedef enum +{ + postimg_none, + postimg_water, + postimg_motion, + postimg_flip, + postimg_heat +} postimg_t; + +typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num) +#define LUMPERROR UINT32_MAX + +typedef UINT32 tic_t; +#define INFTICS UINT32_MAX + +#include "endian.h" // This is needed to make sure the below macro acts correctly in big endian builds + +#ifdef SRB2_BIG_ENDIAN +#define UINT2RGBA(a) a +#else +#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24) +#endif + #endif //__DOOMTYPE__ From fa80d6179978b1d8c88eda73d1efde1f4194c2d4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 17:16:54 +0000 Subject: [PATCH 191/264] byteptr.h: include endian.h to help define WRITE/READ macros correctly according to endianness --- src/byteptr.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/byteptr.h b/src/byteptr.h index 410d7c004..364e6520c 100644 --- a/src/byteptr.h +++ b/src/byteptr.h @@ -15,7 +15,9 @@ #define DEALIGNED #endif -#ifndef _BIG_ENDIAN +#include "endian.h" + +#ifndef SRB2_BIG_ENDIAN // // Little-endian machines // @@ -75,7 +77,7 @@ #define READANGLE(p) *((angle_t *)p)++ #endif -#else //_BIG_ENDIAN +#else //SRB2_BIG_ENDIAN // // definitions for big-endian machines with alignment constraints. // @@ -144,7 +146,7 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr) #define READCHAR(p) ({ char *p_tmp = ( char *)p; char b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; }) #define READFIXED(p) ({ fixed_t *p_tmp = (fixed_t *)p; fixed_t b = readlong(p); p_tmp++; p = (void *)p_tmp; b; }) #define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = readulong(p); p_tmp++; p = (void *)p_tmp; b; }) -#endif //_BIG_ENDIAN +#endif //SRB2_BIG_ENDIAN #undef DEALIGNED From f50f10ef307fe2a09a2d2fb84cb368ea10b89567 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 20:09:00 +0000 Subject: [PATCH 192/264] d_main.c: remove the _MAX_PATH define, the file hasn't used it since v2.0 --- src/d_main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 037aeccf9..15b144dda 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -761,10 +761,6 @@ static inline void D_CleanFile(void) } } -#ifndef _MAX_PATH -#define _MAX_PATH MAX_WADPATH -#endif - // ========================================================================== // Identify the SRB2 version, and IWAD file to use. // ========================================================================== From 82c738ea4b7ee4b1c03de261d26387107da9dd3c Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 21:13:58 +0000 Subject: [PATCH 193/264] Remove hasslope, per colette's warning about it potentially causing desyncs --- src/lua_maplib.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index b59c3c178..37dae5faa 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -46,7 +46,6 @@ enum sector_e { sector_ffloors, sector_fslope, sector_cslope, - sector_hasslope #else sector_ffloors #endif @@ -69,7 +68,6 @@ static const char *const sector_opt[] = { #ifdef ESLOPE "f_slope", "c_slope", - "hasslope", #endif NULL}; @@ -471,9 +469,6 @@ static int sector_get(lua_State *L) case sector_cslope: // c_slope LUA_PushUserdata(L, sector->c_slope, META_SLOPE); return 1; - case sector_hasslope: // hasslope - lua_pushboolean(L, sector->hasslope); - return 1; #endif } return 0; @@ -500,7 +495,6 @@ static int sector_set(lua_State *L) #ifdef ESLOPE case sector_fslope: // f_slope case sector_cslope: // c_slope - case sector_hasslope: // hasslope #endif default: return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]); From 98fd9f8e426e40cc70d6248bf7c5a42bf13f25f1 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 8 Nov 2018 21:22:45 +0000 Subject: [PATCH 194/264] WHY DID I FORGET THIS --- src/lua_maplib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 37dae5faa..1886d7d1a 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -45,7 +45,7 @@ enum sector_e { #ifdef ESLOPE sector_ffloors, sector_fslope, - sector_cslope, + sector_cslope #else sector_ffloors #endif From e937d1bacb1fd157244bfe2f203db0216b65a0e1 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 9 Nov 2018 16:01:29 -0500 Subject: [PATCH 195/264] Update readme --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index d16071454..7d92ab303 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,6 @@ - libupnp (Linux/OS X only) - libgme (Linux/OS X only) -Warning: 64-bit builds are not netgame compatible with 32-bit builds. Use at your own risk. - ## Compiling See [SRB2 Wiki/Source code compiling](http://wiki.srb2.org/wiki/Source_code_compiling) From b8897db3088e807f0866fb9f3b3fbd194dcf7b89 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 9 Nov 2018 21:55:14 -0500 Subject: [PATCH 196/264] Fix crash when page text is empty; add checks for MAX_PROMPTS and MAX_PAGES --- src/dehacked.c | 6 +++--- src/doomstat.h | 7 +++++-- src/f_finale.c | 17 ++++++++++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index dcd61bd31..0802fc49d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1773,17 +1773,17 @@ static void readtextprompt(MYFILE *f, INT32 num) if (fastcmp(word, "NUMPAGES")) { - textprompts[num]->numpages = value; + textprompts[num]->numpages = min(max(value, 0), MAX_PAGES); } else if (fastcmp(word, "PAGE")) { - if (1 <= value && value <= 128) + if (1 <= value && value <= MAX_PAGES) { textprompts[num]->page[value - 1].backcolor = UINT8_MAX; // non-zero default readtextpromptpage(f, num, value - 1); } else - deh_warning("Page number %d out of range (1 - 128)", value); + deh_warning("Page number %d out of range (1 - %d)", value, MAX_PAGES); } else diff --git a/src/doomstat.h b/src/doomstat.h index 7bcf59946..eb1726e54 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -166,6 +166,9 @@ typedef struct extern cutscene_t *cutscenes[128]; +#define MAX_PROMPTS 256 +#define MAX_PAGES 128 + typedef struct { char name[32]; // narrator name @@ -186,11 +189,11 @@ typedef struct typedef struct { - textpage_t page[128]; // 128 pages per prompt. + textpage_t page[MAX_PAGES]; INT32 numpages; // Number of pages in this prompt } textprompt_t; -extern textprompt_t *textprompts[256]; +extern textprompt_t *textprompts[MAX_PROMPTS]; // For the Custom Exit linedef. extern INT16 nextmapoverride; diff --git a/src/f_finale.c b/src/f_finale.c index 8a6a8ce0c..f32e44b57 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2065,7 +2065,7 @@ static void F_PreparePageText(char *pagetext) if (promptpagetext) Z_Free(promptpagetext); - promptpagetext = V_WordWrap(textx, textr, 0, pagetext); + promptpagetext = (pagetext && pagetext[0]) ? V_WordWrap(textx, textr, 0, pagetext) : ""; F_NewCutscene(promptpagetext); cutscene_textspeed = textprompts[cutnum]->page[scenenum].textspeed ? textprompts[cutnum]->page[scenenum].textspeed : TICRATE/5; @@ -2085,7 +2085,7 @@ static void F_AdvanceToNextPage(void) // determine next prompt if (nextprompt) { - if (textprompts[nextprompt-1]) + if (nextprompt <= MAX_PROMPTS && textprompts[nextprompt-1]) cutnum = nextprompt-1; else cutnum = INT32_MAX; @@ -2095,14 +2095,14 @@ static void F_AdvanceToNextPage(void) if (nextpage) { scenenum = nextpage-1; - if (scenenum > textprompts[cutnum]->numpages-1) + if (scenenum >= MAX_PAGES || scenenum > textprompts[cutnum]->numpages-1) scenenum = INT32_MAX; } else { if (cutnum != oldcutnum) scenenum = 0; - else if (scenenum < textprompts[cutnum]->numpages-1) + else if (scenenum + 1 < MAX_PAGES && scenenum < textprompts[cutnum]->numpages-1) scenenum++; else scenenum = INT32_MAX; @@ -2157,8 +2157,8 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex (void)freezerealtime; // \todo freeze player->realtime, maybe this needs to cycle through player thinkers // Initialize current prompt and scene - cutnum = (textprompts[promptnum]) ? promptnum : INT32_MAX; - scenenum = (cutnum != INT32_MAX && pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX; + cutnum = (promptnum < MAX_PROMPTS && textprompts[promptnum]) ? promptnum : INT32_MAX; + scenenum = (cutnum != INT32_MAX && pagenum < MAX_PAGES && pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX; promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX); if (promptactive) @@ -2320,7 +2320,10 @@ void F_TextPromptTicker(void) } // generate letter-by-letter text - if (!F_WriteText()) + if (scenenum >= MAX_PAGES || + !textprompts[cutnum]->page[scenenum].text || + !textprompts[cutnum]->page[scenenum].text[0] || + !F_WriteText()) timetonext = !promptblockcontrols; // never show the chevron if we can't toggle pages } From ae4c1e0e8242ed3e00cb5bb780532dcdf55d4846 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 9 Nov 2018 22:06:53 -0500 Subject: [PATCH 197/264] Fix tmthing crash in EndTextPrompt when loading an invalid prompt on level start --- src/f_finale.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index f32e44b57..f120cd756 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2125,7 +2125,8 @@ void F_EndTextPrompt(boolean forceexec, boolean noexec) boolean promptwasactive = promptactive; promptactive = false; - if (promptwasactive) { + if (promptwasactive) + { if (promptmo && promptmo->player && promptblockcontrols) promptmo->reactiontime = TICRATE/4; // prevent jumping right away // \todo account freeze realtime for this) // \todo reset frozen realtime? @@ -2134,9 +2135,14 @@ void F_EndTextPrompt(boolean forceexec, boolean noexec) // \todo net safety, maybe loop all player thinkers? if ((promptwasactive || forceexec) && !noexec && promptpostexectag) { - P_MapStart(); - P_LinedefExecute(promptpostexectag, promptmo, NULL); - P_MapEnd(); + if (tmthing) // edge case where starting an invalid prompt immediately on level load will make P_MapStart fail + P_LinedefExecute(promptpostexectag, promptmo, NULL); + else + { + P_MapStart(); + P_LinedefExecute(promptpostexectag, promptmo, NULL); + P_MapEnd(); + } } } @@ -2326,6 +2332,4 @@ void F_TextPromptTicker(void) !F_WriteText()) timetonext = !promptblockcontrols; // never show the chevron if we can't toggle pages } - - } From 7daf5d4727eadf2e196e57e0f4f5b8d4f1370096 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 9 Nov 2018 22:38:55 -0500 Subject: [PATCH 198/264] Set up separate background color for prompts vs. console --- src/console.c | 40 ++++++++++++++++++++++++++++++++-------- src/console.h | 2 ++ src/dehacked.c | 2 +- src/doomstat.h | 2 +- src/f_finale.c | 2 +- src/v_video.c | 11 ++++++++--- src/v_video.h | 2 +- 7 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/console.c b/src/console.c index 9bc01cf19..f4234d949 100644 --- a/src/console.c +++ b/src/console.c @@ -232,18 +232,20 @@ UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, *orangem // Console BG color UINT8 *consolebgmap = NULL; +UINT8 *promptbgmap = NULL; +static UINT8 promptbgcolor = UINT8_MAX; -void CON_SetupBackColormap(void) +void CON_SetupBackColormapEx(INT32 color, boolean prompt) { UINT16 i, palsum; UINT8 j, palindex, shift; UINT8 *pal = W_CacheLumpName(GetPalette(), PU_CACHE); - if (!consolebgmap) - consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + if (color == INT32_MAX) + color = cons_backcolor.value; shift = 6; // 12 colors -- shift of 7 means 6 colors - switch (cons_backcolor.value) + switch (color) { case 0: palindex = 15; break; // White case 1: palindex = 31; break; // Gray @@ -257,20 +259,42 @@ void CON_SetupBackColormap(void) case 9: palindex = 187; break; // Magenta case 10: palindex = 139; break; // Aqua // Default green - default: palindex = 175; break; -} + default: palindex = 175; color = 11; break; + } + + if (prompt) + { + if (!promptbgmap) + promptbgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + + if (color == promptbgcolor) + return; + else + promptbgcolor = color; + } + else if (!consolebgmap) + consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); // setup background colormap for (i = 0, j = 0; i < 768; i += 3, j++) { palsum = (pal[i] + pal[i+1] + pal[i+2]) >> shift; - consolebgmap[j] = (UINT8)(palindex - palsum); + if (prompt) + promptbgmap[j] = (UINT8)(palindex - palsum); + else + consolebgmap[j] = (UINT8)(palindex - palsum); } } +void CON_SetupBackColormap(void) +{ + CON_SetupBackColormapEx(cons_backcolor.value, false); + CON_SetupBackColormapEx(1, true); // default to gray +} + static void CONS_backcolor_Change(void) { - CON_SetupBackColormap(); + CON_SetupBackColormapEx(cons_backcolor.value, false); } static void CON_SetupColormaps(void) diff --git a/src/console.h b/src/console.h index 970f841d0..c194f44bf 100644 --- a/src/console.h +++ b/src/console.h @@ -38,7 +38,9 @@ extern UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, * // Console bg color (auto updated to match) extern UINT8 *consolebgmap; +extern UINT8 *promptbgmap; +void CON_SetupBackColormapEx(INT32 color, boolean prompt); void CON_SetupBackColormap(void); void CON_ClearHUD(void); // clear heads up messages diff --git a/src/dehacked.c b/src/dehacked.c index 0802fc49d..61dba24c8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1779,7 +1779,7 @@ static void readtextprompt(MYFILE *f, INT32 num) { if (1 <= value && value <= MAX_PAGES) { - textprompts[num]->page[value - 1].backcolor = UINT8_MAX; // non-zero default + textprompts[num]->page[value - 1].backcolor = 1; // default to gray readtextpromptpage(f, num, value - 1); } else diff --git a/src/doomstat.h b/src/doomstat.h index eb1726e54..6ff32e95d 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -176,7 +176,7 @@ typedef struct boolean rightside; // narrator side, false = left, true = right boolean iconflip; // narrator flip icon horizontally UINT8 lines; // # of lines to show. If name is specified, name takes one of the lines. If 0, defaults to 4. - UINT8 backcolor; // see CON_SetupBackColormap: 0-10, 11 for default, UINT8_MAX for user-defined (CONS_BACKCOLOR) + INT32 backcolor; // see CON_SetupBackColormap: 0-11, INT32_MAX for user-defined (CONS_BACKCOLOR) UINT8 align; // text alignment, 0 = left, 1 = right, 2 = center UINT8 verticalalign; // vertical text alignment, 0 = top, 1 = bottom, 2 = middle UINT8 textspeed; // text speed, delay in tics between characters. diff --git a/src/f_finale.c b/src/f_finale.c index f120cd756..ad9fd26ce 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2199,7 +2199,7 @@ void F_TextPromptDrawer(void) F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); // Draw background - V_DrawTutorialBack(boxh); + V_DrawPromptBack(boxh, textprompts[cutnum]->page[scenenum].backcolor); // Draw narrator icon if (iconlump != LUMPERROR) diff --git a/src/v_video.c b/src/v_video.c index f8d0b392c..7296dc754 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1481,17 +1481,20 @@ void V_DrawFadeConsBack(INT32 plines) } // Very similar to F_DrawFadeConsBack, except we draw from the middle(-ish) of the screen to the bottom. -void V_DrawTutorialBack(INT32 boxheight) +void V_DrawPromptBack(INT32 boxheight, INT32 color) { UINT8 *deststop, *buf; boxheight *= vid.dupy; + if (color == INT32_MAX) + color = cons_backcolor.value; + #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) { UINT32 hwcolor; - switch (cons_backcolor.value) + switch (color) { case 0: hwcolor = 0xffffff00; break; // White case 1: hwcolor = 0x80808000; break; // Gray @@ -1510,12 +1513,14 @@ void V_DrawTutorialBack(INT32 boxheight) } #endif + CON_SetupBackColormapEx(color, true); + // heavily simplified -- we don't need to know x or y position, // just the start and stop positions deststop = screens[0] + vid.rowbytes * vid.height; buf = deststop - vid.rowbytes * ((boxheight * 4) + (boxheight/2)*5); // 4 lines of space plus gaps between and some leeway for (; buf < deststop; ++buf) - *buf = consolebgmap[*buf]; + *buf = promptbgmap[*buf]; } // Gets string colormap, used for 0x80 color codes diff --git a/src/v_video.h b/src/v_video.h index ee958c2fa..84a027963 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -158,7 +158,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum); void V_DrawFadeScreen(UINT16 color, UINT8 strength); void V_DrawFadeConsBack(INT32 plines); -void V_DrawTutorialBack(INT32 boxheight); +void V_DrawPromptBack(INT32 boxheight, INT32 color); // draw a single character void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed); From 9ee894f7775f7c3e1b12e8e6614db929d1c8efc0 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 9 Nov 2018 22:47:42 -0500 Subject: [PATCH 199/264] Make gray/black text prompt backcolor darker in OpenGL --- src/dehacked.c | 9 +++++---- src/hardware/hw_draw.c | 2 +- src/v_video.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 61dba24c8..9130c3e40 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1666,9 +1666,10 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].lines = usi; else if (fastcmp(word, "BACKCOLOR")) { - UINT8 backcolor; + INT32 backcolor; if (i == 0 || fastcmp(word2, "WHITE")) backcolor = 0; - else if (i == 1 || fastcmp(word2, "GRAY") || fastcmp(word2, "GREY")) backcolor = 1; + else if (i == 1 || fastcmp(word2, "GRAY") || fastcmp(word2, "GREY") || + fastcmp(word2, "BLACK")) backcolor = 1; else if (i == 2 || fastcmp(word2, "BROWN")) backcolor = 2; else if (i == 3 || fastcmp(word2, "RED")) backcolor = 3; else if (i == 4 || fastcmp(word2, "ORANGE")) backcolor = 4; @@ -1678,8 +1679,8 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) else if (i == 8 || fastcmp(word2, "PURPLE")) backcolor = 8; else if (i == 9 || fastcmp(word2, "MAGENTA")) backcolor = 9; else if (i == 10 || fastcmp(word2, "AQUA")) backcolor = 10; - else if (i < 0) backcolor = UINT8_MAX; // CONS_BACKCOLOR user-configured - else backcolor = 11; // default green + else if (i < 0) backcolor = INT32_MAX; // CONS_BACKCOLOR user-configured + else backcolor = 1; // default gray textprompts[num]->page[pagenum].backcolor = backcolor; } else if (fastcmp(word, "ALIGN")) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 6d4467439..4c6a29fa3 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -726,7 +726,7 @@ void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight) v[2].tow = v[3].tow = 0.0f; Surf.FlatColor.rgba = UINT2RGBA(color); - Surf.FlatColor.s.alpha = 0x80; + Surf.FlatColor.s.alpha = (color == 0 ? 0xC0 : 0x80); // make black darker, like software HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } diff --git a/src/v_video.c b/src/v_video.c index 7296dc754..3e2910df5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1497,7 +1497,7 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color) switch (color) { case 0: hwcolor = 0xffffff00; break; // White - case 1: hwcolor = 0x80808000; break; // Gray + case 1: hwcolor = 0x00000000; break; // Gray // Note this is different from V_DrawFadeConsBack case 2: hwcolor = 0x40201000; break; // Brown case 3: hwcolor = 0xff000000; break; // Red case 4: hwcolor = 0xff800000; break; // Orange From 7ac641450f07d25bd9fa8660562cdadcfe9bc346 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Fri, 9 Nov 2018 23:26:41 -0500 Subject: [PATCH 200/264] Text prompt Hide HUD dehacked --- src/dehacked.c | 10 ++++++++++ src/doomstat.h | 1 + src/f_finale.c | 9 +++++++++ src/f_finale.h | 1 + 4 files changed, 21 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 9130c3e40..0fc3f905a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1701,6 +1701,14 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].textspeed = get_number(word2); else if (fastcmp(word, "TEXTSFX")) textprompts[num]->page[pagenum].textsfx = get_number(word2); + else if (fastcmp(word, "HIDEHUD")) + { + UINT8 hidehud = 0; + if (usi == 0 || (word2[0] == 'F' && (word2[1] == 'A' || !word2[1])) || word2[0] == 'N') hidehud = 1; // false + else if (usi == 1 || word2[0] == 'T' || word2[0] == 'Y') hidehud = 1; // true (hide appropriate HUD elements) + else if (usi == 2 || word2[0] == 'A' || (word2[0] == 'F' && word2[1] == 'O')) hidehud = 2; // force (hide all HUD elements) + textprompts[num]->page[pagenum].hidehud = hidehud; + } else if (fastcmp(word, "METAPAGE")) { if (usi && usi <= textprompts[num]->numpages) @@ -1716,6 +1724,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].verticalalign = textprompts[num]->page[metapagenum].verticalalign; textprompts[num]->page[pagenum].textspeed = textprompts[num]->page[metapagenum].textspeed; textprompts[num]->page[pagenum].textsfx = textprompts[num]->page[metapagenum].textsfx; + textprompts[num]->page[pagenum].hidehud = textprompts[num]->page[metapagenum].hidehud; } } else if (fastcmp(word, "NEXTPROMPT")) @@ -1781,6 +1790,7 @@ static void readtextprompt(MYFILE *f, INT32 num) if (1 <= value && value <= MAX_PAGES) { textprompts[num]->page[value - 1].backcolor = 1; // default to gray + textprompts[num]->page[value - 1].hidehud = 1; // hide appropriate HUD elements readtextpromptpage(f, num, value - 1); } else diff --git a/src/doomstat.h b/src/doomstat.h index 6ff32e95d..a46711cc4 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -175,6 +175,7 @@ typedef struct char iconname[8]; // narrator icon lump boolean rightside; // narrator side, false = left, true = right boolean iconflip; // narrator flip icon horizontally + UINT8 hidehud; // hide hud, 0 = show all, 1 = hide depending on prompt position (top/bottom), 2 = hide all UINT8 lines; // # of lines to show. If name is specified, name takes one of the lines. If 0, defaults to 4. INT32 backcolor; // see CON_SetupBackColormap: 0-11, INT32_MAX for user-defined (CONS_BACKCOLOR) UINT8 align; // text alignment, 0 = left, 1 = right, 2 = center diff --git a/src/f_finale.c b/src/f_finale.c index ad9fd26ce..aec567123 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -33,6 +33,7 @@ #include "m_cond.h" #include "p_local.h" #include "p_setup.h" +#include "st_stuff.h" // hud hiding #ifdef HAVE_BLUA #include "lua_hud.h" @@ -2030,6 +2031,14 @@ boolean F_CutsceneResponder(event_t *event) // TEXT PROMPTS // ================== +INT32 F_GetPromptHideHud() +{ + if (cutnum == INT32_MAX || scenenum == INT32_MAX || !textprompts[cutnum] || scenenum >= textprompts[cutnum]->numpages) + return 0; + else + return textprompts[cutnum]->page[scenenum]->hidehud; +} + static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *boxh, INT32 *texth, INT32 *texty, INT32 *namey, INT32 *chevrony, INT32 *textx, INT32 *textr) { // reuse: diff --git a/src/f_finale.h b/src/f_finale.h index 8ce7ac22e..a6c962dea 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -55,6 +55,7 @@ void F_EndCutScene(void); void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime); void F_TextPromptDrawer(void); void F_EndTextPrompt(boolean forceexec, boolean noexec); +INT32 F_GetPromptHideHud(void); void F_StartGameEnd(void); void F_StartIntro(void); From 19a8b159128bb43ba24ca2d6da4c2e82de217431 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 00:10:16 -0500 Subject: [PATCH 201/264] Actually fix empty prompt text crash --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index ad9fd26ce..0abee4b45 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2065,7 +2065,7 @@ static void F_PreparePageText(char *pagetext) if (promptpagetext) Z_Free(promptpagetext); - promptpagetext = (pagetext && pagetext[0]) ? V_WordWrap(textx, textr, 0, pagetext) : ""; + promptpagetext = (pagetext && pagetext[0]) ? V_WordWrap(textx, textr, 0, pagetext) : Z_StrDup(""); F_NewCutscene(promptpagetext); cutscene_textspeed = textprompts[cutnum]->page[scenenum].textspeed ? textprompts[cutnum]->page[scenenum].textspeed : TICRATE/5; From 33a94ba2b831f86763aa45dc327d3a5182521a26 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 01:00:18 -0500 Subject: [PATCH 202/264] Prompt HUD hiding implementation --- src/f_finale.c | 62 +++++++++++++++++++++++++++++++++++++++++++------- src/f_finale.h | 3 ++- src/st_stuff.c | 35 +++++++++++++++++++++++++--- 3 files changed, 88 insertions(+), 12 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 64648fdda..8d3aaea67 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2031,14 +2031,6 @@ boolean F_CutsceneResponder(event_t *event) // TEXT PROMPTS // ================== -INT32 F_GetPromptHideHud() -{ - if (cutnum == INT32_MAX || scenenum == INT32_MAX || !textprompts[cutnum] || scenenum >= textprompts[cutnum]->numpages) - return 0; - else - return textprompts[cutnum]->page[scenenum]->hidehud; -} - static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *boxh, INT32 *texth, INT32 *texty, INT32 *namey, INT32 *chevrony, INT32 *textx, INT32 *textr) { // reuse: @@ -2063,6 +2055,60 @@ static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *b *textr = *rightside ? BASEVIDWIDTH - (((*boxh * 4) + (*boxh/2)*4) + 4) : BASEVIDWIDTH-4; } +static fixed_t F_GetPromptHideHudBound(void) +{ + UINT8 pagelines; + boolean rightside; + INT32 boxh, texth, texty, namey, chevrony; + INT32 textx, textr; + + if (cutnum == INT32_MAX || scenenum == INT32_MAX || !textprompts[cutnum] || scenenum >= textprompts[cutnum]->numpages || + !textprompts[cutnum]->page[scenenum].hidehud || + (splitscreen && textprompts[cutnum]->page[scenenum].hidehud != 2)) // don't hide on splitscreen, unless hide all is forced + return 0; + else if (textprompts[cutnum]->page[scenenum].hidehud == 2) // hide all + return BASEVIDHEIGHT; + + F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr); + + // calc boxheight (see V_DrawPromptBack) + boxh *= vid.dupy; + boxh = (boxh * 4) + (boxh/2)*5; // 4 lines of space plus gaps between and some leeway + + // return a coordinate to check + // if negative: don't show hud elements below this coordinate (visually) + // if positive: don't show hud elements above this coordinate (visually) + return 0 - boxh; // \todo: if prompt at top of screen (someday), make this return positive +} + +boolean F_GetPromptHideHudAll(void) +{ + if (cutnum == INT32_MAX || scenenum == INT32_MAX || !textprompts[cutnum] || scenenum >= textprompts[cutnum]->numpages || + !textprompts[cutnum]->page[scenenum].hidehud || + (splitscreen && textprompts[cutnum]->page[scenenum].hidehud != 2)) // don't hide on splitscreen, unless hide all is forced + return false; + else if (textprompts[cutnum]->page[scenenum].hidehud == 2) // hide all + return true; + else + return false; +} + +boolean F_GetPromptHideHud(fixed_t y) +{ + INT32 ybound; + boolean fromtop; + fixed_t ytest; + + if (!promptactive) + return false; + + ybound = F_GetPromptHideHudBound(); + fromtop = (ybound >= 0); + ytest = (fromtop ? ybound : BASEVIDHEIGHT + ybound); + + return (fromtop ? y < ytest : y >= ytest); // true means hide +} + static void F_PreparePageText(char *pagetext) { UINT8 pagelines; diff --git a/src/f_finale.h b/src/f_finale.h index a6c962dea..0c9032ac2 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -55,7 +55,8 @@ void F_EndCutScene(void); void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime); void F_TextPromptDrawer(void); void F_EndTextPrompt(boolean forceexec, boolean noexec); -INT32 F_GetPromptHideHud(void); +boolean F_GetPromptHideHudAll(void); +boolean F_GetPromptHideHud(fixed_t y); void F_StartGameEnd(void); void F_StartIntro(void); diff --git a/src/st_stuff.c b/src/st_stuff.c index fa13e008a..26d9678a3 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -603,6 +603,9 @@ static void ST_drawDebugInfo(void) static void ST_drawScore(void) { + if (F_GetPromptHideHud(hudinfo[HUD_SCORE].y)) + return; + // SCORE: ST_DrawPatchFromHud(HUD_SCORE, sboscore, V_HUDTRANS); if (objectplacing) @@ -712,6 +715,9 @@ static void ST_drawTime(void) tictrn = G_TicsToCentiseconds(tics); } + if (F_GetPromptHideHud(hudinfo[HUD_TIME].y)) + return; + // TIME: ST_DrawPatchFromHud(HUD_TIME, ((downwards && (tics < 30*TICRATE) && (leveltime/5 & 1)) ? sboredtime : sbotime), V_HUDTRANS); @@ -738,6 +744,9 @@ static inline void ST_drawRings(void) { INT32 ringnum; + if (F_GetPromptHideHud(hudinfo[HUD_RINGS].y)) + return; + ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); ringnum = ((objectplacing) ? op_currentdoomednum : max(stplyr->rings, 0)); @@ -756,6 +765,9 @@ static void ST_drawLivesArea(void) if (!stplyr->skincolor) return; // Just joined a server, skin isn't loaded yet! + if (F_GetPromptHideHud(hudinfo[HUD_LIVES].y)) + return; + // face background V_DrawSmallScaledPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, livesback); @@ -927,6 +939,9 @@ static void ST_drawInput(void) if (stplyr->powers[pw_carry] == CR_NIGHTSMODE) y -= 16; + if (F_GetPromptHideHud(y)) + return; + // O backing V_DrawFill(x, y-1, 16, 16, hudinfo[HUD_LIVES].f|20); V_DrawFill(x, y+15, 16, 1, hudinfo[HUD_LIVES].f|29); @@ -1202,6 +1217,9 @@ static void ST_drawPowerupHUD(void) static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0}; #define ICONSEP (16+4) // matches weapon rings HUD + if (F_GetPromptHideHud(hudinfo[HUD_POWERUPS].y)) + return; + if (stplyr->spectator || stplyr->playerstate != PST_LIVE) return; @@ -1364,7 +1382,7 @@ static void ST_drawFirstPersonHUD(void) p = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); // Display the countdown drown numbers! - if (p) + if (p && !F_GetPromptHideHud(60 - SHORT(p->topoffset))) V_DrawScaledPatch((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset), 60 - SHORT(p->topoffset), V_PERPLAYER|V_PERPLAYER|V_TRANSLUCENT, p); } @@ -1908,6 +1926,9 @@ static void ST_drawMatchHUD(void) const INT32 y = 176; // HUD_LIVES INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10) - 6; + if (F_GetPromptHideHud(y)) + return; + if (!G_RingSlingerGametype()) return; @@ -1954,6 +1975,9 @@ static void ST_drawTextHUD(void) y -= 8;\ } + if (F_GetPromptHideHud(y)) + return; + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) { if (leveltime < hidetime * TICRATE) @@ -2087,6 +2111,9 @@ static void ST_drawTeamHUD(void) patch_t *p; #define SEP 20 + if (F_GetPromptHideHud(0)) // y base is 0 + return; + if (gametype == GT_CTF) p = bflagico; else @@ -2200,7 +2227,8 @@ static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offse interval = 0; } - V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, hudinfo[HUD_HUNTPICS].f|V_PERPLAYER|V_HUDTRANS, patches[i]); + if (!F_GetPromptHideHud(hudinfo[HUD_HUNTPICS].y)) + V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, hudinfo[HUD_HUNTPICS].f|V_PERPLAYER|V_HUDTRANS, patches[i]); return interval; } @@ -2298,7 +2326,8 @@ static void ST_overlayDrawer(void) //hu_showscores = auto hide score/time/rings when tab rankings are shown if (!(hu_showscores && (netgame || multiplayer))) { - if (maptol & TOL_NIGHTS || G_IsSpecialStage(gamemap)) + if ((maptol & TOL_NIGHTS || G_IsSpecialStage(gamemap)) && + !F_GetPromptHideHudAll()) ST_drawNiGHTSHUD(); else { From a542006ae846a2ab87d08e8311e06d76747f3886 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 01:17:11 -0500 Subject: [PATCH 203/264] Hide Tutorial menu option if no tutorialmap --- 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 69c609db0..38ff3f998 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -732,7 +732,7 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { - {IT_STRING, NULL, "Tutorial", M_StartTutorial, 84}, + {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 84}, {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108}, @@ -6107,6 +6107,8 @@ 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 = From ffed9f4d20eaf77e75bef5588fd2ecc4b10f3126 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 01:31:30 -0500 Subject: [PATCH 204/264] Force camera defaults during tutorialmode (doesn't work in all cases) --- src/p_user.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index dd2ddbc82..75712ff3a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8848,7 +8848,18 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (P_CameraThinker(player, thiscam, resetcalled)) return true; - if (thiscam == &camera) + if (tutorialmode) + { + // force defaults because we have a camera look section + // \todo would be nice to use cv_cam_*.defaultvalue directly, but string parsing + // is not separated from cv setting (see command.c Setvalue, CV_SetCVar) + camspeed = 0.3; + camstill = false; + camrotate = 0; + camdist = 160; + camheight = 25; + } + else if (thiscam == &camera) { camspeed = cv_cam_speed.value; camstill = cv_cam_still.value; From 28238c41dfd044a46f0624939a07f9fe250bc1c7 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 02:30:21 -0500 Subject: [PATCH 205/264] WIP: First-time tutorial prompt --- src/d_netcmd.c | 1 + src/g_game.h | 1 + src/m_menu.c | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 528d79f3b..dd9ced6c4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -719,6 +719,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_crosshair2); CV_RegisterVar(&cv_alwaysfreelook); CV_RegisterVar(&cv_alwaysfreelook2); + CV_RegisterVar(&cv_postfirsttime); // g_input.c CV_RegisterVar(&cv_sideaxis); diff --git a/src/g_game.h b/src/g_game.h index d6b41830e..00298c623 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -55,6 +55,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu +extern consvar_t cv_postfirsttime; extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2; diff --git a/src/m_menu.c b/src/m_menu.c index 38ff3f998..b61c6396a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -441,6 +441,9 @@ static CV_PossibleValue_t serversort_cons_t[] = { }; consvar_t cv_serversort = {"serversort", "Ping", CV_HIDEN | CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL}; +// first time memory +consvar_t cv_postfirsttime = {"postfirsttime", "No", CV_HIDEN | CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; + // autorecord demos for time attack static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6141,6 +6144,8 @@ static void M_StartTutorial(INT32 choice) if (!tutorialmap) return; // no map to go to, don't bother + CV_SetValue(&cv_postfirsttime, 1); + tutorialmode = true; // turn on tutorial mode emeralds = 0; @@ -6757,6 +6762,20 @@ static void M_HandleLoadSave(INT32 choice) } } +static void M_TutorialResponse(INT32 ch) +{ + CV_SetValue(&cv_postfirsttime, 1); + if (ch != 'y' && ch != KEY_ENTER) + { + return; + // copypasta from M_LoadGame + M_ReadSaveStrings(); + M_SetupNextMenu(&SP_LoadDef); + } + else + M_StartTutorial(0); +} + // // Selected from SRB2 menu // @@ -6764,6 +6783,12 @@ static void M_LoadGame(INT32 choice) { (void)choice; + if (tutorialmap && !cv_postfirsttime.value) + { + M_StartMessage("Do you want to play a brief Tutorial?\n(Press 'Y' to go, or 'N' to skip)", M_TutorialResponse, MM_YESNO); + return; + } + M_ReadSaveStrings(); M_SetupNextMenu(&SP_LoadDef); } From 2da335a1c4cb9af38fbba79c4aadeeb4facf0093 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 10 Nov 2018 13:08:26 +0000 Subject: [PATCH 206/264] Place limit on the amount of alias recursion allowed, to prevent cycles or otherwise excessive recursion --- src/command.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/command.c b/src/command.c index f77fb5a4d..8971d42fc 100644 --- a/src/command.c +++ b/src/command.c @@ -63,6 +63,7 @@ CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}}; CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}}; #define COM_BUF_SIZE 8192 // command buffer size +#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases static INT32 com_wait; // one command per frame (for cmd sequences) @@ -485,6 +486,7 @@ static void COM_ExecuteString(char *ptext) { xcommand_t *cmd; cmdalias_t *a; + static INT32 recursion = 0; // detects recursion and stops it if it goes too far COM_TokenizeString(ptext); @@ -497,6 +499,7 @@ static void COM_ExecuteString(char *ptext) { if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase! { + recursion = 0; cmd->function(); return; } @@ -507,11 +510,20 @@ static void COM_ExecuteString(char *ptext) { if (!stricmp(com_argv[0], a->name)) { + if (recursion > MAX_ALIAS_RECURSION) + { + CONS_Alert(CONS_WARNING, M_GetText("Alias recursion cycle detected!\n")); + recursion = 0; + return; + } + recursion++; COM_BufInsertText(a->value); return; } } + recursion = 0; + // check cvars // Hurdler: added at Ebola's request ;) // (don't flood the console in software mode with bad gr_xxx command) From e1e94c3af2500fa60890a5d632c9a5759ed6005e Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 09:32:53 -0500 Subject: [PATCH 207/264] Added page tags and find page by tag * Added tutorial mode defines to this branch --- src/dehacked.c | 2 ++ src/doomstat.h | 4 ++++ src/f_finale.c | 30 ++++++++++++++++++++++++++++++ src/f_finale.h | 1 + src/g_game.c | 3 +++ src/p_setup.c | 1 + src/p_spec.c | 3 +++ 7 files changed, 44 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 0fc3f905a..214d47a16 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1727,6 +1727,8 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].hidehud = textprompts[num]->page[metapagenum].hidehud; } } + else if (fastcmp(word, "TAG")) + strncpy(textprompts[num]->page[pagenum].tag, word2, 25); else if (fastcmp(word, "NEXTPROMPT")) textprompts[num]->page[pagenum].nextprompt = usi; else if (fastcmp(word, "NEXTPAGE")) diff --git a/src/doomstat.h b/src/doomstat.h index a46711cc4..eb4ed7066 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -129,6 +129,9 @@ extern INT16 titlemap; extern boolean hidetitlepics; extern INT16 bootmap; //bootmap for loading a map on startup +extern INT16 tutorialmap; // map to load for tutorial +extern boolean tutorialmode; // are we in a tutorial right now? + extern boolean looptitle; // CTF colors. @@ -171,6 +174,7 @@ extern cutscene_t *cutscenes[128]; typedef struct { + char tag[25]; // page tag (24 chars due to texture concatenating) char name[32]; // narrator name char iconname[8]; // narrator icon lump boolean rightside; // narrator side, false = left, true = right diff --git a/src/f_finale.c b/src/f_finale.c index 8d3aaea67..9217ced68 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2233,6 +2233,36 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex F_EndTextPrompt(true, false); // run the post-effects immediately } +void F_StartTextPromptByNamedTag(char *tag, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime) +{ + INT32 promptnum, pagenum; + char realtag[25]; + + strncpy(realtag, tag, 25); + realtag[24] = 0; + + // \todo hardcoded tutorial mode behavior: concat control mode (fps, platform, custom) to end of input tag + if (tutorialmode) + strncat(realtag, "FPS", 25); + + for (promptnum = 0; promptnum < MAX_PROMPTS; promptnum++) + { + if (!textprompts[promptnum]) + continue; + + for (pagenum = 0; pagenum < textprompts[promptnum]->numpages && pagenum < MAX_PAGES; pagenum++) + { + if (!strncmp(realtag, textprompts[promptnum]->page[pagenum].tag, 25)) + { + F_StartTextPrompt(promptnum, pagenum, mo, postexectag, blockcontrols, freezerealtime); + return; + } + } + } + + CONS_Debug(DBG_GAMELOGIC, "Text prompt: Can't find a page with named tag %s\n", realtag); +} + void F_TextPromptDrawer(void) { // reuse: diff --git a/src/f_finale.h b/src/f_finale.h index 0c9032ac2..093389c1f 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -53,6 +53,7 @@ void F_CutsceneDrawer(void); void F_EndCutScene(void); void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime); +void F_StartTextPromptByNamedTag(char *tag, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime); void F_TextPromptDrawer(void); void F_EndTextPrompt(boolean forceexec, boolean noexec); boolean F_GetPromptHideHudAll(void); diff --git a/src/g_game.c b/src/g_game.c index d72a1961b..2eecbe1b3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -127,6 +127,9 @@ INT16 titlemap = 0; boolean hidetitlepics = false; INT16 bootmap; //bootmap for loading a map on startup +INT16 tutorialmap = 0; // map to load for tutorial +boolean tutorialmode = false; // are we in a tutorial right now? + boolean looptitle = false; UINT8 skincolor_redteam = SKINCOLOR_RED; diff --git a/src/p_setup.c b/src/p_setup.c index b2dfedb4e..c1e8c17e3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1541,6 +1541,7 @@ static void P_LoadRawSideDefs2(void *data) } case 443: // Calls a named Lua function + case 459: // Control text prompt (named tag) { char process[8*3+1]; memset(process,0,8*3+1); diff --git a/src/p_spec.c b/src/p_spec.c index 42153b4bf..76d7ac249 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3771,9 +3771,12 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) boolean blockcontrols = !(line->flags & ML_EFFECT2); boolean freezerealtime = !(line->flags & ML_EFFECT3); //boolean freezethinkers = (line->flags & ML_EFFECT4); + boolean callbynamedtag = (line->flags & ML_TFERLINE); if (closetextprompt) F_EndTextPrompt(false, false); + else if (callbynamedtag && sides[line->sidenum[0]].text && sides[line->sidenum[0]].text[0]) + F_StartTextPromptByNamedTag(sides[line->sidenum[0]].text, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime); else F_StartTextPrompt(promptnum, pagenum, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime); } From a197c197420df6687a4be16f4945e9f01307fe80 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 09:38:32 -0500 Subject: [PATCH 208/264] Prompt page string field length adjustment; check empty named tag before prompt search --- src/dehacked.c | 8 ++++---- src/doomstat.h | 4 ++-- src/f_finale.c | 11 +++++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 214d47a16..c3323a6af 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1641,11 +1641,11 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) // HACK: Add yellow control char now // so the drawing function doesn't call it repeatedly - char name[32]; + char name[34]; name[0] = '\x82'; // color yellow name[1] = 0; - strncat(name, word2, 31); - name[31] = 0; + strncat(name, word2, 33); + name[33] = 0; // Replace _ with ' ' for (i = 0; i < 32 && name[i]; i++) @@ -1728,7 +1728,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) } } else if (fastcmp(word, "TAG")) - strncpy(textprompts[num]->page[pagenum].tag, word2, 25); + strncpy(textprompts[num]->page[pagenum].tag, word2, 33); else if (fastcmp(word, "NEXTPROMPT")) textprompts[num]->page[pagenum].nextprompt = usi; else if (fastcmp(word, "NEXTPAGE")) diff --git a/src/doomstat.h b/src/doomstat.h index eb4ed7066..432699d99 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -174,8 +174,8 @@ extern cutscene_t *cutscenes[128]; typedef struct { - char tag[25]; // page tag (24 chars due to texture concatenating) - char name[32]; // narrator name + char tag[33]; // page tag + char name[34]; // narrator name, extra char for color char iconname[8]; // narrator icon lump boolean rightside; // narrator side, false = left, true = right boolean iconflip; // narrator flip icon horizontally diff --git a/src/f_finale.c b/src/f_finale.c index 9217ced68..d706bf22e 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2236,14 +2236,17 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex void F_StartTextPromptByNamedTag(char *tag, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime) { INT32 promptnum, pagenum; - char realtag[25]; + char realtag[33]; - strncpy(realtag, tag, 25); - realtag[24] = 0; + if (!tag || !tag[0]) + return; + + strncpy(realtag, tag, 33); + realtag[32] = 0; // \todo hardcoded tutorial mode behavior: concat control mode (fps, platform, custom) to end of input tag if (tutorialmode) - strncat(realtag, "FPS", 25); + strncat(realtag, "FPS", 33); for (promptnum = 0; promptnum < MAX_PROMPTS; promptnum++) { From 99a0831b0b053490664db7115faef5d7f62f1a25 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 10:06:51 -0500 Subject: [PATCH 209/264] Hardcode tutorial prompt offset index --- src/doomstat.h | 6 +++++- src/f_finale.c | 3 ++- src/g_game.c | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 432699d99..b57098d52 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -169,7 +169,11 @@ typedef struct extern cutscene_t *cutscenes[128]; -#define MAX_PROMPTS 256 +// Reserve prompt space for tutorials +#define TUTORIAL_PROMPT 201 // one-based +#define TUTORIAL_AREAS 6 +#define TUTORIAL_AREA_PROMPTS 5 +#define MAX_PROMPTS (TUTORIAL_PROMPT+TUTORIAL_AREAS*TUTORIAL_AREA_PROMPTS*3) // 3 control modes #define MAX_PAGES 128 typedef struct diff --git a/src/f_finale.c b/src/f_finale.c index d706bf22e..0be8dd0bc 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2236,6 +2236,7 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex void F_StartTextPromptByNamedTag(char *tag, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime) { INT32 promptnum, pagenum; + INT32 tutorialpromptnum = (tutorialmode) ? TUTORIAL_PROMPT-1 : 0; char realtag[33]; if (!tag || !tag[0]) @@ -2248,7 +2249,7 @@ void F_StartTextPromptByNamedTag(char *tag, mobj_t *mo, UINT16 postexectag, bool if (tutorialmode) strncat(realtag, "FPS", 33); - for (promptnum = 0; promptnum < MAX_PROMPTS; promptnum++) + for (promptnum = 0 + tutorialpromptnum; promptnum < MAX_PROMPTS; promptnum++) { if (!textprompts[promptnum]) continue; diff --git a/src/g_game.c b/src/g_game.c index 2eecbe1b3..12e9cc961 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -141,7 +141,7 @@ tic_t countdowntimer = 0; boolean countdowntimeup = false; cutscene_t *cutscenes[128]; -textprompt_t *textprompts[256]; +textprompt_t *textprompts[MAX_PROMPTS]; INT16 nextmapoverride; boolean skipstats; From 3d9ce630d2cbe9969b4c4fe35eed6b994cf9a1a6 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 10:30:33 -0500 Subject: [PATCH 210/264] SOC for prompt gfx and music --- src/dehacked.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++- src/doomstat.h | 11 +++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index c3323a6af..936a71777 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1557,6 +1557,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) char *word2; INT32 i; UINT16 usi; + UINT8 picid; do { @@ -1634,8 +1635,72 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) i = atoi(word2); usi = (UINT16)i; + // copypasta from readcutscenescene + if (fastcmp(word, "NUMBEROFPICS")) + { + textprompts[num]->page[pagenum].numpics = (UINT8)i; + } + else if (fastncmp(word, "PIC", 3)) + { + picid = (UINT8)atoi(word + 3); + if (picid > 8 || picid == 0) + { + deh_warning("textpromptscene %d: unknown word '%s'", num, word); + continue; + } + --picid; - if (fastcmp(word, "NAME")) + if (fastcmp(word+4, "NAME")) + { + strncpy(textprompts[num]->page[pagenum].picname[picid], word2, 8); + } + else if (fastcmp(word+4, "HIRES")) + { + textprompts[num]->page[pagenum].pichires[picid] = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y'); + } + else if (fastcmp(word+4, "DURATION")) + { + textprompts[num]->page[pagenum].picduration[picid] = usi; + } + else if (fastcmp(word+4, "XCOORD")) + { + textprompts[num]->page[pagenum].xcoord[picid] = usi; + } + else if (fastcmp(word+4, "YCOORD")) + { + textprompts[num]->page[pagenum].ycoord[picid] = usi; + } + else + deh_warning("textpromptscene %d: unknown word '%s'", num, word); + } + else if (fastcmp(word, "MUSIC")) + { + strncpy(textprompts[num]->page[pagenum].musswitch, word2, 7); + textprompts[num]->page[pagenum].musswitch[6] = 0; + } +#ifdef MUSICSLOT_COMPATIBILITY + else if (fastcmp(word, "MUSICSLOT")) + { + i = get_mus(word2, true); + if (i && i <= 1035) + snprintf(textprompts[num]->page[pagenum].musswitch, 7, "%sM", G_BuildMapName(i)); + else if (i && i <= 1050) + strncpy(textprompts[num]->page[pagenum].musswitch, compat_special_music_slots[i - 1036], 7); + else + textprompts[num]->page[pagenum].musswitch[0] = 0; // becomes empty string + textprompts[num]->page[pagenum].musswitch[6] = 0; + } +#endif + else if (fastcmp(word, "MUSICTRACK")) + { + textprompts[num]->page[pagenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; + } + else if (fastcmp(word, "MUSICLOOP")) + { + textprompts[num]->page[pagenum].musicloop = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y'); + } + // end copypasta from readcutscenescene + else if (fastcmp(word, "NAME")) { INT32 i; @@ -1714,6 +1779,7 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) if (usi && usi <= textprompts[num]->numpages) { UINT8 metapagenum = usi - 1; + strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, 32); strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, 8); textprompts[num]->page[pagenum].rightside = textprompts[num]->page[metapagenum].rightside; @@ -1725,6 +1791,26 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].textspeed = textprompts[num]->page[metapagenum].textspeed; textprompts[num]->page[pagenum].textsfx = textprompts[num]->page[metapagenum].textsfx; textprompts[num]->page[pagenum].hidehud = textprompts[num]->page[metapagenum].hidehud; + + // music: don't copy, else each page change may reset the music + } + } + if (fastcmp(word, "PICSMETAPAGE")) + { + if (usi && usi <= textprompts[num]->numpages) + { + UINT8 metapagenum = usi - 1; + UINT8 picid; + + for (picid = 0; picid < 8; picid++) + { + textprompts[num]->page[pagenum].numpics = textprompts[num]->page[metapagenum].numpics; + strncpy(textprompts[num]->page[pagenum].picname[picid], textprompts[num]->page[metapagenum].picname[picid], 8); + textprompts[num]->page[pagenum].pichires[picid] = textprompts[num]->page[metapagenum].pichires[picid]; + textprompts[num]->page[pagenum].picduration[picid] = textprompts[num]->page[metapagenum].picduration[picid]; + textprompts[num]->page[pagenum].xcoord[picid] = textprompts[num]->page[metapagenum].xcoord[picid]; + textprompts[num]->page[pagenum].ycoord[picid] = textprompts[num]->page[metapagenum].ycoord[picid]; + } } } else if (fastcmp(word, "TAG")) diff --git a/src/doomstat.h b/src/doomstat.h index b57098d52..a3428eb83 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -178,6 +178,17 @@ extern cutscene_t *cutscenes[128]; typedef struct { + UINT8 numpics; + char picname[8][8]; + UINT8 pichires[8]; + UINT16 xcoord[8]; // gfx + UINT16 ycoord[8]; // gfx + UINT16 picduration[8]; + + char musswitch[7]; + UINT16 musswitchflags; + UINT8 musicloop; + char tag[33]; // page tag char name[34]; // narrator name, extra char for color char iconname[8]; // narrator icon lump From a8291c122a106225a6c34aa22ea2eb1f67e39feb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 10 Nov 2018 15:47:04 +0000 Subject: [PATCH 211/264] adding lua_maplib.c comments for new slope-related userdata types --- src/lua_maplib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 84bd73834..66fbb22b3 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1789,6 +1789,10 @@ static int ffloor_set(lua_State *L) } #ifdef ESLOPE +////////////// +// pslope_t // +////////////// + static int slope_get(lua_State *L) { pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); @@ -1925,6 +1929,10 @@ static int slope_set(lua_State *L) return 0; } +/////////////// +// vector*_t // +/////////////// + static int vector2_get(lua_State *L) { vector2_t *vec = *((vector2_t **)luaL_checkudata(L, 1, META_VECTOR2)); From d456a5362cec11899d70191176bc85c1909f705f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 10 Nov 2018 15:55:09 +0000 Subject: [PATCH 212/264] Whoops, mucked up this part of the conflict resolving --- src/hardware/hw_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index a817e1f90..294e6bcd0 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -324,7 +324,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (pscale != FRACUNIT || (splitscreen && option & V_PERPLAYER)) { fwidth = (float)SHORT(gpatch->width) * fscalew * dupx; - fheight = (float)SHORT(gpatch->height) * fscalew * dupy; + fheight = (float)SHORT(gpatch->height) * fscaleh * dupy; } else { From 896de73c6007f462d3826088a84463f03a9972f6 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 10 Nov 2018 16:00:33 +0000 Subject: [PATCH 213/264] ....ow this slipup hurt me badly --- src/lua_hooklib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index bd95d4cbd..bb1f59729 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1209,6 +1209,10 @@ void LUAh_PlayerQuit(player_t *plr, int reason) LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit lua_pushinteger(gL, reason); // Reason for quitting } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); LUA_Call(gL, 2); } From 631c6f93f5db684a71de1b23a888b4dd55bc3079 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 10 Nov 2018 11:05:33 -0500 Subject: [PATCH 214/264] Implement music switching for prompts --- src/f_finale.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/f_finale.c b/src/f_finale.c index 0be8dd0bc..b78bd14d9 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2172,6 +2172,11 @@ static void F_AdvanceToNextPage(void) // on timer mode, number of tics until page advances timetonext = textprompts[cutnum]->page[scenenum].timetonext ? textprompts[cutnum]->page[scenenum].timetonext : TICRATE/10; F_PreparePageText(textprompts[cutnum]->page[scenenum].text); + + if (textprompts[cutnum]->page[scenenum].musswitch[0]) + S_ChangeMusic(textprompts[cutnum]->page[scenenum].musswitch, + textprompts[cutnum]->page[scenenum].musswitchflags, + textprompts[cutnum]->page[scenenum].musicloop); } } @@ -2228,6 +2233,11 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex // on timer mode, number of tics until page advances timetonext = textprompts[cutnum]->page[scenenum].timetonext ? textprompts[cutnum]->page[scenenum].timetonext : TICRATE/10; F_PreparePageText(textprompts[cutnum]->page[scenenum].text); + + if (textprompts[cutnum]->page[scenenum].musswitch[0]) + S_ChangeMusic(textprompts[cutnum]->page[scenenum].musswitch, + textprompts[cutnum]->page[scenenum].musswitchflags, + textprompts[cutnum]->page[scenenum].musicloop); } else F_EndTextPrompt(true, false); // run the post-effects immediately From a733a29f4c5889251192184870cc451cacd9dc96 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 9 Jan 2017 22:13:26 +0000 Subject: [PATCH 215/264] Starting work on porting hw_clip.c/h code, Makefiles and CMake can compile them at least Other notes: * Renamed all new functions to have HWR_ prefix instead of gld_, for consistency * HWR_FrustrumSetup and HWR_SphereInFrustum are disabled and require HAVE_SPHEREFRUSTRUM. This is because 1) SRB2CB did not need the code, so presumably neither will we, and 2) there are some OpenGL API functions used there that due to our way of using OpenGL we don't use outside of r_opengl.c, which makes dealing with HWR_FrustrumSetup complicated in theory * The new clipping functions are not added to OpenGL's "main" rendering code itself just yet, they're just available to use now once hw_clip.h is included --- src/CMakeLists.txt | 2 + src/Makefile | 12 +- src/hardware/hw_clip.c | 465 +++++++++++++++++++++++++++++++++++++++++ src/hardware/hw_clip.h | 24 +++ 4 files changed, 497 insertions(+), 6 deletions(-) create mode 100644 src/hardware/hw_clip.c create mode 100644 src/hardware/hw_clip.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 46a42a92c..0602de9de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -350,6 +350,7 @@ if(${SRB2_CONFIG_HWRENDER}) set(SRB2_HWRENDER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c @@ -358,6 +359,7 @@ if(${SRB2_CONFIG_HWRENDER}) ) set (SRB2_HWRENDER_HEADERS + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h diff --git a/src/Makefile b/src/Makefile index 7a67c3f02..b159de3b8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -269,7 +269,7 @@ ifndef DC endif OPTS+=-DHWRENDER OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ - $(OBJDIR)/hw_main.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o + $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o endif ifdef NOHS @@ -719,7 +719,7 @@ ifdef MINGW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ @@ -727,7 +727,7 @@ else $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@ @@ -880,7 +880,7 @@ ifndef NOHW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ @@ -888,7 +888,7 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ @@ -896,7 +896,7 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \ + hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \ d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c new file mode 100644 index 000000000..47cbbfa2b --- /dev/null +++ b/src/hardware/hw_clip.c @@ -0,0 +1,465 @@ +/* Emacs style mode select -*- C++ -*- + *----------------------------------------------------------------------------- + * + * + * PrBoom: a Doom port merged with LxDoom and LSDLDoom + * based on BOOM, a modified and improved DOOM engine + * Copyright (C) 1999 by + * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman + * Copyright (C) 1999-2000 by + * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze + * Copyright 2005, 2006 by + * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * DESCRIPTION: + * + *--------------------------------------------------------------------- + */ + +/* + * + ** gl_clipper.cpp + ** + ** Handles visibility checks. + ** Loosely based on the JDoom clipper. + ** + **--------------------------------------------------------------------------- + ** Copyright 2003 Tim Stump + ** All rights reserved. + ** + ** Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions + ** are met: + ** + ** 1. Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** 2. Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in the + ** documentation and/or other materials provided with the distribution. + ** 3. The name of the author may not be used to endorse or promote products + ** derived from this software without specific prior written permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **--------------------------------------------------------------------------- + ** + */ + +#include +#include "../v_video.h" +#include "hw_clip.h" +#include "hw_glob.h" +#include "../r_state.h" +#include "../tables.h" +#include "r_opengl/r_opengl.h" + +#ifdef HAVE_SPHEREFRUSTRUM +static GLdouble viewMatrix[16]; +static GLdouble projMatrix[16]; +float frustum[6][4]; +#endif + +typedef struct clipnode_s + { + struct clipnode_s *prev, *next; + angle_t start, end; + } clipnode_t; + +clipnode_t *freelist; +clipnode_t *clipnodes; +clipnode_t *cliphead; + +static clipnode_t * HWR_clipnode_GetNew(void); +static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end); +static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle); +static void HWR_clipper_AddClipRange(angle_t start, angle_t end); +static void HWR_clipper_RemoveRange(clipnode_t * range); +static void HWR_clipnode_Free(clipnode_t *node); + +static clipnode_t * HWR_clipnode_GetNew(void) +{ + if (freelist) + { + clipnode_t * p = freelist; + freelist = p->next; + return p; + } + else + { + return (clipnode_t*)malloc(sizeof(clipnode_t)); + } +} + +static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end) +{ + clipnode_t * c = HWR_clipnode_GetNew(); + c->start = start; + c->end = end; + c->next = c->prev=NULL; + return c; +} + +boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle) +{ + if(startAngle > endAngle) + { + return (HWR_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || HWR_clipper_IsRangeVisible(0, endAngle)); + } + + return HWR_clipper_IsRangeVisible(startAngle, endAngle); +} + +static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) +{ + clipnode_t *ci; + ci = cliphead; + + if (endAngle == 0 && ci && ci->start == 0) + return false; + + while (ci != NULL && ci->start < endAngle) + { + if (startAngle >= ci->start && endAngle <= ci->end) + { + return false; + } + ci = ci->next; + } + + return true; +} + +static void HWR_clipnode_Free(clipnode_t *node) +{ + node->next = freelist; + freelist = node; +} + +static void HWR_clipper_RemoveRange(clipnode_t *range) +{ + if (range == cliphead) + { + cliphead = cliphead->next; + } + else + { + if (range->prev) + { + range->prev->next = range->next; + } + if (range->next) + { + range->next->prev = range->prev; + } + } + + HWR_clipnode_Free(range); +} + +void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle) +{ + if(startangle > endangle) + { + // The range has to added in two parts. + HWR_clipper_AddClipRange(startangle, ANGLE_MAX); + HWR_clipper_AddClipRange(0, endangle); + } + else + { + // Add the range as usual. + HWR_clipper_AddClipRange(startangle, endangle); + } +} + +static void HWR_clipper_AddClipRange(angle_t start, angle_t end) +{ + clipnode_t *node, *temp, *prevNode, *node2, *delnode; + + if (cliphead) + { + //check to see if range contains any old ranges + node = cliphead; + while (node != NULL && node->start < end) + { + if (node->start >= start && node->end <= end) + { + temp = node; + node = node->next; + HWR_clipper_RemoveRange(temp); + } + else + { + if (node->start <= start && node->end >= end) + { + return; + } + else + { + node = node->next; + } + } + } + + //check to see if range overlaps a range (or possibly 2) + node = cliphead; + while (node != NULL && node->start <= end) + { + if (node->end >= start) + { + // we found the first overlapping node + if (node->start > start) + { + // the new range overlaps with this node's start point + node->start = start; + } + if (node->end < end) + { + node->end = end; + } + + node2 = node->next; + while (node2 && node2->start <= node->end) + { + if (node2->end > node->end) + { + node->end = node2->end; + } + + delnode = node2; + node2 = node2->next; + HWR_clipper_RemoveRange(delnode); + } + return; + } + node = node->next; + } + + //just add range + node = cliphead; + prevNode = NULL; + temp = HWR_clipnode_NewRange(start, end); + while (node != NULL && node->start < end) + { + prevNode = node; + node = node->next; + } + temp->next = node; + if (node == NULL) + { + temp->prev = prevNode; + if (prevNode) + { + prevNode->next = temp; + } + if (!cliphead) + { + cliphead = temp; + } + } + else + { + if (node == cliphead) + { + cliphead->prev = temp; + cliphead = temp; + } + else + { + temp->prev = prevNode; + prevNode->next = temp; + node->prev = temp; + } + } + } + else + { + temp = HWR_clipnode_NewRange(start, end); + cliphead = temp; + return; + } +} + +void HWR_clipper_Clear(void) +{ + clipnode_t *node = cliphead; + clipnode_t *temp; + + while (node != NULL) + { + temp = node; + node = node->next; + HWR_clipnode_Free(temp); + } + + cliphead = NULL; +} + +#define RMUL (1.6f/1.333333f) + +angle_t HWR_FrustumAngle(void) +{ + double floatangle; + angle_t a1; + + float tilt = (float)fabs(((double)(int)aimingangle) / ANG1); + + // NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function + + float render_fov = FIXED_TO_FLOAT(cv_grfov.value); + float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right? + float render_multiplier = 64.0f / render_fovratio / RMUL; + + if (tilt > 90.0f) + { + tilt = 90.0f; + } + + // If the pitch is larger than this you can look all around at a FOV of 90 + if (abs(aimingangle) > 46 * ANG1) + return 0xffffffff; + + // ok, this is a gross hack that barely works... + // but at least it doesn't overestimate too much... + floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * (float)render_fov * 48.0f / render_multiplier / 90.0f; + a1 = ANG1 * (int)floatangle; + if (a1 >= ANGLE_180) + return 0xffffffff; + return a1; +} + +// SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either +// compiler complains about (p)glGetDoublev anyway, in case anyone wants this +// only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks +// btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h +#ifdef HAVE_SPHEREFRUSTRUM +// +// HWR_FrustrumSetup +// + +#define CALCMATRIX(a, b, c, d, e, f, g, h)\ +(float)(viewMatrix[a] * projMatrix[b] + \ +viewMatrix[c] * projMatrix[d] + \ +viewMatrix[e] * projMatrix[f] + \ +viewMatrix[g] * projMatrix[h]) + +#define NORMALIZE_PLANE(i)\ +t = (float)sqrt(\ +frustum[i][0] * frustum[i][0] + \ +frustum[i][1] * frustum[i][1] + \ +frustum[i][2] * frustum[i][2]); \ +frustum[i][0] /= t; \ +frustum[i][1] /= t; \ +frustum[i][2] /= t; \ +frustum[i][3] /= t + +void HWR_FrustrumSetup(void) +{ + float t; + float clip[16]; + + pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); + pglGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix); + + clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12); + clip[1] = CALCMATRIX(0, 1, 1, 5, 2, 9, 3, 13); + clip[2] = CALCMATRIX(0, 2, 1, 6, 2, 10, 3, 14); + clip[3] = CALCMATRIX(0, 3, 1, 7, 2, 11, 3, 15); + + clip[4] = CALCMATRIX(4, 0, 5, 4, 6, 8, 7, 12); + clip[5] = CALCMATRIX(4, 1, 5, 5, 6, 9, 7, 13); + clip[6] = CALCMATRIX(4, 2, 5, 6, 6, 10, 7, 14); + clip[7] = CALCMATRIX(4, 3, 5, 7, 6, 11, 7, 15); + + clip[8] = CALCMATRIX(8, 0, 9, 4, 10, 8, 11, 12); + clip[9] = CALCMATRIX(8, 1, 9, 5, 10, 9, 11, 13); + clip[10] = CALCMATRIX(8, 2, 9, 6, 10, 10, 11, 14); + clip[11] = CALCMATRIX(8, 3, 9, 7, 10, 11, 11, 15); + + clip[12] = CALCMATRIX(12, 0, 13, 4, 14, 8, 15, 12); + clip[13] = CALCMATRIX(12, 1, 13, 5, 14, 9, 15, 13); + clip[14] = CALCMATRIX(12, 2, 13, 6, 14, 10, 15, 14); + clip[15] = CALCMATRIX(12, 3, 13, 7, 14, 11, 15, 15); + + // Right plane + frustum[0][0] = clip[ 3] - clip[ 0]; + frustum[0][1] = clip[ 7] - clip[ 4]; + frustum[0][2] = clip[11] - clip[ 8]; + frustum[0][3] = clip[15] - clip[12]; + NORMALIZE_PLANE(0); + + // Left plane + frustum[1][0] = clip[ 3] + clip[ 0]; + frustum[1][1] = clip[ 7] + clip[ 4]; + frustum[1][2] = clip[11] + clip[ 8]; + frustum[1][3] = clip[15] + clip[12]; + NORMALIZE_PLANE(1); + + // Bottom plane + frustum[2][0] = clip[ 3] + clip[ 1]; + frustum[2][1] = clip[ 7] + clip[ 5]; + frustum[2][2] = clip[11] + clip[ 9]; + frustum[2][3] = clip[15] + clip[13]; + NORMALIZE_PLANE(2); + + // Top plane + frustum[3][0] = clip[ 3] - clip[ 1]; + frustum[3][1] = clip[ 7] - clip[ 5]; + frustum[3][2] = clip[11] - clip[ 9]; + frustum[3][3] = clip[15] - clip[13]; + NORMALIZE_PLANE(3); + + // Far plane + frustum[4][0] = clip[ 3] - clip[ 2]; + frustum[4][1] = clip[ 7] - clip[ 6]; + frustum[4][2] = clip[11] - clip[10]; + frustum[4][3] = clip[15] - clip[14]; + NORMALIZE_PLANE(4); + + // Near plane + frustum[5][0] = clip[ 3] + clip[ 2]; + frustum[5][1] = clip[ 7] + clip[ 6]; + frustum[5][2] = clip[11] + clip[10]; + frustum[5][3] = clip[15] + clip[14]; + NORMALIZE_PLANE(5); +} + +boolean HWR_SphereInFrustum(float x, float y, float z, float radius) +{ + int p; + + for (p = 0; p < 4; p++) + { + if (frustum[p][0] * x + + frustum[p][1] * y + + frustum[p][2] * z + + frustum[p][3] <= -radius) + { + return false; + } + } + return true; +} +#endif diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h new file mode 100644 index 000000000..c55041b7e --- /dev/null +++ b/src/hardware/hw_clip.h @@ -0,0 +1,24 @@ +/* + * hw_clip.h + * SRB2CB + * + * PrBoom's OpenGL clipping + * + * + */ + +// OpenGL BSP clipping +#include "../doomdef.h" +#include "../tables.h" +#include "../doomtype.h" + +//#define HAVE_SPHEREFRUSTRUM // enable if you want HWR_SphereInFrustum and related code + +boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); +void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); +void HWR_clipper_Clear(void); +angle_t HWR_FrustumAngle(void); +#ifdef HAVE_SPHEREFRUSTRUM +void HWR_FrustrumSetup(void); +boolean HWR_SphereInFrustum(float x, float y, float z, float radius); +#endif From 1e98e3b4f20ae9517a66e79f2a464cbcda9e28b7 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 10 Jan 2017 18:01:03 +0000 Subject: [PATCH 216/264] More progress, NEWCLIP added to doomdef.h, sadly it actually all lags the game so I've disabled it for now Other notes: * on second thought I'll keep the hw_clip functions' gld prefixes rather than HWR, not like it matters either way * despite the extra lag it does fix the issues with translucent walls and such when displayed at different vertical angles, such as with the GFZ1 waterfall --- src/doomdef.h | 7 ++ src/hardware/hw_clip.c | 62 +++++------ src/hardware/hw_clip.h | 14 +-- src/hardware/hw_main.c | 240 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 280 insertions(+), 43 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 7f641558f..e5fa3a482 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -502,4 +502,11 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// \note Required for proper collision with moving sloped surfaces that have sector specials on them. //#define SECTORSPECIALSAFTERTHINK +/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up +/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down) +/// on the bright side it fixes some weird issues with translucent walls +/// \note SRB2CB port. +/// SRB2CB itself ported this from PrBoom+ +//#define NEWCLIP + #endif // __DOOMDEF__ diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c index 47cbbfa2b..8b01cabd5 100644 --- a/src/hardware/hw_clip.c +++ b/src/hardware/hw_clip.c @@ -92,14 +92,14 @@ clipnode_t *freelist; clipnode_t *clipnodes; clipnode_t *cliphead; -static clipnode_t * HWR_clipnode_GetNew(void); -static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end); -static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle); -static void HWR_clipper_AddClipRange(angle_t start, angle_t end); -static void HWR_clipper_RemoveRange(clipnode_t * range); -static void HWR_clipnode_Free(clipnode_t *node); +static clipnode_t * gld_clipnode_GetNew(void); +static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end); +static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle); +static void gld_clipper_AddClipRange(angle_t start, angle_t end); +static void gld_clipper_RemoveRange(clipnode_t * range); +static void gld_clipnode_Free(clipnode_t *node); -static clipnode_t * HWR_clipnode_GetNew(void) +static clipnode_t * gld_clipnode_GetNew(void) { if (freelist) { @@ -113,26 +113,26 @@ static clipnode_t * HWR_clipnode_GetNew(void) } } -static clipnode_t * HWR_clipnode_NewRange(angle_t start, angle_t end) +static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end) { - clipnode_t * c = HWR_clipnode_GetNew(); + clipnode_t * c = gld_clipnode_GetNew(); c->start = start; c->end = end; c->next = c->prev=NULL; return c; } -boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle) +boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle) { if(startAngle > endAngle) { - return (HWR_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || HWR_clipper_IsRangeVisible(0, endAngle)); + return (gld_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || gld_clipper_IsRangeVisible(0, endAngle)); } - return HWR_clipper_IsRangeVisible(startAngle, endAngle); + return gld_clipper_IsRangeVisible(startAngle, endAngle); } -static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) +static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) { clipnode_t *ci; ci = cliphead; @@ -152,13 +152,13 @@ static boolean HWR_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle) return true; } -static void HWR_clipnode_Free(clipnode_t *node) +static void gld_clipnode_Free(clipnode_t *node) { node->next = freelist; freelist = node; } -static void HWR_clipper_RemoveRange(clipnode_t *range) +static void gld_clipper_RemoveRange(clipnode_t *range) { if (range == cliphead) { @@ -176,25 +176,25 @@ static void HWR_clipper_RemoveRange(clipnode_t *range) } } - HWR_clipnode_Free(range); + gld_clipnode_Free(range); } -void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle) +void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle) { if(startangle > endangle) { // The range has to added in two parts. - HWR_clipper_AddClipRange(startangle, ANGLE_MAX); - HWR_clipper_AddClipRange(0, endangle); + gld_clipper_AddClipRange(startangle, ANGLE_MAX); + gld_clipper_AddClipRange(0, endangle); } else { // Add the range as usual. - HWR_clipper_AddClipRange(startangle, endangle); + gld_clipper_AddClipRange(startangle, endangle); } } -static void HWR_clipper_AddClipRange(angle_t start, angle_t end) +static void gld_clipper_AddClipRange(angle_t start, angle_t end) { clipnode_t *node, *temp, *prevNode, *node2, *delnode; @@ -208,7 +208,7 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) { temp = node; node = node->next; - HWR_clipper_RemoveRange(temp); + gld_clipper_RemoveRange(temp); } else { @@ -250,7 +250,7 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) delnode = node2; node2 = node2->next; - HWR_clipper_RemoveRange(delnode); + gld_clipper_RemoveRange(delnode); } return; } @@ -260,7 +260,7 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) //just add range node = cliphead; prevNode = NULL; - temp = HWR_clipnode_NewRange(start, end); + temp = gld_clipnode_NewRange(start, end); while (node != NULL && node->start < end) { prevNode = node; @@ -296,13 +296,13 @@ static void HWR_clipper_AddClipRange(angle_t start, angle_t end) } else { - temp = HWR_clipnode_NewRange(start, end); + temp = gld_clipnode_NewRange(start, end); cliphead = temp; return; } } -void HWR_clipper_Clear(void) +void gld_clipper_Clear(void) { clipnode_t *node = cliphead; clipnode_t *temp; @@ -311,7 +311,7 @@ void HWR_clipper_Clear(void) { temp = node; node = node->next; - HWR_clipnode_Free(temp); + gld_clipnode_Free(temp); } cliphead = NULL; @@ -319,7 +319,7 @@ void HWR_clipper_Clear(void) #define RMUL (1.6f/1.333333f) -angle_t HWR_FrustumAngle(void) +angle_t gld_FrustumAngle(void) { double floatangle; angle_t a1; @@ -356,7 +356,7 @@ angle_t HWR_FrustumAngle(void) // btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h #ifdef HAVE_SPHEREFRUSTRUM // -// HWR_FrustrumSetup +// gld_FrustrumSetup // #define CALCMATRIX(a, b, c, d, e, f, g, h)\ @@ -375,7 +375,7 @@ frustum[i][1] /= t; \ frustum[i][2] /= t; \ frustum[i][3] /= t -void HWR_FrustrumSetup(void) +void gld_FrustrumSetup(void) { float t; float clip[16]; @@ -446,7 +446,7 @@ void HWR_FrustrumSetup(void) NORMALIZE_PLANE(5); } -boolean HWR_SphereInFrustum(float x, float y, float z, float radius) +boolean gld_SphereInFrustum(float x, float y, float z, float radius) { int p; diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h index c55041b7e..3ba26e5e5 100644 --- a/src/hardware/hw_clip.h +++ b/src/hardware/hw_clip.h @@ -12,13 +12,13 @@ #include "../tables.h" #include "../doomtype.h" -//#define HAVE_SPHEREFRUSTRUM // enable if you want HWR_SphereInFrustum and related code +//#define HAVE_SPHEREFRUSTRUM // enable if you want gld_SphereInFrustum and related code -boolean HWR_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); -void HWR_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); -void HWR_clipper_Clear(void); -angle_t HWR_FrustumAngle(void); +boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); +void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); +void gld_clipper_Clear(void); +angle_t gld_FrustumAngle(void); #ifdef HAVE_SPHEREFRUSTRUM -void HWR_FrustrumSetup(void); -boolean HWR_SphereInFrustum(float x, float y, float z, float radius); +void gld_FrustrumSetup(void); +boolean gld_SphereInFrustum(float x, float y, float z, float radius); #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7e8152583..c10f4bf12 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -44,6 +44,10 @@ #endif #include "hw_md2.h" +#ifdef NEWCLIP +#include "hw_clip.h" +#endif + #define R_FAKEFLOORS #define HWPRECIP #define SORTING @@ -99,8 +103,9 @@ CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NU boolean drawsky = true; // needs fix: walls are incorrectly clipped one column less +#ifndef NEWCLIP static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - +#endif //development variables for diverse uses static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1030,6 +1035,7 @@ static void HWR_ProjectWall(wallVert3D * wallVerts, // (in fact a clipping plane that has a constant, so can clip with simple 2d) // with the wall segment // +#ifndef NEWCLIP static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) { float num, den; @@ -1058,6 +1064,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) return num / den; } +#endif // // HWR_SplitWall @@ -1333,7 +1340,11 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b // Anything between means the wall segment has been clipped with solidsegs, // reducing wall overdraw to a minimum // +#ifdef NEWCLIP +static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom +#else static void HWR_StoreWallRange(double startfrac, double endfrac) +#endif { wallVert3D wallVerts[4]; v2d_t vs, ve; // start, end vertices of 2d line (view from above) @@ -1358,8 +1369,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) extracolormap_t *colormap; FSurfaceInfo Surf; +#ifndef NEWCLIP if (startfrac > endfrac) return; +#endif gr_sidedef = gr_curline->sidedef; gr_linedef = gr_curline->linedef; @@ -1408,15 +1421,19 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // x offset the texture fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset; +#ifndef NEWCLIP // clip texture s start/end coords with solidsegs if (startfrac > 0.0f && startfrac < 1.0f) cliplow = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * startfrac); else +#endif cliplow = (float)texturehpeg; +#ifndef NEWCLIP if (endfrac > 0.0f && endfrac < 1.0f) cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * endfrac); else +#endif cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); } @@ -2325,6 +2342,135 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) //Hurdler: end of 3d-floors test } +// From PrBoom: +// +// e6y: Check whether the player can look beyond this line +// +#ifdef NEWCLIP +// Don't modify anything here, just check +// Kalaron: Modified for sloped linedefs +static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) +{ + fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends + fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends + + // GZDoom method of sloped line clipping + +#ifdef ESLOPE + if (afrontsector->f_slope || afrontsector->c_slope || abacksector->f_slope || abacksector->c_slope) + { + fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t + v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x); + v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y); + v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); + v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, v1x, v1y); \ + end2 = P_GetZAt(slope, v2x, v2y); \ + } else \ + end1 = end2 = normalheight; + + SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector->floorheight) + SLOPEPARAMS(afrontsector->c_slope, frontc1, frontc2, afrontsector->ceilingheight) + SLOPEPARAMS( abacksector->f_slope, backf1, backf2, abacksector->floorheight) + SLOPEPARAMS( abacksector->c_slope, backc1, backc2, abacksector->ceilingheight) +#undef SLOPEPARAMS + } + else +#endif + { + frontf1 = frontf2 = afrontsector->floorheight; + frontc1 = frontc2 = afrontsector->ceilingheight; + backf1 = backf2 = abacksector->floorheight; + backc1 = backc2 = abacksector->ceilingheight; + } + + // now check for closed sectors! + if (backc1 <= frontf1 && backc2 <= frontf2) + { + if (!seg->sidedef->toptexture) + return false; + + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + return false; + + return true; + } + + if (backf1 >= frontc1 && backf2 >= frontc2) + { + if (!seg->sidedef->bottomtexture) + return false; + + // properly render skies (consider door "open" if both floors are sky): + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + return false; + + return true; + } + + if (backc1 <= backf1 && backc2 <= backf2) + { + // preserve a kind of transparent door/lift special effect: + if (backc1 < frontc1 || backc2 < frontc2) + { + if (!seg->sidedef->toptexture) + return false; + } + if (backf1 > frontf1 || backf2 > frontf2) + { + if (!seg->sidedef->bottomtexture) + return false; + } + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + return false; + + if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) + return false; + + return true; + } + + + // Reject empty lines used for triggers and special events. + // Identical floor and ceiling on both sides, + // identical light levels on both sides, + // and no middle texture. + if ( +#ifdef POLYOBJECTS + !seg->polyseg && +#endif + gr_backsector->ceilingpic == gr_frontsector->ceilingpic + && gr_backsector->floorpic == gr_frontsector->floorpic +#ifdef ESLOPE + && gr_backsector->f_slope == gr_frontsector->f_slope + && gr_backsector->c_slope == gr_frontsector->c_slope +#endif + && gr_backsector->lightlevel == gr_frontsector->lightlevel + && !gr_curline->sidedef->midtexture + // Check offsets too! + && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs + && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs + && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle + && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs + && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs + && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle + // Consider altered lighting. + && gr_backsector->floorlightsec == gr_frontsector->floorlightsec + && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec + // Consider colormaps + && gr_backsector->extra_colormap == gr_frontsector->extra_colormap + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || gr_frontsector->tag == gr_backsector->tag)) + { + return false; + } + + + return false; +} +#else //Hurdler: just like in r_bsp.c #if 1 #define MAXSEGS MAXVIDWIDTH/2+1 @@ -2610,6 +2756,7 @@ static void HWR_ClearClipSegs(void) gr_solidsegs[1].last = 0x7fffffff; hw_newend = gr_solidsegs+2; } +#endif // NEWCLIP // -----------------+ // HWR_AddLine : Clips the given segment and adds any visible pieces to the line list. @@ -2618,17 +2765,20 @@ static void HWR_ClearClipSegs(void) // -----------------+ static void HWR_AddLine(seg_t * line) { - INT32 x1, x2; angle_t angle1, angle2; +#ifndef NEWCLIP + INT32 x1, x2; angle_t span, tspan; +#endif // SoM: Backsector needs to be run through R_FakeFlat 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; @@ -2641,6 +2791,18 @@ static void HWR_AddLine(seg_t * line) angle1 = R_PointToAngle(v1x, v1y); angle2 = R_PointToAngle(v2x, v2y); +#ifdef NEWCLIP + // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle! + if (angle2 - angle1 < ANGLE_180) + return; + + // PrBoom: use REAL clipping math YAYYYYYYY!!! + + if (!gld_clipper_SafeCheckRange(angle2, angle1)) + { + return; + } +#else // Clip to view edges. span = angle1 - angle2; @@ -2719,8 +2881,35 @@ static void HWR_AddLine(seg_t * line) return; } */ +#endif + gr_backsector = line->backsector; +#ifdef NEWCLIP + if (!line->backsector) + { + gld_clipper_SafeAddClipRange(angle2, angle1); + } + else + { + gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + if (line->frontsector == line->backsector) + { + if (!line->sidedef->midtexture) + { + //e6y: nothing to do here! + //return; + } + } + if (CheckClip(line, gr_frontsector, gr_backsector)) + { + gld_clipper_SafeAddClipRange(angle2, angle1); + } + } + + HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D + return; +#else // Single sided line? if (!gr_backsector) goto clipsolid; @@ -2835,6 +3024,7 @@ clipsolid: if (x1 == x2) goto clippass; HWR_ClipSolidWallSegment(x1, x2-1); +#endif } // HWR_CheckBBox @@ -2846,9 +3036,13 @@ clipsolid: static boolean HWR_CheckBBox(fixed_t *bspcoord) { - INT32 boxpos, sx1, sx2; + INT32 boxpos; fixed_t px1, py1, px2, py2; - angle_t angle1, angle2, span, tspan; + angle_t angle1, angle2; +#ifndef NEWCLIP + INT32 sx1, sx2; + angle_t span, tspan; +#endif // Find the corners of the box // that define the edges from current viewpoint. @@ -2874,6 +3068,11 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) px2 = bspcoord[checkcoord[boxpos][2]]; py2 = bspcoord[checkcoord[boxpos][3]]; +#ifdef NEWCLIP + angle1 = R_PointToAngle(px1, py1); + angle2 = R_PointToAngle(px2, py2); + return gld_clipper_SafeCheckRange(angle2, angle1); +#else // check clip list for an open space angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle; angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle; @@ -2921,6 +3120,7 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) return false; return HWR_ClipToSolidSegs(sx1, sx2 - 1); +#endif } #ifdef POLYOBJECTS @@ -5694,7 +5894,19 @@ if (0) #ifdef SORTING drawcount = 0; #endif +#ifdef NEWCLIP + if (rendermode == render_opengl) + { + angle_t a1 = gld_FrustumAngle(); + gld_clipper_Clear(); + gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); +#ifdef HAVE_SPHEREFRUSTRUM + gld_FrustrumSetup(); +#endif + } +#else HWR_ClearClipSegs(); +#endif //04/01/2000: Hurdler: added for T&L // Actually it only works on Walls and Planes @@ -5704,6 +5916,7 @@ if (0) HWR_RenderBSPNode((INT32)numnodes-1); +#ifndef NEWCLIP // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) viewangle = localaiming; @@ -5730,6 +5943,7 @@ if (0) dup_viewangle += ANGLE_90; } +#endif // Check for new console commands. NetUpdate(); @@ -5901,7 +6115,19 @@ if (0) #ifdef SORTING drawcount = 0; #endif +#ifdef NEWCLIP + if (rendermode == render_opengl) + { + angle_t a1 = gld_FrustumAngle(); + gld_clipper_Clear(); + gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); +#ifdef HAVE_SPHEREFRUSTRUM + gld_FrustrumSetup(); +#endif + } +#else HWR_ClearClipSegs(); +#endif //04/01/2000: Hurdler: added for T&L // Actually it only works on Walls and Planes @@ -5911,6 +6137,7 @@ if (0) HWR_RenderBSPNode((INT32)numnodes-1); +#ifndef NEWCLIP // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) viewangle = localaiming; @@ -5937,6 +6164,7 @@ if (0) dup_viewangle += ANGLE_90; } +#endif // Check for new console commands. NetUpdate(); @@ -6079,7 +6307,9 @@ static inline void HWR_AddEngineCommands(void) { // engine state variables //CV_RegisterVar(&cv_grzbuffer); +#ifndef NEWCLIP CV_RegisterVar(&cv_grclipwalls); +#endif // engine development mode variables // - usage may vary from version to version.. From c4569e61a8feab59eb5635daf536e9605048a176 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 10 Jan 2017 20:07:02 +0000 Subject: [PATCH 217/264] Made some efforts to improve efficiency of new code, hard to tell if I've made it better or worse though honestly R_IsEmptyLine is now a thing too btw --- src/hardware/hw_main.c | 94 +++++++++--------------------------------- src/r_bsp.c | 60 ++++++++++++++------------- src/r_bsp.h | 1 + 3 files changed, 52 insertions(+), 103 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c10f4bf12..c148e7c41 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2347,6 +2347,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // e6y: Check whether the player can look beyond this line // #ifdef NEWCLIP +boolean checkforemptylines = true; // Don't modify anything here, just check // Kalaron: Modified for sloped linedefs static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) @@ -2389,6 +2390,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks // now check for closed sectors! if (backc1 <= frontf1 && backc2 <= frontf2) { + checkforemptylines = false; if (!seg->sidedef->toptexture) return false; @@ -2400,6 +2402,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks if (backf1 >= frontc1 && backf2 >= frontc2) { + checkforemptylines = false; if (!seg->sidedef->bottomtexture) return false; @@ -2412,6 +2415,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks if (backc1 <= backf1 && backc2 <= backf2) { + checkforemptylines = false; // preserve a kind of transparent door/lift special effect: if (backc1 < frontc1 || backc2 < frontc2) { @@ -2432,41 +2436,12 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks return true; } - - // Reject empty lines used for triggers and special events. - // Identical floor and ceiling on both sides, - // identical light levels on both sides, - // and no middle texture. - if ( -#ifdef POLYOBJECTS - !seg->polyseg && -#endif - gr_backsector->ceilingpic == gr_frontsector->ceilingpic - && gr_backsector->floorpic == gr_frontsector->floorpic -#ifdef ESLOPE - && gr_backsector->f_slope == gr_frontsector->f_slope - && gr_backsector->c_slope == gr_frontsector->c_slope -#endif - && gr_backsector->lightlevel == gr_frontsector->lightlevel - && !gr_curline->sidedef->midtexture - // Check offsets too! - && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs - && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs - && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle - && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs - && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs - && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle - // Consider altered lighting. - && gr_backsector->floorlightsec == gr_frontsector->floorlightsec - && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec - // Consider colormaps - && gr_backsector->extra_colormap == gr_frontsector->extra_colormap - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || gr_frontsector->tag == gr_backsector->tag)) - { - return false; - } - + if (backc1 != frontc1 || backc2 != frontc2 + || backf1 != frontf1 || backf2 != frontf2) + { + checkforemptylines = false; + return false; + } return false; } @@ -2802,6 +2777,8 @@ static void HWR_AddLine(seg_t * line) { return; } + + checkforemptylines = true; #else // Clip to view edges. span = angle1 - angle2; @@ -2893,18 +2870,17 @@ static void HWR_AddLine(seg_t * line) else { gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); - if (line->frontsector == line->backsector) - { - if (!line->sidedef->midtexture) - { - //e6y: nothing to do here! - //return; - } - } if (CheckClip(line, gr_frontsector, gr_backsector)) { gld_clipper_SafeAddClipRange(angle2, angle1); + checkforemptylines = false; } + // Reject empty lines used for triggers and special events. + // Identical floor and ceiling on both sides, + // identical light levels on both sides, + // and no middle texture. + if (checkforemptylines && R_IsEmptyLine(line, gr_frontsector, gr_backsector)) + return; } HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D @@ -2981,38 +2957,8 @@ static void HWR_AddLine(seg_t * line) // Identical floor and ceiling on both sides, // identical light levels on both sides, // and no middle texture. - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - gr_backsector->ceilingpic == gr_frontsector->ceilingpic - && gr_backsector->floorpic == gr_frontsector->floorpic -#ifdef ESLOPE - && gr_backsector->f_slope == gr_frontsector->f_slope - && gr_backsector->c_slope == gr_frontsector->c_slope -#endif - && gr_backsector->lightlevel == gr_frontsector->lightlevel - && !gr_curline->sidedef->midtexture - // Check offsets too! - && gr_backsector->floor_xoffs == gr_frontsector->floor_xoffs - && gr_backsector->floor_yoffs == gr_frontsector->floor_yoffs - && gr_backsector->floorpic_angle == gr_frontsector->floorpic_angle - && gr_backsector->ceiling_xoffs == gr_frontsector->ceiling_xoffs - && gr_backsector->ceiling_yoffs == gr_frontsector->ceiling_yoffs - && gr_backsector->ceilingpic_angle == gr_frontsector->ceilingpic_angle - // Consider altered lighting. - && gr_backsector->floorlightsec == gr_frontsector->floorlightsec - && gr_backsector->ceilinglightsec == gr_frontsector->ceilinglightsec - // Consider colormaps - && gr_backsector->extra_colormap == gr_frontsector->extra_colormap - && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) - || gr_frontsector->tag == gr_backsector->tag)) - // SoM: For 3D sides... Boris, would you like to take a - // crack at rendering 3D sides? You would need to add the - // above check and add code to HWR_StoreWallRange... - { + if (R_IsEmptyLine(curline, frontsector, backsector)) return; - } clippass: if (x1 == x2) diff --git a/src/r_bsp.c b/src/r_bsp.c index abb11204a..4ce89f009 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -365,6 +365,36 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, return sec; } +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 +#ifdef ESLOPE + && back->f_slope == front->f_slope + && back->c_slope == front->c_slope +#endif + && back->lightlevel == front->lightlevel + && !line->sidedef->midtexture + // Check offsets too! + && back->floor_xoffs == front->floor_xoffs + && back->floor_yoffs == front->floor_yoffs + && back->floorpic_angle == front->floorpic_angle + && back->ceiling_xoffs == front->ceiling_xoffs + && back->ceiling_yoffs == front->ceiling_yoffs + && back->ceilingpic_angle == front->ceilingpic_angle + // Consider altered lighting. + && back->floorlightsec == front->floorlightsec + && back->ceilinglightsec == front->ceilinglightsec + // Consider colormaps + && back->extra_colormap == front->extra_colormap + && ((!front->ffloors && !back->ffloors) + || front->tag == back->tag)); +} + // // R_AddLine // Clips the given segment and adds any visible pieces to the line list. @@ -526,36 +556,8 @@ static void R_AddLine(seg_t *line) // Identical floor and ceiling on both sides, identical light levels on both sides, // and no middle texture. - if ( -#ifdef POLYOBJECTS - !line->polyseg && -#endif - backsector->ceilingpic == frontsector->ceilingpic - && backsector->floorpic == frontsector->floorpic -#ifdef ESLOPE - && backsector->f_slope == frontsector->f_slope - && backsector->c_slope == frontsector->c_slope -#endif - && backsector->lightlevel == frontsector->lightlevel - && !curline->sidedef->midtexture - // Check offsets too! - && backsector->floor_xoffs == frontsector->floor_xoffs - && backsector->floor_yoffs == frontsector->floor_yoffs - && backsector->floorpic_angle == frontsector->floorpic_angle - && backsector->ceiling_xoffs == frontsector->ceiling_xoffs - && backsector->ceiling_yoffs == frontsector->ceiling_yoffs - && backsector->ceilingpic_angle == frontsector->ceilingpic_angle - // Consider altered lighting. - && backsector->floorlightsec == frontsector->floorlightsec - && backsector->ceilinglightsec == frontsector->ceilinglightsec - // Consider colormaps - && backsector->extra_colormap == frontsector->extra_colormap - && ((!frontsector->ffloors && !backsector->ffloors) - || frontsector->tag == backsector->tag)) - { + if (R_IsEmptyLine(line, frontsector, backsector)) return; - } - clippass: R_ClipPassWallSegment(x1, x2 - 1); diff --git a/src/r_bsp.h b/src/r_bsp.h index e871b5dde..80824831b 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -50,6 +50,7 @@ extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, INT32 *ceilinglightlevel, boolean back); +boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back); INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside); void R_Prep3DFloors(sector_t *sector); From 8ba0f2a177086a26313aac58eb8ff4b2ecc95c09 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 12 Jan 2017 21:44:27 +0000 Subject: [PATCH 218/264] clipping code didn't seem so bad this time (at least compared to without), let's enable it now? --- src/doomdef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index e5fa3a482..ff09144ed 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -507,6 +507,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// on the bright side it fixes some weird issues with translucent walls /// \note SRB2CB port. /// SRB2CB itself ported this from PrBoom+ -//#define NEWCLIP +#define NEWCLIP #endif // __DOOMDEF__ From 3608f73d39a60fe79c368691f8171a20691ea4ce Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 16 Jan 2017 15:48:07 +0000 Subject: [PATCH 219/264] Updated SRB2.cbp for hw_clip.c/h --- SRB2.cbp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/SRB2.cbp b/SRB2.cbp index 74ec96c6e..5aa623fa8 100644 --- a/SRB2.cbp +++ b/SRB2.cbp @@ -1174,6 +1174,39 @@ HW3SOUND for 3D hardware sound support