Merge branch 'backport_unslot-music' into 'next'

BACKPORT: removal of music slots

Relevant commits cherry-picked. Basically everything except the internal music track name switches.

See merge request !43
This commit is contained in:
Inuyasha 2016-03-03 22:31:21 -05:00
commit a8bca89dbd
21 changed files with 596 additions and 2616 deletions

View file

@ -1854,10 +1854,10 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
if (paused) if (paused)
{ {
if (!menuactive || netgame) if (!menuactive || netgame)
S_PauseSound(); S_PauseAudio();
} }
else else
S_ResumeSound(); S_ResumeAudio();
} }
} }
@ -3761,50 +3761,66 @@ static void Command_Displayplayer_f(void)
static void Command_Tunes_f(void) static void Command_Tunes_f(void)
{ {
const char *tunearg; const char *tunearg;
UINT16 tune, track = 0; UINT16 tunenum, track = 0;
const size_t argc = COM_Argc(); const size_t argc = COM_Argc();
if (argc < 2) //tunes slot ... if (argc < 2) //tunes slot ...
{ {
CONS_Printf("tunes <slot #/map name/\"default\"> <speed> <track>:\n"); CONS_Printf("tunes <name/num> [track] [speed] / <-show> / <-default> / <-none>:\n");
CONS_Printf(M_GetText("Play a music slot at a set speed (\"1\" being normal speed).\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")); CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n"));
CONS_Printf(M_GetText("The current tune is: %d\nThe current track is: %d\n"), CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n"));
(mapmusic & MUSIC_SONGMASK), ((mapmusic & MUSIC_TRACKMASK) >> MUSIC_TRACKSHIFT)); 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; return;
} }
tunearg = COM_Argv(1); tunearg = COM_Argv(1);
tune = (UINT16)atoi(tunearg); tunenum = (UINT16)atoi(tunearg);
track = 0; track = 0;
if (!strcasecmp(tunearg, "default")) if (!strcasecmp(tunearg, "-show"))
{ {
tune = mapheaderinfo[gamemap-1]->musicslot; CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"),
track = mapheaderinfo[gamemap-1]->musicslottrack; mapmusname, (mapmusflags & MUSIC_TRACKMASK));
}
else if (toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z')
tune = (UINT16)M_MapNumber(tunearg[0], tunearg[1]);
if (tune >= NUMMUSIC)
{
CONS_Alert(CONS_NOTICE, M_GetText("Valid slots are 1 to %d, or 0 to stop music\n"), NUMMUSIC - 1);
return; return;
} }
if (!strcasecmp(tunearg, "-none"))
if (argc > 3) {
track = (UINT16)atoi(COM_Argv(3))-1;
mapmusic = tune | (track << MUSIC_TRACKSHIFT);
if (tune == mus_None)
S_StopMusic(); S_StopMusic();
else return;
S_ChangeMusic(mapmusic, true); }
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) 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(2)); float speed = (float)atof(COM_Argv(3));
if (speed > 0.0f) if (speed > 0.0f)
S_SpeedMusic(speed); S_SpeedMusic(speed);
} }

View file

@ -65,7 +65,9 @@ static mobjtype_t get_mobjtype(const char *word);
static statenum_t get_state(const char *word); static statenum_t get_state(const char *word);
static spritenum_t get_sprite(const char *word); static spritenum_t get_sprite(const char *word);
static sfxenum_t get_sfx(const char *word); static sfxenum_t get_sfx(const char *word);
static UINT16 get_mus(const char *word); #ifdef MUSICSLOT_COMPATIBILITY
static UINT16 get_mus(const char *word, UINT8 dehacked_mode);
#endif
static hudnum_t get_huditem(const char *word); static hudnum_t get_huditem(const char *word);
#ifndef HAVE_BLUA #ifndef HAVE_BLUA
static powertype_t get_power(const char *word); static powertype_t get_power(const char *word);
@ -1164,19 +1166,31 @@ static void readlevelheader(MYFILE *f, INT32 num)
mapheaderinfo[num-1]->typeoflevel = tol; mapheaderinfo[num-1]->typeoflevel = tol;
} }
} }
else if (fastcmp(word, "MUSIC"))
{
if (fastcmp(word2, "NONE"))
mapheaderinfo[num-1]->musname[0] = 0; // becomes empty string
else
{
deh_strlcpy(mapheaderinfo[num-1]->musname, word2,
sizeof(mapheaderinfo[num-1]->musname), va("Level header %d: music", num));
}
}
#ifdef MUSICSLOT_COMPATIBILITY
else if (fastcmp(word, "MUSICSLOT")) else if (fastcmp(word, "MUSICSLOT"))
{ {
// Convert to map number i = get_mus(word2, true);
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0') if (i && i <= 1035)
i = M_MapNumber(word2[0], word2[1]); snprintf(mapheaderinfo[num-1]->musname, 7, "%sM", G_BuildMapName(i));
else if (i && i <= 1050)
if (i) // it's just a number strncpy(mapheaderinfo[num-1]->musname, compat_special_music_slots[i - 1036], 7);
mapheaderinfo[num-1]->musicslot = (UINT16)i; else
else // No? Okay, now we'll get technical. mapheaderinfo[num-1]->musname[0] = 0; // becomes empty string
mapheaderinfo[num-1]->musicslot = get_mus(word2); // accepts all of O_CHRSEL, mus_chrsel, or just plain ChrSel mapheaderinfo[num-1]->musname[6] = 0;
} }
else if (fastcmp(word, "MUSICSLOTTRACK")) #endif
mapheaderinfo[num-1]->musicslottrack = ((UINT16)i - 1); else if (fastcmp(word, "MUSICTRACK"))
mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1);
else if (fastcmp(word, "FORCECHARACTER")) else if (fastcmp(word, "FORCECHARACTER"))
{ {
strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1); strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1);
@ -1443,10 +1457,30 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
else else
deh_warning("CutSceneScene %d: unknown word '%s'", num, word); deh_warning("CutSceneScene %d: unknown word '%s'", num, word);
} }
else if (fastcmp(word, "MUSIC"))
{
DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE);
strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7);
cutscenes[num]->scene[scenenum].musswitch[6] = 0;
}
#ifdef MUSICSLOT_COMPATIBILITY
else if (fastcmp(word, "MUSICSLOT")) else if (fastcmp(word, "MUSICSLOT"))
{ {
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musicslot), UNDO_NONE); DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE);
cutscenes[num]->scene[scenenum].musicslot = get_mus(word2); // accepts all of O_MAP01M, mus_map01m, or just plain MAP01M i = get_mus(word2, true);
if (i && i <= 1035)
snprintf(cutscenes[num]->scene[scenenum].musswitch, 7, "%sM", G_BuildMapName(i));
else if (i && i <= 1050)
strncpy(cutscenes[num]->scene[scenenum].musswitch, compat_special_music_slots[i - 1036], 7);
else
cutscenes[num]->scene[scenenum].musswitch[0] = 0; // becomes empty string
cutscenes[num]->scene[scenenum].musswitch[6] = 0;
}
#endif
else if (fastcmp(word, "MUSICTRACK"))
{
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchflags), UNDO_NONE);
cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK;
} }
else if (fastcmp(word, "MUSICLOOP")) else if (fastcmp(word, "MUSICLOOP"))
{ {
@ -7428,21 +7462,45 @@ static sfxenum_t get_sfx(const char *word)
return sfx_None; return sfx_None;
} }
static UINT16 get_mus(const char *word) #ifdef MUSICSLOT_COMPATIBILITY
{ // Returns the value of SFX_ enumerations static UINT16 get_mus(const char *word, UINT8 dehacked_mode)
{ // Returns the value of MUS_ enumerations
UINT16 i; UINT16 i;
char lumptmp[4];
if (*word >= '0' && *word <= '9') if (*word >= '0' && *word <= '9')
return atoi(word); return atoi(word);
if (!word[2] && toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z')
return (UINT16)M_MapNumber(word[0], word[1]);
if (fastncmp("MUS_",word,4)) if (fastncmp("MUS_",word,4))
word += 4; // take off the MUS_ word += 4; // take off the MUS_
else if (fastncmp("O_",word,2) || fastncmp("D_",word,2)) else if (fastncmp("O_",word,2) || fastncmp("D_",word,2))
word += 2; // take off the O_ or D_ word += 2; // take off the O_ or D_
for (i = 0; i < NUMMUSIC; i++)
if (S_music[i].name && fasticmp(word, S_music[i].name)) strncpy(lumptmp, word, 4);
lumptmp[3] = 0;
if (fasticmp("MAP",lumptmp))
{
word += 3;
if (toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z')
return (UINT16)M_MapNumber(word[0], word[1]);
else if ((i = atoi(word)))
return i; return i;
word -= 3;
if (dehacked_mode)
deh_warning("Couldn't find music named 'MUS_%s'",word); deh_warning("Couldn't find music named 'MUS_%s'",word);
return mus_None; return 0;
} }
for (i = 0; compat_special_music_slots[i][0]; ++i)
if (fasticmp(word, compat_special_music_slots[i]))
return i + 1036;
if (dehacked_mode)
deh_warning("Couldn't find music named 'MUS_%s'",word);
return 0;
}
#endif
static hudnum_t get_huditem(const char *word) static hudnum_t get_huditem(const char *word)
{ // Returns the value of HUD_ enumerations { // Returns the value of HUD_ enumerations
@ -7642,11 +7700,13 @@ static fixed_t find_const(const char **rword)
free(word); free(word);
return r; return r;
} }
#ifdef MUSICSLOT_COMPATIBILITY
else if (fastncmp("MUS_",word,4) || fastncmp("O_",word,2)) { else if (fastncmp("MUS_",word,4) || fastncmp("O_",word,2)) {
r = get_mus(word); r = get_mus(word, true);
free(word); free(word);
return r; return r;
} }
#endif
else if (fastncmp("PW_",word,3)) { else if (fastncmp("PW_",word,3)) {
r = get_power(word); r = get_power(word);
free(word); free(word);
@ -8016,33 +8076,29 @@ static inline int lib_getenum(lua_State *L)
if (mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word); if (mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word);
return 0; return 0;
} }
#ifdef MUSICSLOT_COMPATIBILITY
else if (!mathlib && fastncmp("mus_",word,4)) { else if (!mathlib && fastncmp("mus_",word,4)) {
p = word+4; p = word+4;
for (i = 0; i < NUMMUSIC; i++) if ((i = get_mus(p, false)) == 0)
if (S_music[i].name && fastcmp(p, S_music[i].name)) { return 0;
lua_pushinteger(L, i); lua_pushinteger(L, i);
return 1; return 1;
} }
return 0;
}
else if (mathlib && fastncmp("MUS_",word,4)) { // SOCs are ALL CAPS! else if (mathlib && fastncmp("MUS_",word,4)) { // SOCs are ALL CAPS!
p = word+4; p = word+4;
for (i = 0; i < NUMMUSIC; i++) if ((i = get_mus(p, false)) == 0)
if (S_music[i].name && fasticmp(p, S_music[i].name)) { return luaL_error(L, "music '%s' could not be found.\n", word);
lua_pushinteger(L, i); lua_pushinteger(L, i);
return 1; return 1;
} }
return luaL_error(L, "music '%s' could not be found.\n", word);
}
else if (mathlib && (fastncmp("O_",word,2) || fastncmp("D_",word,2))) { else if (mathlib && (fastncmp("O_",word,2) || fastncmp("D_",word,2))) {
p = word+2; p = word+2;
for (i = 0; i < NUMMUSIC; i++) if ((i = get_mus(p, false)) == 0)
if (S_music[i].name && fasticmp(p, S_music[i].name)) { return luaL_error(L, "music '%s' could not be found.\n", word);
lua_pushinteger(L, i); lua_pushinteger(L, i);
return 1; return 1;
} }
return luaL_error(L, "music '%s' could not be found.\n", word); #endif
}
else if (!mathlib && fastncmp("pw_",word,3)) { else if (!mathlib && fastncmp("pw_",word,3)) {
p = word+3; p = word+3;
for (i = 0; i < NUMPOWERS; i++) for (i = 0; i < NUMPOWERS; i++)
@ -8194,8 +8250,11 @@ static inline int lib_getenum(lua_State *L)
} else if (fastcmp(word,"globallevelskynum")) { } else if (fastcmp(word,"globallevelskynum")) {
lua_pushinteger(L, globallevelskynum); lua_pushinteger(L, globallevelskynum);
return 1; return 1;
} else if (fastcmp(word,"mapmusic")) { } else if (fastcmp(word,"mapmusname")) {
lua_pushinteger(L, mapmusic); lua_pushstring(L, mapmusname);
return 1;
} else if (fastcmp(word,"mapmusflags")) {
lua_pushinteger(L, mapmusflags);
return 1; return 1;
} else if (fastcmp(word,"server")) { } else if (fastcmp(word,"server")) {
if ((!multiplayer || !netgame) && !playeringame[serverplayer]) if ((!multiplayer || !netgame) && !playeringame[serverplayer])

View file

@ -490,4 +490,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.) /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
//#define REDSANALOG //#define REDSANALOG
/// Backwards compatibility with musicslots.
/// \note You should leave this enabled unless you're working with a future SRB2 version.
#define MUSICSLOT_COMPATIBILITY
#endif // __DOOMDEF__ #endif // __DOOMDEF__

View file

@ -31,15 +31,11 @@
// Selected by user. // Selected by user.
extern INT16 gamemap; extern INT16 gamemap;
extern char mapmusname[7];
// ----------------xxxxxxxxxxxxxxxx = music slot extern UINT16 mapmusflags;
// -xxxxxxxxxxxxxxx---------------- = track slot #define MUSIC_TRACKMASK 0x0FFF // ----************
// x------------------------------- = reset music bit #define MUSIC_RELOADRESET 0x8000 // *---------------
extern UINT32 mapmusic; // Use other bits if necessary.
#define MUSIC_TRACKSHIFT 16
#define MUSIC_SONGMASK 0x0000FFFF
#define MUSIC_TRACKMASK 0x7FFF0000
#define MUSIC_RELOADRESET 0x80000000
extern INT16 maptol; extern INT16 maptol;
extern UINT8 globalweather; extern UINT8 globalweather;
@ -146,11 +142,13 @@ typedef struct
UINT16 xcoord[8]; UINT16 xcoord[8];
UINT16 ycoord[8]; UINT16 ycoord[8];
UINT16 picduration[8]; UINT16 picduration[8];
UINT16 musicslot;
UINT8 musicloop; UINT8 musicloop;
UINT16 textxpos; UINT16 textxpos;
UINT16 textypos; UINT16 textypos;
char musswitch[7];
UINT16 musswitchflags;
UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade
UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0 UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0
UINT8 fadeoutid; // ID of the second fade, to the new screen UINT8 fadeoutid; // ID of the second fade, to the new screen
@ -218,8 +216,8 @@ typedef struct
UINT8 actnum; ///< Act number or 0 for none. UINT8 actnum; ///< Act number or 0 for none.
UINT16 typeoflevel; ///< Combination of typeoflevel flags. UINT16 typeoflevel; ///< Combination of typeoflevel flags.
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
UINT16 musicslot; ///< Music slot number to play. 0 for no music. char musname[7]; ///< Music track to play. "" for no music.
UINT16 musicslottrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave. UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave.
INT16 skynum; ///< Sky number to use. INT16 skynum; ///< Sky number to use.

View file

@ -559,7 +559,7 @@ static void F_IntroDrawScene(void)
if (finalecount < 4) if (finalecount < 4)
S_StopMusic(); S_StopMusic();
if (finalecount == 4) if (finalecount == 4)
S_ChangeMusic(mus_stjr, false); S_ChangeMusicInternal("stjr", false);
x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(334<<FRACBITS, aspect)/2; x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(334<<FRACBITS, aspect)/2;
y = (BASEVIDHEIGHT<<FRACBITS)/2 - FixedMul(358<<FRACBITS, aspect)/2; y = (BASEVIDHEIGHT<<FRACBITS)/2 - FixedMul(358<<FRACBITS, aspect)/2;
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH1", PU_CACHE)), aspect); V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH1", PU_CACHE)), aspect);
@ -771,7 +771,7 @@ void F_IntroDrawer(void)
F_RunWipe(99,true); F_RunWipe(99,true);
} }
S_ChangeMusic(mus_read_m, false); S_ChangeMusicInternal("read_m", false);
} }
else if (intro_scenenum == 3) else if (intro_scenenum == 3)
roidtics = BASEVIDWIDTH - 64; roidtics = BASEVIDWIDTH - 64;
@ -1126,7 +1126,7 @@ void F_StartCredits(void)
CON_ClearHUD(); CON_ClearHUD();
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_credit, false); S_ChangeMusicInternal("credit", false);
finalecount = 0; finalecount = 0;
animtimer = 0; animtimer = 0;
@ -1423,7 +1423,7 @@ void F_StartTitleScreen(void)
// IWAD dependent stuff. // IWAD dependent stuff.
S_ChangeMusic(mus_titles, looptitle); S_ChangeMusicInternal("titles", looptitle);
animtimer = 0; animtimer = 0;
@ -1589,7 +1589,7 @@ void F_StartContinue(void)
// In case menus are still up?!! // In case menus are still up?!!
M_ClearMenus(true); M_ClearMenus(true);
S_ChangeMusic(mus_contsc, false); S_ChangeMusicInternal("contsc", false);
S_StopSounds(); S_StopSounds();
timetonext = TICRATE*11; timetonext = TICRATE*11;
@ -1703,8 +1703,10 @@ static void F_AdvanceToNextScene(void)
picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum]; picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum];
picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum]; picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
if (cutscenes[cutnum]->scene[scenenum].musicslot != 0) if (cutscenes[cutnum]->scene[scenenum].musswitch[0])
S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop); S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musswitch,
cutscenes[cutnum]->scene[scenenum].musswitchflags,
cutscenes[cutnum]->scene[scenenum].musicloop);
// Fade to the next // Fade to the next
dofadenow = true; dofadenow = true;
@ -1775,8 +1777,10 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
animtimer = cutscenes[cutnum]->scene[0].picduration[0]; // Picture duration animtimer = cutscenes[cutnum]->scene[0].picduration[0]; // Picture duration
stoptimer = 0; stoptimer = 0;
if (cutscenes[cutnum]->scene[scenenum].musicslot != 0) if (cutscenes[cutnum]->scene[0].musswitch[0])
S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop); S_ChangeMusic(cutscenes[cutnum]->scene[0].musswitch,
cutscenes[cutnum]->scene[0].musswitchflags,
cutscenes[cutnum]->scene[0].musicloop);
else else
S_StopMusic(); S_StopMusic();
} }

View file

@ -69,8 +69,10 @@ static void G_DoStartContinue(void);
static void G_DoContinued(void); static void G_DoContinued(void);
static void G_DoWorldDone(void); static void G_DoWorldDone(void);
char mapmusname[7]; // Music name
UINT16 mapmusflags; // Track and reset bit
INT16 gamemap = 1; INT16 gamemap = 1;
UINT32 mapmusic; // music, track, and reset bit
INT16 maptol; INT16 maptol;
UINT8 globalweather = 0; UINT8 globalweather = 0;
INT32 curWeather = PRECIP_NONE; INT32 curWeather = PRECIP_NONE;
@ -2182,12 +2184,13 @@ void G_PlayerReborn(INT32 player)
if (p-players == consoleplayer) if (p-players == consoleplayer)
{ {
if (mapmusic & MUSIC_RELOADRESET) // TODO: Might not need this here if (mapmusflags & MUSIC_RELOADRESET)
{ {
mapmusic = mapheaderinfo[gamemap-1]->musicslot strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
| (mapheaderinfo[gamemap-1]->musicslottrack << MUSIC_TRACKSHIFT); mapmusname[6] = 0;
mapmusflags = mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK;
} }
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
if (gametype == GT_COOP) if (gametype == GT_COOP)
@ -2871,7 +2874,8 @@ static void G_DoCompleted(void)
// We are committed to this map now. // We are committed to this map now.
// We may as well allocate its header if it doesn't exist // We may as well allocate its header if it doesn't exist
if(!mapheaderinfo[nextmap]) // (That is, if it's a real map)
if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
P_AllocMapHeader(nextmap); P_AllocMapHeader(nextmap);
if (skipstats) if (skipstats)
@ -3521,7 +3525,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
if (paused) if (paused)
{ {
paused = false; paused = false;
S_ResumeSound(); S_ResumeAudio();
} }
if (netgame || multiplayer) // Nice try, haxor. if (netgame || multiplayer) // Nice try, haxor.
@ -3595,7 +3599,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
globalweather = mapheaderinfo[gamemap-1]->weather; globalweather = mapheaderinfo[gamemap-1]->weather;
// Don't carry over custom music change to another map. // Don't carry over custom music change to another map.
mapmusic |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
ultimatemode = pultmode; ultimatemode = pultmode;
playerdeadview = false; playerdeadview = false;

View file

@ -1636,18 +1636,63 @@ static int lib_sStopSound(lua_State *L)
static int lib_sChangeMusic(lua_State *L) static int lib_sChangeMusic(lua_State *L)
{ {
UINT32 music_num = (UINT32)luaL_checkinteger(L, 1); #ifdef MUSICSLOT_COMPATIBILITY
const char *music_name;
UINT32 music_num;
char music_compat_name[7];
boolean looping;
player_t *player = NULL;
UINT16 music_flags = 0;
NOHUD
if (lua_isnumber(L, 1))
{
music_num = (UINT32)luaL_checkinteger(L, 1);
music_flags = (UINT16)(music_num & 0x0000FFFF);
if (music_flags && music_flags <= 1035)
snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags));
else if (music_flags && music_flags <= 1050)
strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7);
else
music_compat_name[0] = 0; // becomes empty string
music_compat_name[6] = 0;
music_name = (const char *)&music_compat_name;
music_flags = 0;
}
else
{
music_num = 0;
music_name = luaL_checkstring(L, 1);
}
looping = (boolean)lua_opttrueboolean(L, 2);
#else
const char *music_name = luaL_checkstring(L, 1);
boolean looping = (boolean)lua_opttrueboolean(L, 2); boolean looping = (boolean)lua_opttrueboolean(L, 2);
player_t *player = NULL; player_t *player = NULL;
UINT16 music_flags = 0;
NOHUD NOHUD
#endif
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{ {
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
} }
#ifdef MUSICSLOT_COMPATIBILITY
if (music_num)
music_flags = (UINT16)((music_num & 0x7FFF0000) >> 16);
else
#endif
music_flags = (UINT16)luaL_optinteger(L, 4, 0);
if (!player || P_IsLocalPlayer(player)) if (!player || P_IsLocalPlayer(player))
S_ChangeMusic(music_num, looping); S_ChangeMusic(music_name, music_flags, looping);
return 0; return 0;
} }

