esp32displaytest/src/pride_flags.cpp
2022-03-12 12:33:52 +01:00

277 lines
8.2 KiB
C++

#include "ExtendedScreen.h"
#include "bitmap.h"
#include "colors.h"
#include <Arduino.h>
#include <Adafruit_SSD1351.h>
#include <SPI.h>
#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<int16_t>(offset_y),
.width = static_cast<uint16_t>(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<int16_t>(x), static_cast<int16_t>(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;
}