diff options
| author | bernard <[email protected]> | 2017-12-16 00:05:23 +0800 |
|---|---|---|
| committer | bernard <[email protected]> | 2017-12-16 00:05:23 +0800 |
| commit | 7c2bcdd3dee8e84388ddd7d62fd6fda8c4dc8d03 (patch) | |
| tree | 8f687bb25bd8bed9209738401e0320594600a138 /bsp/simulator/drivers | |
| parent | a4776edb5fe300666d63cd7e2c59a005637653cb (diff) | |
[BSP] update SDL to SDL2 in simulator.
Diffstat (limited to 'bsp/simulator/drivers')
| -rwxr-xr-x | bsp/simulator/drivers/sdl_fb.c | 307 |
1 files changed, 225 insertions, 82 deletions
diff --git a/bsp/simulator/drivers/sdl_fb.c b/bsp/simulator/drivers/sdl_fb.c index 5399de8d58..b1332449c9 100755 --- a/bsp/simulator/drivers/sdl_fb.c +++ b/bsp/simulator/drivers/sdl_fb.c @@ -1,5 +1,7 @@ #include <rtthread.h> +#include <stdio.h> + #ifdef _WIN32 #include <sdl.h> #else @@ -8,16 +10,20 @@ #include <rtdevice.h> #include <rtgui/driver.h> -#define SDL_SCREEN_WIDTH 800 -#define SDL_SCREEN_HEIGHT 480 +#define SDL_SCREEN_WIDTH 480 +#define SDL_SCREEN_HEIGHT 320 extern void rt_hw_exit(void); +#define SDL_SCREEN_FORMAT SDL_PIXELFORMAT_RGB565 + struct sdlfb_device { struct rt_device parent; - SDL_Surface *screen; + SDL_Renderer *renderer; /* window renderer */ + SDL_Surface *surface; /* screen surface */ + rt_uint16_t width; rt_uint16_t height; }; @@ -38,6 +44,34 @@ static rt_err_t sdlfb_close(rt_device_t dev) return RT_EOK; } +int sdlfb_info(int *format, int *bpp) +{ + int bit_pp; /* texture bits per pixel */ + Uint32 Rmask, Gmask, Bmask, Amask; /* masks for pixel format passed into OpenGL */ + + /* Grab info about format that will be passed into OpenGL */ + SDL_PixelFormatEnumToMasks(SDL_SCREEN_FORMAT, &bit_pp, &Rmask, &Gmask, + &Bmask, &Amask); + + *bpp = bit_pp; + switch (SDL_SCREEN_FORMAT) + { + case SDL_PIXELFORMAT_RGB565: + *format = RTGRAPHIC_PIXEL_FORMAT_RGB565; + break; + case SDL_PIXELFORMAT_RGB888: + *format = RTGRAPHIC_PIXEL_FORMAT_RGB888; + break; + case SDL_PIXELFORMAT_ARGB8888: + *format = RTGRAPHIC_PIXEL_FORMAT_ARGB888; + break; + case SDL_PIXELFORMAT_ABGR8888: + *format = RTGRAPHIC_PIXEL_FORMAT_ABGR888; + } + + return 0; +} + static rt_mutex_t sdllock; static rt_err_t sdlfb_control(rt_device_t dev, int cmd, void *args) { @@ -46,57 +80,45 @@ static rt_err_t sdlfb_control(rt_device_t dev, int cmd, void *args) rt_mutex_take(sdllock, RT_WAITING_FOREVER); device = (struct sdlfb_device *)dev; RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->screen != RT_NULL); switch (cmd) { case RTGRAPHIC_CTRL_GET_INFO: { + int format, bpp; struct rt_device_graphic_info *info; + sdlfb_info(&format, &bpp); info = (struct rt_device_graphic_info *) args; - info->bits_per_pixel = 16; - info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565; - info->framebuffer = device->screen->pixels; - info->width = device->screen->w; - info->height = device->screen->h; + info->bits_per_pixel = bpp; + info->pixel_format = format; + info->framebuffer = (rt_uint8_t*)device->surface->pixels; + info->width = device->width; + info->height = device->height; } break; case RTGRAPHIC_CTRL_RECT_UPDATE: { + SDL_Texture * texture; struct rt_device_rect_info *rect; - rect = (struct rt_device_rect_info *)args; - - /* SDL_UpdateRect(_device.screen, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); */ - SDL_UpdateRect(_device.screen, 0, 0, device->width, device->height); - } - break; - case RTGRAPHIC_CTRL_SET_MODE: - { -#if 0 - struct rt_device_rect_info *rect; + SDL_Rect _rect = { 0, 0, SDL_SCREEN_WIDTH, SDL_SCREEN_HEIGHT }; rect = (struct rt_device_rect_info *)args; - if ((_device.width == rect->width) && (_device.height == rect->height)) return -RT_ERROR; - _device.width = rect->width; - _device.height = rect->height; + SDL_RenderClear(_device.renderer); - if (_device.screen != RT_NULL) - { - SDL_FreeSurface(_device.screen); + texture = SDL_CreateTextureFromSurface(_device.renderer, _device.surface); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + SDL_RenderCopy(_device.renderer, texture, NULL, &_rect); - /* re-create screen surface */ - _device.screen = SDL_SetVideoMode(_device.width, _device.height, 16, SDL_SWSURFACE | SDL_DOUBLEBUF); - if (_device.screen == NULL) - { - fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); - exit(1); - } + SDL_RenderPresent(_device.renderer); - SDL_WM_SetCaption("RT-Thread/GUI Simulator", NULL); - } -#endif + SDL_DestroyTexture(texture); + } + break; + case RTGRAPHIC_CTRL_SET_MODE: + { + break; } break; } @@ -104,13 +126,46 @@ static rt_err_t sdlfb_control(rt_device_t dev, int cmd, void *args) return RT_EOK; } +Uint16 pixels[16 * 16] = { // ...or with raw pixel data: + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, + 0x0fff, 0x0aab, 0x0789, 0x0bcc, 0x0eee, 0x09aa, 0x099a, 0x0ddd, + 0x0fff, 0x0eee, 0x0899, 0x0fff, 0x0fff, 0x1fff, 0x0dde, 0x0dee, + 0x0fff, 0xabbc, 0xf779, 0x8cdd, 0x3fff, 0x9bbc, 0xaaab, 0x6fff, + 0x0fff, 0x3fff, 0xbaab, 0x0fff, 0x0fff, 0x6689, 0x6fff, 0x0dee, + 0xe678, 0xf134, 0x8abb, 0xf235, 0xf678, 0xf013, 0xf568, 0xf001, + 0xd889, 0x7abc, 0xf001, 0x0fff, 0x0fff, 0x0bcc, 0x9124, 0x5fff, + 0xf124, 0xf356, 0x3eee, 0x0fff, 0x7bbc, 0xf124, 0x0789, 0x2fff, + 0xf002, 0xd789, 0xf024, 0x0fff, 0x0fff, 0x0002, 0x0134, 0xd79a, + 0x1fff, 0xf023, 0xf000, 0xf124, 0xc99a, 0xf024, 0x0567, 0x0fff, + 0xf002, 0xe678, 0xf013, 0x0fff, 0x0ddd, 0x0fff, 0x0fff, 0xb689, + 0x8abb, 0x0fff, 0x0fff, 0xf001, 0xf235, 0xf013, 0x0fff, 0xd789, + 0xf002, 0x9899, 0xf001, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0xe789, + 0xf023, 0xf000, 0xf001, 0xe456, 0x8bcc, 0xf013, 0xf002, 0xf012, + 0x1767, 0x5aaa, 0xf013, 0xf001, 0xf000, 0x0fff, 0x7fff, 0xf124, + 0x0fff, 0x089a, 0x0578, 0x0fff, 0x089a, 0x0013, 0x0245, 0x0eff, + 0x0223, 0x0dde, 0x0135, 0x0789, 0x0ddd, 0xbbbc, 0xf346, 0x0467, + 0x0fff, 0x4eee, 0x3ddd, 0x0edd, 0x0dee, 0x0fff, 0x0fff, 0x0dee, + 0x0def, 0x08ab, 0x0fff, 0x7fff, 0xfabc, 0xf356, 0x0457, 0x0467, + 0x0fff, 0x0bcd, 0x4bde, 0x9bcc, 0x8dee, 0x8eff, 0x8fff, 0x9fff, + 0xadee, 0xeccd, 0xf689, 0xc357, 0x2356, 0x0356, 0x0467, 0x0467, + 0x0fff, 0x0ccd, 0x0bdd, 0x0cdd, 0x0aaa, 0x2234, 0x4135, 0x4346, + 0x5356, 0x2246, 0x0346, 0x0356, 0x0467, 0x0356, 0x0467, 0x0467, + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, + 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff +}; + static void sdlfb_hw_init(void) { - /* set video driver for VC++ debug */ - //_putenv("SDL_VIDEODRIVER=windib"); + SDL_Window *win; - //if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) < 0) - if (SDL_Init(SDL_INIT_VIDEO) < 0) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(1); @@ -125,14 +180,37 @@ static void sdlfb_hw_init(void) _device.width = SDL_SCREEN_WIDTH; _device.height = SDL_SCREEN_HEIGHT; - _device.screen = SDL_SetVideoMode(_device.width, _device.height, 16, SDL_SWSURFACE | SDL_DOUBLEBUF); - if (_device.screen == NULL) + + { + int bpp; /* texture bits per pixel */ + Uint32 Rmask, Gmask, Bmask, Amask; /* masks for pixel format passed into OpenGL */ + + /* Grab info about format that will be passed into OpenGL */ + SDL_PixelFormatEnumToMasks(SDL_SCREEN_FORMAT, &bpp, &Rmask, &Gmask, + &Bmask, &Amask); + + _device.surface = SDL_CreateRGBSurface(0, SDL_SCREEN_WIDTH, SDL_SCREEN_HEIGHT, + bpp, Rmask, Gmask, Bmask, Amask); + } + + win = SDL_CreateWindow("RT-Thread/Persimmon", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + SDL_SCREEN_WIDTH, SDL_SCREEN_HEIGHT, SDL_WINDOW_OPENGL); + if (win == NULL) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } - SDL_WM_SetCaption("RT-Thread/GUI Simulator", NULL); + /* set the icon of Window */ + { + SDL_Surface *surface; + surface = SDL_CreateRGBSurfaceFrom(pixels, 16, 16, 16, 16 * 2, 0x0f00, 0x00f0, 0x000f, 0xf000); + SDL_SetWindowIcon(win, surface); + } + + _device.renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); + rt_device_register(RT_DEVICE(&_device), "sdl", RT_DEVICE_FLAG_RDWR); sdllock = rt_mutex_create("fb", RT_IPC_FLAG_FIFO); @@ -165,9 +243,18 @@ static void *sdl_loop(void *lpParam) { int quit = 0; SDL_Event event; - int button_state = 0; + int state = 0; rt_device_t device; + int timeout = 1000000; + + int last_x = -1, last_y = -1; + + int motion_x, motion_y; + int motion_button = 0; + int motion_tick = 50; + int mouse_id = 1; + #ifndef _WIN32 sigset_t sigmask, oldmask; /* set the getchar without buffer */ @@ -190,74 +277,130 @@ static void *sdl_loop(void *lpParam) /* handle SDL event */ while (!quit) { - SDL_WaitEvent(&event); - - switch (event.type) + if (motion_button & RTGUI_MOUSE_BUTTON_DOWN) { - case SDL_MOUSEMOTION: + timeout = motion_tick - SDL_GetTicks(); + } + else + { + timeout = 1000 * 1000; + } + + int tick = SDL_GetTicks(); + SDL_WaitEventTimeout(&event, timeout); + if (SDL_GetTicks() >= motion_tick && (motion_button & RTGUI_MOUSE_BUTTON_DOWN)) /* whether timeout */ { + /* sendout motion event */ struct rtgui_event_mouse emouse; + emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION; emouse.parent.sender = RT_NULL; emouse.wid = RT_NULL; + emouse.id = mouse_id; + emouse.ts = rt_tick_get(); - emouse.x = ((SDL_MouseMotionEvent *)&event)->x; - emouse.y = ((SDL_MouseMotionEvent *)&event)->y; + if ((motion_x > 0 && motion_x < SDL_SCREEN_WIDTH) && + (motion_y > 0 && motion_y < SDL_SCREEN_HEIGHT)) + { + emouse.x = motion_x; + emouse.y = motion_y; - /* init mouse button */ - emouse.button = button_state; + /* init mouse button */ + emouse.button = motion_button; - /* send event to server */ - rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); + /* send event to server */ + rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); + } + + /* reset motion tick */ + motion_tick = 50 + SDL_GetTicks(); + } + + switch (event.type) + { + case SDL_MOUSEMOTION: + { + /* save to (x,y) in the motion */ + motion_x = ((SDL_MouseMotionEvent *)&event)->x; + motion_y = ((SDL_MouseMotionEvent *)&event)->y; } break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { + int x, y; struct rtgui_event_mouse emouse; SDL_MouseButtonEvent *mb; emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; emouse.parent.sender = RT_NULL; emouse.wid = RT_NULL; + if (event.type == SDL_MOUSEBUTTONDOWN && state == 0) + mouse_id = rt_tick_get(); + + emouse.id = mouse_id; + emouse.ts = rt_tick_get(); mb = (SDL_MouseButtonEvent *)&event; - emouse.x = mb->x; - emouse.y = mb->y; + x = mb->x; + y = mb->y; + if ((x > 0 && x < SDL_SCREEN_WIDTH) && + (y > 0 && y < SDL_SCREEN_HEIGHT)) + { + emouse.x = x; + emouse.y = y; - /* init mouse button */ - emouse.button = 0; + /* init mouse button */ + emouse.button = 0; - /* set emouse button */ - if (mb->button & (1 << (SDL_BUTTON_LEFT - 1))) - { - emouse.button |= RTGUI_MOUSE_BUTTON_LEFT; - } - else if (mb->button & (1 << (SDL_BUTTON_RIGHT - 1))) - { - emouse.button |= RTGUI_MOUSE_BUTTON_RIGHT; - } - else if (mb->button & (1 << (SDL_BUTTON_MIDDLE - 1))) - { - emouse.button |= RTGUI_MOUSE_BUTTON_MIDDLE; - } + /* set emouse button */ + if (mb->button & (1 << (SDL_BUTTON_LEFT - 1))) + { + emouse.button |= RTGUI_MOUSE_BUTTON_LEFT; + } + else if (mb->button & (1 << (SDL_BUTTON_RIGHT - 1))) + { + emouse.button |= RTGUI_MOUSE_BUTTON_RIGHT; + } + else if (mb->button & (1 << (SDL_BUTTON_MIDDLE - 1))) + { + emouse.button |= RTGUI_MOUSE_BUTTON_MIDDLE; + } - if (mb->type == SDL_MOUSEBUTTONDOWN) - { - emouse.button |= RTGUI_MOUSE_BUTTON_DOWN; - button_state = emouse.button; - } - else - { - emouse.button |= RTGUI_MOUSE_BUTTON_UP; - button_state = 0; - } + if (mb->type == SDL_MOUSEBUTTONDOWN) + { + emouse.button |= RTGUI_MOUSE_BUTTON_DOWN; + motion_button = emouse.button; + /* set motion timeout tick */ + motion_tick = 50 + SDL_GetTicks(); - /* send event to server */ - rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); + if (state == 0) + { + /* send event to server */ + rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); + last_x = -1; last_y = -1; + + state = 1; + } + } + else + { + emouse.button |= RTGUI_MOUSE_BUTTON_UP; + motion_button = 0; + + if (state == 1) + { + /* send event to server */ + rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); + last_x = -1; last_y = -1; + + state = 0; + } + } + } } break; |
