From 4183e7f0bf5f9945af546ad26f267570884f8778 Mon Sep 17 00:00:00 2001 From: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com> Date: Mon, 23 May 2022 12:45:18 +0300 Subject: [PATCH] Refactored midi multiple track support. Cleaned up TCollisionComponent. Issue #129. --- SpaceCadetPinball/TCollisionComponent.cpp | 41 +++++--------- SpaceCadetPinball/TCollisionComponent.h | 2 +- SpaceCadetPinball/TPinballTable.cpp | 2 +- SpaceCadetPinball/control.cpp | 18 +++---- SpaceCadetPinball/midi.cpp | 65 ++++++++++++++++------- SpaceCadetPinball/midi.h | 27 +++++----- 6 files changed, 84 insertions(+), 71 deletions(-) diff --git a/SpaceCadetPinball/TCollisionComponent.cpp b/SpaceCadetPinball/TCollisionComponent.cpp index 8078dfa..96d4fd7 100644 --- a/SpaceCadetPinball/TCollisionComponent.cpp +++ b/SpaceCadetPinball/TCollisionComponent.cpp @@ -51,38 +51,33 @@ void TCollisionComponent::port_draw() edge->port_draw(); } -int TCollisionComponent::DefaultCollision(TBall* ball, vector2* nextPosition, vector2* direction) +bool TCollisionComponent::DefaultCollision(TBall* ball, vector2* nextPosition, vector2* direction) { if (PinballTable->TiltLockFlag) { maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0); - return 0; + return false; } + auto projSpeed = maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, Boost); - if (projSpeed <= Threshold) - { - if (projSpeed > 0.2f) - { - if (SoftHitSoundId) - loader::play_sound(SoftHitSoundId); - } - return 0; - } - if (HardHitSoundId) + if (projSpeed > Threshold) loader::play_sound(HardHitSoundId); - return 1; + else if (projSpeed > 0.2f) + loader::play_sound(SoftHitSoundId); + else + return false; + return true; } void TCollisionComponent::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge) { - int soundIndex; - if (PinballTable->TiltLockFlag) { maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0); return; } + auto projSpeed = maths::basic_collision( ball, nextPosition, @@ -91,18 +86,10 @@ void TCollisionComponent::Collision(TBall* ball, vector2* nextPosition, vector2* Smoothness, Threshold, Boost); - if (projSpeed <= Threshold) - { - if (projSpeed <= 0.2f) - return; - soundIndex = SoftHitSoundId; - } - else - { - soundIndex = HardHitSoundId; - } - if (soundIndex) - loader::play_sound(soundIndex); + if (projSpeed > Threshold) + loader::play_sound(HardHitSoundId); + else if (projSpeed > 0.2f) + loader::play_sound(SoftHitSoundId); } int TCollisionComponent::FieldEffect(TBall* ball, vector2* vecDst) diff --git a/SpaceCadetPinball/TCollisionComponent.h b/SpaceCadetPinball/TCollisionComponent.h index 1f9d5e6..e0d727c 100644 --- a/SpaceCadetPinball/TCollisionComponent.h +++ b/SpaceCadetPinball/TCollisionComponent.h @@ -22,5 +22,5 @@ public: virtual void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge); virtual int FieldEffect(TBall* ball, vector2* vecDst); - int DefaultCollision(TBall* ball, vector2* nextPosition, vector2* direction); + bool DefaultCollision(TBall* ball, vector2* nextPosition, vector2* direction); }; diff --git a/SpaceCadetPinball/TPinballTable.cpp b/SpaceCadetPinball/TPinballTable.cpp index 11fdafe..f36e2f5 100644 --- a/SpaceCadetPinball/TPinballTable.cpp +++ b/SpaceCadetPinball/TPinballTable.cpp @@ -450,7 +450,7 @@ int TPinballTable::Message(int code, float value) LightShowTimer = timer::set(time, this, LightShow_timeout); } - midi::play_track(midi::track1); + midi::play_track(MidiTracks::Track1, true); break; case 1018: if (ReplayTimer) diff --git a/SpaceCadetPinball/control.cpp b/SpaceCadetPinball/control.cpp index 5d4dfe8..345bc65 100644 --- a/SpaceCadetPinball/control.cpp +++ b/SpaceCadetPinball/control.cpp @@ -968,8 +968,7 @@ void control::table_set_flag_lights() void control::table_set_multiball() { info_text_box->Display(pinball::get_rc_string(16, 0), 2.0); - if (midi::get_active_track() != midi::track3) - midi::play_track(midi::track3); + midi::play_track(MidiTracks::Track3, true); } void control::table_bump_ball_sink_lock() @@ -2575,8 +2574,7 @@ void control::BallDrainControl(int code, TPinballComponent* caller) { lite200->Message(20, 0.0); lite199->Message(20, 0.0); - if (midi::get_active_track() != midi::track1) - midi::play_track(midi::track1); + midi::play_track(MidiTracks::Track1, false); } if (light_on(&control_lite200_tag)) { @@ -3107,8 +3105,7 @@ void control::GameoverController(int code, TPinballComponent* caller) flip1->Message(1022, 0.0); flip2->Message(1022, 0.0); mission_text_box->MessageField = 0; - if (midi::get_active_track() != midi::track1) - midi::play_track(midi::track1); + midi::play_track(MidiTracks::Track1, false); return; } if (code != 67) @@ -4015,8 +4012,7 @@ void control::SelectMissionController(int code, TPinballComponent* caller) int addedScore = SpecialAddScore(mission_select_scores[scoreId]); snprintf(Buffer, sizeof Buffer, pinball::get_rc_string(77, 0), addedScore); mission_text_box->Display(Buffer, 4.0); - if (midi::get_active_track() != midi::track2) - midi::play_track(midi::track2); + midi::play_track(MidiTracks::Track2, true); } return; } @@ -4130,8 +4126,7 @@ void control::SelectMissionController(int code, TPinballComponent* caller) return; } case 66: - if (midi::get_active_track() != midi::track1) - midi::play_track(midi::track1); + midi::play_track(MidiTracks::Track1, false); lite198->Message(20, 0.0); outer_circle->Message(34, 0.0); ramp_tgt_lights->Message(20, 0.0); @@ -4419,8 +4414,7 @@ void control::WaitingDeploymentController(int code, TPinballComponent* caller) case 66: mission_text_box->Clear(); waiting_deployment_flag = 0; - if (midi::get_active_track() != midi::track1) - midi::play_track(midi::track1); + midi::play_track(MidiTracks::Track1, false); break; case 67: mission_text_box->Display(pinball::get_rc_string(50, 0), -1.0); diff --git a/SpaceCadetPinball/midi.cpp b/SpaceCadetPinball/midi.cpp index ad0b705..af6b800 100644 --- a/SpaceCadetPinball/midi.cpp +++ b/SpaceCadetPinball/midi.cpp @@ -7,7 +7,8 @@ std::vector midi::LoadedTracks{}; -Mix_Music *midi::track1, *midi::track2, *midi::track3, *midi::active_track, *midi::NextTrack; +Mix_Music* midi::track1, * midi::track2, * midi::track3; +MidiTracks midi::active_track, midi::NextTrack; int midi::Volume = MIX_MAX_VOLUME; bool midi::IsPlaying = false; @@ -36,8 +37,8 @@ void midi::music_play() if (!IsPlaying) { IsPlaying = true; - play_track(NextTrack); - NextTrack = nullptr; + play_track(NextTrack, true); + NextTrack = MidiTracks::None; } } @@ -53,19 +54,20 @@ void midi::music_stop() void midi::StopPlayback() { - if (active_track != nullptr) + if (active_track != MidiTracks::None) { Mix_HaltMusic(); - active_track = nullptr; + active_track = MidiTracks::None; } } int midi::music_init(int volume) { SetVolume(volume); - active_track = nullptr; - NextTrack = nullptr; + active_track = MidiTracks::None; + NextTrack = MidiTracks::None; IsPlaying = false; + track1 = track2 = track3 = nullptr; if (pb::FullTiltMode) { @@ -83,10 +85,6 @@ int midi::music_init(int volume) track1 = load_track("PINBALL"); } - if (!track2) - track2 = track1; - if (!track3) - track3 = track1; return track1 != nullptr; } @@ -98,7 +96,7 @@ void midi::music_shutdown() { Mix_FreeMusic(midi); } - active_track = nullptr; + active_track = MidiTracks::None; LoadedTracks.clear(); } @@ -159,31 +157,62 @@ Mix_Music* midi::load_track(std::string fileName) return audio; } -bool midi::play_track(Mix_Music* midi) +bool midi::play_track(MidiTracks track, bool replay) { - StopPlayback(); - if (!midi) + auto midi = TrackToMidi(track); + if (!midi || (!replay && active_track == track)) return false; + StopPlayback(); + if (!IsPlaying) { - NextTrack = midi; + NextTrack = track; return false; } if (Mix_PlayMusic(midi, -1)) { - active_track = nullptr; + active_track = MidiTracks::None; 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; + active_track = track; return true; } +MidiTracks midi::get_active_track() +{ + if (!IsPlaying) + return NextTrack; + else + return active_track; +} + +Mix_Music* midi::TrackToMidi(MidiTracks track) +{ + Mix_Music* midi; + switch (track) + { + default: + case MidiTracks::None: + midi = nullptr; + break; + case MidiTracks::Track1: + midi = track1; + break; + case MidiTracks::Track2: + midi = track2; + break; + case MidiTracks::Track3: + midi = track3; + break; + } + return midi; +} /// /// SDL_mixed does not support MIDS. To support FT music, a conversion to MIDI is required. diff --git a/SpaceCadetPinball/midi.h b/SpaceCadetPinball/midi.h index d12686a..e8dc5cd 100644 --- a/SpaceCadetPinball/midi.h +++ b/SpaceCadetPinball/midi.h @@ -83,30 +83,33 @@ static_assert(sizeof(midi_track) == 8, "Wrong size of midi_track"); #pragma pack(pop) +enum class MidiTracks +{ + None, + Track1, + Track2, + Track3 +}; + class midi { public: - static Mix_Music * track1, * track2, * track3; - static void music_play(); - static void music_stop(); static int music_init(int volume); static void music_shutdown(); + static void music_play(); + static void music_stop(); static void SetVolume(int volume); - static bool play_track(Mix_Music* midi); - static Mix_Music* get_active_track() - { - if (active_track == nullptr) - return NextTrack; - else - return active_track; - } + static bool play_track(MidiTracks track, bool replay); + static MidiTracks get_active_track(); private: static std::vector LoadedTracks; - static Mix_Music *active_track, *NextTrack; + static Mix_Music* track1, * track2, * track3; + static MidiTracks active_track, NextTrack; static int Volume; static bool IsPlaying; static void StopPlayback(); static Mix_Music* load_track(std::string fileName); + static Mix_Music* TrackToMidi(MidiTracks track); static std::vector* MdsToMidi(std::string file); };