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 "pink/pda_mgr.h"
24 #include "pink/pink.h"
25 #include "pink/director.h"
26 #include "pink/objects/actors/pda_button_actor.h"
27 #include "pink/objects/actors/lead_actor.h"
28 #include "pink/objects/pages/pda_page.h"
29 #include "pink/objects/actions/action_play_with_sfx.h"
30
31 namespace Pink {
32
33 static const char * const g_countries[] = {"BRI", "EGY", "BHU", "AUS", "IND", "CHI"};
34 static const char * const g_domains[] = {"NAT", "CLO", "HIS", "REL", "PLA", "ART", "FOO", "PEO"};
35
PDAMgr(PinkEngine * game)36 PDAMgr::PDAMgr(PinkEngine *game)
37 : _game(game), _lead(nullptr), _page(nullptr), _globalPage(nullptr),
38 _cursorMgr(game, nullptr), _countryIndex(0), _domainIndex(0),
39 _iteration(0), _handFrame(0), _leftHandAction(kLeft1) {}
40
~PDAMgr()41 PDAMgr::~PDAMgr() {
42 delete _globalPage;
43 delete _page;
44 }
45
saveState(Archive & archive)46 void PDAMgr::saveState(Archive &archive) {
47 if (_page)
48 archive.writeString(_page->getName());
49 else
50 archive.writeString("");
51 }
52
execute(const Command & command)53 void PDAMgr::execute(const Command &command) {
54 switch (command.type) {
55 case Command::kGoToPage:
56 goToPage(command.arg);
57 break;
58 case Command::kGoToPreviousPage:
59 assert(_previousPages.size() >= 2);
60 _previousPages.pop();
61 goToPage(_previousPages.pop());
62 break;
63 case Command::kGoToDomain:
64 goToPage(Common::String::format("%.6s", _page->getName().c_str()));
65 break;
66 case Command::kGoToHelp:
67 warning("Command GoToHelp is not supported and won't be");
68 break;
69 case Command::kNavigateToDomain:
70 goToPage(Common::String(g_countries[_countryIndex]) += g_domains[_domainIndex]);
71 break;
72 case Command::kIncrementCountry:
73 _countryIndex = (_countryIndex + 1) % 6;
74 updateWheels(1);
75 updateLocator();
76 break;
77 case Command::kDecrementCountry:
78 _countryIndex = (_countryIndex + 5) % 6;
79 updateWheels(1);
80 updateLocator();
81 break;
82 case Command::kIncrementDomain:
83 _domainIndex = (_domainIndex + 1) % 8;
84 updateWheels(1);
85 break;
86 case Command::kDecrementDomain:
87 _domainIndex = (_domainIndex + 7) % 8;
88 updateWheels(1);
89 break;
90 case Command::kClose:
91 close();
92 break;
93 default:
94 break;
95 }
96 }
97
goToPage(const Common::String pageName)98 void PDAMgr::goToPage(const Common::String pageName) {
99 if (_page && !_page->getName().compareToIgnoreCase(pageName))
100 return;
101
102 loadGlobal();
103
104 delete _page;
105 _page = new PDAPage(pageName, getGame());
106
107 _previousPages.push(_page->getName());
108
109 if (_game->isPeril())
110 initPerilButtons();
111
112 _cursorMgr.setPage(_page);
113 onMouseMove(_game->getEventManager()->getMousePos());
114 }
115
onLeftButtonClick(Common::Point point)116 void PDAMgr::onLeftButtonClick(Common::Point point) {
117 Actor* rightHand = _globalPage->findActor(kRightHand);
118 if (rightHand)
119 static_cast<ActionStill*>(rightHand->getAction())->setFrame(1);
120 Actor *actor = _game->getDirector()->getActorByPoint(point);
121 if (actor)
122 actor->onLeftClickMessage();
123 }
124
onLeftButtonUp()125 void PDAMgr::onLeftButtonUp() {
126 Actor* rightHand = _globalPage->findActor(kRightHand);
127 if (rightHand)
128 static_cast<ActionStill*>(rightHand->getAction())->setFrame(0);
129 }
130
onMouseMove(Common::Point point)131 void PDAMgr::onMouseMove(Common::Point point) {
132 Actor *actor = _game->getDirector()->getActorByPoint(point);
133 if (actor && dynamic_cast<PDAButtonActor *>(actor))
134 actor->onMouseOver(point, &_cursorMgr);
135 else
136 _cursorMgr.setCursor(kPDADefaultCursor, point, Common::String());
137
138 if (!_game->isPeril())
139 return;
140
141 float k = (float)point.x / (480 - point.y);
142 Actor *leftHand = _globalPage->findActor(kLeftHand);
143 if (k > 0.5) {
144 if (k > 1) {
145 if (k > 1.5 && _leftHandAction != kLeft4) {
146 leftHand->setAction(kLeft4Name);
147 static_cast<ActionStill*>(leftHand->getAction())->setFrame(_handFrame + 1);
148 _leftHandAction = kLeft4;
149 } else if (_leftHandAction != kLeft3) {
150 leftHand->setAction(kLeft3Name);
151 static_cast<ActionStill*>(leftHand->getAction())->setFrame(_handFrame + 1);
152 _leftHandAction = kLeft3;
153 }
154 } else if (_leftHandAction != kLeft2) {
155 leftHand->setAction(kLeft2Name);
156 static_cast<ActionStill*>(leftHand->getAction())->setFrame(_handFrame + 1);
157 _leftHandAction = kLeft2;
158 }
159 } else if (_leftHandAction != kLeft1) {
160 leftHand->setAction(kLeft1Name);
161 static_cast<ActionStill*>(leftHand->getAction())->setFrame(_handFrame + 1);
162 _leftHandAction = kLeft1;
163 }
164
165 if (_iteration == 0) {
166 _handFrame = (_handFrame + 1) % 4;
167 static_cast<ActionStill*>(leftHand->getAction())->nextFrameLooped();
168 }
169 _iteration = (_iteration + 1) % 4;
170 }
171
close()172 void PDAMgr::close() {
173 if (!_globalPage)
174 return;
175
176 delete _globalPage;
177 delete _page;
178 _globalPage = nullptr;
179 _page = nullptr;
180
181 _lead->onPDAClose();
182 }
183
loadGlobal()184 void PDAMgr::loadGlobal() {
185 if (_globalPage)
186 return;
187
188 delete _globalPage;
189 _globalPage = new PDAPage("GLOBAL", getGame());
190 }
191
initPerilButtons()192 void PDAMgr::initPerilButtons() {
193 Actor *prevPageButton = _globalPage->findActor(kPreviousPageButton);
194 if (_previousPages.size() < 2)
195 prevPageButton->setAction(kInactiveAction);
196 else
197 prevPageButton->setAction(kIdleAction);
198
199 Actor *navigatorButton = _globalPage->findActor(kNavigatorButton);
200 Actor *domainButton = _globalPage->findActor(kDomainButton);
201 if (isNavigate(_page->getName())) {
202 navigatorButton->setAction(kInactiveAction);
203 domainButton->setAction(kInactiveAction);
204 updateWheels();
205 } else {
206 calculateIndexes();
207 navigatorButton->setAction(kIdleAction);
208 if (isDomain(_page->getName()))
209 domainButton->setAction(kInactiveAction);
210 else
211 domainButton->setAction(kIdleAction);
212 }
213 updateLocator();
214 }
215
updateWheels(bool playSfx)216 void PDAMgr::updateWheels(bool playSfx) {
217 Actor *wheel = _page->findActor(kCountryWheel);
218 if (playSfx && wheel->getAction()->getName() != g_countries[_countryIndex]) {
219 wheel->setAction(Common::String(g_countries[_countryIndex]) + kSfx);
220 static_cast<ActionPlayWithSfx*>(wheel->getAction())->update(); // hack
221 }
222 wheel->setAction(g_countries[_countryIndex]);
223
224 wheel = _page->findActor(kDomainWheel);
225 if (playSfx && wheel->getAction()->getName() != g_domains[_domainIndex]) {
226 wheel->setAction(Common::String(g_domains[_domainIndex]) + kSfx);
227 static_cast<ActionPlayWithSfx*>(wheel->getAction())->update(); // hack
228 }
229 wheel->setAction(g_domains[_domainIndex]);
230 }
231
isNavigate(const Common::String & name)232 bool PDAMgr::isNavigate(const Common::String &name) {
233 return !name.compareToIgnoreCase(kNavigatePage);
234 }
235
isDomain(const Common::String & name)236 bool PDAMgr::isDomain(const Common::String &name) {
237 return name.size() == 6;
238 }
239
updateLocator()240 void PDAMgr::updateLocator() {
241 Actor *locator = _globalPage->findActor(kLocator);
242 if (locator)
243 locator->setAction(g_countries[_countryIndex]);
244 }
245
calculateIndexes()246 void PDAMgr::calculateIndexes() {
247 Common::String country = Common::String::format("%.3s", _page->getName().c_str());
248 for (uint i = 0; i < 6; ++i) {
249 if (country == g_countries[i]) {
250 _countryIndex = i;
251 break;
252 }
253 }
254
255 Common::String domain = _page->getName();
256 domain.erase(0, 3);
257 if (domain.size() >= 4)
258 domain.erase(3);
259 for (uint i = 0; i < 8; ++i) {
260 if (domain == g_domains[i]) {
261 _domainIndex = i;
262 break;
263 }
264 }
265 }
266
267 } // End of namespace Pink
268