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.
21 #include "cave/helper/cavemap.hpp"
22 #include "cave/cavetypes.hpp"
24 // forward declarations
32 * The GameControl class controls the flow of a game: iterating the cave,
33 * loading the caves, adding score, managing number of lives etc.
34 * It loads a cave from the caveset, passes movement keypresses
35 * to the cave iterate routine, controls uncover and cover animations,
36 * saves replays, manages highscore.
38 * While it is not the responsibility of this class to draw the cave to
39 * the screen, it manages two maps; one map (gfx_buffer) contains the cell
40 * indexes, which are essentially the cave, and the other one (covered)
41 * is a map of booleans which show which cell is covered and which is not
42 * (after loading and before a new cave). These maps are in the GameControl
43 * class so it can easily manage them when loading a cave.
45 * The GameControl class has members which store the cave number, the pointer
46 * to the currently played cave and so on. When playing a game, a new
47 * GameControl object is created, and it is given a caveset with a start cave
48 * number, or a rendered cave with or without a replay, or a stored cave
49 * to test from the editor.
51 * The object controls rendereding the caves if needed, and also has a gfx_buffer
52 * structure, which is a map with the same size that of the cave, and stores
53 * the pixbuf indexes of the elements. It also controls recording replays.
54 * Manages counting lives, manages bonus scores.
56 * To run the whole process, the main_int() function has to be called regurarly.
57 * Usually it is called at 25hz or 50hz, depending on user interface settings.
58 * Its first parameter is a milliseconds value, in which the caller tells the
59 * GameControl, how many milliseconds have passed since the last call (40ms or
60 * 20ms, respectively). The object then decides what to do - it may load the
61 * cave, it may iterate the cave, it may count bonus points. The return value
62 * of this function has information valuable to the caller; for example, loading
63 * the cave is signaled (new cave size, new cave colors), also it is signaled
64 * when the status bars have to be updated.
66 * Internally the GameControl has a state counter, which starts from its lowest value
67 * (LOAD_CAVE), and is or is not incremented by the main_int() call. The
68 * life cycle of a singe cave is as follows:
69 * - LOAD_CAVE: to load the cave from the caveset (for replays, tests, nothing)
70 * - SHOW_STORY: showing the story of the cave (only for games)
71 * - (SHOW_STORY_WAIT: waiting for the user to press fire)
72 * - (UNCOVER_START: the first frame of the uncover animation)
73 * - UNCOVER: uncovering the cave (70 frames total)
74 * - (UNCOVER_ALL: last frame of uncover animation)
75 * - CAVE_RUNNING: play.
76 * - CHECK_BONUS_TIME: when the cave is finished, bonus time is added to the points,
77 * depending on remaining cave time.
78 * - WAIT_BEFORE_COVER: a 4s wait before covering the cave, after counting bonus
80 * - COVER_START: first frame of covering animation (8 frames total)
81 * - COVER_ALL: last frame of covering animation
85 /// Type of a GameControl.
87 TYPE_NORMAL
, ///< Normal game from a caveset, with cave number and level number.
88 TYPE_SNAPSHOT
, ///< Playing from a snapshot (continuing).
89 TYPE_TEST
, ///< Testing a cave from the editor.
90 TYPE_REPLAY
, ///< Playing a replay.
91 TYPE_CONTINUE_REPLAY
, ///< During the replay, the user took control of the cave.
94 /// Returned by the main_int() function, this state variable stores important information for
95 /// the caller, who controls drawing the cave on the screen.
97 STATE_CAVE_LOADED
, ///< The new cave is loaded.
98 STATE_SHOW_STORY
, ///< When this is received, the story should be shown to the user. First frame.
99 STATE_SHOW_STORY_WAIT
, ///< When the story is shown, and has to be redrawn.
100 STATE_PREPARE_FIRST_FRAME
, ///< Show thing in ui on which the cave can be drawn
101 STATE_FIRST_FRAME
, ///< First frame - screen should be ready for drawing.
102 STATE_NOTHING
, ///< Nothing special. Just draw the cave.
103 STATE_LABELS_CHANGED
, ///< Draw the cave, and redraw header (with points etc.)
104 STATE_TIMEOUT_NOW
, ///< This may be given once, at the exact moment of the cave timeout.
105 STATE_NO_MORE_LIVES
, ///< Will be a game over; show "game over" sign to the user. A cover animation is still on the way!
106 STATE_STOP
, ///< Finished; the GameControl object can be destroyed.
107 STATE_GAME_OVER
, ///< Finished, but this is a game over, so highscore can be recorded by the caller for the game.
110 static GameControl
*new_normal(CaveSet
*caveset
, std::string _player_name
, int _cave
, int _level
);
111 static GameControl
*new_snapshot(const CaveRendered
*snapshot
);
112 static GameControl
*new_test(CaveStored
*cave
, int level
);
113 static GameControl
*new_replay(CaveSet
*caveset
, CaveStored
*cave
, CaveReplay
*replay
);
116 /* functions to work on */
117 CaveRendered
*create_snapshot() const;
118 State
main_int(int millisecs_elapsed
, GdDirectionEnum player_move
, bool fire
, bool suicide
, bool restart
, bool allow_iterate
, bool fast_forward
);
120 /// Returns true if the game is running or finished - ie. game header should be shown.
121 bool game_header() const { return state_counter
>=0; }
123 /* public variables */
126 std::string player_name
; ///< Name of player
127 int player_score
; ///< Score of player
128 int player_lives
; ///< Remaining lives of player
130 CaveSet
*caveset
; ///< Caveset used to load next cave in normal games.
131 CaveRendered
*played_cave
; ///< Rendered version of the cave. This is the iterated one
132 CaveStored
*original_cave
; ///< original cave from caveset. Used to record highscore, as it is associated with the original cave in the caveset.
134 int bonus_life_flash
; ///< flashing for bonus life
135 int animcycle
; ///< animation frames, from 0 to 7, and then again 0
137 CaveMap
<int> gfx_buffer
; ///< contains the indexes to the cells; created by *start_level, deleted by *stop_game
138 CaveMap
<bool> covered
; ///< a map which stores which cells of the cave are still covered
140 int replay_no_more_movements
;
141 bool story_shown
; ///< variable to remember if the story for a particular cave is to be shown.
144 CaveReplay
*replay_record
;
145 CaveReplay
*replay_from
;
146 unsigned int cave_num
; ///< actual playing cave number
147 unsigned int level_num
; ///< actual playing level
148 int cave_score
; ///< score collected in this cave
149 int milliseconds_game
; ///< here we remember, how many milliseconds have passed since we last iterated the cave
150 int milliseconds_anim
; ///< to remember how many milliseconds passed since last drawing the cave
151 int state_counter
; ///< counter used to control the game flow, rendering of caves
153 void add_bonus_life(bool inform_user
);
154 void increment_score(int increment
);
155 void select_next_level_indexes();
157 /* internal functions for the different states */
160 void start_uncover();
161 void uncover_animation();
163 State
iterate_cave(int millisecs_elapsed
, bool fast_forward
, GdDirectionEnum player_move
, bool fire
, bool suicide
, bool restart
);
164 State
wait_before_cover();
165 State
check_bonus_score();
166 void cover_animation();
167 State
finished_covering();
169 // default constructor - only used internally
172 // do not allow copying and assigning - these functions are unimplemented
173 GameControl(const GameControl
&);
174 GameControl
& operator=(const GameControl
&);