diff --git a/src/d_main.cpp b/src/d_main.cpp index e6f7fefcb..585c6ddc5 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -655,6 +655,7 @@ static void D_Display(void) I_lock_mutex(&m_menu_mutex); #endif M_Drawer(); // menu is drawn even on top of everything + HU_DrawSongCredits(); // As are music credits. #ifdef HAVE_THREADS I_unlock_mutex(m_menu_mutex); #endif diff --git a/src/deh_soc.c b/src/deh_soc.c index 53367985f..e75221663 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2241,6 +2241,22 @@ void readmenu(MYFILE *f, INT32 num) menudefs[num].musignore = (value || word2[0] == 'T' || word2[0] == 'Y'); titlechanged = true; } + else if (fastcmp(word, "MUSICCREDITSHOW")) + { + menudefs[num].muscreditshow = (value || word2[0] == 'T' || word2[0] == 'Y'); + } + else if (fastcmp(word, "MUSICCREDITYOFFSET")) + { + menudefs[num].muscredity = get_number(word2); + } + else if (fastcmp(word, "MUSICCREDITANIMTIME") || fastcmp(word, "MUSICCREDITANIMATIONTIME")) + { + menudefs[num].muscreditanimtime = (UINT16)get_number(word2); + } + else if (fastcmp(word, "MUSICCREDITSNAPFLAGS")) + { + menudefs[num].muscreditsnapflags = (INT32)get_number(word2); + } else if (fastcmp(word, "FADESTRENGTH")) { // one-based, <= 0 means use default value. 1-32 diff --git a/src/f_finale.c b/src/f_finale.c index 2d3c954db..cd016d64d 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -711,7 +711,7 @@ void F_StartCredits(void) S_StopSounds(); S_ChangeMusicInternal("credit", false); - S_ShowMusicCredit(); + S_ShowMusicCredit(0, 5*TICRATE, 0); finalecount = 0; animtimer = 0; @@ -979,7 +979,7 @@ void F_BlanStartCredits(void) S_StopSounds(); S_ChangeMusicInternal("BLANCD", true); - S_ShowMusicCredit(); + S_ShowMusicCredit(0, 5*TICRATE, 0); finalecount = 0; animtimer = 0; @@ -1699,7 +1699,10 @@ void F_WaitingPlayersTicker(void) // dumb hack, only start the music on the 1st tick so if you instantly go into the map you aren't hearing a tic of music if (finalecount == 2) + { S_ChangeMusicInternal("WAIT2J", true); + S_ShowMusicCredit(0, 5*TICRATE, 0); + } } void F_WaitingPlayersDrawer(void) diff --git a/src/g_game.c b/src/g_game.c index 528f7e746..0b8483cfc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2220,13 +2220,13 @@ void G_Ticker(boolean run) F_TextPromptTicker(); AM_Ticker(); HU_Ticker(); - break; case GS_INTERMISSION: if (run) Y_Ticker(); HU_Ticker(); + break; case GS_VOTING: @@ -2287,6 +2287,7 @@ void G_Ticker(boolean run) case FORCEWIPE: break; // do nothing } + HU_TickSongCredits(); if (run) { @@ -2738,7 +2739,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) P_RestoreMusic(p); if (songcredit) - S_ShowMusicCredit(); + S_ShowMusicCredit(0, 5*TICRATE, 0); if (leveltime > (starttime + (TICRATE/2)) && !p->spectator) p->respawn = 48; // Respawn effect @@ -4260,7 +4261,10 @@ static void G_DoCompleted(void) // play some generic music if there's no win/cool/lose music going on (for exitlevel commands) if ((gametyperules & GTR_CIRCUIT) && ((multiplayer && demo.playback) || j == r_splitscreen+1) && (cv_inttime.value > 0)) + { S_ChangeMusicInternal("racent", true); + S_ShowMusicCredit(-30*FRACUNIT, 5*TICRATE, V_SNAPTOTOP); + } if (automapactive) AM_Stop(); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 7350bc827..80ffaa8c3 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -928,13 +928,11 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) // // -static void HU_TickSongCredits(void) +void HU_TickSongCredits(void) { if (cursongcredit.def == NULL) // No def { - cursongcredit.x = cursongcredit.old_x = 0; - cursongcredit.anim = 0; - cursongcredit.trans = NUMTRANSMAPS; + S_ClearMusicCredit(); return; } @@ -1037,8 +1035,6 @@ void HU_Ticker(void) } resynch_ticker++; - - HU_TickSongCredits(); } static boolean teamtalk = false; @@ -2063,6 +2059,7 @@ void HU_DrawSongCredits(void) { fixed_t x; fixed_t y = (r_splitscreen ? (BASEVIDHEIGHT/2)-4 : 32) * FRACUNIT; + INT32 snapflags = cursongcredit.snapflags; INT32 bgt; if (!cursongcredit.def || cursongcredit.trans >= NUMTRANSMAPS) // No def @@ -2072,16 +2069,17 @@ void HU_DrawSongCredits(void) bgt = (NUMTRANSMAPS/2) + (cursongcredit.trans / 2); x = R_InterpolateFixed(cursongcredit.old_x, cursongcredit.x); + y += cursongcredit.y; if (bgt < NUMTRANSMAPS) { V_DrawFixedPatch(x, y - (2 * FRACUNIT), - FRACUNIT, V_SNAPTOLEFT|(bgt<numlaps; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 67c46b222..9896d9c08 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3112,8 +3112,44 @@ static int lib_sShowMusicCredit(lua_State *L) if (!player) return LUA_ErrInvalid(L, "player_t"); } + fixed_t yoffset = luaL_checkfixed(L, 2); + UINT16 animtime = lua_isnone(L, 3) ? 5*TICRATE : luaL_checkinteger(L, 3); + INT32 snapflags = luaL_checkinteger(L, 4); if (!player || P_IsLocalPlayer(player)) - S_ShowMusicCredit(); + S_ShowMusicCredit(yoffset, animtime, snapflags); + return 0; +} + +static int lib_sChangeMusicCreditSettings(lua_State *L) +{ + player_t *player = NULL; + //HUDSAFE + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + fixed_t yoffset = luaL_checkfixed(L, 2); + INT32 snapflags = luaL_checkinteger(L, 3); + if (!player || P_IsLocalPlayer(player)) + S_ChangeMusicCreditSettings(yoffset, snapflags); + return 0; +} + +static int lib_sClearMusicCredit(lua_State *L) +{ + player_t *player = NULL; + //HUDSAFE + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + + if (!player || P_IsLocalPlayer(player)) + S_ClearMusicCredit(); return 0; } @@ -4974,6 +5010,8 @@ static luaL_Reg lib[] = { {"S_SoundPlaying",lib_sSoundPlaying}, {"S_StartMusicCaption", lib_sStartMusicCaption}, {"S_ShowMusicCredit",lib_sShowMusicCredit}, + {"S_ChangeMusicCreditSettings",lib_sChangeMusicCreditSettings}, + {"S_ClearMusicCredit",lib_sClearMusicCredit}, // g_game {"G_AddGametype", lib_gAddGametype}, diff --git a/src/m_menu.c b/src/m_menu.c index 3648b7e46..18758ed4c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -848,11 +848,15 @@ void M_InitMenuPresTables(void) menudefs[i].bgcolor = -1; menudefs[i].titlescrollxspeed = INT32_MAX; menudefs[i].titlescrollyspeed = INT32_MAX; + menudefs[i].muscredity = 0; + menudefs[i].muscreditanimtime = 2*TICRATE; + menudefs[i].muscreditsnapflags = 0; menudefs[i].bghide = true; // default true menudefs[i].enterbubble = true; menudefs[i].exitbubble = true; menudefs[i].muslooping = true; + menudefs[i].muscreditshow = true; } } @@ -912,15 +916,33 @@ void M_ChangeMenuMusic(void) else if (menudefs[menutype].musstop) { S_StopMusic(); + S_ClearMusicCredit(); return; } else if (menudefs[menutype].musignore) return; } if (target == MN_MAIN && gamestate == GS_TITLESCREEN && finalecount < 50) + { S_StopMusic(); + S_ClearMusicCredit(); + } else - S_ChangeMusic(menudefs[target].musname, menudefs[target].mustrack, menudefs[target].muslooping); + { + if (stricmp(menudefs[target].musname, S_MusicName())) + { + S_ChangeMusic(menudefs[target].musname, menudefs[target].mustrack, menudefs[target].muslooping); + + if (menudefs[target].muscreditshow) + { + S_ShowMusicCredit(menudefs[target].muscredity, menudefs[target].muscreditanimtime, menudefs[target].muscreditsnapflags); + } + } + else + { + S_ChangeMusic(menudefs[target].musname, menudefs[target].mustrack, menudefs[target].muslooping); + } + } } void M_SetMenuCurFadeValue(void) @@ -4213,6 +4235,7 @@ INT32 MR_QuitReplayHut(INT32 choice) demolist = NULL; demo.inreplayhut = false; + S_ClearMusicCredit(); return true; } @@ -5692,6 +5715,7 @@ INT32 MR_QuitTimeAttackMenu(INT32 choice) // you know what? always putting these in the buffer won't hurt anything. COM_BufAddText(va("skin \"%s\"\n", skins[cv_chooseskin.value].name)); + S_ClearMusicCredit(); return true; } diff --git a/src/m_menu.h b/src/m_menu.h index de2477014..6ff014c0b 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -230,6 +230,12 @@ struct menu_t boolean musstop; ///< Don't play any music boolean musignore; ///< Let the current music keep playing + // Music credit shit. + boolean muscreditshow; + fixed_t muscredity; + UINT16 muscreditanimtime; + INT32 muscreditsnapflags; + boolean enterbubble; // run all entrance line execs after common ancestor and up to child. If false, only run the child's exec boolean exitbubble; // run all exit line execs from child and up to before common ancestor. If false, only run the child's exec INT32 entertag; // line exec to run on menu enter, if titlemap diff --git a/src/p_spec.c b/src/p_spec.c index e37a912df..d28fd23ed 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2975,7 +2975,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha !(args[0] & TMM_FADE) ? postfadems : 0); if (!(args[0] & TMM_NOCREDIT)) - S_ShowMusicCredit(); + S_ShowMusicCredit(0, 5*TICRATE, 0); if ((args[0] & TMM_FADE) && fadetarget) { diff --git a/src/p_tick.c b/src/p_tick.c index 76e90552e..67e11ccdd 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -773,7 +773,7 @@ void P_Ticker(boolean run) if (leveltime == 0) { S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); - S_ShowMusicCredit(); + S_ShowMusicCredit(0, 5*TICRATE, 0); } } // Plays the music after the starting countdown. @@ -807,7 +807,7 @@ void P_Ticker(boolean run) else if (leveltime == startingtime + (TICRATE/2)) // Plays the music after the starting countdown. { S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); - S_ShowMusicCredit(); + S_ShowMusicCredit(0, 5*TICRATE, 0); } } } diff --git a/src/s_sound.c b/src/s_sound.c index 20794222e..5c5749f56 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1690,7 +1690,7 @@ void S_InitMusicDefs(void) // // Display current song's credit on screen // -void S_ShowMusicCredit(void) +void S_ShowMusicCredit(fixed_t yoffset, UINT16 animtime, INT32 snapflags) { UINT8 i = 0; musicdef_t *def = S_FindMusicDef(music_name, &i); @@ -1756,7 +1756,7 @@ void S_ShowMusicCredit(void) MUSICCREDITAPPEND(def->author, false); MUSICCREDITAPPEND(def->source, true); -//#undef MUSICCREDITAPPEND +#undef MUSICCREDITAPPEND } if (credittext[0] == '\0') @@ -1765,8 +1765,32 @@ void S_ShowMusicCredit(void) cursongcredit.def = def; Z_Free(cursongcredit.text); cursongcredit.text = Z_StrDup(credittext); - cursongcredit.anim = 5*TICRATE; + cursongcredit.anim = animtime; // 5*TICRATE cursongcredit.x = cursongcredit.old_x = 0; + cursongcredit.y = yoffset; + cursongcredit.snapflags = snapflags; + cursongcredit.trans = NUMTRANSMAPS; +} + +void S_ChangeMusicCreditSettings(INT32 yoffset, INT32 snapflags) +{ + if (cursongcredit.def != NULL) + { + cursongcredit.y = yoffset; + cursongcredit.snapflags = snapflags; + } +} + +// +// S_ClearMusicCredit +// +// Clear the currently displaying song credit on the screen +// +void S_ClearMusicCredit(void) +{ + cursongcredit.x = cursongcredit.old_x = 0; + cursongcredit.y = 0; + cursongcredit.anim = 0; cursongcredit.trans = NUMTRANSMAPS; } diff --git a/src/s_sound.h b/src/s_sound.h index 4c2803670..cd9168c5d 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -199,6 +199,8 @@ extern struct cursongcredit UINT8 trans; fixed_t x; fixed_t old_x; + fixed_t y; + INT32 snapflags; } cursongcredit; extern musicdef_t soundtestsfx; @@ -211,7 +213,9 @@ extern int musicdef_volume; void S_LoadMusicDefs(UINT16 wadnum); void S_InitMusicDefs(void); musicdef_t *S_FindMusicDef(const char *name, UINT8 *i); -void S_ShowMusicCredit(void); +void S_ShowMusicCredit(fixed_t yoffset, UINT16 animtime, INT32 snapflags); +void S_ChangeMusicCreditSettings(INT32 yoffset, INT32 snapflags); +void S_ClearMusicCredit(void); boolean S_PrepareSoundTest(void); // diff --git a/src/y_inter.c b/src/y_inter.c index aa9c8b68d..823530556 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -959,13 +959,18 @@ void Y_StartIntermission(void) if (prevmap >= nummapheaders || !mapheaderinfo[prevmap]) I_Error("Y_StartIntermission: Internal map ID %d not found (nummapheaders = %d)", prevmap, nummapheaders); + S_ShowMusicCredit(-30*FRACUNIT, 5*TICRATE, 0); + switch (intertype) { case int_battle: case int_battletime: { if (cv_inttime.value > 0) + { S_ChangeMusicInternal("racent", true); // loop it + S_ShowMusicCredit(-30*FRACUNIT, 5*TICRATE, 0); + } // Calculate who won if (intertype == int_battle) @@ -1637,7 +1642,10 @@ void Y_VoteTicker(void) D_PickVote(); if (!votetic) + { S_ChangeMusicInternal("vote", true); + S_ShowMusicCredit(0, 5*TICRATE, 0); + } if (timer) timer--; @@ -1693,6 +1701,7 @@ void Y_VoteTicker(void) if (M_RandomChance(FRACUNIT/32)) // Let it cheat occasionally~ voteclient.rendoff++; S_ChangeMusicInternal("voteeb", false); + S_ShowMusicCredit(0, 5*TICRATE, 0); break; } } @@ -2039,6 +2048,7 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) { voteendtic = votetic + (5*TICRATE); S_ChangeMusicInternal("voteeb", false); + S_ShowMusicCredit(0, 5*TICRATE, 0); Y_VoteStops(pick, level); } else if (endtype == 0) // Might as well put this here, too. @@ -2048,7 +2058,10 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) return; } else + { S_ChangeMusicInternal("voteea", true); + S_ShowMusicCredit(0, 5*TICRATE, 0); + } } deferredlevel = level;