aboutsummaryrefslogtreecommitdiff
path: root/mirai.old/utils/graphics/pixel.zig
diff options
context:
space:
mode:
Diffstat (limited to 'mirai.old/utils/graphics/pixel.zig')
-rw-r--r--mirai.old/utils/graphics/pixel.zig197
1 files changed, 197 insertions, 0 deletions
diff --git a/mirai.old/utils/graphics/pixel.zig b/mirai.old/utils/graphics/pixel.zig
new file mode 100644
index 0000000..29bd446
--- /dev/null
+++ b/mirai.old/utils/graphics/pixel.zig
@@ -0,0 +1,197 @@
+//! Pixel and framebuffer utilities
+
+const boot = @import("../../boot/multiboot/multiboot.zig");
+const color = @import("color.zig");
+const video = @import("../../common/constants/video.zig");
+
+pub inline fn ptr_32(addr: u64) [*]volatile u32 {
+ return @as([*]volatile u32, @ptrFromInt(addr));
+}
+
+pub inline fn ptr_8(addr: u64) [*]volatile u8 {
+ return @as([*]volatile u8, @ptrFromInt(addr));
+}
+
+pub inline fn offset_32(fb: boot.FramebufferInfo, x: u32, y: u32) usize {
+ return y * (fb.pitch / video.BYTES_PER_PIXEL_32) + x;
+}
+
+pub inline fn offset_24(fb: boot.FramebufferInfo, x: u32, y: u32) usize {
+ return y * fb.pitch + x * video.BYTES_PER_PIXEL_24;
+}
+
+pub inline fn pixels_per_row(fb: boot.FramebufferInfo) u32 {
+ return fb.pitch / video.BYTES_PER_PIXEL_32;
+}
+
+pub fn put(fb: boot.FramebufferInfo, x: u32, y: u32, c: u32) void {
+ if (x >= fb.width or y >= fb.height) return;
+
+ if (fb.bpp == video.BPP_32) {
+ put_32(fb, x, y, c);
+ } else if (fb.bpp == video.BPP_24) {
+ put_24(fb, x, y, c);
+ }
+}
+
+pub fn put_32(fb: boot.FramebufferInfo, x: u32, y: u32, c: u32) void {
+ const pixels = ptr_32(fb.addr);
+ pixels[offset_32(fb, x, y)] = c;
+}
+
+pub fn put_24(fb: boot.FramebufferInfo, x: u32, y: u32, c: u32) void {
+ const pixels = ptr_8(fb.addr);
+ const off = offset_24(fb, x, y);
+ const rgb = color.extract(c);
+ pixels[off] = rgb.b;
+ pixels[off + 1] = rgb.g;
+ pixels[off + 2] = rgb.r;
+}
+
+pub fn fill(fb: boot.FramebufferInfo, c: u32) void {
+ if (fb.bpp == video.BPP_32) {
+ fill_32(fb, c);
+ } else if (fb.bpp == video.BPP_24) {
+ fill_24(fb, c);
+ }
+}
+
+pub fn fill_32(fb: boot.FramebufferInfo, c: u32) void {
+ const pixels = ptr_32(fb.addr);
+ const total = fb.width * fb.height;
+ var i: usize = 0;
+ while (i < total) : (i += 1) {
+ pixels[i] = c;
+ }
+}
+
+pub fn fill_24(fb: boot.FramebufferInfo, c: u32) void {
+ const pixels = ptr_8(fb.addr);
+ const rgb = color.extract(c);
+
+ var y: u32 = 0;
+ while (y < fb.height) : (y += 1) {
+ var x: u32 = 0;
+ while (x < fb.width) : (x += 1) {
+ const off = offset_24(fb, x, y);
+ pixels[off] = rgb.b;
+ pixels[off + 1] = rgb.g;
+ pixels[off + 2] = rgb.r;
+ }
+ }
+}
+
+pub fn fill_rect(fb: boot.FramebufferInfo, x: u32, y: u32, w: u32, h: u32, c: u32) void {
+ if (fb.bpp == video.BPP_32) {
+ fill_rect_32(fb, x, y, w, h, c);
+ } else if (fb.bpp == video.BPP_24) {
+ fill_rect_24(fb, x, y, w, h, c);
+ }
+}
+
+pub fn fill_rect_32(fb: boot.FramebufferInfo, x: u32, y: u32, w: u32, h: u32, c: u32) void {
+ const pixels = ptr_32(fb.addr);
+
+ var row: u32 = 0;
+ while (row < h) : (row += 1) {
+ var col: u32 = 0;
+ while (col < w) : (col += 1) {
+ const px = x + col;
+ const py = y + row;
+ if (px < fb.width and py < fb.height) {
+ pixels[offset_32(fb, px, py)] = c;
+ }
+ }
+ }
+}
+
+pub fn fill_rect_24(fb: boot.FramebufferInfo, x: u32, y: u32, w: u32, h: u32, c: u32) void {
+ const pixels = ptr_8(fb.addr);
+ const rgb = color.extract(c);
+
+ var row: u32 = 0;
+ while (row < h) : (row += 1) {
+ var col: u32 = 0;
+ while (col < w) : (col += 1) {
+ const px = x + col;
+ const py = y + row;
+ if (px < fb.width and py < fb.height) {
+ const off = offset_24(fb, px, py);
+ pixels[off] = rgb.b;
+ pixels[off + 1] = rgb.g;
+ pixels[off + 2] = rgb.r;
+ }
+ }
+ }
+}
+
+pub fn copy_row(fb: boot.FramebufferInfo, dst_y: u32, src_y: u32) void {
+ if (fb.bpp == video.BPP_32) {
+ copy_row_32(fb, dst_y, src_y);
+ } else if (fb.bpp == video.BPP_24) {
+ copy_row_24(fb, dst_y, src_y);
+ }
+}
+
+pub fn copy_row_32(fb: boot.FramebufferInfo, dst_y: u32, src_y: u32) void {
+ const pixels = ptr_32(fb.addr);
+ const ppr = pixels_per_row(fb);
+
+ var x: u32 = 0;
+ while (x < fb.width) : (x += 1) {
+ pixels[dst_y * ppr + x] = pixels[src_y * ppr + x];
+ }
+}
+
+pub fn copy_row_24(fb: boot.FramebufferInfo, dst_y: u32, src_y: u32) void {
+ const pixels = ptr_8(fb.addr);
+
+ var x: u32 = 0;
+ while (x < fb.width) : (x += 1) {
+ const src_off = offset_24(fb, x, src_y);
+ const dst_off = offset_24(fb, x, dst_y);
+ pixels[dst_off] = pixels[src_off];
+ pixels[dst_off + 1] = pixels[src_off + 1];
+ pixels[dst_off + 2] = pixels[src_off + 2];
+ }
+}
+
+pub fn clear_row(fb: boot.FramebufferInfo, y: u32, c: u32) void {
+ if (fb.bpp == video.BPP_32) {
+ clear_row_32(fb, y, c);
+ } else if (fb.bpp == video.BPP_24) {
+ clear_row_24(fb, y, c);
+ }
+}
+
+pub fn clear_row_32(fb: boot.FramebufferInfo, y: u32, c: u32) void {
+ const pixels = ptr_32(fb.addr);
+ const ppr = pixels_per_row(fb);
+
+ var x: u32 = 0;
+ while (x < fb.width) : (x += 1) {
+ pixels[y * ppr + x] = c;
+ }
+}
+
+pub fn clear_row_24(fb: boot.FramebufferInfo, y: u32, c: u32) void {
+ const pixels = ptr_8(fb.addr);
+ const rgb = color.extract(c);
+
+ var x: u32 = 0;
+ while (x < fb.width) : (x += 1) {
+ const off = offset_24(fb, x, y);
+ pixels[off] = rgb.b;
+ pixels[off + 1] = rgb.g;
+ pixels[off + 2] = rgb.r;
+ }
+}
+
+pub fn line_width(fb: boot.FramebufferInfo) u32 {
+ if (fb.bpp == video.BPP_32) {
+ return fb.pitch / video.BYTES_PER_PIXEL_32;
+ } else if (fb.bpp == video.BPP_24) {
+ return fb.pitch / video.BYTES_PER_PIXEL_24;
+ }
+ return fb.width;
+}