~ruther/CTU-FEE-B0B35APO-Semestral-project

ref: 247d0c106cc3c32caef42a555948bb0b8cd32ff6 CTU-FEE-B0B35APO-Semestral-project/image-viewer/src/cursor.c -rw-r--r-- 4.1 KiB
247d0c10 — František Boháček fix: floating point exception 3 years ago
                                                                                
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "cursor.h"
#include "direction.h"
#include "display_utils.h"
#include "image.h"
#include "coords.h"

const uint8_t CURSOR[] = {
  0x0, 0x0, 0x0, 0x0, 0x2, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0, // end of 1st line
  0x0, 0x0, 0x0, 0x0, 0x2, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, // end of 2nd line
  0x0, 0x0, 0x0, 0x0, 0x2, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, // end of 3rd line
  0x0, 0x0, 0x0, 0x0, 0x2, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, // end of 4th line
  0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, // end of 5th line
  0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, // end of 6th line
  0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, // end of 7th line
  0x0, 0x0, 0x0, 0x0, 0x2, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, // end of 8th line
  0x0, 0x0, 0x0, 0x0, 0x2, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, // end of 9th line
  0x0, 0x0, 0x0, 0x0, 0x2, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, // end of 10th line
  0x0, 0x0, 0x0, 0x0, 0x2, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0, // end of 11th line
  0x0, 0x0
};

const display_pixel_t CURSOR_OUTLINE_COLOR = {.fields = {.r = (uint8_t)DISPLAY_MAX_RED,
                                                 .g = DISPLAY_MAX_GREEN,
                                                 .b = DISPLAY_MAX_BLUE}};
const display_pixel_t CURSOR_COLOR = {
    .fields = {.r = 0, .g = 0, .b = 0}};

cursor_t cursor_create() {
  cursor_t cursor = {
    .x = 0,
    .y = 0,
    .shown = false,
    .shown_at = 0,
  };

  return cursor;
}

void cursor_center(cursor_t *cursor, image_region_t region) {
  cursor->x = region.x + region.width / 2;
  cursor->y = region.y + region.height / 2;
}

bool cursor_move(cursor_t *cursor, image_region_t region, direction_t direction, int16_t amount) {
  int32_t x = cursor->x, y = cursor->y;
  direction_move_xy(direction, &x, &y, amount);

  if (x < region.x) {
    x = region.x;
  } else if (x > region.x + region.width - 1) {
    x = region.x + region.width - 1;
  }

  if (y < region.y) {
    y = region.y;
  } else if (y > region.y + region.height - 1) {
    y = region.y + region.height - 1;
  }

  bool moved = cursor->x != x || cursor->y != y;
  cursor->x = x;
  cursor->y = y;
  return moved;
}

void cursor_show(cursor_t *cursor, image_t *image, image_zoom_t zoom,
                 display_t *display) {
  cursor_hide(cursor, image, zoom, display);
  cursor->shown_at = time(NULL);
  cursor->shown = true;

  coords_t screen_coords =
      image_get_screen_coords(image, zoom, coords_create(cursor->x, cursor->y));
  uint16_t base_x = screen_coords.x;
  uint16_t base_y = screen_coords.y;

  uint16_t first_x = base_x - CURSOR_WIDTH / 2;
  uint16_t first_y = base_y - CURSOR_WIDTH / 2;

  for (uint16_t iy = 0; iy < CURSOR_WIDTH; iy++) {
    for (uint16_t ix = 0; ix < CURSOR_WIDTH; ix++) {
      uint16_t x = first_x + ix;
      uint16_t y = first_y + iy;

      uint8_t colorn = CURSOR[iy * CURSOR_WIDTH + ix];
      display_pixel_t color;
      switch (colorn) {
      case 0x1:
        color = CURSOR_COLOR;
        break;
      case 0x2:
        color = CURSOR_OUTLINE_COLOR;
        break;
      default:
        continue;
      }

      cursor->previous_display_data[iy * CURSOR_WIDTH + ix] = display_get_pixel(display, x, y);
      display_set_pixel(display, x, y, color);
    }
  }
}

void cursor_hide(cursor_t *cursor, image_t *image, image_zoom_t zoom,
                 display_t *display) {
  if (!cursor->shown) {
    return;
  }

  coords_t screen_coords =
      image_get_screen_coords(image, zoom, coords_create(cursor->x, cursor->y));
  uint16_t base_x = screen_coords.x;
  uint16_t base_y = screen_coords.y;
  uint16_t first_x = base_x - CURSOR_WIDTH / 2;
  uint16_t first_y = base_y - CURSOR_WIDTH / 2;

  for (int iy = 0; iy < CURSOR_WIDTH; iy++) {
    for (int ix = 0; ix < CURSOR_WIDTH; ix++) {
      uint16_t x = first_x + ix;
      uint16_t y = first_y + iy;

      uint8_t colorn = CURSOR[iy * CURSOR_WIDTH + ix];
      switch (colorn) {
      case 0x1:
      case 0x2:
        break;
      default:
        continue;
      }

      display_set_pixel(display, x, y,
                        cursor->previous_display_data[iy * CURSOR_WIDTH + ix]);
    }
  }

  cursor->shown = false;
}
Do not follow this link