1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2010 by The Allacrost Project
3 //                         All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ///////////////////////////////////////////////////////////////////////////////
9 
10 /** ****************************************************************************
11 *** \file    boot.h
12 *** \author  Viljami Korhonen, mindflayer@allacrost.org
13 *** \brief   Header file for boot mode interface.
14 ***
15 *** This code handles the game event processing and frame drawing when the user
16 *** is in boot mode (the boot screen and menus).
17 *** ***************************************************************************/
18 
19 #ifndef __BOOT_HEADER__
20 #define __BOOT_HEADER__
21 
22 #include "defs.h"
23 #include "utils.h"
24 
25 #include "mode_manager.h"
26 #include "video.h"
27 
28 #include "boot_menu.h"
29 #include "menu_views.h"
30 
31 //! \brief All calls to boot mode are wrapped in this namespace.
32 namespace hoa_boot {
33 
34 //! \brief Determines whether the code in the hoa_boot namespace should print debug statements or not.
35 extern bool BOOT_DEBUG;
36 
37 //! \brief An internal namespace to be used only within the boot code. Don't use this namespace anywhere else!
38 namespace private_boot {
39 
40 const std::string _LANGUAGE_FILE = "dat/config/languages.lua";
41 
42 //! \brief Various states that boot mode may be in
43 enum BOOT_STATE {
44 	BOOT_INVALID = 0,
45 	BOOT_INTRO   = 1,
46 	BOOT_MAIN    = 2,
47 	BOOT_LOAD    = 3,
48 	BOOT_OPTIONS = 4,
49 	BOOT_CREDITS = 5,
50 	BOOT_TOTAL   = 6
51 };
52 
53 //! \brief ???
54 enum WAIT_FOR {
55 	WAIT_KEY,
56 	WAIT_JOY_BUTTON,
57 	WAIT_JOY_AXIS
58 };
59 
60 //! \brief ???
61 enum PICK_LETTER {
62 	END = 27,
63 	BACK = 26,
64 	MAX_NAME = 19,
65 };
66 
67 } // namespace private_boot
68 
69 /** ****************************************************************************
70 *** \brief Handles the game execution while the player is on the boot menu screen.
71 ***
72 *** This is the first mode that is pushed onto the game stack when the program starts.
73 *** Its primary functions are available from the highest level menu:
74 ***
75 *** - "New Game": starts a new game
76 *** - "Load Game": activates save mode to allow the player to select a game to load
77 *** - "Options": enables the player to change various application settings
78 *** - "Credits": displays a rolling list of the game credits
79 *** - "Quit": exits the application
80 ***
81 *** The majority of the code in this class is for enabling the player to change their
82 *** application settings in the "Options" menu and its related sub-menus.
83 ***
84 *** When boot mode is entered for the very first time upon the application starting
85 *** up, the opening animation of the title screen is displayed. This only occurs the
86 *** first time that boot mode is entered for the lifetime of the application process.
87 *** After the boot animation, a welcome screen may be displayed that lists the default
88 *** controls for the player. This screen is only visible the very first time the player
89 *** installs and starts the application and is hidden otherwise.
90 ***
91 *** \note BootMode is currently "hacked" to make it easy to arrive at and test
92 *** the various other game modes. This is temporary because we don't have any other
93 *** form of a testing interface for the game at this time. There are several methods
94 *** and variables pre-fixed with "TEMP" to indicate these testing routines. At some
95 *** point in the future, they should be removed permanently.
96 ***
97 *** \todo BootMode uses SDL functions directly for many of its functions that handle
98 *** keyboard/joystick input. This code should probably be moved to the input engine
99 *** so that boot mode does not have to directly interface with one of the game's
100 *** libraries.
101 ***
102 *** \todo BootMode makes use of some classes available in the menu mode code and
103 *** needs to directly include a menu mode header file to do so. This is not good
104 *** coding practice. The class shared by boot mode and menu mode should be moved
105 *** to somewhere in src/common and appropriately renamed, or BootMode should implement
106 *** its own version of this class and not include "menu_views.h" anywhere
107 *** ***************************************************************************/
108 class BootMode : public hoa_mode_manager::GameMode {
109 public:
110 	BootMode();
111 
112 	~BootMode();
113 
114 	//! \brief Returns a pointer to the active instance of boot mode
CurrentInstance()115 	static BootMode* CurrentInstance()
116 		{ return _current_instance; }
117 
118 	//! \brief Resets appropriate class members. Called whenever BootMode is made the active game mode.
119 	void Reset();
120 
121 	//! \brief Handles user input and updates the boot menu
122 	void Update();
123 
124 	//! \brief Draws the contents and menus of boot mode depending on the current state
125 	void Draw();
126 
127 private:
128 	//! \brief Determines if this is the first time boot mode is entered. Used for the logo animation
129 	static bool _initial_entry;
130 
131 	//! \brief A pointer to the most recently active instance of boot mode
132 	static BootMode* _current_instance;
133 
134 	//! \brief When true boot mode is exiting and the screen should be faded out
135 	bool _fade_out;
136 
137 	//! \brief Set to true when the player has made modification to any application settings
138 	bool _has_modified_settings;
139 
140 	//! \brief Filename for profiles, this has to be global right now to work this will be fixed in the boot.cpp revision
141 	std::string _current_filename;
142 
143 	//! \brief Stores languages' corresponding gettext PO file names, where index in vector is equivalent to the language name's position in the language options window
144 	std::vector<std::string> _po_files;
145 
146 	//! \brief Images that will be used at the boot screen.
147 	std::vector<hoa_video::StillImage> _boot_images;
148 
149 	//! \brief Music pieces to be used at the boot screen.
150 	std::vector<hoa_audio::MusicDescriptor> _boot_music;
151 
152 	//! \brief Sounds that will be used at the boot screen.
153 	std::vector<hoa_audio::SoundDescriptor> _boot_sounds;
154 
155 	//! \brief Rendered text of the release version number
156 	hoa_video::TextImage _version_text;
157 
158 	//! \brief Rendered text of the game copyright notice
159 	hoa_video::TextImage _copyright_text;
160 
161 	//! \brief A simple menu window where the various options menus are displayed
162 	hoa_gui::MenuWindow _options_window;
163 
164 	//! \brief A window used to display the game credits
165 	private_boot::CreditsWindow* _credits_window;
166 
167 	//! \brief A window used to display important information to the player
168 	private_boot::WelcomeWindow* _welcome_window;
169 
170 	//! \brief Pointer to the currently active boot menu object
171 	private_boot::BootMenu* _active_menu;
172 
173 	/** \name Various menus available in boot mode
174 	*** The name of the menu objects is rather self explanatory. There are a number of methods in
175 	*** BootMode that are used by these menus.
176 	***
177 	*** -# Setup methods used to initialize the properties of these menus
178 	*** -# Refresh methods used to refresh the menu option text to reflect current state information
179 	*** -# Handler methods used as callback functions when input on the menus occur
180 	***
181 	*** Some of these methods are exclusive to their respective menus while others are not. Some
182 	*** of these menus do not have all of these types of methods available for them.
183 	**/
184 	//@{
185 	private_boot::BootMenu _main_menu;
186 	private_boot::BootMenu _options_menu;
187 	private_boot::BootMenu _video_options_menu;
188 	private_boot::BootMenu _resolution_menu;
189 	private_boot::BootMenu _audio_options_menu;
190 	private_boot::BootMenu _language_options_menu;
191 	private_boot::BootMenu _key_settings_menu;
192 	private_boot::BootMenu _joy_settings_menu;
193 	private_boot::BootMenu _user_input_menu;
194 	private_boot::BootMenu _profiles_menu;
195 	private_boot::BootMenu _load_profile_menu;
196 	private_boot::BootMenu _save_profile_menu;
197 	private_boot::BootMenu _delete_profile_menu;
198 	//@}
199 
200 	//! \brief A pointer to the function to call when a key has been pressed when we're waiting for one
201 	void (BootMode::*_key_setting_function)(const SDLKey &);
202 
203 	//! \brief A pointer to the function to call when a joystick button has been pressed when we're waiting for one
204 	void (BootMode::*_joy_setting_function)(uint8 button);
205 
206 	//! \brief A pointer to the function to call when a joyystick axis has been moved when we're waiting for one
207 	void (BootMode::*_joy_axis_setting_function)(int8 axis);
208 
209 	//! \brief The function to call when we want to overwrite
210 	//! \todo I don't understand this function pointer. Is it necessary? What does it overwrite?
211 	void (BootMode::*_overwrite_function) ();
212 
213 	//! \brief Window display message for "select a key"
214 	hoa_menu::MessageWindow _message_window;
215 
216 	//! \brief Window display message for "please type a file name"
217 	hoa_menu::MessageWindow _file_name_alert;
218 
219 	//! \brief Window displays of the actual filename being typed
220 	hoa_menu::MessageWindow _file_name_window;
221 
222 	// ---------- Setup and refresh methods for boot menus
223 
224 	//! \brief Setup functions for the various boot menus
225 	//@{
226 	void _SetupMainMenu();
227 	void _SetupOptionsMenu();
228 	void _SetupVideoOptionsMenu();
229 	void _SetupAudioOptionsMenu();
230 	void _SetupLanguageOptionsMenu();
231 	void _SetupKeySetttingsMenu();
232 	void _SetupJoySetttingsMenu();
233 	void _SetupResolutionMenu();
234 	void _SetupProfileMenu();
235 	void _SetupLoadProfileMenu();
236 	void _SetupSaveProfileMenu();
237 	void _SetupDeleteProfileMenu();
238 	void _SetupUserInputMenu();
239 	//@}
240 
241 	//! \brief Refreshes the option text displays on various option menus
242 	//@{
243 	void _RefreshVideoOptions();
244 	void _RefreshAudioOptions();
245 	void _RefreshKeySettings();
246 	void _RefreshJoySettings();
247 	void _RefreshSaveAndLoadProfiles();
248 	//@}
249 
250 	// ---------- Handler methods for boot menus
251 
252 	//! \brief Handler methods for the main menu
253 	//@{
254 	void _OnNewGame();
255 	void _OnLoadGame();
256 	void _OnOptions();
257 	void _OnCredits();
258 	void _OnQuit();
259 
260 	void _TEMP_OnBattle();
261 	void _TEMP_OnMenu();
262 	void _TEMP_OnShop();
263 	//@}
264 
265 	//! \brief Handler methods for the primary options menu
266 	//@{
267 	void _OnVideoOptions();
268 	void _OnAudioOptions();
269 	void _OnLanguageOptions();
270 	void _OnKeySettings();
271 	void _OnJoySettings();
272 	void _OnProfiles();
273 	//@}
274 
275 	//! \brief Handler methods for the video options menu
276 	//@{
277 	void _OnToggleFullscreen();
278 	void _OnResolution();
279 	void _OnResolution640x480();
280 	void _OnResolution800x600();
281 	void _OnResolution1024x768();
282 	void _OnResolution1280x1024();
283 	void _OnBrightnessLeft();
284 	void _OnBrightnessRight();
285 	//@}
286 
287 	//! \brief Handler methods for the audio options menu
288 	//@{
289 	void _OnSoundLeft();
290 	void _OnSoundRight();
291 	void _OnMusicLeft();
292 	void _OnMusicRight();
293 	//@}
294 
295 	//! \brief Handler methods for the language options menu
296 	//@{
297 	void _OnLanguageSelect();
298 	//@}
299 
300 	//! \brief Handler methods for the key settings options menu
301 	//@{
302 	void _OnRestoreDefaultKeys();
303 	//@}
304 
305 	//! \brief Handler methods for the joystick settings options menu
306 	//@{
307 	void _OnRestoreDefaultJoyButtons();
308 	//@}
309 
310 	//! \brief Handler methods for the profiles options menu
311 	//@{
312 	void _OnLoadProfile();
313 	void _OnSaveProfile();
314 	void _OnDeleteProfile();
315 	//@}
316 
317 	//! \brief Handler methods for the specific profile sub-options menus
318 	//@{
319 	//! \brief Loads the settings file specified by the user
320 	void _OnLoadFile();
321 	//! \brief Asks user for filename and then saves the settings to a .lua file
322 	void _OnSaveFile();
323 	//! \brief Deletes the profile
324 	void _OnDeleteFile();
325 	//! \brief Adds a letter to the currently selected filename
326 	void _OnPickLetter();
327 	//@}
328 
329 	// ---------- Helper methods not directly tied to any specific boot menu
330 
331 	//! \brief Draws the background image, logo and sword at their standard locations
332 	void _DrawBackgroundItems();
333 
334 	/** \brief Animates the game logo when this class is first initialized
335 	*** The logo animation is performed in a series of sequences. When the animation is finished,
336 	*** the _initial_entry member is set to false. The audio that plays during this animation is
337 	*** a special music file (.ogg) that was created specifically to the timings of this animation.
338 	*** Therefore, don't screw with the timings in this method! A visual description of this
339 	*** animation is described below.
340 	***
341 	*** -#) When the animation sequence begins, initially the screen is completely black.
342 	*** -#) The logo gradually fades in from the background to appear on the center of the screen,
343 	***     with the sword placed horizontally as if it were "sheathed" inside the word "Allacros".
344 	***     The background remains black with only the logo partially visible.
345 	*** -#) After the logo fade in is complete, the sword slides out ("unsheathes") and moves to
346 	***     the right
347 	*** -#) After the sword is completely removed, it moves upwards and performs two 360 degree
348 	***     swings as if an invisible person was swinging/twirling it. The speed slows to a rest
349 	***     above the logo with the sword tip facing downward.
350 	*** -#) The sword then comes crashing down into the logo and sets into its final vertical
351 	***     position.
352 	*** -#) A brilliant flash of white light eminates from the sword, quickly whiting out the
353 	***     entire screen
354 	*** -#) The light fades away, now revealing the background image instead of a black backdrop
355 	***     and the logo is now located at the top center of the screen.
356 	*** -#) When the light fade finishes, the boot menu and other text instantly appear.
357 	**/
358 	void _AnimateLogo();
359 
360 	//! \brief Immediately finishes and ends the opening logo animation
361 	void _EndLogoAnimation();
362 
363 	/** \brief Shows the message window to display text that its waiting for either a joystick or keyboard event
364 	*** \param joystick True if the window should state its waiting for a joystick event, false for a keyboard event
365 	**/
366 	void _ShowMessageWindow(bool joystick);
367 
368 	/** \brief Shows the message window to display text that its waiting for either a keybpard, joystick button, or joystick axis event
369 	*** \param wait The type of event the message box should state its waiting for
370 	**/
371 	void _ShowMessageWindow(private_boot::WAIT_FOR wait);
372 
373 	/** \brief Changes the screen resolution, applies the new settings, and refreshes the video options
374 	*** \param width The width of the new resolution in pixels
375 	*** \param height The height of the new resolution in pixels
376 	**/
377 	void _ChangeResolution(int32 width, int32 height);
378 
379 	/** \brief Saves the settings to a file specified by the user
380 	*** \param filename the name of the file for the settings to be loaded from if a blank string
381 	*** is passed the default "settings.lua" will be used
382 	*** \return true if file could be loaded, false otherwise
383 	**/
384 	bool _LoadSettingsFile(const std::string& filename);
385 
386 	/** \brief Saves the settings to a file specified by the user
387 	*** \param filename the name of the file for the settings to be saved to, if a blank string is
388 	*** passed the default "settings.lua" will be used
389 	*** \return true if file could be saved, false otherwise
390 	**/
391 	bool _SaveSettingsFile(const std::string& filename);
392 
393 	/** \brief Returns the directory listing for the user data path
394 	*** \return A vector listing all the files in the directory not including the default
395 	*** settings.lua file, this is meant for personalized profiles only
396 	**/
397 	std::vector<std::string> _GetDirectoryListingUserProfilePath();
398 
399 	/** /brief Adds in the profiles as options under whichever menu you pass in
400 	**/
401 	void _AddProfileOptions(private_boot::BootMenu* menu);
402 
403 	//! \brief Overwrites the selected profile Lua file
404 	void _OverwriteProfile();
405 
406 	// ---------- Input configuration methods
407 
408 	/** \brief Waits indefinitely until the player presses any key
409 	*** \return The SDL key symbol of the key which was pressed
410 	**/
411 	SDLKey _WaitKeyPress();
412 
413 	/** \brief Waits indefinitely until the player presses any joystick button
414 	*** \return The SDL integer ID of the joystick button which was pressed
415 	**/
416 	uint8 _WaitJoyPress();
417 
418 	//! \brief Redefines a key command to be mapped to another key
419 	//@{
420 	void _RedefineUpKey();
421 	void _RedefineDownKey();
422 	void _RedefineLeftKey();
423 	void _RedefineRightKey();
424 	void _RedefineConfirmKey();
425 	void _RedefineCancelKey();
426 	void _RedefineMenuKey();
427 	void _RedefineSwapKey();
428 	void _RedefineLeftSelectKey();
429 	void _RedefineRightSelectKey();
430 	void _RedefinePauseKey();
431 	//@}
432 
433 	/** \brief Wrapper functions to the InputManager used by the redefine key methods
434 	*** \note This was stated to be necessary because on Windows, having the _Redefine*Key() function
435 	*** pointers directly access the InputManager caused heap corruption.
436 	**/
437 	//@{
438 	void _SetUpKey(const SDLKey &key);
439 	void _SetDownKey(const SDLKey &key);
440 	void _SetLeftKey(const SDLKey &key);
441 	void _SetRightKey(const SDLKey &key);
442 	void _SetConfirmKey(const SDLKey &key);
443 	void _SetCancelKey(const SDLKey &key);
444 	void _SetMenuKey(const SDLKey &key);
445 	void _SetSwapKey(const SDLKey &key);
446 	void _SetLeftSelectKey(const SDLKey &key);
447 	void _SetRightSelectKey(const SDLKey &key);
448 	void _SetPauseKey(const SDLKey &key);
449 	//@}
450 
451 	//! \brief Redefines a joystick command to be mapped to another axis/button
452 	//@{
453 	void _RedefineXAxisJoy();
454 	void _RedefineYAxisJoy();
455 	void _RedefineThresholdJoy();
456 	void _RedefineConfirmJoy();
457 	void _RedefineCancelJoy();
458 	void _RedefineMenuJoy();
459 	void _RedefineSwapJoy();
460 	void _RedefineLeftSelectJoy();
461 	void _RedefineRightSelectJoy();
462 	void _RedefinePauseJoy();
463 	void _RedefineQuitJoy();
464 	//@}
465 
466 	/** \brief Wrapper functions to the InputManager used by the redefine joy methods
467 	*** \note This was stated to be necessary because on Windows, having the _Redefine*Joy() function
468 	*** pointers directly access the InputManager caused heap corruption.
469 	**/
470 	//@{
471 	void _SetXAxisJoy(int8 axis);
472 	void _SetYAxisJoy(int8 axis);
473 	void _SetConfirmJoy(uint8 button);
474 	void _SetCancelJoy(uint8 button);
475 	void _SetMenuJoy(uint8 button);
476 	void _SetSwapJoy(uint8 button);
477 	void _SetLeftSelectJoy(uint8 button);
478 	void _SetRightSelectJoy(uint8 button);
479 	void _SetPauseJoy(uint8 button);
480 	//@}
481 }; // class BootMode : public hoa_mode_manager::GameMode
482 
483 } // namespace hoa_boot
484 
485 #endif // __BOOT_HEADER__
486