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 */

Generated on Wed Jul 15 20:36:00 2009 for OpenTTD by  doxygen 1.5.6