mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2023-12-30 21:52:56 +00:00
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:
parent
97aea20586
commit
e283a643b3
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
#include "midi.h"
|
||||||
#include "pb.h"
|
#include "pb.h"
|
||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
@ -448,6 +449,8 @@ int TPinballTable::Message(int code, float value)
|
|||||||
auto time = loader::play_sound(SoundIndex1);
|
auto time = loader::play_sound(SoundIndex1);
|
||||||
LightShowTimer = timer::set(time, this, LightShow_timeout);
|
LightShowTimer = timer::set(time, this, LightShow_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
midi::play_track(midi::track1);
|
||||||
break;
|
break;
|
||||||
case 1018:
|
case 1018:
|
||||||
if (ReplayTimer)
|
if (ReplayTimer)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
|
||||||
|
#include "midi.h"
|
||||||
#include "pb.h"
|
#include "pb.h"
|
||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
#include "TBlocker.h"
|
#include "TBlocker.h"
|
||||||
@ -967,6 +968,8 @@ 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(midi::track3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void control::table_bump_ball_sink_lock()
|
void control::table_bump_ball_sink_lock()
|
||||||
@ -2572,6 +2575,8 @@ 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(midi::track1);
|
||||||
}
|
}
|
||||||
if (light_on(&control_lite200_tag))
|
if (light_on(&control_lite200_tag))
|
||||||
{
|
{
|
||||||
@ -3102,6 +3107,8 @@ 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(midi::track1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (code != 67)
|
if (code != 67)
|
||||||
@ -4008,6 +4015,8 @@ 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(midi::track2);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4121,6 +4130,8 @@ void control::SelectMissionController(int code, TPinballComponent* caller)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 66:
|
case 66:
|
||||||
|
if (midi::get_active_track() != midi::track1)
|
||||||
|
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);
|
||||||
@ -4408,6 +4419,8 @@ 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(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);
|
||||||
|
@ -8,8 +8,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, *midi::active_track, *midi::NextTrack;
|
||||||
bool midi::SetNextTrackFlag;
|
|
||||||
int midi::Volume = MIX_MAX_VOLUME;
|
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)
|
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;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int midi::play_pb_theme()
|
void midi::music_play()
|
||||||
{
|
{
|
||||||
// Todo: add support for tracks 2 and 3
|
if (!IsPlaying)
|
||||||
return play_track(track1);
|
{
|
||||||
|
IsPlaying = true;
|
||||||
|
play_track(NextTrack);
|
||||||
|
NextTrack = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int midi::music_stop()
|
void midi::music_stop()
|
||||||
{
|
{
|
||||||
if (active_track)
|
if (IsPlaying)
|
||||||
{
|
{
|
||||||
active_track = nullptr;
|
IsPlaying = false;
|
||||||
Mix_HaltMusic();
|
NextTrack = active_track;
|
||||||
|
StopPlayback();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
void midi::StopPlayback()
|
||||||
|
{
|
||||||
|
if (active_track != nullptr)
|
||||||
|
{
|
||||||
|
Mix_HaltMusic();
|
||||||
|
active_track = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int midi::music_init(int volume)
|
int midi::music_init(int volume)
|
||||||
{
|
{
|
||||||
SetVolume(volume);
|
SetVolume(volume);
|
||||||
active_track = nullptr;
|
active_track = nullptr;
|
||||||
|
NextTrack = nullptr;
|
||||||
|
IsPlaying = false;
|
||||||
|
|
||||||
if (pb::FullTiltMode)
|
if (pb::FullTiltMode)
|
||||||
{
|
{
|
||||||
@ -78,8 +92,7 @@ int midi::music_init(int volume)
|
|||||||
|
|
||||||
void midi::music_shutdown()
|
void midi::music_shutdown()
|
||||||
{
|
{
|
||||||
if (active_track)
|
music_stop();
|
||||||
Mix_HaltMusic();
|
|
||||||
|
|
||||||
for (auto midi : LoadedTracks)
|
for (auto midi : LoadedTracks)
|
||||||
{
|
{
|
||||||
@ -105,7 +118,7 @@ Mix_Music* midi::load_track(std::string fileName)
|
|||||||
fileName.insert(0, "SOUND");
|
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.
|
// 3DPB music is MIDI only.
|
||||||
auto basePath = pinball::make_path_name(fileName);
|
auto basePath = pinball::make_path_name(fileName);
|
||||||
for (int i = 0; i <= 1 && !audio; i++)
|
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)
|
bool midi::play_track(Mix_Music* midi)
|
||||||
{
|
{
|
||||||
music_stop();
|
StopPlayback();
|
||||||
if (!midi)
|
if (!midi)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (SetNextTrackFlag)
|
if (!IsPlaying)
|
||||||
{
|
{
|
||||||
NextTrack = midi;
|
NextTrack = midi;
|
||||||
SetNextTrackFlag = false;
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Mix_PlayMusic(midi, -1))
|
if (Mix_PlayMusic(midi, -1))
|
||||||
@ -331,7 +343,7 @@ std::vector<uint8_t>* midi::MdsToMidi(std::string file)
|
|||||||
while (false);
|
while (false);
|
||||||
|
|
||||||
delete[] fileBuf;
|
delete[] fileBuf;
|
||||||
if (returnCode && midiOut)
|
if (returnCode && midiOut)
|
||||||
{
|
{
|
||||||
delete midiOut;
|
delete midiOut;
|
||||||
midiOut = nullptr;
|
midiOut = nullptr;
|
||||||
|
@ -86,18 +86,27 @@ static_assert(sizeof(midi_track) == 8, "Wrong size of midi_track");
|
|||||||
class midi
|
class midi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static int play_pb_theme();
|
static Mix_Music * track1, * track2, * track3;
|
||||||
static int music_stop();
|
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 SetVolume(int volume);
|
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:
|
private:
|
||||||
static std::vector<Mix_Music*> LoadedTracks;
|
static std::vector<Mix_Music*> LoadedTracks;
|
||||||
static Mix_Music *track1, *track2, *track3, *active_track, *NextTrack;
|
static Mix_Music *active_track, *NextTrack;
|
||||||
static bool SetNextTrackFlag;
|
|
||||||
static int Volume;
|
static int Volume;
|
||||||
|
static bool IsPlaying;
|
||||||
|
|
||||||
|
static void StopPlayback();
|
||||||
static Mix_Music* load_track(std::string fileName);
|
static Mix_Music* load_track(std::string fileName);
|
||||||
static bool play_track(Mix_Music* midi);
|
|
||||||
static std::vector<uint8_t>* MdsToMidi(std::string file);
|
static std::vector<uint8_t>* MdsToMidi(std::string file);
|
||||||
};
|
};
|
||||||
|
@ -226,7 +226,7 @@ void options::toggle(Menu1 uIDCheckItem)
|
|||||||
if (!Options.Music)
|
if (!Options.Music)
|
||||||
midi::music_stop();
|
midi::music_stop();
|
||||||
else
|
else
|
||||||
midi::play_pb_theme();
|
midi::music_play();
|
||||||
return;
|
return;
|
||||||
case Menu1::Show_Menu:
|
case Menu1::Show_Menu:
|
||||||
Options.ShowMenu = Options.ShowMenu == 0;
|
Options.ShowMenu = Options.ShowMenu == 0;
|
||||||
|
@ -232,7 +232,7 @@ void pb::replay_level(bool demoMode)
|
|||||||
demo_mode = demoMode;
|
demo_mode = demoMode;
|
||||||
mode_change(GameModes::InGame);
|
mode_change(GameModes::InGame);
|
||||||
if (options::Options.Music)
|
if (options::Options.Music)
|
||||||
midi::play_pb_theme();
|
midi::music_play();
|
||||||
MainTable->Message(1014, static_cast<float>(options::Options.Players));
|
MainTable->Message(1014, static_cast<float>(options::Options.Players));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +379,7 @@ void pb::pause_continue()
|
|||||||
pinball::InfoTextBox->Display(text, textTime);
|
pinball::InfoTextBox->Display(text, textTime);
|
||||||
}
|
}
|
||||||
if (options::Options.Music && !winmain::single_step)
|
if (options::Options.Music && !winmain::single_step)
|
||||||
midi::play_pb_theme();
|
midi::music_play();
|
||||||
Sound::Activate();
|
Sound::Activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -813,7 +813,7 @@ int winmain::event_handler(const SDL_Event* event)
|
|||||||
activated = true;
|
activated = true;
|
||||||
Sound::Activate();
|
Sound::Activate();
|
||||||
if (Options.Music && !single_step)
|
if (Options.Music && !single_step)
|
||||||
midi::play_pb_theme();
|
midi::music_play();
|
||||||
no_time_loss = true;
|
no_time_loss = true;
|
||||||
has_focus = true;
|
has_focus = true;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user