fire/main.c

157 lines
3.8 KiB
C
Raw Normal View History

2019-12-12 22:08:35 +00:00
#include <stdlib.h>
2019-12-12 23:46:24 +00:00
#include "bool.h"
2019-12-13 03:27:13 +00:00
#include "output.h"
#include "draw.h"
#include "termbox.h"
#include "args.h"
2019-12-13 02:18:56 +00:00
#ifdef __OpenBSD__
#include "sys/types.h"
#else
2020-09-17 11:42:48 +00:00
#include "stdint.h"
#endif
2020-09-17 11:42:48 +00:00
#define VERSION "0.2.0"
2019-12-13 03:39:35 +00:00
2019-12-13 03:27:13 +00:00
// argument parsing (args.h)
char *argv0;
struct Options *opts;
2019-12-12 22:08:35 +00:00
int
main(int argc, char *argv[])
2019-12-12 22:08:35 +00:00
{
opts = (struct Options*) calloc(1, sizeof(struct Options));
2019-12-13 21:15:29 +00:00
if (opts == NULL) {
2020-09-17 12:04:12 +00:00
perror("fire: error: calloc()");
2019-12-13 21:15:29 +00:00
}
// default args
2020-09-17 18:34:19 +00:00
opts->animation_speed = 5;
opts->refresh_rate = 1;
size_t output_mode = TB_OUTPUT_NORMAL;
opts->truecolor = FALSE;
opts->max_heat_loss = 1;
opts->wind = 1;
opts->random_wind = TRUE;
opts->random_factor = 4;
2019-12-13 21:15:29 +00:00
2019-12-13 03:39:35 +00:00
// argument parsing
argv0 = argv[0];
ARGBEGIN {
2019-12-13 21:15:29 +00:00
case 't':
2019-12-13 21:35:13 +00:00
output_mode = TB_OUTPUT_TRUECOLOR;
2019-12-13 21:15:29 +00:00
opts->truecolor = TRUE;
break;
2020-09-17 18:34:19 +00:00
case 's':
opts->animation_speed = atoi(ARGF());
break;
2019-12-13 21:15:29 +00:00
case 'r':
opts->refresh_rate = atoi(ARGF());
break;
case 'l':
opts->max_heat_loss = atoi(ARGF());
break;
case 'w':
opts->wind = atoi(ARGF());
break;
case 'R':
opts->random_wind = FALSE;
break;
case 'f':
opts->random_factor = atoi(ARGF());
break;
2019-12-13 03:39:35 +00:00
case 'V':
2020-09-17 11:54:08 +00:00
printf("%s %s\n", argv0, VERSION);
2020-09-17 12:04:12 +00:00
return 0;
2019-12-13 03:39:35 +00:00
case 'h':
default:
2020-09-17 18:34:19 +00:00
printf("Usage: %s [-RtVh] [-r rate] [-s speed] [-l loss] [-w wind] [-f fact]\n", argv0);
2020-09-17 11:54:08 +00:00
printf("Display a nice fiery animation.\n\n");
printf("ARGUMENTS:\n");
2020-09-17 18:34:19 +00:00
printf(" -r [rate] Change refresh rate. (default: 1)\n");
printf(" Higher values == slower refresh rate.\n");
printf(" -s [speed] Change animation speed. (default: 5)\n");
printf(" Higher values == slower animation.\n");
printf(" -l [loss] Maximum heat loss for each row upward. (default: 1)\n");
printf(" Higher values will lead to a smaller fire.\n");
printf(" -w [wind] Wind. Negative values, or values less than one will\n");
printf(" cause the fire to be blown west. (default: 1)\n");
printf(" To disable wind, set this value to 0 and use the -R flag.\n");
printf(" -f [fact] Set the chance of the random value being refreshed\n");
printf(" for each tile in the fire animation. (default: 4)\n");
printf(" High values will cause a matrix-like effect.\n");
printf(" -R Disable random wind factor.\n");
printf(" -t Enable truecolor. (Will not work on *rxvt)\n");
printf(" -h Display this help message and exit.\n");
printf(" -V Display version and exit.\n\n");
printf("EXAMPLES:\n");
2020-09-17 18:34:19 +00:00
printf(" %s 'Normal' fire.\n", argv0);
printf(" %s -Rw0 -f100 Cmatrix-esque effect.\n", argv0);
printf(" %s -l2 -w2 Small fire with wind blowing east.\n", argv0);
printf(" %s -Rw0 -f10000000 Heatwaves!\n", argv0);
2020-09-17 11:54:08 +00:00
printf("(c) Kiëd Llaentenn, nullgemm\n");
printf("https://github.com/lptstr/fire\n");
2020-09-17 12:04:12 +00:00
return 0;
2019-12-13 03:39:35 +00:00
} ARGEND
2019-12-12 23:46:24 +00:00
// initialize termbox
tb_init();
2019-12-13 21:35:13 +00:00
tb_select_output_mode(output_mode);
2019-12-12 23:46:24 +00:00
tb_clear();
2019-12-13 03:27:13 +00:00
struct buffer buf;
2019-12-13 04:03:58 +00:00
struct tb_event e;
2019-12-12 23:46:24 +00:00
2019-12-13 02:18:56 +00:00
// initialize drawing
init(&buf);
2019-12-12 22:08:35 +00:00
2020-09-17 18:34:19 +00:00
uint64_t ctr = 0;
2019-12-13 02:18:56 +00:00
// animate
2020-09-17 12:04:12 +00:00
while (TRUE) {
2020-09-17 18:34:19 +00:00
ctr += 1;
2019-12-13 03:27:13 +00:00
// update framebuffer
2019-12-13 02:18:56 +00:00
dofire(&buf);
2019-12-13 03:27:13 +00:00
2020-09-17 18:34:19 +00:00
if ((ctr % opts->refresh_rate) != 0) {
continue;
}
2019-12-13 03:27:13 +00:00
// draw framebuffer to terminal
2019-12-13 02:18:56 +00:00
tb_present();
2019-12-12 23:46:24 +00:00
2019-12-13 04:03:58 +00:00
// event handling
2020-09-17 18:34:19 +00:00
int err = (size_t) tb_peek_event(&e, opts->animation_speed);
2019-12-13 04:03:58 +00:00
2020-09-17 12:04:12 +00:00
if (err < 0) {
2019-12-13 04:03:58 +00:00
continue;
2020-09-17 12:04:12 +00:00
}
2019-12-13 04:03:58 +00:00
2020-09-17 12:04:12 +00:00
// handle keypresses
// q, ctrl+c, ctrl+d => quit
if (e.type == TB_EVENT_KEY) {
2020-09-17 11:58:22 +00:00
switch (e.ch) {
case 'q':
goto cleanup;
default:
break;
}
2020-09-17 12:04:12 +00:00
switch (e.key) {
case TB_KEY_CTRL_C:
case TB_KEY_CTRL_D:
goto cleanup;
default:
break;
2019-12-13 04:03:58 +00:00
}
}
}
2019-12-13 03:27:13 +00:00
2020-09-17 11:58:22 +00:00
cleanup:
2019-12-13 04:03:58 +00:00
cleanup(&buf);
2019-12-12 22:08:35 +00:00
return 0;
}