1
0
Fork 0
mirror of https://gitlab.com/niansa/minituxi.git synced 2025-03-06 20:49:18 +01:00

Specific Coord and Rect types

This commit is contained in:
Nils 2021-08-08 18:15:37 +02:00
parent 45bb1f36ee
commit 0c160eb956
4 changed files with 112 additions and 53 deletions

View file

@ -24,4 +24,4 @@ set(SRCS
add_executable(${CMAKE_PROJECT_NAME} ${SRCS})
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC pthread)
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC -static pthread)

View file

@ -33,6 +33,8 @@ inline T check_sysc(T v, std::string_view msg = "Syscall failed") {
return v;
}
class SysInfo {
struct sysinfo i;
@ -47,7 +49,6 @@ public:
};
class Mounts {
public:
Mounts() {
@ -83,6 +84,17 @@ public:
struct Size {
uint width, height;
};
struct Coord {
uint x, y;
};
struct Rect {
Coord first, second;
};
class Framebuffer {
using pixType = uint32_t;
@ -122,6 +134,19 @@ public:
return vinfo;
}
Rect get_centered(Size s) {
Coord rad;
rad.x = vinfo.xres / 2 - s.width / 2;
rad.y = vinfo.yres / 2 - s.height / 2;
return {
{vinfo.xres / 2 - s.width / 2, vinfo.yres / 2 - s.height / 2},
{vinfo.xres / 2 + s.width / 2, vinfo.yres / 2 + s.height / 2}
};
}
Coord get_center() {
return {vinfo.xres / 2, vinfo.yres / 2};
}
bool inBounds(size_t idx) {
return idx < bufArrSize;
}
@ -139,9 +164,9 @@ public:
dBuf[idx] = color;
}
}
void draw(uint x, uint y, pixType color) {
if (x < vinfo.xres && y < vinfo.yres) {
dBuf[y * vinfo.xres + x] = color;
void draw(Coord c, pixType color) {
if (c.x < vinfo.xres && c.y < vinfo.yres) {
dBuf[c.y * vinfo.xres + c.x] = color;
}
}
@ -151,34 +176,33 @@ public:
}
}
void draw_text(std::string_view str, uint x, uint y, pixType color = 0xFFFFFF);
void draw_text(std::string_view str, Coord coord, pixType color = 0xFFFFFF, bool centered = false);
void draw_horizontal_line(uint x1, uint x2, uint y, pixType color) {
for (uint i = x1; i < x2; i++) {
draw(i, y, color);
draw({i, y}, color);
}
}
void draw_vertical_line(uint x, uint y1, uint y2, pixType color) {
for (uint i = y1; i < y2; i++) {
draw(x, i, color);
draw({x, i}, color);
}
}
void draw_line(uint x1, uint y1, uint x2, uint y2, pixType color);
void draw_line(const Rect& r, pixType color);
void draw_circle(double cx, double cy, uint radius, pixType color, bool filled = false);
void draw_rect(uint x1, uint y1, uint x2, uint y2, pixType color) {
void draw_rect(const Rect& r, pixType color) {
// Individual lines
draw_line(x1, y1, x2, y1, color);
draw_line(x1, y1, x1, y2, color);
draw_line(x2, y1, x2, y2, color);
draw_line(x1, y2, x2, y2, color);
draw_line({r.first, {r.second.x, r.first.y}}, color);
draw_line({r.first, {r.first.x, r.second.y}}, color);
draw_line({{r.second.x, r.first.y}, r.second}, color);
draw_line({{r.first.x, r.second.y}, r.second}, color);
}
void draw_rect_filled(uint x1, uint y1, uint x2, uint y2, pixType color);
void draw_rect_filled(const Rect& r, pixType color);
};
class Mouse {
int mouse_fd;

View file

@ -11,11 +11,38 @@
class ProgressWindow {
System::Rect wRect;
System::Rect barRect;
uint barX = 0;
uint textX;
public:
std::string text = "Loading...";
ProgressWindow(const System::Rect& wRect) : wRect(wRect) {
barRect = {wRect.first.x+10, wRect.first.y+10, wRect.second.x-10, wRect.first.y+20};
textX = wRect.first.x+(wRect.second.x-wRect.first.x)/2;
}
void draw(System::Framebuffer& fb) const {
fb.draw_rect_filled(wRect, 0xFFFFFF); // Window
fb.draw_text(text, {textX, wRect.second.y-Font::height}, 0x000000, true); // Text
fb.draw_rect_filled({barRect.first, {barRect.first.x+barX, barRect.second.y}}, 0x0000FF); // Progress bar
fb.draw_rect(barRect, 0x000000); // Progress bar outline
}
void updateProgress(uint8_t percentage) {
if (percentage <= 100) {
barX = (barRect.second.x-barRect.first.x)/100.f*percentage;
}
}
};
struct UMain {
std::mutex mutex;
System::Framebuffer fb;
System::Mouse mouse;
struct {uint x = 100, y = 100;} mousePos;
System::Coord mousePos;
void pollLoop() {
while (true) {
@ -33,20 +60,25 @@ struct UMain {
void drawLoop() {
using namespace std::literals::chrono_literals;
ProgressWindow pWin(fb.get_centered({500, 50}));
uint8_t p = 0;
while (true) {
mutex.unlock();
std::this_thread::sleep_for(15ms);
mutex.lock();
// Clear screen
fb.fill(0x000000);
// Draw stuff
fb.draw_rect_filled(0, 0, 100, 100, 0xFAFA0F);
fb.draw_circle(100, 100, 50, 0xFF0000, true);
fb.draw_horizontal_line(0, 100, 100, 0x0000FF);
fb.draw_text("Hello world!", 250, 250);
// Draw mouse
fb.draw_circle(mousePos.x, mousePos.y, 5, 0xFFFFFF, true);
fb.draw_text("This is the cursor", mousePos.x + 20, mousePos.y - Font::height / 2, 0x00FF00);
// Some window with a progress bar
if (p != 100) {
pWin.text = "Loading... "+std::to_string(p)+"%";
pWin.draw(fb);
pWin.updateProgress(p++);
} else {
// Draw mouse
fb.draw_circle(mousePos.x, mousePos.y, 5, 0xFFFFFF, true);
fb.draw_text("This is the cursor", {mousePos.x + 20, mousePos.y - Font::height / 2}, 0x00FF00);
fb.draw_line({{0, 0}, mousePos}, 0xFF00FF);
}
// Display
fb.display();
}

View file

@ -26,35 +26,39 @@ void critical_stop(std::string_view msg) {
void Framebuffer::draw_text(std::string_view str, uint x, uint y, pixType color) {
void Framebuffer::draw_text(std::string_view str, Coord coord, pixType color, bool centered) {
// Get half pixel width if centered
if (centered) {
coord.x -= (str.size() * Font::width) / 2;
}
// Iterate through string
for (const auto c : str) {
// Get bitmap
auto bitmap = Font::getChar(c);
// Render
int rx = 0;
int ry = 0;
Coord r = {0,0};
for (const auto pixel : bitmap) {
if (rx == Font::width) {
rx = 0;
ry++;
if (r.x == Font::width) {
r.x = 0;
r.y++;
}
if (ry == Font::height) {
if (r.y == Font::height) {
break;
}
if (pixel) {
draw(x + rx, y + ry, color);
draw({coord.x + r.x, coord.y + r.y}, color);
}
rx++;
r.x++;
}
// Increase x
x += Font::width;
coord.x += Font::width;
}
}
void Framebuffer::draw_line(uint x1, uint y1, uint x2, uint y2, pixType pixel) {
void Framebuffer::draw_line(const Rect& r, pixType pixel) {
// Deltas
int dx = x2 - x1;
int dy = y2 - y1;
int dx = r.second.x - r.first.x;
int dy = r.second.y - r.first.y;
// Absolute deltas
uint dxabs = abs(dx);
uint dyabs = abs(dy);
@ -64,8 +68,8 @@ void Framebuffer::draw_line(uint x1, uint y1, uint x2, uint y2, pixType pixel) {
// Misc stuff
int x = dyabs / 2;
int y = dxabs / 2;
int px = x1;
int py = y1;
int px = r.first.x;
int py = r.first.y;
if (dxabs>=dyabs) {
for (int i = 0; i < dxabs; i++) {
@ -75,7 +79,7 @@ void Framebuffer::draw_line(uint x1, uint y1, uint x2, uint y2, pixType pixel) {
py += sdy;
}
px += sdx;
draw(px,py,pixel);
draw({static_cast<uint>(px), static_cast<uint>(py)}, pixel);
}
} else {
for (int i = 0; i < dyabs; i++) {
@ -85,7 +89,7 @@ void Framebuffer::draw_line(uint x1, uint y1, uint x2, uint y2, pixType pixel) {
px += sdx;
}
py += sdy;
draw(px,py,pixel);
draw({static_cast<uint>(px), static_cast<uint>(py)}, pixel);
}
}
}
@ -96,10 +100,10 @@ void Framebuffer::draw_circle(double cx, double cy, uint radius, pixType color,
draw_horizontal_line(cx - x, cx + x, cy + y, color);
draw_horizontal_line(cx - x, cx + x, cy - y, color);
} else {
draw(cx + x, cy + y, color);
draw(cx - x, cy + y, color);
draw(cx + x, cy - y, color);
draw(cx - x, cy - y, color);
draw({static_cast<uint>(cx + x), static_cast<uint>(cy + y)}, color);
draw({static_cast<uint>(cx - x), static_cast<uint>(cy + y)}, color);
draw({static_cast<uint>(cx + x), static_cast<uint>(cy - y)}, color);
draw({static_cast<uint>(cx - x), static_cast<uint>(cy - y)}, color);
}
};
auto plot8points = [&] (double x, double y) {
@ -126,13 +130,12 @@ void Framebuffer::draw_circle(double cx, double cy, uint radius, pixType color,
}
}
void Framebuffer::draw_rect_filled(uint x1, uint y1, uint x2, uint y2, pixType color) {
for (auto x = x1,
y = y1;;) {
draw(x, y, color);
if (x++ == x2) {
x = x1;
if (y++ == y2) {
void Framebuffer::draw_rect_filled(const Rect &r, pixType color) {
for (auto p = r.first;;) {
draw({p.x, p.y}, color);
if (p.x++ == r.second.x) {
p.x = r.first.x;
if (p.y++ == r.second.y) {
break;
}
}