positional sound!
This commit is contained in:
@@ -50,7 +50,7 @@ namespace OpenRA
|
||||
world.AddFrameEndTask(
|
||||
w => w.Add(new Explosion(w, args.dest, warhead.Explosion, isWater)));
|
||||
|
||||
Sound.Play(GetImpactSound(warhead, isWater));
|
||||
Sound.Play(GetImpactSound(warhead, isWater), args.dest);
|
||||
|
||||
if (warhead.SmudgeType != null)
|
||||
{
|
||||
|
||||
@@ -312,6 +312,7 @@ namespace OpenRA
|
||||
{
|
||||
++RenderFrame;
|
||||
viewport.DrawRegions(world);
|
||||
Sound.SetListenerPosition(viewport.Location + .5f * new float2(viewport.Width, viewport.Height));
|
||||
}
|
||||
|
||||
PerfHistory.items["render"].Tick();
|
||||
|
||||
@@ -58,14 +58,24 @@ namespace OpenRA
|
||||
stopped = false;
|
||||
}
|
||||
|
||||
public static void SetListenerPosition(float2 position) { soundEngine.SetListenerPosition(position); }
|
||||
|
||||
public static void Play(string name)
|
||||
{
|
||||
if (name == "" || name == null)
|
||||
return;
|
||||
|
||||
var sound = sounds[name];
|
||||
// todo: positioning
|
||||
soundEngine.Play2D(sound, false);
|
||||
soundEngine.Play2D(sound, false, true, float2.Zero);
|
||||
}
|
||||
|
||||
public static void Play(string name, float2 pos)
|
||||
{
|
||||
if (name == "" || name == null)
|
||||
return;
|
||||
|
||||
var sound = sounds[name];
|
||||
soundEngine.Play2D(sound, false, false, pos);
|
||||
}
|
||||
|
||||
public static void PlayToPlayer(Player player, string name)
|
||||
@@ -74,6 +84,12 @@ namespace OpenRA
|
||||
Play( name );
|
||||
}
|
||||
|
||||
public static void PlayToPlayer(Player player, string name, float2 pos)
|
||||
{
|
||||
if (player == player.World.LocalPlayer)
|
||||
Play(name, pos);
|
||||
}
|
||||
|
||||
public static void PlayMusic(string name)
|
||||
{
|
||||
if (name == "" || name == null)
|
||||
@@ -83,7 +99,7 @@ namespace OpenRA
|
||||
soundEngine.StopSound(music);
|
||||
|
||||
var sound = sounds[name];
|
||||
music = soundEngine.Play2D(sound, true);
|
||||
music = soundEngine.Play2D(sound, true, true, float2.Zero);
|
||||
music.Volume = musicVolume;
|
||||
}
|
||||
|
||||
@@ -160,12 +176,13 @@ namespace OpenRA
|
||||
interface ISoundEngine
|
||||
{
|
||||
ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate);
|
||||
ISound Play2D(ISoundSource sound, bool loop);
|
||||
ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos);
|
||||
float Volume { get; set; }
|
||||
void PauseSound(ISound sound, bool paused);
|
||||
void StopSound(ISound sound);
|
||||
void SetAllSoundsPaused(bool paused);
|
||||
void StopAllSounds();
|
||||
void SetListenerPosition(float2 position);
|
||||
}
|
||||
|
||||
interface ISoundSource {}
|
||||
@@ -241,10 +258,10 @@ namespace OpenRA
|
||||
return new OpenAlSoundSource(data, channels, sampleBits, sampleRate);
|
||||
}
|
||||
|
||||
public ISound Play2D(ISoundSource sound, bool loop)
|
||||
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos)
|
||||
{
|
||||
int source = GetSourceFromPool();
|
||||
return new OpenAlSound(source, (sound as OpenAlSoundSource).buffer, loop);
|
||||
return new OpenAlSound(source, (sound as OpenAlSoundSource).buffer, loop, relative, pos);
|
||||
}
|
||||
|
||||
public float Volume
|
||||
@@ -298,6 +315,14 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
public void SetListenerPosition(float2 position)
|
||||
{
|
||||
var orientation = new [] { 0f, 0f, 1f, 0f, -1f, 0f };
|
||||
|
||||
Al.alListener3f(Al.AL_POSITION, position.X, position.Y, 50);
|
||||
Al.alListenerfv(Al.AL_ORIENTATION, ref orientation[0]);
|
||||
Al.alListenerf(Al.AL_METERS_PER_UNIT, .01f);
|
||||
}
|
||||
}
|
||||
|
||||
class OpenAlSoundSource : ISoundSource
|
||||
@@ -324,16 +349,20 @@ namespace OpenRA
|
||||
public readonly int source = -1;
|
||||
float volume = 1f;
|
||||
|
||||
public OpenAlSound(int source, int buffer, bool looping)
|
||||
public OpenAlSound(int source, int buffer, bool looping, bool relative, float2 pos)
|
||||
{
|
||||
if (source == -1) return;
|
||||
this.source = source;
|
||||
Al.alSourcef(source, Al.AL_PITCH, 1f);
|
||||
Al.alSourcef(source, Al.AL_GAIN, 1f);
|
||||
Al.alSource3f(source, Al.AL_POSITION, 0f, 0f, 0f);
|
||||
Al.alSource3f(source, Al.AL_POSITION, pos.X, pos.Y, 0f);
|
||||
Al.alSource3f(source, Al.AL_VELOCITY, 0f, 0f, 0f);
|
||||
Al.alSourcei(source, Al.AL_BUFFER, buffer);
|
||||
Al.alSourcei(source, Al.AL_LOOPING, looping ? Al.AL_TRUE : Al.AL_FALSE);
|
||||
Al.alSourcei(source, Al.AL_SOURCE_RELATIVE, relative ? 1 : 0);
|
||||
Al.alSourcef(source, Al.AL_REFERENCE_DISTANCE, 200);
|
||||
Al.alSourcef(source, Al.AL_MAX_DISTANCE, 1500);
|
||||
|
||||
Al.alSourcePlay(source);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace OpenRA.Traits.Activities
|
||||
initialLocation = self.CenterLocation;
|
||||
|
||||
self.traits.Get<RenderInfantry>().Attacking(self);
|
||||
Sound.Play("dogg5p.aud");
|
||||
Sound.Play("dogg5p.aud", self.CenterLocation);
|
||||
}
|
||||
|
||||
public IActivity NextActivity { get; set; }
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace OpenRA.Traits
|
||||
self.World.Add(projectile);
|
||||
|
||||
if (!string.IsNullOrEmpty(args.weapon.Report))
|
||||
Sound.Play(args.weapon.Report + ".aud");
|
||||
Sound.Play(args.weapon.Report + ".aud", self.CenterLocation);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace OpenRA.Traits
|
||||
if (e.DamageState == DamageState.Dead)
|
||||
{
|
||||
self.World.WorldActor.traits.Get<ScreenShaker>().AddEffect(10, self.CenterLocation, 1);
|
||||
Sound.Play(Info.DestroyedSound);
|
||||
Sound.Play(Info.DestroyedSound, self.CenterLocation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,12 +71,12 @@ namespace OpenRA.Traits
|
||||
|
||||
void OnCloak()
|
||||
{
|
||||
Sound.Play(self.Info.Traits.Get<CloakInfo>().CloakSound);
|
||||
Sound.Play(self.Info.Traits.Get<CloakInfo>().CloakSound, self.CenterLocation);
|
||||
}
|
||||
|
||||
void OnUncloak()
|
||||
{
|
||||
Sound.Play(self.Info.Traits.Get<CloakInfo>().UncloakSound);
|
||||
Sound.Play(self.Info.Traits.Get<CloakInfo>().UncloakSound, self.CenterLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace OpenRA.Traits
|
||||
break;
|
||||
case DamageState.Half:
|
||||
anim.ReplaceAnim("damaged-idle");
|
||||
Sound.Play(self.Info.Traits.Get<BuildingInfo>().DamagedSound);
|
||||
Sound.Play(self.Info.Traits.Get<BuildingInfo>().DamagedSound, self.CenterLocation);
|
||||
break;
|
||||
case DamageState.Dead:
|
||||
self.World.AddFrameEndTask(w => w.Add(new Explosion(w, self.CenterLocation.ToInt2(), 7, false)));
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Traits
|
||||
|
||||
public void PlayCharge(Actor self)
|
||||
{
|
||||
Sound.Play(self.Info.Traits.Get<RenderBuildingChargeInfo>().ChargeAudio);
|
||||
Sound.Play(self.Info.Traits.Get<RenderBuildingChargeInfo>().ChargeAudio, self.CenterLocation);
|
||||
anim.PlayThen(GetPrefix(self) + "active",
|
||||
() => anim.PlayRepeating(GetPrefix(self) + "idle"));
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace OpenRA.Traits
|
||||
break;
|
||||
case DamageState.Half:
|
||||
anim.Play( "damaged-idle" );
|
||||
Sound.Play(self.Info.Traits.Get<BuildingInfo>().DamagedSound);
|
||||
Sound.Play(self.Info.Traits.Get<BuildingInfo>().DamagedSound, self.CenterLocation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,13 +85,13 @@ namespace OpenRA.Traits
|
||||
break;
|
||||
case ExtendedDamageState.Half:
|
||||
seqName = "damaged-idle";
|
||||
Sound.Play(self.Info.Traits.Get<BuildingInfo>().DamagedSound);
|
||||
Sound.Play(self.Info.Traits.Get<BuildingInfo>().DamagedSound, self.CenterLocation);
|
||||
break;
|
||||
case ExtendedDamageState.Quarter:
|
||||
if (damageStates >= 3)
|
||||
{
|
||||
seqName = "critical-idle";
|
||||
Sound.Play(self.Info.Traits.Get<BuildingInfo>().DamagedSound);
|
||||
Sound.Play(self.Info.Traits.Get<BuildingInfo>().DamagedSound, self.CenterLocation);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -74,12 +74,12 @@ namespace OpenRA.Traits
|
||||
|
||||
void OnSurface()
|
||||
{
|
||||
Sound.Play(self.Info.Traits.Get<SubmarineInfo>().SurfaceSound);
|
||||
Sound.Play(self.Info.Traits.Get<SubmarineInfo>().SurfaceSound, self.CenterLocation);
|
||||
}
|
||||
|
||||
void OnDive()
|
||||
{
|
||||
Sound.Play(self.Info.Traits.Get<SubmarineInfo>().SubmergeSound);
|
||||
Sound.Play(self.Info.Traits.Get<SubmarineInfo>().SubmergeSound, self.CenterLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,8 @@ namespace OpenRA.Mods.Aftermath
|
||||
Game.controller.CancelInputMode();
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new Teleport(order.TargetLocation));
|
||||
Sound.Play("chrotnk1.aud");
|
||||
Sound.Play("chrotnk1.aud", self.CenterLocation);
|
||||
Sound.Play("chrotnk1.aud", Game.CellSize * order.TargetLocation.ToFloat2());
|
||||
chargeTick = 25 * self.Info.Traits.Get<ChronoshiftDeployInfo>().ChargeTime;
|
||||
|
||||
foreach (var a in self.World.Queries.WithTrait<ChronoshiftPaletteEffect>())
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace OpenRA.Mods.Aftermath
|
||||
Combat.DoExplosion(self, info.PrimaryWeapon, detonateLocation, altitude);
|
||||
var report = self.GetPrimaryWeapon().Report;
|
||||
if (report != null)
|
||||
Sound.Play(report + ".aud");
|
||||
Sound.Play(report + ".aud", self.CenterLocation);
|
||||
|
||||
// Remove from world
|
||||
self.Health = 0;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Cnc
|
||||
{
|
||||
Owner.World.AddFrameEndTask(w =>
|
||||
{
|
||||
Sound.Play(Info.LaunchSound);
|
||||
Sound.Play(Info.LaunchSound, Game.CellSize * order.TargetLocation.ToFloat2());
|
||||
w.Add(new IonCannon(self, w, order.TargetLocation));
|
||||
});
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA
|
||||
self.World.Add(args.weapon.Projectile.Create(args));
|
||||
|
||||
if (!string.IsNullOrEmpty(args.weapon.Report))
|
||||
Sound.Play(args.weapon.Report + ".aud");
|
||||
Sound.Play(args.weapon.Report + ".aud", self.CenterLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.RA
|
||||
if (curtain != null)
|
||||
curtain.traits.Get<RenderBuilding>().PlayCustomAnim(curtain, "active");
|
||||
|
||||
Sound.Play("ironcur9.aud");
|
||||
Sound.Play("ironcur9.aud", order.TargetActor.CenterLocation);
|
||||
|
||||
order.TargetActor.traits.Get<IronCurtainable>().Activate(order.TargetActor,
|
||||
(int)((Info as IronCurtainPowerInfo).Duration * 25 * 60));
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace OpenRA.Mods.RA
|
||||
Util.CenterOfCell((1 / 24f * self.CenterLocation).ToInt2()),
|
||||
self.traits.Get<Unit>().Altitude, a)));
|
||||
|
||||
Sound.Play("chute1.aud");
|
||||
Sound.Play("chute1.aud", self.CenterLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.RA.SupportPowers
|
||||
|
||||
if (success)
|
||||
{
|
||||
Sound.Play("chrono2.aud");
|
||||
Sound.Play("chrono2.aud", chronosphere.CenterLocation);
|
||||
|
||||
// Trigger screen desaturate effect
|
||||
foreach (var a in self.World.Queries.WithTrait<ChronoshiftPaletteEffect>())
|
||||
|
||||
Reference in New Issue
Block a user