peter1138@2847: /* $Id$ */ bjarni@2736: rubidium@9111: /** @file splash.cpp Splash screen support for OSX. */ rubidium@9111: bjarni@2736: #include "../../stdafx.h" bjarni@2736: #include "../../openttd.h" bjarni@2736: #include "../../variables.h" bjarni@2736: #include "../../debug.h" rubidium@8123: #include "../../gfx_func.h" bjarni@2736: #include "../../fileio.h" egladil@7792: #include "../../blitter/factory.hpp" bjarni@2736: bjarni@2736: #include "splash.h" bjarni@2736: bjarni@2736: #ifdef WITH_PNG bjarni@2736: bjarni@2736: #include bjarni@2736: bjarni@2736: static void PNGAPI png_my_error(png_structp png_ptr, png_const_charp message) bjarni@2736: { Darkvater@5388: DEBUG(misc, 0, "[libpng] error: %s - %s", message, (char *)png_get_error_ptr(png_ptr)); bjarni@2736: longjmp(png_ptr->jmpbuf, 1); bjarni@2736: } bjarni@2736: bjarni@2736: static void PNGAPI png_my_warning(png_structp png_ptr, png_const_charp message) bjarni@2736: { Darkvater@5388: DEBUG(misc, 1, "[libpng] warning: %s - %s", message, (char *)png_get_error_ptr(png_ptr)); bjarni@2736: } bjarni@2736: rubidium@6247: void DisplaySplashImage() bjarni@2736: { bjarni@2736: png_byte header[8]; bjarni@2736: FILE *f; bjarni@2736: png_structp png_ptr; bjarni@2736: png_infop info_ptr, end_info; bjarni@2736: uint width, height, bit_depth, color_type; bjarni@2736: png_colorp palette; bjarni@2736: int num_palette; bjarni@2736: png_bytep *row_pointers; egladil@7792: uint8 *src; bjarni@2736: uint y; bjarni@2736: uint xoff, yoff; bjarni@2736: int i; bjarni@2736: bjarni@2736: f = FioFOpenFile(SPLASH_IMAGE_FILE); bjarni@2736: if (f == NULL) return; bjarni@2736: bjarni@2736: fread(header, 1, 8, f); bjarni@2736: if (png_sig_cmp(header, 0, 8) != 0) { bjarni@2736: fclose(f); bjarni@2736: return; bjarni@2736: } bjarni@2736: bjarni@2736: png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp) NULL, png_my_error, png_my_warning); bjarni@2736: bjarni@2736: if (png_ptr == NULL) { bjarni@2736: fclose(f); bjarni@2736: return; bjarni@2736: } bjarni@2736: bjarni@2736: info_ptr = png_create_info_struct(png_ptr); bjarni@2736: if (info_ptr == NULL) { bjarni@2736: png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); bjarni@2736: fclose(f); bjarni@2736: return; bjarni@2736: } bjarni@2736: bjarni@2736: end_info = png_create_info_struct(png_ptr); bjarni@2736: if (end_info == NULL) { bjarni@2736: png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); bjarni@2736: fclose(f); bjarni@2736: return; bjarni@2736: } bjarni@2736: bjarni@2736: if (setjmp(png_jmpbuf(png_ptr))) { bjarni@2736: png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); bjarni@2736: fclose(f); bjarni@2736: return; bjarni@2736: } bjarni@2736: bjarni@2736: png_init_io(png_ptr, f); bjarni@2736: png_set_sig_bytes(png_ptr, 8); bjarni@2736: bjarni@2736: png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); bjarni@2736: bjarni@2736: width = png_get_image_width(png_ptr, info_ptr); bjarni@2736: height = png_get_image_height(png_ptr, info_ptr); bjarni@2736: bit_depth = png_get_bit_depth(png_ptr, info_ptr); bjarni@2736: color_type = png_get_color_type(png_ptr, info_ptr); bjarni@2736: peter1138@2953: if (color_type != PNG_COLOR_TYPE_PALETTE || bit_depth != 8) { bjarni@2736: png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); bjarni@2736: fclose(f); bjarni@2736: return; bjarni@2736: } bjarni@2736: peter1138@2953: if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) { bjarni@2736: png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); bjarni@2736: fclose(f); bjarni@2736: return; bjarni@2736: } bjarni@2736: bjarni@2736: png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); bjarni@2736: bjarni@2736: row_pointers = png_get_rows(png_ptr, info_ptr); bjarni@2736: peter1138@2953: if (width > (uint) _screen.width) width = _screen.width; peter1138@2953: if (height > (uint) _screen.height) height = _screen.height; bjarni@2736: bjarni@2736: xoff = (_screen.width - width) / 2; bjarni@2736: yoff = (_screen.height - height) / 2; bjarni@2736: egladil@7792: switch (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth()) { egladil@7792: case 8: { egladil@7792: uint8 *dst; bjarni@2736: egladil@7792: memset(_screen.dst_ptr, 0xff, _screen.pitch * _screen.height); bjarni@2736: egladil@7792: for (y = 0; y < height; y++) { egladil@7792: src = row_pointers[y]; egladil@7792: dst = ((uint8 *) _screen.dst_ptr) + (yoff + y) * _screen.pitch + xoff; egladil@7792: egladil@7792: memcpy(dst, src, width); egladil@7792: } egladil@7792: egladil@7792: for (i = 0; i < num_palette; i++) { egladil@7792: _cur_palette[i].r = palette[i].red; egladil@7792: _cur_palette[i].g = palette[i].green; egladil@7792: _cur_palette[i].b = palette[i].blue; egladil@7792: } egladil@7792: egladil@7792: _cur_palette[0xff].r = 0; egladil@7792: _cur_palette[0xff].g = 0; egladil@7792: _cur_palette[0xff].b = 0; egladil@7792: egladil@7792: _pal_first_dirty = 0; egladil@7792: _pal_count_dirty = 256; egladil@7792: } egladil@7792: break; egladil@7792: case 32: { egladil@7792: uint32 *dst; bjarni@7801: uint x; egladil@7792: egladil@7792: memset(_screen.dst_ptr, 0xff000000, _screen.pitch * _screen.height * 4); egladil@7792: egladil@7792: for (y = 0; y < height; y++) { egladil@7792: src = row_pointers[y]; egladil@7792: dst = ((uint32 *) _screen.dst_ptr) + (yoff + y) * _screen.pitch + xoff; egladil@7792: egladil@7792: for (x = 0; x < width; x++) egladil@7792: dst[x] = palette[src[x]].blue | (palette[src[x]].green << 8) | (palette[src[x]].red << 16) | 0xff000000; egladil@7792: } egladil@7792: } egladil@7792: break; egladil@7792: } bjarni@2736: bjarni@2736: png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); bjarni@2736: fclose(f); bjarni@2736: return; bjarni@2736: } bjarni@2736: bjarni@2736: bjarni@2736: truelight@4300: #else /* WITH_PNG */ bjarni@2736: rubidium@6247: void DisplaySplashImage() {} bjarni@2736: truelight@4300: #endif /* WITH_PNG */