From 17d2e39a57a3ba78c7fea4af6b4d9bd6584b2a89 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 20 Apr 2025 21:25:39 +0000 Subject: [PATCH] fix archive creation, must be o2r --- .../accessible-actors/AccessibleActorList.cpp | 498 ++++--- .../AccessibleAudioEngine.cpp | 808 ++++++----- .../accessible-actors/AccessibleAudioEngine.h | 133 +- .../accessible-actors/ActorAccessibility.cpp | 1187 ++++++++--------- .../accessible-actors/ActorAccessibility.h | 87 +- .../accessible-actors/SfxExtractor.cpp | 29 +- .../Enhancements/accessible-actors/SfxTable.h | 5 +- .../accessible-actors/accessibility_cues.cpp | 614 ++++----- soh/soh/OTRGlobals.cpp | 2 +- 9 files changed, 1598 insertions(+), 1765 deletions(-) diff --git a/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp b/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp index d1912baa7..6553dcbb4 100644 --- a/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp +++ b/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp @@ -13,61 +13,56 @@ #include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h" std::vector buttonList = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, - BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; -//Declarations specific to chests. + BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; +// Declarations specific to chests. #include "overlays/actors/ovl_En_Box/z_en_box.h" extern "C" { void EnBox_WaitOpen(EnBox*, PlayState*); } -//Declarations specific to Babas. +// Declarations specific to Babas. #include "overlays/actors/ovl_En_Karebaba/z_en_karebaba.h" extern "C" { void EnKarebaba_DeadItemDrop(EnKarebaba*, PlayState*); } -//Declarations specific to Torches +// Declarations specific to Torches #include "overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h" -//Declarations specific to dogs +// Declarations specific to dogs #include "overlays/actors/ovl_En_Dog/z_en_dog.h" extern "C" { void EnDog_FollowPlayer(EnDog*, PlayState*); s8 EnDog_CanFollow(EnDog*, PlayState*); } - //User data for the general helper VA. -typedef struct -{ +// User data for the general helper VA. +typedef struct { s16 currentScene; s8 currentRoom; bool currentRoomClear; -}GeneralHelperData; -typedef struct -{ +} GeneralHelperData; +typedef struct { f32 linearVelocity; int framesUntilChime; -}AudioCompassData; -typedef struct -{ +} AudioCompassData; +typedef struct { int framesUntilAboveChime; -}SwitchData; +} SwitchData; - // Begin actor-specific policy callbacks. +// Begin actor-specific policy callbacks. void accessible_en_ishi(AccessibleActor* actor) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_OCTAROCK_ROCK, false); - //ActorAccessibility_PlaySpecialSound(actor, NA_SE_EN_OCTAROCK_ROCK); + // ActorAccessibility_PlaySpecialSound(actor, NA_SE_EN_OCTAROCK_ROCK); } void accessible_en_NPC_Gen(AccessibleActor* actor) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_VO_NB_LAUGH, false); - } void accessible_en_chest(AccessibleActor* actor) { - - + Player* player = GET_PLAYER(actor->play); EnBox* chest = (EnBox*)actor->actor; if (chest->actionFunc != EnBox_WaitOpen) @@ -77,37 +72,35 @@ void accessible_en_chest(AccessibleActor* actor) { if (chest->type <= 8 && chest->type >= 5) { size = 15; // small } else { - size = 30;//large + size = 30; // large } if (!(treasureFlag >= 20 && treasureFlag < 32)) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_TBOX_UNLOCK, false); } - //Only chests that are "waiting to be opened" should play a sound. Chests which have not yet appeared (because some enemy has not been killed, switch has not been hit, etc) will not be in this action mode. + // Only chests that are "waiting to be opened" should play a sound. Chests which have not yet appeared (because some + // enemy has not been killed, switch has not been hit, etc) will not be in this action mode. f32 leftAngle = actor->actor->world.rot.y - 16384; f32 velocityXRight = Math_SinS(leftAngle); f32 velocityZRight = Math_CosS(leftAngle); - + f32 frontAngle = actor->actor->world.rot.y; f32 velocityXFront = Math_SinS(frontAngle); f32 velocityZFront = Math_CosS(frontAngle); - f32 xdist = (player->actor.world.pos.x - actor->actor->world.pos.x) * velocityXFront + - (player->actor.world.pos.z-actor->actor->world.pos.z) * velocityZFront; - f32 zdist = fabs((player->actor.world.pos.x - actor->actor->world.pos.x) * velocityXRight + - (player->actor.world.pos.z-actor->actor->world.pos.z) * velocityZRight); - + f32 xdist = (player->actor.world.pos.x - actor->actor->world.pos.x) * velocityXFront + + (player->actor.world.pos.z - actor->actor->world.pos.z) * velocityZFront; + f32 zdist = fabs((player->actor.world.pos.x - actor->actor->world.pos.x) * velocityXRight + + (player->actor.world.pos.z - actor->actor->world.pos.z) * velocityZRight); if ((xdist - size / 2) < 0) { ActorAccessibility_SetSoundPitch(actor, 0, 0.5); } else if ((xdist + size / 2) > 0 && zdist < size / 2 && xdist < 150.0) { ActorAccessibility_PlaySoundForActor(actor, 1, NA_SE_EV_DIAMOND_SWITCH, false); } - - } void accessible_en_gerudo(AccessibleActor* actor) { - ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_VO_NB_LAUGH, false);//update sound for ones that detect you + ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_VO_NB_LAUGH, false); // update sound for ones that detect you } void accessible_en_Sign(AccessibleActor* actor) { @@ -154,7 +147,7 @@ void accessible_torches(AccessibleActor* actor) { return; } - //unlit permanent torches + // unlit permanent torches if ((actor->actor->params) == 8192) { if (torche->litTimer == 0) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_IT_BOMB_IGNIT, false); @@ -162,7 +155,7 @@ void accessible_torches(AccessibleActor* actor) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_ANUBIS_FIRE, false); } } - //lit permanent torches + // lit permanent torches if ((actor->actor->params) == 9216 || (actor->actor->params) == 962) { actor->policy.volume = 0.5; @@ -187,20 +180,17 @@ bool accessible_switch_init(AccessibleActor* actor) { SwitchData* data = (SwitchData*)malloc(sizeof(SwitchData)); data->framesUntilAboveChime = 0; if (data == NULL) - return false;//failure to allocate memory. - actor->userData = (void*) data; + return false; // failure to allocate memory. + actor->userData = (void*)data; return true; - } -void accessible_switch_cleanup(AccessibleActor* actor) -{ +void accessible_switch_cleanup(AccessibleActor* actor) { free(actor->userData); - } - void accessible_switch(AccessibleActor * actor) { +void accessible_switch(AccessibleActor* actor) { - SwitchData* data = (SwitchData*)actor->userData; + SwitchData* data = (SwitchData*)actor->userData; Player* player = GET_PLAYER(actor->play); ObjSwitch* sw = (ObjSwitch*)actor->actor; @@ -211,26 +201,24 @@ void accessible_switch_cleanup(AccessibleActor* actor) } if (scale.y >= 33.0f / 200.0f) { if (actor->play->sceneNum == 0 && actor->play->roomCtx.curRoom.num == 5 && actor->xzDistToPlayer < 20) { - ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIAMOND_SWITCH, false);//Should result in same behaviour. + ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIAMOND_SWITCH, + false); // Should result in same behaviour. } if (actor->frameCount % 30 != 0) { return; } ActorAccessibility_PlaySoundForActor(actor, 1, NA_SE_EV_FOOT_SWITCH, false); -} - } - else if (actor->frameCount % 30 != 0) { + } + } else if (actor->frameCount % 30 != 0) { return; - } - else if ((actor->actor->params & 7) == 1) { + } else if ((actor->actor->params & 7) == 1) { if (actor->xyzDistToPlayer > 800) { return; } if (scale.y >= 33.0f / 200.0f) { //(!(Flags_GetSwitch(actor->play, (actor->params >> 8 & 0x3F)))) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_IT_HAMMER_HIT, false); } - } - else if ((actor->actor->params & 7) == 2) { + } else if ((actor->actor->params & 7) == 2) { if (sw->eyeTexIndex == 0) { //(!(Flags_GetSwitch(actor->play, (actor->params >> 8 & 0x3F)))) // make it only play for open eye actor->policy.aimAssist.isProvider = true; @@ -243,9 +231,7 @@ void accessible_switch_cleanup(AccessibleActor* actor) return; } ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIAMOND_SWITCH, false); - } - } void accessible_larva(AccessibleActor* actor) { @@ -261,7 +247,6 @@ void accessible_va_prototype(AccessibleActor* actor) { Player* player = GET_PLAYER(actor->play); ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_IT_BOMB_EXPLOSION, false); - } void accessible_maruta(AccessibleActor* actor) { @@ -279,7 +264,7 @@ void accessible_area_change(AccessibleActor* actor) { actor->play->sceneNum != 82) { return; } - /*switch (actor->sceneIndex) { + /*switch (actor->sceneIndex) { case 85 || 91: ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_SARIA_MELODY, false); case 81: @@ -287,9 +272,9 @@ void accessible_area_change(AccessibleActor* actor) { case 0: ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_FANTOM_WARP_L, false); }*/ - - //hyrule field attenuation - if (actor->play->sceneNum == 81) { + + // hyrule field attenuation + if (actor->play->sceneNum == 81) { if (actor->xzDistToPlayer > 700) { actor->policy.distance = actor->xzDistToPlayer * 1.2; if (actor->xzDistToPlayer > 8000) { @@ -302,145 +287,142 @@ void accessible_area_change(AccessibleActor* actor) { } } } - //kakariko village attenuation - else if (actor->play->sceneNum == 82) { - if (actor->sceneIndex == 83 || actor->sceneIndex == 81 || actor->sceneIndex == 96) { - actor->policy.runsAlways = true; - actor->policy.ydist = 5000; - if (actor->xzDistToPlayer > 700) { - if (actor->sceneIndex == 81) { - actor->policy.distance = actor->xyzDistToPlayer * 1.4; - } else { - actor->policy.distance = actor->xyzDistToPlayer * 1.2; - } - if (actor->xzDistToPlayer > 8000) { - return; - } + // kakariko village attenuation + else if (actor->play->sceneNum == 82) { + if (actor->sceneIndex == 83 || actor->sceneIndex == 81 || actor->sceneIndex == 96) { + actor->policy.runsAlways = true; + actor->policy.ydist = 5000; + if (actor->xzDistToPlayer > 700) { + if (actor->sceneIndex == 81) { + actor->policy.distance = actor->xyzDistToPlayer * 1.4; } else { - actor->policy.distance = 1500; - if (actor->xzDistToPlayer > 1500) { - return; - } + actor->policy.distance = actor->xyzDistToPlayer * 1.2; } - } else if (actor->sceneIndex == 8) { - if (!(((gSaveContext.eventChkInf[6]) >> (7)) & 1)) - return; - } - else { - actor->policy.ydist = 500; - actor->policy.distance = 1000; - if (actor->xzDistToPlayer > 1000) { + if (actor->xzDistToPlayer > 8000) { + return; + } + } else { + actor->policy.distance = 1500; + if (actor->xzDistToPlayer > 1500) { return; } - } } - - - else if (actor->play->sceneNum == 91 || actor->play->sceneNum == 69 || actor->play->sceneNum == 70) { + } else if (actor->sceneIndex == 8) { + if (!(((gSaveContext.eventChkInf[6]) >> (7)) & 1)) + return; + } else { + actor->policy.ydist = 500; actor->policy.distance = 1000; if (actor->xzDistToPlayer > 1000) { return; } } - /* if (actor->play->sceneNum <= 11) { - actor->policy.distance = 500; - }*/ - else { - if (actor->xzDistToPlayer > 1500) { - return; - } + } + + else if (actor->play->sceneNum == 91 || actor->play->sceneNum == 69 || actor->play->sceneNum == 70) { + actor->policy.distance = 1000; + if (actor->xzDistToPlayer > 1000) { + return; } + } + /* if (actor->play->sceneNum <= 11) { + actor->policy.distance = 500; + }*/ + else { + if (actor->xzDistToPlayer > 1500) { + return; + } + } if (actor->sceneIndex == 85 || actor->sceneIndex == 91) { if (actor->play->sceneNum == 91 && gSaveContext.entranceIndex != 1504 && gSaveContext.entranceIndex != 1246) { return; } if (actor->play->sceneNum == 85 && actor->world.pos.y < 0) { - + ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_HORSE_RUN_LEVEL, false); } else { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_SARIA_MELODY, false); } - //kokiri forest and lost woods + // kokiri forest and lost woods } else if (actor->play->sceneNum >= 17 && actor->play->sceneNum <= 25) { return; // dont check for entrances while in boss rooms } else if (actor->sceneIndex == 81) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_HORSE_RUN_LEVEL, false); - //hyrule field - } else if (actor->sceneIndex == 10 && actor->play->sceneNum != 85) {//temp + // hyrule field + } else if (actor->sceneIndex == 10 && actor->play->sceneNum != 85) { // temp ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_OC_DOOR_OPEN, false); } else if (actor->sceneIndex <= 11) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_FANTOM_WARP_L, false); - //dungeons + // dungeons } else if (actor->sceneIndex >= 27 && actor->sceneIndex <= 29) { if (actor->play->sceneNum >= 32 && actor->play->sceneNum <= 34) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_HORSE_RUN_LEVEL, false); } else { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_SMALL_DOG_BARK, false); - } + } } else if (actor->sceneIndex >= 30 && actor->sceneIndex <= 33) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_SMALL_DOG_BARK, false); - //market sound + // market sound } else if ((actor->sceneIndex >= 34 && actor->sceneIndex <= 36) || actor->sceneIndex == 67) { if (actor->play->sceneNum == 67) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_SMALL_DOG_BARK, false); } else { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_STONE_BOUND, false); } - - //ToT sound + + // ToT sound } else if (actor->sceneIndex == 69 || actor->sceneIndex == 70) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_MUSI_SINK, false); } else if (actor->sceneIndex == 82) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_CHICKEN_CRY_M, false); - //kakariko sound + // kakariko sound } else if (actor->sceneIndex == 83) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_PO_APPEAR, false); - //graveyard sound - } else if (actor->sceneIndex == 84 || actor->sceneIndex == 88 || actor->sceneIndex == 89) { //last one is zora fountain maybe seperate? + // graveyard sound + } else if (actor->sceneIndex == 84 || actor->sceneIndex == 88 || + actor->sceneIndex == 89) { // last one is zora fountain maybe seperate? ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_RIVER_STREAM_S, false); - //zora sound - } else if (actor->sceneIndex == 86) {//might not need to exist - //forest medow sound + // zora sound + } else if (actor->sceneIndex == 86) { // might not need to exist + // forest medow sound } else if (actor->sceneIndex == 87) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_WATER_WALL, false); - //Lake Hylia sound - } else if (actor->sceneIndex == 90 || actor->sceneIndex == 93) { //gerudo valley and fortress + // Lake Hylia sound + } else if (actor->sceneIndex == 90 || actor->sceneIndex == 93) { // gerudo valley and fortress ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_GERUDOFT_BREATH, false); - //gerudo valley sound - } else if (actor->sceneIndex == 92 || actor->sceneIndex == 94) {//haunted wasteland and desert colosus + // gerudo valley sound + } else if (actor->sceneIndex == 92 || actor->sceneIndex == 94) { // haunted wasteland and desert colosus ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_SAND_STORM, false); - - } else if (actor->sceneIndex == 100 || actor->sceneIndex ==95) { + + } else if (actor->sceneIndex == 100 || actor->sceneIndex == 95) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_BRIDGE_OPEN, false); - //Hyrule Castle sound + // Hyrule Castle sound } else if (actor->sceneIndex == 96) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_DODO_K_ROLL, false); - //DMT sound + // DMT sound } else if (actor->sceneIndex == 97) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_DODO_K_LAVA, false); - //DMC sound + // DMC sound } else if (actor->sceneIndex == 98) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_DARUNIA_HIT_BREAST, false); - //Goron City + // Goron City } else if (actor->sceneIndex == 99) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_COW_CRY, false); - //Lon Lon + // Lon Lon } else if (actor->sceneIndex >= 17 && actor->sceneIndex <= 25) { - return;//boss rooms - } - else { + return; // boss rooms + } else { actor->policy.distance = 500; if (actor->play->sceneNum == 83) { actor->policy.ydist = 0; } ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_OC_DOOR_OPEN, false); - } } void accessible_231_dekus(AccessibleActor* actor) { - + if (actor->actor->params == 1) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_NUTS_FAINT, false); ActorAccessibility_SetSoundPitch(actor, 0, 1.0); @@ -455,7 +437,6 @@ void accessible_231_dekus(AccessibleActor* actor) { } else { return; } - } void accessible_hana(AccessibleActor* actor) { @@ -464,7 +445,6 @@ void accessible_hana(AccessibleActor* actor) { } else if (actor->actor->params == 0) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIG_UP, false); } - } void accessible_climable(AccessibleActor* actor) { @@ -482,35 +462,36 @@ void accessible_en_guard(AccessibleActor* actor) { f32 guardsfx = NA_SE_IT_SWORD_IMPACT; if (fabs(actor->actor->world.pos.x - player->actor.world.pos.x) > fabs(actor->actor->world.pos.z - player->actor.world.pos.z)) { - if (fabs(actor->actor->shape.rot.y - 16384) <1000) { if (actor->actor->world.pos.x < player->actor.world.pos.x) { - ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); - ActorAccessibility_SetSoundPitch(actor, 0, 2.0); - } else { - ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); - ActorAccessibility_SetSoundPitch(actor, 0, 0.2); - } - } else if ((actor->actor->shape.rot.y + 16384)<1000) { - if (actor->actor->world.pos.x < player->actor.world.pos.x) { - ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); - ActorAccessibility_SetSoundPitch(actor, 0, 0.2); - } else { - ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); - ActorAccessibility_SetSoundPitch(actor, 0, 2.0); - } - } else { - ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); - ActorAccessibility_SetSoundPitch(actor, 0, 1.0); - } - } else { - if (fabs(actor->actor->shape.rot.y) < 1000) { - if (actor->actor->world.pos.z < player->actor.world.pos.z) { + if (fabs(actor->actor->shape.rot.y - 16384) < 1000) { + if (actor->actor->world.pos.x < player->actor.world.pos.x) { ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); ActorAccessibility_SetSoundPitch(actor, 0, 2.0); } else { ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); ActorAccessibility_SetSoundPitch(actor, 0, 0.2); } - } else if (fabs(actor->actor->shape.rot.y+32768)<1000) { + } else if ((actor->actor->shape.rot.y + 16384) < 1000) { + if (actor->actor->world.pos.x < player->actor.world.pos.x) { + ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); + ActorAccessibility_SetSoundPitch(actor, 0, 0.2); + } else { + ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); + ActorAccessibility_SetSoundPitch(actor, 0, 2.0); + } + } else { + ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); + ActorAccessibility_SetSoundPitch(actor, 0, 1.0); + } + } else { + if (fabs(actor->actor->shape.rot.y) < 1000) { + if (actor->actor->world.pos.z < player->actor.world.pos.z) { + ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); + ActorAccessibility_SetSoundPitch(actor, 0, 2.0); + } else { + ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); + ActorAccessibility_SetSoundPitch(actor, 0, 0.2); + } + } else if (fabs(actor->actor->shape.rot.y + 32768) < 1000) { if (actor->actor->world.pos.z < player->actor.world.pos.z) { ActorAccessibility_PlaySoundForActor(actor, 0, guardsfx, false); ActorAccessibility_SetSoundPitch(actor, 0, 0.2); @@ -523,8 +504,6 @@ void accessible_en_guard(AccessibleActor* actor) { ActorAccessibility_SetSoundPitch(actor, 0, 1.0); } } - - } void accessible_en_dogs(AccessibleActor* actor) { @@ -533,22 +512,19 @@ void accessible_en_dogs(AccessibleActor* actor) { dog->actionFunc = EnDog_FollowPlayer; ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIAMOND_SWITCH, false); ActorAccessibility_SetSoundPitch(actor, 0, 1.0); - } if (actor->frameCount % 30 != 0) { return; } if (actor->actor->params == 608 || actor->actor->params == 336 || actor->actor->params == 304 || - actor->actor->params == 3088 || - actor->actor->params == 2576 || actor->actor->params <0) { + actor->actor->params == 3088 || actor->actor->params == 2576 || actor->actor->params < 0) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_SMALL_DOG_BARK, false); - + ActorAccessibility_SetSoundPitch(actor, 0, 2.0); } else { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_SMALL_DOG_BARK, false); ActorAccessibility_SetSoundPitch(actor, 0, 0.5); } - } void accessible_goma(AccessibleActor* actor) { @@ -562,19 +538,18 @@ void accessible_door_of_time(AccessibleActor* actor) { ActorAccessibility_PlaySampleForActor(actor, 0, "Chanting", false); ActorAccessibility_SetSoundPitch(actor, 0, 1.0); - //ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIAMOND_SWITCH, false); + // ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIAMOND_SWITCH, false); } void accessible_sticks(AccessibleActor* actor) { EnKarebaba* baba = (EnKarebaba*)actor->actor; - + if (baba->actionFunc != EnKarebaba_DeadItemDrop) return; if (actor->actor->flags == 80) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_NUTS_DAMAGE, false); } - } void accessible_graveyard_soil(AccessibleActor* actor) { @@ -583,7 +558,7 @@ void accessible_graveyard_soil(AccessibleActor* actor) { void accessible_cucco(AccessibleActor* actor) { if (actor->actor->params == 14) { - + } else if (actor->actor->params == 13) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_CHICKEN_CRY_N, false); ActorAccessibility_SetSoundPitch(actor, 0, 1.5); @@ -602,40 +577,31 @@ bool accessible_general_helper_init(AccessibleActor* actor) { actor->userData = data; return true; - } -void accessible_general_helper_cleanup(AccessibleActor* actor) -{ +void accessible_general_helper_cleanup(AccessibleActor* actor) { free(actor->userData); actor->userData = NULL; } -void accessible_va_general_helper(AccessibleActor* actor) -{ +void accessible_va_general_helper(AccessibleActor* actor) { GeneralHelperData* data = (GeneralHelperData*)actor->userData; - if (data->currentScene == actor->play->sceneNum && data->currentRoom != actor->play->roomCtx.curRoom.num) - { + if (data->currentScene == actor->play->sceneNum && data->currentRoom != actor->play->roomCtx.curRoom.num) { ActorAccessibility_AnnounceRoomNumber(actor->play); data->currentRoom = actor->play->roomCtx.curRoom.num; data->currentRoomClear = Flags_GetClear(actor->play, data->currentRoom); } - if (data->currentScene != actor->play->sceneNum) - { + if (data->currentScene != actor->play->sceneNum) { ActorAccessibility_InterpretCurrentScene(actor->play); data->currentScene = actor->play->sceneNum; data->currentRoom = actor->play->roomCtx.curRoom.num; data->currentRoomClear = Flags_GetClear(actor->play, data->currentRoom); - } -//Report when a room is completed. - if (!data->currentRoomClear && Flags_GetClear(actor->play, data->currentRoom)) - { + // Report when a room is completed. + if (!data->currentRoomClear && Flags_GetClear(actor->play, data->currentRoom)) { data->currentRoomClear = Flags_GetClear(actor->play, data->currentRoom); ActorAccessibility_AnnounceRoomNumber(actor->play); - } } -bool accessible_audio_compass_init(AccessibleActor* actor) -{ +bool accessible_audio_compass_init(AccessibleActor* actor) { AudioCompassData* data = (AudioCompassData*)malloc(sizeof(AudioCompassData)); if (data == NULL) return false; @@ -644,73 +610,68 @@ bool accessible_audio_compass_init(AccessibleActor* actor) actor->userData = data; return true; - } -void accessible_audio_compass_cleanup(AccessibleActor* actor) -{ +void accessible_audio_compass_cleanup(AccessibleActor* actor) { free(actor->userData); } void accessible_audio_compass(AccessibleActor* actor) { Player* player = GET_PLAYER(actor->play); if (player->stateFlags1 & PLAYER_STATE1_Z_TARGETING || player->stateFlags1 & PLAYER_STATE1_CLIMBING_LADDER) return; - OSContPad* trackerButtonsPressed = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + OSContPad* trackerButtonsPressed = + std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); AudioCompassData* data = (AudioCompassData*)actor->userData; bool compassCombo = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & buttonList[11] && trackerButtonsPressed[0].button & buttonList[6]; actor->world.pos = player->actor.world.pos; actor->world.pos.z -= 50; - if (data->framesUntilChime > 0) data->framesUntilChime--; if (compassCombo && data->framesUntilChime <= 0) { ActorAccessibility_PlaySoundForActor(actor, 0, actor->policy.sound, false); data->framesUntilChime = 30; - } - - - - /* Player* player = GET_PLAYER(actor->play); - if (player->stateFlags1 & PLAYER_STATE1_Z_TARGETING || player->stateFlags1 & PLAYER_STATE1_CLIMBING_LADDER) - return; - - actor->world.pos = player->actor.world.pos; - actor->world.pos.z -= 50; - bool shouldChime = false; - if (actor->world.rot.y != player->actor.world.rot.y) { - actor->world.rot.y = player->actor.world.rot.y; - if (player->linearVelocity == 0) - shouldChime = true; } - AudioCompassData* data = (AudioCompassData*)actor->userData; - if (data->linearVelocity == 0.0 && player->linearVelocity > 0.0) { - shouldChime = true; - } - data->linearVelocity = player->linearVelocity; - if (data->framesUntilChime > 0) - data->framesUntilChime--; - if (shouldChime && data->framesUntilChime <= 0) { + /* Player* player = GET_PLAYER(actor->play); +if (player->stateFlags1 & PLAYER_STATE1_Z_TARGETING || player->stateFlags1 & PLAYER_STATE1_CLIMBING_LADDER) + return; - ActorAccessibility_PlaySoundForActor(actor, 0, actor->policy.sound, false); - data->framesUntilChime = 10; +actor->world.pos = player->actor.world.pos; +actor->world.pos.z -= 50; +bool shouldChime = false; +if (actor->world.rot.y != player->actor.world.rot.y) { + actor->world.rot.y = player->actor.world.rot.y; + if (player->linearVelocity == 0) + shouldChime = true; +} +AudioCompassData* data = (AudioCompassData*)actor->userData; +if (data->linearVelocity == 0.0 && player->linearVelocity > 0.0) { + shouldChime = true; - }*/ +} +data->linearVelocity = player->linearVelocity; +if (data->framesUntilChime > 0) + data->framesUntilChime--; +if (shouldChime && data->framesUntilChime <= 0) { + ActorAccessibility_PlaySoundForActor(actor, 0, actor->policy.sound, false); + data->framesUntilChime = 10; + +}*/ } void accessible_stick_warning(AccessibleActor* actor) { Player* player = GET_PLAYER(actor->play); actor->world.pos = player->actor.world.pos; actor->world.pos.z -= 50; - if (fabs(player->unk_860 - 25) < 24.0 && player->heldItemId==0) { + if (fabs(player->unk_860 - 25) < 24.0 && player->heldItemId == 0) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_SY_WARNING_COUNT_N, false); } } - void ActorAccessibility_InitActors() { +void ActorAccessibility_InitActors() { const int Npc_Frames = 35; ActorAccessibilityPolicy policy; ActorAccessibility_InitPolicy(&policy, "Rock", accessible_en_ishi, 0); @@ -826,7 +787,7 @@ void accessible_stick_warning(AccessibleActor* actor) { policy.distance = 800; ActorAccessibility_AddSupportedActor(ACTOR_EN_KANBAN, policy); - //ACTOR_EN_A_OBJ has exactly the same configuration. + // ACTOR_EN_A_OBJ has exactly the same configuration. ActorAccessibility_AddSupportedActor(ACTOR_EN_A_OBJ, policy); ActorAccessibility_InitPolicy(&policy, "Large Crate", NULL, NA_SE_EV_WOODBOX_BREAK); ActorAccessibility_AddSupportedActor(ACTOR_OBJ_KIBAKO2, policy); @@ -867,7 +828,7 @@ void accessible_stick_warning(AccessibleActor* actor) { policy.distance = 2000; policy.pitch = 1.2; ActorAccessibility_AddSupportedActor(ACTOR_BG_YDAN_SP, policy); - + ActorAccessibility_InitPolicy(&policy, "Shutter Door", accessible_door, 0); policy.n = 30; policy.distance = 1000; @@ -881,7 +842,6 @@ void accessible_stick_warning(AccessibleActor* actor) { policy.n = 1; policy.ydist = 200; policy.pitch = 1.1; - ActorAccessibility_AddSupportedActor(ACTOR_OBJ_SWITCH, policy); ActorAccessibility_InitPolicy(&policy, "Ocarina Spots", NULL, NA_SE_EV_DIAMOND_SWITCH); @@ -902,14 +862,14 @@ void accessible_stick_warning(AccessibleActor* actor) { policy.distance = 800; ActorAccessibility_AddSupportedActor(ACTOR_OBJ_SYOKUDAI, policy); ActorAccessibility_InitPolicy(&policy, "Deku Tree Moving Platform", accessible_hasi, 0); - //policy.volume = 1.3; + // policy.volume = 1.3; policy.distance = 1000; ActorAccessibility_AddSupportedActor(ACTOR_BG_YDAN_HASI, policy); ActorAccessibility_InitPolicy(&policy, "Pot", NULL, NA_SE_EV_POT_BROKEN); ActorAccessibility_AddSupportedActor(ACTOR_OBJ_TSUBO, policy); - //ActorAccessibility_InitPolicy(&policy, "Deku Tree Entrance", NULL, NA_SE_EV_FANTOM_WARP_L); - //policy.distance = 5000; - //ActorAccessibility_AddSupportedActor(ACTOR_BG_TREEMOUTH, policy); + // ActorAccessibility_InitPolicy(&policy, "Deku Tree Entrance", NULL, NA_SE_EV_FANTOM_WARP_L); + // policy.distance = 5000; + // ActorAccessibility_AddSupportedActor(ACTOR_BG_TREEMOUTH, policy); ActorAccessibility_InitPolicy(&policy, "Platform collapsable", NULL, NA_SE_EV_BLOCK_SHAKE); ActorAccessibility_AddSupportedActor(ACTOR_OBJ_LIFT, policy); ActorAccessibility_InitPolicy(&policy, "Ladder in Slingshot Room", accessible_maruta, 0); @@ -964,29 +924,28 @@ void accessible_stick_warning(AccessibleActor* actor) { policy.distance = 2000; ActorAccessibility_AddSupportedActor(VA_CRAWLSPACE, policy); ActorAccessibility_InitPolicy(&policy, "Ladder/climable", accessible_climable, 0); - //policy.volume = 1.5; + // policy.volume = 1.5; policy.pitch = 1.3; - //policy.distance = 2000; + // policy.distance = 2000; ActorAccessibility_AddSupportedActor(VA_CLIMB, policy); ActorAccessibility_InitPolicy(&policy, "Door", NULL, NA_SE_OC_DOOR_OPEN); policy.n = 30; policy.pitch = 1.1; policy.distance = 1000; ActorAccessibility_AddSupportedActor(VA_DOOR, policy); - + ActorAccessibility_InitPolicy(&policy, "Area Change", accessible_area_change, 0); policy.n = 60; policy.distance = 100000; ActorAccessibility_AddSupportedActor(VA_AREA_CHANGE, policy); - ActorAccessibility_InitPolicy(&policy, "marker", NULL, - NA_SE_EV_DIAMOND_SWITCH); + ActorAccessibility_InitPolicy(&policy, "marker", NULL, NA_SE_EV_DIAMOND_SWITCH); policy.distance = 1000; policy.pitch = 1.7; ActorAccessibility_AddSupportedActor(VA_MARKER, policy); - //ActorAccessibility_InitPolicy(&policy, "Spike", NULL, NA_SE_EV_DIAMOND_SWITCH); - //policy.distance = 200; - //policy.pitch = 0.5; - //ActorAccessibility_AddSupportedActor(VA_SPIKE, policy); + // ActorAccessibility_InitPolicy(&policy, "Spike", NULL, NA_SE_EV_DIAMOND_SWITCH); + // policy.distance = 200; + // policy.pitch = 0.5; + // ActorAccessibility_AddSupportedActor(VA_SPIKE, policy); ActorAccessibility_InitPolicy(&policy, "Stick Burnout Warning", accessible_stick_warning, 0); policy.n = 1; policy.runsAlways = true; @@ -1002,27 +961,27 @@ void accessible_stick_warning(AccessibleActor* actor) { policy.cleanupUserData = accessible_audio_compass_cleanup; policy.initUserData = accessible_audio_compass_init; policy.runsAlways = true; - policy.sound = NA_SE_EV_SHIP_BELL;//Setting this here so it's easy to change if we ever decide to change it. + policy.sound = NA_SE_EV_SHIP_BELL; // Setting this here so it's easy to change if we ever decide to change it. policy.pitch = 0.5; - ActorAccessibility_AddSupportedActor(VA_AUDIO_COMPASS, policy); // Now query a list of virtual actors for a given - // location (scene - // and room - // number). - VirtualActorList* list = (VirtualActorList*)ActorAccessibility_GetVirtualActorList(EVERYWHERE, 0);//Global/ omnipresent. + // location (scene + // and room + // number). + VirtualActorList* list = + (VirtualActorList*)ActorAccessibility_GetVirtualActorList(EVERYWHERE, 0); // Global/ omnipresent. // Now place the actor. ActorAccessibility_AddVirtualActor(list, VA_GENERAL_HELPER, { { 0.0, 0.0, 0.0 }, { 0, 0, 0 } }); - ActorAccessibility_AddVirtualActor(list, VA_AUDIO_COMPASS, { { 0.0, 0.0, 0.0}, { 0, 0, 0 } }); + ActorAccessibility_AddVirtualActor(list, VA_AUDIO_COMPASS, { { 0.0, 0.0, 0.0 }, { 0, 0, 0 } }); ActorAccessibility_AddVirtualActor(list, VA_STICK_WARNING, { { 0.0, 0.0, 0.0 }, { 0, 0, 0 } }); list = ActorAccessibility_GetVirtualActorList(85, 0); // Kokiri Forest ActorAccessibility_AddVirtualActor(list, VA_CRAWLSPACE, { { -784.0, 120.0, 1046.00 }, { 0, 14702, 0 } }); ActorAccessibility_AddVirtualActor(list, VA_MARKER, { { 2146.5, 1.0, -142.8 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -547.0, 60.0, -1036.00 }, { 0, 14702, 0 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -29.0, -80.0, 983.00 }, { 0, 14702, 0 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -547.0, 60.0, -1036.00 }, { 0, 14702, 0 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -29.0, -80.0, 983.00 }, { 0, 14702, 0 } }); /*ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { -448.0, 0.0, -528.00 }, { 0, 14702, 0 } }); ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { -1082.0, 120.0, 383.00 }, { 0, 14702, 0 } }); ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { -27.0, 100.0, 1117.00 }, { 0, 14702, 0 } }); @@ -1030,50 +989,52 @@ void accessible_stick_warning(AccessibleActor* actor) { ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 1046.0, 0.0, 549.00 }, { 0, 14702, 0 } }); ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 848.0, 0.0, -323.00 }, { 0, 14702, 0 } }); */ - //ActorAccessibility_AddVirtualActor(list, VA_AREA_CHANGE,{ { -317.0, 373.2, -1542.00 }, {0, 14702, 0 }}, AREA_KORIRI); - - //ActorAccessibility_AddVirtualActor(list, VA_AREA_CHANGE, { { -1380.0, -67.0, -288.00 }, { 0, 14702, 0 } }, AREA_HYRULE_FIELD); + // ActorAccessibility_AddVirtualActor(list, VA_AREA_CHANGE,{ { -317.0, 373.2, -1542.00 }, {0, 14702, 0 }}, + // AREA_KORIRI); + + // ActorAccessibility_AddVirtualActor(list, VA_AREA_CHANGE, { { -1380.0, -67.0, -288.00 }, { 0, 14702, 0 } }, + // AREA_HYRULE_FIELD); list = ActorAccessibility_GetVirtualActorList(85, 2); // Kokiri Forest Room with boulder and kokiri sword ActorAccessibility_AddVirtualActor(list, VA_CRAWLSPACE, { { -788.0, 120.0, 1392.00 }, { 0, 14702, 0 } }); - //list = ActorAccessibility_GetVirtualActorList(38, 0); //know-it-all house - //ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 12.0, 0.0, -131.00 }, { 0, 14702, 0 } }); + // list = ActorAccessibility_GetVirtualActorList(38, 0); //know-it-all house + // ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 12.0, 0.0, -131.00 }, { 0, 14702, 0 } }); - //list = ActorAccessibility_GetVirtualActorList(40, 0); // mido house - //ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { -6.6, 0.0, -179.00 }, { 0, 14702, 0 } }); + // list = ActorAccessibility_GetVirtualActorList(40, 0); // mido house + // ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { -6.6, 0.0, -179.00 }, { 0, 14702, 0 } }); - //list = ActorAccessibility_GetVirtualActorList(52, 0); // link's house - //ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 2.3, 0.0, -134.00 }, { 0, 14702, 0 } }); + // list = ActorAccessibility_GetVirtualActorList(52, 0); // link's house + // ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 2.3, 0.0, -134.00 }, { 0, 14702, 0 } }); - //list = ActorAccessibility_GetVirtualActorList(41, 0); // saria's house - //ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 1.7, 0.0, -188.00 }, { 0, 14702, 0 } }); + // list = ActorAccessibility_GetVirtualActorList(41, 0); // saria's house + // ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 1.7, 0.0, -188.00 }, { 0, 14702, 0 } }); - //list = ActorAccessibility_GetVirtualActorList(39, 0); // twins house - //ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 3.0, 0.0, -179.00 }, { 0, 14702, 0 } }); + // list = ActorAccessibility_GetVirtualActorList(39, 0); // twins house + // ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 3.0, 0.0, -179.00 }, { 0, 14702, 0 } }); - //list = ActorAccessibility_GetVirtualActorList(45, 0); // Kokiri Shop - //ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 0.0, 0.0, 150.00 }, { 0, 14702, 0 } }); + // list = ActorAccessibility_GetVirtualActorList(45, 0); // Kokiri Shop + // ActorAccessibility_AddVirtualActor(list, VA_DOOR, { { 0.0, 0.0, 150.00 }, { 0, 14702, 0 } }); - list = ActorAccessibility_GetVirtualActorList(0, 0);//deku tree main room - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -226.7, 0, 197.0 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 118.6, 0, -286.6 } }); + list = ActorAccessibility_GetVirtualActorList(0, 0); // deku tree main room + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -226.7, 0, 197.0 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 118.6, 0, -286.6 } }); - //ActorAccessibility_AddVirtualActor(list, VA_AREA_CHANGE, { {0, 0, 640} }, AREA_KORIRI); - - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 287.4, 368.0, 347.0 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 419.4, 368.0, 173.6 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 323, 567.0, 314.6 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 127.5, 897.0, 433.6 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 440.9, 897.0, 101.6 } }); + // ActorAccessibility_AddVirtualActor(list, VA_AREA_CHANGE, { {0, 0, 640} }, AREA_KORIRI); + + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 287.4, 368.0, 347.0 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 419.4, 368.0, 173.6 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 323, 567.0, 314.6 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 127.5, 897.0, 433.6 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 440.9, 897.0, 101.6 } }); list = ActorAccessibility_GetVirtualActorList(0, 2); // deku tree slingshot room - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -1159, 288.0, 1403.0 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -1179.6, 480.0, 1463.6 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -1398.9, 288.0, 1161.6 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -1159, 288.0, 1403.0 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -1179.6, 480.0, 1463.6 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -1398.9, 288.0, 1161.6 } }); list = ActorAccessibility_GetVirtualActorList(0, 10); // deku tree compass room - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -762, 733.0, 151.0 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -762, 733.0, 151.0 } }); /*ActorAccessibility_AddVirtualActor(list, VA_MARKER, { { -935, 780.0, -113 } }); ActorAccessibility_AddVirtualActor(list, VA_MARKER, { { -1031.0, 800.0, 109.7 } }); ActorAccessibility_AddVirtualActor(list, VA_MARKER, { { -1184, 820.0, -103.4 } });*/ @@ -1084,14 +1045,14 @@ void accessible_stick_warning(AccessibleActor* actor) { list = ActorAccessibility_GetVirtualActorList(0, 3); // deku tree basement 1 lobby ActorAccessibility_AddVirtualActor(list, VA_CRAWLSPACE, { { -901, -820.0, 0.5 } }); ActorAccessibility_AddVirtualActor(list, VA_MARKER, { { -181.761, -905.0, -28.3 } }); - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 108, -919.5, 5.0 } }); + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { 108, -919.5, 5.0 } }); list = ActorAccessibility_GetVirtualActorList(0, 9); // deku tree b2 lobby - //ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -639, -1912.5, 188.0 } }); - //Install cues for walls, ledges etc. - list = ActorAccessibility_GetVirtualActorList(1, 2);//dodongo bombflower stairs room + // ActorAccessibility_AddVirtualActor(list, VA_CLIMB, { { -639, -1912.5, 188.0 } }); + // Install cues for walls, ledges etc. + list = ActorAccessibility_GetVirtualActorList(1, 2); // dodongo bombflower stairs room ActorAccessibility_AddVirtualActor(list, VA_MARKER, { { -1958, 20, -1297 } }); - list = ActorAccessibility_GetVirtualActorList(69, 0);//hyrule courtyard + list = ActorAccessibility_GetVirtualActorList(69, 0); // hyrule courtyard ActorAccessibility_AddVirtualActor(list, VA_MARKER, { { 1734.0, 0.0, 140.514 } }); AccessibleActor* temp = ActorAccessibility_AddVirtualActor(list, VA_MARKER, { { 1734.0, 0.0, 140.514 } }); temp->policy.pitch = 0.3; @@ -1117,5 +1078,4 @@ void accessible_stick_warning(AccessibleActor* actor) { temp->policy.pitch = 1.8; temp->policy.volume = 0.5; ActorAccessibility_InitCues(); - } diff --git a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp index 9b55fe6f7..973e56578 100644 --- a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp +++ b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.cpp @@ -7,11 +7,11 @@ #define AAE_MAX_BUFFER_SIZE AAE_SAMPLE_RATE / 10 #define AAE_PREP_CHUNK_SIZE 64 #define AAE_MIX_CHUNK_SIZE 64 -#define AAE_GC_INTERVAL 20 * 60//How often, in frames, do we clean up sound handles that are no longer active. +#define AAE_GC_INTERVAL 20 * 60 // How often, in frames, do we clean up sound handles that are no longer active. #define AAE_MAX_DB_REDUCTION -20 #define AAE_LPF_ORDER 4 -#define NOMINMAX//because Windows is a joke. +#define NOMINMAX // because Windows is a joke. #include "AccessibleAudioEngine.h" extern "C" { @@ -25,25 +25,25 @@ enum AAE_COMMANDS { AAE_STOP, AAE_STOP_ALL, AAE_PITCH, - AAE_PITCH_BEHIND,//Specify how much to change the pitch when the sound is behind the listener. + AAE_PITCH_BEHIND, // Specify how much to change the pitch when the sound is behind the listener. AAE_VOLUME, AAE_PAN, AAE_FILTER, -AAE_SEEK, - AAE_LISTENER, //Set the listener's position and direction. -AAE_POS,//Set the sound source's position and direction. -AAE_PREPARE, -AAE_TERMINATE, + AAE_SEEK, + AAE_LISTENER, // Set the listener's position and direction. + AAE_POS, // Set the sound source's position and direction. + AAE_PREPARE, + AAE_TERMINATE, }; typedef float f32; typedef int8_t s8; typedef uint8_t u8; -//Processing for our custom audio positioning. +// Processing for our custom audio positioning. static float lerp_aae(float x, float y, float z) { return (1.0 - z) * x + z * y; } - static float computeGain(SoundExtras * extras) { +static float computeGain(SoundExtras* extras) { if (extras->maxDistance == 0) return 0; float leftover = ma_volume_db_to_linear(AAE_MAX_DB_REDUCTION); @@ -53,23 +53,24 @@ static float lerp_aae(float x, float y, float z) { gain -= lerp_aae(0, leftover, normDist); return gain; } - //Borrow the pan calculation from the game itself. Todo: this is technical debt, so copy/ revise it or something at some point. - extern "C" int8_t Audio_ComputeSoundPanSigned(float x, float z, uint8_t token); - static void positioner_process_pcm_frames(ma_node * pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, - float** ppFramesOut, - ma_uint32* pFrameCountOut) -{ +// Borrow the pan calculation from the game itself. Todo: this is technical debt, so copy/ revise it or something at +// some point. +extern "C" int8_t Audio_ComputeSoundPanSigned(float x, float z, uint8_t token); +static void positioner_process_pcm_frames(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, + float** ppFramesOut, ma_uint32* pFrameCountOut) { const float* framesIn = ppFramesIn[0]; float* framesOut = ppFramesOut[0]; ma_copy_pcm_frames(framesOut, framesIn, *pFrameCountIn, ma_format_f32, 2); *pFrameCountOut = *pFrameCountIn; SoundExtras* extras = (SoundExtras*)pNode; -//Pan the sound based on its projected position. + // Pan the sound based on its projected position. float pan; -//Use the game's panning mechanism, which returns a signed 8-bit integer between 0 (far-left) and 127 (far-right). -//It would appear that the correct thing to do is interpret this value as a gain factor in decibels. In practice, values below 38 or above 90 are never seen, so a sound that's panned far to one side or the other amounts to about -25DB worth of attenuation. - //Also: lie about the value of Z and give it a constant value to prevent weird behaviour when Z is far away. + // Use the game's panning mechanism, which returns a signed 8-bit integer between 0 (far-left) and 127 (far-right). + // It would appear that the correct thing to do is interpret this value as a gain factor in decibels. In practice, + // values below 38 or above 90 are never seen, so a sound that's panned far to one side or the other amounts to + // about -25DB worth of attenuation. Also: lie about the value of Z and give it a constant value to prevent weird + // behaviour when Z is far away. s8 panSigned = Audio_ComputeSoundPanSigned(extras->x, extras->z, 4); int db; if (panSigned < 64) @@ -82,36 +83,38 @@ static float lerp_aae(float x, float y, float z) { ma_panner_set_pan(&extras->panner, pan); ma_panner_process_pcm_frames(&extras->panner, framesOut, framesOut, *pFrameCountIn); - //Next we'll apply the gain based on the object's distance relationship to the player. The strategy here is to use a combination of decibel-based and linear attenuation, so that the gain reaches 0 at the exact point when the object is at exactly the maximum distance from the player. + // Next we'll apply the gain based on the object's distance relationship to the player. The strategy here is to use + // a combination of decibel-based and linear attenuation, so that the gain reaches 0 at the exact point when the + // object is at exactly the maximum distance from the player. float gain = computeGain(extras); ma_gainer_set_gain(&extras->gainer, gain); ma_gainer_process_pcm_frames(&extras->gainer, framesOut, framesOut, *pFrameCountIn); -//Run LPF only when necessary because we can't afford to run a 4th-order lowpass on every single sound. This probably causes minor glitches when the filter switches on and off. Todo: cross that bridge. + // Run LPF only when necessary because we can't afford to run a 4th-order lowpass on every single sound. This + // probably causes minor glitches when the filter switches on and off. Todo: cross that bridge. if (extras->cutoff != 1.0) - ma_lpf_process_pcm_frames(&extras->filter, framesOut, framesOut, *pFrameCountIn); - } + ma_lpf_process_pcm_frames(&extras->filter, framesOut, framesOut, *pFrameCountIn); +} -static ma_node_vtable positioner_vtable = { -positioner_process_pcm_frames, NULL, 1, 1, 0}; +static ma_node_vtable positioner_vtable = { positioner_process_pcm_frames, NULL, 1, 1, 0 }; static ma_uint32 positioner_channels[1] = { 2 }; - void AccessibleAudioEngine::destroy() { - switch (initialized){ - case 3: +void AccessibleAudioEngine::destroy() { + switch (initialized) { + case 3: ma_engine_uninit(&engine); case 2: ma_pcm_rb_uninit(&preparedOutput); case 1: ma_resource_manager_uninit(&resourceManager); - } - } + } +} void AccessibleAudioEngine::destroyAndThrow(const char* exceptionText) { destroy(); -throw std::runtime_error(exceptionText); + throw std::runtime_error(exceptionText); } - uint32_t AccessibleAudioEngine::retrieve(float* buffer, uint32_t nFrames) { +uint32_t AccessibleAudioEngine::retrieve(float* buffer, uint32_t nFrames) { uint32_t framesAvailable = ma_pcm_rb_available_read(&preparedOutput); if (nFrames > framesAvailable) nFrames = framesAvailable; @@ -128,16 +131,13 @@ throw std::runtime_error(exceptionText); memcpy(buffer, readBuffer, sizeof(float) * framesObtained * AAE_CHANNELS); buffer += framesObtained * AAE_CHANNELS; -nFrames -= framesObtained; + nFrames -= framesObtained; ma_pcm_rb_commit_read(&preparedOutput, framesObtained); - } return ogNFrames; - } -void AccessibleAudioEngine::doPrepare(SoundAction& action) -{ +void AccessibleAudioEngine::doPrepare(SoundAction& action) { framesUntilGC--; int nFrames = ma_pcm_rb_available_write(&preparedOutput); if (nFrames <= 0) @@ -145,19 +145,19 @@ void AccessibleAudioEngine::doPrepare(SoundAction& action) float* chunk; while (nFrames > 0) { - //This should not loop more than twice. + // This should not loop more than twice. uint32_t nextChunk = nFrames; - ma_pcm_rb_acquire_write(&preparedOutput, &nextChunk, (void**)&chunk);//Might reduce nextChunk if there isn't enough buffer space available to accommodate the request. + ma_pcm_rb_acquire_write(&preparedOutput, &nextChunk, + (void**)&chunk); // Might reduce nextChunk if there isn't enough buffer space available + // to accommodate the request. ma_uint64 framesRead = 0; ma_engine_read_pcm_frames(&engine, chunk, nextChunk, &framesRead); - //Even if we get fewer frames than expected, we should still submit a full buffer of silence. + // Even if we get fewer frames than expected, we should still submit a full buffer of silence. if (framesRead < nextChunk) ma_silence_pcm_frames(chunk + (framesRead * 2), (nextChunk - framesRead), ma_format_f32, 2); - ma_pcm_rb_commit_write(&preparedOutput, (uint32_t) nextChunk); + ma_pcm_rb_commit_write(&preparedOutput, (uint32_t)nextChunk); nFrames -= nextChunk; - } - } int AccessibleAudioEngine::getSoundActions(SoundAction* dest, int limit) { std::unique_lock lock(mtx); @@ -171,9 +171,8 @@ int AccessibleAudioEngine::getSoundActions(SoundAction* dest, int limit) { limit--; } return actionsOut; - } -void AccessibleAudioEngine::postSoundActions(){ +void AccessibleAudioEngine::postSoundActions() { { std::scoped_lock lock(mtx); for (int i = 0; i < nextOutgoingSoundAction; i++) @@ -187,284 +186,263 @@ void AccessibleAudioEngine::postHighPrioritySoundAction(SoundAction& action) { soundActions.push_front(action); cv.notify_one(); } - SoundAction& AccessibleAudioEngine::getNextOutgoingSoundAction() { +SoundAction& AccessibleAudioEngine::getNextOutgoingSoundAction() { if (nextOutgoingSoundAction >= AAE_SOUND_ACTION_BATCH_SIZE) postSoundActions(); nextOutgoingSoundAction++; return outgoingSoundActions[nextOutgoingSoundAction - 1]; - } - void AccessibleAudioEngine::runThread() { +} +void AccessibleAudioEngine::runThread() { bool shouldTerminate = false; - SoundAction incomingSoundActions[AAE_SOUND_ACTION_BATCH_SIZE]; - while (true) { + SoundAction incomingSoundActions[AAE_SOUND_ACTION_BATCH_SIZE]; + while (true) { processAudioJobs(); - if (framesUntilGC <= 0) - garbageCollect(); + if (framesUntilGC <= 0) + garbageCollect(); - int batchSize = getSoundActions(incomingSoundActions, AAE_SOUND_ACTION_BATCH_SIZE); - for (int i = 0; i < batchSize; i++) { - SoundAction& action = incomingSoundActions[i]; - switch (action.command) { - case AAE_TERMINATE: - return; - case AAE_START: - doPlaySound(action); - break; - case AAE_STOP: - doStopSound(action); - break; - case AAE_STOP_ALL: - doStopAllSounds(action); - break; + int batchSize = getSoundActions(incomingSoundActions, AAE_SOUND_ACTION_BATCH_SIZE); + for (int i = 0; i < batchSize; i++) { + SoundAction& action = incomingSoundActions[i]; + switch (action.command) { + case AAE_TERMINATE: + return; + case AAE_START: + doPlaySound(action); + break; + case AAE_STOP: + doStopSound(action); + break; + case AAE_STOP_ALL: + doStopAllSounds(action); + break; - case AAE_PITCH: - doSetPitch(action); - break; - case AAE_PITCH_BEHIND: - doSetPitchBehindModifier(action); - break; - case AAE_VOLUME: - doSetVolume(action); - break; - case AAE_PAN: - doSetPan(action); - break; - case AAE_FILTER: - doSetFilter(action); - break; - case AAE_SEEK: - doSeekSound(action); - break; - case AAE_LISTENER: - doSetListenerPos(action); - break; - case AAE_POS: - doSetSoundPos(action); - break; + case AAE_PITCH: + doSetPitch(action); + break; + case AAE_PITCH_BEHIND: + doSetPitchBehindModifier(action); + break; + case AAE_VOLUME: + doSetVolume(action); + break; + case AAE_PAN: + doSetPan(action); + break; + case AAE_FILTER: + doSetFilter(action); + break; + case AAE_SEEK: + doSeekSound(action); + break; + case AAE_LISTENER: + doSetListenerPos(action); + break; + case AAE_POS: + doSetSoundPos(action); + break; - case AAE_PREPARE: - doPrepare(action); - break; - - } + case AAE_PREPARE: + doPrepare(action); + break; } - + } } } - SoundSlot* AccessibleAudioEngine::findSound(SoundAction& action) - { +SoundSlot* AccessibleAudioEngine::findSound(SoundAction& action) { if (action.slot < 0 || action.slot >= AAE_SLOTS_PER_HANDLE) - return NULL; + return NULL; auto i = sounds.find(action.handle); if (i == sounds.end()) - return NULL; + return NULL; SoundSlot& target = i->second[action.slot]; if (!target.active) - return NULL; + return NULL; return ⌖ - - } - void AccessibleAudioEngine::doPlaySound(SoundAction& action) { +} +void AccessibleAudioEngine::doPlaySound(SoundAction& action) { SoundSlot* sound; if (sounds.contains(action.handle)) { - sound = &sounds[action.handle][action.slot]; - if (sound->active) { - ma_sound_stop(&sound->sound); - destroySound(sound); - } + sound = &sounds[action.handle][action.slot]; + if (sound->active) { + ma_sound_stop(&sound->sound); + destroySound(sound); + } } else { SoundSlots temp; for (int i = 0; i < AAE_SLOTS_PER_HANDLE; i++) - temp[i].active = false; - - sounds[action.handle] = temp; + temp[i].active = false; + + sounds[action.handle] = temp; sound = &sounds[action.handle][action.slot]; } - if (ma_sound_init_from_file(&engine, action.path.c_str(), MA_SOUND_FLAG_NO_SPATIALIZATION|MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT, NULL, NULL, + if (ma_sound_init_from_file(&engine, action.path.c_str(), + MA_SOUND_FLAG_NO_SPATIALIZATION | MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT, NULL, NULL, &sound->sound) != MA_SUCCESS) - return; + return; initSoundExtras(sound); - ma_sound_set_looping(&sound->sound, action.looping); - //We actually attach the extras to the engine, not the sound itself. - ma_node_attach_output_bus(&sound->extras, 0, ma_node_graph_get_endpoint(&engine.nodeGraph), 0); + ma_sound_set_looping(&sound->sound, action.looping); + // We actually attach the extras to the engine, not the sound itself. + ma_node_attach_output_bus(&sound->extras, 0, ma_node_graph_get_endpoint(&engine.nodeGraph), 0); - ma_sound_start(&sound->sound); + ma_sound_start(&sound->sound); - sound->active = true; + sound->active = true; +} +void AccessibleAudioEngine::doStopSound(SoundAction& action) { + SoundSlot* slot = findSound(action); + if (slot == NULL) + return; + destroySound(slot); +} +void AccessibleAudioEngine::doStopAllSounds(SoundAction& action) { + auto it = sounds.find(action.handle); + if (it == sounds.end()) + return; + SoundSlots& slots = it->second; + for (int i = 0; i < AAE_SLOTS_PER_HANDLE; i++) { + if (slots[i].active) + destroySound(&slots[i]); } - void AccessibleAudioEngine::doStopSound(SoundAction& action) { - SoundSlot* slot = findSound(action); - if (slot == NULL) - return; - destroySound(slot); - } - void AccessibleAudioEngine::doStopAllSounds(SoundAction& action) - { - auto it = sounds.find(action.handle); - if (it == sounds.end()) - return; - SoundSlots& slots = it->second; - for (int i = 0; i < AAE_SLOTS_PER_HANDLE; i++) - { - if (slots[i].active) - destroySound(&slots[i]); - } - sounds.erase(it); + sounds.erase(it); +} +void AccessibleAudioEngine::doSetPitch(SoundAction& action) { + SoundSlot* slot = findSound(action); + if (slot == NULL) + return; + slot->extras.pitch = action.pitch; + float pitch = action.pitch; + if (slot->extras.z < 0) + pitch *= (1.0 - slot->extras.pitchBehindModifier); + ma_sound_set_pitch(&slot->sound, pitch); +} - } - void AccessibleAudioEngine::doSetPitch(SoundAction& action) - { - SoundSlot* slot = findSound(action); - if (slot == NULL) - return; - slot->extras.pitch = action.pitch; - float pitch = action.pitch; - if (slot->extras.z < 0) - pitch *= (1.0 - slot->extras.pitchBehindModifier); - ma_sound_set_pitch(&slot->sound, pitch); - - } - - void AccessibleAudioEngine::doSetPitchBehindModifier(SoundAction& action) - { - SoundSlot* slot = findSound(action); - if (slot == NULL) - return; - slot->extras.pitchBehindModifier = action.pitch; - } - void AccessibleAudioEngine::doSetVolume(SoundAction& action) - { - SoundSlot* slot = findSound(action); - if (slot == NULL) - return; - ma_sound_set_volume(&slot->sound, action.pitch); - - } - void AccessibleAudioEngine::doSetPan(SoundAction& action) - { - SoundSlot* slot = findSound(action); - if (slot == NULL) - return; - ma_sound_set_pan(&slot->sound, action.pan); - } - void AccessibleAudioEngine::doSetFilter(SoundAction& action) - { - SoundSlot* slot = findSound(action); - if (slot == NULL) - return; - slot->extras.cutoff = action.cutoff; - ma_lpf_config config = - ma_lpf_config_init(ma_format_f32, AAE_CHANNELS, AAE_SAMPLE_RATE, lerp_aae(0.0, AAE_SAMPLE_RATE / 2, action.cutoff), AAE_LPF_ORDER); - ma_lpf_reinit(&config, &slot->extras.filter); - - } - void AccessibleAudioEngine::doSeekSound(SoundAction& action) - { - SoundSlot* slot = findSound(action); - if (slot == NULL) - return; - ma_sound_seek_to_pcm_frame(&slot->sound, action.offset); - } - void AccessibleAudioEngine::doSetListenerPos(SoundAction& action) - { - - } - void AccessibleAudioEngine::doSetSoundPos(SoundAction& action) - { - SoundSlot* slot = findSound(action); - if (slot == NULL) - return; - slot->extras.x = action.posX; - slot->extras.y = action.posY; - slot->extras.z = action.posZ; - slot->extras.distToPlayer = action.distToPlayer; - slot->extras.maxDistance = action.maxDistance; - float pitch = slot->extras.pitch; - if (action.posZ < 0) - pitch *= (1.0 - slot->extras.pitchBehindModifier); - ma_sound_set_pitch(&slot->sound, pitch); - } - void AccessibleAudioEngine::garbageCollect() - { - for (auto i = sounds.begin(); i != sounds.end(); ) { - int deadSlots = 0; - for (int x = 0; x < AAE_SLOTS_PER_HANDLE; x++) { - if (!i->second[x].active) - deadSlots++; - else if (!ma_sound_is_playing(&i->second[x].sound)) { - destroySound(&i->second[x]); - i->second[x].active = false; - deadSlots++; - - } +void AccessibleAudioEngine::doSetPitchBehindModifier(SoundAction& action) { + SoundSlot* slot = findSound(action); + if (slot == NULL) + return; + slot->extras.pitchBehindModifier = action.pitch; +} +void AccessibleAudioEngine::doSetVolume(SoundAction& action) { + SoundSlot* slot = findSound(action); + if (slot == NULL) + return; + ma_sound_set_volume(&slot->sound, action.pitch); +} +void AccessibleAudioEngine::doSetPan(SoundAction& action) { + SoundSlot* slot = findSound(action); + if (slot == NULL) + return; + ma_sound_set_pan(&slot->sound, action.pan); +} +void AccessibleAudioEngine::doSetFilter(SoundAction& action) { + SoundSlot* slot = findSound(action); + if (slot == NULL) + return; + slot->extras.cutoff = action.cutoff; + ma_lpf_config config = ma_lpf_config_init(ma_format_f32, AAE_CHANNELS, AAE_SAMPLE_RATE, + lerp_aae(0.0, AAE_SAMPLE_RATE / 2, action.cutoff), AAE_LPF_ORDER); + ma_lpf_reinit(&config, &slot->extras.filter); +} +void AccessibleAudioEngine::doSeekSound(SoundAction& action) { + SoundSlot* slot = findSound(action); + if (slot == NULL) + return; + ma_sound_seek_to_pcm_frame(&slot->sound, action.offset); +} +void AccessibleAudioEngine::doSetListenerPos(SoundAction& action) { +} +void AccessibleAudioEngine::doSetSoundPos(SoundAction& action) { + SoundSlot* slot = findSound(action); + if (slot == NULL) + return; + slot->extras.x = action.posX; + slot->extras.y = action.posY; + slot->extras.z = action.posZ; + slot->extras.distToPlayer = action.distToPlayer; + slot->extras.maxDistance = action.maxDistance; + float pitch = slot->extras.pitch; + if (action.posZ < 0) + pitch *= (1.0 - slot->extras.pitchBehindModifier); + ma_sound_set_pitch(&slot->sound, pitch); +} +void AccessibleAudioEngine::garbageCollect() { + for (auto i = sounds.begin(); i != sounds.end();) { + int deadSlots = 0; + for (int x = 0; x < AAE_SLOTS_PER_HANDLE; x++) { + if (!i->second[x].active) + deadSlots++; + else if (!ma_sound_is_playing(&i->second[x].sound)) { + destroySound(&i->second[x]); + i->second[x].active = false; + deadSlots++; } - if (deadSlots == AAE_SLOTS_PER_HANDLE) // Entire batch is garbage. - i = sounds.erase(i); - else - i++; } - framesUntilGC = AAE_GC_INTERVAL; + if (deadSlots == AAE_SLOTS_PER_HANDLE) // Entire batch is garbage. + i = sounds.erase(i); + else + i++; } - void AccessibleAudioEngine::processAudioJobs() - { - ma_job job; - while (ma_resource_manager_next_job(&resourceManager, &job) == MA_SUCCESS) - ma_job_process(&job); + framesUntilGC = AAE_GC_INTERVAL; +} +void AccessibleAudioEngine::processAudioJobs() { + ma_job job; + while (ma_resource_manager_next_job(&resourceManager, &job) == MA_SUCCESS) + ma_job_process(&job); +} +bool AccessibleAudioEngine::initSoundExtras(SoundSlot* slot) { + ma_node_config config = ma_node_config_init(); + config.inputBusCount = 1; + config.outputBusCount = 1; + config.pInputChannels = positioner_channels; + config.pOutputChannels = positioner_channels; + config.vtable = &positioner_vtable; + memset(&slot->extras, 0, sizeof(SoundExtras)); + if (ma_node_init(&engine.nodeGraph, &config, NULL, &slot->extras) != MA_SUCCESS) + return false; + ma_panner_config pc = ma_panner_config_init(ma_format_f32, AAE_CHANNELS); + pc.mode = ma_pan_mode_balance; + ma_panner_init(&pc, &slot->extras.panner); + ma_gainer_config gc = ma_gainer_config_init( + AAE_CHANNELS, + AAE_SAMPLE_RATE / 20); // Allow one in-game frame for the gain to work its way towards the target value. + if (ma_gainer_init(&gc, NULL, &slot->extras.gainer) != MA_SUCCESS) + return false; + ma_lpf_config fc = + ma_lpf_config_init(ma_format_f32, AAE_CHANNELS, AAE_SAMPLE_RATE, AAE_SAMPLE_RATE / 2, AAE_LPF_ORDER); + ma_lpf_init(&fc, NULL, &slot->extras.filter); + slot->extras.cutoff = 1.0f; + slot->extras.pitch = 1.0f; + slot->extras.pitchBehindModifier = 0.0f; + // ma_node_attach_output_bus(&slot->sound, 0, &slot->extras.filter, 0); + ma_node_attach_output_bus(&slot->sound, 0, &slot->extras, 0); + return true; +} +void AccessibleAudioEngine::destroySound(SoundSlot* slot) { + ma_node_detach_all_output_buses(&slot->extras); + ma_sound_uninit(&slot->sound); + ma_gainer_uninit(&slot->extras.gainer, NULL); - } - bool AccessibleAudioEngine::initSoundExtras(SoundSlot* slot) { - ma_node_config config = ma_node_config_init(); - config.inputBusCount = 1; - config.outputBusCount = 1; - config.pInputChannels = positioner_channels; - config.pOutputChannels = positioner_channels; - config.vtable = &positioner_vtable; - memset(&slot->extras, 0, sizeof(SoundExtras)); - if (ma_node_init(&engine.nodeGraph, &config, NULL, &slot->extras) != MA_SUCCESS) - return false; - ma_panner_config pc = ma_panner_config_init(ma_format_f32, AAE_CHANNELS); - pc.mode = ma_pan_mode_balance; - ma_panner_init(&pc, &slot->extras.panner); - ma_gainer_config gc = ma_gainer_config_init(AAE_CHANNELS, AAE_SAMPLE_RATE / 20);//Allow one in-game frame for the gain to work its way towards the target value. - if (ma_gainer_init(&gc, NULL, &slot->extras.gainer) != MA_SUCCESS) - return false; - ma_lpf_config fc = ma_lpf_config_init(ma_format_f32, AAE_CHANNELS, AAE_SAMPLE_RATE, AAE_SAMPLE_RATE / 2, AAE_LPF_ORDER); - ma_lpf_init(&fc, NULL, &slot->extras.filter); - slot->extras.cutoff = 1.0f; - slot->extras.pitch = 1.0f; - slot->extras.pitchBehindModifier = 0.0f; - //ma_node_attach_output_bus(&slot->sound, 0, &slot->extras.filter, 0); - ma_node_attach_output_bus(&slot->sound, 0, &slot->extras, 0); - return true; + slot->active = false; +} - } - void AccessibleAudioEngine::destroySound(SoundSlot* slot) { - ma_node_detach_all_output_buses(&slot->extras); - ma_sound_uninit(&slot->sound); - ma_gainer_uninit(&slot->extras.gainer, NULL); - - slot->active = false; - - } - - AccessibleAudioEngine::AccessibleAudioEngine() { - initialized = 0; - ma_resource_manager_config rmc = ma_resource_manager_config_init(); - rmc.decodedChannels = AAE_CHANNELS; - rmc.decodedFormat = ma_format_f32; - rmc.decodedSampleRate = AAE_SAMPLE_RATE; - rmc.flags = MA_RESOURCE_MANAGER_FLAG_NON_BLOCKING; - rmc.jobThreadCount = 0; - if (ma_resource_manager_init(&rmc, &resourceManager) != MA_SUCCESS) - destroyAndThrow("AccessibleAudioEngine: Unable to initialize the resource manager."); - initialized = 1; - if (ma_pcm_rb_init(ma_format_f32, AAE_CHANNELS, AAE_MAX_BUFFER_SIZE, NULL, NULL, &preparedOutput) != MA_SUCCESS) - destroyAndThrow("AccessibleAudioEngine: Unable to initialize the output buffer."); - initialized = 2; - ma_engine_config ec = ma_engine_config_init(); +AccessibleAudioEngine::AccessibleAudioEngine() { + initialized = 0; + ma_resource_manager_config rmc = ma_resource_manager_config_init(); + rmc.decodedChannels = AAE_CHANNELS; + rmc.decodedFormat = ma_format_f32; + rmc.decodedSampleRate = AAE_SAMPLE_RATE; + rmc.flags = MA_RESOURCE_MANAGER_FLAG_NON_BLOCKING; + rmc.jobThreadCount = 0; + if (ma_resource_manager_init(&rmc, &resourceManager) != MA_SUCCESS) + destroyAndThrow("AccessibleAudioEngine: Unable to initialize the resource manager."); + initialized = 1; + if (ma_pcm_rb_init(ma_format_f32, AAE_CHANNELS, AAE_MAX_BUFFER_SIZE, NULL, NULL, &preparedOutput) != MA_SUCCESS) + destroyAndThrow("AccessibleAudioEngine: Unable to initialize the output buffer."); + initialized = 2; + ma_engine_config ec = ma_engine_config_init(); ec.channels = AAE_CHANNELS; ec.noDevice = true; ec.sampleRate = AAE_SAMPLE_RATE; @@ -477,152 +455,150 @@ void AccessibleAudioEngine::postHighPrioritySoundAction(SoundAction& action) { nextOutgoingSoundAction = 0; framesUntilGC = AAE_GC_INTERVAL; thread = std::thread(&AccessibleAudioEngine::runThread, this); - - } - AccessibleAudioEngine::~AccessibleAudioEngine() { - //Place a terminate command on the top of the pile, then wait for thread to die. - SoundAction action; - action.command = AAE_TERMINATE; - postHighPrioritySoundAction(action); - thread.join(); - destroy(); - - } - void AccessibleAudioEngine::mix(int16_t * ogBuffer, uint32_t nFrames) { - uint32_t framesAvailable = ma_pcm_rb_available_read(&preparedOutput); - float sourceChunk[AAE_MIX_CHUNK_SIZE * AAE_CHANNELS]; - float mixedChunk[AAE_MIX_CHUNK_SIZE * AAE_CHANNELS]; - while (nFrames > 0) { - uint32_t nextChunk = std::min (AAE_MIX_CHUNK_SIZE, nFrames); - ma_silence_pcm_frames(sourceChunk, nextChunk, ma_format_f32, AAE_CHANNELS);//This is so that it doesn't matter if we have less output available than expected. - ma_silence_pcm_frames(mixedChunk, nextChunk, ma_format_f32, AAE_CHANNELS); - retrieve(sourceChunk, nextChunk); - ma_pcm_s16_to_f32(mixedChunk, ogBuffer, nextChunk * AAE_CHANNELS, ma_dither_mode_none);//The game's output is changed to 32-bit floating point samples. - ma_mix_pcm_frames_f32(mixedChunk, sourceChunk, nextChunk, AAE_CHANNELS, 1.0); -//If we've gone over 1.0, we'll need to scale back before we go back to 16-bit or we'll distort. - float scalar = 1.0; +} +AccessibleAudioEngine::~AccessibleAudioEngine() { + // Place a terminate command on the top of the pile, then wait for thread to die. + SoundAction action; + action.command = AAE_TERMINATE; + postHighPrioritySoundAction(action); + thread.join(); + destroy(); +} +void AccessibleAudioEngine::mix(int16_t* ogBuffer, uint32_t nFrames) { + uint32_t framesAvailable = ma_pcm_rb_available_read(&preparedOutput); + float sourceChunk[AAE_MIX_CHUNK_SIZE * AAE_CHANNELS]; + float mixedChunk[AAE_MIX_CHUNK_SIZE * AAE_CHANNELS]; + while (nFrames > 0) { + uint32_t nextChunk = std::min(AAE_MIX_CHUNK_SIZE, nFrames); + ma_silence_pcm_frames( + sourceChunk, nextChunk, ma_format_f32, + AAE_CHANNELS); // This is so that it doesn't matter if we have less output available than expected. + ma_silence_pcm_frames(mixedChunk, nextChunk, ma_format_f32, AAE_CHANNELS); + retrieve(sourceChunk, nextChunk); + ma_pcm_s16_to_f32(mixedChunk, ogBuffer, nextChunk * AAE_CHANNELS, + ma_dither_mode_none); // The game's output is changed to 32-bit floating point samples. + ma_mix_pcm_frames_f32(mixedChunk, sourceChunk, nextChunk, AAE_CHANNELS, 1.0); + // If we've gone over 1.0, we'll need to scale back before we go back to 16-bit or we'll distort. + float scalar = 1.0; + for (int i = 0; i < nextChunk * AAE_CHANNELS; i++) + scalar = std::max(scalar, mixedChunk[i]); + if (scalar > 1.0) { + scalar = 1.0 / scalar; for (int i = 0; i < nextChunk * AAE_CHANNELS; i++) - scalar = std::max(scalar, mixedChunk[i]); - if (scalar > 1.0) { - scalar = 1.0 / scalar; - for (int i = 0; i < nextChunk * AAE_CHANNELS; i++) - mixedChunk[i] *= scalar; - } - ma_pcm_f32_to_s16(ogBuffer, mixedChunk, nextChunk * AAE_CHANNELS, ma_dither_mode_triangle);//Chunk is ready to go out via the game's usual channels. - ogBuffer += nextChunk * AAE_CHANNELS; - nFrames -= nextChunk; - } - + mixedChunk[i] *= scalar; + } + ma_pcm_f32_to_s16(ogBuffer, mixedChunk, nextChunk * AAE_CHANNELS, + ma_dither_mode_triangle); // Chunk is ready to go out via the game's usual channels. + ogBuffer += nextChunk * AAE_CHANNELS; + nFrames -= nextChunk; } +} void AccessibleAudioEngine::playSound(uintptr_t handle, int slot, const char* path, bool looping) { if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) - return; - SoundAction& action = getNextOutgoingSoundAction(); + return; + SoundAction& action = getNextOutgoingSoundAction(); action.handle = handle; - action.slot = slot; - action.command = AAE_START; + action.slot = slot; + action.command = AAE_START; action.path = path; - action.looping = looping; - } + action.looping = looping; +} void AccessibleAudioEngine::stopSound(uintptr_t handle, int slot) { - if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) - return; - SoundAction& action = getNextOutgoingSoundAction(); - action.command = AAE_STOP; - action.handle = (uintptr_t) handle; - action.slot = slot; - } + if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) + return; + SoundAction& action = getNextOutgoingSoundAction(); + action.command = AAE_STOP; + action.handle = (uintptr_t)handle; + action.slot = slot; +} void AccessibleAudioEngine::stopAllSounds(uintptr_t handle) { - SoundAction& action = getNextOutgoingSoundAction(); - action.command = AAE_STOP_ALL; - action.handle = handle; - } - void AccessibleAudioEngine::setPitch(uintptr_t handle, int slot, float pitch) { - if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) - return; + SoundAction& action = getNextOutgoingSoundAction(); + action.command = AAE_STOP_ALL; + action.handle = handle; +} +void AccessibleAudioEngine::setPitch(uintptr_t handle, int slot, float pitch) { + if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) + return; - SoundAction& action = getNextOutgoingSoundAction(); - action.command = AAE_PITCH; - action.handle = handle; - action.slot = slot; - action.pitch = pitch; + SoundAction& action = getNextOutgoingSoundAction(); + action.command = AAE_PITCH; + action.handle = handle; + action.slot = slot; + action.pitch = pitch; +} +void AccessibleAudioEngine::setPitchBehindModifier(uintptr_t handle, int slot, float mod) { + if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) + return; - } - void AccessibleAudioEngine::setPitchBehindModifier(uintptr_t handle, int slot, float mod) { - if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) - return; + SoundAction& action = getNextOutgoingSoundAction(); + action.command = AAE_PITCH_BEHIND; + action.handle = handle; + action.slot = slot; + action.pitch = mod; +} - SoundAction& action = getNextOutgoingSoundAction(); - action.command = AAE_PITCH_BEHIND; - action.handle = handle; - action.slot = slot; - action.pitch = mod; +void AccessibleAudioEngine::setVolume(uintptr_t handle, int slot, float volume) { - - } - - void AccessibleAudioEngine::setVolume(uintptr_t handle, int slot, float volume) { - - if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) - return; - SoundAction& action = getNextOutgoingSoundAction(); - action.command = AAE_VOLUME; - action.handle = handle; - action.slot = slot; - action.volume = volume; - } + if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) + return; + SoundAction& action = getNextOutgoingSoundAction(); + action.command = AAE_VOLUME; + action.handle = handle; + action.slot = slot; + action.volume = volume; +} void AccessibleAudioEngine::setPan(uintptr_t handle, int slot, float pan) { - if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) - return; - SoundAction& action = getNextOutgoingSoundAction(); - action.command = AAE_PAN; - action.handle = handle; - action.slot = slot; - action.pan = pan; - } + if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) + return; + SoundAction& action = getNextOutgoingSoundAction(); + action.command = AAE_PAN; + action.handle = handle; + action.slot = slot; + action.pan = pan; +} void AccessibleAudioEngine::setFilter(uintptr_t handle, int slot, float cutoff) { - if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) - return; - if (cutoff < 0.0 || cutoff > 1.0) - return; - SoundAction& action = getNextOutgoingSoundAction(); - action.handle = handle; - action.slot = slot; - action.command = AAE_FILTER; - action.cutoff = cutoff; - } - - void AccessibleAudioEngine::seekSound(uintptr_t handle, int slot, size_t offset) { - if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) - return; - SoundAction& action = getNextOutgoingSoundAction(); - action.handle = handle; - action.slot = slot; - action.command = AAE_SEEK; -action.offset = offset; - + if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) + return; + if (cutoff < 0.0 || cutoff > 1.0) + return; + SoundAction& action = getNextOutgoingSoundAction(); + action.handle = handle; + action.slot = slot; + action.command = AAE_FILTER; + action.cutoff = cutoff; } -void AccessibleAudioEngine::setSoundPosition(uintptr_t handle, int slot, float posX, float posY, float posZ, float distToPlayer, float maxDistance) { - if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) - return; - SoundAction& action = getNextOutgoingSoundAction(); - action.command = AAE_POS; - action.handle = handle; - action.slot = slot; - action.posX = posX; - action.posY = posY; - action.posZ = posZ; - action.distToPlayer = distToPlayer; - action.maxDistance = maxDistance; +void AccessibleAudioEngine::seekSound(uintptr_t handle, int slot, size_t offset) { + if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) + return; + SoundAction& action = getNextOutgoingSoundAction(); + action.handle = handle; + action.slot = slot; + action.command = AAE_SEEK; + action.offset = offset; +} +void AccessibleAudioEngine::setSoundPosition(uintptr_t handle, int slot, float posX, float posY, float posZ, + float distToPlayer, float maxDistance) { + if (slot < 0 || slot >= AAE_SLOTS_PER_HANDLE) + return; + SoundAction& action = getNextOutgoingSoundAction(); + action.command = AAE_POS; + action.handle = handle; + action.slot = slot; + action.posX = posX; + action.posY = posY; + action.posZ = posZ; + action.distToPlayer = distToPlayer; + action.maxDistance = maxDistance; +} +void AccessibleAudioEngine::prepare() { + SoundAction& action = getNextOutgoingSoundAction(); + action.command = AAE_PREPARE; + // This is called once at the end of every frame, so now is the time to post all of the accumulated commands. + postSoundActions(); } - void AccessibleAudioEngine::prepare() { - SoundAction& action = getNextOutgoingSoundAction(); - action.command = AAE_PREPARE; -//This is called once at the end of every frame, so now is the time to post all of the accumulated commands. - postSoundActions(); - } void AccessibleAudioEngine::cacheDecodedSample(std::string& path, void* data, size_t size) { -//The data is stored in wave format, so we register it with MiniAudio as an encoded asset as opposed to a decoded one. - ma_resource_manager_register_encoded_data(&resourceManager, path.c_str(), data, size); - } \ No newline at end of file + // The data is stored in wave format, so we register it with MiniAudio as an encoded asset as opposed to a decoded + // one. + ma_resource_manager_register_encoded_data(&resourceManager, path.c_str(), data, size); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.h b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.h index d069a1cef..07bbb2ec5 100644 --- a/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.h +++ b/soh/soh/Enhancements/accessible-actors/AccessibleAudioEngine.h @@ -13,90 +13,91 @@ #define AAE_SLOTS_PER_HANDLE 10 class IResource; struct DecodedSample { - void* data;//A wav file. + void* data; // A wav file. size_t dataSize; }; struct SoundAction { uintptr_t handle; // This handle is user-defined and uniquely identifies a sound source. It can be anything, but the - // address of an object with which the sound is associated is recommended. - int slot;//Allows multiple sounds per handle. The exact number is controlled by AAE_SOUNDS_PER_HANDLE. - int command; // One of the items belonging to AAE_COMMANDS. + // address of an object with which the sound is associated is recommended. + int slot; // Allows multiple sounds per handle. The exact number is controlled by AAE_SOUNDS_PER_HANDLE. + int command; // One of the items belonging to AAE_COMMANDS. std::string path; // If command is AAE_START, this is the path to the desired resource. bool looping; // If command is AAE_START, specifies whether or not the sound should loop. - union { - float pitch; - float volume; - float pan; - float cutoff; - size_t offset;//for seeking. - float distance; - }; + union { + float pitch; + float volume; + float pan; + float cutoff; + size_t offset; // for seeking. + float distance; + }; - //Position and rotation vectors for AAE_LISTENER and AAE_POS. - float posX; - float posY; - float posZ; - float distToPlayer; - float maxDistance; - uint32_t frames; // If command is AAE_PREPARE, this tells the engine how many PCM frames to get ready. + // Position and rotation vectors for AAE_LISTENER and AAE_POS. + float posX; + float posY; + float posZ; + float distToPlayer; + float maxDistance; + uint32_t frames; // If command is AAE_PREPARE, this tells the engine how many PCM frames to get ready. }; -typedef struct -{ - ma_node_base base; - ma_panner panner; - ma_gainer gainer; - ma_lpf filter; - float cutoff; - float x; - float y; - float z; - float distToPlayer; - float maxDistance; - float pitch; - float pitchBehindModifier; -}SoundExtras;//Used for attenuation and other effects. +typedef struct { + ma_node_base base; + ma_panner panner; + ma_gainer gainer; + ma_lpf filter; + float cutoff; + float x; + float y; + float z; + float distToPlayer; + float maxDistance; + float pitch; + float pitchBehindModifier; +} SoundExtras; // Used for attenuation and other effects. -typedef struct -{ - ma_sound sound; - SoundExtras extras; +typedef struct { + ma_sound sound; + SoundExtras extras; - bool active; -}SoundSlot; + bool active; +} SoundSlot; typedef std::array SoundSlots; class AccessibleAudioEngine { int initialized; ma_resource_manager resourceManager; ma_engine engine; - ma_pcm_rb preparedOutput;//Lock-free single producer single consumer. - std::deque soundActions;//A command cue. + ma_pcm_rb preparedOutput; // Lock-free single producer single consumer. + std::deque soundActions; // A command cue. std::thread thread; std::condition_variable cv; std::mutex mtx; std::unordered_map sounds; - SoundAction outgoingSoundActions[AAE_SOUND_ACTION_BATCH_SIZE];//Allows batch delivery of SoundActions to the FIFO to minimize the amount of time spent locking and unlocking. + SoundAction + outgoingSoundActions[AAE_SOUND_ACTION_BATCH_SIZE]; // Allows batch delivery of SoundActions to the FIFO to + // minimize the amount of time spent locking and unlocking. int nextOutgoingSoundAction; int framesUntilGC; - void destroy();//Called by the destructor, or if a throw occurs during construction. - //Dismantal a partial initialization and throw an exception. - void destroyAndThrow(const char* exceptionText); + void destroy(); // Called by the destructor, or if a throw occurs during construction. + // Dismantal a partial initialization and throw an exception. + void destroyAndThrow(const char* exceptionText); - //Retrieve some audio from the output buffer. This is to be performed by the audio thread. May return less data than requested. + // Retrieve some audio from the output buffer. This is to be performed by the audio thread. May return less data + // than requested. uint32_t retrieve(float* buffer, uint32_t nFrames); - //Functions dealing with the command queue. + // Functions dealing with the command queue. int getSoundActions(SoundAction* dest, int limit); void postSoundActions(); - void postHighPrioritySoundAction(SoundAction& action);//For now this is used only for termination events. + void postHighPrioritySoundAction(SoundAction& action); // For now this is used only for termination events. SoundAction& getNextOutgoingSoundAction(); void runThread(); -//Find a sound by handle and slot, if it exists. -SoundSlot* findSound(SoundAction& action); + // Find a sound by handle and slot, if it exists. + SoundSlot* findSound(SoundAction& action); -//Functions which correspond to SoundAction commands. - //Ready a sound for playback. + // Functions which correspond to SoundAction commands. + // Ready a sound for playback. void doPlaySound(SoundAction& action); void doStopSound(SoundAction& action); void doStopAllSounds(SoundAction& action); @@ -113,37 +114,39 @@ SoundSlot* findSound(SoundAction& action); // Generate some output, and store it in the output buffer for later retrieval. May generate less output than // requested if buffer space is insufficient. void doPrepare(SoundAction& action); -//Run every so often to clean up expired sound handles. + // Run every so often to clean up expired sound handles. void garbageCollect(); - //Run MiniAudio's jobs. + // Run MiniAudio's jobs. void processAudioJobs(); -//Set up the panner and other effect processing on a sound slot. + // Set up the panner and other effect processing on a sound slot. bool initSoundExtras(SoundSlot* slot); void destroySound(SoundSlot* slot); public: AccessibleAudioEngine(); ~AccessibleAudioEngine(); - //Mix the game's audio with this engine's audio to produce the final mix. To be performed exclusively in the audio thread. Mixing is done in-place (meaning the buffer containing the game's audio is overwritten with the mixed content). + // Mix the game's audio with this engine's audio to produce the final mix. To be performed exclusively in the audio + // thread. Mixing is done in-place (meaning the buffer containing the game's audio is overwritten with the mixed + // content). void mix(int16_t* ogBuffer, uint32_t nFrames); -//Start playing a sound. + // Start playing a sound. void playSound(uintptr_t handle, int slot, const char* path, bool looping); void stopSound(uintptr_t handle, int slot); - //Stop all sounds belonging to a handle. + // Stop all sounds belonging to a handle. void stopAllSounds(uintptr_t handle); void setPitch(uintptr_t handle, int slot, float pitch); void setPitchBehindModifier(uintptr_t handle, int slot, float mod); void setVolume(uintptr_t handle, int slot, float volume); void setPan(uintptr_t handle, int slot, float pan); -//Set the lowpass filter cutoff. Set to 1.0 for no filtering. - void setFilter(uintptr_t handle, int slot, float cutoff); -//Seek the sound to a particular PCM frame. + // Set the lowpass filter cutoff. Set to 1.0 for no filtering. + void setFilter(uintptr_t handle, int slot, float cutoff); + // Seek the sound to a particular PCM frame. void seekSound(uintptr_t handle, int slot, size_t offset); - void setSoundPosition(uintptr_t handle, int slot, float posX, float posY, float posZ, float distToPlayer, float maxDistance); - //Schedule the preparation of output for delivery. + void setSoundPosition(uintptr_t handle, int slot, float posX, float posY, float posZ, float distToPlayer, + float maxDistance); + // Schedule the preparation of output for delivery. void prepare(); void cacheDecodedSample(std::string& path, void* data, size_t size); - }; #endif diff --git a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp index aca2cb37f..3f22b2d4f 100644 --- a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp +++ b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp @@ -31,13 +31,15 @@ extern bool freezeActors; const char* GetLanguageCode(); -#define MAX_DB_REDUCTION 35// This is the amount in DB that a sound will be reduced by when it is at the maximum distance - // from the player. +#define MAX_DB_REDUCTION \ + 35 // This is the amount in DB that a sound will be reduced by when it is at the maximum distance + // from the player. extern "C" { - void CollisionPoly_GetVertices(CollisionPoly* poly, Vec3s* vtxList, Vec3f* dest);//Used to tell where polygons are located. - } +void CollisionPoly_GetVertices(CollisionPoly* poly, Vec3s* vtxList, + Vec3f* dest); // Used to tell where polygons are located. +} - typedef struct { +typedef struct { union { struct { s16 sceneIndex; // Corresponds directly to the game's scene indices. @@ -46,19 +48,23 @@ extern "C" { s32 raw; // Combination of the two which can be used for dictionary lookups. }; - } SceneAndRoom; - typedef std::map SupportedActors_t;//Maps actors to their accessibility policies, which describe how accessibility should treat them. -typedef std::map TrackedActors_t;//Maps real actors to internal IDs specific to accessibility. -typedef std::map AccessibleActorList_t;//Maps internal IDs to wrapped actor objects. These actors can be real or virtual. -typedef std::vector VAList_t;//Denotes a list of virtual actors specific to a single room. -typedef std::map VAZones_t;//Maps room/ scene indices to their corresponding virtual actor collections. -typedef std::unordered_set SceneList_t;//A list of scenes which have already been visited (since the game was launched). Used to prevent re-creation of terrain VAs every time the player reloads a scene. +} SceneAndRoom; +typedef std::map SupportedActors_t; // Maps actors to their accessibility policies, which + // describe how accessibility should treat them. +typedef std::map TrackedActors_t; // Maps real actors to internal IDs specific to accessibility. +typedef std::map + AccessibleActorList_t; // Maps internal IDs to wrapped actor objects. These actors can be real or virtual. +typedef std::vector VAList_t; // Denotes a list of virtual actors specific to a single room. +typedef std::map VAZones_t; // Maps room/ scene indices to their corresponding virtual actor collections. +typedef std::unordered_set + SceneList_t; // A list of scenes which have already been visited (since the game was launched). Used to prevent + // re-creation of terrain VAs every time the player reloads a scene. typedef struct { std::string path; std::shared_ptr resource; - std::shared_ptr decodedSample;//Set if the record is for a raw sample as opposed to a SFX. -}SfxRecord; + std::shared_ptr decodedSample; // Set if the record is for a raw sample as opposed to a SFX. +} SfxRecord; class AudioGlossaryData { public: @@ -73,7 +79,7 @@ class AudioGlossaryData { class ActorAccessibility { public: - int isOn = 0; + int isOn = 0; uint64_t nextActorID = 0; SupportedActors_t supportedActors; TrackedActors_t trackedActors; @@ -83,8 +89,9 @@ class ActorAccessibility { SceneList_t sceneList; AccessibleAudioEngine* audioEngine; SfxExtractor sfxExtractor; - std::unordered_map sfxMap;//Maps internal sfx to external (prerendered) resources. - std::unordered_map sampleMap;//Similar to above, but this one maps raw audio samples as opposed to SFX. + std::unordered_map sfxMap; // Maps internal sfx to external (prerendered) resources. + std::unordered_map + sampleMap; // Similar to above, but this one maps raw audio samples as opposed to SFX. int extractSfx = 0; s16 currentScene = -1; s8 currentRoom = -1; @@ -94,9 +101,6 @@ class ActorAccessibility { }; static ActorAccessibility* aa; - - - uint64_t ActorAccessibility_GetNextID() { uint64_t result = aa->nextActorID; aa->nextActorID++; @@ -111,24 +115,20 @@ void ActorAccessibility_OnGameFrameUpdate() { if (gPlayState == NULL) return; if (!GameInteractor::IsSaveLoaded() && !aa->extractSfx) - return;//Title screen, skip. + return; // Title screen, skip. ActorAccessibility_RunAccessibilityForAllActors(gPlayState); } -void ActorAccessibility_OnActorDestroy(void* actor) -{ - ActorAccessibility_RemoveTrackedActor((Actor*) actor); - +void ActorAccessibility_OnActorDestroy(void* actor) { + ActorAccessibility_RemoveTrackedActor((Actor*)actor); } -void ActorAccessibility_OnGameStillFrozen() -{ +void ActorAccessibility_OnGameStillFrozen() { if (gPlayState == NULL) return; if (aa->extractSfx) ActorAccessibility_HandleSoundExtractionMode(gPlayState); - } - void ActorAccessibility_Init() { +void ActorAccessibility_Init() { aa = new ActorAccessibility(); aa->glossary = new AudioGlossaryData(); @@ -145,13 +145,13 @@ void ActorAccessibility_OnGameStillFrozen() GameInteractor::Instance->RegisterGameHook(ActorAccessibility_OnGameFrameUpdate); GameInteractor::Instance->RegisterGameHook(ActorAccessibility_OnGameStillFrozen); - } +} void ActorAccessibility_Shutdown() { ActorAccessibility_ShutdownAudio(); delete aa; } - void ActorAccessibility_InitPolicy(ActorAccessibilityPolicy * policy, const char* englishName, - ActorAccessibilityCallback callback, s16 sfx) { +void ActorAccessibility_InitPolicy(ActorAccessibilityPolicy* policy, const char* englishName, + ActorAccessibilityCallback callback, s16 sfx) { policy->callback = callback; policy->distance = 500; policy->ydist = 80; @@ -167,266 +167,228 @@ void ActorAccessibility_Shutdown() { policy->aimAssist.isProvider = false; policy->aimAssist.sfx = NA_SE_SY_HITPOINT_ALARM; policy->aimAssist.tolerance = 0.0; +} - } - - void ActorAccessibility_AddSupportedActor(s16 type, ActorAccessibilityPolicy policy) { +void ActorAccessibility_AddSupportedActor(s16 type, ActorAccessibilityPolicy policy) { aa->supportedActors[type] = policy; - } ActorAccessibilityPolicy* ActorAccessibility_GetPolicyForActor(s16 type) { SupportedActors_t::iterator i = aa->supportedActors.find(type); - if (i == aa->supportedActors.end()) - return NULL; - return &(i->second); - - } + if (i == aa->supportedActors.end()) + return NULL; + return &(i->second); +} int ActorAccessibility_GetRandomStartingFrameCount(int min, int max) { - static std::mt19937 gen; + static std::mt19937 gen; std::uniform_int_distribution<> dist(min, max); - return dist(gen); + return dist(gen); +} - } +void ActorAccessibility_TrackNewActor(Actor* actor) { + // Don't track actors for which no accessibility policy has been configured. + ActorAccessibilityPolicy* policy = ActorAccessibility_GetPolicyForActor(actor->id); + if (policy == NULL) + return; + AccessibleActor accessibleActor; + accessibleActor.instanceID = ActorAccessibility_GetNextID(); + accessibleActor.actor = actor; + accessibleActor.id = actor->id; + // Stagger the start times so that all of the sounds don't play at exactly the same time. + accessibleActor.frameCount = ActorAccessibility_GetRandomStartingFrameCount(0, policy->n); + accessibleActor.basePitch = policy->pitch; + accessibleActor.policy = *policy; + accessibleActor.currentPitch = accessibleActor.policy.pitch; + accessibleActor.baseVolume = accessibleActor.policy.volume; + accessibleActor.currentVolume = accessibleActor.policy.volume; + accessibleActor.sceneIndex = 0; + for (int i = 0; i < NUM_MANAGED_SOUND_SLOTS; i++) + accessibleActor.managedSoundSlots[i] = false; + accessibleActor.aimAssist.framesSinceAimAssist = 32768; + accessibleActor.aimAssist.frequency = 10; + accessibleActor.aimAssist.pitch = 1.0; - void ActorAccessibility_TrackNewActor(Actor * actor) { - // Don't track actors for which no accessibility policy has been configured. - ActorAccessibilityPolicy* policy = ActorAccessibility_GetPolicyForActor(actor->id); - if (policy == NULL) - return; - AccessibleActor accessibleActor; - accessibleActor.instanceID = ActorAccessibility_GetNextID(); - accessibleActor.actor = actor; - accessibleActor.id = actor->id; - //Stagger the start times so that all of the sounds don't play at exactly the same time. - accessibleActor.frameCount = ActorAccessibility_GetRandomStartingFrameCount(0, policy->n); - accessibleActor.basePitch = policy->pitch; - accessibleActor.policy = *policy; - accessibleActor.currentPitch = accessibleActor.policy.pitch; - accessibleActor.baseVolume = accessibleActor.policy.volume; - accessibleActor.currentVolume = accessibleActor.policy.volume; - accessibleActor.sceneIndex = 0; - for (int i = 0; i < NUM_MANAGED_SOUND_SLOTS; i++) - accessibleActor.managedSoundSlots[i] = false; - accessibleActor.aimAssist.framesSinceAimAssist = 32768; - accessibleActor.aimAssist.frequency = 10; - accessibleActor.aimAssist.pitch = 1.0; + aa->trackedActors[actor] = accessibleActor.instanceID; + aa->accessibleActorList[accessibleActor.instanceID] = accessibleActor; + AccessibleActor& savedActor = aa->accessibleActorList[accessibleActor.instanceID]; + if (policy->initUserData && !policy->initUserData(&savedActor)) { + ActorAccessibility_RemoveTrackedActor(actor); - aa->trackedActors[actor] = accessibleActor.instanceID; - aa->accessibleActorList[accessibleActor.instanceID] = accessibleActor; - AccessibleActor& savedActor = aa->accessibleActorList[accessibleActor.instanceID]; - if (policy->initUserData && !policy->initUserData(&savedActor)) { - ActorAccessibility_RemoveTrackedActor(actor); + return; // Probably a malloc error preventing user data initialization. + } +} +void ActorAccessibility_RemoveTrackedActor(Actor* actor) { + TrackedActors_t::iterator i = aa->trackedActors.find(actor); + if (i == aa->trackedActors.end()) + return; + uint64_t id = i->second; + aa->trackedActors.erase(i); + AccessibleActorList_t::iterator i2 = aa->accessibleActorList.find(id); + if (i2 == aa->accessibleActorList.end()) + return; + if (i2->second.policy.cleanupUserData) + i2->second.policy.cleanupUserData(&i2->second); + ActorAccessibility_StopAllSoundsForActor(&i2->second); + aa->accessibleActorList.erase(i2); +} - return; // Probably a malloc error preventing user data initialization. +f32 ActorAccessibility_DBToLinear(float gain) { + return (float)pow(10.0, gain / 20.0f); +} +f32 ActorAccessibility_ComputeCurrentVolume(f32 maxDistance, f32 xzDistToPlayer) { + if (maxDistance == 0) + return 0.0; + f32 absDistance = fabs(xzDistToPlayer); + + f32 db = LERP(0.0 - MAX_DB_REDUCTION, 0.0, (maxDistance - absDistance) / maxDistance); + + return ActorAccessibility_DBToLinear(db); +} +const char* ActorAccessibility_MapSfxToExternalAudio(s16 sfxId); +void ActorAccessibility_PlaySound(void* handle, int slot, s16 sfxId, bool looping) { + const char* path = ActorAccessibility_MapSfxToExternalAudio(sfxId); + if (path == NULL) + return; + aa->audioEngine->playSound((uintptr_t)handle, slot, path, looping); +} +const char* ActorAccessibility_MapRawSampleToExternalAudio(const char* name); + +void ActorAccessibility_PlayRawSample(void* handle, int slot, const char* name, bool looping) { + const char* path = ActorAccessibility_MapRawSampleToExternalAudio(name); + if (path == NULL) + return; + aa->audioEngine->playSound((uintptr_t)handle, slot, path, looping); +} +void ActorAccessibility_StopSound(void* handle, int slot) { + aa->audioEngine->stopSound((uintptr_t)handle, slot); +} +void ActorAccessibility_StopAllSounds(void* handle) { + aa->audioEngine->stopAllSounds((uintptr_t)handle); +} +void ActorAccessibility_SetSoundPitch(void* handle, int slot, float pitch) { + aa->audioEngine->setPitch((uintptr_t)handle, slot, pitch); +} +void ActorAccessibility_SetPitchBehindModifier(void* handle, int slot, float mod) { + aa->audioEngine->setPitchBehindModifier((uintptr_t)handle, slot, mod); +} +void ActorAccessibility_SetSoundPos(void* handle, int slot, Vec3f* pos, f32 distToPlayer, f32 maxDistance) { + aa->audioEngine->setSoundPosition((uintptr_t)handle, slot, pos->x, pos->y, pos->z, distToPlayer, maxDistance); +} +void ActorAccessibility_SetSoundVolume(void* handle, int slot, float volume) { + aa->audioEngine->setVolume((uintptr_t)handle, slot, volume); +} +void ActorAccessibility_SetSoundPan(void* handle, int slot, Vec3f* projectedPos) { + 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); +} +void ActorAccessibility_SetSoundFilter(void* handle, int slot, float cutoff) { + aa->audioEngine->setFilter((uintptr_t)handle, slot, cutoff); +} +void ActorAccessibility_SeekSound(void* handle, int slot, size_t offset) { + aa->audioEngine->seekSound((uintptr_t)handle, slot, offset); +} +void ActorAccessibility_ConfigureSoundForActor(AccessibleActor* actor, int slot) { + ActorAccessibility_SetSoundPitch(actor, slot, actor->policy.pitch); + ActorAccessibility_SetPitchBehindModifier(actor, slot, actor->policy.pitchModifier); + ActorAccessibility_SetSoundPos(actor, slot, &actor->projectedPos, actor->xyzDistToPlayer, actor->policy.distance); + ActorAccessibility_SetSoundVolume(actor, slot, actor->policy.volume); + actor->managedSoundSlots[slot] = true; +} +void ActorAccessibility_PlaySoundForActor(AccessibleActor* actor, int slot, s16 sfxId, bool looping) { + if (slot < 0 || slot > NUM_MANAGED_SOUND_SLOTS) + return; + ActorAccessibility_PlaySound(actor, slot, sfxId, looping); + ActorAccessibility_ConfigureSoundForActor(actor, slot); +} +void ActorAccessibility_PlaySampleForActor(AccessibleActor* actor, int slot, const char* name, bool looping) { + if (slot < 0 || slot > NUM_MANAGED_SOUND_SLOTS) + return; + ActorAccessibility_PlayRawSample(actor, slot, name, looping); + ActorAccessibility_ConfigureSoundForActor(actor, slot); +} +void ActorAccessibility_StopSoundForActor(AccessibleActor* actor, int slot) { + if (slot < 0 || slot >= NUM_MANAGED_SOUND_SLOTS) + return; + ActorAccessibility_StopSound(actor, slot); + actor->managedSoundSlots[slot] = false; +} +void ActorAccessibility_StopAllSoundsForActor(AccessibleActor* actor) + +{ + ActorAccessibility_StopAllSounds(actor); + for (int i = 0; i < NUM_MANAGED_SOUND_SLOTS; i++) + actor->managedSoundSlots[i] = false; +} + +bool ActorAccessibility_IsRealActor(AccessibleActor* actor) { + return actor->actor != NULL; +} +void ActorAccessibility_CopyParamsFromRealActor(AccessibleActor* actor) { + Player* player = GET_PLAYER(actor->play); + if (actor->actor == NULL) + return; + actor->projectedPos = actor->actor->projectedPos; + actor->xzDistToPlayer = actor->actor->xzDistToPlayer; + actor->isDrawn = actor->actor->isDrawn; + actor->xyzDistToPlayer = Math_Vec3f_DistXYZ(&actor->actor->world.pos, &player->actor.world.pos); +} +void ActorAccessibility_PrepareNextAudioFrame(); +void ActorAccessibility_StopAllVirtualActors(VirtualActorList* list) { + if (list == NULL) + return; + + VAList_t* val = (VAList_t*)list; + for (auto i = val->begin(); i != val->end(); i++) + ActorAccessibility_StopAllSounds((void*)&(*i)); +} +void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActor* actor) { + Player* player = GET_PLAYER(play); + actor->play = play; + if (ActorAccessibility_IsRealActor(actor)) + ActorAccessibility_CopyParamsFromRealActor(actor); + + else { + // Perform calculations that the game would normally take care of for real actors. + f32 w = 0.0f; + // Set actor->projectedPos. + SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &actor->world.pos, &actor->projectedPos, &w); + // Set actor->xzDistToPlayer. + + actor->xzDistToPlayer = Math_Vec3f_DistXZ(&actor->world.pos, &player->actor.world.pos); + actor->xyzDistToPlayer = Math_Vec3f_DistXYZ(&actor->world.pos, &player->actor.world.pos); + actor->yDistToPlayer = fabs((actor->world.pos.y) - (player->actor.world.pos.y)); + } + + if (actor->actor != NULL && fabs(actor->actor->yDistToPlayer) > actor->policy.ydist) { + return; + } + // Send sound parameters to the new audio engine. Eventually remove the old stuff once all actors are carried over. + for (int i = 0; i < NUM_MANAGED_SOUND_SLOTS; i++) { + if (actor->managedSoundSlots[i]) { + ActorAccessibility_SetSoundPos(actor, i, &actor->projectedPos, actor->xyzDistToPlayer, + actor->policy.distance); + // Judgement call: pitch changes are rare enough that it doesn't make sense to pay the cost of updating it + // every frame. If you want a pitch change, call the function as needed. } - } - void ActorAccessibility_RemoveTrackedActor(Actor* actor) { - TrackedActors_t::iterator i = aa->trackedActors.find(actor); - if (i == aa->trackedActors.end()) - return; - uint64_t id = i->second; - aa->trackedActors.erase(i); - AccessibleActorList_t::iterator i2 = aa->accessibleActorList.find(id); - if (i2 == aa->accessibleActorList.end()) - return; - if (i2->second.policy.cleanupUserData) - i2->second.policy.cleanupUserData(&i2->second); - ActorAccessibility_StopAllSoundsForActor(&i2->second); - aa->accessibleActorList.erase(i2); - + actor->frameCount++; + if (aa->glossary->GlossaryStarted) { + aa->glossary->frameCount++; } - - f32 ActorAccessibility_DBToLinear(float gain) { - return (float)pow(10.0, gain / 20.0f); + if (actor->frameCount != 1 && (actor->frameCount - 1) % actor->policy.n != 0) + return; + if (!actor->policy.runsAlways && actor->xyzDistToPlayer > actor->policy.distance) { + return; } - f32 ActorAccessibility_ComputeCurrentVolume(f32 maxDistance, f32 xzDistToPlayer) { - if (maxDistance == 0) - return 0.0; - f32 absDistance = fabs(xzDistToPlayer); - - f32 db = LERP(0.0 - MAX_DB_REDUCTION, 0.0, (maxDistance - absDistance) / maxDistance); - - return ActorAccessibility_DBToLinear(db); - - } - const char* ActorAccessibility_MapSfxToExternalAudio(s16 sfxId); - void ActorAccessibility_PlaySound(void* handle, int slot, s16 sfxId, bool looping) - { - const char* path = ActorAccessibility_MapSfxToExternalAudio(sfxId); - if (path == NULL) - return; - aa->audioEngine->playSound((uintptr_t)handle, slot, path, looping); - } - const char* ActorAccessibility_MapRawSampleToExternalAudio(const char* name); - - void ActorAccessibility_PlayRawSample(void* handle, int slot, const char* name, bool looping) - { - const char* path = ActorAccessibility_MapRawSampleToExternalAudio(name); - if (path == NULL) - return; - aa->audioEngine->playSound((uintptr_t)handle, slot, path, looping); - - } - void ActorAccessibility_StopSound(void* handle, int slot) - { - aa->audioEngine->stopSound((uintptr_t) handle, slot); - - } - void ActorAccessibility_StopAllSounds(void* handle) - { - aa->audioEngine->stopAllSounds((uintptr_t)handle); - } - void ActorAccessibility_SetSoundPitch(void* handle, int slot, float pitch) - { - aa->audioEngine->setPitch((uintptr_t)handle, slot, pitch); - - } - void ActorAccessibility_SetPitchBehindModifier(void* handle, int slot, float mod) - { - aa->audioEngine->setPitchBehindModifier((uintptr_t) handle, slot, mod); - - } - void ActorAccessibility_SetSoundPos(void* handle, int slot, Vec3f* pos, f32 distToPlayer, f32 maxDistance) { - aa->audioEngine->setSoundPosition((uintptr_t) handle, slot, pos->x, pos->y, pos->z, distToPlayer, maxDistance); - } - void ActorAccessibility_SetSoundVolume(void* handle, int slot, float volume) - { - aa->audioEngine->setVolume((uintptr_t)handle, slot, volume); - - } - void ActorAccessibility_SetSoundPan(void* handle, int slot, Vec3f* projectedPos) - { - 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); - - } - void ActorAccessibility_SetSoundFilter(void* handle, int slot, float cutoff) - { - aa->audioEngine->setFilter((uintptr_t)handle, slot, cutoff); - - } - void ActorAccessibility_SeekSound(void* handle, int slot, size_t offset) - { - aa->audioEngine->seekSound((uintptr_t)handle, slot, offset); - - } - void ActorAccessibility_ConfigureSoundForActor(AccessibleActor* actor, int slot) - { - ActorAccessibility_SetSoundPitch(actor, slot, actor->policy.pitch); - ActorAccessibility_SetPitchBehindModifier(actor, slot, actor->policy.pitchModifier); - ActorAccessibility_SetSoundPos(actor, slot, &actor->projectedPos, actor->xyzDistToPlayer, - actor->policy.distance); - ActorAccessibility_SetSoundVolume(actor, slot, actor->policy.volume); - actor->managedSoundSlots[slot] = true; - } - void ActorAccessibility_PlaySoundForActor(AccessibleActor* actor, int slot, s16 sfxId, bool looping) - { - if (slot < 0 || slot > NUM_MANAGED_SOUND_SLOTS) - return; - ActorAccessibility_PlaySound(actor, slot, sfxId, looping); - ActorAccessibility_ConfigureSoundForActor(actor, slot); - - } - void ActorAccessibility_PlaySampleForActor(AccessibleActor* actor, int slot, const char* name, bool looping) - { - if (slot < 0 || slot > NUM_MANAGED_SOUND_SLOTS) - return; - ActorAccessibility_PlayRawSample(actor, slot, name, looping); - ActorAccessibility_ConfigureSoundForActor(actor, slot); - - } - void ActorAccessibility_StopSoundForActor(AccessibleActor* actor, int slot) - { - if (slot < 0 || slot >= NUM_MANAGED_SOUND_SLOTS) - return; - ActorAccessibility_StopSound(actor, slot); - actor->managedSoundSlots[slot] = false; - } - void ActorAccessibility_StopAllSoundsForActor(AccessibleActor* actor) - - { - ActorAccessibility_StopAllSounds(actor); - for (int i = 0; i < NUM_MANAGED_SOUND_SLOTS; i++) - actor->managedSoundSlots[i] = false; - } - - bool ActorAccessibility_IsRealActor(AccessibleActor* actor) { - return actor->actor != NULL; - - } - void ActorAccessibility_CopyParamsFromRealActor(AccessibleActor* actor) { - Player* player = GET_PLAYER(actor->play); - if (actor->actor == NULL) - return; - actor->projectedPos = actor->actor->projectedPos; - actor->xzDistToPlayer = actor->actor->xzDistToPlayer; - actor->isDrawn = actor->actor->isDrawn; - actor->xyzDistToPlayer = Math_Vec3f_DistXYZ(&actor->actor->world.pos, &player->actor.world.pos); - } - void ActorAccessibility_PrepareNextAudioFrame(); - void ActorAccessibility_StopAllVirtualActors(VirtualActorList* list) - { - if (list == NULL) - return; - - VAList_t* val = (VAList_t*)list; - for (auto i = val->begin(); i != val->end(); i++) - ActorAccessibility_StopAllSounds((void*) &(*i)); - - } - void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActor* actor) { - Player* player = GET_PLAYER(play); - actor->play = play; - if(ActorAccessibility_IsRealActor(actor)) - ActorAccessibility_CopyParamsFromRealActor(actor); - - else { -//Perform calculations that the game would normally take care of for real actors. - f32 w = 0.0f; - //Set actor->projectedPos. - SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &actor->world.pos, &actor->projectedPos, - &w); -//Set actor->xzDistToPlayer. - - actor->xzDistToPlayer = Math_Vec3f_DistXZ(&actor->world.pos, &player->actor.world.pos); - actor->xyzDistToPlayer = Math_Vec3f_DistXYZ(&actor->world.pos, &player->actor.world.pos); - actor->yDistToPlayer = fabs((actor->world.pos.y) - (player->actor.world.pos.y)); - } - - if (actor->actor != NULL && fabs(actor->actor->yDistToPlayer) > actor->policy.ydist) { - return; - } - //Send sound parameters to the new audio engine. Eventually remove the old stuff once all actors are carried over. - for (int i = 0; i < NUM_MANAGED_SOUND_SLOTS; i++) - { - if (actor->managedSoundSlots[i]) - { - ActorAccessibility_SetSoundPos(actor, i, &actor->projectedPos, actor->xyzDistToPlayer, actor->policy.distance); - //Judgement call: pitch changes are rare enough that it doesn't make sense to pay the cost of updating it every frame. If you want a pitch change, call the function as needed. - - } - } - actor->frameCount++; - if (aa->glossary->GlossaryStarted) { - aa->glossary->frameCount++; - } - if (actor->frameCount != 1 && (actor->frameCount - 1) % actor->policy.n != 0) - return; - if (!actor->policy.runsAlways && actor->xyzDistToPlayer > actor->policy.distance) { - return; - } - if (actor->isDrawn == 0 && actor->actor->id != 406 && actor->actor->id != 302 && !aa->glossary->GlossaryStarted) - return; - if (actor->policy.aimAssist.isProvider) { - if (player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON && - (player->stateFlags1 & PLAYER_STATE1_USING_BOOMERANG || - player->stateFlags1 & PLAYER_STATE1_ITEM_IN_HAND)) { + if (actor->isDrawn == 0 && actor->actor->id != 406 && actor->actor->id != 302 && !aa->glossary->GlossaryStarted) + return; + if (actor->policy.aimAssist.isProvider) { + if (player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON && + (player->stateFlags1 & PLAYER_STATE1_USING_BOOMERANG || player->stateFlags1 & PLAYER_STATE1_ITEM_IN_HAND)) { ActorAccessibility_SetSoundPitch(actor, 9, actor->aimAssist.pitch); actor->aimAssist.framesSinceAimAssist++; ActorAccessibility_ProvideAimAssistForActor(actor); @@ -437,384 +399,351 @@ int ActorAccessibility_GetRandomStartingFrameCount(int min, int max) { actor->aimAssist.framesSinceAimAssist = 0; ActorAccessibility_PlaySoundForActor(actor, 9, actor->policy.aimAssist.sfx, false); } - } else - actor->aimAssist.framesSinceAimAssist = 32768;//Make sure there's no delay the next time you draw your bow or whatever. - - } - - if (actor->policy.callback != NULL) - actor->policy.callback(actor); - else - ActorAccessibility_PlaySoundForActor(actor, 0, actor->policy.sound, false); - + } else + actor->aimAssist.framesSinceAimAssist = + 32768; // Make sure there's no delay the next time you draw your bow or whatever. } - void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play) { - - Player* player = GET_PLAYER(play); - if (play->sceneNum != aa->currentScene) - { - ActorAccessibility_StopAllVirtualActors(aa->currentEverywhere); - ActorAccessibility_StopAllVirtualActors(aa->currentSceneGlobal); - ActorAccessibility_StopAllVirtualActors(aa->currentRoomLocal); - aa->currentEverywhere = ActorAccessibility_GetVirtualActorList(EVERYWHERE, 0); - aa->currentSceneGlobal = ActorAccessibility_GetVirtualActorList(play->sceneNum, -1); - aa->currentScene = play->sceneNum; - aa->currentRoomLocal = NULL; - aa->currentRoom = -1; - } - if (aa->currentRoom != play->roomCtx.curRoom.num) - { - ActorAccessibility_StopAllVirtualActors(aa->currentRoomLocal); - aa->currentRoomLocal = ActorAccessibility_GetVirtualActorList(play->sceneNum, play->roomCtx.curRoom.num); - aa->currentRoom = play->roomCtx.curRoom.num; + if (actor->policy.callback != NULL) + actor->policy.callback(actor); + else + ActorAccessibility_PlaySoundForActor(actor, 0, actor->policy.sound, false); +} +void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play) { - } - if (aa->glossary->currentScene != play->sceneNum || aa->glossary->currentRoom != play->roomCtx.curRoom.num) { - if (aa->glossary->GlossaryStarted = true) { - aa->glossary->cooldown = 0; - aa->glossary->GlossaryStarted = false; - freezeActors = false; - - } - - } - if (player->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE) { - return; - } - ActorAccessibility_AudioGlossary(play); - if (aa->glossary->GlossaryStarted) { - - return; - } - //Real actors. - for (AccessibleActorList_t::iterator i = aa->accessibleActorList.begin(); i != aa->accessibleActorList.end(); i++) - ActorAccessibility_RunAccessibilityForActor(play, &i->second); -//Virtual actors in the "everywhere" group. - VAList_t* list = (VAList_t*)aa->currentEverywhere; - - for (VAList_t::iterator i = list->begin(); i != list->end(); i++) - ActorAccessibility_RunAccessibilityForActor(play, &(*i)); -//Virtual actors for the current room and scene. - list = (VAList_t*)aa->currentRoomLocal; - for (VAList_t::iterator i = list->begin(); i != list->end(); i++) - ActorAccessibility_RunAccessibilityForActor(play, &(*i)); - //Scene-global virtual actors. Most of these are automatically generated VAs from polygons, because there's no way to sort these into rooms. - list = (VAList_t*)aa->currentSceneGlobal; - for (VAList_t::iterator i = list->begin(); i != list->end(); i++) - ActorAccessibility_RunAccessibilityForActor(play, &(*i)); - - - - //Processes external audio engine. - ActorAccessibility_PrepareNextAudioFrame(); + Player* player = GET_PLAYER(play); + if (play->sceneNum != aa->currentScene) { + ActorAccessibility_StopAllVirtualActors(aa->currentEverywhere); + ActorAccessibility_StopAllVirtualActors(aa->currentSceneGlobal); + ActorAccessibility_StopAllVirtualActors(aa->currentRoomLocal); + aa->currentEverywhere = ActorAccessibility_GetVirtualActorList(EVERYWHERE, 0); + aa->currentSceneGlobal = ActorAccessibility_GetVirtualActorList(play->sceneNum, -1); + aa->currentScene = play->sceneNum; + aa->currentRoomLocal = NULL; + aa->currentRoom = -1; } - - void ActorAccessibility_AudioGlossary(PlayState* play) { - - if (aa->glossary->GlossaryStarted) { - - freezeActors = true; - AccessibleActor glossaryActor = (*aa->glossary->current).second; - ActorAccessibility_CopyParamsFromRealActor(&glossaryActor); - glossaryActor.policy.distance = glossaryActor.xzDistToPlayer * 3; - glossaryActor.policy.ydist = 1000; - glossaryActor.frameCount = aa->glossary->frameCount; - ActorAccessibility_RunAccessibilityForActor(play, &glossaryActor); - } - if (aa->glossary->cooldown != 0) { - aa->glossary->cooldown--; - return; - } - - OSContPad* trackerButtonsPressed = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); - bool comboStartGlossary = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & buttons[10] && - trackerButtonsPressed[0].button & buttons[6]; - if (comboStartGlossary) { - aa->glossary->GlossaryStarted = true; - aa->glossary->current = aa->accessibleActorList.begin(); - aa->glossary->currentScene = play->sceneNum; - aa->glossary->currentRoom = play->roomCtx.curRoom.num; - SpeechSynthesizer::Instance->Speak((*aa->glossary->current).second.policy.englishName, GetLanguageCode()); - return; - } - bool comboNextGlossary = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & buttons[13] && - trackerButtonsPressed[0].button & buttons[6]; - if (comboNextGlossary && aa->glossary->GlossaryStarted) { - aa->glossary->current++; - if (aa->glossary->current == aa->accessibleActorList.end()) { - aa->glossary->current = aa->accessibleActorList.begin(); - }; - aa->glossary->cooldown = 5; - SpeechSynthesizer::Instance->Speak((*aa->glossary->current).second.policy.englishName, GetLanguageCode()); - } - bool comboPrevGlossary = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & buttons[12] && - trackerButtonsPressed[0].button & buttons[6]; - if (comboPrevGlossary && aa->glossary->GlossaryStarted) { - if (aa->glossary->current != aa->accessibleActorList.begin()) { - aa->glossary->current--; - } - aa->glossary->cooldown = 5; - - - SpeechSynthesizer::Instance->Speak((*aa->glossary->current).second.policy.englishName, GetLanguageCode()); - - } - bool comboDisableGlossary = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & buttons[11] && - trackerButtonsPressed[0].button & buttons[6]; - if (comboDisableGlossary) { + if (aa->currentRoom != play->roomCtx.curRoom.num) { + ActorAccessibility_StopAllVirtualActors(aa->currentRoomLocal); + aa->currentRoomLocal = ActorAccessibility_GetVirtualActorList(play->sceneNum, play->roomCtx.curRoom.num); + aa->currentRoom = play->roomCtx.curRoom.num; + } + if (aa->glossary->currentScene != play->sceneNum || aa->glossary->currentRoom != play->roomCtx.curRoom.num) { + if (aa->glossary->GlossaryStarted = true) { aa->glossary->cooldown = 0; aa->glossary->GlossaryStarted = false; freezeActors = false; } - // Processes external audio engine. - ActorAccessibility_PrepareNextAudioFrame(); - + } + if (player->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE) { + return; + } + ActorAccessibility_AudioGlossary(play); + if (aa->glossary->GlossaryStarted) { + + return; + } + // Real actors. + for (AccessibleActorList_t::iterator i = aa->accessibleActorList.begin(); i != aa->accessibleActorList.end(); i++) + ActorAccessibility_RunAccessibilityForActor(play, &i->second); + // Virtual actors in the "everywhere" group. + VAList_t* list = (VAList_t*)aa->currentEverywhere; + + for (VAList_t::iterator i = list->begin(); i != list->end(); i++) + ActorAccessibility_RunAccessibilityForActor(play, &(*i)); + // Virtual actors for the current room and scene. + list = (VAList_t*)aa->currentRoomLocal; + for (VAList_t::iterator i = list->begin(); i != list->end(); i++) + ActorAccessibility_RunAccessibilityForActor(play, &(*i)); + // Scene-global virtual actors. Most of these are automatically generated VAs from polygons, because there's no way + // to sort these into rooms. + list = (VAList_t*)aa->currentSceneGlobal; + for (VAList_t::iterator i = list->begin(); i != list->end(); i++) + ActorAccessibility_RunAccessibilityForActor(play, &(*i)); + + // Processes external audio engine. + ActorAccessibility_PrepareNextAudioFrame(); +} + +void ActorAccessibility_AudioGlossary(PlayState* play) { + + if (aa->glossary->GlossaryStarted) { + + freezeActors = true; + AccessibleActor glossaryActor = (*aa->glossary->current).second; + ActorAccessibility_CopyParamsFromRealActor(&glossaryActor); + glossaryActor.policy.distance = glossaryActor.xzDistToPlayer * 3; + glossaryActor.policy.ydist = 1000; + glossaryActor.frameCount = aa->glossary->frameCount; + ActorAccessibility_RunAccessibilityForActor(play, &glossaryActor); + } + if (aa->glossary->cooldown != 0) { + aa->glossary->cooldown--; + return; } - - //Virtual actor config. - VirtualActorList* ActorAccessibility_GetVirtualActorList(s16 sceneNum, s8 roomNum) - { - SceneAndRoom sr; - sr.values.sceneIndex = sceneNum; - sr.values.roomIndex = roomNum; - if (sceneNum == EVERYWHERE) - sr.values.sceneIndex = EVERYWHERE; - - VAList_t* l = &aa->vaZones[sr.raw]; - return (VirtualActorList*)l; - + OSContPad* trackerButtonsPressed = + std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + bool comboStartGlossary = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & buttons[10] && + trackerButtonsPressed[0].button & buttons[6]; + if (comboStartGlossary) { + aa->glossary->GlossaryStarted = true; + aa->glossary->current = aa->accessibleActorList.begin(); + aa->glossary->currentScene = play->sceneNum; + aa->glossary->currentRoom = play->roomCtx.curRoom.num; + SpeechSynthesizer::Instance->Speak((*aa->glossary->current).second.policy.englishName, GetLanguageCode()); + return; } - AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRTUAL_ACTOR_TABLE type, PosRot where) - { - ActorAccessibilityPolicy* policy = ActorAccessibility_GetPolicyForActor(type); - if (policy == NULL) - return NULL; - - AccessibleActor actor; - actor.actor = NULL; - actor.basePitch = 1.0; - actor.baseVolume = 1.0; - actor.currentPitch = 1.0; - actor.currentVolume = 1.0; - actor.frameCount = 0; - actor.id = (s16)type; - actor.instanceID = ActorAccessibility_GetNextID(); - actor.isDrawn = 1; - actor.play = NULL; - actor.world = where; - actor.sceneIndex = 0; - for (int i = 0; i < NUM_MANAGED_SOUND_SLOTS; i++) - actor.managedSoundSlots[i] = 0; - actor.aimAssist.framesSinceAimAssist = 0; - actor.aimAssist.frequency = 10; - actor.aimAssist.pitch = 1.0; - - actor.policy = *policy; - VAList_t* l = (VAList_t*)list; - l->push_back(actor); - size_t index = l->size() - 1; - AccessibleActor* savedActor = &(*l)[l->size() - 1]; - if (policy->initUserData && !policy->initUserData(savedActor)) { - l->pop_back(); - - return NULL; // Probably a malloc error preventing user data initialization. + bool comboNextGlossary = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & buttons[13] && + trackerButtonsPressed[0].button & buttons[6]; + if (comboNextGlossary && aa->glossary->GlossaryStarted) { + aa->glossary->current++; + if (aa->glossary->current == aa->accessibleActorList.end()) { + aa->glossary->current = aa->accessibleActorList.begin(); + }; + aa->glossary->cooldown = 5; + SpeechSynthesizer::Instance->Speak((*aa->glossary->current).second.policy.englishName, GetLanguageCode()); + } + bool comboPrevGlossary = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & buttons[12] && + trackerButtonsPressed[0].button & buttons[6]; + if (comboPrevGlossary && aa->glossary->GlossaryStarted) { + if (aa->glossary->current != aa->accessibleActorList.begin()) { + aa->glossary->current--; } - return savedActor; + aa->glossary->cooldown = 5; + SpeechSynthesizer::Instance->Speak((*aa->glossary->current).second.policy.englishName, GetLanguageCode()); } - void ActorAccessibility_InterpretCurrentScene(PlayState* play) - { - if (aa->sceneList.contains(play->sceneNum)) - return;//Scene interpretation already complete for this scene. - aa->sceneList.insert(play->sceneNum); - VirtualActorList* list = ActorAccessibility_GetVirtualActorList(play->sceneNum, -1);//Scene-global VAs. - if (list == NULL) - return; - for (int i = 0; i < play->colCtx.colHeader->numPolygons; i++) - { - CollisionPoly* poly = &play->colCtx.colHeader->polyList[i]; - // checks if climable - if ((func_80041DB8(&play->colCtx, poly, BGCHECK_SCENE) == 8 || func_80041DB8(&play->colCtx, poly, BGCHECK_SCENE) == 3)) { + bool comboDisableGlossary = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & buttons[11] && + trackerButtonsPressed[0].button & buttons[6]; + if (comboDisableGlossary) { + aa->glossary->cooldown = 0; + aa->glossary->GlossaryStarted = false; + freezeActors = false; + } + // Processes external audio engine. + ActorAccessibility_PrepareNextAudioFrame(); +} + +// Virtual actor config. +VirtualActorList* ActorAccessibility_GetVirtualActorList(s16 sceneNum, s8 roomNum) { + SceneAndRoom sr; + sr.values.sceneIndex = sceneNum; + sr.values.roomIndex = roomNum; + if (sceneNum == EVERYWHERE) + sr.values.sceneIndex = EVERYWHERE; + + VAList_t* l = &aa->vaZones[sr.raw]; + return (VirtualActorList*)l; +} +AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRTUAL_ACTOR_TABLE type, PosRot where) { + ActorAccessibilityPolicy* policy = ActorAccessibility_GetPolicyForActor(type); + if (policy == NULL) + return NULL; + + AccessibleActor actor; + actor.actor = NULL; + actor.basePitch = 1.0; + actor.baseVolume = 1.0; + actor.currentPitch = 1.0; + actor.currentVolume = 1.0; + actor.frameCount = 0; + actor.id = (s16)type; + actor.instanceID = ActorAccessibility_GetNextID(); + actor.isDrawn = 1; + actor.play = NULL; + actor.world = where; + actor.sceneIndex = 0; + for (int i = 0; i < NUM_MANAGED_SOUND_SLOTS; i++) + actor.managedSoundSlots[i] = 0; + actor.aimAssist.framesSinceAimAssist = 0; + actor.aimAssist.frequency = 10; + actor.aimAssist.pitch = 1.0; + + actor.policy = *policy; + VAList_t* l = (VAList_t*)list; + l->push_back(actor); + size_t index = l->size() - 1; + AccessibleActor* savedActor = &(*l)[l->size() - 1]; + if (policy->initUserData && !policy->initUserData(savedActor)) { + l->pop_back(); + + return NULL; // Probably a malloc error preventing user data initialization. + } + return savedActor; +} +void ActorAccessibility_InterpretCurrentScene(PlayState* play) { + if (aa->sceneList.contains(play->sceneNum)) + return; // Scene interpretation already complete for this scene. + aa->sceneList.insert(play->sceneNum); + VirtualActorList* list = ActorAccessibility_GetVirtualActorList(play->sceneNum, -1); // Scene-global VAs. + if (list == NULL) + return; + for (int i = 0; i < play->colCtx.colHeader->numPolygons; i++) { + CollisionPoly* poly = &play->colCtx.colHeader->polyList[i]; + // checks if climable + if ((func_80041DB8(&play->colCtx, poly, BGCHECK_SCENE) == 8 || + func_80041DB8(&play->colCtx, poly, BGCHECK_SCENE) == 3)) { ActorAccessibility_PolyToVirtualActor(play, poly, VA_CLIMB, list); - } - if (SurfaceType_IsWallDamage(&play->colCtx, poly, BGCHECK_SCENE)) { - ActorAccessibility_PolyToVirtualActor(play, poly, VA_SPIKE, list); - } - if (SurfaceType_GetSceneExitIndex(&play->colCtx, poly, BGCHECK_SCENE) != 0) - ActorAccessibility_PolyToVirtualActor(play, poly, VA_AREA_CHANGE, list); - /*s8 floorparam = func_80041D4C(&play->colCtx, poly, BGCHECK_SCENE); - if (floorparam == 2) { - ActorAccessibility_PolyToVirtualActor(play, poly, VA_SPIKE, list); - }*/ - } - - } -//Convert poly to VA. - void ActorAccessibility_PolyToVirtualActor(PlayState* play, CollisionPoly* poly, VIRTUAL_ACTOR_TABLE va, VirtualActorList* destination) - { - Vec3f polyVerts[3]; - CollisionPoly_GetVertices(poly, play->colCtx.colHeader->vtxList, polyVerts); - PosRot where; - where.pos.y = std::min(polyVerts[0].y, std::min(polyVerts[1].y, polyVerts[2].y)); - f32 minX = std::min(polyVerts[0].x, std::min(polyVerts[1].x, polyVerts[2].x)); - f32 maxX = std::max(polyVerts[0].x, std::max(polyVerts[1].x, polyVerts[2].x)); - f32 minZ = std::min(polyVerts[0].z, std::min(polyVerts[1].z, polyVerts[2].z)); - f32 maxZ = std::max(polyVerts[0].z, std::max(polyVerts[1].z, polyVerts[2].z)); - where.pos.x = maxX - ((maxX - minX) / 2); - where.pos.z = maxZ - ((maxZ - minZ) / 2); - where.rot = { 0, 0, 0 }; - AccessibleActor* actor = ActorAccessibility_AddVirtualActor(destination, va, where); - if (actor == NULL) - return; - if (va == VA_AREA_CHANGE) { - actor->sceneIndex = SurfaceType_GetSceneExitIndex(&play->colCtx, poly, BGCHECK_SCENE); - s16 nextEntranceIndex = play->setupExitList[actor->sceneIndex - 1]; - actor->sceneIndex = gEntranceTable[nextEntranceIndex].scene; - } - } - void ActorAccessibility_AnnounceRoomNumber(PlayState* play) - { - std::stringstream ss; - ss << "Room" << (int)play->roomCtx.curRoom.num; - if (Flags_GetClear(play, play->roomCtx.curRoom.num)) - ss << ", completed." << std::endl; - else - ss << "." << std::endl; - SpeechSynthesizer::Instance->Speak(ss.str().c_str(), GetLanguageCode()); - - } - //Aim cue support. - void ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* actor) - { - Player* player = GET_PLAYER(actor->play); - // 16384 - s32 angle = player->actor.focus.rot.x; - angle = angle / -14000.0 * 16384; - f32 slope = Math_SinS(angle) / Math_CosS(angle)*1.0; - s32 yIntercept = (slope * (actor->xzDistToPlayer)) + player->actor.focus.pos.y; - s32 yHight = actor->actor->world.pos.y+25; - if (slope < 1) { - slope = 1; - } - s32 correction = (1 - 1 / slope)*100; - if ((yIntercept) > yHight + 25) { - actor->aimAssist.pitch = 1.5; - } else if ((yIntercept) < yHight - 25) { - actor->aimAssist.pitch = 0.5; - } - s32 yDiff = fabs(yIntercept-yHight); - if (yIntercept - yHight > 0) { - yDiff -= correction; - if (yDiff < 0) { - yDiff = 0; - } - } - if (yDiff > 300) { - actor->aimAssist.frequency = 30; - } else { - actor->aimAssist.frequency = 1 + (uint8_t)(yDiff / 5); - } - } - - //External audio engine stuff. - bool ActorAccessibility_InitAudio() { - try { - aa->audioEngine = new AccessibleAudioEngine(); - } catch (...) { - aa->audioEngine = NULL; - return false; } - return true; + if (SurfaceType_IsWallDamage(&play->colCtx, poly, BGCHECK_SCENE)) { + ActorAccessibility_PolyToVirtualActor(play, poly, VA_SPIKE, list); + } + if (SurfaceType_GetSceneExitIndex(&play->colCtx, poly, BGCHECK_SCENE) != 0) + ActorAccessibility_PolyToVirtualActor(play, poly, VA_AREA_CHANGE, list); + /*s8 floorparam = func_80041D4C(&play->colCtx, poly, BGCHECK_SCENE); + if (floorparam == 2) { + ActorAccessibility_PolyToVirtualActor(play, poly, VA_SPIKE, list); + }*/ } - void ActorAccessibility_ShutdownAudio() { - if (aa->isOn == 0) - return; - delete aa->audioEngine; +} +// Convert poly to VA. +void ActorAccessibility_PolyToVirtualActor(PlayState* play, CollisionPoly* poly, VIRTUAL_ACTOR_TABLE va, + VirtualActorList* destination) { + Vec3f polyVerts[3]; + CollisionPoly_GetVertices(poly, play->colCtx.colHeader->vtxList, polyVerts); + PosRot where; + where.pos.y = std::min(polyVerts[0].y, std::min(polyVerts[1].y, polyVerts[2].y)); + f32 minX = std::min(polyVerts[0].x, std::min(polyVerts[1].x, polyVerts[2].x)); + f32 maxX = std::max(polyVerts[0].x, std::max(polyVerts[1].x, polyVerts[2].x)); + f32 minZ = std::min(polyVerts[0].z, std::min(polyVerts[1].z, polyVerts[2].z)); + f32 maxZ = std::max(polyVerts[0].z, std::max(polyVerts[1].z, polyVerts[2].z)); + where.pos.x = maxX - ((maxX - minX) / 2); + where.pos.z = maxZ - ((maxZ - minZ) / 2); + where.rot = { 0, 0, 0 }; + AccessibleActor* actor = ActorAccessibility_AddVirtualActor(destination, va, where); + if (actor == NULL) + return; + if (va == VA_AREA_CHANGE) { + actor->sceneIndex = SurfaceType_GetSceneExitIndex(&play->colCtx, poly, BGCHECK_SCENE); + s16 nextEntranceIndex = play->setupExitList[actor->sceneIndex - 1]; + actor->sceneIndex = gEntranceTable[nextEntranceIndex].scene; } - void ActorAccessibility_MixAccessibleAudioWithGameAudio(int16_t* ogBuffer, uint32_t nFrames) { - if (aa->isOn == 0) - return; - - aa->audioEngine->mix(ogBuffer, nFrames); - +} +void ActorAccessibility_AnnounceRoomNumber(PlayState* play) { + std::stringstream ss; + ss << "Room" << (int)play->roomCtx.curRoom.num; + if (Flags_GetClear(play, play->roomCtx.curRoom.num)) + ss << ", completed." << std::endl; + else + ss << "." << std::endl; + SpeechSynthesizer::Instance->Speak(ss.str().c_str(), GetLanguageCode()); +} +// Aim cue support. +void ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* actor) { + Player* player = GET_PLAYER(actor->play); + // 16384 + s32 angle = player->actor.focus.rot.x; + angle = angle / -14000.0 * 16384; + f32 slope = Math_SinS(angle) / Math_CosS(angle) * 1.0; + s32 yIntercept = (slope * (actor->xzDistToPlayer)) + player->actor.focus.pos.y; + s32 yHight = actor->actor->world.pos.y + 25; + if (slope < 1) { + slope = 1; } - // Map one of the game's sfx to a path which as understood by the external audio engine. The returned token is a - // short hex string that can be passed directly to the audio engine. - const char* ActorAccessibility_MapSfxToExternalAudio(s16 sfxId) - { - SfxRecord* record; - auto it = aa->sfxMap.find(sfxId); - if (it == aa->sfxMap.end()) - { - SfxRecord tempRecord; - std::string fullPath = SfxExtractor::getExternalFileName(sfxId); - auto res = std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fullPath)); - -if(res == nullptr) -return NULL;//Resource doesn't exist, user's gotta run the extractor. - tempRecord.resource = res; - std::stringstream ss; - ss << std::setw(4) << std::setfill('0') << std::hex << sfxId; - tempRecord.path = ss.str(); - aa->sfxMap[sfxId] = tempRecord; - record = &aa->sfxMap[sfxId]; - aa->audioEngine->cacheDecodedSample(record->path, record->resource->GetRawPointer(), - record->resource->GetPointerSize()); - } else - record = &it->second; - - return record->path.c_str(); - - + s32 correction = (1 - 1 / slope) * 100; + if ((yIntercept) > yHight + 25) { + actor->aimAssist.pitch = 1.5; + } else if ((yIntercept) < yHight - 25) { + actor->aimAssist.pitch = 0.5; } -//Map the path to a raw sample to the external audio engine. - const char* ActorAccessibility_MapRawSampleToExternalAudio(const char* name) - { - SfxRecord* record; - std::string key(name); - auto it = aa->sampleMap.find(key); - if (it == aa->sampleMap.end()) { - SfxRecord tempRecord; - std::stringstream ss; - ss << "audio/samples/" << key; - std::string fullPath = ss.str(); - auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fullPath); - if (res == nullptr) -return NULL; // Resource doesn't exist, user's gotta run the extractor. - AudioDecoder decoder; - decoder.setSample((SOH::AudioSample*)res.get()); - s16* wav; - size_t wavSize = decoder.decodeToWav(&wav); - - tempRecord.path = key; - tempRecord.decodedSample = std::make_shared(wav); - aa->sampleMap[key] = tempRecord; - record = &aa->sampleMap[key]; - aa->audioEngine->cacheDecodedSample(record->path, wav, - wavSize); - } else - record = &it->second; - - return record->path.c_str(); + s32 yDiff = fabs(yIntercept - yHight); + if (yIntercept - yHight > 0) { + yDiff -= correction; + if (yDiff < 0) { + yDiff = 0; + } } - // Call once per frame to tell the audio engine to start working on the latest batch of queued instructions. - - void ActorAccessibility_PrepareNextAudioFrame() { - aa->audioEngine->prepare(); - + if (yDiff > 300) { + actor->aimAssist.frequency = 30; + } else { + actor->aimAssist.frequency = 1 + (uint8_t)(yDiff / 5); } - void ActorAccessibility_HandleSoundExtractionMode(PlayState* play) - { - aa->sfxExtractor.frameCallback(); +} +// External audio engine stuff. +bool ActorAccessibility_InitAudio() { + try { + aa->audioEngine = new AccessibleAudioEngine(); + } catch (...) { + aa->audioEngine = NULL; + return false; } + return true; +} +void ActorAccessibility_ShutdownAudio() { + if (aa->isOn == 0) + return; + delete aa->audioEngine; +} +void ActorAccessibility_MixAccessibleAudioWithGameAudio(int16_t* ogBuffer, uint32_t nFrames) { + if (aa->isOn == 0) + return; - void ActorAccessibility_DoSoundExtractionStep() - { - aa->sfxExtractor.captureCallback(); + aa->audioEngine->mix(ogBuffer, nFrames); +} +// Map one of the game's sfx to a path which as understood by the external audio engine. The returned token is a +// short hex string that can be passed directly to the audio engine. +const char* ActorAccessibility_MapSfxToExternalAudio(s16 sfxId) { + SfxRecord* record; + auto it = aa->sfxMap.find(sfxId); + if (it == aa->sfxMap.end()) { + SfxRecord tempRecord; + std::string fullPath = SfxExtractor::getExternalFileName(sfxId); + auto res = std::static_pointer_cast( + Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fullPath)); - } + if (res == nullptr) + return NULL; // Resource doesn't exist, user's gotta run the extractor. + tempRecord.resource = res; + std::stringstream ss; + ss << std::setw(4) << std::setfill('0') << std::hex << sfxId; + tempRecord.path = ss.str(); + aa->sfxMap[sfxId] = tempRecord; + record = &aa->sfxMap[sfxId]; + aa->audioEngine->cacheDecodedSample(record->path, record->resource->GetRawPointer(), + record->resource->GetPointerSize()); + } else + record = &it->second; + return record->path.c_str(); +} +// Map the path to a raw sample to the external audio engine. +const char* ActorAccessibility_MapRawSampleToExternalAudio(const char* name) { + SfxRecord* record; + std::string key(name); + auto it = aa->sampleMap.find(key); + if (it == aa->sampleMap.end()) { + SfxRecord tempRecord; + std::stringstream ss; + ss << "audio/samples/" << key; + std::string fullPath = ss.str(); + auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(fullPath); + if (res == nullptr) + return NULL; // Resource doesn't exist, user's gotta run the extractor. + AudioDecoder decoder; + decoder.setSample((SOH::AudioSample*)res.get()); + s16* wav; + size_t wavSize = decoder.decodeToWav(&wav); + tempRecord.path = key; + tempRecord.decodedSample = std::make_shared(wav); + aa->sampleMap[key] = tempRecord; + record = &aa->sampleMap[key]; + aa->audioEngine->cacheDecodedSample(record->path, wav, wavSize); + } else + record = &it->second; + + return record->path.c_str(); +} +// Call once per frame to tell the audio engine to start working on the latest batch of queued instructions. + +void ActorAccessibility_PrepareNextAudioFrame() { + aa->audioEngine->prepare(); +} +void ActorAccessibility_HandleSoundExtractionMode(PlayState* play) { + aa->sfxExtractor.frameCallback(); +} + +void ActorAccessibility_DoSoundExtractionStep() { + aa->sfxExtractor.captureCallback(); +} diff --git a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h index 2265e4fc1..fda9b1034 100644 --- a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h +++ b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h @@ -4,7 +4,9 @@ #ifdef __cplusplus extern "C" { #endif - #define NUM_MANAGED_SOUND_SLOTS 10 //How many auto-managed sound slots can any given actor have? this can differ from AAE_SLOTS_PER_HANDLE, but cannot be greater. +#define NUM_MANAGED_SOUND_SLOTS \ + 10 // How many auto-managed sound slots can any given actor have? this can differ from AAE_SLOTS_PER_HANDLE, but + // cannot be greater. struct AccessibleActor; typedef struct AccessibleActor AccessibleActor; // A callback that is run regularely as the game progresses in order to provide accessibility services for an actor. @@ -28,20 +30,20 @@ typedef struct { int n; // How often to run the callback in frames. f32 distance; // Maximum xz distance from player before the actor should be considered out of range. - f32 ydist; // Maximum y distance from player before the actor should be considered out of range. + f32 ydist; // Maximum y distance from player before the actor should be considered out of range. f32 pitch; f32 volume; f32 pitchModifier; bool runsAlways; // If set, then the distance policy is ignored. ActorAccessibilityUserDataInit initUserData; ActorAccessibilityUserDataCleanup cleanupUserData; -//Aim assist settings. + // Aim assist settings. struct { - bool isProvider;//determines whether or not this actor supports aim assist. - s16 sfx; // The sound to play when this actor provides aim assist. Uses sound slot 9. - f32 tolerance; // How close to the center of the actor does Link have to aim for aim assist to consider - // it lined up. - }aimAssist; + bool isProvider; // determines whether or not this actor supports aim assist. + s16 sfx; // The sound to play when this actor provides aim assist. Uses sound slot 9. + f32 tolerance; // How close to the center of the actor does Link have to aim for aim assist to consider + // it lined up. + } aimAssist; } ActorAccessibilityPolicy; @@ -71,8 +73,10 @@ struct AccessibleActor { f32 basePitch; f32 currentPitch; - s16 sceneIndex;//If this actor represents a scene transition, then this will contain the destination scene index. Zero otherwise. - bool managedSoundSlots[NUM_MANAGED_SOUND_SLOTS];//These have their attenuation and panning parameters updated every frame automatically. + s16 sceneIndex; // If this actor represents a scene transition, then this will contain the destination scene index. + // Zero otherwise. + bool managedSoundSlots[NUM_MANAGED_SOUND_SLOTS]; // These have their attenuation and panning parameters updated + // every frame automatically. struct { u16 framesSinceAimAssist; // Allows rate-based vertical aim assist. Incremented every frame for aim assist // actors. Manually reset by aim assist provider. @@ -99,22 +103,25 @@ void ActorAccessibility_AddSupportedActor(s16 type, ActorAccessibilityPolicy pol void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActor* actor); void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play); /* -*Play sounds (usually from the game) using the external sound engine. This is probably not the function you want to call most of the time (see below). -* handle: pointer to an arbitrary object. This object can be anything as it's only used as a classifier, but it's recommended that you use an AccessibleActor* as your handle whenever possible. Using AccessibleActor* as the handle gives you automatic cleanup when the actor is killed. -* slot: Allows multiple sounds to be assigned to a single handle. The maximum number of slots per actor is 10 by default (but can be controlled by modifying AAE_SLOTS_PER_HANDLE). -* sfxId: one of the game's sfx IDs. Note that this plays prerendered sounds which you must have previously prepared. - *looping: whether to play the sound just once or on a continuous loop. -*/ + *Play sounds (usually from the game) using the external sound engine. This is probably not the function you want to + *call most of the time (see below). handle: pointer to an arbitrary object. This object can be anything as it's only + *used as a classifier, but it's recommended that you use an AccessibleActor* as your handle whenever possible. Using + *AccessibleActor* as the handle gives you automatic cleanup when the actor is killed. slot: Allows multiple sounds to + *be assigned to a single handle. The maximum number of slots per actor is 10 by default (but can be controlled by + *modifying AAE_SLOTS_PER_HANDLE). sfxId: one of the game's sfx IDs. Note that this plays prerendered sounds which you + *must have previously prepared. looping: whether to play the sound just once or on a continuous loop. + */ void ActorAccessibility_PlaySound(void* actor, int slot, s16 sfxId, bool looping); -//Play one of the game's internal samples. - void ActorAccessibility_PlayRawSample(void* handle, int slot, const char* name, bool looping); -// -//Stop a sound. Todo: consider making this a short fade instead of just cutting it off. +// Play one of the game's internal samples. +void ActorAccessibility_PlayRawSample(void* handle, int slot, const char* name, bool looping); +// +// Stop a sound. Todo: consider making this a short fade instead of just cutting it off. void ActorAccessibility_StopSound(void* handle, int slot); void ActorAccessibility_StopAllSounds(void* handle); void ActorAccessibility_SetSoundPitch(void* handle, int slot, float pitch); -//When we don't have access to something super fancy (such as HRTF), blind-accessible games generally use a change in pitch to tell the player that an object is behind the player. +// When we don't have access to something super fancy (such as HRTF), blind-accessible games generally use a change in +// pitch to tell the player that an object is behind the player. void ActorAccessibility_SetPitchBehindModifier(void* handle, int slot, float mod); void ActorAccessibility_SetListenerPos(Vec3f* pos, Vec3f* rot); @@ -125,18 +132,19 @@ void ActorAccessibility_SetSoundPan(void* handle, int slot, Vec3f* projectedPos) void ActorAccessibility_SetSoundFilter(void* handle, int slot, float cutoff); void ActorAccessibility_SeekSound(void* handle, int slot, size_t offset); - /* -* Play a sound on behalf of an AccessibleActor. -* This version includes automatic sound management: pitch, panning and attenuation parameters will be updated automatically based on the actor's position. -* -*/ +/* + * Play a sound on behalf of an AccessibleActor. + * This version includes automatic sound management: pitch, panning and attenuation parameters will be updated + * automatically based on the actor's position. + * + */ void ActorAccessibility_PlaySoundForActor(AccessibleActor* actor, int slot, s16 sfxId, bool looping); void ActorAccessibility_PlaySampleForActor(AccessibleActor* actor, int slot, const char* name, bool looping); void ActorAccessibility_StopSoundForActor(AccessibleActor* actor, int slot); void ActorAccessibility_StopAllSoundsForActor(AccessibleActor* actor); 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); void ActorAccessibility_InitCues(); // Stuff related to lists of virtual actors. @@ -153,38 +161,37 @@ typedef enum { VA_MARKER, VA_SPIKE, VA_GENERAL_HELPER, // Room announcements, action icon and other misc help. - VA_AUDIO_COMPASS,//Points north. - VA_STICK_WARNING,//beep when stick is about to burn out. + VA_AUDIO_COMPASS, // Points north. + VA_STICK_WARNING, // beep when stick is about to burn out. VA_FINAL, } VIRTUAL_ACTOR_TABLE; - #define EVERYWHERE -32768 // Denotes a virtual actor that is global/ omnipresent. // Get the list of virtual actors for a given scene and room index. VirtualActorList* ActorAccessibility_GetVirtualActorList(s16 sceneNum, s8 roomNum); AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRTUAL_ACTOR_TABLE type, PosRot where); -//Parses the loaded seen and converts select polygons (like ladders, spikes and scene exits) into virtual actors. +// Parses the loaded seen and converts select polygons (like ladders, spikes and scene exits) into virtual actors. void ActorAccessibility_InterpretCurrentScene(PlayState* play); -//Convert a collision polygon into a virtual actor. -void ActorAccessibility_PolyToVirtualActor(PlayState* play, CollisionPoly* poly, VIRTUAL_ACTOR_TABLE va, VirtualActorList* destination); -//Report which room of a dungeon the player is in. - void ActorAccessibility_AnnounceRoomNumber(PlayState* play); - //Aim cue support. - void ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* actor); - // External audio engine stuff. +// Convert a collision polygon into a virtual actor. +void ActorAccessibility_PolyToVirtualActor(PlayState* play, CollisionPoly* poly, VIRTUAL_ACTOR_TABLE va, + VirtualActorList* destination); +// Report which room of a dungeon the player is in. +void ActorAccessibility_AnnounceRoomNumber(PlayState* play); +// Aim cue support. +void ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* actor); +// External audio engine stuff. // Initialize the accessible audio engine. bool ActorAccessibility_InitAudio(); void ActorAccessibility_ShutdownAudio(); // Combine the games' audio with the output from AccessibleAudioEngine. To be called exclusively from the audio thread. void ActorAccessibility_MixAccessibleAudioWithGameAudio(int16_t* ogBuffer, uint32_t nFrames); void ActorAccessibility_HandleSoundExtractionMode(PlayState* play); -//This is called by the audio thread when it's ready to try to pull sfx from the game. +// This is called by the audio thread when it's ready to try to pull sfx from the game. void ActorAccessibility_DoSoundExtractionStep(); - void ActorAccessibility_AudioGlossary(PlayState* play); #ifdef __cplusplus } diff --git a/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp b/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp index 24d20f2dc..545d17708 100644 --- a/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp +++ b/soh/soh/Enhancements/accessible-actors/SfxExtractor.cpp @@ -92,13 +92,13 @@ void SfxExtractor::renderOutput() { void SfxExtractor::setup() { try { - - SpeechSynthesizer::Instance->Speak("Sfx extraction speedrun initiated. Please wait. This will take a few minutes.", GetLanguageCode()); + SpeechSynthesizer::Instance->Speak( + "Sfx extraction speedrun initiated. Please wait. This will take a few minutes.", GetLanguageCode()); // Kill the audio thread so we can take control. captureThreadState = CT_WAITING; OTRAudio_InstallSfxCaptureThread(); // Make sure we're starting from a clean slate. - std::string sohAccessibilityPath = Ship::Context::GetPathRelativeToAppDirectory("accessibility.otr"); + std::string sohAccessibilityPath = Ship::Context::GetPathRelativeToAppDirectory("accessibility.o2r"); if (std::filesystem::exists(sohAccessibilityPath)) { currentStep = STEP_ERROR_OTR; return; @@ -115,10 +115,11 @@ void SfxExtractor::setup() { for (int i = 1; i < 10; i++) { progressMilestones[i - 1] = sfxToRip.size() - ((int)ceil(sfxToRip.size() * (i / 10.0f))); } - archive = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->AddArchive("accessibility.otr"); - + archive = std::make_shared("accessibility.o2r"); + archive->Open(); } catch (...) { currentStep = STEP_ERROR; } } + void SfxExtractor::ripNextSfx() { { auto lock = OTRAudio_Lock(); @@ -143,7 +144,8 @@ void SfxExtractor::ripNextSfx() { sfxToRip.pop(); startOfInput = 0; endOfInput = 0; - Audio_PlaySoundGeneral(currentSfx, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(currentSfx, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); { auto lock = OTRAudio_Lock(); @@ -161,17 +163,18 @@ void SfxExtractor::finished() { Audio_QueueSeqCmd(NA_BGM_TITLE); if (currentStep == STEP_ERROR || currentStep == STEP_ERROR_OTR) { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); std::stringstream ss; ss << "Sorry, we tried to extract the sound effects, but Ganondorf overruled us with an iron fist." << std::endl; if (currentStep == STEP_ERROR_OTR) - ss << "In all seriousness, please delete accessibility.otr and try again."; + ss << "In all seriousness, please delete accessibility.o2r and try again."; SpeechSynthesizer::Instance->Speak(ss.str().c_str(), GetLanguageCode()); } else Audio_PlayFanfare(NA_BGM_ITEM_GET); - } void SfxExtractor::maybeGiveProgressReport() { size_t ripsRemaining = sfxToRip.size() + 1; @@ -188,7 +191,7 @@ SfxExtractor::SfxExtractor() { currentStep = STEP_SETUP; } - void SfxExtractor::frameCallback() { +void SfxExtractor::frameCallback() { switch (currentStep) { case STEP_SETUP: setup(); @@ -223,9 +226,9 @@ void SfxExtractor::captureCallback() { AudioMgr_CreateNextAudioBuffer(mark, SFX_EXTRACTION_ONE_FRAME); if (!outputStarted && isAllZero(mark, SFX_EXTRACTION_ONE_FRAME * 2)) { -waitTime++; + waitTime++; if (waitTime < 300) - continue;//Output is silent, allow more time for audio to begin. + continue; // Output is silent, allow more time for audio to begin. captureThreadState = CT_FINISHED; // Sound is unavailable, so skip over it and move on. return; } diff --git a/soh/soh/Enhancements/accessible-actors/SfxTable.h b/soh/soh/Enhancements/accessible-actors/SfxTable.h index 912654a9b..4933895a6 100644 --- a/soh/soh/Enhancements/accessible-actors/SfxTable.h +++ b/soh/soh/Enhancements/accessible-actors/SfxTable.h @@ -1,6 +1,7 @@ #pragma once -//A big nasty array containing every SFX ID in the game. -//All of the "DUMMY's" and "YOBI's" have been removed as they produce duplicate sounds at best, and cause errors or even crashes at worst. +// A big nasty array containing every SFX ID in the game. +// All of the "DUMMY's" and "YOBI's" have been removed as they produce duplicate sounds at best, and cause errors or +// even crashes at worst. const s16 sfxTable[1207] = { NA_SE_PL_WALK_GROUND, diff --git a/soh/soh/Enhancements/accessible-actors/accessibility_cues.cpp b/soh/soh/Enhancements/accessible-actors/accessibility_cues.cpp index 9b7382ef7..64f45a25f 100644 --- a/soh/soh/Enhancements/accessible-actors/accessibility_cues.cpp +++ b/soh/soh/Enhancements/accessible-actors/accessibility_cues.cpp @@ -13,27 +13,29 @@ f32 BgCheck_RaycastFloorImpl(PlayState* play, CollisionContext* colCtx, u16 xpFl #include "soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h" #include "soh/Enhancements/tts/tts.h" } -# define DETECTION_DISTANCE 500.0 +#define DETECTION_DISTANCE 500.0 #define MIN_INCLINE_DISTANCE 5.0 #define MIN_DECLINE_DISTANCE 5.0 #define DEFAULT_PROBE_SPEED 5.5 #define NOMINMAX -static Player fakePlayer;//Used for wall height detection. +static Player fakePlayer; // Used for wall height detection. static Vec3f D_80854798 = { 0.0f, 18.0f, 0.0f }; // From z_player.c. const char* GetLanguageCode(); -enum { DISCOVERED_NOTHING = 0, -DISCOVERED_INCLINE, -DISCOVERED_DECLINE, -DISCOVERED_LEDGE, -DISCOVERED_WALL, -DISCOVERED_SPIKE, -DISCOVERED_WATER, -DISCOVERED_GROUND, -DISCOVERED_LAVA, +enum { + DISCOVERED_NOTHING = 0, + DISCOVERED_INCLINE, + DISCOVERED_DECLINE, + DISCOVERED_LEDGE, + DISCOVERED_WALL, + DISCOVERED_SPIKE, + DISCOVERED_WATER, + DISCOVERED_GROUND, + DISCOVERED_LAVA, }; -//Abstract class for terrain cue sound handling. Implementations should not allocate memory. These are always in-place constructed in static memory owned by the TerrainCueDirection object. +// Abstract class for terrain cue sound handling. Implementations should not allocate memory. These are always in-place +// constructed in static memory owned by the TerrainCueDirection object. class TerrainCueSound { protected: AccessibleActor* actor; @@ -42,7 +44,7 @@ class TerrainCueSound { f32 currentPitch; f32 xzDistToPlayer; s16 currentSFX; - int restFrames;//Used to control how often sounds get played. + int restFrames; // Used to control how often sounds get played. bool shouldLoop; // Call to start playback. @@ -50,7 +52,6 @@ class TerrainCueSound { ActorAccessibility_PlaySound(this, 0, currentSFX, shouldLoop); ActorAccessibility_SetSoundPos(this, 0, &terrainProjectedPos, xzDistToPlayer, actor->policy.distance); ActorAccessibility_SetSoundPitch(this, 0, currentPitch); - } // Call when terrain is no longer present to stop playback. @@ -58,12 +59,12 @@ class TerrainCueSound { ActorAccessibility_StopSound(this, 0); } - //Custom terrain sound behaviour. + // Custom terrain sound behaviour. virtual void run() = 0; // Update sound position and volume once per frame. virtual void updatePositions(Vec3f& pos) { terrainPos = pos; - Player* player = GET_PLAYER(actor->play); + Player* player = GET_PLAYER(actor->play); f32 w = 0.0f; // Set projectedPos. @@ -73,7 +74,6 @@ class TerrainCueSound { xzDistToPlayer = Math_Vec3f_DistXZ(&terrainPos, &player->actor.world.pos); ActorAccessibility_SetSoundPos(this, 0, &terrainProjectedPos, xzDistToPlayer, actor->policy.distance); ActorAccessibility_SetSoundPitch(this, 0, currentPitch); - } public: @@ -84,16 +84,13 @@ class TerrainCueSound { restFrames = 0; xzDistToPlayer = 0; currentSFX = 0; - } virtual ~TerrainCueSound() { stop(); - } void update(Vec3f& pos) { updatePositions(pos); run(); - } }; class Incline : protected TerrainCueSound { @@ -117,7 +114,7 @@ class Incline : protected TerrainCueSound { return; } - ActorAccessibility_SetSoundPitch(this, 0, 0.5 + (1-pitchModifier)); + ActorAccessibility_SetSoundPitch(this, 0, 0.5 + (1 - pitchModifier)); /*currentPitch += 0.1; if (currentPitch >= 2.0) { stop(); @@ -125,155 +122,141 @@ class Incline : protected TerrainCueSound { restFrames = 5; }*/ } - void setPitchModifier(float modifier) - { + void setPitchModifier(float modifier) { pitchModifier = modifier; - } }; class Decline : protected TerrainCueSound { float pitchModifier; - public: - Decline(AccessibleActor* actor, Vec3f pos, float pitchModifier) : TerrainCueSound(actor, pos) { - restFrames = 0; + public: + Decline(AccessibleActor* actor, Vec3f pos, float pitchModifier) : TerrainCueSound(actor, pos) { + restFrames = 0; + currentPitch = 2.0; + currentSFX = NA_SE_PL_MAGIC_SOUL_FLASH; + this->pitchModifier = 0.0; + + play(); + } + virtual ~Decline() { + } + virtual void run() { + if (restFrames > 0) { + restFrames--; + if (restFrames == 0) + play(); + + return; + } + ActorAccessibility_SetSoundPitch(this, 0, 1.0 + pitchModifier); + /*currentPitch -= 0.1; + if (currentPitch < 0.5) { + stop(); currentPitch = 2.0; - currentSFX = NA_SE_PL_MAGIC_SOUL_FLASH; - this->pitchModifier = 0.0; + restFrames = 5; + }*/ + } + void setPitchModifier(float mod) { + pitchModifier = mod; + } +}; +class Ledge : protected TerrainCueSound { + s8 savedType; // Distinguishes between a ledge link can fall from and one he can climb up. + Vec3s probeRot; - play(); - } - virtual ~Decline() { - } - virtual void run() { - if (restFrames > 0) { - restFrames--; - if (restFrames == 0) - play(); - - return; - } - ActorAccessibility_SetSoundPitch(this, 0, 1.0 + pitchModifier); - /*currentPitch -= 0.1; - if (currentPitch < 0.5) { - stop(); - currentPitch = 2.0; - restFrames = 5; - }*/ - } - void setPitchModifier(float mod) - { - pitchModifier = mod; - - } - - }; -class Ledge :protected TerrainCueSound { - s8 savedType;//Distinguishes between a ledge link can fall from and one he can climb up. - Vec3s probeRot; - - public: + public: Ledge(AccessibleActor* actor, Vec3f pos, Vec3s probeRot, s8 type = 0) : TerrainCueSound(actor, pos) { - if (type == 1) - currentPitch = 2.0; - savedType = type; - switch (type) { - case 0: - currentSFX = NA_SE_EV_WIND_TRAP; - shouldLoop = 1; - break; - - case 1: - currentSFX = NA_SE_EV_WOOD_BOUND; - shouldLoop = 0; - break; - case 2: - currentSFX = NA_SE_PL_LAND_WATER0; - shouldLoop = 0; - break; - case 3: - currentSFX = NA_SE_SY_WARNING_COUNT_N; - shouldLoop = 0; - break; - } - - this->probeRot = probeRot; - if (type == 0) { - if (probeRot.y == 0) - currentPitch = 0.4; - else if (probeRot.y < 0) - currentPitch = 0.2; - else - currentPitch = 0.8; + if (type == 1) + currentPitch = 2.0; + savedType = type; + switch (type) { + case 0: + currentSFX = NA_SE_EV_WIND_TRAP; + shouldLoop = 1; + break; + + case 1: + currentSFX = NA_SE_EV_WOOD_BOUND; + shouldLoop = 0; + break; + case 2: + currentSFX = NA_SE_PL_LAND_WATER0; + shouldLoop = 0; + break; + case 3: + currentSFX = NA_SE_SY_WARNING_COUNT_N; + shouldLoop = 0; + break; } - play(); + this->probeRot = probeRot; + if (type == 0) { + if (probeRot.y == 0) + currentPitch = 0.4; + else if (probeRot.y < 0) + currentPitch = 0.2; + else + currentPitch = 0.8; + } + play(); } virtual ~Ledge() { - } s8 type() { return savedType; - } void run() { - if (savedType==0) - return;//Downward ledges play a looping sound and do not need ongoing maintenance. - if (restFrames == 0) - { - play(); - restFrames = 10; - return; - + if (savedType == 0) + return; // Downward ledges play a looping sound and do not need ongoing maintenance. + if (restFrames == 0) { + play(); + restFrames = 10; + return; } restFrames--; - } - }; -class Platform: protected TerrainCueSound { +}; +class Platform : protected TerrainCueSound { public: Platform(AccessibleActor* actor, Vec3f pos) : TerrainCueSound(actor, pos) { currentPitch = 2.0; -//actor->policy.volume = 1.5; + // actor->policy.volume = 1.5; currentSFX = NA_SE_IT_SHIELD_REFLECT_SW; shouldLoop = false; - } virtual ~Platform() { } - void setActor(AccessibleActor* actor) - { + void setActor(AccessibleActor* actor) { this->actor = actor; - } - void setPosition(Vec3f& pos) - { + void setPosition(Vec3f& pos) { updatePositions(pos); } void run() { if (restFrames == 0) { - play(); - restFrames = 10; - return; + play(); + restFrames = 10; + return; } restFrames--; } }; -class Wall: protected TerrainCueSound { - int frames; +class Wall : protected TerrainCueSound { + int frames; Vec3s probeRot; - f32 targetPitch; + f32 targetPitch; + public: Wall(AccessibleActor* actor, Vec3f pos, Vec3s rot) : TerrainCueSound(actor, pos) { probeRot = rot; currentPitch = 0.5; - targetPitch = (f32) probeRot.y / (16384.0f * 2.0f); + targetPitch = (f32)probeRot.y / (16384.0f * 2.0f); if (probeRot.y != 0 && targetPitch < -0.4) - targetPitch = -0.4; + targetPitch = -0.4; currentSFX = NA_SE_IT_SWORD_CHARGE; @@ -288,18 +271,18 @@ class Wall: protected TerrainCueSound { frames++; if (frames == 20) { - frames = 0; - play(); - ActorAccessibility_SeekSound(this, 0, 44100 * 2); - } - f32 pitchModifier = 0.0; + frames = 0; + play(); + ActorAccessibility_SeekSound(this, 0, 44100 * 2); + } + f32 pitchModifier = 0.0; - if (targetPitch < 0) - pitchModifier = LERP(2.5, 0.5 + targetPitch, (f32)frames / 20.0f); - else if (targetPitch > 0) - pitchModifier = LERP(0.1, (0.5 + targetPitch), (f32)frames / 20.0f); + if (targetPitch < 0) + pitchModifier = LERP(2.5, 0.5 + targetPitch, (f32)frames / 20.0f); + else if (targetPitch > 0) + pitchModifier = LERP(0.1, (0.5 + targetPitch), (f32)frames / 20.0f); - ActorAccessibility_SetSoundPitch(this, 0, pitchModifier); + ActorAccessibility_SetSoundPitch(this, 0, pitchModifier); } }; class Spike : protected TerrainCueSound { @@ -341,6 +324,7 @@ class Water : protected TerrainCueSound { class Ground : protected TerrainCueSound { float pitchModifier; + public: Ground(AccessibleActor* actor, Vec3f pos, float pitchModifier) : TerrainCueSound(actor, pos) { currentPitch = 1.0; @@ -356,7 +340,7 @@ class Ground : protected TerrainCueSound { restFrames = 10; return; } - ActorAccessibility_SetSoundPitch(this, 0, 1.0 + (2*pitchModifier)); + ActorAccessibility_SetSoundPitch(this, 0, 1.0 + (2 * pitchModifier)); restFrames--; } void setPitchModifier(float modifier) { @@ -368,7 +352,7 @@ class Lava : protected TerrainCueSound { public: Lava(AccessibleActor* actor, Vec3f pos) : TerrainCueSound(actor, pos) { currentPitch = 1.0; - currentSFX = NA_SE_SY_WARNING_COUNT_N; //change? + currentSFX = NA_SE_SY_WARNING_COUNT_N; // change? play(); } virtual ~Lava() { @@ -383,9 +367,10 @@ class Lava : protected TerrainCueSound { } }; - class TerrainCueDirection { +class TerrainCueDirection { AccessibleActor* actor; - int startingBodyPart;//Decides where the probe starts from. Probes going out to the left or right of the player start from the shoulders. + int startingBodyPart; // Decides where the probe starts from. Probes going out to the left or right of the player + // start from the shoulders. Vec3f pos; Vec3f prevPos; Vec3s relRot; // Relative angle. @@ -464,7 +449,7 @@ class Lava : protected TerrainCueSound { destroyCurrentSound(); new (&decline) Decline(actor, pos, pitchModifier); - + currentSound = (TerrainCueSound*)&decline; terrainDiscovered = DISCOVERED_DECLINE; } @@ -484,10 +469,9 @@ class Lava : protected TerrainCueSound { void discoverWall(Vec3f pos) { Player* player = GET_PLAYER(actor->play); - if (player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON) - { + if (player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON) { if (terrainDiscovered == DISCOVERED_WALL) - destroyCurrentSound(); + destroyCurrentSound(); return; } if (terrainDiscovered == DISCOVERED_WALL) @@ -644,7 +628,7 @@ class Lava : protected TerrainCueSound { velocity.x += pushedSpeed * Math_SinS(pushedYaw); velocity.z += pushedSpeed * Math_CosS(pushedYaw); } - + bool checkPerpendicularWall(Vec3f_ ppos, Vec3s_ ogRot) { pos = ppos; Player* player = GET_PLAYER(actor->play); @@ -658,7 +642,6 @@ class Lava : protected TerrainCueSound { move(false); move(false); - rot = ogRot; rot.y += 16384; rot.y += 16384; @@ -688,7 +671,7 @@ class Lava : protected TerrainCueSound { return true; } wallPoly = checkWall(pos, prevPos, wallPos); - if (wallPoly == NULL || rdist(pos)>200) { + if (wallPoly == NULL || rdist(pos) > 200) { return false; } @@ -706,8 +689,8 @@ class Lava : protected TerrainCueSound { platform.run(); return true; } - return false; - } + return false; + } // Check if we're being pushed away from our intended destination. bool isPushedAway() { f32 dist = Math_Vec3f_DistXZ(&velocity, &expectedVelocity); @@ -793,9 +776,9 @@ class Lava : protected TerrainCueSound { return true; } pos.x += velocity.x; - + pos.z += velocity.z; - + if (gravity == 1) { pos.y += velocity.y; f32 floorHeight = 0; @@ -806,7 +789,6 @@ class Lava : protected TerrainCueSound { if (!BgCheck_PosInStaticBoundingBox(&actor->play->colCtx, &pos)) return false; // Out of bounds. } - return true; } @@ -845,15 +827,15 @@ class Lava : protected TerrainCueSound { return 0; } s8 floorparam = func_80041D4C(colCtx, floorpoly, BG_ACTOR_MAX); - if (floorparam == 2 || floorparam ==3) { - + if (floorparam == 2 || floorparam == 3) { + return 1; } else { return 0; } } - + void scan() { Player* player = GET_PLAYER(actor->play); @@ -881,13 +863,12 @@ class Lava : protected TerrainCueSound { rot = ActorAccessibility_ComputeRelativeAngle(&player->actor.world.rot, &relRot); pushedSpeed = 0.0; pushedYaw = 0; - probeSpeed = DEFAULT_PROBE_SPEED;//Experiment with this. + probeSpeed = DEFAULT_PROBE_SPEED; // Experiment with this. // Draw a line from Link's position to the max detection distance based on the configured relative angle. if (!trackingModeStarted) { pos = player->actor.world.pos; -//If a starting body part has been specified, then set the probe's initial X and Z position only. - if (startingBodyPart != PLAYER_BODYPART_MAX) - { + // If a starting body part has been specified, then set the probe's initial X and Z position only. + if (startingBodyPart != PLAYER_BODYPART_MAX) { pos.x = player->bodyPartsPos[startingBodyPart].x; pos.z = player->bodyPartsPos[startingBodyPart].y; } @@ -901,7 +882,8 @@ class Lava : protected TerrainCueSound { distToTravel = 1.0; Vec3f collisionResult; s32 bgId = 0; -//Don't be fooled: link being in the air does not mean we've found a dropoff. I mean... it could mean that, but it's a little too late to do anything about it at that point anyway. + // Don't be fooled: link being in the air does not mean we've found a dropoff. I mean... it could mean that, but + // it's a little too late to do anything about it at that point anyway. if (player->stateFlags3 & PLAYER_STATE3_MIDAIR || player->stateFlags2 & PLAYER_STATE2_HOPPING) { f32 floorHeight = 0; @@ -918,7 +900,7 @@ class Lava : protected TerrainCueSound { setVelocity(); f32 step = fabs(velocity.x + velocity.z); distToTravel -= (step + fabs(pos.y - pos.y)); - //checks if link is in the water, needs different logic + // checks if link is in the water, needs different logic if (player->stateFlags1 & PLAYER_STATE1_IN_WATER) { pos.y = player->actor.prevPos.y; if (!move()) { @@ -932,9 +914,9 @@ class Lava : protected TerrainCueSound { // is there an incline ahead that leads out of the water if (pos.y > player->actor.world.pos.y) { discoverIncline(pos); - break; + break; } - //keeps probe at links feet + // keeps probe at links feet if (pos.y < player->actor.world.pos.y) { pos.y = player->actor.world.pos.y; } @@ -945,21 +927,20 @@ class Lava : protected TerrainCueSound { continue; } - //sets probe to be at surface of water + // sets probe to be at surface of water pos.y += player->actor.yDistToWater; prevPos.y += player->actor.yDistToWater; - //checks for new wall poly + // checks for new wall poly wallPoly = checkWall(pos, prevPos, wallPos); - - //if not climable and exists then treats it as a wall + // if not climable and exists then treats it as a wall if (wallPoly != NULL) { discoverWall(pos); break; } - - //checks for ledges + + // checks for ledges pos.y = player->actor.world.pos.y - 10.0; f32 ogStep = step; step = 1.0; @@ -997,7 +978,8 @@ class Lava : protected TerrainCueSound { rot.y = ogRot.y; pos = ogPos; - if (clockwiseTest && counterclockwiseTest && (forwardTest || wallHeight < 44.0) && wallHeight < 48 && //probably have to change for adult + if (clockwiseTest && counterclockwiseTest && (forwardTest || wallHeight < 44.0) && + wallHeight < 48 && // probably have to change for adult (fabs(clockwiseY - counterclockwiseY) < 2.0 || fabs(clockwiseY - counterclockwiseY) > wallHeight - 5.0)) { discoverLedge(pos, true); @@ -1006,54 +988,54 @@ class Lava : protected TerrainCueSound { discoverWall(pos); break; } - //link is climbing + // link is climbing } else if (player->stateFlags1 == PLAYER_STATE1_CLIMBING_LADDER) { - f32 playerHeight = BgCheck_EntityRaycastFloor3(&actor->play->colCtx, &floorPoly, &floorBgId, &player->actor.world.pos); + f32 playerHeight = + BgCheck_EntityRaycastFloor3(&actor->play->colCtx, &floorPoly, &floorBgId, &player->actor.world.pos); f32 floorHeight; s8 moveMethod = false; Vec3s_ ogRot = rot; setVelocity(); - + if (ogRot.y == player->actor.world.rot.y) { - //sets forward probe to look above link + // sets forward probe to look above link moveMethod = 2; - } - player->actor.world.rot.y = player->actor.shape.rot.y;//corrects links rotation - + player->actor.world.rot.y = player->actor.shape.rot.y; // corrects links rotation + if (!move(moveMethod)) { destroyCurrentSound(); break; // Probe is out of bounds. } - //this following bit checks the wall poly and for now just checks if it has a drop off below it - //or if it is the forward probe, checks if the vine ends otherwise it continues + // this following bit checks the wall poly and for now just checks if it has a drop off below it + // or if it is the forward probe, checks if the vine ends otherwise it continues Vec3f wallPos; CollisionPoly* wallPoly = checkWall(pos, prevPos, wallPos); - + if (wallPoly != NULL) { - - if ((moveMethod == 2) && (func_80041DB8(&actor->play->colCtx, wallPoly, BGCHECK_SCENE) != 8 && - func_80041DB8(&actor->play->colCtx, wallPoly, BGCHECK_SCENE) != 3)) { - - if (fabs(pos.y - player->actor.world.pos.y) < 100) { - discoverLedge(pos, false); - - break; - } else { - destroyCurrentSound(); - break; - } - - } else { - if (moveMethod != 2 && checkVinePlatform(pos, ogRot, playerHeight)){ + + if ((moveMethod == 2) && (func_80041DB8(&actor->play->colCtx, wallPoly, BGCHECK_SCENE) != 8 && + func_80041DB8(&actor->play->colCtx, wallPoly, BGCHECK_SCENE) != 3)) { + + if (fabs(pos.y - player->actor.world.pos.y) < 100) { + discoverLedge(pos, false); + + break; + } else { + destroyCurrentSound(); + break; + } + + } else { + if (moveMethod != 2 && checkVinePlatform(pos, ogRot, playerHeight)) { break; } continue; } } - //this means that either the wall poly found above is not a vine or is NULL - //the next three secections check infront and behind the probe for wall polys + // this means that either the wall poly found above is not a vine or is NULL + // the next three secections check infront and behind the probe for wall polys // if (moveMethod != 2) { prevPos = pos; @@ -1127,7 +1109,7 @@ class Lava : protected TerrainCueSound { } } } - //this means no wall polys were found, first we check for ceilng poly + // this means no wall polys were found, first we check for ceilng poly if (moveMethod == 2) { rot.y = player->actor.shape.rot.y; rot.y += 16384; @@ -1139,18 +1121,17 @@ class Lava : protected TerrainCueSound { break; // Probe is out of bounds. } prevPos = pos; - //pos.y += 200; + // pos.y += 200; f32 checkHeight = fabs(player->actor.world.pos.y - pos.y); f32 ceilingPos; if (BgCheck_AnyCheckCeiling(&actor->play->colCtx, &ceilingPos, &player->actor.world.pos, checkHeight + 30)) { - + if (checkHeight < 100) { pos.y = ceilingPos; discoverWall(pos); break; } - } destroyCurrentSound(); break; /*else { @@ -1158,8 +1139,7 @@ class Lava : protected TerrainCueSound { discoverLedge(pos, true); break; } - }*///not needed? - + }*/ // not needed? } if (moveMethod != 2 && checkPerpendicularWall(pos, ogRot)) { discoverWall(pos); @@ -1167,9 +1147,9 @@ class Lava : protected TerrainCueSound { } discoverLedge(pos, false); break; - + } - + else if (checkForLava(player->actor.world.pos)) { if (!move()) { destroyCurrentSound(); @@ -1179,19 +1159,17 @@ class Lava : protected TerrainCueSound { discoverGround(pos); break; } - - } + } // link is on land else { - + if (!move()) { destroyCurrentSound(); break; // Probe is out of bounds. } - if (isPushedAway() && player->stateFlags1 != PLAYER_STATE1_CLIMBING_LADDER) { // Call this a wall for now. discoverWall(pos); @@ -1203,12 +1181,11 @@ class Lava : protected TerrainCueSound { // This is a fall. bool foundLiquid = false; - if (((pos.y - player->actor.prevPos.y) < player->actor.yDistToWater-30) && + if (((pos.y - player->actor.prevPos.y) < player->actor.yDistToWater - 30) && (player->actor.yDistToWater < 0)) { discoverLedge(pos, 2); foundLiquid = true; - } - else if (rdist(pos) < 100.0) { + } else if (rdist(pos) < 100.0) { s8 i = 50; Vec3f_ oldPos = pos; while (i > 0) { @@ -1225,13 +1202,13 @@ class Lava : protected TerrainCueSound { if (!foundLiquid) { discoverLedge(pos); } - + testForPlatform(); break; } - //checks for water + // checks for water if (((pos.y - player->actor.prevPos.y) < player->actor.yDistToWater) && (player->actor.yDistToWater < 0 && player->stateFlags1 != PLAYER_STATE1_CLIMBING_LADDER)) { discoverWater(pos); @@ -1243,7 +1220,6 @@ class Lava : protected TerrainCueSound { discoverLedge(pos); } - if (pos.y > prevPos.y && fabs(pos.y - prevPos.y) < 20 && fabs(pos.y - prevPos.y) > 1.2 && player->stateFlags1 != PLAYER_STATE1_CLIMBING_LADDER) { // This is an incline. @@ -1259,7 +1235,7 @@ class Lava : protected TerrainCueSound { player->stateFlags1 != PLAYER_STATE1_CLIMBING_LADDER)) { prevPos = pos; if (!move()) { - //destroyCurrentSound(); + // destroyCurrentSound(); break; // Probe is out of bounds. } } @@ -1283,7 +1259,7 @@ class Lava : protected TerrainCueSound { player->stateFlags1 != PLAYER_STATE1_CLIMBING_LADDER)) { prevPos = pos; if (!move()) { - //destroyCurrentSound(); + // destroyCurrentSound(); break; // Probe is out of bounds. } } @@ -1313,14 +1289,14 @@ class Lava : protected TerrainCueSound { continue; // Is this a spiked wall? Vec3f polyVerts[3]; - + CollisionPoly_GetVertices(wallPoly, colCtx->colHeader->vtxList, polyVerts); if (SurfaceType_IsWallDamage(&actor->play->colCtx, wallPoly, BGCHECK_SCENE)) { discoverSpike(pos); break; } // is this a ladder or vine wall? - + wallHeight = findWallHeight(pos, wallPoly); if (wallHeight <= player->ageProperties->unk_0C && player->stateFlags1 != PLAYER_STATE1_CLIMBING_LADDER) { @@ -1333,8 +1309,6 @@ class Lava : protected TerrainCueSound { break; } - - else { continue; @@ -1344,25 +1318,20 @@ class Lava : protected TerrainCueSound { discoverWall(pos); break; } - - } } if (trackingMode) -player->actor.world.pos = pos; - //Emit sound from the discovered position. -if (currentSound) + player->actor.world.pos = pos; + // Emit sound from the discovered position. + if (currentSound) currentSound->update(pos); -if (currentSound && trackingMode) { -disabled = true; -trackingMode = false; -trackingModeStarted = false; -} - - + if (currentSound && trackingMode) { + disabled = true; + trackingMode = false; + trackingModeStarted = false; + } } - void testForPlatform() - { + void testForPlatform() { Player* player = GET_PLAYER(actor->play); f32 ledgeCheckDistance = 200.0; @@ -1374,70 +1343,65 @@ trackingModeStarted = false; f32 step = fabs(velocity.x + velocity.z); if (!move()) { - break; // Probe is out of bounds. + break; // Probe is out of bounds. } ledgeCheckDistance -= (step + fabs(pos.y - pos.y)); if ((fabs(pos.y - player->actor.prevPos.y) <= 70.00) && fabs(pos.y - prevPos.y) >= 20.0) { - platform.setPosition(pos); - platform.run(); - break; + platform.setPosition(pos); + platform.run(); + break; } } pos = startingPos; } - }; +}; typedef struct { TerrainCueDirection directions[3]; // Directly ahead of Link, 90 degrees to his left and 90 degrees to his right. - int previousAction; //previous action icon state -}TerrainCueState; + int previousAction; // previous action icon state +} TerrainCueState; - //Callback for initialization of terrain cue state. +// Callback for initialization of terrain cue state. bool ActorAccessibility_InitTerrainCueState(AccessibleActor* actor) { - TerrainCueState* state = (TerrainCueState*) malloc(sizeof(TerrainCueState)); + TerrainCueState* state = (TerrainCueState*)malloc(sizeof(TerrainCueState)); if (state == NULL) return false; state->directions[0].init(actor, { 0, 0, 0 }); - state->directions[1].init(actor, { 0, 16384, 0 });//, PLAYER_BODYPART_L_SHOULDER); - state->directions[2].init(actor, { 0, -16384, 0 });//, PLAYER_BODYPART_R_SHOULDER); + state->directions[1].init(actor, { 0, 16384, 0 }); //, PLAYER_BODYPART_L_SHOULDER); + state->directions[2].init(actor, { 0, -16384, 0 }); //, PLAYER_BODYPART_R_SHOULDER); state->previousAction = DO_ACTION_NONE; actor->userData = state; return true; - - } void ActorAccessibility_CleanupTerrainCueState(AccessibleActor* actor) { free(actor->userData); actor->userData = NULL; - } -//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 rot = *origin; rot.x += offset->x; rot.y += offset->y; rot.z += offset->z; return rot; - } - -void accessible_va_terrain_cue(AccessibleActor * actor) { +void accessible_va_terrain_cue(AccessibleActor* actor) { TerrainCueState* state = (TerrainCueState*)actor->userData; for (int i = 0; i < 3; i++) - state->directions[i].scan(); + state->directions[i].scan(); int currentState = actor->play->interfaceCtx.unk_1F0; Player* player = GET_PLAYER(actor->play); if (state->previousAction != currentState) { - //Audio_PlaySoundGeneral(NA_SE_EV_DIAMOND_SWITCH, &player->actor.world.pos, 4, &actor->basePitch, - // &actor->baseVolume, - // &actor->currentReverb); - switch (currentState) { + // Audio_PlaySoundGeneral(NA_SE_EV_DIAMOND_SWITCH, &player->actor.world.pos, 4, &actor->basePitch, + // &actor->baseVolume, + // &actor->currentReverb); + switch (currentState) { case DO_ACTION_CHECK: SpeechSynthesizer::Instance->Speak("Check", GetLanguageCode()); break; @@ -1457,112 +1421,102 @@ void accessible_va_terrain_cue(AccessibleActor * actor) { SpeechSynthesizer::Instance->Speak("Speak", GetLanguageCode()); break; case DO_ACTION_STOP: - SpeechSynthesizer::Instance->Speak("Stop", GetLanguageCode()); // possibly disable? not sure what it does + SpeechSynthesizer::Instance->Speak("Stop", + GetLanguageCode()); // possibly disable? not sure what it does break; default: SpeechSynthesizer::Instance->Speak(" ", GetLanguageCode()); break; } - - state->previousAction = currentState; } else { state->previousAction = currentState; } } - - - /* - void accessible_va_wall_cue(AccessibleActor* actor) { - Player* player = GET_PLAYER(actor->play); +/* + void accessible_va_wall_cue(AccessibleActor* actor) { +Player* player = GET_PLAYER(actor->play); //The virtual cue actors travel in lines relative to Link's angle. Vec3s rot = computeRelativeAngle(player->actor.world.rot, actor->world.rot); - Vec3f velocity; - velocity.x = Math_SinS(rot.y); - velocity.z = Math_CosS(rot.y); +Vec3f velocity; +velocity.x = Math_SinS(rot.y); +velocity.z = Math_CosS(rot.y); //Draw a line from Link's position to the max detection distance based on the configured relative angle. - Vec3f pos = player->actor.world.pos; - Vec3f headPos = player->bodyPartsPos[PLAYER_BODYPART_TORSO]; - f32 headDistY = headPos.y - pos.y; +Vec3f pos = player->actor.world.pos; +Vec3f headPos = player->bodyPartsPos[PLAYER_BODYPART_TORSO]; +f32 headDistY = headPos.y - pos.y; - f32 step = fabs(velocity.x + velocity.z); - f32 distToTravel = detectionDistance; - CollisionPoly* poly = NULL; - Vec3f collisionResult; - s32 bgId = 0; - while (true) { - Vec3f prevPos = pos; - Vec3f prevHeadPos = headPos; +f32 step = fabs(velocity.x + velocity.z); +f32 distToTravel = detectionDistance; +CollisionPoly* poly = NULL; +Vec3f collisionResult; +s32 bgId = 0; +while (true) { +Vec3f prevPos = pos; +Vec3f prevHeadPos = headPos; - pos.x += velocity.x; - pos.y += 1; - pos.z += velocity.z; - headPos.x += velocity.x; - headPos.y += 1; - headPos.z += velocity.z; +pos.x += velocity.x; +pos.y += 1; +pos.z += velocity.z; +headPos.x += velocity.x; +headPos.y += 1; +headPos.z += velocity.z; - distToTravel -= step; - f32 floorHeight = 0; - CollisionPoly tempPoly; - floorHeight = BgCheck_AnyRaycastFloor1(&actor->play->colCtx, &tempPoly, &pos); - pos.y = floorHeight; - headPos.y = floorHeight + headDistY; +distToTravel -= step; +f32 floorHeight = 0; +CollisionPoly tempPoly; +floorHeight = BgCheck_AnyRaycastFloor1(&actor->play->colCtx, &tempPoly, &pos); + pos.y = floorHeight; +headPos.y = floorHeight + headDistY; - if (BgCheck_AnyLineTest3(&actor->play->colCtx, &prevPos, &pos, &collisionResult, &poly, 1, 0, 0, 0, &bgId)) { - s16 wallYaw = Math_Atan2S(poly->normal.z, poly->normal.x); - CollisionPoly* headPoly = NULL; +if (BgCheck_AnyLineTest3(&actor->play->colCtx, &prevPos, &pos, &collisionResult, &poly, 1, 0, 0, 0, &bgId)) { + s16 wallYaw = Math_Atan2S(poly->normal.z, poly->normal.x); + CollisionPoly* headPoly = NULL; - BgCheck_AnyLineTest3(&actor->play->colCtx, &prevHeadPos, &headPos, &collisionResult, &headPoly, 1, 0, 0, 0, - &bgId); - if (headPoly != NULL) - break; + BgCheck_AnyLineTest3(&actor->play->colCtx, &prevHeadPos, &headPos, &collisionResult, &headPoly, 1, 0, 0, 0, + &bgId); + if (headPoly != NULL) + break; - poly = NULL; + poly = NULL; - } - - if (distToTravel <= 0) - break; - - } - if (poly == NULL) { - //Audio_StopSfxByPosAndId(&actor->world.pos, wallCueSound); - return; // Nothing found. - - } - // Move the virtual actor to the position of the discovered wall so we can use preexisting sound - // logic. - actor->world.pos = collisionResult; - framesUntilCue--; - if (framesUntilCue < 1) { - framesUntilCue = 10; - ActorAccessibility_PlaySpecialSound(actor, wallCueSound); - - } - - } - */ +} +if (distToTravel <= 0) + break; +} +if (poly == NULL) { +//Audio_StopSfxByPosAndId(&actor->world.pos, wallCueSound); +return; // Nothing found. +} +// Move the virtual actor to the position of the discovered wall so we can use preexisting sound + // logic. +actor->world.pos = collisionResult; +framesUntilCue--; +if (framesUntilCue < 1) { +framesUntilCue = 10; +ActorAccessibility_PlaySpecialSound(actor, wallCueSound); +} +} +*/ void ActorAccessibility_InitCues() { -ActorAccessibilityPolicy policy; + ActorAccessibilityPolicy policy; ActorAccessibility_InitPolicy(&policy, "Terrain cue helper", accessible_va_terrain_cue, 0); - policy.n = 1; - policy.runsAlways = true; - policy.distance = 500; - policy.initUserData = ActorAccessibility_InitTerrainCueState; - policy.cleanupUserData = ActorAccessibility_CleanupTerrainCueState; + 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 }, { 0, 0, 0 } }); - - - } \ No newline at end of file + ActorAccessibility_AddSupportedActor(VA_TERRAIN_CUE, policy); + VirtualActorList* list = ActorAccessibility_GetVirtualActorList(EVERYWHERE, 0); + ActorAccessibility_AddVirtualActor(list, VA_TERRAIN_CUE, { { 0, 0, 0 }, { 0, 0, 0 } }); +} \ No newline at end of file diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index ac4a963b0..1a4559a9e 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -274,7 +274,7 @@ OTRGlobals::OTRGlobals() { if (std::filesystem::exists(ootPath)) { OTRFiles.push_back(ootPath); } - std::string sohOtrPath = Ship::Context::GetPathRelativeToAppBundle("soh.otr"); + std::string sohOtrPath = Ship::Context::GetPathRelativeToAppBundle("soh.o2r"); if (std::filesystem::exists(sohOtrPath)) { OTRFiles.push_back(sohOtrPath); }