about summary refs log tree commit diff
path: root/flipdot.c
blob: 7a6d5576c45dc9498fafb46ab5523b9706be7820 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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;
}