diff --git a/SpaceCadetPinball/Sound.cpp b/SpaceCadetPinball/Sound.cpp index 3959df0..082377e 100644 --- a/SpaceCadetPinball/Sound.cpp +++ b/SpaceCadetPinball/Sound.cpp @@ -4,11 +4,9 @@ int Sound::num_channels; bool Sound::enabled_flag = false; int* Sound::TimeStamps = nullptr; -int Sound::Volume = MIX_MAX_VOLUME; -bool Sound::Init(int channels, bool enableFlag, int volume) +bool Sound::Init(int channels, bool enableFlag) { - Volume = volume; Mix_Init(MIX_INIT_MID_Proxy); auto result = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); SetChannels(channels); @@ -82,11 +80,4 @@ void Sound::SetChannels(int channels) delete[] TimeStamps; TimeStamps = new int[num_channels](); Mix_AllocateChannels(num_channels); - SetVolume(Volume); -} - -void Sound::SetVolume(int volume) -{ - Volume = volume; - Mix_Volume(-1, volume); } diff --git a/SpaceCadetPinball/Sound.h b/SpaceCadetPinball/Sound.h index 2e2c3ca..0665b78 100644 --- a/SpaceCadetPinball/Sound.h +++ b/SpaceCadetPinball/Sound.h @@ -4,7 +4,7 @@ class Sound { public: - static bool Init(int channels, bool enableFlag, int volume); + static bool Init(int channels, bool enableFlag); static void Enable(bool enableFlag); static void Activate(); static void Deactivate(); @@ -13,10 +13,8 @@ public: static Mix_Chunk* LoadWaveFile(const std::string& lpName); static void FreeSound(Mix_Chunk* wave); static void SetChannels(int channels); - static void SetVolume(int volume); private: static int num_channels; static bool enabled_flag; static int* TimeStamps; - static int Volume; }; diff --git a/SpaceCadetPinball/high_score.cpp b/SpaceCadetPinball/high_score.cpp index 819eefc..443c97e 100644 --- a/SpaceCadetPinball/high_score.cpp +++ b/SpaceCadetPinball/high_score.cpp @@ -154,7 +154,7 @@ void high_score::RenderHighScoreDialog() bool unused_open = true; if (ImGui::BeginPopupModal("High Scores", &unused_open, ImGuiWindowFlags_AlwaysAutoResize)) { - if (ImGui::BeginTable("table1", 3, ImGuiTableFlags_Borders)) + if (ImGui::BeginTable("table1", 3, 0)) { char buf[36]; ImGui::TableSetupColumn("Rank"); @@ -166,7 +166,7 @@ void high_score::RenderHighScoreDialog() { ImGui::TableNextRow(); ImGui::TableNextColumn(); - snprintf(buf, sizeof buf, "%d", row + 1); + snprintf(buf, sizeof buf, "%d", row); ImGui::TextUnformatted(buf); auto currentRow = &dlg_hst[row + offset]; @@ -190,6 +190,7 @@ void high_score::RenderHighScoreDialog() } ImGui::EndTable(); } + ImGui::Separator(); if (ImGui::Button("Ok")) { diff --git a/SpaceCadetPinball/midi.cpp b/SpaceCadetPinball/midi.cpp index f17c6d2..b045524 100644 --- a/SpaceCadetPinball/midi.cpp +++ b/SpaceCadetPinball/midi.cpp @@ -9,7 +9,6 @@ std::vector midi::LoadedTracks{}; Mix_Music *midi::track1, *midi::track2, *midi::track3, *midi::active_track, *midi::NextTrack; bool midi::SetNextTrackFlag; -int midi::Volume = MIX_MAX_VOLUME; constexpr uint32_t FOURCC(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { @@ -48,9 +47,8 @@ int midi::music_stop() return true; } -int midi::music_init(int volume) +int midi::music_init() { - SetVolume(volume); active_track = nullptr; if (pb::FullTiltMode) @@ -89,12 +87,6 @@ void midi::music_shutdown() LoadedTracks.clear(); } -void midi::SetVolume(int volume) -{ - Volume = volume; - Mix_VolumeMusic(volume); -} - Mix_Music* midi::load_track(std::string fileName) { Mix_Music* audio = nullptr; @@ -165,9 +157,6 @@ bool midi::play_track(Mix_Music* midi) return false; } - // On Windows, MIDI volume can only be set during playback. - // And it changes application master volume for some reason. - SetVolume(Volume); active_track = midi; return true; } diff --git a/SpaceCadetPinball/midi.h b/SpaceCadetPinball/midi.h index 864cbdc..91441b8 100644 --- a/SpaceCadetPinball/midi.h +++ b/SpaceCadetPinball/midi.h @@ -88,15 +88,12 @@ class midi public: static int play_pb_theme(); static int music_stop(); - static int music_init(int volume); + static int music_init(); static void music_shutdown(); - static void SetVolume(int volume); private: static std::vector LoadedTracks; static Mix_Music *track1, *track2, *track3, *active_track, *NextTrack; static bool SetNextTrackFlag; - static int Volume; - static Mix_Music* load_track(std::string fileName); static bool play_track(Mix_Music* midi); static std::vector* MdsToMidi(std::string file); diff --git a/SpaceCadetPinball/options.cpp b/SpaceCadetPinball/options.cpp index d05074e..e444f49 100644 --- a/SpaceCadetPinball/options.cpp +++ b/SpaceCadetPinball/options.cpp @@ -9,7 +9,6 @@ constexpr int options::MaxUps, options::MaxFps, options::MinUps, options::MinFps, options::DefUps, options::DefFps; constexpr int options::MaxSoundChannels, options::MinSoundChannels, options::DefSoundChannels; -constexpr int options::MaxVolume, options::MinVolume, options::DefVolume; optionsStruct options::Options{}; std::map options::settings{}; @@ -93,17 +92,16 @@ void options::InitPrimary() ImGui::GetIO().FontGlobalScale = get_float("UI Scale", 1.0f); Options.Resolution = get_int("Screen Resolution", -1); Options.LinearFiltering = get_int("Linear Filtering", true); - Options.FramesPerSecond = Clamp(get_int("Frames Per Second", DefFps), MinFps, MaxFps); - Options.UpdatesPerSecond = Clamp(get_int("Updates Per Second", DefUps), MinUps, MaxUps); + Options.FramesPerSecond = std::min(MaxFps, std::max(MinUps, get_int("Frames Per Second", DefFps))); + Options.UpdatesPerSecond = std::min(MaxUps, std::max(MinUps, get_int("Updates Per Second", DefUps))); Options.UpdatesPerSecond = std::max(Options.UpdatesPerSecond, Options.FramesPerSecond); Options.ShowMenu = get_int("ShowMenu", true); Options.UncappedUpdatesPerSecond = get_int("Uncapped Updates Per Second", false); - Options.SoundChannels = Clamp(get_int("Sound Channels", DefSoundChannels), MinSoundChannels, MaxSoundChannels); + Options.SoundChannels = get_int("Sound Channels", DefSoundChannels); + Options.SoundChannels = std::min(MaxSoundChannels, std::max(MinSoundChannels, Options.SoundChannels)); Options.HybridSleep = get_int("HybridSleep", false); Options.Prefer3DPBGameData = get_int("Prefer 3DPB Game Data", false); Options.IntegerScaling = get_int("Integer Scaling", false); - Options.SoundVolume = Clamp(get_int("Sound Volume", DefVolume), MinVolume, MaxVolume); - Options.MusicVolume = Clamp(get_int("Music Volume", DefVolume), MinVolume, MaxVolume); } void options::InitSecondary() @@ -141,8 +139,6 @@ void options::uninit() set_int("HybridSleep", Options.HybridSleep); set_int("Prefer 3DPB Game Data", Options.Prefer3DPBGameData); set_int("Integer Scaling", Options.IntegerScaling); - set_int("Sound Volume", Options.SoundVolume); - set_int("Music Volume", Options.MusicVolume); } diff --git a/SpaceCadetPinball/options.h b/SpaceCadetPinball/options.h index 7ba4a20..3bb1383 100644 --- a/SpaceCadetPinball/options.h +++ b/SpaceCadetPinball/options.h @@ -78,8 +78,6 @@ struct optionsStruct bool HybridSleep; bool Prefer3DPBGameData; bool IntegerScaling; - int SoundVolume; - int MusicVolume; }; struct ControlRef @@ -97,7 +95,6 @@ public: DefUps = 120, DefFps = 60; // Original uses 8 sound channels static constexpr int MaxSoundChannels = 32, MinSoundChannels = 1, DefSoundChannels = 8; - static constexpr int MaxVolume = MIX_MAX_VOLUME, MinVolume = 0, DefVolume = MaxVolume; static optionsStruct Options; static void InitPrimary(); diff --git a/SpaceCadetPinball/pch.h b/SpaceCadetPinball/pch.h index 7d7cb2e..281dfd1 100644 --- a/SpaceCadetPinball/pch.h +++ b/SpaceCadetPinball/pch.h @@ -78,18 +78,12 @@ inline float RandFloat() return static_cast(std::rand() / static_cast(RAND_MAX)); } -template -constexpr int Sign(T val) +template constexpr +int Sign(T val) { return (T(0) < val) - (val < T(0)); } -template -const T& Clamp(const T& n, const T& lower, const T& upper) -{ - return std::max(lower, std::min(n, upper)); -} - // UTF-8 path adapter for fopen on Windows, implemented in SpaceCadetPinball.cpp #ifdef _WIN32 extern FILE* fopenu(const char* path, const char* opt); diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 12e5d1a..e19891c 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -133,10 +133,10 @@ int winmain::WinMain(LPCSTR lpCmdLine) // Second step: run updates depending on FullTiltMode options::InitSecondary(); - if (!Sound::Init(Options.SoundChannels, Options.Sounds, Options.SoundVolume)) + if (!Sound::Init(Options.SoundChannels, Options.Sounds)) Options.Sounds = false; - if (!pinball::quickFlag && !midi::music_init(Options.MusicVolume)) + if (!pinball::quickFlag && !midi::music_init()) Options.Music = false; if (pb::init()) @@ -291,7 +291,8 @@ int winmain::WinMain(LPCSTR lpCmdLine) } // Limit duration to 2 * target time - sleepRemainder = Clamp(DurationMs(frameEnd - updateEnd) - targetTimeDelta, -TargetFrameTime, TargetFrameTime); + sleepRemainder = std::max(std::min(DurationMs(frameEnd - updateEnd) - targetTimeDelta, TargetFrameTime), + -TargetFrameTime); frameDuration = std::min(DurationMs(frameEnd - frameStart), 2 * TargetFrameTime); frameStart = frameEnd; UpdateToFrameCounter++; @@ -430,46 +431,50 @@ void winmain::RenderUi() } ImGui::EndMenu(); } + ImGui::Separator(); + + if (ImGui::MenuItem("Sound", "F5", Options.Sounds)) + { + options::toggle(Menu1::Sounds); + } + if (ImGui::MenuItem("Music", "F6", Options.Music)) + { + options::toggle(Menu1::Music); + } + ImGui::TextUnformatted("Sound Channels"); + if (ImGui::SliderInt("##Sound Channels", &Options.SoundChannels, options::MinSoundChannels, + options::MaxSoundChannels, "%d", ImGuiSliderFlags_AlwaysClamp)) + { + Options.SoundChannels = std::min(options::MaxSoundChannels, + std::max(options::MinSoundChannels, Options.SoundChannels)); + Sound::SetChannels(Options.SoundChannels); + } + ImGui::Separator(); + if (ImGui::MenuItem("Player Controls...", "F8")) { pause(false); options::ShowControlDialog(); } - ImGui::Separator(); - - if (ImGui::BeginMenu("Audio")) + if (ImGui::BeginMenu("Table Resolution")) { - if (ImGui::MenuItem("Sound", "F5", Options.Sounds)) + char buffer[20]{}; + auto maxResText = pinball::get_rc_string(fullscrn::GetMaxResolution() + 2030, 0); + if (ImGui::MenuItem(maxResText, nullptr, Options.Resolution == -1)) { - options::toggle(Menu1::Sounds); + options::toggle(Menu1::MaximumResolution); } - ImGui::TextUnformatted("Sound Volume"); - if (ImGui::SliderInt("##Sound Volume", &Options.SoundVolume, options::MinVolume, options::MaxVolume, "%d", - ImGuiSliderFlags_AlwaysClamp)) + for (auto i = 0; i <= fullscrn::GetMaxResolution(); i++) { - Sound::SetVolume(Options.SoundVolume); - } - ImGui::TextUnformatted("Sound Channels"); - if (ImGui::SliderInt("##Sound Channels", &Options.SoundChannels, options::MinSoundChannels, - options::MaxSoundChannels, "%d", ImGuiSliderFlags_AlwaysClamp)) - { - Sound::SetChannels(Options.SoundChannels); - } - ImGui::Separator(); - - if (ImGui::MenuItem("Music", "F6", Options.Music)) - { - options::toggle(Menu1::Music); - } - ImGui::TextUnformatted("Music Volume"); - if (ImGui::SliderInt("##Music Volume", &Options.MusicVolume, options::MinVolume, options::MaxVolume, "%d", - ImGuiSliderFlags_AlwaysClamp)) - { - midi::SetVolume(Options.MusicVolume); + auto& res = fullscrn::resolution_array[i]; + snprintf(buffer, sizeof buffer - 1, "%d x %d", res.ScreenWidth, res.ScreenHeight); + if (ImGui::MenuItem(buffer, nullptr, Options.Resolution == i)) + { + options::toggle(static_cast(static_cast(Menu1::R640x480) + i)); + } } ImGui::EndMenu(); } - if (ImGui::BeginMenu("Graphics")) { if (ImGui::MenuItem("Uniform Scaling", nullptr, Options.UniformScaling)) @@ -528,26 +533,6 @@ void winmain::RenderUi() ImGui::EndMenu(); } - if (ImGui::BeginMenu("Table Resolution")) - { - char buffer[20]{}; - auto maxResText = pinball::get_rc_string(fullscrn::GetMaxResolution() + 2030, 0); - if (ImGui::MenuItem(maxResText, nullptr, Options.Resolution == -1)) - { - options::toggle(Menu1::MaximumResolution); - } - for (auto i = 0; i <= fullscrn::GetMaxResolution(); i++) - { - auto& res = fullscrn::resolution_array[i]; - snprintf(buffer, sizeof buffer - 1, "%d x %d", res.ScreenWidth, res.ScreenHeight); - if (ImGui::MenuItem(buffer, nullptr, Options.Resolution == i)) - { - options::toggle(static_cast(static_cast(Menu1::R640x480) + i)); - } - } - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Game Data")) { if (ImGui::MenuItem("Prefer 3DPB Data", nullptr, Options.Prefer3DPBGameData))