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
29 #include "cave/helper/cavemap.hpp"
30 #include "cave/cavetypes.hpp"
32 // forward declarations
37 class GameInputHandler
;
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
89 * - COVER_START: first frame of covering animation (8 frames total)
90 * - COVER_ALL: last frame of covering animation
94 /// Type of a GameControl.
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.
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
);
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 */
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
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 */
182 void start_uncover();
183 void uncover_animation();
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.