#include "ExtendedScreen.h" #include "bitmap.h" #include "colors.h" #include #include #include #include "screen-settings.h" SPIClass hspi(HSPI); Adafruit_SSD1351 hardware_screen(SCREEN_WIDTH, SCREEN_HEIGHT, &hspi, CS_PIN, DC_PIN, RST_PIN); ExtendedScreen screen(&hardware_screen); rect_t draw_striped_bitmap(bitmap_t &image, uint16_t x, uint16_t y, int num_stripes, const RGB stripes[], RGB background, rect_t old_rect); rect_t draw_bouncy_striped_bitmap(bitmap_t &image, uint16_t num_stripes, const RGB stripes[], RGB background); RGB black = RGB{0, 0, 0}; void setup() { Serial.begin(9600); hardware_screen.begin(32000000); screen.fillScreen(black.to_565()); } uint16_t rainbow_saturation = 100; uint16_t rainbow_lightness = 50; const int16_t rainbow_flag[] = {0, 60, 120, 180, 240, 300}; const uint16_t rainbow_length = sizeof(rainbow_flag) / sizeof(rainbow_flag[0]); #define hue_step 1 << 7 #define start_x 20 #define start_y 90 #define x_step 7 << 5 #define y_step 9 << 5 constexpr RGB dark(50, 50, 50); //RGB blue(0, 200, 255); constexpr RGB blue(0x00, 0xC8, 0xFF); //RGB trans_pink(220, 0, 255); constexpr RGB trans_pink(0xDC, 0x00, 0xFF); //RGB white(255, 255, 255); constexpr RGB white(0xFF, 0xFF, 0xFF); const RGB trans_flag[] = {blue, trans_pink, white, trans_pink, blue}; const uint16_t trans_flag_length = sizeof(trans_flag) / sizeof(trans_flag[0]); RGB gray(150, 150, 150); RGB green(150, 255, 45); const RGB agender_flag[] = {dark, gray, white, green, white, gray, dark}; const uint16_t agender_flag_length = sizeof(agender_flag) / sizeof(agender_flag[0]); RGB red(214, 41, 0); RGB orange(255, 155, 85); RGB lesbian_pink(212, 97, 166); RGB lesbian_purple(165, 0, 98); const RGB lesbian_flag[] = {red, orange, white, lesbian_pink, lesbian_purple}; const uint16_t lesbian_flag_length = sizeof(lesbian_flag) / sizeof(lesbian_flag[0]); const RGB enby_yellow(255, 255, 0); const RGB enby_purple(150, 20, 255); const RGB enby_flag[] = {enby_yellow, white, enby_purple, dark}; const uint16_t enby_flag_length = sizeof(enby_flag) / sizeof(enby_flag[0]); #include "bitmaps/cyber96.h" int32_t hue_time = 0; int32_t toggle_count = 0; void loop() { int selector = (toggle_count / 100) % 5; RGB rainbow_stripes[rainbow_length]; switch (selector) { case 0: for (size_t i = 0; i < rainbow_length; ++i) { uint16_t hue = (int16_t) ((rainbow_flag[i] + (hue_time >> 8)) % 360); rainbow_stripes[i] = HSL(hue, rainbow_saturation, rainbow_lightness).toRGB(); } draw_bouncy_striped_bitmap(cyber96, rainbow_length, rainbow_stripes, black); hue_time = (int32_t) (((360 << 8) + hue_time + hue_step) % (360 << 8)); break; case 1: draw_bouncy_striped_bitmap(cyber96, trans_flag_length, trans_flag, black); break; case 2: draw_bouncy_striped_bitmap(cyber96, agender_flag_length, agender_flag, black); break; case 3: draw_bouncy_striped_bitmap(cyber96, lesbian_flag_length, lesbian_flag, black); break; case 4: draw_bouncy_striped_bitmap(cyber96, enby_flag_length, enby_flag, black); break; } toggle_count += 1; delay(20); } /** * draws a bitmap in colored horizontal stripes * colors are in RGB65 * note: the width of the image MUST be a multiple of 8 * returns the rect in which the image was drawn */ rect_t draw_striped_bitmap(bitmap_t &image, uint16_t x, uint16_t y, int num_stripes, const RGB stripes[], RGB background, rect_t old_rect) { int row_height = image.height / num_stripes; int leftover = image.height % num_stripes; bool even = num_stripes % 2 == 0; int middle_row_height_1; int middle_row_height_2; if (even) { middle_row_height_1 = row_height + leftover / 2; middle_row_height_2 = middle_row_height_1 + (leftover % 2); } else { middle_row_height_1 = row_height + leftover; middle_row_height_2 = 0; } uint16_t offset_y = 0; int16_t rect_x_offset = 0; uint16_t rect_width_offset = 0; if (old_rect.width > 0) { if (old_rect.x < x) { rect_width_offset = x - old_rect.x; rect_x_offset = -rect_width_offset; } else { rect_x_offset = 0; rect_width_offset = old_rect.x - x; } } for (int i = 0; i < num_stripes; i++) { RGB current_color = stripes[i]; uint16_t offset_data = offset_y * image.width / 8; uint16_t current_row_height = row_height; if (even) { if (i == num_stripes / 2) { current_row_height = middle_row_height_1; } else if (i == num_stripes / 2 - 1) { current_row_height = middle_row_height_2; } } else { if (i == num_stripes / 2) { current_row_height = middle_row_height_1; } } rect_t stripe_rect = { .x = rect_x_offset, .y = static_cast(offset_y), .width = static_cast(image.width + rect_width_offset), .height = current_row_height, }; int16_t rect_y_offset = 0; uint16_t rect_height_offset = 0; if (old_rect.height > 0) { if (i == 0 && old_rect.y < y) { rect_height_offset = y - old_rect.y; rect_y_offset = -rect_height_offset; } else if (i == num_stripes - 1 && old_rect.y > y) { rect_height_offset = (old_rect.y + old_rect.height) - (y + offset_y + current_row_height); } } stripe_rect.height += rect_height_offset; stripe_rect.y += rect_y_offset; screen.drawTransparentBitmap(x + rect_x_offset, y + offset_y + rect_y_offset, image, current_color, background, stripe_rect); offset_y += current_row_height; } return rect_t{static_cast(x), static_cast(y), image.width, image.height}; } /** * draws a bouncy image with looping stripes, each time this function is called the image moves and the colors of the stripes are shifted * colors are in HSL * start positions are screen coordinates * steps for position and hue are scaled with 255 * returns the rect in which the image was drawn */ rect_t draw_bouncy_striped_bitmap(bitmap_t &image, uint16_t num_stripes, const RGB stripes[], RGB background ) { static int16_t x = start_x; static int16_t y = start_y; static int32_t scaled_x = start_x << 8; static int32_t scaled_y = start_y << 8; static int32_t move_x = x_step; static int32_t move_y = y_step; static rect_t rect = {}; const int32_t max_scaled_x = (SCREEN_WIDTH - image.width - 1) << 8; const int32_t max_scaled_y = (SCREEN_HEIGHT - image.height - 1) << 8; if (x_step >= max_scaled_x || x_step <= -max_scaled_x) { screen.setCursor(0, 5); screen.setTextColor(RGB(255, 0, 0).to_565()); screen.setTextSize(1); screen.println("x_step is too large"); return rect_t{}; } if (y_step >= max_scaled_y || y_step <= -max_scaled_y) { screen.setCursor(0, 5); screen.setTextColor(RGB(255, 0, 0).to_565()); screen.setTextSize(1); screen.println("y_step is too large"); return rect_t{}; } rect = draw_striped_bitmap(image, x, y, num_stripes, stripes, background, rect); scaled_x = scaled_x + move_x; scaled_y = scaled_y + move_y; if (scaled_x < 0) { scaled_x = -scaled_x; move_x = -move_x; } else if (scaled_x > max_scaled_x) { scaled_x = 2 * max_scaled_x - scaled_x; move_x = -move_x; } if (scaled_y < 0) { scaled_y = -scaled_y; move_y = -move_y; } else if (scaled_y > max_scaled_y) { scaled_y = 2 * max_scaled_y - scaled_y; move_y = -move_y; } x = (int16_t) (scaled_x >> 8); y = (int16_t) (scaled_y >> 8); return rect; }