Basic positional support for built-in sounds

- needs soundset to be in mono
 - no support yet for scripting soundsource positions
This commit is contained in:
cim 2013-11-11 22:45:05 +00:00
parent 6df270e3b1
commit 907a3e6441
15 changed files with 230 additions and 83 deletions

View File

@ -795,6 +795,7 @@ typedef enum
- (OOWeaponType) weaponForFacing:(OOWeaponFacing)facing;
- (OOWeaponType) currentWeapon;
- (Vector) currentLaserOffset;
- (void) rotateCargo;

View File

@ -4453,7 +4453,14 @@ static GLfloat sBaseMass = 0.0;
if ([ms isEqual:@"INCOMING_MISSILE"])
{
[self playIncomingMissile];
if ([self primaryAggressor] != nil)
{
[self playIncomingMissile:HPVectorToVector([[self primaryAggressor] position])];
}
else
{
[self playIncomingMissile:kZeroVector];
}
[UNIVERSE addMessage:DESC(@"incoming-missile") forCount:4.5];
}
@ -4547,7 +4554,7 @@ static GLfloat sBaseMass = 0.0;
{
firedMissile = [self launchMine:missile];
if (!replacingMissile) [self removeFromPylon:activeMissile];
if (firedMissile != nil) [self playMineLaunched];
if (firedMissile != nil) [self playMineLaunched:[self missileLaunchPosition]];
}
else
{
@ -4558,7 +4565,7 @@ static GLfloat sBaseMass = 0.0;
if (firedMissile != nil)
{
if (!replacingMissile) [self removeFromPylon:activeMissile];
[self playMissileLaunched];
[self playMissileLaunched:[self missileLaunchPosition]];
}
}
@ -4772,6 +4779,12 @@ static GLfloat sBaseMass = 0.0;
}
- (Vector) currentLaserOffset
{
return [self laserPortOffset:currentWeaponFacing];
}
- (BOOL) fireMainWeapon
{
int weapon_to_be_fired = [self currentWeapon];
@ -4783,7 +4796,7 @@ static GLfloat sBaseMass = 0.0;
if (weapon_temp / PLAYER_MAX_WEAPON_TEMP >= WEAPON_COOLING_CUTOUT)
{
[self playWeaponOverheated];
[self playWeaponOverheated:[self currentLaserOffset]];
[UNIVERSE addMessage:DESC(@"weapon-overheat") forCount:3.0];
return NO;
}
@ -4943,7 +4956,7 @@ static GLfloat sBaseMass = 0.0;
- (void) takeEnergyDamage:(double)amount from:(Entity *)ent becauseOf:(Entity *)other
{
HPVector rel_pos;
double d_forward;
double d_forward, d_right, d_up;
BOOL internal_damage = NO; // base chance
OOLog(@"player.ship.damage", @"Player took damage from %@ becauseOf %@", ent, other);
@ -4971,8 +4984,11 @@ static GLfloat sBaseMass = 0.0;
if ([ent isShip]) [(ShipEntity *)ent doScriptEvent:OOJSID("shipAttackedOther") withArgument:self];
d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
[self playShieldHit];
d_right = dot_product(HPVectorToVector(rel_pos), v_right);
d_up = dot_product(HPVectorToVector(rel_pos), v_up);
Vector relative = make_vector(d_right,d_up,d_forward);
[self playShieldHit:relative];
// firing on an innocent ship is an offence
if ([other isShip])
@ -5013,7 +5029,7 @@ static GLfloat sBaseMass = 0.0;
{
internal_damage = ((ranrot_rand() & PLAYER_INTERNAL_DAMAGE_FACTOR) < amount); // base chance of damage to systems
energy -= amount;
[self playDirectHit];
[self playDirectHit:relative];
ship_temperature += (amount / [self heatInsulation]);
}
[self noteTakingDamage:amount from:other type:damageType];
@ -5038,7 +5054,7 @@ static GLfloat sBaseMass = 0.0;
- (void) takeScrapeDamage:(double) amount from:(Entity *) ent
{
HPVector rel_pos;
double d_forward;
double d_forward, d_right, d_up;
BOOL internal_damage = NO; // base chance
if ([self status] == STATUS_DEAD) return;
@ -5055,8 +5071,11 @@ static GLfloat sBaseMass = 0.0;
rel_pos = HPvector_subtract(rel_pos, position);
// rel_pos is now small
d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
[self playScrapeDamage];
d_right = dot_product(HPVectorToVector(rel_pos), v_right);
d_up = dot_product(HPVectorToVector(rel_pos), v_up);
Vector relative = make_vector(d_right,d_up,d_forward);
[self playScrapeDamage:relative];
if (d_forward >= 0)
{
forward_shield -= amount;

View File

@ -916,7 +916,7 @@ static NSTimeInterval time_last_frame;
{
if ([self fireMainWeapon])
{
[self playLaserHit:[self shipHitByLaser] != nil];
[self playLaserHit:([self shipHitByLaser] != nil) offset:[self currentLaserOffset]];
}
}

View File

@ -24,7 +24,6 @@ MA 02110-1301, USA.
#import "PlayerEntity.h"
@interface PlayerEntity (Sound)
- (void) setUpSound;
@ -107,7 +106,7 @@ MA 02110-1301, USA.
// Warning sounds
- (void) playHostileWarning;
- (void) playAlertConditionRed;
- (void) playIncomingMissile;
- (void) playIncomingMissile:(Vector)missileVector;
- (void) playEnergyLow;
- (void) playDockingDenied;
- (void) playWitchjumpFailure;
@ -118,15 +117,15 @@ MA 02110-1301, USA.
- (void) playFuelLeak;
// Damage sounds
- (void) playShieldHit;
- (void) playDirectHit;
- (void) playScrapeDamage;
- (void) playShieldHit:(Vector)attackVector;
- (void) playDirectHit:(Vector)attackVector;
- (void) playScrapeDamage:(Vector)attackVector;
// Weapon sounds
- (void) playLaserHit:(BOOL)hit;
- (void) playWeaponOverheated;
- (void) playMissileLaunched;
- (void) playMineLaunched;
- (void) playLaserHit:(BOOL)hit offset:(Vector)weaponOffset;
- (void) playWeaponOverheated:(Vector)weaponOffset;
- (void) playMissileLaunched:(Vector)weaponOffset;
- (void) playMineLaunched:(Vector)weaponOffset;
// Miscellaneous sounds
- (void) playEscapePodScooped;

View File

@ -27,6 +27,7 @@ MA 02110-1301, USA.
#import "ResourceManager.h"
#import "Universe.h"
#import "OOSoundSourcePool.h"
#import "OOMaths.h"
// Sizes of sound source pools
@ -51,6 +52,14 @@ static OOSoundSource *sBreakPatternSource;
static OOSoundSourcePool *sBuySellSourcePool;
static OOSoundSource *sAfterburnerSources[2];
const Vector kInterfaceBeepPosition = { 0.0f, -0.2f, 0.5f };
const Vector kInterfaceWarningPosition = { 0.0f, -0.2f, 0.4f };
const Vector kBreakPatternPosition = { 0.0f, 0.0f, 1.0f };
const Vector kEcmPosition = { 0.2f, 0.6f, -0.1f };
const Vector kWitchspacePosition = { 0.0f, -0.3f, -0.3f };
// maybe these should actually track engine positions
const Vector kAfterburner1Position = { -0.1f, 0.0f, -1.0f };
const Vector kAfterburner2Position = { 0.1f, 0.0f, -1.0f };
@implementation PlayerEntity (Sound)
@ -59,9 +68,16 @@ static OOSoundSource *sAfterburnerSources[2];
[self destroySound];
sInterfaceBeepSource = [[OOSoundSource alloc] init];
[sInterfaceBeepSource setPosition:kInterfaceBeepPosition];
sBreakPatternSource = [[OOSoundSource alloc] init];
[sBreakPatternSource setPosition:kBreakPatternPosition];
sEcmSource = [[OOSoundSource alloc] init];
[sEcmSource setPosition:kEcmPosition];
sHyperspaceSoundSource = [[OOSoundSource alloc] init];
[sHyperspaceSoundSource setPosition:kWitchspacePosition];
sBuySellSourcePool = [[OOSoundSourcePool alloc] initWithCount:kBuySellSourcePoolSize minRepeatTime:0.0];
sWarningSoundPool = [[OOSoundSourcePool alloc] initWithCount:kWarningPoolSize minRepeatTime:0.0];
@ -72,7 +88,9 @@ static OOSoundSource *sAfterburnerSources[2];
// Two sources with the same sound are used to simulate looping.
OOSound *afterburnerSound = [ResourceManager ooSoundNamed:@"afterburner1.ogg" inFolder:@"Sounds"];
sAfterburnerSources[0] = [[OOSoundSource alloc] initWithSound:afterburnerSound];
[sAfterburnerSources[0] setPosition:kAfterburner1Position];
sAfterburnerSources[1] = [[OOSoundSource alloc] initWithSound:afterburnerSound];
[sAfterburnerSources[1] setPosition:kAfterburner2Position];
}
@ -340,6 +358,8 @@ static OOSoundSource *sAfterburnerSources[2];
{
if(![sInterfaceBeepSource isPlaying])
{
/* TODO: this should use the scoop position, not the standard
* interface beep position */
[self playInterfaceBeep:@"[scoop]"];
scoopSoundPlayTime = 0.5;
}
@ -484,134 +504,134 @@ static OOSoundSource *sAfterburnerSources[2];
- (void) playHostileWarning
{
[sWarningSoundPool playSoundWithKey:@"[hostile-warning]" priority:1];
[sWarningSoundPool playSoundWithKey:@"[hostile-warning]" priority:1 position:kInterfaceWarningPosition];
}
- (void) playAlertConditionRed
{
[sWarningSoundPool playSoundWithKey:@"[alert-condition-red]" priority:2];
[sWarningSoundPool playSoundWithKey:@"[alert-condition-red]" priority:2 position:kInterfaceWarningPosition];
}
- (void) playIncomingMissile
- (void) playIncomingMissile:(Vector)missileVector
{
[sWarningSoundPool playSoundWithKey:@"[incoming-missile]" priority:3];
[sWarningSoundPool playSoundWithKey:@"[incoming-missile]" priority:3 position:missileVector];
}
- (void) playEnergyLow
{
[sWarningSoundPool playSoundWithKey:@"[energy-low]" priority:0.5];
[sWarningSoundPool playSoundWithKey:@"[energy-low]" priority:0.5 position:kInterfaceWarningPosition];
}
- (void) playDockingDenied
{
[sWarningSoundPool playSoundWithKey:@"[autopilot-denied]" priority:1];
[sWarningSoundPool playSoundWithKey:@"[autopilot-denied]" priority:1 position:kInterfaceWarningPosition];
}
- (void) playWitchjumpFailure
{
[sWarningSoundPool playSoundWithKey:@"[witchdrive-failure]" priority:1.5];
[sWarningSoundPool playSoundWithKey:@"[witchdrive-failure]" priority:1.5 position:kWitchspacePosition];
}
- (void) playWitchjumpMisjump
{
[sWarningSoundPool playSoundWithKey:@"[witchdrive-malfunction]" priority:1.5];
[sWarningSoundPool playSoundWithKey:@"[witchdrive-malfunction]" priority:1.5 position:kWitchspacePosition];
}
- (void) playWitchjumpBlocked
{
[sWarningSoundPool playSoundWithKey:@"[witch-blocked-by-@]" priority:1.3];
[sWarningSoundPool playSoundWithKey:@"[witch-blocked-by-@]" priority:1.3 position:kWitchspacePosition];
}
- (void) playWitchjumpDistanceTooGreat
{
[sWarningSoundPool playSoundWithKey:@"[witch-too-far]" priority:1.3];
[sWarningSoundPool playSoundWithKey:@"[witch-too-far]" priority:1.3 position:kWitchspacePosition];
}
- (void) playWitchjumpInsufficientFuel
{
[sWarningSoundPool playSoundWithKey:@"[witch-no-fuel]" priority:1.3];
[sWarningSoundPool playSoundWithKey:@"[witch-no-fuel]" priority:1.3 position:kWitchspacePosition];
}
- (void) playFuelLeak
{
[sWarningSoundPool playSoundWithKey:@"[fuel-leak]" priority:0.5];
[sWarningSoundPool playSoundWithKey:@"[fuel-leak]" priority:0.5 position:kWitchspacePosition];
}
- (void) playShieldHit
- (void) playShieldHit:(Vector)attackVector
{
[sDamageSoundPool playSoundWithKey:@"[player-hit-by-weapon]"];
[sDamageSoundPool playSoundWithKey:@"[player-hit-by-weapon]" position:attackVector];
}
- (void) playDirectHit
- (void) playDirectHit:(Vector)attackVector
{
[sDamageSoundPool playSoundWithKey:@"[player-direct-hit]"];
[sDamageSoundPool playSoundWithKey:@"[player-direct-hit]" position:attackVector];
}
- (void) playScrapeDamage
- (void) playScrapeDamage:(Vector)attackVector
{
[sDamageSoundPool playSoundWithKey:@"[player-scrape-damage]"];
[sDamageSoundPool playSoundWithKey:@"[player-scrape-damage]" position:attackVector];
}
- (void) playLaserHit:(BOOL)hit
- (void) playLaserHit:(BOOL)hit offset:(Vector)weaponOffset
{
if (hit)
{
[sWeaponSoundPool playSoundWithKey:@"[player-laser-hit]" priority:1 expiryTime:0.05];
[sWeaponSoundPool playSoundWithKey:@"[player-laser-hit]" priority:1.0 expiryTime:0.05 overlap:YES position:weaponOffset];
}
else
{
[sWeaponSoundPool playSoundWithKey:@"[player-laser-miss]" priority:1 expiryTime:0.05];
[sWeaponSoundPool playSoundWithKey:@"[player-laser-miss]" priority:1.0 expiryTime:0.05 overlap:YES position:weaponOffset];
}
}
- (void) playWeaponOverheated
- (void) playWeaponOverheated:(Vector)weaponOffset
{
[sWeaponSoundPool playSoundWithKey:@"[weapon-overheat]" overlap:NO];
[sWeaponSoundPool playSoundWithKey:@"[weapon-overheat]" overlap:NO position:weaponOffset];
}
- (void) playMissileLaunched
- (void) playMissileLaunched:(Vector)weaponOffset
{
[sWeaponSoundPool playSoundWithKey:@"[missile-launched]"];
[sWeaponSoundPool playSoundWithKey:@"[missile-launched]" position:weaponOffset];
}
- (void) playMineLaunched
- (void) playMineLaunched:(Vector)weaponOffset
{
[sWeaponSoundPool playSoundWithKey:@"[mine-launched]"];
[sWeaponSoundPool playSoundWithKey:@"[mine-launched]" position:weaponOffset];
}
- (void) playEscapePodScooped
{
[sMiscSoundPool playSoundWithKey:@"[escape-pod-scooped]"];
[sMiscSoundPool playSoundWithKey:@"[escape-pod-scooped]" position:kInterfaceBeepPosition];
}
- (void) playAegisCloseToPlanet
{
[sMiscSoundPool playSoundWithKey:@"[aegis-planet]"];
[sMiscSoundPool playSoundWithKey:@"[aegis-planet]" position:kInterfaceBeepPosition];
}
- (void) playAegisCloseToStation
{
[sMiscSoundPool playSoundWithKey:@"[aegis-station]"];
[sMiscSoundPool playSoundWithKey:@"[aegis-station]" position:kInterfaceBeepPosition];
}

View File

@ -997,11 +997,13 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (BOOL) fireDirectLaserShot:(double)range;
- (BOOL) fireDirectLaserDefensiveShot;
- (BOOL) fireDirectLaserShotAt:(Entity *)my_target;
- (Vector) laserPortOffset:(OOWeaponFacing)direction;
- (BOOL) fireLaserShotInDirection:(OOWeaponFacing)direction;
- (void) adjustMissedShots:(int)delta;
- (int) missedShots;
- (BOOL) firePlasmaShotAtOffset:(double)offset speed:(double)speed color:(OOColor *)color;
- (void) considerFiringMissile:(double)delta_t;
- (Vector) missileLaunchPosition;
- (ShipEntity *) fireMissile;
- (ShipEntity *) fireMissileWithIdentifier:(NSString *) identifier andTarget:(Entity *) target;
- (BOOL) isMissileFlagSet;

View File

@ -10764,15 +10764,9 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
}
- (BOOL) fireLaserShotInDirection:(OOWeaponFacing)direction
- (Vector) laserPortOffset:(OOWeaponFacing)direction
{
double range_limit2 = weaponRange * weaponRange;
GLfloat hit_at_range;
Vector vel = vector_multiply_scalar(v_forward, flightSpeed);
Vector laserPortOffset = kZeroVector;
last_shot_time = [UNIVERSE getTime];
Vector laserPortOffset = kZeroVector;
switch (direction)
{
case WEAPON_FACING_FORWARD:
@ -10792,7 +10786,19 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
laserPortOffset = starboardWeaponOffset;
break;
}
return laserPortOffset;
}
- (BOOL) fireLaserShotInDirection:(OOWeaponFacing)direction
{
double range_limit2 = weaponRange * weaponRange;
GLfloat hit_at_range;
Vector vel = vector_multiply_scalar(v_forward, flightSpeed);
Vector laserPortOffset = [self laserPortOffset:direction];
last_shot_time = [UNIVERSE getTime];
ShipEntity *victim = [UNIVERSE firstShipHitByLaserFromShip:self inDirection:direction offset:laserPortOffset gettingRangeFound:&hit_at_range];
[self setShipHitByLaser:victim];
@ -11044,6 +11050,28 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
}
- (Vector) missileLaunchPosition
{
Vector start;
// default launching position
start.x = 0.0f; // in the middle
start.y = boundingBox.min.y - 4.0f; // 4m below bounding box
start.z = boundingBox.max.z + 1.0f; // 1m ahead of bounding box
// custom launching position
start = [shipinfoDictionary oo_vectorForKey:@"missile_launch_position" defaultValue:start];
if (start.x == 0.0f && start.y == 0.0f && start.z <= 0.0f) // The kZeroVector as start is illegal also.
{
OOLog(@"ship.missileLaunch.invalidPosition", @"***** ERROR: The missile_launch_position defines a position %@ behind the %@. In future versions such missiles may explode on launch because they have to travel through the ship.", VectorDescription(start), self);
start.x = 0.0f;
start.y = boundingBox.min.y - 4.0f;
start.z = boundingBox.max.z + 1.0f;
}
return start;
}
- (ShipEntity *) fireMissile
{
return [self fireMissileWithIdentifier:nil andTarget:[self primaryTarget]];
@ -11062,21 +11090,7 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
if ([UNIVERSE getTime] < missile_launch_time) return nil;
// default launching position
start.x = 0.0f; // in the middle
start.y = boundingBox.min.y - 4.0f; // 4m below bounding box
start.z = boundingBox.max.z + 1.0f; // 1m ahead of bounding box
// custom launching position
start = [shipinfoDictionary oo_vectorForKey:@"missile_launch_position" defaultValue:start];
if (start.x == 0.0f && start.y == 0.0f && start.z <= 0.0f) // The kZeroVector as start is illegal also.
{
OOLog(@"ship.missileLaunch.invalidPosition", @"***** ERROR: The missile_launch_position defines a position %@ behind the %@. In future versions such missiles may explode on launch because they have to travel through the ship.", VectorDescription(start), self);
start.x = 0.0f;
start.y = boundingBox.min.y - 4.0f;
start.z = boundingBox.max.z + 1.0f;
}
start = [self missileLaunchPosition];
double throw_speed = 250.0f;

View File

@ -32,6 +32,7 @@ SOFTWARE.
#import <Foundation/Foundation.h>
#import "OOOpenALController.h"
#import "OOMaths.h"
@class OOSound;
@ -57,6 +58,8 @@ SOFTWARE.
- (OOSoundChannel *) next;
- (void) setNext:(OOSoundChannel *)next;
// set sound position relative to listener
- (void) setPosition:(Vector) vector;
- (BOOL) playSound:(OOSound *)sound looped:(BOOL)loop;
- (void)stop;

View File

@ -28,6 +28,7 @@ SOFTWARE.
#import "OOALSoundChannel.h"
#import "OOALSound.h"
#import "OOLogging.h"
#import "OOMaths.h"
@interface OOSoundChannel (Private)
@ -52,6 +53,9 @@ SOFTWARE.
[self release];
self = nil;
}
// sources are all relative to listener, defaulting to zero vector
OOAL(alSourcei(_source, AL_SOURCE_RELATIVE, AL_TRUE));
OOAL(alSource3f(_source, AL_POSITION, 0.0f, 0.0f, 0.0f));
}
return self;
}
@ -139,6 +143,12 @@ SOFTWARE.
}
- (void) setPosition:(Vector) vector
{
OOAL(alSource3f(_source, AL_POSITION, vector.x, vector.y, vector.z));
}
- (BOOL) playSound:(OOSound *)sound looped:(BOOL)loop
{
if (sound == nil) return NO;

View File

@ -64,6 +64,7 @@ static id sSingleton = nil;
{
OOLog(kOOLogSoundInitError,@"Error %d creating sound context",error);
}
OOAL(alDistanceModel(AL_NONE));
}
return self;
}

View File

@ -44,6 +44,8 @@ OUT OF OR
BOOL _loop;
uint8_t _repeatCount,
_remainingCount;
Vector _position;
BOOL _positional;
}
+ (instancetype) sourceWithSound:(OOSound *)inSound;
@ -69,9 +71,10 @@ OUT OF OR
- (void) playSound:(OOSound *)inSound repeatCount:(uint8_t)inCount;
- (void) playOrRepeatSound:(OOSound *)inSound;
// Positional audio attributes are ignored in this implementation
// Positional audio attributes are used in this implementation
- (void) setPositional:(BOOL)inPositional;
- (void) setPosition:(Vector)inPosition;
// *Advanced* positional audio attributes are ignored in this implementation
- (void) setVelocity:(Vector)inVelocity;
- (void) setOrientation:(Vector)inOrientation;
- (void) setConeAngle:(float)inAngle;

View File

@ -27,7 +27,7 @@ SOFTWARE.
#import "OOSoundInternal.h"
#import "OOLogging.h"
#import "OOMaths.h"
static NSMutableSet *sPlayingSoundSources;
@ -45,6 +45,9 @@ static NSMutableSet *sPlayingSoundSources;
self = [self init];
if (!self) return nil;
_positional = NO;
_position = kZeroVector;
[self setSound:inSound];
return self;
@ -133,6 +136,7 @@ static NSMutableSet *sPlayingSoundSources;
{
_remainingCount = [self repeatCount];
[_channel setDelegate:self];
[_channel setPosition:_position];
[_channel playSound:[self sound] looped:[self loop]];
[self retain];
}
@ -211,16 +215,32 @@ static NSMutableSet *sPlayingSoundSources;
- (void) setPositional:(BOOL)inPositional
{
if (inPositional)
{
_positional = YES;
}
else
{
/* OpenAL doesn't easily do non-positional sounds beyond the
* stereo/mono distinction, but setting the position to the
* zero vector is probably close enough */
_positional = NO;
[self setPosition:kZeroVector];
}
}
- (void) setPosition:(Vector)inPosition
{
_position = inPosition;
if (_channel)
{
[_channel setPosition:_position];
}
}
/* Following not yet implemented */
- (void) setVelocity:(Vector)inVelocity
{

View File

@ -35,7 +35,7 @@ SOFTWARE.
#import <Foundation/Foundation.h>
#import "OOTypes.h"
#import "OOMaths.h"
@interface OOSoundSourcePool: NSObject
{
@ -52,6 +52,12 @@ SOFTWARE.
+ (instancetype) poolWithCount:(uint8_t)count minRepeatTime:(OOTimeDelta)minRepeat;
- (id) initWithCount:(uint8_t)count minRepeatTime:(OOTimeDelta)minRepeat;
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority
expiryTime:(OOTimeDelta)expiryTime
overlap:(BOOL)overlap
position:(Vector)position;
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority
expiryTime:(OOTimeDelta)expiryTime;
@ -59,9 +65,17 @@ SOFTWARE.
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority; // expiryTime:0.1 +/- 0.5
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority
position:(Vector)position; // expiryTime:0.1 +/- 0.5
- (void) playSoundWithKey:(NSString *)key
position:(Vector)position; // expiryTime:0.1 +/- 0.5
- (void) playSoundWithKey:(NSString *)key; // priority: 1.0, expiryTime:0.1 +/- 0.5
- (void) playSoundWithKey:(NSString *)key overlap:(BOOL)overlap; // if overlap == NO it waits for key to finish before playing key again
- (void) playSoundWithKey:(NSString *)key overlap:(BOOL)overlap position:(Vector)position;
@end

View File

@ -103,6 +103,7 @@ typedef struct OOSoundSourcePoolElement
priority:(float)priority
expiryTime:(OOTimeDelta)expiryTime
overlap:(BOOL)overlap
position:(Vector)position
{
uint8_t slot;
OOTimeAbsolute now, absExpiryTime;
@ -137,6 +138,7 @@ typedef struct OOSoundSourcePoolElement
if (!overlap) _reserved = slot;
// Play and store metadata
[element->source setPosition:position];
[element->source playSound:sound];
element->expiryTime = absExpiryTime;
element->priority = priority;
@ -159,7 +161,20 @@ typedef struct OOSoundSourcePoolElement
[self playSoundWithKey:key
priority:priority
expiryTime:expiryTime
overlap:YES];
overlap:YES
position:kZeroVector];
}
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority
position:(Vector)position
{
[self playSoundWithKey:key
priority:priority
expiryTime:0.5 + randf() * 0.1
overlap:YES
position:position];
}
@ -178,14 +193,32 @@ typedef struct OOSoundSourcePoolElement
}
- (void) playSoundWithKey:(NSString *)key position:(Vector)position
{
[self playSoundWithKey:key priority:1.0 position:position];
}
- (void) playSoundWithKey:(NSString *)key overlap:(BOOL)overlap
{
[self playSoundWithKey:key
priority:1.0
expiryTime:0.5
overlap:overlap];
overlap:overlap
position:kZeroVector];
}
- (void) playSoundWithKey:(NSString *)key overlap:(BOOL)overlap position:(Vector)position
{
[self playSoundWithKey:key
priority:1.0
expiryTime:0.5
overlap:overlap
position:position];
}
@end

