From 8a72f42818ad4779bfe29a8b751cb08da7ac6ddb Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 15 Aug 2023 16:40:00 -0700 Subject: [PATCH 1/7] Split G_ExitLevel into G_BeginLevelExit and G_FinishExitLevel - Save retry condition in G_BeginLevelExit - Apply condition in G_FinishExitLevel Preparation for ACS level end scripts, since the exit condition will need be known when the countdown starts, not when it ends (that'd be too late to do anything in the level). --- src/acs/call-funcs.cpp | 1 + src/d_netcmd.c | 2 +- src/doomstat.h | 7 ++ src/g_demo.c | 2 +- src/g_game.c | 168 ++++++++++++++++++++++------------------- src/g_game.h | 3 +- src/k_grandprix.c | 6 ++ src/lua_baselib.c | 3 +- src/p_saveg.c | 8 ++ src/p_setup.c | 3 + src/p_user.c | 13 +--- src/typedef.h | 1 + 12 files changed, 126 insertions(+), 91 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 747d74144..dff63f890 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -1802,6 +1802,7 @@ bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Wor if (argV[1] == 0) skipstats = 1; + G_BeginLevelExit(); exitcountdown = 1; if (server) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f49647810..582f3d98d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5776,7 +5776,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) if (G_GamestateUsesExitLevel() == false) return; - G_ExitLevel(); + G_FinishExitLevel(); } static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) diff --git a/src/doomstat.h b/src/doomstat.h index c4f8b37e7..01c2acfaa 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -762,8 +762,15 @@ extern UINT8 maxXtraLife; // Max extra lives from rings extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations +struct exitcondition_t +{ + boolean losing; + boolean retry; +}; + // For racing extern tic_t racecountdown, exitcountdown, musiccountdown; +extern exitcondition_t g_exit; #define DEFAULT_GRAVITY (4*FRACUNIT/5) extern fixed_t gravity; diff --git a/src/g_demo.c b/src/g_demo.c index 7f58d289e..de15625c0 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -4161,7 +4161,7 @@ boolean G_CheckDemoStatus(void) I_Quit(); if (multiplayer && !demo.title) - G_ExitLevel(); + G_FinishExitLevel(); else { G_StopDemo(); diff --git a/src/g_game.c b/src/g_game.c index 08fc60159..1d4218062 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -274,6 +274,7 @@ mobj_t *hunt2; mobj_t *hunt3; tic_t racecountdown, exitcountdown, musiccountdown; // for racing +exitcondition_t g_exit; fixed_t gravity; fixed_t mapobjectscale; @@ -2927,95 +2928,108 @@ void G_AddPlayer(INT32 playernum) demo_extradata[playernum] |= DXD_JOINDATA|DXD_PLAYSTATE|DXD_COLOR|DXD_NAME|DXD_SKIN|DXD_FOLLOWER; // Set everything } -void G_ExitLevel(void) +void G_BeginLevelExit(void) +{ + g_exit.losing = true; + g_exit.retry = false; + + if (grandprixinfo.gp == true) + { + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + { + K_PlayerFinishGrandPrix(&players[i]); + } + } + } + + if (!G_GametypeUsesLives() || skipstats != 0) + { + g_exit.losing = false; // never force a retry + } + else if (specialstageinfo.valid == true || (gametyperules & GTR_BOSS)) + { + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator && !players[i].bot) + { + if (!K_IsPlayerLosing(&players[i])) + { + g_exit.losing = false; + break; + } + } + } + } + else if (grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_NONE) + { + g_exit.losing = (grandprixinfo.wonround != true); + } + + if (g_exit.losing) + { + // You didn't win... + + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator && !players[i].bot) + { + if (players[i].lives > 0) + { + g_exit.retry = true; + break; + } + } + } + } + + if (g_exit.losing && specialstageinfo.valid) + { + exitcountdown = TICRATE; + } + else + { + exitcountdown = raceexittime+1; + } +} + +void G_FinishExitLevel(void) { G_ResetAllDeviceRumbles(); if (gamestate == GS_LEVEL) { - UINT8 i; - boolean doretry = false; - - if (grandprixinfo.gp == true) + if (g_exit.retry) { - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator) - { - K_PlayerFinishGrandPrix(&players[i]); - } - } - } - - if (!G_GametypeUsesLives() || skipstats != 0) - ; // never force a retry - else if (specialstageinfo.valid == true || (gametyperules & GTR_BOSS)) - { - doretry = true; - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator && !players[i].bot) - { - if (!K_IsPlayerLosing(&players[i])) - { - doretry = false; - break; - } - } - } - } - else if (grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_NONE) - { - doretry = (grandprixinfo.wonround != true); - } - - if (doretry) - { - // You didn't win... - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator && !players[i].bot) - { - if (players[i].lives > 0) - { - break; - } - } - } - - if (i == MAXPLAYERS) - { - // GAME OVER, try again from the start! - if (grandprixinfo.gp == true - && grandprixinfo.eventmode == GPEVENT_SPECIAL) - { - // We were in a Special Stage. - // We can still progress to the podium when we game over here. - doretry = false; - } - else if (netgame) - { - ; // Restart cup here whenever we do Online GP - } - else - { - // Back to the menu with you. - G_HandleSaveLevel(true); - D_QuitNetGame(); - CL_Reset(); - D_ClearState(); - M_StartControlPanel(); - } - } - else + // Restart cup here whenever we do Online GP + if (!netgame) { // We have lives, just redo this one course. G_SetRetryFlag(); + return; } + } + else if (g_exit.losing) + { + // We were in a Special Stage. + // We can still progress to the podium when we game over here. + const boolean special = grandprixinfo.gp == true && grandprixinfo.eventmode == GPEVENT_SPECIAL; - if (doretry == true) + if (!netgame && !special) { + // Back to the menu with you. + G_HandleSaveLevel(true); + D_QuitNetGame(); + CL_Reset(); + D_ClearState(); + M_StartControlPanel(); return; } } diff --git a/src/g_game.h b/src/g_game.h index 72e9ce005..0b922b4da 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -206,7 +206,8 @@ boolean G_GametypeUsesLives(void); boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); INT16 G_SometimesGetDifferentEncore(void); -void G_ExitLevel(void); +void G_BeginLevelExit(void); +void G_FinishExitLevel(void); void G_NextLevel(void); void G_GetNextMap(void); void G_Continue(void); diff --git a/src/k_grandprix.c b/src/k_grandprix.c index dfbb65669..0d4b4b654 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -844,6 +844,12 @@ boolean K_CanChangeRules(boolean allowdemos) --------------------------------------------------*/ void K_PlayerFinishGrandPrix(player_t *player) { + if (grandprixinfo.wonround == true) + { + // This was already completed. + return; + } + if (player->exiting == false) { // You did not finish diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9af9ccd32..bd1771a89 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2869,7 +2869,8 @@ static int lib_gExitLevel(lua_State *L) // Moved this bit to G_SetCustomExitVars if (n >= 1) // Don't run the reset to defaults option lib_gSetCustomExitVars(L); - G_ExitLevel(); + G_BeginLevelExit(); + G_FinishExitLevel(); return 0; } diff --git a/src/p_saveg.c b/src/p_saveg.c index f948c7fa0..aa1f970c5 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -5731,6 +5731,10 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending) WRITEUINT32(save->p, racecountdown); WRITEUINT32(save->p, exitcountdown); + // exitcondition_t + WRITEUINT8(save->p, g_exit.losing); + WRITEUINT8(save->p, g_exit.retry); + WRITEFIXED(save->p, gravity); WRITEFIXED(save->p, mapobjectscale); @@ -5906,6 +5910,10 @@ static boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading) racecountdown = READUINT32(save->p); exitcountdown = READUINT32(save->p); + // exitcondition_t + g_exit.losing = READUINT8(save->p); + g_exit.retry = READUINT8(save->p); + gravity = READFIXED(save->p); mapobjectscale = READFIXED(save->p); diff --git a/src/p_setup.c b/src/p_setup.c index 48caf293a..727fddb7e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7505,6 +7505,9 @@ static void P_InitLevelSettings(void) racecountdown = exitcountdown = musiccountdown = exitfadestarted = 0; curlap = bestlap = 0; // SRB2Kart + g_exit.losing = false; + g_exit.retry = false; + // Gamespeed and frantic items gamespeed = KARTSPEED_EASY; franticitems = false; diff --git a/src/p_user.c b/src/p_user.c index f7a7967b6..4129881c3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1318,19 +1318,12 @@ void P_DoPlayerExit(player_t *player, pflags_t flags) if (P_CheckRacers() && !exitcountdown) { - if (specialout == true) - { - exitcountdown = TICRATE; - } - else - { - exitcountdown = raceexittime+1; - } + G_BeginLevelExit(); } } else if (!exitcountdown) // All other gametypes { - exitcountdown = raceexittime+1; + G_BeginLevelExit(); } if (grandprixinfo.gp == true && player->bot == false && losing == false) @@ -3777,7 +3770,7 @@ void P_DoTimeOver(player_t *player) if (!exitcountdown) { - exitcountdown = raceexittime; + G_BeginLevelExit(); } } diff --git a/src/typedef.h b/src/typedef.h index 7bbc232b6..ee15f0ab4 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -134,6 +134,7 @@ TYPEDEF (unloaded_mapheader_t); TYPEDEF (tolinfo_t); TYPEDEF (cupheader_t); TYPEDEF (unloaded_cupheader_t); +TYPEDEF (exitcondition_t); // font.h TYPEDEF (font_t); From 9b4367773cdb4f5fa0ad5ee56a95e8cf2c5da25c Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 15 Aug 2023 17:00:03 -0700 Subject: [PATCH 2/7] Add GAMEOVER ACS script type Triggered when the level ends with a losing condition and there are no extra lives. --- src/acs/interface.cpp | 16 ++++++++++++++++ src/acs/interface.h | 11 +++++++++++ src/acs/thread.hpp | 1 + src/g_game.c | 8 ++++++++ 4 files changed, 36 insertions(+) diff --git a/src/acs/interface.cpp b/src/acs/interface.cpp index bba86c3b9..4c14a8e2e 100644 --- a/src/acs/interface.cpp +++ b/src/acs/interface.cpp @@ -315,6 +315,22 @@ void ACS_RunEmeraldScript(mobj_t *mo) map->scriptStartType(ACS_ST_EMERALD, scriptInfo); } +/*-------------------------------------------------- + void ACS_RunGameOverScript(void) + + See header file for description. +--------------------------------------------------*/ +void ACS_RunGameOverScript(void) +{ + Environment *env = &ACSEnv; + + ACSVM::GlobalScope *const global = env->getGlobalScope(0); + ACSVM::HubScope *const hub = global->getHubScope(0); + ACSVM::MapScope *const map = hub->getMapScope(0); + + map->scriptStartType(ACS_ST_GAMEOVER, {}); +} + /*-------------------------------------------------- void ACS_Tick(void) diff --git a/src/acs/interface.h b/src/acs/interface.h index 206414663..5e9c9ba9f 100644 --- a/src/acs/interface.h +++ b/src/acs/interface.h @@ -179,6 +179,17 @@ void ACS_RunCatcherScript(mobj_t *mo); void ACS_RunEmeraldScript(mobj_t *mo); +/*-------------------------------------------------- + void ACS_RunGameOverScript(void); + + Runs the map's special scripts for exiting + the level, due to a losing condition and + without any extra lives to retry. +--------------------------------------------------*/ + +void ACS_RunGameOverScript(void); + + /*-------------------------------------------------- void ACS_Tick(void); diff --git a/src/acs/thread.hpp b/src/acs/thread.hpp index 3c146ddf6..561945cf0 100644 --- a/src/acs/thread.hpp +++ b/src/acs/thread.hpp @@ -42,6 +42,7 @@ enum acs_scriptType_e ACS_ST_OVERTIME = 7, // OVERTIME: Runs when Overtime starts in timed game modes. ACS_ST_UFO = 8, // UFO: Runs when the UFO Catcher is destroyed in a Special Stage. ACS_ST_EMERALD = 9, // EMERALD: Runs when the Chaos Emerald is collected in a Special Stage. + ACS_ST_GAMEOVER = 10, // GAMEOVER: Runs when the level ends due to a losing condition and no player has an extra life. }; // diff --git a/src/g_game.c b/src/g_game.c index 1d4218062..a248e4907 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2998,6 +2998,14 @@ void G_BeginLevelExit(void) { exitcountdown = raceexittime+1; } + + if (g_exit.losing) + { + if (!g_exit.retry) + { + ACS_RunGameOverScript(); + } + } } void G_FinishExitLevel(void) From 1a3ef843a586154d72951c1d1f8481499aa7a0b9 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 15 Aug 2023 17:46:44 -0700 Subject: [PATCH 3/7] acs/call-funcs.cpp: add StopLevelExit function --- src/acs/call-funcs.cpp | 14 ++++++++++++++ src/acs/call-funcs.hpp | 1 + src/acs/environment.cpp | 1 + 3 files changed, 16 insertions(+) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index dff63f890..88424cf2d 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -1857,6 +1857,20 @@ bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word return false; } +/*-------------------------------------------------- + bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Halts the level exit if it's happening. +--------------------------------------------------*/ +bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + (void)argV; + (void)argC; + + exitcountdown = 0; + return false; +} + /*-------------------------------------------------- bool CallFunc_Get/SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) diff --git a/src/acs/call-funcs.hpp b/src/acs/call-funcs.hpp index bb9aa23b5..9c75cbed0 100644 --- a/src/acs/call-funcs.hpp +++ b/src/acs/call-funcs.hpp @@ -87,6 +87,7 @@ bool CallFunc_SetLineRenderStyle(ACSVM::Thread *thread, const ACSVM::Word *argV, bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_GetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index 78ffa2256..87ff3cdaf 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -171,6 +171,7 @@ Environment::Environment() addFuncDataACS0( 503, addCallFunc(CallFunc_SetLineRenderStyle)); addFuncDataACS0( 504, addCallFunc(CallFunc_MapWarp)); addFuncDataACS0( 505, addCallFunc(CallFunc_AddBot)); + addFuncDataACS0( 506, addCallFunc(CallFunc_StopLevelExit)); } ACSVM::Thread *Environment::allocThread() From 2ffc41b52e52b1e0a4733ec5b05e78d4c4b405f2 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 15 Aug 2023 17:50:20 -0700 Subject: [PATCH 4/7] G_MapNumber: let parse NEXTMAP --- src/g_game.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index a248e4907..569bae9a4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -806,9 +806,7 @@ const char *G_BuildMapName(INT32 map) */ INT32 G_MapNumber(const char * name) { -#ifdef NEXTMAPINSOC if (strncasecmp("NEXTMAP_", name, 8) != 0) -#endif { INT32 map; UINT32 hash = quickncasehash(name, MAXMAPLUMPNAME); @@ -827,7 +825,6 @@ INT32 G_MapNumber(const char * name) return NEXTMAP_INVALID; } -#ifdef NEXTMAPINSOC name += 8; if (strcasecmp("EVALUATION", name) == 0) @@ -836,9 +833,10 @@ INT32 G_MapNumber(const char * name) return NEXTMAP_CREDITS; if (strcasecmp("CEREMONY", name) == 0) return NEXTMAP_CEREMONY; - //if (strcasecmp("TITLE", name) == 0) + if (strcasecmp("TITLE", name) == 0) return NEXTMAP_TITLE; -#endif + + return NEXTMAP_INVALID; } /** Clips the console player's mouse aiming to the current view. From 0b9d691ad61a35d33bdb201f9ec56fe37547486d Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 20 Aug 2023 00:56:05 -0700 Subject: [PATCH 5/7] acs/call-funcs.cpp: add ExitLevel function --- src/acs/call-funcs.cpp | 30 ++++++++++++++++++++++++++++++ src/acs/call-funcs.hpp | 1 + src/acs/environment.cpp | 1 + 3 files changed, 32 insertions(+) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 88424cf2d..4103be255 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -1871,6 +1871,36 @@ bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSV return false; } +/*-------------------------------------------------- + bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Exits the level. +--------------------------------------------------*/ +bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + (void)argV; + (void)argC; + + if (exitcountdown == 1) + { + // An exit is already in progress. + return false; + } + + if (argC >= 1) + { + skipstats = (argV[0] == 0); + } + + G_BeginLevelExit(); + exitcountdown = 1; + + if (server) + SendNetXCmd(XD_EXITLEVEL, NULL, 0); + + return false; +} + /*-------------------------------------------------- bool CallFunc_Get/SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) diff --git a/src/acs/call-funcs.hpp b/src/acs/call-funcs.hpp index 9c75cbed0..864c0b2c8 100644 --- a/src/acs/call-funcs.hpp +++ b/src/acs/call-funcs.hpp @@ -88,6 +88,7 @@ bool CallFunc_SetLineRenderStyle(ACSVM::Thread *thread, const ACSVM::Word *argV, bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_GetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index 87ff3cdaf..1a43f1a2b 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -172,6 +172,7 @@ Environment::Environment() addFuncDataACS0( 504, addCallFunc(CallFunc_MapWarp)); addFuncDataACS0( 505, addCallFunc(CallFunc_AddBot)); addFuncDataACS0( 506, addCallFunc(CallFunc_StopLevelExit)); + addFuncDataACS0( 507, addCallFunc(CallFunc_ExitLevel)); } ACSVM::Thread *Environment::allocThread() From 5f9f573f20671dbf10b12ce4936852e0882d2e37 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Aug 2023 00:44:27 -0700 Subject: [PATCH 6/7] Remove all code related to linedef 413, Change music --- src/p_setup.c | 62 -------------------------------------- src/p_spec.c | 82 --------------------------------------------------- 2 files changed, 144 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 727fddb7e..048f0a54e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1203,46 +1203,6 @@ static void P_LoadSidedefs(UINT8 *data) sd->toptexture = sd->midtexture = sd->bottomtexture = 0; break; - case 413: // Change music - { - if (!isfrontside) - break; - - char process[8+1]; - - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') - { - M_Memcpy(process,msd->bottomtexture,8); - process[8] = '\0'; - sd->bottomtexture = get_number(process); - } - - if (!(msd->midtexture[0] == '-' && msd->midtexture[1] == '\0') || msd->midtexture[1] != '\0') - { - M_Memcpy(process,msd->midtexture,8); - process[8] = '\0'; - sd->midtexture = get_number(process); - } - - if (msd->toptexture[0] != '-' && msd->toptexture[1] != '\0') - { - sd->line->stringargs[0] = Z_Malloc(7, PU_LEVEL, NULL); - M_Memcpy(process,msd->toptexture,8); - process[8] = '\0'; - - // If they type in O_ or D_ and their music name, just shrug, - // then copy the rest instead. - if ((process[0] == 'O' || process[0] == 'D') && process[7]) - M_Memcpy(sd->line->stringargs[0], process+2, 6); - else // Assume it's a proper music name. - M_Memcpy(sd->line->stringargs[0], process, 6); - sd->line->stringargs[0][6] = '\0'; - } - - break; - } - case 414: // Play SFX { sd->toptexture = sd->midtexture = sd->bottomtexture = 0; @@ -5569,28 +5529,6 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; lines[i].args[4] = lines[i].frontsector->ceilingheight >> FRACBITS; break; - case 413: //Change music - if (lines[i].flags & ML_NOCLIMB) - lines[i].args[1] |= TMM_ALLPLAYERS; - if (lines[i].flags & ML_SKEWTD) - lines[i].args[1] |= TMM_OFFSET; - if (lines[i].flags & ML_NOSKEW) - lines[i].args[1] |= TMM_FADE; - if (lines[i].flags & ML_BLOCKPLAYERS) - lines[i].args[1] |= TMM_NORELOAD; - if (lines[i].flags & ML_NOTBOUNCY) - lines[i].args[1] |= TMM_FORCERESET; - if (lines[i].flags & ML_MIDSOLID) - lines[i].args[1] |= TMM_NOLOOP; - if (lines[i].flags & ML_MIDPEG) - lines[i].args[1] |= TMM_NOCREDIT; - lines[i].args[2] = sides[lines[i].sidenum[0]].midtexture; - lines[i].args[3] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; - lines[i].args[4] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; - lines[i].args[5] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0; - lines[i].args[6] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : -1; - lines[i].args[7] = sides[lines[i].sidenum[0]].bottomtexture; - break; case 414: //Play sound effect lines[i].args[3] = tag; if (tag != 0) diff --git a/src/p_spec.c b/src/p_spec.c index 0d08cdcc0..5bb9131cb 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2886,88 +2886,6 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha } break; - case 413: // Change music - // FIXME: port to new music system -#if 0 - // console player only unless TMM_ALLPLAYERS is set - if ((args[1] & TMM_ALLPLAYERS) || (mo && mo->player && P_IsLocalPlayer(mo->player)) || titlemapinaction) - { - boolean musicsame = (!stringargs[0] || !stringargs[0][0] || !strnicmp(stringargs[0], S_MusicName(), 7)); - UINT16 tracknum = (UINT16)max(args[7], 0); - INT32 position = (INT32)max(args[2], 0); - UINT32 prefadems = (UINT32)max(args[3], 0); - UINT32 postfadems = (UINT32)max(args[4], 0); - UINT8 fadetarget = (UINT8)max(args[5], 0); - INT16 fadesource = (INT16)max(args[6], -1); - - // Seek offset from current song position - if (args[1] & TMM_OFFSET) - { - // adjust for loop point if subtracting - if (position < 0 && S_GetMusicLength() && - S_GetMusicPosition() > S_GetMusicLoopPoint() && - S_GetMusicPosition() + position < S_GetMusicLoopPoint()) - position = max(S_GetMusicLength() - (S_GetMusicLoopPoint() - (S_GetMusicPosition() + position)), 0); - else - position = max(S_GetMusicPosition() + position, 0); - } - - // Fade current music to target volume (if music won't be changed) - if ((args[1] & TMM_FADE) && fadetarget && musicsame) - { - // 0 fadesource means fade from current volume. - // meaning that we can't specify volume 0 as the source volume -- this starts at 1. - if (!fadesource) - fadesource = -1; - - if (!postfadems) - S_SetInternalMusicVolume(fadetarget); - else - S_FadeMusicFromVolume(fadetarget, fadesource, postfadems); - - if (position) - S_SetMusicPosition(position); - } - // Change the music and apply position/fade operations - else - { - if (!stringargs[0]) - break; - - strncpy(mapmusname, stringargs[0], 7); - mapmusname[6] = 0; - - mapmusflags = tracknum & MUSIC_TRACKMASK; - if (!(args[1] & TMM_NORELOAD)) - mapmusflags |= MUSIC_RELOADRESET; - if (args[1] & TMM_FORCERESET) - mapmusflags |= MUSIC_FORCERESET; - - mapmusposition = position; - mapmusresume = 0; - - S_ChangeMusicEx(mapmusname, mapmusflags, !(args[1] & TMM_NOLOOP), position, - !(args[1] & TMM_FADE) ? prefadems : 0, - !(args[1] & TMM_FADE) ? postfadems : 0); - - if (!(args[1] & TMM_NOCREDIT)) - S_ShowMusicCredit(); - - if ((args[1] & TMM_FADE) && fadetarget) - { - if (!postfadems) - S_SetInternalMusicVolume(fadetarget); - else - S_FadeMusicFromVolume(fadetarget, fadesource, postfadems); - } - } - - // Except, you can use the TMM_NORELOAD flag to change this behavior. - // if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn. - } -#endif - break; - case 414: // Play SFX P_PlaySFX(stringargs[0] ? get_number(stringargs[0]) : sfx_None, mo, callsec, args[3], args[1], args[2]); break; From f234c47d8a8877292cfcaf413797179f6d576506 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Aug 2023 01:04:19 -0700 Subject: [PATCH 7/7] ACS: add Music_Play, Music_StopAll and Music_Remap --- src/acs/call-funcs.cpp | 42 +++++++++++++++++++++++++++++++++++++++++ src/acs/call-funcs.hpp | 3 +++ src/acs/environment.cpp | 3 +++ 3 files changed, 48 insertions(+) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 4103be255..b122c9943 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -43,6 +43,7 @@ #include "../k_podium.h" #include "../k_bot.h" #include "../z_zone.h" +#include "../music.h" #include "call-funcs.hpp" @@ -1901,6 +1902,47 @@ bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::W return false; } +/*-------------------------------------------------- + bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Play a tune. If it's already playing, restart from the + beginning. +--------------------------------------------------*/ +bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + ACSVM::MapScope *map = thread->scopeMap; + + Music_Play(map->getString(argV[0])->str); + + return false; +} + +/*-------------------------------------------------- + bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Stop every tune that is currently playing. +--------------------------------------------------*/ +bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + Music_StopAll(); + + return false; +} + +/*-------------------------------------------------- + bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) + + Change the actual song lump that a tune will play. +--------------------------------------------------*/ +bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) +{ + ACSVM::MapScope *map = thread->scopeMap; + + Music_Remap(map->getString(argV[0])->str, map->getString(argV[1])->str); + + return false; +} + /*-------------------------------------------------- bool CallFunc_Get/SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) diff --git a/src/acs/call-funcs.hpp b/src/acs/call-funcs.hpp index 864c0b2c8..b67302f47 100644 --- a/src/acs/call-funcs.hpp +++ b/src/acs/call-funcs.hpp @@ -89,6 +89,9 @@ bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Wor bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_StopLevelExit(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_ExitLevel(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); +bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_GetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); bool CallFunc_SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC); diff --git a/src/acs/environment.cpp b/src/acs/environment.cpp index 1a43f1a2b..bfa296485 100644 --- a/src/acs/environment.cpp +++ b/src/acs/environment.cpp @@ -173,6 +173,9 @@ Environment::Environment() addFuncDataACS0( 505, addCallFunc(CallFunc_AddBot)); addFuncDataACS0( 506, addCallFunc(CallFunc_StopLevelExit)); addFuncDataACS0( 507, addCallFunc(CallFunc_ExitLevel)); + addFuncDataACS0( 508, addCallFunc(CallFunc_MusicPlay)); + addFuncDataACS0( 509, addCallFunc(CallFunc_MusicStopAll)); + addFuncDataACS0( 510, addCallFunc(CallFunc_MusicRemap)); } ACSVM::Thread *Environment::allocThread()