summaryrefslogtreecommitdiff
path: root/applications/goldman/source/renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'applications/goldman/source/renderer.cpp')
-rw-r--r--applications/goldman/source/renderer.cpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/applications/goldman/source/renderer.cpp b/applications/goldman/source/renderer.cpp
new file mode 100644
index 0000000..629c375
--- /dev/null
+++ b/applications/goldman/source/renderer.cpp
@@ -0,0 +1,102 @@
+#include "renderer.hpp"
+
+renderer::renderer(
+ daguerre::image<daguerre::hilbert_color> &&fb,
+ daguerre::image<daguerre::hilbert_color> &&bg,
+ daguerre::hilbert_color bgc,
+ daguerre::image<daguerre::hilbert_color> &&c,
+ daguerre::hilbert_color cbg)
+
+: framebuffer(std::move(fb)),
+ double_buffer(framebuffer.width, framebuffer.height),
+ background(std::move(bg)), cursor(std::move(c)), cursor_background(cbg),
+ cursor_x(framebuffer.width / 2), cursor_y(framebuffer.height / 2) {
+
+ euler::syscall::create_private_socket(dispatcher_handle_1, dispatcher_handle_2);
+
+ if (background.width != framebuffer.width ||
+ background.height != framebuffer.height) {
+
+ daguerre::image<daguerre::hilbert_color>
+ new_background(framebuffer.width, framebuffer.height);
+
+ new_background.fill(bgc);
+
+ int from_x = 0;
+ int from_y = 0;
+ int to_x = framebuffer.width / 2 - background.width / 2;
+ int to_y = framebuffer.height / 2 - background.height / 2;
+ int width = background.width;
+ int height = background.height;
+
+ daguerre::make_safe(to_x, from_x, width, 0, framebuffer.width);
+ daguerre::make_safe(to_y, from_y, height, 0, framebuffer.height);
+
+ new_background.copy_from(background, to_x, to_y, from_x, from_y, width, height);
+ background = std::move(new_background);
+
+ }
+
+}
+
+template <class color_t>
+void overlay_trans(color_t &to, const color_t &from, const color_t &param) {
+ if (from != param)
+ to = from;
+}
+
+void renderer::do_render() {
+
+ double_buffer.copy_from(background, 0, 0);
+
+ for (auto it = windows.begin(); it != windows.end(); ++it)
+
+ double_buffer.copy_from(
+ (*it)->contents, (*it)->x, (*it)->y, 0, 0,
+ std::min((*it)->contents.width, double_buffer.width - (*it)->x),
+ std::min((*it)->contents.height, double_buffer.height - (*it)->y));
+
+ double_buffer.convert_from(
+ cursor_background, cursor, cursor_x, cursor_y, 0, 0,
+ std::min(cursor.width, framebuffer.width - cursor_x),
+ std::min(cursor.height, framebuffer.height - cursor_y),
+ &overlay_trans);
+
+}
+
+[[noreturn]] void renderer::render_thread_main() {
+ euler::syscall::set_thread_name("render thread");
+ while (true) {
+ uint8_t byte;
+ euler::syscall::read_from_stream(dispatcher_handle_2, 1, &byte);
+ mut.lock();
+ euler::syscall::clear_socket_read_queue(dispatcher_handle_2);
+ do_render();
+ mut.unlock();
+ framebuffer.copy_from(double_buffer, 0, 0);
+ }
+}
+
+void renderer::bump_cursor(int x_offset, int y_offset) {
+
+ cursor_x += x_offset;
+ if (cursor_x < 0)
+ cursor_x = 0;
+ else if (cursor_x >= framebuffer.width)
+ cursor_x = framebuffer.width - 1;
+
+ cursor_y += y_offset;
+ if (cursor_y < 0)
+ cursor_y = 0;
+ else if (cursor_y >= framebuffer.height)
+ cursor_y = framebuffer.height - 1;
+
+}
+
+void renderer::add_window(const window *w) {
+ windows.push_back(w);
+}
+
+void renderer::remove_window(const window *w) {
+ windows.remove(w);
+}