init
This commit is contained in:
commit
8d3892b6de
12 changed files with 516 additions and 0 deletions
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
* text=auto eol=lf
|
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# This file is for zig-specific build artifacts.
|
||||||
|
# If you have OS-specific or editor-specific files to ignore,
|
||||||
|
# such as *.swp or .DS_Store, put those in your global
|
||||||
|
# ~/.gitignore and put this in your ~/.gitconfig:
|
||||||
|
#
|
||||||
|
# [core]
|
||||||
|
# excludesfile = ~/.gitignore
|
||||||
|
#
|
||||||
|
# Cheers!
|
||||||
|
# -andrewrk
|
||||||
|
|
||||||
|
.zig-cache/
|
||||||
|
zig-cache/
|
||||||
|
zig-out/
|
||||||
|
/release/
|
||||||
|
/debug/
|
||||||
|
/build/
|
||||||
|
/build-*/
|
||||||
|
/docgen_tmp/
|
74
build.zig
Normal file
74
build.zig
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
// const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const wasm_mod = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/wasm.zig"),
|
||||||
|
.target = b.resolveTargetQuery(.{
|
||||||
|
.cpu_arch = .wasm32,
|
||||||
|
.os_tag = .freestanding,
|
||||||
|
}),
|
||||||
|
// .optimize = .ReleaseSafe,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const wasm = b.addExecutable(.{
|
||||||
|
.name = "ledbox",
|
||||||
|
.root_module = wasm_mod,
|
||||||
|
});
|
||||||
|
wasm.entry = .disabled;
|
||||||
|
wasm.rdynamic = true;
|
||||||
|
wasm.import_memory = true;
|
||||||
|
wasm.initial_memory = std.wasm.page_size * 2;
|
||||||
|
wasm.max_memory = std.wasm.page_size * 2;
|
||||||
|
wasm.stack_size = std.wasm.page_size;
|
||||||
|
wasm.global_base = 6560;
|
||||||
|
b.installArtifact(wasm);
|
||||||
|
|
||||||
|
// const lib_mod = b.createModule(.{
|
||||||
|
// .root_source_file = b.path("src/root.zig"),
|
||||||
|
// .target = target,
|
||||||
|
// .optimize = optimize,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const exe_mod = b.createModule(.{
|
||||||
|
// .root_source_file = b.path("src/main.zig"),
|
||||||
|
// .target = target,
|
||||||
|
// .optimize = optimize,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// exe_mod.addImport("ledbox_lib", lib_mod);
|
||||||
|
|
||||||
|
// const lib = b.addLibrary(.{
|
||||||
|
// .linkage = .static,
|
||||||
|
// .name = "ledbox",
|
||||||
|
// .root_module = lib_mod,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// b.installArtifact(lib);
|
||||||
|
|
||||||
|
// const exe = b.addExecutable(.{
|
||||||
|
// .name = "ledbox",
|
||||||
|
// .root_module = exe_mod,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// b.installArtifact(exe);
|
||||||
|
|
||||||
|
// const lib_unit_tests = b.addTest(.{
|
||||||
|
// .root_module = lib_mod,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||||
|
|
||||||
|
// const exe_unit_tests = b.addTest(.{
|
||||||
|
// .root_module = exe_mod,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
||||||
|
|
||||||
|
// const test_step = b.step("test", "Run unit tests");
|
||||||
|
// test_step.dependOn(&run_lib_unit_tests.step);
|
||||||
|
// test_step.dependOn(&run_exe_unit_tests.step);
|
||||||
|
}
|
12
build.zig.zon
Normal file
12
build.zig.zon
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.{
|
||||||
|
.name = .ledbox,
|
||||||
|
.version = "0.0.0",
|
||||||
|
.fingerprint = 0xdc8a67c307abf09e,
|
||||||
|
.minimum_zig_version = "0.15.0-dev.129+b84db311d",
|
||||||
|
|
||||||
|
.paths = .{
|
||||||
|
"build.zig",
|
||||||
|
"build.zig.zon",
|
||||||
|
"src",
|
||||||
|
},
|
||||||
|
}
|
21
cert.pem
Normal file
21
cert.pem
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDazCCAlOgAwIBAgIUJ4me6Svr4LN0POTKXD8iMsjFDeUwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||||
|
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNTA0MDUxMzE2MzFaFw0zNTA0
|
||||||
|
MDMxMzE2MzFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
||||||
|
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4IBDwAwggEKAoIBAQCTD1fUqbGo7NeCsxjm2l1BJy1cuR706bwxyLEcTi3O
|
||||||
|
mV0dopVpBACol7jQ9W8NTGTxdDVe93sYdEL3A2VBmo7QK4fysUbMnQ3j/nvl+Fgj
|
||||||
|
Z0eGKFuC4ReKmOwdx+kmIrbitYG0EntY7JArV50n1GkF8C3gN5RQOzmFJ7uhu0JR
|
||||||
|
6B8z5PJH41SB07JjxBfntNaoET88RjekSM/Y+IvMWwcWOjGHtHgzfkajkKOmYmIU
|
||||||
|
KRuJmXNF6iJS6SSIbkDcMH2d8kdG62Qdv2LcGjkqSkmx5xnT1UmllKRtWHDAoWyN
|
||||||
|
gUmhflE3UEdr5MEf9JMzE8wmy9Edwq8Gwd3ulUT80MeVAgMBAAGjUzBRMB0GA1Ud
|
||||||
|
DgQWBBRUcVjjuIm3d2UNzoFVQMqqSyksLTAfBgNVHSMEGDAWgBRUcVjjuIm3d2UN
|
||||||
|
zoFVQMqqSyksLTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBY
|
||||||
|
KQhTPqp7m6sypagfDsbS3roZZx6FVbFC4z7WDCGmjzBbXDD3sHxswPpbsrpPJedW
|
||||||
|
5ZgihOhwNXtKKz+Ey12+YxN4htVLrxmRnogqs3bz421LI1R4wJ3aCHBrS1vjvrgh
|
||||||
|
vxykm/hckEmxkQjuEASEt/rwgBmEnV+JGEpifWiid7A5WIfJONEzxo/BciS/+z63
|
||||||
|
+UO7IYe2ZX3u4F0dBzpgESAqEeH35lnxmDDkL1DTltihuQgursiIT810d0rnx1nP
|
||||||
|
C6NJ3B+1D8aDfrHxsTUgOXQI0pxOm1dNQ9MRwvvgFhLHJX5xyv8TC1bwK31Ntq/x
|
||||||
|
M0H4tXXOtLanPND7O3Md
|
||||||
|
-----END CERTIFICATE-----
|
78
flake.lock
generated
Normal file
78
flake.lock
generated
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1743125403,
|
||||||
|
"narHash": "sha256-ax5yY7IA9XaO+qHiu2XNs7oivWlD4+YG+G8+VaAl8bE=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "b25d37292b5b6a56a6a508d4632feceb52266333",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"zig2nix": "zig2nix"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zig2nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1743144458,
|
||||||
|
"narHash": "sha256-0vS/7AWx4O7vI7kJ156tk+nahxQb+HXd/CiFx6ZPBQE=",
|
||||||
|
"owner": "Cloudef",
|
||||||
|
"repo": "zig2nix",
|
||||||
|
"rev": "de3fa1e6475471ca6c76ba9a88dfa4df2befe13c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Cloudef",
|
||||||
|
"repo": "zig2nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
78
flake.nix
Normal file
78
flake.nix
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
{
|
||||||
|
description = "Zig project flake";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
zig2nix.url = "github:Cloudef/zig2nix";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { zig2nix, ... }: let
|
||||||
|
flake-utils = zig2nix.inputs.flake-utils;
|
||||||
|
in (flake-utils.lib.eachDefaultSystem (system: let
|
||||||
|
# Zig flake helper
|
||||||
|
# Check the flake.nix in zig2nix project for more options:
|
||||||
|
# <https://github.com/Cloudef/zig2nix/blob/master/flake.nix>
|
||||||
|
env = zig2nix.outputs.zig-env.${system} { zig = zig2nix.outputs.packages.${system}.zig-master; };
|
||||||
|
in with builtins; with env.pkgs.lib; rec {
|
||||||
|
# Produces clean binaries meant to be ship'd outside of nix
|
||||||
|
# nix build .#foreign
|
||||||
|
packages.foreign = env.package {
|
||||||
|
src = cleanSource ./.;
|
||||||
|
|
||||||
|
# Packages required for compiling
|
||||||
|
nativeBuildInputs = with env.pkgs; [];
|
||||||
|
|
||||||
|
# Packages required for linking
|
||||||
|
buildInputs = with env.pkgs; [];
|
||||||
|
|
||||||
|
# Smaller binaries and avoids shipping glibc.
|
||||||
|
zigPreferMusl = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# nix build .
|
||||||
|
packages.default = packages.foreign.override (attrs: {
|
||||||
|
# Prefer nix friendly settings.
|
||||||
|
zigPreferMusl = false;
|
||||||
|
|
||||||
|
# Executables required for runtime
|
||||||
|
# These packages will be added to the PATH
|
||||||
|
zigWrapperBins = with env.pkgs; [];
|
||||||
|
|
||||||
|
# Libraries required for runtime
|
||||||
|
# These packages will be added to the LD_LIBRARY_PATH
|
||||||
|
zigWrapperLibs = attrs.buildInputs or [];
|
||||||
|
});
|
||||||
|
|
||||||
|
# For bundling with nix bundle for running outside of nix
|
||||||
|
# example: https://github.com/ralismark/nix-appimage
|
||||||
|
apps.bundle = {
|
||||||
|
type = "app";
|
||||||
|
program = "${packages.foreign}/bin/master";
|
||||||
|
};
|
||||||
|
|
||||||
|
# nix run .
|
||||||
|
apps.default = env.app [] "zig build run -- \"$@\"";
|
||||||
|
|
||||||
|
# nix run .#build
|
||||||
|
apps.build = env.app [] "zig build \"$@\"";
|
||||||
|
|
||||||
|
# nix run .#test
|
||||||
|
apps.test = env.app [] "zig build test -- \"$@\"";
|
||||||
|
|
||||||
|
# nix run .#docs
|
||||||
|
apps.docs = env.app [] "zig build docs -- \"$@\"";
|
||||||
|
|
||||||
|
# nix run .#zig2nix
|
||||||
|
apps.zig2nix = env.app [] "zig2nix \"$@\"";
|
||||||
|
|
||||||
|
# nix develop
|
||||||
|
devShells.default = env.mkShell {
|
||||||
|
# Packages required for compiling, linking and running
|
||||||
|
# Libraries added here will be automatically added to the LD_LIBRARY_PATH and PKG_CONFIG_PATH
|
||||||
|
nativeBuildInputs = []
|
||||||
|
++ packages.default.nativeBuildInputs
|
||||||
|
++ packages.default.buildInputs
|
||||||
|
++ packages.default.zigWrapperBins
|
||||||
|
++ packages.default.zigWrapperLibs;
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
55
index.html
Normal file
55
index.html
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>vLEDMatrix</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas" width="768" height="384" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const canvas = document.getElementById("canvas");
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
function draw(pixelData) {
|
||||||
|
ctx.clearRect(0, 0, 768, 384);
|
||||||
|
for (let y = 0; y < 32; y++) {
|
||||||
|
for (let x = 0; x < 64; x++) {
|
||||||
|
const idx = y * 64 * 3 + x * 3;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x * 12 + 4, y * 12 + 4, 4, 0, 2 * Math.PI);
|
||||||
|
ctx.fillStyle = `rgb(${pixelData[idx]} ${pixelData[idx + 1]} ${pixelData[idx + 2]})`;
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const memory = new WebAssembly.Memory({
|
||||||
|
initial: 2,
|
||||||
|
maximum: 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
const importObject = {
|
||||||
|
env: {
|
||||||
|
memory: memory,
|
||||||
|
printi64: (arg) => console.log(arg),
|
||||||
|
printf32: (arg) => console.log(arg),
|
||||||
|
timestamp: () => {
|
||||||
|
return BigInt(Math.floor(Date.now() / 1000));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
WebAssembly.instantiateStreaming(fetch("zig-out/bin/ledbox.wasm"), importObject).then((result) => {
|
||||||
|
const wasmMemoryArray = new Uint8Array(memory.buffer);
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
result.instance.exports.draw();
|
||||||
|
const pointer = result.instance.exports.getPixelDataPointer();
|
||||||
|
const pixelData = wasmMemoryArray.slice(pointer, pointer + 64 * 32 * 3);
|
||||||
|
draw(pixelData);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<body>
|
||||||
|
</html>
|
28
key.pem
Normal file
28
key.pem
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCTD1fUqbGo7NeC
|
||||||
|
sxjm2l1BJy1cuR706bwxyLEcTi3OmV0dopVpBACol7jQ9W8NTGTxdDVe93sYdEL3
|
||||||
|
A2VBmo7QK4fysUbMnQ3j/nvl+FgjZ0eGKFuC4ReKmOwdx+kmIrbitYG0EntY7JAr
|
||||||
|
V50n1GkF8C3gN5RQOzmFJ7uhu0JR6B8z5PJH41SB07JjxBfntNaoET88RjekSM/Y
|
||||||
|
+IvMWwcWOjGHtHgzfkajkKOmYmIUKRuJmXNF6iJS6SSIbkDcMH2d8kdG62Qdv2Lc
|
||||||
|
GjkqSkmx5xnT1UmllKRtWHDAoWyNgUmhflE3UEdr5MEf9JMzE8wmy9Edwq8Gwd3u
|
||||||
|
lUT80MeVAgMBAAECggEACbwhR02jGhibkjuthqf74QfpOSh0A9MZMdPO4vMgldA8
|
||||||
|
hBgIJfcth/uLMMyeeQCOn2ve60DHYEYJ93S9FjZXWoZsgxn4eCu0CLIG8kvvTGCr
|
||||||
|
hmuo1dAgESewXFmodcLPMntrcPKBlyW0ds9fnYxdFhc2d4+WUif+1cax5VySYP46
|
||||||
|
qJPHS7RBSk2d7ceJijM8E3tYgzk8ecMpsJ5kNDb0fd61P/5BKsKCbgrSqd34b6F9
|
||||||
|
6GsYdvzicbdNGpaks+M68yEMTQw+kenGs5t6i1Sft0brsnDwl0ee+AgxtpT7qe8L
|
||||||
|
FeSM+51ocUlhIR3IDp90wnkl30Xuu1Vu9SVl/47HHQKBgQDGfLKBWCIe662G58rg
|
||||||
|
99opgI2IF5j9yCA9LvNDrPNPxLkU4M4ewuLSCtpD70T/uknU7EudRIc2w2KX2aX8
|
||||||
|
99LTd0rvM8DZWdwv2Oxzn2FzgQEOeef4+I4QUvFYJJL2CNRubasoNP4XkUjjWEqn
|
||||||
|
bqki4hFz0MIczTRZShz3/WL0kwKBgQC9q+aLKsAv1GitxaXlG2+KFJtWxJX0dzc4
|
||||||
|
QX3T2/LbSOWd1wVwBQ2gWTlA0B3lum8+ypBJa/mfdntFEnuYdbBdhELx05nlBQ1a
|
||||||
|
s+ZNkbmWaIaq/PheGOao5QySasNAZHQ572BbIxtdRPkTY8Rdya1vx0LP1O5HNXiw
|
||||||
|
xDwpiTpUNwKBgBmktJ83Vrkt865RNgnYm6vu+toRSmfHOjsNXMpqhsjQfqTu4lJh
|
||||||
|
FVLTqh1KxVxQogdLO/2mg92UYqGBsgs7rVY6vEipJAowrNzVpr7NYZa9nPhU0Z59
|
||||||
|
5kS/ooSjvQTiYSefLZS1O/qpf4Q3vPViu6FRGbYfy2RTMqcyhwmXB/jXAoGBAKix
|
||||||
|
6JXkixS/Ve8geKFiGn10QIkWxcyt77YgQbqZyNGSb29IXDS6udjhIpPrxnuZqvHt
|
||||||
|
FhHHcDiNF6xieP0rx5YVWbleG2VfbfY7RV2+e5M0GnqgDoMaoKSdO+ZKAKkX72vL
|
||||||
|
5SaJ/f+hperB9Ff6VUCyuFDDML6y50pI7r1+qRtXAoGBAKnEgB62mNZsJMcj0Sma
|
||||||
|
OEsLDDlZifubKnz6eGTyRnTCvQQLB3ZrGtrCuB/491THbwRGHoWfH433jgybkB+t
|
||||||
|
curB5sOv7Grn6gyc91RPWh/a4RwUWz1ZhW/bCz77idOfukVG4yCvaEdHCrNc7C4U
|
||||||
|
5pgpK7wpQ+Egl2Vr+1M6Zs0K
|
||||||
|
-----END PRIVATE KEY-----
|
3
src/main.zig
Normal file
3
src/main.zig
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn main() !void {}
|
13
src/root.zig
Normal file
13
src/root.zig
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//! By convention, root.zig is the root source file when making a library. If
|
||||||
|
//! you are making an executable, the convention is to delete this file and
|
||||||
|
//! start with main.zig instead.
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
pub export fn add(a: i32, b: i32) i32 {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "basic add functionality" {
|
||||||
|
try testing.expect(add(3, 7) == 10);
|
||||||
|
}
|
134
src/wasm.zig
Normal file
134
src/wasm.zig
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const width = 64;
|
||||||
|
const height = 32;
|
||||||
|
|
||||||
|
var pixel_data = std.mem.zeroes([height * width * 3]u8);
|
||||||
|
|
||||||
|
export fn getPixelDataPointer() [*]u8 {
|
||||||
|
return @ptrCast(&pixel_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const marker_color = Color{ .r = 0xAA, .g = 0x61, .b = 0xB7 };
|
||||||
|
const seconds_color = Color{ .r = 0xFF, .g = 0x98, .b = 0x00 };
|
||||||
|
const minutes_color = Color{ .r = 0x29, .g = 0xB6, .b = 0xF6 };
|
||||||
|
const hours_color = Color{ .r = 0x38, .g = 0x8E, .b = 0x3C };
|
||||||
|
|
||||||
|
const indicator_from = 6;
|
||||||
|
const indicator_to = 6;
|
||||||
|
|
||||||
|
const seconds_from = 5;
|
||||||
|
const seconds_to = 5;
|
||||||
|
|
||||||
|
const minutes_from = 0;
|
||||||
|
const minutes_to = 4;
|
||||||
|
|
||||||
|
const hours_from = 0;
|
||||||
|
const hours_to = 3;
|
||||||
|
|
||||||
|
const position = Vector2{ .x = 6, .y = 6 };
|
||||||
|
|
||||||
|
export fn draw() void {
|
||||||
|
@memset(&pixel_data, 0);
|
||||||
|
|
||||||
|
for (0..12) |a| {
|
||||||
|
clockHand(position, indicator_from, indicator_to, (@as(f32, @floatFromInt(a)) / 12.0) * 360.0, marker_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
const epoch_seconds = std.time.epoch.EpochSeconds{ .secs = timestamp() - std.time.s_per_hour * 6 };
|
||||||
|
const day_seconds = epoch_seconds.getDaySeconds();
|
||||||
|
|
||||||
|
const seconds: f32 = @floatFromInt(day_seconds.getSecondsIntoMinute());
|
||||||
|
const minutes: f32 = @floatFromInt(day_seconds.getMinutesIntoHour());
|
||||||
|
const hours: f32 = @floatFromInt(day_seconds.getHoursIntoDay());
|
||||||
|
|
||||||
|
clockHand(position, seconds_from, seconds_to, 270 + (seconds / 60.0) * 360.0, seconds_color);
|
||||||
|
clockHand(position, minutes_from, minutes_to, 270 + (minutes / 60.0) * 360.0, minutes_color);
|
||||||
|
clockHand(position, hours_from, hours_to, 270 + (hours / 12.0) * 360.0, hours_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clockHand(pos: Vector2, from: u8, to: u8, angle: f32, color: Color) void {
|
||||||
|
const radians = angle * std.math.pi / 180.0;
|
||||||
|
const x: f32 = @floatFromInt(pos.x);
|
||||||
|
const y: f32 = @floatFromInt(pos.y);
|
||||||
|
const from_float: f32 = @floatFromInt(from);
|
||||||
|
const to_float: f32 = @floatFromInt(to);
|
||||||
|
line(
|
||||||
|
.{
|
||||||
|
.x = @intFromFloat(@round(x + @cos(radians) * from_float)),
|
||||||
|
.y = @intFromFloat(@round(y + @sin(radians) * from_float)),
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.x = @intFromFloat(@round(x + @cos(radians) * to_float)),
|
||||||
|
.y = @intFromFloat(@round(y + @sin(radians) * to_float)),
|
||||||
|
},
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn line(from: Vector2, to: Vector2, color: Color) void {
|
||||||
|
const dx = @abs(@as(i16, @intCast(to.x)) - @as(i16, @intCast(from.x)));
|
||||||
|
const dy = @abs(@as(i16, @intCast(to.y)) - @as(i16, @intCast(from.y)));
|
||||||
|
const sx: i2 = if (from.x < to.x) 1 else -1;
|
||||||
|
const sy: i2 = if (from.y < to.y) 1 else -1;
|
||||||
|
var v = from;
|
||||||
|
|
||||||
|
if (dx > dy) {
|
||||||
|
var err = @as(f32, @floatFromInt(dx)) / 2.0;
|
||||||
|
while (v.x != to.x) {
|
||||||
|
setPixel(v, color);
|
||||||
|
err -= @floatFromInt(dy);
|
||||||
|
if (err < 0) {
|
||||||
|
v.y = @intCast(@as(i16, @intCast(v.y)) + sy);
|
||||||
|
err += @floatFromInt(dx);
|
||||||
|
}
|
||||||
|
v.x = @intCast(@as(i16, @intCast(v.x)) + sx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var err = @as(f32, @floatFromInt(dy)) / 2.0;
|
||||||
|
while (v.y != to.y) {
|
||||||
|
setPixel(v, color);
|
||||||
|
err -= @floatFromInt(dx);
|
||||||
|
if (err < 0) {
|
||||||
|
v.x = @intCast(@as(i16, @intCast(v.x)) + sx);
|
||||||
|
err += @floatFromInt(dy);
|
||||||
|
}
|
||||||
|
v.y = @intCast(@as(i16, @intCast(v.y)) + sy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setPixel(v, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn setPixel(pos: Vector2, color: Color) void {
|
||||||
|
const ptr: *[height][width][3]u8 = @ptrCast(&pixel_data);
|
||||||
|
ptr[pos.y][pos.x][0] = color.r;
|
||||||
|
ptr[pos.y][pos.x][1] = color.g;
|
||||||
|
ptr[pos.y][pos.x][2] = color.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn getPixel(pos: Vector2) Color {
|
||||||
|
const ptr: *[height][width][3]u8 = @ptrCast(&pixel_data);
|
||||||
|
return .{
|
||||||
|
.r = ptr[pos.x][pos.x][0],
|
||||||
|
.g = ptr[pos.x][pos.x][1],
|
||||||
|
.b = ptr[pos.x][pos.x][2],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const Color = struct {
|
||||||
|
r: u8,
|
||||||
|
g: u8,
|
||||||
|
b: u8,
|
||||||
|
|
||||||
|
pub const WHITE = Color{ .r = 0xFF, .g = 0xFF, .b = 0xFF };
|
||||||
|
pub const BLACK = Color{ .r = 0x00, .g = 0x00, .b = 0x00 };
|
||||||
|
};
|
||||||
|
|
||||||
|
const Vector2 = struct {
|
||||||
|
x: u8,
|
||||||
|
y: u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern fn timestamp() u64;
|
||||||
|
extern fn printi64(arg: i64) void;
|
||||||
|
extern fn printf32(arg: f32) void;
|
Loading…
Add table
Add a link
Reference in a new issue