94 lines
2.4 KiB
C++
94 lines
2.4 KiB
C++
|
|
#pragma once
|
||
|
|
|
||
|
|
#include <stdint.h>
|
||
|
|
#include "datatypes.cpp"
|
||
|
|
|
||
|
|
namespace UwU {
|
||
|
|
|
||
|
|
class Helpers {
|
||
|
|
public:
|
||
|
|
static uint8_t lerp8(uint8_t a, uint8_t b, uint8_t t) {
|
||
|
|
uint16_t product = (a * (255 - t)) + (b * t);
|
||
|
|
return product / 255;
|
||
|
|
}
|
||
|
|
|
||
|
|
static Color lerpColor(Color a, Color b, uint8_t t) {
|
||
|
|
Color mixed = Color();
|
||
|
|
mixed.r = lerp8(a.r, b.r, t);
|
||
|
|
mixed.g = lerp8(a.g, b.g, t);
|
||
|
|
mixed.b = lerp8(a.b, b.b, t);
|
||
|
|
mixed.a = lerp8(a.a, b.a, t); // maybe the alpha channel should be handled differently?
|
||
|
|
return mixed;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void bresenhamLow(uint16_t x0, int16_t y0, uint16_t x1, int16_t y1, int16_t* LUT) {
|
||
|
|
int16_t dx = int16_t(x1) - int16_t(x0);
|
||
|
|
int16_t dy = y1 - y0;
|
||
|
|
int16_t yi = 1;
|
||
|
|
if (dy < 0) {
|
||
|
|
yi = -1;
|
||
|
|
dy = -dy;
|
||
|
|
}
|
||
|
|
int16_t d = (2 * dy) - dx;
|
||
|
|
int16_t y = y0;
|
||
|
|
for (uint16_t x = x0; x <= x1; x++) {
|
||
|
|
LUT[x] = y;
|
||
|
|
if (d > 0) {
|
||
|
|
y += yi;
|
||
|
|
d += (2 * (dy - dx));
|
||
|
|
} else {
|
||
|
|
d += (2 * dy);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void bresenhamHigh(uint16_t x0, int16_t y0, uint16_t x1, int16_t y1, int16_t* LUT) {
|
||
|
|
int16_t dx = (int16_t)x1 - (int16_t)x0;
|
||
|
|
int16_t dy = y1 - y0;
|
||
|
|
int16_t xi = 1;
|
||
|
|
if (dx < 0) {
|
||
|
|
xi = -1;
|
||
|
|
dx = -dx;
|
||
|
|
}
|
||
|
|
int16_t d = (2 * dx) - dy;
|
||
|
|
int16_t x = (int16_t)x0;
|
||
|
|
for (int16_t y = y0; y <= y1; y++) {
|
||
|
|
LUT[x] = y;
|
||
|
|
if (d > 0) {
|
||
|
|
x += xi;
|
||
|
|
d += (2 * (dx - dy));
|
||
|
|
} else {
|
||
|
|
d += (2 * dx);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// x1 must >= x0 && LUT must be size x1 + 1
|
||
|
|
static void bresenham(uint16_t x0, int16_t y0, uint16_t x1, int16_t y1, int16_t* LUT) {
|
||
|
|
if (x0 == x1) {
|
||
|
|
// catch vline condition
|
||
|
|
LUT[x0] = y1;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (y0 == y1) {
|
||
|
|
// catch hline condition
|
||
|
|
for (uint16_t i = x0; i <= x1; i++) {
|
||
|
|
LUT[i] = y1;
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (abs(y1 - y0) <= x1) {
|
||
|
|
bresenhamLow(x0, y0, x1, y1, LUT);
|
||
|
|
} else {
|
||
|
|
if (y0 > y1) {
|
||
|
|
bresenhamHigh(x1, y1, x0, y0, LUT);
|
||
|
|
} else {
|
||
|
|
bresenhamHigh(x0, y0, x1, y1, LUT);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|