summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-11-17 15:08:59 -0500
committerFreya Murphy <freya@freyacat.org>2025-11-17 15:08:59 -0500
commitd2521fcb32972e98170bc703984fc5a91f14ccb2 (patch)
tree45fd561e3c558246b9dfcdf1bd56e1e7fd64dd44
parentwasm: add a default emsdk sysroot for non nixos users (diff)
downloadDungeonCrawl-d2521fcb32972e98170bc703984fc5a91f14ccb2.tar.gz
DungeonCrawl-d2521fcb32972e98170bc703984fc5a91f14ccb2.tar.bz2
DungeonCrawl-d2521fcb32972e98170bc703984fc5a91f14ccb2.zip
wasm: add options for logs, debug, and seed
-rw-r--r--Makefile2
-rw-r--r--game/Cargo.toml5
-rw-r--r--game/src/main.rs68
-rw-r--r--game/www/index.html111
-rw-r--r--game/www/style.css121
5 files changed, 231 insertions, 76 deletions
diff --git a/Makefile b/Makefile
index faf04f3..0451fd2 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ EMCC_CFLAGS := -O3 \
-sWASM=1 \
-sASYNCIFY \
-sGL_ENABLE_GET_PROC_ADDRESS=1 \
- -sEXPORTED_RUNTIME_METHODS=HEAPF32,ccall,cwrap
+ -sEXPORTED_RUNTIME_METHODS=HEAPF32,ccall,cwrap,callMain
web: dist $(ASSETS_DST)
diff --git a/game/Cargo.toml b/game/Cargo.toml
index 0e64d0e..5cdf4af 100644
--- a/game/Cargo.toml
+++ b/game/Cargo.toml
@@ -8,6 +8,7 @@ publish.workspace = true
rust-version.workspace = true
[dependencies]
+argh.workspace = true
dungeon.workspace = true
graphics.workspace = true
@@ -20,7 +21,3 @@ x11 = ["graphics/x11"]
wayland = ["graphics/wayland"]
sdl = ["graphics/sdl"]
static = ["graphics/static"]
-
-# desktop dependencies
-[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dependencies]
-argh.workspace = true
diff --git a/game/src/main.rs b/game/src/main.rs
index a44f317..1ab49fe 100644
--- a/game/src/main.rs
+++ b/game/src/main.rs
@@ -1,49 +1,29 @@
-#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
-mod arch {
- use argh::FromArgs;
- use game::Game;
- use graphics::WindowBuilder;
+use argh::FromArgs;
+use game::Game;
+use graphics::WindowBuilder;
- /// Play a dungeon crawl game
- #[derive(FromArgs)]
- struct Args {
- /// enable vsync
- #[argh(switch)]
- vsync: bool,
- /// enable verbose logging
- #[argh(switch, short = 'v')]
- verbose: bool,
- /// set the map seed
- #[argh(option)]
- seed: Option<u64>,
- }
-
- pub fn main() -> graphics::Result<()> {
- // Parse arguments
- let args: Args = argh::from_env();
- // Load the window
- let window = WindowBuilder::new()
- .vsync(args.vsync)
- .verbose(args.verbose)
- .build()?;
- Game::new(window, args.seed).run();
- Ok(())
- }
-}
-
-#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
-mod arch {
- use game::Game;
- use graphics::WindowBuilder;
-
- pub fn main() -> graphics::Result<()> {
- // Load the window
- let window = WindowBuilder::new().build()?;
- Game::new(window, None).run();
- Ok(())
- }
+/// Play a dungeon crawl game
+#[derive(FromArgs)]
+struct Args {
+ /// enable vsync
+ #[argh(switch)]
+ vsync: bool,
+ /// enable verbose logging
+ #[argh(switch, short = 'v')]
+ verbose: bool,
+ /// set the map seed
+ #[argh(option)]
+ seed: Option<u64>,
}
pub fn main() -> graphics::Result<()> {
- arch::main()
+ // Parse arguments
+ let args: Args = argh::from_env();
+ // Load the window
+ let window = WindowBuilder::new()
+ .vsync(args.vsync)
+ .verbose(args.verbose)
+ .build()?;
+ Game::new(window, args.seed).run();
+ Ok(())
}
diff --git a/game/www/index.html b/game/www/index.html
index 2181c25..123f6a3 100644
--- a/game/www/index.html
+++ b/game/www/index.html
@@ -7,38 +7,95 @@
<meta property="og:title" content="Dungeon Crawl">
<meta property="og:description" content="Dungeon Crawl game!">
<title>Dungeon Crawl</title>
- <style>
- * {
- margin: 0;
- padding: none;
- border: none;
+ <link rel="stylesheet" href="/style.css">
+ </head>
+ <body id="body">
+ <div id="options">
+ <details id="logs_details">
+ <summary>Logs</summary>
+ <div class="menu">
+ <label>Logs</label>
+ <div id="logs"></div>
+ </div>
+ </details>
+
+ <button onclick="sendKey(114)">Toggle Debug</button>
+
+ <form onsubmit="play(event)" autocomplete="off">
+ <input placeholder="Seed" id="seed" /><button type="submit">Play</button>
+ </form>
+ </div>
+
+ <canvas id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
+
+ <script type='text/javascript'>
+ var canvas = document.querySelector('#canvas');
+ var logs = document.querySelector('#logs');
+ var seed = document.querySelector('#seed');
+ var loaded = false;
+
+ function outputLog(...args) {
+ let text = args.join(' ');
+ let span = document.createElement('span');
+ span.innerText = text;
+ logs.appendChild(span);
+ console.log(text)
+ }
+
+ function errorLog(...args) {
+ let text = args.join(' ');
+ let span = document.createElement('span');
+ span.innerText = text;
+ span.classList.add('error')
+ logs.appendChild(span);
+ console.error(text)
+ document.querySelector('#logs_details').open = true;
+ }
+
+ function sendKey(keyCode) {
+ canvas.dispatchEvent(new KeyboardEvent("keydown", {keyCode}));
+ setTimeout(() => {
+ canvas.dispatchEvent(new KeyboardEvent("keyup", {keyCode}));
+ }, 100);
+ }
+
+ function onRuntimeInitialized() {
+ loaded = true;
+ }
+
+ function play(e) {
+ e.preventDefault();
+
+ let seed_text = seed.value.trim();
+ let seed_num = Number(seed_text);
+ let args = [];
+
+ if (seed_text != '' && Number.isInteger(seed_num)) {
+ args.push('--seed');
+ args.push(String(seed_num));
+ }
+
+ outputLog('Using args:', args)
+
+ if (!loaded) {
+ errorLog("Game has not yet loaded")
+ }
+
+ seed.parentElement.remove();
+
+ Module.callMain(args)
}
- canvas {
- width: 100%;
- height: 100%;
- display: block;
- background: black;
- }
- </style>
- </head>
- <body>
- <canvas id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
- <script type='text/javascript'>
var Module = {
- canvas: (function () {
- var canvas = document.querySelector('#canvas');
- canvas.addEventListener("webglcontextlost", function (e) {
- alert('WebGL context lost. You will need to reload the page.');
- e.preventDefault();
- }, false);
- return canvas;
- })(),
- print: console.log,
- printErr: console.error,
- setStatus: console.debug,
+ canvas,
+ print: outputLog,
+ printErr: errorLog,
+ noInitialRun: true,
+ onRuntimeInitialized,
};
</script>
<script src="game.js"></script>
+ <script>
+ </script>
</body>
</html>
diff --git a/game/www/style.css b/game/www/style.css
new file mode 100644
index 0000000..3adf108
--- /dev/null
+++ b/game/www/style.css
@@ -0,0 +1,121 @@
+:root {
+ /* basic colors */
+ --bg: #334;
+ --fg: #faf9f8;
+ --error: #f9a;
+
+ /* button */
+ --button-bg: #667;
+ --button-fg: var(--fg);
+ --button-border: #def;
+ --button-hover: #556;
+
+ /* surface elements */
+ --surface-bg: #445;
+ --surface-fg: var(--fg);
+}
+
+* {
+ box-sizing: border-box;
+ font-family: monospace;
+ font-size: 16px;
+}
+
+body, html {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ background: black;
+}
+
+#canvas {
+ width: 100%;
+}
+
+#options {
+ background: var(--bg);
+ color: var(--fg);
+ position: relative;
+ width: 100%;
+ padding: 10px;
+ display: flex;
+ flex-direction: row;
+
+ details, button {
+ background: var(--button-bg);
+ color: var(--button-fg);
+ border: 1px solid var(--button-bg);
+ width: fit-content;
+ margin-right: 10px;
+
+ &:hover {
+ border: 1px solid var(--button-border);
+ background: var(--button-hover);
+ cursor: pointer;
+ }
+ }
+
+ input {
+ margin: 0;
+ background: var(--surface-bg);
+ color: var(--surface-fg);
+ boder: none;
+ outline: none;
+ box-shadow: none;
+ }
+
+ details summary, button, input {
+ padding: 10px;
+ font-weight: normal;
+ }
+
+}
+
+form {
+ padding: 0;
+ margin: 0;
+}
+
+details {
+ ::marker {
+ content: "";
+ }
+
+ .menu {
+ pointer-events: all;
+ position: absolute;
+ margin: 10px;
+ padding: 10px;
+ top: 100%;
+ height: fit-content;
+ overflow: auto;
+ max-height: 40vh;
+ background: var(--bg);
+ color: var(--fg);
+ border-radius: 5px;
+ box-shadow: 0 0 4px 1px #00000088;
+
+ label {
+ padding-bottom: 5px;
+ }
+ }
+}
+
+#logs {
+ width: 40vw;
+ height: 200px;
+ font-size: 15px;
+ background-color: var(--surface-bg);
+ color: var(--surface-fg);
+ border: none;
+ padding: 5px;
+ display: flex;
+ flex-direction: column;
+ overflow-y: auto;
+ border-radius: 5px;
+
+ .error {
+ color: var(--error);
+ }
+}