diff --git a/.cargo/config.toml b/.cargo/config.toml index d321f8a..8ce636d 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -5,7 +5,7 @@ rustflags = [ #"-C", "link-args=-O3 --closure 1", "-C", "link-args=-sASYNCIFY -sALLOW_MEMORY_GROWTH=1", # "-C", "link-args=-sALLOW_MEMORY_GROWTH=1", - "-C", "link-args=-sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS=['png']", + "-C", "link-args=-sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sUSE_SDL_TTF=2 -sSDL2_IMAGE_FORMATS=['png']", # USE_OGG, USE_VORBIS for OGG/VORBIS usage "-C", "link-args=--preload-file assets/", ] diff --git a/.vscode/settings.json b/.vscode/settings.json index 352a626..15b66bf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,8 @@ { "rust-analyzer.linkedProjects": [ "./Cargo.toml" + ], + "cSpell.words": [ + "rwops" ] } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 27a9171..fad4172 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,6 +101,7 @@ version = "0.1.0" dependencies = [ "colors-transform", "lazy_static", + "libc", "rand", "sdl2", "spin_sleep", @@ -215,9 +216,9 @@ checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "sdl2" -version = "0.36.0" +version = "0.35.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8356b2697d1ead5a34f40bcc3c5d3620205fe0c7be0a14656223bfeec0258891" +checksum = "f7959277b623f1fb9e04aea73686c3ca52f01b2145f8ea16f4ff30d8b7623b1a" dependencies = [ "bitflags", "lazy_static", @@ -227,9 +228,9 @@ dependencies = [ [[package]] name = "sdl2-sys" -version = "0.36.0" +version = "0.35.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26bcacfdd45d539fb5785049feb0038a63931aa896c7763a2a12e125ec58bd29" +checksum = "e3586be2cf6c0a8099a79a12b4084357aa9b3e0b0d7980e3b67aaf7a9d55f9f0" dependencies = [ "cfg-if", "libc", diff --git a/Cargo.toml b/Cargo.toml index 0fa1a90..1282b99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,11 @@ edition = "2021" colors-transform = "0.2.11" lazy_static = "1.4.0" rand = "0.8.5" -sdl2 = { version = "0.36", features = ["image", "ttf", "mixer"] } +sdl2 = { version = "0.35", features = ["image", "ttf"] } spin_sleep = "1.1.1" tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_level_debug"]} tracing-error = "0.2.0" tracing-subscriber = {version = "0.3.17", features = ["env-filter"]} + +[target.'cfg(target_os = "emscripten")'.dependencies] +libc = "0.2.16" \ No newline at end of file diff --git a/assets/TerminalVector.ttf b/assets/TerminalVector.ttf new file mode 100644 index 0000000..60468e6 Binary files /dev/null and b/assets/TerminalVector.ttf differ diff --git a/scripts/build.sh b/scripts/build.sh index 7fd0c07..cf03277 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -37,12 +37,11 @@ fi if [ "$skip_emsdk" = 'false' ]; then echo "Activating Emscripten" - ./../emsdk/emsdk activate latest + # SDL2-TTF requires 3.1.43, fails to build on latest + ./../emsdk/emsdk activate 3.1.43 source ../emsdk/emsdk_env.sh fi -# export EMCC_CFLAGS="-s USE_SDL=2" - echo "Building WASM with Emscripten" build_type='debug' if [ "$release" = 'true' ]; then diff --git a/src/main.rs b/src/main.rs index 1d14b4b..b9fe34d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,16 @@ use std::process; use std::time::Duration; +use sdl2::rwops::RWops; +use sdl2::ttf; use sdl2::event::Event; use sdl2::image::LoadTexture; use sdl2::keyboard::Keycode; use sdl2::pixels::Color; use sdl2::rect::{Point, Rect}; + +static FONT_DATA: &[u8] = include_bytes!("../assets/TerminalVector.ttf"); static BLACK: Color = Color::RGB(0, 0, 0); #[cfg(target_os = "emscripten")] @@ -35,6 +39,18 @@ fn sleep(ms: u32) { emscripten::emscripten::sleep(ms); } +#[cfg(not(target_os = "emscripten"))] +fn ttf_context() -> ttf::Sdl2TtfContext { + ttf::init().unwrap() +} + +// Honestly, I don't know why this is necessary. I'm just copying from https://github.com/aelred/tetris/blob/0ad88153db1ca7962b42277504c0f7f9f3c675a9/tetris-sdl/src/main.rs#L88-L92 +#[cfg(target_os = "emscripten")] +fn ttf_context() -> &'static ttf::Sdl2TtfContext { + // Deliberately leak so we get a static lifetime + Box::leak(Box::new(ttf::init().unwrap())) +} + fn main() { let ctx = sdl2::init().unwrap(); let video_ctx = ctx.video().unwrap(); @@ -57,11 +73,13 @@ fn main() { let texture_creator = canvas.texture_creator(); let mut point = Point::new(0, 0); + let ttf_ctx = ttf_context(); + let mut prev = now(); - // let ctx = Rc::new(RefCell::new(ctx)); - // let canvas = Rc::new(RefCell::new(canvas)); - // let texture_creator = Rc::new(texture_creator); + let font_data = RWops::from_bytes(FONT_DATA).unwrap(); + let font_size = 32; + let font = ttf_ctx.load_font_from_rwops(font_data, font_size).unwrap(); let fruit_atlas = texture_creator .load_texture("./assets/fruit.png") @@ -135,6 +153,14 @@ fn main() { canvas.set_draw_color(BLACK); canvas.clear(); + // draw fps counter + let surface = font + .render(&format!("{:.2}", avg_fps)) + .blended(Color::RGBA(255, 255, 255, 255)) + .unwrap(); + let texture = texture_creator.create_texture_from_surface(&surface).unwrap(); + let _ = canvas.copy(&texture, None, Rect::new(0, 0, 100, 100)); + canvas .copy_ex( &fruit_atlas,