diff options
Diffstat (limited to 'applications/goldman/source/renderer.cpp')
-rw-r--r-- | applications/goldman/source/renderer.cpp | 102 |
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 ¶m) { + 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); +} |