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.
19 #include <glib/gi18n.h>
21 #include "misc/logger.hpp"
22 #include "misc/printf.hpp"
23 #include "framework/titlescreenactivity.hpp"
24 #include "framework/gameactivity.hpp"
25 #include "framework/inputtextactivity.hpp"
26 #include "framework/settingsactivity.hpp"
27 #include "framework/replaymenuactivity.hpp"
28 #include "framework/commands.hpp"
29 #include "input/gameinputhandler.hpp"
30 #include "cave/caveset.hpp"
31 #include "cave/titleanimation.hpp"
32 #include "settings.hpp"
33 #include "gfx/screen.hpp"
34 #include "gfx/pixmap.hpp"
35 #include "gfx/pixbuffactory.hpp"
36 #include "gfx/fontmanager.hpp"
37 #include "sound/sound.hpp"
38 #include "misc/about.hpp"
39 #include "cave/gamecontrol.hpp"
40 #include "settings.hpp"
43 TitleScreenActivity::TitleScreenActivity(App
*app
)
46 scale(app
->pixbuf_factory
->get_pixmap_scale()),
47 image_centered_threshold(164*scale
),
48 frames(0), time_ms(0), animcycle(0),
49 alternate_status(false)
51 cavenum
= app
->caveset
->last_selected_cave
;
52 levelnum
= app
->caveset
->last_selected_level
;
56 TitleScreenActivity::~TitleScreenActivity() {
61 void TitleScreenActivity::shown_event() {
62 int scale
= app
->pixbuf_factory
->get_pixmap_scale();
63 app
->screen
->set_size(scale
* 320, scale
* 200);
65 /* render title screen animation in memory pixmap */
66 animation
= get_title_animation_pixmap(app
->caveset
->title_screen
, app
->caveset
->title_screen_scroll
, false, *app
->pixbuf_factory
);
68 /* height of title screen, then decide which lines to show and where */
69 image_h
=animation
[0]->get_height();
70 int font_h
=app
->font_manager
->get_font_height();
71 /* less than 2 lines left - place for only one line of text. */
72 if (app
->screen
->get_height()-image_h
< 2*font_h
) {
74 y_caveline
=image_h
+ (app
->screen
->get_height()-image_h
-font_h
)/2; /* centered in the small place */
77 else if (app
->screen
->get_height()-image_h
< 3*font_h
) {
78 /* more than 2, less than 3 - place for status bar. game name is not shown, as this will */
79 /* only be true for a game with its own title screen, and i decided that in that case it */
80 /* would make more sense. */
82 y_caveline
=image_h
+ (app
->screen
->get_height()-image_h
-font_h
*2)/2; /* centered there */
85 /* more than 3, less than 4 - place for everything. */
86 y_gameline
=image_h
+ (app
->screen
->get_height()-image_h
-font_h
-font_h
*2)/2; /* centered with cave name */
87 y_caveline
=y_gameline
+font_h
;
88 /* if there is some place, move the cave line one pixel lower. */
89 if (y_caveline
+2*font_h
<app
->screen
->get_height())
94 app
->screen
->set_title(CPrintf("GDash - %s") % app
->caveset
->name
);
95 gd_music_play_random();
99 void TitleScreenActivity::clear_animation() {
100 for (unsigned x
=0; x
<animation
.size(); x
++)
106 void TitleScreenActivity::hidden_event() {
111 void TitleScreenActivity::redraw_event() {
112 app
->screen
->start_drawing();
116 if (y_gameline
!=-1) {
117 // TRANSLATORS: Game here is like caveset, the loaded game from which the user will select the cave to play
118 app
->blittext_n(0, y_gameline
, CPrintf("%c%s: %c%s %c%s") % GD_COLOR_INDEX_WHITE
% _("Game") % GD_COLOR_INDEX_YELLOW
% app
->caveset
->name
% GD_COLOR_INDEX_RED
% (app
->caveset
->edited
? "*" : ""));
121 int dx
=(app
->screen
->get_width()-animation
[animcycle
]->get_width())/2; /* centered horizontally */
123 if (animation
[animcycle
]->get_height()<image_centered_threshold
)
124 dy
=(image_centered_threshold
- animation
[animcycle
]->get_height())/2; /* centered vertically */
126 dy
=0; /* top of screen, as not too much space was left for info lines */
127 app
->screen
->blit(*animation
[animcycle
], dx
, dy
);
130 if (alternate_status
) {
131 // TRANSLATORS: 40 chars max. Joy here is the joystick (that one can also select the cave)
132 app
->status_line(_("Joy: select Fire: play"));
134 // TRANSLATORS: 40 chars max. Select the game to play.
135 app
->status_line(_("Crsr: select Space: Play H: Help"));
138 if (!get_active_logger().empty()) {
139 /* show error flag */
140 app
->set_color(GD_GDASH_RED
);
141 app
->blittext_n(app
->screen
->get_width()-app
->font_manager
->get_font_width_narrow(),
142 app
->screen
->get_height()-app
->font_manager
->get_font_height(), CPrintf("%c") % GD_BALL_CHAR
);
146 if (app
->caveset
->caves
.size() == 0) {
147 app
->blittext_n(0, y_caveline
, CPrintf(_("%cNo caves.")) % GD_COLOR_INDEX_WHITE
);
149 // TRANSLATORS: Cave is the name of the cave to play
150 app
->blittext_n(0, y_caveline
, CPrintf(_("%cCave: %c%s%c/%c%d")) % GD_COLOR_INDEX_WHITE
% GD_COLOR_INDEX_YELLOW
% app
->caveset
->cave(cavenum
).name
% GD_COLOR_INDEX_WHITE
% GD_COLOR_INDEX_YELLOW
% (levelnum
+1));
157 static int previous_selectable_cave(CaveSet
& caveset
, unsigned cavenum
) {
161 if (gd_all_caves_selectable
|| caveset
.cave(cn
).selectable
)
165 /* if not found any suitable, return current */
170 static int next_selectable_cave(CaveSet
& caveset
, unsigned cavenum
) {
172 while (cn
+1<caveset
.caves
.size()) {
174 if (gd_all_caves_selectable
|| caveset
.cave(cn
).selectable
)
178 /* if not found any suitable, return current */
183 void TitleScreenActivity::timer_event(int ms_elapsed
) {
184 time_ms
+= ms_elapsed
;
187 animcycle
=(animcycle
+1)%animation
.size();
191 alternate_status
=!alternate_status
;
194 /* on every 5th timer event... */
195 if (frames
% 5 == 0) {
196 /* joystick or keyboard up */
197 if (app
->gameinput
->up()) {
202 /* joystick or keyboard down */
203 if (app
->gameinput
->down()) {
208 /* joystick or keyboard left */
209 if (app
->gameinput
->left())
210 cavenum
= previous_selectable_cave(*app
->caveset
, cavenum
);
211 /* joystick or keyboard right */
212 if (app
->gameinput
->right())
213 cavenum
= next_selectable_cave(*app
->caveset
, cavenum
);
215 /* for a fire event, maybe from the joystick, start the game immediately.
216 * when from the keyboard, we would ask the user name,
217 * but how would the user press the enter key? :) */
218 if (app
->gameinput
->fire1()) {
219 NewGameCommand
*command
= new NewGameCommand(app
, cavenum
, levelnum
);
220 command
->set_param1(gd_username
);
221 app
->enqueue_command(command
);
230 void show_errors(App
*app
, Logger
&l
) {
233 Logger::Container
const& errors
= l
.get_messages();
234 for (Logger::Container::const_iterator it
= errors
.begin(); it
!= errors
.end(); ++it
) {
238 // TRANSLATORS: 40 chars max
239 app
->show_text_and_do_command(_("GDASH ERROR CONSOLE"), text
);
244 void TitleScreenActivity::keypress_event(KeyCode keycode
, int gfxlib_keycode
) {
249 static char const *strings
[]={
250 // TRANSLATORS: cursor keys selected for playing, or joystick movement
251 _("Cursor, joy"), _("Select cave & level"),
252 // TRANSLATORS: users press space of game/joystick fire button to play
253 _("Space, Fire1"), _("Play the game"),
255 // TRANSLATORS: string should be short (~20 chars)
256 "L, Tab (C)", _("Load (installed caves)"),
257 // TRANSLATORS: string should be short (~20 chars)
258 "S (N)", _("Save (Save as)"),
259 "I", _("Caveset info"),
260 "F", _("Hall of fame"),
265 "F9", _("Sound volume"),
266 // TRANSLATORS: string should be short (~20 chars)
267 "F11", _("Fullscreen ON/OFF"),
269 "K", _("Keyboard options"),
270 "X", _("Error console"),
271 "A", _("About GDash"),
273 "Escape", _("Quit game"),
276 app
->show_text_and_do_command(_("GDash Help"), help_strings_to_string(strings
));
281 app
->show_about_info();
285 app
->enqueue_command(new ShowCaveInfoCommand(app
));
289 app
->enqueue_command(new SaveFileCommand(app
));
293 app
->enqueue_command(new SaveFileAsCommand(app
));
298 app
->enqueue_command(new SelectFileToLoadIfDiscardableCommand(app
, gd_last_folder
));
302 app
->enqueue_command(new SelectFileToLoadIfDiscardableCommand(app
, gd_system_caves_dir
));
310 app
->show_settings(gd_get_game_settings_array());
314 app
->show_settings(gd_get_keyboard_settings_array(app
->gameinput
));
318 app
->enqueue_command(new ShowHighScoreCommand(app
, NULL
, -1));
322 app
->enqueue_command(new ShowErrorsCommand(app
, get_active_logger()));
326 app
->enqueue_command(new PushActivityCommand(app
, new ReplayMenuActivity(app
)));
330 app
->caveset
->last_selected_cave
= cavenum
;
331 app
->caveset
->last_selected_level
= levelnum
;
332 app
->input_text_and_do_command(_("Enter your name"), gd_username
.c_str(), new NewGameCommand(app
, cavenum
, levelnum
));
335 /* escape on the title screen is the same as closing the application */