This commit is contained in:
MontyTRC89 2021-09-22 05:51:37 +02:00
commit 8428a0ae0e
12 changed files with 90 additions and 68 deletions

View file

@ -762,7 +762,7 @@ void ControlGrenade(short itemNumber)
AlertNearbyGuards(item);
SoundEffect(SFX_TR4_EXPLOSION1, &item->pos, PITCH_SHIFT | 0x1800000);
SoundEffect(SFX_TR4_EXPLOSION1, &item->pos, 0, 0.7f, 0.5f);
SoundEffect(SFX_TR4_EXPLOSION2, &item->pos, 0);
// Setup the counter for spawned grenades in the case of flash and super grenades ammos
@ -979,7 +979,7 @@ void ControlRocket(short itemNumber)
AlertNearbyGuards(item);
SoundEffect(SFX_TR4_EXPLOSION1, &item->pos, PITCH_SHIFT | 0x1800000);
SoundEffect(SFX_TR4_EXPLOSION1, &item->pos, 0, 0.7f, 0.5f);
SoundEffect(SFX_TR4_EXPLOSION2, &item->pos, 0);
ExplodeItemNode(item, 0, 0, EXPLODE_NORMAL);
@ -1495,7 +1495,7 @@ void ControlCrossbowBolt(short itemNumber)
AlertNearbyGuards(item);
SoundEffect(SFX_TR4_EXPLOSION1, &item->pos, PITCH_SHIFT | 0x1800000);
SoundEffect(SFX_TR4_EXPLOSION1, &item->pos, 0, 0.7f, 0.5f);
SoundEffect(SFX_TR4_EXPLOSION2, &item->pos, 0);
ExplodeItemNode(item, 0, 0, EXPLODE_NORMAL);

View file

@ -126,7 +126,7 @@ void AnimatePistols(LARA_WEAPON_TYPE weaponType)
Lara.rightArm.flash_gun = weapon->flashTime;
SoundEffect(SFX_TR4_EXPLOSION1, &LaraItem->pos, PITCH_SHIFT | 0x2000000);
SoundEffect(SFX_TR4_EXPLOSION1, &LaraItem->pos, 0, 0.9f, 0.5f);
SoundEffect(weapon->sampleNum, &LaraItem->pos, 0);
soundPlayed = true;
@ -224,7 +224,7 @@ void AnimatePistols(LARA_WEAPON_TYPE weaponType)
if (!soundPlayed)
{
SoundEffect(SFX_TR4_EXPLOSION1, &LaraItem->pos, PITCH_SHIFT | 0x2000000);
SoundEffect(SFX_TR4_EXPLOSION1, &LaraItem->pos, 0, 0.9f, 0.5f);
SoundEffect(weapon->sampleNum, &LaraItem->pos, 0);
}

View file

@ -126,7 +126,7 @@ void AddFootprint(ITEM_INFO* item)
switch (floor->Material)
{
case GroundMaterial::Concrete:
//fx = sound_effects::SFX_TR4_LARA_FEET;
fx = sound_effects::SFX_TR4_LARA_FEET;
break;
case GroundMaterial::Grass:
@ -170,7 +170,7 @@ void AddFootprint(ITEM_INFO* item)
break;
case GroundMaterial::Stone:
//fx = sound_effects::SFX_TR4_LARA_FEET;
fx = sound_effects::SFX_TR4_LARA_FEET;
break;
case GroundMaterial::Water:
@ -182,7 +182,9 @@ void AddFootprint(ITEM_INFO* item)
break;
}
SoundEffect(fx, &item->pos, 0);
// HACK: must be here until reference wad2 is revised
if (fx != sound_effects::SFX_TR4_LARA_FEET)
SoundEffect(fx, &item->pos, 0);
FOOTPRINT_STRUCT footprint;

View file

