Adds a helper function that does the structural 'Perform Sin/Con, then multiply, then scale down' that was littered across code.
Updates code to use it.
Pin spriteGroup1_ to r4 with an explicit register variable, which lets two
of the five asm("") barriers go. The target keeps two redundant pointer
copies in its entry block (adds r4, r6, #0 and mov r5, sl); the pin is
enough to keep the first one alive, so the alias1 launder and the oamData
launder are no longer needed. The remaining three barriers protect the
spriteGroup2_ copy, which cannot also be pinned -- the target reuses r5 as
a scratch register once that alias dies, and a pin would reserve it for the
whole function. Three is a hard floor: no configuration with two or fewer
barriers matches.
Also drop the contrived independent re-derivation. spriteGroup2_ =
spriteGroup2 now matches, where it previously required
= &gMain.spriteGroups[1], so the function no longer re-derives a pointer it
already has. Declarations follow RenderPokedexSprites' house style: int i
first, function-scope oamData and spriteSet temps rather than per-branch
copies, and the group pointer as LoadSpriteSets' third argument, as
pokedex.c and field_select.c both do.
Name the sprite group indices via constants/sprite_groups.h, adding the
missing SG_HIGH_SCORE_PRESS_START_0/1. spriteGroup1 and spriteGroup2 are
the page navigation arrows, not page icons -- confirmed by their positions
at baseX 220 and 4, and matching the right/left arrows in the GBC
predecessor's high score screen.
make compare OK; RenderHighScoreSprites stays instruction-exact
(words=0, insns=477, 18-word literal pool).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>