From f16c8880b4a1ec3654b9032f99720455e4fd4451 Mon Sep 17 00:00:00 2001 From: "Stephen E. Baker" Date: Tue, 18 Sep 2018 23:24:05 -0400 Subject: [PATCH] Show errors when loading bitmaps Use exceptions and lua_error to show the cause of any error loading bitmaps instead of simply false. This makes diagnosing errors much easier. --- CorsixTH/Src/th_gfx_sdl.cpp | 73 ++++++++++++++++++++++--------------- CorsixTH/Src/th_gfx_sdl.h | 6 +-- CorsixTH/Src/th_lua_gfx.cpp | 14 +++++-- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/CorsixTH/Src/th_gfx_sdl.cpp b/CorsixTH/Src/th_gfx_sdl.cpp index 6b77d83c2e..be875375bf 100644 --- a/CorsixTH/Src/th_gfx_sdl.cpp +++ b/CorsixTH/Src/th_gfx_sdl.cpp @@ -81,10 +81,14 @@ static inline uint32_t makeSwapRedBlue(uint8_t iOpacity, uint8_t iR, uint8_t iG, return palette::pack_argb(iOpacity, iNewRed, iG, static_cast(iNewBlue)); } -bool full_colour_renderer::decode_image(const uint8_t* pImg, const palette *pPalette, uint32_t iSpriteFlags) +void full_colour_renderer::decode_image(const uint8_t* pImg, const palette *pPalette, uint32_t iSpriteFlags) { - if (width <= 0 || height <= 0) - return false; + if (width <= 0) { + throw std::logic_error("width cannot be <= 0 when decoding an image"); + } + if (height <= 0) { + throw std::logic_error("height cannot be <= 0 when decoding an image"); + } iSpriteFlags &= thdf_alt32_mask; @@ -175,7 +179,9 @@ bool full_colour_renderer::decode_image(const uint8_t* pImg, const palette *pPal if (y >= height) break; } - return x == 0; + if (y != height || x != 0) { + throw std::logic_error("Image data does not match given dimensions"); + } } full_colour_storing::full_colour_storing(uint32_t *pDest, int iWidth, int iHeight) : full_colour_renderer(iWidth, iHeight) @@ -604,10 +610,7 @@ static uint8_t *convertLegacySprite(const uint8_t* pPixelData, size_t iPixelData size_t iNumFilled = iPixelDataLength / 63; size_t iRemaining = iPixelDataLength - iNumFilled * 63; size_t iNewSize = iNumFilled * (3 + 63) + ((iRemaining > 0) ? 3 + iRemaining : 0); - - uint8_t *pData = new (std::nothrow) uint8_t[iNewSize]; - if (pData == nullptr) - return nullptr; + uint8_t *pData = new uint8_t[iNewSize]; uint8_t *pDest = pData; while (iPixelDataLength > 0) @@ -628,14 +631,10 @@ SDL_Texture* render_target::create_palettized_texture( int iWidth, int iHeight, const uint8_t* pPixels, const palette* pPalette, uint32_t iSpriteFlags) const { - uint32_t *pARGBPixels = new (std::nothrow) uint32_t[iWidth * iHeight]; - if(pARGBPixels == nullptr) - return 0; + uint32_t *pARGBPixels = new uint32_t[iWidth * iHeight]; full_colour_storing oRenderer(pARGBPixels, iWidth, iHeight); - bool bOk = oRenderer.decode_image(pPixels, pPalette, iSpriteFlags); - if (!bOk) - return 0; + oRenderer.decode_image(pPixels, pPalette, iSpriteFlags); SDL_Texture *pTexture = create_texture(iWidth, iHeight, pARGBPixels); delete [] pARGBPixels; @@ -646,10 +645,31 @@ SDL_Texture* render_target::create_texture(int iWidth, int iHeight, const uint32_t* pPixels) const { SDL_Texture *pTexture = SDL_CreateTexture(renderer, pixel_format->format, SDL_TEXTUREACCESS_STATIC, iWidth, iHeight); - SDL_UpdateTexture(pTexture, nullptr, pPixels, static_cast(sizeof(*pPixels) * iWidth)); - SDL_SetTextureBlendMode(pTexture, SDL_BLENDMODE_BLEND); - SDL_SetTextureColorMod(pTexture, 0xFF, 0xFF, 0xFF); - SDL_SetTextureAlphaMod(pTexture, 0xFF); + + if (pTexture == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + + int err = 0; + err = SDL_UpdateTexture(pTexture, nullptr, pPixels, static_cast(sizeof(*pPixels) * iWidth)); + if (err < 0) { + throw std::runtime_error(SDL_GetError()); + } + + err = SDL_SetTextureBlendMode(pTexture, SDL_BLENDMODE_BLEND); + if (err < 0) { + throw std::runtime_error(SDL_GetError()); + } + + err = SDL_SetTextureColorMod(pTexture, 0xFF, 0xFF, 0xFF); + if (err < 0) { + throw std::runtime_error(SDL_GetError()); + } + + err = SDL_SetTextureAlphaMod(pTexture, 0xFF); + if (err < 0) { + throw std::runtime_error(SDL_GetError()); + } return pTexture; } @@ -786,28 +806,23 @@ void raw_bitmap::set_palette(const palette* pPalette) bitmap_palette = pPalette; } -bool raw_bitmap::load_from_th_file(const uint8_t* pPixelData, - size_t iPixelDataLength, int iWidth, - render_target *pEventualCanvas) +void raw_bitmap::load_from_th_file(const uint8_t* pPixelData, + size_t iPixelDataLength, int iWidth, + render_target *pEventualCanvas) { - if(pEventualCanvas == nullptr) - return false; + if (pEventualCanvas == nullptr) { + throw std::invalid_argument("pEventualCanvas cannot be null"); + } uint8_t* converted_sprite = convertLegacySprite(pPixelData, iPixelDataLength); - if (converted_sprite == nullptr) - return false; int iHeight = static_cast(iPixelDataLength) / iWidth; texture = pEventualCanvas->create_palettized_texture(iWidth, iHeight, converted_sprite, bitmap_palette, thdf_alt32_plain); delete[] converted_sprite; - if(!texture) - return false; - width = iWidth; height = iHeight; target = pEventualCanvas; - return true; } /** diff --git a/CorsixTH/Src/th_gfx_sdl.h b/CorsixTH/Src/th_gfx_sdl.h index 6c0bf90963..022678f02c 100644 --- a/CorsixTH/Src/th_gfx_sdl.h +++ b/CorsixTH/Src/th_gfx_sdl.h @@ -55,7 +55,7 @@ class full_colour_renderer @param iSpriteFlags Flags how to render the sprite. @return Decoding was successful. */ - bool decode_image(const uint8_t* pImg, const ::palette *pPalette, uint32_t iSpriteFlags); + void decode_image(const uint8_t* pImg, const ::palette *pPalette, uint32_t iSpriteFlags); private: //! Store a decoded pixel. Use x and y if necessary. @@ -87,7 +87,7 @@ class full_colour_renderer } else { - x = 1; // Will return 'failed'. + throw new std::logic_error("Attempt to push_pixel past the end of the image"); } } }; @@ -383,7 +383,7 @@ class raw_bitmap @param pEventualCanvas Canvas to render the image to (eventually). @return Loading was a success. */ - bool load_from_th_file(const uint8_t* pPixelData, size_t iPixelDataLength, + void load_from_th_file(const uint8_t* pPixelData, size_t iPixelDataLength, int iWidth, render_target *pEventualCanvas); //! Draw the image at a given position at the given canvas. diff --git a/CorsixTH/Src/th_lua_gfx.cpp b/CorsixTH/Src/th_lua_gfx.cpp index d06fc55a4d..a0bef3dfe0 100644 --- a/CorsixTH/Src/th_lua_gfx.cpp +++ b/CorsixTH/Src/th_lua_gfx.cpp @@ -24,6 +24,7 @@ SOFTWARE. #include "th_gfx.h" #include #include +#include static int l_palette_new(lua_State *L) { @@ -80,11 +81,16 @@ static int l_rawbitmap_load(lua_State *L) int iWidth = static_cast(luaL_checkinteger(L, 3)); render_target* pSurface = luaT_testuserdata(L, 4, luaT_upvalueindex(1), false); - if(pBitmap->load_from_th_file(pData, iDataLen, iWidth, pSurface)) - lua_pushboolean(L, 1); - else - lua_pushboolean(L, 0); + try { + pBitmap->load_from_th_file(pData, iDataLen, iWidth, pSurface); + } + catch (const std::exception& ex) { + lua_pushstring(L, ex.what()); + lua_error(L); + return 1; + } + lua_pushboolean(L, 1); return 1; }