Added support for multiple music tracks in FT mode.

Note that taba3 is not currently played as it needs multiball support.
Issue #129.
This commit is contained in:
Muzychenko Andrey 2022-05-20 19:32:09 +03:00
parent 97aea20586
commit e283a643b3
7 changed files with 63 additions and 26 deletions

View File

@ -4,6 +4,7 @@
#include "control.h"
#include "loader.h"
#include "midi.h"
#include "pb.h"
#include "pinball.h"
#include "render.h"
@ -448,6 +449,8 @@ int TPinballTable::Message(int code, float value)
auto time = loader::play_sound(SoundIndex1);
LightShowTimer = timer::set(time, this, LightShow_timeout);
}
midi::play_track(midi::track1);
break;
case 1018:
if (ReplayTimer)

View File

@ -1,6 +1,7 @@
#include "pch.h"
#include "control.h"
#include "midi.h"
#include "pb.h"
#include "pinball.h"
#include "TBlocker.h"
@ -967,6 +968,8 @@ 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);
}
void control::table_bump_ball_sink_lock()
@ -2572,6 +2575,8 @@ 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);
}
if (light_on(&control_lite200_tag))
{
@ -3102,6 +3107,8 @@ 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);
return;
}
if (code != 67)
@ -4008,6 +4015,8 @@ 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);
}
return;
}
@ -4121,6 +4130,8 @@ void control::SelectMissionController(int code, TPinballComponent* caller)
return;
}
case 66:
if (midi::get_active_track() != midi::track1)
midi::play_track(midi::track1);
lite198->Message(20, 0.0);
outer_circle->Message(34, 0.0);
ramp_tgt_lights->Message(20, 0.0);
@ -4408,6 +4419,8 @@ 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);
break;
case 67:
mission_text_box->Display(pinball::get_rc_string(50, 0), -1.0);

View File

@ -8,8 +8,8 @@
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;
bool midi::IsPlaying = false;
constexpr uint32_t FOURCC(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
@ -31,27 +31,41 @@ int ToVariableLen(uint32_t value, uint32_t& dst)
return count;
}
int midi::play_pb_theme()
void midi::music_play()
{
// Todo: add support for tracks 2 and 3
return play_track(track1);
if (!IsPlaying)
{
IsPlaying = true;
play_track(NextTrack);
NextTrack = nullptr;
}
}
int midi::music_stop()
void midi::music_stop()
{
if (active_track)
if (IsPlaying)
{
active_track = nullptr;
Mix_HaltMusic();
IsPlaying = false;
NextTrack = active_track;
StopPlayback();
}
}
return true;
void midi::StopPlayback()
{
if (active_track != nullptr)
{
Mix_HaltMusic();
active_track = nullptr;
}
}
int midi::music_init(int volume)
{
SetVolume(volume);
active_track = nullptr;
NextTrack = nullptr;
IsPlaying = false;
if (pb::FullTiltMode)
{
@ -78,8 +92,7 @@ int midi::music_init(int volume)
void midi::music_shutdown()
{
if (active_track)
Mix_HaltMusic();
music_stop();
for (auto midi : LoadedTracks)
{
@ -105,7 +118,7 @@ Mix_Music* midi::load_track(std::string fileName)
fileName.insert(0, "SOUND");
}
// FT has music in two formats, depending on version: MIDI in 16bit, MIDS in 32bit.
// FT has music in two formats, depending on game version: MIDI in 16bit, MIDS in 32bit.
// 3DPB music is MIDI only.
auto basePath = pinball::make_path_name(fileName);
for (int i = 0; i <= 1 && !audio; i++)
@ -148,15 +161,14 @@ Mix_Music* midi::load_track(std::string fileName)
bool midi::play_track(Mix_Music* midi)
{
music_stop();
StopPlayback();
if (!midi)
return false;
if (SetNextTrackFlag)
if (!IsPlaying)
{
NextTrack = midi;
SetNextTrackFlag = false;
return true;
return false;
}
if (Mix_PlayMusic(midi, -1))
@ -331,7 +343,7 @@ std::vector<uint8_t>* midi::MdsToMidi(std::string file)
while (false);
delete[] fileBuf;
if (returnCode && midiOut)
if (returnCode && midiOut)
{
delete midiOut;
midiOut = nullptr;

View File

@ -86,18 +86,27 @@ static_assert(sizeof(midi_track) == 8, "Wrong size of midi_track");
class midi
{
public:
static int play_pb_theme();
static int music_stop();
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 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;
}
private:
static std::vector<Mix_Music*> LoadedTracks;
static Mix_Music *track1, *track2, *track3, *active_track, *NextTrack;
static bool SetNextTrackFlag;
static Mix_Music *active_track, *NextTrack;
static int Volume;
static bool IsPlaying;
static void StopPlayback();
static Mix_Music* load_track(std::string fileName);
static bool play_track(Mix_Music* midi);
static std::vector<uint8_t>* MdsToMidi(std::string file);
};

View File

@ -226,7 +226,7 @@ void options::toggle(Menu1 uIDCheckItem)
if (!Options.Music)
midi::music_stop();
else
midi::play_pb_theme();
midi::music_play();
return;
case Menu1::Show_Menu:
Options.ShowMenu = Options.ShowMenu == 0;

View File

@ -232,7 +232,7 @@ void pb::replay_level(bool demoMode)
demo_mode = demoMode;
mode_change(GameModes::InGame);
if (options::Options.Music)
midi::play_pb_theme();
midi::music_play();
MainTable->Message(1014, static_cast<float>(options::Options.Players));
}
@ -379,7 +379,7 @@ void pb::pause_continue()
pinball::InfoTextBox->Display(text, textTime);
}
if (options::Options.Music && !winmain::single_step)
midi::play_pb_theme();
midi::music_play();
Sound::Activate();
}
}

View File

@ -813,7 +813,7 @@ int winmain::event_handler(const SDL_Event* event)
activated = true;
Sound::Activate();
if (Options.Music && !single_step)
midi::play_pb_theme();
midi::music_play();
no_time_loss = true;
has_focus = true;
break;