Login
1 branch 0 tags
Ben (Desktop/Arch) lvgl 67cbd91 1 month ago 12 Commits
moon / firmware / sdl_src / lvgl_port_sdl.c
/**
 * @file lvgl_port_sdl.c
 * LVGL display driver for SDL2 simulator
 */

#include "lvgl_port.h"
#include "moon.h"
#include <string.h>

// Draw buffer for partial refresh (32 lines at 160px, ARGB8888)
#define DRAW_BUF_LINES 32
static uint8_t draw_buf[SCREEN_WIDTH * DRAW_BUF_LINES * 4];

static lv_display_t *display;

// Flush callback - copies LVGL buffer to framebuffer via blit_buf
static void flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) {
    (void)disp;

    int y_start = area->y1;
    int y_end = area->y2 + 1;
    int width = area->x2 - area->x1 + 1;
    int height = y_end - y_start;

    // If full width, we can blit directly
    if (area->x1 == 0 && width == SCREEN_WIDTH) {
        blit_buf(px_map, y_start, y_end);
    } else {
        // Partial width - need to copy line by line to a full-width buffer
        static uint32_t line_buf[SCREEN_WIDTH * DRAW_BUF_LINES];

        for (int y = 0; y < height; y++) {
            uint32_t *src = (uint32_t *)px_map + y * width;
            uint32_t *dst = line_buf + y * SCREEN_WIDTH + area->x1;
            memcpy(dst, src, width * 4);
        }
        blit_buf(line_buf, y_start, y_end);
    }

    lv_display_flush_ready(disp);
}

void lvgl_port_init(void) {
    lv_init();

    // Create display with ARGB8888 color format
    display = lv_display_create(SCREEN_WIDTH, SCREEN_HEIGHT);
    lv_display_set_color_format(display, LV_COLOR_FORMAT_ARGB8888);

    // Set draw buffers (single buffer mode for simplicity)
    lv_display_set_buffers(display, draw_buf, NULL,
                           sizeof(draw_buf), LV_DISPLAY_RENDER_MODE_PARTIAL);

    // Set flush callback
    lv_display_set_flush_cb(display, flush_cb);
}

lv_display_t *lvgl_port_get_display(void) {
    return display;
}