00001
00002
00005 #include "../../stdafx.h"
00006 #include "../../openttd.h"
00007 #include "../../variables.h"
00008 #include "../../debug.h"
00009 #include "../../gfx_func.h"
00010 #include "../../fileio_func.h"
00011 #include "../../blitter/factory.hpp"
00012
00013 #include "splash.h"
00014
00015 #ifdef WITH_PNG
00016
00017 #include <png.h>
00018
00019 static void PNGAPI png_my_error(png_structp png_ptr, png_const_charp message)
00020 {
00021 DEBUG(misc, 0, "[libpng] error: %s - %s", message, (char *)png_get_error_ptr(png_ptr));
00022 longjmp(png_ptr->jmpbuf, 1);
00023 }
00024
00025 static void PNGAPI png_my_warning(png_structp png_ptr, png_const_charp message)
00026 {
00027 DEBUG(misc, 1, "[libpng] warning: %s - %s", message, (char *)png_get_error_ptr(png_ptr));
00028 }
00029
00030 void DisplaySplashImage()
00031 {
00032 png_byte header[8];
00033 FILE *f;
00034 png_structp png_ptr;
00035 png_infop info_ptr, end_info;
00036 uint width, height, bit_depth, color_type;
00037 png_colorp palette;
00038 int num_palette;
00039 png_bytep *row_pointers;
00040 uint8 *src;
00041 uint y;
00042 uint xoff, yoff;
00043 int i;
00044
00045 f = FioFOpenFile(SPLASH_IMAGE_FILE);
00046 if (f == NULL) return;
00047
00048 fread(header, 1, 8, f);
00049 if (png_sig_cmp(header, 0, 8) != 0) {
00050 fclose(f);
00051 return;
00052 }
00053
00054 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp) NULL, png_my_error, png_my_warning);
00055
00056 if (png_ptr == NULL) {
00057 fclose(f);
00058 return;
00059 }
00060
00061 info_ptr = png_create_info_struct(png_ptr);
00062 if (info_ptr == NULL) {
00063 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
00064 fclose(f);
00065 return;
00066 }
00067
00068 end_info = png_create_info_struct(png_ptr);
00069 if (end_info == NULL) {
00070 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
00071 fclose(f);
00072 return;
00073 }
00074
00075 if (setjmp(png_jmpbuf(png_ptr))) {
00076 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00077 fclose(f);
00078 return;
00079 }
00080
00081 png_init_io(png_ptr, f);
00082 png_set_sig_bytes(png_ptr, 8);
00083
00084 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
00085
00086 width = png_get_image_width(png_ptr, info_ptr);
00087 height = png_get_image_height(png_ptr, info_ptr);
00088 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
00089 color_type = png_get_color_type(png_ptr, info_ptr);
00090
00091 if (color_type != PNG_COLOR_TYPE_PALETTE || bit_depth != 8) {
00092 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00093 fclose(f);
00094 return;
00095 }
00096
00097 if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) {
00098 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00099 fclose(f);
00100 return;
00101 }
00102
00103 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
00104
00105 row_pointers = png_get_rows(png_ptr, info_ptr);
00106
00107 if (width > (uint) _screen.width) width = _screen.width;
00108 if (height > (uint) _screen.height) height = _screen.height;
00109
00110 xoff = (_screen.width - width) / 2;
00111 yoff = (_screen.height - height) / 2;
00112
00113 switch (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth()) {
00114 case 8: {
00115 uint8 *dst;
00116
00117 memset(_screen.dst_ptr, 0xff, _screen.pitch * _screen.height);
00118
00119 for (y = 0; y < height; y++) {
00120 src = row_pointers[y];
00121 dst = ((uint8 *) _screen.dst_ptr) + (yoff + y) * _screen.pitch + xoff;
00122
00123 memcpy(dst, src, width);
00124 }
00125
00126 for (i = 0; i < num_palette; i++) {
00127 _cur_palette[i].a = i == 0 ? 0 : 0xff;
00128 _cur_palette[i].r = palette[i].red;
00129 _cur_palette[i].g = palette[i].green;
00130 _cur_palette[i].b = palette[i].blue;
00131 }
00132
00133 _cur_palette[0xff].a = 0xff;
00134 _cur_palette[0xff].r = 0;
00135 _cur_palette[0xff].g = 0;
00136 _cur_palette[0xff].b = 0;
00137
00138 _pal_first_dirty = 0;
00139 _pal_count_dirty = 256;
00140 }
00141 break;
00142 case 32: {
00143 uint32 *dst;
00144 uint x;
00145
00146 memset(_screen.dst_ptr, 0xff000000, _screen.pitch * _screen.height * 4);
00147
00148 for (y = 0; y < height; y++) {
00149 src = row_pointers[y];
00150 dst = ((uint32 *) _screen.dst_ptr) + (yoff + y) * _screen.pitch + xoff;
00151
00152 for (x = 0; x < width; x++)
00153 dst[x] = palette[src[x]].blue | (palette[src[x]].green << 8) | (palette[src[x]].red << 16) | 0xff000000;
00154 }
00155 }
00156 break;
00157 }
00158
00159 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00160 fclose(f);
00161 return;
00162 }
00163
00164
00165
00166 #else
00167
00168 void DisplaySplashImage() {}
00169
00170 #endif