mirror of https://github.com/fairyglade/ly.git
115 lines
3.6 KiB
Zig
115 lines
3.6 KiB
Zig
const std = @import("std");
|
|
const Allocator = std.mem.Allocator;
|
|
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
|
|
const utils = @import("../tui/utils.zig");
|
|
|
|
const interop = @import("../interop.zig");
|
|
const termbox = interop.termbox;
|
|
|
|
const Doom = @This();
|
|
|
|
pub const STEPS = 13;
|
|
pub const FIRE = [_]utils.Cell{
|
|
utils.initCell(' ', 9, 0),
|
|
utils.initCell(0x2591, 2, 0), // Red
|
|
utils.initCell(0x2592, 2, 0), // Red
|
|
utils.initCell(0x2593, 2, 0), // Red
|
|
utils.initCell(0x2588, 2, 0), // Red
|
|
utils.initCell(0x2591, 4, 2), // Yellow
|
|
utils.initCell(0x2592, 4, 2), // Yellow
|
|
utils.initCell(0x2593, 4, 2), // Yellow
|
|
utils.initCell(0x2588, 4, 2), // Yellow
|
|
utils.initCell(0x2591, 8, 4), // White
|
|
utils.initCell(0x2592, 8, 4), // White
|
|
utils.initCell(0x2593, 8, 4), // White
|
|
utils.initCell(0x2588, 8, 4), // White
|
|
};
|
|
|
|
allocator: Allocator,
|
|
terminal_buffer: *TerminalBuffer,
|
|
buffer: []u8,
|
|
|
|
pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer) !Doom {
|
|
const buffer = try allocator.alloc(u8, terminal_buffer.width * terminal_buffer.height);
|
|
initBuffer(buffer, terminal_buffer.width);
|
|
|
|
return .{
|
|
.allocator = allocator,
|
|
.terminal_buffer = terminal_buffer,
|
|
.buffer = buffer,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: Doom) void {
|
|
self.allocator.free(self.buffer);
|
|
}
|
|
|
|
pub fn realloc(self: *Doom) !void {
|
|
const buffer = try self.allocator.realloc(self.buffer, self.terminal_buffer.width * self.terminal_buffer.height);
|
|
initBuffer(buffer, self.terminal_buffer.width);
|
|
self.buffer = buffer;
|
|
}
|
|
|
|
pub fn draw_with_update(self: Doom) void {
|
|
for (0..self.terminal_buffer.width) |x| {
|
|
for (1..self.terminal_buffer.height) |y| {
|
|
// get source index
|
|
const source = y * self.terminal_buffer.width + x;
|
|
|
|
// random number between 0 and 3 inclusive
|
|
const random = (self.terminal_buffer.random.int(u16) % 7) & 3;
|
|
|
|
// adjust destination index based on random value
|
|
var dest = (source - @min(source, random)) + 1;
|
|
if (self.terminal_buffer.width > dest) dest = 0 else dest -= self.terminal_buffer.width;
|
|
|
|
// get source intensity and destination offset
|
|
const buffer_source = self.buffer[source];
|
|
const buffer_dest_offset = random & 1;
|
|
|
|
if (buffer_source < buffer_dest_offset) continue;
|
|
|
|
// calculate the destination intensity
|
|
var buffer_dest = buffer_source - buffer_dest_offset;
|
|
if (buffer_dest > 12) buffer_dest = 0;
|
|
self.buffer[dest] = @intCast(buffer_dest);
|
|
|
|
// update terminal
|
|
self.terminal_buffer.buffer[dest] = toTermboxCell(FIRE[buffer_dest]);
|
|
self.terminal_buffer.buffer[source] = toTermboxCell(FIRE[buffer_source]);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn draw(self: Doom) void {
|
|
for (0..self.terminal_buffer.width) |x| {
|
|
for (1..self.terminal_buffer.height) |y| {
|
|
// get source index
|
|
const source = y * self.terminal_buffer.width + x;
|
|
|
|
// get intensity from buffer
|
|
const buffer_source = self.buffer[source];
|
|
|
|
// set cell to correct fire char
|
|
self.terminal_buffer.buffer[source] = toTermboxCell(FIRE[buffer_source]);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn initBuffer(buffer: []u8, width: usize) void {
|
|
const length = buffer.len;
|
|
const slice_start = buffer[0..length];
|
|
const slice_end = buffer[length - width .. length];
|
|
|
|
@memset(slice_start, 0);
|
|
@memset(slice_end, STEPS - 1);
|
|
}
|
|
|
|
fn toTermboxCell(cell: utils.Cell) termbox.tb_cell {
|
|
return .{
|
|
.ch = cell.ch,
|
|
.fg = cell.fg,
|
|
.bg = cell.bg,
|
|
};
|
|
}
|