View File

@ -29,6 +29,7 @@ MA 02110-1301, USA.
#import "ResourceManager.h"
#import "OOSound.h"
#import "OOStringParsing.h"
#import "OOMaths.h"
static void InitTrumbleSounds(void);
@ -987,7 +988,12 @@ static void InitTrumbleSounds(void)
static void PlayTrumbleIdle(void)
{
// Only play idle sound if no trumble is making noise.
if (![sTrumbleSoundSource isPlaying]) [sTrumbleSoundSource playSound:sTrumbleIdleSound];
if (![sTrumbleSoundSource isPlaying])
{
// trumble sound from random direction - where's it gone now?
[sTrumbleSoundSource setPosition:OORandomUnitVector()];
[sTrumbleSoundSource playSound:sTrumbleIdleSound];
}
}
@ -996,6 +1002,8 @@ static void PlayTrumbleSqueal(void)
// Play squeal sound if no trumble is currently squealing, but trumping idle sound.
if (![sTrumbleSoundSource isPlaying] || [sTrumbleSoundSource sound] == sTrumbleIdleSound)
{
// trumble sound from random direction - where's it gone now?
[sTrumbleSoundSource setPosition:OORandomUnitVector()];
[sTrumbleSoundSource playSound:sTrumbleSqealSound];
}
}