Refactored midi multiple track support.

Cleaned up TCollisionComponent.
Issue #129.
This commit is contained in:
Muzychenko Andrey 2022-05-23 12:45:18 +03:00
parent e283a643b3
commit 4183e7f0bf
6 changed files with 84 additions and 71 deletions

View File

@ -51,38 +51,33 @@ void TCollisionComponent::port_draw()
edge->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) if (PinballTable->TiltLockFlag)
{ {
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0); 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); auto projSpeed = maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, Boost);
if (projSpeed <= Threshold) if (projSpeed > Threshold)
{
if (projSpeed > 0.2f)
{
if (SoftHitSoundId)
loader::play_sound(SoftHitSoundId);
}
return 0;
}
if (HardHitSoundId)
loader::play_sound(HardHitSoundId); 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, void TCollisionComponent::Collision(TBall* ball, vector2* nextPosition, vector2* direction,
float distance, TEdgeSegment* edge) float distance, TEdgeSegment* edge)
{ {
int soundIndex;
if (PinballTable->TiltLockFlag) if (PinballTable->TiltLockFlag)
{ {
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0); maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
return; return;
} }
auto projSpeed = maths::basic_collision( auto projSpeed = maths::basic_collision(
ball, ball,
nextPosition, nextPosition,
@ -91,18 +86,10 @@ void TCollisionComponent::Collision(TBall* ball, vector2* nextPosition, vector2*
Smoothness, Smoothness,
Threshold, Threshold,
Boost); Boost);
if (projSpeed <= Threshold) if (projSpeed > Threshold)
{ loader::play_sound(HardHitSoundId);
if (projSpeed <= 0.2f) else if (projSpeed > 0.2f)
return; loader::play_sound(SoftHitSoundId);
soundIndex = SoftHitSoundId;
}
else
{
soundIndex = HardHitSoundId;
}
if (soundIndex)
loader::play_sound(soundIndex);
} }
int TCollisionComponent::FieldEffect(TBall* ball, vector2* vecDst) int TCollisionComponent::FieldEffect(TBall* ball, vector2* vecDst)

View File

@ -22,5 +22,5 @@ public:
virtual void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, virtual void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
TEdgeSegment* edge); TEdgeSegment* edge);
virtual int FieldEffect(TBall* ball, vector2* vecDst); virtual int FieldEffect(TBall* ball, vector2* vecDst);
int DefaultCollision(TBall* ball, vector2* nextPosition, vector2* direction); bool DefaultCollision(TBall* ball, vector2* nextPosition, vector2* direction);
}; };

View File

@ -450,7 +450,7 @@ int TPinballTable::Message(int code, float value)
LightShowTimer = timer::set(time, this, LightShow_timeout); LightShowTimer = timer::set(time, this, LightShow_timeout);
} }
midi::play_track(midi::track1); midi::play_track(MidiTracks::Track1, true);
break; break;
case 1018: case 1018:
if (ReplayTimer) if (ReplayTimer)

View File

@ -968,8 +968,7 @@ void control::table_set_flag_lights()
void control::table_set_multiball() void control::table_set_multiball()
{ {
info_text_box->Display(pinball::get_rc_string(16, 0), 2.0); info_text_box->Display(pinball::get_rc_string(16, 0), 2.0);
if (midi::get_active_track() != midi::track3) midi::play_track(MidiTracks::Track3, true);
midi::play_track(midi::track3);
} }
void control::table_bump_ball_sink_lock() void control::table_bump_ball_sink_lock()
@ -2575,8 +2574,7 @@ void control::BallDrainControl(int code, TPinballComponent* caller)
{ {
lite200->Message(20, 0.0); lite200->Message(20, 0.0);
lite199->Message(20, 0.0); lite199->Message(20, 0.0);
if (midi::get_active_track() != midi::track1) midi::play_track(MidiTracks::Track1, false);
midi::play_track(midi::track1);
} }
if (light_on(&control_lite200_tag)) if (light_on(&control_lite200_tag))
{ {
@ -3107,8 +3105,7 @@ void control::GameoverController(int code, TPinballComponent* caller)
flip1->Message(1022, 0.0); flip1->Message(1022, 0.0);
flip2->Message(1022, 0.0); flip2->Message(1022, 0.0);
mission_text_box->MessageField = 0; mission_text_box->MessageField = 0;
if (midi::get_active_track() != midi::track1) midi::play_track(MidiTracks::Track1, false);
midi::play_track(midi::track1);
return; return;
} }
if (code != 67) if (code != 67)
@ -4015,8 +4012,7 @@ void control::SelectMissionController(int code, TPinballComponent* caller)
int addedScore = SpecialAddScore(mission_select_scores[scoreId]); int addedScore = SpecialAddScore(mission_select_scores[scoreId]);
snprintf(Buffer, sizeof Buffer, pinball::get_rc_string(77, 0), addedScore); snprintf(Buffer, sizeof Buffer, pinball::get_rc_string(77, 0), addedScore);
mission_text_box->Display(Buffer, 4.0); mission_text_box->Display(Buffer, 4.0);
if (midi::get_active_track() != midi::track2) midi::play_track(MidiTracks::Track2, true);
midi::play_track(midi::track2);
} }
return; return;
} }
@ -4130,8 +4126,7 @@ void control::SelectMissionController(int code, TPinballComponent* caller)
return; return;
} }
case 66: case 66:
if (midi::get_active_track() != midi::track1) midi::play_track(MidiTracks::Track1, false);
midi::play_track(midi::track1);
lite198->Message(20, 0.0); lite198->Message(20, 0.0);
outer_circle->Message(34, 0.0); outer_circle->Message(34, 0.0);
ramp_tgt_lights->Message(20, 0.0); ramp_tgt_lights->Message(20, 0.0);
@ -4419,8 +4414,7 @@ void control::WaitingDeploymentController(int code, TPinballComponent* caller)
case 66: case 66:
mission_text_box->Clear(); mission_text_box->Clear();
waiting_deployment_flag = 0; waiting_deployment_flag = 0;
if (midi::get_active_track() != midi::track1) midi::play_track(MidiTracks::Track1, false);
midi::play_track(midi::track1);
break; break;
case 67: case 67:
mission_text_box->Display(pinball::get_rc_string(50, 0), -1.0); mission_text_box->Display(pinball::get_rc_string(50, 0), -1.0);

