summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenji Dial <benji@benjidial.net>2024-05-19 14:39:06 -0400
committerBenji Dial <benji@benjidial.net>2024-05-19 14:39:06 -0400
commit5a54df93c4e9368c36e69d1e9c88cd2904e92308 (patch)
tree094f294c51701a34a6ce18b43965fff708f3fdd5
parent649ff9636fe7289749c91141bbf32b2dcbe6dde4 (diff)
downloadhilbert-os-5a54df93c4e9368c36e69d1e9c88cd2904e92308.tar.gz
rework daguerre a bit
-rw-r--r--applications/init/source/main.cpp126
-rw-r--r--euler/include/algorithm12
-rw-r--r--libraries/daguerre/include/daguerre.hpp100
3 files changed, 139 insertions, 99 deletions
diff --git a/applications/init/source/main.cpp b/applications/init/source/main.cpp
index c5df77c..cae17a2 100644
--- a/applications/init/source/main.cpp
+++ b/applications/init/source/main.cpp
@@ -1,23 +1,37 @@
#include <daguerre.hpp>
-void alpha_overlay(
- daguerre::hilbert_color &dest, const daguerre::rgb24 &src) {
- if (src.r != 0xff || src.g != 0x00 || src.b != 0xff)
- daguerre::default_overlay(dest, src);
-}
+static daguerre::hilbert_color transparent_color;
-void invert(daguerre::rgb24 &dest, const daguerre::rgb24 &src) {
- dest.r = 255 - src.r;
- dest.g = 255 - src.g;
- dest.b = 255 - src.b;
+void alpha_overlay(
+ daguerre::hilbert_color &dest, const daguerre::hilbert_color &src) {
+ if (src != transparent_color)
+ dest = src;
}
int main(int, char **) {
- auto framebuffer = daguerre::get_hilbert_framebuffer();
-
- daguerre::image<daguerre::rgb24> burden;
- daguerre::try_load_ppm("/assets/burden.ppm", burden);
+ daguerre::default_overlay(
+ transparent_color, (daguerre::rgb24){.r = 255, .g = 0, .b = 255});
+
+ auto raw_framebuffer = daguerre::get_hilbert_framebuffer();
+ const unsigned fbw = raw_framebuffer.width;
+ const unsigned fbh = raw_framebuffer.height;
+
+ daguerre::image<daguerre::rgb24> raw_burden;
+ daguerre::try_load_ppm("/assets/burden.ppm", raw_burden);
+
+ daguerre::image<daguerre::rgb24> burden_stretch(fbw, fbh);
+ daguerre::image<daguerre::rgb24> burden_stretch_inverted(fbw, fbh);
+ for (unsigned y = 0; y < fbh; ++y)
+ for (unsigned x = 0; x < fbw; ++x) {
+ daguerre::rgb24 color = raw_burden.get(
+ x * raw_burden.width / fbw, y * raw_burden.height / fbh);
+ burden_stretch.set(x, y, color);
+ burden_stretch_inverted.set(x, y, {
+ .r = (uint8_t)(255 - color.r),
+ .g = (uint8_t)(255 - color.g),
+ .b = (uint8_t)(255 - color.b)});
+ }
daguerre::image<daguerre::rgb24> pointer;
daguerre::try_load_ppm("/assets/pointer.ppm", pointer);
@@ -25,54 +39,64 @@ int main(int, char **) {
daguerre::fixed_bitmap_font<bool> terminus;
daguerre::try_load_psf("/assets/terminus-bold-18x10.psf", terminus);
- terminus.overlay_text<>(burden, 0, 0, "this is a test");
+ terminus.overlay_text<>(burden_stretch, 0, 0, "this is a test");
+ terminus.overlay_text<>(burden_stretch_inverted, 0, 0, "tset a si siht");
+
+ daguerre::image<daguerre::hilbert_color>
+ burden_stretch_hilbert(burden_stretch);
+
+ daguerre::image<daguerre::hilbert_color>
+ burden_stretch_inverted_hilbert(burden_stretch_inverted);
+
+ daguerre::image<daguerre::hilbert_color> pointer_hilbert(pointer);
- int32_t width = burden.width < framebuffer.width
- ? burden.width : framebuffer.width;
- int32_t height = burden.height < framebuffer.height
- ? burden.height : framebuffer.height;
- unsigned x = (framebuffer.width - width) / 2;
- unsigned y = (framebuffer.height - height) / 2;
+ daguerre::image<daguerre::hilbert_color> double_buffer(
+ fbw + pointer.width - 1, fbh + pointer.height - 1);
- int32_t new_mouse_x = width / 2;
- int32_t new_mouse_y = height / 2;
- int32_t old_mouse_x = new_mouse_x;
- int32_t old_mouse_y = new_mouse_y;
+ int32_t mouse_x = fbw / 2;
+ int32_t mouse_y = fbh / 2;
bool was_left_mouse_down = false;
- daguerre::overlay_region<>(framebuffer, x, y, burden, 0, 0, width, height);
+ bool should_draw = true;
while (1) {
+ if (should_draw) {
+ double_buffer.overlay_from<>(
+ burden_stretch_hilbert, 0, 0, 0, 0, fbw, fbh);
+ double_buffer.overlay_from<daguerre::hilbert_color, alpha_overlay>(
+ pointer_hilbert, mouse_x, mouse_y,
+ 0, 0, pointer.width, pointer.height);
+ raw_framebuffer.overlay_from<>(double_buffer, 0, 0, 0, 0, fbw, fbh);
+ should_draw = false;
+ }
+
__euler_mouse_buttons mouse_buttons;
int16_t mouse_change_x, mouse_change_y;
uint32_t key_packet;
__euler_input_packet_type packet_type = __euler_get_input_packet(
mouse_buttons, mouse_change_x, mouse_change_y, key_packet);
- bool anything_changed = false;
bool should_invert = false;
if (packet_type == __EULER_IPT_MOUSE) {
if (mouse_change_x != 0 || mouse_change_y != 0) {
- old_mouse_x = new_mouse_x;
- old_mouse_y = new_mouse_y;
- new_mouse_x += mouse_change_x;
- new_mouse_y += mouse_change_y;
+ mouse_x += mouse_change_x;
+ mouse_y += mouse_change_y;
- if (new_mouse_x < 0)
- new_mouse_x = 0;
- else if ((unsigned)new_mouse_x > width - pointer.width)
- new_mouse_x = width - pointer.width;
+ if (mouse_x < 0)
+ mouse_x = 0;
+ else if ((unsigned)mouse_x >= fbw)
+ mouse_x = fbw - 1;
- if (new_mouse_y < 0)
- new_mouse_y = 0;
- else if ((unsigned)new_mouse_y > height - pointer.height)
- new_mouse_y = height - pointer.height;
+ if (mouse_y < 0)
+ mouse_y = 0;
+ else if ((unsigned)mouse_y >= fbh)
+ mouse_y = fbh - 1;
- anything_changed = true;
+ should_draw = true;
}
@@ -88,28 +112,8 @@ int main(int, char **) {
should_invert = true;
if (should_invert) {
-
- //this works with the current implementation of overlay_region, but
- //maybe it would be better to have a dedicated function for when the
- //two regions are exactly the same, given the comment on overlay_region.
- daguerre::overlay_region<daguerre::rgb24, daguerre::rgb24, invert>(
- burden, 0, 0, burden, 0, 0, width, height);
-
- daguerre::overlay_region<>(
- framebuffer, x, y, burden, 0, 0, width, height);
-
- anything_changed = true;
-
- }
-
- if (anything_changed) {
- daguerre::overlay_region<>(
- framebuffer, old_mouse_x + x, old_mouse_y + y, burden,
- old_mouse_x, old_mouse_y, pointer.width, pointer.height);
- daguerre::overlay_region<
- daguerre::hilbert_color, daguerre::rgb24, alpha_overlay>(
- framebuffer, new_mouse_x + x, new_mouse_y + y,
- pointer, 0, 0, pointer.width, pointer.height);
+ daguerre::swap(burden_stretch_hilbert, burden_stretch_inverted_hilbert);
+ should_draw = true;
}
}
diff --git a/euler/include/algorithm b/euler/include/algorithm
new file mode 100644
index 0000000..08702f9
--- /dev/null
+++ b/euler/include/algorithm
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace std {
+
+ template <class t>
+ void swap(t &a, t &b) {
+ t tmp = a;
+ a = b;
+ b = tmp;
+ }
+
+}
diff --git a/libraries/daguerre/include/daguerre.hpp b/libraries/daguerre/include/daguerre.hpp
index c236cb9..9468826 100644
--- a/libraries/daguerre/include/daguerre.hpp
+++ b/libraries/daguerre/include/daguerre.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <algorithm>
#include <stdint.h>
#include <cstring>
#include <cstdio>
@@ -14,6 +15,11 @@ namespace daguerre {
uint8_t b;
};
+ template <class color_t>
+ static inline void default_overlay(color_t &dest, const color_t &src) {
+ dest = src;
+ }
+
static inline void default_overlay(hilbert_color &dest, const rgb24 &src) {
dest = __euler_encode_color(src.r, src.g, src.b);
}
@@ -53,7 +59,14 @@ namespace daguerre {
delete[] buffer;
}
- image(const image<color_t> &other) = delete;
+ template <class other_color_t,
+ void overlay(color_t &, const other_color_t &) = default_overlay>
+ image(const image<other_color_t> &other)
+ : delete_buffer_on_destruct(true),
+ buffer(new color_t[other.width * other.height]), width(other.width),
+ height(other.height), pitch(other.width) {
+ overlay_from<other_color_t, overlay>(other, 0, 0, 0, 0, width, height);
+ }
image(image<color_t> &&other)
: delete_buffer_on_destruct(other.delete_buffer_on_destruct),
@@ -62,7 +75,19 @@ namespace daguerre {
other.buffer = 0;
}
- image<color_t> &operator =(const image<color_t> &other) = delete;
+ template <class other_color_t,
+ void overlay(color_t &, const other_color_t &) = default_overlay>
+ image<color_t> &operator =(const image<other_color_t> &other) {
+ if (delete_buffer_on_destruct && buffer)
+ delete[] buffer;
+ delete_buffer_on_destruct = true;
+ width = other.width;
+ height = other.height;
+ pitch = width;
+ buffer = new color_t[width * height];
+ overlay_from<other_color_t, overlay>(other, 0, 0, 0, 0, width, height);
+ return *this;
+ }
image<color_t> &operator =(image<color_t> &&other) {
if (delete_buffer_on_destruct && buffer)
@@ -84,46 +109,45 @@ namespace daguerre {
buffer[y * pitch + x] = c;
}
- };
+ void copy_from(
+ const image<color_t> &other, unsigned to_x, unsigned to_y,
+ unsigned from_x, unsigned from_y, unsigned width, unsigned height) {
- //it is assumed that the regions do not overlap in memory.
- //copies into [to_x, to_x + width) x [to_y, to_y + height)
- //from [from_x, from_x + width) x [from_y, from_y + height).
- template <class color_t>
- void copy_region(
- image<color_t> &to, unsigned to_x, unsigned to_y,
- const image<color_t> &from, unsigned from_x, unsigned from_y,
- unsigned width, unsigned height) {
+ color_t *to_start = buffer + pitch * to_y + to_x;
+ const color_t *from_start = other.buffer + other.pitch * from_y + from_x;
- color_t *to_start = to.buffer + to.pitch * to_y + to_x;
- const color_t *from_start = from.buffer + from.pitch * from_y + from_x;
+ for (unsigned y = 0; y < height; ++y)
+ std::memcpy(
+ to_start + pitch * y, from_start + other.pitch * y,
+ width * sizeof(color_t));
- for (unsigned y = 0; y < height; ++y)
- std::memcpy(
- to_start + to.pitch * y, from_start + from.pitch * y,
- width * sizeof(color_t));
+ }
- }
+ template <class other_color_t,
+ void overlay(color_t &, const other_color_t &) = default_overlay>
+ void overlay_from(
+ const image<other_color_t> &other, unsigned to_x, unsigned to_y,
+ unsigned from_x, unsigned from_y, unsigned width, unsigned height) {
+
+ color_t *to_start = buffer + pitch * to_y + to_x;
+ const other_color_t *from_start =
+ other.buffer + other.pitch * from_y + from_x;
- //it is assumed that the regions do not overlap in memory.
- //copies into [to_x, to_x + width) x [to_y, to_y + height)
- //from [from_x, from_x + width) x [from_y, from_y + height).
- template <
- class to_color_t, class from_color_t,
- void overlay(to_color_t &dest, const from_color_t &src) = default_overlay>
- void overlay_region(
- image<to_color_t> &to, unsigned to_x, unsigned to_y,
- const image<from_color_t> &from, unsigned from_x, unsigned from_y,
- unsigned width, unsigned height) {
-
- to_color_t *to_start = to.buffer + to.pitch * to_y + to_x;
- const from_color_t *from_start =
- from.buffer + from.pitch * from_y + from_x;
-
- for (unsigned y = 0; y < height; ++y)
- for (unsigned x = 0; x < width; ++x)
- overlay(to_start[to.pitch * y + x], from_start[from.pitch * y + x]);
+ for (unsigned y = 0; y < height; ++y)
+ for (unsigned x = 0; x < width; ++x)
+ overlay(to_start[pitch * y + x], from_start[other.pitch * y + x]);
+ }
+
+ };
+
+ template <class color_t>
+ void swap(image<color_t> &a, image<color_t> &b) {
+ std::swap(a.delete_buffer_on_destruct, b.delete_buffer_on_destruct);
+ std::swap(a.buffer, b.buffer);
+ std::swap(a.width, b.width);
+ std::swap(a.height, b.height);
+ std::swap(a.pitch, b.pitch);
}
image<hilbert_color> get_hilbert_framebuffer();
@@ -159,8 +183,8 @@ namespace daguerre {
if (ch == 0)
return;
if (ch < 128) {
- overlay_region<target_color_t, color_t, overlay>(
- target, x, y, glyphs[ch], 0, 0, width, height);
+ target.template overlay_from<color_t, overlay>(
+ glyphs[ch], x, y, 0, 0, width, height);
x += width;
}
++text;