diff options
author | sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> | 2020-12-24 23:27:18 +0100 |
---|---|---|
committer | sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> | 2020-12-24 23:27:18 +0100 |
commit | ab1ead3ed15b2fcadabc490dc268cfc75a42cc44 (patch) | |
tree | 436cf86701dfdb12f4e3af953da62cad7f2d7cdd | |
parent | dfd64e48de81898e73d09455d92110fa5047e6e7 (diff) |
feat(flipdot): add flipdot utils to libbuchstabensuppe
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | bs-renderflipdot.c | 42 | ||||
-rw-r--r-- | default.o.do | 3 | ||||
-rw-r--r-- | flipdot.c | 94 | ||||
-rw-r--r-- | include/buchstabensuppe/flipdot.h | 84 | ||||
-rw-r--r-- | libbuchstabensuppe.a.do | 2 |
6 files changed, 188 insertions, 38 deletions
diff --git a/Makefile b/Makefile index c4b8027..ff5bb04 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ install: install -Dm755 bs-renderflipdot.exe $(BINDIR)/bs-renderflipdot install -Dm644 include/buchstabensuppe.h -t $(INCDIR) install -Dm644 include/buchstabensuppe/bitmap.h -t $(INCDIR)/buchstabensuppe + install -Dm644 include/buchstabensuppe/flipdot.h -t $(INCDIR)/buchstabensuppe install -Dm644 third_party/stb/stb_truetype.h -t $(INCDIR) install -Dm644 libbuchstabensuppe.a -t $(LIBDIR) install -Dm644 doc/man/bs-renderflipdot.1 -t $(MANDIR)/man1 diff --git a/bs-renderflipdot.c b/bs-renderflipdot.c index 19a66ac..377b543 100644 --- a/bs-renderflipdot.c +++ b/bs-renderflipdot.c @@ -11,6 +11,7 @@ #include <unistd.h> #include <buchstabensuppe.h> +#include <buchstabensuppe/flipdot.h> #define DEFAULT_FONT_SIZE 16 #define DEFAULT_FLIPDOT_WIDTH 80 @@ -67,26 +68,6 @@ void print_usage(const char *name) { DEFAULT_FLIPDOT_WIDTH, DEFAULT_FLIPDOT_HEIGHT); } -bool scroll_next_view(bs_view_t *view, int flipdot_width) { - if(view->bs_view_offset_x >= view->bs_view_bitmap.bs_bitmap_width) { - view->bs_view_offset_x = -flipdot_width; - return true; - } else { - view->bs_view_offset_x++; - return false; - } -} - -bool page_next_view(bs_view_t *view, int flipdot_width) { - if(view->bs_view_offset_x + view->bs_view_width - >= view->bs_view_bitmap.bs_bitmap_width) { - return true; - } else { - view->bs_view_offset_x += flipdot_width; - } - return false; -} - void ignore_signal(int signum) { (void) signum; } @@ -138,11 +119,6 @@ bool render_flipdot(const char *host, const char *port, int family, const char * mode == RENDER_PAGE; bool finished = false; - // render first frame immediately - - size_t bits_size; - uint8_t *bits = bs_view_bitarray(view, &bits_size, invert); - if(multiple_frames) { // TODO use sigaction // TODO handle SIGINT and SIGTERM @@ -152,31 +128,23 @@ bool render_flipdot(const char *host, const char *port, int family, const char * } while(!finished && !failure) { - if(bits == NULL) { - failure = true; - break; - } - - failure = sendto(sockfd, bits, bits_size, 0, - addrs->ai_addr, addrs->ai_addrlen) != (ssize_t) bits_size; + failure = bs_flipdot_render(sockfd, addrs->ai_addr, + addrs->ai_addrlen, view, invert) != 0; if(multiple_frames) { // restore handler which is removed by sendto signal(SIGALRM, ignore_signal); } - free(bits); - if(mode == RENDER_SCROLL) { - finished = scroll_next_view(&view, flipdot_width); + finished = bs_scroll_next_view(&view, 1, BS_DIMENSION_X); } else if(mode == RENDER_PAGE) { - finished = page_next_view(&view, flipdot_width); + finished = bs_page_next_view(&view, 1, BS_DIMENSION_X); } if(!multiple_frames) { finished = true; } else if(!finished) { - bits = bs_view_bitarray(view, &bits_size, invert); pause(); } } diff --git a/default.o.do b/default.o.do index 88d23a1..044a571 100644 --- a/default.o.do +++ b/default.o.do @@ -23,6 +23,9 @@ case "$2" in bitmap) redo-ifchange util.h ;; + flipdot) + redo-ifchange include/buchstabensuppe/bitmap.h + ;; *) esac diff --git a/flipdot.c b/flipdot.c new file mode 100644 index 0000000..7a6d557 --- /dev/null +++ b/flipdot.c @@ -0,0 +1,94 @@ +#include <errno.h> +#include <stdlib.h> + +#include <buchstabensuppe/flipdot.h> + +bool bs_scroll_next_view(bs_view_t *view, int step, enum bs_dimension dim) { + if(step == 0) { + return true; + } + + int bitmap_len, len; + int *offset; + + switch(dim) { + case BS_DIMENSION_Y: + bitmap_len = view->bs_view_bitmap.bs_bitmap_height; + offset = &(view->bs_view_offset_y); + len = view->bs_view_width; + break; + case BS_DIMENSION_X: /* is also default case */ + default: + bitmap_len = view->bs_view_bitmap.bs_bitmap_width; + offset = &(view->bs_view_offset_x); + len = view->bs_view_height; + break; + } + + if(step > 0 && *offset >= bitmap_len) { + *offset = -len; + return true; + } else if(step < 0 && *offset <= -len) { + *offset = bitmap_len; + return true; + } else { + *offset = *offset + step; + } + + return false; +} + +bool bs_page_next_view(bs_view_t *view, int dir, enum bs_dimension dim) { + if(dir == 0) { + return true; + } + + int bitmap_len, len; + int *offset; + + switch(dim) { + case BS_DIMENSION_Y: + bitmap_len = view->bs_view_bitmap.bs_bitmap_height; + offset = &(view->bs_view_offset_y); + len = view->bs_view_width; + break; + case BS_DIMENSION_X: /* is also default case */ + default: + bitmap_len = view->bs_view_bitmap.bs_bitmap_width; + offset = &(view->bs_view_offset_x); + len = view->bs_view_height; + break; + } + + if(dir > 0 && *offset + len >= bitmap_len) { + *offset = 0; + return true; + } else if(dir < 0 && *offset <= 0) { + *offset = bitmap_len - len; + return true; + } else { + *offset = *offset + dir * len; + } + + return false; +} + +int bs_flipdot_render(int sockfd, struct sockaddr *addr, socklen_t addrlen, bs_view_t view, unsigned char overflow_color) { + size_t bits_size; + uint8_t *bits = bs_view_bitarray(view, &bits_size, overflow_color); + + if(bits == NULL) { + errno = ENOMEM; + return -1; + } + + ssize_t sent = sendto(sockfd, bits, bits_size, 0, addr, addrlen); + + free(bits); + + if(sent != (ssize_t) bits_size) { + return -1; + } + + return 0; +} diff --git a/include/buchstabensuppe/flipdot.h b/include/buchstabensuppe/flipdot.h new file mode 100644 index 0000000..f74ae10 --- /dev/null +++ b/include/buchstabensuppe/flipdot.h @@ -0,0 +1,84 @@ +/*! + * @file buchstabensuppe/flipdot.h + * + * Facilities for rendering bitmaps onto flipdot displays + * and useful bitmap manipulation when targeting flipdot displays. + */ +#ifndef BUCHSTABENSUPPE_FLIPDOT_H +#define BUCHSTABENSUPPE_FLIPDOT_H + +#include <stdbool.h> /* bool */ +#include <sys/socket.h> /* sockaddr */ + +#include <buchstabensuppe/bitmap.h> + +/*! + * @brief Render a bitmap view onto a flipdot display + * + * This function renders a view to a flipdot display compatible bitarray + * using bs_view_bitmap() and sends it to a display listening at the given + * address using a given socket. + * + * The viewed bitmap must be a binary bitmap for this to work properly. + * Zero is black, all values greater than zero are white. + * + * @param sockfd file descriptor of a `SOCK_DGRAM` socket + * @param addr address of the target flipdot display + * @param addrlen length of the address structure + * @param view bitmap view to render + * @param overflow_color value area outside of the picture should get (either 0 or 1) + */ +int bs_flipdot_render(int sockfd, struct sockaddr *addr, socklen_t addrlen, + bs_view_t view, unsigned char overflow_color); + +/*! + * @brief Axis description + * + * Describes which direction to perform a movement in for + * bs_scroll_next_view() and bs_page_next_view(). + */ +enum bs_dimension { + BS_DIMENSION_X, //!< X Axis + BS_DIMENSION_Y, //!< Y Axis +}; + +/*! + * @brief Calculates next view for a one dimensional scroll through a bitmap. + * + * Advance a bitmap view by `step` in a given dimension. Will return `true` + * as soon as the bitmap is out of view and wrap around, i. e. sets the offset + * to `-len`. This is intended to provide the view for the next frame to be + * rendered to a (flipdot) display. + * + * The given view is expected to be fully intialized and `bs_view_width` and + * `bs_view_height` to be equal to the dimensions of the target screen. Also + * the first view position must be set by the caller. + * + * @param view bitmap view to alter + * @param step step to advance by + * @param dim dimension to advance in + * + * @return true if the bitmap has come out of view, + * i. e. the scrolling motion is finished + */ +bool bs_scroll_next_view(bs_view_t *view, int step, enum bs_dimension dim); + +/*! + * @brief Calculates next view for one dimensional paging through a bitmap. + * + * This is similar to bs_scroll_next_view(), but the scroll step is the target + * display's width or height and the picture is never scrolled out of view. + * + * If the edge of the bitmap is in view, true is returned and the offset is + * set so the first page is in view. + * + * @param view bitmap view to alter + * @param step step to advance by + * @param dim dimension to advance in + * + * @return true if another page would mean the bitmap would come out of view + * i. e. all pages have been viewed + */ +bool bs_page_next_view(bs_view_t *view, int direction, enum bs_dimension dim); + +#endif diff --git a/libbuchstabensuppe.a.do b/libbuchstabensuppe.a.do index 6a54444..2e96ce9 100644 --- a/libbuchstabensuppe.a.do +++ b/libbuchstabensuppe.a.do @@ -1,7 +1,7 @@ source ./build_config redo-ifchange ./build_config -OBJS="third_party/stb_truetype.o bitmap.o buchstabensuppe.o" +OBJS="third_party/stb_truetype.o bitmap.o buchstabensuppe.o flipdot.o" redo-ifchange $OBJS tmp_dir="$(mktemp -d)" |