From 9f9b76e9b50e0aca2f1abd5e9f16df59fbe017a7 Mon Sep 17 00:00:00 2001 From: Fred Date: Sat, 31 Oct 2020 18:40:11 +0100 Subject: [PATCH] Make the SDL window resizable --- platform/drivers/display/display_libSDL.c | 121 +++++++++++----------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/platform/drivers/display/display_libSDL.c b/platform/drivers/display/display_libSDL.c index b51f8291..6acbef33 100644 --- a/platform/drivers/display/display_libSDL.c +++ b/platform/drivers/display/display_libSDL.c @@ -28,9 +28,10 @@ #include #include #include + #undef main /* necessary to avoid conflicts with SDL_main */ -/* +/* * Screen dimensions, adjust basing on the size of the screen you need to * emulate */ @@ -46,22 +47,22 @@ #warning No pixel format defined, defaulting to RGB565 #define PIX_FMT_RGB565 #endif - -SDL_Window *window; /* SDL window */ -SDL_Surface *renderSurface; /* SDL rendering surface */ -void *frameBuffer; /* Pointer to framebuffer */ -bool inProgress; /* Flag to signal when rendering is in progress */ + +SDL_Renderer *renderer; /* SDL renderer */ +SDL_Window *window; /* SDL window */ +SDL_Texture *displayTexture; /* SDL rendering surface */ +void *frameBuffer; /* Pointer to framebuffer */ +bool inProgress; /* Flag to signal when rendering is in progress */ /** * @internal * Internal helper function which fetches pixel at position (x, y) from framebuffer * and returns it in SDL-compatible format, which is ARGB8888. */ -uint32_t fetchPixelFromFb(unsigned int x, unsigned int y) -{ +uint32_t fetchPixelFromFb(unsigned int x, unsigned int y) { uint32_t pixel = 0; - #ifdef PIX_FMT_BW +#ifdef PIX_FMT_BW /* * Black and white 1bpp format: framebuffer is an array of uint8_t, where * each cell contains the values of eight pixels, one per bit. @@ -70,30 +71,30 @@ uint32_t fetchPixelFromFb(unsigned int x, unsigned int y) unsigned int cell = (x + y*SCREEN_WIDTH) / 8; unsigned int elem = (x + y*SCREEN_WIDTH) % 8; if(fb[cell] & (1 << elem)) pixel = 0xFFFFFFFF; - #endif +#endif - #ifdef PIX_FMT_GRAYSC +#ifdef PIX_FMT_GRAYSC /* - * Convert from 8bpp grayscale to ARGB8888, we have to do nothing more that + * Convert from 8bpp grayscale to ARGB8888, we have to do nothing more that * replicating the pixel value for the three components */ uint8_t *fb = (uint8_t *)(frameBuffer); uint8_t px = fb[x + y*SCREEN_WIDTH]; pixel = 0xFF000000 | (px << 16) | (px << 8) | px; - #endif +#endif - #ifdef PIX_FMT_RGB565 +#ifdef PIX_FMT_RGB565 /* * SDL pixel format is ARGB8888, while ours is RGB565, thus we need * to do some conversions when writing framebuffer content to the * window. We also set alpha value to its maximum. */ - uint16_t *fb = (uint16_t *)(frameBuffer); + uint16_t *fb = (uint16_t *) (frameBuffer); - uint32_t r = (fb[x + y*SCREEN_WIDTH] & 0xF800) >> 11; - uint32_t g = (fb[x + y*SCREEN_WIDTH] & 0x07E0) >> 5; - uint32_t b = (fb[x + y*SCREEN_WIDTH] & 0x001F) & 0x1F; + uint32_t r = (fb[x + y * SCREEN_WIDTH] & 0xF800) >> 11; + uint32_t g = (fb[x + y * SCREEN_WIDTH] & 0x07E0) >> 5; + uint32_t b = (fb[x + y * SCREEN_WIDTH] & 0x001F) & 0x1F; /* * Here we do conversions by multiplying by some scaling factors, @@ -103,62 +104,63 @@ uint32_t fetchPixelFromFb(unsigned int x, unsigned int y) * - five bit to eight bit: 8.226 * - six bit to eight bit: 4.0476 */ - r = (r * 8) + (r * 226)/1000; - g = (g * 4) + (g * 476)/10000; - b = (b * 8) + (b * 226)/1000; + r = (r * 8) + (r * 226) / 1000; + g = (g * 4) + (g * 476) / 10000; + b = (b * 8) + (b * 226) / 1000; pixel = 0xFF000000 | (r << 16) | (g << 8) | b; - #endif +#endif return pixel; } -void display_init() -{ - if(SDL_Init(SDL_INIT_VIDEO) < 0) - { +void display_init() { + if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL video init error!!\n"); - } - else - { + } else { - window = SDL_CreateWindow(" ", + window = SDL_CreateWindow("OpenRTX", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - SCREEN_WIDTH,SCREEN_HEIGHT, - SDL_WINDOW_SHOWN); + SCREEN_WIDTH * 3, SCREEN_HEIGHT * 3, + SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); - renderSurface = SDL_GetWindowSurface(window); - SDL_FillRect(renderSurface,NULL,0xFFFFFF); + renderer = SDL_CreateRenderer(window, -1, 0); + SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); + displayTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, + SCREEN_WIDTH, SCREEN_HEIGHT); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, displayTexture, NULL, NULL); + SDL_RenderPresent(renderer); /* * Black and white pixel format: framebuffer type is uint8_t where each * bit represents a pixel. We have to allocate * (SCREEN_HEIGHT * SCREEN_WIDTH)/8 elements */ - #ifdef PIX_FMT_BW +#ifdef PIX_FMT_BW unsigned int fbSize = (SCREEN_HEIGHT * SCREEN_WIDTH)/8; if((fbSize * 8) < (SCREEN_HEIGHT * SCREEN_WIDTH)) fbSize += 1; /* Compensate for eventual truncation error in division */ fbSize *= sizeof(uint8_t); - #endif +#endif /* * Grayscale pixel format: framebuffer type is uint8_t where each element * controls one pixel */ - #ifdef PIX_FMT_GRAYSC +#ifdef PIX_FMT_GRAYSC unsigned int fbSize = SCREEN_HEIGHT * SCREEN_WIDTH * sizeof(uint8_t); - #endif +#endif /* * RGB565 pixel format: framebuffer type is uint16_t where each element * controls one pixel */ - #ifdef PIX_FMT_RGB565 +#ifdef PIX_FMT_RGB565 unsigned int fbSize = SCREEN_HEIGHT * SCREEN_WIDTH * sizeof(uint16_t); - #endif +#endif frameBuffer = malloc(fbSize); memset(frameBuffer, 0xFFFF, fbSize); @@ -166,43 +168,40 @@ void display_init() } } -void display_terminate() -{ - while(inProgress) { } /* Wait until current render finishes */ +void display_terminate() { + while (inProgress) {} /* Wait until current render finishes */ printf("Terminating SDL display emulator, goodbye!\n"); free(frameBuffer); SDL_DestroyWindow(window); SDL_Quit(); } -void display_renderRows(uint8_t startRow, uint8_t endRow) -{ - Uint32 *pixels = (Uint32*)renderSurface->pixels; +void display_renderRows(uint8_t startRow, uint8_t endRow) { + Uint32 *pixels; + int pitch = 0; + if (SDL_LockTexture(displayTexture, NULL, (void **) &pixels, &pitch) < 0) { + printf("SDL_lock failed: %s\n", SDL_GetError()); + } inProgress = true; - - for(unsigned int x = 0; x < SCREEN_WIDTH; x++) - { - for(unsigned int y = startRow; y < endRow; y++) - { - pixels[x + y*SCREEN_WIDTH] = fetchPixelFromFb(x, y); + for (unsigned int x = 0; x < SCREEN_WIDTH; x++) { + for (unsigned int y = startRow; y < endRow; y++) { + pixels[x + y * SCREEN_WIDTH] = fetchPixelFromFb(x, y); } } - + SDL_UnlockTexture(displayTexture); + SDL_RenderCopy(renderer, displayTexture, NULL, NULL); + SDL_RenderPresent(renderer); inProgress = false; - SDL_UpdateWindowSurface(window); } -void display_render() -{ +void display_render() { display_renderRows(0, SCREEN_HEIGHT); } -bool display_renderingInProgress() -{ +bool display_renderingInProgress() { return inProgress; } -void *display_getFrameBuffer() -{ - return (void *)(frameBuffer); +void *display_getFrameBuffer() { + return (void *) (frameBuffer); }