@ -984,7 +984,7 @@ bool SkidooControl()
skinfo->trackMesh = ((skinfo->trackMesh & 3) == 1) ? 2 : 1;
skinfo->pitch += (pitch - skinfo->pitch) / 4;
SoundEffect(SFX_TR2_SKIDOO_ACCELERATE, &skidoo->pos, 4 + ((0x10000 - (SKIDOO_MAX_SPEED - skinfo->pitch) * 100) * 256));
SoundEffect(skinfo->pitch ? SFX_TR2_SKIDOO_MOVING : SFX_TR2_SKIDOO_ACCELERATE, &skidoo->pos, 0, 0.5f + skinfo->pitch / (float)SKIDOO_MAX_SPEED);
}
else
{

View file

@ -2,8 +2,6 @@
#include "items.h"
#include "collide.h"
void InitialiseSkidoo(short itemNum);
void SkidooCollision(short itemNum, ITEM_INFO* litem, COLL_INFO* coll);
bool SkidooControl();

View file

@ -54,7 +54,7 @@ enum TONY_STATE
static BOSS_STRUCT BossData;
#define TONYBOSS_TURN ANGLE(2.0f)
#define TONYBOSS_HITS 100
#define TONYBOSS_HITS 1 //Tony Harder To Kill, was 100 (6 shotgun shots)
#define MAX_TONY_TRIGGER_RANGE 0x4000
static void TriggerTonyEffect(const TONY_FLAME flame)
@ -430,7 +430,7 @@ void ControlTonyFireBall(short fxNumber)
LaraItem->hitStatus = true;
KillEffect(fxNumber);
LaraItem->hitPoints -= 200;
LaraBurn();
//LaraBurn();
return;
}
}
@ -496,8 +496,6 @@ static void ExplodeTonyBoss(ITEM_INFO* item)
TriggerExplosionSparks(x, y, z, 3, -2, 0, item->roomNumber);
for (int i = 0; i < 2; i++)
TriggerExplosionSparks(x, y, z, 3, -1, 0, item->roomNumber);
SoundEffect(SFX_TR3_BLAST_CIRCLE, &item->pos, PITCH_SHIFT | 0x800000);
}
if (BossData.DrawExplode)

View file

