Initial commit
This commit is contained in:
commit
42c7dc5ba7
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
5
.idea/.gitignore
generated
vendored
Normal file
5
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
11
.idea/dial.iml
generated
Normal file
11
.idea/dial.iml
generated
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="EMPTY_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
8
.idea/misc.xml
generated
Normal file
8
.idea/misc.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeSettings">
|
||||
<configurations>
|
||||
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" ENABLED="true" />
|
||||
</configurations>
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/dial.iml" filepath="$PROJECT_DIR$/.idea/dial.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
363
Cargo.lock
generated
Normal file
363
Cargo.lock
generated
Normal file
@ -0,0 +1,363 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dial"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"macroquad",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontdue"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0793f5137567643cf65ea42043a538804ff0fbf288649e2141442b602d81f9bc"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.24.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"num-traits",
|
||||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "macroquad"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81fef16b2d4de22ac372b5d7d76273c0ead0a31f9de9bc649af8f816816db8a8"
|
||||
dependencies = [
|
||||
"fontdue",
|
||||
"glam",
|
||||
"image",
|
||||
"macroquad_macro",
|
||||
"miniquad",
|
||||
"quad-rand",
|
||||
"slotmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macroquad_macro"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64b1d96218903768c1ce078b657c0d5965465c95a60d2682fd97443c9d2483dd"
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
version = "0.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniquad"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2124e5e6bab86d96f263d78dc763c29e0da4c4f7ff0e1bb33f1d3905d1121262"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"ndk-sys",
|
||||
"objc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||
dependencies = [
|
||||
"malloc_buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
"miniz_oxide 0.7.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quad-rand"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "658fa1faf7a4cc5f057c9ee5ef560f717ad9d8dc66d975267f709624d6e1ab88"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "slotmap"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "dial"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
macroquad = "0.4.13"
|
||||
log = "0.4.22"
|
29
index.html
Normal file
29
index.html
Normal file
@ -0,0 +1,29 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>TITLE</title>
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
canvas {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
background: black;
|
||||
z-index: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="glcanvas" tabindex='1'></canvas>
|
||||
<!-- Minified and statically hosted version of https://github.com/not-fl3/macroquad/blob/master/js/mq_js_bundle.js -->
|
||||
<script src="https://not-fl3.github.io/miniquad-samples/mq_js_bundle.js"></script>
|
||||
<script>load("target/wasm32-unknown-unknown/debug/dial.wasm");</script> <!-- Your compiled wasm file -->
|
||||
</body>
|
||||
|
||||
</html>
|
99
src/disc.rs
Normal file
99
src/disc.rs
Normal file
@ -0,0 +1,99 @@
|
||||
use macroquad::logging::info;
|
||||
use std::f32::consts::PI;
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Disc {
|
||||
pub letter_map: Vec<char>,
|
||||
}
|
||||
|
||||
impl Default for Disc {
|
||||
fn default() -> Self {
|
||||
let mut letters = ('a'..='z').into_iter().collect::<Vec<char>>();
|
||||
let mut numbers = ('0'..='9').into_iter().collect::<Vec<char>>();
|
||||
|
||||
letters.append(&mut numbers);
|
||||
|
||||
Self {
|
||||
letter_map: letters,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct DecoderState {
|
||||
pub inner_disc: Disc,
|
||||
pub outer_disc: Disc,
|
||||
pub outer_disc_index: usize,
|
||||
pub outer_disc_current_angle: f32,
|
||||
}
|
||||
|
||||
impl DecoderState {
|
||||
pub fn set_index(&mut self, index: usize) {
|
||||
self.outer_disc_index = index;
|
||||
}
|
||||
|
||||
pub fn change_index(&mut self, diff: i32) {
|
||||
let new_index = (((self.outer_disc_index as i32) + diff)
|
||||
.rem_euclid(self.outer_disc.letter_map.len() as i32)) as usize;
|
||||
|
||||
info!("New Index: {}", new_index);
|
||||
self.set_index(new_index);
|
||||
}
|
||||
|
||||
pub fn get_angle_per_letter(&self) -> f32 {
|
||||
(2.0 * PI) / (self.outer_disc.letter_map.len() as f32)
|
||||
}
|
||||
|
||||
pub fn get_current_target_angle(&self) -> f32 {
|
||||
self.get_angle_per_letter() * (self.outer_disc_index as f32)
|
||||
}
|
||||
|
||||
pub fn get_outer_letter_at_index(&self, index: usize) -> char {
|
||||
let index = (index as i32 - self.outer_disc_index as i32)
|
||||
.rem_euclid(self.outer_disc.letter_map.len() as i32) as usize;
|
||||
self.outer_disc.letter_map[index]
|
||||
}
|
||||
|
||||
pub fn get_index_from_inner_letter(&self, c: char) -> usize {
|
||||
self.inner_disc
|
||||
.letter_map
|
||||
.iter()
|
||||
.position(|n| *n == c)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn get_index_from_outer_letter(&self, c: char) -> usize {
|
||||
let norm_index = self
|
||||
.outer_disc
|
||||
.letter_map
|
||||
.iter()
|
||||
.position(|n| *n == c)
|
||||
.unwrap();
|
||||
|
||||
let index = (norm_index as i32 + self.outer_disc_index as i32)
|
||||
.rem_euclid(self.outer_disc.letter_map.len() as i32) as usize;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn get_inner_letter_at_index(&self, index: usize) -> char {
|
||||
self.inner_disc.letter_map[index]
|
||||
}
|
||||
|
||||
pub fn encode(&mut self, in_char: char) -> char {
|
||||
let index = self.get_index_from_inner_letter(in_char);
|
||||
|
||||
let char = self.get_outer_letter_at_index(index);
|
||||
|
||||
return char;
|
||||
}
|
||||
|
||||
pub fn decode(&mut self, in_char: char) -> char {
|
||||
let index = self.get_index_from_outer_letter(in_char);
|
||||
|
||||
let char = self.get_inner_letter_at_index(index);
|
||||
|
||||
return char;
|
||||
}
|
||||
}
|
564
src/main.rs
Normal file
564
src/main.rs
Normal file
@ -0,0 +1,564 @@
|
||||
mod disc;
|
||||
|
||||
use crate::disc::{DecoderState, Disc};
|
||||
use macroquad::prelude::*;
|
||||
use std::f32::consts::PI;
|
||||
use std::string::ToString;
|
||||
|
||||
const SHADOW: Color = Color::new(0.25, 0.25, 0.25, 0.5);
|
||||
|
||||
const GAME_NAME: &str = "dial";
|
||||
|
||||
pub struct Context {
|
||||
decoder_state: DecoderState,
|
||||
input_state: DecoderState,
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub enum Mode {
|
||||
Encode,
|
||||
Decode,
|
||||
}
|
||||
|
||||
pub fn conf() -> Conf {
|
||||
Conf {
|
||||
window_title: GAME_NAME.to_string(),
|
||||
high_dpi: true,
|
||||
fullscreen: true,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn game_init() {
|
||||
info!("Starting {}", GAME_NAME);
|
||||
}
|
||||
|
||||
pub fn rotate_vec2(vec: Vec2, angle: f32) -> Vec2 {
|
||||
Mat2::from_angle(angle) * vec
|
||||
}
|
||||
|
||||
pub fn draw_display(pos: Vec2, size: Vec2, text: &str, font_size: f32) {
|
||||
let text_center = get_text_center(text, None, font_size as u16, 1.0, 0.0);
|
||||
|
||||
draw_rectangle_ex(
|
||||
pos.x,
|
||||
pos.y,
|
||||
size.x,
|
||||
size.y,
|
||||
DrawRectangleParams {
|
||||
rotation: 0.0,
|
||||
color: BLACK,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
let text_pos = pos + size * 0.5 - text_center;
|
||||
draw_text(text, text_pos.x, text_pos.y, font_size, SKYBLUE);
|
||||
}
|
||||
|
||||
pub fn draw_label(pos: Vec2, size: Vec2, text: &str, font_size: f32) {
|
||||
let text_center = get_text_center(text, None, font_size as u16, 1.0, 0.0);
|
||||
|
||||
draw_rectangle_ex(
|
||||
pos.x,
|
||||
pos.y,
|
||||
size.x,
|
||||
size.y,
|
||||
DrawRectangleParams {
|
||||
rotation: 0.0,
|
||||
color: BLACK,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
let text_pos = pos + size * 0.5 - text_center;
|
||||
draw_text(text, text_pos.x, text_pos.y, font_size, WHITE);
|
||||
}
|
||||
|
||||
pub fn draw_disc(
|
||||
disc: &Disc,
|
||||
base_pos: Vec2,
|
||||
text_radius: f32,
|
||||
radius: f32,
|
||||
start_angle: f32,
|
||||
color: Color,
|
||||
) {
|
||||
draw_circle(
|
||||
base_pos.x + radius * 0.05,
|
||||
base_pos.y + radius * 0.05,
|
||||
radius,
|
||||
SHADOW,
|
||||
);
|
||||
draw_circle(base_pos.x, base_pos.y, radius, color);
|
||||
draw_circle(base_pos.x, base_pos.y, radius * 0.10, BLACK);
|
||||
draw_circle_lines(
|
||||
base_pos.x,
|
||||
base_pos.y,
|
||||
radius - radius * 0.01,
|
||||
radius * 0.025,
|
||||
BLACK,
|
||||
);
|
||||
|
||||
let len = disc.letter_map.len();
|
||||
|
||||
let angle_per_letter = (2.0 * PI) / (len as f32);
|
||||
|
||||
let mut text_pos = Vec2::new(0.0, -text_radius);
|
||||
let mut line_pos = Vec2::new(0.0, radius);
|
||||
|
||||
let font_size = 30;
|
||||
|
||||
let mut angle = start_angle;
|
||||
|
||||
text_pos = rotate_vec2(text_pos, start_angle);
|
||||
line_pos = rotate_vec2(line_pos, start_angle);
|
||||
|
||||
for (ndx, letter) in disc.letter_map.iter().enumerate() {
|
||||
let text_center = get_text_center(letter.to_string().as_str(), None, font_size, 1.0, angle);
|
||||
let letter_pos = text_pos + base_pos - text_center;
|
||||
|
||||
let mut line_pos_1 = rotate_vec2(line_pos, -angle_per_letter * 0.5);
|
||||
line_pos_1 = line_pos_1 + base_pos;
|
||||
let mut line_pos_2 = rotate_vec2(line_pos, angle_per_letter * 0.5);
|
||||
line_pos_2 = line_pos_2 + base_pos;
|
||||
|
||||
draw_line(
|
||||
base_pos.x,
|
||||
base_pos.y,
|
||||
line_pos_1.x,
|
||||
line_pos_1.y,
|
||||
2.0,
|
||||
BLACK,
|
||||
);
|
||||
draw_line(
|
||||
base_pos.x,
|
||||
base_pos.y,
|
||||
line_pos_2.x,
|
||||
line_pos_2.y,
|
||||
2.0,
|
||||
BLACK,
|
||||
);
|
||||
|
||||
if ndx == 0 {
|
||||
draw_circle(
|
||||
text_pos.x + base_pos.x,
|
||||
text_pos.y + base_pos.y,
|
||||
radius * 0.05,
|
||||
GRAY,
|
||||
);
|
||||
}
|
||||
|
||||
draw_text_ex(
|
||||
letter.to_string().as_str(),
|
||||
letter_pos.x,
|
||||
letter_pos.y,
|
||||
TextParams {
|
||||
font_size,
|
||||
color: WHITE,
|
||||
rotation: angle,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
text_pos = rotate_vec2(text_pos, angle_per_letter);
|
||||
line_pos = rotate_vec2(line_pos, angle_per_letter);
|
||||
angle += angle_per_letter;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_switch(pos: Vec2, size: Vec2, mut state: bool) -> bool {
|
||||
draw_circle(pos.x, pos.y, size.x * 0.5, BLACK);
|
||||
|
||||
if is_mouse_in_area(pos - size * 0.5, size) {
|
||||
state = !state;
|
||||
}
|
||||
|
||||
let rot = if state { 180.0_f32.to_radians() } else { 0.0 };
|
||||
|
||||
draw_rectangle_ex(
|
||||
pos.x + (size.x * 0.07),
|
||||
pos.y + (size.y * 0.1),
|
||||
size.x * 0.33,
|
||||
size.y,
|
||||
DrawRectangleParams {
|
||||
rotation: rot,
|
||||
color: SHADOW,
|
||||
offset: Vec2::new(0.5, 0.0),
|
||||
},
|
||||
);
|
||||
|
||||
draw_rectangle_ex(
|
||||
pos.x,
|
||||
pos.y,
|
||||
size.x * 0.33,
|
||||
size.y,
|
||||
DrawRectangleParams {
|
||||
rotation: rot,
|
||||
color: DARKBLUE,
|
||||
offset: Vec2::new(0.5, 0.0),
|
||||
},
|
||||
);
|
||||
|
||||
draw_rectangle_lines_ex(
|
||||
pos.x,
|
||||
pos.y,
|
||||
size.x * 0.33,
|
||||
size.y,
|
||||
size.x * 0.025,
|
||||
DrawRectangleParams {
|
||||
rotation: rot,
|
||||
color: BLACK,
|
||||
offset: Vec2::new(0.5, 0.0),
|
||||
},
|
||||
);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
pub fn is_mouse_in_area(pos: Vec2, size: Vec2) -> bool {
|
||||
//draw_rectangle_lines(pos.x, pos.y, size.x, size.y, 5.0, RED);
|
||||
|
||||
if is_mouse_button_pressed(MouseButton::Left) {
|
||||
let lower_bound = pos;
|
||||
let upper_bound = pos + size;
|
||||
let mouse_pos: Vec2 = mouse_position().into();
|
||||
|
||||
let lower_bound_check = lower_bound.x <= mouse_pos.x && lower_bound.y <= mouse_pos.y;
|
||||
let upper_bound_check = upper_bound.x >= mouse_pos.x && upper_bound.y >= mouse_pos.y;
|
||||
|
||||
if lower_bound_check && upper_bound_check {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub fn draw_device(ctx: &mut Context) {
|
||||
let screen_height = screen_height();
|
||||
let screen_width = screen_width();
|
||||
|
||||
let width = screen_width * 0.33;
|
||||
let height = screen_height * 0.9;
|
||||
|
||||
let dev_x = screen_width * 0.5 - width * 0.5;
|
||||
let dev_y = screen_height * 0.5 - height * 0.5;
|
||||
|
||||
let size = Vec2::new(width, height);
|
||||
let base_pos = Vec2::new(dev_x, dev_y);
|
||||
|
||||
input_dial(&mut ctx.input_state, base_pos, size);
|
||||
|
||||
draw_rectangle_ex(
|
||||
dev_x,
|
||||
dev_y,
|
||||
width,
|
||||
height,
|
||||
DrawRectangleParams {
|
||||
offset: Default::default(),
|
||||
rotation: 0.0,
|
||||
color: DARKGREEN,
|
||||
},
|
||||
);
|
||||
|
||||
draw_rectangle_lines(dev_x, dev_y, width, height, dev_x * 0.005, BLACK);
|
||||
|
||||
draw_rectangle_ex(
|
||||
dev_x + width * 0.02,
|
||||
dev_y + height * 0.015,
|
||||
width * 0.68,
|
||||
height * 0.05,
|
||||
DrawRectangleParams {
|
||||
offset: Default::default(),
|
||||
rotation: 0.0,
|
||||
color: LIGHTGRAY,
|
||||
},
|
||||
);
|
||||
|
||||
draw_text(
|
||||
"PROPERTY OF Foghaven Guard",
|
||||
dev_x + width * 0.02,
|
||||
dev_y + height * 0.05,
|
||||
50.0,
|
||||
RED,
|
||||
);
|
||||
|
||||
input_panel(ctx, base_pos, size);
|
||||
|
||||
let next_button_pos = Vec2::new(size.x * 0.9, size.y * 0.4) + base_pos;
|
||||
let next_button_size = Vec2::new(size.x * 0.1, size.x * 0.1);
|
||||
|
||||
if is_mouse_in_area(next_button_pos - next_button_size * 0.5, next_button_size) {
|
||||
if ctx.mode == Mode::Encode {
|
||||
ctx.decoder_state.change_index(1);
|
||||
} else {
|
||||
ctx.decoder_state.change_index(-1);
|
||||
}
|
||||
}
|
||||
|
||||
draw_circle(
|
||||
next_button_pos.x + next_button_size.x * 0.05,
|
||||
next_button_pos.y + next_button_size.y * 0.05,
|
||||
next_button_size.x * 0.5,
|
||||
SHADOW,
|
||||
);
|
||||
draw_circle(
|
||||
next_button_pos.x,
|
||||
next_button_pos.y,
|
||||
next_button_size.x * 0.5,
|
||||
RED,
|
||||
);
|
||||
|
||||
let base_pos = Vec2::new(dev_x + width * 0.5, dev_y + height * 0.66);
|
||||
|
||||
if ctx.decoder_state.get_current_target_angle() - ctx.decoder_state.outer_disc_current_angle
|
||||
> f32::EPSILON
|
||||
{
|
||||
ctx.decoder_state.outer_disc_current_angle += 1.0_f32.to_radians() * (get_time() as f32);
|
||||
} else {
|
||||
ctx.decoder_state.outer_disc_current_angle = ctx.decoder_state.get_current_target_angle();
|
||||
}
|
||||
|
||||
draw_disc(
|
||||
&ctx.decoder_state.outer_disc,
|
||||
base_pos,
|
||||
width * 0.40,
|
||||
width * 0.45,
|
||||
ctx.decoder_state.outer_disc_current_angle,
|
||||
BROWN,
|
||||
);
|
||||
|
||||
draw_disc(
|
||||
&ctx.decoder_state.inner_disc,
|
||||
base_pos,
|
||||
width * 0.20,
|
||||
width * 0.25,
|
||||
0.0,
|
||||
GOLD,
|
||||
);
|
||||
|
||||
let surplus_sticker_pos = Vec2::new(dev_x + width * 0.75, dev_y + height * 0.01);
|
||||
let surplus_sticker_size = Vec2::new(width * 0.24, height * 0.06);
|
||||
draw_rectangle_ex(
|
||||
surplus_sticker_pos.x + surplus_sticker_size.x * 0.02,
|
||||
surplus_sticker_pos.y + surplus_sticker_size.x * 0.02,
|
||||
surplus_sticker_size.x,
|
||||
surplus_sticker_size.y,
|
||||
DrawRectangleParams {
|
||||
offset: Default::default(),
|
||||
rotation: 10.0_f32.to_radians(),
|
||||
color: SHADOW,
|
||||
},
|
||||
);
|
||||
|
||||
draw_rectangle_ex(
|
||||
surplus_sticker_pos.x,
|
||||
surplus_sticker_pos.y,
|
||||
surplus_sticker_size.x,
|
||||
surplus_sticker_size.y,
|
||||
DrawRectangleParams {
|
||||
offset: Default::default(),
|
||||
rotation: 10.0_f32.to_radians(),
|
||||
color: Color::new(0.25, 0.25, 0.25, 1.0),
|
||||
},
|
||||
);
|
||||
draw_text_ex(
|
||||
"(SURPLUS)",
|
||||
dev_x + width * 0.75,
|
||||
dev_y + height * 0.05,
|
||||
TextParams {
|
||||
font: None,
|
||||
font_size: 50,
|
||||
font_scale: 1.0,
|
||||
font_scale_aspect: 1.0,
|
||||
rotation: 10.0f32.to_radians(),
|
||||
color: RED,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn input_dial(input_disc: &mut DecoderState, base: Vec2, size: Vec2) {
|
||||
let dial_pos = Vec2::new(base.x + size.x * 0.15, base.y + size.y * 0.3);
|
||||
|
||||
draw_disc(
|
||||
&input_disc.outer_disc,
|
||||
dial_pos,
|
||||
size.y * 0.15,
|
||||
size.y * 0.2,
|
||||
input_disc.outer_disc_current_angle,
|
||||
DARKGREEN,
|
||||
);
|
||||
|
||||
let marker_pos = dial_pos + Vec2::new(-size.y * 0.11, 0.0);
|
||||
draw_circle(marker_pos.x, marker_pos.y, size.y * 0.005, RED);
|
||||
|
||||
if input_disc.get_current_target_angle() - input_disc.outer_disc_current_angle > f32::EPSILON {
|
||||
input_disc.outer_disc_current_angle += 1.0_f32.to_radians() * (get_time() as f32);
|
||||
} else {
|
||||
input_disc.outer_disc_current_angle = input_disc.get_current_target_angle();
|
||||
}
|
||||
|
||||
let click_area = Vec2::new(size.y * 0.1, size.y * 0.15);
|
||||
let upper_click_pos = dial_pos - Vec2::new(size.y * 0.1, 0.0) - click_area;
|
||||
let lower_click_pos = dial_pos - Vec2::new(size.y * 0.1, -click_area.y) - click_area;
|
||||
|
||||
if is_mouse_in_area(upper_click_pos, click_area) {
|
||||
input_disc.change_index(1);
|
||||
} else if is_mouse_in_area(lower_click_pos, click_area) {
|
||||
input_disc.change_index(-1);
|
||||
}
|
||||
}
|
||||
|
||||
fn input_panel(ctx: &mut Context, base: Vec2, size: Vec2) {
|
||||
let border_pos = Vec2::new(base.x + size.x * 0.05, base.y + size.y * 0.075);
|
||||
let border_size = Vec2::new(size.x * 0.9, size.y * 0.25);
|
||||
|
||||
draw_rectangle_ex(
|
||||
border_pos.x + border_size.x * 0.01,
|
||||
border_pos.y + border_size.y * 0.02,
|
||||
border_size.x,
|
||||
border_size.y,
|
||||
DrawRectangleParams {
|
||||
offset: Default::default(),
|
||||
rotation: 0.0,
|
||||
color: SHADOW,
|
||||
},
|
||||
);
|
||||
|
||||
draw_rectangle_ex(
|
||||
border_pos.x,
|
||||
border_pos.y,
|
||||
border_size.x,
|
||||
border_size.y,
|
||||
DrawRectangleParams {
|
||||
offset: Default::default(),
|
||||
rotation: 0.0,
|
||||
color: GRAY,
|
||||
},
|
||||
);
|
||||
|
||||
draw_rectangle_lines(
|
||||
border_pos.x,
|
||||
border_pos.y,
|
||||
border_size.x,
|
||||
border_size.y,
|
||||
border_size.x * 0.005,
|
||||
BLACK,
|
||||
);
|
||||
|
||||
let input_letter_disp_loc = border_pos + Vec2::new(border_size.x * 0.05, border_size.x * 0.05);
|
||||
let input_letter_size = Vec2::new(border_size.x * 0.10, border_size.y * 0.3);
|
||||
|
||||
let input_letter = ctx
|
||||
.input_state
|
||||
.get_outer_letter_at_index(ctx.input_state.outer_disc.letter_map.len() * 3 / 4);
|
||||
draw_display(
|
||||
input_letter_disp_loc,
|
||||
input_letter_size,
|
||||
input_letter.to_string().as_str(),
|
||||
80.0,
|
||||
);
|
||||
|
||||
let input_label_pos = input_letter_disp_loc
|
||||
+ Vec2::new(
|
||||
input_letter_size.x + border_size.x * 0.05,
|
||||
input_letter_size.y * 0.25,
|
||||
);
|
||||
let input_label_size = Vec2::new(border_size.x * 0.2, border_size.y * 0.15);
|
||||
draw_label(input_label_pos, input_label_size, "INPUT", 40.0);
|
||||
|
||||
let index_disp_loc =
|
||||
input_letter_disp_loc + Vec2::new(0.0, input_letter_size.y + border_size.x * 0.05);
|
||||
draw_display(
|
||||
index_disp_loc,
|
||||
input_letter_size,
|
||||
ctx.decoder_state.outer_disc_index.to_string().as_str(),
|
||||
80.0,
|
||||
);
|
||||
|
||||
let index_label_pos = index_disp_loc
|
||||
+ Vec2::new(
|
||||
input_letter_size.x + border_size.x * 0.05,
|
||||
input_letter_size.y * 0.25,
|
||||
);
|
||||
|
||||
draw_label(index_label_pos, input_label_size, "INDEX", 40.0);
|
||||
|
||||
let output_disp_loc = border_pos + Vec2::new(border_size.x * 0.55, border_size.x * 0.05);
|
||||
let output_disp_size = Vec2::new(border_size.x * 0.33, border_size.y * 0.6);
|
||||
|
||||
let output_disp = if ctx.mode == Mode::Encode {
|
||||
ctx.decoder_state.encode(input_letter)
|
||||
} else {
|
||||
ctx.decoder_state.decode(input_letter)
|
||||
};
|
||||
|
||||
draw_display(
|
||||
output_disp_loc,
|
||||
output_disp_size,
|
||||
output_disp.to_string().as_str(),
|
||||
160.0,
|
||||
);
|
||||
|
||||
let output_disp_label_loc = output_disp_loc
|
||||
+ Vec2::new(
|
||||
output_disp_size.x / 2.0 - input_label_size.x / 2.0,
|
||||
output_disp_size.y + size.y * 0.01,
|
||||
);
|
||||
|
||||
draw_label(output_disp_label_loc, input_label_size, "OUTPUT", 40.0);
|
||||
|
||||
let switch_pos = border_pos + border_size * 0.5;
|
||||
let switch_size = Vec2::new(border_size.x * 0.05, border_size.y * 0.25);
|
||||
draw_label(
|
||||
switch_pos + Vec2::new(-border_size.x * 0.05 * 0.5, switch_size.y),
|
||||
Vec2::new(border_size.x * 0.05, border_size.x * 0.05),
|
||||
"D",
|
||||
40.0,
|
||||
);
|
||||
draw_label(
|
||||
switch_pos + Vec2::new(-border_size.x * 0.05 * 0.5, -switch_size.y * 1.5),
|
||||
Vec2::new(border_size.x * 0.05, border_size.x * 0.05),
|
||||
"E",
|
||||
40.0,
|
||||
);
|
||||
|
||||
if draw_switch(switch_pos, switch_size, ctx.mode == Mode::Encode) {
|
||||
if ctx.mode != Mode::Encode {
|
||||
info!("Mode set to encode!");
|
||||
ctx.mode = Mode::Encode
|
||||
}
|
||||
} else {
|
||||
if ctx.mode != Mode::Decode {
|
||||
info!("Mode set to decode!");
|
||||
ctx.mode = Mode::Decode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macroquad::main(conf)]
|
||||
async fn main() {
|
||||
game_init();
|
||||
|
||||
let decoder = DecoderState::default();
|
||||
let input_disc = DecoderState::default();
|
||||
|
||||
let mut context = Context {
|
||||
decoder_state: decoder,
|
||||
input_state: input_disc,
|
||||
mode: Mode::Decode,
|
||||
};
|
||||
|
||||
context
|
||||
.input_state
|
||||
.set_index(context.input_state.outer_disc.letter_map.len() * 3 / 4);
|
||||
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
|
||||
draw_device(&mut context);
|
||||
|
||||
next_frame().await;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user