mirror of https://github.com/kiedtl/fire.git
Compare commits
29 Commits
Author | SHA1 | Date |
---|---|---|
Kiëd Llaentenn | 3b1b65ad2b | |
Kiëd Llaentenn | 6765bb8fc7 | |
Kiëd Llaentenn | fc0d0207aa | |
Kiëd Llaentenn | 92cee32160 | |
Kiëd Llaentenn | 37caaa70a3 | |
Kiëd Llaentenn | 12c84f877a | |
Kiëd Llaentenn | 1648d8143c | |
Kiëd Llaentenn | 38165e8071 | |
Kiëd Llaentenn | 85794e888f | |
Kiëd Llaentenn | 7a417130c9 | |
Kiëd Llaentenn | d3e4ed96d6 | |
Kiëd Llaentenn | 5adc07df8f | |
Kiëd Llaentenn | f0db1af7a5 | |
Kiëd Llaentenn | 6c076eb2a9 | |
Kiëd Llaentenn | da742e282d | |
Kiëd Llaentenn | d1ad444cd0 | |
Kiëd Llaentenn | 228292d9f9 | |
Kiëd Llaentenn | 0701008aea | |
Kiëd Llaentenn | f62a6ad48c | |
Kiëd Llaentenn | 818a160894 | |
Kiëd Llaentenn | aac9f704e9 | |
Mitch Weaver | 48f7ea3f3b | |
Mitch Weaver | 44d5ede804 | |
Mitch Weaver | bf6ce9452b | |
Kiëd Llaentenn | 861d806379 | |
Kied Llaentenn | 0f742ab9af | |
Kied Llaentenn | c460aaf4ac | |
Kiëd Llaentenn | 5cad8d0b3e | |
Kied Llaentenn | e38315c816 |
|
@ -1,6 +1,3 @@
|
|||
[submodule "sub/termbox_next"]
|
||||
path = sub/termbox_next
|
||||
url = https://github.com/cylgom/termbox_next
|
||||
[submodule "sub/ccommon"]
|
||||
path = sub/ccommon
|
||||
url = https://github.com/lptstr/ccommon
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
MIT License
|
||||
===========
|
||||
|
||||
- Copyright © 2018-2020 nullgemm
|
||||
- Copyright © 2019-2021 Kiëd Llaentenn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
(mis)use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
- The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
20
LICENSE.md
20
LICENSE.md
|
@ -1,20 +0,0 @@
|
|||
### MIT License
|
||||
|
||||
> Copyright 2019 Kied Llaentenn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to (mis)use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
- The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
**the software is provided "as is", without warranty of any kind, express or implied,
|
||||
including but not limited to the warranties of merchantability, fitness for a
|
||||
particular purpose and noninfringement. in no event shall the authors or copyright
|
||||
holders be liable for any claim, damages or other liability, whether in an action of
|
||||
contract, tort or otherwise, arising from, out of or in connection with the software
|
||||
or the use or other dealings in the software.**
|
33
README.md
33
README.md
|
@ -1,10 +1,12 @@
|
|||
![](https://github.com/lptstr/lptstr-images/blob/master/proj/fire/scrot.jpg?raw=true)
|
||||
|
||||
# fire
|
||||
|
||||
> The ancient DOOM fire animation in the terminal!
|
||||
|
||||
## what?
|
||||
`fire` is a remake of the PSX DOOM fire animation in the terminal,
|
||||
as seen in the [ly](https://github.com/cylgom/ly) display manager.
|
||||
as seen in the [ly](https://github.com/nullgemm/ly) display manager.
|
||||
It's described nicely by Fabien Sanglard on his
|
||||
[blog](https://fabiensanglard.net/doom_fire_psx/index.html).
|
||||
|
||||
|
@ -18,11 +20,12 @@ It's described nicely by Fabien Sanglard on his
|
|||
You will need:
|
||||
- `git`
|
||||
- a c99 compiler (gcc or clang)
|
||||
- GNU Make (unknown if other `make`s will work)
|
||||
- `gmake` (`bmake` is untested, but might work.)
|
||||
|
||||
Clone the source via `git`:
|
||||
Retrieve the source:
|
||||
```
|
||||
$ git --recurse clone https://github.com/lptstr/fire
|
||||
$ # via git:
|
||||
$ git clone https://github.com/lptstr/fire --recurse
|
||||
```
|
||||
|
||||
Build:
|
||||
|
@ -37,23 +40,29 @@ and install:
|
|||
|
||||
Uninstall, if you wish:
|
||||
```
|
||||
# rm -f /usr/bin/fire
|
||||
# make uninstall
|
||||
```
|
||||
|
||||
## how?
|
||||
simply run `./fire` (or `fire`, if you installed) and enjoy.
|
||||
```
|
||||
$ fire
|
||||
$ fire # no args for default animation
|
||||
$ fire -h # help message
|
||||
$ fire -Rw0 -f100 # matrix effect
|
||||
$ fire -l2 -w2 # small fire with wind blowing east
|
||||
$ fire -Rw0 -f1000000 # california animation
|
||||
$ fire -t -l2 -f3 # truecolor!
|
||||
```
|
||||
|
||||
### why?
|
||||
I'm bored
|
||||
|
||||
## credits
|
||||
- Thanks to @cylgom, for inspiring me to make this project.
|
||||
- More thanks to @cylgom, from whose repositories I sto^Hborrowed a lot
|
||||
of stuff :)
|
||||
This code was originally based on [`ly`](https://github.com/nullgemm/ly)'s
|
||||
animation code.
|
||||
|
||||
## license
|
||||
This project is licensed under the MIT license. View the LICENSE.md file
|
||||
for more information.
|
||||
This project is licensed under the MIT license. View the [COPYING](COPYING)
|
||||
file for more information.
|
||||
|
||||
## contributing
|
||||
Prepare to see some of the worst C code in your life.
|
||||
|
|
30
args.h
30
args.h
|
@ -2,13 +2,11 @@
|
|||
// Copy me if you can.
|
||||
// by 20h
|
||||
//
|
||||
// Copied by kiedtl
|
||||
// on 2019-12-11 1516
|
||||
//
|
||||
|
||||
// This file is was proudly stol^Hborrowed
|
||||
// from the st project and is copyright all
|
||||
// st contributors. View the LICENSE at:
|
||||
// This file was proudly stol^Hborrowed
|
||||
// from the st project.
|
||||
//
|
||||
// (c) all st contributors. View the LICENSE at:
|
||||
// https://git.suckless.org/st/file/LICENSE.html
|
||||
|
||||
|
||||
|
@ -16,13 +14,29 @@
|
|||
#define ARGS_INCLUDED
|
||||
#include "bool.h"
|
||||
#include "args.h"
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#include "sys/types.h"
|
||||
#else
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
extern char *argv0;
|
||||
|
||||
typedef struct Options {
|
||||
usize refresh_rate;
|
||||
size_t refresh_rate;
|
||||
size_t animation_speed;
|
||||
size_t heat_loss;
|
||||
size_t wind;
|
||||
size_t random_factor;
|
||||
bool random_wind;
|
||||
bool truecolor;
|
||||
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
bool farbfeld_mode;
|
||||
size_t ff_frame;
|
||||
} Options;
|
||||
|
||||
/* use main(int argc, char *argv[]) */
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
#ifndef COLORS_INCLUDED
|
||||
#define COLORS_INCLUDED
|
||||
|
||||
#include "colors.h"
|
||||
#include "termbox.h"
|
||||
|
||||
#define BLACK 0x000000
|
||||
|
||||
const struct tb_cell normcolors[13] = {
|
||||
// default
|
||||
{ ' ', 9, 0 },
|
||||
|
||||
// red/black
|
||||
{ 0x2591, 2, 0 },
|
||||
{ 0x2592, 2, 0 },
|
||||
{ 0x2593, 2, 0 },
|
||||
{ 0x2588, 2, 0 },
|
||||
|
||||
// yellow/red
|
||||
{ 0x2591, 4, 2 },
|
||||
{ 0x2592, 4, 2 },
|
||||
{ 0x2593, 4, 2 },
|
||||
{ 0x2588, 4, 2 },
|
||||
|
||||
// white/red
|
||||
{ 0x2591, 8, 2 },
|
||||
{ 0x2592, 8, 2 },
|
||||
{ 0x2593, 8, 2 },
|
||||
{ 0x2588, 8, 2 },
|
||||
};
|
||||
|
||||
const struct tb_cell truecolors[36] = {
|
||||
{ ' ', BLACK, 0x070707 },
|
||||
{ ' ', BLACK, 0x1F0707 },
|
||||
{ ' ', BLACK, 0x2F0F07 },
|
||||
{ ' ', BLACK, 0x470F07 },
|
||||
{ ' ', BLACK, 0x571707 },
|
||||
{ ' ', BLACK, 0x671F07 },
|
||||
{ ' ', BLACK, 0x771F07 },
|
||||
{ ' ', BLACK, 0x8F2707 },
|
||||
{ ' ', BLACK, 0x9F2F07 },
|
||||
{ ' ', BLACK, 0xAF3F07 },
|
||||
{ ' ', BLACK, 0xBF4707 },
|
||||
{ ' ', BLACK, 0xC74707 },
|
||||
{ ' ', BLACK, 0xDF4F07 },
|
||||
{ ' ', BLACK, 0xDF5707 },
|
||||
{ ' ', BLACK, 0xDF5707 },
|
||||
{ ' ', BLACK, 0xD75F07 },
|
||||
{ ' ', BLACK, 0xD7670F },
|
||||
{ ' ', BLACK, 0xCF6F0F },
|
||||
{ ' ', BLACK, 0xCF770F },
|
||||
{ ' ', BLACK, 0xCF7F0F },
|
||||
{ ' ', BLACK, 0xCF8717 },
|
||||
{ ' ', BLACK, 0xC78717 },
|
||||
{ ' ', BLACK, 0xC78F17 },
|
||||
{ ' ', BLACK, 0xC7971F },
|
||||
{ ' ', BLACK, 0xBF9F1F },
|
||||
{ ' ', BLACK, 0xBF9F1F },
|
||||
{ ' ', BLACK, 0xBFA727 },
|
||||
{ ' ', BLACK, 0xBFA727 },
|
||||
{ ' ', BLACK, 0xBFAF2F },
|
||||
{ ' ', BLACK, 0xB7AF2F },
|
||||
{ ' ', BLACK, 0xB7B737 },
|
||||
{ ' ', BLACK, 0xCFCF6F },
|
||||
{ ' ', BLACK, 0xDFDF9F },
|
||||
{ ' ', BLACK, 0xEFEFC7 },
|
||||
{ ' ', BLACK, 0xFFFFFF }
|
||||
};
|
||||
|
||||
#endif
|
56
colors.h
56
colors.h
|
@ -1,61 +1,9 @@
|
|||
#ifndef COLORS_INCLUDED
|
||||
#define COLORS_INCLUDED
|
||||
|
||||
#include "types.h"
|
||||
#include "termbox.h"
|
||||
#define CLRS_LEN 13
|
||||
|
||||
#define RED 0xdd1111
|
||||
#define BLACK 0x000000
|
||||
#define YELLOW 0xff7700
|
||||
#define WHITE 0xffffff
|
||||
|
||||
struct tb_cell normcolors[CLRS_LEN] =
|
||||
{
|
||||
// default
|
||||
{ ' ', 9, 0 },
|
||||
|
||||
// red/black
|
||||
{ 0x2591, 2, 0 },
|
||||
{ 0x2592, 2, 0 },
|
||||
{ 0x2593, 2, 0 },
|
||||
{ 0x2588, 2, 0 },
|
||||
|
||||
// yellow/red
|
||||
{ 0x2591, 4, 2 },
|
||||
{ 0x2592, 4, 2 },
|
||||
{ 0x2593, 4, 2 },
|
||||
{ 0x2588, 4, 2 },
|
||||
|
||||
// white/red
|
||||
{ 0x2591, 8, 2 },
|
||||
{ 0x2592, 8, 2 },
|
||||
{ 0x2593, 8, 2 },
|
||||
{ 0x2588, 8, 2 },
|
||||
};
|
||||
|
||||
struct tb_cell truecolors[CLRS_LEN] =
|
||||
{
|
||||
// default
|
||||
{ ' ', 9, 0 },
|
||||
|
||||
// red/black
|
||||
{ 0x2591, RED, BLACK },
|
||||
{ 0x2592, RED, BLACK },
|
||||
{ 0x2593, RED, BLACK },
|
||||
{ 0x2588, RED, BLACK },
|
||||
|
||||
// yellow/red
|
||||
{ 0x2591, YELLOW, RED },
|
||||
{ 0x2592, YELLOW, RED },
|
||||
{ 0x2593, YELLOW, RED },
|
||||
{ 0x2588, YELLOW, RED },
|
||||
|
||||
// white/red
|
||||
{ 0x2591, WHITE, RED },
|
||||
{ 0x2592, WHITE, RED },
|
||||
{ 0x2593, WHITE, RED },
|
||||
{ 0x2588, WHITE, RED },
|
||||
};
|
||||
extern struct tb_cell normcolors[13];
|
||||
extern struct tb_cell truecolors[36];
|
||||
|
||||
#endif
|
||||
|
|
100
draw.c
100
draw.c
|
@ -4,72 +4,105 @@
|
|||
|
||||
#include "args.h"
|
||||
#include "termbox.h"
|
||||
#include "types.h"
|
||||
#include "draw.h"
|
||||
#include "colors.h"
|
||||
#include "output.h"
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#include "sys/types.h"
|
||||
#else
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
#define MAX(VAL1, VAL2) ((VAL1) > (VAL2) ? (VAL1) : (VAL2))
|
||||
#define MIN(VAL1, VAL2) ((VAL1) < (VAL2) ? (VAL1) : (VAL2))
|
||||
|
||||
// arguments
|
||||
extern struct Options *opts;
|
||||
|
||||
// initialize the framebuffer
|
||||
void
|
||||
init ( struct buffer *buf )
|
||||
init(struct buffer *buf, uint16_t width, uint16_t height)
|
||||
{
|
||||
// initialize width/height of terminal
|
||||
buf->width = tb_width();
|
||||
buf->height = tb_height();
|
||||
buf->width = width;
|
||||
buf->height = height;
|
||||
|
||||
usize len = buf->width * buf->height;
|
||||
buf->buf = (u8*) malloc(len);
|
||||
size_t len = buf->width * buf->height;
|
||||
buf->buf = (uint8_t*) calloc(len, sizeof(uint8_t));
|
||||
len -= buf->width;
|
||||
|
||||
if (buf->buf == NULL) {
|
||||
PRINT("fire: cannot ");
|
||||
EPRINT("fire: cannot ");
|
||||
perror("calloc()");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// initialize the entire screen to black...
|
||||
memset(buf->buf, 0, len);
|
||||
|
||||
// calloc sets the entire screen to black
|
||||
// ...except for the last row, which is white.
|
||||
// this is the 'base' of the fire.
|
||||
memset(buf->buf + len, 12, buf->width);
|
||||
memset(buf->buf + len, opts->truecolor ? 34 : 12, buf->width);
|
||||
}
|
||||
|
||||
// update the framebuffer
|
||||
void
|
||||
dofire ( struct buffer *buf )
|
||||
dofire(struct buffer *buf)
|
||||
{
|
||||
usize src;
|
||||
usize random;
|
||||
usize dest;
|
||||
size_t src;
|
||||
size_t rnd_wind = (lrand48() % 7) & 3;
|
||||
size_t rnd_lose = lrand48() % 100;
|
||||
size_t rnd_loss = (lrand48() % 7) & 3;
|
||||
size_t dest;
|
||||
|
||||
struct tb_cell *realbuf = tb_cell_buffer();
|
||||
|
||||
for (usize x = 0; x < buf->width; ++x)
|
||||
{
|
||||
for (usize y = 1; y < buf->height; ++y)
|
||||
{
|
||||
for (size_t x = 0; x < buf->width; ++x) {
|
||||
for (size_t y = 1; y < buf->height; ++y) {
|
||||
// TODO; test rngs
|
||||
if ((lrand48() % opts->random_factor) == 0) {
|
||||
rnd_wind = (lrand48() % 7) & 3;
|
||||
rnd_lose = lrand48() % 100;
|
||||
rnd_loss = (lrand48() % 7) & 3;
|
||||
}
|
||||
|
||||
src = y * buf->width + x;
|
||||
random = (rand() % 7) & 3;
|
||||
dest = src - random + 1;
|
||||
|
||||
if (buf->width > dest)
|
||||
dest = 0;
|
||||
else
|
||||
dest -= buf->width;
|
||||
|
||||
buf->buf[dest] = buf->buf[src] - (random & 1);
|
||||
|
||||
if (buf->buf[dest] > 12)
|
||||
buf->buf[dest] = 0;
|
||||
if (opts->random_wind) {
|
||||
dest = src - rnd_wind + opts->wind;
|
||||
} else {
|
||||
dest = src + opts->wind;
|
||||
}
|
||||
|
||||
size_t max_value;
|
||||
struct tb_cell *colors;
|
||||
if (opts->truecolor == TRUE)
|
||||
if (opts->truecolor == TRUE) {
|
||||
colors = (struct tb_cell*) &truecolors;
|
||||
else colors = (struct tb_cell*) &normcolors;
|
||||
max_value = 35;
|
||||
} else {
|
||||
colors = (struct tb_cell*) &normcolors;
|
||||
max_value = 12;
|
||||
}
|
||||
|
||||
if (buf->width > dest) {
|
||||
dest = 0;
|
||||
} else {
|
||||
dest -= buf->width;
|
||||
}
|
||||
|
||||
size_t loss = rnd_lose < opts->heat_loss ? 2 : 0;
|
||||
buf->buf[dest] = MAX(buf->buf[src] - (rnd_loss & loss), 0);
|
||||
|
||||
if (buf->buf[dest] > max_value) {
|
||||
buf->buf[dest] = 0;
|
||||
}
|
||||
|
||||
// TODO: comment everything
|
||||
|
||||
// copy from our buffer to termbox's buffer
|
||||
// unless, of course, our buffer is bigger
|
||||
if (src >= tb_width() * tb_height()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
realbuf[dest] = colors[buf->buf[dest]];
|
||||
realbuf[src] = colors[buf->buf[src]];
|
||||
|
@ -80,8 +113,7 @@ dofire ( struct buffer *buf )
|
|||
|
||||
// free framebuffer and shutdown termbox
|
||||
void
|
||||
cleanup ( struct buffer *buf )
|
||||
cleanup(struct buffer *buf)
|
||||
{
|
||||
free(buf->buf);
|
||||
tb_shutdown();
|
||||
}
|
||||
|
|
23
draw.h
23
draw.h
|
@ -1,18 +1,21 @@
|
|||
#ifndef DRAW_INCLUDED
|
||||
#define DRAW_INCLUDED
|
||||
|
||||
#include "types.h"
|
||||
#ifdef __OpenBSD__
|
||||
#include "sys/types.h"
|
||||
#else
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
typedef struct buffer
|
||||
{
|
||||
usize width;
|
||||
usize height;
|
||||
struct buffer {
|
||||
size_t width;
|
||||
size_t height;
|
||||
|
||||
u8* buf;
|
||||
} buffer;
|
||||
uint8_t* buf;
|
||||
};
|
||||
|
||||
void init ( struct buffer *buf );
|
||||
void dofire ( struct buffer *buf );
|
||||
void cleanup ( struct buffer *buf );
|
||||
void init(struct buffer *buf, uint16_t width, uint16_t height);
|
||||
void dofire(struct buffer *buf);
|
||||
void cleanup(struct buffer *buf);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* winsock.h on windows,
|
||||
* arpa/inet.h on unix
|
||||
* for htons()
|
||||
*/
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "termbox.h"
|
||||
#include "bool.h"
|
||||
#include "ff.h"
|
||||
|
||||
static uint16_t
|
||||
clr(uint32_t clr)
|
||||
{
|
||||
uint16_t nclr = (((uint16_t) clr) & 0xff) & 0xffff;
|
||||
return nclr | (nclr << 8);
|
||||
}
|
||||
|
||||
void
|
||||
ff_from_tbscr(uint32_t width, uint32_t height, uint8_t *img, struct tb_cell *colors, FILE *fp)
|
||||
{
|
||||
/* write farbfeld headers */
|
||||
fputs("farbfeld", fp);
|
||||
uint32_t tmp;
|
||||
tmp = htonl(width);
|
||||
fwrite(&tmp, sizeof(tmp), 1, fp);
|
||||
tmp = htonl(height);
|
||||
fwrite(&tmp, sizeof(tmp), 1, fp);
|
||||
|
||||
/* write image row by row */
|
||||
uint16_t *rowbuf = malloc(width * (4 * sizeof(uint16_t)));
|
||||
|
||||
for (size_t y = 0; y < height; ++y) {
|
||||
for (size_t x = 0; x < width; ++x) {
|
||||
uint32_t color = colors[img[y * width + x]].bg;
|
||||
|
||||
rowbuf[4 * x + 0] = htons(clr(color >> 16));
|
||||
rowbuf[4 * x + 1] = htons(clr(color >> 8));
|
||||
rowbuf[4 * x + 2] = htons(clr(color));
|
||||
rowbuf[4 * x + 3] = htons((uint16_t) 0xffff);
|
||||
}
|
||||
|
||||
fwrite(rowbuf, sizeof(uint16_t), width * 4, fp);
|
||||
memset(rowbuf, 0, width * (4 * sizeof(uint16_t)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef FF_H
|
||||
#define FF_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "termbox.h"
|
||||
#include "bool.h"
|
||||
|
||||
void ff_from_tbscr(
|
||||
uint32_t width, uint32_t height,
|
||||
uint8_t *img, struct tb_cell *colors,
|
||||
FILE *fp
|
||||
);
|
||||
|
||||
#endif
|
172
main.c
172
main.c
|
@ -1,100 +1,198 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bool.h"
|
||||
#include "output.h"
|
||||
#include "draw.h"
|
||||
#include "types.h"
|
||||
#include "colors.h"
|
||||
#include "terminfo.h"
|
||||
#include "termbox.h"
|
||||
#include "args.h"
|
||||
#include "ff.h"
|
||||
|
||||
#define VERSION "0.2.0"
|
||||
#ifdef __OpenBSD__
|
||||
#include "sys/types.h"
|
||||
#else
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
#define VERSION "0.2.0"
|
||||
|
||||
// argument parsing (args.h)
|
||||
char *argv0;
|
||||
struct Options *opts;
|
||||
|
||||
int
|
||||
main ( int argc, char *argv[] )
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
opts = (struct Options*) calloc(1, sizeof(struct Options*));
|
||||
opts = (struct Options*) calloc(1, sizeof(struct Options));
|
||||
if (opts == NULL) {
|
||||
PRINT("fire: error: cannot ");
|
||||
perror("calloc()");
|
||||
perror("fire: error: calloc()");
|
||||
}
|
||||
|
||||
// default args
|
||||
opts->refresh_rate = 5;
|
||||
opts->truecolor = FALSE;
|
||||
usize output_mode = TB_OUTPUT_NORMAL;
|
||||
opts->animation_speed = 5;
|
||||
opts->refresh_rate = 1;
|
||||
size_t output_mode = TB_OUTPUT_NORMAL;
|
||||
opts->truecolor = FALSE;
|
||||
opts->heat_loss = 45;
|
||||
opts->wind = 1;
|
||||
opts->random_wind = TRUE;
|
||||
opts->random_factor = 4;
|
||||
opts->width = ttywidth();
|
||||
opts->height = ttyheight();
|
||||
|
||||
// argument parsing
|
||||
argv0 = argv[0];
|
||||
|
||||
ARGBEGIN {
|
||||
case 'F':
|
||||
opts->farbfeld_mode = TRUE;
|
||||
opts->ff_frame = atoi(ARGF());
|
||||
output_mode = TB_OUTPUT_TRUECOLOR;
|
||||
opts->truecolor = TRUE;
|
||||
break;
|
||||
case 'H':
|
||||
opts->height = atoi(ARGF());
|
||||
break;
|
||||
case 'W':
|
||||
opts->width = atoi(ARGF());
|
||||
break;
|
||||
case 't':
|
||||
output_mode = TB_OUTPUT_TRUECOLOR;
|
||||
opts->truecolor = TRUE;
|
||||
break;
|
||||
case 's':
|
||||
opts->animation_speed = atoi(ARGF());
|
||||
break;
|
||||
case 'r':
|
||||
opts->refresh_rate = atoi(ARGF());
|
||||
break;
|
||||
case 'l':
|
||||
opts->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;
|
||||
case 'v':
|
||||
case 'V':
|
||||
PRINT("%s %s\n", argv0, VERSION);
|
||||
exit(0);
|
||||
printf("%s %s\n", argv0, VERSION);
|
||||
return 0;
|
||||
case 'h':
|
||||
default:
|
||||
PRINT("fire %s\n(c) Kied Llaentenn and contributors\n", VERSION);
|
||||
PRINT("https://github.com/lptstr/fire\n");
|
||||
PRINT("\nUSAGE:\n\t$ fire\n\n");
|
||||
PRINT("OPTIONS:\n\t-t\tenable true colors.\n");
|
||||
PRINT("\t-V\tshow version and exit.\n");
|
||||
PRINT("\t-h\tshow this help message and exit.\n\n");
|
||||
exit(1);
|
||||
printf("Usage: %s [-RtVh] [-r rate] [-s speed] [-l loss] [-w wind] [-f fact]\n", argv0);
|
||||
printf("Display a nice fiery animation.\n\n");
|
||||
printf("ARGUMENTS:\n");
|
||||
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] Heat loss for each row upward. (default: 45)\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");
|
||||
printf(" %s 'Normal' fire.\n", argv0);
|
||||
printf(" %s -R -w0 -f100 Cmatrix-esque effect.\n", argv0);
|
||||
printf(" %s -l2 -w2 Small fire with wind blowing east.\n", argv0);
|
||||
printf(" %s -R -w0 -f1000000 Heatwaves!\n", argv0);
|
||||
printf(" %s -t -l2 -f3 Truecolor fire animation.\n\n", argv0);
|
||||
printf("(c) Kiëd Llaentenn, nullgemm\n");
|
||||
printf("https://github.com/lptstr/fire\n");
|
||||
|
||||
return 0;
|
||||
} ARGEND
|
||||
|
||||
// initialize termbox
|
||||
tb_init();
|
||||
tb_init(); /* check return value */
|
||||
tb_select_output_mode(output_mode);
|
||||
tb_clear();
|
||||
|
||||
struct buffer buf;
|
||||
struct tb_event e;
|
||||
|
||||
// initialize drawing
|
||||
init(&buf);
|
||||
init(&buf, opts->width, opts->height);
|
||||
|
||||
uint64_t ctr = 0;
|
||||
|
||||
// animate
|
||||
while (TRUE)
|
||||
{
|
||||
// clear the screen
|
||||
tb_clear();
|
||||
while (TRUE) {
|
||||
ctr += 1;
|
||||
|
||||
// update framebuffer
|
||||
dofire(&buf);
|
||||
|
||||
/* check if we should print the image now */
|
||||
if (opts->farbfeld_mode && ctr >= opts->ff_frame) {
|
||||
tb_shutdown(); /* shutdown so we can output the image to stdout */
|
||||
|
||||
if (isatty(STDOUT_FILENO)) {
|
||||
EPRINT("fire: cowardly refusing to write farbfeld image to the terminal.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ff_from_tbscr(opts->width, opts->height, buf.buf,
|
||||
(struct tb_cell*) &truecolors, stdout);
|
||||
|
||||
cleanup(&buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* don't display or check for events if not on refresh frame */
|
||||
if ((ctr % opts->refresh_rate) != 0 || opts->farbfeld_mode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// draw framebuffer to terminal
|
||||
tb_present();
|
||||
|
||||
// event handling
|
||||
int err = (usize) tb_peek_event(&e, opts->refresh_rate);
|
||||
int err = (size_t) tb_peek_event(&e, opts->animation_speed);
|
||||
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e.type == TB_EVENT_KEY)
|
||||
{
|
||||
switch (e.key)
|
||||
{
|
||||
case 0x03:
|
||||
cleanup(&buf);
|
||||
exit(0);
|
||||
default:
|
||||
break;
|
||||
// handle keypresses
|
||||
// q, ctrl+c, ctrl+d => quit
|
||||
/* TODO: handle resizes */
|
||||
if (e.type == TB_EVENT_KEY) {
|
||||
switch (e.ch) {
|
||||
case 'q':
|
||||
goto cleanup;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (e.key) {
|
||||
case TB_KEY_CTRL_C:
|
||||
case TB_KEY_CTRL_D:
|
||||
goto cleanup;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// perform cleanup
|
||||
cleanup:
|
||||
cleanup(&buf);
|
||||
|
||||
tb_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
21
makefile
21
makefile
|
@ -6,18 +6,21 @@
|
|||
|
||||
NAME = fire
|
||||
WARNING = -Wall -Wextra -pedantic -Wmissing-prototypes \
|
||||
-Wold-style-definition -Werror
|
||||
-Wold-style-definition
|
||||
|
||||
INC = -Isub/termbox_next/src -Isub/ccommon/
|
||||
INC = -Isub/termbox_next/src
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -std=c99 -O3 $(WARNING) $(INC)
|
||||
LDFLAGS =
|
||||
CFLAGS = -std=c99 -O0 -ggdb $(WARNING) $(INC) #-fsanitize=address
|
||||
LDFLAGS = -static
|
||||
|
||||
TRMBOX = sub/termbox_next/bin/termbox.a
|
||||
SRC = main.c draw.c
|
||||
SRC = main.c draw.c ff.c colors.c terminfo.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
DESTDIR = /
|
||||
PREFIX = /usr/local/
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
clean:
|
||||
|
@ -33,9 +36,13 @@ $(TRMBOX):
|
|||
|
||||
$(NAME): $(OBJ) $(TRMBOX)
|
||||
@echo "\tLD\t\t$(NAME)"
|
||||
@$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
@$(CC) -o $(NAME) $(OBJ) $(TRMBOX) $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
install: $(NAME)
|
||||
install -m755 ./$(NAME) /usr/bin/$(NAME)
|
||||
@echo "\tINSTALL\t\t$(NAME)\t$(DESTDIR)/$(PREFIX)/bin/$(NAME)"
|
||||
@install -m755 ./$(NAME) $(DESTDIR)/$(PREFIX)/bin/$(NAME)
|
||||
|
||||
uninstall:
|
||||
@echo "\tRM\t\t$(DESTDIR)/$(PREFIX)/bin/$(NAME)"
|
||||
@rm -f $(DESTDIR)/$(PREFIX)/bin/$(NAME)
|
||||
.PHONY: all clean install
|
||||
|
|
2
output.h
2
output.h
|
@ -2,6 +2,6 @@
|
|||
#define OUTP_H
|
||||
#include <stdio.h>
|
||||
|
||||
#define PRINT(...) fprintf(stderr, __VA_ARGS__);
|
||||
#define EPRINT(...) fprintf(stderr, __VA_ARGS__);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 4a52d5153f63b20691410debdaba619f7923e493
|
|
@ -1 +1 @@
|
|||
Subproject commit 2312da153e44face7bb45aa2798ec284289c17ca
|
||||
Subproject commit 7b85905531bf9e5908c67276dac55d3241361f20
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* terminfo.c: get TTY/console's buffer
|
||||
* height and width.
|
||||
*
|
||||
* TODO: test this on Windows 10.
|
||||
*
|
||||
* why is all Windows programming so
|
||||
* damn complicated.
|
||||
*
|
||||
* Thanks to this SO question for Windows stuff:
|
||||
* stackoverflow.com/questions/6812224/getting-terminal-size-in-c-for-windows
|
||||
*
|
||||
* (c) Kiëd Llaentenn and contributors
|
||||
* See the LICENSE.md file for copyright
|
||||
* information.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "terminfo.h"
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
#define WOE_IS_ME
|
||||
#endif
|
||||
|
||||
#ifdef WOE_IS_ME
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sizes to fall back to if:
|
||||
* 1) stdout isn't a tty
|
||||
* 2) if on Windows (temporary, only until win32
|
||||
* support it added
|
||||
*/
|
||||
const uint16_t fallback_width = 80;
|
||||
const uint16_t fallback_height = 24;
|
||||
|
||||
/* file descriptor to get dimensions of */
|
||||
#ifdef WOE_IS_ME
|
||||
CONST DWORD fd = STD_OUTPUT_HANDLE;
|
||||
#else
|
||||
const size_t fd = STDOUT_FILENO;
|
||||
#endif
|
||||
|
||||
uint16_t
|
||||
ttywidth(void)
|
||||
{
|
||||
#ifdef WOE_IS_ME
|
||||
/* why on earth does _isatty return NONZERO
|
||||
* if FD is a tty?! */
|
||||
if (_isatty(fd))
|
||||
return fallback_width;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
GetConsoleScreenBufferInfo(
|
||||
GetStdHandle(fd), &csbi
|
||||
);
|
||||
|
||||
return csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
||||
#else
|
||||
if (!isatty(fd))
|
||||
return fallback_width;
|
||||
|
||||
struct winsize w;
|
||||
ioctl(fd, TIOCGWINSZ, &w);
|
||||
return w.ws_col;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t
|
||||
ttyheight(void)
|
||||
{
|
||||
#ifdef WOE_IS_ME
|
||||
if (_isatty(fd))
|
||||
return fallback_height;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
GetConsoleScreenBufferInfo(
|
||||
GetStdHandle(fd), &csbi
|
||||
);
|
||||
|
||||
return csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
||||
#else
|
||||
if (!isatty(fd))
|
||||
return fallback_height;
|
||||
|
||||
struct winsize w;
|
||||
ioctl(fd, TIOCGWINSZ, &w);
|
||||
|
||||
return w.ws_row;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* terminfo.h: get TTY/console's buffer
|
||||
* height and width.
|
||||
*
|
||||
* (c) Kiëd Llaentenn and contributors
|
||||
* See the LICENSE.md file for copyright
|
||||
* information.
|
||||
*/
|
||||
|
||||
#ifndef TERMINFO_H
|
||||
#define TERMINFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint16_t ttywidth(void);
|
||||
uint16_t ttyheight(void);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue