mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-12-24 06:32:37 -05:00
parent
43af97127b
commit
0a2d6847ba
8 changed files with 99 additions and 46 deletions
SpaceCadetPinball
|
@ -4,9 +4,11 @@
|
|||
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)
|
||||
bool Sound::Init(int channels, bool enableFlag, int volume)
|
||||
{
|
||||
Volume = volume;
|
||||
Mix_Init(MIX_INIT_MID_Proxy);
|
||||
auto result = Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
|
||||
SetChannels(channels);
|
||||
|
@ -80,4 +82,11 @@ 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);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
class Sound
|
||||
{
|
||||
public:
|
||||
static bool Init(int channels, bool enableFlag);
|
||||
static bool Init(int channels, bool enableFlag, int volume);
|
||||
static void Enable(bool enableFlag);
|
||||
static void Activate();
|
||||
static void Deactivate();
|
||||
|
@ -13,8 +13,10 @@ 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;
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
std::vector<Mix_Music*> 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)
|
||||
{
|
||||
|
@ -47,8 +48,9 @@ int midi::music_stop()
|
|||
return true;
|
||||
}
|
||||
|
||||
int midi::music_init()
|
||||
int midi::music_init(int volume)
|
||||
{
|
||||
SetVolume(volume);
|
||||
active_track = nullptr;
|
||||
|
||||
if (pb::FullTiltMode)
|
||||
|
@ -87,6 +89,12 @@ 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;
|
||||
|
@ -157,6 +165,9 @@ 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;
|
||||
}
|
||||
|
|
|
@ -88,12 +88,15 @@ class midi
|
|||
public:
|
||||
static int play_pb_theme();
|
||||
static int music_stop();
|
||||
static int music_init();
|
||||
static int music_init(int volume);
|
||||
static void music_shutdown();
|
||||
static void SetVolume(int volume);
|
||||
private:
|
||||
static std::vector<Mix_Music*> 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<uint8_t>* MdsToMidi(std::string file);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
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<std::string, std::string> options::settings{};
|
||||
|
@ -92,16 +93,17 @@ 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 = 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.FramesPerSecond = Clamp(get_int("Frames Per Second", DefFps), MinFps, MaxFps);
|
||||
Options.UpdatesPerSecond = Clamp(get_int("Updates Per Second", DefUps), MinUps, MaxUps);
|
||||
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 = get_int("Sound Channels", DefSoundChannels);
|
||||
Options.SoundChannels = std::min(MaxSoundChannels, std::max(MinSoundChannels, Options.SoundChannels));
|
||||
Options.SoundChannels = Clamp(get_int("Sound Channels", DefSoundChannels), MinSoundChannels, MaxSoundChannels);
|
||||
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()
|
||||
|
@ -139,6 +141,8 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ struct optionsStruct
|
|||
bool HybridSleep;
|
||||
bool Prefer3DPBGameData;
|
||||
bool IntegerScaling;
|
||||
int SoundVolume;
|
||||
int MusicVolume;
|
||||
};
|
||||
|
||||
struct ControlRef
|
||||
|
@ -95,6 +97,7 @@ 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();
|
||||
|
|
|
@ -78,12 +78,18 @@ inline float RandFloat()
|
|||
return static_cast<float>(std::rand() / static_cast<double>(RAND_MAX));
|
||||
}
|
||||
|
||||
template <typename T> constexpr
|
||||
int Sign(T val)
|
||||
template <typename T>
|
||||
constexpr int Sign(T val)
|
||||
{
|
||||
return (T(0) < val) - (val < T(0));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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);
|
||||
|
|
|
@ -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))
|
||||
if (!Sound::Init(Options.SoundChannels, Options.Sounds, Options.SoundVolume))
|
||||
Options.Sounds = false;
|
||||
|
||||
if (!pinball::quickFlag && !midi::music_init())
|
||||
if (!pinball::quickFlag && !midi::music_init(Options.MusicVolume))
|
||||
Options.Music = false;
|
||||
|
||||
if (pb::init())
|
||||
|
@ -291,8 +291,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
|
|||
}
|
||||
|
||||
// Limit duration to 2 * target time
|
||||
sleepRemainder = std::max(std::min(DurationMs(frameEnd - updateEnd) - targetTimeDelta, TargetFrameTime),
|
||||
-TargetFrameTime);
|
||||
sleepRemainder = Clamp(DurationMs(frameEnd - updateEnd) - targetTimeDelta, -TargetFrameTime, TargetFrameTime);
|
||||
frameDuration = std::min<DurationMs>(DurationMs(frameEnd - frameStart), 2 * TargetFrameTime);
|
||||
frameStart = frameEnd;
|
||||
UpdateToFrameCounter++;
|
||||
|
@ -431,50 +430,46 @@ 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();
|
||||
}
|
||||
if (ImGui::BeginMenu("Table Resolution"))
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::BeginMenu("Audio"))
|
||||
{
|
||||
char buffer[20]{};
|
||||
auto maxResText = pinball::get_rc_string(fullscrn::GetMaxResolution() + 2030, 0);
|
||||
if (ImGui::MenuItem(maxResText, nullptr, Options.Resolution == -1))
|
||||
if (ImGui::MenuItem("Sound", "F5", Options.Sounds))
|
||||
{
|
||||
options::toggle(Menu1::MaximumResolution);
|
||||
options::toggle(Menu1::Sounds);
|
||||
}
|
||||
for (auto i = 0; i <= fullscrn::GetMaxResolution(); i++)
|
||||
ImGui::TextUnformatted("Sound Volume");
|
||||
if (ImGui::SliderInt("##Sound Volume", &Options.SoundVolume, options::MinVolume, options::MaxVolume, "%d",
|
||||
ImGuiSliderFlags_AlwaysClamp))
|
||||
{
|
||||
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<Menu1>(static_cast<int>(Menu1::R640x480) + 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);
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Graphics"))
|
||||
{
|
||||
if (ImGui::MenuItem("Uniform Scaling", nullptr, Options.UniformScaling))
|
||||
|
@ -533,6 +528,26 @@ 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<Menu1>(static_cast<int>(Menu1::R640x480) + i));
|
||||
}
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Game Data"))
|
||||
{
|
||||
if (ImGui::MenuItem("Prefer 3DPB Data", nullptr, Options.Prefer3DPBGameData))
|
||||
|
|
Loading…
Reference in a new issue