feat(assets): swap card art to hayeah/playing-cards-assets (MIT)
Replaces the previous xCards-derived card faces (LGPL-3.0) with
hayeah/playing-cards-assets, which itself derives from the
public-domain vector-playing-cards Google Code project. The whole
package is MIT now — see CREDITS.md for the new attribution table
and the simpler license summary.
solitaire_engine/assets/themes/default/
52 face SVGs (clubs/diamonds/hearts/spades × ace/2-10/jack/queen/
king) — copied from hayeah, renamed to the canonical
`{suit}_{rank}.svg` form `CardKey::manifest_name` produces. The
bundled default theme manifest references each by the same name.
back.svg — original midnight-purple-themed card back, hand-written
to match the project's design tokens (BG_BASE / BG_ELEVATED /
ACCENT_PRIMARY / ACCENT_SECONDARY). MIT, original work.
assets/cards/faces/{RANK}{SUIT}.png
52 PNGs regenerated from the new SVGs at 750-tall via resvg 0.47.
These remain the legacy backwards-compat path that
`card_plugin::load_card_images` reads at startup; once the runtime
theme system finishes loading the embedded default theme, the
CardImageSet's face handles are overwritten with the SVG-rendered
variants and these PNGs become moot. Keeping them in place avoids
a brief blank-card flash before the async theme load completes.
solitaire_engine/src/assets/sources.rs
embed_default_svg!() macro + DEFAULT_THEME_SVGS table that bundles
every face + the back into the binary at compile time via
include_bytes!. populate_embedded_default_theme now iterates the
table so the EmbeddedAssetRegistry is populated under the same
asset paths the manifest references.
CREDITS.md
License summary collapses from MIT + LGPL-3.0 + OFL-1.1 to MIT +
OFL-1.1 (the OFL still applies to FiraMono). The hayeah upstream
URL replaces the previously-blank xCards entry.
cargo build / clippy --workspace --all-targets -- -D warnings / test
--workspace all green (960 passed, 0 failed, 9 ignored).
This commit is contained in:
@@ -83,6 +83,78 @@ const DEFAULT_THEME_MANIFEST_PATH: &str = "solitaire_engine/assets/themes/defaul
|
||||
const DEFAULT_THEME_MANIFEST_BYTES: &[u8] =
|
||||
include_bytes!("../../assets/themes/default/theme.ron");
|
||||
|
||||
/// Generates a `(stable_path, bytes)` entry for one default-theme
|
||||
/// SVG so the bulk-embed table below stays declarative. The path
|
||||
/// matches what `theme.ron` references; `include_bytes!` resolves
|
||||
/// relative to this source file.
|
||||
macro_rules! embed_default_svg {
|
||||
($name:literal) => {
|
||||
(
|
||||
concat!("solitaire_engine/assets/themes/default/", $name),
|
||||
include_bytes!(concat!("../../assets/themes/default/", $name)) as &[u8],
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// Every default-theme SVG file bundled into the binary. Adding a new
|
||||
/// face / back artwork is a single `embed_default_svg!(...)` line —
|
||||
/// the populate function below iterates this table.
|
||||
const DEFAULT_THEME_SVGS: &[(&str, &[u8])] = &[
|
||||
embed_default_svg!("back.svg"),
|
||||
embed_default_svg!("clubs_ace.svg"),
|
||||
embed_default_svg!("clubs_2.svg"),
|
||||
embed_default_svg!("clubs_3.svg"),
|
||||
embed_default_svg!("clubs_4.svg"),
|
||||
embed_default_svg!("clubs_5.svg"),
|
||||
embed_default_svg!("clubs_6.svg"),
|
||||
embed_default_svg!("clubs_7.svg"),
|
||||
embed_default_svg!("clubs_8.svg"),
|
||||
embed_default_svg!("clubs_9.svg"),
|
||||
embed_default_svg!("clubs_10.svg"),
|
||||
embed_default_svg!("clubs_jack.svg"),
|
||||
embed_default_svg!("clubs_queen.svg"),
|
||||
embed_default_svg!("clubs_king.svg"),
|
||||
embed_default_svg!("diamonds_ace.svg"),
|
||||
embed_default_svg!("diamonds_2.svg"),
|
||||
embed_default_svg!("diamonds_3.svg"),
|
||||
embed_default_svg!("diamonds_4.svg"),
|
||||
embed_default_svg!("diamonds_5.svg"),
|
||||
embed_default_svg!("diamonds_6.svg"),
|
||||
embed_default_svg!("diamonds_7.svg"),
|
||||
embed_default_svg!("diamonds_8.svg"),
|
||||
embed_default_svg!("diamonds_9.svg"),
|
||||
embed_default_svg!("diamonds_10.svg"),
|
||||
embed_default_svg!("diamonds_jack.svg"),
|
||||
embed_default_svg!("diamonds_queen.svg"),
|
||||
embed_default_svg!("diamonds_king.svg"),
|
||||
embed_default_svg!("hearts_ace.svg"),
|
||||
embed_default_svg!("hearts_2.svg"),
|
||||
embed_default_svg!("hearts_3.svg"),
|
||||
embed_default_svg!("hearts_4.svg"),
|
||||
embed_default_svg!("hearts_5.svg"),
|
||||
embed_default_svg!("hearts_6.svg"),
|
||||
embed_default_svg!("hearts_7.svg"),
|
||||
embed_default_svg!("hearts_8.svg"),
|
||||
embed_default_svg!("hearts_9.svg"),
|
||||
embed_default_svg!("hearts_10.svg"),
|
||||
embed_default_svg!("hearts_jack.svg"),
|
||||
embed_default_svg!("hearts_queen.svg"),
|
||||
embed_default_svg!("hearts_king.svg"),
|
||||
embed_default_svg!("spades_ace.svg"),
|
||||
embed_default_svg!("spades_2.svg"),
|
||||
embed_default_svg!("spades_3.svg"),
|
||||
embed_default_svg!("spades_4.svg"),
|
||||
embed_default_svg!("spades_5.svg"),
|
||||
embed_default_svg!("spades_6.svg"),
|
||||
embed_default_svg!("spades_7.svg"),
|
||||
embed_default_svg!("spades_8.svg"),
|
||||
embed_default_svg!("spades_9.svg"),
|
||||
embed_default_svg!("spades_10.svg"),
|
||||
embed_default_svg!("spades_jack.svg"),
|
||||
embed_default_svg!("spades_queen.svg"),
|
||||
embed_default_svg!("spades_king.svg"),
|
||||
];
|
||||
|
||||
/// Registers asset sources that must be in place *before*
|
||||
/// `AssetPlugin` is built.
|
||||
///
|
||||
@@ -128,26 +200,39 @@ impl Plugin for AssetSourcesPlugin {
|
||||
/// unit test below can exercise it without spinning up a full Bevy
|
||||
/// `App` with `AssetPlugin`.
|
||||
///
|
||||
/// **Adding files to the bundled default theme** is a single edit
|
||||
/// per file: add an `include_bytes!` constant that points at the file
|
||||
/// under `solitaire_engine/assets/themes/default/`, then add a
|
||||
/// matching `registry.insert_asset(...)` call here. Keep the
|
||||
/// `asset_path` argument exactly the relative path that the manifest
|
||||
/// references (e.g. `solitaire_engine/assets/themes/default/back.svg`).
|
||||
/// **Adding files to the bundled default theme** is a single edit:
|
||||
/// append one `embed_default_svg!("filename.svg")` line to the
|
||||
/// `DEFAULT_THEME_SVGS` table above. The file resolves relative to
|
||||
/// `solitaire_engine/assets/themes/default/` and registers under
|
||||
/// the matching `embedded://` URL automatically.
|
||||
pub fn populate_embedded_default_theme(app: &mut App) {
|
||||
let registry = app
|
||||
.world_mut()
|
||||
.get_resource_or_insert_with(EmbeddedAssetRegistry::default);
|
||||
|
||||
// `full_path` is only consulted by the optional
|
||||
// `embedded_watcher` cargo feature (which we don't enable). Use
|
||||
// the manifest's logical workspace path so a future debugger
|
||||
// session sees a sensible source-of-truth string.
|
||||
// The manifest first — its asset URL is the entry point everything
|
||||
// else (`set_theme`, the registry, the loader) references via
|
||||
// `DEFAULT_THEME_MANIFEST_URL`.
|
||||
//
|
||||
// `full_path` is only consulted by the optional `embedded_watcher`
|
||||
// cargo feature (which we don't enable). Use the manifest's
|
||||
// logical workspace path so a future debugger session sees a
|
||||
// sensible source-of-truth string.
|
||||
registry.insert_asset(
|
||||
std::path::PathBuf::from(DEFAULT_THEME_MANIFEST_PATH),
|
||||
std::path::Path::new(DEFAULT_THEME_MANIFEST_PATH),
|
||||
DEFAULT_THEME_MANIFEST_BYTES,
|
||||
);
|
||||
|
||||
// Then every face + back SVG. The manifest references each by the
|
||||
// same relative path used here.
|
||||
for (path, bytes) in DEFAULT_THEME_SVGS {
|
||||
registry.insert_asset(
|
||||
std::path::PathBuf::from(*path),
|
||||
std::path::Path::new(*path),
|
||||
*bytes,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user