2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
19 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #ifndef REPLAYSAVERACTIVITY_HPP_INCLUDED
24 #define REPLAYSAVERACTIVITY_HPP_INCLUDED
27 /* the replay saver thing only works in the sdl version */
32 #include "framework/activity.hpp"
33 #include "sdl/sdlscreen.hpp"
34 #include "sdl/sdlpixbuffactory.hpp"
35 #include "gfx/fontmanager.hpp"
36 #include "gfx/cellrenderer.hpp"
37 #include "cave/gamerender.hpp"
43 /** This is a special SDL screen, which is a bitmap in memory.
44 * During the replay, the drawing routine draws on this, and it can be saved to disk. */
45 class SDLInmemoryScreen
: public SDLAbstractScreen
{
47 SDLInmemoryScreen(PixbufFactory
&pixbuf_factory
) : SDLAbstractScreen(pixbuf_factory
) {}
48 virtual void set_title(char const *);
49 virtual void configure_size();
51 virtual Pixmap
*create_pixmap_from_pixbuf(Pixbuf
const &pb
, bool keep_alpha
) const;
53 Pixbuf
const *create_pixbuf_screenshot() const;
54 void save(char const *filename
);
59 * This activity plays a replay, and saves every animation frame to
60 * a PNG file, along with the sound to a WAV file.
62 * This is implemented using a normal GameControl object, but it is given
63 * a special kind of Screen which can be saved to a PNG file. Also
64 * the normal sound stream is closed, and a special stream is requested
65 * from SDL with the dummy audio driver. A mixer callback func is also
66 * registered for SDL_Mixer, which will save the audio data.
68 * During saving the replay, the normal timer events which are forwarded
69 * from the App are not used for the timing of the cave. The mixer callback
70 * registered to SDL_Mixer also pushes SDL events (SDL_USEREVENT+1), which
71 * are then sent to App::timer2_event() in sdlmain.cpp. This is used
72 * to iterate the cave. The size of
73 * the sound buffer is set to hold 20ms of sound data, so SDL_Mixer is
74 * forced to generate us the events every 20ms - thus we can do an 50fps
77 * During saving the replay, the image is shown to the user, but it is not
78 * scaled, and there will be no sound. (As sound goes only to the memory
79 * and the WAV file.) This does not take too much CPU power; compressing
80 * the PNG files is eats much more.
82 * The whole thing only works in the SDL version, it is not implemented
83 * in the GTK game. Maybe it would be nice to put it in the GTK version
85 class ReplaySaverActivity
: public Activity
{
88 * The created Activity, when pushed, will start to record the replay.
89 * When finishing, it will automatically quit. There is no way for
90 * the user to cancel the saving.
91 * @param app The parent app.
92 * @param cave The cave which has the replay to record.
93 * @param replay The replay to record to the files.
94 * @param filename_prefix A filename prefix of the output files,
95 * to which .wav and _xxxxxx.png will be appended. */
96 ReplaySaverActivity(App
*app
, CaveStored
*cave
, CaveReplay
*replay
, std::string
const &filename_prefix
);
98 * Has many things to do - write a WAV header, reinstall the normal mixer etc. */
99 ~ReplaySaverActivity();
100 virtual void redraw_event(bool full
) const;
102 * When the Activity is shown, it will install its own sound mixer. */
103 virtual void shown_event();
104 /** The timer2 event generated by the sound mixer will do the cave timing. */
105 virtual void timer2_event();
108 /** The SDL_Mixer post mixing callback, which saves the WAV file
109 * and sends SDL_USEREVENT+1-s to do the cave timing. */
110 static void mixfunc(void *udata
, Uint8
*stream
, int len
);
111 /** Save sound preferences of the user, restart the SDL audio subsystem
112 * with the required settings and install the mixer callbacks. */
113 void install_own_mixer();
114 /** Revert to the original sound preferences of the user. */
115 void uninstall_own_mixer();
117 /** Bytes written to the wav file. */
119 /** Number of image frames written. */
121 /** Sound settings reported by SDL. */
122 int frequency
, channels
, bits
;
123 std::string filename_prefix
;
124 /** The WAV file opened for writing. */
128 /** User's sound preference to be restored after replay saving. */
129 bool saved_gd_sdl_sound
;
130 /** User's sound preference to be restored after replay saving. */
131 bool saved_gd_sdl_44khz_mixing
;
132 /** User's sound preference to be restored after replay saving. */
133 bool saved_gd_sdl_16bit_mixing
;
134 /** User's sound preference to be restored after replay saving. */
135 bool saved_gd_show_name_of_game
;
136 /** User's sound preference to be restored after replay saving. */
137 bool saved_gd_sound_stereo
;
138 /** SDL sound environment variable saved, to be restored after replay saving. */
139 std::string saved_driver
;
141 /** GameControl object which plays the replay. */
143 /** A PixbufFactory set to no scaling, no pal emulation. */
145 /** A Screen, which is much like an image in memory, so it can be saved to PNG */
146 SDLInmemoryScreen pm
;
147 /** A font manager, which uses the pf PixbufFactory. */
149 /** A CellRenderer needed by the GameControl object. */
150 CellRenderer cellrenderer
;
151 /** A GameRenderer, which will draw the cave. */
152 GameRenderer gamerenderer
;
155 #endif /* IFDEF HAVE_SDL */