# splash.cpp

Go to the documentation of this file.

    00001 /* $Id: splash.cpp 17872 2009-10-25 17:55:13Z smatz $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    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         /* Initialize buffer */
    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         /* Initialize buffer */
    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 /* WITH_PNG */
    00165
    00166 void DisplaySplashImage() {}
    00167
    00168 #endif /* WITH_PNG */