mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-23 14:01:14 +00:00
Merge branch 'last-music' into 'master'
Last Music See merge request KartKrew/Kart!2076
This commit is contained in:
commit
c019dfa517
13 changed files with 353 additions and 40 deletions
|
|
@ -1234,8 +1234,6 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
break;
|
||||
deh_strlcpy(mapheaderinfo[num]->musname[j], tmp,
|
||||
sizeof(mapheaderinfo[num]->musname[j]), va("Level header %d: music", num));
|
||||
if (j)
|
||||
mapheaderinfo[num]->cache_muslock[j - 1] = MAXUNLOCKABLES;
|
||||
j++;
|
||||
} while ((tmp = strtok(NULL,",")) != NULL);
|
||||
|
||||
|
|
@ -1244,6 +1242,30 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
mapheaderinfo[num]->musname_size = j;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "ENCOREMUSIC"))
|
||||
{
|
||||
if (fastcmp(word2, "NONE"))
|
||||
{
|
||||
mapheaderinfo[num]->encoremusname[0][0] = 0; // becomes empty string
|
||||
mapheaderinfo[num]->encoremusname_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 j = 0; // i was declared elsewhere
|
||||
tmp = strtok(word2, ",");
|
||||
do {
|
||||
if (j >= MAXMUSNAMES)
|
||||
break;
|
||||
deh_strlcpy(mapheaderinfo[num]->encoremusname[j], tmp,
|
||||
sizeof(mapheaderinfo[num]->encoremusname[j]), va("Level header %d: encore music", num));
|
||||
j++;
|
||||
} while ((tmp = strtok(NULL,",")) != NULL);
|
||||
|
||||
if (tmp != NULL)
|
||||
deh_warning("Level header %d: additional music slots past %d discarded", num, MAXMUSNAMES);
|
||||
mapheaderinfo[num]->encoremusname_size = j;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "ASSOCIATEDMUSIC"))
|
||||
{
|
||||
if (fastcmp(word2, "NONE"))
|
||||
|
|
|
|||
|
|
@ -515,10 +515,12 @@ struct mapheader_t
|
|||
|
||||
// Music information
|
||||
char musname[MAXMUSNAMES][7]; ///< Music tracks to play. First dimension is the track number, second is the music string. "" for no music.
|
||||
char encoremusname[MAXMUSNAMES][7]; ///< Music tracks to play in Encore. First dimension is the track number, second is the music string. "" for no music.
|
||||
UINT16 cache_muslock[MAXMUSNAMES-1]; ///< Cached Alt Music IDs
|
||||
char associatedmus[MAXMUSNAMES][7]; ///< Associated music tracks for sound test unlock.
|
||||
char positionmus[7]; ///< Custom Position track. Doesn't play in Encore or other fun game-controlled contexts
|
||||
UINT8 musname_size; ///< Number of music tracks defined
|
||||
UINT8 encoremusname_size; ///< Number of Encore music tracks defined
|
||||
UINT8 associatedmus_size; ///< Number of associated music tracks defined
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
UINT32 muspos; ///< Music position to jump to.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ extern "C" {
|
|||
|
||||
// Level title font
|
||||
#define LT_FONTSTART '!' // the first font characters
|
||||
#define LT_FONTEND 'z' // the last font characters
|
||||
#define LT_FONTEND '~' // the last font characters
|
||||
#define LT_FONTSIZE (LT_FONTEND - LT_FONTSTART + 1)
|
||||
|
||||
#define CRED_FONTSTART '!' // the first font character
|
||||
|
|
|
|||
|
|
@ -7089,6 +7089,90 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
|
||||
break;
|
||||
}
|
||||
case SECRET_ALTMUSIC:
|
||||
{
|
||||
UINT16 map = M_UnlockableMapNum(ref);
|
||||
if (map >= nummapheaders
|
||||
|| !mapheaderinfo[map])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UINT8 musicid;
|
||||
for (musicid = 1; musicid < MAXMUSNAMES; musicid++)
|
||||
{
|
||||
if (mapheaderinfo[map]->cache_muslock[musicid - 1] == challengesmenu.currentunlock)
|
||||
break;
|
||||
}
|
||||
|
||||
if (musicid == MAXMUSNAMES)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
spritedef_t *sprdef = &sprites[SPR_ALTM];
|
||||
spriteframe_t *sprframe;
|
||||
patch_t *patch;
|
||||
UINT32 addflags = 0;
|
||||
|
||||
x -= 10;
|
||||
y += 15;
|
||||
|
||||
if (sprdef->numframes)
|
||||
{
|
||||
sprframe = &sprdef->spriteframes[0];
|
||||
patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||
|
||||
if (sprframe->flip & 1) // Only for first sprite
|
||||
{
|
||||
addflags ^= V_FLIP; // This sprite is left/right flipped!
|
||||
}
|
||||
|
||||
V_DrawFixedPatch(x*FRACUNIT, (y+2)*FRACUNIT, FRACUNIT/2, addflags, patch, NULL);
|
||||
}
|
||||
|
||||
x = 8;
|
||||
y = BASEVIDHEIGHT-16;
|
||||
|
||||
const boolean thismusplaying = Music_Playing("challenge_altmusic");
|
||||
boolean pushed = false;
|
||||
const char *song = NULL;
|
||||
|
||||
if (M_SecretUnlocked(SECRET_ENCORE, true)
|
||||
&& musicid < mapheaderinfo[map]->encoremusname_size)
|
||||
{
|
||||
if (thismusplaying)
|
||||
{
|
||||
song = Music_Song("challenge_altmusic");
|
||||
pushed = strcmp(song, mapheaderinfo[map]->encoremusname[musicid]) == 0;
|
||||
}
|
||||
|
||||
K_drawButton(x&FRACUNIT, y*FRACUNIT, 0, kp_button_l, pushed);
|
||||
x += SHORT(kp_button_l[0]->width);
|
||||
V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "E Side");
|
||||
|
||||
x = 8;
|
||||
y -= 10;
|
||||
}
|
||||
|
||||
if (musicid < mapheaderinfo[map]->musname_size)
|
||||
{
|
||||
if (pushed || !thismusplaying)
|
||||
{
|
||||
pushed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!song)
|
||||
song = Music_Song("challenge_altmusic");
|
||||
pushed = strcmp(song, mapheaderinfo[map]->musname[musicid]) == 0;
|
||||
}
|
||||
|
||||
K_drawButton(x*FRACUNIT, y*FRACUNIT, 0, kp_button_a[1], pushed);
|
||||
x += SHORT(kp_button_a[1][0]->width);
|
||||
V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "Play CD");
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
|
|
@ -8359,7 +8443,7 @@ void M_DrawSoundTest(void)
|
|||
{
|
||||
UINT32 currenttime = min(Music_Elapsed(tune), Music_TotalDuration(tune));
|
||||
|
||||
V_DrawRightAlignedMenuString(x + 272-1, 18+32, 0,
|
||||
V_DrawRightAlignedThinString(x + 272-1, 18+32, 0,
|
||||
va("%02u:%02u",
|
||||
G_TicsToMinutes(currenttime, true),
|
||||
G_TicsToSeconds(currenttime)
|
||||
|
|
@ -8373,7 +8457,7 @@ void M_DrawSoundTest(void)
|
|||
{
|
||||
UINT32 exittime = Music_TotalDuration(tune);
|
||||
|
||||
V_DrawRightAlignedMenuString(x + 272-1, 18+32+10, 0,
|
||||
V_DrawRightAlignedThinString(x + 272-1, 18+32+10, 0,
|
||||
va("%02u:%02u",
|
||||
G_TicsToMinutes(exittime, true),
|
||||
G_TicsToSeconds(exittime)
|
||||
|
|
|
|||
|
|
@ -1247,7 +1247,14 @@ void K_ResetCeremony(void)
|
|||
mapmusrng = 0;
|
||||
}
|
||||
|
||||
while (mapmusrng >= std::max<UINT8>(1, mapheaderinfo[gamemap-1]->musname_size))
|
||||
UINT8 limit = (encoremode && mapheaderinfo[gamemap-1]->encoremusname_size)
|
||||
? mapheaderinfo[gamemap-1]->encoremusname_size
|
||||
: mapheaderinfo[gamemap-1]->musname_size;
|
||||
|
||||
if (limit < 1)
|
||||
limit = 1;
|
||||
|
||||
while (mapmusrng >= limit)
|
||||
{
|
||||
mapmusrng--;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2507,12 +2507,36 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(field,"encoremusname")) // we create a table here because it saves us from a userdata nightmare
|
||||
{
|
||||
UINT8 i;
|
||||
lua_createtable(L, header->encoremusname_size, 0);
|
||||
for (i = 0; i < header->encoremusname_size; i++)
|
||||
{
|
||||
lua_pushstring(L, header->encoremusname[i]);
|
||||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(field,"associatedmus")) // we create a table here because it saves us from a userdata nightmare
|
||||
{
|
||||
UINT8 i;
|
||||
lua_createtable(L, header->associatedmus_size, 0);
|
||||
for (i = 0; i < header->associatedmus_size; i++)
|
||||
{
|
||||
lua_pushstring(L, header->associatedmus[i]);
|
||||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(field,"mustrack"))
|
||||
lua_pushinteger(L, header->mustrack);
|
||||
else if (fastcmp(field,"muspos"))
|
||||
lua_pushinteger(L, header->muspos);
|
||||
else if (fastcmp(field,"musname_size"))
|
||||
lua_pushinteger(L, header->musname_size);
|
||||
else if (fastcmp(field,"encoremusname_size"))
|
||||
lua_pushinteger(L, header->encoremusname_size);
|
||||
else if (fastcmp(field,"associatedmus_size"))
|
||||
lua_pushinteger(L, header->associatedmus_size);
|
||||
else if (fastcmp(field,"weather"))
|
||||
lua_pushinteger(L, header->weather);
|
||||
else if (fastcmp(field,"skytexture"))
|
||||
|
|
|
|||
|
|
@ -1077,7 +1077,8 @@ static void M_PrecacheLevelLocks(void)
|
|||
if (map < nummapheaders
|
||||
&& mapheaderinfo[map])
|
||||
{
|
||||
for (j = 1; j < mapheaderinfo[map]->musname_size; j++)
|
||||
UINT8 greatersize = max(mapheaderinfo[map]->musname_size, mapheaderinfo[map]->encoremusname_size);
|
||||
for (j = 1; j < greatersize; j++)
|
||||
{
|
||||
if (mapheaderinfo[map]->cache_muslock[j - 1] != MAXUNLOCKABLES)
|
||||
{
|
||||
|
|
@ -1143,7 +1144,7 @@ static void M_PrecacheLevelLocks(void)
|
|||
|
||||
break;
|
||||
}
|
||||
if (j == mapheaderinfo[map]->musname_size)
|
||||
if (j == greatersize)
|
||||
CONS_Alert(CONS_ERROR, "Unlockable %u: Too many SECRET_ALTMUSICs associated with Level %s\n", i+1, mapheaderinfo[map]->lumpname);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -834,6 +834,8 @@ boolean M_ChallengesInputs(INT32 ch)
|
|||
{
|
||||
if (M_MenuBackPressed(pid) || start)
|
||||
{
|
||||
Music_Stop("challenge_altmusic");
|
||||
|
||||
currentMenu->prevMenu = M_SpecificMenuRestore(currentMenu->prevMenu);
|
||||
|
||||
M_GoBack(0);
|
||||
|
|
@ -1021,17 +1023,83 @@ boolean M_ChallengesInputs(INT32 ch)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (M_MenuConfirmPressed(pid)
|
||||
&& challengesmenu.currentunlock < MAXUNLOCKABLES
|
||||
if (challengesmenu.currentunlock < MAXUNLOCKABLES
|
||||
&& gamedata->unlocked[challengesmenu.currentunlock])
|
||||
{
|
||||
switch (unlockables[challengesmenu.currentunlock].type)
|
||||
{
|
||||
case SECRET_ALTTITLE: {
|
||||
extern consvar_t cv_alttitle;
|
||||
CV_AddValue(&cv_alttitle, 1);
|
||||
S_StartSound(NULL, sfx_s3kc3s);
|
||||
M_SetMenuDelay(pid);
|
||||
case SECRET_ALTTITLE:
|
||||
{
|
||||
if (M_MenuConfirmPressed(pid))
|
||||
{
|
||||
extern consvar_t cv_alttitle;
|
||||
CV_AddValue(&cv_alttitle, 1);
|
||||
S_StartSound(NULL, sfx_s3kc3s);
|
||||
M_SetMenuDelay(pid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SECRET_ALTMUSIC:
|
||||
{
|
||||
UINT8 trymus = 0, musicid = MAXMUSNAMES;
|
||||
|
||||
if (M_MenuConfirmPressed(pid))
|
||||
{
|
||||
trymus = 1;
|
||||
}
|
||||
else if (M_MenuButtonPressed(pid, MBT_L))
|
||||
{
|
||||
trymus = 2;
|
||||
}
|
||||
|
||||
if (trymus)
|
||||
{
|
||||
const char *trymusname = NULL;
|
||||
|
||||
UINT16 map = M_UnlockableMapNum(&unlockables[challengesmenu.currentunlock]);
|
||||
if (map >= nummapheaders
|
||||
|| !mapheaderinfo[map])
|
||||
{
|
||||
;
|
||||
}
|
||||
else for (musicid = 1; musicid < MAXMUSNAMES; musicid++)
|
||||
{
|
||||
if (mapheaderinfo[map]->cache_muslock[musicid - 1] == challengesmenu.currentunlock)
|
||||
break;
|
||||
}
|
||||
|
||||
if (trymus == 1)
|
||||
{
|
||||
if (musicid < mapheaderinfo[map]->musname_size)
|
||||
{
|
||||
trymusname = mapheaderinfo[map]->musname[musicid];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (musicid < mapheaderinfo[map]->encoremusname_size)
|
||||
{
|
||||
trymusname = mapheaderinfo[map]->encoremusname[musicid];
|
||||
}
|
||||
}
|
||||
|
||||
if (trymusname)
|
||||
{
|
||||
if (!Music_Playing("challenge_altmusic")
|
||||
|| strcmp(Music_Song("challenge_altmusic"), trymusname))
|
||||
{
|
||||
Music_Remap("challenge_altmusic", trymusname);
|
||||
Music_Play("challenge_altmusic");
|
||||
}
|
||||
else
|
||||
{
|
||||
Music_Stop("challenge_altmusic");
|
||||
}
|
||||
|
||||
M_SetMenuDelay(pid);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -195,6 +195,14 @@ void Music_Init(void)
|
|||
tune.fade_out = 5000;
|
||||
tune.fade_out_inclusive = false;
|
||||
}
|
||||
|
||||
{
|
||||
Tune& tune = g_tunes.insert("challenge_altmusic");
|
||||
|
||||
tune.priority = 100;
|
||||
tune.resist = true;
|
||||
tune.credit = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Music_Tick(void)
|
||||
|
|
@ -218,6 +226,23 @@ void Music_Play(const char* id)
|
|||
}
|
||||
}
|
||||
|
||||
void Music_SetFadeOut(const char* id, int fade_out)
|
||||
{
|
||||
Tune* tune = g_tunes.find(id);
|
||||
|
||||
if (tune)
|
||||
{
|
||||
tune->fade_out = fade_out;
|
||||
|
||||
if (tune->time_remaining() <= detail::msec_to_tics(tune->fade_out))
|
||||
{
|
||||
// If this action would cause a fade out, start
|
||||
// fading immediately.
|
||||
g_tunes.tick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Music_DelayEnd(const char* id, tic_t duration)
|
||||
{
|
||||
Tune* tune = g_tunes.find(id);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,10 @@ const char *Music_CurrentId(void);
|
|||
// back to the start.)
|
||||
void Music_Play(const char *id);
|
||||
|
||||
// Set fade out duration. Mostly to fix a last minute bug
|
||||
// with Stereo Mode.
|
||||
void Music_SetFadeOut(const char* id, int fade_out);
|
||||
|
||||
// Postpone the end of this tune until N tics from now. The
|
||||
// tune should already be playing before calling this.
|
||||
void Music_DelayEnd(const char *id, tic_t duration);
|
||||
|
|
|
|||
|
|
@ -103,7 +103,12 @@ public:
|
|||
return (1.f/encoremul);
|
||||
}
|
||||
|
||||
return encoremul;
|
||||
if (!nightcoreable
|
||||
|| mapheaderinfo[gamemap-1]->encoremusname_size == 0)
|
||||
{
|
||||
// We only vape if the level doesn't have alternate tracks.
|
||||
return encoremul;
|
||||
}
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
|
|
|
|||
|
|
@ -433,6 +433,8 @@ static void P_ClearMapHeaderLighting(mapheader_lighting_t *lighting)
|
|||
*/
|
||||
static void P_ClearSingleMapHeaderInfo(INT16 num)
|
||||
{
|
||||
int i;
|
||||
|
||||
mapheaderinfo[num]->lvlttl[0] = '\0';
|
||||
mapheaderinfo[num]->menuttl[0] = '\0';
|
||||
mapheaderinfo[num]->zonttl[0] = '\0';
|
||||
|
|
@ -441,13 +443,24 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
|
|||
mapheaderinfo[num]->gravity = DEFAULT_GRAVITY;
|
||||
mapheaderinfo[num]->keywords[0] = '\0';
|
||||
mapheaderinfo[num]->relevantskin[0] = '\0';
|
||||
|
||||
mapheaderinfo[num]->musname[0][0] = 0;
|
||||
mapheaderinfo[num]->musname_size = 0;
|
||||
mapheaderinfo[num]->encoremusname[0][0] = 0;
|
||||
mapheaderinfo[num]->encoremusname_size = 0;
|
||||
|
||||
for (i = 0; i < MAXMUSNAMES-1; i++)
|
||||
{
|
||||
mapheaderinfo[num]->cache_muslock[i] = MAXUNLOCKABLES;
|
||||
}
|
||||
|
||||
mapheaderinfo[num]->positionmus[0] = '\0';
|
||||
mapheaderinfo[num]->associatedmus[0][0] = 0;
|
||||
mapheaderinfo[num]->associatedmus_size = 0;
|
||||
|
||||
mapheaderinfo[num]->mustrack = 0;
|
||||
mapheaderinfo[num]->muspos = 0;
|
||||
|
||||
mapheaderinfo[num]->weather = PRECIP_NONE;
|
||||
snprintf(mapheaderinfo[num]->skytexture, 5, "SKY1");
|
||||
mapheaderinfo[num]->skytexture[4] = 0;
|
||||
|
|
@ -494,7 +507,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 num)
|
|||
|
||||
if (mapheaderinfo[num]->ghostBrief != NULL)
|
||||
{
|
||||
for (int i = 0; i < mapheaderinfo[num]->ghostCount; i++)
|
||||
for (i = 0; i < mapheaderinfo[num]->ghostCount; i++)
|
||||
{
|
||||
Z_Free(mapheaderinfo[num]->ghostBrief[i]);
|
||||
}
|
||||
|
|
@ -8183,6 +8196,9 @@ void P_ResetLevelMusic(void)
|
|||
UINT8 idx = 0;
|
||||
|
||||
mapheader_t* mapheader = mapheaderinfo[gamemap - 1];
|
||||
UINT8 truesize = (encoremode && mapheader->encoremusname_size)
|
||||
? mapheader->encoremusname_size
|
||||
: mapheader->musname_size;
|
||||
|
||||
// To keep RNG in sync, we will always pull from RNG, even if unused
|
||||
UINT32 random = P_Random(PR_MUSICSELECT);
|
||||
|
|
@ -8190,20 +8206,20 @@ void P_ResetLevelMusic(void)
|
|||
if (demo.playback)
|
||||
{
|
||||
// mapmusrng has already been set by the demo; just make sure it's valid
|
||||
if (mapmusrng >= mapheader->musname_size)
|
||||
if (mapmusrng >= truesize)
|
||||
{
|
||||
mapmusrng = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapheader->musname_size > 1)
|
||||
if (truesize > 1)
|
||||
{
|
||||
UINT8 tempmapmus[MAXMUSNAMES], tempmapmus_size = 1, i;
|
||||
|
||||
tempmapmus[0] = 0;
|
||||
|
||||
for (i = 1; i < mapheader->musname_size; i++)
|
||||
for (i = 1; i < truesize; i++)
|
||||
{
|
||||
if (mapheader->cache_muslock[i-1] < MAXUNLOCKABLES
|
||||
&& !M_CheckNetUnlockByID(mapheader->cache_muslock[i-1]))
|
||||
|
|
@ -8249,7 +8265,12 @@ void P_LoadLevelMusic(void)
|
|||
mapheader_t* mapheader = mapheaderinfo[gamemap-1];
|
||||
const char *music = mapheader->musname[0];
|
||||
|
||||
if (mapmusrng < mapheader->musname_size)
|
||||
if (encoremode && mapheader->encoremusname_size
|
||||
&& mapmusrng < mapheader->encoremusname_size)
|
||||
{
|
||||
music = mapheader->encoremusname[mapmusrng];
|
||||
}
|
||||
else if (mapmusrng < mapheader->musname_size)
|
||||
{
|
||||
music = mapheader->musname[mapmusrng];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1292,6 +1292,11 @@ static void S_InsertMapIntoSoundTestSequence(UINT16 map, musicdef_t ***tail)
|
|||
{
|
||||
S_InsertMusicAtSoundTestSequenceTail(mapheaderinfo[map]->associatedmus[i], map, ALTREF_REQUIRESBEATEN, tail);
|
||||
}
|
||||
|
||||
for (i = 0; i < mapheaderinfo[map]->encoremusname_size; i++)
|
||||
{
|
||||
S_InsertMusicAtSoundTestSequenceTail(mapheaderinfo[map]->encoremusname[i], map, i+MAXMUSNAMES, tail);
|
||||
}
|
||||
}
|
||||
|
||||
void S_PopulateSoundTestSequence(void)
|
||||
|
|
@ -1317,7 +1322,22 @@ void S_PopulateSoundTestSequence(void)
|
|||
|
||||
tail = &soundtest.sequence.next;
|
||||
|
||||
// We iterate over all cups.
|
||||
// We iterate over all tutorial maps.
|
||||
for (i = 0; i < nummapheaders; i++)
|
||||
{
|
||||
if (!mapheaderinfo[i])
|
||||
continue;
|
||||
|
||||
if (mapheaderinfo[i]->cup != NULL)
|
||||
continue;
|
||||
|
||||
if ((mapheaderinfo[i]->typeoflevel & TOL_TUTORIAL) == 0)
|
||||
continue;
|
||||
|
||||
S_InsertMapIntoSoundTestSequence(i, &tail);
|
||||
}
|
||||
|
||||
// Next, we iterate over all cups.
|
||||
{
|
||||
cupheader_t *cup;
|
||||
for (cup = kartcupheaders; cup; cup = cup->next)
|
||||
|
|
@ -1338,7 +1358,7 @@ void S_PopulateSoundTestSequence(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Then, we iterate over all non-cupped maps.
|
||||
// Then, we iterate over all remaining non-cupped maps.
|
||||
for (i = 0; i < nummapheaders; i++)
|
||||
{
|
||||
if (!mapheaderinfo[i])
|
||||
|
|
@ -1347,6 +1367,9 @@ void S_PopulateSoundTestSequence(void)
|
|||
if (mapheaderinfo[i]->cup != NULL)
|
||||
continue;
|
||||
|
||||
if (mapheaderinfo[i]->typeoflevel & TOL_TUTORIAL)
|
||||
continue;
|
||||
|
||||
S_InsertMapIntoSoundTestSequence(i, &tail);
|
||||
}
|
||||
|
||||
|
|
@ -1417,17 +1440,33 @@ static boolean S_SoundTestDefLocked(musicdef_t *def)
|
|||
&& !(header->records.mapvisited & MV_VISITED))
|
||||
return true;
|
||||
|
||||
// Associated music only when completed
|
||||
if ((def->sequence.altref == ALTREF_REQUIRESBEATEN)
|
||||
&& !(header->records.mapvisited & MV_BEATEN))
|
||||
return true;
|
||||
|
||||
if (def->sequence.altref != 0 && def->sequence.altref < header->musname_size)
|
||||
if (def->sequence.altref != 0)
|
||||
{
|
||||
// Alt music requires unlocking the alt
|
||||
if ((header->cache_muslock[def->sequence.altref - 1] < MAXUNLOCKABLES)
|
||||
&& gamedata->unlocked[header->cache_muslock[def->sequence.altref - 1]] == false)
|
||||
return true;
|
||||
if ((def->sequence.altref == ALTREF_REQUIRESBEATEN))
|
||||
{
|
||||
// Associated music only when completed
|
||||
if (!(header->records.mapvisited & MV_BEATEN))
|
||||
return true;
|
||||
}
|
||||
else if (def->sequence.altref < MAXMUSNAMES)
|
||||
{
|
||||
// Alt music requires unlocking the alt
|
||||
if ((header->cache_muslock[def->sequence.altref - 1] < MAXUNLOCKABLES)
|
||||
&& gamedata->unlocked[header->cache_muslock[def->sequence.altref - 1]] == false)
|
||||
return true;
|
||||
}
|
||||
else if (def->sequence.altref < MAXMUSNAMES*2)
|
||||
{
|
||||
// Encore!
|
||||
if (M_SecretUnlocked(SECRET_ENCORE, true) == false)
|
||||
return true;
|
||||
|
||||
// Side B of the same CD
|
||||
if (def->sequence.altref > MAXMUSNAMES
|
||||
&& (header->cache_muslock[def->sequence.altref - (1 + MAXMUSNAMES)] < MAXUNLOCKABLES)
|
||||
&& gamedata->unlocked[header->cache_muslock[def->sequence.altref - (1 + MAXMUSNAMES)]] == false)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, do a full-fat map check.
|
||||
|
|
@ -1672,10 +1711,7 @@ const char *S_SoundTestTune(UINT8 invert)
|
|||
|
||||
boolean S_SoundTestCanSequenceFade(void)
|
||||
{
|
||||
return
|
||||
soundtest.current->basenoloop[soundtest.currenttrack] == false &&
|
||||
// Only fade out if we're the last track for this song.
|
||||
soundtest.currenttrack == soundtest.current->numtracks-1;
|
||||
return soundtest.current->basenoloop[soundtest.currenttrack] == false;
|
||||
}
|
||||
|
||||
static void S_SoundTestReconfigure(const char *tune)
|
||||
|
|
@ -1710,12 +1746,16 @@ void S_SoundTestPlay(void)
|
|||
}
|
||||
|
||||
// Does song have default loop?
|
||||
if (soundtest.current->basenoloop[soundtest.currenttrack] == false)
|
||||
if (S_SoundTestCanSequenceFade() == true)
|
||||
{
|
||||
// I'd personally like songs in sequence to last between 3 and 6 minutes.
|
||||
if (sequencemaxtime < 3*60*1000)
|
||||
{
|
||||
// I'd personally like songs in sequence to last between 3 and 6 minutes.
|
||||
const UINT32 loopduration = (sequencemaxtime - I_GetSongLoopPoint());
|
||||
const UINT32 looppoint = I_GetSongLoopPoint();
|
||||
const UINT32 loopduration =
|
||||
(looppoint < sequencemaxtime)
|
||||
? sequencemaxtime - looppoint
|
||||
: 0;
|
||||
|
||||
if (!loopduration)
|
||||
;
|
||||
|
|
@ -1727,6 +1767,16 @@ void S_SoundTestPlay(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Only the last track fades out... but we still use stereo_fade to handle stopping.
|
||||
if (soundtest.currenttrack == soundtest.current->numtracks-1)
|
||||
{
|
||||
Music_SetFadeOut("stereo_fade", 5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Music_SetFadeOut("stereo_fade", 0);
|
||||
}
|
||||
|
||||
Music_DelayEnd(
|
||||
S_SoundTestCanSequenceFade() ? "stereo_fade" : "stereo",
|
||||
(TICRATE*sequencemaxtime)/1000 // ms to TICRATE conversion
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue