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 /*
24 * This code is based on original Soltys source code
25 * Copyright (c) 1994-1995 Janusz B. Wisniewski and L.K. Avalon
26 */
27
28 #include "cge/general.h"
29 #include "cge/sound.h"
30 #include "cge/snail.h"
31 #include "cge/vga13h.h"
32 #include "cge/text.h"
33 #include "cge/cge_main.h"
34 #include "cge/events.h"
35 #include "cge/walk.h"
36
37 namespace CGE {
38
39 const char *CommandHandler::_commandText[] = {
40 "LABEL", "PAUSE", "WAIT", "LEVEL", "HIDE",
41 "SAY", "INF", "TIME", "CAVE", "KILL",
42 "RSEQ", "SEQ", "SEND", "SWAP", "KEEP",
43 "GIVE", "IF", "GAME", "SETX0", "SETY0",
44 "SLAVE", "SETXY", "RELX", "RELY", "RELZ",
45 "SETX", "SETY", "SETZ", "TRANS", "PORT",
46 "NEXT", "NNEXT", "TNEXT", "RNNEXT", "RTNEXT",
47 "RMNEAR", "RMTAKE", "FLAG", "SETREF", "BACKPT",
48 "FLASH", "LIGHT", "SETHB", "SETVB", "WALK",
49 "REACH", "COVER", "UNCOVER", "CLEAR", "TALK",
50 "MOUSE", "SOUND", "COUNT", NULL
51 };
52
CommandHandler(CGEEngine * vm,bool turbo)53 CommandHandler::CommandHandler(CGEEngine *vm, bool turbo)
54 : _turbo(turbo), _busy(false), _textDelay(false),
55 _timerExpiry(0), _talkEnable(true),
56 _head(0), _tail(0), _commandList((Command *)malloc(sizeof(Command) * 256)), _vm(vm) {
57 }
58
~CommandHandler()59 CommandHandler::~CommandHandler() {
60 free(_commandList);
61 }
62
63 /**
64 * Add a Command on the head of _commandList
65 * @param com Command
66 * @param ref Reference
67 * @param val Value
68 * @param ptr Sprite pointer
69 */
addCommand(CommandType com,int ref,int val,void * ptr)70 void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
71 Command *headCmd = &_commandList[_head++];
72 headCmd->_commandType = com;
73 headCmd->_ref = ref;
74 headCmd->_val = val;
75 headCmd->_spritePtr = ptr;
76 headCmd->_cbType = kNullCB;
77 if (headCmd->_commandType == kCmdClear) {
78 _tail = _head;
79 _vm->killText();
80 _timerExpiry = 0;
81 }
82 }
83
84 /**
85 * Add a Callback on the head of _commandList
86 * @param com Command
87 * @param ref Reference
88 * @param val Value
89 * @param CallbackType Callback type
90 */
addCallback(CommandType com,int ref,int val,CallbackType cbType)91 void CommandHandler::addCallback(CommandType com, int ref, int val, CallbackType cbType) {
92 Command *headCmd = &_commandList[_head++];
93 headCmd->_commandType = com;
94 headCmd->_ref = ref;
95 headCmd->_val = val;
96 headCmd->_spritePtr = NULL;
97 headCmd->_cbType = cbType;
98 if (headCmd->_commandType == kCmdClear) {
99 _tail = _head;
100 _vm->killText();
101 _timerExpiry = 0;
102 }
103 }
104
105 /**
106 * Add a Command on the tail of _commandList
107 * @param com Command
108 * @param ref Reference
109 * @param val Value
110 * @param ptr Sprite pointer
111 */
insertCommand(CommandType com,int ref,int val,void * ptr)112 void CommandHandler::insertCommand(CommandType com, int ref, int val, void *ptr) {
113 Command *tailCmd;
114
115 if (_busy) {
116 _commandList[(_tail - 1) & 0xFF] = _commandList[_tail];
117 tailCmd = &_commandList[_tail];
118 } else
119 tailCmd = &_commandList[(_tail - 1) & 0xFF];
120 _tail--;
121 tailCmd->_commandType = com;
122 tailCmd->_ref = ref;
123 tailCmd->_val = val;
124 tailCmd->_spritePtr = ptr;
125 tailCmd->_cbType = kNullCB;
126 if (tailCmd->_commandType == kCmdClear) {
127 _tail = _head;
128 _vm->killText();
129 _timerExpiry = 0;
130 }
131 }
132
runCommand()133 void CommandHandler::runCommand() {
134 if (_busy)
135 return;
136
137 _busy = true;
138 uint8 tmpHead = _head;
139 while (_tail != tmpHead) {
140 Command *tailCmd = &_commandList[_tail];
141
142 if (!_turbo) { // only for the slower one
143 if (_timerExpiry) {
144 // Delay in progress
145 if (_timerExpiry > g_system->getMillis())
146 // Delay not yet ended
147 break;
148
149 // Delay is finished
150 _timerExpiry = 0;
151 } else {
152 if (_textDelay) {
153 _vm->killText();
154 _textDelay = false;
155 }
156 }
157 if (_vm->_talk && tailCmd->_commandType != kCmdPause)
158 break;
159 }
160
161 Sprite *spr = ((tailCmd->_ref >= 0) ? _vm->locate(tailCmd->_ref) : ((Sprite *) tailCmd->_spritePtr));
162 switch (tailCmd->_commandType) {
163 case kCmdLabel:
164 break;
165 case kCmdPause:
166 _timerExpiry = g_system->getMillis() + tailCmd->_val * kCommandFrameDelay;
167 if (_vm->_talk)
168 _textDelay = true;
169 break;
170 case kCmdWait:
171 if (spr) {
172 if (spr->seqTest(tailCmd->_val) &&
173 (tailCmd->_val >= 0 || spr != _vm->_hero || _vm->_hero->_tracePtr < 0)) {
174 _timerExpiry = g_system->getMillis() + spr->_time * kCommandFrameDelay;
175 } else {
176 _busy = false;
177 return;
178 }
179 }
180 break;
181 case kCmdLevel:
182 _vm->snLevel(spr, tailCmd->_val);
183 break;
184 case kCmdHide:
185 _vm->snHide(spr, tailCmd->_val);
186 break;
187 case kCmdSay:
188 if (spr && _talkEnable) {
189 if (spr == _vm->_hero && spr->seqTest(-1))
190 spr->step(kSeqHTalk);
191 _vm->_text->say(_vm->_text->getText(tailCmd->_val), spr);
192 _vm->_sys->_funDel = kHeroFun0;
193 }
194 break;
195 case kCmdInf:
196 if (_talkEnable) {
197 _vm->inf(_vm->_text->getText(tailCmd->_val), true);
198 _vm->_sys->_funDel = kHeroFun0;
199 }
200 break;
201 case kCmdTime:
202 if (spr && _talkEnable) {
203 if (spr == _vm->_hero && spr->seqTest(-1))
204 spr->step(kSeqHTalk);
205 _vm->_text->sayTime(spr);
206 }
207 break;
208 case kCmdCave:
209 _vm->switchScene(tailCmd->_val);
210 break;
211 case kCmdKill:
212 _vm->snKill(spr);
213 break;
214 case kCmdSeq:
215 _vm->snSeq(spr, tailCmd->_val);
216 break;
217 case kCmdRSeq:
218 _vm->snRSeq(spr, tailCmd->_val);
219 break;
220 case kCmdSend:
221 _vm->snSend(spr, tailCmd->_val);
222 break;
223 case kCmdSwap:
224 _vm->snSwap(spr, tailCmd->_val);
225 break;
226 case kCmdCover:
227 _vm->snCover(spr, tailCmd->_val);
228 break;
229 case kCmdUncover:
230 _vm->snUncover(spr, (tailCmd->_val >= 0) ? _vm->locate(tailCmd->_val) : ((Sprite *) tailCmd->_spritePtr));
231 break;
232 case kCmdKeep:
233 _vm->snKeep(spr, tailCmd->_val);
234 break;
235 case kCmdGive:
236 _vm->snGive(spr, tailCmd->_val);
237 break;
238 case kCmdGame:
239 _vm->snGame(spr, tailCmd->_val);
240 break;
241 case kCmdSetX0:
242 _vm->snSetX0(tailCmd->_ref, tailCmd->_val);
243 break;
244 case kCmdSetY0:
245 _vm->snSetY0(tailCmd->_ref, tailCmd->_val);
246 break;
247 case kCmdSetXY:
248 _vm->snSetXY(spr, tailCmd->_val);
249 break;
250 case kCmdRelX:
251 _vm->snRelX(spr, tailCmd->_val);
252 break;
253 case kCmdRelY:
254 _vm->snRelY(spr, tailCmd->_val);
255 break;
256 case kCmdRelZ:
257 _vm->snRelZ(spr, tailCmd->_val);
258 break;
259 case kCmdSetX:
260 _vm->snSetX(spr, tailCmd->_val);
261 break;
262 case kCmdSetY:
263 _vm->snSetY(spr, tailCmd->_val);
264 break;
265 case kCmdSetZ:
266 _vm->snSetZ(spr, tailCmd->_val);
267 break;
268 case kCmdSlave:
269 _vm->snSlave(spr, tailCmd->_val);
270 break;
271 case kCmdTrans:
272 _vm->snTrans(spr, tailCmd->_val);
273 break;
274 case kCmdPort:
275 _vm->snPort(spr, tailCmd->_val);
276 break;
277 case kCmdNext:
278 case kCmdIf:
279 case kCmdTalk:
280 break;
281 case kCmdMouse:
282 _vm->snMouse(tailCmd->_val != 0);
283 break;
284 case kCmdNNext:
285 _vm->snNNext(spr, tailCmd->_val);
286 break;
287 case kCmdTNext:
288 _vm->snTNext(spr, tailCmd->_val);
289 break;
290 case kCmdRNNext:
291 _vm->snRNNext(spr, tailCmd->_val);
292 break;
293 case kCmdRTNext:
294 _vm->snRTNext(spr, tailCmd->_val);
295 break;
296 case kCmdRMNear:
297 _vm->snRmNear(spr);
298 break;
299 case kCmdRmTake:
300 _vm->snRmTake(spr);
301 break;
302 case kCmdFlag:
303 _vm->snFlag(tailCmd->_ref & 3, tailCmd->_val != 0);
304 break;
305 case kCmdSetRef:
306 _vm->snSetRef(spr, tailCmd->_val);
307 break;
308 case kCmdBackPt:
309 _vm->snBackPt(spr, tailCmd->_val);
310 break;
311 case kCmdFlash:
312 _vm->snFlash(tailCmd->_val != 0);
313 break;
314 case kCmdLight:
315 _vm->snLight(tailCmd->_val != 0);
316 break;
317 case kCmdSetHBarrier:
318 _vm->snHBarrier(tailCmd->_ref, tailCmd->_val);
319 break;
320 case kCmdSetVBarrier:
321 _vm->snVBarrier(tailCmd->_ref, tailCmd->_val);
322 break;
323 case kCmdWalk:
324 _vm->snWalk(spr, tailCmd->_ref, tailCmd->_val);
325 break;
326 case kCmdReach:
327 _vm->snReach(spr, tailCmd->_val);
328 break;
329 case kCmdSound:
330 _vm->snSound(spr, tailCmd->_val);
331 break;
332 case kCmdCount:
333 _vm->_sound->setRepeat(tailCmd->_val);
334 break;
335 case kCmdExec:
336 switch (tailCmd->_cbType) {
337 case kQGame:
338 _vm->qGame();
339 break;
340 case kMiniStep:
341 _vm->miniStep(tailCmd->_val);
342 break;
343 case kXScene:
344 _vm->xScene();
345 break;
346 case kSoundSetVolume:
347 _vm->sndSetVolume();
348 break;
349 default:
350 error("Unknown Callback Type in SNEXEC");
351 }
352 break;
353 case kCmdStep:
354 spr->step();
355 break;
356 case kCmdZTrim:
357 _vm->snZTrim(spr);
358 break;
359 case kCmdGhost:
360 _vm->snGhost((Bitmap *) tailCmd->_spritePtr);
361 break;
362 default:
363 warning("Unhandled snc->_com in SNMouse(bool)");
364 break;
365 }
366 _tail++;
367 if (!_turbo)
368 break;
369 }
370
371 _busy = false;
372 }
373
idle()374 bool CommandHandler::idle() {
375 return (_head == _tail);
376 }
377
reset()378 void CommandHandler::reset() {
379 _tail = _head;
380 }
381
382 /**
383 * Handles mini-Games logic
384 * @param com Command
385 * @param num mini game number
386 */
snGame(Sprite * spr,int num)387 void CGEEngine::snGame(Sprite *spr, int num) {
388 debugC(1, kCGEDebugEngine, "CGEEngine::snGame(spr, %d)", num);
389
390 switch (num) {
391 case 1: {
392 static Sprite *dup[3] = { NULL, NULL, NULL };
393 int buref = 0;
394 int Stage = 0;
395
396 for (dup[0] = _vga->_showQ->first(); dup[0]; dup[0] = dup[0]->_next) {
397 buref = dup[0]->_ref;
398 if (buref / 1000 == 16 && buref % 100 == 6) {
399 Stage = (buref / 100) % 10;
400 break;
401 }
402 }
403 if (dup[1] == NULL) {
404 dup[1] = _vga->_showQ->locate(16003); // pan
405 dup[2] = _vga->_showQ->locate(16004); // pani
406 }
407
408 if (_game) { // continue game
409 int i = newRandom(3), hand = (dup[0]->_shpCnt == 6);
410 Stage++;
411 if (hand && Stage > kDressed)
412 ++hand;
413 if (i >= 0 && (dup[i] == spr && newRandom(3) == 0)) {
414 _commandHandler->addCommand(kCmdSeq, -1, 3, dup[0]); // Yes
415 _commandHandler->addCommand(kCmdSeq, -1, 3, dup[1]); // Yes
416 _commandHandler->addCommand(kCmdSeq, -1, 3, dup[2]); // Yes
417 _commandHandler->addCommand(kCmdTNext, -1, 0, dup[0]); // Reset Take
418 _commandHandler->addCommand(kCmdTNext, -1, 0, dup[1]); // Reset Take
419 _commandHandler->addCommand(kCmdTNext, -1, 0, dup[2]); // Reset Take
420 _commandHandler->addCommand(kCmdNNext, -1, 0, dup[0]); // Reset Near
421 _commandHandler->addCommand(kCmdPause, -1, 72, NULL); // Pause the game for 72/80 second
422 _commandHandler->addCommand(kCmdSay, 1, 16009, NULL); // Say "I win.."
423 _commandHandler->addCommand(kCmdSay, buref, 16010, NULL); // Say "Go Sit..."
424 _commandHandler->addCommand(kCmdSay, 1, 16011, NULL); // Say "I prefer not"
425
426 if (hand) {
427 _commandHandler->addCommand(kCmdSend, 16060 + hand, 16, NULL); // Give hand
428 _commandHandler->addCommand(kCmdSeq, buref, 4, NULL); // Take off
429 _commandHandler->addCommand(kCmdSeq, 16060 + hand, 1, NULL); // start one of the Bartender animations
430 _commandHandler->addCommand(kCmdSound, 16060 + hand, 16002, NULL); // Play tear sound
431 _commandHandler->addCommand(kCmdWait, 16060 + hand, 3, NULL); // Take up
432 _commandHandler->addCommand(kCmdSwap, buref, buref + 100, NULL); // Open hand
433 _commandHandler->addCommand(kCmdSeq, 16016, Stage, NULL); // Start Belongings animation
434 _commandHandler->addCommand(kCmdSend, 16060 + hand, -1, NULL); // Hide hand
435 _commandHandler->addCommand(kCmdWait, 16060 + hand, -1, NULL); // Stop moving hand
436 } else {
437 _commandHandler->addCommand(kCmdSeq, buref, 4, NULL); // Take off
438 _commandHandler->addCommand(kCmdSound, 16060 + hand, 16002, NULL); // Play tear sound
439 _commandHandler->addCommand(kCmdWait, buref, -1, NULL); // Will take off
440 _commandHandler->addCommand(kCmdSwap, buref, buref + 100, NULL); // Open hand
441 _commandHandler->addCommand(kCmdSeq, 16016, Stage, NULL); // Start Belongings animation
442 }
443 _commandHandler->addCommand(kCmdPause, -1, 72, NULL); // Pause the game for 72/80 second
444 _commandHandler->addCommand(kCmdSeq, -1, 0, dup[1]); // Get away (Him)
445 _commandHandler->addCommand(kCmdSetXY, -1, 203 + kScrWidth * 49, dup[1]);
446 _commandHandler->addCommand(kCmdSetZ, -1, 7, dup[1]);
447 _commandHandler->addCommand(kCmdSeq, -1, 0, dup[2]); // Get Away (Her)
448 _commandHandler->addCommand(kCmdSetXY, -1, 182 + kScrWidth * 62, dup[2]);
449 _commandHandler->addCommand(kCmdSetZ, -1, 9, dup[2]);
450 _game = false;
451 return;
452 } else {
453 _commandHandler->addCommand(kCmdSeq, -1, 2, dup[0]); // reset animation sequence
454 _commandHandler->addCommand(kCmdSeq, -1, 2, dup[1]); // reset animation sequence
455 _commandHandler->addCommand(kCmdSeq, -1, 2, dup[2]); // reset animation sequence
456 _commandHandler->addCommand(kCmdPause, -1, 72, NULL); // Pause the game for 72/80 second
457 }
458 }
459 _commandHandler->addCommand(kCmdWalk, 198, 134, NULL); // Go to place
460 _commandHandler->addCommand(kCmdWait, 1, -1, NULL); // Stop moving
461 _commandHandler->addCommand(kCmdCover, 1, 16101, NULL); // Man to beat
462 _commandHandler->addCommand(kCmdSeq, 16101, 1, NULL); // Start Chief animation (16dupnia)
463 _commandHandler->addCommand(kCmdWait, 16101, 5, NULL); // wait
464 _commandHandler->addCommand(kCmdPause, 16101, 24, NULL); // Pause the game for 24/80 second
465 _commandHandler->addCommand(kCmdSeq, 16040, 1, NULL); // Start Slap animation (16plask)
466 _commandHandler->addCommand(kCmdSound, 16101, 16001, NULL); // Play "Slap" sound
467 _commandHandler->addCommand(kCmdPause, 16101, 24, NULL); // Pause the game for 24/80 second
468 _commandHandler->addCommand(kCmdSeq, 16040, 0, NULL); // Reset animation sequence
469 _commandHandler->addCommand(kCmdWait, 16101, -1, NULL); // stay
470 _commandHandler->addCommand(kCmdUncover, 1, 16101, NULL); // SDS
471 if (!_game) {
472 _commandHandler->addCommand(kCmdSay, buref, 16008, NULL); // say "Guess!"
473 _game = true;
474 }
475 }
476 break;
477 case 2:
478 if (_sprTv == NULL) {
479 _sprTv = _vga->_showQ->locate(20700);
480 _sprK1 = _vga->_showQ->locate(20701);
481 _sprK2 = _vga->_showQ->locate(20702);
482 _sprK3 = _vga->_showQ->locate(20703);
483 }
484
485 if (!_game) { // init
486 _commandHandler->addCommand(kCmdGame, 20002, 2, NULL);
487 _game = true;
488 break;
489 }
490
491 // cont
492 _sprK1->step(newRandom(6));
493 _sprK2->step(newRandom(6));
494 _sprK3->step(newRandom(6));
495
496 // check the ALT key as it's the solution of the puzzle
497 // the test has been restricted to some specific OSes
498 // in order to avoid some obvious issues (like Android, iOS, NDS, N64...)
499 // Not perfect, but at least better than nothing.
500 #if defined(WIN32) || defined(UNIX) || defined(MACOSX)
501 if (spr->_ref == 1 && _keyboard->_keyAlt) {
502 #else
503 if (spr->_ref == 1 && _gameCase2Cpt > 1) {
504 #endif
505 _sprK1->step(5);
506 _sprK2->step(5);
507 _sprK3->step(5);
508 }
509
510 _commandHandler->addCommand(kCmdSetZ, 20700, 0, NULL);
511 {
512 bool hit = (_sprK1->_seqPtr + _sprK2->_seqPtr + _sprK3->_seqPtr == 15);
513 if (hit) {
514 if (spr->_ref == 1) {
515 _commandHandler->addCommand(kCmdSay, 1, 20003, NULL); // hurray!
516 _commandHandler->addCommand(kCmdSeq, 20011, 2, NULL); // Camera away
517 _commandHandler->addCommand(kCmdSend, 20701, -1, NULL); // move dice1 to scene -1
518 _commandHandler->addCommand(kCmdSend, 20702, -1, NULL); // move dice2 to scene -1
519 _commandHandler->addCommand(kCmdSend, 20703, -1, NULL); // move dice3 to scene -1
520 _commandHandler->addCommand(kCmdSend, 20700, -1, NULL); // move TV to scene -1
521 _commandHandler->addCommand(kCmdKeep, 20007, 0, NULL); // to pocket
522 _commandHandler->addCommand(kCmdSend, 20006, 20, NULL); // Move Coin to scene 20
523 _commandHandler->addCommand(kCmdSound, 20006, 20002, NULL); // Play Coin sound
524 _commandHandler->addCommand(kCmdSay, 20002, 20004, NULL); // Say "Luck guy..."
525 _commandHandler->addCommand(kCmdSend, 20010, 20, NULL); // Move Paper to scene 20
526 _commandHandler->addCommand(kCmdSound, 20010, 20003, NULL); // Play "ksh" sound! (fx20003.wav)
527 _commandHandler->addCommand(kCmdSay, 20001, 20005, NULL); // Say "Congratulations"
528 _game = false;
529 return;
530 } else {
531 _sprK3->step(newRandom(5));
532 }
533 }
534 }
535
536 if (_gameCase2Cpt < 100) {
537 switch (_gameCase2Cpt) {
538 case 15:
539 // Give hint about ALTered dice
540 _commandHandler->addCommand(kCmdSay, 20003, 20021, NULL);
541 break;
542 case 30:
543 case 45:
544 case 60:
545 case 75:
546 // Tell to use ALT key
547 _commandHandler->addCommand(kCmdSay, 20003, 20022, NULL);
548 break;
549 default:
550 break;
551 }
552 _gameCase2Cpt++;
553 }
554
555 switch (spr->_ref) {
556 case 1:
557 _commandHandler->addCommand(kCmdSay, 20001, 20011, NULL); // Say "It'a my turn"
558 _commandHandler->addCommand(kCmdSeq, 20001, 1, NULL); // Throw dice
559 _commandHandler->addCommand(kCmdWait, 20001, 1, NULL); // wait
560 _commandHandler->addCommand(kCmdSetZ, 20700, 2, NULL); // hide dice
561 _commandHandler->addCommand(kCmdHide, 20007, 1, NULL); // hide dice
562 _commandHandler->addCommand(kCmdWait, 20001, 16, NULL); // wait
563 _commandHandler->addCommand(kCmdSeq, 20007, 1, NULL); // Start dice animation (20kosci)
564 _commandHandler->addCommand(kCmdHide, 20007, 0, NULL); // unhide
565 _commandHandler->addCommand(kCmdSound, 20007, 20001, NULL); // Play Dice sound
566 _commandHandler->addCommand(kCmdWait, 20007, -1, NULL); // the end
567 _commandHandler->addCommand(kCmdGame, 20001, 2, NULL); // again!
568 break;
569
570 case 20001:
571 _commandHandler->addCommand(kCmdSay, 20002, 20012, NULL); // Say "Now it's mine"
572 _commandHandler->addCommand(kCmdSeq, 20002, 1, NULL); // Throw dice
573 _commandHandler->addCommand(kCmdWait, 20002, 3, NULL); // wait
574 _commandHandler->addCommand(kCmdSetZ, 20700, 2, NULL); // hide dice
575 _commandHandler->addCommand(kCmdHide, 20007, 1, NULL); // hide dice
576 _commandHandler->addCommand(kCmdWait, 20002, 10, NULL); // wait
577 _commandHandler->addCommand(kCmdSeq, 20007, 2, NULL); // Start dice animation (20kosci)
578 _commandHandler->addCommand(kCmdHide, 20007, 0, NULL); // unhide
579 _commandHandler->addCommand(kCmdSound, 20007, 20001, NULL); // Play Dice sound
580 _commandHandler->addCommand(kCmdWait, 20007, -1, NULL); // the end
581 _commandHandler->addCommand(kCmdGame, 20002, 2, NULL); // again!
582 break;
583
584 case 20002:
585 _commandHandler->addCommand(kCmdSay, 20002, 20010, NULL); // "Roll the bones!"
586 _commandHandler->addCommand(kCmdWalk, 20005, -1, NULL); // Walk to table
587 _commandHandler->addCommand(kCmdWait, 1, -1, NULL); // Wait
588 _commandHandler->addCommand(kCmdCover, 1, 20101, NULL); // grasol ??
589 _commandHandler->addCommand(kCmdSeq, 20101, 1, NULL); // Start Chief animation (20solgra)
590 _commandHandler->addCommand(kCmdWait, 20101, 5, NULL); // Wait
591 _commandHandler->addCommand(kCmdSetZ, 20700, 2, NULL); // Hide dice
592 _commandHandler->addCommand(kCmdHide, 20007, 1, NULL); // Hide dice
593 _commandHandler->addCommand(kCmdWait, 20101, 15, NULL); // wait
594 _commandHandler->addCommand(kCmdSeq, 20007, 1, NULL); // Start dice animation (20kosci)
595 _commandHandler->addCommand(kCmdHide, 20007, 0, NULL); // Unhide
596 _commandHandler->addCommand(kCmdSound, 20007, 20001, NULL); // Play Dice sound
597 _commandHandler->addCommand(kCmdWait, 20101, -1, NULL); // the end
598 _commandHandler->addCommand(kCmdUncover, 1, 20101, NULL); // SDS ??
599 _commandHandler->addCommand(kCmdGame, 1, 2, NULL); // again!
600 break;
601
602 default:
603 break;
604 }
605
606 default:
607 break;
608 }
609 }
610
611 void CGEEngine::expandSprite(Sprite *spr) {
612 debugC(5, kCGEDebugEngine, "CGEEngine::expandSprite(spr)");
613
614 if (spr)
615 _vga->_showQ->insert(_vga->_spareQ->remove(spr));
616 }
617
618 void CGEEngine::contractSprite(Sprite *spr) {
619 debugC(1, kCGEDebugEngine, "CGEEngine::contractSprite(spr)");
620
621 if (spr)
622 _vga->_spareQ->append(_vga->_showQ->remove(spr));
623 }
624
625 /**
626 * Check if an item is in the inventory, and returns its position
627 * @param spr Sprite pointer
628 * @return -1 if not found, else index.
629 */
630 int CGEEngine::findPocket(Sprite *spr) {
631 debugC(1, kCGEDebugEngine, "CGEEngine::findPocket(spr)");
632
633 for (int i = 0; i < kPocketNX; i++)
634 if (_pocket[i] == spr)
635 return i;
636 return -1;
637 }
638
639 /**
640 * Check if an item is in the inventory, and returns its position
641 * @param Inventory slot number Sprite pointer
642 */
643 void CGEEngine::selectPocket(int n) {
644 debugC(1, kCGEDebugEngine, "CGEEngine::selectPocket(%d)", n);
645
646 if (n < 0 || (_pocLight->_seqPtr && _pocPtr == n)) {
647 // If no slot specified, or another slot already selected
648 // stop the blinking animation
649 _pocLight->step(0);
650 n = findPocket(NULL);
651 if (n >= 0)
652 _pocPtr = n;
653 } else {
654 // If slot specified, check if the slot if used.
655 // Is so, start the blinking animation
656 if (_pocket[n] != NULL) {
657 _pocPtr = n;
658 _pocLight->step(1);
659 }
660 }
661 _pocLight->gotoxy(kPocketX + _pocPtr * kPocketDX + kPocketSX, kPocketY + kPocketSY);
662 }
663
664 /**
665 * Logic used when all the inventory slots are full and the user tries to pick
666 * another object.
667 * @param Inventory slot number Sprite pointer
668 */
669 void CGEEngine::pocFul() {
670 debugC(1, kCGEDebugEngine, "CGEEngine::pocFul()");
671
672 if (!_hero)
673 error("pocFul - Unexpected null _hero");
674
675 _hero->park();
676 _commandHandler->addCommand(kCmdWait, -1, -1, _hero);
677 _commandHandler->addCommand(kCmdSeq, -1, kSeqPocketFull, _hero);
678 _commandHandler->addCommand(kCmdSound, -1, 2, _hero); // Play the 'hum-hum" sound (fx00002)
679 _commandHandler->addCommand(kCmdWait, -1, -1, _hero);
680 _commandHandler->addCommand(kCmdSay, 1, kPocketFull, _hero);
681 }
682
683 void CGEEngine::hide1(Sprite *spr) {
684 debugC(1, kCGEDebugEngine, "CGEEngine::hide1(spr)");
685
686 _commandHandlerTurbo->addCommand(kCmdGhost, -1, 0, spr->ghost());
687 }
688
689 void CGEEngine::snGhost(Bitmap *bmp) {
690 debugC(1, kCGEDebugEngine, "CGEEngine::snGhost(bmp)");
691
692 bmp->hide(bmp->_map & 0xFFFF, bmp->_map >> 16);
693 bmp->_m = NULL;
694 bmp->_map = 0;
695 delete bmp;
696 }
697
698 void CGEEngine::feedSnail(Sprite *spr, SnList snq) {
699 debugC(1, kCGEDebugEngine, "CGEEngine::feedSnail(spr, snq)");
700
701 if (!spr || !spr->active())
702 return;
703
704 uint8 ptr = (snq == kTake) ? spr->_takePtr : spr->_nearPtr;
705
706 if (ptr == kNoPtr)
707 return;
708
709 CommandHandler::Command *comtab = spr->snList(snq);
710 CommandHandler::Command *c = comtab + ptr;
711
712 if (findPocket(NULL) < 0) { // no empty pockets?
713 CommandHandler::Command *p;
714 for (p = c; p->_commandType != kCmdNext; p++) { // find KEEP command
715 if (p->_commandType == kCmdKeep) {
716 pocFul();
717 return;
718 }
719 if (p->_spritePtr)
720 break;
721 }
722 }
723 while (true) {
724 if (c->_commandType == kCmdTalk) {
725 if ((_commandHandler->_talkEnable = (c->_val != 0)) == false)
726 killText();
727 }
728 if (c->_commandType == kCmdNext) {
729 Sprite *s = (c->_ref < 0) ? spr : locate(c->_ref);
730 if (s) {
731 uint8 *idx = (snq == kTake) ? &s->_takePtr : &s->_nearPtr;
732 if (*idx != kNoPtr) {
733 int v;
734 switch (c->_val) {
735 case -1 :
736 v = c - comtab + 1;
737 break;
738 case -2 :
739 v = c - comtab;
740 break;
741 case -3 :
742 v = -1;
743 break;
744 default :
745 v = c->_val;
746 break;
747 }
748 if (v >= 0)
749 *idx = v;
750 }
751 }
752 if (s == spr)
753 break;
754 }
755 if (c->_commandType == kCmdIf) {
756 Sprite *s = (c->_ref < 0) ? spr : locate(c->_ref);
757 if (s) { // sprite extsts
758 if (! s->seqTest(-1))
759 c = comtab + c->_val; // not parked
760 else
761 ++c;
762 } else
763 ++c;
764 } else {
765 _commandHandler->addCommand(c->_commandType, c->_ref, c->_val, spr);
766 if (c->_spritePtr)
767 break;
768 else
769 c++;
770 }
771 }
772 }
773
774 void CGEEngine::snNNext(Sprite *spr, int p) {
775 debugC(1, kCGEDebugEngine, "CGEEngine::snNNext(spr, %d)", p);
776
777 if (spr)
778 if (spr->_nearPtr != kNoPtr)
779 spr->_nearPtr = p;
780 }
781
782 void CGEEngine::snTNext(Sprite *spr, int p) {
783 debugC(1, kCGEDebugEngine, "CGEEngine::snTNext(spr, %d)", p);
784
785 if (spr)
786 if (spr->_takePtr != kNoPtr)
787 spr->_takePtr = p;
788 }
789
790 void CGEEngine::snRNNext(Sprite *spr, int p) {
791 debugC(1, kCGEDebugEngine, "CGEEngine::snRNNext(spr, %d)", p);
792
793 if (spr)
794 if (spr->_nearPtr != kNoPtr)
795 spr->_nearPtr += p;
796 }
797
798
799 void CGEEngine::snRTNext(Sprite *spr, int p) {
800 debugC(1, kCGEDebugEngine, "CGEEngine::snRTNext(spr, %d)", p);
801
802 if (spr)
803 if (spr->_takePtr != kNoPtr)
804 spr->_takePtr += p;
805 }
806
807 void CGEEngine::snZTrim(Sprite *spr) {
808 debugC(4, kCGEDebugEngine, "CGEEngine::snZTrim(spr)");
809
810 if (!spr || !spr->active())
811 return;
812
813 Sprite *s = (spr->_flags._shad) ? spr->_prev : NULL;
814 _vga->_showQ->insert(_vga->_showQ->remove(spr));
815 if (s) {
816 s->_z = spr->_z;
817 _vga->_showQ->insert(_vga->_showQ->remove(s), spr);
818 }
819 }
820
821 void CGEEngine::snHide(Sprite *spr, int val) {
822 debugC(1, kCGEDebugEngine, "CGEEngine::snHide(spr, %d)", val);
823
824 if (spr) {
825 spr->_flags._hide = (val >= 0) ? (val != 0) : (!spr->_flags._hide);
826 if (spr->_flags._shad)
827 spr->_prev->_flags._hide = spr->_flags._hide;
828 }
829 }
830
831 void CGEEngine::snRmNear(Sprite *spr) {
832 debugC(1, kCGEDebugEngine, "CGEEngine::snRmNear(spr)");
833
834 if (spr)
835 spr->_nearPtr = kNoPtr;
836 }
837
838 void CGEEngine::snRmTake(Sprite *spr) {
839 debugC(1, kCGEDebugEngine, "CGEEngine::snRmTake(spr)");
840
841 if (spr)
842 spr->_takePtr = kNoPtr;
843 }
844
845 void CGEEngine::snSeq(Sprite *spr, int val) {
846 debugC(1, kCGEDebugEngine, "CGEEngine::snSeq(spr, %d)", val);
847
848 if (spr) {
849 if (spr == _hero && val == 0)
850 _hero->park();
851 else
852 spr->step(val);
853 }
854 }
855
856 void CGEEngine::snRSeq(Sprite *spr, int val) {
857 debugC(1, kCGEDebugEngine, "CGEEngine::snRSeq(spr, %d)", val);
858
859 if (spr)
860 snSeq(spr, spr->_seqPtr + val);
861 }
862
863 void CGEEngine::snSend(Sprite *spr, int val) {
864 debugC(1, kCGEDebugEngine, "CGEEngine::snSend(spr, %d)", val);
865
866 if (!spr)
867 return;
868
869 int was = spr->_scene;
870 bool was1 = (was == 0 || was == _now);
871 bool val1 = (val == 0 || val == _now);
872 spr->_scene = val;
873 if (val1 != was1) {
874 if (was1) {
875 if (spr->_flags._kept) {
876 int n = findPocket(spr);
877 if (n >= 0)
878 _pocket[n] = NULL;
879 }
880 hide1(spr);
881 contractSprite(spr);
882 spr->_flags._slav = false;
883 } else {
884 if (spr->_ref % 1000 == 0)
885 _bitmapPalette = _vga->_sysPal;
886 if (spr->_flags._back)
887 spr->backShow(true);
888 else
889 expandSprite(spr);
890 _bitmapPalette = NULL;
891 }
892 }
893 }
894
895 void CGEEngine::snSwap(Sprite *spr, int xref) {
896 debugC(1, kCGEDebugEngine, "CGEEngine::snSwap(spr, %d)", xref);
897
898 Sprite *xspr = locate(xref);
899 if (!spr || !xspr)
900 return;
901
902 int was = spr->_scene;
903 int xwas = xspr->_scene;
904 bool was1 = (was == 0 || was == _now);
905 bool xwas1 = (xwas == 0 || xwas == _now);
906
907 SWAP(spr->_scene, xspr->_scene);
908 SWAP(spr->_x, xspr->_x);
909 SWAP(spr->_y, xspr->_y);
910 SWAP(spr->_z, xspr->_z);
911 if (spr->_flags._kept) {
912 int n = findPocket(spr);
913 if (n >= 0)
914 _pocket[n] = xspr;
915 xspr->_flags._kept = true;
916 xspr->_flags._port = false;
917 }
918 if (xwas1 != was1) {
919 if (was1) {
920 hide1(spr);
921 contractSprite(spr);
922 } else
923 expandSprite(spr);
924 if (xwas1) {
925 hide1(xspr);
926 contractSprite(xspr);
927 } else
928 expandSprite(xspr);
929 }
930 }
931
932 void CGEEngine::snCover(Sprite *spr, int xref) {
933 debugC(1, kCGEDebugEngine, "CGEEngine::snCover(spr, %d)", xref);
934
935 Sprite *xspr = locate(xref);
936 if (!spr || !xspr)
937 return;
938
939 spr->_flags._hide = true;
940 xspr->_z = spr->_z;
941 xspr->_scene = spr->_scene;
942 xspr->gotoxy(spr->_x, spr->_y);
943 expandSprite(xspr);
944 if ((xspr->_flags._shad = spr->_flags._shad) == 1) {
945 _vga->_showQ->insert(_vga->_showQ->remove(spr->_prev), xspr);
946 spr->_flags._shad = false;
947 }
948 feedSnail(xspr, kNear);
949 }
950
951 void CGEEngine::snUncover(Sprite *spr, Sprite *xspr) {
952 debugC(1, kCGEDebugEngine, "CGEEngine::snUncover(spr, xspr)");
953
954 if (!spr || !xspr)
955 return;
956
957 spr->_flags._hide = false;
958 spr->_scene = xspr->_scene;
959 spr->gotoxy(xspr->_x, xspr->_y);
960 if ((spr->_flags._shad = xspr->_flags._shad) == 1) {
961 _vga->_showQ->insert(_vga->_showQ->remove(xspr->_prev), spr);
962 xspr->_flags._shad = false;
963 }
964 spr->_z = xspr->_z;
965 snSend(xspr, -1);
966 if (spr->_time == 0)
967 spr->_time++;
968 }
969
970 void CGEEngine::snSetX0(int scene, int x0) {
971 debugC(1, kCGEDebugEngine, "CGEEngine::snSetX0(%d, %d)", scene, x0);
972
973 _heroXY[scene - 1].x = x0;
974 }
975
976 void CGEEngine::snSetY0(int scene, int y0) {
977 debugC(1, kCGEDebugEngine, "CGEEngine::snSetY0(%d, %d)", scene, y0);
978
979 _heroXY[scene - 1].y = y0;
980 }
981
982 void CGEEngine::snSetXY(Sprite *spr, uint16 xy) {
983 debugC(1, kCGEDebugEngine, "CGEEngine::snSetXY(spr, %d)", xy);
984
985 if (spr)
986 spr->gotoxy(xy % kScrWidth, xy / kScrWidth);
987 }
988
989 void CGEEngine::snRelX(Sprite *spr, int x) {
990 debugC(1, kCGEDebugEngine, "CGEEngine::snRelX(spr, %d)", x);
991
992 if (spr && _hero)
993 spr->gotoxy(_hero->_x + x, spr->_y);
994 }
995
996 void CGEEngine::snRelY(Sprite *spr, int y) {
997 debugC(1, kCGEDebugEngine, "CGEEngine::snRelY(spr, %d)", y);
998
999 if (spr && _hero)
1000 spr->gotoxy(spr->_x, _hero->_y + y);
1001 }
1002
1003 void CGEEngine::snRelZ(Sprite *spr, int z) {
1004 debugC(1, kCGEDebugEngine, "CGEEngine::snRelZ(spr, %d)", z);
1005
1006 if (spr && _hero) {
1007 spr->_z = _hero->_z + z;
1008 snZTrim(spr);
1009 }
1010 }
1011
1012 void CGEEngine::snSetX(Sprite *spr, int x) {
1013 debugC(1, kCGEDebugEngine, "CGEEngine::snSetX(spr, %d)", x);
1014
1015 if (spr)
1016 spr->gotoxy(x, spr->_y);
1017 }
1018
1019 void CGEEngine::snSetY(Sprite *spr, int y) {
1020 debugC(1, kCGEDebugEngine, "CGEEngine::snSetY(spr, %d)", y);
1021
1022 if (spr)
1023 spr->gotoxy(spr->_x, y);
1024 }
1025
1026 void CGEEngine::snSetZ(Sprite *spr, int z) {
1027 debugC(1, kCGEDebugEngine, "CGEEngine::snSetZ(spr, %d)", z);
1028
1029 if (spr) {
1030 spr->_z = z;
1031 snZTrim(spr);
1032 }
1033 }
1034
1035 void CGEEngine::snSlave(Sprite *spr, int ref) {
1036 debugC(1, kCGEDebugEngine, "CGEEngine::snSlave(spr, %d)", ref);
1037
1038 Sprite *slv = locate(ref);
1039 if (spr && slv) {
1040 if (spr->active()) {
1041 snSend(slv, spr->_scene);
1042 slv->_flags._slav = true;
1043 slv->_z = spr->_z;
1044 _vga->_showQ->insert(_vga->_showQ->remove(slv), spr->_next);
1045 }
1046 }
1047 }
1048
1049 void CGEEngine::snTrans(Sprite *spr, int trans) {
1050 debugC(1, kCGEDebugEngine, "CGEEngine::snTrans(spr, %d)", trans);
1051
1052 if (spr)
1053 spr->_flags._tran = (trans < 0) ? !spr->_flags._tran : (trans != 0);
1054 }
1055
1056 void CGEEngine::snPort(Sprite *spr, int port) {
1057 debugC(1, kCGEDebugEngine, "CGEEngine::snPort(spr, %d)", port);
1058
1059 if (spr)
1060 spr->_flags._port = (port < 0) ? !spr->_flags._port : (port != 0);
1061 }
1062
1063 void CGEEngine::snKill(Sprite *spr) {
1064 debugC(1, kCGEDebugEngine, "CGEEngine::snKill(spr)");
1065
1066 if (!spr)
1067 return;
1068
1069 if (spr->_flags._kept) {
1070 int n = findPocket(spr);
1071 if (n >= 0)
1072 _pocket[n] = NULL;
1073 }
1074 Sprite *nx = spr->_next;
1075 hide1(spr);
1076 _vga->_showQ->remove(spr);
1077 _eventManager->clearEvent(spr);
1078 if (spr->_flags._kill) {
1079 delete spr;
1080 } else {
1081 spr->_scene = -1;
1082 _vga->_spareQ->append(spr);
1083 }
1084 if (nx) {
1085 if (nx->_flags._slav)
1086 snKill(nx);
1087 }
1088 }
1089
1090 /**
1091 * Play a FX sound
1092 * @param spr Sprite pointer
1093 * @param wav FX index
1094 */
1095 void CGEEngine::snSound(Sprite *spr, int wav) {
1096 debugC(1, kCGEDebugEngine, "CGEEngine::snSound(spr, %d)", wav);
1097
1098 if (wav == -1)
1099 _sound->stop();
1100 else
1101 _sound->play((*_fx)[wav], (spr) ? ((spr->_x + spr->_w / 2) / (kScrWidth / 16)) : 8);
1102
1103 _sound->setRepeat(1);
1104 }
1105
1106 void CGEEngine::snKeep(Sprite *spr, int stp) {
1107 debugC(1, kCGEDebugEngine, "CGEEngine::snKeep(spr, %d)", stp);
1108
1109 selectPocket(-1);
1110 if (spr && ! spr->_flags._kept && _pocket[_pocPtr] == NULL) {
1111 int16 oldRepeat = _sound->getRepeat();
1112 _sound->setRepeat(1);
1113 snSound(spr, 3);
1114 _sound->setRepeat(oldRepeat);
1115 _pocket[_pocPtr] = spr;
1116 spr->_scene = 0;
1117 spr->_flags._kept = true;
1118 spr->gotoxy(kPocketX + kPocketDX * _pocPtr + kPocketDX / 2 - spr->_w / 2,
1119 kPocketY + kPocketDY / 2 - spr->_h / 2);
1120 if (stp >= 0)
1121 spr->step(stp);
1122 }
1123 selectPocket(-1);
1124 }
1125
1126 /**
1127 * Remove an object from the inventory and (if specified) trigger an animation
1128 * @param spr Inventory item
1129 * @param stp Animation
1130 */
1131 void CGEEngine::snGive(Sprite *spr, int stp) {
1132 debugC(1, kCGEDebugEngine, "CGEEngine::snGive(spr, %d)", stp);
1133
1134 if (spr) {
1135 int p = findPocket(spr);
1136 if (p >= 0) {
1137 _pocket[p] = NULL;
1138 spr->_scene = _now;
1139 spr->_flags._kept = false;
1140 if (stp >= 0)
1141 spr->step(stp);
1142 }
1143 }
1144 selectPocket(-1);
1145 }
1146
1147 void CGEEngine::snBackPt(Sprite *spr, int stp) {
1148 debugC(1, kCGEDebugEngine, "CGEEngine::snBackPt(spr, %d)", stp);
1149
1150 if (spr) {
1151 if (stp >= 0)
1152 spr->step(stp);
1153 spr->backShow(true);
1154 }
1155 }
1156
1157 void CGEEngine::snLevel(Sprite *spr, int lev) {
1158 debugC(1, kCGEDebugEngine, "CGEEngine::snLevel(spr, %d)", lev);
1159
1160 assert((lev >= 0) && (lev < 5));
1161
1162 for (int i = 0; i < 5; i++) {
1163 spr = _vga->_spareQ->locate(100 + i);
1164 if (spr) {
1165 if (i <= lev) {
1166 spr->backShow(true);
1167 spr->_scene = 0;
1168 spr->_flags._hide = false;
1169 } else {
1170 spr->_flags._hide = true;
1171 spr->_scene = -1;
1172 }
1173 } else {
1174 warning("SPR not found! ref: %d", 100 + i);
1175 }
1176 }
1177
1178 _lev = lev;
1179 _maxScene = _maxSceneArr[_lev];
1180 }
1181
1182 /**
1183 * Set a flag to a value
1184 * @param indx Flag index
1185 * @param val Flag value
1186 */
1187 void CGEEngine::snFlag(int indx, bool val) {
1188 _flag[indx] = val;
1189 }
1190
1191 void CGEEngine::snSetRef(Sprite *spr, int nr) {
1192 debugC(1, kCGEDebugEngine, "CGEEngine::snSetRef(spr, %d)", nr);
1193
1194 if (spr)
1195 spr->_ref = nr;
1196 }
1197
1198 void CGEEngine::snFlash(bool on) {
1199 debugC(1, kCGEDebugEngine, "CGEEngine::snFlash(%s)", on ? "true" : "false");
1200
1201 if (on) {
1202 Dac *pal = (Dac *)malloc(sizeof(Dac) * kPalCount);
1203 if (pal) {
1204 memcpy(pal, _vga->_sysPal, kPalSize);
1205 for (int i = 0; i < kPalCount; i++) {
1206 int c;
1207 c = pal[i]._r << 1;
1208 pal[i]._r = (c < 64) ? c : 63;
1209 c = pal[i]._g << 1;
1210 pal[i]._g = (c < 64) ? c : 63;
1211 c = pal[i]._b << 1;
1212 pal[i]._b = (c < 64) ? c : 63;
1213 }
1214 _vga->setColors(pal, 64);
1215 }
1216
1217 free(pal);
1218 } else
1219 _vga->setColors(_vga->_sysPal, 64);
1220 _dark = false;
1221 }
1222
1223 void CGEEngine::snLight(bool in) {
1224 debugC(1, kCGEDebugEngine, "CGEEngine::snLight(%s)", in ? "true" : "false");
1225
1226 if (in)
1227 _vga->sunrise(_vga->_sysPal);
1228 else
1229 _vga->sunset();
1230 _dark = !in;
1231 }
1232
1233 /**
1234 * Set an horizontal boundary
1235 * @param scene Scene number
1236 * @param barX Horizontal boundary value
1237 */
1238 void CGEEngine::snHBarrier(const int scene, const int barX) {
1239 debugC(1, kCGEDebugEngine, "CGEEngine::snHBarrier(%d, %d)", scene, barX);
1240
1241 _barriers[(scene > 0) ? scene : _now]._horz = barX;
1242 }
1243
1244 /**
1245 * Set a vertical boundary
1246 * @param scene Scene number
1247 * @param barY Vertical boundary value
1248 */
1249 void CGEEngine::snVBarrier(const int scene, const int barY) {
1250 debugC(1, kCGEDebugEngine, "CGEEngine::snVBarrier(%d, %d)", scene, barY);
1251
1252 _barriers[(scene > 0) ? scene : _now]._vert = barY;
1253 }
1254
1255 void CGEEngine::snWalk(Sprite *spr, int x, int y) {
1256 debugC(1, kCGEDebugEngine, "CGEEngine::snWalk(spr, %d, %d)", x, y);
1257
1258 if (_hero) {
1259 if (spr && y < 0)
1260 _hero->findWay(spr);
1261 else
1262 _hero->findWay(XZ(x, y));
1263 }
1264 }
1265
1266 void CGEEngine::snReach(Sprite *spr, int mode) {
1267 debugC(1, kCGEDebugEngine, "CGEEngine::snReach(spr, %d)", mode);
1268
1269 if (_hero)
1270 _hero->reach(spr, mode);
1271 }
1272
1273 void CGEEngine::snMouse(bool on) {
1274 debugC(1, kCGEDebugEngine, "CGEEngine::snMouse(%s)", on ? "true" : "false");
1275
1276 if (on)
1277 _mouse->on();
1278 else
1279 _mouse->off();
1280 }
1281
1282 } // End of namespace CGE
1283