View file

@ -1172,10 +1172,10 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->typeoflevel); lua_pushinteger(L, header->typeoflevel);
else if (fastcmp(field,"nextlevel")) else if (fastcmp(field,"nextlevel"))
lua_pushinteger(L, header->nextlevel); lua_pushinteger(L, header->nextlevel);
else if (fastcmp(field,"musicslot")) else if (fastcmp(field,"musname"))
lua_pushinteger(L, header->musicslot); lua_pushstring(L, header->musname);
else if (fastcmp(field,"musicslottrack")) else if (fastcmp(field,"mustrack"))
lua_pushinteger(L, header->musicslottrack); lua_pushinteger(L, header->mustrack);
else if (fastcmp(field,"forcecharacter")) else if (fastcmp(field,"forcecharacter"))
lua_pushstring(L, header->forcecharacter); lua_pushstring(L, header->forcecharacter);
else if (fastcmp(field,"weather")) else if (fastcmp(field,"weather"))

View file

@ -4751,7 +4751,7 @@ static void M_SetupChoosePlayer(INT32 choice)
if (Playing() == false) if (Playing() == false)
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_chrsel, true); S_ChangeMusicInternal("chrsel", true);
} }
SP_PlayerDef.prevMenu = currentMenu; SP_PlayerDef.prevMenu = currentMenu;
@ -5202,7 +5202,7 @@ void M_DrawTimeAttackMenu(void)
lumpnum_t lumpnum; lumpnum_t lumpnum;
char beststr[40]; char beststr[40];
S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5365,7 +5365,7 @@ static void M_TimeAttack(INT32 choice)
itemOn = tastart; // "Start" is selected. itemOn = tastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true); S_ChangeMusicInternal("racent", true);
} }
// Drawing function for Nights Attack // Drawing function for Nights Attack
@ -5375,7 +5375,7 @@ void M_DrawNightsAttackMenu(void)
lumpnum_t lumpnum; lumpnum_t lumpnum;
char beststr[40]; char beststr[40];
S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5498,7 +5498,7 @@ static void M_NightsAttack(INT32 choice)
itemOn = nastart; // "Start" is selected. itemOn = nastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true); S_ChangeMusicInternal("racent", true);
} }
// Player has selected the "START" from the nights attack screen // Player has selected the "START" from the nights attack screen
@ -5732,7 +5732,7 @@ static void M_ModeAttackEndGame(INT32 choice)
itemOn = currentMenu->lastOn; itemOn = currentMenu->lastOn;
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
modeattacking = ATTACKING_NONE; modeattacking = ATTACKING_NONE;
S_ChangeMusic(mus_racent, true); S_ChangeMusicInternal("racent", true);
// Update replay availability. // Update replay availability.
CV_AddValue(&cv_nextmap, 1); CV_AddValue(&cv_nextmap, 1);
CV_AddValue(&cv_nextmap, -1); CV_AddValue(&cv_nextmap, -1);
@ -6944,7 +6944,7 @@ static void M_ToggleDigital(void)
if (nodigimusic) return; if (nodigimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_lclear, false); S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
} }
else else
@ -6971,7 +6971,7 @@ static void M_ToggleMIDI(void)
I_InitMIDIMusic(); I_InitMIDIMusic();
if (nomidimusic) return; if (nomidimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
S_ChangeMusic(mus_lclear, false); S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
} }
else else

