diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4021e76..3b3304f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -278,7 +278,7 @@ jobs: steps: - uses: actions/checkout@v4 with: - repository: "cxreiff/tap" + repository: "cxreiff/homebrew-tap" token: ${{ secrets.HOMEBREW_TAP_TOKEN }} # So we have access to the formula - name: Fetch homebrew formulae diff --git a/assets/dvd_logo.png b/assets/dvd_logo.png new file mode 100644 index 0000000..1bf5843 Binary files /dev/null and b/assets/dvd_logo.png differ diff --git a/assets/tty_logo.png b/assets/tty_logo.png new file mode 100644 index 0000000..c28e68f Binary files /dev/null and b/assets/tty_logo.png differ diff --git a/src/assets.rs b/src/assets.rs index 59c32b5..f7522f3 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -4,4 +4,6 @@ use bevy::prelude::*; pub(super) fn plugin(app: &mut App) { let prefix = "src/"; embedded_asset!(app, prefix, "../assets/bubble.png"); + embedded_asset!(app, prefix, "../assets/dvd_logo.png"); + embedded_asset!(app, prefix, "../assets/tty_logo.png"); } diff --git a/src/bubbles.rs b/src/bubbles.rs index 187a00b..87bb66f 100644 --- a/src/bubbles.rs +++ b/src/bubbles.rs @@ -105,16 +105,6 @@ fn bubbles_setup_system( camera.camera.target = ratatui_render.target("main").unwrap_or_default(); commands.spawn(camera); - commands.spawn(PointLightBundle { - transform: Transform::from_xyz(0., 0., -5.), - point_light: PointLight { - intensity: 10_000., - shadows_enabled: true, - ..default() - }, - ..default() - }); - let rng = ChaCha8Rng::seed_from_u64(19878367467712); commands.insert_resource(BubbleRng(rng)); commands.insert_resource(BubbleSprite( diff --git a/src/lib.rs b/src/lib.rs index f20f724..d98f212 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,13 +3,15 @@ use std::time::Duration; use bevy::{app::ScheduleRunnerPlugin, log::LogPlugin, prelude::*, window::ExitCondition}; use bevy_ratatui::RatatuiPlugins; use bevy_ratatui_render::RatatuiRenderPlugin; +use logo::LogoPath; +pub use logo::{LOGO_PATH_DVD, LOGO_PATH_TTY}; use rand::{distributions::Standard, prelude::Distribution, Rng}; mod assets; mod bubbles; mod common; +mod logo; mod maze; -mod pipes; pub struct AppPlugin(pub SaverVariant); @@ -26,17 +28,21 @@ impl Plugin for AppPlugin { .disable::(), ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1. / 60.)), RatatuiPlugins::default(), - RatatuiRenderPlugin::new("main", (1, 1)).autoresize(), + RatatuiRenderPlugin::new("main", (256, 256)).autoresize(), )) .insert_resource(Msaa::Off) .init_resource::(); app.add_plugins((assets::plugin, common::plugin)); + if let SaverVariant::Logo(ref logo_path) = self.0 { + app.insert_resource(LogoPath(logo_path.into())); + } + app.add_plugins(match self.0 { - SaverVariant::Maze => maze::plugin, - SaverVariant::Pipes => pipes::plugin, SaverVariant::Bubbles => bubbles::plugin, + SaverVariant::Logo(_) => logo::plugin, + SaverVariant::Maze => maze::plugin, }); } } @@ -48,17 +54,17 @@ pub struct Flags { } pub enum SaverVariant { - Maze, - Pipes, Bubbles, + Logo(String), + Maze, } impl Distribution for Standard { fn sample(&self, rng: &mut R) -> SaverVariant { match rng.gen_range(0..=2) { - 0 => SaverVariant::Maze, - 1 => SaverVariant::Pipes, - _ => SaverVariant::Bubbles, + 0 => SaverVariant::Bubbles, + 1 => SaverVariant::Logo(LOGO_PATH_TTY.into()), + _ => SaverVariant::Maze, } } } diff --git a/src/logo.rs b/src/logo.rs new file mode 100644 index 0000000..37f7fa5 --- /dev/null +++ b/src/logo.rs @@ -0,0 +1,123 @@ +use bevy::prelude::*; +use bevy_ratatui::event::ResizeEvent; +use bevy_ratatui_render::RatatuiRenderContext; +use rand::SeedableRng; +use rand_chacha::ChaCha8Rng; + +pub const LOGO_PATH_DVD: &str = "embedded://ttysvr/../assets/dvd_logo.png"; +pub const LOGO_PATH_TTY: &str = "embedded://ttysvr/../assets/tty_logo.png"; + +const ORTHO_SCALING: f32 = 0.5; +const LOGO_RADIUS: f32 = 32.; +const LOGO_SPEED: f32 = 24.; + +pub(super) fn plugin(app: &mut App) { + app.init_resource::() + .add_systems(Startup, logo_setup_system) + .add_systems(Update, (handle_resize_system, logo_movement_system)); +} + +#[derive(Component, Deref, DerefMut)] +pub struct Logo { + #[deref] + velocity: Vec2, +} + +#[derive(Resource, Deref)] +pub struct LogoPath(pub String); + +#[derive(Resource, Deref, DerefMut, Default)] +pub struct LogoVisibleRegion(Vec2); + +#[derive(Bundle)] +pub struct LogoBundle { + logo: Logo, + sprite: SpriteBundle, +} + +impl LogoBundle { + fn new(rng: &mut ChaCha8Rng, texture: Handle, region: Rectangle) -> Self { + Self { + logo: Logo { + velocity: Vec2::new(LOGO_SPEED, -LOGO_SPEED), + }, + sprite: SpriteBundle { + transform: Transform::from_translation(region.sample_interior(rng).extend(0.)), + texture, + sprite: Sprite { + color: Color::hsl(0., 1.0, 0.6), + custom_size: Some(Vec2::splat(LOGO_RADIUS * 2.)), + ..default() + }, + ..default() + }, + } + } +} + +fn logo_setup_system( + mut commands: Commands, + ratatui_render: Res, + asset_server: Res, + mut visible_region: ResMut, + logo_path: Res, +) { + let mut camera = Camera2dBundle::default(); + camera.projection.scale = ORTHO_SCALING; + camera.camera.target = ratatui_render.target("main").unwrap_or_default(); + commands.spawn(camera); + + **visible_region = get_visible_region(&ratatui_render); + let texture = asset_server.load(&**logo_path); + let mut rng = ChaCha8Rng::seed_from_u64(19878367467712); + commands.spawn(LogoBundle::new( + &mut rng, + texture, + Rectangle::from_size(**visible_region * 0.5 - LOGO_RADIUS * 2.), + )); +} + +fn handle_resize_system( + mut resize_events: EventReader, + mut visible_region: ResMut, + ratatui_render: Res, +) { + for _ in resize_events.read() { + **visible_region = get_visible_region(&ratatui_render); + } +} + +fn logo_movement_system( + time: Res