20130313
[gdash.git] / src / cave / titleanimation.cpp
blob08a6542c98264c7b212fe783cd46309913561836
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include "config.h"
19 #include "title.cpp"
21 #include <memory>
23 #include "misc/printf.hpp"
24 #include "misc/logger.hpp"
25 #include "gfx/pixbuf.hpp"
26 #include "gfx/pixmap.hpp"
27 #include "gfx/pixbuffactory.hpp"
28 #include "cave/helper/colors.hpp"
29 #include "cave/cavetypes.hpp"
30 #include "cave/titleanimation.hpp"
32 std::vector<Pixbuf *> get_title_animation_pixbuf(const GdString& title_screen, const GdString& title_screen_scroll, bool one_frame_only, PixbufFactory& pixbuf_factory) {
33 typedef std::auto_ptr<Pixbuf> PixbufPtr;
35 std::vector<Pixbuf *> animation;
37 PixbufPtr screen, tile;
38 try {
39 if (title_screen!="")
40 screen=PixbufPtr(pixbuf_factory.create_from_base64(title_screen.c_str()));
41 if (screen.get()!=NULL && screen->has_alpha() && title_screen_scroll!="")
42 tile=PixbufPtr(pixbuf_factory.create_from_base64(title_screen_scroll.c_str()));
43 } catch (std::exception& e) {
44 gd_message(CPrintf("Caveset is storing an invalid title screen image: %s") % e.what());
45 return animation;
48 if (tile.get()!=NULL && tile->get_height()>40) {
49 gd_message("Caveset is storing an oversized tile image");
50 tile.release();
53 /* if no special title image or unable to load that one, load the built-in */
54 if (screen.get()==NULL) {
55 /* the screen */
56 screen=PixbufPtr(pixbuf_factory.create_from_inline(sizeof(gdash_screen), gdash_screen));
57 /* the tile to be put under the screen */
58 tile=PixbufPtr(pixbuf_factory.create_from_inline(sizeof(gdash_tile), gdash_tile));
59 g_assert(screen.get()!=NULL);
60 g_assert(tile.get()!=NULL);
63 /* if no tile, let it be black. */
64 if (tile.get()==NULL) {
65 /* one-row pixbuf, so no animation; totally black. */
66 tile=PixbufPtr(pixbuf_factory.create(screen->get_width(), 1));
67 tile->fill(GdColor::from_rgb(0,0,0));
70 /* do not allow more than 40 frames of animation */
71 g_assert(tile->get_height()<40);
73 /* create a big image, which is one tile larger than the title image size */
74 Pixbuf *bigone=pixbuf_factory.create(screen->get_width(), screen->get_height()+tile->get_height());
75 /* and fill it with the tile. use copy(), so pixbuf data is initialized! */
76 for (int y=0; y<screen->get_height()+tile->get_height(); y+=tile->get_height())
77 for (int x=0; x<screen->get_width(); x+=tile->get_width())
78 tile->copy(*bigone, x, y);
80 int framenum=one_frame_only ? 1 : tile->get_height();
81 for (int i=0; i<framenum; i++) {
82 Pixbuf *frame=pixbuf_factory.create(screen->get_width(), screen->get_height());
83 // copy part of the big tiled image
84 bigone->copy(0, i, screen->get_width(), screen->get_height(), *frame, 0, 0);
85 // and composite it with the title image
86 screen->blit(*frame, 0, 0);
87 // copy to array
88 animation.push_back(frame);
90 delete bigone;
92 return animation;
95 std::vector<Pixmap *> get_title_animation_pixmap(const GdString& title_screen, const GdString& title_screen_scroll, bool one_frame_only, PixbufFactory& pixbuf_factory) {
96 std::vector<Pixbuf *> pixbufs;
97 pixbufs = get_title_animation_pixbuf(title_screen, title_screen_scroll, one_frame_only, pixbuf_factory);
98 if (pixbufs.empty())
99 pixbufs=get_title_animation_pixbuf(GdString(), GdString(), one_frame_only, pixbuf_factory);
101 std::vector<Pixmap *> pixmaps;
102 for (unsigned i=0; i<pixbufs.size(); ++i) {
103 pixmaps.push_back(pixbuf_factory.create_pixmap_from_pixbuf(*pixbufs[i], false));
104 delete pixbufs[i];
107 return pixmaps;