README.md edited online with Bitbucket
[gdash.git] / src / framework / replaysaveractivity.hpp
blobb91dc0b46bffa7ea5681d8383b7786c7d716620d
1 /*
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 */
28 #ifdef HAVE_SDL
30 #include <SDL.h>
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"
39 class CaveStored;
40 class CaveReplay;
41 class GameControl;
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 {
46 public:
47 SDLInmemoryScreen(PixbufFactory &pixbuf_factory) : SDLAbstractScreen(pixbuf_factory) {}
48 virtual void set_title(char const *);
49 virtual void configure_size();
50 ~SDLInmemoryScreen();
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);
58 /**
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
75 * animation.
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
84 * instead. */
85 class ReplaySaverActivity: public Activity {
86 public:
87 /** Ctor.
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);
97 /** Destructor.
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();
107 private:
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. */
118 unsigned int wavlen;
119 /** Number of image frames written. */
120 unsigned int frame;
121 /** Sound settings reported by SDL. */
122 int frequency, channels, bits;
123 std::string filename_prefix;
124 /** The WAV file opened for writing. */
125 FILE *wavfile;
127 // saved settings
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. */
142 GameControl *game;
143 /** A PixbufFactory set to no scaling, no pal emulation. */
144 SDLPixbufFactory pf;
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. */
148 FontManager fm;
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 */
157 #endif