1 /*
2 * Copyright 2010-2014 OpenXcom Developers.
3 *
4 * This file is part of OpenXcom.
5 *
6 * OpenXcom is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenXcom is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with OpenXcom. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "OptionsBaseState.h"
20 #include <SDL.h>
21 #include "../Engine/Game.h"
22 #include "../Engine/Options.h"
23 #include "../Engine/Palette.h"
24 #include "../Engine/Language.h"
25 #include "../Engine/Screen.h"
26 #include "../Resource/ResourcePack.h"
27 #include "../Savegame/SavedGame.h"
28 #include "../Savegame/SavedBattleGame.h"
29 #include "../Interface/Window.h"
30 #include "../Interface/TextButton.h"
31 #include "../Interface/Text.h"
32 #include "../Engine/Action.h"
33 #include "MainMenuState.h"
34 #include "../Geoscape/GeoscapeState.h"
35 #include "../Battlescape/BattlescapeState.h"
36 #include "OptionsVideoState.h"
37 #include "OptionsAudioState.h"
38 #include "OptionsNoAudioState.h"
39 #include "OptionsControlsState.h"
40 #include "OptionsGeoscapeState.h"
41 #include "OptionsBattlescapeState.h"
42 #include "OptionsAdvancedState.h"
43 #include "OptionsModsState.h"
44 #include "OptionsDefaultsState.h"
45 #include "OptionsConfirmState.h"
46 #include "StartState.h"
47
48 namespace OpenXcom
49 {
50
51 /**
52 * Initializes all the elements in the Options window.
53 * @param game Pointer to the core game.
54 * @param origin Game section that originated this state.
55 */
OptionsBaseState(Game * game,OptionsOrigin origin)56 OptionsBaseState::OptionsBaseState(Game *game, OptionsOrigin origin) : State(game), _origin(origin)
57 {
58 // Create objects
59 _window = new Window(this, 320, 200, 0, 0);
60
61 _btnVideo = new TextButton(80, 16, 8, 8);
62 _btnAudio = new TextButton(80, 16, 8, 28);
63 _btnControls = new TextButton(80, 16, 8, 48);
64 _btnGeoscape = new TextButton(80, 16, 8, 68);
65 _btnBattlescape = new TextButton(80, 16, 8, 88);
66 _btnAdvanced = new TextButton(80, 16, 8, 108);
67 _btnMods = new TextButton(80, 16, 8, 128);
68
69 _btnOk = new TextButton(100, 16, 8, 176);
70 _btnCancel = new TextButton(100, 16, 110, 176);
71 _btnDefault = new TextButton(100, 16, 212, 176);
72
73 _txtTooltip = new Text(305, 25, 8, 148);
74
75 // Set palette
76 if (_origin == OPT_BATTLESCAPE)
77 {
78 setPalette("PAL_BATTLESCAPE");
79 }
80 else
81 {
82 setPalette("PAL_GEOSCAPE", 0);
83 }
84
85 add(_window);
86
87 add(_btnVideo);
88 add(_btnAudio);
89 add(_btnControls);
90 add(_btnGeoscape);
91 add(_btnBattlescape);
92 add(_btnAdvanced);
93 add(_btnMods);
94
95 add(_btnOk);
96 add(_btnCancel);
97 add(_btnDefault);
98
99 add(_txtTooltip);
100
101 // Set up objects
102 _window->setColor(Palette::blockOffset(8)+5);
103 _window->setBackground(_game->getResourcePack()->getSurface("BACK01.SCR"));
104
105 _btnVideo->setColor(Palette::blockOffset(8)+5);
106 _btnVideo->setText(tr("STR_VIDEO"));
107 _btnVideo->onMousePress((ActionHandler)&OptionsBaseState::btnGroupPress, SDL_BUTTON_LEFT);
108
109 _btnAudio->setColor(Palette::blockOffset(8)+5);
110 _btnAudio->setText(tr("STR_AUDIO"));
111 _btnAudio->onMousePress((ActionHandler)&OptionsBaseState::btnGroupPress, SDL_BUTTON_LEFT);
112
113 _btnControls->setColor(Palette::blockOffset(8)+5);
114 _btnControls->setText(tr("STR_CONTROLS"));
115 _btnControls->onMousePress((ActionHandler)&OptionsBaseState::btnGroupPress, SDL_BUTTON_LEFT);
116
117 _btnGeoscape->setColor(Palette::blockOffset(8)+5);
118 _btnGeoscape->setText(tr("STR_GEOSCAPE_UC"));
119 _btnGeoscape->onMousePress((ActionHandler)&OptionsBaseState::btnGroupPress, SDL_BUTTON_LEFT);
120
121 _btnBattlescape->setColor(Palette::blockOffset(8)+5);
122 _btnBattlescape->setText(tr("STR_BATTLESCAPE_UC"));
123 _btnBattlescape->onMousePress((ActionHandler)&OptionsBaseState::btnGroupPress, SDL_BUTTON_LEFT);
124
125 _btnAdvanced->setColor(Palette::blockOffset(8)+5);
126 _btnAdvanced->setText(tr("STR_ADVANCED"));
127 _btnAdvanced->onMousePress((ActionHandler)&OptionsBaseState::btnGroupPress, SDL_BUTTON_LEFT);
128
129 _btnMods->setColor(Palette::blockOffset(8)+5);
130 _btnMods->setText(tr("STR_MODS"));
131 _btnMods->onMousePress((ActionHandler)&OptionsBaseState::btnGroupPress, SDL_BUTTON_LEFT);
132 _btnMods->setVisible(_origin == OPT_MENU); // Mods require a restart, don't enable them in-game
133
134 _btnOk->setColor(Palette::blockOffset(8)+5);
135 _btnOk->setText(tr("STR_OK"));
136 _btnOk->onMouseClick((ActionHandler)&OptionsBaseState::btnOkClick);
137 _btnOk->onKeyboardPress((ActionHandler)&OptionsBaseState::btnOkClick, Options::keyOk);
138
139 _btnCancel->setColor(Palette::blockOffset(8)+5);
140 _btnCancel->setText(tr("STR_CANCEL"));
141 _btnCancel->onMouseClick((ActionHandler)&OptionsBaseState::btnCancelClick);
142 _btnCancel->onKeyboardPress((ActionHandler)&OptionsBaseState::btnCancelClick, Options::keyCancel);
143
144 _btnDefault->setColor(Palette::blockOffset(8)+5);
145 _btnDefault->setText(tr("STR_RESTORE_DEFAULTS"));
146 _btnDefault->onMouseClick((ActionHandler)&OptionsBaseState::btnDefaultClick);
147
148 _txtTooltip->setColor(Palette::blockOffset(8)+5);
149 _txtTooltip->setWordWrap(true);
150 }
151
152 /**
153 *
154 */
~OptionsBaseState()155 OptionsBaseState::~OptionsBaseState()
156 {
157
158 }
159
restart(Game * game,OptionsOrigin origin)160 void OptionsBaseState::restart(Game *game, OptionsOrigin origin)
161 {
162 if (origin == OPT_MENU)
163 {
164 game->setState(new MainMenuState(game));
165 }
166 else if (origin == OPT_GEOSCAPE)
167 {
168 game->setState(new GeoscapeState(game));
169 }
170 else if (origin == OPT_BATTLESCAPE)
171 {
172 game->setState(new GeoscapeState(game));
173 BattlescapeState *bs = new BattlescapeState(game);
174 game->pushState(bs);
175 game->getSavedGame()->getSavedBattle()->setBattleState(bs);
176 }
177 }
178
179 /**
180 * Initializes UI colors according to origin.
181 */
init()182 void OptionsBaseState::init()
183 {
184 State::init();
185 if (_origin == OPT_BATTLESCAPE)
186 {
187 applyBattlescapeTheme();
188 }
189 }
190
191 /**
192 * Handles the pressed-button state for the category buttons.
193 * @param button Button to press.
194 */
setCategory(TextButton * button)195 void OptionsBaseState::setCategory(TextButton *button)
196 {
197 _group = button;
198 _btnVideo->setGroup(&_group);
199 _btnAudio->setGroup(&_group);
200 _btnControls->setGroup(&_group);
201 _btnGeoscape->setGroup(&_group);
202 _btnBattlescape->setGroup(&_group);
203 _btnAdvanced->setGroup(&_group);
204 _btnMods->setGroup(&_group);
205 }
206
207 /**
208 * Saves the new options and returns to the proper origin screen.
209 * @param action Pointer to an action.
210 */
btnOkClick(Action *)211 void OptionsBaseState::btnOkClick(Action *)
212 {
213 int dX = Options::baseXResolution;
214 int dY = Options::baseYResolution;
215 Screen::updateScale(Options::battlescapeScale, Options::newBattlescapeScale, Options::baseXBattlescape, Options::baseYBattlescape, _origin == OPT_BATTLESCAPE);
216 Screen::updateScale(Options::geoscapeScale, Options::newGeoscapeScale, Options::baseXGeoscape, Options::baseYGeoscape, _origin != OPT_BATTLESCAPE);
217 dX = Options::baseXResolution - dX;
218 dY = Options::baseYResolution - dY;
219 recenter(dX, dY);
220 Options::switchDisplay();
221 Options::save();
222 _game->loadLanguage(Options::language);
223 SDL_WM_GrabInput(Options::captureMouse);
224 _game->getScreen()->resetDisplay();
225 _game->setVolume(Options::soundVolume, Options::musicVolume, Options::uiVolume);
226 if (Options::reload && _origin == OPT_MENU)
227 {
228 _game->setState(new StartState(_game));
229 }
230 else
231 {
232 // Confirm any video options changes
233 if (Options::displayWidth != Options::newDisplayWidth ||
234 Options::displayHeight != Options::newDisplayHeight ||
235 Options::useOpenGL != Options::newOpenGL ||
236 Options::useScaleFilter != Options::newScaleFilter ||
237 Options::useHQXFilter != Options::newHQXFilter ||
238 Options::useOpenGLShader != Options::newOpenGLShader)
239 {
240 _game->pushState(new OptionsConfirmState(_game, _origin));
241 }
242 else
243 {
244 restart(_game, _origin);
245 }
246 }
247 }
248
249 /**
250 * Loads previous options and returns to the previous screen.
251 * @param action Pointer to an action.
252 */
btnCancelClick(Action *)253 void OptionsBaseState::btnCancelClick(Action *)
254 {
255 Options::reload = false;
256 Options::load();
257 SDL_WM_GrabInput(Options::captureMouse);
258 Screen::updateScale(Options::newBattlescapeScale, Options::battlescapeScale, Options::baseXBattlescape, Options::baseYBattlescape, _origin == OPT_BATTLESCAPE);
259 Screen::updateScale(Options::newGeoscapeScale, Options::geoscapeScale, Options::baseXGeoscape, Options::baseYGeoscape, _origin != OPT_BATTLESCAPE);
260 _game->setVolume(Options::soundVolume, Options::musicVolume, Options::uiVolume);
261 _game->popState();
262 }
263
264 /**
265 * Restores the Options to default settings.
266 * @param action Pointer to an action.
267 */
btnDefaultClick(Action * action)268 void OptionsBaseState::btnDefaultClick(Action *action)
269 {
270 _game->pushState(new OptionsDefaultsState(_game, _origin, this));
271 }
272
btnGroupPress(Action * action)273 void OptionsBaseState::btnGroupPress(Action *action)
274 {
275 Surface *sender = action->getSender();
276 //if (sender != _group)
277 {
278 _game->popState();
279 if (sender == _btnVideo)
280 {
281 _game->pushState(new OptionsVideoState(_game, _origin));
282 }
283 else if (sender == _btnAudio)
284 {
285 if (!Options::mute)
286 {
287 _game->pushState(new OptionsAudioState(_game, _origin));
288 }
289 else
290 {
291 _game->pushState(new OptionsNoAudioState(_game, _origin));
292 }
293 }
294 else if (sender == _btnControls)
295 {
296 _game->pushState(new OptionsControlsState(_game, _origin));
297 }
298 else if (sender == _btnGeoscape)
299 {
300 _game->pushState(new OptionsGeoscapeState(_game, _origin));
301 }
302 else if (sender == _btnBattlescape)
303 {
304 _game->pushState(new OptionsBattlescapeState(_game, _origin));
305 }
306 else if (sender == _btnAdvanced)
307 {
308 _game->pushState(new OptionsAdvancedState(_game, _origin));
309 }
310 else if (sender == _btnMods)
311 {
312 _game->pushState(new OptionsModsState(_game, _origin));
313 }
314 }
315 }
316
317 /**
318 * Shows a tooltip for the appropriate button.
319 * @param action Pointer to an action.
320 */
txtTooltipIn(Action * action)321 void OptionsBaseState::txtTooltipIn(Action *action)
322 {
323 _currentTooltip = action->getSender()->getTooltip();
324 _txtTooltip->setText(tr(_currentTooltip));
325 }
326
327 /**
328 * Clears the tooltip text.
329 * @param action Pointer to an action.
330 */
txtTooltipOut(Action * action)331 void OptionsBaseState::txtTooltipOut(Action *action)
332 {
333 if (_currentTooltip == action->getSender()->getTooltip())
334 {
335 _txtTooltip->setText(L"");
336 }
337 }
338
339 /**
340 * Updates the scale.
341 * @param dX delta of X;
342 * @param dY delta of Y;
343 */
resize(int & dX,int & dY)344 void OptionsBaseState::resize(int &dX, int &dY)
345 {
346 Options::newDisplayWidth = Options::displayWidth;
347 Options::newDisplayHeight = Options::displayHeight;
348 State::resize(dX, dY);
349
350 }
351 }
352