From 2162cac9771bb50059f440c50e9a30d982cdd848 Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Fri, 2 Dec 2022 14:46:22 +0300 Subject: [PATCH] Moved SDL mixer initialization out of partial restart loop. This might help with issue #167. --- SpaceCadetPinball/Sound.cpp | 31 ++++++++++++---------- SpaceCadetPinball/Sound.h | 3 ++- SpaceCadetPinball/SpaceCadetPinball.cpp | 4 +++ SpaceCadetPinball/midi.cpp | 16 ++++++++---- SpaceCadetPinball/midi.h | 4 +-- SpaceCadetPinball/winmain.cpp | 34 ++++++++++++++++++++++--- 6 files changed, 68 insertions(+), 24 deletions(-) diff --git a/SpaceCadetPinball/Sound.cpp b/SpaceCadetPinball/Sound.cpp index 6660080..3673e0a 100644 --- a/SpaceCadetPinball/Sound.cpp +++ b/SpaceCadetPinball/Sound.cpp @@ -7,44 +7,44 @@ int Sound::num_channels; bool Sound::enabled_flag = false; std::vector Sound::Channels{}; int Sound::Volume = MIX_MAX_VOLUME; +bool Sound::MixOpen = false; -bool Sound::Init(int channels, bool enableFlag, int volume) +void Sound::Init(bool mixOpen, int channels, bool enableFlag, int volume) { + MixOpen = mixOpen; Volume = volume; - Mix_Init(MIX_INIT_MID_Proxy); - auto result = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); SetChannels(channels); Enable(enableFlag); - return !result; } void Sound::Enable(bool enableFlag) { enabled_flag = enableFlag; - if (!enableFlag) + if (MixOpen && !enableFlag) Mix_HaltChannel(-1); } void Sound::Activate() { - Mix_Resume(-1); + if (MixOpen) + Mix_Resume(-1); } void Sound::Deactivate() { - Mix_Pause(-1); + if (MixOpen) + Mix_Pause(-1); } void Sound::Close() { + Enable(false); Channels.clear(); - Mix_CloseAudio(); - Mix_Quit(); } void Sound::PlaySound(Mix_Chunk* wavePtr, int time, TPinballComponent* soundSource, const char* info) { - if (wavePtr && enabled_flag) + if (MixOpen && wavePtr && enabled_flag) { if (Mix_Playing(-1) == num_channels) { @@ -117,6 +117,9 @@ void Sound::PlaySound(Mix_Chunk* wavePtr, int time, TPinballComponent* soundSour Mix_Chunk* Sound::LoadWaveFile(const std::string& lpName) { + if (!MixOpen) + return nullptr; + auto wavFile = fopenu(lpName.c_str(), "r"); if (!wavFile) return nullptr; @@ -127,7 +130,7 @@ Mix_Chunk* Sound::LoadWaveFile(const std::string& lpName) void Sound::FreeSound(Mix_Chunk* wave) { - if (wave) + if (MixOpen && wave) Mix_FreeChunk(wave); } @@ -138,12 +141,14 @@ void Sound::SetChannels(int channels) num_channels = channels; Channels.resize(num_channels); - Mix_AllocateChannels(num_channels); + if (MixOpen) + Mix_AllocateChannels(num_channels); SetVolume(Volume); } void Sound::SetVolume(int volume) { Volume = volume; - Mix_Volume(-1, volume); + if (MixOpen) + Mix_Volume(-1, volume); } diff --git a/SpaceCadetPinball/Sound.h b/SpaceCadetPinball/Sound.h index 97ddf9f..fc84b52 100644 --- a/SpaceCadetPinball/Sound.h +++ b/SpaceCadetPinball/Sound.h @@ -13,7 +13,7 @@ class Sound public: static std::vector Channels; - static bool Init(int channels, bool enableFlag, int volume); + static void Init(bool mixOpen, int channels, bool enableFlag, int volume); static void Enable(bool enableFlag); static void Activate(); static void Deactivate(); @@ -27,4 +27,5 @@ private: static int num_channels; static bool enabled_flag; static int Volume; + static bool MixOpen; }; diff --git a/SpaceCadetPinball/SpaceCadetPinball.cpp b/SpaceCadetPinball/SpaceCadetPinball.cpp index 2452dde..250e0e8 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.cpp +++ b/SpaceCadetPinball/SpaceCadetPinball.cpp @@ -5,7 +5,11 @@ int main(int argc, char* argv[]) { std::string cmdLine; for (int i = 1; i < argc; i++) + { + if (i > 1) + cmdLine += " "; cmdLine += argv[i]; + } return winmain::WinMain(cmdLine.c_str()); } diff --git a/SpaceCadetPinball/midi.cpp b/SpaceCadetPinball/midi.cpp index a2b3596..a90e8d1 100644 --- a/SpaceCadetPinball/midi.cpp +++ b/SpaceCadetPinball/midi.cpp @@ -9,7 +9,7 @@ std::vector midi::LoadedTracks{}; Mix_Music* midi::track1, * midi::track2, * midi::track3; MidiTracks midi::active_track, midi::NextTrack; int midi::Volume = MIX_MAX_VOLUME; -bool midi::IsPlaying = false; +bool midi::IsPlaying = false, midi::MixOpen = false; constexpr uint32_t FOURCC(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { @@ -55,13 +55,15 @@ void midi::StopPlayback() { if (active_track != MidiTracks::None) { - Mix_HaltMusic(); + if (MixOpen) + Mix_HaltMusic(); active_track = MidiTracks::None; } } -int midi::music_init(int volume) +int midi::music_init(bool mixOpen, int volume) { + MixOpen = mixOpen; SetVolume(volume); active_track = MidiTracks::None; NextTrack = MidiTracks::None; @@ -102,11 +104,15 @@ void midi::music_shutdown() void midi::SetVolume(int volume) { Volume = volume; - Mix_VolumeMusic(volume); + if (MixOpen) + Mix_VolumeMusic(volume); } Mix_Music* midi::load_track(std::string fileName) { + if (!MixOpen || pb::quickFlag) + return nullptr; + if (pb::FullTiltMode) { // FT sounds are in SOUND subfolder @@ -184,7 +190,7 @@ bool midi::play_track(MidiTracks track, bool replay) return false; } - if (Mix_PlayMusic(midi, -1)) + if (MixOpen && Mix_PlayMusic(midi, -1)) { active_track = MidiTracks::None; return false; diff --git a/SpaceCadetPinball/midi.h b/SpaceCadetPinball/midi.h index 91efd28..32a904a 100644 --- a/SpaceCadetPinball/midi.h +++ b/SpaceCadetPinball/midi.h @@ -94,7 +94,7 @@ enum class MidiTracks class midi { public: - static int music_init(int volume); + static int music_init(bool mixOpen, int volume); static void music_shutdown(); static void music_play(); static void music_stop(); @@ -106,7 +106,7 @@ private: static Mix_Music* track1, * track2, * track3; static MidiTracks active_track, NextTrack; static int Volume; - static bool IsPlaying; + static bool IsPlaying, MixOpen; static void StopPlayback(); static Mix_Music* load_track(std::string fileName); diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index f774033..c42a316 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -52,6 +52,7 @@ int winmain::WinMain(LPCSTR lpCmdLine) std::set_new_handler(memalloc_failure); printf("Game version: %s\n", Version); + printf("Command line: %s\n", lpCmdLine); printf("Compiled with: SDL %d.%d.%d;", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL); printf(" SDL_mixer %d.%d.%d;", SDL_MIXER_MAJOR_VERSION, SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL); printf(" ImGui %s\n", IMGUI_VERSION); @@ -107,6 +108,25 @@ int winmain::WinMain(LPCSTR lpCmdLine) auto prefPath = SDL_GetPrefPath("", "SpaceCadetPinball"); auto basePath = SDL_GetBasePath(); + + // SDL mixer init + bool mixOpened = false, noAudio = strstr(lpCmdLine, "-noaudio") != nullptr; + if (!noAudio) + { + if ((Mix_Init(MIX_INIT_MID_Proxy) & MIX_INIT_MID_Proxy) == 0) + { + printf("Could not initialize SDL MIDI, music might not work.\nSDL Error: %s\n", SDL_GetError()); + SDL_ClearError(); + } + if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024) != 0) + { + printf("Could not open audio device, continuing without audio.\nSDL Error: %s\n", SDL_GetError()); + SDL_ClearError(); + } + else + mixOpened = true; + } + do { restart = false; @@ -171,10 +191,11 @@ int winmain::WinMain(LPCSTR lpCmdLine) // Second step: run updates that depend on .DAT file selection options::InitSecondary(); - if (!Sound::Init(Options.SoundChannels, Options.Sounds, Options.SoundVolume)) + Sound::Init(mixOpened, Options.SoundChannels, Options.Sounds, Options.SoundVolume); + if (!mixOpened) Options.Sounds = false; - if (!pb::quickFlag && !midi::music_init(Options.MusicVolume)) + if (!midi::music_init(mixOpened, Options.MusicVolume)) Options.Music = false; if (pb::init()) @@ -219,8 +240,8 @@ int winmain::WinMain(LPCSTR lpCmdLine) options::uninit(); midi::music_shutdown(); - pb::uninit(); Sound::Close(); + pb::uninit(); ImGuiSDL::Deinitialize(); ImGui_ImplSDL2_Shutdown(); @@ -228,6 +249,13 @@ int winmain::WinMain(LPCSTR lpCmdLine) } while (restart); + if (!noAudio) + { + if (mixOpened) + Mix_CloseAudio(); + Mix_Quit(); + } + SDL_free(basePath); SDL_free(prefPath); delete gfr_display;