Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved examples #342

Merged
merged 1 commit into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ build = "build.rs"
edition = "2018"
readme = "README.md"

exclude = ["resources/"]
exclude = ["examples/resources/"]

[badges]
maintenance = { status = "actively-developed" }
Expand Down
63 changes: 37 additions & 26 deletions examples/char_callback.rs
Original file line number Diff line number Diff line change
@@ -1,62 +1,73 @@
use minifb::{Key, Window, WindowOptions};
use std::cell::RefCell;
use std::rc::Rc;
use minifb::{InputCallback, Key, Window, WindowOptions};
use std::{cell::RefCell, rc::Rc};

const WIDTH: usize = 640;
const HEIGHT: usize = 360;
const WIDTH: usize = 1280;
const HEIGHT: usize = 720;

type KeyVec = Rc<RefCell<Vec<u32>>>;

struct Input {
keys: KeyVec,
}

impl Input {
fn new(data: &KeyVec) -> Input {
Input { keys: data.clone() }
}
}

impl minifb::InputCallback for Input {
impl InputCallback for Input {
/// Will be called every time a character key is pressed
fn add_char(&mut self, uni_char: u32) {
self.keys.borrow_mut().push(uni_char);
}
}

fn main() {
let mut buffer: Vec<u32> = vec![0; WIDTH * HEIGHT];
let mut buffer = vec![0u32; WIDTH * HEIGHT];

let mut window = Window::new(
"Test - ESC to exit",
"char_callback example - press ESC to exit",
WIDTH,
HEIGHT,
WindowOptions::default(),
)
.unwrap_or_else(|e| {
panic!("{:?}", e);
});

let keys_data = KeyVec::new(RefCell::new(Vec::new()));

let input = Box::new(Input::new(&keys_data));
.expect("Unable to create the window");

window.set_target_fps(60);
window.set_input_callback(input);

let keys = KeyVec::new(RefCell::new(Vec::new()));
window.set_input_callback(Box::new(Input { keys: keys.clone() }));

// produces a wave pattern where the screen goes from red to blue, and vice-versa
let mut wave: u8 = 0;
let mut wave_direction: i8 = 1;
while window.is_open() && !window.is_key_down(Key::Escape) {
for i in buffer.iter_mut() {
*i = 0; // write something more funny here!
let red: u32 = (wave as u32) << 16;
let green: u32 = 64 << 8;
let blue: u32 = (255 - wave) as u32;
let bg_color = red | green | blue;

for pixel in buffer.iter_mut() {
*pixel = bg_color;
}

// We unwrap here as we want this code to exit if it fails. Real applications may want to handle this in a different way
window.update_with_buffer(&buffer, WIDTH, HEIGHT).unwrap();

let mut keys = keys_data.borrow_mut();
let mut keys = keys.borrow_mut();

for t in keys.iter() {
println!("Code point: {}, Character: {:?}", *t, char::from_u32(*t));
println!("Code point: {}, Character: {:?}", *t, char::from_u32(*t));
}

keys.clear();

// switch color wave directions
match wave.checked_add_signed(wave_direction) {
Some(new_wave) => wave = new_wave,
None => {
wave_direction = -wave_direction;
if wave_direction > 0 {
wave += 1;
} else {
wave -= 1;
}
}
}
}
}
31 changes: 17 additions & 14 deletions examples/drop.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
use minifb::{Window, WindowOptions};
use std::thread;
use std::time::{Duration, Instant};
use std::{
thread,
time::{Duration, Instant},
};

const WIDTH: usize = 640 / 2;
const HEIGHT: usize = 360 / 2;
const WIDTH: usize = 1280;
const HEIGHT: usize = 720;

fn main() {
println!("Creating and showing a Window");

fn show_window() {
let mut window = Window::new(
"Drop Test - Window will close after 2 seconds.",
"Drop example - Window will close after 5 seconds",
WIDTH,
HEIGHT,
WindowOptions::default(),
)
.expect("Unable to create window");
.expect("Unable to create the window");

let now = Instant::now();
window.set_target_fps(60);

while window.is_open() && now.elapsed().as_secs() < 2 {
let now = Instant::now();
while window.is_open() && now.elapsed().as_secs() < 5 {
window.update();
}
}

fn main() {
println!("Showing Window");
show_window();
drop(window);
println!("Dropped");
thread::sleep(Duration::from_millis(2000));

thread::sleep(Duration::from_secs(2));
println!("Exiting");
}
29 changes: 12 additions & 17 deletions examples/julia.rs → examples/fractal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ const FRACTAL_DEPTH: u32 = 64;
const GENERATION_INFINITY: f64 = 16.;

fn main() {
let mut buffer: Vec<u32> = vec![0; WIDTH * HEIGHT];
let mut buffer = vec![0u32; WIDTH * HEIGHT];

let mut window = Window::new(
"Fractal - ESC to exit",
"Fractal example - press ESC to exit",
WIDTH,
HEIGHT,
WindowOptions {
resize: true,
scale: Scale::X2,
scale: Scale::X4,
scale_mode: ScaleMode::AspectRatioStretch,
..WindowOptions::default()
},
)
.expect("Unable to Open Window");
.expect("Unable to create the window");

window.set_target_fps(60);

Expand All @@ -39,9 +39,8 @@ fn main() {
let mut real = map((i % WIDTH) as f64, 0., WIDTH as f64, x_min, x_max);
let mut imag = map((i / HEIGHT) as f64, 0., HEIGHT as f64, y_min, y_max);

let mut n = 0;

while n < FRACTAL_DEPTH {
let mut depth = 0;
while depth < FRACTAL_DEPTH {
let re = real.powf(2.) - imag.powf(2.);
let im = 2. * real * imag;

Expand All @@ -51,10 +50,14 @@ fn main() {
if (real + imag).abs() > GENERATION_INFINITY {
break; // Leave when achieve infinity
}
n += 1;
depth += 1;
}

*pixel = fill(n);
*pixel = if depth == FRACTAL_DEPTH {
0x00
} else {
depth * 32 % 255
};
}

angle += 0.1;
Expand All @@ -67,11 +70,3 @@ fn main() {
fn map(val: f64, start1: f64, stop1: f64, start2: f64, stop2: f64) -> f64 {
start2 + (stop2 - start2) * ((val - start1) / (stop1 - start1))
}

fn fill(n: u32) -> u32 {
if FRACTAL_DEPTH == n {
0x00
} else {
n * 32 % 255
}
}
19 changes: 13 additions & 6 deletions examples/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,25 @@ use std::str::FromStr;

use minifb::{Icon, Key, Window, WindowOptions};

const WIDTH: usize = 1280;
const HEIGHT: usize = 720;

fn main() {
let mut window = Window::new(
"Window Icon Test - Press ESC to exit",
300,
300,
"Window icon example - press ESC to exit",
WIDTH,
HEIGHT,
WindowOptions {
resize: true,
..WindowOptions::default()
},
)
.expect("Unable to open Window");
.expect("Unable to create the window");

window.set_target_fps(60);

#[cfg(target_os = "windows")]
window.set_icon(Icon::from_str("resources/icon256.ico").unwrap());
window.set_icon(Icon::from_str("examples/resources/icon256.ico").unwrap());

#[cfg(target_os = "linux")]
{
Expand Down Expand Up @@ -170,7 +175,9 @@ fn main() {
1476329472, 1342111744, 1207894016, 1056899072, 939458560, 788463616, 654245888,
536281096, 385810432, 251592704, 134152192,
];
window.set_icon(Icon::try_from(&test[..]).unwrap());

// NOTE(@StefanoIncardone): this does not work on wayland
window.set_icon(Icon::try_from(test.as_slice()).unwrap());
}

while window.is_open() && !window.is_key_down(Key::Escape) {
Expand Down
76 changes: 43 additions & 33 deletions examples/image.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,53 @@
use minifb::{Key, ScaleMode, Window, WindowOptions};
use minifb::{Key, Window, WindowOptions};
use png::{Decoder, Transformations};
use std::fs::File;

fn main() {
use std::fs::File;
// The decoder is a build for reader and can be used to set various decoding options
// via `Transformations`. The default output transformation is `Transformations::EXPAND
// | Transformations::STRIP_ALPHA`.
let decoder = png::Decoder::new(File::open("resources/uv.png").unwrap());
let mut decoder = Decoder::new(File::open("examples/resources/planet.png").unwrap());

// Reading the image in RGBA format.
decoder.set_transformations(Transformations::ALPHA);
let mut reader = decoder.read_info().unwrap();
// Allocate the output buffer.
let mut buf = vec![0; reader.output_buffer_size()];
// Read the next frame. Currently this function should only called once.
// The default options
reader.next_frame(&mut buf).unwrap();
// convert buffer to u32

let u32_buffer: Vec<u32> = buf
.chunks(3)
.map(|v| ((v[0] as u32) << 16) | ((v[1] as u32) << 8) | v[2] as u32)
.collect();

let mut buffer = vec![0u32; reader.output_buffer_size()];

// View of pixels as individual subpixels (avoids allocating a second pixel buffer).
let mut u8_buffer = unsafe {
std::slice::from_raw_parts_mut(
buffer.as_mut_ptr() as *mut u8,
buffer.len() * std::mem::size_of::<u32>(),
)
};

// Read the next frame. Currently this function should only be called once.
reader.next_frame(&mut u8_buffer).unwrap();

// convert RGBA buffer read by the reader to an ARGB buffer as expected by minifb.
for (rgba, argb) in u8_buffer.chunks_mut(4).zip(buffer.iter_mut()) {
// extracting the subpixels
let r = rgba[0] as u32;
let g = rgba[1] as u32;
let b = rgba[2] as u32;
let a = rgba[3] as u32;

// merging the subpixels in ARGB format.
*argb = a << 24 | r << 16 | g << 8 | b;
}

let width = reader.info().width as usize;
let height = reader.info().height as usize;

let mut window = Window::new(
"Noise Test - Press ESC to exit",
reader.info().width as usize,
reader.info().height as usize,
WindowOptions {
resize: true,
scale_mode: ScaleMode::Center,
..WindowOptions::default()
},
"Image background example - Press ESC to exit",
width,
height,
WindowOptions::default(),
)
.expect("Unable to open Window");
.expect("Unable to create the window");

window.set_target_fps(60);

while window.is_open() && !window.is_key_down(Key::Escape) {
window
.update_with_buffer(
&u32_buffer,
reader.info().width as usize,
reader.info().height as usize,
)
.unwrap();
window.update_with_buffer(&buffer, width, height).unwrap();
}
}
Loading
Loading