1 /* $Id: splash.cpp 26209 2014-01-02 22:41:58Z rubidium $ */
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
10 /** @file splash.cpp Splash screen support for OSX. */
12 #include "../../stdafx.h"
13 #include "../../openttd.h"
14 #include "../../debug.h"
15 #include "../../gfx_func.h"
16 #include "../../fileio_func.h"
17 #include "../../blitter/factory.hpp"
18 #include "../../core/mem_func.hpp"
26 #include "../../safeguards.h"
29 * Handle pnglib error.
31 * @param png_ptr Pointer to png struct.
32 * @param message Error message text.
34 static void PNGAPI
png_my_error(png_structp png_ptr
, png_const_charp message
)
36 DEBUG(misc
, 0, "[libpng] error: %s - %s", message
, (char *)png_get_error_ptr(png_ptr
));
37 longjmp(png_jmpbuf(png_ptr
), 1);
41 * Handle warning in pnglib.
43 * @param png_ptr Pointer to png struct.
44 * @param message Warning message text.
46 static void PNGAPI
png_my_warning(png_structp png_ptr
, png_const_charp message
)
48 DEBUG(misc
, 1, "[libpng] warning: %s - %s", message
, (char *)png_get_error_ptr(png_ptr
));
52 * Display a splash image shown on startup (WITH_PNG).
54 void DisplaySplashImage()
56 FILE *f
= FioFOpenFile(SPLASH_IMAGE_FILE
, "r", BASESET_DIR
);
57 if (f
== NULL
) return;
60 fread(header
, sizeof(png_byte
), 8, f
);
61 if (png_sig_cmp(header
, 0, 8) != 0) {
66 png_structp png_ptr
= png_create_read_struct(PNG_LIBPNG_VER_STRING
, (png_voidp
) NULL
, png_my_error
, png_my_warning
);
68 if (png_ptr
== NULL
) {
73 png_infop info_ptr
= png_create_info_struct(png_ptr
);
74 if (info_ptr
== NULL
) {
75 png_destroy_read_struct(&png_ptr
, (png_infopp
)NULL
, (png_infopp
)NULL
);
80 png_infop end_info
= png_create_info_struct(png_ptr
);
81 if (end_info
== NULL
) {
82 png_destroy_read_struct(&png_ptr
, &info_ptr
, (png_infopp
)NULL
);
87 if (setjmp(png_jmpbuf(png_ptr
))) {
88 png_destroy_read_struct(&png_ptr
, &info_ptr
, &end_info
);
93 png_init_io(png_ptr
, f
);
94 png_set_sig_bytes(png_ptr
, 8);
96 png_read_png(png_ptr
, info_ptr
, PNG_TRANSFORM_IDENTITY
, NULL
);
98 uint width
= png_get_image_width(png_ptr
, info_ptr
);
99 uint height
= png_get_image_height(png_ptr
, info_ptr
);
100 uint bit_depth
= png_get_bit_depth(png_ptr
, info_ptr
);
101 uint color_type
= png_get_color_type(png_ptr
, info_ptr
);
103 if (color_type
!= PNG_COLOR_TYPE_PALETTE
|| bit_depth
!= 8) {
104 png_destroy_read_struct(&png_ptr
, &info_ptr
, &end_info
);
109 if (!png_get_valid(png_ptr
, info_ptr
, PNG_INFO_PLTE
)) {
110 png_destroy_read_struct(&png_ptr
, &info_ptr
, &end_info
);
117 png_get_PLTE(png_ptr
, info_ptr
, &palette
, &num_palette
);
119 png_bytep
*row_pointers
= png_get_rows(png_ptr
, info_ptr
);
121 if (width
> (uint
) _screen
.width
) width
= _screen
.width
;
122 if (height
> (uint
) _screen
.height
) height
= _screen
.height
;
124 uint xoff
= (_screen
.width
- width
) / 2;
125 uint yoff
= (_screen
.height
- height
) / 2;
127 switch (BlitterFactory::GetCurrentBlitter()->GetScreenDepth()) {
129 uint8
*dst_ptr
= (uint8
*)_screen
.dst_ptr
;
130 /* Initialize buffer */
131 MemSetT(dst_ptr
, 0xff, _screen
.pitch
* _screen
.height
);
133 for (uint y
= 0; y
< height
; y
++) {
134 uint8
*src
= row_pointers
[y
];
135 uint8
*dst
= dst_ptr
+ (yoff
+ y
) * _screen
.pitch
+ xoff
;
137 memcpy(dst
, src
, width
);
140 for (int i
= 0; i
< num_palette
; i
++) {
141 _cur_palette
.palette
[i
].a
= i
== 0 ? 0 : 0xff;
142 _cur_palette
.palette
[i
].r
= palette
[i
].red
;
143 _cur_palette
.palette
[i
].g
= palette
[i
].green
;
144 _cur_palette
.palette
[i
].b
= palette
[i
].blue
;
147 _cur_palette
.palette
[0xff].a
= 0xff;
148 _cur_palette
.palette
[0xff].r
= 0;
149 _cur_palette
.palette
[0xff].g
= 0;
150 _cur_palette
.palette
[0xff].b
= 0;
152 _cur_palette
.first_dirty
= 0;
153 _cur_palette
.count_dirty
= 256;
157 uint32
*dst_ptr
= (uint32
*)_screen
.dst_ptr
;
158 /* Initialize buffer */
159 MemSetT(dst_ptr
, 0, _screen
.pitch
* _screen
.height
);
161 for (uint y
= 0; y
< height
; y
++) {
162 uint8
*src
= row_pointers
[y
];
163 uint32
*dst
= dst_ptr
+ (yoff
+ y
) * _screen
.pitch
+ xoff
;
165 for (uint x
= 0; x
< width
; x
++) {
166 dst
[x
] = palette
[src
[x
]].blue
| (palette
[src
[x
]].green
<< 8) | (palette
[src
[x
]].red
<< 16) | 0xff000000;
173 png_destroy_read_struct(&png_ptr
, &info_ptr
, &end_info
);
183 * Empty 'Display a splash image' routine (WITHOUT_PNG).
185 void DisplaySplashImage() {}
187 #endif /* WITH_PNG */