Compare commits

...

4 Commits

Author SHA1 Message Date
973fa08ac9 ci: better build scripts 2025-06-17 11:48:09 -05:00
4a1f565f72 feat(wasm): add index.html 2025-06-17 11:48:01 -05:00
2ddf2611d9 ci: add wasm32 cargo flags 2025-06-17 11:47:52 -05:00
b3a3664578 feat: game loop 2025-06-17 11:47:43 -05:00
10 changed files with 154 additions and 10 deletions

4
.cargo/config.toml Normal file
View File

@@ -0,0 +1,4 @@
[target.wasm32-unknown-emscripten]
rustflags = [
"--use-preload-plugins --preload-file assets -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s ASSERTIONS=1",
]

7
build.ps1 Normal file
View File

@@ -0,0 +1,7 @@
& cargo build --target=wasm32-unknown-emscripten --release
mkdir -p dist -Force
cp ./target/wasm32-unknown-emscripten/release/Pac_Man.wasm ./dist
cp ./target/wasm32-unknown-emscripten/release/Pac-Man.js ./dist
cp index.html dist

4
build.sh Normal file → Executable file
View File

@@ -5,6 +5,6 @@ cargo build --target=wasm32-unknown-emscripten --release
mkdir -p dist
cp target/wasm32-unknown-emscripten/release/rust_sdl2_wasm.wasm dist
cp target/wasm32-unknown-emscripten/release/rust-sdl2-wasm.js dist
cp target/wasm32-unknown-emscripten/release/Pac_Man.wasm dist
cp target/wasm32-unknown-emscripten/release/Pac-Man.js dist
cp index.html dist

21
index.html Normal file
View File

@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
let Module = {
canvas: (function () {
// this is how we provide a canvas to our sdl2
return document.getElementById("canvas");
})(),
preRun: [function () {
ENV.RUST_LOG = "info,wgpu=warn"
}]
};
</script>
<script src="Pac-Man.js"></script>
</body>
</html>

3
serve.ps1 Normal file
View File

@@ -0,0 +1,3 @@
& ./build.ps1
cd ./dist
python -m http.server

0
src/board.rs Normal file
View File

44
src/constants.rs Normal file
View File

@@ -0,0 +1,44 @@
pub const BOARD_WIDTH: u32 = 28;
pub const BOARD_HEIGHT: u32 = 36;
pub const BLOCK_SIZE_24: u32 = 24;
pub const BLOCK_SIZE_32: u32 = 32;
pub const WINDOW_WIDTH: u32 = BLOCK_SIZE_24 * BOARD_WIDTH;
pub const WINDOW_HEIGHT: u32 = BLOCK_SIZE_24 * BOARD_HEIGHT;
pub const RAW_BOARD: &str = r###"
############################
#............##............#
#.####.#####.##.#####.####.#
#o####.#####.##.#####.####o#
#.####.#####.##.#####.####.#
#..........................#
#.####.##.########.##.####.#
#.####.##.########.##.####.#
#......##....##....##......#
######.##### ## #####.######
#.##### ## #####.#
#.## 1 ##.#
#.## ###==### ##.#
######.## # # ##.######
. #2 3 4 # .
######.## # # ##.######
#.## ######## ##.#
#.## ##.#
#.## ######## ##.#
######.## ######## ##.######
#............##............#
#.####.#####.##.#####.####.#
#.####.#####.##.#####.####.#
#o..##.......0 .......##..o#
###.##.##.########.##.##.###
###.##.##.########.##.##.###
#......##....##....##......#
#.##########.##.##########.#
#.##########.##.##########.#
#..........................#
############################
"###;

44
src/emscripten.rs Normal file
View File

@@ -0,0 +1,44 @@
// taken from https://github.com/Gigoteur/PX8/blob/master/src/px8/emscripten.rs
#[cfg(target_os = "emscripten")]
pub mod emscripten {
use std::cell::RefCell;
use std::ptr::null_mut;
use std::os::raw::{c_int, c_void, c_char, c_float};
use std::ffi::{CStr, CString};
#[allow(non_camel_case_types)]
type em_callback_func = unsafe extern "C" fn();
extern "C" {
// void emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop)
pub fn emscripten_set_main_loop(func: em_callback_func,
fps: c_int,
simulate_infinite_loop: c_int);
pub fn emscripten_cancel_main_loop();
pub fn emscripten_pause_main_loop();
pub fn emscripten_get_now() -> c_float;
}
thread_local!(static MAIN_LOOP_CALLBACK: RefCell<*mut c_void> = RefCell::new(null_mut()));
pub fn set_main_loop_callback<F>(callback: F)
where F: FnMut()
{
MAIN_LOOP_CALLBACK
.with(|log| { *log.borrow_mut() = &callback as *const _ as *mut c_void; });
unsafe {
emscripten_set_main_loop(wrapper::<F>, -1, 1);
}
unsafe extern "C" fn wrapper<F>()
where F: FnMut()
{
MAIN_LOOP_CALLBACK.with(|z| {
let closure = *z.borrow_mut() as *mut F;
(*closure)();
});
}
}
}

11
src/game.rs Normal file
View File

@@ -0,0 +1,11 @@
pub struct Game {}
impl Game {
pub fn new() -> Game {
Game {}
}
pub fn tick() {}
pub fn draw() {}
}

View File

@@ -5,6 +5,9 @@ use sdl2::keyboard::{Keycode, Mod};
use std::time::Duration;
use crate::constants::{WINDOW_WIDTH, WINDOW_HEIGHT};
#[cfg(target_os = "emscripten")]
pub mod emscripten;
mod constants;
mod board;
mod game;
@@ -19,27 +22,34 @@ pub fn main() {
.expect("Could not initialize window");
let mut canvas = window.into_canvas().build().expect("Could not build canvas");
let texture_creator= canvas.texture_creator();
let texture_creator = canvas.texture_creator();
let map_texture = texture_creator.load_texture("assets/map.png").expect("Could not load pacman texture");
canvas.copy(&map_texture, None, None).expect("Could not render texture on canvas");
let mut event_pump = sdl_context.event_pump().expect("Could not get SDL EventPump");
'main: loop {
let mut main_loop = || {
for event in event_pump.poll_iter() {
match event {
Event::Quit { .. } |
Event::KeyDown { keycode: Some(Keycode::Q), .. } => {
break 'main;
}
event @ Event::KeyDown { .. } => {
Event::KeyDown { keycode: Some(Keycode::Q), .. } => break,
event @ Event::KeyDown { .. } => {
println!("{:?}", event);
},
}
_ => {}
}
}
canvas.present();
::std::thread::sleep(Duration::from_millis(10));
}
};
#[cfg(target_os = "emscripten")]
use emscripten::{emscripten};
#[cfg(target_os = "emscripten")]
emscripten::set_main_loop_callback(main_loop);
#[cfg(not(target_os = "emscripten"))]
loop { main_loop(); }
}