diff --git a/build.zig b/build.zig index 51e1fb4..2c19bb5 100644 --- a/build.zig +++ b/build.zig @@ -196,6 +196,8 @@ fn install_ly(allocator: std.mem.Allocator, io: std.Io, patch_map: PatchMap, ins try installText(io, patched_setup, config_dir, ly_config_directory, "setup.sh", .{ .permissions = .fromMode(0o755) }); try installFile(io, "res/example.dur", config_dir, ly_config_directory, "example.dur", .{ .permissions = .fromMode(0o755) }); + + try installFile(io, "res/example.lua", config_dir, ly_config_directory, "example.lua", .{ .permissions = .fromMode(0o755) }); } { diff --git a/res/config.ini b/res/config.ini index a290773..169f5ea 100644 --- a/res/config.ini +++ b/res/config.ini @@ -25,6 +25,7 @@ allow_empty_password = true # colormix -> Color mixing shader # gameoflife -> John Conway's Game of Life # dur_file -> .dur file format (https://github.com/cmang/durdraw/tree/master) +# lua -> user-made animation written in LuaJIT animation = none # Delay between each animation frame in milliseconds @@ -298,6 +299,9 @@ login_defs_path = /etc/login.defs # no need to add `exec "$@"` at the end logout_cmd = null +# The file pointing to the Lua file to be used when using the Lua animation option +lua_animation_file = $CONFIG_DIRECTORY/ly/example.lua + # General log file path # If null, syslog will be used instead ly_log = /var/log/ly.log diff --git a/res/example.lua b/res/example.lua new file mode 100644 index 0000000..fd5a02e --- /dev/null +++ b/res/example.lua @@ -0,0 +1,49 @@ +-- [[ +-- This is an example of using LuaJIT to create a custom animation in Ly, in this case a +-- bouncing square that changes colors. +-- +-- You are given the following `ly` table: +-- { +-- height: number -- The height of the terminal +-- width: number -- The width of the terminal +-- frame_delay: number -- The amount of frames to delay an update to the animation +-- putCell(byte, fg, bg, x, y) -- Put the cell a buffer. This buffer will be drawn +-- on screen after draw() is called. It will not clear +-- itself automatically, see `ly.clear()`. +-- All arguments to this function are numbers, and +-- must be in the unsigned 32-bit integer range: 0 to 2^32-1. +-- clear() -- Clear the buffer. +-- } +-- ]] + +local SQUARE_WIDTH = 10 +local SQUARE_HEIGHT = 5 + +local SQUARE_X = 0 +local SQUARE_Y = 0 + +local SQUARE_VX = 1 +local SQUARE_VY = 1 + +local timer = os.clock() +local color = math.random(0xFFFFFF) + +function draw() + -- Rather than progressing the animation by frame, do it based on + -- seconds, like from os.clock(). + if timer + 0.025 < os.clock() then + ly.clear() + SQUARE_X = SQUARE_X + SQUARE_VX + SQUARE_Y = SQUARE_Y + SQUARE_VY + for x = SQUARE_X, SQUARE_X + SQUARE_WIDTH do + for y = SQUARE_Y, SQUARE_Y + SQUARE_HEIGHT do + ly.putCell(string.byte(' '), 0, color, x, y) + end + end + if SQUARE_X <= 0 then SQUARE_VX = 1; color = math.random(0xFFFFFF) end + if SQUARE_X + SQUARE_WIDTH >= ly.width-1 then SQUARE_VX = -1; color = math.random(0xFFFFFF) end + if SQUARE_Y <= 0 then SQUARE_VY = 1; color = math.random(0xFFFFFF) end + if SQUARE_Y + SQUARE_HEIGHT >= ly.height-1 then SQUARE_VY = -1; color = math.random(0xFFFFFF) end + timer = os.clock() + end +end diff --git a/src/animations/Lua.zig b/src/animations/Lua.zig index 26cd5cc..af93fc6 100644 --- a/src/animations/Lua.zig +++ b/src/animations/Lua.zig @@ -129,7 +129,7 @@ fn draw(self: *Lua) void { self.lua.pop(1); self.lua.pop(1); if (pos < 0) continue; // do not draw cells that underflow - Cell.init(@intCast(char), @intCast(fg), @intCast(bg)) + Cell.init(@intCast(char), @intCast(@as(i32, @truncate(fg))), @intCast(@as(i32, @truncate(bg)))) .put(@rem(@as(usize, @intCast(pos)), self.width), @divFloor(@as(usize, @bitCast(pos)), self.width)) catch {}; } } else {