fix(smx): gif pack option display and CanBeEmpty fallback semantics#616
fix(smx): gif pack option display and CanBeEmpty fallback semantics#616fchorney wants to merge 2 commits into
Conversation
The SmxBgPack and SmxJudgePack rows hold a single static placeholder choice; the real list (Default plus discovered packs) is provided dynamically by the options layout. The screen-init sync went through set_choice_by_id, which clamps the index to the static choice list length, forcing the displayed selection to 0. The rows therefore always showed Default when re-entering the options screen, even though the saved config and the actual pad lighting kept the chosen pack. Write the index directly via get_choice_by_id_mut instead, matching the noteskin and software-renderer-threads rows that use the same dynamic-choices pattern.
CanBeEmpty exists so a pack can say a role should never have an animation. The registry honored that for the pack-level chain (declared Fallback pack, automatic common fallback), but the app's screen resolution then tried the default role, so a pack that declared CanBeEmpty=gameplay while supplying its own default gif still showed that default gif during gameplay. Walk the role candidates (grade-specific results roles, the screen role, then default) in order and stop dead at any candidate the selected pack declares under CanBeEmpty without supplying: no animation resolves at all. A supplied gif still wins over its own declaration, and per-song / per-pack scoped gifs sit above pack policy and are unaffected. Also aligns the docs with the actual empty behavior: during gameplay the game keeps LED ownership so an empty background is solid black; on other screens an empty pad is handed back to the pad firmware's built-in lighting.
3cfc44d to
417846b
Compare
Heads up:
|
Two fixes for the gif-pack bug reports against v0.4.2004.
1. Selected gif pack shows as Default when re-entering the options screen
Selecting a pad or judgement gif pack on the StepManiaX options page appears not to stick: re-entering the options screen always shows Default checked, regardless of what was selected.
The saved value is actually fine the whole time: the config, the ini round-trip, and the pad lighting all keep the chosen pack. Only the displayed row selection resets.
Cause: the
SmxBgPack/SmxJudgePackrows are defined with a single static placeholder choice; their real choice list (Defaultplus the discovered packs) is provided dynamically by the options layout. The screen-init sync usedset_choice_by_id, which clamps the incoming index against the static row definition's choice list:Fix: write the index directly via
get_choice_by_id_mut, the same pattern already used by the other dynamically-populated rows (DefaultNoteSkin,SoftwareRendererThreads). The remaining dynamic rows (display mode/resolution/refresh rate, sound device) already use direct writes; the per-player pack rows in Player Options bake their full choice list into the row and are not affected.2.
CanBeEmptyroles still slid over to the pack'sdefaultgifA pack that supplies all of its own gifs except
gameplayand declaresCanBeEmpty = "gameplay"expects no background during gameplay. The registry honored the declaration for the pack-level chain (noFallbackpack, nocommon), but the app's screen resolution then fell back to thedefaultrole, so the pack's owndefaultgif showed during gameplay anyway.Fix: the role-candidate walk (grade-specific results roles, then the screen role, then
default) now stops dead at any candidate the selected pack declares underCanBeEmptywithout supplying: that event shows no animation at all.CanBeEmptynow means what it says: this name never has an animation, no matter which fallback would have provided one.Details:
GifRegistry::background_declared_emptyexposes the declared-empty state (the existingbackground()lookup cannot distinguish "empty by declaration" from "missing, keep falling back"), with a unit test.CanBeEmptytable row, and the "when to use" example now describe the stop-dead semantics. Also corrected the section that claimed an opted-out role shows solid black with the game holding LED ownership at all times: actual behavior is solid black during gameplay (the game still owns the LEDs for judgement effects), and outside gameplay an empty pad is handed back to the pad firmware's built-in lighting.Testing
cargo test -p deadsync-smx: 76 passed (includes the newbackground_declared_emptytest).cargo buildclean.