diff --git a/sdl-demo/.cargo/config.toml b/sdl-demo/.cargo/config.toml new file mode 100644 index 0000000..0c00172 --- /dev/null +++ b/sdl-demo/.cargo/config.toml @@ -0,0 +1,2 @@ +[env] +RESOURCE_DIR = { value = "rsc", relative = true } diff --git a/sdl-demo/Cargo.lock b/sdl-demo/Cargo.lock new file mode 100644 index 0000000..416d9fd --- /dev/null +++ b/sdl-demo/Cargo.lock @@ -0,0 +1,63 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" + +[[package]] +name = "sdl-demo" +version = "0.1.0" +dependencies = [ + "sdl2", +] + +[[package]] +name = "sdl2" +version = "0.35.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7959277b623f1fb9e04aea73686c3ca52f01b2145f8ea16f4ff30d8b7623b1a" +dependencies = [ + "bitflags", + "lazy_static", + "libc", + "sdl2-sys", +] + +[[package]] +name = "sdl2-sys" +version = "0.35.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3586be2cf6c0a8099a79a12b4084357aa9b3e0b0d7980e3b67aaf7a9d55f9f0" +dependencies = [ + "cfg-if", + "libc", + "version-compare", +] + +[[package]] +name = "version-compare" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" diff --git a/sdl-demo/Cargo.toml b/sdl-demo/Cargo.toml new file mode 100644 index 0000000..e2854c9 --- /dev/null +++ b/sdl-demo/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "sdl-demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies.sdl2] +version = "0.35" +default-features = false +features = [ "ttf", "image" ] diff --git a/sdl-demo/rsc/fonts/fira-code-regular.ttf b/sdl-demo/rsc/fonts/fira-code-regular.ttf new file mode 100644 index 0000000..e237398 Binary files /dev/null and b/sdl-demo/rsc/fonts/fira-code-regular.ttf differ diff --git a/sdl-demo/rsc/img/ina.png b/sdl-demo/rsc/img/ina.png new file mode 100644 index 0000000..c905230 Binary files /dev/null and b/sdl-demo/rsc/img/ina.png differ diff --git a/sdl-demo/src/main.rs b/sdl-demo/src/main.rs new file mode 100644 index 0000000..74a429f --- /dev/null +++ b/sdl-demo/src/main.rs @@ -0,0 +1,133 @@ +extern crate sdl2; + +use sdl2::image::LoadTexture; +use sdl2::pixels::Color; +use sdl2::event::Event; +use sdl2::keyboard::Keycode; +use sdl2::ttf; +use sdl2::image; +use sdl2::rect::Rect; + +const RESOURCE_DIR: &str = env!("RESOURCE_DIR"); + +fn main() { + let sdl_ctx = sdl2::init().unwrap_or_else(|_| { + eprintln!("error: could not init sdl2"); + panic!() + }); + let video_ctx = sdl_ctx.video().unwrap_or_else(|_| { + eprintln!("error: could not init sdl2 video subsystem"); + panic!() + }); + + let ttf_ctx = ttf::init().unwrap_or_else(|_| { + eprintln!("error: could not init sdl2 font subsystem"); + panic!() + }); + let fira_code_path = RESOURCE_DIR.to_owned() + "/fonts/fira-code-regular.ttf"; + let fira_code = ttf_ctx.load_font(fira_code_path, 64).unwrap_or_else(|_| { + eprintln!("error: could not load font"); + panic!() + }); + + let _ = image::init(image::InitFlag::PNG).unwrap_or_else(|_| { + eprintln!("error: could not init sdl2 image subsystem"); + panic!() + }); + + let window = video_ctx.window("Rust SDL2 Demo", 1000, 1000) + .position_centered().build().unwrap_or_else(|_| { + eprintln!("error: could not create window"); + panic!() + }); + let mut canvas = window.into_canvas().build().unwrap_or_else(|_| { + eprintln!("error: could not create canvas for window"); + panic!() + }); + + draw_loop(&sdl_ctx, &mut canvas, &fira_code); +} + +fn draw_loop(cxt: &sdl2::Sdl, + canvas: &mut sdl2::render::WindowCanvas, + font: &ttf::Font) { + canvas.set_draw_color(Color::WHITE); + canvas.clear(); + canvas.present(); + let texture_creator = canvas.texture_creator(); + let img_path = RESOURCE_DIR.to_owned() + "/img/ina.png"; + let img_png = texture_creator.load_texture(img_path).unwrap_or_else(|_| { + eprintln!("error: could not load ina png"); + panic!() + }); + let img_box = get_box_for_texture(canvas.window(), &img_png, 0.3); + let mut event_pump = cxt.event_pump().unwrap(); + let mut color: u8 = 255; + 'game_loop: loop { + let color1 = Color::RGB(color, color, color); + let color2 = Color::RGB(255 - color, 255 - color, 255 - color); + canvas.set_draw_color(color1); + canvas.clear(); + + canvas.set_draw_color(color2); + let _ = canvas.fill_rect(Rect::new(100, 100, 800, 800)); + + canvas.set_draw_color(color1); + let _ = canvas.fill_rect(Rect::new(200, 200, 600, 600)); + + canvas.set_draw_color(color2); + let _ = canvas.fill_rect(Rect::new(300, 300, 400, 400)); + + canvas.set_draw_color(color1); + let _ = canvas.fill_rect(Rect::new(400, 400, 200, 200)); + + canvas.set_draw_color(color2); + let text_surround_box = get_box_for_text(canvas.window(), font, "SDL2 Rust Demo"); + let _ = canvas.fill_rect(text_surround_box); + canvas.set_draw_color(color1); + let _ = canvas.draw_rect(text_surround_box); + let text_suface = font.render("SDL2 Rust Demo").solid(color1).unwrap(); + let text_texture = texture_creator.create_texture_from_surface(text_suface).unwrap(); + let _ = canvas.copy(&text_texture, None, text_surround_box); + + let _ = canvas.copy(&img_png, None, img_box); + + for evt in event_pump.poll_iter() { + match evt { + Event::Quit {..} | + Event::KeyDown { keycode: Some(Keycode::Q), .. } | + Event::KeyDown { keycode: Some(Keycode::Escape), .. } => break 'game_loop, + Event::KeyDown { keycode: Some(Keycode::Equals), .. } => if color < 255 { color += 5 }, + Event::KeyDown { keycode: Some(Keycode::Minus), .. } => if color > 0 { color -= 5 }, + _ => {} + } + } + canvas.present(); + } +} + +fn get_box_for_text(win: &sdl2::video::Window, font: &ttf::Font, text: &str) -> Rect { + let (ww, wh) = win.size(); + let (tw, th) = font.size_of(text).unwrap(); + let cx = (ww as f32 / 2.0) as i32; + let cy = (wh as f32 / 2.0) as i32; + Rect::new( + cx - (tw as f32 / 2.0) as i32, + cy - (th as f32 / 2.0) as i32, + tw, + th + ) +} + +fn get_box_for_texture(win: &sdl2::video::Window, tex: &sdl2::render::Texture, scale: f32) -> Rect { + let tq = tex.query(); + let tw = (tq.width as f32 * scale) as u32; + let th = (tq.height as f32 * scale) as u32; + let (ww, _) = win.size(); + Rect::new( + ((ww as f32 / 2.0) - (tw as f32 / 2.0)) as i32, + 10, + tw, + th + ) +}