README.md edited online with Bitbucket
[gdash.git] / src / cave / gamecontrol.hpp
blob503393c49e7e7e75c9a2602507374bad77392860
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 GAMECONTROL_HPP_INCLUDED
24 #define GAMECONTROL_HPP_INCLUDED
26 #include "config.h"
28 #include <memory>
29 #include "cave/helper/cavemap.hpp"
30 #include "cave/cavetypes.hpp"
32 // forward declarations
33 class CaveSet;
34 class CaveRendered;
35 class CaveReplay;
36 class CaveStored;
37 class GameInputHandler;
39 /// @ingroup Cave
40 /**
41 * The GameControl class controls the flow of a game: iterating the cave,
42 * loading the caves, adding score, managing number of lives etc.
43 * It loads a cave from the caveset, passes movement keypresses
44 * to the cave iterate routine, controls uncover and cover animations,
45 * saves replays, manages highscore.
47 * While it is not the responsibility of this class to draw the cave to
48 * the screen, it manages two maps; one map (gfx_buffer) contains the cell
49 * indexes, which are essentially the cave, and the other one (covered)
50 * is a map of booleans which show which cell is covered and which is not
51 * (after loading and before a new cave). These maps are in the GameControl
52 * class so it can easily manage them when loading a cave.
54 * The GameControl class has members which store the cave number, the pointer
55 * to the currently played cave and so on. When playing a game, a new
56 * GameControl object is created, and it is given a caveset with a start cave
57 * number, or a rendered cave with or without a replay, or a stored cave
58 * to test from the editor.
60 * The object controls rendereding the caves if needed, and also has a gfx_buffer
61 * structure, which is a map with the same size that of the cave, and stores
62 * the pixbuf indexes of the elements. It also controls recording replays.
63 * Manages counting lives, manages bonus scores.
65 * To run the whole process, the main_int() function has to be called regurarly.
66 * Usually it is called at 25hz or 50hz, depending on user interface settings.
67 * Its first parameter is a milliseconds value, in which the caller tells the
68 * GameControl, how many milliseconds have passed since the last call (40ms or
69 * 20ms, respectively). The object then decides what to do - it may load the
70 * cave, it may iterate the cave, it may count bonus points. The return value
71 * of this function has information valuable to the caller; for example, loading
72 * the cave is signaled (new cave size, new cave colors), also it is signaled
73 * when the status bars have to be updated.
75 * Internally the GameControl has a state counter, which starts from its lowest value
76 * (LOAD_CAVE), and is or is not incremented by the main_int() call. The
77 * life cycle of a singe cave is as follows:
78 * - LOAD_CAVE: to load the cave from the caveset (for replays, tests, nothing)
79 * - SHOW_STORY: showing the story of the cave (only for games)
80 * - (SHOW_STORY_WAIT: waiting for the user to press fire)
81 * - (UNCOVER_START: the first frame of the uncover animation)
82 * - UNCOVER: uncovering the cave (70 frames total)
83 * - (UNCOVER_ALL: last frame of uncover animation)
84 * - CAVE_RUNNING: play.
85 * - CHECK_BONUS_TIME: when the cave is finished, bonus time is added to the points,
86 * depending on remaining cave time.
87 * - WAIT_BEFORE_COVER: a 4s wait before covering the cave, after counting bonus
88 * points.
89 * - COVER_START: first frame of covering animation (8 frames total)
90 * - COVER_ALL: last frame of covering animation
92 class GameControl {
93 public:
94 /// Type of a GameControl.
95 enum Type {
96 TYPE_NORMAL, ///< Normal game from a caveset, with cave number and level number.
97 TYPE_SNAPSHOT, ///< Playing from a snapshot (continuing).
98 TYPE_TEST, ///< Testing a cave from the editor.
99 TYPE_REPLAY, ///< Playing a replay.
100 TYPE_CONTINUE_REPLAY, ///< During the replay, the user took control of the cave.
103 /// Returned by the main_int() function, this state variable stores important information for
104 /// the caller, who controls drawing the cave on the screen.
105 enum State {
106 STATE_CAVE_LOADED, ///< The new cave is loaded.
107 STATE_SHOW_STORY, ///< When this is received, the story should be shown to the user. First frame.
108 STATE_SHOW_STORY_WAIT, ///< When the story is shown, and has to be redrawn.
109 STATE_FIRST_FRAME, ///< First frame - screen should be ready for drawing.
110 STATE_NOTHING, ///< Nothing special. Just draw the cave.
111 STATE_STOP, ///< Finished; the GameControl object can be destroyed.
112 STATE_GAME_OVER, ///< Finished, but this is a game over, so highscore can be recorded by the caller for the game.
115 /// Status bar state. So the renderer knows which status bar to show.
116 enum StatusBarState {
117 status_bar_none, ///< Do not drow status bar.
118 status_bar_uncover, ///< Uncover - show name of cave and game.
119 status_bar_game, ///< In game, with points and other stuff.
120 status_bar_game_over, ///< Game over status.
123 /// Named constructor.
124 static GameControl *new_normal(CaveSet *caveset, std::string _player_name, int _cave, int _level);
125 /// Named constructor.
126 static GameControl *new_snapshot();
127 /// Named constructor.
128 static GameControl *new_test(CaveStored *cave, int level);
129 /// Named constructor.
130 static GameControl *new_replay(CaveSet *caveset, CaveStored *cave, CaveReplay *replay);
131 ~GameControl();
133 /* functions to work on */
134 bool save_snapshot() const;
135 bool load_snapshot();
136 State main_int(GameInputHandler *inputhandler, bool allow_iterate);
137 bool is_uncovering() const;
139 /* public variables */
140 Type type;
142 std::string player_name; ///< Name of player
143 int player_score; ///< Score of player
144 int player_lives; ///< Remaining lives of player
146 CaveSet *caveset; ///< Caveset used to load next cave in normal games.
147 std::auto_ptr<CaveRendered> played_cave; ///< Rendered version of the cave. This is the iterated one
148 CaveStored *original_cave; ///< original cave from caveset. Used to record highscore, as it is associated with the original cave in the caveset.
150 int bonus_life_flash; ///< flashing for bonus life
151 StatusBarState statusbartype;
152 int statusbarsince; ///< The number of milliseconds since the last status bar change. If zero, just changed.
154 CaveMapFast<int> gfx_buffer; ///< contains the indexes to the cells; created by *start_level, deleted by *stop_game
155 CaveMapFast<bool> covered; ///< a map which stores which cells of the cave are still covered
157 int replay_no_more_movements;
158 bool story_shown; ///< variable to remember if the story for a particular cave is to be shown.
159 bool caveset_has_levels; ///< set to true in the constructor if the caveset has difficulty levels
161 private:
162 std::auto_ptr<CaveReplay> replay_record;
163 CaveReplay *replay_from;
164 unsigned int cave_num; ///< actual playing cave number
165 unsigned int level_num; ///< actual playing level
166 int cave_score; ///< score collected in this cave
167 int milliseconds_game; ///< here we remember, how many milliseconds have passed since we last iterated the cave
168 int state_counter; ///< counter used to control the game flow, rendering of caves
170 static std::auto_ptr<CaveRendered> snapshot_cave; ///< Saved snapshot
172 void add_bonus_life(bool inform_user);
173 void increment_score(int increment);
174 void select_next_level_indexes();
176 void set_status_bar_state(StatusBarState s);
178 /* internal functions for the different states */
179 void load_cave();
180 void unload_cave();
181 State show_story();
182 void start_uncover();
183 void uncover_animation();
184 void uncover_all();
185 State iterate_cave(GameInputHandler *inputhandler);
186 State wait_before_cover();
187 void check_bonus_score();
188 void cover_animation();
189 State finished_covering();
191 /// Default constructor - only used internally by the named constructors.
192 GameControl();
195 #endif