Move SDL_LoadBMP call to libopenrct2ui (#5616)

This commit is contained in:
Ted John 2017-06-14 19:47:22 +01:00 committed by GitHub
parent 46b575ee18
commit 1dae7f9f32
6 changed files with 86 additions and 23 deletions

View File

@ -27,6 +27,7 @@
#include <openrct2/core/Math.hpp>
#include <openrct2/core/String.hpp>
#include <openrct2/drawing/IDrawingEngine.h>
#include <openrct2/localisation/string_ids.h>
#include <openrct2/platform/Platform2.h>
#include <openrct2/ui/UiContext.h>
#include <openrct2/Version.h>
@ -43,6 +44,7 @@ extern "C"
#include <openrct2/input.h>
#include <openrct2/interface/console.h>
#include <openrct2/interface/window.h>
#include <openrct2/windows/error.h>
}
using namespace OpenRCT2;
@ -574,6 +576,70 @@ public:
return _windowManager;
}
bool ReadBMP(void * * outPixels, uint32 * outWidth, uint32 * outHeight, const std::string &path) override
{
auto bitmap = SDL_LoadBMP(path.c_str());
if (bitmap != nullptr)
{
sint32 numChannels = bitmap->format->BytesPerPixel;
if (numChannels < 3 || bitmap->format->BitsPerPixel < 24)
{
window_error_open(STR_HEIGHT_MAP_ERROR, STR_ERROR_24_BIT_BITMAP);
SDL_FreeSurface(bitmap);
return false;
}
// Copy pixels over, then discard the surface
*outPixels = nullptr;
*outWidth = bitmap->w;
*outHeight = bitmap->h;
if (SDL_LockSurface(bitmap) == 0)
{
*outPixels = malloc(bitmap->w * bitmap->h * 4);
memset(*outPixels, 0xFF, bitmap->w * bitmap->h);
auto src = (const uint8 *)bitmap->pixels;
auto dst = (uint8 *)*outPixels;
if (numChannels == 4)
{
for (sint32 y = 0; y < bitmap->h; y++)
{
memcpy(dst, src, bitmap->w);
src += bitmap->pitch;
dst += bitmap->w;
}
}
else
{
for (sint32 y = 0; y < bitmap->h; y++)
{
for (sint32 x = 0; x < bitmap->w; x++)
{
memcpy(dst, src, 3);
src += 3;
dst += 4;
}
src += bitmap->pitch - (bitmap->w * 3);
}
}
SDL_UnlockSurface(bitmap);
}
else
{
return false;
}
SDL_FreeSurface(bitmap);
return true;
}
else
{
log_warning("Failed to load bitmap: %s", SDL_GetError());
window_error_open(STR_HEIGHT_MAP_ERROR, STR_ERROR_READING_BITMAP);
return false;
}
}
private:
void OnResize(sint32 width, sint32 height)
{

View File

@ -671,6 +671,11 @@ extern "C"
windowManager->HandleKeyboard(isTitle);
}
bool context_read_bmp(void * * outPixels, uint32 * outWidth, uint32 * outHeight, const utf8 * path)
{
return GetContext()->GetUiContext()->ReadBMP(outPixels, outWidth, outHeight, std::string(path));
}
bool platform_open_common_file_dialog(utf8 * outFilename, file_dialog_desc * desc, size_t outSize)
{
try

View File

@ -129,6 +129,7 @@ extern "C"
void context_set_cursor_trap(bool value);
rct_window * context_open_window(rct_windowclass wc);
void context_input_handle_keyboard(bool isTitle);
bool context_read_bmp(void * * outPixels, uint32 * outWidth, uint32 * outHeight, const utf8 * path);
#ifdef __cplusplus
}
#endif

View File

@ -76,6 +76,9 @@ namespace OpenRCT2 { namespace Ui
{
return _windowManager;
}
// Misc
bool ReadBMP(void * * outPixels, uint32 * outWidth, uint32 * outHeight, const std::string &path) override { return false; }
};
IUiContext * CreateDummyUiContext()

View File

@ -131,6 +131,11 @@ namespace OpenRCT2
// In-game UI
virtual IWindowManager * GetWindowManager() abstract;
// Misc.
// HACK: This should either be implemented ourselves in libopenrct2
// or the mapgen height map code is moved to libopenrct2ui.
virtual bool ReadBMP(void * * outPixels, uint32 * outWidth, uint32 * outHeight, const std::string &path) abstract;
};
IUiContext * CreateDummyUiContext();

View File

@ -16,7 +16,8 @@
#include "../common.h"
#include <math.h>
#include <SDL.h>
#include "../Context.h"
#include "../Imaging.h"
#include "../core/Guard.hpp"
#include "../game.h"
@ -805,31 +806,13 @@ bool mapgen_load_heightmap(const utf8 *path)
pitch = width * numChannels;
}
else if (strcicmp(extension, ".bmp") == 0) {
SDL_Surface *bitmap = SDL_LoadBMP(path);
if (bitmap == NULL) {
log_warning("Failed to load bitmap: %s", SDL_GetError());
window_error_open(STR_HEIGHT_MAP_ERROR, STR_ERROR_READING_BITMAP);
if (!context_read_bmp((void *)&pixels, &width, &height, path)) {
// ReadBMP contains window_error_open calls
return false;
}
width = bitmap->w;
height = bitmap->h;
numChannels = bitmap->format->BytesPerPixel;
pitch = bitmap->pitch;
if (numChannels < 3 || bitmap->format->BitsPerPixel < 24)
{
window_error_open(STR_HEIGHT_MAP_ERROR, STR_ERROR_24_BIT_BITMAP);
SDL_FreeSurface(bitmap);
return false;
}
// Copy pixels over, then discard the surface
SDL_LockSurface(bitmap);
pixels = malloc(height * bitmap->pitch);
memcpy(pixels, bitmap->pixels, height * bitmap->pitch);
SDL_UnlockSurface(bitmap);
SDL_FreeSurface(bitmap);
numChannels = 4;
pitch = width * numChannels;
}
else
{