commit 27d8ff1717354f761c1e697f3704105ac703cca8 Author: Stephen Seo Date: Wed Sep 18 19:22:56 2024 +0900 Init commit template for emscripten Rust diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..178135c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/dist/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..da65e65 --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +ifdef RELEASE + RUST_BUILD_TYPE := release + RUST_EXTRA_FLAGS := --release + C_OTHER_FLAGS := -DNDEBUG -O2 +else + RUST_BUILD_TYPE := debug + RUST_EXTRA_FLAGS := + C_OTHER_FLAGS := -Og +endif + +CC := source ${HOME}/git/emsdk/emsdk_env.sh && emcc +CFLAGS := \ + -Irust_src/include \ + -sEXPORTED_FUNCTIONS=_main \ + -sSTACK_SIZE=2097152 \ + ${C_OTHER_FLAGS} +# Check https://emscripten.org/docs/tools_reference/emcc.html for more compiler +# flags to pass to emcc. + +HEADERS := \ + rust_src/include/rust_src.h + +all: dist + +rust_src/target/wasm32-unknown-emscripten/${RUST_BUILD_TYPE}/libems_rust_template.a: + cd rust_src && cargo build --target=wasm32-unknown-emscripten ${RUST_EXTRA_FLAGS} + +dist: rust_src/target/wasm32-unknown-emscripten/${RUST_BUILD_TYPE}/libems_rust_template.a src/main.c.o + @mkdir dist + ${CC} -o dist/game.html ${CFLAGS} $^ + ln -s game.html dist/index.html + +.PHONY: clean + +clean: + cd rust_src && cargo clean + rm -f src/*.c.o + rm -rf dist + +%.c.o: %.c ${HEADERS} + ${CC} -o $@ -c ${CFLAGS} $< diff --git a/rust_src/.gitignore b/rust_src/.gitignore new file mode 100644 index 0000000..a5ff07f --- /dev/null +++ b/rust_src/.gitignore @@ -0,0 +1,8 @@ +/target + + +# Added by cargo +# +# already existing elements were commented out + +#/target diff --git a/rust_src/Cargo.lock b/rust_src/Cargo.lock new file mode 100644 index 0000000..23b7a83 --- /dev/null +++ b/rust_src/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ems_rust_template" +version = "0.1.0" diff --git a/rust_src/Cargo.toml b/rust_src/Cargo.toml new file mode 100644 index 0000000..ea520ba --- /dev/null +++ b/rust_src/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "ems_rust_template" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["staticlib"] + +[profile.release] +panic = "abort" + +[profile.dev] +panic = "abort" + +[dependencies] diff --git a/rust_src/include/rust_src.h b/rust_src/include/rust_src.h new file mode 100644 index 0000000..e201b5a --- /dev/null +++ b/rust_src/include/rust_src.h @@ -0,0 +1,9 @@ +#ifndef EMSCRIPTEN_RUST_TEMPLATE_RUST_SRC_H_ +#define EMSCRIPTEN_RUST_TEMPLATE_RUST_SRC_H_ + +extern void *get_main_ctx(void); +extern void ctx_update(void *ctx); +extern void ctx_draw(void *ctx); +extern void ctx_resize_event_callback(void *ctx, int width, int height); + +#endif diff --git a/rust_src/src/lib.rs b/rust_src/src/lib.rs new file mode 100644 index 0000000..59944f1 --- /dev/null +++ b/rust_src/src/lib.rs @@ -0,0 +1,57 @@ +use std::ffi; + +#[no_mangle] +pub extern "C" fn get_main_ctx() -> *mut ffi::c_void { + Context::ems_new() +} + +#[no_mangle] +pub extern "C" fn ctx_update(ctx: *mut ffi::c_void) { + unsafe { + let ctx: *mut Context = ctx as *mut Context; + (*ctx).update(); + } +} + +#[no_mangle] +pub extern "C" fn ctx_draw(ctx: *mut ffi::c_void) { + unsafe { + let ctx: *mut Context = ctx as *mut Context; + (*ctx).draw(); + } +} + +#[no_mangle] +pub extern "C" fn ctx_resize_event_callback(ctx: *mut ffi::c_void, width: ffi::c_int, height: ffi::c_int) { + unsafe { + let ctx: *mut Context = ctx as *mut Context; + (*ctx).resize_event_callback(width, height); + } +} + +struct Context { +} + +impl Context { + pub fn new() -> Self { + Self { + } + } + + pub fn ems_new() -> *mut ffi::c_void { + let ctx_box: Box = Box::new(Context::new()); + Box::::leak(ctx_box) as *mut Context as *mut ffi::c_void + } + + pub fn update(&mut self) { + println!("update called."); + } + + pub fn draw(&mut self) { + println!("draw called."); + } + + pub fn resize_event_callback(&mut self, width: ffi::c_int, height: ffi::c_int) { + println!("Resize event: {}, {}", width, height); + } +} diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..777b937 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +*.c.o diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..de4b26e --- /dev/null +++ b/src/main.c @@ -0,0 +1,39 @@ +#include +#include + +#include + +EM_JS(int, canvas_get_width, (), { + return document.getElementById("canvas").clientWidth; +}); +EM_JS(int, canvas_get_height, (), { + return document.getElementById("canvas").clientHeight; +}); + +void *main_init(void) { + return get_main_ctx(); +} + +EM_BOOL resize_event_callback(int event_type, const EmscriptenUiEvent *event, void *ud) { + if (event_type == EMSCRIPTEN_EVENT_RESIZE) { + ctx_resize_event_callback(ud, canvas_get_width(), canvas_get_height()); + } + return false; +} + +void main_loop_update(void *ud) { + ctx_update(ud); + ctx_draw(ud); +} + +int main(void) { + void *ctx = main_init(); + + emscripten_set_resize_callback( + EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, resize_event_callback); + + // This function never returns. + emscripten_set_main_loop_arg(main_loop_update, ctx, 0, 1); + + return 0; +}