vxKernel/src/driver/mpu/x86/sdl2/window.c

140 lines
2.8 KiB
C

#include <SDL2/SDL.h>
#include <vhex/display.h>
#include <vhex/display/interface.h>
#include <vhex/driver.h>
extern SDL_Window *__sdl_window;
//---
// Driver primitives
//---
uint32_t vhex_vram[(396*224) / 2];
/* sdl_frame_start() - prepar the screen and reset surfaces */
int sdl_frame_start(dsurface_t *surface)
{
surface->vram = (void*)vhex_vram;
surface->width = 396;
surface->height = 224;
surface->x1 = 0;
surface->y1 = 0;
surface->x2 = 395;
surface->y2 = 223;
return (0);
}
/* sdl_frame_frag_next() : update the next fragment */
int sdl_frame_frag_next(dsurface_t *surface)
{
(void)surface;
return -1;
}
/* sdl_frame_frag_send() : send fragment to the screen */
int sdl_frame_frag_send(dsurface_t *surface)
{
SDL_SetWindowSize(__sdl_window, 396 * 2, 224 * 2);
SDL_Surface *src = SDL_CreateRGBSurface(
0, 396 * 2, 224 * 2, 24,
0x000000ff, 0x0000ff00, 0x0000ff00, 0
);
uint16_t *vram = surface->vram;
uint8_t *disp = src->pixels;
int r;
int g;
int b;
off_t yoff = 0;
for (int y = 0 ; y < 224; ++y) {
for (int x = 0; x < 396 ; ++x) {
r = (((vram[(y * 396) + x] & 0xf800) >> 11) * 255) / 31;
g = (((vram[(y * 396) + x] & 0x07e0) >> 5) * 255) / 63;
b = (((vram[(y * 396) + x] & 0x001f) >> 0) * 255) / 31;
disp[yoff + (x * 6) + 0] = r;
disp[yoff + (x * 6) + 1] = g;
disp[yoff + (x * 6) + 2] = b;
disp[yoff + (x * 6) + 3] = r;
disp[yoff + (x * 6) + 4] = g;
disp[yoff + (x * 6) + 5] = b;
}
memcpy(&disp[yoff + (396 * 6)], &disp[yoff], 396 * 6);
yoff += 396 * 6;
yoff += 396 * 6;
}
SDL_Surface *dst = SDL_GetWindowSurface(__sdl_window);
SDL_BlitSurface(src, NULL, dst, NULL);
SDL_FreeSurface(src);
SDL_UpdateWindowSurface(__sdl_window);
return 0;
}
/* sdl_frame_end() : destructor */
int sdl_frame_end(dsurface_t *surface)
{
(void)surface;
return 0;
}
//---
// Driver context management
//---
static int __sdl_configure(void)
{
printf("[drv] LCD: fake driver initialized\n");
__sdl_window = SDL_CreateWindow(
"vxKernel",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
396 * 2,
224 * 2,
0
);
return 0;
}
static void __sdl_hsave(void)
{
// Nothing to do, this is a fake driver
;
}
static void __sdl_hrestore(void)
{
// Nothing to do, this is a fake driver
;
}
struct vhex_driver drv_sdl = {
.name = "SDL",
.hsave = (void*)&__sdl_hsave,
.hrestore = (void*)&__sdl_hrestore,
.configure = (void*)&__sdl_configure,
.state_size = 4,
.flags = {
.DISPLAY = 1,
.SHARED = 0,
.UNUSED = 0,
},
.module_data = &(struct dstack_drv_interface){
.frame_start = &sdl_frame_start,
.frame_frag_next = &sdl_frame_frag_next,
.frame_frag_send = &sdl_frame_frag_send,
.frame_end = &sdl_frame_end,
.display_width = 396,
.display_height = 224
}
};
VHEX_DECLARE_DRIVER(16, drv_sdl);