From 8ae43fd0ff93f4474ea671a7ebe23d40bdf7654c Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 29 Dec 2015 13:50:31 +0000 Subject: [PATCH 1/7] use libpng for screenshots --- src/interface/screenshot.c | 166 ++++++++++++++++++++++--------------- 1 file changed, 101 insertions(+), 65 deletions(-) diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index 25af755b56..c492007fb6 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -17,9 +17,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *****************************************************************************/ + #pragma pack(1) -#include +#ifdef USE_LIBPNG + #include +#else + #include +#endif + #include "../addresses.h" #include "../config.h" #include "../drawing/drawing.h" @@ -37,6 +43,13 @@ static const char *_screenshot_format_extension[] = { ".bmp", ".png" }; static int screenshot_dump_bmp(); static int screenshot_dump_png(); +bool screenshot_write_png(rct_drawpixelinfo *dpi, const char *path); + +#ifdef USE_LIBPNG + static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length); + static void my_png_flush(png_structp png_ptr); +#endif + /** * * rct2: 0x006E3AEC @@ -242,80 +255,87 @@ int screenshot_dump_bmp() int screenshot_dump_png() { - rct_drawpixelinfo *dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); - - int i, index, width, height, padding; - char path[MAX_PATH] = ""; - unsigned int error; - unsigned char r, g, b, a = 255; - - unsigned char* png; - size_t pngSize; - LodePNGState state; - // Get a free screenshot path - if ((index = screenshot_get_next_path(path, SCREENSHOT_FORMAT_PNG)) == -1) + int index; + char path[MAX_PATH] = ""; + if ((index = screenshot_get_next_path(path, SCREENSHOT_FORMAT_PNG)) == -1) { return -1; - - - lodepng_state_init(&state); - state.info_raw.colortype = LCT_PALETTE; - - // Get image size - width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); - height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); - - padding = dpi->pitch; - - for (i = 0; i < 256; i++) { - b = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 0]; - g = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 1]; - r = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 2]; - - lodepng_palette_add(&state.info_raw, r, g, b, a); } - uint8* pixels = dpi->bits; - - if (padding > 0) { - pixels = malloc(width * height); - if (!pixels) { - return -1; - } - uint8* src = dpi->bits; - uint8* dst = pixels; - for (int y = height; y > 0; y--) { - for (int x = width; x > 0; x--) { - *dst++ = *src++; - } - src += padding; - } - } - - error = lodepng_encode(&png, &pngSize, pixels, width, height, &state); - if (error) { - log_error("Unable to save screenshot, %u: %s", lodepng_error_text(error)); - index = -1; + rct_drawpixelinfo *dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); + if (screenshot_write_png(dpi, path)) { + return index; } else { - SDL_RWops *file = SDL_RWFromFile(path, "wb"); - if (file == NULL) { - log_error("Unable to save screenshot, %s", SDL_GetError()); - index = -1; - } else { - SDL_RWwrite(file, png, pngSize, 1); - SDL_RWclose(file); - } + return -1; } - - free(png); - if ((utf8*)pixels != (utf8*)dpi->bits) { - free(pixels); - } - return index; } bool screenshot_write_png(rct_drawpixelinfo *dpi, const char *path) { +#ifdef USE_LIBPNG + // Get image size + int stride = dpi->width + dpi->pitch; + + // Setup PNG + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) { + return false; + } + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return false; + } + + png_colorp palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof(png_color)); + for (int i = 0; i < 256; i++) { + palette[i].blue = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 0]; + palette[i].green = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 1]; + palette[i].red = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 2]; + } + + png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); + + // Open file for writing + SDL_RWops *file = SDL_RWFromFile(path, "wb"); + if (file == NULL) { + png_free(png_ptr, palette); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return false; + } + png_set_write_fn(png_ptr, file, my_png_write_data, my_png_flush); + + // Set error handler + if (setjmp(png_jmpbuf(png_ptr))) { + png_free(png_ptr, palette); + png_destroy_write_struct(&png_ptr, &info_ptr); + SDL_RWclose(file); + return false; + } + + // Write header + png_set_IHDR( + png_ptr, info_ptr, dpi->width, dpi->height, 8, + PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT + ); + png_write_info(png_ptr, info_ptr); + + // Write pixels + uint8 *bits = dpi->bits; + for (int y = 0; y < dpi->height; y++) { + png_write_row(png_ptr, (png_const_bytep)bits); + bits += stride; + } + + // Finish + png_write_end(png_ptr, NULL); + SDL_RWclose(file); + + png_free(png_ptr, palette); + png_destroy_write_struct(&png_ptr, &info_ptr); + return true; +#else unsigned int error; unsigned char* png; size_t pngSize; @@ -353,6 +373,7 @@ bool screenshot_write_png(rct_drawpixelinfo *dpi, const char *path) free(png); return true; +#endif } void screenshot_giant() @@ -577,3 +598,18 @@ int cmdline_for_screenshot(const char **argv, int argc) openrct2_dispose(); return 1; } + +#ifdef USE_LIBPNG + +static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + SDL_RWops *file = (SDL_RWops*)png_get_io_ptr(png_ptr); + SDL_RWwrite(file, data, length, 1); +} + +static void my_png_flush(png_structp png_ptr) +{ + +} + +#endif From 9321c53b878c9d052c3f62e1476b4cdb6e51d92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Tue, 29 Dec 2015 15:15:25 +0100 Subject: [PATCH 2/7] Enable libpng on Linux builds Lodepng is still available. --- CMakeLists.txt | 12 ++++++++++-- src/interface/screenshot.c | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e0a44bcff2..564cfb7613 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ project(${PROJECT}) add_definitions(-DORCT2_RESOURCE_DIR="${ORCT2_RESOURCE_DIR}") add_definitions(-DHAVE_CONFIG_H) add_definitions(-DCURL_STATICLIB) +add_definitions(-DUSE_LIBPNG) INCLUDE(FindPkgConfig) @@ -135,6 +136,13 @@ else (STATIC) SET(SDL2LIBS ${SDL2_LIBRARIES}) endif (STATIC) +PKG_CHECK_MODULES(PNG REQUIRED libpng>=1.6) +if (STATIC) + SET(PNGLIBS ${PNG_STATIC_LIBRARIES}) +else (STATIC) + SET(PNGLIBS ${PNG_LIBRARIES}) +endif (STATIC) + if (NOT DISABLE_HTTP_TWITCH) PKG_CHECK_MODULES(LIBCURL REQUIRED libcurl) PKG_CHECK_MODULES(JANSSON REQUIRED jansson>=2.7) @@ -165,7 +173,7 @@ if (UNIX) set(DLLIB dl) endif (UNIX) -INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS}) LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS}) @@ -200,7 +208,7 @@ endif (UNIX AND NOT APPLE) # libopenrct2.dll -> openrct2.dll set_target_properties(${PROJECT} PROPERTIES PREFIX "") -TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2LIBS} ${ORCTLIBS_LIB} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB}) +TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2LIBS} ${ORCTLIBS_LIB} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB} ${PNGLIBS}) if (APPLE OR STATIC) FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c) diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index c492007fb6..7966fecaed 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -21,7 +21,7 @@ #pragma pack(1) #ifdef USE_LIBPNG - #include + #include #else #include #endif From 00e5c4418d038abf72c0d690da11e8343a4ac015 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 29 Dec 2015 14:32:51 +0000 Subject: [PATCH 3/7] refactor image IO to new source file --- openrct2.vcxproj | 2 + openrct2.vcxproj.filters | 6 + src/drawing/drawing.h | 11 ++ src/image_io.c | 258 +++++++++++++++++++++++++++++++++++ src/image_io.h | 10 ++ src/interface/screenshot.c | 271 ++----------------------------------- 6 files changed, 302 insertions(+), 256 deletions(-) create mode 100644 src/image_io.c create mode 100644 src/image_io.h diff --git a/openrct2.vcxproj b/openrct2.vcxproj index 9eba05d0b3..a430d4746c 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -49,6 +49,7 @@ + @@ -218,6 +219,7 @@ + diff --git a/openrct2.vcxproj.filters b/openrct2.vcxproj.filters index bd11a5e391..4d1a1f4363 100644 --- a/openrct2.vcxproj.filters +++ b/openrct2.vcxproj.filters @@ -558,6 +558,9 @@ Source\Windows + + Source + @@ -839,5 +842,8 @@ Source\Core + + Source + \ No newline at end of file diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index f4a6f885f7..0cd56e2cfb 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -69,6 +69,17 @@ typedef struct { void *data; } rct_gx; +typedef struct { + uint8 blue; + uint8 green; + uint8 red; + uint8 alpha; +} rct_palette_entry; + +typedef struct { + rct_palette_entry entries[256]; +} rct_palette; + #define SPRITE_ID_PALETTE_COLOUR_1(colourId) ((IMAGE_TYPE_USE_PALETTE << 28) | ((colourId) << 19)) extern const uint16 palette_to_g1_offset[]; diff --git a/src/image_io.c b/src/image_io.c new file mode 100644 index 0000000000..0dbb87ace5 --- /dev/null +++ b/src/image_io.c @@ -0,0 +1,258 @@ +#ifdef USE_LIBPNG + #include +#else + #include +#endif + +#include "image_io.h" + +#ifdef USE_LIBPNG + static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length); + static void my_png_flush(png_structp png_ptr); +#endif + +bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette, const utf8 *path) +{ +#ifdef USE_LIBPNG + // Get image size + int stride = dpi->width + dpi->pitch; + + // Setup PNG + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) { + return false; + } + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return false; + } + + png_colorp png_palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof(png_color)); + for (int i = 0; i < 256; i++) { + const rct_palette_entry *entry = &palette->entries[i]; + png_palette[i].blue = entry->blue; + png_palette[i].green = entry->green; + png_palette[i].red = entry->red; + } + + png_set_PLTE(png_ptr, info_ptr, png_palette, PNG_MAX_PALETTE_LENGTH); + + // Open file for writing + SDL_RWops *file = SDL_RWFromFile(path, "wb"); + if (file == NULL) { + png_free(png_ptr, png_palette); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return false; + } + png_set_write_fn(png_ptr, file, my_png_write_data, my_png_flush); + + // Set error handler + if (setjmp(png_jmpbuf(png_ptr))) { + png_free(png_ptr, png_palette); + png_destroy_write_struct(&png_ptr, &info_ptr); + SDL_RWclose(file); + return false; + } + + // Write header + png_set_IHDR( + png_ptr, info_ptr, dpi->width, dpi->height, 8, + PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT + ); + png_write_info(png_ptr, info_ptr); + + // Write pixels + uint8 *bits = dpi->bits; + for (int y = 0; y < dpi->height; y++) { + png_write_row(png_ptr, (png_const_bytep)bits); + bits += stride; + } + + // Finish + png_write_end(png_ptr, NULL); + SDL_RWclose(file); + + png_free(png_ptr, png_palette); + png_destroy_write_struct(&png_ptr, &info_ptr); + return true; +#else + unsigned int error; + unsigned char* png; + size_t pngSize; + LodePNGState state; + + lodepng_state_init(&state); + state.info_raw.colortype = LCT_PALETTE; + + // Get image size + int stride = dpi->width + dpi->pitch; + + for (int i = 0; i < 256; i++) { + const rct_palette_entry *entry = &palette->entries[i]; + uint8 r = entry->red; + uint8 g = entry->green; + uint8 b = entry->blue; + uint8 a = 255; + lodepng_palette_add(&state.info_raw, r, g, b, a); + } + + error = lodepng_encode(&png, &pngSize, dpi->bits, stride, dpi->height, &state); + if (error != 0) { + free(png); + return false; + } else { + SDL_RWops *file = SDL_RWFromFile(path, "wb"); + if (file == NULL) { + free(png); + return false; + } + SDL_RWwrite(file, png, pngSize, 1); + SDL_RWclose(file); + } + + free(png); + return true; +#endif +} + +#ifdef USE_LIBPNG + +static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + SDL_RWops *file = (SDL_RWops*)png_get_io_ptr(png_ptr); + SDL_RWwrite(file, data, length, 1); +} + +static void my_png_flush(png_structp png_ptr) +{ + +} + +#endif + +// Bitmap header structs, for cross platform purposes +typedef struct { + uint16 bfType; + uint32 bfSize; + uint16 bfReserved1; + uint16 bfReserved2; + uint32 bfOffBits; +} BitmapFileHeader; + +typedef struct { + uint32 biSize; + sint32 biWidth; + sint32 biHeight; + uint16 biPlanes; + uint16 biBitCount; + uint32 biCompression; + uint32 biSizeImage; + sint32 biXPelsPerMeter; + sint32 biYPelsPerMeter; + uint32 biClrUsed; + uint32 biClrImportant; +} BitmapInfoHeader; + +/** + * + * rct2: 0x00683D20 + */ +bool image_io_bmp_write(const rct_drawpixelinfo *dpi, const rct_palette *palette, const utf8 *path) +{ + BitmapFileHeader header; + BitmapInfoHeader info; + + int i, y, width, height, stride; + uint8 *buffer, *row; + SDL_RWops *fp; + unsigned int bytesWritten; + + // Open binary file for writing + if ((fp = SDL_RWFromFile(path, "wb")) == NULL){ + return false; + } + + // Allocate buffer + buffer = malloc(0xFFFF); + if (buffer == NULL) { + SDL_RWclose(fp); + return false; + } + + // Get image size + width = dpi->width; + height = dpi->height; + stride = dpi->width + dpi->pitch; + + // File header + memset(&header, 0, sizeof(header)); + header.bfType = 0x4D42; + header.bfSize = height * stride + 1038; + header.bfOffBits = 1038; + + bytesWritten = SDL_RWwrite(fp, &header, sizeof(BitmapFileHeader), 1); + if (bytesWritten != 1) { + SDL_RWclose(fp); + SafeFree(buffer); + log_error("failed to save screenshot"); + return false; + } + + // Info header + memset(&info, 0, sizeof(info)); + info.biSize = sizeof(info); + info.biWidth = width; + info.biHeight = height; + info.biPlanes = 1; + info.biBitCount = 8; + info.biXPelsPerMeter = 2520; + info.biYPelsPerMeter = 2520; + info.biClrUsed = 246; + + bytesWritten = SDL_RWwrite(fp, &info, sizeof(BitmapInfoHeader), 1); + if (bytesWritten != 1) { + SDL_RWclose(fp); + SafeFree(buffer); + log_error("failed to save screenshot"); + return false; + } + + // Palette + memset(buffer, 0, 246 * 4); + for (i = 0; i < 246; i++) { + const rct_palette_entry *entry = &palette->entries[i]; + buffer[i * 4 + 0] = entry->blue; + buffer[i * 4 + 1] = entry->green; + buffer[i * 4 + 2] = entry->red; + } + + bytesWritten = SDL_RWwrite(fp, buffer, sizeof(char), 246 * 4); + if (bytesWritten != 246*4){ + SDL_RWclose(fp); + SafeFree(buffer); + log_error("failed to save screenshot"); + return false; + } + + // Image, save upside down + for (y = dpi->height - 1; y >= 0; y--) { + row = dpi->bits + y * (dpi->width + dpi->pitch); + + memset(buffer, 0, stride); + memcpy(buffer, row, dpi->width); + + bytesWritten = SDL_RWwrite(fp, buffer, sizeof(char), stride); + if (bytesWritten != stride){ + SDL_RWclose(fp); + SafeFree(buffer); + log_error("failed to save screenshot"); + return false; + } + } + + SDL_RWclose(fp); + free(buffer); + return true; +} diff --git a/src/image_io.h b/src/image_io.h new file mode 100644 index 0000000000..70ce4cdcc7 --- /dev/null +++ b/src/image_io.h @@ -0,0 +1,10 @@ +#ifndef _IMAGE_IO_H_ +#define _IMAGE_IO_H_ + +#include "common.h" +#include "drawing/drawing.h" + +bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette, const utf8 *path); +bool image_io_bmp_write(const rct_drawpixelinfo *dpi, const rct_palette *palette, const utf8 *path); + +#endif diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index 7966fecaed..81b7693e0e 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -18,18 +18,11 @@ * along with this program. If not, see . *****************************************************************************/ -#pragma pack(1) - -#ifdef USE_LIBPNG - #include -#else - #include -#endif - #include "../addresses.h" #include "../config.h" #include "../drawing/drawing.h" #include "../game.h" +#include "../image_io.h" #include "../localisation/localisation.h" #include "../openrct2.h" #include "../platform/platform.h" @@ -43,13 +36,6 @@ static const char *_screenshot_format_extension[] = { ".bmp", ".png" }; static int screenshot_dump_bmp(); static int screenshot_dump_png(); -bool screenshot_write_png(rct_drawpixelinfo *dpi, const char *path); - -#ifdef USE_LIBPNG - static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length); - static void my_png_flush(png_structp png_ptr); -#endif - /** * * rct2: 0x006E3AEC @@ -122,135 +108,26 @@ int screenshot_dump() } } -// Bitmap header structs, for cross platform purposes -typedef struct { - uint16 bfType; - uint32 bfSize; - uint16 bfReserved1; - uint16 bfReserved2; - uint32 bfOffBits; -} BitmapFileHeader; - -typedef struct { - uint32 biSize; - sint32 biWidth; - sint32 biHeight; - uint16 biPlanes; - uint16 biBitCount; - uint32 biCompression; - uint32 biSizeImage; - sint32 biXPelsPerMeter; - sint32 biYPelsPerMeter; - uint32 biClrUsed; - uint32 biClrImportant; -} BitmapInfoHeader; - /** * * rct2: 0x00683D20 */ int screenshot_dump_bmp() { - BitmapFileHeader header; - BitmapInfoHeader info; - - int i, y, index, width, height, stride; - char path[MAX_PATH]; - uint8 *buffer, *row; - SDL_RWops *fp; - unsigned int bytesWritten; - // Get a free screenshot path - if ((index = screenshot_get_next_path(path, SCREENSHOT_FORMAT_BMP)) == -1) - return -1; - - // Open binary file for writing - if ((fp = SDL_RWFromFile(path, "wb")) == NULL){ + int index; + char path[MAX_PATH] = ""; + if ((index = screenshot_get_next_path(path, SCREENSHOT_FORMAT_BMP)) == -1) { return -1; } - // Allocate buffer - buffer = malloc(0xFFFF); - if (buffer == NULL) { - SDL_RWclose(fp); - return -1; - } - - // Get image size - width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); - height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); - stride = (width + 3) & 0xFFFFFFFC; - - // File header - memset(&header, 0, sizeof(header)); - header.bfType = 0x4D42; - header.bfSize = height * stride + 1038; - header.bfOffBits = 1038; - - bytesWritten = SDL_RWwrite(fp, &header, sizeof(BitmapFileHeader), 1); - if (bytesWritten != 1) { - SDL_RWclose(fp); - SafeFree(buffer); - log_error("failed to save screenshot"); - return -1; - } - - // Info header - memset(&info, 0, sizeof(info)); - info.biSize = sizeof(info); - info.biWidth = width; - info.biHeight = height; - info.biPlanes = 1; - info.biBitCount = 8; - info.biXPelsPerMeter = 2520; - info.biYPelsPerMeter = 2520; - info.biClrUsed = 246; - - bytesWritten = SDL_RWwrite(fp, &info, sizeof(BitmapInfoHeader), 1); - if (bytesWritten != 1) { - SDL_RWclose(fp); - SafeFree(buffer); - log_error("failed to save screenshot"); - return -1; - } - - // Palette - memset(buffer, 0, 246 * 4); - for (i = 0; i < 246; i++) { - buffer[i * 4 + 0] = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 0]; - buffer[i * 4 + 1] = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 1]; - buffer[i * 4 + 2] = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 2]; - } - - bytesWritten = SDL_RWwrite(fp, buffer, sizeof(char), 246 * 4); - if (bytesWritten != 246*4){ - SDL_RWclose(fp); - SafeFree(buffer); - log_error("failed to save screenshot"); - return -1; - } - - // Image, save upside down rct_drawpixelinfo *dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); - for (y = dpi->height - 1; y >= 0; y--) { - row = dpi->bits + y * (dpi->width + dpi->pitch); - - memset(buffer, 0, stride); - memcpy(buffer, row, dpi->width); - - bytesWritten = SDL_RWwrite(fp, buffer, sizeof(char), stride); - if (bytesWritten != stride){ - SDL_RWclose(fp); - SafeFree(buffer); - log_error("failed to save screenshot"); - return -1; - } + rct_palette *palette = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, rct_palette); + if (image_io_bmp_write(dpi, palette, path)) { + return index; + } else { + return -1; } - - SDL_RWclose(fp); - free(buffer); - - return index; } int screenshot_dump_png() @@ -263,119 +140,14 @@ int screenshot_dump_png() } rct_drawpixelinfo *dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); - if (screenshot_write_png(dpi, path)) { + rct_palette *palette = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, rct_palette); + if (image_io_png_write(dpi, palette, path)) { return index; } else { return -1; } } -bool screenshot_write_png(rct_drawpixelinfo *dpi, const char *path) -{ -#ifdef USE_LIBPNG - // Get image size - int stride = dpi->width + dpi->pitch; - - // Setup PNG - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (png_ptr == NULL) { - return false; - } - - png_infop info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - return false; - } - - png_colorp palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof(png_color)); - for (int i = 0; i < 256; i++) { - palette[i].blue = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 0]; - palette[i].green = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 1]; - palette[i].red = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 2]; - } - - png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); - - // Open file for writing - SDL_RWops *file = SDL_RWFromFile(path, "wb"); - if (file == NULL) { - png_free(png_ptr, palette); - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - return false; - } - png_set_write_fn(png_ptr, file, my_png_write_data, my_png_flush); - - // Set error handler - if (setjmp(png_jmpbuf(png_ptr))) { - png_free(png_ptr, palette); - png_destroy_write_struct(&png_ptr, &info_ptr); - SDL_RWclose(file); - return false; - } - - // Write header - png_set_IHDR( - png_ptr, info_ptr, dpi->width, dpi->height, 8, - PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT - ); - png_write_info(png_ptr, info_ptr); - - // Write pixels - uint8 *bits = dpi->bits; - for (int y = 0; y < dpi->height; y++) { - png_write_row(png_ptr, (png_const_bytep)bits); - bits += stride; - } - - // Finish - png_write_end(png_ptr, NULL); - SDL_RWclose(file); - - png_free(png_ptr, palette); - png_destroy_write_struct(&png_ptr, &info_ptr); - return true; -#else - unsigned int error; - unsigned char* png; - size_t pngSize; - LodePNGState state; - - lodepng_state_init(&state); - state.info_raw.colortype = LCT_PALETTE; - - // Get image size - int stride = (dpi->width + 3) & ~3; - - for (int i = 0; i < 256; i++) { - unsigned char r, g, b, a = 255; - - b = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 0]; - g = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 1]; - r = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, uint8)[i * 4 + 2]; - - lodepng_palette_add(&state.info_raw, r, g, b, a); - } - - error = lodepng_encode(&png, &pngSize, dpi->bits, stride, dpi->height, &state); - if (error != 0) { - free(png); - return false; - } else { - SDL_RWops *file = SDL_RWFromFile(path, "wb"); - if (file == NULL) { - free(png); - return false; - } - SDL_RWwrite(file, png, pngSize, 1); - SDL_RWclose(file); - } - - free(png); - return true; -#endif -} - void screenshot_giant() { int originalRotation = get_current_rotation(); @@ -457,7 +229,8 @@ void screenshot_giant() return; } - screenshot_write_png(&dpi, path); + rct_palette *palette = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, rct_palette); + image_io_png_write(&dpi, palette, path); free(dpi.bits); @@ -591,25 +364,11 @@ int cmdline_for_screenshot(const char **argv, int argc) viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); - screenshot_write_png(&dpi, outputPath); + rct_palette *palette = RCT2_ADDRESS(RCT2_ADDRESS_PALETTE, rct_palette); + image_io_png_write(&dpi, palette, outputPath); free(dpi.bits); } openrct2_dispose(); return 1; } - -#ifdef USE_LIBPNG - -static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - SDL_RWops *file = (SDL_RWops*)png_get_io_ptr(png_ptr); - SDL_RWwrite(file, data, length, 1); -} - -static void my_png_flush(png_structp png_ptr) -{ - -} - -#endif From cabd0fdc3a223d7813c98d52e1e1296dbf5e0963 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 29 Dec 2015 15:16:05 +0000 Subject: [PATCH 4/7] use image_io_png_write in cmdline_sprite --- src/cmdline_sprite.c | 31 +++++-------------------------- src/image_io.c | 6 +++++- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/src/cmdline_sprite.c b/src/cmdline_sprite.c index dff9acbf18..7f4c12974f 100644 --- a/src/cmdline_sprite.c +++ b/src/cmdline_sprite.c @@ -21,6 +21,7 @@ #include #include "cmdline.h" #include "drawing/drawing.h" +#include "image_io.h" #include "platform/platform.h" #include "util/util.h" #include "openrct2.h" @@ -168,33 +169,11 @@ bool sprite_file_export(int spriteIndex, const char *outPath) memcpy(spriteFilePalette, _standardPalette, 256 * 4); gfx_rle_sprite_to_buffer(spriteHeader->offset, pixels, (uint8*)spriteFilePalette, &dpi, IMAGE_TYPE_NO_BACKGROUND, 0, spriteHeader->height, 0, spriteHeader->width); - LodePNGState pngState; - unsigned int pngError; - unsigned char* pngData; - size_t pngSize; - - lodepng_state_init(&pngState); - pngState.info_raw.colortype = LCT_PALETTE; - lodepng_palette_add(&pngState.info_raw, 0, 0, 0, 0); - for (int i = 1; i < 256; i++) { - lodepng_palette_add( - &pngState.info_raw, - spriteFilePalette[i].r, - spriteFilePalette[i].g, - spriteFilePalette[i].b, - 255 - ); - } - - pngError = lodepng_encode(&pngData, &pngSize, pixels, spriteHeader->width, spriteHeader->height, &pngState); - if (pngError != 0) { - free(pngData); - fprintf(stderr, "Error creating PNG data, %u: %s", pngError, lodepng_error_text(pngError)); - return false; - } else { - lodepng_save_file(pngData, pngSize, outPath); - free(pngData); + if (image_io_png_write(&dpi, (rct_palette*)spriteFilePalette, outPath)) { return true; + } else { + fprintf(stderr, "Error writing PNG"); + return false; } } diff --git a/src/image_io.c b/src/image_io.c index 0dbb87ace5..d6e90decbc 100644 --- a/src/image_io.c +++ b/src/image_io.c @@ -61,6 +61,8 @@ bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette png_ptr, info_ptr, dpi->width, dpi->height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ); + png_byte transparentIndex = 0; + png_set_tRNS(png_ptr, info_ptr, &transparentIndex, 1, NULL); png_write_info(png_ptr, info_ptr); // Write pixels @@ -89,7 +91,8 @@ bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette // Get image size int stride = dpi->width + dpi->pitch; - for (int i = 0; i < 256; i++) { + lodepng_palette_add(&state.info_raw, 0, 0, 0, 0); + for (int i = 1; i < 256; i++) { const rct_palette_entry *entry = &palette->entries[i]; uint8 r = entry->red; uint8 g = entry->green; @@ -100,6 +103,7 @@ bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette error = lodepng_encode(&png, &pngSize, dpi->bits, stride, dpi->height, &state); if (error != 0) { + log_error("Error creating PNG data, %u: %s", error, lodepng_error_text(error)); free(png); return false; } else { From 68a600f67993cef488961e491f8ce3d054099786 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 29 Dec 2015 16:21:08 +0000 Subject: [PATCH 5/7] finish converting last lodepng calls to libpng --- src/cmdline_sprite.c | 19 +++----- src/image_io.c | 109 +++++++++++++++++++++++++++++++++++++++++++ src/image_io.h | 2 + 3 files changed, 118 insertions(+), 12 deletions(-) diff --git a/src/cmdline_sprite.c b/src/cmdline_sprite.c index 7f4c12974f..c7fc2eec5c 100644 --- a/src/cmdline_sprite.c +++ b/src/cmdline_sprite.c @@ -18,13 +18,12 @@ * along with this program. If not, see . *****************************************************************************/ -#include #include "cmdline.h" #include "drawing/drawing.h" #include "image_io.h" +#include "openrct2.h" #include "platform/platform.h" #include "util/util.h" -#include "openrct2.h" #define MODE_DEFAULT 0 #define MODE_CLOSEST 1 @@ -240,16 +239,10 @@ typedef struct { bool sprite_file_import(const char *path, rct_g1_element *outElement, uint8 **outBuffer, int *outBufferLength, int mode) { - unsigned char *pixels; - unsigned int width, height; - unsigned int pngError; - - memcpy(spriteFilePalette, _standardPalette, 256 * 4); - - pngError = lodepng_decode_file(&pixels, &width, &height, path, LCT_RGBA, 8); - if (pngError != 0) { - free(pixels); - fprintf(stderr, "Error creating PNG data, %u: %s", pngError, lodepng_error_text(pngError)); + uint8 *pixels; + uint32 width, height; + if (!image_io_png_read(&pixels, &width, &height, path)) { + fprintf(stderr, "Error reading PNG"); return false; } @@ -259,6 +252,8 @@ bool sprite_file_import(const char *path, rct_g1_element *outElement, uint8 **ou return false; } + memcpy(spriteFilePalette, _standardPalette, 256 * 4); + uint8 *buffer = malloc((height * 2) + (width * height * 16)); memset(buffer, 0, (height * 2) + (width * height * 16)); uint16 *yOffsets = (uint16*)buffer; diff --git a/src/image_io.c b/src/image_io.c index d6e90decbc..cc14cc012c 100644 --- a/src/image_io.c +++ b/src/image_io.c @@ -7,10 +7,113 @@ #include "image_io.h" #ifdef USE_LIBPNG + static void my_png_read_data(png_structp png_ptr, png_bytep data, png_size_t length); static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length); static void my_png_flush(png_structp png_ptr); #endif +bool image_io_png_read(uint8 **pixels, uint32 *width, uint32 *height, const utf8 *path) +{ +#ifdef USE_LIBPNG + png_structp png_ptr; + png_infop info_ptr; + unsigned int sig_read = 0; + + // Setup PNG structures + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) { + return false; + } + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + png_destroy_read_struct(&png_ptr, NULL, NULL); + return false; + } + + // Open PNG file + SDL_RWops *fp = SDL_RWFromFile(path, "rb"); + if (fp == NULL) { + return false; + } + + // Set error handling + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + SDL_RWclose(fp); + return false; + } + + // Setup png reading + png_set_read_fn(png_ptr, fp, my_png_read_data); + png_set_sig_bytes(png_ptr, sig_read); + + // To simplify the reading process, convert 4-16 bit data to 24-32 bit data + png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL); + + // Read header + png_uint_32 pngWidth, pngHeight; + int bit_depth, color_type, interlace_type; + png_get_IHDR(png_ptr, info_ptr, &pngWidth, &pngHeight, &bit_depth, &color_type, &interlace_type, NULL, NULL); + + // Read pixels as 32bpp RGBA data + png_size_t rowBytes = png_get_rowbytes(png_ptr, info_ptr); + png_bytepp rowPointers = png_get_rows(png_ptr, info_ptr); + uint8 *pngPixels = (uint8*)malloc(pngWidth * pngHeight * 4); + uint8 *dst = pngPixels; + if (color_type == PNG_COLOR_TYPE_RGB) { + // 24-bit PNG (no alpha) + const png_size_t expectedRowSize = pngWidth * 3; + for (png_uint_32 i = 0; i < pngHeight; i++) { + assert(rowBytes == expectedRowSize); + + uint8 *src = rowPointers[i]; + for (png_uint_32 x = 0; x < pngWidth; x++) { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = 255; + } + } + } else { + // 32-bit PNG (with alpha) + const png_size_t expectedRowSize = pngWidth * 4; + for (png_uint_32 i = 0; i < pngHeight; i++) { + assert(rowBytes == expectedRowSize); + + memcpy(dst, rowPointers[i], rowBytes); + dst += rowBytes; + } + } + + // Close the PNG + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + SDL_RWclose(fp); + + // Return the output data + *pixels = (uint8*)pngPixels; + if (width != NULL) *width = pngWidth; + if (height != NULL) *height = pngHeight; + return true; +#else + // Read the pixels as 32bpp RGBA + unsigned char *pngPixels; + unsigned int pngWidth, pngHeight; + unsigned int pngError = lodepng_decode_file(&pngPixels, &pngWidth, &pngHeight, path, LCT_RGBA, 8); + if (pngError != 0) { + free(pngPixels); + log_error("Error creating PNG data, %u: %s", pngError, lodepng_error_text(pngError)); + return false; + } + + // Return the output data + *pixels = (uint8*)pngPixels; + if (width != NULL) *width = pngWidth; + if (height != NULL) *height = pngHeight; + return true; +#endif +} + bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette, const utf8 *path) { #ifdef USE_LIBPNG @@ -123,6 +226,12 @@ bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette #ifdef USE_LIBPNG +static void my_png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + SDL_RWops *file = (SDL_RWops*)png_get_io_ptr(png_ptr); + SDL_RWread(file, data, length, 1); +} + static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { SDL_RWops *file = (SDL_RWops*)png_get_io_ptr(png_ptr); diff --git a/src/image_io.h b/src/image_io.h index 70ce4cdcc7..fa8c086b05 100644 --- a/src/image_io.h +++ b/src/image_io.h @@ -4,6 +4,8 @@ #include "common.h" #include "drawing/drawing.h" +bool image_io_png_read(uint8 **pixels, uint32 *width, uint32 *height, const utf8 *path); + bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette, const utf8 *path); bool image_io_bmp_write(const rct_drawpixelinfo *dpi, const rct_palette *palette, const utf8 *path); From 94a3ccdab5976cf268ee48d12dea267694d0203f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Tue, 29 Dec 2015 17:57:13 +0100 Subject: [PATCH 6/7] Detect libpng>=1.6 and fall back to lodepng --- CMakeLists.txt | 25 +++++++++++++++++++++---- scripts/linux/install.sh | 3 ++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 564cfb7613..7bd8c6c612 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,6 @@ project(${PROJECT}) add_definitions(-DORCT2_RESOURCE_DIR="${ORCT2_RESOURCE_DIR}") add_definitions(-DHAVE_CONFIG_H) add_definitions(-DCURL_STATICLIB) -add_definitions(-DUSE_LIBPNG) INCLUDE(FindPkgConfig) @@ -46,6 +45,19 @@ endif (DISABLE_NETWORK) option(STATIC "Create a static build.") +# Not required yet +PKG_CHECK_MODULES(PNG libpng>=1.6) +if (NOT PNG_FOUND) + PKG_CHECK_MODULES(PNG libpng16) +endif (NOT PNG_FOUND) + +if (PNG_FOUND) + set (USE_LODEPNG FALSE) +else (PNG_FOUND) + set (USE_LODEPNG TRUE) + message("Falling back to deprecated Lodepng for PNG support. Please upgrade your system to libpng 1.6") +endif (PNG_FOUND) + # Handle creating the rct2 text and data files on OS X and Linux # See details in src/openrct2.c:openrct2_setup_rct2_segment for how the values # were derived. @@ -97,10 +109,16 @@ set(DEBUG_LEVEL 0 CACHE STRING "Select debug level for compilation. Use value in set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG=${DEBUG_LEVEL}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG=${DEBUG_LEVEL}") +if (USE_LODEPNG) + set (LODEPNG_SOURCES "lib/lodepng/*.c") +else (USE_LODEPNG) + add_definitions(-DUSE_LIBPNG) +endif (USE_LODEPNG) + # include lib include_directories("lib/") # add source files -file(GLOB_RECURSE ORCT2_SOURCES "src/*.c" "src/*.cpp" "lib/argparse/*.c" "lib/cutest/*.c" "lib/lodepng/*.c") +file(GLOB_RECURSE ORCT2_SOURCES "src/*.c" "src/*.cpp" "lib/argparse/*.c" "lib/cutest/*.c" ${LODEPNG_SOURCES}) if (APPLE) file(GLOB_RECURSE ORCT2_MM_SOURCES "src/*.m") set_source_files_properties(${ORCT2_MM_SOURCES} PROPERTIES COMPILE_FLAGS "-x objective-c -fmodules") @@ -136,7 +154,6 @@ else (STATIC) SET(SDL2LIBS ${SDL2_LIBRARIES}) endif (STATIC) -PKG_CHECK_MODULES(PNG REQUIRED libpng>=1.6) if (STATIC) SET(PNGLIBS ${PNG_STATIC_LIBRARIES}) else (STATIC) @@ -175,7 +192,7 @@ endif (UNIX) INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS}) -LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS}) +LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS}) if (WIN32) # build as library for now, replace with add_executable diff --git a/scripts/linux/install.sh b/scripts/linux/install.sh index 466a7d44e0..c0bde470cd 100755 --- a/scripts/linux/install.sh +++ b/scripts/linux/install.sh @@ -170,8 +170,9 @@ elif [[ $(uname) == "Linux" ]]; then case "$TARGET" in "linux") sudo dpkg --add-architecture i386 + sudo add-apt-repository -y ppa:djcj/tools sudo apt-get update - sudo apt-get install --no-install-recommends -y --force-yes cmake libsdl2-dev:i386 libsdl2-ttf-dev:i386 gcc-4.8 pkg-config:i386 g++-4.8-multilib gcc-4.8-multilib libjansson-dev:i386 libspeex-dev:i386 libspeexdsp-dev:i386 libcurl4-openssl-dev:i386 libcrypto++-dev:i386 clang libfontconfig1-dev:i386 libfreetype6-dev:i386 libpng-dev:i386 + sudo apt-get install --no-install-recommends -y --force-yes cmake libsdl2-dev:i386 libsdl2-ttf-dev:i386 gcc-4.8 pkg-config:i386 g++-4.8-multilib gcc-4.8-multilib libjansson-dev:i386 libspeex-dev:i386 libspeexdsp-dev:i386 libcurl4-openssl-dev:i386 libcrypto++-dev:i386 clang libfontconfig1-dev:i386 libfreetype6-dev:i386 libpng-dev:i386 libpng16-dev:i386 download https://launchpad.net/ubuntu/+archive/primary/+files/libjansson4_2.7-1ubuntu1_i386.deb libjansson4_2.7-1ubuntu1_i386.deb download https://launchpad.net/ubuntu/+archive/primary/+files/libjansson-dev_2.7-1ubuntu1_i386.deb libjansson-dev_2.7-1ubuntu1_i386.deb sudo dpkg -i libjansson4_2.7-1ubuntu1_i386.deb From 83a1b36088979923aef21aa213416b5c8581a508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Wed, 30 Dec 2015 01:11:25 +0100 Subject: [PATCH 7/7] Update mingw libs with libpng16 --- scripts/linux/build.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/linux/build.sh b/scripts/linux/build.sh index 5a796a00f5..bef6f53e17 100755 --- a/scripts/linux/build.sh +++ b/scripts/linux/build.sh @@ -17,7 +17,7 @@ if [[ $(uname -s) == "Darwin" ]]; then # keep in sync with version in Xcode project sha256sum=2cec3958352477fbb876a5b6398722077084b5ff7e95a7d3cd67492abf5012fc else - sha256sum=69ff98c9544838fb16384bc78af9dc1c452b9d01d919e43f5fec686d02c9bdd8 + sha256sum=31c5e19d9f794bd5f0e75f20c2b4c3c4664d736b0a4d50c8cde14a9a9007b62d fi libVFile="./libversion" libdir="./lib" @@ -62,10 +62,12 @@ pushd build PARENT=$(readlink -f ../) chmod a+rwx $(pwd) chmod g+s $(pwd) - docker run -u travis -v $PARENT:/work/openrct2 -w /work/openrct2/build -i -t openrct2/openrct2:32bit-only bash -c "cmake ../ $OPENRCT2_CMAKE_OPTS && make" + # CMAKE and MAKE opts from environment + docker run -u travis -v $PARENT:/work/openrct2 -w /work/openrct2/build -i -t openrct2/openrct2:32bit-only bash -c "cmake ../ $OPENRCT2_CMAKE_OPTS && make $OPENRCT_MAKE_OPTS" else cmake -DCMAKE_BUILD_TYPE=Debug $OPENRCT2_CMAKE_OPTS .. - make + # NOT the same variable as above + make $OPENRCT2_MAKE_OPTS fi popd