try add stereo element to aim assist

This commit is contained in:
Demur Rumed 2025-05-30 04:46:11 +00:00
commit 69d86681cd
2 changed files with 42 additions and 29 deletions

View file

@ -58,10 +58,10 @@ typedef std::map<s32, VAList_t> VAZones_t; // Maps room/ scene indices to their
// re-creation of terrain VAs every time the player reloads a scene. // re-creation of terrain VAs every time the player reloads a scene.
typedef std::unordered_set<s16> SceneList_t; typedef std::unordered_set<s16> SceneList_t;
typedef struct { struct SfxRecord {
std::string path; std::string path;
std::shared_ptr<Ship::File> resource; std::shared_ptr<Ship::File> resource;
} SfxRecord; };
class AudioGlossaryData { class AudioGlossaryData {
public: public:
@ -219,7 +219,6 @@ void ActorAccessibility_TrackNewActor(Actor* actor) {
accessibleActor.managedSoundSlots = 0; accessibleActor.managedSoundSlots = 0;
accessibleActor.aimAssist.framesSinceAimAssist = 32768; accessibleActor.aimAssist.framesSinceAimAssist = 32768;
accessibleActor.aimAssist.frequency = 10; accessibleActor.aimAssist.frequency = 10;
accessibleActor.aimAssist.pitch = 1.0;
aa->trackedActors[actor] = accessibleActor.instanceID; aa->trackedActors[actor] = accessibleActor.instanceID;
aa->accessibleActorList[accessibleActor.instanceID] = accessibleActor; aa->accessibleActorList[accessibleActor.instanceID] = accessibleActor;
@ -282,12 +281,7 @@ void ActorAccessibility_SetSoundPos(void* handle, int slot, Vec3f* pos, f32 dist
void ActorAccessibility_SetSoundVolume(void* handle, int slot, float volume) { void ActorAccessibility_SetSoundVolume(void* handle, int slot, float volume) {
aa->audioEngine->setVolume((uintptr_t)handle, slot, volume); aa->audioEngine->setVolume((uintptr_t)handle, slot, volume);
} }
void ActorAccessibility_SetSoundPan(void* handle, int slot, Vec3f* projectedPos) { void ActorAccessibility_SetSoundPan(void* handle, int slot, float pan) {
float pan = projectedPos->x / 270;
if (pan < -1.0)
pan = -1.0;
if (pan > 1.0)
pan = 1.0;
aa->audioEngine->setPan((uintptr_t)handle, slot, pan); aa->audioEngine->setPan((uintptr_t)handle, slot, pan);
} }
void ActorAccessibility_SetSoundFilter(void* handle, int slot, float cutoff) { void ActorAccessibility_SetSoundFilter(void* handle, int slot, float cutoff) {
@ -363,6 +357,8 @@ void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActo
} }
// Send sound parameters to the new audio engine. Eventually remove the old stuff once all actors are carried over. // Send sound parameters to the new audio engine. Eventually remove the old stuff once all actors are carried over.
for (int i = 0; i < AAE_SLOTS_PER_HANDLE; i++) { for (int i = 0; i < AAE_SLOTS_PER_HANDLE; i++) {
if (i == 9)
continue;
if (actor->managedSoundSlots & (1 << i)) { if (actor->managedSoundSlots & (1 << i)) {
ActorAccessibility_SetSoundPos(actor, i, &actor->projectedPos, actor->xyzDistToPlayer, ActorAccessibility_SetSoundPos(actor, i, &actor->projectedPos, actor->xyzDistToPlayer,
actor->policy.distance); actor->policy.distance);
@ -386,13 +382,14 @@ void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActo
Player* player = GET_PLAYER(play); Player* player = GET_PLAYER(play);
if (player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON && if (player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON &&
(player->stateFlags1 & PLAYER_STATE1_USING_BOOMERANG || player->stateFlags1 & PLAYER_STATE1_ITEM_IN_HAND)) { (player->stateFlags1 & PLAYER_STATE1_USING_BOOMERANG || player->stateFlags1 & PLAYER_STATE1_ITEM_IN_HAND)) {
ActorAccessibility_SetSoundPitch(actor, 9, actor->aimAssist.pitch); auto aimAssistProps = ActorAccessibility_ProvideAimAssistForActor(actor);
actor->aimAssist.framesSinceAimAssist++; ActorAccessibility_SetSoundPitch(actor, 9, aimAssistProps.pitch);
ActorAccessibility_ProvideAimAssistForActor(actor); ActorAccessibility_SetSoundVolume(actor, 9, aimAssistProps.volume);
ActorAccessibility_SetSoundPan(actor, 9, aimAssistProps.pan);
// The above will have taken care of setting the appropriate frequency and pitch, so we'll take care of the // The above will have taken care of setting the appropriate frequency and pitch, so we'll take care of the
// audio here based on those results. // audio here based on those results.
if (actor->aimAssist.framesSinceAimAssist >= actor->aimAssist.frequency) { if (++actor->aimAssist.framesSinceAimAssist >= actor->aimAssist.frequency) {
actor->aimAssist.framesSinceAimAssist = 0; actor->aimAssist.framesSinceAimAssist = 0;
ActorAccessibility_PlaySoundForActor(actor, 9, actor->policy.aimAssist.sfx, false); ActorAccessibility_PlaySoundForActor(actor, 9, actor->policy.aimAssist.sfx, false);
} }
@ -552,7 +549,6 @@ AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRT
actor.managedSoundSlots = 0; actor.managedSoundSlots = 0;
actor.aimAssist.framesSinceAimAssist = 0; actor.aimAssist.framesSinceAimAssist = 0;
actor.aimAssist.frequency = 10; actor.aimAssist.frequency = 10;
actor.aimAssist.pitch = 1.0;
actor.policy = *policy; actor.policy = *policy;
VAList_t* l = (VAList_t*)list; VAList_t* l = (VAList_t*)list;
@ -623,25 +619,26 @@ void ActorAccessibility_AnnounceRoomNumber(PlayState* play) {
ss << "." << std::endl; ss << "." << std::endl;
SpeechSynthesizer::Instance->Speak(ss.str().c_str(), GetLanguageCode()); SpeechSynthesizer::Instance->Speak(ss.str().c_str(), GetLanguageCode());
} }
// Aim cue support.
void ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* actor) { AimAssistProps ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* actor) {
Player* player = GET_PLAYER(actor->play); Player* player = GET_PLAYER(actor->play);
s32 angle = player->actor.focus.rot.x; s32 angle = player->actor.focus.rot.x;
angle = angle / -14000.0 * 16384; angle = angle / -14000.0 * 16384;
f32 slope = Math_SinS(angle) / Math_CosS(angle) * 1.0; f32 slope = Math_SinS(angle) / Math_CosS(angle) * 1.0;
s32 yIntercept = (slope * (actor->xzDistToPlayer)) + player->actor.focus.pos.y; s32 yIntercept = slope * actor->xzDistToPlayer + player->actor.focus.pos.y;
s32 yHight = actor->world.pos.y + 25; s32 yHeight = actor->world.pos.y + 25;
if (slope < 1) { if (slope < 1) {
slope = 1; slope = 1;
} }
s32 correction = (1 - 1 / slope) * 100; s32 correction = (1 - 1 / slope) * 100;
if ((yIntercept) > yHight + 25) { AimAssistProps aimAssistProps;
actor->aimAssist.pitch = 1.5; if (yIntercept > yHeight + 25) {
} else if ((yIntercept) < yHight - 25) { aimAssistProps.pitch = 1.5;
actor->aimAssist.pitch = 0.5; } else if (yIntercept < yHeight - 25) {
aimAssistProps.pitch = 0.5;
} }
s32 yDiff = fabs(yIntercept - yHight); s32 yDiff = fabs(yIntercept - yHeight);
if (yIntercept - yHight > 0) { if (yIntercept - yHeight > 0) {
yDiff -= correction; yDiff -= correction;
if (yDiff < 0) { if (yDiff < 0) {
yDiff = 0; yDiff = 0;
@ -652,6 +649,17 @@ void ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* actor) {
} else { } else {
actor->aimAssist.frequency = 1 + (uint8_t)(yDiff / 5); actor->aimAssist.frequency = 1 + (uint8_t)(yDiff / 5);
} }
s16 yawdiff = player->yaw - Math_Atan2S(actor->world.pos.z - player->actor.world.pos.z,
actor->world.pos.x - player->actor.world.pos.x);
if (yawdiff > -0x1000 && yawdiff < 0x1000) {
aimAssistProps.volume = 1.0 - (yawdiff * yawdiff) / (float)0x2000000;
} else if (yawdiff > -0x2000 && yawdiff < 0x2000) {
aimAssistProps.volume = 0.4;
} else {
aimAssistProps.volume = 0.2;
}
aimAssistProps.pan = std::min(std::max(yawdiff / (float)0x1000, -1.0f), 1.0f);
return aimAssistProps;
} }
// External audio engine stuff. // External audio engine stuff.

View file

@ -56,7 +56,7 @@ struct AccessibleActor {
PlayState* play; PlayState* play;
u8 isDrawn; // Do we just never play accessibility sounds for actors that aren't drawn? u8 isDrawn; // Do we just never play accessibility sounds for actors that aren't drawn?
int frameCount; // Incremented every time the callback is called. The callback is free to modify this. Can be used u16 frameCount; // Incremented every time the callback is called. The callback is free to modify this. Can be used
// to implement playback of sounds at regular intervals. // to implement playback of sounds at regular intervals.
f32 baseVolume; f32 baseVolume;
f32 currentVolume; f32 currentVolume;
@ -69,7 +69,6 @@ struct AccessibleActor {
struct { struct {
u16 framesSinceAimAssist; // Allows rate-based vertical aim assist. Incremented every frame for aim assist u16 framesSinceAimAssist; // Allows rate-based vertical aim assist. Incremented every frame for aim assist
// actors. Manually reset by aim assist provider. // actors. Manually reset by aim assist provider.
f32 pitch; // Used to report whether Link is aiming higher or lower than the actor.
u8 frequency; // How often the sound will be played. Lower frequencies indicate that Link's vertical aim is u8 frequency; // How often the sound will be played. Lower frequencies indicate that Link's vertical aim is
// closer to the actor. // closer to the actor.
} aimAssist; } aimAssist;
@ -79,6 +78,12 @@ struct AccessibleActor {
void* userData; // Set by the policy. Can be anything. void* userData; // Set by the policy. Can be anything.
}; };
struct AimAssistProps {
f32 pitch;
f32 volume;
f32 pan;
};
// Initialize accessibility. // Initialize accessibility.
void ActorAccessibility_Init(); void ActorAccessibility_Init();
void ActorAccessibility_InitActors(); void ActorAccessibility_InitActors();
@ -116,7 +121,7 @@ void ActorAccessibility_SetListenerPos(Vec3f* pos, Vec3f* rot);
void ActorAccessibility_SetSoundPos(void* handle, int slot, Vec3f* pos, f32 distToPlayer, f32 maxDistance); void ActorAccessibility_SetSoundPos(void* handle, int slot, Vec3f* pos, f32 distToPlayer, f32 maxDistance);
void ActorAccessibility_SetSoundVolume(void* handle, int slot, float volume); void ActorAccessibility_SetSoundVolume(void* handle, int slot, float volume);
void ActorAccessibility_SetSoundPan(void* handle, int slot, Vec3f* projectedPos); void ActorAccessibility_SetSoundPan(void* handle, int slot, float pan);
void ActorAccessibility_SetSoundFilter(void* handle, int slot, float cutoff); void ActorAccessibility_SetSoundFilter(void* handle, int slot, float cutoff);
void ActorAccessibility_SeekSound(void* handle, int slot, size_t offset); void ActorAccessibility_SeekSound(void* handle, int slot, size_t offset);
@ -166,7 +171,7 @@ void ActorAccessibility_PolyToVirtualActor(PlayState* play, CollisionPoly* poly,
// Report which room of a dungeon the player is in. // Report which room of a dungeon the player is in.
void ActorAccessibility_AnnounceRoomNumber(PlayState* play); void ActorAccessibility_AnnounceRoomNumber(PlayState* play);
// Aim cue support. // Aim cue support.
void ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* actor); AimAssistProps ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* actor);
// External audio engine stuff. // External audio engine stuff.
// Initialize the accessible audio engine. // Initialize the accessible audio engine.
bool ActorAccessibility_InitAudio(); bool ActorAccessibility_InitAudio();