View file

@ -3063,12 +3063,8 @@ void A_Invincibility(mobj_t *actor)
{ {
S_StopMusic(); S_StopMusic();
if (mariomode) if (mariomode)
{
S_ChangeMusic(mus_minvnc, false);
G_GhostAddColor(GHC_INVINCIBLE); G_GhostAddColor(GHC_INVINCIBLE);
} S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
else
S_ChangeMusic(mus_invinc, false);
} }
} }
@ -3104,7 +3100,7 @@ void A_SuperSneakers(mobj_t *actor)
else else
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_shoes, false); S_ChangeMusicInternal("shoes", false);
} }
} }
} }

View file

@ -2076,7 +2076,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
if (P_IsLocalPlayer(target->player) && target->player == &players[consoleplayer]) if (P_IsLocalPlayer(target->player) && target->player == &players[consoleplayer])
{ {
S_StopMusic(); // Stop the Music! Tails 03-14-2000 S_StopMusic(); // Stop the Music! Tails 03-14-2000
S_ChangeMusic(mus_gmover, false); // Yousa dead now, Okieday? Tails 03-14-2000 S_ChangeMusicInternal("gmover", false); // Yousa dead now, Okieday? Tails 03-14-2000
} }
} }
} }
@ -2464,7 +2464,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
&& player->nightstime < 10*TICRATE) && player->nightstime < 10*TICRATE)
{ {
//S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH //S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
S_ChangeMusic(mus_drown,false); S_ChangeMusicInternal("drown",false);
} }
} }
} }

View file

@ -3203,7 +3203,7 @@ static inline boolean P_NetUnArchiveMisc(void)
// tell the sound code to reset the music since we're skipping what // tell the sound code to reset the music since we're skipping what
// normally sets this flag // normally sets this flag
mapmusic |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
G_SetGamestate(READINT16(save_p)); G_SetGamestate(READINT16(save_p));

View file

@ -180,10 +180,11 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->typeoflevel = 0;
DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE); DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE);
mapheaderinfo[num]->nextlevel = (INT16)(i + 1); mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
DEH_WriteUndoline("MUSICSLOT", va("%d", mapheaderinfo[num]->musicslot), UNDO_NONE); DEH_WriteUndoline("MUSIC", mapheaderinfo[num]->musname, UNDO_NONE);
mapheaderinfo[num]->musicslot = mus_map01m + num; snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
DEH_WriteUndoline("MUSICSLOTTRACK", va("%d", mapheaderinfo[num]->musicslottrack), UNDO_NONE); mapheaderinfo[num]->musname[6] = 0;
mapheaderinfo[num]->musicslottrack = 0; DEH_WriteUndoline("MUSICTRACK", va("%d", mapheaderinfo[num]->mustrack), UNDO_NONE);
mapheaderinfo[num]->mustrack = 0;
DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE); DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE);
mapheaderinfo[num]->forcecharacter[0] = '\0'; mapheaderinfo[num]->forcecharacter[0] = '\0';
DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE); DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE);
@ -1439,6 +1440,29 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
#endif #endif
case 413: // Change music case 413: // Change music
{
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)-1;
}
M_Memcpy(process,msd->toptexture,8);
process[8] = '\0';
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
// 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->text, process+2, 6);
else // Assume it's a proper music name.
M_Memcpy(sd->text, process, 6);
sd->text[6] = 0;
break;
}
case 414: // Play SFX case 414: // Play SFX
{ {
sd->toptexture = sd->midtexture = sd->bottomtexture = 0; sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
@ -1449,13 +1473,6 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
process[8] = '\0'; process[8] = '\0';
sd->toptexture = get_number(process); sd->toptexture = get_number(process);
} }
if (sd->special == 413 && (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0'))
{
char process[8+1];
M_Memcpy(process,msd->bottomtexture,8);
process[8] = '\0';
sd->bottomtexture = get_number(process)-1;
}
break; break;
} }

View file

@ -2390,20 +2390,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// console player only unless NOCLIMB is set // console player only unless NOCLIMB is set
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)))
{ {
UINT16 musicnum = (UINT16)sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS;
UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture; UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture;
mapmusic = musicnum | (tracknum << MUSIC_TRACKSHIFT); strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
if (!(line->flags & ML_BLOCKMONSTERS)) mapmusname[6] = 0;
mapmusic |= MUSIC_RELOADRESET;
if (musicnum >= NUMMUSIC || musicnum == mus_None) mapmusflags = tracknum & MUSIC_TRACKMASK;
S_StopMusic(); if (!(line->flags & ML_BLOCKMONSTERS))
else mapmusflags |= MUSIC_RELOADRESET;
S_ChangeMusic(mapmusic, !(line->flags & ML_EFFECT4));
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4));
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior. // Except, you can use the ML_BLOCKMONSTERS flag to change this behavior.
// if (mapmusic & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn. // if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.
} }
break; break;

View file

@ -962,7 +962,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player)) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_supers, true); S_ChangeMusicInternal("supers", true);
} }
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
@ -1098,7 +1098,7 @@ void P_PlayLivesJingle(player_t *player)
if (player) if (player)
player->powers[pw_extralife] = extralifetics + 1; player->powers[pw_extralife] = extralifetics + 1;
S_StopMusic(); // otherwise it won't restart if this is done twice in a row S_StopMusic(); // otherwise it won't restart if this is done twice in a row
S_ChangeMusic(mus_xtlife, false); S_ChangeMusicInternal("xtlife", false);
} }
} }
@ -1116,21 +1116,21 @@ void P_RestoreMusic(player_t *player)
return; return;
S_SpeedMusic(1.0f); S_SpeedMusic(1.0f);
if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC))
S_ChangeMusic(mus_supers, true); S_ChangeMusicInternal("supers", true);
else if (player->powers[pw_invulnerability] > 1) else if (player->powers[pw_invulnerability] > 1)
S_ChangeMusic((mariomode) ? mus_minvnc : mus_invinc, false); S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
else if (player->powers[pw_sneakers] > 1 && !player->powers[pw_super]) else if (player->powers[pw_sneakers] > 1 && !player->powers[pw_super])
{ {
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC) if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
{ {
S_SpeedMusic(1.4f); S_SpeedMusic(1.4f);
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
else else
S_ChangeMusic(mus_shoes, true); S_ChangeMusicInternal("shoes", true);
} }
else else
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
// //
@ -2039,7 +2039,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
mobj_t *killer; mobj_t *killer;
if ((netgame || multiplayer) && P_IsLocalPlayer(player)) if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL); killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL);
killer->threshold = 42; // Special flag that it was drowning which killed you. killer->threshold = 42; // Special flag that it was drowning which killed you.
@ -2048,7 +2048,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
else if (player->powers[pw_spacetime] == 1) else if (player->powers[pw_spacetime] == 1)
{ {
if ((netgame || multiplayer) && P_IsLocalPlayer(player)) if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
P_DamageMobj(player->mo, NULL, NULL, 10000); P_DamageMobj(player->mo, NULL, NULL, 10000);
} }
@ -2083,7 +2083,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
&& player == &players[consoleplayer]) && player == &players[consoleplayer])
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_drown, false); S_ChangeMusicInternal("drown", false);
} }
if (player->powers[pw_underwater] == 25*TICRATE + 1) if (player->powers[pw_underwater] == 25*TICRATE + 1)
@ -5579,7 +5579,7 @@ static void P_NiGHTSMovement(player_t *player)
} }
else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE) else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE)
// S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH // S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
S_ChangeMusic(mus_drown,false); S_ChangeMusicInternal("drown",false);
if (player->mo->z < player->mo->floorz) if (player->mo->z < player->mo->floorz)
@ -7717,7 +7717,7 @@ static void P_DeathThink(player_t *player)
// Return to level music // Return to level music
if (netgame && player->deadtimer == gameovertics && P_IsLocalPlayer(player)) if (netgame && player->deadtimer == gameovertics && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
if (!player->mo) if (!player->mo)
@ -8703,7 +8703,7 @@ void P_PlayerThink(player_t *player)
if (countdown == 11*TICRATE - 1) if (countdown == 11*TICRATE - 1)
{ {
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
S_ChangeMusic(mus_drown, false); S_ChangeMusicInternal("drown", false);
} }
// If you've hit the countdown and you haven't made // If you've hit the countdown and you haven't made

View file

@ -141,14 +141,6 @@ typedef struct
static channel_t *channels = NULL; static channel_t *channels = NULL;
static INT32 numofchannels = 0; static INT32 numofchannels = 0;
// whether songs are mus_paused
static boolean mus_paused = 0;
// music currently being played
musicinfo_t *mus_playing = 0;
static INT32 nextcleanup;
// //
// Internals. // Internals.
// //
@ -307,47 +299,6 @@ static void SetChannelsNum(void)
channels[i].sfxinfo = 0; channels[i].sfxinfo = 0;
} }
//
// 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_SetDigMusicVolume(digMusicVolume);
S_SetMIDIMusicVolume(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"));
}
}
// Retrieve the lump number of sfx // Retrieve the lump number of sfx
// //
@ -371,12 +322,6 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx)
return W_GetNumForName("dsthok"); return W_GetNumForName("dsthok");
} }
//
// Per level startup code.
// Kills playing sounds at start of level,
// determines music if any, changes music.
//
// Stop all sounds, load level info, THEN start sounds. // Stop all sounds, load level info, THEN start sounds.
void S_StopSounds(void) void S_StopSounds(void)
{ {
@ -442,22 +387,6 @@ void S_StopSoundByNum(sfxenum_t sfxnum)
} }
} }
void S_Start(void)
{
if (mapmusic & MUSIC_RELOADRESET)
{
mapmusic = mapheaderinfo[gamemap-1]->musicslot
| (mapheaderinfo[gamemap-1]->musicslottrack << MUSIC_TRACKSHIFT);
}
mus_paused = 0;
if (cv_resetmusic.value)
S_StopMusic();
S_ChangeMusic(mapmusic, true);
nextcleanup = 15;
}
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
{ {
INT32 sep, pitch, priority, cnum; INT32 sep, pitch, priority, cnum;
@ -745,43 +674,6 @@ void S_StopSound(void *origin)
} }
} }
//
// Stop and resume music, during game PAUSE.
//
void S_PauseSound(void)
{
if (!nodigimusic)
I_PauseSong(0);
if (mus_playing && !mus_paused)
{
I_PauseSong(mus_playing->handle);
mus_paused = true;
}
// pause cd music
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
I_PauseCD();
#else
I_StopCD();
#endif
}
void S_ResumeSound(void)
{
if (!nodigimusic)
I_ResumeSong(0);
else
if (mus_playing && mus_paused)
{
I_ResumeSong(mus_playing->handle);
mus_paused = false;
}
// resume cd music
I_ResumeCD();
}
// //
// Updates music & sounds // Updates music & sounds
// //
@ -883,38 +775,6 @@ void S_UpdateSounds(void)
} }
} }
// Clean up unused data.
#if 0
{
static tic_t nextcleanup = 0;
size_t i;
sfxinfo_t *sfx;
if (!gametic) nextcleanup = 0;
if (gametic > nextcleanup)
{
for (i = 1; i < NUMSFX; i++)
{
if (S_sfx[i].usefulness == 0)
{
S_sfx[i].usefulness--;
// don't forget to unlock it !!!
// __dmpi_unlock_....
//Z_ChangeTag(S_sfx[i].data, PU_CACHE);
I_FreeSfx(S_sfx+i);
//S_sfx[i].data = 0;
CONS_Debug(DBG_GAMELOGIC, "flushed sfx %.6s\n", S_sfx[i].name);
}
}
nextcleanup = gametic + 15;
}
}
#endif
// FIXTHIS: nextcleanup is probably unused
for (cnum = 0; cnum < numofchannels; cnum++) for (cnum = 0; cnum < numofchannels; cnum++)
{ {
c = &channels[cnum]; c = &channels[cnum];
@ -984,37 +844,6 @@ void S_UpdateSounds(void)
I_UpdateSound(); I_UpdateSound();
} }
void S_SetDigMusicVolume(INT32 volume)
{
if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
CV_SetValue(&cv_digmusicvolume, volume&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
if (!nodigimusic)
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);
actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var
#ifdef DJGPPDOS
I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
#endif
I_SetMIDIMusicVolume(volume&0x1f);
}
void S_SetSfxVolume(INT32 volume) void S_SetSfxVolume(INT32 volume)
{ {
if (volume < 0 || volume > 31) if (volume < 0 || volume > 31)
@ -1031,137 +860,6 @@ void S_SetSfxVolume(INT32 volume)
#endif #endif
} }
static boolean S_MIDIMusic(musicinfo_t *music, boolean looping)
{
if (nomidimusic)
return true; // no error
if (music_disabled)
return true; // no error
// get lumpnum if neccessary
if (!music->lumpnum)
{
if (W_CheckNumForName(va("d_%s", music->name)) == LUMPERROR)
return false;
music->lumpnum = W_GetNumForName(va("d_%s", music->name));
}
// load & register it
music->data = W_CacheLumpNum(music->lumpnum, PU_MUSIC);
#if defined (macintosh) && !defined (HAVE_SDL)
music->handle = I_RegisterSong(music_num);
#else
music->handle = I_RegisterSong(music->data, W_LumpLength(music->lumpnum));
#endif
#ifdef MUSSERV
if (msg_id != -1)
{
struct musmsg msg_buffer;
msg_buffer.msg_type = 6;
memset(msg_buffer.msg_text, 0, sizeof (msg_buffer.msg_text));
sprintf(msg_buffer.msg_text, "d_%s", music->name);
msgsnd(msg_id, (struct msgbuf*)&msg_buffer, sizeof (msg_buffer.msg_text), IPC_NOWAIT);
}
#endif
// play it
if (!I_PlaySong(music->handle, looping))
return false;
mus_playing = music;
return true;
}
static boolean S_DigMusic(musicinfo_t *music, boolean looping)
{
if (nodigimusic)
return false; // try midi
if (digital_disabled)
return false; // try midi
if (!I_StartDigSong(music->name, looping))
return false;
mus_playing = music;
return true;
}
void S_ChangeMusic(UINT32 mslotnum, boolean looping)
{
musicinfo_t *music;
musicenum_t music_num = (signed)(mslotnum & MUSIC_SONGMASK);
INT32 track_num = (mslotnum & MUSIC_TRACKMASK) >> MUSIC_TRACKSHIFT;
#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X)
S_ClearSfx();
#endif
if (nomidimusic && nodigimusic)
return;
if (music_disabled && digital_disabled)
return;
// No Music
if (music_num == mus_None)
{
S_StopMusic();
return;
}
if (music_num >= NUMMUSIC)
{
CONS_Alert(CONS_ERROR, "Bad music number %d\n", music_num);
return;
}
else
music = &S_music[music_num];
if (mus_playing != music)
{
S_StopMusic(); // shutdown old music
if (!S_DigMusic(music, looping) && !S_MIDIMusic(music, looping))
{
CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), music->name);
return;
}
}
I_SetSongTrack(track_num);
}
boolean S_SpeedMusic(float speed)
{
return I_SetSongSpeed(speed);
}
void S_StopMusic(void)
{
if (!mus_playing)
return;
if (mus_paused)
I_ResumeSong(mus_playing->handle);
if (!nodigimusic)
I_StopDigSong();
S_SpeedMusic(1.0f);
I_StopSong(mus_playing->handle);
I_UnRegisterSong(mus_playing->handle);
#ifndef HAVE_SDL //SDL uses RWOPS
Z_ChangeTag(mus_playing->data, PU_CACHE);
#endif
mus_playing->data = NULL;
mus_playing = NULL;
}
void S_ClearSfx(void) void S_ClearSfx(void)
{ {
#ifndef DJGPPDOS #ifndef DJGPPDOS
@ -1452,3 +1150,285 @@ void S_StartSoundName(void *mo, const char *soundname)
S_StartSound(mo, soundnum); S_StartSound(mo, soundnum);
} }
/// ------------------------
/// Music
/// ------------------------
#ifdef MUSICSLOT_COMPATIBILITY
const char *compat_special_music_slots[16] =
{
"titles", // 1036 title screen
"read_m", // 1037 intro
"lclear", // 1038 level clear
"invinc", // 1039 invincibility
"shoes", // 1040 super sneakers
"minvnc", // 1041 Mario invincibility
"drown", // 1042 drowning
"gmover", // 1043 game over
"xtlife", // 1044 extra life
"contsc", // 1045 continue screen
"supers", // 1046 Super Sonic
"chrsel", // 1047 character select
"credit", // 1048 credits
"racent", // 1049 Race Results
"stjr", // 1050 Sonic Team Jr. Presents
""
};
#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 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 S_MIDIMusic(const char *mname, boolean looping)
{
lumpnum_t mlumpnum;
void *mdata;
INT32 mhandle;
if (nomidimusic || music_disabled)
return false; // didn't search.
if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR)
return false;
mlumpnum = W_GetNumForName(va("d_%s", mname));
// load & register it
mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC);
mhandle = I_RegisterSong(mdata, W_LumpLength(mlumpnum));
#ifdef MUSSERV
if (msg_id != -1)
{
struct musmsg msg_buffer;
msg_buffer.msg_type = 6;
memset(msg_buffer.msg_text, 0, sizeof (msg_buffer.msg_text));
sprintf(msg_buffer.msg_text, "d_%s", mname);
msgsnd(msg_id, (struct msgbuf*)&msg_buffer, sizeof (msg_buffer.msg_text), IPC_NOWAIT);
}
#endif
// play it
if (!I_PlaySong(mhandle, looping))
return false;
strncpy(music_name, mname, 7);
music_name[6] = 0;
music_lumpnum = mlumpnum;
music_data = mdata;
music_handle = mhandle;
return true;
}
static boolean S_DigMusic(const char *mname, boolean looping)
{
if (nodigimusic || digital_disabled)
return false; // try midi
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;
}
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
{
#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X)
S_ClearSfx();
#endif
if ((nomidimusic || music_disabled) && (nodigimusic || digital_disabled))
return;
// No Music (empty string)
if (mmusic[0] == 0)
{
S_StopMusic();
return;
}
if (strncmp(music_name, mmusic, 6))
{
S_StopMusic(); // shutdown old music
if (!S_DigMusic(mmusic, looping) && !S_MIDIMusic(mmusic, looping))
{
CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic);
return;
}
}
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();
S_SpeedMusic(1.0f);
I_StopSong(music_handle);
I_UnRegisterSong(music_handle);
#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)
{
if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
CV_SetValue(&cv_digmusicvolume, volume&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
if (!nodigimusic)
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);
actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var
#ifdef DJGPPDOS
I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
#endif
I_SetMIDIMusicVolume(volume&0x1f);
}
/// ------------------------
/// 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_SetDigMusicVolume(digMusicVolume);
S_SetMIDIMusicVolume(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,
// determines music if any, changes music.
//
void S_Start(void)
{
if (mapmusflags & MUSIC_RELOADRESET)
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0;
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(0);
if (music_playing && !mus_paused)
{
I_PauseSong(music_handle);
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(0);
else
if (music_playing && mus_paused)
{
I_ResumeSong(music_handle);
mus_paused = false;
}
// resume cd music
I_ResumeCD();
}

View file

@ -48,9 +48,6 @@ typedef enum
extern consvar_t play_mode; extern consvar_t play_mode;
#endif #endif
//in case you're wondering why: I need to define this as extern so P_RestoreMusic can get to it so we don't do stupid song/speed changes
extern musicinfo_t *mus_playing;
typedef enum typedef enum
{ {
SF_TOTALLYSINGLE = 1, // Only play one of these sounds at a time...GLOBALLY SF_TOTALLYSINGLE = 1, // Only play one of these sounds at a time...GLOBALLY
@ -100,11 +97,12 @@ void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume);
// Stop sound for thing at <origin> // Stop sound for thing at <origin>
void S_StopSound(void *origin); void S_StopSound(void *origin);
// Start music using <music_id> from sounds.h, and set whether looping // Start music track, arbitrary, given its name, and set whether looping
// note: music slot is first 16 bits for songnum, // note: music flags 12 bits for tracknum (gme, other formats with more than one track)
// next 15 bits for tracknum (gme, other formats with more than one track) // 13-15 aren't used yet
// and the last bit we ignore (internal game flag for resetting music on reload) // and the last bit we ignore (internal game flag for resetting music on reload)
void S_ChangeMusic(UINT32 mslotnum, boolean looping); #define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b)
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping);
// Set Speed of Music // Set Speed of Music
boolean S_SpeedMusic(float speed); boolean S_SpeedMusic(float speed);
@ -113,8 +111,8 @@ boolean S_SpeedMusic(float speed);
void S_StopMusic(void); void S_StopMusic(void);
// Stop and resume music, during game PAUSE. // Stop and resume music, during game PAUSE.
void S_PauseSound(void); void S_PauseAudio(void);
void S_ResumeSound(void); void S_ResumeAudio(void);
// //
// Updates music & sounds // Updates music & sounds
@ -141,4 +139,10 @@ void S_StopSoundByNum(sfxenum_t sfxnum);
#define S_StartScreamSound S_StartSound #define S_StartScreamSound S_StartSound
#endif #endif
#ifdef MUSICSLOT_COMPATIBILITY
// For compatibility with code/scripts relying on older versions
// This is a list of all the "special" slot names and their associated numbers
const char *compat_special_music_slots[16];
#endif
#endif #endif

View file

@ -395,6 +395,7 @@ void I_FreeSfx(sfxinfo_t *sfx)
if (sfx->data) if (sfx->data)
Mix_FreeChunk(sfx->data); Mix_FreeChunk(sfx->data);
sfx->data = NULL; sfx->data = NULL;
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)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -632,7 +632,7 @@ void Y_Ticker(void)
boolean anybonuses = false; boolean anybonuses = false;
if (!intertic) // first time only if (!intertic) // first time only
S_ChangeMusic(mus_lclear, false); // don't loop it S_ChangeMusicInternal("lclear", false); // don't loop it
if (intertic < TICRATE) // one second pause before tally begins if (intertic < TICRATE) // one second pause before tally begins
return; return;
@ -693,7 +693,7 @@ void Y_Ticker(void)
if (!intertic) // first time only if (!intertic) // first time only
{ {
S_ChangeMusic(mus_lclear, false); // don't loop it S_ChangeMusicInternal("lclear", false); // don't loop it
tallydonetic = 0; tallydonetic = 0;
} }
@ -754,7 +754,7 @@ void Y_Ticker(void)
else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match
{ {
if (!intertic) // first time only if (!intertic) // first time only
S_ChangeMusic(mus_racent, true); // loop it S_ChangeMusicInternal("racent", true); // loop it
// If a player has left or joined, recalculate scores. // If a player has left or joined, recalculate scores.
if (data.match.numplayers != D_NumPlayers()) if (data.match.numplayers != D_NumPlayers())
@ -763,7 +763,7 @@ void Y_Ticker(void)
else if (intertype == int_race || intertype == int_classicrace) // race else if (intertype == int_race || intertype == int_classicrace) // race
{ {
if (!intertic) // first time only if (!intertic) // first time only
S_ChangeMusic(mus_racent, true); // loop it S_ChangeMusicInternal("racent", true); // loop it
// Don't bother recalcing for race. It doesn't make as much sense. // Don't bother recalcing for race. It doesn't make as much sense.
} }