2020-09-28 04:15:06 +02:00
|
|
|
#define MUSIC_DEFINITION
|
2020-07-19 21:43:29 +02:00
|
|
|
#include "Music.h"
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
#include <SDL.h>
|
|
|
|
#include <stdio.h>
|
2020-07-19 21:43:29 +02:00
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
#include "BinaryBlob.h"
|
2020-04-04 00:37:59 +02:00
|
|
|
#include "Map.h"
|
2020-07-19 21:05:41 +02:00
|
|
|
#include "UtilityClass.h"
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
static void songend(void);
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
musicclass::musicclass(void)
|
Don't reset entire musicclass when mounting and unmounting assets
musicclass::init() re-initializes every attribute of musicclass
unnecessarily, when initialization should be put in a constructor
instead. This is bad, because music.init() gets called whenever we enter
and exit a custom level that has assets.
Otherwise, this would result in a bug where music.usingmmmmmm would be
reset, causing you to revert to PPPPPP on the title screen whenever you
enter a level with MMMMMM selected and exit it.
This also causes a confusing desync between game.usingmmmmmm and
music.usingmmmmmm since the values of the two variables are now
different (these duplicate variables should probably be removed, too,
and a lot of other duplicate variables like these exist, too, which are
a real headache). Which means despite MMMMMM playing on the title
screen, exiting the game and re-launching it will play PPPPPP instead.
What's even more is that going to game options and switching to PPPPPP
will play PPPPPP, but afterwards launching and re-entering will play
MMMMMM. Again, having duplicate variables is very bad, and should
probably be fixed, but that's a separate patch.
2020-11-13 00:55:58 +01:00
|
|
|
{
|
|
|
|
safeToProcessMusic= false;
|
|
|
|
m_doFadeInVol = false;
|
|
|
|
musicVolume = MIX_MAX_VOLUME;
|
|
|
|
FadeVolAmountPerFrame = 0;
|
|
|
|
|
|
|
|
currentsong = 0;
|
|
|
|
nicechange = -1;
|
|
|
|
nicefade = false;
|
|
|
|
resumesong = 0;
|
|
|
|
quick_fade = true;
|
|
|
|
|
|
|
|
songStart = 0;
|
|
|
|
songEnd = 0;
|
|
|
|
|
|
|
|
Mix_HookMusicFinished(&songend);
|
|
|
|
|
|
|
|
usingmmmmmm = false;
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void musicclass::init(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-06-07 21:49:18 +02:00
|
|
|
soundTracks.push_back(SoundTrack( "sounds/jump.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/jump2.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/hurt.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/souleyeminijingle.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/coin.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/save.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/crumble.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/vanish.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/blip.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/preteleport.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/teleport.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/crew1.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/crew2.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/crew3.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/crew4.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/crew5.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/crew6.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/terminal.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/gamesaved.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/crashing.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/blip2.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/countdown.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/go.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/crash.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/combine.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/newrecord.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/trophy.wav" ));
|
|
|
|
soundTracks.push_back(SoundTrack( "sounds/rescue.wav" ));
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
#ifdef VVV_COMPILEMUSIC
|
|
|
|
binaryBlob musicWriteBlob;
|
2021-02-16 01:38:10 +01:00
|
|
|
#define FOREACH_TRACK(blob, track_name) blob.AddFileToBinaryBlob(track_name);
|
|
|
|
TRACK_NAMES(musicWriteBlob)
|
2020-07-01 00:17:02 +02:00
|
|
|
#undef FOREACH_TRACK
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
musicWriteBlob.writeBinaryBlob("data/BinaryMusic.vvv");
|
2021-02-16 02:44:19 +01:00
|
|
|
musicWriteBlob.clear();
|
2020-01-01 21:29:24 +01:00
|
|
|
#endif
|
|
|
|
|
2020-07-01 02:08:37 +02:00
|
|
|
num_mmmmmm_tracks = 0;
|
|
|
|
num_pppppp_tracks = 0;
|
|
|
|
|
Separate musicReadBlob into mmmmmm_blob and pppppp_blob
musicReadBlob was used for both MMMMMM and PPPPPP soundtracks. This
causes a memory leak if you have mmmmmm.vvv installed, because the
pointers holding each allocated block of MMMMMM would be lost when
PPPPPP got loaded. Valgrind complains about this memory leak.
This is in contrast to 2.2 and previous behavior, where musicReadBlob
was only a temporary object instead of being held in musicclass.
However, this wasn't really a memory leak (moreso something that just
didn't get cleaned up when closing the game), but it did get turned into
a leak when per-level assets mounting and unmounting got introduced in
2.3 (loading a level with custom assets after starting the game with an
mmmmmm.vvv, or exiting out of a level that had an mmmmmm.vvv, would
cause the game to leak memory). Leo recognized this, and moved
musicReadBlob onto musicclass in a separate 2.3 PR, but either he didn't
think about what was happening here too closely, or he didn't use
Valgrind, because he forgot about the memory leak caused by re-using the
same binaryBlob for PPPPPP and MMMMMM.
So instead, just use two different binaryBlob objects for MMMMMM and
PPPPPP. That way, no memory leaks happen.
2021-02-16 01:42:58 +01:00
|
|
|
if (!mmmmmm_blob.unPackBinary("mmmmmm.vvv"))
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
mmmmmm = false;
|
|
|
|
usingmmmmmm=false;
|
Separate musicReadBlob into mmmmmm_blob and pppppp_blob
musicReadBlob was used for both MMMMMM and PPPPPP soundtracks. This
causes a memory leak if you have mmmmmm.vvv installed, because the
pointers holding each allocated block of MMMMMM would be lost when
PPPPPP got loaded. Valgrind complains about this memory leak.
This is in contrast to 2.2 and previous behavior, where musicReadBlob
was only a temporary object instead of being held in musicclass.
However, this wasn't really a memory leak (moreso something that just
didn't get cleaned up when closing the game), but it did get turned into
a leak when per-level assets mounting and unmounting got introduced in
2.3 (loading a level with custom assets after starting the game with an
mmmmmm.vvv, or exiting out of a level that had an mmmmmm.vvv, would
cause the game to leak memory). Leo recognized this, and moved
musicReadBlob onto musicclass in a separate 2.3 PR, but either he didn't
think about what was happening here too closely, or he didn't use
Valgrind, because he forgot about the memory leak caused by re-using the
same binaryBlob for PPPPPP and MMMMMM.
So instead, just use two different binaryBlob objects for MMMMMM and
PPPPPP. That way, no memory leaks happen.
2021-02-16 01:42:58 +01:00
|
|
|
bool ohCrap = pppppp_blob.unPackBinary("vvvvvvmusic.vvv");
|
2020-01-01 21:29:24 +01:00
|
|
|
SDL_assert(ohCrap && "Music not found!");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mmmmmm = true;
|
2020-07-01 00:17:02 +02:00
|
|
|
int index;
|
|
|
|
SDL_RWops *rw;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-02-16 01:38:10 +01:00
|
|
|
#define FOREACH_TRACK(blob, track_name) \
|
|
|
|
index = blob.getIndex(track_name); \
|
|
|
|
if (index >= 0 && index < blob.max_headers) \
|
2020-08-14 11:02:16 +02:00
|
|
|
{ \
|
2021-02-23 05:21:12 +01:00
|
|
|
rw = SDL_RWFromConstMem(blob.getAddress(index), blob.getSize(index)); \
|
2020-08-14 11:23:41 +02:00
|
|
|
if (rw == NULL) \
|
|
|
|
{ \
|
|
|
|
printf("Unable to read music file header: %s\n", SDL_GetError()); \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
musicTracks.push_back(MusicTrack( rw )); \
|
|
|
|
} \
|
2020-08-14 11:02:16 +02:00
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Separate musicReadBlob into mmmmmm_blob and pppppp_blob
musicReadBlob was used for both MMMMMM and PPPPPP soundtracks. This
causes a memory leak if you have mmmmmm.vvv installed, because the
pointers holding each allocated block of MMMMMM would be lost when
PPPPPP got loaded. Valgrind complains about this memory leak.
This is in contrast to 2.2 and previous behavior, where musicReadBlob
was only a temporary object instead of being held in musicclass.
However, this wasn't really a memory leak (moreso something that just
didn't get cleaned up when closing the game), but it did get turned into
a leak when per-level assets mounting and unmounting got introduced in
2.3 (loading a level with custom assets after starting the game with an
mmmmmm.vvv, or exiting out of a level that had an mmmmmm.vvv, would
cause the game to leak memory). Leo recognized this, and moved
musicReadBlob onto musicclass in a separate 2.3 PR, but either he didn't
think about what was happening here too closely, or he didn't use
Valgrind, because he forgot about the memory leak caused by re-using the
same binaryBlob for PPPPPP and MMMMMM.
So instead, just use two different binaryBlob objects for MMMMMM and
PPPPPP. That way, no memory leaks happen.
2021-02-16 01:42:58 +01:00
|
|
|
TRACK_NAMES(mmmmmm_blob)
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-08-14 11:02:16 +02:00
|
|
|
num_mmmmmm_tracks += musicTracks.size();
|
2020-07-01 02:08:37 +02:00
|
|
|
|
2021-02-18 08:48:41 +01:00
|
|
|
size_t index_ = 0;
|
|
|
|
while (mmmmmm_blob.nextExtra(&index_))
|
2020-07-01 00:35:50 +02:00
|
|
|
{
|
2021-02-23 05:21:12 +01:00
|
|
|
rw = SDL_RWFromConstMem(mmmmmm_blob.getAddress(index_), mmmmmm_blob.getSize(index_));
|
2020-07-01 00:35:50 +02:00
|
|
|
musicTracks.push_back(MusicTrack( rw ));
|
2020-07-01 02:08:37 +02:00
|
|
|
|
|
|
|
num_mmmmmm_tracks++;
|
2021-02-18 08:48:41 +01:00
|
|
|
index_++;
|
2020-07-01 00:35:50 +02:00
|
|
|
}
|
|
|
|
|
Separate musicReadBlob into mmmmmm_blob and pppppp_blob
musicReadBlob was used for both MMMMMM and PPPPPP soundtracks. This
causes a memory leak if you have mmmmmm.vvv installed, because the
pointers holding each allocated block of MMMMMM would be lost when
PPPPPP got loaded. Valgrind complains about this memory leak.
This is in contrast to 2.2 and previous behavior, where musicReadBlob
was only a temporary object instead of being held in musicclass.
However, this wasn't really a memory leak (moreso something that just
didn't get cleaned up when closing the game), but it did get turned into
a leak when per-level assets mounting and unmounting got introduced in
2.3 (loading a level with custom assets after starting the game with an
mmmmmm.vvv, or exiting out of a level that had an mmmmmm.vvv, would
cause the game to leak memory). Leo recognized this, and moved
musicReadBlob onto musicclass in a separate 2.3 PR, but either he didn't
think about what was happening here too closely, or he didn't use
Valgrind, because he forgot about the memory leak caused by re-using the
same binaryBlob for PPPPPP and MMMMMM.
So instead, just use two different binaryBlob objects for MMMMMM and
PPPPPP. That way, no memory leaks happen.
2021-02-16 01:42:58 +01:00
|
|
|
bool ohCrap = pppppp_blob.unPackBinary("vvvvvvmusic.vvv");
|
2020-01-01 21:29:24 +01:00
|
|
|
SDL_assert(ohCrap && "Music not found!");
|
|
|
|
}
|
|
|
|
|
2020-07-01 00:17:02 +02:00
|
|
|
int index;
|
|
|
|
SDL_RWops *rw;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Separate musicReadBlob into mmmmmm_blob and pppppp_blob
musicReadBlob was used for both MMMMMM and PPPPPP soundtracks. This
causes a memory leak if you have mmmmmm.vvv installed, because the
pointers holding each allocated block of MMMMMM would be lost when
PPPPPP got loaded. Valgrind complains about this memory leak.
This is in contrast to 2.2 and previous behavior, where musicReadBlob
was only a temporary object instead of being held in musicclass.
However, this wasn't really a memory leak (moreso something that just
didn't get cleaned up when closing the game), but it did get turned into
a leak when per-level assets mounting and unmounting got introduced in
2.3 (loading a level with custom assets after starting the game with an
mmmmmm.vvv, or exiting out of a level that had an mmmmmm.vvv, would
cause the game to leak memory). Leo recognized this, and moved
musicReadBlob onto musicclass in a separate 2.3 PR, but either he didn't
think about what was happening here too closely, or he didn't use
Valgrind, because he forgot about the memory leak caused by re-using the
same binaryBlob for PPPPPP and MMMMMM.
So instead, just use two different binaryBlob objects for MMMMMM and
PPPPPP. That way, no memory leaks happen.
2021-02-16 01:42:58 +01:00
|
|
|
TRACK_NAMES(pppppp_blob)
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-07-01 00:17:02 +02:00
|
|
|
#undef FOREACH_TRACK
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-08-14 11:02:16 +02:00
|
|
|
num_pppppp_tracks += musicTracks.size() - num_mmmmmm_tracks;
|
2020-07-01 02:08:37 +02:00
|
|
|
|
2021-02-18 08:48:41 +01:00
|
|
|
size_t index_ = 0;
|
|
|
|
while (pppppp_blob.nextExtra(&index_))
|
2020-07-01 00:35:50 +02:00
|
|
|
{
|
2021-02-23 05:21:12 +01:00
|
|
|
rw = SDL_RWFromConstMem(pppppp_blob.getAddress(index_), pppppp_blob.getSize(index_));
|
2020-07-01 00:35:50 +02:00
|
|
|
musicTracks.push_back(MusicTrack( rw ));
|
2020-07-01 02:08:37 +02:00
|
|
|
|
|
|
|
num_pppppp_tracks++;
|
2021-02-18 08:48:41 +01:00
|
|
|
index_++;
|
2020-07-01 00:35:50 +02:00
|
|
|
}
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
static void songend(void)
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
{
|
2020-09-28 04:15:06 +02:00
|
|
|
extern musicclass music;
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
music.songEnd = SDL_GetPerformanceCounter();
|
2021-03-10 06:49:07 +01:00
|
|
|
music.resumesong = music.currentsong;
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
music.currentsong = -1;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void musicclass::destroy(void)
|
2021-02-16 01:24:21 +01:00
|
|
|
{
|
|
|
|
for (size_t i = 0; i < soundTracks.size(); ++i)
|
|
|
|
{
|
|
|
|
Mix_FreeChunk(soundTracks[i].sound);
|
|
|
|
}
|
|
|
|
soundTracks.clear();
|
|
|
|
|
|
|
|
// Before we free all the music: stop playing music, else SDL2_mixer
|
|
|
|
// will call SDL_Delay() if we are fading, resulting in no-draw frames
|
|
|
|
Mix_HaltMusic();
|
|
|
|
|
|
|
|
for (size_t i = 0; i < musicTracks.size(); ++i)
|
|
|
|
{
|
|
|
|
Mix_FreeMusic(musicTracks[i].m_music);
|
|
|
|
}
|
|
|
|
musicTracks.clear();
|
|
|
|
|
Separate musicReadBlob into mmmmmm_blob and pppppp_blob
musicReadBlob was used for both MMMMMM and PPPPPP soundtracks. This
causes a memory leak if you have mmmmmm.vvv installed, because the
pointers holding each allocated block of MMMMMM would be lost when
PPPPPP got loaded. Valgrind complains about this memory leak.
This is in contrast to 2.2 and previous behavior, where musicReadBlob
was only a temporary object instead of being held in musicclass.
However, this wasn't really a memory leak (moreso something that just
didn't get cleaned up when closing the game), but it did get turned into
a leak when per-level assets mounting and unmounting got introduced in
2.3 (loading a level with custom assets after starting the game with an
mmmmmm.vvv, or exiting out of a level that had an mmmmmm.vvv, would
cause the game to leak memory). Leo recognized this, and moved
musicReadBlob onto musicclass in a separate 2.3 PR, but either he didn't
think about what was happening here too closely, or he didn't use
Valgrind, because he forgot about the memory leak caused by re-using the
same binaryBlob for PPPPPP and MMMMMM.
So instead, just use two different binaryBlob objects for MMMMMM and
PPPPPP. That way, no memory leaks happen.
2021-02-16 01:42:58 +01:00
|
|
|
pppppp_blob.clear();
|
|
|
|
mmmmmm_blob.clear();
|
2021-02-16 01:24:21 +01:00
|
|
|
}
|
|
|
|
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
void musicclass::play(int t, const double position_sec /*= 0.0*/, const int fadein_ms /*= 3000*/)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-07-01 02:08:37 +02:00
|
|
|
if (mmmmmm && usingmmmmmm)
|
|
|
|
{
|
2020-08-14 11:15:09 +02:00
|
|
|
// Don't conjoin this if-statement with the above one...
|
|
|
|
if (num_mmmmmm_tracks > 0)
|
|
|
|
{
|
|
|
|
t %= num_mmmmmm_tracks;
|
|
|
|
}
|
2020-07-01 02:08:37 +02:00
|
|
|
}
|
2020-08-14 11:15:09 +02:00
|
|
|
else if (num_pppppp_tracks > 0)
|
2020-07-01 02:08:37 +02:00
|
|
|
{
|
|
|
|
t %= num_pppppp_tracks;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-01-04 08:20:35 +01:00
|
|
|
if (mmmmmm && !usingmmmmmm)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-07-01 02:08:37 +02:00
|
|
|
t += num_mmmmmm_tracks;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2021-01-04 08:20:35 +01:00
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
safeToProcessMusic = true;
|
2020-10-11 08:42:02 +02:00
|
|
|
musicVolume = MIX_MAX_VOLUME;
|
2021-01-04 08:20:35 +01:00
|
|
|
|
2021-01-16 19:09:16 +01:00
|
|
|
if (currentsong == t && Mix_FadingMusic() != MIX_FADING_OUT)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2021-01-04 08:22:00 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-01-04 08:23:46 +01:00
|
|
|
currentsong = t;
|
|
|
|
|
2021-01-04 08:26:05 +01:00
|
|
|
if (t == -1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!INBOUNDS_VEC(t, musicTracks))
|
|
|
|
{
|
|
|
|
puts("play() out-of-bounds!");
|
|
|
|
currentsong = -1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (currentsong == 0 || currentsong == 7 || (!map.custommode && (currentsong == 0+num_mmmmmm_tracks || currentsong == 7+num_mmmmmm_tracks)))
|
|
|
|
{
|
|
|
|
// Level Complete theme, no fade in or repeat
|
|
|
|
if (Mix_FadeInMusicPos(musicTracks[t].m_music, 0, 0, position_sec) == -1)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2021-01-04 08:26:05 +01:00
|
|
|
printf("Mix_FadeInMusicPos: %s\n", Mix_GetError());
|
2021-01-04 08:23:46 +01:00
|
|
|
}
|
2021-01-04 08:26:05 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Mix_FadingMusic() == MIX_FADING_OUT)
|
|
|
|
{
|
|
|
|
// We're already fading out
|
|
|
|
nicechange = t;
|
|
|
|
nicefade = true;
|
|
|
|
currentsong = -1;
|
2021-01-04 08:20:35 +01:00
|
|
|
|
2021-01-04 08:26:05 +01:00
|
|
|
if (quick_fade)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2021-01-04 08:26:05 +01:00
|
|
|
Mix_FadeOutMusic(500); // fade out quicker
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-01-04 08:26:05 +01:00
|
|
|
quick_fade = true;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2021-01-04 08:26:05 +01:00
|
|
|
}
|
|
|
|
else if (Mix_FadeInMusicPos(musicTracks[t].m_music, -1, fadein_ms, position_sec) == -1)
|
|
|
|
{
|
|
|
|
printf("Mix_FadeInMusicPos: %s\n", Mix_GetError());
|
|
|
|
}
|
|
|
|
}
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
|
2021-01-04 08:26:05 +01:00
|
|
|
songStart = SDL_GetPerformanceCounter();
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
void musicclass::resume(const int fadein_ms /*= 0*/)
|
|
|
|
{
|
|
|
|
const double offset = static_cast<double>(songEnd - songStart);
|
|
|
|
const double frequency = static_cast<double>(SDL_GetPerformanceFrequency());
|
|
|
|
|
|
|
|
const double position_sec = offset / frequency;
|
|
|
|
|
|
|
|
play(resumesong, position_sec, fadein_ms);
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void musicclass::fadein(void)
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
{
|
|
|
|
resume(3000); // 3000 ms fadein
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void musicclass::haltdasmusik(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
Mix_HaltMusic();
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void musicclass::silencedasmusik(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
musicVolume = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void musicclass::fadeMusicVolumeIn(int ms)
|
|
|
|
{
|
|
|
|
m_doFadeInVol = true;
|
|
|
|
FadeVolAmountPerFrame = MIX_MAX_VOLUME / (ms / 33);
|
|
|
|
}
|
|
|
|
|
2020-11-06 09:51:04 +01:00
|
|
|
void musicclass::fadeout(const bool quick_fade_ /*= true*/)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
Mix_FadeOutMusic(2000);
|
Fix resumemusic/musicfadein not working
It seems like they were unfinished. This commit makes them properly
work.
When a track is stopped with stopmusic() or musicfadeout(),
resumemusic() will resume from where the track stopped. musicfadein()
does the same but does it with a gradual fade instead of suddenly
playing it at full volume.
I changed several interfaces around for this. First, setting currentsong
to -1 when music is stopped is handled in the hook callback that gets
called by SDL_mixer whenever the music stops. Otherwise, it'd be
problematic if currentsong was set to -1 when the song starts fading out
instead of when the song actually ends.
Also, music.play() has a few optional arguments now, to reduce the
copying-and-pasting of music code.
Lastly, we have to roll our own tracker of music length by using
SDL_GetPerformanceCounter(), because there's no way to get the music
position if a song fades out. (We could implicitly keep the music
position if we abruptly stopped the song using Mix_PauseMusic(), and
resume it using Mix_ResumeMusic(), but ignoring the fact that those two
functions are also used on the unfocus-pause (which, as it turns out, is
basically a non-issue because the unfocus-pause can use some other
functions), there's no equivalent for fading out, i.e. there's no
"fade out and pause when it fully fades out" function in SDL_mixer.) And
then we have to account for the unfocus-pause in our manual tracker.
Other than that, these commands are now fully functional.
2020-06-27 10:31:09 +02:00
|
|
|
resumesong = currentsong;
|
2020-11-06 09:51:04 +01:00
|
|
|
quick_fade = quick_fade_;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void musicclass::processmusicfadein(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
musicVolume += FadeVolAmountPerFrame;
|
|
|
|
if (musicVolume >= MIX_MAX_VOLUME)
|
|
|
|
{
|
|
|
|
m_doFadeInVol = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void musicclass::processmusic(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
if(!safeToProcessMusic)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-11-06 09:20:58 +01:00
|
|
|
if (nicefade && Mix_PlayingMusic() == 0)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
play(nicechange);
|
2020-11-06 09:20:58 +01:00
|
|
|
nicechange = -1;
|
|
|
|
nicefade = false;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if(m_doFadeInVol)
|
|
|
|
{
|
|
|
|
processmusicfadein();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void musicclass::niceplay(int t)
|
|
|
|
{
|
|
|
|
// important: do nothing if the correct song is playing!
|
2020-11-06 09:04:57 +01:00
|
|
|
if((!mmmmmm && currentsong!=t) || (mmmmmm && usingmmmmmm && currentsong!=t) || (mmmmmm && !usingmmmmmm && currentsong!=t+num_mmmmmm_tracks))
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-01-23 01:26:29 +01:00
|
|
|
if(currentsong!=-1)
|
|
|
|
{
|
2020-11-06 09:51:04 +01:00
|
|
|
fadeout(false);
|
2020-01-23 01:26:29 +01:00
|
|
|
}
|
2020-11-06 09:20:58 +01:00
|
|
|
nicefade = true;
|
2020-01-01 21:29:24 +01:00
|
|
|
nicechange = t;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void musicclass::changemusicarea(int x, int y)
|
|
|
|
{
|
|
|
|
switch(musicroom(x, y))
|
|
|
|
{
|
|
|
|
case musicroom(11, 4):
|
|
|
|
niceplay(2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case musicroom(2, 4):
|
|
|
|
case musicroom(7, 15):
|
|
|
|
niceplay(3);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case musicroom(18, 1):
|
|
|
|
case musicroom(15, 0):
|
|
|
|
niceplay(12);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case musicroom(0, 0):
|
|
|
|
case musicroom(0, 16):
|
|
|
|
case musicroom(2, 11):
|
|
|
|
case musicroom(7, 9):
|
|
|
|
case musicroom(8, 11):
|
|
|
|
case musicroom(13, 2):
|
|
|
|
case musicroom(17, 12):
|
|
|
|
case musicroom(14, 19):
|
|
|
|
case musicroom(17, 17):
|
|
|
|
niceplay(4);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
niceplay(1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-02 01:36:35 +02:00
|
|
|
void musicclass::playef(int t)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-09-10 06:58:59 +02:00
|
|
|
if (!INBOUNDS_VEC(t, soundTracks))
|
Add bounds checks to script commands that didn't have them
Continuing from #280, another potential source of out-of-bounds indexing
(and thus, Undefined Behavior badness) comes from script commands. A
majority of them don't do any input validation at all, which means the
potential for out-of-bounds indexing and segfaulting in custom levels.
So it's always good to add bounds checks to them.
Interesting note, the only existing command that has bounds checks is
the flag() command. That means you can't turn out-of-bounds flags on or
off. But there's no bounds checks for ifflag(), or customifflag(), which
means you CAN index out-of-bounds with those commands! That's a bit bad
to do, so.
Also, I decided to add the bounds checks for playef() at the
musicclass::playef() level, instead of just the level of the playef()
command. I don't know of any other cases outside of the command where
musicclass::playef() will index out of bounds, but musicclass is the one
containing the indexed vector anyway, I wanted to cover more cases, and
it's better to be safe than sorry.
2020-06-13 06:55:41 +02:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
int channel;
|
|
|
|
|
|
|
|
channel = Mix_PlayChannel(-1, soundTracks[t].sound, 0);
|
|
|
|
if(channel == -1)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Unable to play WAV file: %s\n", Mix_GetError());
|
|
|
|
}
|
|
|
|
}
|