html terminal
viewer
| -rw-r--r-- | html-src/masm-bindings.js | 1 | ||||
| -rw-r--r-- | html-src/masm.wasm | bin | 0 -> 1002318 bytes | |||
| -rw-r--r-- | html-src/viewer.html | 60 | ||||
| -rw-r--r-- | src/server.rs | 24 |
4 files changed, 84 insertions, 1 deletions
diff --git a/html-src/masm-bindings.js b/html-src/masm-bindings.js new file mode 100644 index 0000000..e3d9ec1 --- /dev/null +++ b/html-src/masm-bindings.js @@ -0,0 +1 @@ +let wasm;const cachedTextDecoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-8",{ignoreBOM:true,fatal:true}):{decode:()=>{throw Error("TextDecoder not available")}};if(typeof TextDecoder!=="undefined"){cachedTextDecoder.decode()}let cachedUint8Memory0=null;function getUint8Memory0(){if(cachedUint8Memory0===null||cachedUint8Memory0.byteLength===0){cachedUint8Memory0=new Uint8Array(wasm.memory.buffer)}return cachedUint8Memory0}function getStringFromWasm0(ptr,len){ptr=ptr>>>0;return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr,ptr+len))}let WASM_VECTOR_LEN=0;function passArray8ToWasm0(arg,malloc){const ptr=malloc(arg.length*1,1)>>>0;getUint8Memory0().set(arg,ptr/1);WASM_VECTOR_LEN=arg.length;return ptr}let cachedInt32Memory0=null;function getInt32Memory0(){if(cachedInt32Memory0===null||cachedInt32Memory0.byteLength===0){cachedInt32Memory0=new Int32Array(wasm.memory.buffer)}return cachedInt32Memory0}function getArrayU8FromWasm0(ptr,len){ptr=ptr>>>0;return getUint8Memory0().subarray(ptr/1,ptr/1+len)}export function render(v){try{const retptr=wasm.__wbindgen_add_to_stack_pointer(-16);const ptr0=passArray8ToWasm0(v,wasm.__wbindgen_export_0);const len0=WASM_VECTOR_LEN;wasm.render(retptr,ptr0,len0);var r0=getInt32Memory0()[retptr/4+0];var r1=getInt32Memory0()[retptr/4+1];var v2=getArrayU8FromWasm0(r0,r1).slice();wasm.__wbindgen_export_1(r0,r1*1);return v2}finally{wasm.__wbindgen_add_to_stack_pointer(16)}}async function __wbg_load(module,imports){if(typeof Response==="function"&&module instanceof Response){if(typeof WebAssembly.instantiateStreaming==="function"){try{return await WebAssembly.instantiateStreaming(module,imports)}catch(e){if(module.headers.get("Content-Type")!="application/wasm"){console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",e)}else{throw e}}}const bytes=await module.arrayBuffer();return await WebAssembly.instantiate(bytes,imports)}else{const instance=await WebAssembly.instantiate(module,imports);if(instance instanceof WebAssembly.Instance){return{instance:instance,module:module}}else{return instance}}}function __wbg_get_imports(){const imports={};imports.wbg={};imports.wbg.__wbindgen_throw=function(arg0,arg1){throw new Error(getStringFromWasm0(arg0,arg1))};return imports}function __wbg_init_memory(imports,maybe_memory){}function __wbg_finalize_init(instance,module){wasm=instance.exports;__wbg_init.__wbindgen_wasm_module=module;cachedInt32Memory0=null;cachedUint8Memory0=null;return wasm}function initSync(module){if(wasm!==undefined)return wasm;const imports=__wbg_get_imports();__wbg_init_memory(imports);if(!(module instanceof WebAssembly.Module)){module=new WebAssembly.Module(module)}const instance=new WebAssembly.Instance(module,imports);return __wbg_finalize_init(instance,module)}async function __wbg_init(input){if(wasm!==undefined)return wasm;if(typeof input==="undefined"){input=new URL("masm_bg.wasm",import.meta.url)}const imports=__wbg_get_imports();if(typeof input==="string"||typeof Request==="function"&&input instanceof Request||typeof URL==="function"&&input instanceof URL){input=fetch(input)}__wbg_init_memory(imports);const{instance,module}=await __wbg_load(await input,imports);return __wbg_finalize_init(instance,module)}export{initSync};export default __wbg_init; diff --git a/html-src/masm.wasm b/html-src/masm.wasm Binary files differnew file mode 100644 index 0000000..e4fb386 --- /dev/null +++ b/html-src/masm.wasm diff --git a/html-src/viewer.html b/html-src/viewer.html new file mode 100644 index 0000000..0630dde --- /dev/null +++ b/html-src/viewer.html @@ -0,0 +1,60 @@ +<!doctype html> +<html lang="en-US"> + +<head> + <meta charset="utf-8" /> + <title>view the current game</title> + <style> + img { + user-select: none; + } + + body { + background-color: #3E3B3B; + } + </style> +</head> + +<body> + <img id="picture" draggable="false"> + <script src="https://unpkg.com/@panzoom/[email protected]/dist/panzoom.min.js"></script> + <script type="module"> + let begin = [] + let end = [0, 0] + let press = false + import init, { render } from "/masm.js"; + async function base(buffer) { + const base64url = await new Promise(r => { + const reader = new FileReader() + reader.onload = () => r(reader.result) + reader.readAsDataURL(new Blob([buffer])) + }); + return base64url.slice(base64url.indexOf(',') + 1) + } + init().then(() => { + fetch("http://apricotalliance.org/savefile").then(function (content) { + content.arrayBuffer().then(function (buf) { + let pic = document.getElementById('picture'); + let imgbuf = render(new Uint8Array(buf)); + console.log("render done"); + pic.src = URL.createObjectURL(new Blob([imgbuf])) + let panzoom = Panzoom(pic, { maxScale: 7, cursor: "grab", noBind: true }); + panzoom.pan(pic.width / 2, pic.height / 2, { animate: true }) + panzoom.zoom(1, { animate: true }) + pic.addEventListener('pointerdown', (event) => { + pic.style.cursor = "grabbing" + panzoom.handleDown(event) + }) + pic.addEventListener('pointerup', (event) => { + pic.style.cursor = "grab" + panzoom.handleUp(event) + }) + pic.addEventListener('pointermove', panzoom.handleMove) + pic.addEventListener('wheel', panzoom.zoomWithWheel) + }) + }) + }); + </script> +</body> + +</html>
\ No newline at end of file diff --git a/src/server.rs b/src/server.rs index 78e3b1c..1f14153 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,7 +1,7 @@ use crate::bot::Bot; use crate::process::Process; use axum::{ - http::header::CONTENT_TYPE, + http::header::{CONTENT_ENCODING, CONTENT_TYPE}, response::{AppendHeaders, Html, IntoResponse}, routing::get, Router, Server as AxumServer, @@ -83,6 +83,28 @@ impl Server { .route("/favicon.ico", png!(logo32)) .route("/view", get(map_view)) .route("/savefile", get(map_file)) + .route( + "/masm_bg.wasm", + get(|| async { + ( + AppendHeaders([ + (CONTENT_TYPE, "application/wasm"), + (CONTENT_ENCODING, "gzip"), + ]), + include_bytes!("../html-src/masm.wasm"), + ) + }), + ) + .route( + "/masm.js", + get(|| async { + ( + AppendHeaders([(CONTENT_TYPE, "application/javascript")]), + include_str!("../html-src/masm-bindings.js"), + ) + }), + ) + .route("/viewer", html!(viewer)) .with_state(state.clone()); tokio::spawn(async move { AxumServer::bind(&addr) |