├── .gitignore ├── Makefile ├── README.md ├── doc └── termboy_screen.3 ├── misc ├── demo.py ├── run_demo ├── screenshot.png └── termboy.py ├── out └── .gitignore └── src ├── animation.c ├── common.h ├── demo.c ├── keyboard.c ├── misc.c ├── pixmaps ├── all.h ├── headerify ├── link_stand_left.h ├── link_stand_right.h ├── link_walk_left.h ├── link_walk_right.h ├── mountains.h ├── trees.h ├── waves0.h ├── waves1.h ├── waves2.h └── waves3.h ├── screen.c ├── sprite.c └── termboy.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | tags 3 | __pycache__ 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = clang 2 | OUT_DIR = out 3 | SRC_DIR = src 4 | LDFLAGS = -L$(OUT_DIR) 5 | LDLIBS = -lpthread -ltermboy 6 | CFLAGS = -I$(SRC_DIR) -fPIC -g -O -Wall -ansi -pedantic 7 | _OBJECTS = keyboard screen sprite animation misc 8 | 9 | OBJECTS = $(patsubst %,$(OUT_DIR)/%.o,$(_OBJECTS)) 10 | LIBTERMBOY = $(OUT_DIR)/libtermboy.so 11 | DEMO = $(OUT_DIR)/demo 12 | 13 | $(DEMO): $(SRC_DIR)/demo.c $(SRC_DIR)/pixmaps/*.h $(LIBTERMBOY) 14 | $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $< -o $@ 15 | 16 | $(LIBTERMBOY): $(OBJECTS) 17 | $(CC) -shared $^ -o $@ 18 | 19 | $(OUT_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/*.h 20 | $(CC) $(CFLAGS) -c $< -o $@ 21 | 22 | tags: $(SRC_DIR)/* 23 | ctags $^ 24 | 25 | .PHONY: run 26 | run: $(DEMO) 27 | LD_LIBRARY_PATH=$(OUT_DIR) $(DEMO) 28 | 29 | .PHONY: debug 30 | debug: $(DEMO) 31 | LD_LIBRARY_PATH=$(OUT_DIR) gdb $(DEMO) 32 | 33 | .PHONY: clean 34 | clean: 35 | rm -f out/* 36 | rm -f tags 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libtermboy 2 | ========== 3 | 4 | **libtermboy** is a graphics library for the Linux console. No, it's not an ASCII art library like [aalib](http://aa-project.sourceforge.net/aalib/) or [libcaca](http://caca.zoy.org/wiki/libcaca). With libtermboy, you can draw pixel-perfect images in a text mode terminal. 5 | 6 | To see the magic in action, clone the repository and execute `make run`. Use ←/→ to move and press ESC to quit. If your sound is on, press A-G for an extra surprise! 7 | 8 | The documentation for the most useful functions can be viewed by running `man doc/termboy_screen.3` (or just look at the source, it's not that long...). 9 | 10 | ![Screenshot](misc/screenshot.png) 11 | -------------------------------------------------------------------------------- /doc/termboy_screen.3: -------------------------------------------------------------------------------- 1 | .Dd October 11, 2014 2 | .Dt TERMBOY_SCREEN \&3 "Linux Programmer's Manual" 3 | .Os Linux 4 | .Sh NAME 5 | .Nm termboy_screen 6 | .Nd graphics routines for text mode consoles 7 | .Sh SYNOPSIS 8 | .In termboy.h 9 | .Fn "int tb_screen_init" "int pixel_size" 10 | .Fn "void tb_screen_size" "int *width" "int *height" 11 | .Fn "void tb_screen_color" "enum tb_color color" "int value" 12 | .Fn "int tb_screen_put" "int x" "int y" "enum tb_color color" 13 | .Fn "int tb_screen_flush" "void" 14 | .Fn "int tb_screen_restore" "void" 15 | .Sh DESCRIPTION 16 | Before drawing anything to the screen, 17 | .Fn tb_screen_init 18 | must be called to initialize the display. It accepts a single argument, 19 | .Fa pixel_size , 20 | which specifies the height and width of the displayed pixels (measured in 21 | physical pixels). Valid values range between 1 and 8. 22 | .Pp 23 | .Fn tb_screen_size 24 | stores the current screen dimensions in the integers pointed to by 25 | .Fa width 26 | and 27 | .Fa height . 28 | If the screen has not yet been initialized, both dimensions will be set to 29 | zero. 30 | .Pp 31 | The Linux console is capable of displaying sixteen distinct colors, which can 32 | be customized by calling 33 | .Fn tb_screen_color . 34 | The 35 | .Fa color 36 | argument refers to one of the sixteen colors to be redefined, such as 37 | .Dv TB_COLOR_RED . 38 | Its color content will be set according to the 24-bit RGB 39 | .Fa value . 40 | .Pp 41 | To draw a pixel on the screen, call 42 | .Fn tb_screen_put 43 | with the desired coordinates and color of the pixel. 44 | .Fa x 45 | and 46 | .Fa y 47 | specify the location of the pixel relative to the top-left corner of the 48 | screen. 49 | .Pp 50 | For performance reasons, draws to the screen are buffered. As a result, 51 | newly drawn pixels will not necessarily be immediately visible. Calling 52 | .Fn tb_screen_flush 53 | will force the screen to be updated. 54 | .Pp 55 | All programs should be sure to call 56 | .Fn tb_screen_restore 57 | before exiting. If a program happens to crash before it has a chance to 58 | restore the screen, the 59 | .Xr setfont 8 60 | command can be run from a "blind" state to make the tty usable again. 61 | .Sh RETURN VALUE 62 | On success, these functions return zero. Functions with a 63 | .Ft void 64 | return type will always succeed. 65 | -------------------------------------------------------------------------------- /misc/demo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import time 4 | import termboy 5 | 6 | with termboy.Screen() as screen: 7 | c = 0 8 | for x in range(screen.size()[0]): 9 | for y in range(screen.size()[1]): 10 | screen[x, y] = c 11 | c = (c+1) % 16 12 | input() 13 | -------------------------------------------------------------------------------- /misc/run_demo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | 3 | LD_LIBRARY_PATH=../out python demo.py 4 | -------------------------------------------------------------------------------- /misc/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dobyrch/libtermboy/353204028281d82b9e4a7a063363ec311ea40a87/misc/screenshot.png -------------------------------------------------------------------------------- /misc/termboy.py: -------------------------------------------------------------------------------- 1 | #TODO: see faulthandler module 2 | from ctypes import byref, c_int, c_void_p, CDLL, CFUNCTYPE 3 | from enum import Enum, IntEnum 4 | from functools import partial 5 | 6 | clib = CDLL('libtermboy.so') 7 | 8 | 9 | class Color(IntEnum): 10 | Black = 0; Red = 1; Green = 2 11 | Yellow = 3; Blue = 4; Magenta = 5 12 | Cyan = 6; White = 7; Bold = 8 13 | 14 | 15 | class Screen(): 16 | def __init__(self, pixelsize=4): 17 | clib.tb_screen_init(pixelsize) 18 | 19 | def __enter__(self): 20 | return self 21 | 22 | def __exit__(self, exc_type, exc_val, exc_tb): 23 | clib.tb_screen_restore() 24 | 25 | def __getitem__(self, position): 26 | raise NotImplementedError 27 | 28 | def __setitem__(self, position, color): 29 | x, y = position 30 | # TODO: index check, type check 31 | clib.tb_screen_put(x, y, color) 32 | 33 | def size(self): 34 | width = c_int() 35 | height = c_int() 36 | clib.tb_screen_size(byref(width), byref(height)) 37 | return width.value, height.value 38 | 39 | 40 | class Event(Enum): 41 | Press = 0 42 | Release = 1 43 | Hold = 2 44 | 45 | 46 | class Keyboard(): 47 | callbacks = [] 48 | 49 | def __init__(self): 50 | clib.tb_key_listen(1) 51 | 52 | def __enter__(self): 53 | return self 54 | 55 | def __exit__(self, exc_type, exc_val, exc_tb): 56 | clib.tb_key_restore() 57 | 58 | def register(self, key, handler, *args, **kwargs): 59 | @CFUNCTYPE(c_void_p, c_void_p) 60 | def callback(dummy): 61 | handler(*args, **kwargs) 62 | self.callbacks.append(callback) 63 | clib.tb_key_handle_press(key, callback, None) 64 | -------------------------------------------------------------------------------- /out/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /src/animation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "common.h" 3 | #include "termboy.h" 4 | 5 | static void *animate(void *arg); 6 | 7 | /* 8 | TODO: Add destructor 9 | */ 10 | int tb_anim_init(struct tb_anim *anim, struct tb_sprite *sprite, int frames) 11 | { 12 | anim->sprite = sprite; 13 | anim->frames = frames; 14 | anim->_frames = 0; 15 | anim->delays = calloc(frames, sizeof(int)); 16 | anim->data = calloc(frames, sizeof(enum tb_color *)); 17 | 18 | return 0; 19 | } 20 | 21 | void tb_anim_del(struct tb_anim *anim) 22 | { 23 | free(anim->delays); 24 | free(anim->data); 25 | } 26 | 27 | int tb_anim_add_frame(struct tb_anim *anim, enum tb_color *colors, int delay_ms) 28 | { 29 | if (anim->_frames == anim->frames) 30 | return -1; 31 | 32 | anim->delays[anim->_frames] = delay_ms; 33 | anim->data[anim->_frames] = colors; 34 | ++anim->_frames; 35 | 36 | return 0; 37 | } 38 | 39 | int tb_anim_start(struct tb_anim *anim) 40 | { 41 | pthread_create(&anim->_thread, NULL, animate, anim); 42 | pthread_detach(anim->_thread); 43 | 44 | return 0; 45 | } 46 | 47 | int tb_anim_stop(struct tb_anim *anim) 48 | { 49 | struct tb_sprite sprite = *anim->sprite; 50 | enum tb_color *colors = anim->data[anim->_frames - 1]; 51 | 52 | pthread_cancel(anim->_thread); 53 | TB_SPRITE_FILL(sprite, colors); 54 | tb_sprite_redraw(&sprite); 55 | 56 | return 0; 57 | } 58 | 59 | static void *animate(void *arg) 60 | { 61 | struct tb_anim *anim = arg; 62 | struct tb_sprite sprite = *anim->sprite; 63 | enum tb_color *colors; 64 | int i; 65 | 66 | i = 0; 67 | while (1) { 68 | colors = anim->data[i]; 69 | /* TODO: Assign pointer instead of copying? */ 70 | TB_SPRITE_FILL(sprite, colors); 71 | tb_sprite_redraw(&sprite); 72 | 73 | tb_msleep(anim->delays[i]); 74 | i = (i + 1) % anim->_frames; 75 | } 76 | 77 | return NULL; 78 | } 79 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define FAILIF(retval) do { \ 4 | if ((retval) == -1) \ 5 | return -1; \ 6 | } while (0) 7 | -------------------------------------------------------------------------------- /src/demo.c: -------------------------------------------------------------------------------- 1 | #define _POSIX_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "pixmaps/all.h" 9 | 10 | void *start_walking(void *arg); 11 | void *keep_walking(void *arg); 12 | void *stop_walking(void *arg); 13 | void *start_playing(void *arg); 14 | void *stop_playing(void *arg); 15 | void handler(int sig); 16 | 17 | static struct tb_sprite player, mountains, trees, waves, fill0, fill1, fill2; 18 | static struct tb_anim walk_right, walk_left, waves_anim; 19 | 20 | int main(void) 21 | { 22 | int y, width, height, left = -1, right = 1; 23 | 24 | /* 25 | * It's a good idea to handle fatal signals so we have a chance 26 | * to clean up the screen if something goes wrong. 27 | */ 28 | signal(SIGABRT, handler); 29 | signal(SIGSEGV, handler); 30 | 31 | /* 32 | * tb_screen_init must be called before attempting to draw 33 | * anything. It accepts a value (between 1 and 8) indicating 34 | * how large the pixels should appear. 35 | */ 36 | if (tb_screen_init(4) != 0) { 37 | printf("This libtermboy demo must be run in a Linux " 38 | "virtual console.\n(Try pressing CTRL+ALT+F2)\n"); 39 | exit(EXIT_FAILURE); 40 | } 41 | 42 | /* Retrieve the current screen dimensions */ 43 | tb_screen_size(&width, &height); 44 | 45 | /* 46 | * Colors values can be redefined to whatever we want. 47 | * Sixteen colors are available. 48 | */ 49 | tb_screen_color(0, 0x000000); 50 | tb_screen_color(1, 0x04262E); 51 | tb_screen_color(2, 0x316034); 52 | tb_screen_color(3, 0x6A75C0); 53 | tb_screen_color(4, 0x452112); 54 | tb_screen_color(5, 0x625727); 55 | tb_screen_color(6, 0xE0A962); 56 | tb_screen_color(7, 0xFFF2BF); 57 | tb_screen_color(8, 0xD59470); 58 | tb_screen_color(9, 0x9A5A77); 59 | tb_screen_color(10, 0xFFFFFF); 60 | tb_screen_color(11, 0xF7C0B1); 61 | tb_screen_color(12, 0X1F7531); 62 | 63 | /* Initialize a new sprite with the specified dimensions */ 64 | tb_sprite_init(&fill0, 1, 1); 65 | 66 | /* 67 | * TB_SPRITE_COLOR can get or set a sprite's color at a 68 | * particular position. Note that, unlike tb_sprite_init, it 69 | * does *not* accept a pointer argument (because it is 70 | * implemented as a macro) 71 | */ 72 | TB_SPRITE_COLOR(fill0, 0, 0) = 3; 73 | 74 | /* 75 | * Sprites can be tiled horizontally, vertically, or both; 76 | * the pattern will be repeated across the entire screen. 77 | */ 78 | fill0.tile = TB_TILE_HORIZONTAL | TB_TILE_VERTICAL; 79 | 80 | tb_sprite_init(&mountains, 64, 7); 81 | /* Copy sprite data from an array of colors */ 82 | TB_SPRITE_FILL(mountains, MOUNTAINS); 83 | mountains.tile = TB_TILE_HORIZONTAL; 84 | mountains.y = 20; 85 | 86 | tb_sprite_init(&fill1, 1, 25); 87 | for (y = 0; y < 25; ++y) 88 | TB_SPRITE_COLOR(fill1, 0, y) = 1; 89 | fill1.tile = TB_TILE_HORIZONTAL; 90 | /* The position of a sprite can be adjusted by setting x or y */ 91 | fill1.y = 27; 92 | 93 | tb_sprite_init(&trees, 64, 26); 94 | TB_SPRITE_FILL(trees, TREES); 95 | trees.tile = TB_TILE_HORIZONTAL; 96 | trees.y = 52; 97 | 98 | tb_sprite_init(&fill2, 1, 25); 99 | for (y = 0; y < 25; ++y) 100 | TB_SPRITE_COLOR(fill2, 0, y) = 7; 101 | fill2.tile = TB_TILE_HORIZONTAL; 102 | fill2.y = 78; 103 | 104 | tb_sprite_init(&waves, 64, 31); 105 | TB_SPRITE_FILL(waves, WAVES0); 106 | waves.y = 103; 107 | waves.tile = TB_TILE_HORIZONTAL; 108 | 109 | tb_sprite_init(&player, 14, 16); 110 | TB_SPRITE_FILL(player, LINK_STAND_RIGHT); 111 | player.x = width/2 - 7; 112 | player.y = 80; 113 | /* Sprites on higher layers are drawn on top of lower layers */ 114 | player.layer = 1; 115 | 116 | /* Make all of our sprites visible */ 117 | tb_sprite_show(&fill0); 118 | tb_sprite_show(&mountains); 119 | tb_sprite_show(&fill1); 120 | tb_sprite_show(&trees); 121 | tb_sprite_show(&fill2); 122 | tb_sprite_show(&waves); 123 | tb_sprite_show(&player); 124 | 125 | /* 126 | * Initialize a new animation for the specified sprite 127 | * with the given number of frames 128 | */ 129 | tb_anim_init(&walk_right, &player, 2); 130 | 131 | /* Add a new frame to be shown for 150 milliseconds */ 132 | tb_anim_add_frame(&walk_right, LINK_WALK_RIGHT, 150); 133 | tb_anim_add_frame(&walk_right, LINK_STAND_RIGHT, 150); 134 | 135 | tb_anim_init(&walk_left, &player, 2); 136 | tb_anim_add_frame(&walk_left, LINK_WALK_LEFT, 150); 137 | tb_anim_add_frame(&walk_left, LINK_STAND_LEFT, 150); 138 | 139 | tb_anim_init(&waves_anim, &waves, 6); 140 | tb_anim_add_frame(&waves_anim, WAVES0, 600); 141 | tb_anim_add_frame(&waves_anim, WAVES1, 200); 142 | tb_anim_add_frame(&waves_anim, WAVES2, 200); 143 | tb_anim_add_frame(&waves_anim, WAVES3, 600); 144 | tb_anim_add_frame(&waves_anim, WAVES2, 200); 145 | tb_anim_add_frame(&waves_anim, WAVES1, 200); 146 | tb_anim_start(&waves_anim); 147 | 148 | /* 149 | * Register functions to be called (on separate threads) when 150 | * certain key events occur. Keys are defined in linux/input.h. 151 | */ 152 | tb_key_handle(KEY_RIGHT, start_walking, keep_walking, stop_walking, &right); 153 | tb_key_handle(KEY_LEFT, start_walking, keep_walking, stop_walking, &left); 154 | tb_key_handle(KEY_A, start_playing, NULL, stop_playing, "A"); 155 | tb_key_handle(KEY_B, start_playing, NULL, stop_playing, "B"); 156 | tb_key_handle(KEY_C, start_playing, NULL, stop_playing, "C"); 157 | tb_key_handle(KEY_D, start_playing, NULL, stop_playing, "D"); 158 | tb_key_handle(KEY_E, start_playing, NULL, stop_playing, "E"); 159 | tb_key_handle(KEY_F, start_playing, NULL, stop_playing, "F"); 160 | tb_key_handle(KEY_G, start_playing, NULL, stop_playing, "G"); 161 | 162 | /* 163 | * Begin listening for key events. This call will block until 164 | * the user presses the escape key. TB_LISTEN_NONBLOCKING can 165 | * be used instead if you wish to use your own event loop. 166 | */ 167 | tb_key_listen(TB_LISTEN_BLOCKING); 168 | 169 | /* Make sure to restore the screen before exiting the program */ 170 | tb_screen_restore(); 171 | 172 | /* Free all of the memory allocated for our "objects" */ 173 | tb_sprite_del(&player); 174 | tb_sprite_del(&mountains); 175 | tb_sprite_del(&trees); 176 | tb_sprite_del(&waves); 177 | tb_sprite_del(&fill0); 178 | tb_sprite_del(&fill1); 179 | tb_sprite_del(&fill2); 180 | tb_anim_del(&walk_right); 181 | tb_anim_del(&walk_left); 182 | tb_anim_del(&waves_anim); 183 | 184 | return EXIT_SUCCESS; 185 | } 186 | 187 | void *start_walking(void *arg) 188 | { 189 | int dir = *(int *)arg; 190 | 191 | if (dir == 1) 192 | tb_anim_start(&walk_right); 193 | else 194 | tb_anim_start(&walk_left); 195 | 196 | return NULL; 197 | } 198 | 199 | void *keep_walking(void *arg) 200 | { 201 | int dir = *(int *)arg; 202 | 203 | tb_sprite_move(&waves, waves.x - 3*dir, waves.y); 204 | tb_sprite_move(&trees, trees.x - 2*dir, trees.y); 205 | tb_sprite_move(&mountains, mountains.x - 1*dir, mountains.y); 206 | tb_msleep(30); 207 | 208 | return NULL; 209 | } 210 | 211 | void *stop_walking(void *arg) 212 | { 213 | int dir = *(int *)arg; 214 | 215 | if (dir == 1) 216 | tb_anim_stop(&walk_right); 217 | else 218 | tb_anim_stop(&walk_left); 219 | 220 | return NULL; 221 | } 222 | 223 | void *start_playing(void *arg) 224 | { 225 | char note = *(char *)arg; 226 | int frequency; 227 | 228 | switch (note) { 229 | default: 230 | case 'A': 231 | frequency = 440; 232 | break; 233 | case 'B': 234 | frequency = 494; 235 | break; 236 | case 'C': 237 | frequency = 262; 238 | break; 239 | case 'D': 240 | frequency = 294; 241 | break; 242 | case 'E': 243 | frequency = 330; 244 | break; 245 | case 'F': 246 | frequency = 349; 247 | break; 248 | case 'G': 249 | frequency = 392; 250 | break; 251 | } 252 | tb_tone_start(frequency); 253 | 254 | return NULL; 255 | } 256 | 257 | void *stop_playing(void *arg) 258 | { 259 | tb_tone_stop(); 260 | 261 | return NULL; 262 | } 263 | 264 | void handler(int sig) 265 | { 266 | tb_screen_restore(); 267 | tb_key_restore(); 268 | signal(sig, SIG_DFL); 269 | kill(getpid(), sig); 270 | } 271 | -------------------------------------------------------------------------------- /src/keyboard.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "common.h" 8 | #include "termboy.h" 9 | 10 | #define KEY_RELEASE (1<<7) 11 | 12 | static int key_init(void); 13 | static void *key_listen_helper(void *arg); 14 | 15 | static struct termios tty_attr_orig; 16 | static int kbd_mode_orig; 17 | static int rawmode = 0; 18 | 19 | static int pressed[128]; 20 | static void *(*press_handlers[128])(void *); 21 | static void *(*release_handlers[128])(void *); 22 | static void *(*hold_handlers[128])(void *); 23 | static void *handler_args[128]; 24 | static pthread_t hold_threads[128]; 25 | 26 | /* TODO: Is there a better way of doing this? */ 27 | static int fixed_ints[128] = { 28 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 29 | 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 30 | 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 31 | 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 32 | 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 33 | 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 34 | 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 35 | 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 36 | 124, 125, 126, 127 37 | }; 38 | 39 | int tb_key_listen(enum tb_listen_mode mode) 40 | { 41 | pthread_t thread; 42 | 43 | /* TODO: Error handling */ 44 | pthread_create(&thread, NULL, key_listen_helper, NULL); 45 | 46 | if (mode == TB_LISTEN_BLOCKING) 47 | pthread_join(thread, NULL); 48 | else 49 | pthread_detach(thread); 50 | 51 | return 0; 52 | } 53 | 54 | int tb_key_pressed(int key) 55 | { 56 | if (key >= 0 && key < 128) 57 | return pressed[key]; 58 | else 59 | return -1; 60 | } 61 | 62 | void tb_key_handle(int key, 63 | void *(*press_handler)(void *), 64 | void *(*hold_handler)(void *), 65 | void *(*release_handler)(void *), 66 | void *args) 67 | { 68 | press_handlers[key] = press_handler; 69 | hold_handlers[key] = hold_handler; 70 | release_handlers[key] = release_handler; 71 | handler_args[key] = args; 72 | } 73 | 74 | static void *repeat(void *key) 75 | { 76 | int k = *(int *)key; 77 | void *(*handler)(void *) = hold_handlers[k]; 78 | void *args = handler_args[k]; 79 | 80 | while (1) { 81 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 82 | handler(args); 83 | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 84 | pthread_testcancel(); 85 | } 86 | 87 | return NULL; 88 | } 89 | 90 | /* Make this function public? */ 91 | static int key_init(void) 92 | { 93 | struct termios tty_attr; 94 | 95 | if (rawmode) 96 | return 0; 97 | 98 | FAILIF(tcgetattr(STDOUT_FILENO, &tty_attr_orig)); 99 | tty_attr = tty_attr_orig; 100 | tty_attr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP 101 | | INLCR | IGNCR | ICRNL | IXON); 102 | tty_attr.c_oflag &= ~OPOST; 103 | tty_attr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 104 | tty_attr.c_cflag &= ~(CSIZE | PARENB); 105 | tty_attr.c_cflag |= CS8; 106 | FAILIF(tcsetattr(STDOUT_FILENO, TCSANOW, &tty_attr)); 107 | 108 | FAILIF(ioctl(STDOUT_FILENO, KDGKBMODE, &kbd_mode_orig)); 109 | FAILIF(ioctl(STDOUT_FILENO, KDSKBMODE, K_MEDIUMRAW)); 110 | 111 | rawmode = 1; 112 | return 0; 113 | } 114 | 115 | int tb_key_restore(void) 116 | { 117 | if (rawmode) { 118 | FAILIF(tcsetattr(STDOUT_FILENO, TCSAFLUSH, &tty_attr_orig)); 119 | FAILIF(ioctl(STDOUT_FILENO, KDSKBMODE, kbd_mode_orig)); 120 | rawmode = 0; 121 | } 122 | 123 | return 0; 124 | } 125 | 126 | static void *key_listen_helper(void *arg) 127 | { 128 | int key; 129 | pthread_t thread; 130 | pthread_attr_t attr; 131 | 132 | pthread_attr_init(&attr); 133 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 134 | 135 | key_init(); 136 | 137 | do { 138 | key = getchar(); 139 | 140 | if (key & KEY_RELEASE) { 141 | key ^= KEY_RELEASE; 142 | if (pressed[key] == 0) 143 | continue; 144 | if (hold_handlers[key]) { 145 | pthread_cancel(hold_threads[key]); 146 | } 147 | if (release_handlers[key]) { 148 | pthread_create(&thread, &attr, 149 | release_handlers[key], 150 | handler_args[key]); 151 | } 152 | pressed[key] = 0; 153 | } else { 154 | if (pressed[key] == 1) 155 | continue; 156 | if (press_handlers[key]) { 157 | pthread_create(&thread, &attr, 158 | press_handlers[key], 159 | handler_args[key]); 160 | } 161 | if (hold_handlers[key]) { 162 | pthread_create(&hold_threads[key], &attr, 163 | repeat, 164 | &fixed_ints[key]); 165 | } 166 | pressed[key] = 1; 167 | } 168 | } while (key != KEY_ESC); 169 | 170 | tb_key_restore(); 171 | 172 | pthread_attr_destroy(&attr); 173 | 174 | return NULL; 175 | } 176 | -------------------------------------------------------------------------------- /src/misc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "common.h" 7 | #include "termboy.h" 8 | 9 | #define CLOCK_TICK_RATE 1193180 10 | 11 | int tb_msleep(int milliseconds) 12 | { 13 | struct timeval timeout; 14 | timeout.tv_sec = milliseconds / 1000; 15 | timeout.tv_usec = milliseconds%1000 * 1000; 16 | return select(0, NULL, NULL, NULL, &timeout); 17 | } 18 | 19 | int tb_beep(int frequency, int duration) 20 | { 21 | FAILIF(tb_tone_start(frequency)); 22 | tb_msleep(duration); 23 | FAILIF(tb_tone_stop()); 24 | 25 | return 0; 26 | } 27 | 28 | int tb_tone_start(int frequency) 29 | { 30 | FAILIF(ioctl(STDOUT_FILENO, KIOCSOUND, CLOCK_TICK_RATE/frequency)); 31 | 32 | return 0; 33 | } 34 | 35 | int tb_tone_stop(void) 36 | { 37 | FAILIF(ioctl(STDOUT_FILENO, KIOCSOUND, 0)); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /src/pixmaps/all.h: -------------------------------------------------------------------------------- 1 | #include "mountains.h" 2 | #include "trees.h" 3 | #include "waves0.h" 4 | #include "waves1.h" 5 | #include "waves2.h" 6 | #include "waves3.h" 7 | #include "link_stand_left.h" 8 | #include "link_stand_right.h" 9 | #include "link_walk_left.h" 10 | #include "link_walk_right.h" 11 | -------------------------------------------------------------------------------- /src/pixmaps/headerify: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | #TODO: Error handling 4 | 5 | image=${1:?} 6 | 7 | function hex_to_dec() { 8 | dc -e "16 i ${*} f" | \ 9 | tac 10 | } 11 | 12 | read width height <<< $(identify -format '%w %h' ${1}) 13 | 14 | echo -n 'enum tb_color ' 15 | echo -n $(basename ${1} | cut -d '.' -f 1) 16 | echo "[${width}*${height}] = {" 17 | 18 | stream -map orgb "${image}" /dev/stdout | \ 19 | xxd -c4 -g1 -u | \ 20 | cut -d ' ' -f 2-6 | \ 21 | while read pixel; do 22 | read opacity red green blue <<< $(hex_to_dec ${pixel}) 23 | 24 | tb_color=0 25 | ((tb_color |= (blue >= 0x60) << 0)) 26 | ((tb_color |= (green >= 0x60) << 1)) 27 | ((tb_color |= (red >= 0x60) << 2)) 28 | 29 | # ANSI color codes do not follow the same ordering as their 30 | # respective RGB values, so we need to swap mismatched values 31 | case $tb_color in 32 | 1) tb_color=4;; 33 | 3) tb_color=6;; 34 | 4) tb_color=1;; 35 | 6) tb_color=3;; 36 | esac 37 | 38 | luminance=$((red*3 + blue*1 + green*4 >> 3)) 39 | ((tb_color |= (luminance >= 0x60) << 3)) 40 | 41 | if (( opacity & 0x80 )); then 42 | tb_color=-1 43 | fi 44 | printf '%2s,' ${tb_color} 45 | 46 | ((++pixel_count)) 47 | if (( pixel_count % width )); then 48 | printf ' ' 49 | else 50 | printf '\n' 51 | fi 52 | done 53 | 54 | echo '};' 55 | -------------------------------------------------------------------------------- /src/pixmaps/link_stand_left.h: -------------------------------------------------------------------------------- 1 | enum tb_color LINK_STAND_LEFT[14*16] = { 2 | -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, -1, -1, -1, -1, 3 | -1, -1, -1, 0, 0, 12, 11, 12, 12, 12, 0, -1, -1, -1, 4 | -1, -1, 0, 11, 11, 0, 12, 11, 11, 12, 12, 0, -1, -1, 5 | 0, 0, 0, 12, 11, 11, 0, 12, 12, 0, 12, 12, 0, -1, 6 | -1, 0, 0, 0, 12, 11, 11, 0, 0, 11, 0, 12, 12, 0, 7 | -1, -1, -1, 0, 0, 0, 12, 0, 12, 11, 0, 12, 12, 0, 8 | -1, 0, 0, 11, 0, 11, 0, 0, 11, 11, 0, 12, 0, -1, 9 | -1, 0, 11, 11, 0, 11, 11, 0, 11, 11, 0, 0, -1, -1, 10 | -1, -1, 0, 12, 11, 11, 11, 0, 11, 12, 0, -1, -1, -1, 11 | -1, -1, -1, 0, 12, 12, 12, 0, 12, 0, 0, -1, -1, -1, 12 | -1, -1, -1, 0, 0, 0, 0, 0, 0, 12, 0, -1, -1, -1, 13 | -1, -1, -1, 0, 12, 0, 11, 11, 0, 12, 12, 0, -1, -1, 14 | -1, -1, -1, 0, 11, 0, 11, 11, 0, 12, 12, 0, -1, -1, 15 | -1, -1, -1, 0, 12, 0, 0, 0, 0, 0, 0, 0, -1, -1, 16 | -1, -1, -1, 0, 0, 0, 11, 11, 11, 11, 0, -1, -1, -1, 17 | -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 18 | }; 19 | -------------------------------------------------------------------------------- /src/pixmaps/link_stand_right.h: -------------------------------------------------------------------------------- 1 | enum tb_color LINK_STAND_RIGHT[14*16] = { 2 | -1, -1, -1, -1, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 3 | -1, -1, -1, 0, 12, 12, 12, 11, 12, 0, 0, -1, -1, -1, 4 | -1, -1, 0, 12, 12, 11, 11, 12, 0, 11, 11, 0, -1, -1, 5 | -1, 0, 12, 12, 0, 12, 12, 0, 11, 11, 12, 0, 0, 0, 6 | 0, 12, 12, 0, 11, 0, 0, 11, 11, 12, 0, 0, 0, -1, 7 | 0, 12, 12, 0, 11, 12, 0, 12, 0, 0, 0, -1, -1, -1, 8 | -1, 0, 12, 0, 11, 11, 0, 0, 11, 0, 11, 0, 0, -1, 9 | -1, -1, 0, 0, 11, 11, 0, 11, 11, 0, 11, 11, 0, -1, 10 | -1, -1, -1, 0, 12, 11, 0, 11, 11, 11, 12, 0, -1, -1, 11 | -1, -1, -1, 0, 0, 12, 0, 12, 12, 12, 0, -1, -1, -1, 12 | -1, -1, -1, 0, 12, 0, 0, 0, 0, 0, 0, -1, -1, -1, 13 | -1, -1, 0, 12, 12, 0, 11, 11, 0, 12, 0, -1, -1, -1, 14 | -1, -1, 0, 12, 12, 0, 11, 11, 0, 11, 0, -1, -1, -1, 15 | -1, -1, 0, 0, 0, 0, 0, 0, 0, 12, 0, -1, -1, -1, 16 | -1, -1, -1, 0, 11, 11, 11, 11, 0, 0, 0, -1, -1, -1, 17 | -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 18 | }; 19 | -------------------------------------------------------------------------------- /src/pixmaps/link_walk_left.h: -------------------------------------------------------------------------------- 1 | enum tb_color LINK_WALK_LEFT[14*16] = { 2 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3 | -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, 4 | -1, 0, -1, 0, 0, 12, 11, 11, 12, 12, 12, 0, 0, -1, 5 | -1, 0, 0, 11, 11, 0, 12, 12, 11, 11, 12, 12, 12, 0, 6 | -1, 0, 0, 12, 11, 11, 0, 12, 12, 0, 12, 12, 12, 0, 7 | -1, -1, 0, 0, 12, 11, 11, 0, 0, 11, 0, 12, 12, 0, 8 | -1, -1, -1, 0, 0, 0, 12, 0, 12, 11, 0, 12, 0, -1, 9 | -1, 0, 0, 11, 0, 11, 0, 0, 11, 11, 0, 12, 0, -1, 10 | -1, 0, 11, 11, 0, 11, 11, 0, 11, 11, 0, 0, -1, -1, 11 | -1, -1, 0, 12, 11, 11, 11, 0, 11, 12, 0, -1, -1, -1, 12 | -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 13 | -1, -1, -1, -1, 0, 11, 11, 0, 12, 12, 0, 0, -1, -1, 14 | -1, -1, -1, -1, 0, 11, 11, 0, 12, 12, 0, 11, 0, -1, 15 | -1, -1, -1, 0, 0, 0, 0, 12, 12, 0, 0, 11, 0, -1, 16 | -1, -1, 0, 11, 11, 11, 11, 0, 0, 0, 11, 11, 0, -1, 17 | -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18 | }; 19 | -------------------------------------------------------------------------------- /src/pixmaps/link_walk_right.h: -------------------------------------------------------------------------------- 1 | enum tb_color LINK_WALK_RIGHT[14*16] = { 2 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3 | -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 4 | -1, 0, 0, 12, 12, 12, 11, 11, 12, 0, 0, -1, 0, -1, 5 | 0, 12, 12, 12, 11, 11, 12, 12, 0, 11, 11, 0, 0, -1, 6 | 0, 12, 12, 12, 0, 12, 12, 0, 11, 11, 12, 0, 0, -1, 7 | 0, 12, 12, 0, 11, 0, 0, 11, 11, 12, 0, 0, -1, -1, 8 | -1, 0, 12, 0, 11, 12, 0, 12, 0, 0, 0, -1, -1, -1, 9 | -1, 0, 12, 0, 11, 11, 0, 0, 11, 0, 11, 0, 0, -1, 10 | -1, -1, 0, 0, 11, 11, 0, 11, 11, 0, 11, 11, 0, -1, 11 | -1, -1, -1, 0, 12, 11, 0, 11, 11, 11, 12, 0, -1, -1, 12 | -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 13 | -1, -1, 0, 0, 12, 12, 0, 11, 11, 0, -1, -1, -1, -1, 14 | -1, 0, 11, 0, 12, 12, 0, 11, 11, 0, -1, -1, -1, -1, 15 | -1, 0, 11, 0, 0, 12, 12, 0, 0, 0, 0, -1, -1, -1, 16 | -1, 0, 11, 11, 0, 0, 0, 11, 11, 11, 11, 0, -1, -1, 17 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 18 | }; 19 | -------------------------------------------------------------------------------- /src/pixmaps/mountains.h: -------------------------------------------------------------------------------- 1 | enum tb_color MOUNTAINS[64*7] = { 2 | 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 | 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 5 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 6 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9 | }; 10 | -------------------------------------------------------------------------------- /src/pixmaps/trees.h: -------------------------------------------------------------------------------- 1 | enum tb_color TREES[64*26] = { 2 | 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 2, 2, 2, 2, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 2, 2, 2, 2, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 3 | 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 1, 1, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1, 1, 2, 2, 2, 2, 4 | 1, 1, 2, 2, 2, 1, 0, 1, 0, 0, 2, 2, 2, 1, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0, 1, 0, 0, 2, 2, 2, 1, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 1, 2, 2, 2, 2, 1, 5 | 1, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 1, 1, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 1, 1, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 1, 6 | 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 7 | 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8 | 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 10 | 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 4, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 4, 0, 0, 0, 2, 2, 2, 11 | 2, 2, 2, 0, 0, 0, 0, 4, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 4, 4, 0, 4, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 4, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 4, 4, 0, 4, 0, 0, 0, 2, 12 | 2, 0, 0, 0, 0, 1, 0, 4, 4, 4, 0, 2, 2, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 4, 4, 4, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0, 1, 0, 4, 4, 4, 0, 2, 2, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 4, 4, 4, 0, 1, 1, 0, 0, 13 | 0, 0, 0, 0, 1, 1, 1, 0, 4, 0, 0, 0, 2, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 4, 0, 0, 0, 2, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 14 | 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 15 | 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 16 | 0, 0, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 17 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 18 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20 | 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 22 | 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 23 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 24 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 25 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 26 | 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 27 | 7, 7, 7, 7, 6, 6, 6, 6, 7, 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 7, 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 7, 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 7, 7, 6, 6, 6, 7, 7, 7, 28 | }; 29 | -------------------------------------------------------------------------------- /src/pixmaps/waves0.h: -------------------------------------------------------------------------------- 1 | enum tb_color WAVES0[64*31] = { 2 | 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 3 | 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 4 | 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 5 | 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6 | 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7 | 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 8 | 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 9 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 10 | 8, 8, 8, 8, 8, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 11 | 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 8, 8, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 12 | 10, 10, 3, 3, 10, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 10, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 10, 10, 10, 10, 10, 10, 10, 10, 13 | 10, 3, 3, 3, 10, 3, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 10, 3, 10, 10, 10, 10, 3, 10, 10, 10, 3, 10, 3, 10, 3, 10, 3, 3, 3, 10, 3, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 10, 3, 10, 10, 10, 10, 3, 10, 10, 10, 3, 10, 3, 10, 3, 14 | 3, 10, 10, 10, 10, 10, 3, 3, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 10, 10, 10, 3, 10, 10, 10, 10, 10, 3, 3, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 10, 10, 10, 15 | 3, 3, 3, 10, 10, 10, 10, 3, 10, 10, 3, 3, 10, 10, 3, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 3, 10, 10, 3, 3, 10, 10, 3, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16 | 3, 3, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 17 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 18 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 19 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 20 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 21 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 22 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 23 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 24 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 25 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 26 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 29 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 30 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 31 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 32 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 33 | }; 34 | -------------------------------------------------------------------------------- /src/pixmaps/waves1.h: -------------------------------------------------------------------------------- 1 | enum tb_color WAVES1[64*31] = { 2 | 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 3 | 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 4 | 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 5 | 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6 | 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7 | 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 8 | 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 9 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 10 | 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 11 | 8, 8, 9, 9, 9, 10, 10, 10, 9, 9, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 9, 9, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 12 | 9, 9, 9, 10, 10, 10, 3, 3, 10, 10, 9, 9, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 3, 3, 10, 10, 9, 9, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 13 | 9, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 3, 3, 10, 10, 10, 10, 10, 9, 9, 9, 9, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 3, 3, 10, 10, 10, 10, 10, 9, 9, 9, 14 | 10, 10, 3, 3, 10, 3, 3, 3, 3, 3, 10, 10, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 10, 10, 10, 10, 10, 10, 10, 3, 3, 10, 3, 3, 3, 3, 3, 10, 10, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 10, 10, 10, 10, 10, 15 | 10, 3, 3, 3, 10, 10, 3, 3, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 3, 10, 3, 10, 10, 3, 3, 3, 10, 10, 3, 3, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 3, 10, 3, 10, 16 | 10, 10, 10, 10, 3, 3, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 10, 10, 3, 3, 10, 10, 10, 10, 10, 10, 3, 3, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 10, 10, 3, 3, 10, 10, 17 | 3, 3, 3, 10, 10, 3, 10, 3, 10, 10, 3, 3, 10, 10, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 3, 10, 3, 10, 10, 3, 3, 10, 10, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 18 | 3, 3, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 19 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 20 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 21 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 22 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 23 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 24 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 25 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 26 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 29 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 30 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 31 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 32 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 33 | }; 34 | -------------------------------------------------------------------------------- /src/pixmaps/waves2.h: -------------------------------------------------------------------------------- 1 | enum tb_color WAVES2[64*31] = { 2 | 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 3 | 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 4 | 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 5 | 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6 | 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7 | 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 8 | 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 9 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 10 | 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 11 | 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 12 | 9, 9, 9, 9, 9, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 13 | 9, 9, 9, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 14 | 9, 10, 10, 10, 10, 10, 3, 3, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 3, 3, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 15 | 10, 3, 3, 3, 10, 3, 3, 3, 10, 10, 10, 10, 10, 10, 3, 3, 3, 10, 10, 10, 10, 10, 3, 3, 10, 10, 3, 10, 10, 10, 10, 10, 10, 3, 3, 3, 10, 3, 3, 3, 10, 10, 10, 10, 10, 10, 3, 3, 3, 10, 10, 10, 10, 10, 3, 3, 10, 10, 3, 10, 10, 10, 10, 10, 16 | 3, 3, 3, 3, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 10, 3, 3, 10, 10, 3, 3, 10, 3, 3, 3, 3, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 10, 3, 3, 10, 10, 3, 3, 10, 17 | 10, 10, 10, 10, 10, 10, 3, 3, 10, 10, 10, 10, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 10, 10, 10, 10, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 18 | 3, 10, 10, 10, 3, 3, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 10, 10, 3, 10, 10, 10, 3, 3, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 10, 10, 19 | 3, 3, 10, 10, 10, 3, 10, 3, 10, 10, 3, 10, 10, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 3, 10, 3, 10, 10, 3, 10, 10, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 20 | 3, 3, 3, 3, 3, 10, 10, 3, 10, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 3, 10, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 21 | 3, 3, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 22 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 23 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 24 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 25 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 26 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 29 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 30 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 31 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 32 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 33 | }; 34 | -------------------------------------------------------------------------------- /src/pixmaps/waves3.h: -------------------------------------------------------------------------------- 1 | enum tb_color WAVES3[64*31] = { 2 | 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 3 | 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 4 | 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 5 | 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6, 7, 7, 7, 6 | 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7 | 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 6, 7, 7, 6, 7, 8 | 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 9 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 8, 8, 8, 10, 8, 8, 8, 8, 8, 8, 10 | 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 11 | 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 12 | 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 13 | 9, 9, 9, 9, 9, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14 | 9, 9, 9, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 15 | 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 16 | 10, 10, 3, 3, 3, 10, 10, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 10, 10, 3, 10, 10, 3, 3, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 10, 10, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 10, 10, 3, 10, 10, 3, 3, 10, 10, 10, 10, 10, 17 | 10, 3, 3, 3, 3, 10, 10, 3, 3, 10, 10, 10, 10, 10, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 10, 3, 3, 10, 10, 3, 3, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 10, 10, 10, 10, 10, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 10, 3, 3, 10, 10, 3, 3, 10, 18 | 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 3, 10, 3, 3, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 3, 10, 3, 3, 10, 19 | 10, 10, 3, 3, 10, 10, 3, 3, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 3, 3, 10, 10, 3, 3, 10, 10, 10, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 10, 20 | 3, 10, 10, 3, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 10, 10, 3, 10, 10, 3, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 10, 10, 21 | 3, 3, 10, 10, 10, 10, 3, 3, 10, 10, 3, 10, 10, 3, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 3, 3, 10, 10, 3, 10, 10, 3, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 22 | 3, 3, 3, 3, 3, 10, 3, 3, 10, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 3, 3, 10, 3, 3, 3, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 23 | 3, 3, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 24 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 25 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 26 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 29 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 30 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 31 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 32 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 33 | }; 34 | -------------------------------------------------------------------------------- /src/screen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "common.h" 11 | #include "termboy.h" 12 | 13 | #define MAX_FONT_SIZE 65536 14 | #define BYTES_PER_CHAR 32 15 | #define MAGIC_CHAR ' ' 16 | 17 | #define CODE_CLEARSCREEN "\x1B""c" 18 | #define CODE_DEFINECOLOR "\x1B]P%X%.6X" 19 | #define CODE_HIDECURSOR "\x1B[?25l" 20 | #define CODE_MOVECURSOR "\x1B[%d;%df" 21 | #define CODE_RESETPALETTE "\x1B]R" 22 | #define CODE_SETCOLOR "\x1B[%d;3%dm" 23 | 24 | static int pixel_mode = 0; 25 | 26 | static struct console_font_op orig_font; 27 | static unsigned char orig_font_data[MAX_FONT_SIZE]; 28 | 29 | struct winsize size; 30 | static unsigned char *color_map; 31 | static pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER; 32 | 33 | int tb_screen_init(int pixel_size) 34 | { 35 | struct console_font_op new_font; 36 | unsigned char new_font_data[256*BYTES_PER_CHAR]; 37 | 38 | if (pixel_size < 1 || pixel_size > 8) 39 | return -1; 40 | 41 | if (!pixel_mode) { 42 | orig_font.op = KD_FONT_OP_GET; 43 | orig_font.flags = 0; 44 | orig_font.width = orig_font.height = 32; 45 | orig_font.charcount = 1024; 46 | orig_font.data = orig_font_data; 47 | FAILIF(ioctl(STDOUT_FILENO, KDFONTOP, &orig_font)); 48 | 49 | if (isatty(STDERR_FILENO)) 50 | freopen("/dev/null", "w", stderr); 51 | } 52 | 53 | if (pixel_mode != pixel_size) { 54 | memset(new_font_data + MAGIC_CHAR*BYTES_PER_CHAR, 55 | 0xFF, 56 | BYTES_PER_CHAR); 57 | new_font.op = KD_FONT_OP_SET; 58 | new_font.flags = 0; 59 | new_font.width = pixel_size; 60 | new_font.height = pixel_size; 61 | new_font.charcount = 256; 62 | new_font.data = new_font_data; 63 | FAILIF(ioctl(STDOUT_FILENO, KDFONTOP, &new_font)); 64 | 65 | pixel_mode = pixel_size; 66 | FAILIF(ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)); 67 | free(color_map); 68 | color_map = calloc(sizeof(char), size.ws_col*size.ws_row); 69 | if (color_map == NULL) { 70 | tb_screen_restore(); 71 | return -1; 72 | } 73 | 74 | } 75 | 76 | printf(CODE_CLEARSCREEN); 77 | printf(CODE_HIDECURSOR); 78 | 79 | return 0; 80 | } 81 | 82 | void tb_screen_size(int *width, int *height) 83 | { 84 | *width = size.ws_col; 85 | *height = size.ws_row; 86 | } 87 | 88 | void tb_screen_color(enum tb_color color, int value) 89 | { 90 | printf(CODE_DEFINECOLOR, color, value); 91 | } 92 | 93 | /* TODO: Always put coords last? */ 94 | int tb_screen_put(int x, int y, enum tb_color color) 95 | { 96 | static int lastx = -1, lasty = -1; 97 | 98 | if (x >= size.ws_col || y >= size.ws_row || x < 0 || y < 0) 99 | return -1; 100 | 101 | pthread_mutex_lock(&print_lock); 102 | if (color_map[x + y*size.ws_col] != color) { 103 | if (x != lastx+1 || y != lasty) 104 | printf(CODE_MOVECURSOR, y+1, x+1); 105 | 106 | printf(CODE_SETCOLOR "%c", 107 | (color & TB_COLOR_BOLD) != 0, 108 | color & ~TB_COLOR_BOLD, 109 | MAGIC_CHAR); 110 | 111 | color_map[x + y*size.ws_col] = color; 112 | lastx = x; 113 | lasty = y; 114 | } 115 | pthread_mutex_unlock(&print_lock); 116 | 117 | return 0; 118 | } 119 | 120 | int tb_screen_flush(void) 121 | { 122 | return fflush(stdout); 123 | } 124 | 125 | int tb_screen_restore(void) 126 | { 127 | if (pixel_mode) { 128 | printf(CODE_CLEARSCREEN); 129 | printf(CODE_RESETPALETTE); 130 | size.ws_col = size.ws_row = 0; 131 | free(color_map); 132 | 133 | orig_font.op = KD_FONT_OP_SET; 134 | FAILIF(ioctl(STDOUT_FILENO, KDFONTOP, &orig_font)); 135 | pixel_mode = 0; 136 | } 137 | 138 | return 0; 139 | } 140 | -------------------------------------------------------------------------------- /src/sprite.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "common.h" 4 | #include "termboy.h" 5 | 6 | struct sprite_listnode 7 | { 8 | struct tb_sprite *sprite; 9 | struct sprite_listnode *next; 10 | }; 11 | 12 | static enum tb_color sprite_color(struct tb_sprite *sprite, int x, int y); 13 | 14 | static struct sprite_listnode *sprites; 15 | static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER; 16 | static pthread_mutex_t move_lock = PTHREAD_MUTEX_INITIALIZER; 17 | 18 | int tb_sprite_init(struct tb_sprite *sprite, int width, int height) 19 | { 20 | /* TODO: Check that sprite is non-NULL */ 21 | /* TODO: Use unsigned for dimensions */ 22 | sprite->x = 0; 23 | sprite->y = 0; 24 | sprite->width = width; 25 | sprite->height = height; 26 | sprite->layer = 0; 27 | sprite->tile = TB_TILE_NONE; 28 | sprite->colors = calloc(sizeof(enum tb_color), width * height); 29 | 30 | if (sprite->colors == NULL) 31 | return -1; 32 | 33 | return 0; 34 | } 35 | 36 | void tb_sprite_del(struct tb_sprite *sprite) 37 | { 38 | free(sprite->colors); 39 | } 40 | 41 | /* TODO: Add a 'tb_sprite_hide' function */ 42 | int tb_sprite_show(struct tb_sprite *sprite) 43 | { 44 | struct sprite_listnode *curr_node, *next_node, *new_node; 45 | pthread_mutex_lock(&list_lock); 46 | 47 | curr_node = sprites; 48 | new_node = malloc(sizeof(struct sprite_listnode)); 49 | if (new_node == NULL) 50 | goto failure; 51 | 52 | new_node->sprite = sprite; 53 | new_node->next = NULL; 54 | 55 | if (curr_node == NULL) { 56 | sprites = new_node; 57 | goto success; 58 | } 59 | 60 | if (sprite->layer >= curr_node->sprite->layer) { 61 | new_node->next = curr_node; 62 | sprites = new_node; 63 | goto success; 64 | } 65 | 66 | while (curr_node->next != NULL) { 67 | next_node = curr_node->next; 68 | 69 | if (sprite->layer < curr_node->sprite->layer && 70 | sprite->layer >= next_node->sprite->layer) { 71 | new_node->next = next_node; 72 | curr_node->next = new_node; 73 | goto success; 74 | } 75 | 76 | curr_node = next_node; 77 | } 78 | 79 | curr_node->next = new_node; 80 | 81 | success: 82 | pthread_mutex_unlock(&list_lock); 83 | tb_sprite_redraw(sprite); 84 | return 0; 85 | 86 | failure: 87 | pthread_mutex_unlock(&list_lock); 88 | return -1; 89 | } 90 | 91 | int tb_sprite_move(struct tb_sprite *sprite, int new_x, int new_y) 92 | { 93 | pthread_mutex_lock(&move_lock); 94 | sprite->x = new_x; 95 | sprite->y = new_y; 96 | /* TODO: redraw old position */ 97 | tb_sprite_redraw(sprite); 98 | pthread_mutex_unlock(&move_lock); 99 | 100 | return 0; 101 | } 102 | 103 | int tb_sprite_redraw(struct tb_sprite *sprite) 104 | { 105 | int left, right, top, bottom, maxwidth, maxheight, x, y; 106 | struct sprite_listnode *curr_node; 107 | struct tb_sprite *curr_sprite; 108 | enum tb_color color; 109 | 110 | /* TODO: Factor out this duplicated block */ 111 | left = sprite->x; 112 | right = left + sprite->width; 113 | top = sprite->y; 114 | bottom = top + sprite->height; 115 | tb_screen_size(&maxwidth, &maxheight); 116 | 117 | if (sprite->tile & TB_TILE_HORIZONTAL) { 118 | left = 0; 119 | right = maxwidth; 120 | } 121 | if (sprite->tile & TB_TILE_VERTICAL) { 122 | top = 0; 123 | bottom = maxheight; 124 | } 125 | 126 | for (y = top; y < bottom; ++y) { 127 | for (x = left; x < right; ++x) { 128 | curr_node = sprites; 129 | while (curr_node != NULL) { 130 | curr_sprite = curr_node->sprite; 131 | color = sprite_color(curr_sprite, x, y); 132 | if (color != TB_COLOR_TRANSPARENT) { 133 | tb_screen_put(x, y, color); 134 | break; 135 | } 136 | curr_node = curr_node->next; 137 | } 138 | } 139 | } 140 | 141 | tb_screen_flush(); 142 | 143 | return 0; 144 | } 145 | 146 | enum tb_color sprite_color(struct tb_sprite *sprite, int x, int y) 147 | { 148 | int left, right, top, bottom; 149 | 150 | left = sprite->x; 151 | right = left + sprite->width; 152 | top = sprite->y; 153 | bottom = top + sprite->height; 154 | 155 | if (sprite->tile & TB_TILE_HORIZONTAL) { 156 | while (x < left) 157 | x += sprite->width; 158 | while (x >= right) 159 | x -= sprite->width; 160 | } 161 | if (sprite->tile & TB_TILE_VERTICAL) { 162 | while (y < top) 163 | y += sprite->height; 164 | while (y >= bottom) 165 | y -= sprite->height; 166 | } 167 | 168 | if (x >= left && x < right && y >= top && y < bottom) 169 | return TB_SPRITE_COLOR(*sprite, x - left, y - top); 170 | 171 | return TB_COLOR_TRANSPARENT; 172 | } 173 | -------------------------------------------------------------------------------- /src/termboy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /* TODO: Switch macros to inline functions? */ 7 | #define TB_SPRITE_COLOR(sprite, x, y) \ 8 | ((sprite).colors[(y)*((sprite).width) + (x)]) 9 | 10 | #define TB_SPRITE_FILL(sprite, data) \ 11 | memcpy((sprite).colors, (data), \ 12 | sizeof(enum tb_color) * (sprite).width * (sprite).height) 13 | 14 | enum tb_color { 15 | TB_COLOR_BLACK, TB_COLOR_RED, TB_COLOR_GREEN, TB_COLOR_YELLOW, 16 | TB_COLOR_BLUE, TB_COLOR_MAGENTA, TB_COLOR_CYAN, TB_COLOR_WHITE, 17 | TB_COLOR_BOLD, TB_COLOR_TRANSPARENT = -1 18 | }; 19 | 20 | enum tb_listen_mode { 21 | TB_LISTEN_BLOCKING, 22 | TB_LISTEN_NONBLOCKING 23 | }; 24 | 25 | enum tb_tile { 26 | TB_TILE_NONE, 27 | TB_TILE_HORIZONTAL, 28 | TB_TILE_VERTICAL 29 | }; 30 | 31 | struct tb_sprite { 32 | int x; 33 | int y; 34 | int width; 35 | int height; 36 | int layer; 37 | enum tb_tile tile; 38 | enum tb_color *colors; 39 | }; 40 | 41 | struct tb_anim { 42 | struct tb_sprite *sprite; 43 | int frames; 44 | int *delays; 45 | enum tb_color **data; 46 | int _frames; 47 | pthread_t _thread; 48 | }; 49 | 50 | int tb_screen_init(int pixel_size); 51 | void tb_screen_size(int *width, int *height); 52 | void tb_screen_color(enum tb_color color, int value); 53 | int tb_screen_put(int x, int y, enum tb_color color); 54 | int tb_screen_flush(void); 55 | int tb_screen_restore(void); 56 | 57 | int tb_key_listen(enum tb_listen_mode); 58 | int tb_key_restore(void); 59 | int tb_key_pressed(int key); 60 | void tb_key_handle(int key, 61 | void *(*press_handler)(void *), 62 | void *(*hold_handler)(void *), 63 | void *(*release_handler)(void *), 64 | void *args); 65 | 66 | struct tb_sprite *tb_sprite_background(void); 67 | int tb_sprite_init(struct tb_sprite *sprite, int width, int height); 68 | int tb_sprite_show(struct tb_sprite *sprite); 69 | int tb_sprite_move(struct tb_sprite *sprite, int x, int y); 70 | int tb_sprite_redraw(struct tb_sprite *sprite); 71 | void tb_sprite_del(struct tb_sprite *sprite); 72 | 73 | int tb_anim_init(struct tb_anim *anim, struct tb_sprite *sprite, int frames); 74 | int tb_anim_add_frame(struct tb_anim *anim, enum tb_color *colors, int delay_ms); 75 | int tb_anim_start(struct tb_anim *anim); 76 | int tb_anim_stop(struct tb_anim *anim); 77 | void tb_anim_del(struct tb_anim *anim); 78 | 79 | int tb_msleep(int milliseconds); 80 | int tb_beep(int frequency, int duration); 81 | int tb_tone_start(int frequency); 82 | int tb_tone_stop(void); 83 | --------------------------------------------------------------------------------