From 875366184553360b0c17a3fc43222597956c98df Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Wed, 3 May 2023 22:28:17 +0200 Subject: [PATCH] Handle MONITOR_ZOOM for screen transitions and captures Something must have changed, but now the MONITOR_ZOOM factor must be considered when calling `SDL_RenderReadPixels`. Always calling with a monitor width and height of 240 results in a segmentation fault in said function. Fixes: https://github.com/InfiniTimeOrg/InfiniSim/issues/95 --- main.cpp | 18 ++++++++++-------- sim/displayapp/LittleVgl.cpp | 9 +++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/main.cpp b/main.cpp index 68ece27..9c61966 100644 --- a/main.cpp +++ b/main.cpp @@ -141,16 +141,17 @@ void saveScreenshot() for (int i = 0; i < height; i++) { row_pointers[i] = (png_bytep)png_malloc(png_ptr, width*4); } + constexpr size_t zoom = MONITOR_ZOOM; const Uint32 format = SDL_PIXELFORMAT_RGBA8888; - SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, format); + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, width*zoom, height*zoom, 32, format); SDL_RenderReadPixels(renderer, NULL, format, surface->pixels, surface->pitch); png_bytep pixels = (png_bytep)surface->pixels; for (int hi = 0; hi < height; hi++) { for (int wi = 0; wi < width; wi++) { int c = wi * 4; - row_pointers.at(hi)[wi*4+0] = pixels[hi*surface->pitch + wi*4 + 3]; // red - row_pointers.at(hi)[wi*4+1] = pixels[hi*surface->pitch + wi*4 + 2]; // greeen - row_pointers.at(hi)[wi*4+2] = pixels[hi*surface->pitch + wi*4 + 1]; // blue + row_pointers.at(hi)[wi*4+0] = pixels[hi*surface->pitch*zoom + wi*4*zoom + 3]; // red + row_pointers.at(hi)[wi*4+1] = pixels[hi*surface->pitch*zoom + wi*4*zoom + 2]; // greeen + row_pointers.at(hi)[wi*4+2] = pixels[hi*surface->pitch*zoom + wi*4*zoom + 1]; // blue row_pointers.at(hi)[wi*4+3] = 255; // alpha } } @@ -223,17 +224,18 @@ public: { last_frame = std::chrono::system_clock::now(); auto renderer = monitor.renderer; + constexpr size_t zoom = MONITOR_ZOOM; const Uint32 format = SDL_PIXELFORMAT_RGBA8888; - SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, sdl_width, sdl_height, 32, format); + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, sdl_width*zoom, sdl_height*zoom, 32, format); SDL_RenderReadPixels(renderer, NULL, format, surface->pixels, surface->pitch); uint8_t *pixels = (uint8_t*) surface->pixels; std::array image; for (int hi = 0; hi < sdl_height; hi++) { for (int wi = 0; wi < sdl_width; wi++) { - auto red = pixels[hi*surface->pitch + wi*4 + 3]; // red - auto green = pixels[hi*surface->pitch + wi*4 + 2]; // green - auto blue = pixels[hi*surface->pitch + wi*4 + 1]; // blue + auto red = pixels[hi*surface->pitch*zoom + wi*4*zoom + 3]; // red + auto green = pixels[hi*surface->pitch*zoom + wi*4*zoom + 2]; // green + auto blue = pixels[hi*surface->pitch*zoom + wi*4*zoom + 1]; // blue image[(hi * sdl_width + wi)*4 + 0] = red; image[(hi * sdl_width + wi)*4 + 1] = green; image[(hi * sdl_width + wi)*4 + 2] = blue; diff --git a/sim/displayapp/LittleVgl.cpp b/sim/displayapp/LittleVgl.cpp index 04a7482..088accf 100644 --- a/sim/displayapp/LittleVgl.cpp +++ b/sim/displayapp/LittleVgl.cpp @@ -194,17 +194,18 @@ void MoveScreen(lv_disp_drv_t *disp_drv, int16_t height) { const int sdl_height = 240; auto renderer = monitor.renderer; + constexpr size_t zoom = MONITOR_ZOOM; const Uint32 format = SDL_PIXELFORMAT_RGBA8888; - SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, sdl_width, sdl_height, 32, format); + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, sdl_width*zoom, sdl_height*zoom, 32, format); SDL_RenderReadPixels(renderer, NULL, format, surface->pixels, surface->pitch); uint8_t *pixels = (uint8_t*) surface->pixels; std::array color_p; for (int hi = 0; hi < sdl_height; hi++) { for (int wi = 0; wi < sdl_width; wi++) { - auto red = pixels[hi*surface->pitch + wi*4 + 3]; // red - auto green = pixels[hi*surface->pitch + wi*4 + 2]; // greeen - auto blue = pixels[hi*surface->pitch + wi*4 + 1]; // blue + auto red = pixels[hi*surface->pitch*zoom + wi*4*zoom + 3]; // red + auto green = pixels[hi*surface->pitch*zoom + wi*4*zoom + 2]; // greeen + auto blue = pixels[hi*surface->pitch*zoom + wi*4*zoom + 1]; // blue color_p.at(hi * sdl_width + wi) = LV_COLOR_MAKE(red, green, blue); } }