@ -1321,9 +1321,9 @@ int QuadBikeControl(void)
quad->pitch = pitch;
if (quad->pitch < -0x8000)
quad->pitch = -0x8000;
else if (quad->pitch > 0xa000)
quad->pitch = 0xa000;
SoundEffect(SFX_TR3_QUAD_MOVE, &item->pos, (PITCH_SHIFT + ((0x10000 + quad->pitch)) * 256));
else if (quad->pitch > 0xA000)
quad->pitch = 0xA000;
SoundEffect(SFX_TR3_QUAD_MOVE, &item->pos, 0, 0.5f + (float)abs(quad->pitch) / (float)MAX_VELOCITY);
}
else
{

View file

@ -998,9 +998,9 @@ void RubberBoatControl(short itemNum)
binfo->pitch += ((pitch - binfo->pitch) / 4);
if (boat->speed > 8)
SoundEffect(SFX_TR3_BOAT_MOVING, &boat->pos, PITCH_SHIFT + ((0x10000 - (110 - binfo->pitch)) * 256));
SoundEffect(SFX_TR3_BOAT_MOVING, &boat->pos, 0, 0.5f + (float)abs(binfo->pitch) / (float)RUBBER_BOAT_MAX_SPEED);
else if (drive)
SoundEffect(SFX_TR3_BOAT_IDLE, &boat->pos, PITCH_SHIFT + ((0x10000 - (110 - binfo->pitch)) * 256));
SoundEffect(SFX_TR3_BOAT_IDLE, &boat->pos, 0, 0.5f + (float)abs(binfo->pitch) / (float)RUBBER_BOAT_MAX_SPEED);
if (Lara.Vehicle != itemNum)
return;

View file

@ -75,7 +75,7 @@ void SethaControl(short itemNumber)
int height4 = GetFloorHeight(floor, x, y, z);
AI_INFO info;
short angle;
short angle = 0;
if (item->hitPoints <= 0)
{

View file

@ -30,7 +30,7 @@ namespace TEN::Entities::TR4
{
SoundEffect(SFX_TR4_EXPLOSION1, &item->pos, 0);
SoundEffect(SFX_TR4_EXPLOSION2, &item->pos, 0);
SoundEffect(SFX_TR4_EXPLOSION1, &item->pos, PITCH_SHIFT | 0x1800000);
SoundEffect(SFX_TR4_EXPLOSION1, &item->pos, 0, 0.7f, 0.5f);
if (num > 0)
{

View file

@ -54,17 +54,17 @@ void SetVolumeFX(int vol)
GlobalFXVolume = vol;
}
bool Sound_LoadSample(char *pointer, int compSize, int uncompSize, int index) // Replaces DXCreateSampleADPCM()
bool Sound_LoadSample(char *pointer, int compSize, int uncompSize, int index)
{
if (index >= SOUND_MAX_SAMPLES)
{
printf("Sample index is larger than max. amount of samples (%d) \n", index);
logD("Sample index is larger than max. amount of samples (%d) \n", index);
return 0;
}
if (pointer == NULL || compSize <= 0)
{
printf("Sample size or memory address is incorrect \n", index);
logD("Sample size or memory address is incorrect \n", index);
return 0;
}
@ -73,7 +73,7 @@ bool Sound_LoadSample(char *pointer, int compSize, int uncompSize, int index) //
if (!sample)
{
printf("Error loading sample %d \n", index);
logE("Error loading sample %d \n", index);
return false;
}
@ -87,7 +87,7 @@ bool Sound_LoadSample(char *pointer, int compSize, int uncompSize, int index) //
if (info.freq != 22050 || info.chans != 1)
{
printf("Wrong sample parameters, must be 22050 Hz Mono \n");
logE("Wrong sample parameters, must be 22050 Hz Mono \n");
return false;
}
@ -133,7 +133,7 @@ bool Sound_LoadSample(char *pointer, int compSize, int uncompSize, int index) //
return true;
}
long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags, float pitchMultiplier, float gainMultiplier)
{
if (effectID >= g_Level.SoundMap.size())
return 0;
@ -155,7 +155,7 @@ long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
// We set it to -2 afterwards to prevent further debug message firings.
if (sampleIndex == -1)
{
printf("Non present effect %d \n", effectID);
logE("Non present effect %d \n", effectID);
g_Level.SoundMap[effectID] = -2;
return 0;
}
@ -166,7 +166,7 @@ long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
if (sampleInfo->number < 0)
{
printf("No valid samples count for effect %d", sampleIndex);
logD("No valid samples count for effect %d", sampleIndex);
return 0;
}
@ -181,6 +181,32 @@ long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
if (position)
sampleFlags |= BASS_SAMPLE_3D;
// Set & randomize volume (if needed)
float gain = (static_cast<float>(sampleInfo->volume) / 255.0f) * gainMultiplier;
if ((sampleInfo->flags & SOUND_FLAG_RND_GAIN))
gain -= (static_cast<float>(GetRandomControl()) / static_cast<float>(RAND_MAX))* SOUND_MAX_GAIN_CHANGE;
// Set and randomize pitch and additionally multiply by provided value (for vehicles etc)
float pitch = (1.0f + static_cast<float>(sampleInfo->pitch) / 127.0f) * pitchMultiplier;
// Randomize pitch (if needed)
if ((sampleInfo->flags & SOUND_FLAG_RND_PITCH))
pitch += ((static_cast<float>(GetRandomControl()) / static_cast<float>(RAND_MAX)) - 0.5f)* SOUND_MAX_PITCH_CHANGE * 2.0f;
// Calculate sound radius and distance to sound
float radius = (float)(sampleInfo->radius) * 1024.0f;
float distance = Sound_DistanceToListener(position);
// Don't play sound if it's too far from listener's position.
if (distance > radius)
return 0;
// Get final volume of a sound.
float volume = Sound_Attenuate(gain, distance, radius);
// Get existing index, if any, of sound which is playing.
int existingChannel = Sound_EffectIsPlaying(effectID, position);
// Select behaviour based on effect playback type (bytes 0-1 of flags field)
int playType = sampleInfo->flags & 3;
switch (playType)
@ -189,37 +215,26 @@ long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
break;
case SOUND_WAIT:
if (Sound_EffectIsPlaying(effectID, position) != -1) return 0; // Don't play until stopped
if (existingChannel != -1) // Don't play until stopped
return 0;
break;
case SOUND_RESTART:
Sound_FreeSlot(Sound_EffectIsPlaying(effectID, position), SOUND_XFADETIME_CUTSOUND); // Stop existing and continue
if (existingChannel != -1) // Stop existing and continue
Sound_FreeSlot(existingChannel, SOUND_XFADETIME_CUTSOUND);
break;
case SOUND_LOOPED:
if (Sound_UpdateEffectPosition(Sound_EffectIsPlaying(effectID, position), position))
if (existingChannel != -1) // Just update parameters and return, if already playing
{
Sound_UpdateEffectPosition(existingChannel, position);
Sound_UpdateEffectAttributes(existingChannel, pitch, volume);
return 0;
}
sampleFlags |= BASS_SAMPLE_LOOP;
break;
}
float radius = (float)(sampleInfo->radius) * 1024.0f;
float distance = Sound_DistanceToListener(position);
// Don't play sound if it's too far from listener's position.
if (distance > radius)
return 0;
// Set and randomize volume (if needed)
float gain = static_cast<float>(sampleInfo->volume) / 255.0f;
if ((sampleInfo->flags & SOUND_FLAG_RND_GAIN))
gain -= (static_cast<float>(GetRandomControl()) / static_cast<float>(RAND_MAX)) * SOUND_MAX_GAIN_CHANGE;
// Set and randomize pitch (if needed)
float pitch = 1.0f + static_cast<float>(sampleInfo->pitch) / 127.0f;
if ((sampleInfo->flags & SOUND_FLAG_RND_PITCH))
pitch += ((static_cast<float>(GetRandomControl()) / static_cast<float>(RAND_MAX)) - 0.5f) * SOUND_MAX_PITCH_CHANGE * 2.0f;
// Randomly select arbitrary sample from the list, if more than one is present
int sampleToPlay = 0;
int numSamples = (sampleInfo->flags >> 2) & 15;
@ -232,7 +247,7 @@ long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
int freeSlot = Sound_GetFreeSlot();
if (freeSlot == -1)
{
printf("No free channel slot available!");
logD("No free channel slot available!");
return 0;
}
@ -242,29 +257,18 @@ long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
if (Sound_CheckBASSError("Trying to create channel for sample %d", false, sampleToPlay))
return 0;
// Set pitch/volume settings appropriately
BASS_ChannelSetAttribute(channel, BASS_ATTRIB_FREQ, 22050.0f * pitch);
BASS_ChannelSetAttribute(channel, BASS_ATTRIB_VOL, Sound_Attenuate(gain, distance, radius));
if (Sound_CheckBASSError("Applying pitch/gain attribs on channel %x, sample %d", false, channel, sampleToPlay))
return 0;
// Finally ready to play sound, assign it to sound slot.
SoundSlot[freeSlot].state = SOUND_STATE_IDLE;
SoundSlot[freeSlot].effectID = effectID;
SoundSlot[freeSlot].channel = channel;
SoundSlot[freeSlot].gain = gain;
SoundSlot[freeSlot].origin = position ? Vector3(position->xPos, position->yPos, position->zPos) : SOUND_OMNIPRESENT_ORIGIN;
// Set 3D attributes
BASS_ChannelSet3DAttributes(channel, position ? BASS_3DMODE_NORMAL : BASS_3DMODE_OFF, SOUND_MAXVOL_RADIUS, radius, 360, 360, 0.0f);
Sound_UpdateEffectPosition(freeSlot, position, true);
if (Sound_CheckBASSError("Applying 3D attribs on channel %x, sound %d", false, channel, effectID))
if (Sound_CheckBASSError("Applying pitch/gain attribs on channel %x, sample %d", false, channel, sampleToPlay))
return 0;
// Set looped flag, if necessary
if(playType == SOUND_LOOPED)
if (playType == SOUND_LOOPED)
BASS_ChannelFlags(channel, BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP);
// Play channel
@ -273,6 +277,14 @@ long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags)
if (Sound_CheckBASSError("Queuing channel %x on sample mixer", false, freeSlot))
return 0;
// Set attributes
BASS_ChannelSet3DAttributes(channel, position ? BASS_3DMODE_NORMAL : BASS_3DMODE_OFF, SOUND_MAXVOL_RADIUS, radius, 360, 360, 0.0f);
Sound_UpdateEffectPosition(freeSlot, position, true);
Sound_UpdateEffectAttributes(freeSlot, pitch, volume);
if (Sound_CheckBASSError("Applying 3D attribs on channel %x, sound %d", false, channel, effectID))
return 0;
return 1;
}
@ -475,7 +487,7 @@ int Sound_GetFreeSlot()
}
}
printf("Hijacking sound effect slot %d \n", farSlot);
logD("Hijacking sound effect slot %d \n", farSlot);
Sound_FreeSlot(farSlot, SOUND_XFADETIME_HIJACKSOUND);
return farSlot;
}
@ -505,7 +517,7 @@ int Sound_EffectIsPlaying(int effectID, PHD_3DPOS *position)
// Check if effect origin is equal OR in nearest possible hearing range.
Vector3 origin = Vector3(position->xPos, position->yPos, position->zPos);
if (SoundSlot[i].origin == origin ||
if (Vector3::Distance(origin, SoundSlot[i].origin) < 64.0f ||
Vector3(SoundSlot[i].origin - origin).Length() < SOUND_MAXVOL_RADIUS)
return i;
}
@ -584,6 +596,18 @@ bool Sound_UpdateEffectPosition(int index, PHD_3DPOS *position, bool force)
return true;
}
// Update gain and pitch.
bool Sound_UpdateEffectAttributes(int index, float pitch, float gain)
{
if (index > SOUND_MAX_CHANNELS || index < 0)
return false;
BASS_ChannelSetAttribute(SoundSlot[index].channel, BASS_ATTRIB_FREQ, 22050.0f * pitch);
BASS_ChannelSetAttribute(SoundSlot[index].channel, BASS_ATTRIB_VOL, gain);
return true;
}
// Update whole sound scene in a level.
// Must be called every frame to update camera position and 3D parameters.

View file

@ -12,7 +12,6 @@ enum SFX_TYPES
};
#define SFX_ALWAYS 2
#define PITCH_SHIFT 4
#define SOUND_BASS_UNITS 1.0f / 1024.0f // TR->BASS distance unit coefficient
#define SOUND_MAXVOL_RADIUS 1024.0f // Max. volume hearing distance
@ -117,7 +116,7 @@ struct AudioTrack
extern std::unordered_map<std::string, AudioTrack> SoundTracks;
extern std::string CurrentLoopedSoundTrack;
long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags);
long SoundEffect(int effectID, PHD_3DPOS* position, int env_flags, float pitchMultiplier = 1.0f, float gainMultiplier = 1.0f);
void StopSoundEffect(short effectID);
bool Sound_LoadSample(char *buffer, int compSize, int uncompSize, int currentIndex);
void Sound_FreeSamples();
@ -150,3 +149,4 @@ float Sound_DistanceToListener(PHD_3DPOS *position);
float Sound_DistanceToListener(Vector3 position);
float Sound_Attenuate(float gain, float distance, float radius);
bool Sound_UpdateEffectPosition(int index, PHD_3DPOS *position, bool force = false);
bool Sound_UpdateEffectAttributes(int index, float pitch, float gain);