View File

@ -7,7 +7,8 @@
std::vector<Mix_Music*> midi::LoadedTracks{}; std::vector<Mix_Music*> 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; int midi::Volume = MIX_MAX_VOLUME;
bool midi::IsPlaying = false; bool midi::IsPlaying = false;
@ -36,8 +37,8 @@ void midi::music_play()
if (!IsPlaying) if (!IsPlaying)
{ {
IsPlaying = true; IsPlaying = true;
play_track(NextTrack); play_track(NextTrack, true);
NextTrack = nullptr; NextTrack = MidiTracks::None;
} }
} }
@ -53,19 +54,20 @@ void midi::music_stop()
void midi::StopPlayback() void midi::StopPlayback()
{ {
if (active_track != nullptr) if (active_track != MidiTracks::None)
{ {
Mix_HaltMusic(); Mix_HaltMusic();
active_track = nullptr; active_track = MidiTracks::None;
} }
} }
int midi::music_init(int volume) int midi::music_init(int volume)
{ {
SetVolume(volume); SetVolume(volume);
active_track = nullptr; active_track = MidiTracks::None;
NextTrack = nullptr; NextTrack = MidiTracks::None;
IsPlaying = false; IsPlaying = false;
track1 = track2 = track3 = nullptr;
if (pb::FullTiltMode) if (pb::FullTiltMode)
{ {
@ -83,10 +85,6 @@ int midi::music_init(int volume)
track1 = load_track("PINBALL"); track1 = load_track("PINBALL");
} }
if (!track2)
track2 = track1;
if (!track3)
track3 = track1;
return track1 != nullptr; return track1 != nullptr;
} }
@ -98,7 +96,7 @@ void midi::music_shutdown()
{ {
Mix_FreeMusic(midi); Mix_FreeMusic(midi);
} }
active_track = nullptr; active_track = MidiTracks::None;
LoadedTracks.clear(); LoadedTracks.clear();
} }
@ -159,31 +157,62 @@ Mix_Music* midi::load_track(std::string fileName)
return audio; return audio;
} }
bool midi::play_track(Mix_Music* midi) bool midi::play_track(MidiTracks track, bool replay)
{ {
StopPlayback(); auto midi = TrackToMidi(track);
if (!midi) if (!midi || (!replay && active_track == track))
return false; return false;
StopPlayback();
if (!IsPlaying) if (!IsPlaying)
{ {
NextTrack = midi; NextTrack = track;
return false; return false;
} }
if (Mix_PlayMusic(midi, -1)) if (Mix_PlayMusic(midi, -1))
{ {
active_track = nullptr; active_track = MidiTracks::None;
return false; return false;
} }
// On Windows, MIDI volume can only be set during playback. // On Windows, MIDI volume can only be set during playback.
// And it changes application master volume for some reason. // And it changes application master volume for some reason.
SetVolume(Volume); SetVolume(Volume);
active_track = midi; active_track = track;
return true; 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;
}
/// <summary> /// <summary>
/// SDL_mixed does not support MIDS. To support FT music, a conversion to MIDI is required. /// SDL_mixed does not support MIDS. To support FT music, a conversion to MIDI is required.

View File

@ -83,30 +83,33 @@ static_assert(sizeof(midi_track) == 8, "Wrong size of midi_track");
#pragma pack(pop) #pragma pack(pop)
enum class MidiTracks
{
None,
Track1,
Track2,
Track3
};
class midi class midi
{ {
public: public:
static Mix_Music * track1, * track2, * track3;
static void music_play();
static void music_stop();
static int music_init(int volume); static int music_init(int volume);
static void music_shutdown(); static void music_shutdown();
static void music_play();
static void music_stop();
static void SetVolume(int volume); static void SetVolume(int volume);
static bool play_track(Mix_Music* midi); static bool play_track(MidiTracks track, bool replay);
static Mix_Music* get_active_track() static MidiTracks get_active_track();
{
if (active_track == nullptr)
return NextTrack;
else
return active_track;
}
private: private:
static std::vector<Mix_Music*> LoadedTracks; static std::vector<Mix_Music*> LoadedTracks;
static Mix_Music *active_track, *NextTrack; static Mix_Music* track1, * track2, * track3;
static MidiTracks active_track, NextTrack;
static int Volume; static int Volume;
static bool IsPlaying; static bool IsPlaying;
static void StopPlayback(); static void StopPlayback();
static Mix_Music* load_track(std::string fileName); static Mix_Music* load_track(std::string fileName);
static Mix_Music* TrackToMidi(MidiTracks track);
static std::vector<uint8_t>* MdsToMidi(std::string file); static std::vector<uint8_t>* MdsToMidi(std::string file);
}; };