diff --git a/ramdisk/etc/graphics/cursor_normal.tga b/ramdisk/etc/graphics/cursor_normal.tga index 3eb74cb..b78816b 100644 Binary files a/ramdisk/etc/graphics/cursor_normal.tga and b/ramdisk/etc/graphics/cursor_normal.tga differ diff --git a/ramdisk/etc/graphics/window.tga b/ramdisk/etc/graphics/window.tga new file mode 100644 index 0000000..21b14f6 Binary files /dev/null and b/ramdisk/etc/graphics/window.tga differ diff --git a/src/corelib/stdlib.c b/src/corelib/stdlib.c new file mode 100644 index 0000000..6eaed42 --- /dev/null +++ b/src/corelib/stdlib.c @@ -0,0 +1,10 @@ +#include + +static unsigned long int next = 1; + +int rand(void) { + next = next * 1103515245 + 12345; + return (unsigned int)(next / 65536) % 32768; +} + +void srand(unsigned int seed) { next = seed; } \ No newline at end of file diff --git a/src/corelib/stdlib.h b/src/corelib/stdlib.h index f15b217..19feda5 100644 --- a/src/corelib/stdlib.h +++ b/src/corelib/stdlib.h @@ -4,4 +4,8 @@ #include #include +int rand(void); + +void srand(unsigned int seed); + #endif // __STDLIB_H__ \ No newline at end of file diff --git a/src/kernel/boot.c b/src/kernel/boot.c index fbbb909..6bb8233 100644 --- a/src/kernel/boot.c +++ b/src/kernel/boot.c @@ -8,7 +8,6 @@ #include #include #include -#include #include volatile struct limine_module_request mod_request = { @@ -43,8 +42,6 @@ void init_boot(int debug_info) { dprintf("[\e[0;32mSystem\e[0m] Initialized Mouse\n"); init_keyboard(); dprintf("[\e[0;32mSystem\e[0m] Initialized Keyboard\n"); - register_irqs(); - dprintf("[\e[0;32mSystem\e[0m] Registered IRQs\n"); rd = init_rd(); if (rd == NULL) { diff --git a/src/system/drivers/mouse.c b/src/system/drivers/mouse.c index 28742fb..2f67356 100644 --- a/src/system/drivers/mouse.c +++ b/src/system/drivers/mouse.c @@ -1,4 +1,3 @@ -// Credits to https://github.com/asterd-og/BlazarOS #include "mouse.h" uint8_t mouse_state = 0; @@ -7,6 +6,10 @@ uint8_t mouse_bytes[3] = {0, 0, 0}; uint32_t mouse_x = 0; uint32_t mouse_y = 0; +uint32_t old_pixels[50][50]; +uint32_t old_mouse_x = 0; +uint32_t old_mouse_y = 0; + int32_t mouse_wrap_x = 0; int32_t mouse_wrap_y = 0; @@ -15,6 +18,9 @@ bool mouse_right_pressed = false; bool mouse_moved = false; +char *mouse_img = NULL; +uint32_t mouse_img_size = 0; + void mouse_wait_write() { while ((inb8(0x64) & 2) != 0) { ; @@ -39,6 +45,52 @@ uint8_t mouse_read() { return inb8(0x60); } +void draw_mouse(int x, int y) { + if (mouse_img == NULL || mouse_img_size == 0) { + vfs_op_status status = driver_read( + vfs, 0x00000000, "/etc/graphics/cursor_normal.tga", &mouse_img); + if (status == STATUS_OK) { + mouse_img_size = + vfs_get_file_size(vfs, 0x00000000, "/etc/graphics/cursor_normal.tga"); + } else { + return; + } + } + + for (int i = 0; i < 50; i++) { + for (int j = 0; j < 50; j++) { + int pixel_x = x + i; + int pixel_y = y + j; + + old_pixels[i][j] = *(uint32_t *)(framebuffer->address + + pixel_x * (framebuffer->bpp >> 3) + + pixel_y * framebuffer->pitch); + } + } + + draw_tga_from_raw(x, y, mouse_img, mouse_img_size); +} + +void remove_mouse(int x, int y) { + for (int i = 0; i < 50; i++) { + for (int j = 0; j < 50; j++) { + int pixel_x = x + i; + int pixel_y = y + j; + + uint32_t old_pixel = old_pixels[i][j]; + + if (old_pixel != 0) { + uint32_t *framebuffer_address = + (uint32_t *)(framebuffer->address + + pixel_x * (framebuffer->bpp >> 3) + + pixel_y * framebuffer->pitch); + + *framebuffer_address = old_pixel; + } + } + } +} + void mouse_update(int8_t accel_x, int8_t accel_y) { if (mouse_wrap_x + accel_x <= 0) { mouse_wrap_x = 0; @@ -64,18 +116,11 @@ void mouse_update(int8_t accel_x, int8_t accel_y) { mouse_y = (uint32_t)mouse_wrap_y; if (should_draw_cursor) { - char *img; - uint32_t size; - - vfs_op_status status; - - status = - driver_read(vfs, 0x00000000, "/etc/graphics/cursor_normal.tga", &img); - - if (status == STATUS_OK) { - size = - vfs_get_file_size(vfs, 0x00000000, "/etc/graphics/cursor_normal.tga"); - draw_tga_from_raw(mouse_x, mouse_y, img, size); + if (old_mouse_x != mouse_x || old_mouse_y != mouse_y) { + remove_mouse(old_mouse_x, old_mouse_y); + draw_mouse(mouse_x, mouse_y); + old_mouse_x = mouse_x; + old_mouse_y = mouse_y; } } } @@ -96,7 +141,6 @@ void mouse_handler(int_frame_t *frame) { return; } switch (mouse_state) { - // Packet state case 0: mouse_wait_read(); mouse_bytes[0] = mouse_read(); @@ -146,4 +190,4 @@ void mouse_init() { mouse_read(); irq_register(12, mouse_handler); -} \ No newline at end of file +} diff --git a/src/system/pit/pit.c b/src/system/pit/pit.c index bd92678..fa0de93 100644 --- a/src/system/pit/pit.c +++ b/src/system/pit/pit.c @@ -1,9 +1,11 @@ #include "pit.h" +#include #include #include #include #include #include +#include uint64_t uptime_secs; uint16_t uptime_milis; @@ -58,12 +60,19 @@ void pit_set_count(uint16_t count) { return; } +void pit_handler(int_frame_t *frame) { + cur_frame = frame; + update_all_windows(); + pit_int(); +} + void pit_init() { pit_set_count(0); pit_set_divisor(1193182 / 1000); countdown = 0; uptime_milis = 0; uptime_secs = 0; + irq_register(0, pit_handler); } uint64_t pit_get_uptime_secs() { return uptime_secs; } diff --git a/src/system/utilities/irqs.h b/src/system/utilities/irqs.h deleted file mode 100644 index 295cb3d..0000000 --- a/src/system/utilities/irqs.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __IRQS_H__ -#define __IRQS_H__ - -#include -#include -#include -#include -#include -#include -#include - -#include - -void pit_handler(int_frame_t *frame) { - cur_frame = frame; - pit_int(); -} - -void register_irqs() { irq_register(0, pit_handler); } - -#endif // __IRQS_H_ \ No newline at end of file diff --git a/src/system/wm/windows.c b/src/system/wm/windows.c new file mode 100644 index 0000000..926304b --- /dev/null +++ b/src/system/wm/windows.c @@ -0,0 +1,106 @@ +#include "windows.h" + +window_t windows[MAX_WINDOWS]; +int num_windows = 0; + +void spawn_window(window_t *window) { + if (num_windows < MAX_WINDOWS) { + window->buffer = malloc(window->width * window->height * sizeof(uint32_t)); + window->old_buffer = + malloc(window->width * window->height * sizeof(uint32_t)); + if (window->buffer == NULL || window->old_buffer == NULL) { + dprintf("Failed to allocate memory for window buffer\n"); + return; + } + + memset(window->buffer, 0xFFFFFFFF, + window->width * window->height * sizeof(uint32_t)); + memcpy(window->old_buffer, window->buffer, + window->width * window->height * sizeof(uint32_t)); + + int i, j; + uint32_t pixel; + + for (i = 0; i < window->height; i++) { + for (j = 0; j < window->width; j++) { + pixel = window->buffer[i * window->width + j]; + uint8_t alpha = (pixel & ALPHA_MASK) >> ALPHA_SHIFT; + uint8_t red = (pixel & RED_MASK) >> RED_SHIFT; + uint8_t green = (pixel & GREEN_MASK) >> GREEN_SHIFT; + uint8_t blue = (pixel & BLUE_MASK) >> BLUE_SHIFT; + put_pixel_rgba(window->x + j, window->y + i, red, green, blue, alpha); + } + } + + char *img; + uint32_t size; + vfs_op_status status; + + status = driver_read(vfs, 0x00000000, DEFAULT_WIN_DEC, &img); + if (status == STATUS_OK) { + size = vfs_get_file_size(vfs, 0x00000000, DEFAULT_WIN_DEC); + draw_tga_from_raw(window->x, window->y, img, size); + } + + update_window(window); + } else { + dprintf("Maximum number of windows reached\n"); + } +} + +void update_window(window_t *window) { + int i, j; + uint32_t pixel; + + if (!window->initialized) { + for (i = 0; i < window->height; i++) { + for (j = 0; j < window->width; j++) { + pixel = window->buffer[i * window->width + j]; + uint8_t alpha = (pixel & ALPHA_MASK) >> ALPHA_SHIFT; + uint8_t red = (pixel & RED_MASK) >> RED_SHIFT; + uint8_t green = (pixel & GREEN_MASK) >> GREEN_SHIFT; + uint8_t blue = (pixel & BLUE_MASK) >> BLUE_SHIFT; + put_pixel_rgba(window->x + j, window->y + i, red, green, blue, alpha); + } + } + + char *img; + uint32_t size; + vfs_op_status status; + + status = driver_read(vfs, 0x00000000, DEFAULT_WIN_DEC, &img); + if (status == STATUS_OK) { + size = vfs_get_file_size(vfs, 0x00000000, DEFAULT_WIN_DEC); + draw_tga_from_raw(window->x, window->y, img, size); + } + + window->initialized = 1; + } else { + for (i = 0; i < window->height; i++) { + for (j = 0; j < window->width; j++) { + pixel = window->buffer[i * window->width + j]; + uint8_t alpha = (pixel & ALPHA_MASK) >> ALPHA_SHIFT; + uint8_t red = (pixel & RED_MASK) >> RED_SHIFT; + uint8_t green = (pixel & GREEN_MASK) >> GREEN_SHIFT; + uint8_t blue = (pixel & BLUE_MASK) >> BLUE_SHIFT; + put_pixel_rgba(window->x + j, window->y + i, red, green, blue, alpha); + } + } + + char *img; + uint32_t size; + vfs_op_status status; + + status = driver_read(vfs, 0x00000000, DEFAULT_WIN_DEC, &img); + if (status == STATUS_OK) { + size = vfs_get_file_size(vfs, 0x00000000, DEFAULT_WIN_DEC); + draw_tga_from_raw(window->x, window->y, img, size); + } + } +} + +void update_all_windows() { + for (int i = 0; i < num_windows; i++) { + update_window(&windows[i]); + } +} diff --git a/src/system/wm/windows.h b/src/system/wm/windows.h new file mode 100644 index 0000000..b4afd45 --- /dev/null +++ b/src/system/wm/windows.h @@ -0,0 +1,46 @@ +#ifndef __WINDOWS_H__ +#define __WINDOWS_H__ + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_WINDOWS 100 + +#define WIN_WIDTH 688 +#define WIN_HEIGHT 417 + +#define ALPHA_MASK 0xFF000000 +#define RED_MASK 0x00FF0000 +#define GREEN_MASK 0x0000FF00 +#define BLUE_MASK 0x000000FF + +#define ALPHA_SHIFT 24 +#define RED_SHIFT 16 +#define GREEN_SHIFT 8 +#define BLUE_SHIFT 0 + +#define DEFAULT_WIN_DEC "/etc/graphics/window.tga" + +typedef struct { + char *title; + int x; + int y; + int width; + int height; + uint32_t *buffer; + uint32_t *old_buffer; + int initialized; +} window_t; + +extern window_t windows[MAX_WINDOWS]; +extern int num_windows; + +void spawn_window(window_t *window); +void update_window(window_t *window); +void update_all_windows(); +#endif // __WINDOWS_H__ diff --git a/src/system/wm/wm.c b/src/system/wm/wm.c index ef28608..c53322f 100644 --- a/src/system/wm/wm.c +++ b/src/system/wm/wm.c @@ -1,15 +1,4 @@ #include "wm.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #define DHEIGHT 25 @@ -28,21 +17,18 @@ void init_taskbar() { } void init_wm() { + should_draw_cursor = true; + keyboard.out = false; + init_wallpaper(); init_taskbar(); - char *img; - uint32_t size; - - vfs_op_status status; + window_t test_window; + test_window.title = "Test Window"; + test_window.x = 100; + test_window.y = 100; + test_window.width = WIN_WIDTH; + test_window.height = WIN_HEIGHT; - status = driver_read(vfs, 0x00000000, "/root/test/test.tga", &img); - - if (status == STATUS_OK) { - size = vfs_get_file_size(vfs, 0x00000000, "/root/test/test.tga"); - draw_tga_from_raw(0, 0, img, size); - } - - should_draw_cursor = true; - keyboard.out = true; + spawn_window(&test_window); } \ No newline at end of file diff --git a/src/system/wm/wm.h b/src/system/wm/wm.h index b4da9f4..47018a8 100644 --- a/src/system/wm/wm.h +++ b/src/system/wm/wm.h @@ -1,8 +1,21 @@ #ifndef __GUI_H__ #define __GUI_H__ +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include extern bool should_draw_cursor; diff --git a/tools/boot.sh b/tools/boot.sh index c290051..be2158b 100755 --- a/tools/boot.sh +++ b/tools/boot.sh @@ -2,4 +2,4 @@ bash $(pwd)/tools/build.sh -qemu-system-x86_64 -vga std -debugcon stdio -hda image.iso "${@}" +qemu-system-x86_64 --enable-kvm -vga std -debugcon stdio -hda image.iso "${@}"