diff --git a/examples/starter.rs b/examples/starter.rs new file mode 100644 index 0000000..c847f59 --- /dev/null +++ b/examples/starter.rs @@ -0,0 +1,71 @@ +//! pbio starter — Ausgangspunkt für eigene CPU-Render-Projekte. +//! +//! Ausführen: cargo run --example starter --release +//! +//! Zeigt: Game-Loop-Struktur, non-blocking Event-Polling, Tastatur (Esc beendet), +//! Maus, direktes Schreiben auf den indizierten Framebuffer. + +use std::time::Duration; + +use pbio::{Event, Key, MouseButton, Platform, PlatformConfig}; + +fn main() { + let mut p = Platform::new(PlatformConfig { + title: "pbio starter".into(), + window_size: (960, 720), + framebuffer_size: (320, 240), + aspect_ratio: Some(4.0/3.0), + ..Default::default() + }); + + let mut mouse = (0.0_f32, 0.0_f32); + let mut paint = false; + let mut frame = 0u32; + + while !p.should_close() { + // 0-Timeout: nicht-blockierend pollen, damit der Loop unabhängig + // von Eingaben pro Frame durchläuft. None würde bis zum nächsten + // Event schlafen — gut für statische UIs, schlecht für Animation. + p.poll_events(Some(Duration::from_millis(0))); + + // drain_events() borrowt &mut self → Aktionen auf p erst nach dem Loop. + let mut close = false; + for ev in p.drain_events() { + match ev { + Event::Key { key: Key::Escape, pressed: true, .. } => close = true, + Event::MouseMove { x, y } => mouse = (x, y), + Event::MouseBtn { button: MouseButton::Left, pressed } => paint = pressed, + _ => {} + } + } + if close { p.request_close(); } + + let (w, h) = p.framebuffer_size(); + let fb = p.framebuffer_mut(); + + // Diagonal wanderndes Gradientband. Jeder Pixel ist ein Palettenindex + // 0..=255 — Default-Palette ist RGB332, daher die sichtbaren Bänder. + let t = (frame / 256) as u8; + for y in 0..h { + for x in 0..w { + fb[(y * w + x) as usize] = (x as u8).wrapping_add(y as u8).wrapping_add(t); + } + } + + // Cursor: 3x3-Quadrat in Palettenindex 0xE0 (rot), beim Klick 0xFC (gelb). + let (mx, my) = (mouse.0 as i32, mouse.1 as i32); + let cursor_ix = if paint { 0xFC } else { 0xE0 }; + for dy in -1..=1 { + for dx in -1..=1 { + let x = mx + dx; + let y = my + dy; + if (0..w as i32).contains(&x) && (0..h as i32).contains(&y) { + fb[(y as u32 * w + x as u32) as usize] = cursor_ix; + } + } + } + + p.present(); + frame = frame.wrapping_add(1); + } +}