# splash.cpp

Go to the documentation of this file.

    00001 /* $Id: splash.cpp 14200 2008-08-31 11:51:09Z rubidium $ */
    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 /* WITH_PNG */
    00167
    00168 void DisplaySplashImage() {}
    00169
    00170 #endif /* WITH_PNG */