From 1f6e8f25cdb1886b1812cbbb3dbac8dd311304dc Mon Sep 17 00:00:00 2001 From: NepDisk Date: Wed, 12 Mar 2025 12:36:07 -0400 Subject: [PATCH] Music Test port from Saturn pt1 Mostly ported over but its kind of broken for whatever reason... --- src/f_finale.c | 2 +- src/m_menu.c | 358 ++++++++++++++++++++++++++++++++++++++++++++++++- src/s_sound.c | 60 ++++++++- src/s_sound.h | 6 + 4 files changed, 417 insertions(+), 9 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 8fabfe37a..b5617107d 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -956,7 +956,7 @@ void F_BlanStartCredits(void) S_StopMusic(); S_StopSounds(); - S_ChangeMusicInternal("KMAP04", true); + S_ChangeMusicInternal("BLANCD", true); S_ShowMusicCredit(); finalecount = 0; diff --git a/src/m_menu.c b/src/m_menu.c index bb2bcec29..01c069e36 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -226,6 +226,7 @@ static void M_DestroyRobots(INT32 choice); //static void M_LevelSelectWarp(INT32 choice); static void M_Credits(INT32 choice); static void M_BlanCredits(INT32 choice); +static void M_MusicTest(INT32 choice); static void M_PandorasBox(INT32 choice); static void M_EmblemHints(INT32 choice); static char *M_GetConditionString(condition_t cond); @@ -365,6 +366,7 @@ static void M_DrawCenteredMenu(void); static void M_DrawAddons(void); static void M_DrawSkyRoom(void); static void M_DrawChecklist(void); +static void M_DrawMusicTest(void); static void M_DrawEmblemHints(void); static void M_DrawPauseMenu(void); static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade); @@ -391,6 +393,7 @@ static boolean M_ExitPandorasBox(void); static boolean M_QuitMultiPlayerMenu(void); static void M_HandleAddons(INT32 choice); static void M_HandleSoundTest(INT32 choice); +static void M_HandleMusicTest(INT32 choice); static void M_HandleImageDef(INT32 choice); //static void M_HandleLoadSave(INT32 choice); static void M_HandleLevelStats(INT32 choice); @@ -819,6 +822,10 @@ static menuitem_t SR_UnlockChecklistMenu[] = {IT_SUBMENU | IT_STRING, NULL, "NEXT", {.submenu = &MainDef}, 192}, }; +static menuitem_t SR_MusicTestMenu[] = +{ + {IT_KEYHANDLER | IT_STRING, NULL, "", {.routine = M_HandleMusicTest}, 0}, +}; static menuitem_t SR_EmblemHintMenu[] = { {IT_STRING|IT_CVAR, NULL, "Medal Radar", {.cvar = &cv_itemfinder}, 10}, @@ -1389,9 +1396,10 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Powerup Warning", {.cvar = &cv_kartinvinsfx}, 95}, {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", {.routine = M_HandleSoundTest}, 110}, + {IT_STRING|IT_CALL, NULL, "Music Test", {.routine = M_MusicTest}, 120}, - {IT_STRING|IT_CVAR, NULL, "Play Music While Unfocused", {.cvar = &cv_playmusicifunfocused}, 125}, - {IT_STRING|IT_CVAR, NULL, "Play SFX While Unfocused", {.cvar = &cv_playsoundifunfocused}, 135}, + {IT_STRING|IT_CVAR, NULL, "Play Music While Unfocused", {.cvar = &cv_playmusicifunfocused}, 135}, + {IT_STRING|IT_CVAR, NULL, "Play SFX While Unfocused", {.cvar = &cv_playsoundifunfocused}, 145}, }; static menuitem_t OP_DataOptionsMenu[] = @@ -1872,6 +1880,20 @@ menu_t SR_UnlockChecklistDef = 0, NULL }; + +menu_t SR_MusicTestDef = +{ + MN_NONE, + NULL, + sizeof (SR_MusicTestMenu)/sizeof (menuitem_t), + &OP_SoundOptionsDef, + SR_MusicTestMenu, + M_DrawMusicTest, + 60, 150, + 0, + NULL +}; + menu_t SR_EmblemHintDef = { MN_NONE, @@ -6809,6 +6831,338 @@ static void M_HandleSoundTest(INT32 choice) } } +static musicdef_t *curplaying = NULL; +static INT32 st_sel = 0; +static tic_t st_time = 0; +static size_t st_namescroll = 0; +static size_t st_namescrollstate = 0; +//static patch_t* st_radio[9]; +//static patch_t* st_launchpad[4]; + +static void M_MusicTest(INT32 choice) +{ + //INT32 ul = skyRoomMenuTranslations[choice-1]; + //UINT8 i; + //char buf[8]; + (void)choice; + + if (!S_PrepareSoundTest()) + { + M_StartMessage(M_GetText("No selectable tracks found.\n"),NULL,MM_NOTHING); + return; + } + + curplaying = NULL; + st_time = 0; + + st_sel = 0; + + M_SetupNextMenu(&SR_MusicTestDef); +} + +static void M_DrawMusicTest(void) +{ + INT32 x, y, i; + + // let's handle the ticker first. ideally we'd tick this somewhere else, BUT... + if (curplaying) + { + { + fixed_t work; + + work = st_time; + + if (st_time >= (FRACUNIT << (FRACBITS - 2))) // prevent overflow jump - takes about 15 minutes of loop on the same song to reach + st_time = work; + + st_time += renderdeltatics; + } + } + + x = 90<title && curplaying->title[0]) + titl = va("%s - ", curplaying->title); + else if (curplaying->title && curplaying->source[0]) + titl = va("%s - ", curplaying->source); + else + titl = va("%s - ", "What did you do......."); + } + else + titl = "NONE - "; + + i = V_LevelNameWidth(titl); + + st_scroll += renderdeltatics; + + while (st_scroll >= (i << FRACBITS)) + st_scroll -= i << FRACBITS; + + x -= st_scroll >> FRACBITS; + + while (x < BASEVIDWIDTH-y) + x += i; + while (x > y) + { + x -= i; + V_DrawLevelTitle(x, 24, 0, titl); + } + + if (curplaying && curplaying->author && curplaying->composers && curplaying->composers[0] && curplaying->author[0]) + V_DrawRightAlignedThinString(BASEVIDWIDTH-16, 46, V_ALLOWLOWERCASE, va ("%s, %s",curplaying->author, curplaying->composers)); + else if (curplaying && curplaying->author && curplaying->author[0]) + V_DrawRightAlignedThinString(BASEVIDWIDTH-16, 46, V_ALLOWLOWERCASE, curplaying->author); + + if (curplaying) + { + if (!curplaying->usage && !curplaying->usage[0]) + V_DrawString(vid.dupx, vid.height - 10*vid.dupy, V_NOSCALESTART|V_ALLOWLOWERCASE, va("%.6s", &curplaying->name[0][0])); + else { + V_DrawSmallString(vid.dupx, vid.height - 5*vid.dupy, V_NOSCALESTART|V_ALLOWLOWERCASE, va("%.6s - %.255s\n", &curplaying->name[0][0], curplaying->usage)); + } + } + } + + V_DrawFill(20, 60, 280, 128, 159); + + { + INT32 t, b, q, m = 128; + + if (numsoundtestdefs <= 8) + { + t = 0; + b = numsoundtestdefs - 1; + i = 0; + } + else + { + q = m; + m = (5*m)/numsoundtestdefs; + if (st_sel < 3) + { + t = 0; + b = 7; + i = 0; + } + else if (st_sel >= numsoundtestdefs-4) + { + t = numsoundtestdefs - 8; + b = numsoundtestdefs - 1; + i = q-m; + } + else + { + t = st_sel - 3; + b = st_sel + 4; + i = (t * (q-m))/(numsoundtestdefs - 8); + } + } + + V_DrawFill(20+280-1, 60 + i, 1, m, 0); + + if (t != 0) + V_DrawString(20+280+4, 60+4 - (skullAnimCounter/5), V_YELLOWMAP, "\x1A"); + + if (b != numsoundtestdefs - 1) + V_DrawString(20+280+4, 60+128-12 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); + + x = 24; + y = 64; + + if (renderisnewtic) ++st_namescroll; + + while (t <= b) + { + if (t == st_sel) + V_DrawFill(20, y-4, 280-1, 16, 157); + + { + const size_t MAXLENGTH = 34; + const tic_t SCROLLSPEED = TICRATE/5; // Number of tics for name being scrolled by 1 letter + size_t nameoffset = 0; + size_t namelength = soundtestdefs[t]->source ? strlen(soundtestdefs[t]->source) : 0; + if (soundtestdefs[t]->title && (soundtestdefs[t]->title[0])) + namelength = strlen(soundtestdefs[t]->title); + + char buf[MAXLENGTH+1]; + + if (t == st_sel && namelength > MAXLENGTH) + { + switch (st_namescrollstate) + { + case 0: + { + // Scroll forward + nameoffset = (st_namescroll/SCROLLSPEED) % (namelength - MAXLENGTH + 1); + + if (nameoffset == namelength - MAXLENGTH) + { + st_namescroll = 0; + st_namescrollstate++; + } + } + break; + + case 1: + { + nameoffset = namelength - MAXLENGTH; + + // Show name end for 1 second, then start scrolling back + if (st_namescroll == TICRATE) + { + st_namescroll = 0; + st_namescrollstate++; + } + } + break; + + case 2: + { + // Scroll back + nameoffset = (namelength - MAXLENGTH - 1) - (st_namescroll/SCROLLSPEED) % (namelength - MAXLENGTH); + + if (nameoffset == 0) + { + st_namescroll = 0; + st_namescrollstate++; + } + } + break; + + case 3: + { + nameoffset = 0; + + // Show name beginning for 1 second, then start scrolling forward again + if (st_namescroll == TICRATE) + { + st_namescroll = 0; + st_namescrollstate = 0; + } + } + break; + } + } + + if (soundtestdefs[t]->title && soundtestdefs[t]->title[0]) + strncpy(buf, soundtestdefs[t]->title + nameoffset, MAXLENGTH); + else if (soundtestdefs[t]->source && soundtestdefs[t]->source[0]) + strncpy(buf, soundtestdefs[t]->source + nameoffset, MAXLENGTH); + else + strncpy(buf, "How tf did you get here?", MAXLENGTH); + buf[MAXLENGTH] = 0; + + V_DrawString(x, y, (t == st_sel ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE|V_MONOSPACE, buf); + if (curplaying == soundtestdefs[t]) + { + V_DrawFill(20+280-9, y-4, 8, 16, 150); + } + } + t++; + y += 16; + } + } +} + +static void M_HandleMusicTest(INT32 choice) +{ + boolean exitmenu = false; // exit to previous menu + + switch (choice) + { + case KEY_DOWNARROW: + if (st_sel++ >= numsoundtestdefs-1) + st_sel = 0; + { + S_StartSound(NULL, sfx_menu1); + } + st_namescroll = 0; + st_namescrollstate = 0; + break; + case KEY_UPARROW: + if (!st_sel--) + st_sel = numsoundtestdefs-1; + { + S_StartSound(NULL, sfx_menu1); + } + st_namescroll = 0; + st_namescrollstate = 0; + break; + case KEY_PGDN: + if (st_sel < numsoundtestdefs-1) + { + st_sel += 3; + if (st_sel >= numsoundtestdefs-1) + st_sel = numsoundtestdefs-1; + S_StartSound(NULL, sfx_menu1); + } + st_namescroll = 0; + st_namescrollstate = 0; + break; + case KEY_PGUP: + if (st_sel) + { + st_sel -= 3; + if (st_sel < 0) + st_sel = 0; + S_StartSound(NULL, sfx_menu1); + } + st_namescroll = 0; + st_namescrollstate = 0; + break; + case KEY_BACKSPACE: + if (curplaying) + { + S_StopSounds(); + S_StopMusic(); + curplaying = NULL; + st_time = 0; + S_StartSound(NULL, sfx_skid); + } + break; + case KEY_ESCAPE: + exitmenu = true; + st_namescroll = 0; + st_namescrollstate = 0; + break; + + case KEY_RIGHTARROW: + case KEY_LEFTARROW: + case KEY_ENTER: + S_StopSounds(); + S_StopMusic(); + st_time = 0; + curplaying = soundtestdefs[st_sel]; + S_ChangeMusicInternal(&curplaying->name[0][0], true); + break; + + default: + break; + } + if (exitmenu) + { + Z_Free(soundtestdefs); + soundtestdefs = NULL; + + if (currentMenu->prevMenu) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ClearMenus(true); + } +} + // Entering secrets menu /*static void M_SecretsMenu(INT32 choice) { diff --git a/src/s_sound.c b/src/s_sound.c index 586f772eb..4bcd57f79 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -33,6 +33,7 @@ #include "lua_hook.h" // MusicChange hook #include "k_boss.h" // bossinfo #include "byteptr.h" +#include "v_video.h" #ifdef HW3SOUND // 3D Sound Interface @@ -1535,7 +1536,8 @@ ReadMusicDefFields } else if (!stricmp(stoken, "usage")) { - // This does absolutely nothing, just a way to ignore this + Z_Free(def->usage); + def->usage = Z_StrDup(textline); } else { @@ -1630,6 +1632,7 @@ static void S_LoadMusicDefLump(lumpnum_t lumpnum) if (df->legacy && df->source) { df->source = replacechar(df->source, '_', ' '); + df->usage = replacechar(df->usage, '_', ' '); df->title = Z_StrDup(df->source); memset(df->source, 0, strlen(df->source)); df->source = NULL; @@ -1662,7 +1665,9 @@ void S_InitMusicDefs(void) { UINT16 i; for (i = 0; i < numwadfiles; i++) + { S_LoadMusicDefs(i); + } } // @@ -1678,6 +1683,7 @@ void S_ShowMusicCredit(void) char credittext[128] = ""; char *work = NULL; size_t len = 128, worklen; + INT32 widthused = (3*BASEVIDWIDTH/4) - 7, workwidth; if (!cv_songcredits.value || demo.rewinding) return; @@ -1713,20 +1719,27 @@ void S_ShowMusicCredit(void) } } -#define MUSICCREDITAPPEND(field)\ + widthused -= V_ThinStringWidth(credittext, 0); + +#define MUSICCREDITAPPEND(field, force)\ if (field)\ {\ work = va(" - %s", field);\ worklen = strlen(work);\ if (worklen <= len)\ {\ - strncat(credittext, work, len);\ - len -= worklen;\ + workwidth = V_ThinStringWidth(work, 0);\ + if (force || widthused >= workwidth)\ + {\ + strncat(credittext, work, len);\ + len -= worklen;\ + widthused -= workwidth;\ + }\ }\ } - MUSICCREDITAPPEND(def->author); - MUSICCREDITAPPEND(def->source); + MUSICCREDITAPPEND(def->author, true); + MUSICCREDITAPPEND(def->source, false); #undef MUSICCREDITAPPEND } @@ -1742,6 +1755,41 @@ void S_ShowMusicCredit(void) cursongcredit.trans = NUMTRANSMAPS; } +musicdef_t **soundtestdefs = NULL; +INT32 numsoundtestdefs = 0; + +// +// S_PrepareSoundTest +// +// Prepare sound test. What am I, your butler? +// +boolean S_PrepareSoundTest(void) +{ + musicdef_t *def; + INT32 pos = numsoundtestdefs = 0; + + for (def = musicdefstart; def; def = def->next) + { + numsoundtestdefs++; + } + + if (!numsoundtestdefs) + return false; + + if (soundtestdefs) + Z_Free(soundtestdefs); + + if (!(soundtestdefs = Z_Malloc(numsoundtestdefs*sizeof(musicdef_t *), PU_STATIC, NULL))) + I_Error("S_PrepareSoundTest(): could not allocate soundtestdefs."); + + for (def = musicdefstart; def; def = def->next) + { + soundtestdefs[pos++] = def; + } + + return true; +} + /// ------------------------ /// Music Status /// ------------------------ diff --git a/src/s_sound.h b/src/s_sound.h index eed32a439..fdb340d25 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -184,6 +184,7 @@ struct musicdef_t char *author; char *source; char *composers; + char *usage; int volume; boolean contentidunsafe; boolean legacy; @@ -200,13 +201,18 @@ extern struct cursongcredit fixed_t old_x; } cursongcredit; +extern musicdef_t soundtestsfx; extern musicdef_t *musicdefstart; +extern musicdef_t **soundtestdefs; +extern INT32 numsoundtestdefs; +extern UINT8 soundtestpage; 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); +boolean S_PrepareSoundTest(void); // // Music Seeking