Spinning Cube

This commit is contained in:
2026-02-11 01:45:21 +01:00
parent 498d0b1ba8
commit 77ed489f22
3 changed files with 6170 additions and 116 deletions

6093
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,18 +5,30 @@ edition.workspace = true
[dependencies] [dependencies]
g13-driver.workspace = true g13-driver.workspace = true
embedded-graphics = "0.8.1"
# time = { version = "0.3.47", features = ["formatting", "macros"] }
tokio = { version = "1.49.0", features = [
"rt",
"rt-multi-thread",
"sync",
"macros",
"net",
"signal",
"time",
] }
# bevy = { version = "0.18", default-features = false } embedded-graphics = "0.8.1"
bevy = "0.18"
# bevy_ratatui = "0"
# bevy_ratatui_camera = "0"
# ratatui = { version = "0.29.0", default-features = false, features = [
# "unstable-widget-ref",
# ] }
image = "0.25.6"
log = "0.4.27"
# bevy_log = { version = "0.18", default-features = false }
# bevy_asset = { version = "0.18", default-features = false }
# bevy_camera = { version = "0.18", default-features = false }
# bevy_color = { version = "0.18", default-features = false }
# bevy_ecs = { version = "0.18", default-features = false } # bevy_ecs = { version = "0.18", default-features = false }
# bevy_mesh = { version = "0.18", default-features = false }
# bevy_platform = { version = "0.18", default-features = false } # bevy_platform = { version = "0.18", default-features = false }
# bevy_sprite = { version = "0.18", default-features = false }
# bevy_image = { version = "0.18", default-features = false }
# bevy_image_export = { git = "https://github.com/paulkre/bevy_image_export.git", version = "0.16" }
futures = "0.3"
futures-lite = "2.1"
wgpu = "27"
bytemuck = "1.13"
thiserror = "2"

View File

@@ -1,94 +1,79 @@
use std::f32::consts::TAU;
use std::time::Duration; use std::time::Duration;
use embedded_graphics::{ use bevy::app::ScheduleRunnerPlugin;
image::{Image, ImageRaw}, use bevy::camera::RenderTarget;
mono_font::{MonoTextStyle, ascii::*}, use bevy::color::Color;
pixelcolor::BinaryColor, use bevy::prelude::*;
prelude::*, use bevy::render::RenderPlugin;
text::{Alignment, Text, TextStyleBuilder}, use bevy::winit::WinitPlugin;
}; use wgpu::{TextureFormat, TextureUsages};
use tokio::time::Instant;
use g13_driver::{ mod post_process;
G13, G13_LCD_COLUMNS, G13_LCD_ROWS,
joystick::{Axis, Button},
};
const DEADZONE: i32 = 30; use crate::post_process::PostProcessSettings;
use crate::renderer::{ImageExport, ImageExportPlugin, ImageExportSource};
use crate::shared::Spinner;
#[tokio::main] mod renderer;
async fn main() -> Result<(), Box<dyn std::error::Error>> { mod shared;
let mut g13 = G13::new()?;
let _g13 = g13.clone();
tokio::spawn(async move {
// background thread to update button state
loop {
if let Err(e) = _g13.read() {
eprintln!("{:?}", e);
break; // probably due to unplug
}
}
});
g13.set_lcd_color(4, 8, 96)?; fn main() {
App::new()
// let character_style = MonoTextStyle::new(&FONT_5X7, BinaryColor::On); .add_plugins((
// let textstyle = TextStyleBuilder::new() DefaultPlugins
// .baseline(embedded_graphics::text::Baseline::Top) .set(RenderPlugin {
// .alignment(Alignment::Left) synchronous_pipeline_compilation: true,
// .build(); ..default()
})
let mut dt = 0.0; .build()
.disable::<WinitPlugin>(),
let mut x = 20.0; ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1. / 24.)),
let mut y = (G13_LCD_ROWS as f64 / 2.0) - 3.0; post_process::PostProcessPlugin,
ImageExportPlugin,
let speed = 20.0; ))
.insert_resource(ClearColor(Color::linear_rgba(0.0, 0.0, 0.0, 1.0)))
let player_sprite = ImageRaw::<BinaryColor>::new(DATA, 16); .add_systems(Startup, setup_scene_system)
.add_systems(Update, rotate_cube)
loop { .run();
let start = Instant::now();
let mut jx = g13.state().x;
if (-DEADZONE..=DEADZONE).contains(&jx) {
jx = 0;
} }
let mut jy: i32 = g13.state().y; fn setup_scene_system(
if (-DEADZONE..=DEADZONE).contains(&jy) { mut commands: Commands,
jy = 0; meshes: ResMut<Assets<Mesh>>,
materials: ResMut<Assets<StandardMaterial>>,
mut images: ResMut<Assets<Image>>,
mut export_sources: ResMut<Assets<ImageExportSource>>,
) {
shared::spawn_3d_scene(commands.reborrow(), meshes, materials);
let mut image = Image::new_target_texture(
160,
43,
TextureFormat::Rgba8Unorm,
Some(TextureFormat::Rgba8UnormSrgb),
);
image.texture_descriptor.usage = TextureUsages::TEXTURE_BINDING
| TextureUsages::COPY_SRC
| TextureUsages::COPY_DST
| TextureUsages::RENDER_ATTACHMENT;
let image_handle = images.add(image);
commands.spawn((
Camera3d::default(),
Camera::default(),
RenderTarget::Image(image_handle.clone().into()),
Transform::from_xyz(0.0, 1.0, 2.5).looking_at(Vec3::ZERO, Vec3::Y),
PostProcessSettings { scale: 1.0 },
));
commands.spawn((ImageExport(export_sources.add(image_handle)),));
} }
let joyx = jx as f64 / 502.0; fn rotate_cube(mut cubes: Query<(&mut Transform, &Spinner)>, timer: Res<Time>) {
let joyy = jy as f64 / 502.0; for (mut transform, _cube) in &mut cubes {
transform.rotate_y(0.25 * TAU * timer.delta_secs());
x += joyx * speed * dt;
y += joyy * speed * dt;
// Render
g13.clear(BinaryColor::Off).unwrap();
// Player
let image = Image::new(&player_sprite, Point::new(x as i32, y as i32));
image.draw(&mut g13)?;
// Terrain Generation
g13.render().unwrap();
// Calculate delta time
let delta = Instant::now() - start;
tokio::time::sleep(Duration::from_millis(33) - delta).await;
dt = (Instant::now() - start).as_secs_f64();
} }
} }
#[rustfmt::skip]
const DATA: &[u8] = &[
0b11100000, 0b00000000,
0b11111111, 0b00000000,
0b10000000, 0b11000000,
0b10011111, 0b00111000,
0b10000000, 0b00000110,
0b01111111, 0b11111111,
];