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