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:
parent
45bb1f36ee
commit
0c160eb956
4 changed files with 112 additions and 53 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
50
src/main.cpp
50
src/main.cpp
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue