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