Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .gitpod.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ ENV LANG=C.UTF-8
# ARGS
ARG CONTAINER_USER=gitpod
ARG CONTAINER_GROUP=gitpod
ARG TOOLCHAIN_VERSION=1.65.0.1
ARG ESP_BOARD="esp32,esp32s2,esp32s3,esp32c3"
ARG INSTALL_RUST_TOOLCHAIN=espup

Expand All @@ -27,11 +26,11 @@ WORKDIR /home/${CONTAINER_USER}
# Install Rust toolchain, extra crates and esp-idf
ENV PATH=${PATH}:/home/${CONTAINER_USER}/.cargo/bin:/home/${CONTAINER_USER}/opt/bin
ADD --chown=${CONTAINER_USER}:${CONTAINER_GROUP} \
https://github.com/esp-rs/espup/releases/download/v0.2.3/espup-x86_64-unknown-linux-gnu \
https://github.com/esp-rs/espup/releases/latest/download/espup-x86_64-unknown-linux-gnu \
/home/${CONTAINER_USER}/${INSTALL_RUST_TOOLCHAIN}
RUN chmod a+x ${INSTALL_RUST_TOOLCHAIN} \
&& ./${INSTALL_RUST_TOOLCHAIN} install \
--extra-crates "ldproxy,cargo-espflash,wokwi-server" \
--extra-crates "cargo-espflash,wokwi-server" \
--export-file /home/${CONTAINER_USER}/export-esp.sh \
--targets "${ESP_BOARD}"
# Disabled:
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ npm install
npm run serve
```

Open in web browser: http://localhost:8080
Open in web browser: https://localhost:8443.

Note: https is required for access to accelerometer data - https://w3c.github.io/deviceorientation/#security-and-privacy . It's possible to run the app without accelerometer on http.

### Build for ESP32-S3-BOX with ILI9486

Expand Down
2 changes: 1 addition & 1 deletion wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ embedded-graphics-web-simulator = { git = "https://github.com/georgik/embedded-g
# rand = { version = "0.8.5", default-features = false }
getrandom = { version = "0.2.8", features = ["js"] }
rand_chacha = { version = "0.3.1", default-features = false }
spooky-core = { path = "../spooky-core", features = [ "wasm" ]}
spooky-core = { path = "../spooky-core", default-features = false, features = [ "wasm", "static_maze" ]}

# [features]
# default = ["rt"]
Expand Down
12 changes: 12 additions & 0 deletions wasm/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
This README contains HTML5 specific instructions. Please, refer to parent README for full explanation.


## Commands

```
npm run serve
```

### Generate assets

```
npx pwa-asset-generator img icons
```
Binary file added wasm/icons/manifest-icon-192.maskable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wasm/icons/manifest-icon-512.maskable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 20 additions & 1 deletion wasm/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
<html>

<head>
<meta charset="utf-8">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
<meta name="viewport"
content="width=device-width,
initial-scale=1">
<meta name="apple-mobile-web-app-status-bar"
content="#aa7700">
<meta name="theme-color"
content="black">
<link rel="manifest" href="manifest.json">
</head>

<body
Expand All @@ -19,10 +28,20 @@
<input type="button" id="button-teleport" value="Teleport" />
<input type="button" id="button-dynamite" value="Dynamite" />
</div>
<div id="html-console"></div>
</body>

<!-- PWA specific code -->
<script type="text/javascript">

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
})
.catch(function(err) {
console.log('ServiceWorker registration failed: ', err);
});
}
</script>

</html>
55 changes: 54 additions & 1 deletion wasm/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
var keyUp;

const motionDirection = {
none: 0,
up: 1,
down: 2,
left: 3,
right: 4
};

const tiltThreshold = 2;

const rust = import('./pkg')
.then(m => {
let universe = m.Universe.new();
var motionRequestHorizontal = motionDirection.none;
var motionRequestVertical = motionDirection.none;

document.getElementById('html-console').innerHTML = "Initialize";

document.getElementById('button-up').addEventListener('click', () => {
universe.move_up();
});
Expand All @@ -21,6 +37,22 @@ const rust = import('./pkg')
universe.place_dynamite();
});


window.addEventListener("devicemotion", (event) => {

if (event.accelerationIncludingGravity.y > tiltThreshold) {
motionRequestVertical = motionDirection.down;
} else if (event.accelerationIncludingGravity.y < -tiltThreshold) {
motionRequestVertical = motionDirection.up;
}

if (event.accelerationIncludingGravity.x < -tiltThreshold) {
motionRequestHorizontal = motionDirection.right;
} else if (event.accelerationIncludingGravity.x > tiltThreshold) {
motionRequestHorizontal = motionDirection.left;
}
}, true);

document.addEventListener('keydown', (event) => {
if ((event.key === "Up") || (event.key == "ArrowUp")) {
universe.move_up();
Expand All @@ -33,10 +65,31 @@ const rust = import('./pkg')
}
});

universe.initialize();
try {
universe.initialize();
document.getElementById('html-console').innerHTML = "Game is running";
} catch (err) {
document.getElementById('html-console').innerHTML = err.message;
}

var oldTimestamp = 0;
function renderFrame(timestamp) {
if (timestamp - oldTimestamp > 200) {

if (motionRequestVertical == motionDirection.up) { // up
universe.move_up();
} else if (motionRequestVertical == motionDirection.down) { // down
universe.move_down();
}

if (motionRequestHorizontal == motionDirection.left) { // left
universe.move_left();
} else if (motionRequestHorizontal == motionDirection.right) { // right
universe.move_right();
}
motionRequestVertical = motionDirection.none;
motionRequestHorizontal = motionDirection.none;

universe.render_frame();
oldTimestamp = timestamp;
}
Expand Down
37 changes: 37 additions & 0 deletions wasm/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name":"ESP32 Spooky Maze game",
"short_name":"SPO",
"start_url":"https://georgik.rocks/wp-content/html5/spooky/",
"display":"standalone",
"background_color":"#5900b3",
"theme_color":"black",
"scope": ".",
"description":"This is PWA version of Rust application for ESP32.",
"icons":[
{
"src": "icons/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "icons/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "icons/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]

}
3 changes: 2 additions & 1 deletion wasm/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"scripts": {
"build": "webpack",
"serve": "webpack serve"
"serve": "webpack serve --host 0.0.0.0 --port 8443 --https",
"pwa": "webpack serve --host 0.0.0.0 --port 8080"
},
"devDependencies": {
"@wasm-tool/wasm-pack-plugin": "1.5.0",
Expand Down
84 changes: 84 additions & 0 deletions wasm/service-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.3.1/workbox-sw.js');

workbox.setConfig({
// set the local path is not using Google CDN
//modulePathPrefix: '/directory/to/workbox/'

// By default, workbox-sw will use the debug build for sites on localhost,
// but for any other origin it’ll use the production build. Force by setting to true.
// debug: true
});
// Force verbose logging even for the production
// workbox.core.setLogLevel(workbox.core.LOG_LEVELS.debug)

// Cache settings
workbox.core.setCacheNameDetails({
// set the default cache name prefix. each domain should be unique to stop clashes
// this is used for runtime and precaching only
prefix: 'spooky-cache'
});

// Using cache first strategy since the JS files are fingerprinted and this
// filename will change once a new version is created
workbox.routing.registerRoute(
// match only with assets on the assets domain
new RegExp('https://georgik.rocks/.*\.js$'),
workbox.strategies.cacheFirst({
cacheName: 'spooky-js-cache',
plugins: [
new workbox.expiration.Plugin({
// 28 days cache before expiration
maxAgeSeconds: 24 * 60 * 60 * 28,
// Opt-in to automatic cleanup whenever a quota errors occurs anywhere in Workbox
purgeOnQuotaError: true // Opt-in to automatic cleanup.
})
]
})
);

// Using cache first strategy since the CSS files are fingerprinted and this
// filename will change once a new version is created
workbox.routing.registerRoute(
// match only with assets on the assets domain
new RegExp('https://georgik.rocks/.*\.css$'),
workbox.strategies.cacheFirst({
cacheName: 'spooky-css-cache',
plugins: [
new workbox.expiration.Plugin({
// 28 days cache before expiration
maxAgeSeconds: 24 * 60 * 60 * 28,
// Opt-in to automatic cleanup whenever a quota errors occurs anywhere in Workbox
purgeOnQuotaError: true // Opt-in to automatic cleanup.
})
]
})
);

// Using cache first strategy since the WOFF2 files are fingerprinted and this
// filename will change once a new version is created
workbox.routing.registerRoute(
// match only with assets on the assets domain
new RegExp('https://georgik.rocks/.*\.woff2$'),
workbox.strategies.cacheFirst({
cacheName: 'spooky-font-cache',
plugins: [
new workbox.expiration.Plugin({
// 28 days cache before expiration
maxAgeSeconds: 24 * 60 * 60 * 28,
// Opt-in to automatic cleanup whenever a quota errors occurs anywhere in Workbox
purgeOnQuotaError: true // Opt-in to automatic cleanup.
})
]
})
);

// If any precache rules are defined in the Workbox setup this is where they will be injected
workbox.precaching.precacheAndRoute([]);

// skip the 'worker in waiting' phase and activate immediately
workbox.skipWaiting();
// claim any clients that match the worker scope immediately. requests on these pages will
// now go via the service worker.
workbox.clientsClaim();


4 changes: 2 additions & 2 deletions wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ impl Universe {
engine: {
let document = web_sys::window().unwrap().document().unwrap();
let output_settings = OutputSettingsBuilder::new()
.scale(1)
.pixel_spacing(1)
.scale(2)
// .pixel_spacing(1)
.build();
let display = WebSimulatorDisplay::new(
(320, 240),
Expand Down