fix terrain cues

This commit is contained in:
Demur Rumed 2025-06-10 16:49:54 +00:00
commit 92dc122fdb
4 changed files with 71 additions and 38 deletions

View file

@ -979,7 +979,7 @@ void ActorAccessibility_InitActors() {
ActorAccessibility_AddSupportedActor(VA_MARKER, policy); ActorAccessibility_AddSupportedActor(VA_MARKER, policy);
// Virtual actors for a given location (scene and room number). // Virtual actors for a given location (scene and room number).
VirtualActorList* list = (VirtualActorList*)ActorAccessibility_GetVirtualActorList(EVERYWHERE, 0); VirtualActorList* list;
AccessibleActor* temp; AccessibleActor* temp;
list = ActorAccessibility_GetVirtualActorList(SCENE_KOKIRI_FOREST, 0); list = ActorAccessibility_GetVirtualActorList(SCENE_KOKIRI_FOREST, 0);
@ -1160,5 +1160,31 @@ void ActorAccessibility_InitActors() {
temp->policy.ydist = 100; temp->policy.ydist = 100;
temp->policy.sound = NA_SE_EV_BLOCK_SHAKE; temp->policy.sound = NA_SE_EV_BLOCK_SHAKE;
ActorAccessibility_InitCues(); ActorAccessibility_InitPolicy(&policy, "Terrain cue helper", accessible_va_terrain_cue);
policy.n = 1;
policy.runsAlways = true;
policy.distance = 500;
policy.initUserData = ActorAccessibility_InitTerrainCueState;
policy.cleanupUserData = ActorAccessibility_CleanupTerrainCueState;
ActorAccessibility_AddSupportedActor(VA_TERRAIN_CUE, policy);
AccessibleActor* actor = new AccessibleActor;
actor->actor = nullptr;
actor->basePitch = 1.0;
actor->baseVolume = 1.0;
actor->currentPitch = 1.0;
actor->currentVolume = 1.0;
actor->frameCount = 0;
actor->id = VA_TERRAIN_CUE;
actor->instanceID = ActorAccessibility_GetNextID();
actor->isDrawn = 1;
actor->play = nullptr;
actor->pos = { 0, 0, 0 };
actor->sceneIndex = 0;
actor->managedSoundSlots = 0;
actor->aimAssist.framesSinceAimAssist = 0;
actor->aimAssist.frequency = 10;
actor->policy = policy;
ActorAccessibility_InitTerrainCueState(actor);
ActorAccessibility_AddTerrainCues(actor);
} }

View file

