diff options
-rw-r--r-- | applications/init/source/main.cpp | 126 | ||||
-rw-r--r-- | euler/include/algorithm | 12 | ||||
-rw-r--r-- | libraries/daguerre/include/daguerre.hpp | 100 |
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; |