diff --git a/sortix.c b/sortix.c index fb32f0f..c646a55 100644 --- a/sortix.c +++ b/sortix.c @@ -22,6 +22,7 @@ struct window_data { uint32_t window_id; int modifiers; + uint32_t *buffer; }; static int default_window_width = 600; @@ -111,6 +112,10 @@ static void on_resize(void *ctx, uint32_t window_id, uint32_t width, uint32_t he if (!width || !height) return; + free(window_data->buffer); + // TODO: Overflow when multiplying + window_data->buffer = mem_alloc(width * height * sizeof(uint32_t)); + current_dev->size.x2 = width; current_dev->size.y2 = height; if (current_dev->resize_handler) @@ -155,6 +160,7 @@ static unsigned char *sortix_init_driver(unsigned char *param, unsigned char *di static struct graphics_device *sortix_init_device(void) { + // TODO: Multi-window support struct graphics_device *dev = mem_calloc(sizeof(struct graphics_device)); dev->size.x1 = 0; @@ -167,6 +173,8 @@ static struct graphics_device *sortix_init_device(void) struct window_data *window_data = mem_calloc(sizeof(struct window_data)); dev->driver_data = window_data; window_data->window_id = 0; + // TODO: Overflow when multiplying + window_data->buffer = mem_alloc(default_window_width * default_window_height * sizeof(uint32_t)); display_create_window(connection, window_data->window_id); display_resize_window(connection, window_data->window_id, dev->size.x2, dev->size.y2); @@ -181,6 +189,7 @@ static void sortix_shutdown_device(struct graphics_device *dev) { struct window_data *window_data = dev->driver_data; display_destroy_window(connection, window_data->window_id); + free(window_data->buffer); free(window_data); } @@ -234,61 +243,61 @@ static void sortix_unregister_bitmap(struct bitmap *bmp) mem_free(bmp->data); } -static void sortix_draw_bitmap(struct graphics_device *dev, struct bitmap *bmp, int x1, int y1) +static void sortix_draw_bitmap(struct graphics_device *dev, struct bitmap *bmp, int x, int y) { - struct window_data *window_data = dev->driver_data; + CLIP_DRAW_BITMAP - size_t width = bmp->x; - size_t height = bmp->y; + struct window_data *window_data = dev->driver_data; + int pitch = dev->size.x2; + + int width = bmp->x; + int height = bmp->y; if (!width || !height) return; - // TODO: Overflow when multiplying - uint32_t *buffer = mem_alloc(width * height * sizeof(uint32_t)); - for (size_t y = 0; y < height; y++) { - for (size_t x = 0; x < width; x++) { - void *pixel_data = ((unsigned char*)bmp->data) + y * bmp->skip + x * sizeof(uint32_t); + for (int bitmap_y = 0; bitmap_y < height; bitmap_y++) { + for (int bitmap_x = 0; bitmap_x < width; bitmap_x++) { + void *pixel_data = ((unsigned char*)bmp->data) + bitmap_y * bmp->skip + bitmap_x * sizeof(uint32_t); uint32_t pixel; memcpy(&pixel, pixel_data, sizeof(uint32_t)); // Set alpha (see sortix_fill_area() for more details) pixel |= 0xff000000; - buffer[y * width + x] = pixel; + window_data->buffer[(y + bitmap_y) * pitch + x + bitmap_x] = pixel; } } - display_render_window(connection, window_data->window_id, x1, y1, width, height, buffer); - free(buffer); + + display_render_window(connection, window_data->window_id, 0, 0, dev->size.x2, dev->size.y2, window_data->buffer); } static void sortix_fill_area(struct graphics_device *dev, int x1, int y1, int x2, int y2, long color) { - struct window_data *window_data = dev->driver_data; + CLIP_FILL_AREA - size_t width = x2 - x1; - size_t height = y2 - y1; - if (!width || !height) - return; - // TODO: Overflow when multiplying - uint32_t *buffer = mem_alloc(width * height * sizeof(uint32_t)); + struct window_data *window_data = dev->driver_data; + int pitch = dev->size.x2; // Links uses a pixel format where the top byte is clear // Sortix stores alpha there, so set it to 255 uint32_t pixel = color | 0xff000000; - for (size_t y = 0; y < height; y++) { - for (size_t x = 0; x < width; x++) - buffer[y * width + x] = pixel; + for (int y = y1; y < y2; y++) { + for (int x = x1; x < x2; x++) { + window_data->buffer[y * pitch + x] = pixel; + } } - display_render_window(connection, window_data->window_id, x1, y1, width, height, buffer); - free(buffer); + + display_render_window(connection, window_data->window_id, 0, 0, dev->size.x2, dev->size.y2, window_data->buffer); } static void sortix_draw_hline(struct graphics_device *dev, int x1, int y, int x2, long color) { + CLIP_DRAW_HLINE sortix_fill_area(dev, x1, y, x2, y + 1, color); } static void sortix_draw_vline(struct graphics_device *dev, int x, int y1, int y2, long color) { + CLIP_DRAW_VLINE sortix_fill_area(dev, x, y1, x + 1, y2, color); }