void AmbientSounds::UpdateForCamType() { const WorldView::CamType cam = Pi::worldView->GetCamType(); float v_env = (cam == WorldView::CAM_EXTERNAL ? 1.0f : 0.5f) * Sound::GetSfxVolume(); if (s_stationNoise.IsPlaying()) s_stationNoise.SetVolume(0.3f*v_env, 0.3f*v_env); if (s_starNoise.IsPlaying()) s_starNoise.SetVolume(0.3f*v_env, 0.3f*v_env); if (s_planetSurfaceNoise.IsPlaying()) s_planetSurfaceNoise.SetVolume(0.3f*v_env, 0.3f*v_env); }
void AmbientSounds::Update() { float v_env = (Pi::worldView->GetActiveCamera()->IsExternal() ? 1.0f : 0.5f) * Sound::GetSfxVolume(); if (Pi::player->GetFlightState() == Ship::DOCKED) { if (starNoise.IsPlaying()) { float target[2] = {0.0f,0.0f}; float dv_dt[2] = {1.0f,1.0f}; starNoise.VolumeAnimate(target, dv_dt); starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } if (atmosphereNoise.IsPlaying()) { float target[2] = {0.0f,0.0f}; float dv_dt[2] = {1.0f,1.0f}; atmosphereNoise.VolumeAnimate(target, dv_dt); atmosphereNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } if (planetSurfaceNoise.IsPlaying()) { float target[2] = {0.0f,0.0f}; float dv_dt[2] = {1.0f,1.0f}; planetSurfaceNoise.VolumeAnimate(target, dv_dt); planetSurfaceNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } if (!stationNoise.IsPlaying()) { const char *sounds[] = { "Large_Station_ambient", "Medium_Station_ambient", "Small_Station_ambient" }; // just use a random station noise until we have a // concept of 'station size' stationNoise.Play(sounds[Pi::player->GetDockedWith()->GetSystemBody()->seed % 3], 0.3f*v_env, 0.3f*v_env, Sound::OP_REPEAT); } } else if (Pi::player->GetFlightState() == Ship::LANDED) { /* Planet surface noise on rough-landing */ if (starNoise.IsPlaying()) { float target[2] = {0.0f,0.0f}; float dv_dt[2] = {1.0f,1.0f}; starNoise.VolumeAnimate(target, dv_dt); starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } if (atmosphereNoise.IsPlaying()) { float target[2] = {0.0f,0.0f}; float dv_dt[2] = {1.0f,1.0f}; atmosphereNoise.VolumeAnimate(target, dv_dt); atmosphereNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } if (stationNoise.IsPlaying()) { float target[2] = {0.0f,0.0f}; float dv_dt[2] = {1.0f,1.0f}; stationNoise.VolumeAnimate(target, dv_dt); stationNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } // lets try something random for the time being if (!planetSurfaceNoise.IsPlaying()) { SystemBody *sbody = Pi::player->GetFrame()->GetSystemBodyFor(); assert(sbody); const char *sample = NULL; if (sbody->m_life > fixed(1,5)) { const char *s[] = { "Wind", "Thunder_1", "Thunder_2", "Thunder_3", "Thunder_4", "Storm", "Rain_Light", "River", "RainForestIntroducedNight", "RainForestIntroduced", "NormalForestIntroduced" }; sample = s[sbody->seed % 11]; } else if (sbody->m_volatileGas > fixed(1,2)) { const char *s[] = { "Wind", "Thunder_1", "Thunder_2", "Thunder_3", "Thunder_4", "Storm" }; sample = s[sbody->seed % 6]; } else if (sbody->m_volatileGas > fixed(1,10)) { sample = "Wind"; } if (sample) { planetSurfaceNoise.Play(sample, 0.3f*v_env, 0.3f*v_env, Sound::OP_REPEAT); } } } else if (planetSurfaceNoise.IsPlaying()) { // planetSurfaceNoise.IsPlaying() - if we are out of the atmosphere then stop playing if (Pi::player->GetFrame()->m_astroBody) { Body *astro = Pi::player->GetFrame()->m_astroBody; if (astro->IsType(Object::PLANET)) { double dist = Pi::player->GetPosition().Length(); double pressure, density; static_cast<Planet*>(astro)->GetAtmosphericState(dist, &pressure, &density); if (pressure < 0.001) { // Stop playing surface noise once out of the atmosphere planetSurfaceNoise.Stop(); } } } } else { if (stationNoise.IsPlaying()) { float target[2] = {0.0f,0.0f}; float dv_dt[2] = {1.0f,1.0f}; stationNoise.VolumeAnimate(target, dv_dt); stationNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } { if (Pi::game->IsNormalSpace()) { StarSystem *s = Pi::game->GetSpace()->GetStarSystem().Get(); if (astroNoiseSeed != s->GetSeed()) { // change sound! astroNoiseSeed = s->GetSeed(); float target[2] = {0.0f,0.0f}; float dv_dt[2] = {0.1f,0.1f}; starNoise.VolumeAnimate(target, dv_dt); starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); // XXX the way Sound::Event works isn't totally obvious. // to destroy the object doesn't stop the sound. it is // really just a sound event reference starNoise = Sound::Event(); } } } // when all the sounds are in we can use the body we are in frame of reference to if (!starNoise.IsPlaying()) { Frame *f = Pi::player->GetFrame(); if (!f) return; // When player has no frame (game abort) then get outta here!! const SystemBody *sbody = f->GetSystemBodyFor(); const char *sample = 0; for (; sbody && !sample; sbody = f->GetSystemBodyFor()) { switch (sbody->type) { case SystemBody::TYPE_BROWN_DWARF: sample = "Brown_Dwarf_Substellar_Object"; break; case SystemBody::TYPE_STAR_M: sample = "M_Red_Star"; break; case SystemBody::TYPE_STAR_K: sample = "K_Star"; break; case SystemBody::TYPE_WHITE_DWARF: sample = "White_Dwarf_Star"; break; case SystemBody::TYPE_STAR_G: sample = "G_Star"; break; case SystemBody::TYPE_STAR_F: sample = "F_Star"; break; case SystemBody::TYPE_STAR_A: sample = "A_Star"; break; case SystemBody::TYPE_STAR_B: sample = "B_Hot_Blue_STAR"; break; case SystemBody::TYPE_STAR_O: sample = "Blue_Super_Giant"; break; case SystemBody::TYPE_PLANET_GAS_GIANT: { if (sbody->mass > fixed(400,1)) { sample = "Very_Large_Gas_Giant"; } else if (sbody->mass > fixed(80,1)) { sample = "Large_Gas_Giant"; } else if (sbody->mass > fixed(20,1)) { sample = "Medium_Gas_Giant"; } else { sample = "Small_Gas_Giant"; } } break; default: sample = 0; break; } if (sample) { starNoise.Play(sample, 0.0f, 0.0f, Sound::OP_REPEAT); starNoise.VolumeAnimate(.3f*v_env, .3f*v_env, .05f, .05f); } else { // go up orbital hierarchy tree to see if we can find a sound f = f->m_parent; if (f == 0) break; } } } Body *astro; if ((astro = Pi::player->GetFrame()->m_astroBody) && (astro->IsType(Object::PLANET))) { double dist = Pi::player->GetPosition().Length(); double pressure, density; static_cast<Planet*>(astro)->GetAtmosphericState(dist, &pressure, &density); // maximum volume at around 2km/sec at earth density, pressure float volume = float(density * Pi::player->GetVelocity().Length() * 0.0005); volume = Clamp(volume, 0.0f, 1.0f) * v_env; if (atmosphereNoise.IsPlaying()) { float target[2] = {volume, volume}; float dv_dt[2] = {1.0f,1.0f}; atmosphereNoise.VolumeAnimate(target, dv_dt); } else { atmosphereNoise.Play("Atmosphere_Flying", volume, volume, Sound::OP_REPEAT); } } else { float target[2] = {0.0f,0.0f}; float dv_dt[2] = {1.0f,1.0f}; atmosphereNoise.VolumeAnimate(target, dv_dt); atmosphereNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } } }
void AmbientSounds::Update() { const float v_env = (Pi::worldView->GetCameraController()->IsExternal() ? 1.0f : 0.5f) * Sound::GetSfxVolume(); if (Pi::player->GetFlightState() == Ship::DOCKED) { if (s_starNoise.IsPlaying()) { const float target[2] = {0.0f,0.0f}; const float dv_dt[2] = {1.0f,1.0f}; s_starNoise.VolumeAnimate(target, dv_dt); s_starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } for(int i=0; i<eMaxNumAtmosphereSounds; i++) { if (s_atmosphereNoises[i].IsPlaying()) { const float target[2] = {0.0f,0.0f}; const float dv_dt[2] = {1.0f,1.0f}; s_atmosphereNoises[i].VolumeAnimate(target, dv_dt); s_atmosphereNoises[i].SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } } if (s_planetSurfaceNoise.IsPlaying()) { const float target[2] = {0.0f,0.0f}; const float dv_dt[2] = {1.0f,1.0f}; s_planetSurfaceNoise.VolumeAnimate(target, dv_dt); s_planetSurfaceNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } if (!s_stationNoise.IsPlaying()) { // just use a random station noise until we have a // concept of 'station size' s_stationNoise.Play(s_stationNoiseSounds[Pi::player->GetDockedWith()->GetSystemBody()->GetSeed() % NUM_STATION_SOUNDS], 0.3f*v_env, 0.3f*v_env, Sound::OP_REPEAT); } } else if (Pi::player->GetFlightState() == Ship::LANDED) { /* Planet surface noise on rough-landing */ if (s_starNoise.IsPlaying()) { const float target[2] = {0.0f,0.0f}; const float dv_dt[2] = {1.0f,1.0f}; s_starNoise.VolumeAnimate(target, dv_dt); s_starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } for(int i=0; i<eMaxNumAtmosphereSounds; i++) { if (s_atmosphereNoises[i].IsPlaying()) { const float target[2] = {0.0f,0.0f}; const float dv_dt[2] = {1.0f,1.0f}; s_atmosphereNoises[i].VolumeAnimate(target, dv_dt); s_atmosphereNoises[i].SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } } if (s_stationNoise.IsPlaying()) { const float target[2] = {0.0f,0.0f}; const float dv_dt[2] = {1.0f,1.0f}; s_stationNoise.VolumeAnimate(target, dv_dt); s_stationNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } // lets try something random for the time being if (!s_planetSurfaceNoise.IsPlaying()) { const SystemBody *sbody = Pi::player->GetFrame()->GetSystemBody(); assert(sbody); const char *sample = 0; if (sbody->GetLifeAsFixed() > fixed(1,5)) { sample = s_surfaceLifeSounds[sbody->GetSeed() % NUM_SURFACE_LIFE_SOUNDS]; } else if (sbody->GetVolatileGasAsFixed() > fixed(1,2)) { sample = s_surfaceSounds[sbody->GetSeed() % NUM_SURFACE_DEAD_SOUNDS]; } else if (sbody->GetVolatileGasAsFixed() > fixed(1,10)) { sample = "Wind"; } if (sample) { s_planetSurfaceNoise.Play(sample, 0.3f*v_env, 0.3f*v_env, Sound::OP_REPEAT); } } } else if (s_planetSurfaceNoise.IsPlaying()) { // s_planetSurfaceNoise.IsPlaying() - if we are out of the atmosphere then stop playing if (Pi::player->GetFrame()->IsRotFrame()) { const Body *astro = Pi::player->GetFrame()->GetBody(); if (astro->IsType(Object::PLANET)) { const double dist = Pi::player->GetPosition().Length(); double pressure, density; static_cast<const Planet*>(astro)->GetAtmosphericState(dist, &pressure, &density); if (pressure < 0.001) { // Stop playing surface noise once out of the atmosphere s_planetSurfaceNoise.Stop(); } } } } else { if (s_stationNoise.IsPlaying()) { const float target[2] = {0.0f,0.0f}; const float dv_dt[2] = {1.0f,1.0f}; s_stationNoise.VolumeAnimate(target, dv_dt); s_stationNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } if (Pi::game->IsNormalSpace()) { StarSystem *s = Pi::game->GetSpace()->GetStarSystem().Get(); if (astroNoiseSeed != s->GetSeed()) { // change sound! astroNoiseSeed = s->GetSeed(); const float target[2] = {0.0f,0.0f}; const float dv_dt[2] = {0.1f,0.1f}; s_starNoise.VolumeAnimate(target, dv_dt); s_starNoise.SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); // XXX the way Sound::Event works isn't totally obvious. // to destroy the object doesn't stop the sound. it is // really just a sound event reference s_starNoise = Sound::Event(); } } // when all the sounds are in we can use the body we are in frame of reference to if (!s_starNoise.IsPlaying()) { Frame *f = Pi::player->GetFrame(); if (!f) return; // When player has no frame (game abort) then get outta here!! const SystemBody *sbody = f->GetSystemBody(); const char *sample = 0; for (; sbody && !sample; sbody = f->GetSystemBody()) { switch (sbody->GetType()) { case SystemBody::TYPE_BROWN_DWARF: sample = "Brown_Dwarf_Substellar_Object"; break; case SystemBody::TYPE_STAR_M: sample = "M_Red_Star"; break; case SystemBody::TYPE_STAR_K: sample = "K_Star"; break; case SystemBody::TYPE_WHITE_DWARF: sample = "White_Dwarf_Star"; break; case SystemBody::TYPE_STAR_G: sample = "G_Star"; break; case SystemBody::TYPE_STAR_F: sample = "F_Star"; break; case SystemBody::TYPE_STAR_A: sample = "A_Star"; break; case SystemBody::TYPE_STAR_B: sample = "B_Hot_Blue_STAR"; break; case SystemBody::TYPE_STAR_O: sample = "Blue_Super_Giant"; break; case SystemBody::TYPE_PLANET_GAS_GIANT: { if (sbody->GetMassAsFixed() > fixed(400,1)) { sample = "Very_Large_Gas_Giant"; } else if (sbody->GetMassAsFixed() > fixed(80,1)) { sample = "Large_Gas_Giant"; } else if (sbody->GetMassAsFixed() > fixed(20,1)) { sample = "Medium_Gas_Giant"; } else { sample = "Small_Gas_Giant"; } } break; default: sample = 0; break; } if (sample) { s_starNoise.Play(sample, 0.0f, 0.0f, Sound::OP_REPEAT); s_starNoise.VolumeAnimate(.3f*v_env, .3f*v_env, .05f, .05f); } else { // go up orbital hierarchy tree to see if we can find a sound f = f->GetParent(); if (f == 0) break; } } } const Body *astro = Pi::player->GetFrame()->GetBody(); if (astro && Pi::player->GetFrame()->IsRotFrame() && (astro->IsType(Object::PLANET))) { double dist = Pi::player->GetPosition().Length(); double pressure, density; static_cast<const Planet*>(astro)->GetAtmosphericState(dist, &pressure, &density); // maximum volume at around 2km/sec at earth density, pressure const float pressureVolume = float(density * Pi::player->GetVelocity().Length() * 0.0005); //volume = Clamp(volume, 0.0f, 1.0f) * v_env; float volumes[eMaxNumAtmosphereSounds]; for(int i=0; i<eMaxNumAtmosphereSounds; i++) { const float beg = s_rangeTable[i][0]; const float inv = s_rangeTable[i][1]; volumes[i] = Clamp((pressureVolume - beg) * inv, 0.0f, 1.0f) * v_env; } for(int i=0; i<eMaxNumAtmosphereSounds; i++) { const float volume = volumes[i]; if (s_atmosphereNoises[i].IsPlaying()) { const float target[2] = {volume, volume}; const float dv_dt[2] = {1.0f,1.0f}; s_atmosphereNoises[i].VolumeAnimate(target, dv_dt); } else { s_atmosphereNoises[i].Play(s_airflowTable[i], volume, volume, Sound::OP_REPEAT); } } } else { const float target[2] = {0.0f,0.0f}; const float dv_dt[2] = {1.0f,1.0f}; for(int i=0; i<eMaxNumAtmosphereSounds; i++) { s_atmosphereNoises[i].VolumeAnimate(target, dv_dt); s_atmosphereNoises[i].SetOp(Sound::OP_REPEAT | Sound::OP_STOP_AT_TARGET_VOLUME); } } } }
void Player::StaticUpdate(const float timeStep) { vector3d v; matrix4x4d m; Ship::StaticUpdate(timeStep); // also calls autopilot AI if (GetFlightState() == Ship::FLYING) { switch (m_flightControlState) { case CONTROL_FIXSPEED: if (Pi::GetView() == Pi::worldView) PollControls(timeStep); if (IsAnyThrusterKeyDown()) break; GetRotMatrix(m); v = m * vector3d(0, 0, -m_setSpeed); if (m_setSpeedTarget) { v += m_setSpeedTarget->GetVelocityRelTo(GetFrame()); } AIMatchVel(v); break; case CONTROL_MANUAL: if (Pi::GetView() == Pi::worldView) PollControls(timeStep); break; case CONTROL_AUTOPILOT: if (AIIsActive()) break; Pi::game->RequestTimeAccel(Game::TIMEACCEL_1X); // AIMatchVel(vector3d(0.0)); // just in case autopilot doesn't... // actually this breaks last timestep slightly in non-relative target cases AIMatchAngVelObjSpace(vector3d(0.0)); if (GetFrame()->IsRotatingFrame()) SetFlightControlState(CONTROL_FIXSPEED); else SetFlightControlState(CONTROL_MANUAL); m_setSpeed = 0.0; break; } } else SetFlightControlState(CONTROL_MANUAL); /* This wank probably shouldn't be in Player... */ /* Ship engine noise. less loud inside */ float v_env = (Pi::worldView->GetCamType() == WorldView::CAM_EXTERNAL ? 1.0f : 0.5f) * Sound::GetSfxVolume(); static Sound::Event sndev; float volBoth = 0.0f; volBoth += 0.5f*fabs(GetThrusterState().y); volBoth += 0.5f*fabs(GetThrusterState().z); float targetVol[2] = { volBoth, volBoth }; if (GetThrusterState().x > 0.0) targetVol[0] += 0.5f*float(GetThrusterState().x); else targetVol[1] += -0.5f*float(GetThrusterState().x); targetVol[0] = v_env * Clamp(targetVol[0], 0.0f, 1.0f); targetVol[1] = v_env * Clamp(targetVol[1], 0.0f, 1.0f); float dv_dt[2] = { 4.0f, 4.0f }; if (!sndev.VolumeAnimate(targetVol, dv_dt)) { sndev.Play("Thruster_large", 0.0f, 0.0f, Sound::OP_REPEAT); sndev.VolumeAnimate(targetVol, dv_dt); } float angthrust = 0.1f * v_env * float(Pi::player->GetAngThrusterState().Length()); static Sound::Event angThrustSnd; if (!angThrustSnd.VolumeAnimate(angthrust, angthrust, 5.0f, 5.0f)) { angThrustSnd.Play("Thruster_Small", 0.0f, 0.0f, Sound::OP_REPEAT); angThrustSnd.VolumeAnimate(angthrust, angthrust, 5.0f, 5.0f); } }
void Player::AbortHyperjump() { s_soundHyperdrive.Play("Hyperdrive_Abort"); Ship::AbortHyperjump(); }
void Player::ResetHyperspaceCountdown() { s_soundHyperdrive.Play("Hyperdrive_Abort"); Ship::ResetHyperspaceCountdown(); }