C-button loop should not read D-pad,
D-pad keys off index like SyncButtonItemsForSlot,
B-button skips, ITEM_NONE while swordless would every empty slot green
Pointless to give control while player waits for big octo to descend (& still play cutscene),
just opens up complications & speedrun discussion raised concern about backflip to get behind Big Octo
The decoder cached on a note was keyed on nothing, so a note reused for a
different streamed sample carried on decoding the previous track. Audible as
the wrong custom music: the sequence and soundfont the audio editor reports
are correct, only the samples reaching the mixer are not.
Reproduced on the game-start cutscene chain with a streamed music pack in 4
of 6 runs; 0 of 6 after.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: serprex <159546+serprex@users.noreply.github.com>
Massively optimize Lang::Translate & add Lang::TryTranslate.
Move all rando option text to lang json.
In the future we should have something like .TranslationTooltip() that takes the translation string to use instead of .Tooltip() as that'd allow us to change language at runtime.
Fix masks not rendering properly with completed mask quest
Remove completed mask quest option, add all masks to starting items menu
logic: handle starting with masks being able to skip ahead a bit in trade sequence
Streamed samples were read a whole block at a time regardless of where the loop
ended, so playback ran past it and only then jumped back. The seam therefore landed
at a random offset up to a block late instead of where the sample asked for it, which
is why a loop that is clean in an editor pops in game.
Fixes#5780.
Claude-Session: https://claude.ai/code/session_011Ex3z29fQzPEZgwH4EA641
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Add guard to check if camera mode is CAMERA_MODE_FIRST_PERSON before applying fixes
Also adds missing PLAYER_IA modes for magic arrows, as well as applying camera fix for Hookshot outside of just lakeside lab.
Move gameinteractor for change aiming camera inside bow/sling/hook aiming block
The function declares realId and then indexes with it thirteen times -
the load-status tables, AudioLoad_SearchCaches, the table entry it reads
size and address from, every cache allocation, and the status write at the
end - but nothing assigns it. It has read an uninitialised local since
"Custom Sequences" (#2066) dropped the assignment in 2022.
Restoring the line puts back the value the rest of the function expects.
For SEQUENCE_TABLE and FONT_TABLE, AudioLoad_GetRealTableIndex returns the
id unchanged, so this is only a correctness fix in practice: the paths that
reach this function today go through the sequence script's async load
command, which is rare enough that the garbage index has not been tied to
any report.
#6917 guarded the three seqLoadStatus accessors against sequenceMapSize
because the array was allocated at exactly that size, so a custom sequence
id past it read and wrote off the end.
#6932 sized the array to sequenceMapSize + 0xF to match sequenceMap, which
covers the whole id space rather than rejecting the ids outside it, and also
protects the writers those guards never saw: AudioHeap_AllocCached and
AudioHeap_PopCache index seqLoadStatus directly.
The guards are now not just redundant but bounded wrong - they treat the ids
in [sequenceMapSize, sequenceMapSize + 0xF) as absent from a table that now
has room for them. Nothing breaks today because every entry starts at 5, so
AudioLoad_IsSeqLoadComplete answers true regardless and
AudioLoad_SetSeqLoadStatus already declines to overwrite a 5 - but once the
heap cache path moves such an entry off 5, the guard blocks an update that
should happen.
Reverting them restores the three functions to their decompiled form. The
sizing from #6932 and the id check in AudioLoad_SyncInitSeqPlayerInternal
remain the actual protection.
Reaching the Fast3d GUI is spelled out in full at every call site:
std::dynamic_pointer_cast<Fast::Fast3dGui>(
Ship::Context::GetRawInstance()->GetWindow()->GetGui())->GetTextureByName(name)
Each one locks the Context weak_ptr, copies a shared_ptr for the window
and one for the GUI, then runs a dynamic_cast, only to drop all three
again. InputViewer::DrawElement does that 43 times per frame, and the
item tracker and save editor repeat it once per icon drawn.
Binding it to a local once per scope leaves the behaviour identical and
reads better. The local goes in the innermost block that covers the call
sites, so it stays behind the guards that were already there: DrawElement
still resolves nothing when the input viewer is off.
RenderButton keeps its inline casts. Its two call sites are in exclusive
branches, so a local would add a cast on the path that takes neither.