1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "titanic/game_state.h"
24 #include "titanic/game_view.h"
25 #include "titanic/events.h"
26 #include "titanic/game_manager.h"
27 #include "titanic/support/screen_manager.h"
28 #include "titanic/titanic.h"
29 
30 namespace Titanic {
31 
empty()32 bool CGameStateMovieList::empty() {
33 	for (CGameStateMovieList::iterator i = begin(); i != end(); ) {
34 		CMovie *movie = *i;
35 
36 		if (movie->isActive()) {
37 			++i;
38 		} else {
39 			i = erase(i);
40 		}
41 	}
42 
43 	return Common::List<CMovie *>::empty();
44 }
45 
46 /*------------------------------------------------------------------------*/
47 
CGameState(CGameManager * gameManager)48 CGameState::CGameState(CGameManager *gameManager) :
49 		_gameManager(gameManager), _gameLocation(this), _passengerClass(NO_CLASS),
50 		_priorClass(NO_CLASS), _mode(GSMODE_NONE), _seasonNum(SEASON_SUMMER),
51 		_petActive(false), _soundMakerAllowed(false), _quitGame(false), _parrotMet(false),
52 		_nodeChangeCtr(0), _nodeEnterTicks(0), _parrotResponseIndex(0) {
53 }
54 
save(SimpleFile * file) const55 void CGameState::save(SimpleFile *file) const {
56 	file->writeNumber(_petActive);
57 	file->writeNumber(_passengerClass);
58 	file->writeNumber(_priorClass);
59 	file->writeNumber(_seasonNum);
60 	file->writeNumber(_parrotMet);
61 	file->writeNumber(_parrotResponseIndex);
62 	_gameLocation.save(file);
63 	file->writeNumber(_soundMakerAllowed);
64 }
65 
load(SimpleFile * file)66 void CGameState::load(SimpleFile *file) {
67 	_petActive = file->readNumber() != 0;
68 	_passengerClass = (PassengerClass)file->readNumber();
69 	_priorClass = (PassengerClass)file->readNumber();
70 	_seasonNum = (Season)file->readNumber();
71 	_parrotMet = file->readNumber();
72 	_parrotResponseIndex = file->readNumber();
73 	_gameLocation.load(file);
74 
75 	_soundMakerAllowed = file->readNumber();
76 	_nodeChangeCtr = 0;
77 	_nodeEnterTicks = 0;
78 }
79 
setMode(GameStateMode newMode)80 void CGameState::setMode(GameStateMode newMode) {
81 	CScreenManager *sm = CScreenManager::_screenManagerPtr;
82 
83 	if (newMode == GSMODE_CUTSCENE && _mode != GSMODE_CUTSCENE) {
84 		if (_gameManager)
85 			_gameManager->lockInputHandler();
86 
87 		if (sm && sm->_mouseCursor)
88 			sm->_mouseCursor->incBusyCount();
89 
90 	} else if (newMode != GSMODE_CUTSCENE && _mode == GSMODE_CUTSCENE) {
91 		if (sm && sm->_mouseCursor)
92 			sm->_mouseCursor->decBusyCount();
93 
94 		if (_gameManager)
95 			_gameManager->unlockInputHandler();
96 	}
97 
98 	_mode = newMode;
99 }
100 
enterNode()101 void CGameState::enterNode() {
102 	++_nodeChangeCtr;
103 	_nodeEnterTicks = g_vm->_events->getTicksCount();
104 }
105 
enterView()106 void CGameState::enterView() {
107 	CViewItem *oldView = _gameLocation.getView();
108 	CViewItem *newView = _movieList._destView;
109 	oldView->preEnterView(newView);
110 
111 	_gameManager->_gameView->setView(newView);
112 	CRoomItem *oldRoom = oldView->findNode()->findRoom();
113 	CRoomItem *newRoom = newView->findNode()->findRoom();
114 	_gameManager->playClip(_movieList._movieClip, oldRoom, newRoom);
115 
116 	_gameManager->_sound.preEnterView(newView, newRoom != oldRoom);
117 	_gameManager->decTransitions();
118 	oldView->enterView(newView);
119 
120 	_movieList._destView = nullptr;
121 	_movieList._movieClip = nullptr;
122 }
123 
triggerLink(CLinkItem * link)124 void CGameState::triggerLink(CLinkItem *link) {
125 	changeView(link->getDestView(), link->getClip());
126 }
127 
changeView(CViewItem * newView,CMovieClip * clip)128 void CGameState::changeView(CViewItem *newView, CMovieClip *clip) {
129 	// Signal the old view that it's being left
130 	CViewItem *oldView = _gameLocation.getView();
131 	oldView->leaveView(newView);
132 
133 	// If Shift key is pressed, skip showing the transition clip
134 	if (g_vm->_events->isSpecialPressed(MK_SHIFT))
135 		clip = nullptr;
136 
137 	if (_mode == GSMODE_CUTSCENE) {
138 		_movieList._destView = newView;
139 		_movieList._movieClip = clip;
140 		_gameManager->incTransitions();
141 	} else {
142 		oldView->preEnterView(newView);
143 		_gameManager->_gameView->setView(newView);
144 		CRoomItem *oldRoom = oldView->findNode()->findRoom();
145 		CRoomItem *newRoom = newView->findNode()->findRoom();
146 
147 		// If a transition clip is defined, play it
148 		if (clip)
149 			_gameManager->playClip(clip, oldRoom, newRoom);
150 
151 		// Final view change handling
152 		_gameManager->_sound.preEnterView(newView, newRoom != oldRoom);
153 		oldView->enterView(newView);
154 	}
155 }
156 
checkForViewChange()157 void CGameState::checkForViewChange() {
158 	if (_mode == GSMODE_CUTSCENE && _movieList.empty()) {
159 		setMode(GSMODE_INTERACTIVE);
160 		if (_movieList._destView)
161 			enterView();
162 	}
163 }
164 
addMovie(CMovie * movie)165 void CGameState::addMovie(CMovie *movie) {
166 	_movieList.push_back(movie);
167 	setMode(GSMODE_CUTSCENE);
168 }
169 
170 } // End of namespace Titanic
171