2020-01-01 21:29:24 +01:00
|
|
|
#ifndef MUSIC_H
|
|
|
|
#define MUSIC_H
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
2020-07-19 21:43:29 +02:00
|
|
|
#include "BinaryBlob.h"
|
|
|
|
#include "SoundSystem.h"
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
#define musicroom(rx, ry) ((rx) + ((ry) * 20))
|
|
|
|
|
|
|
|
class musicclass
|
|
|
|
{
|
|
|
|
public:
|
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
|
|
|
musicclass();
|
Allow using help/graphics/music/game/key/map/obj everywhere
This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and
`obj` essentially static global objects that can be used everywhere.
This is useful in case we ever need to add a new function in the future,
so we don't have to bother with passing a new argument in which means we
have to pass a new argument in to the function that calls that function
which means having to pass a new argument into the function that calls
THAT function, etc. which is a real headache when working on fan mods of
the source code.
Note that this changes NONE of the existing function signatures, it
merely just makes those variables accessible everywhere in the same way
`script` and `ed` are.
Also note that some classes had to be initialized after the filesystem
was initialized, but C++ would keep initializing them before the
filesystem got initialized, because I *had* to put them at the top of
`main.cpp`, or else they wouldn't be global variables.
The only way to work around this was to use entityclass's initialization
style (which I'm pretty sure entityclass of all things doesn't need to
be initialized this way), where you actually initialize the class in an
`init()` function, and so then you do `graphics.init()` after the
filesystem initialization, AFTER doing `Graphics graphics` up at the
top.
I've had to do this for `graphics` (but only because its child
GraphicsResources `grphx` needs to be initialized this way), `music`,
and `game`. I don't think this will affect anything. Other than that,
`help`, `key`, and `map` are still using the C++-intended method of
having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
|
|
|
void init();
|
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 play(int t, const double position_sec = 0.0, const int fadein_ms = 3000);
|
|
|
|
void resume(const int fadein_ms = 0);
|
2020-01-01 21:29:24 +01:00
|
|
|
void haltdasmusik();
|
|
|
|
void silencedasmusik();
|
|
|
|
void fadeMusicVolumeIn(int ms);
|
2020-11-06 09:51:04 +01:00
|
|
|
void fadeout(const bool quick_fade_ = true);
|
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 fadein();
|
2020-01-01 21:29:24 +01:00
|
|
|
void processmusicfadein();
|
|
|
|
void processmusic();
|
|
|
|
void niceplay(int t);
|
|
|
|
|
|
|
|
void changemusicarea(int x, int y);
|
|
|
|
|
2020-06-27 10:40:58 +02:00
|
|
|
int currentsong;
|
2020-01-01 21:29:24 +01:00
|
|
|
int resumesong;
|
|
|
|
|
2020-04-02 01:36:35 +02:00
|
|
|
void playef(int t);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
std::vector<SoundTrack> soundTracks;
|
|
|
|
std::vector<MusicTrack> musicTracks;
|
|
|
|
SoundSystem soundSystem;
|
|
|
|
bool safeToProcessMusic;
|
|
|
|
|
2020-11-06 09:36:25 +01:00
|
|
|
int nicechange; // -1 if no song queued
|
2020-11-06 09:20:58 +01:00
|
|
|
bool nicefade;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
bool m_doFadeInVol;
|
|
|
|
int FadeVolAmountPerFrame;
|
|
|
|
int musicVolume;
|
|
|
|
|
2020-11-06 09:51:04 +01:00
|
|
|
bool quick_fade;
|
2020-01-13 04:33:58 +01:00
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
// MMMMMM mod settings
|
|
|
|
bool mmmmmm;
|
|
|
|
bool usingmmmmmm;
|
2020-06-07 22:11:35 +02:00
|
|
|
|
|
|
|
binaryBlob musicReadBlob;
|
2020-07-01 02:08:37 +02:00
|
|
|
int num_pppppp_tracks;
|
|
|
|
int num_mmmmmm_tracks;
|
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
|
|
|
|
|
|
|
Uint64 songStart;
|
|
|
|
Uint64 songEnd;
|
2020-01-01 21:29:24 +01:00
|
|
|
};
|
|
|
|
|
2020-09-28 04:15:06 +02:00
|
|
|
#ifndef MUSIC_DEFINITION
|
Allow using help/graphics/music/game/key/map/obj everywhere
This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and
`obj` essentially static global objects that can be used everywhere.
This is useful in case we ever need to add a new function in the future,
so we don't have to bother with passing a new argument in which means we
have to pass a new argument in to the function that calls that function
which means having to pass a new argument into the function that calls
THAT function, etc. which is a real headache when working on fan mods of
the source code.
Note that this changes NONE of the existing function signatures, it
merely just makes those variables accessible everywhere in the same way
`script` and `ed` are.
Also note that some classes had to be initialized after the filesystem
was initialized, but C++ would keep initializing them before the
filesystem got initialized, because I *had* to put them at the top of
`main.cpp`, or else they wouldn't be global variables.
The only way to work around this was to use entityclass's initialization
style (which I'm pretty sure entityclass of all things doesn't need to
be initialized this way), where you actually initialize the class in an
`init()` function, and so then you do `graphics.init()` after the
filesystem initialization, AFTER doing `Graphics graphics` up at the
top.
I've had to do this for `graphics` (but only because its child
GraphicsResources `grphx` needs to be initialized this way), `music`,
and `game`. I don't think this will affect anything. Other than that,
`help`, `key`, and `map` are still using the C++-intended method of
having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
|
|
|
extern musicclass music;
|
2020-09-28 04:15:06 +02:00
|
|
|
#endif
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
#endif /* MUSIC_H */
|