const std = @import("std"); const rl = @import("raylib"); const c = @cImport({ @cInclude("cute_aseprite.h"); }); const assert = std.debug.assert; ase: *c.ase_t, pub fn init(allocator: std.mem.Allocator, memory: []const u8) !@This() { _ = allocator; // TODO: Pass allocator to function const parsed = c.cute_aseprite_load_from_memory(@ptrCast(memory), @intCast(memory.len), null); if (parsed == null) { return error.CuteLoadFromMemory; } return @This(){ .ase = @ptrCast(parsed) }; } pub fn deinit(self: @This()) void { c.cute_aseprite_free(self.ase); } pub fn getTag(self: @This(), name: []const u8) ?c.struct_ase_tag_t { const tag_count: usize = @intCast(self.ase.tag_count); for (self.ase.tags[0..tag_count]) |tag| { const tag_name = std.mem.span(tag.name); if (std.mem.eql(u8, tag_name, name)) { return tag; } } return null; } pub fn getFrameImage(self: @This(), frame_index: usize) rl.Image { const width: usize = @intCast(self.ase.w); const height: usize = @intCast(self.ase.h); var image = rl.genImageColor(@intCast(width), @intCast(height), rl.Color.black.alpha(0)); assert(@intFromPtr(image.data) != 0); image.setFormat(rl.PixelFormat.pixelformat_uncompressed_r8g8b8a8); const pixel_count = width * height; const frame = self.ase.frames[frame_index]; for (0.., frame.pixels[0..pixel_count]) |pixel_index, pixel| { const x = @mod(pixel_index, width); const y = @divFloor(pixel_index, height); image.drawPixel(@intCast(x), @intCast(y), .{ .r = pixel.r, .g = pixel.g, .b = pixel.b, .a = pixel.a, }); } return image; } pub fn getTagImage(self: @This(), tag: c.struct_ase_tag_t) rl.Image { return getFrameImage(self, @intCast(tag.from_frame)); }