diff --git a/src/platform/shared.c b/src/platform/shared.c index fcd34e4027..7b40e019fa 100644 --- a/src/platform/shared.c +++ b/src/platform/shared.c @@ -49,7 +49,9 @@ int gResolutionsAllowAnyAspectRatio = 0; SDL_Window *gWindow = NULL; SDL_Renderer *gRenderer = NULL; SDL_Texture *gBufferTexture = NULL; +SDL_PixelFormat *gBufferTextureFormat = NULL; SDL_Color gPalette[256]; +uint32 gPaletteHWMapped[256]; static SDL_Surface *_surface; static SDL_Palette *_palette; @@ -180,25 +182,18 @@ void platform_draw() void *pixels; int pitch; if (SDL_LockTexture(gBufferTexture, NULL, &pixels, &pitch) == 0) { - uint8 *dst = pixels; uint8 *src = (uint8*)_screenBuffer; - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - uint8 paletteIndex = *src; - SDL_Color colour = gPalette[paletteIndex]; - - dst[0] = 255; - dst[1] = colour.b; - dst[2] = colour.g; - dst[3] = colour.r; - - src += 1; - dst += 4; - } - - src += _screenBufferPitch - width; - dst += pitch - (width * 4); + if (pitch == width * 4) { + uint32 *dst = pixels; + for (int i = width * height; i > 0; i--) *(dst++) = *(uint32 *)(&gPaletteHWMapped[*src++]); + } else + if (((pitch == width * 2) + 3) & ~3) { + uint16 *dst = pixels; + for (int i = width * height; i > 0; i--) *(dst++) = *(uint16 *)(&gPaletteHWMapped[*src++]); + } else + if (((pitch == width) + 3) & ~3) { + uint8 *dst = pixels; + for (int i = width * height; i > 0; i--) *(dst++) = *(uint8 *)(&gPaletteHWMapped[*src++]); } SDL_UnlockTexture(gBufferTexture); } @@ -274,6 +269,9 @@ void platform_update_palette(char* colours, int start_index, int num_colours) gPalette[i].b = colours[0]; gPalette[i].a = 0; colours += 4; + if (gBufferTextureFormat != NULL) { + gPaletteHWMapped[i] = SDL_MapRGB(gBufferTextureFormat, gPalette[i].r, gPalette[i].g, gPalette[i].b); + } } if (!gOpenRCT2Headless && !gConfigGeneral.hardware_display) { @@ -727,8 +725,24 @@ void platform_refresh_video() if (gBufferTexture != NULL) SDL_DestroyTexture(gBufferTexture); + + if (gBufferTextureFormat != NULL) + SDL_FreeFormat(gBufferTextureFormat); + + SDL_RendererInfo rendererinfo; + SDL_GetRendererInfo(gRenderer, &rendererinfo); + Uint32 pixelformat = SDL_PIXELFORMAT_UNKNOWN; + for(unsigned int i = 0; i < rendererinfo.num_texture_formats; i++){ + Uint32 format = rendererinfo.texture_formats[i]; + if(!SDL_ISPIXELFORMAT_FOURCC(format) && !SDL_ISPIXELFORMAT_INDEXED(format) && (pixelformat == SDL_PIXELFORMAT_UNKNOWN || SDL_BYTESPERPIXEL(format) < SDL_BYTESPERPIXEL(pixelformat))){ + pixelformat = format; + } + } - gBufferTexture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STREAMING, width, height); + gBufferTexture = SDL_CreateTexture(gRenderer, pixelformat, SDL_TEXTUREACCESS_STREAMING, width, height); + Uint32 format; + SDL_QueryTexture(gBufferTexture, &format, 0, 0, 0); + gBufferTextureFormat = SDL_AllocFormat(format); platform_refresh_screenbuffer(width, height, width); } else { if (_surface != NULL)