From 7f450aab1762345e57f895b6297434e3ce77c360 Mon Sep 17 00:00:00 2001 From: funman300 Date: Sat, 16 May 2026 13:24:25 -0700 Subject: [PATCH] fix(android): default to classic theme to fix AMOLED card-back invisibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dark theme back.svg uses #151515 (near-black) as the card back background, which AMOLED screens render as fully-off pixels, leaving only the tiny #a54242 red badge visible — user sees solid red squares instead of card backs. Fix: change fresh-install default theme from "dark" to "classic" (white background with navy diamond pattern, clearly visible on all display types). Also remove the stale "classic" -> "dark" sanitize migration, correct wrong asset paths in load_card_images (classic/ subdirectory was missing), and update tests that hardcoded the old TABLEAU_FAN_FRAC=0.25 constant. Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 14 ++++++++++++++ solitaire_data/src/settings.rs | 9 ++++----- solitaire_engine/src/card_plugin.rs | 4 ++-- solitaire_engine/src/input_plugin.rs | 5 ++--- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 073b052..33cc91a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,20 @@ project follows [Semantic Versioning](https://semver.org/). ## [Unreleased] +## [0.31.0] — 2026-05-16 + +### Fixed + +- **Face-down cards rendered as solid red squares on AMOLED phones** (Bug 1). + The dark theme's card back (`back.svg`) uses a near-black background + (`#151515`) which AMOLED screens render as fully-off pixels, leaving only a + tiny `#a54242` red badge visible — exactly what was reported. Fixed by + changing the fresh-install default theme from "dark" to "classic" (white + background with navy diamond pattern, clearly readable on all display types). + Also corrected stale asset paths in `load_card_images` (`cards/backs/back_N` + → `cards/backs/classic/back_N`, `cards/faces/XY` → `cards/faces/classic/XY`) + so the PNG fallback loads correctly when the embedded theme hasn't arrived yet. + ## [0.30.0] — 2026-05-16 ### Changed diff --git a/solitaire_data/src/settings.rs b/solitaire_data/src/settings.rs index ab27a9b..4818f15 100644 --- a/solitaire_data/src/settings.rs +++ b/solitaire_data/src/settings.rs @@ -275,7 +275,7 @@ fn default_music_volume() -> f32 { } fn default_theme_id() -> String { - "dark".to_string() + "classic".to_string() } /// Default tooltip-hover dwell delay in seconds. Mirrors @@ -402,11 +402,10 @@ impl Settings { /// their respective ranges after deserialization or hand-editing of /// `settings.json`. pub fn sanitized(self) -> Self { - // Migrate stale theme IDs: "default" was removed when the theme was - // renamed to "dark"; "classic" was briefly the default before "dark" - // was restored as the shipped default. + // Migrate stale theme IDs: "default" was the original name before it + // was renamed to "dark". let selected_theme_id = match self.selected_theme_id.as_str() { - "default" | "classic" => "dark".to_string(), + "default" => "dark".to_string(), _ => self.selected_theme_id, }; Self { diff --git a/solitaire_engine/src/card_plugin.rs b/solitaire_engine/src/card_plugin.rs index aae1c27..23f91ce 100644 --- a/solitaire_engine/src/card_plugin.rs +++ b/solitaire_engine/src/card_plugin.rs @@ -484,13 +484,13 @@ fn load_card_images(asset_server: Option>, mut commands: Comman let faces: [[Handle; 13]; 4] = std::array::from_fn(|suit| { std::array::from_fn(|rank| { asset_server.load(format!( - "cards/faces/{}{}.png", + "cards/faces/classic/{}{}.png", RANK_STRS[rank], SUIT_CHARS[suit] )) }) }); let backs = std::array::from_fn(|i| { - asset_server.load(format!("cards/backs/back_{i}.png")) + asset_server.load(format!("cards/backs/classic/back_{i}.png")) }); commands.insert_resource(CardImageSet { faces, diff --git a/solitaire_engine/src/input_plugin.rs b/solitaire_engine/src/input_plugin.rs index 51e4b5e..9dec6ae 100644 --- a/solitaire_engine/src/input_plugin.rs +++ b/solitaire_engine/src/input_plugin.rs @@ -1785,9 +1785,8 @@ mod tests { let layout = compute_layout(Vec2::new(1280.0, 800.0), 0.0, 0.0, true); // Tableau 6 has 7 cards. let (_, size) = pile_drop_rect(&PileType::Tableau(6), &layout, &game); - // Expected: card_height + 6 * fan. fan = 0.25 * card_height, so - // size.y = card_height * (1 + 6 * 0.25) = card_height * 2.5. - let expected = layout.card_size.y * 2.5; + // Expected: card_height + 6 fan steps. + let expected = layout.card_size.y * (1.0 + 6.0 * layout.tableau_fan_frac); assert!( (size.y - expected).abs() < 1e-3, "expected {expected}, got {}",