Compare commits

..

No commits in common. "a2bca12bc775f54bf5c3f2ec338be5f004af5057" and "c2ba2efd7623796620749ae1d6dca0f0101371b8" have entirely different histories.

7 changed files with 46 additions and 80 deletions

View File

@ -1,29 +0,0 @@
name: Generic zig build
on:
workflow_dispatch:
push:
branches:
- '*'
- '!zig-develop*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: elerch/setup-zig@v3
with:
version: 0.12.0
- uses: elerch/zig-action-cache@v1.1.6
- name: Build project
run: zig build --summary all
- name: Run tests
run: zig build test --summary all
- name: Notify
uses: elerch/action-notify-ntfy@v2.github
if: env.GITEA_ACTIONS == 'true'
with:
host: ${{ secrets.NTFY_HOST }}
topic: ${{ secrets.NTFY_TOPIC }}
status: ${{ job.status }}
user: ${{ secrets.NTFY_USER }}
password: ${{ secrets.NTFY_PASSWORD }}

View File

@ -11,7 +11,7 @@ path: []const u8,
pub fn create(b: *std.build.Builder, opt: struct {
path: []const u8,
}) *AsciiPrintableStep {
const result = b.allocator.create(AsciiPrintableStep) catch @panic("OOM");
var result = b.allocator.create(AsciiPrintableStep) catch @panic("OOM");
result.* = AsciiPrintableStep{
.step = std.build.Step.init(.{
.id = .custom,
@ -40,7 +40,7 @@ fn hasDependency(step: *const std.build.Step, dep_candidate: *const std.build.St
}
fn make(step: *std.build.Step, _: *std.Progress.Node) !void {
const self: AsciiPrintableStep = @fieldParentPtr("step", step);
const self = @fieldParentPtr(AsciiPrintableStep, "step", step);
const zig_file = std.fmt.allocPrint(self.builder.allocator, "{s}/images.zig", .{self.path}) catch @panic("OOM");
defer self.builder.allocator.free(zig_file);
@ -67,7 +67,7 @@ fn make(step: *std.build.Step, _: *std.Progress.Node) !void {
// try writer.print(" \"\",\n", .{});
// continue;
// }
const char_str = [_]u8{@intCast(i)};
const char_str = [_]u8{@intCast(u8, i)};
// Need to escape the following chars: 32 (' ') 92 ('\')
const label_param = parm: {
switch (i) {

View File

@ -1,7 +1,7 @@
const std = @import("std");
const AsciiPrintableStep = @import("AsciiPrintableStep.zig");
pub fn build(b: *std.Build) !void {
pub fn build(b: *std.build.Builder) !void {
// comptime {
// const current_zig = builtin.zig_version;
// const min_zig = std.SemanticVersion.parse("0.11.0-dev.1254+1f8f79cd5") catch return; // add helper functions to std.zig.Ast
@ -31,10 +31,7 @@ pub fn build(b: *std.Build) !void {
.target = target,
.optimize = optimize,
});
i2cdriver.addCSourceFile(.{
.file = b.path("lib/i2cdriver/i2cdriver.c"),
.flags = &[_][]const u8{ "-Wall", "-Wpointer-sign", "-Werror" },
});
i2cdriver.addCSourceFile("lib/i2cdriver/i2cdriver.c", &[_][]const u8{ "-Wall", "-Wpointer-sign", "-Werror" });
i2cdriver.linkLibC();
const exe = b.addExecutable(.{
@ -46,8 +43,8 @@ pub fn build(b: *std.Build) !void {
exe.linkLibrary(im_dep.artifact("MagickWand"));
exe.linkLibrary(z_dep.artifact("z"));
exe.linkLibrary(i2cdriver);
exe.addIncludePath(b.path("lib/i2cdriver"));
b.installArtifact(exe);
exe.addIncludePath("lib/i2cdriver");
exe.install();
const exe_fontgen = b.addExecutable(.{
.name = "fontgen",
@ -57,11 +54,11 @@ pub fn build(b: *std.Build) !void {
});
exe_fontgen.linkLibrary(im_dep.artifact("MagickWand"));
exe_fontgen.linkLibrary(z_dep.artifact("z"));
exe.step.dependOn(&b.addRunArtifact(exe_fontgen).step);
exe.step.dependOn(&exe_fontgen.run().step);
// If image based characters are needed, uncomment this
// exe.step.dependOn(&AsciiPrintableStep.create(b, .{ .path = "src/images" }).step);
const run_cmd = b.addRunArtifact(exe);
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
@ -78,10 +75,10 @@ pub fn build(b: *std.Build) !void {
exe_tests.linkLibrary(im_dep.artifact("MagickWand"));
exe_tests.linkLibrary(z_dep.artifact("z"));
exe_tests.linkLibrary(i2cdriver);
exe_tests.addIncludePath(b.path("lib/i2cdriver"));
exe_tests.addIncludePath("lib/i2cdriver");
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&b.addRunArtifact(exe_tests).step);
test_step.dependOn(&exe_tests.run().step);
}
// Should be able to remove this

View File

@ -1,18 +1,15 @@
.{
.name = "i2c",
.version = "0.0.1",
.paths = .{
"",
},
.dependencies = .{
.ImageMagick = .{
.url = "https://github.com/elerch/ImageMagick/archive/91d7290d02188139486fd5078446ddd88e57aebe.tar.gz",
.hash = "1220a49c78df0938f80aca90d23ac694a1550d5329fe0594918c000fbcf0c9354822",
.url = "https://github.com/elerch/ImageMagick/archive/0c78c43ba348fe2d764593b074b4f53d087a3a26.tar.gz",
.hash = "12208162dcc0b1f2e5fb6376136fe5266b2b493a38ca8f30eff94b735f7da6ada462",
},
.libz = .{
.url = "https://github.com/elerch/libz/archive/1632972f211c6876d6dd8fcfdc13414a26b55c65.tar.gz",
.hash = "12200d3858388c9f74ef769cab3762cfddb4aee33133a5e08c96ee68130b2664f13a",
.url="https://github.com/andrewrk/libz/archive/9e71b746b83d2b5bf5eb247663eb65a52cf0f68f.tar.gz",
.hash = "12204ea3490e5bdf379f56aa11784d906aed6d4c553c724fa5427169915f2cf4a651",
},
},
}

View File

@ -37,9 +37,10 @@ pub fn main() !void {
const generated_file = try proj_path.createFile("src/fonts/fonts.zig", .{
.read = false,
.truncate = true,
.lock = .exclusive,
.lock = .Exclusive,
.lock_nonblocking = false,
.mode = 0o666,
.intended_io_mode = .blocking,
});
defer generated_file.close();
@ -73,7 +74,7 @@ pub fn main() !void {
// try writer.print(" \"\",\n", .{});
// continue;
// }
const char_str = [_]u8{@intCast(i)};
const char_str = [_]u8{@intCast(u8, i)};
// Need to escape the following chars: 32 (' ') 92 ('\')
const label_param = parm: {
switch (i) {
@ -154,11 +155,11 @@ fn run(allocator: std.mem.Allocator, argv: []const []const u8) !void {
}
std.log.debug("[RUN] {s}", .{msg.items});
}
std.posix.exit(0xff);
std.os.exit(0xff);
},
else => {
std.log.err("command failed with: {}", .{result});
std.posix.exit(0xff);
std.os.exit(0xff);
},
}
}
@ -171,8 +172,8 @@ pub fn unpackBits(pixels: *[GLYPH_WIDTH * GLYPH_HEIGHT]u8) void {
// overwrites
var i: isize = (GLYPH_WIDTH * GLYPH_HEIGHT / 8 - 1);
while (i >= 0) {
const start = @as(usize, @intCast(i)) * 8;
const packed_byte = pixels[@intCast(i)];
const start = @intCast(usize, i) * 8;
const packed_byte = pixels[@intCast(usize, i)];
pixels[start + 7] = ((packed_byte & 0b10000000) >> 7) * 0xFF;
pixels[start + 6] = ((packed_byte & 0b01000000) >> 6) * 0xFF;
pixels[start + 5] = ((packed_byte & 0b00100000) >> 5) * 0xFF;
@ -234,7 +235,7 @@ fn convertImage(filename: [:0]u8, pixels: *[GLYPH_WIDTH * GLYPH_HEIGHT]u8) !void
if (status == c.MagickFalse)
return error.CouldNotQuantizeImage;
status = c.MagickExportImagePixels(mw, 0, 0, GLYPH_WIDTH, GLYPH_HEIGHT, "I", c.CharPixel, @as(*anyopaque, @ptrCast(pixels)));
status = c.MagickExportImagePixels(mw, 0, 0, GLYPH_WIDTH, GLYPH_HEIGHT, "I", c.CharPixel, @ptrCast(*anyopaque, pixels));
if (status == c.MagickFalse)
return error.CouldNotExportImage;

View File

@ -1,6 +1,6 @@
const std = @import("std");
pub fn ioctl(handle: std.posix.fd_t, request: u32, arg: usize) !void {
pub fn ioctl(handle: std.os.fd_t, request: u32, arg: usize) !void {
const rc = std.os.linux.ioctl(handle, request, arg);
try throwReturnCodeError(rc);
return;
@ -8,7 +8,7 @@ pub fn ioctl(handle: std.posix.fd_t, request: u32, arg: usize) !void {
pub fn throwReturnCodeError(return_code: usize) LinuxGenericError!void {
// zig fmt: off
switch (std.posix.errno(return_code)) {
switch (std.os.errno(return_code)) {
.SUCCESS => return,
.PERM => return LinuxGenericError.OperationNotPermittedError,
.NOENT => return LinuxGenericError.NoSuchFileOrDirectoryError,

View File

@ -34,7 +34,7 @@ fn usage(args: [][]u8) !void {
try writer.print("usage: {s} <device> [-bg <image file>] [-<num> text]...\n", .{args[0]});
try writer.print("\t-<num> text: line number and text to display\n", .{});
try writer.print("\te.g. \"-1 'hello world'\" will display \"hello world\" on line 1\n", .{});
std.posix.exit(1);
std.os.exit(1);
}
const Options = struct {
background_filename: [:0]u8,
@ -76,7 +76,7 @@ pub fn main() !void {
try std.io.getStdErr().writer().print("ERROR: data provided exceeds what can be sent to device!\n", .{});
try usage(args);
}
const read_data = stdin_data[0..read];
var read_data = stdin_data[0..read];
var it = std.mem.split(u8, read_data, "\n");
while (it.next()) |line| {
if (line.len == 0) continue;
@ -153,7 +153,7 @@ fn processArgs(args: [][:0]u8, line_array: *[display.LINES]*const [:0]u8) !Optio
"ERROR: text for line {d} has {d} chars, exceeding maximum length {d}\n",
.{ line, arg.len, display.CHARS_PER_LINE },
);
std.posix.exit(1);
std.os.exit(1);
}
std.log.debug("line {d} text: \"{s}\"\n", .{ line, arg });
line_array.*[line] = &args[i];
@ -181,7 +181,7 @@ fn flipImage(pixels: *[display.WIDTH * display.HEIGHT]u8) void {
}
fn addTextToImage(allocator: std.mem.Allocator, pixels: *[display.WIDTH * display.HEIGHT]u8, data: []*[]u8) !void {
const maybe_font_data = try getFontData(allocator, DEFAULT_FONT);
var maybe_font_data = try getFontData(allocator, DEFAULT_FONT);
if (maybe_font_data == null) return error.FontNotFound;
var font_data = maybe_font_data.?;
@ -220,7 +220,7 @@ fn getFontData(allocator: std.mem.Allocator, font_name: []const u8) !?FontInnerH
if (font_arena == null) {
font_arena = std.heap.ArenaAllocator.init(allocator);
}
const alloc = font_arena.?.allocator();
var alloc = font_arena.?.allocator();
// The bit lookup will be a bit tricky because we have runtime value to look up
// We can use an inline for but compute complexity is a bit crazy. Best to use a
// hashmap here
@ -277,7 +277,7 @@ fn getFontMap(allocator: std.mem.Allocator, comptime font_name: []const u8) !*Fo
.{fmtSliceHexLower(@field(font_struct, point.name))},
);
}
const key_ptr = try allocator.create(u21);
var key_ptr = try allocator.create(u21);
key_ptr.* = std.fmt.parseInt(u21, point.name, 10) catch unreachable;
map.putAssumeCapacity(
key_ptr.*,
@ -344,7 +344,7 @@ fn sendPixelsThroughI2CDriver(pixels: []const u8, file: [*:0]const u8, device_id
.ccitt_crc = 0,
.e_ccitt_crc = 0,
};
const c_file: [*c]const u8 = @ptrCast(file);
const c_file = @ptrCast([*c]const u8, file);
const stdout_file = std.io.getStdOut().writer();
var bw = std.io.bufferedWriter(stdout_file);
const stdout = bw.writer();
@ -382,7 +382,7 @@ fn sendPixelsThroughI2CDriver(pixels: []const u8, file: [*:0]const u8, device_id
}
fn i2cWrite(i2c: *c.I2CDriver, bytes: []const u8) !void {
const rc = c.i2c_write(i2c, @ptrCast(bytes), bytes.len); // nn is size of array
var rc = c.i2c_write(i2c, @ptrCast([*c]const u8, bytes), bytes.len); // nn is size of array
if (rc != 1)
return error.BadWrite;
}
@ -439,7 +439,7 @@ fn formatSliceGreyscaleImage(
fn reportMagickError(mw: ?*c.MagickWand) !void {
var severity: c.ExceptionType = undefined;
var description = c.MagickGetException(mw, &severity);
defer description = @ptrCast(c.MagickRelinquishMemory(description));
defer description = @ptrCast([*c]u8, c.MagickRelinquishMemory(description));
try std.io.getStdErr().writer().print("{s}\n", .{description});
}
fn textForLine(line: usize) []u8 {
@ -514,8 +514,8 @@ fn convertImage(filename: [:0]u8, pixels: *[display.WIDTH * display.HEIGHT]u8, t
mw,
display.WIDTH,
display.HEIGHT,
-@as(isize, @intCast((display.WIDTH - resize_dimensions.width) / 2)),
-@as(isize, @intCast((display.HEIGHT - resize_dimensions.height) / 2)),
-@intCast(isize, (display.WIDTH - resize_dimensions.width) / 2),
-@intCast(isize, (display.HEIGHT - resize_dimensions.height) / 2),
);
if (status == c.MagickFalse)
@ -525,7 +525,7 @@ fn convertImage(filename: [:0]u8, pixels: *[display.WIDTH * display.HEIGHT]u8, t
const text = text_fn(i);
if (text.len == 0) continue;
// We have text!
const y: isize = display.FONT_HEIGHT * @as(isize, @intCast(i));
const y: isize = display.FONT_HEIGHT * @intCast(isize, i);
var x: isize = display.BORDER_LEFT;
var left_spaces: isize = 0;
for (text) |ch| {
@ -536,7 +536,7 @@ fn convertImage(filename: [:0]u8, pixels: *[display.WIDTH * display.HEIGHT]u8, t
break;
}
x += (display.FONT_WIDTH * left_spaces);
mw = try drawString(mw, text[@intCast(left_spaces)..], x, y);
mw = try drawString(mw, text[@intCast(usize, left_spaces)..], x, y);
}
// We make the image monochrome by quantizing the image with 2 colors in the
@ -558,7 +558,7 @@ fn convertImage(filename: [:0]u8, pixels: *[display.WIDTH * display.HEIGHT]u8, t
if (status == c.MagickFalse)
return error.CouldNotQuantizeImage;
status = c.MagickExportImagePixels(mw, 0, 0, display.WIDTH, display.HEIGHT, "I", c.CharPixel, @as(*anyopaque, @ptrCast(pixels)));
status = c.MagickExportImagePixels(mw, 0, 0, display.WIDTH, display.HEIGHT, "I", c.CharPixel, @ptrCast(*anyopaque, pixels));
if (status == c.MagickFalse)
return error.CouldNotExportImage;
@ -577,7 +577,7 @@ fn drawString(mw: ?*c.MagickWand, str: []const u8, x: isize, y: isize) !?*c.Magi
rc = try drawCharacter(
rc,
ch,
-(x + @as(isize, @intCast(display.FONT_WIDTH * i))),
-(x + @intCast(isize, display.FONT_WIDTH * i)),
-y,
);
}
@ -596,7 +596,7 @@ fn drawCharacter(mw: ?*c.MagickWand, char: u8, x: isize, y: isize) !?*c.MagickWa
}
const image_char = chars[char];
if (image_char.len == 0) return error.CharacterNotSupported;
var status = c.MagickReadImageBlob(cw, @ptrCast(image_char), image_char.len);
var status = c.MagickReadImageBlob(cw, @ptrCast(?*const anyopaque, image_char), image_char.len);
if (status == c.MagickFalse) unreachable; // Something is terribly wrong if this fails
// For character placement, we need to set the image to the correct
@ -650,20 +650,20 @@ const Dimensions = struct {
fn getNewDimensions(width: usize, height: usize, desired_width: usize, desired_height: usize) Dimensions {
// assuming we're shrinking for now.
// TODO: Handle expansion
const width_ratio = @as(f64, @floatFromInt(width)) / @as(f64, @floatFromInt(desired_width));
const height_ratio = @as(f64, @floatFromInt(height)) / @as(f64, @floatFromInt(desired_height));
const width_ratio = @intToFloat(f64, width) / @intToFloat(f64, desired_width);
const height_ratio = @intToFloat(f64, height) / @intToFloat(f64, desired_height);
const resize_ratio = if (width_ratio > height_ratio) width_ratio else height_ratio;
return .{
.width = @intFromFloat(@as(f64, @floatFromInt(width)) / resize_ratio), // 48,
.height = @intFromFloat(@as(f64, @floatFromInt(height)) / resize_ratio), // 64,
.width = @floatToInt(usize, @intToFloat(f64, width) / resize_ratio), // 48,
.height = @floatToInt(usize, @intToFloat(f64, height) / resize_ratio), // 64,
};
}
test "gets proper font data" {
// std.testing.log_level = .debug;
std.log.debug("\n", .{});
defer deinit();
const maybe_font_data = try getFontData(std.testing.allocator, DEFAULT_FONT);
var maybe_font_data = try getFontData(std.testing.allocator, DEFAULT_FONT);
try std.testing.expect(maybe_font_data != null);
var font_data = maybe_font_data.?;