#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; }