From e60fa7740cd7d245d1b22a25fea9df0768d32668 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Sun, 19 May 2024 04:34:40 -0400 Subject: mouse support (working in qemu, semi-working in virtualbox) --- applications/init/source/main.cpp | 124 +++++++++++++++++++++++++++++++++----- 1 file changed, 108 insertions(+), 16 deletions(-) (limited to 'applications') diff --git a/applications/init/source/main.cpp b/applications/init/source/main.cpp index ed0ef8e..6aa85a4 100644 --- a/applications/init/source/main.cpp +++ b/applications/init/source/main.cpp @@ -1,28 +1,120 @@ #include +void overlay_encode( + daguerre::hilbert_color &dest, const daguerre::rgb24 &src) { + if (src.r != 0xff || src.g != 0x00 || src.b != 0xff) + daguerre::encode(dest, src); +} + +void invert(daguerre::rgb24 &dest, const daguerre::rgb24 &src) { + dest.r = 255 - src.r; + dest.g = 255 - src.g; + dest.b = 255 - src.b; +} + int main(int, char **) { - auto hfb = daguerre::get_hilbert_framebuffer(); - daguerre::image bim; + auto framebuffer = daguerre::get_hilbert_framebuffer(); - std::FILE *burdon = std::fopen("/assets/burden.ppm", "r"); - daguerre::try_load_ppm(burdon, bim); - std::fclose(burdon); + daguerre::image burden; + std::FILE *burden_file = std::fopen("/assets/burden.ppm", "r"); + daguerre::try_load_ppm(burden_file, burden); + std::fclose(burden_file); - unsigned width = bim.width < hfb.width ? bim.width : hfb.width; - unsigned height = bim.height < hfb.height ? bim.height : hfb.height; - unsigned x = (hfb.width - width) / 2; - unsigned y = (hfb.height - height) / 2; + daguerre::image pointer; + std::FILE *pointer_file = std::fopen("/assets/pointer.ppm", "r"); + daguerre::try_load_ppm(pointer_file, pointer); + std::fclose(pointer_file); + + 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; + + 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; + bool was_left_mouse_down = false; + + daguerre::overlay_region< + daguerre::hilbert_color, daguerre::rgb24, daguerre::encode>( + framebuffer, x, y, burden, 0, 0, width, height); while (1) { - daguerre::copy_region<>(hfb, bim, 0, 0, x, y, width, height); - while ((__euler_read_key_packet() & 0x0400ff) != 0x00005a) - ; - for (unsigned i = 0; i < bim.width * bim.height; ++i) { - bim.buffer[i].r = 255 - bim.buffer[i].r; - bim.buffer[i].g = 255 - bim.buffer[i].g; - bim.buffer[i].b = 255 - bim.buffer[i].b; + + __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; + + 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 (new_mouse_y < 0) + new_mouse_y = 0; + else if ((unsigned)new_mouse_y > height - pointer.height) + new_mouse_y = height - pointer.height; + + anything_changed = true; + + } + + if (!was_left_mouse_down && (mouse_buttons & __EULER_MB_LEFT)) + should_invert = true; + + was_left_mouse_down = mouse_buttons & __EULER_MB_LEFT; + + } + + else if (packet_type == __EULER_IPT_KEYBOARD) + if ((key_packet & 0x0400ff) == 0x00005a) + 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( + burden, 0, 0, burden, 0, 0, width, height); + + daguerre::overlay_region< + daguerre::hilbert_color, daguerre::rgb24, daguerre::encode>( + framebuffer, x, y, burden, 0, 0, width, height); + + anything_changed = true; + } + + if (anything_changed) { + daguerre::overlay_region< + daguerre::hilbert_color, daguerre::rgb24, daguerre::encode>( + 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, overlay_encode>( + framebuffer, new_mouse_x + x, new_mouse_y + y, + pointer, 0, 0, pointer.width, pointer.height); + } + } } -- cgit v1.2.3