20130320
[gdash.git] / src / framework / gameactivity.cpp
blob885628f121b3f56a5cf4c85ee5c5df85c6f43059
1 /*
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.
17 #include "config.h"
19 #include <glib/gi18n.h>
21 #include "framework/gameactivity.hpp"
22 #include "framework/titlescreenactivity.hpp"
23 #include "framework/commands.hpp"
24 #include "gfx/screen.hpp"
25 #include "cave/caveset.hpp"
26 #include "cave/gamecontrol.hpp"
27 #include "settings.hpp"
28 #include "sound/sound.hpp"
29 #include "input/gameinputhandler.hpp"
32 GameActivity::GameActivity(App *app, GameControl *game)
33 : Activity(app),
34 game(game),
35 cellrenderer(*app->pixbuf_factory, gd_theme),
36 gamerenderer(*app->screen, cellrenderer, *app->font_manager, *game),
37 exit_game(false),
38 show_highscore(false),
39 paused(false),
40 time_ms(0) {
44 GameActivity::~GameActivity() {
45 gd_sound_off(); /* we stop sounds. */
49 void GameActivity::shown_event() {
50 app->game_active(true);
51 int cell_size = cellrenderer.get_cell_size();
52 app->screen->set_size(cell_size*GAME_RENDERER_SCREEN_SIZE_X, cell_size*GAME_RENDERER_SCREEN_SIZE_Y);
53 gd_music_stop();
57 void GameActivity::hidden_event() {
58 app->game_active(false);
62 void GameActivity::redraw_event() {
63 gamerenderer.redraw();
67 void GameActivity::keypress_event(KeyCode keycode, int gfxlib_keycode) {
68 switch (keycode) {
69 case EndGameKey:
70 exit_game = true;
71 break;
72 case RestartLevelKey:
73 app->gameinput->restart_level = true; /* hack */
74 break;
75 case PauseKey:
76 paused = !paused;
77 if (paused) {
78 gamerenderer.statusbar_since = 0; /* count frames "paused" */
79 gd_sound_off(); /* if paused, no sound. */
81 break;
82 case RandomColorKey:
83 gamerenderer.set_random_colors();
84 break;
85 case 'h':
86 case 'H': {
87 /* switch off sounds when showing help. */
88 /* no need to turn on sounds later; next cave iteration will restore them. */
89 gd_sound_off();
90 const char *strings_menu[]= {
91 app->gameinput->get_key_name(GameInputHandler::KeyLeft), _("Move left"),
92 app->gameinput->get_key_name(GameInputHandler::KeyRight), _("Move right"),
93 app->gameinput->get_key_name(GameInputHandler::KeyUp), _("Move up"),
94 app->gameinput->get_key_name(GameInputHandler::KeyDown), _("Move down"),
95 app->gameinput->get_key_name(GameInputHandler::KeyFire1), _("Snap"),
96 app->gameinput->get_key_name(GameInputHandler::KeySuicide), _("Suicide"),
97 // TRANSLATORS: "hold" here means that the key must be kept depressed by the user.
98 app->gameinput->get_key_name(GameInputHandler::KeyFastForward), _("Fast forward (hold)"),
99 // TRANSLATORS: "hold" here means that the key must be kept depressed by the user.
100 app->gameinput->get_key_name(GameInputHandler::KeyStatusBar), _("Status bar (hold)"),
101 app->gameinput->get_key_name(GameInputHandler::KeyRestartLevel), _("Restart level"),
102 /* if you change these, change the enum in the class definition as well */
103 "", "",
104 _("Space"), _("Pause"),
105 //~ "F3", _("Take snapshot"),
106 //~ "F4", _("Revert to snapshot"),
107 "", "",
108 "F2", _("Random colors"),
109 "F9", _("Sound volume"),
110 "F1", _("End game"),
111 NULL
113 // TRANSLATORS: title of the help window during the game
114 app->show_text_and_do_command(_("Game Help"), help_strings_to_string(strings_menu));
116 break;
121 void GameActivity::timer_event(int ms_elapsed) {
122 time_ms += ms_elapsed;
123 int step = gd_fine_scroll ? 20 : 40;
124 /* check if enough time has elapsed to signal the game object. */
125 if (time_ms < step)
126 return;
127 time_ms -= step;
129 GdDirectionEnum player_move = gd_direction_from_keypress(app->gameinput->up(), app->gameinput->down(), app->gameinput->left(), app->gameinput->right());
130 GameRenderer::State state = gamerenderer.main_int(step, player_move, app->gameinput->fire1() || app->gameinput->fire2(), app->gameinput->suicide, app->gameinput->restart_level, paused, app->gameinput->alternate_status, app->gameinput->fast_forward);
132 /* state of game, returned by gd_game_main_int */
133 switch (state) {
134 case GameRenderer::CaveLoaded:
135 case GameRenderer::Iterated:
136 case GameRenderer::Nothing:
137 break;
139 case GameRenderer::Stop: /* game stopped, this could be a replay or a snapshot */
140 exit_game=true;
141 break;
143 case GameRenderer::GameOver: /* normal game stopped, may jump to highscore later. */
144 exit_game=true;
145 show_highscore=true;
146 break;
149 if (exit_game) {
150 /* pop the game activity. */
151 app->enqueue_command(new PopActivityCommand(app));
152 /* if showing highscore, enqueue a command to show it. */
153 /* there might be a command to be run after the game. if there is no highscore,
154 * the game object will execute it, when popping. if there is a highscoresactivity
155 * object, the command to be run is passed to it. */
156 if (show_highscore && game->caveset->highscore.is_highscore(game->player_score)) {
157 /* enter to highscore table */
158 int rank = game->caveset->highscore.add(game->player_name, game->player_score);
159 app->enqueue_command(new ShowHighScoreCommand(app, NULL, rank));
160 } else {
161 /* no high score */