@ -94,8 +94,9 @@ class ActorAccessibility {
Vec3f prevPos = { 0, 0, 0 }; Vec3f prevPos = { 0, 0, 0 };
s16 prevYaw = 0; s16 prevYaw = 0;
bool extractSfx = false; bool extractSfx = false;
VirtualActorList* currentSceneGlobal = NULL; AccessibleActor* terrainCues = nullptr;
VirtualActorList* currentRoomLocal = NULL; VirtualActorList* currentSceneGlobal = nullptr;
VirtualActorList* currentRoomLocal = nullptr;
}; };
static ActorAccessibility* aa; static ActorAccessibility* aa;
@ -117,9 +118,11 @@ void ActorAccessibility_OnGameFrameUpdate() {
ActorAccessibility_RunAccessibilityForAllActors(gPlayState); ActorAccessibility_RunAccessibilityForAllActors(gPlayState);
} }
void ActorAccessibility_OnActorDestroy(void* actor) { void ActorAccessibility_OnActorDestroy(void* actor) {
ActorAccessibility_RemoveTrackedActor((Actor*)actor); ActorAccessibility_RemoveTrackedActor((Actor*)actor);
} }
void ActorAccessibility_OnGameStillFrozen() { void ActorAccessibility_OnGameStillFrozen() {
if (gPlayState == NULL) if (gPlayState == NULL)
return; return;
@ -183,6 +186,10 @@ void ActorAccessibility_AddSupportedActor(s16 type, ActorAccessibilityPolicy pol
aa->supportedActors[type] = policy; aa->supportedActors[type] = policy;
} }
void ActorAccessibility_AddTerrainCues(AccessibleActor* actor) {
aa->terrainCues = actor;
}
ActorAccessibilityPolicy* ActorAccessibility_GetPolicyForActor(s16 type) { ActorAccessibilityPolicy* ActorAccessibility_GetPolicyForActor(s16 type) {
SupportedActors_t::iterator i = aa->supportedActors.find(type); SupportedActors_t::iterator i = aa->supportedActors.find(type);
if (i == aa->supportedActors.end()) if (i == aa->supportedActors.end())
@ -224,6 +231,7 @@ void ActorAccessibility_TrackNewActor(Actor* actor) {
policy->initUserData(&savedActor); policy->initUserData(&savedActor);
} }
} }
void ActorAccessibility_RemoveTrackedActor(Actor* actor) { void ActorAccessibility_RemoveTrackedActor(Actor* actor) {
TrackedActors_t::iterator i = aa->trackedActors.find(actor); TrackedActors_t::iterator i = aa->trackedActors.find(actor);
if (i == aa->trackedActors.end()) if (i == aa->trackedActors.end())
@ -242,6 +250,7 @@ void ActorAccessibility_RemoveTrackedActor(Actor* actor) {
f32 ActorAccessibility_DBToLinear(float gain) { f32 ActorAccessibility_DBToLinear(float gain) {
return powf(10.0, gain / 20.0f); return powf(10.0, gain / 20.0f);
} }
f32 ActorAccessibility_ComputeCurrentVolume(f32 maxDistance, f32 xzDistToPlayer) { f32 ActorAccessibility_ComputeCurrentVolume(f32 maxDistance, f32 xzDistToPlayer) {
if (maxDistance == 0) if (maxDistance == 0)
return 0.0; return 0.0;
@ -250,6 +259,7 @@ f32 ActorAccessibility_ComputeCurrentVolume(f32 maxDistance, f32 xzDistToPlayer)
return ActorAccessibility_DBToLinear(db); return ActorAccessibility_DBToLinear(db);
} }
const char* ActorAccessibility_MapSfxToExternalAudio(s16 sfxId); const char* ActorAccessibility_MapSfxToExternalAudio(s16 sfxId);
void ActorAccessibility_PlaySound(void* handle, int slot, s16 sfxId) { void ActorAccessibility_PlaySound(void* handle, int slot, s16 sfxId) {
const char* path = ActorAccessibility_MapSfxToExternalAudio(sfxId); const char* path = ActorAccessibility_MapSfxToExternalAudio(sfxId);
@ -285,6 +295,7 @@ 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) {
aa->audioEngine->seekSound((uintptr_t)handle, slot, offset); aa->audioEngine->seekSound((uintptr_t)handle, slot, offset);
} }
void ActorAccessibility_ConfigureSoundForActor(AccessibleActor* actor, int slot) { void ActorAccessibility_ConfigureSoundForActor(AccessibleActor* actor, int slot) {
ActorAccessibility_SetSoundPitch(actor, slot, actor->policy.pitch); ActorAccessibility_SetSoundPitch(actor, slot, actor->policy.pitch);
ActorAccessibility_SetPitchBehindModifier(actor, slot, actor->policy.pitchModifier); ActorAccessibility_SetPitchBehindModifier(actor, slot, actor->policy.pitchModifier);
@ -292,12 +303,14 @@ void ActorAccessibility_ConfigureSoundForActor(AccessibleActor* actor, int slot)
ActorAccessibility_SetSoundVolume(actor, slot, actor->policy.volume); ActorAccessibility_SetSoundVolume(actor, slot, actor->policy.volume);
actor->managedSoundSlots |= 1 << slot; actor->managedSoundSlots |= 1 << slot;
} }
void ActorAccessibility_PlaySoundForActor(AccessibleActor* actor, int slot, s16 sfxId) { void ActorAccessibility_PlaySoundForActor(AccessibleActor* actor, int slot, s16 sfxId) {
if (slot < 0 || slot > AAE_SLOTS_PER_HANDLE) if (slot < 0 || slot > AAE_SLOTS_PER_HANDLE)
return; return;
ActorAccessibility_PlaySound(actor, slot, sfxId); ActorAccessibility_PlaySound(actor, slot, sfxId);
ActorAccessibility_ConfigureSoundForActor(actor, slot); ActorAccessibility_ConfigureSoundForActor(actor, slot);
} }
void ActorAccessibility_StopSoundForActor(AccessibleActor* actor, int slot) { void ActorAccessibility_StopSoundForActor(AccessibleActor* actor, int slot) {
if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE)
return; return;
@ -310,9 +323,6 @@ void ActorAccessibility_StopAllSoundsForActor(AccessibleActor* actor) {
actor->managedSoundSlots = 0; actor->managedSoundSlots = 0;
} }
bool ActorAccessibility_IsRealActor(AccessibleActor* actor) {
return actor->actor != NULL;
}
void ActorAccessibility_CopyParamsFromRealActor(AccessibleActor* actor) { void ActorAccessibility_CopyParamsFromRealActor(AccessibleActor* actor) {
Player* player = GET_PLAYER(actor->play); Player* player = GET_PLAYER(actor->play);
if (actor->actor == NULL) if (actor->actor == NULL)
@ -335,7 +345,7 @@ void ActorAccessibility_StopAllVirtualActors(VirtualActorList* list) {
void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActor* actor) { void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActor* actor) {
actor->play = play; actor->play = play;
if (ActorAccessibility_IsRealActor(actor)) { if (actor->actor != nullptr) {
ActorAccessibility_CopyParamsFromRealActor(actor); ActorAccessibility_CopyParamsFromRealActor(actor);
} else { } else {
Player* player = GET_PLAYER(play); Player* player = GET_PLAYER(play);
@ -363,14 +373,15 @@ void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActo
if (aa->glossary->GlossaryStarted) { if (aa->glossary->GlossaryStarted) {
aa->glossary->frameCount++; aa->glossary->frameCount++;
} }
if (actor->frameCount % actor->policy.n) if (actor->frameCount % actor->policy.n) {
return; return;
if (!actor->policy.runsAlways && actor->xyzDistToPlayer > actor->policy.distance) { } else if (!actor->policy.runsAlways && actor->xyzDistToPlayer > actor->policy.distance) {
return;
} else if (actor->isDrawn == 0 && actor->actor->id != ACTOR_EN_IT && actor->actor->id != ACTOR_EN_OKARINA_TAG &&
!aa->glossary->GlossaryStarted) {
return; return;
} }
if (actor->isDrawn == 0 && actor->actor->id != ACTOR_EN_IT && actor->actor->id != ACTOR_EN_OKARINA_TAG &&
!aa->glossary->GlossaryStarted)
return;
if (actor->policy.aimAssist.isProvider) { if (actor->policy.aimAssist.isProvider) {
Player* player = GET_PLAYER(play); Player* player = GET_PLAYER(play);
if (player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON && if (player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON &&
@ -399,6 +410,8 @@ void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActo
void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play) { void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play) {
Player* player = GET_PLAYER(play); Player* player = GET_PLAYER(play);
if (play->sceneNum != aa->currentScene) { if (play->sceneNum != aa->currentScene) {
if (aa->terrainCues)
ActorAccessibility_StopAllSounds(aa->terrainCues);
ActorAccessibility_StopAllVirtualActors(aa->currentSceneGlobal); ActorAccessibility_StopAllVirtualActors(aa->currentSceneGlobal);
ActorAccessibility_StopAllVirtualActors(aa->currentRoomLocal); ActorAccessibility_StopAllVirtualActors(aa->currentRoomLocal);
aa->currentSceneGlobal = ActorAccessibility_GetVirtualActorList(play->sceneNum, -1); aa->currentSceneGlobal = ActorAccessibility_GetVirtualActorList(play->sceneNum, -1);
@ -432,6 +445,10 @@ void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play) {
for (AccessibleActorList_t::iterator i = aa->accessibleActorList.begin(); i != aa->accessibleActorList.end(); i++) for (AccessibleActorList_t::iterator i = aa->accessibleActorList.begin(); i != aa->accessibleActorList.end(); i++)
ActorAccessibility_RunAccessibilityForActor(play, &i->second); ActorAccessibility_RunAccessibilityForActor(play, &i->second);
if (aa->terrainCues) {
ActorAccessibility_RunAccessibilityForActor(play, aa->terrainCues);
}
// Virtual actors for the current room and scene. // Virtual actors for the current room and scene.
VAList_t* list = (VAList_t*)aa->currentRoomLocal; VAList_t* list = (VAList_t*)aa->currentRoomLocal;
for (VAList_t::iterator i = list->begin(); i != list->end(); i++) for (VAList_t::iterator i = list->begin(); i != list->end(); i++)
@ -599,18 +616,14 @@ VirtualActorList* ActorAccessibility_GetVirtualActorList(s16 sceneNum, s8 roomNu
SceneAndRoom sr; SceneAndRoom sr;
sr.values.sceneIndex = sceneNum; sr.values.sceneIndex = sceneNum;
sr.values.roomIndex = roomNum; sr.values.roomIndex = roomNum;
if (sceneNum == EVERYWHERE)
sr.values.sceneIndex = EVERYWHERE;
return (VirtualActorList*)&aa->vaZones[sr.raw]; return (VirtualActorList*)&aa->vaZones[sr.raw];
} }
AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRTUAL_ACTOR_TABLE type, Vec3f where) { AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRTUAL_ACTOR_TABLE type, Vec3f where) {
ActorAccessibilityPolicy* policy = ActorAccessibility_GetPolicyForActor(type); ActorAccessibilityPolicy* policy = ActorAccessibility_GetPolicyForActor(type);
if (policy == NULL)
return NULL;
AccessibleActor actor; AccessibleActor actor;
actor.actor = NULL; actor.actor = nullptr;
actor.basePitch = 1.0; actor.basePitch = 1.0;
actor.baseVolume = 1.0; actor.baseVolume = 1.0;
actor.currentPitch = 1.0; actor.currentPitch = 1.0;
@ -619,14 +632,14 @@ AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRT
actor.id = (s16)type; actor.id = (s16)type;
actor.instanceID = ActorAccessibility_GetNextID(); actor.instanceID = ActorAccessibility_GetNextID();
actor.isDrawn = 1; actor.isDrawn = 1;
actor.play = NULL; actor.play = nullptr;
actor.pos = where; actor.pos = where;
actor.sceneIndex = 0; actor.sceneIndex = 0;
actor.managedSoundSlots = 0; actor.managedSoundSlots = 0;
actor.aimAssist.framesSinceAimAssist = 0; actor.aimAssist.framesSinceAimAssist = 0;
actor.aimAssist.frequency = 10; actor.aimAssist.frequency = 10;
actor.policy = *policy; actor.policy = *policy;
VAList_t* l = (VAList_t*)list; VAList_t* l = (VAList_t*)list;
l->push_back(actor); l->push_back(actor);
size_t index = l->size() - 1; size_t index = l->size() - 1;
@ -635,6 +648,7 @@ AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRT
policy->initUserData(savedActor); policy->initUserData(savedActor);
return savedActor; return savedActor;
} }
void ActorAccessibility_InterpretCurrentScene(PlayState* play) { void ActorAccessibility_InterpretCurrentScene(PlayState* play) {
if (aa->sceneList.contains(play->sceneNum)) if (aa->sceneList.contains(play->sceneNum))
return; // Scene interpretation already complete for this scene. return; // Scene interpretation already complete for this scene.
@ -657,6 +671,7 @@ void ActorAccessibility_InterpretCurrentScene(PlayState* play) {
} }
} }
} }
// Convert poly to VA. // Convert poly to VA.
void ActorAccessibility_PolyToVirtualActor(PlayState* play, CollisionPoly* poly, VIRTUAL_ACTOR_TABLE va, void ActorAccessibility_PolyToVirtualActor(PlayState* play, CollisionPoly* poly, VIRTUAL_ACTOR_TABLE va,
VirtualActorList* destination) { VirtualActorList* destination) {
@ -745,6 +760,10 @@ bool ActorAccessibility_InitAudio() {
void ActorAccessibility_ShutdownAudio() { void ActorAccessibility_ShutdownAudio() {
if (aa->isOn) { if (aa->isOn) {
delete aa->audioEngine; delete aa->audioEngine;
if (aa->terrainCues) {
ActorAccessibility_CleanupTerrainCueState(aa->terrainCues);
delete aa->terrainCues;
}
aa->isOn = false; aa->isOn = false;
} }
} }

View file

@ -92,10 +92,15 @@ void ActorAccessibility_InitPolicy(ActorAccessibilityPolicy* policy, const char*
void ActorAccessibility_InitPolicy(ActorAccessibilityPolicy* policy, const char* englishName, void ActorAccessibility_InitPolicy(ActorAccessibilityPolicy* policy, const char* englishName,
ActorAccessibilityCallback callback); ActorAccessibilityCallback callback);
void ActorAccessibility_InitPolicy(ActorAccessibilityPolicy* policy, const char* englishName, s16 sfx); void ActorAccessibility_InitPolicy(ActorAccessibilityPolicy* policy, const char* englishName, s16 sfx);
void ActorAccessibility_InitTerrainCueState(AccessibleActor* actor);
void ActorAccessibility_CleanupTerrainCueState(AccessibleActor* actor);
void accessible_va_terrain_cue(AccessibleActor* actor);
uint64_t ActorAccessibility_GetNextID();
void ActorAccessibility_TrackNewActor(Actor* actor); void ActorAccessibility_TrackNewActor(Actor* actor);
void ActorAccessibility_RemoveTrackedActor(Actor* actor); void ActorAccessibility_RemoveTrackedActor(Actor* actor);
void ActorAccessibility_AddSupportedActor(s16 type, ActorAccessibilityPolicy policy); void ActorAccessibility_AddSupportedActor(s16 type, ActorAccessibilityPolicy policy);
void ActorAccessibility_AddTerrainCues(AccessibleActor* actor);
void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActor* actor); void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActor* actor);
void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play); void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play);
@ -139,7 +144,6 @@ void ActorAccessibility_StopAllSoundsForActor(AccessibleActor* actor);
f32 ActorAccessibility_ComputeCurrentVolume(f32 maxDistance, f32 xzDistToPlayer); f32 ActorAccessibility_ComputeCurrentVolume(f32 maxDistance, f32 xzDistToPlayer);
// Computes a relative angle based on Link's (or some other actor's) current angle. // Computes a relative angle based on Link's (or some other actor's) current angle.
Vec3s ActorAccessibility_ComputeRelativeAngle(Vec3s* origin, Vec3s* offset); Vec3s ActorAccessibility_ComputeRelativeAngle(Vec3s* origin, Vec3s* offset);
void ActorAccessibility_InitCues();
// Stuff related to lists of virtual actors. // Stuff related to lists of virtual actors.
typedef enum { typedef enum {
// Similar to the game's actual actor table // Similar to the game's actual actor table
@ -155,8 +159,6 @@ typedef enum {
VA_MAX, VA_MAX,
} VIRTUAL_ACTOR_TABLE; } VIRTUAL_ACTOR_TABLE;
#define EVERYWHERE -32768 // Denotes a virtual actor that is global
// Get the list of virtual actors for a given scene and room index. // Get the list of virtual actors for a given scene and room index.
VirtualActorList* ActorAccessibility_GetVirtualActorList(s16 sceneNum, s8 roomNum); VirtualActorList* ActorAccessibility_GetVirtualActorList(s16 sceneNum, s8 roomNum);
AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRTUAL_ACTOR_TABLE type, Vec3f where); AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRTUAL_ACTOR_TABLE type, Vec3f where);

View file

@ -1374,18 +1374,4 @@ void accessible_va_terrain_cue(AccessibleActor* actor) {
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
state->directions[i].scan(); state->directions[i].scan();
}
void ActorAccessibility_InitCues() {
ActorAccessibilityPolicy policy;
ActorAccessibility_InitPolicy(&policy, "Terrain cue helper", accessible_va_terrain_cue);
policy.n = 1;
policy.runsAlways = true;
policy.distance = 500;
policy.initUserData = ActorAccessibility_InitTerrainCueState;
policy.cleanupUserData = ActorAccessibility_CleanupTerrainCueState;
ActorAccessibility_AddSupportedActor(VA_TERRAIN_CUE, policy);
VirtualActorList* list = ActorAccessibility_GetVirtualActorList(EVERYWHERE, 0);
ActorAccessibility_AddVirtualActor(list, VA_TERRAIN_CUE, { 0, 0, 0 });
} }