mirror of
https://github.com/open-goal/jak-project
synced 2026-07-11 07:25:37 -04:00
Prevent putting nullptr into child sound list (#2072)
CreateChildSound did not check for nullptr return from soundbank::make_handler, which would happen for sounds with no grains. Prevent further problems with this by switching to optional instead of passing nullptr.
This commit is contained in:
@@ -626,7 +626,9 @@ void* RPC_Player2(unsigned int /*fno*/, void* data, int size) {
|
||||
snd_SetGlobalExcite(cmd->midi_reg.value);
|
||||
} else {
|
||||
Sound* sound = LookupSound(666);
|
||||
snd_SetMIDIRegister(sound->sound_handle, cmd->midi_reg.reg, cmd->midi_reg.value);
|
||||
if (sound != nullptr) {
|
||||
snd_SetMIDIRegister(sound->sound_handle, cmd->midi_reg.reg, cmd->midi_reg.value);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case Jak2SoundCommand::set_reverb: {
|
||||
|
||||
@@ -10,21 +10,6 @@
|
||||
namespace snd {
|
||||
std::array<s8, 32> g_block_reg{};
|
||||
|
||||
void blocksound_handler::init() {
|
||||
m_next_grain = 0;
|
||||
m_countdown = m_sfx.grains[0]->delay();
|
||||
|
||||
// if (m_sfx.d.Flags & 2) {
|
||||
// fmt::print("solo flag\n");
|
||||
// m_done = true;
|
||||
// return;
|
||||
// }
|
||||
|
||||
while (m_countdown <= 0 && !m_done) {
|
||||
do_grain();
|
||||
}
|
||||
}
|
||||
|
||||
bool blocksound_handler::tick() {
|
||||
m_voices.remove_if([](std::weak_ptr<blocksound_voice>& p) { return p.expired(); });
|
||||
|
||||
|
||||
@@ -92,6 +92,19 @@ class blocksound_handler : public sound_handler {
|
||||
if (params.registers.has_value()) {
|
||||
m_registers = params.registers.value();
|
||||
}
|
||||
|
||||
// Figure this stuff out properly someday
|
||||
// if (m_sfx.d.Flags & 2) {
|
||||
// fmt::print("solo flag\n");
|
||||
// m_done = true;
|
||||
// return;
|
||||
// }
|
||||
|
||||
m_next_grain = 0;
|
||||
m_countdown = m_sfx.grains[0]->delay();
|
||||
while (m_countdown <= 0 && !m_done) {
|
||||
do_grain();
|
||||
}
|
||||
}
|
||||
|
||||
~blocksound_handler() override {
|
||||
@@ -115,8 +128,6 @@ class blocksound_handler : public sound_handler {
|
||||
void set_register(u8 reg, u8 value) override { m_registers.at(reg) = value; };
|
||||
void set_pbend(s32 bend) override;
|
||||
|
||||
void init();
|
||||
|
||||
void do_grain();
|
||||
|
||||
void update_pitch();
|
||||
|
||||
@@ -33,34 +33,33 @@ MusicBank::MusicBank(locator& loc, u32 id, BankTag* tag)
|
||||
bank_name = data->BankID;
|
||||
}
|
||||
|
||||
std::unique_ptr<sound_handler> MusicBank::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) {
|
||||
std::optional<std::unique_ptr<sound_handler>> MusicBank::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) {
|
||||
auto& sound = m_sounds[sound_id];
|
||||
std::unique_ptr<sound_handler> handler;
|
||||
|
||||
if (sound.Type == 4) { // midi
|
||||
auto midi = static_cast<MIDIBlockHeader*>(m_locator.get_midi(sound.MIDIID));
|
||||
handler = std::make_unique<midi_handler>(midi, vm, sound, vol, pan, m_locator, *this);
|
||||
return std::make_unique<midi_handler>(midi, vm, sound, vol, pan, m_locator, *this);
|
||||
} else if (sound.Type == 5) { // ame
|
||||
auto midi = static_cast<MultiMIDIBlockHeader*>(m_locator.get_midi(sound.MIDIID));
|
||||
handler = std::make_unique<ame_handler>(midi, vm, sound, vol, pan, m_locator, *this);
|
||||
return std::make_unique<ame_handler>(midi, vm, sound, vol, pan, m_locator, *this);
|
||||
} else {
|
||||
lg::error("Invalid music sound type");
|
||||
return std::nullopt;
|
||||
// error
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
std::unique_ptr<sound_handler> MusicBank::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) {
|
||||
return nullptr;
|
||||
std::optional<std::unique_ptr<sound_handler>> MusicBank::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace snd
|
||||
|
||||
@@ -61,18 +61,18 @@ struct Prog;
|
||||
class MusicBank : public SoundBank {
|
||||
public:
|
||||
MusicBank(locator& loc, u32 id, BankTag* tag);
|
||||
std::unique_ptr<sound_handler> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) override;
|
||||
std::optional<std::unique_ptr<sound_handler>> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) override;
|
||||
|
||||
std::unique_ptr<sound_handler> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) override;
|
||||
std::optional<std::unique_ptr<sound_handler>> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) override;
|
||||
|
||||
std::vector<Prog> m_programs;
|
||||
std::vector<MIDISound> m_sounds;
|
||||
|
||||
@@ -132,12 +132,12 @@ u32 player::play_sound(u32 bank_id, u32 sound_id, s32 vol, s32 pan, s32 pm, s32
|
||||
}
|
||||
|
||||
auto handler = bank->make_handler(m_vmanager, sound_id, vol, pan, pm, pb);
|
||||
if (handler == nullptr) {
|
||||
if (!handler.has_value()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 handle = m_handle_allocator.get_id();
|
||||
m_handlers.emplace(handle, std::move(handler));
|
||||
m_handlers.emplace(handle, std::move(handler.value()));
|
||||
// fmt::print("play_sound {}:{} - {}\n", bank_id, sound_id, handle);
|
||||
|
||||
return handle;
|
||||
|
||||
@@ -28,21 +28,19 @@ SFXBlock::SFXBlock(locator& loc, u32 id, BankTag* tag)
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<sound_handler> SFXBlock::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) {
|
||||
std::optional<std::unique_ptr<sound_handler>> SFXBlock::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) {
|
||||
auto& SFX = m_sounds[sound_id];
|
||||
|
||||
if (SFX.grains.empty()) {
|
||||
// fmt::print("skipping empty sfx\n");
|
||||
return nullptr;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto handler =
|
||||
std::make_unique<blocksound_handler>(*this, m_sounds[sound_id], vm, vol, pan, params);
|
||||
handler->init();
|
||||
return handler;
|
||||
}
|
||||
} // namespace snd
|
||||
|
||||
@@ -53,11 +53,11 @@ struct SFX {
|
||||
class SFXBlock : public SoundBank {
|
||||
public:
|
||||
SFXBlock(locator& loc, u32 handle, BankTag* tag);
|
||||
std::unique_ptr<sound_handler> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) override;
|
||||
std::optional<std::unique_ptr<sound_handler>> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) override;
|
||||
|
||||
private:
|
||||
locator& m_locator;
|
||||
|
||||
@@ -64,27 +64,24 @@ SFXBlock2::SFXBlock2(locator& loc, u32 id, BankTag* tag)
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<sound_handler> SFXBlock2::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) {
|
||||
std::optional<std::unique_ptr<sound_handler>> SFXBlock2::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) {
|
||||
if (sound_id >= m_sounds.size()) {
|
||||
lg::error("out of bounds sound_id");
|
||||
return nullptr;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto& SFX = m_sounds[sound_id];
|
||||
|
||||
if (SFX.grains.empty()) {
|
||||
// fmt::print("skipping empty sfx\n");
|
||||
return nullptr;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
lg::info("playing sound: {}", SFX.name);
|
||||
auto handler =
|
||||
std::make_unique<blocksound_handler>(*this, m_sounds[sound_id], vm, vol, pan, params);
|
||||
handler->init();
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,11 +92,11 @@ struct SFX2 {
|
||||
class SFXBlock2 : public SoundBank {
|
||||
public:
|
||||
SFXBlock2(locator& loc, u32 handle, BankTag* tag);
|
||||
std::unique_ptr<sound_handler> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) override;
|
||||
std::optional<std::unique_ptr<sound_handler>> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) override;
|
||||
|
||||
std::optional<std::string_view> get_name() override { return m_name; };
|
||||
std::optional<u32> get_sound_by_name(const char* name) override;
|
||||
|
||||
@@ -158,7 +158,10 @@ s32 SFXGrain_StartChildSound::execute(blocksound_handler& handler) {
|
||||
s32 index = m_psp.sound_id;
|
||||
|
||||
if (index >= 0) {
|
||||
handler.m_children.emplace_front(block.make_handler(handler.m_vm, index, vol, pan, params));
|
||||
auto child_handler = block.make_handler(handler.m_vm, index, vol, pan, params);
|
||||
if (child_handler.has_value()) {
|
||||
handler.m_children.emplace_front(std::move(child_handler.value()));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,12 +38,12 @@ class SoundBank {
|
||||
SoundBank(u32 id, BankType type) : type(type), bank_id(id){};
|
||||
virtual ~SoundBank() = default;
|
||||
|
||||
virtual std::unique_ptr<sound_handler> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) {
|
||||
virtual std::optional<std::unique_ptr<sound_handler>> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) {
|
||||
SndPlayParams params{};
|
||||
params.vol = vol;
|
||||
params.pan = pan;
|
||||
@@ -53,11 +53,11 @@ class SoundBank {
|
||||
return make_handler(vm, sound_id, -1, -1, params);
|
||||
};
|
||||
|
||||
virtual std::unique_ptr<sound_handler> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) = 0;
|
||||
virtual std::optional<std::unique_ptr<sound_handler>> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
SndPlayParams& params) = 0;
|
||||
|
||||
virtual std::optional<std::string_view> get_name() { return std::nullopt; };
|
||||
virtual std::optional<u32> get_sound_by_name(const char* /*name*/) { return std::nullopt; };
|
||||
|
||||
Reference in New Issue
Block a user