ItemEffect* getItemEffect(int itemID) { const itemdata& data=itemsbuf[itemID]; switch(data.family) { case itype_clock: return new ClockEffect(Link, data.misc1); case itype_nayruslove: if(get_bit(quest_rules,qr_MORESOUNDS)) { return new NayrusLoveEffect(Link, data.misc1, sfxMgr.getSFX(data.usesound), sfxMgr.getSFX(data.usesound+1)); } else return new NayrusLoveEffect(Link, data.misc1, SFX(0), SFX(0)); } return 0; }
/** This loops runs in a different threads, and starts sfx to be played. * This can sometimes take up to 5 ms, so it needs to be handled in a thread * in order to avoid rendering delays. * \param obj A pointer to the SFX singleton. */ void* SFXManager::mainLoop(void *obj) { SFXManager *me = (SFXManager*)obj; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); me->m_sfx_commands.lock(); // Wait till we have an empty sfx in the queue while (me->m_sfx_commands.getData().empty() || me->m_sfx_commands.getData().front()->m_command!=SFX_EXIT) { bool empty = me->m_sfx_commands.getData().empty(); // Wait in cond_wait for a request to arrive. The 'while' is necessary // since "spurious wakeups from the pthread_cond_wait ... may occur" // (pthread_cond_wait man page)! while (empty) { pthread_cond_wait(&me->m_cond_request, me->m_sfx_commands.getMutex()); empty = me->m_sfx_commands.getData().empty(); } SFXCommand *current = me->m_sfx_commands.getData().front(); me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); if (current->m_command == SFX_EXIT) { delete current; break; } me->m_sfx_commands.unlock(); switch (current->m_command) { case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; case SFX_STOP: current->m_sfx->reallyStopNow(); break; case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; case SFX_SPEED: current->m_sfx->reallySetSpeed( current->m_parameter.getX()); break; case SFX_POSITION: current->m_sfx->reallySetPosition( current->m_parameter); break; case SFX_VOLUME: current->m_sfx->reallySetVolume( current->m_parameter.getX()); break; case SFX_MASTER_VOLUME: current->m_sfx->reallySetMasterVolumeNow( current->m_parameter.getX()); break; case SFX_LOOP: current->m_sfx->reallySetLoop( current->m_parameter.getX() != 0); break; case SFX_DELETE: me->deleteSFX(current->m_sfx); break; case SFX_PAUSE_ALL: me->reallyPauseAllNow(); break; case SFX_RESUME_ALL: me->reallyResumeAllNow(); break; case SFX_LISTENER: me->reallyPositionListenerNow(); break; case SFX_UPDATE: me->reallyUpdateNow(current); break; case SFX_MUSIC_START: { current->m_music_information->setDefaultVolume(); current->m_music_information->startMusic(); break; } case SFX_MUSIC_STOP: current->m_music_information->stopMusic(); break; case SFX_MUSIC_PAUSE: current->m_music_information->pauseMusic(); break; case SFX_MUSIC_RESUME: current->m_music_information->resumeMusic(); // This might be necessasary if the volume was changed // in the in-game menu current->m_music_information->setDefaultVolume(); break; case SFX_MUSIC_SWITCH_FAST: current->m_music_information->switchToFastMusic(); break; case SFX_MUSIC_SET_TMP_VOLUME: { MusicInformation *mi = current->m_music_information; mi->setTemporaryVolume(current->m_parameter.getX()); break; } case SFX_MUSIC_WAITING: current->m_music_information->setMusicWaiting(); break; case SFX_MUSIC_DEFAULT_VOLUME: { current->m_music_information->setDefaultVolume(); } default: assert("Not yet supported."); } delete current; current = NULL; // We access the size without lock, doesn't matter if we // should get an incorrect value because of concurrent read/writes if (me->m_sfx_commands.getData().size() == 0) { // Wait some time to let other threads run, then queue an // update event to keep music playing. double t = StkTime::getRealTime(); StkTime::sleep(1); t = StkTime::getRealTime() - t; me->queue(SFX_UPDATE, (SFXBase*)NULL, float(t)); } me->m_sfx_commands.lock(); } // while // Signal that the sfx manager can now be deleted. // We signal this even before cleaning up memory, since there is no // need to keep the user waiting for STK to exit. me->setCanBeDeleted(); // Clean up memory to avoid leak detection while(!me->m_sfx_commands.getData().empty()) { delete me->m_sfx_commands.getData().front(); me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); } return NULL; } // mainLoop
/** This loops runs in a different threads, and starts sfx to be played. * This can sometimes take up to 5 ms, so it needs to be handled in a thread * in order to avoid rendering delays. * \param obj A pointer to the SFX singleton. */ void* SFXManager::mainLoop(void *obj) { SFXManager *me = (SFXManager*)obj; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); me->m_sfx_commands.lock(); // Wait till we have an empty sfx in the queue while (me->m_sfx_commands.getData().empty() || me->m_sfx_commands.getData().front()->m_command!=SFX_EXIT) { bool empty = me->m_sfx_commands.getData().empty(); // Wait in cond_wait for a request to arrive. The 'while' is necessary // since "spurious wakeups from the pthread_cond_wait ... may occur" // (pthread_cond_wait man page)! while (empty) { pthread_cond_wait(&me->m_cond_request, me->m_sfx_commands.getMutex()); empty = me->m_sfx_commands.getData().empty(); } SFXCommand *current = me->m_sfx_commands.getData().front(); me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); if (current->m_command == SFX_EXIT) { delete current; break; } me->m_sfx_commands.unlock(); switch(current->m_command) { case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; case SFX_STOP: current->m_sfx->reallyStopNow(); break; case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; case SFX_SPEED: current->m_sfx->reallySetSpeed( current->m_parameter.getX()); break; case SFX_POSITION: current->m_sfx->reallySetPosition( current->m_parameter); break; case SFX_VOLUME: current->m_sfx->reallySetVolume( current->m_parameter.getX()); break; case SFX_MASTER_VOLUME: current->m_sfx->reallySetMasterVolumeNow( current->m_parameter.getX()); break; case SFX_LOOP: current->m_sfx->reallySetLoop( current->m_parameter.getX()!=0); break; case SFX_DELETE: { me->deleteSFX(current->m_sfx); break; } case SFX_PAUSE_ALL: me->reallyPauseAllNow(); break; case SFX_RESUME_ALL: me->reallyResumeAllNow(); break; case SFX_LISTENER: me->reallyPositionListenerNow(); break; case SFX_UPDATE: me->reallyUpdateNow(current); break; default: assert("Not yet supported."); } delete current; current = NULL; me->m_sfx_commands.lock(); } // while // Clean up memory to avoid leak detection while(!me->m_sfx_commands.getData().empty()) { delete me->m_sfx_commands.getData().front(); me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin()); } return NULL; } // mainLoop
LinkHandler::LinkHandler(): link(Link), lowHealthSFX(sfxMgr.getSFX(WAV_ER)) { }