mirror of
https://codeberg.org/fairyglade/ly.git
synced 2026-08-20 04:24:19 +02:00
Add support of negitive offset and new alignments
This commit is contained in:
parent
2eea683078
commit
e9844dde1b
4 changed files with 86 additions and 30 deletions
|
|
@ -167,6 +167,16 @@ doom_bottom_color = 0x00FFFFFF
|
|||
# Dur file path
|
||||
dur_file_path = $CONFIG_DIRECTORY/ly/example.dur
|
||||
|
||||
# Dur file alignment (center is the default for example)
|
||||
# |-----------------|
|
||||
# |1 2 3|
|
||||
# | |
|
||||
# |4 0 5|
|
||||
# | |
|
||||
# |6 7 8|
|
||||
# |-----------------|
|
||||
dur_offset_alignment = 0
|
||||
|
||||
# Dur offset x direction
|
||||
dur_x_offset = 0
|
||||
|
||||
|
|
|
|||
|
|
@ -286,25 +286,41 @@ fn convert_256_to_rgb(color_256: u32) u32 {
|
|||
return rgb_color;
|
||||
}
|
||||
|
||||
const UVec2 = @Vector(2, u16);
|
||||
const IVec2 = @Vector(2, i32);
|
||||
|
||||
const VEC_X = 0;
|
||||
const VEC_Y = 1;
|
||||
|
||||
const Alignment = struct {
|
||||
pub const CENTER = 0; // Center is the default so we have it out of order
|
||||
pub const TOP_LEFT = 1;
|
||||
pub const TOP_CENTER = 2;
|
||||
pub const TOP_RIGHT = 3;
|
||||
pub const CENTER_LEFT = 4;
|
||||
pub const CENTER_RIGHT = 5;
|
||||
pub const BOTTOM_LEFT = 6;
|
||||
pub const BOTTOM_CENTER = 7;
|
||||
pub const BOTTOM_RIGHT = 8;
|
||||
};
|
||||
|
||||
|
||||
const DurFile = @This();
|
||||
|
||||
allocator: Allocator,
|
||||
terminal_buffer: *TerminalBuffer,
|
||||
frames: u64,
|
||||
time_previous: i64,
|
||||
x_offset: u32,
|
||||
y_offset: u32,
|
||||
full_color: bool,
|
||||
dur_movie: DurFormat,
|
||||
frame_width: u32,
|
||||
frame_height: u32,
|
||||
frames: u64,
|
||||
frame_size: UVec2,
|
||||
start_pos: IVec2,
|
||||
full_color: bool,
|
||||
frame_time: u32,
|
||||
time_previous: i64,
|
||||
is_color_format_16: bool,
|
||||
|
||||
pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, log_writer: *std.io.Writer, file_path: []const u8, x_offset: u32, y_offset: u32, full_color: bool) !DurFile {
|
||||
pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, log_writer: *std.io.Writer, file_path: []const u8, offset_alignment: u32, x_offset: i32, y_offset: i32, full_color: bool) !DurFile {
|
||||
var dur_movie: DurFormat = .init(allocator);
|
||||
|
||||
// error state is recoverable when thrown to main and results in no background with Dummy in main
|
||||
dur_movie.create_from_file(allocator, file_path) catch |err| switch (err) {
|
||||
error.FileNotFound => {
|
||||
try log_writer.print("error: dur_file was not found at: {s}\n", .{file_path});
|
||||
|
|
@ -324,19 +340,35 @@ pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, log_writer:
|
|||
return error.InvalidColorFormat;
|
||||
}
|
||||
|
||||
const buf_width: u32 = @intCast(terminal_buffer.width);
|
||||
const buf_height: u32 = @intCast(terminal_buffer.height);
|
||||
const buf_width: u16 = @intCast(terminal_buffer.width);
|
||||
const buf_height: u16 = @intCast(terminal_buffer.height);
|
||||
|
||||
const movie_width: u32 = @intCast(dur_movie.columns.?);
|
||||
const movie_height: u32 = @intCast(dur_movie.lines.?);
|
||||
const movie_width: u16 = @intCast(dur_movie.columns.?);
|
||||
const movie_height: u16 = @intCast(dur_movie.lines.?);
|
||||
|
||||
// Clamp to prevent user from exceeding draw window
|
||||
const x_offset_clamped = std.math.clamp(x_offset, 0, buf_width - 1);
|
||||
const y_offset_clamped = std.math.clamp(y_offset, 0, buf_height - 1);
|
||||
// if the user has an even number of columns or rows, we will default to the left or higher position (e.g. 4 columns center = .x..)
|
||||
const center = struct {
|
||||
fn center(v: u16) i32 { return @intCast((v / 2) + (v % 2)); }
|
||||
}.center;
|
||||
|
||||
// Ensure if user offsets and frame goes offscreen, it will not overflow draw
|
||||
const frame_width = if ((movie_width + x_offset_clamped) < buf_width) movie_width else buf_width - x_offset_clamped;
|
||||
const frame_height = if ((movie_height + y_offset_clamped) < buf_height) movie_height else buf_height - y_offset_clamped;
|
||||
var start_pos = switch (offset_alignment) {
|
||||
Alignment.CENTER => IVec2{ center(buf_width) - center(movie_width), center(buf_height) - center(movie_height) },
|
||||
Alignment.TOP_LEFT => IVec2{ 0, 0 },
|
||||
Alignment.TOP_CENTER => IVec2{ center(buf_width) - center(movie_width), 0 },
|
||||
Alignment.TOP_RIGHT => IVec2{ buf_width - movie_width, 0 },
|
||||
Alignment.CENTER_LEFT => IVec2{ 0, center(buf_width) - center(movie_width) },
|
||||
Alignment.CENTER_RIGHT => IVec2{ buf_width - movie_width, center(buf_width) - center(movie_width) },
|
||||
Alignment.BOTTOM_LEFT => IVec2{ 0, buf_width - movie_height },
|
||||
Alignment.BOTTOM_CENTER => IVec2{ center(buf_width) - center(movie_width), buf_width - movie_height },
|
||||
Alignment.BOTTOM_RIGHT => IVec2{ buf_width - movie_width, buf_height - movie_height },
|
||||
else => return error.InvalidDurOffsetAlignment,
|
||||
};
|
||||
|
||||
start_pos += IVec2{ x_offset, y_offset };
|
||||
|
||||
// Draw only the needed amount if movie smaller than screen. If movie is bigger, we will just draw entire screen
|
||||
const frame_width = if (movie_width < buf_width) movie_width else buf_width;
|
||||
const frame_height = if (movie_height < buf_height) movie_height else buf_height;
|
||||
|
||||
// Convert dur fps to frames per ms
|
||||
const frame_time: u32 = @intFromFloat(1000 / dur_movie.framerate.?);
|
||||
|
|
@ -346,12 +378,10 @@ pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, log_writer:
|
|||
.terminal_buffer = terminal_buffer,
|
||||
.frames = 0,
|
||||
.time_previous = std.time.milliTimestamp(),
|
||||
.x_offset = x_offset_clamped,
|
||||
.y_offset = y_offset_clamped,
|
||||
.frame_size = UVec2{ frame_width, frame_height },
|
||||
.start_pos = start_pos,
|
||||
.full_color = full_color,
|
||||
.dur_movie = dur_movie,
|
||||
.frame_width = frame_width,
|
||||
.frame_height = frame_height,
|
||||
.frame_time = frame_time,
|
||||
.is_color_format_16 = eql(u8, dur_movie.colorFormat.?, "16"),
|
||||
};
|
||||
|
|
@ -370,10 +400,25 @@ fn realloc(_: *DurFile) anyerror!void {}
|
|||
fn draw(self: *DurFile) void {
|
||||
const current_frame = self.dur_movie.frames.items[self.frames];
|
||||
|
||||
for (0..self.frame_height) |y| {
|
||||
const buf_width: u16 = @intCast(self.terminal_buffer.width);
|
||||
const buf_height: u16 = @intCast(self.terminal_buffer.height);
|
||||
|
||||
// y is used as an iterator in the durformat, while cell_y gives us the correct placement for the cell (same for x)
|
||||
for (0..self.frame_size[VEC_Y]) |y| {
|
||||
const y_offset_i: i32 = @as(i32, @intCast(y)) + self.start_pos[VEC_Y];
|
||||
// we skip the pass if it falls outside of the draw window (ensure no int underflow)
|
||||
const cell_y: u32 = if (y_offset_i >= 0 and y_offset_i < buf_height) @intCast(y_offset_i) else continue;
|
||||
|
||||
var iter = std.unicode.Utf8View.initUnchecked(current_frame.contents[y]).iterator();
|
||||
|
||||
for (0..self.frame_width) |x| {
|
||||
for (0..self.frame_size[VEC_X]) |x| {
|
||||
const x_offset_i: i32 = @as(i32, @intCast(x)) + self.start_pos[VEC_X];
|
||||
// skip pass, same as y but also incriment the codepoint iter to fetch correct values in later passes
|
||||
const cell_x: u32 = if (x_offset_i >= 0 and x_offset_i < buf_width) @intCast(x_offset_i) else {
|
||||
_ = iter.nextCodepoint().?;
|
||||
continue;
|
||||
};
|
||||
|
||||
const codepoint: u21 = iter.nextCodepoint().?;
|
||||
const color_map = current_frame.colorMap[x][y];
|
||||
|
||||
|
|
@ -390,7 +435,7 @@ fn draw(self: *DurFile) void {
|
|||
|
||||
const cell = Cell{ .ch = @intCast(codepoint), .fg = fg_color, .bg = bg_color };
|
||||
|
||||
cell.put(x + self.x_offset, y + self.y_offset);
|
||||
cell.put(cell_x, cell_y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,8 +43,9 @@ doom_top_color: u32 = 0x00FF0000,
|
|||
doom_middle_color: u32 = 0x00FFFF00,
|
||||
doom_bottom_color: u32 = 0x00FFFFFF,
|
||||
dur_file_path: []const u8 = build_options.config_directory ++ "/ly/example.dur",
|
||||
dur_x_offset: u32 = 0,
|
||||
dur_y_offset: u32 = 0,
|
||||
dur_offset_alignment: u32 = 0,
|
||||
dur_x_offset: i32 = 0,
|
||||
dur_y_offset: i32 = 0,
|
||||
edge_margin: u8 = 0,
|
||||
error_bg: u32 = 0x00000000,
|
||||
error_fg: u32 = 0x01FF0000,
|
||||
|
|
|
|||
|
|
@ -580,7 +580,7 @@ pub fn main() !void {
|
|||
animation = game_of_life.animation();
|
||||
},
|
||||
.dur_file => {
|
||||
var dur = try DurFile.init(allocator, &buffer, log_writer, config.dur_file_path, config.dur_x_offset, config.dur_y_offset, config.full_color);
|
||||
var dur = try DurFile.init(allocator, &buffer, log_writer, config.dur_file_path, config.dur_offset_alignment, config.dur_x_offset, config.dur_y_offset, config.full_color);
|
||||
animation = dur.animation();
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue