#include "muxer.h" #include #include #include "runtime.h" void ERRCHECK_fn(FMOD_RESULT result, const char* file, int line) { if (result != FMOD_OK) { std::cout << file << "(" << line << "): FMOD error " << result << " - " << FMOD_ErrorString(result); abort(); } } #define ERRCHECK(_result) ERRCHECK_fn(_result, __FILE__, __LINE__) Muxer::Muxer() { FMOD::Studio::System* system_holder = nullptr; ERRCHECK(FMOD::Studio::System::create(&system_holder)); system_.reset(system_holder); FMOD::System* coreSystem = nullptr; ERRCHECK(system_->getCoreSystem(&coreSystem)); ERRCHECK(coreSystem->setSoftwareFormat(0, FMOD_SPEAKERMODE_5POINT1, 0)); ERRCHECK(system_->initialize(1024, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, nullptr)); FMOD::Studio::Bank* masterBank = nullptr; ERRCHECK(system_->loadBankFile(Runtime::getResourcePath("Master.bank").c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank)); FMOD::Studio::Bank* stringsBank = nullptr; ERRCHECK(system_->loadBankFile(Runtime::getResourcePath("Master.strings.bank").c_str(), FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank)); } void Muxer::setPlayerLoc(int x, int y) { FMOD_3D_ATTRIBUTES attributes = {{0}}; attributes.forward.z = 1.0f; attributes.up.y = 1.0f; attributes.position.x = x; attributes.position.y = y; ERRCHECK(system_->setListenerAttributes(0, &attributes)); } void Muxer::playSound(std::string name) { if (muted_) return; std::string eventPath = std::string("event:/") + name; FMOD::Studio::EventDescription* eventDescription = nullptr; ERRCHECK(system_->getEvent(eventPath.c_str(), &eventDescription)); FMOD::Studio::EventInstance* eventInstance = nullptr; ERRCHECK(eventDescription->createInstance(&eventInstance)); ERRCHECK(eventInstance->start()); ERRCHECK(eventInstance->release()); } void Muxer::playSoundAtPosition(std::string name, float x, float y) { if (muted_) return; std::string eventPath = std::string("event:/") + name; FMOD::Studio::EventDescription* eventDescription = nullptr; ERRCHECK(system_->getEvent(eventPath.c_str(), &eventDescription)); FMOD::Studio::EventInstance* eventInstance = nullptr; ERRCHECK(eventDescription->createInstance(&eventInstance)); FMOD_3D_ATTRIBUTES attributes = {{0}}; attributes.forward.z = 1.0f; attributes.up.y = 1.0f; attributes.position.x = x; attributes.position.y = y; ERRCHECK(eventInstance->set3DAttributes(&attributes)); ERRCHECK(eventInstance->start()); ERRCHECK(eventInstance->release()); } void Muxer::setMusicLevel(int level) { if (transition_state_ == TransitionState::Pre) { if (level >= 3) { ERRCHECK(exploration_event_->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT)); ERRCHECK(exploration_event_->release()); if (muted_) { FMOD::Studio::EventDescription* eventDescription = nullptr; ERRCHECK(system_->getEvent("event:/the_world", &eventDescription)); ERRCHECK(eventDescription->createInstance(&the_world_event_)); ERRCHECK(the_world_event_->start()); ERRCHECK(the_world_event_->setVolume(0)); transition_state_ = TransitionState::Post; } else { FMOD::Studio::EventDescription* eventDescription = nullptr; ERRCHECK(system_->getEvent("event:/transition", &eventDescription)); ERRCHECK(eventDescription->createInstance(&transition_event_)); ERRCHECK(transition_event_->start()); transition_state_ = TransitionState::Transition; } } else { ERRCHECK(exploration_event_->setParameterByName("level", level)); } } else if (transition_state_ == TransitionState::Post) { if (level <= 3) { ERRCHECK(the_world_event_->setParameterByName("level_full", 0)); } else { ERRCHECK(the_world_event_->setParameterByName("level_full", level - 3)); } } } void Muxer::startMusic() { FMOD::Studio::EventDescription* exploration_desc = nullptr; ERRCHECK(system_->getEvent("event:/exploration", &exploration_desc)); ERRCHECK(exploration_desc->createInstance(&exploration_event_)); ERRCHECK(exploration_event_->start()); if (muted_) { ERRCHECK(exploration_event_->setVolume(0)); } transition_state_ = TransitionState::Pre; } void Muxer::stopMusic() { switch (transition_state_) { case TransitionState::Pre: { ERRCHECK(exploration_event_->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT)); break; } case TransitionState::Transition: { ERRCHECK(transition_event_->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT)); break; } case TransitionState::Post: { ERRCHECK(the_world_event_->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT)); break; } case TransitionState::Stopped: { // Do nothing. break; } } transition_state_ = TransitionState::Stopped; } void Muxer::update() { if (transition_state_ == TransitionState::Transition) { FMOD_STUDIO_PLAYBACK_STATE playbackState; ERRCHECK(transition_event_->getPlaybackState(&playbackState)); if (playbackState == FMOD_STUDIO_PLAYBACK_STOPPED) { transition_state_ = TransitionState::Post; transition_event_->release(); FMOD::Studio::EventDescription* eventDescription = nullptr; ERRCHECK(system_->getEvent("event:/the_world", &eventDescription)); ERRCHECK(eventDescription->createInstance(&the_world_event_)); ERRCHECK(the_world_event_->start()); if (muted_) { ERRCHECK(the_world_event_->setVolume(0)); } } } ERRCHECK(system_->update()); } void Muxer::toggleMute() { muted_ = !muted_; if (muted_) { switch (transition_state_) { case TransitionState::Pre: { ERRCHECK(exploration_event_->setVolume(0)); break; } case TransitionState::Transition: { ERRCHECK(transition_event_->setVolume(0)); break; } case TransitionState::Post: { ERRCHECK(the_world_event_->setVolume(0)); break; } case TransitionState::Stopped: { // Do nothing. break; } } } else { switch (transition_state_) { case TransitionState::Pre: { ERRCHECK(exploration_event_->setVolume(1)); break; } case TransitionState::Transition: { ERRCHECK(transition_event_->setVolume(1)); break; } case TransitionState::Post: { ERRCHECK(the_world_event_->setVolume(1)); break; } case TransitionState::Stopped: { // Do nothing. break; } } } }