277 lines
8.2 KiB
C++
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;
|
|
}
|