diff --git a/sww/source/platform/fb.c b/sww/source/platform/fb.c index 9a59b57..e773045 100644 --- a/sww/source/platform/fb.c +++ b/sww/source/platform/fb.c @@ -49,6 +49,8 @@ struct swwApp { struct termios term; + uint8_t* fb; + int fbfd; int xres; int yres; @@ -68,12 +70,15 @@ struct swwWindow { swwImage* surface; + /* Poistion on display(framebuffer) */ + uint32_t x, y; + /* common data */ swwWindowCallback callback; void* userdata; }; -swwApp g_app = {{0}, 0, 0, 0, 0, 0, NULL, {-1}, 0, {0}, {0}}; +swwApp g_app = {{0}, NULL, 0, 0, 0, 0, 0, NULL, {-1}, 0, {0}, {0}}; /* Signal Handler */ typedef enum @@ -291,8 +296,6 @@ void swwApp_Initialize() // EnableRawMode(); struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; - long int screensize = 0; - char* fbp = 0; g_app.fbfd = open("/dev/fb0", O_RDWR); if (g_app.fbfd == -1) { @@ -315,6 +318,13 @@ void swwApp_Initialize() exit(4); } + g_app.fb = (uint8_t*)mmap(0, g_app.xres * g_app.yres * 4, PROT_READ | PROT_WRITE, MAP_SHARED, + g_app.fbfd, 0); + if (g_app.fb == (void*)-1) { + perror("Error: failed to map framebuffer device to memory"); + exit(5); + } + g_app.xres = vinfo.xres; g_app.yres = vinfo.yres; @@ -354,6 +364,8 @@ void swwApp_Cleanup() close(g_app.event_source[i].fd); } } + + munmap(g_app.fb, g_app.xres * g_app.yres * 4); close(g_app.fbfd); // DisableRawMode(); } @@ -391,22 +403,11 @@ swwWindow* swwWindow_Create(const char* title, uint32_t width, uint32_t height) assert(width > 0 && height > 0 && width < g_app.xres && height < g_app.yres); - int screensize = g_app.xres * g_app.yres * 4; - - uint8_t* fbp = (uint8_t*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, g_app.fbfd, 0); - if (fbp == (void*)-1) { - perror("Error: failed to map framebuffer device to memory"); - exit(5); - } - o = (swwWindow*)malloc(sizeof(swwWindow)); memset(o, 0, sizeof(swwWindow)); - o->surface = swwImage_Create(10, 10, 4); - // NOTE(donkey): An guly patch, the buffer will be allocated by mmap - free(o->surface->buffer); - o->surface->buffer = fbp; - o->surface->width = g_app.xres; - o->surface->height = g_app.yres; + o->surface = swwImage_Create(width, height, 4); + o->x = (g_app.xres - width) >> 1; // divided by 2 + o->y = (g_app.yres - height) >> 1; // divided by 2 g_app.window = o; ++g_app.window_count; @@ -417,15 +418,34 @@ swwWindow* swwWindow_Create(const char* title, uint32_t width, uint32_t height) void swwWindow_Destroy(swwWindow* o) { if (o != NULL) { - munmap(o->surface->buffer, o->surface->width * o->surface->height * 4); + swwImage_Destroy(o->surface); free(o); --g_app.window_count; g_app.window = NULL; } } -void swwWindow_Present(swwWindow* window) -{} +void swwWindow_Present(swwWindow* o) +{ + int i = 0; + /* Start position: [y][x] */ + uint8_t* start = g_app.fb + (((o->y * g_app.xres) + o->x) << 2); + uint8_t* buf = o->surface->buffer; + size_t line_size = o->o->surface->width << 2; + + // VSYNC + int zero = 0; + int ret = ioctl(g_app.fbfd, FBIO_WAITFORVSYNC, &zero); + + if (ret != 0) { + perror("Failed to do VSYNC!"); + } + + /* Copy the window buffer to framebuffer line by line */ + for (; i < o->height; ++i, start += (g_app.xres << 2), buf += line_size) { + memcpy(start, buf, line_size); + } +} uint8_t* swwWindow_LockBuffer(swwWindow* o) {