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 "common/random.h"
24
25 #include "hdb/hdb.h"
26 #include "hdb/ai.h"
27 #include "hdb/gfx.h"
28 #include "hdb/lua-script.h"
29 #include "hdb/map.h"
30 #include "hdb/mpc.h"
31 #include "hdb/sound.h"
32 #include "hdb/window.h"
33
34 namespace HDB {
35
Window()36 Window::Window() {
37 if (g_hdb->isPPC()) {
38 _weaponX = (g_hdb->_screenWidth - 34);
39 _weaponY = 2;
40 _invItemSpace = 36;
41 _invItemPerLine = 5;
42 _textOutCenterX = 120;
43 _dlvItemSpaceX = 0;
44 _dlvItemSpaceY = 0;
45 _dlvItemPerLine = 0;
46 _dlvItemTextY = 0;
47 _dialogTextLeft = 8;
48 _dialogTextRight = 208;
49 _openDialogTextLeft = 0;
50 _openDialogTextRight = 228;
51 _tryY1 = 60; // TRY
52 _tryY2 = 100; // AGAIN
53 _tryRestartY = 240; // (ok)
54 _panicXStop = g_hdb->_screenDrawWidth / 4;
55 _panicZoneFaceX = g_hdb->_screenDrawWidth - 32;
56
57 // Fields not used in the PPC version
58 _invItemSpaceX = 1;
59 _invItemSpaceY = 1;
60 } else {
61 _weaponX = (480 - 34);
62 _weaponY = 2;
63 _invItemSpaceX = 48;
64 _invItemSpaceY = 40;
65 _invItemPerLine = 3;
66 _textOutCenterX = ((g_hdb->_screenWidth - kTileWidth * 5) / 2);
67 _dlvItemSpaceX = 48;
68 _dlvItemSpaceY = kTileHeight * 2 + 16;
69 _dlvItemPerLine = 3;
70 _dlvItemTextY = (g_hdb->_screenHeight - 30);
71 _dialogTextLeft = 64;
72 _dialogTextRight = _dialogTextLeft + kTileWidth * 9;
73 _openDialogTextLeft = _dialogTextLeft;
74 _openDialogTextRight = _dialogTextRight + kTileWidth * 2;
75 _tryY1 = (g_hdb->_screenHeight >> 2); // TRY
76 _tryY2 = (_tryY1 + 32); // AGAIN
77 _tryRestartY = ((g_hdb->_screenHeight >> 2) * 3); // (ok)
78 _panicXStop = g_hdb->_screenDrawWidth / 3;
79 _panicZoneFaceX = g_hdb->_screenDrawWidth - 32;
80 // Fields only used in the PPC version
81 _invItemSpace = 0;
82 }
83
84 _pauseY = (g_hdb->_screenHeight / 2 - 64);
85
86 _gGfxTM = nullptr;
87 _gGfxTR = nullptr;
88 _gGfxL = nullptr;
89 _gGfxM = nullptr;
90 _gGfxR = nullptr;
91 _gGfxBL = nullptr;
92 _gGfxBM = nullptr;
93 _gGfxBR = nullptr;
94 _gGfxTitleL = nullptr;
95 _gGfxTitleM = nullptr;
96 _gGfxTitleR = nullptr;
97 _gfxIndent = nullptr;
98 _gfxArrowTo = nullptr;
99 _gfxHandright = nullptr;
100 _gfxTry = nullptr;
101 _gfxAgain = nullptr;
102 _gfxInvSelect = nullptr;
103 _gfxLevelRestart = nullptr;
104 _gfxPausePlaque = nullptr;
105 _gemGfx = nullptr;
106 _mstoneGfx = nullptr;
107 _gfxResources = nullptr;
108 _gfxDeliveries = nullptr;
109 _gfxInfobar = nullptr;
110 _gfxDarken = nullptr;
111 _infobarDimmed = 0;
112 _dialogDelay = 0;
113 _numMsgQueue = 0;
114 _gfxTL = nullptr;
115 _gfxTM = nullptr;
116 _gfxTR = nullptr;
117 _gfxL = nullptr;
118 _gfxM = nullptr;
119 _gfxR = nullptr;
120 _gfxBL = nullptr;
121 _gfxBM = nullptr;
122 _gfxBR = nullptr;
123 _gfxTitleL = nullptr;
124 _gfxTitleM = nullptr;
125 _gfxTitleR = nullptr;
126 _gGfxTL = nullptr;
127 }
128
~Window()129 Window::~Window() {
130 delete _gfxTL;
131 delete _gfxTM;
132 delete _gfxTR;
133
134 delete _gfxL;
135 delete _gfxM;
136 delete _gfxR;
137
138 delete _gfxBL;
139 delete _gfxBM;
140 delete _gfxBR;
141
142 delete _gfxTitleL;
143 delete _gfxTitleM;
144 delete _gfxTitleR;
145
146 delete _gGfxTL;
147 delete _gGfxTM;
148 delete _gGfxTR;
149
150 delete _gGfxL;
151 delete _gGfxM;
152 delete _gGfxR;
153
154 delete _gGfxBL;
155 delete _gGfxBM;
156 delete _gGfxBR;
157
158 delete _gGfxTitleL;
159 delete _gGfxTitleM;
160 delete _gGfxTitleR;
161
162 delete _gfxIndent;
163 delete _gfxArrowTo;
164
165 delete _gfxInvSelect;
166 delete _gfxHandright;
167
168 if (g_hdb->isPPC()) {
169 delete _gfxResources;
170 delete _gfxDeliveries;
171 } else {
172 delete _gfxInfobar;
173 delete _gfxDarken;
174 delete _gfxPausePlaque;
175 delete _mstoneGfx;
176 }
177
178
179 delete _gemGfx;
180 }
181
init()182 void Window::init() {
183 _gfxTL = g_hdb->_gfx->loadPic(MENU_BACK_TOPLEFT);
184 _gfxTM = g_hdb->_gfx->loadPic(MENU_BACK_TOP);
185 _gfxTR = g_hdb->_gfx->loadPic(MENU_BACK_TOPRIGHT);
186
187 _gfxL = g_hdb->_gfx->loadPic(MENU_BACK_LEFT);
188 _gfxM = g_hdb->_gfx->loadPic(MENU_BACK_MIDDLE);
189 _gfxR = g_hdb->_gfx->loadPic(MENU_BACK_RIGHT);
190
191 _gfxBL = g_hdb->_gfx->loadPic(MENU_BACK_BTMLEFT);
192 _gfxBM = g_hdb->_gfx->loadPic(MENU_BACK_BOTTOM);
193 _gfxBR = g_hdb->_gfx->loadPic(MENU_BACK_BTMRIGHT);
194
195 _gfxTitleL = g_hdb->_gfx->loadPic(MENU_TITLE_LEFT);
196 _gfxTitleM = g_hdb->_gfx->loadPic(MENU_TITLE_MID);
197 _gfxTitleR = g_hdb->_gfx->loadPic(MENU_TITLE_RIGHT);
198
199 _gGfxTL = g_hdb->_gfx->loadPic(G_MENU_BACK_TOPLEFT);
200 _gGfxTM = g_hdb->_gfx->loadPic(G_MENU_BACK_TOP);
201 _gGfxTR = g_hdb->_gfx->loadPic(G_MENU_BACK_TOPRIGHT);
202
203 _gGfxL = g_hdb->_gfx->loadPic(G_MENU_BACK_LEFT);
204 _gGfxM = g_hdb->_gfx->loadPic(G_MENU_BACK_MIDDLE);
205 _gGfxR = g_hdb->_gfx->loadPic(G_MENU_BACK_RIGHT);
206
207 _gGfxBL = g_hdb->_gfx->loadPic(G_MENU_BACK_BTMLEFT);
208 _gGfxBM = g_hdb->_gfx->loadPic(G_MENU_BACK_BOTTOM);
209 _gGfxBR = g_hdb->_gfx->loadPic(G_MENU_BACK_BTMRIGHT);
210
211 _gGfxTitleL = g_hdb->_gfx->loadPic(G_MENU_TITLE_LEFT);
212 _gGfxTitleM = g_hdb->_gfx->loadPic(G_MENU_TITLE_MID);
213 _gGfxTitleR = g_hdb->_gfx->loadPic(G_MENU_TITLE_RIGHT);
214
215 _gfxIndent = g_hdb->_gfx->loadPic(MENU_DELIVERY_INDENTATION);
216 _gfxArrowTo = g_hdb->_gfx->loadPic(MENU_ARROW_DELIVERTO);
217
218 _gfxTry = _gfxAgain = nullptr; // They will be loaded when needed
219
220 _gfxInvSelect = g_hdb->_gfx->loadPic(INVENTORY_NORMAL);
221 _gfxHandright = g_hdb->_gfx->loadPic(MENU_HAND_POINTRIGHT);
222
223 if (g_hdb->isPPC()) {
224
225 _gfxResources = g_hdb->_gfx->loadPic(MENU_TITLE_RESOURCES);
226 _gfxDeliveries = g_hdb->_gfx->loadPic(MENU_TITLE_DELIVERIES);
227
228 _invWinInfo.width = g_hdb->_screenWidth - 32;
229 _invWinInfo.height = 112;
230
231 _dlvsInfo.width = g_hdb->_screenWidth - 48;
232 _dlvsInfo.height = 160;
233 _dlvsInfo.selected = 0;
234
235 } else {
236 _gfxInfobar = g_hdb->_gfx->loadPic(PIC_INFOBAR);
237 _gfxDarken = g_hdb->_gfx->loadPic(SCREEN_DARKEN);
238 _gfxPausePlaque = g_hdb->_gfx->loadPic(PAUSE_PLAQUE);
239 _mstoneGfx = g_hdb->_gfx->loadPic(MINI_MSTONE);
240
241 _infobarDimmed = 0;
242
243 _invWinInfo.width = _invItemSpaceX * 3;
244 _invWinInfo.height = _invItemSpaceY * 4;
245 _invWinInfo.x = g_hdb->_screenWidth - _gfxInfobar->_width + 16;
246 _invWinInfo.y = 40;
247
248 _dlvsInfo.width = _invItemSpaceX * 3;
249 _dlvsInfo.height = _invItemSpaceY * 4;
250 _dlvsInfo.x = (g_hdb->_screenWidth - _gfxInfobar->_width) + 16;
251 _dlvsInfo.y = 272;
252 }
253
254 _gemGfx = nullptr;
255
256 restartSystem();
257 }
258
save(Common::OutSaveFile * out)259 void Window::save(Common::OutSaveFile *out) {
260
261 int i;
262
263 // Save out the various window and game state info
264
265 // clear out gfx ptrs in _pzInfo struct before writing...
266
267 // Copy, clear and save Panic Zone Info
268 memcpy(&_tempPzInfo, &_pzInfo, sizeof(_pzInfo));
269
270 for (i = 0; i < 10; i++) {
271 _tempPzInfo.gfxNumber[i] = nullptr;
272 if (i < 2)
273 _tempPzInfo.gfxFace[i] = nullptr;
274 }
275 _tempPzInfo.gfxPanic = _tempPzInfo.gfxZone = nullptr;
276
277 out->writeByte(_tempPzInfo.active);
278 out->writeSint32LE(_tempPzInfo.sequence);
279 out->writeSint32LE(_tempPzInfo.timer);
280 out->writeSint32LE(_tempPzInfo.x1);
281 out->writeSint32LE(_tempPzInfo.y1);
282 out->writeSint32LE(_tempPzInfo.x2);
283 out->writeSint32LE(_tempPzInfo.y2);
284 out->writeSint32LE(_tempPzInfo.xv);
285 out->writeSint32LE(_tempPzInfo.yv);
286 out->writeSint32LE(_tempPzInfo.numberTime);
287 out->writeSint32LE(_tempPzInfo.numberTimeMaster);
288 out->writeSint32LE(_tempPzInfo.numberValue);
289
290 // Save Dialog Info
291 out->write(_dialogInfo.title, 64);
292 out->writeSint32LE(_dialogInfo.tileIndex);
293 out->write(_dialogInfo.string, 160);
294 out->writeByte(_dialogInfo.active);
295 out->writeSint32LE(_dialogInfo.x);
296 out->writeSint32LE(_dialogInfo.y);
297 out->writeSint32LE(_dialogInfo.width);
298 out->writeSint32LE(_dialogInfo.height);
299 out->writeSint32LE(_dialogInfo.titleWidth);
300 out->writeSint32LE(_dialogInfo.more);
301 out->writeSint32LE(_dialogInfo.el);
302 out->writeSint32LE(_dialogInfo.er);
303 out->writeSint32LE(_dialogInfo.et);
304 out->writeSint32LE(_dialogInfo.eb);
305 out->write(_dialogInfo.luaMore, 64);
306
307 // Save Dialog Delay
308 out->writeSint32LE(_dialogDelay);
309
310 // Save Dialog Choice Info
311 out->write(_dialogChoiceInfo.title, 64);
312 out->write(_dialogChoiceInfo.text, 160);
313 out->write(_dialogChoiceInfo.func, 64);
314 out->writeByte(_dialogChoiceInfo.active);
315 out->writeSint32LE(_dialogChoiceInfo.x);
316 out->writeSint32LE(_dialogChoiceInfo.y);
317 out->writeSint32LE(_dialogChoiceInfo.width);
318 out->writeSint32LE(_dialogChoiceInfo.height);
319 out->writeSint32LE(_dialogChoiceInfo.textHeight);
320 out->writeSint32LE(_dialogChoiceInfo.titleWidth);
321 out->writeSint32LE(_dialogChoiceInfo.el);
322 out->writeSint32LE(_dialogChoiceInfo.er);
323 out->writeSint32LE(_dialogChoiceInfo.et);
324 out->writeSint32LE(_dialogChoiceInfo.eb);
325 out->writeUint32LE(_dialogChoiceInfo.timeout);
326 out->writeSint32LE(_dialogChoiceInfo.selection);
327 out->writeSint32LE(_dialogChoiceInfo.numChoices);
328
329 for (i = 0; i < 10; i++) {
330 out->write(_dialogChoiceInfo.choices[i], 64);
331 }
332
333 // Save Msg Info
334 out->writeByte(_msgInfo.active);
335 out->write(_msgInfo.title, 128);
336 out->writeSint32LE(_msgInfo.timer);
337 out->writeSint32LE(_msgInfo.x);
338 out->writeSint32LE(_msgInfo.y);
339 out->writeSint32LE(_msgInfo.width);
340 out->writeSint32LE(_msgInfo.height);
341
342 for (i = 0; i < kMaxMsgQueue; i++)
343 out->write(_msgQueueStr[i], 128);
344 for (i = 0; i < kMaxMsgQueue; i++)
345 out->writeSint32LE(_msgQueueWait[i]);
346 out->writeSint32LE(_numMsgQueue);
347
348 // Save Inventory Info
349 out->writeSint32LE(_invWinInfo.x);
350 out->writeSint32LE(_invWinInfo.y);
351 out->writeSint32LE(_invWinInfo.width);
352 out->writeSint32LE(_invWinInfo.height);
353 out->writeSint32LE(_invWinInfo.selection);
354 out->writeByte(_invWinInfo.active);
355
356 // Save Deliveries Info
357 out->writeSint32LE(_dlvsInfo.x);
358 out->writeSint32LE(_dlvsInfo.y);
359 out->writeSint32LE(_dlvsInfo.width);
360 out->writeSint32LE(_dlvsInfo.height);
361 out->writeByte(_dlvsInfo.active);
362 out->writeSint32LE(_dlvsInfo.selected);
363 out->writeByte(_dlvsInfo.animate);
364 out->writeUint32LE(_dlvsInfo.delay1);
365 out->writeUint32LE(_dlvsInfo.delay2);
366 out->writeUint32LE(_dlvsInfo.delay3);
367 out->writeByte(_dlvsInfo.go1);
368 out->writeByte(_dlvsInfo.go2);
369 out->writeByte(_dlvsInfo.go3);
370
371 // Save Try Again Info
372 out->writeDoubleLE(_tryAgainInfo.y1);
373 out->writeDoubleLE(_tryAgainInfo.y2);
374 out->writeDoubleLE(_tryAgainInfo.yv1);
375 out->writeDoubleLE(_tryAgainInfo.yv2);
376 out->writeDoubleLE(_tryAgainInfo.yv1v);
377 out->writeDoubleLE(_tryAgainInfo.yv2v);
378 out->writeDoubleLE(_tryAgainInfo.x1);
379 out->writeDoubleLE(_tryAgainInfo.x2);
380
381 // Save TextOut Info
382 out->writeUint32LE(_textOutList.size());
383 for (i = 0; (uint)i < _textOutList.size(); i++) {
384 out->write(_textOutList[i]->text, 128);
385 out->writeSint32LE(_textOutList[i]->x);
386 out->writeSint32LE(_textOutList[i]->y);
387 out->writeUint32LE(_textOutList[i]->timer);
388 }
389
390 out->writeSint32LE(_infobarDimmed);
391 }
392
loadSaveFile(Common::InSaveFile * in)393 void Window::loadSaveFile(Common::InSaveFile *in) {
394
395 int i;
396
397 // Clear out everything
398 restartSystem();
399
400 // Load out various Window and Game State Info
401
402 // Load Panic Zone Info
403 for (i = 0; i < 10; i++) {
404 _pzInfo.gfxNumber[i] = nullptr;
405 if (i < 2)
406 _pzInfo.gfxFace[i] = nullptr;
407 }
408 _pzInfo.gfxPanic = _pzInfo.gfxZone = nullptr;
409
410 _pzInfo.active = in->readByte();
411 _pzInfo.sequence = in->readSint32LE();
412 _pzInfo.timer = in->readSint32LE();
413 _pzInfo.x1 = in->readSint32LE();
414 _pzInfo.y1 = in->readSint32LE();
415 _pzInfo.x2 = in->readSint32LE();
416 _pzInfo.y2 = in->readSint32LE();
417 _pzInfo.xv = in->readSint32LE();
418 _pzInfo.yv = in->readSint32LE();
419 _pzInfo.numberTime = in->readSint32LE();
420 _pzInfo.numberTimeMaster = in->readSint32LE();
421 _pzInfo.numberValue = in->readSint32LE();
422
423 // Load Dialog Info
424 in->read(_dialogInfo.title, 64);
425 _dialogInfo.tileIndex = in->readSint32LE();
426 in->read(_dialogInfo.string, 160);
427 _dialogInfo.active = in->readByte();
428 _dialogInfo.x = in->readSint32LE();
429 _dialogInfo.y = in->readSint32LE();
430 _dialogInfo.width = in->readSint32LE();
431 _dialogInfo.height = in->readSint32LE();
432 _dialogInfo.titleWidth = in->readSint32LE();
433 _dialogInfo.more = in->readSint32LE();
434 _dialogInfo.el = in->readSint32LE();
435 _dialogInfo.er = in->readSint32LE();
436 _dialogInfo.et = in->readSint32LE();
437 _dialogInfo.eb = in->readSint32LE();
438 in->read(_dialogInfo.luaMore, 64);
439
440 // Load Dialog Delay
441 _dialogDelay = in->readSint32LE();
442 if (_dialogDelay)
443 _dialogDelay = g_system->getMillis() + 1000;
444
445 // Load Dialog Choice Info
446 in->read(_dialogChoiceInfo.title, 64);
447 in->read(_dialogChoiceInfo.text, 160);
448 in->read(_dialogChoiceInfo.func, 64);
449 _dialogChoiceInfo.active = in->readByte();
450 _dialogChoiceInfo.x = in->readSint32LE();
451 _dialogChoiceInfo.y = in->readSint32LE();
452 _dialogChoiceInfo.width = in->readSint32LE();
453 _dialogChoiceInfo.height = in->readSint32LE();
454 _dialogChoiceInfo.textHeight = in->readSint32LE();
455 _dialogChoiceInfo.titleWidth = in->readSint32LE();
456 _dialogChoiceInfo.el = in->readSint32LE();
457 _dialogChoiceInfo.er = in->readSint32LE();
458 _dialogChoiceInfo.et = in->readSint32LE();
459 _dialogChoiceInfo.eb = in->readSint32LE();
460 _dialogChoiceInfo.timeout = in->readUint32LE();
461 _dialogChoiceInfo.selection = in->readSint32LE();
462 _dialogChoiceInfo.numChoices = in->readSint32LE();
463 for (i = 0; i < 10; i++)
464 in->read(_dialogChoiceInfo.choices[i], 64);
465
466 _dialogChoiceInfo.timeout = g_system->getMillis() + 1000;
467
468 // Load Msg Info
469 _msgInfo.active = in->readByte();
470 in->read(_msgInfo.title, 128);
471 _msgInfo.timer = in->readSint32LE();
472 _msgInfo.x = in->readSint32LE();
473 _msgInfo.y = in->readSint32LE();
474 _msgInfo.width = in->readSint32LE();
475 _msgInfo.height = in->readSint32LE();
476
477 for (i = 0; i < kMaxMsgQueue; i++)
478 in->read(_msgQueueStr[i], 128);
479 for (i = 0; i < kMaxMsgQueue; i++)
480 _msgQueueWait[i] = in->readSint32LE();
481
482 _numMsgQueue = in->readSint32LE();
483
484 // Load Inventory Info
485 _invWinInfo.x = in->readSint32LE();
486 _invWinInfo.y = in->readSint32LE();
487 _invWinInfo.width = in->readSint32LE();
488 _invWinInfo.height = in->readSint32LE();
489 _invWinInfo.selection = in->readSint32LE();
490 _invWinInfo.active = in->readByte();
491
492 // Load Deliveries Info
493 _dlvsInfo.x = in->readSint32LE();
494 _dlvsInfo.y = in->readSint32LE();
495 _dlvsInfo.width = in->readSint32LE();
496 _dlvsInfo.height = in->readSint32LE();
497 _dlvsInfo.active = in->readByte();
498 _dlvsInfo.selected = in->readSint32LE();
499 _dlvsInfo.animate = in->readByte();
500 _dlvsInfo.delay1 = in->readUint32LE();
501 _dlvsInfo.delay2 = in->readUint32LE();
502 _dlvsInfo.delay3 = in->readUint32LE();
503 _dlvsInfo.go1 = in->readByte();
504 _dlvsInfo.go2 = in->readByte();
505 _dlvsInfo.go3 = in->readByte();
506
507 // Load Try Again Info
508 _tryAgainInfo.y1 = in->readDoubleLE();
509 _tryAgainInfo.y2 = in->readDoubleLE();
510 _tryAgainInfo.yv1 = in->readDoubleLE();
511 _tryAgainInfo.yv2 = in->readDoubleLE();
512 _tryAgainInfo.yv1v = in->readDoubleLE();
513 _tryAgainInfo.yv2v = in->readDoubleLE();
514 _tryAgainInfo.x1 = in->readDoubleLE();
515 _tryAgainInfo.x2 = in->readDoubleLE();
516
517 // Load Textout Info
518 uint32 tsize = in->readUint32LE();
519 for (i = 0; (uint)i < tsize; i++) {
520 TOut *t = new TOut;
521
522 in->read(t->text, 128);
523 t->x = in->readSint32LE();
524 t->y = in->readSint32LE();
525 (void)in->readUint32LE(); // Skip timer value
526 t->timer = g_system->getMillis() + 1000; // And override it to a second
527
528 _textOutList.push_back(t);
529 }
530
531 // Load Infobar Info
532 _infobarDimmed = in->readSint32LE();
533 }
534
restartSystem()535 void Window::restartSystem() {
536 _numMsgQueue = 0;
537 _msgInfo.active = false;
538 _dialogInfo.active = false;
539 _dialogChoiceInfo.active = false;
540 _invWinInfo.active = false;
541 _dialogDelay = _invWinInfo.selection = 0;
542 if (_gemGfx)
543 delete _gemGfx;
544 _gemGfx = g_hdb->_gfx->loadTile(GEM_WHITE_GFX);
545 _infobarDimmed = 0;
546 }
547
setInfobarDark(int value)548 void Window::setInfobarDark(int value) {
549 if (g_hdb->isPPC())
550 return;
551 _infobarDimmed = value;
552 }
553
drawPause()554 void Window::drawPause() {
555 if (g_hdb->isPPC())
556 return;
557 if (g_hdb->getPause())
558 _gfxPausePlaque->drawMasked(g_hdb->_screenDrawWidth / 2 - _gfxPausePlaque->_width / 2, _pauseY);
559 }
560
checkPause(int x,int y)561 void Window::checkPause(int x, int y) {
562 if (x >= g_hdb->_screenDrawWidth / 2 - _gfxPausePlaque->_width / 2 && g_hdb->_screenDrawWidth / 2 + _gfxPausePlaque->_width / 2 > x
563 && y >= _pauseY && y < _pauseY + _gfxPausePlaque->_height) {
564 g_hdb->togglePause();
565 g_hdb->_sound->playSound(SND_POP);
566 }
567 }
568
drawWeapon()569 void Window::drawWeapon() {
570 if (!g_hdb->isPPC())
571 return;
572
573 int xoff = 40 * _pzInfo.active;
574 if (ITEM_CLUB != g_hdb->_ai->getPlayerWeapon()) {
575 Common::String wordString = Common::String::format("%d", g_hdb->_ai->getGemAmount());
576 g_hdb->_gfx->setCursor(_weaponX + 4 - xoff, _weaponY + kTileHeight + 2);
577 g_hdb->_gfx->drawText(wordString.c_str());
578 }
579 }
580
chooseWeapon(AIType wType)581 void Window::chooseWeapon(AIType wType) {
582 static AIType lastWeaponSelected = AI_NONE;
583 int slot = g_hdb->_ai->queryInventoryTypeSlot(wType);
584
585 if (slot == -1)
586 return;
587
588 g_hdb->_sound->playSound(SND_MENU_SLIDER);
589
590 if (!g_hdb->getActionMode())
591 return;
592
593 Tile *gfx = g_hdb->_ai->getInvItemGfx(slot);
594
595 switch (wType) {
596 case ITEM_CLUB:
597 case ITEM_ROBOSTUNNER:
598 case ITEM_SLUGSLINGER:
599 g_hdb->_ai->setPlayerWeapon(wType, gfx);
600 if (wType == lastWeaponSelected)
601 return;
602 lastWeaponSelected = wType;
603 g_hdb->_sound->playSound(SND_MENU_ACCEPT);
604 return;
605 default:
606 break;
607 }
608 g_hdb->_sound->playSound(SND_CELLHOLDER_USE_REJECT);
609 }
610
closeAll()611 void Window::closeAll() {
612 closeDialog();
613 closeDialogChoice();
614 closeMsg();
615 closeTextOut();
616
617 if (g_hdb->isPPC()) {
618 closeDlvs();
619 closeInv();
620 }
621 }
622
openDialog(const char * title,int tileIndex,const char * string,int more,const char * luaMore)623 void Window::openDialog(const char *title, int tileIndex, const char *string, int more, const char *luaMore) {
624 if (_dialogInfo.active)
625 return;
626
627 _dialogInfo.gfx = nullptr;
628 _dialogInfo.el = _dialogInfo.er = _dialogInfo.et = _dialogInfo.eb = 0;
629 _dialogInfo.luaMore[0] = 0;
630
631 _dialogInfo.tileIndex = tileIndex;
632 Common::strlcpy(_dialogInfo.title, title, 128);
633 _dialogInfo.active = true;
634
635 // This could need to be truncated
636 Common::strlcpy(_dialogInfo.string, string, 128);
637
638 int e1, e2, e3, e4;
639 g_hdb->_gfx->getTextEdges(&e1, &e2, &e3, &e4);
640 g_hdb->_gfx->setTextEdges(_dialogTextLeft, _dialogTextRight, 0, g_hdb->_screenDrawHeight);
641 int width, height;
642 g_hdb->_gfx->getDimensions(string, &width, &height);
643 int titleWidth, titleHeight;
644 g_hdb->_gfx->getDimensions(title, &titleWidth, &titleHeight);
645 g_hdb->_gfx->setTextEdges(e1, e2, e3, e4);
646 _dialogInfo.height = (height + 2) * 16;
647 int w = _dialogInfo.width = width + 32;
648 _dialogInfo.titleWidth = titleWidth;
649 if (titleWidth > w)
650 w = titleWidth;
651
652 _dialogInfo.x = (g_hdb->_screenDrawWidth >> 1) - (w >> 1);
653
654 int px, py;
655 g_hdb->_ai->getPlayerXY(&px, &py);
656 if (py < (g_hdb->_screenHeight >> 1) - 16)
657 _dialogInfo.y = (g_hdb->_screenHeight >> 1) + 16;
658 else
659 _dialogInfo.y = (g_hdb->_screenHeight >> 1) - (_dialogInfo.height + 64);
660
661 if (_dialogInfo.y < 16)
662 _dialogInfo.y = 16;
663
664 _dialogInfo.more = more;
665 if (luaMore)
666 Common::strlcpy(_dialogInfo.luaMore, luaMore, 64);
667 g_hdb->_sound->playSound(SND_MOVE_SELECTION);
668 }
669
drawDialog()670 void Window::drawDialog() {
671
672 #if 0
673 _gfxTL->drawMasked(0, 0);
674 _gfxTM->drawMasked(_gfxTL->_width, 0);
675 _gfxTR->drawMasked(_gfxTL->_width + _gfxTM->_width, 0);
676
677 _gfxL->drawMasked(0, _gfxTL->_height);
678 _gfxM->drawMasked(_gfxL->_width, _gfxTL->_height);
679 _gfxR->drawMasked(_gfxL->_width + _gfxM->_width, _gfxTL->_height);
680
681 _gfxBL->drawMasked(0, _gfxTL->_height + _gfxL->_height);
682 _gfxBM->drawMasked(_gfxBL->_width, _gfxTL->_height + _gfxL->_height);
683 _gfxBR->drawMasked(_gfxBL->_width + _gfxBM->_width, _gfxTL->_height + _gfxL->_height);
684 #endif
685
686 if (g_hdb->getActionMode()) {
687 Tile *gfx2 = g_hdb->_ai->getPlayerWeaponGfx();
688 if (gfx2) {
689 int xOff = 40 * _pzInfo.active;
690 Tile *gfx = g_hdb->_ai->getPlayerWeaponSelGfx();
691 gfx->drawMasked(_weaponX - xOff - 1, _weaponY);
692 gfx2->drawMasked(_weaponX - xOff, _weaponY);
693 drawWeapon();
694 }
695 }
696
697 if (!_dialogInfo.active)
698 return;
699 bool guyTalking = !scumm_stricmp(_dialogInfo.title, "guy");
700
701 int w = _dialogInfo.width;
702 if (_dialogInfo.titleWidth > w)
703 w = _dialogInfo.titleWidth;
704
705 drawBorder(_dialogInfo.x, _dialogInfo.y, w, _dialogInfo.height, guyTalking);
706
707 int blocks;
708 if (!guyTalking) {
709 _gfxTitleL->drawMasked(_dialogInfo.x, _dialogInfo.y - 10);
710 blocks = _dialogInfo.titleWidth / 16;
711 for (int i = 0; i < blocks; i++)
712 _gfxTitleM->drawMasked(_dialogInfo.x + 16 * (i + 1), _dialogInfo.y - 10);
713 _gfxTitleR->drawMasked(_dialogInfo.x + (blocks + 1) * 16, _dialogInfo.y - 10);
714 } else {
715 _gGfxTitleL->drawMasked(_dialogInfo.x, _dialogInfo.y - 10);
716 blocks = _dialogInfo.titleWidth / 16;
717 for (int i = 0; i < blocks; i++)
718 _gGfxTitleM->drawMasked(_dialogInfo.x + 16 * (i + 1), _dialogInfo.y - 10);
719 _gGfxTitleR->drawMasked(_dialogInfo.x + (blocks + 1) * 16, _dialogInfo.y - 10);
720 }
721
722 int e1, e2, e3, e4;
723 g_hdb->_gfx->getTextEdges(&e1, &e2, &e3, &e4);
724 g_hdb->_gfx->setTextEdges(_dialogInfo.x + 10, g_hdb->_screenDrawWidth, 0, g_hdb->_screenHeight);
725 g_hdb->_gfx->setCursor(0, _dialogInfo.y - 7);
726 if (strlen(_dialogInfo.title) > 0)
727 g_hdb->_gfx->drawText(_dialogInfo.title);
728 g_hdb->_gfx->setTextEdges(_dialogInfo.x + 16, _dialogInfo.x + _dialogInfo.width - 16, 0, g_hdb->_screenHeight);
729 g_hdb->_gfx->setCursor(0, _dialogInfo.y + 16);
730 if (strlen(_dialogInfo.string) > 0)
731 g_hdb->_gfx->drawText(_dialogInfo.string);
732 g_hdb->_gfx->setTextEdges(e1, e2, e3, e4);
733 }
734
closeDialog()735 void Window::closeDialog() {
736 if (_dialogInfo.active) {
737 g_hdb->_sound->playSound(SND_SWITCH_USE);
738 _dialogInfo.active = false;
739 _dialogDelay = 0;
740 if (_dialogInfo.luaMore[0] && !g_hdb->_ai->cinematicsActive())
741 g_hdb->_lua->callFunction(_dialogInfo.luaMore, 0);
742 }
743 }
744
checkDialogClose(int x,int y)745 bool Window::checkDialogClose(int x, int y) {
746 if (!_dialogInfo.active)
747 return false;
748
749 if (x >= _dialogInfo.x && x < _dialogInfo.x + _dialogInfo.width && y >= _dialogInfo.y && y < _dialogInfo.y + _dialogInfo.height) {
750 closeDialog();
751 return true;
752 }
753
754 // If Cinematics are on, we need to timeout instead of get a click
755 if (g_hdb->_ai->cinematicsActive()) {
756 if (_dialogDelay < g_hdb->getTimeSlice()) {
757 closeDialog();
758 _dialogDelay = 0;
759 return true;
760 }
761 }
762
763 return false;
764 }
765
drawBorder(int x,int y,int width,int height,bool guyTalking)766 void Window::drawBorder(int x, int y, int width, int height, bool guyTalking) {
767 int wide, high, i, j;
768 if (!guyTalking) {
769 wide = (width / 16) + 1;
770 high = height / 16;
771 for (j = 0; j < high; j++)
772 for (i = 0; i < wide; i++) {
773 // Top Line
774 if (!i && !j)
775 _gfxTL->drawMasked(x, y);
776 else if ((i == wide - 1) && !j)
777 _gfxTR->drawMasked(x + i * 16, y + j * 16);
778 else if (!j)
779 _gfxTM->drawMasked(x + i * 16, y + j * 16);
780 else {
781
782 // Bottom Lines
783 if ((j == high - 1) && !i)
784 _gfxBL->drawMasked(x + i * 16, y + j * 16);
785 else if ((j == high - 1) && (i == wide - 1))
786 _gfxBR->drawMasked(x + i * 16, y + j * 16);
787 else if ((j == high - 1) && i < wide)
788 _gfxBM->drawMasked(x + i * 16, y + j * 16);
789 else {
790 // Middle lines
791 if (!i && j < high)
792 _gfxL->drawMasked(x + i * 16, y + j * 16);
793 else if ((i == wide - 1) && j < high)
794 _gfxR->drawMasked(x + i * 16, y + j * 16);
795 else
796 // Most drawn = middle block
797 _gfxM->drawMasked(x + i * 16, y + j * 16);
798 }
799 }
800 }
801 } else {
802 wide = (width / 16) + 1;
803 high = height / 16;
804 for (j = 0; j < high; j++)
805 for (i = 0; i < wide; i++) {
806 // Top Line
807 if (!i && !j)
808 _gGfxTL->drawMasked(x, y);
809 else if ((i == wide - 1) && !j)
810 _gGfxTR->drawMasked(x + i * 16, y + j * 16);
811 else if (!j)
812 _gGfxTM->draw(x + i * 16, y + j * 16);
813 else {
814
815 // Bottom Lines
816 if ((j == high - 1) && !i)
817 _gGfxBL->drawMasked(x + i * 16, y + j * 16);
818 else if ((j == high - 1) && (i == wide - 1))
819 _gGfxBR->drawMasked(x + i * 16, y + j * 16);
820 else if ((j == high - 1) && i < wide)
821 _gGfxBM->draw(x + i * 16, y + j * 16);
822 else {
823
824 // Middle lines
825 if (!i && j < high)
826 _gGfxL->draw(x + i * 16, y + j * 16);
827 else if ((i == wide - 1) && j < high)
828 _gGfxR->draw(x + i * 16, y + j * 16);
829 else
830 // Most drawn = middle block
831 _gGfxM->draw(x + i * 16, y + j * 16);
832 }
833 }
834 }
835 }
836 }
837
setDialogDelay(int delay)838 void Window::setDialogDelay(int delay) {
839 _dialogDelay = g_system->getMillis() + 1000 * delay;
840 }
841
openDialogChoice(const char * title,const char * text,const char * func,int numChoices,const char * choices[10])842 void Window::openDialogChoice(const char *title, const char *text, const char *func, int numChoices, const char *choices[10]) {
843 int width, height, titleWidth, titleHeight;
844 int e1, e2, e3, e4;
845
846 if (_dialogInfo.active)
847 return;
848
849 _dialogChoiceInfo.el = _dialogChoiceInfo.er = _dialogChoiceInfo.et = _dialogChoiceInfo.eb = 0;
850 for (int i = 0; i < 10; i++)
851 _dialogChoiceInfo.choices[i][0] = 0;
852
853 Common::strlcpy(_dialogChoiceInfo.title, title, 64);
854 Common::strlcpy(_dialogChoiceInfo.text, text, 160);
855 Common::strlcpy(_dialogChoiceInfo.func, func, 64);
856 _dialogChoiceInfo.numChoices = numChoices;
857
858 for (int i = 0; i < numChoices; i++)
859 Common::strlcpy(_dialogChoiceInfo.choices[i], choices[i], 64);
860 _dialogChoiceInfo.active = true;
861
862 g_hdb->_gfx->getTextEdges(&e1, &e2, &e3, &e4);
863 g_hdb->_gfx->setTextEdges(_openDialogTextLeft, _openDialogTextRight, 0, g_hdb->_screenDrawHeight);
864 g_hdb->_gfx->getDimensions(text, &width, &height);
865 g_hdb->_gfx->getDimensions(title, &titleWidth, &titleHeight);
866
867 for (int i = 0; i < 10; i++)
868 if (choices[i]) {
869 int w, h;
870 g_hdb->_gfx->getDimensions(choices[i], &w, &h);
871 if (w > width)
872 width = w;
873 }
874
875 g_hdb->_gfx->setTextEdges(e1, e2, e3, e4);
876 _dialogChoiceInfo.textHeight = (height + 1) * 16;
877 _dialogChoiceInfo.height = (height + 2 + numChoices) * 16;
878 _dialogChoiceInfo.width = width + 48;
879 _dialogChoiceInfo.titleWidth = titleWidth;
880
881 _dialogChoiceInfo.x = (g_hdb->_screenDrawWidth >> 1) - (_dialogChoiceInfo.width >> 1);
882 _dialogChoiceInfo.y = (g_hdb->_screenHeight >> 1) - ((_dialogChoiceInfo.height >> 1) + 32);
883 if (_dialogChoiceInfo.y < 0)
884 _dialogChoiceInfo.y = 0;
885
886 _dialogChoiceInfo.selection = 0;
887 _dialogChoiceInfo.timeout = 0;
888 g_hdb->_sound->playSound(SND_MOVE_SELECTION);
889 }
890
drawDialogChoice()891 void Window::drawDialogChoice() {
892 if (!_dialogChoiceInfo.active)
893 return;
894
895 // time out?
896 if (_dialogChoiceInfo.timeout && _dialogChoiceInfo.timeout < g_hdb->getTimeSlice()) {
897 closeDialogChoice();
898 return;
899 }
900
901 bool guyTalking = !scumm_stricmp(_dialogChoiceInfo.title, "guy");
902
903 int w = _dialogChoiceInfo.width;
904 if (_dialogChoiceInfo.titleWidth > w)
905 w = _dialogChoiceInfo.titleWidth;
906
907 drawBorder(_dialogChoiceInfo.x, _dialogChoiceInfo.y, w, _dialogChoiceInfo.height, guyTalking);
908
909 if (!guyTalking) {
910 _gfxTitleL->drawMasked(_dialogChoiceInfo.x, _dialogChoiceInfo.y - 10);
911 int blocks = _dialogChoiceInfo.titleWidth / 16;
912 for (int i = 0; i < blocks; i++)
913 _gfxTitleM->drawMasked(_dialogChoiceInfo.x + 16 * (i + 1), _dialogChoiceInfo.y - 10);
914 _gfxTitleR->drawMasked(_dialogChoiceInfo.x + (blocks + 1) * 16, _dialogChoiceInfo.y - 10);
915 } else {
916 _gGfxTitleL->drawMasked(_dialogChoiceInfo.x, _dialogChoiceInfo.y - 10);
917 int blocks = _dialogChoiceInfo.titleWidth / 16;
918 for (int i = 0; i < blocks; i++)
919 _gGfxTitleM->drawMasked(_dialogChoiceInfo.x + 16 * (i + 1), _dialogChoiceInfo.y - 10);
920 _gGfxTitleR->drawMasked(_dialogChoiceInfo.x + (blocks + 1) * 16, _dialogChoiceInfo.y - 10);
921 }
922
923 int e1, e2, e3, e4;
924 g_hdb->_gfx->getTextEdges(&e1, &e2, &e3, &e4);
925 g_hdb->_gfx->setTextEdges(_dialogChoiceInfo.x + 10, _openDialogTextRight, 0, g_hdb->_screenDrawHeight);
926 g_hdb->_gfx->setCursor(0, _dialogChoiceInfo.y - 7);
927 if (strlen(_dialogChoiceInfo.title) > 0)
928 g_hdb->_gfx->drawText(_dialogChoiceInfo.title);
929 g_hdb->_gfx->setTextEdges(_dialogChoiceInfo.x + 16, _openDialogTextRight, 0, g_hdb->_screenDrawHeight);
930 g_hdb->_gfx->setCursor(0, _dialogChoiceInfo.y + 16);
931 if (strlen(_dialogChoiceInfo.text) > 0)
932 g_hdb->_gfx->drawText(_dialogChoiceInfo.text);
933
934 for (int i = 0; i < _dialogChoiceInfo.numChoices; i++) {
935 g_hdb->_gfx->setCursor(_dialogChoiceInfo.x + 48, _dialogChoiceInfo.y + _dialogChoiceInfo.textHeight + 16 * i);
936 g_hdb->_gfx->drawText(_dialogChoiceInfo.choices[i]);
937 }
938 g_hdb->_gfx->setTextEdges(e1, e2, e3, e4);
939
940 _gfxHandright->drawMasked(_dialogChoiceInfo.x + 10, 4 + _dialogChoiceInfo.y + _dialogChoiceInfo.textHeight + 16 * _dialogChoiceInfo.selection);
941 }
942
closeDialogChoice()943 void Window::closeDialogChoice() {
944 if (_dialogChoiceInfo.active) {
945 _dialogChoiceInfo.active = false;
946 g_hdb->_lua->pushFunction(_dialogChoiceInfo.func);
947 g_hdb->_lua->pushInt(_dialogChoiceInfo.selection);
948 g_hdb->_lua->call(1, 0);
949 g_hdb->_sound->playSound(SND_SWITCH_USE);
950 }
951 }
952
checkDialogChoiceClose(int x,int y)953 bool Window::checkDialogChoiceClose(int x, int y) {
954 if (!_dialogChoiceInfo.active || _dialogChoiceInfo.timeout)
955 return false;
956
957 if (x >= _dialogChoiceInfo.x && x < _dialogChoiceInfo.x + _dialogChoiceInfo.width &&
958 y >= _dialogChoiceInfo.y + _dialogChoiceInfo.textHeight && y < _dialogChoiceInfo.y + _dialogChoiceInfo.textHeight + _dialogChoiceInfo.numChoices * 16) {
959 g_hdb->_sound->playSound(SND_SWITCH_USE);
960 _dialogChoiceInfo.selection = (y - (_dialogChoiceInfo.y + _dialogChoiceInfo.textHeight)) >> 4;
961 _dialogChoiceInfo.timeout = g_hdb->getTimeSlice() + 500;
962 return true;
963 }
964
965 return false;
966 }
967
dialogChoiceMoveup()968 void Window::dialogChoiceMoveup() {
969 _dialogChoiceInfo.selection--;
970 if (_dialogChoiceInfo.selection < 0)
971 _dialogChoiceInfo.selection = _dialogChoiceInfo.numChoices - 1;
972 g_hdb->_sound->playSound(SND_MOVE_SELECTION);
973 }
974
dialogChoiceMovedown()975 void Window::dialogChoiceMovedown() {
976 _dialogChoiceInfo.selection++;
977 if (_dialogChoiceInfo.selection >= _dialogChoiceInfo.numChoices)
978 _dialogChoiceInfo.selection = 0;
979 g_hdb->_sound->playSound(SND_MOVE_SELECTION);
980 }
981
openMessageBar(const char * title,int time)982 void Window::openMessageBar(const char *title, int time) {
983 // is the messagebar already up? if so, add this msg to the queue
984 if (_msgInfo.active) {
985 if (_numMsgQueue < kMaxMsgQueue) {
986 int i;
987 if (!scumm_stricmp(_msgInfo.title, title))
988 return;
989
990 for (i = 0; i < _numMsgQueue; i++)
991 if (!scumm_stricmp(_msgQueueStr[i], title))
992 return;
993 Common::strlcpy(_msgQueueStr[_numMsgQueue], title, 128);
994 _msgQueueWait[_numMsgQueue] = time;
995 _numMsgQueue++;
996 }
997 return;
998 }
999
1000 _msgInfo.y = 0;
1001 _msgInfo.timer = (time * kGameFPS);
1002 Common::strlcpy(_msgInfo.title, title, 128);
1003
1004 int e1, e2, e3, e4;
1005 g_hdb->_gfx->getTextEdges(&e1, &e2, &e3, &e4);
1006 g_hdb->_gfx->setTextEdges(_dialogTextLeft, _dialogTextRight, 0, g_hdb->_screenDrawHeight);
1007 int width, height;
1008 g_hdb->_gfx->getDimensions(title, &width, &height);
1009 g_hdb->_gfx->setTextEdges(e1, e2, e3, e4);
1010
1011 _msgInfo.height = (height + 2) * 16;
1012 _msgInfo.width = width + 32;
1013
1014 _msgInfo.x = (g_hdb->_screenDrawWidth >> 1) - (_msgInfo.width >> 1);
1015 _msgInfo.active = true;
1016 }
1017
drawMessageBar()1018 void Window::drawMessageBar() {
1019 // if msgbar's not up OR inventory is up, exit
1020 if (!_msgInfo.active || _invWinInfo.active || _dialogInfo.active)
1021 return;
1022
1023 int xx, py, my;
1024 g_hdb->_ai->getPlayerXY(&xx, &py); // don't care about the x
1025 g_hdb->_map->getMapXY(&xx, &my);
1026 _msgInfo.y = (py - my) - _msgInfo.height - 64; // put msgbar directly above player
1027 if (_msgInfo.y < _msgInfo.height)
1028 _msgInfo.y = (py - my) + 40; // if at top, but it directly below
1029
1030 drawBorder(_msgInfo.x, _msgInfo.y, _msgInfo.width, _msgInfo.height, false);
1031
1032 int e1, e2, e3, e4;
1033 g_hdb->_gfx->getTextEdges(&e1, &e2, &e3, &e4);
1034 g_hdb->_gfx->setTextEdges(_msgInfo.x + 16, _msgInfo.x + _msgInfo.width - 16, 0, 320);
1035 g_hdb->_gfx->setCursor(_msgInfo.x + 16, _msgInfo.y + 16);
1036 g_hdb->_gfx->drawText(_msgInfo.title);
1037 g_hdb->_gfx->setTextEdges(e1, e2, e3, e4);
1038
1039 //
1040 // time to go away? see if we have any more msgs in the queue...
1041 //
1042 if (_msgInfo.timer-- < 1)
1043 nextMsgQueued();
1044 }
1045
checkMsgClose(int x,int y)1046 bool Window::checkMsgClose(int x, int y) {
1047 if (x >= _msgInfo.x && x < _msgInfo.x + _msgInfo.width &&
1048 y >= _msgInfo.y && y < _msgInfo.y + _msgInfo.height) {
1049 closeMsg();
1050 return true;
1051 }
1052
1053 return false;
1054 }
1055
nextMsgQueued()1056 void Window::nextMsgQueued() {
1057 if (!_numMsgQueue) {
1058 _msgInfo.active = false;
1059 return;
1060 }
1061
1062 Common::strlcpy(_msgInfo.title, _msgQueueStr[0], 128);
1063 _msgInfo.timer = (_msgQueueWait[0] * kGameFPS);
1064
1065 int e1, e2, e3, e4;
1066 g_hdb->_gfx->getTextEdges(&e1, &e2, &e3, &e4);
1067 g_hdb->_gfx->setTextEdges(_dialogTextLeft, _dialogTextRight, 0, g_hdb->_screenDrawHeight);
1068 int width, height;
1069 g_hdb->_gfx->getDimensions(_msgInfo.title, &width, &height);
1070 g_hdb->_gfx->setTextEdges(e1, e2, e3, e4);
1071
1072 _msgInfo.height = (height + 2) * 16;
1073
1074 _msgInfo.width = width + 32;
1075 _msgInfo.x = (g_hdb->_screenDrawWidth >> 1) - (_msgInfo.width >> 1);
1076 _msgInfo.y = (g_hdb->_screenHeight >> 2) - (_msgInfo.height >> 1);
1077
1078 for (int xx = 0; xx < _numMsgQueue - 1; xx++) {
1079 Common::strlcpy(_msgQueueStr[xx], _msgQueueStr[xx + 1], 128);
1080 _msgQueueWait[xx] = _msgQueueWait[xx + 1];
1081 }
1082
1083 _numMsgQueue--;
1084 _msgInfo.active = true;
1085 }
1086
closeMsg()1087 void Window::closeMsg() {
1088 nextMsgQueued();
1089 g_hdb->_sound->playSound(SND_DIALOG_CLOSE);
1090 }
1091
drawInventory()1092 void Window::drawInventory() {
1093 static uint32 timer = g_hdb->getTimeSlice() + 300; // unused
1094
1095 if (g_hdb->isPPC()) {
1096 if (!_invWinInfo.active)
1097 return;
1098
1099 drawBorder(_invWinInfo.x, _invWinInfo.y, _invWinInfo.width, _invWinInfo.height, false);
1100
1101 _gfxTitleL->drawMasked(_invWinInfo.x, _invWinInfo.y - 10);
1102 int blocks = _gfxResources->_width / 16;
1103 for (int i = 0; i < blocks; i++)
1104 _gfxTitleM->drawMasked(_invWinInfo.x + 16 * (i + 1), _invWinInfo.y - 10);
1105 _gfxTitleR->drawMasked(_invWinInfo.x + 16 * (blocks + 1), _invWinInfo.y - 10);
1106
1107 _gfxResources->drawMasked(_invWinInfo.x + 16, _invWinInfo.y - 6);
1108
1109 //
1110 // blink the INV hand...
1111 //
1112 if (g_hdb->getTimeSlice() > timer - 150)
1113 _gfxHandright->drawMasked(g_hdb->_screenWidth - _gfxHandright->_width, _invWinInfo.y + _invItemSpace * 2);
1114
1115 if (timer < g_hdb->getTimeSlice())
1116 timer = g_hdb->getTimeSlice() + 300;
1117
1118 int drawX = _invWinInfo.x + 16;
1119 int baseX = drawX;
1120 int drawY = _invWinInfo.y + 16;
1121
1122 // Draw Inv Items
1123 AIEntity *sel = nullptr;
1124 if (_invWinInfo.selection >= g_hdb->_ai->getInvAmount())
1125 _invWinInfo.selection = g_hdb->_ai->getInvAmount() - 1;
1126
1127 for (int inv = 0; inv < g_hdb->_ai->getInvAmount(); inv++) {
1128 AIEntity *e = g_hdb->_ai->getInvItem(inv);
1129 if (inv == _invWinInfo.selection)
1130 sel = e;
1131
1132 e->standdownGfx[0]->drawMasked(drawX, drawY);
1133
1134 drawX += _invItemSpace;
1135 if (drawX >= baseX + (_invItemSpace * _invItemPerLine)) {
1136 drawX = baseX;
1137 drawY += _invItemSpace;
1138 }
1139 }
1140
1141 // Draw the gems
1142 drawY = _invWinInfo.y + 8 + _invItemSpace * 2;
1143 drawX = baseX + _invItemSpace * 4 + 8;
1144 _gemGfx->drawMasked(drawX, drawY);
1145 int gems = g_hdb->_ai->getGemAmount();
1146 Common::String gemString = Common::String::format("%d", gems);
1147 g_hdb->_gfx->setCursor(drawX + 22, drawY + 8);
1148 g_hdb->_gfx->drawText(gemString.c_str());
1149
1150 // if you have an inventory, draw the selection cursor
1151 if (g_hdb->_ai->getInvAmount()) {
1152 if (_invWinInfo.selection < 0)
1153 _invWinInfo.selection = 0;
1154
1155 // Draw the inventory select cursor
1156 if (_invWinInfo.selection > 4)
1157 drawX = baseX + (_invWinInfo.selection - 5) * _invItemSpace;
1158 else
1159 drawX = baseX + _invWinInfo.selection * _invItemSpace;
1160
1161 if (_invWinInfo.selection < 5)
1162 drawY = _invWinInfo.y + 16;
1163 else
1164 drawY = _invWinInfo.y + 16 + _invItemSpace;
1165
1166 _gfxInvSelect->drawMasked(drawX, drawY);
1167
1168 // Draw the name of the inventory item
1169 if (sel) {
1170 drawY = _invWinInfo.y + 8 + _invItemSpace * 2;
1171 g_hdb->_gfx->setCursor(baseX, drawY + 8);
1172 g_hdb->_gfx->drawText(sel->printedName);
1173 }
1174 }
1175 } else {
1176 // INFOBAR blit - only once per frame
1177 // note: if 2, don't draw ANY info at all
1178 if (_infobarDimmed > 1)
1179 return;
1180
1181 _gfxInfobar->draw(g_hdb->_screenWidth - _gfxInfobar->_width, 0);
1182
1183 int drawX = _invWinInfo.x;
1184 int baseX = drawX;
1185 int drawY = _invWinInfo.y;
1186
1187 // Draw Inv Items
1188 AIEntity *sel = nullptr;
1189 if (_invWinInfo.selection >= g_hdb->_ai->getInvAmount())
1190 _invWinInfo.selection = g_hdb->_ai->getInvAmount() - 1;
1191
1192 for (int inv = 0; inv < g_hdb->_ai->getInvAmount(); inv++) {
1193 AIEntity *e = g_hdb->_ai->getInvItem(inv);
1194 if (inv == _invWinInfo.selection)
1195 sel = e;
1196
1197 e->standdownGfx[0]->drawMasked(drawX, drawY);
1198
1199 drawX += _invItemSpaceX;
1200 if (drawX >= baseX + (_invItemSpaceX * _invItemPerLine)) {
1201 drawX = baseX;
1202 drawY += _invItemSpaceY;
1203 }
1204 }
1205
1206 // Draw the Gem
1207 drawY = _invWinInfo.y + _invItemSpaceY * 4 - 8;
1208 drawX = baseX - 8;
1209 _gemGfx->drawMasked(drawX, drawY);
1210
1211 // Draw the Gem Amount
1212 int gems = g_hdb->_ai->getGemAmount();
1213 Common::String gemString = Common::String::format("%d", gems);
1214 g_hdb->_gfx->setCursor(drawX + 32, drawY + 8);
1215 g_hdb->_gfx->drawText(gemString.c_str());
1216
1217 // Draw the mini monkeystone
1218 int mstones = g_hdb->_ai->getMonkeystoneAmount();
1219 if (mstones) {
1220 drawX = baseX + _invItemSpaceX * 2 - 8;
1221 _mstoneGfx->drawMasked(drawX, drawY + 8);
1222
1223 // Draw the monkeystone amount
1224 Common::String stoneString = Common::String::format("%d", mstones);
1225 g_hdb->_gfx->setCursor(drawX + 28, drawY + 8);
1226 g_hdb->_gfx->drawText(stoneString.c_str());
1227 }
1228
1229 // If you have an inventory, draw the selection cursor
1230 if (g_hdb->_ai->getInvAmount()) {
1231 if (_invWinInfo.selection < 0)
1232 _invWinInfo.selection = 0;
1233
1234 // Draw the Inventory Select Cursor
1235 drawX = baseX + (_invWinInfo.selection % _invItemPerLine) * _invItemSpaceX;
1236 drawY = _invWinInfo.y + (_invWinInfo.selection / _invItemPerLine) * _invItemSpaceY;
1237 _gfxInvSelect->drawMasked(drawX, drawY);
1238
1239 if (sel) {
1240 int centerX = baseX - 4 + (g_hdb->_screenWidth - baseX) / 2;
1241 drawY = _invWinInfo.y + (_invItemSpaceY * 4) + 16;
1242 g_hdb->_gfx->setCursor(centerX - g_hdb->_gfx->stringLength(sel->printedName) / 2, drawY);
1243 g_hdb->_gfx->drawText(sel->printedName);
1244 }
1245 }
1246 }
1247 }
1248
checkInvSelect(int x,int y)1249 void Window::checkInvSelect(int x, int y) {
1250 if (x >= _invWinInfo.x && x < _invWinInfo.x + _invWinInfo.width && y >= _invWinInfo.y && y < _invWinInfo.y + _invWinInfo.height) {
1251 int xc = (x - _invWinInfo.x) / _invItemSpaceX;
1252 int yc = (y - _invWinInfo.y) / _invItemSpaceY;
1253 if (yc * _invItemPerLine + xc > g_hdb->_ai->getInvAmount())
1254 return;
1255
1256 _invWinInfo.selection = yc * _invItemPerLine + xc;
1257
1258 // If this is a weapon, choose it
1259 AIType t = g_hdb->_ai->getInvItemType(_invWinInfo.selection);
1260 switch (t) {
1261 case ITEM_CLUB:
1262 case ITEM_ROBOSTUNNER:
1263 case ITEM_SLUGSLINGER:
1264 chooseWeapon(t);
1265 if (t == ITEM_CLUB)
1266 g_hdb->_sound->playSound(SND_GET_CLUB);
1267 else if (t == ITEM_ROBOSTUNNER)
1268 g_hdb->_sound->playSound(SND_GET_STUNNER);
1269 else if (t == ITEM_SLUGSLINGER)
1270 g_hdb->_sound->playSound(SND_GET_SLUG);
1271 return;
1272 default:
1273 break;
1274 }
1275
1276 g_hdb->_sound->playSound(SND_POP);
1277 }
1278
1279 return;
1280 }
1281
openInventory()1282 void Window::openInventory() {
1283 if (!g_hdb->isPPC())
1284 return;
1285
1286 if (_invWinInfo.active)
1287 return;
1288
1289 centerTextOut(g_hdb->getInMapName(), 304, 60 * 3);
1290
1291 if (!g_hdb->_ai->getInvAmount() && !g_hdb->_ai->getGemAmount()) {
1292 if (!g_hdb->_ai->getDeliveriesAmount())
1293 openMessageBar("You have nothing.", 3);
1294 else
1295 openDeliveries(false);
1296 return;
1297 }
1298
1299 _invWinInfo.x = (g_hdb->_screenWidth >> 1) - (_invWinInfo.width >> 1) - 8;
1300
1301 int px, py;
1302 g_hdb->_ai->getPlayerXY(&px, &py);
1303 if (py < (g_hdb->_screenHeight >> 1) - 16)
1304 _invWinInfo.y = (g_hdb->_screenHeight >> 1) + 16;
1305 else
1306 _invWinInfo.y = 16;
1307
1308 g_hdb->_sound->playSound(SND_POP);
1309 _invWinInfo.active = true;
1310 }
1311
checkInvClose(int x,int y)1312 bool Window::checkInvClose(int x, int y) {
1313 if (!g_hdb->isPPC())
1314 return false;
1315
1316 if (x >= g_hdb->_screenWidth - _gfxHandright->_width &&
1317 y >= _invWinInfo.y && y < _invWinInfo.y + _invItemSpace * 3) {
1318 closeInv();
1319 openDeliveries(0);
1320 return true;
1321 } else if (x >= _invWinInfo.x && x < _invWinInfo.x + _invWinInfo.width &&
1322 y >= _invWinInfo.y && y < _invWinInfo.y + _invWinInfo.height) {
1323 int xc = (x - _invWinInfo.x) / _invItemSpace;
1324 int yc = (y - _invWinInfo.y) / _invItemSpace;
1325 if (yc * 5 + xc > g_hdb->_ai->getInvAmount()) {
1326 closeInv();
1327 return true;
1328 }
1329 _invWinInfo.selection = yc * 5 + xc;
1330 g_hdb->_sound->playSound(SND_MENU_SLIDER);
1331
1332 static AIType lastWeaponSelected = AI_NONE;
1333
1334 if (!g_hdb->getActionMode())
1335 return false;
1336
1337 AIType t = g_hdb->_ai->getInvItemType(_invWinInfo.selection);
1338 Tile *gfx = g_hdb->_ai->getInvItemGfx(_invWinInfo.selection);
1339
1340 switch (t) {
1341 case ITEM_CLUB:
1342 case ITEM_ROBOSTUNNER:
1343 case ITEM_SLUGSLINGER:
1344 g_hdb->_ai->setPlayerWeapon(t, gfx);
1345 if (t == lastWeaponSelected) {
1346 closeInv();
1347 return false;
1348 }
1349 lastWeaponSelected = t;
1350 g_hdb->_sound->playSound(SND_MENU_ACCEPT);
1351 return true;
1352 default:
1353 break;
1354 }
1355 g_hdb->_sound->playSound(SND_CELLHOLDER_USE_REJECT);
1356 }
1357
1358 return false;
1359 }
1360
closeInv()1361 void Window::closeInv() {
1362 if (!g_hdb->isPPC())
1363 return;
1364
1365 g_hdb->_sound->playSound(SND_DIALOG_CLOSE);
1366 _invWinInfo.active = false;
1367 }
1368
openDeliveries(bool animate)1369 void Window::openDeliveries(bool animate) {
1370 // Load Gfx
1371 for (int i = 0; i < g_hdb->_ai->getDeliveriesAmount(); i++) {
1372 DlvEnt *d = g_hdb->_ai->getDeliveryItem(i);
1373 if (d->itemGfxName[0])
1374 d->itemGfx = g_hdb->_gfx->loadTile(d->itemGfxName);
1375 if (d->destGfxName[0])
1376 d->destGfx = g_hdb->_gfx->loadTile(d->destGfxName);
1377 }
1378
1379 if (g_hdb->isPPC()) {
1380 // calc the X & Y for the window
1381 _dlvsInfo.x = (g_hdb->_screenWidth >> 1) - (_dlvsInfo.width >> 1) - 8;
1382
1383 int px, py;
1384 g_hdb->_ai->getPlayerXY(&px, &py);
1385 if (py < (g_hdb->_screenHeight >> 1) - 16)
1386 _dlvsInfo.y = (g_hdb->_screenHeight >> 1);
1387 else
1388 _dlvsInfo.y = 16;
1389 }
1390
1391 g_hdb->_sound->playSound(SND_POP);
1392 _dlvsInfo.animate = animate;
1393 _dlvsInfo.delay1 = g_hdb->getTimeSlice() + 500;
1394 _dlvsInfo.go1 = _dlvsInfo.go2 = _dlvsInfo.go3 = false;
1395
1396 if (animate) {
1397 _dlvsInfo.go1 = true;
1398 _dlvsInfo.selected = g_hdb->_ai->getDeliveriesAmount() - 1;
1399 }
1400
1401 // Make sure cursor isn't on an empty delivery
1402 if (_dlvsInfo.selected >= g_hdb->_ai->getDeliveriesAmount())
1403 _dlvsInfo.selected = g_hdb->_ai->getDeliveriesAmount() - 1;
1404
1405 if (g_hdb->isPPC())
1406 _dlvsInfo.active = true;
1407 }
1408
drawDeliveries()1409 void Window::drawDeliveries() {
1410 static uint32 timer = g_hdb->getTimeSlice() + 300; //unused
1411 static const int crazySounds[kNumCrazy] = {
1412 SND_GUI_INPUT,
1413 SND_MAIL_PROCESS,
1414 SND_MONKEY_OOHOOH,
1415 SND_GET_GEM,
1416 SND_MENU_ACCEPT,
1417 SND_MENU_BACKOUT,
1418 SND_MENU_SLIDER,
1419 SND_DIALOG_CLOSE,
1420 SND_POP,
1421 SND_SPLASH,
1422 SND_CHICKEN_AMBIENT,
1423 SND_SWITCH_USE,
1424 SND_BARREL_EXPLODE,
1425 SND_BARREL_MELTING,
1426 SND_MOVE_SELECTION,
1427 SND_NOTICE,
1428 SND_DIALOG_OPEN,
1429 SND_TOUCHPLATE_CLICK,
1430 SND_MBOT_HYEAH,
1431 SND_MBOT_YEAH,
1432 SND_MBOT_WHISTLE1,
1433 SND_CLUB_MISS,
1434 SND_CLUB_HIT_METAL,
1435 SND_CLUB_HIT_FLESH,
1436 SND_FROG_LICK,
1437 SND_ROBOT_STUNNED,
1438 SND_BRIDGE_EXTEND,
1439 SND_BRIDGE_END,
1440 SND_AIRLOCK_CLOSE,
1441 SND_FART,
1442 SND_FART2,
1443 SND_GEM_THROW,
1444 SND_INV_SELECT,
1445 SND_INFOCOMP,
1446 SND_CLOCK_BONK,
1447 SND_GET_GOO,
1448 SND_MANNY_CRASH
1449 };
1450
1451 if (g_hdb->isPPC()) {
1452 if (!_dlvsInfo.active)
1453 return;
1454
1455 // draw the window first
1456 drawBorder(_dlvsInfo.x, _dlvsInfo.y, _dlvsInfo.width, _dlvsInfo.height, false);
1457
1458 _gfxTitleL->drawMasked(_dlvsInfo.x, _dlvsInfo.y - 10);
1459 int blocks = _gfxDeliveries->_width / 16;
1460 for (int i = 0; i < blocks; i++)
1461 _gfxTitleM->drawMasked(_dlvsInfo.x + 16 * (i + 1), _dlvsInfo.y - 10);
1462 _gfxTitleR->drawMasked(_dlvsInfo.x + (blocks + 1) * 16, _dlvsInfo.y - 10);
1463
1464 _gfxDeliveries->drawMasked(_dlvsInfo.x + 16, _dlvsInfo.y - 6);
1465
1466 //
1467 // blink the DELIVERY hand...
1468 //
1469 if (g_hdb->_ai->getInvAmount()) {
1470 if (g_hdb->getTimeSlice() > timer - 150)
1471 _gfxHandright->drawMasked(_dlvsInfo.x + _dlvsInfo.width, _dlvsInfo.y + _invItemSpace * 2);
1472
1473 if (timer < g_hdb->getTimeSlice())
1474 timer = g_hdb->getTimeSlice() + 300;
1475 }
1476
1477 int drawX = _dlvsInfo.x + 16;
1478 int drawY = _dlvsInfo.y + 16;
1479 int baseX = drawX;
1480
1481 // Draw delivery items
1482 int inv = 0;
1483 for (; inv < g_hdb->_ai->getDeliveriesAmount(); inv++) {
1484 DlvEnt *d = g_hdb->_ai->getDeliveryItem(inv);
1485 if (_dlvsInfo.animate && inv == g_hdb->_ai->getDeliveriesAmount() - 1) {
1486 if (_dlvsInfo.go1) {
1487 if (_dlvsInfo.delay1 < g_hdb->getTimeSlice()) {
1488 // draw Item
1489 _gfxIndent->draw(drawX, drawY);
1490 d->itemGfx->drawMasked(drawX, drawY);
1491
1492 g_hdb->_gfx->setCursor(drawX, drawY + _invItemSpace * 2 + 20);
1493 g_hdb->_gfx->centerPrint(d->itemTextName);
1494 if (!_dlvsInfo.go2) {
1495 _dlvsInfo.go2 = true;
1496 _dlvsInfo.delay2 = g_hdb->getTimeSlice() + 500;
1497 g_hdb->_sound->playSound(crazySounds[g_hdb->_rnd->getRandomNumber(kNumCrazy - 1)]);
1498 }
1499 }
1500 }
1501 if (_dlvsInfo.go2) {
1502 if (_dlvsInfo.delay2 < g_hdb->getTimeSlice()) {
1503 // arrow TO...
1504 _gfxArrowTo->drawMasked(_dlvsInfo.x + 24 + _invItemSpace * _dlvsInfo.selected, drawY + _invItemSpace);
1505
1506 g_hdb->_gfx->setCursor(drawX, drawY + _invItemSpace * 2 + 32);
1507 g_hdb->_gfx->centerPrint("to");
1508 if (!_dlvsInfo.go3) {
1509 _dlvsInfo.go3 = true;
1510 _dlvsInfo.delay3 = g_hdb->getTimeSlice() + 500;
1511 g_hdb->_sound->playSound(crazySounds[g_hdb->_rnd->getRandomNumber(kNumCrazy - 1)]);
1512 }
1513 }
1514 }
1515 if (_dlvsInfo.go3) {
1516 if (_dlvsInfo.delay3 < g_hdb->getTimeSlice()) {
1517 // draw Deliveree
1518 _gfxIndent->draw(drawX, drawY + _invItemSpace + 16);
1519 d->destGfx->drawMasked(drawX, drawY + _invItemSpace + 16);
1520
1521 g_hdb->_gfx->setCursor(drawX, drawY + _invItemSpace * 2 + 44);
1522 g_hdb->_gfx->centerPrint(d->destTextName);
1523
1524 g_hdb->_sound->playSound(crazySounds[g_hdb->_rnd->getRandomNumber(kNumCrazy - 1)]);
1525 _dlvsInfo.animate = false;
1526 }
1527 }
1528 } else {
1529 // draw Item
1530 _gfxIndent->draw(drawX, drawY);
1531 d->itemGfx->drawMasked(drawX, drawY);
1532
1533 // draw Deliveree
1534 _gfxIndent->draw(drawX, drawY + _invItemSpace + 16);
1535 d->destGfx->drawMasked(drawX, drawY + _invItemSpace + 16);
1536
1537 if (!_dlvsInfo.animate && inv == _dlvsInfo.selected) {
1538 g_hdb->_gfx->setCursor(drawX, drawY + _invItemSpace * 2 + 20);
1539 g_hdb->_gfx->centerPrint(d->itemTextName);
1540 g_hdb->_gfx->setCursor(drawX, drawY + _invItemSpace * 2 + 32);
1541 g_hdb->_gfx->centerPrint("to");
1542 g_hdb->_gfx->setCursor(drawX, drawY + _invItemSpace * 2 + 44);
1543 g_hdb->_gfx->centerPrint(d->destTextName);
1544 }
1545
1546 drawX += _invItemSpace;
1547 }
1548 }
1549
1550 if (!inv) {
1551 g_hdb->_gfx->setCursor(baseX, _dlvsInfo.y + 32);
1552 g_hdb->_gfx->drawText("No Deliveries");
1553 _dlvsInfo.animate = false;
1554 } else if (!_dlvsInfo.animate) {
1555 // arrow TO...
1556 _gfxArrowTo->drawMasked(_dlvsInfo.x + 24 + _invItemSpace * _dlvsInfo.selected, drawY + _invItemSpace);
1557 }
1558 } else {
1559 if (_infobarDimmed > 1)
1560 return;
1561
1562 int baseX = _dlvsInfo.x;
1563 int drawX = _dlvsInfo.x;
1564 int drawY = _dlvsInfo.y;
1565
1566 if (_dlvsInfo.selected >= g_hdb->_ai->getDeliveriesAmount())
1567 _dlvsInfo.selected = g_hdb->_ai->getDeliveriesAmount() - 1;
1568
1569 // Draw Delivery Items
1570 int inv = 0;
1571 for (; inv < g_hdb->_ai->getDeliveriesAmount(); inv++) {
1572 int centerX = baseX + (g_hdb->_screenWidth - baseX) / 2;
1573 DlvEnt *d = g_hdb->_ai->getDeliveryItem(inv);
1574 if (_dlvsInfo.animate && inv == g_hdb->_ai->getDeliveriesAmount() - 1) {
1575 if (_dlvsInfo.go1) {
1576 if (_dlvsInfo.delay1 < g_hdb->getTimeSlice()) {
1577 // Draw Item
1578 _gfxIndent->draw(drawX, drawY);
1579 if (d->itemGfx)
1580 d->itemGfx->drawMasked(drawX, drawY);
1581
1582 g_hdb->_gfx->setCursor(centerX - g_hdb->_gfx->stringLength(d->itemTextName) / 2, _dlvItemTextY);
1583 g_hdb->_gfx->drawText(d->itemTextName);
1584 if (!_dlvsInfo.go2) {
1585 _dlvsInfo.go2 = true;
1586 _dlvsInfo.delay2 = g_hdb->getTimeSlice() + 500;
1587 g_hdb->_sound->playSound(crazySounds[g_hdb->_rnd->getRandomNumber(kNumCrazy - 1)]);
1588 }
1589 }
1590 }
1591 if (_dlvsInfo.go2) {
1592 if (_dlvsInfo.delay2 < g_hdb->getTimeSlice()) {
1593 // Draw TO
1594 _gfxArrowTo->drawMasked(_dlvsInfo.x + _dlvItemSpaceX * _dlvsInfo.selected + 8, drawY + kTileHeight);
1595
1596 g_hdb->_gfx->setCursor(centerX - g_hdb->_gfx->stringLength("to") / 2, _dlvItemTextY + 12);
1597 g_hdb->_gfx->drawText("to");
1598 if (!_dlvsInfo.go3) {
1599 _dlvsInfo.go3 = true;
1600 _dlvsInfo.delay3 = g_hdb->getTimeSlice() + 500;
1601 g_hdb->_sound->playSound(crazySounds[g_hdb->_rnd->getRandomNumber(kNumCrazy - 1)]);
1602 }
1603 }
1604 }
1605 if (_dlvsInfo.go3) {
1606 if (_dlvsInfo.delay3 < g_hdb->getTimeSlice()) {
1607 // Draw Delivery
1608 _gfxIndent->draw(drawX, drawY + kTileHeight + 16);
1609 if (d->destGfx)
1610 d->destGfx->drawMasked(drawX, drawY + kTileHeight + 16);
1611
1612 g_hdb->_gfx->setCursor(centerX - (g_hdb->_gfx->stringLength(d->destTextName) + g_hdb->_gfx->stringLength("to")) / 2, _dlvItemTextY + 12);
1613 g_hdb->_gfx->drawText("to ");
1614 g_hdb->_gfx->drawText(d->destTextName);
1615
1616 g_hdb->_sound->playSound(crazySounds[g_hdb->_rnd->getRandomNumber(kNumCrazy - 1)]);
1617 _dlvsInfo.animate = false;
1618 }
1619 }
1620
1621 } else {
1622 // Draw Item
1623 _gfxIndent->draw(drawX, drawY);
1624 if (d->itemGfx)
1625 d->itemGfx->drawMasked(drawX, drawY);
1626 // Draw Delivery
1627 _gfxIndent->draw(drawX, drawY + kTileHeight + 16);
1628 if (d->destGfx)
1629 d->destGfx->drawMasked(drawX, drawY + kTileHeight + 16);
1630
1631 if (!_dlvsInfo.animate && inv == _dlvsInfo.selected) {
1632 g_hdb->_gfx->setCursor(centerX - g_hdb->_gfx->stringLength(d->itemTextName) / 2, _dlvItemTextY);
1633 g_hdb->_gfx->drawText(d->itemTextName);
1634 g_hdb->_gfx->setCursor(centerX - (g_hdb->_gfx->stringLength(d->destTextName) + g_hdb->_gfx->stringLength("to ")) / 2, _dlvItemTextY + 12);
1635 g_hdb->_gfx->drawText("to ");
1636 g_hdb->_gfx->drawText(d->destTextName);
1637 }
1638
1639 drawX += _dlvItemSpaceX;
1640 if (drawX >= g_hdb->_screenWidth) {
1641 drawX = baseX;
1642 drawY += _dlvItemSpaceY + 8;
1643 }
1644 }
1645 }
1646
1647 // Draw "No Deliveries" or the arrow that points to the currently selected one
1648 if (!inv) {
1649 g_hdb->_gfx->setCursor(baseX + 16, _dlvsInfo.y);
1650 g_hdb->_gfx->drawText("No Deliveries");
1651 } else if (!_dlvsInfo.animate) {
1652 int dx, dy, rowtwo;
1653
1654 rowtwo = _dlvsInfo.selected > 2;
1655 dx = 8 + _dlvsInfo.x + _dlvItemSpaceX * (_dlvsInfo.selected % 3);
1656 dy = _dlvsInfo.y + kTileHeight + (_dlvItemSpaceY + 8) * rowtwo;
1657 _gfxArrowTo->drawMasked(dx, dy);
1658 }
1659
1660 // If the infobar is dimmed out, this where we dim the whole thing
1661 if (_infobarDimmed) {
1662 for (int j = 0; j < g_hdb->_screenHeight; j += kTileHeight) {
1663 for (int i = (g_hdb->_screenWidth - _gfxInfobar->_width); i < g_hdb->_screenWidth; i += kTileWidth)
1664 _gfxDarken->drawMasked(i, j);
1665 }
1666 }
1667 }
1668 }
1669
setSelectedDelivery(int which)1670 void Window::setSelectedDelivery(int which) {
1671 _dlvsInfo.selected = which;
1672 g_hdb->_sound->playSound(SND_MENU_SLIDER);
1673 }
1674
checkDlvSelect(int x,int y)1675 void Window::checkDlvSelect(int x, int y) {
1676 if (_dlvsInfo.animate)
1677 return;
1678
1679 int amt = g_hdb->_ai->getDeliveriesAmount();
1680
1681 // Click on a Delivery to select it for inspection?
1682 if (x >= _dlvsInfo.x && x < _dlvsInfo.x + _dlvsInfo.width && y >= _dlvsInfo.y && y < _dlvsInfo.y + _dlvsInfo.height) {
1683 int xc = (x - _dlvsInfo.x) / _dlvItemSpaceX;
1684 int yc = (y - _dlvsInfo.y) / _dlvItemSpaceY;
1685 int value = yc * _dlvItemPerLine + xc;
1686 if (value < amt)
1687 setSelectedDelivery(value);
1688 }
1689 }
1690
checkDlvsClose(int x,int y)1691 bool Window::checkDlvsClose(int x, int y) {
1692 if (!g_hdb->isPPC())
1693 return false;
1694
1695 if (_dlvsInfo.animate)
1696 return false;
1697
1698 int amt = g_hdb->_ai->getDeliveriesAmount();
1699
1700 // click on a delivery to select it for inspection?
1701 if (x >= _dlvsInfo.x + 16 && x < _dlvsInfo.x + 16 + amt * _invItemSpace &&
1702 y >= _dlvsInfo.y && y < _dlvsInfo.y + _invItemSpace * 3) {
1703 setSelectedDelivery(((x - _dlvsInfo.x + 16) / _invItemSpace) - 1);
1704 } else if (g_hdb->_ai->getInvAmount() &&
1705 x >= g_hdb->_screenWidth - _gfxHandright->_width &&
1706 y >= _dlvsInfo.y && y < _dlvsInfo.y + _invItemSpace * 3) {
1707 // click on HAND?
1708 closeDlvs();
1709 openInventory();
1710 return true;
1711 } else if (x >= _dlvsInfo.x && x < _dlvsInfo.x + _dlvsInfo.width &&
1712 y >= _dlvsInfo.y && y < _dlvsInfo.y + _dlvsInfo.height) {
1713 // click anywhere else in window to close it?
1714 closeDlvs();
1715 return true;
1716 }
1717
1718 return false;
1719 }
1720
closeDlvs()1721 void Window::closeDlvs() {
1722 if (!g_hdb->isPPC())
1723 return;
1724
1725 if (_dlvsInfo.animate)
1726 return;
1727
1728 g_hdb->_sound->playSound(SND_DIALOG_CLOSE);
1729 _dlvsInfo.active = false;
1730 }
1731
drawTryAgain()1732 void Window::drawTryAgain() {
1733 if (!g_hdb->_ai->playerDead())
1734 return;
1735
1736 if (nullptr == _gfxTry) {
1737 _gfxTry = g_hdb->_gfx->loadPic(GAME_TRY);
1738 _gfxAgain = g_hdb->_gfx->loadPic(GAME_AGAIN);
1739 _gfxLevelRestart = g_hdb->_gfx->loadPic(GAME_TA_LEVELRESTART);
1740
1741 _tryAgainInfo.y1 = _tryY1;
1742 _tryAgainInfo.y2 = _tryY2;
1743 _tryAgainInfo.x1 = g_hdb->_screenDrawWidth / 2 - _gfxTry->_width / 2;
1744 _tryAgainInfo.x2 = g_hdb->_screenDrawWidth / 2 - _gfxAgain->_width / 2;
1745 }
1746
1747 int xv = g_hdb->_rnd->getRandomNumber(3) - 2, yv = g_hdb->_rnd->getRandomNumber(3) - 2;
1748
1749 _gfxTry->drawMasked((int)_tryAgainInfo.x1 + xv, (int)_tryAgainInfo.y1 + yv);
1750 _gfxAgain->drawMasked((int)_tryAgainInfo.x2 + yv, (int)_tryAgainInfo.y2 + xv);
1751 _gfxLevelRestart->drawMasked((int)(g_hdb->_screenDrawWidth / 2 - _gfxLevelRestart->_width / 2 + xv), g_hdb->_window->_tryRestartY + yv);
1752 }
1753
clearTryAgain()1754 void Window::clearTryAgain() {
1755 delete _gfxTry;
1756 delete _gfxAgain;
1757 delete _gfxLevelRestart;
1758
1759 _gfxTry = _gfxAgain = _gfxLevelRestart = nullptr;
1760 }
1761
loadPanicZoneGfx()1762 void Window::loadPanicZoneGfx() {
1763 _pzInfo.gfxPanic = g_hdb->_gfx->loadPic(PANIC_PANIC);
1764 _pzInfo.gfxZone = g_hdb->_gfx->loadPic(PANIC_ZONE);
1765 _pzInfo.gfxFace[0] = g_hdb->_gfx->loadPic(PANIC_POINTER1);
1766 _pzInfo.gfxFace[1] = g_hdb->_gfx->loadPic(PANIC_POINTER2);
1767 _pzInfo.gfxNumber[0] = g_hdb->_gfx->loadPic(PANIC_NUM0);
1768 _pzInfo.gfxNumber[1] = g_hdb->_gfx->loadPic(PANIC_NUM1);
1769 _pzInfo.gfxNumber[2] = g_hdb->_gfx->loadPic(PANIC_NUM2);
1770 _pzInfo.gfxNumber[3] = g_hdb->_gfx->loadPic(PANIC_NUM3);
1771 _pzInfo.gfxNumber[4] = g_hdb->_gfx->loadPic(PANIC_NUM4);
1772 _pzInfo.gfxNumber[5] = g_hdb->_gfx->loadPic(PANIC_NUM5);
1773 _pzInfo.gfxNumber[6] = g_hdb->_gfx->loadPic(PANIC_NUM6);
1774 _pzInfo.gfxNumber[7] = g_hdb->_gfx->loadPic(PANIC_NUM7);
1775 _pzInfo.gfxNumber[8] = g_hdb->_gfx->loadPic(PANIC_NUM8);
1776 _pzInfo.gfxNumber[9] = g_hdb->_gfx->loadPic(PANIC_NUM9);
1777 }
1778
drawPanicZone()1779 void Window::drawPanicZone() {
1780 if (!_pzInfo.active || !g_hdb->isDemo())
1781 return;
1782
1783 switch (_pzInfo.sequence) {
1784 // Wait before displaying PANIC ZONE
1785 case PANICZONE_TIMER:
1786 _pzInfo.timer--;
1787 if (!_pzInfo.timer) {
1788 _pzInfo.sequence++;
1789 g_hdb->_sound->playSound(SND_PANIC);
1790 }
1791 break;
1792
1793 // Move PANIC ZONE to screen center
1794 case PANICZONE_START:
1795 {
1796 int xx = g_hdb->_rnd->getRandomNumber(9) - 5;
1797 int yy = g_hdb->_rnd->getRandomNumber(9) - 5;
1798 _pzInfo.x1 += _pzInfo.xv;
1799 _pzInfo.y1++;
1800 _pzInfo.x2 += _pzInfo.yv;
1801 _pzInfo.y2--;
1802 if (_pzInfo.x1 > _panicXStop) {
1803 _pzInfo.timer = 30;
1804 _pzInfo.sequence++;
1805 }
1806 _pzInfo.gfxPanic->drawMasked(_pzInfo.x1 + xx, _pzInfo.y1 + yy);
1807 _pzInfo.gfxZone->drawMasked(_pzInfo.x2 + yy, _pzInfo.y2 + xx);
1808 }
1809 break;
1810 case PANICZONE_TITLESTOP:
1811 {
1812 int xx = g_hdb->_rnd->getRandomNumber(9) - 5;
1813 int yy = g_hdb->_rnd->getRandomNumber(9) - 5;
1814 _pzInfo.gfxPanic->drawMasked(_pzInfo.x1 + xx, _pzInfo.y1 + yy);
1815 _pzInfo.gfxZone->drawMasked(_pzInfo.x2 + yy, _pzInfo.y2 + xx);
1816 _pzInfo.timer--;
1817 if (!_pzInfo.timer)
1818 _pzInfo.sequence++;
1819 }
1820 break;
1821 case PANICZONE_BLASTOFF:
1822 {
1823 int xx = g_hdb->_rnd->getRandomNumber(9) - 5;
1824 int yy = g_hdb->_rnd->getRandomNumber(9) - 5;
1825 _pzInfo.y1 -= 10;
1826 _pzInfo.y2 += 10;
1827 _pzInfo.gfxPanic->drawMasked(_pzInfo.x1 + xx, _pzInfo.y1 + yy);
1828 _pzInfo.gfxZone->drawMasked(_pzInfo.x2 + yy, _pzInfo.y2 + xx);
1829 if (_pzInfo.y1 < -_pzInfo.gfxPanic->_height &&
1830 _pzInfo.y2 > g_hdb->_screenHeight) {
1831 g_hdb->_sound->playSound(SND_PANIC_COUNT);
1832 _pzInfo.sequence++;
1833 _pzInfo.timer = 30 + g_hdb->getTime();
1834 }
1835 }
1836 break;
1837 case PANICZONE_COUNTDOWN:
1838 {
1839 static int last_seconds = 0, seconds = 0;
1840 _pzInfo.gfxFace[seconds & 1]->drawMasked(_panicZoneFaceX, kPanicZoneFaceY);
1841
1842 // make knocking timer sound
1843 if (last_seconds != seconds)
1844 g_hdb->_sound->playSound(SND_PANIC_COUNT);
1845
1846 last_seconds = seconds;
1847 seconds = _pzInfo.timer - g_hdb->getTime();
1848 if (seconds >= 10) {
1849 _pzInfo.gfxNumber[seconds / 10]->drawMasked(_panicZoneFaceX, kPanicZoneFaceY + 32);
1850 _pzInfo.gfxNumber[seconds % 10]->drawMasked(_panicZoneFaceX + 16, kPanicZoneFaceY + 32);
1851 } else
1852 _pzInfo.gfxNumber[seconds]->drawMasked(_panicZoneFaceX + 8, kPanicZoneFaceY + 32);
1853
1854 // time until death!
1855 if (!seconds) {
1856 // dead
1857 g_hdb->_ai->killPlayer(DEATH_PANICZONE);
1858 _pzInfo.active = false;
1859 return;
1860 }
1861 }
1862 break;
1863 default:
1864 break;
1865 }
1866 }
1867
startPanicZone()1868 void Window::startPanicZone() {
1869 _pzInfo.active = true;
1870 _pzInfo.sequence = PANICZONE_TIMER;
1871
1872 // load PANIC ZONE gfx if they aren't loaded
1873 if (!_pzInfo.gfxPanic)
1874 loadPanicZoneGfx();
1875
1876 _pzInfo.x1 = -(_pzInfo.gfxPanic->_width + 5);
1877 _pzInfo.y1 = (g_hdb->_screenHeight / 4) - (_pzInfo.gfxPanic->_height >> 1);
1878 _pzInfo.x2 = g_hdb->_screenDrawWidth + (_pzInfo.gfxZone->_width >> 1);
1879 _pzInfo.y2 = (g_hdb->_screenHeight / 4) * 3 - (_pzInfo.gfxZone->_height >> 1);
1880 _pzInfo.xv = 10; // horizontal speed
1881 _pzInfo.yv = -12; // vertical speed
1882 _pzInfo.timer = 30; // 30 seconds to get out!
1883 }
1884
stopPanicZone()1885 void Window::stopPanicZone() {
1886 _pzInfo.active = false;
1887 }
1888
textOut(const char * text,int x,int y,int timer)1889 void Window::textOut(const char *text, int x, int y, int timer) {
1890 TOut *t = new TOut;
1891
1892 t->x = x;
1893 t->y = y;
1894 Common::strlcpy(t->text, text, 128);
1895 t->timer = g_system->getMillis() + (uint32)(timer << 4);
1896
1897 if (x < 0) {
1898 int pw, lines;
1899 g_hdb->_gfx->getDimensions(t->text, &pw, &lines);
1900 t->x = _textOutCenterX - pw / 2;
1901 }
1902
1903 _textOutList.push_back(t);
1904 }
1905
centerTextOut(const char * text,int y,int timer)1906 void Window::centerTextOut(const char *text, int y, int timer) {
1907 int width, lines;
1908 g_hdb->_gfx->getDimensions(text, &width, &lines);
1909 textOut(text, _textOutCenterX - ((width - 8) >> 1), y, timer);
1910 }
1911
drawTextOut()1912 void Window::drawTextOut() {
1913 if (_textOutList.empty())
1914 return;
1915
1916 int e1, e2, e3, e4;
1917 g_hdb->_gfx->getTextEdges(&e1, &e2, &e3, &e4);
1918 g_hdb->_gfx->setTextEdges(0, g_hdb->_screenDrawWidth, 0, g_hdb->_screenHeight);
1919
1920 uint32 time = g_system->getMillis();
1921
1922 for (uint i = 0; i < _textOutList.size(); i++) {
1923 TOut *t = _textOutList[i];
1924 g_hdb->_gfx->setCursor(t->x, t->y);
1925 g_hdb->_gfx->drawText(t->text);
1926
1927 if (t->timer < time) {
1928 delete _textOutList[i];
1929 _textOutList.remove_at(i);
1930 i--;
1931 }
1932 }
1933
1934 g_hdb->_gfx->setTextEdges(e1, e2, e3, e4);
1935 }
1936
closeTextOut()1937 void Window::closeTextOut() {
1938 _textOutList.clear();
1939 }
1940 } // End of Namespace
1941