mirror of https://github.com/fairyglade/ly.git
				
				
				
			reimplements PSX Doom fire animation; adds flame height control
This commit is contained in:
		
							parent
							
								
									1bcbb08202
								
							
						
					
					
						commit
						ab23631e66
					
				|  | @ -104,13 +104,20 @@ colormix_col3 = 0x20000000 | |||
| # Available inputs: info_line, session, login, password | ||||
| default_input = login | ||||
| 
 | ||||
| # DOOM animation top color (low intensity flames) | ||||
| # DOOM animation fire height (1 thru 9) | ||||
| doom_fire_height = 6 | ||||
| 
 | ||||
| # DOOM animation use natural fire colors | ||||
| # If false, below custom colors used | ||||
| doom_default_colors = true | ||||
| 
 | ||||
| # DOOM animation custom top color (low intensity flames) | ||||
| doom_top_color = 0x00FF0000 | ||||
| 
 | ||||
| # DOOM animation middle color (medium intensity flames) | ||||
| # DOOM animation custom middle color (medium intensity flames) | ||||
| doom_middle_color = 0x00FFFF00 | ||||
| 
 | ||||
| # DOOM animation bottom color (high intensity flames) | ||||
| # DOOM animation custom bottom color (high intensity flames) | ||||
| doom_bottom_color = 0x00FFFFFF | ||||
| 
 | ||||
| # Error background color id | ||||
|  |  | |||
|  | @ -11,17 +11,31 @@ pub const STEPS = 12; | |||
| allocator: Allocator, | ||||
| terminal_buffer: *TerminalBuffer, | ||||
| buffer: []u8, | ||||
| height: u8, | ||||
| fire: [STEPS + 1]Cell, | ||||
| 
 | ||||
| pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, top_color: u32, middle_color: u32, bottom_color: u32) !Doom { | ||||
| pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, fire_height: u8, default_colors: bool, top_color: u32, middle_color: u32, bottom_color: u32) !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, | ||||
|         .fire = [_]Cell{ | ||||
|     const levels = if (default_colors) | ||||
|         [_]Cell{ | ||||
|             Cell.init(' ', TerminalBuffer.Color.DEFAULT, TerminalBuffer.Color.DEFAULT), | ||||
|             Cell.init(0x2591, 0x070707, TerminalBuffer.Color.DEFAULT), | ||||
|             Cell.init(0x2592, 0x470F07, TerminalBuffer.Color.DEFAULT), | ||||
|             Cell.init(0x2593, 0x771F07, TerminalBuffer.Color.DEFAULT), | ||||
|             Cell.init(0x2588, 0xAF3F07, TerminalBuffer.Color.DEFAULT), | ||||
|             Cell.init(0x2591, 0xC74707, 0xAF3F07), | ||||
|             Cell.init(0x2592, 0xDF5707, 0xAF3F07), | ||||
|             Cell.init(0x2593, 0xCF6F0F, 0xAF3F07), | ||||
|             Cell.init(0x2588, 0xC78F17, 0xAF3F07), | ||||
|             Cell.init(0x2591, 0xBF9F1F, 0xAF3F07), | ||||
|             Cell.init(0x2592, 0xBFAF2F, 0xAF3F07), | ||||
|             Cell.init(0x2593, 0xCFCF6F, 0xAF3F07), | ||||
|             Cell.init(0x2588, 0xFFFFFF, 0xAF3F07), | ||||
|         } | ||||
|     else | ||||
|         [_]Cell{ | ||||
|             Cell.init(' ', TerminalBuffer.Color.DEFAULT, TerminalBuffer.Color.DEFAULT), | ||||
|             Cell.init(0x2591, top_color, TerminalBuffer.Color.DEFAULT), | ||||
|             Cell.init(0x2592, top_color, TerminalBuffer.Color.DEFAULT), | ||||
|  | @ -35,7 +49,14 @@ pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, top_color: u | |||
|             Cell.init(0x2592, bottom_color, middle_color), | ||||
|             Cell.init(0x2593, bottom_color, middle_color), | ||||
|             Cell.init(0x2588, bottom_color, middle_color), | ||||
|         }, | ||||
|         }; | ||||
| 
 | ||||
|     return .{ | ||||
|         .allocator = allocator, | ||||
|         .terminal_buffer = terminal_buffer, | ||||
|         .buffer = buffer, | ||||
|         .height = @min(9, fire_height), | ||||
|         .fire = levels, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  | @ -57,20 +78,31 @@ fn draw(self: *Doom) void { | |||
|     for (0..self.terminal_buffer.width) |x| { | ||||
|         // We start from 1 so that we always have the topmost line when spreading fire | ||||
|         for (1..self.terminal_buffer.height) |y| { | ||||
|             // Get current cell | ||||
|             // Get index of current cell in fire level buffer | ||||
|             const from = y * self.terminal_buffer.width + x; | ||||
|             const cell_index = self.buffer[from]; | ||||
| 
 | ||||
|             // Spread fire | ||||
|             const propagate = self.terminal_buffer.random.int(u1); | ||||
|             const to = from - self.terminal_buffer.width; // Get the line above | ||||
|             // Generate random datum for fire propagation | ||||
|             const random = (self.terminal_buffer.random.int(u16) % 10); | ||||
| 
 | ||||
|             self.buffer[to] = if (cell_index > 0) cell_index - propagate else cell_index; | ||||
|             // Select semi-random target cell | ||||
|             const to = from -| self.terminal_buffer.width -| (random & 3) + 1; | ||||
| 
 | ||||
|             // Put the cell | ||||
|             const cell = self.fire[cell_index]; | ||||
|             cell.put(x, y); | ||||
|             // Get fire level of current cell | ||||
|             const level_buf_from = self.buffer[from]; | ||||
| 
 | ||||
|             // Choose new fire level and store in level buffer | ||||
|             var level_buf_to = level_buf_from; | ||||
|             if (random >= self.height) level_buf_to -|= 1; | ||||
|             self.buffer[to] = @intCast(level_buf_to); | ||||
| 
 | ||||
|             // Send fire level to terminal buffer | ||||
|             const to_cell = self.fire[level_buf_to]; | ||||
|             to_cell.put(x, y); | ||||
|         } | ||||
| 
 | ||||
|         // Draw bottom line (fire source) | ||||
|         const src_cell = self.fire[STEPS]; | ||||
|         src_cell.put(x, self.terminal_buffer.height - 1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,6 +29,8 @@ colormix_col1: u32 = 0x00FF0000, | |||
| colormix_col2: u32 = 0x000000FF, | ||||
| colormix_col3: u32 = 0x20000000, | ||||
| default_input: Input = .login, | ||||
| doom_fire_height: u8 = 6, | ||||
| doom_default_colors: bool = true, | ||||
| doom_top_color: u32 = 0x00FF0000, | ||||
| doom_middle_color: u32 = 0x00FFFF00, | ||||
| doom_bottom_color: u32 = 0x00FFFFFF, | ||||
|  |  | |||
|  | @ -354,7 +354,7 @@ pub fn main() !void { | |||
|             animation = dummy.animation(); | ||||
|         }, | ||||
|         .doom => { | ||||
|             var doom = try Doom.init(allocator, &buffer, config.doom_top_color, config.doom_middle_color, config.doom_bottom_color); | ||||
|             var doom = try Doom.init(allocator, &buffer, config.doom_fire_height, config.doom_default_colors, config.doom_top_color, config.doom_middle_color, config.doom_bottom_color); | ||||
|             animation = doom.animation(); | ||||
|         }, | ||||
|         .matrix => { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue