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 Janus 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) || defined(MOTOEZX) || defined(LINUXMOTO_SDL)
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 bool hit = (_sprK1->_seqPtr + _sprK2->_seqPtr + _sprK3->_seqPtr == 15);
512 if (hit) {
513 if (spr->_ref == 1) {
514 _commandHandler->addCommand(kCmdSay, 1, 20003, NULL); // hurray!
515 _commandHandler->addCommand(kCmdSeq, 20011, 2, NULL); // Camera away
516 _commandHandler->addCommand(kCmdSend, 20701, -1, NULL); // move dice1 to scene -1
517 _commandHandler->addCommand(kCmdSend, 20702, -1, NULL); // move dice2 to scene -1
518 _commandHandler->addCommand(kCmdSend, 20703, -1, NULL); // move dice3 to scene -1
519 _commandHandler->addCommand(kCmdSend, 20700, -1, NULL); // move TV to scene -1
520 _commandHandler->addCommand(kCmdKeep, 20007, 0, NULL); // to pocket
521 _commandHandler->addCommand(kCmdSend, 20006, 20, NULL); // Move Coin to scene 20
522 _commandHandler->addCommand(kCmdSound, 20006, 20002, NULL); // Play Coin sound
523 _commandHandler->addCommand(kCmdSay, 20002, 20004, NULL); // Say "Luck guy..."
524 _commandHandler->addCommand(kCmdSend, 20010, 20, NULL); // Move Paper to scene 20
525 _commandHandler->addCommand(kCmdSound, 20010, 20003, NULL); // Play "ksh" sound! (fx20003.wav)
526 _commandHandler->addCommand(kCmdSay, 20001, 20005, NULL); // Say "Congratulations"
527 _game = false;
528 return;
529 } else
530 _sprK3->step(newRandom(5));
531 }
532
533 if (_gameCase2Cpt < 100) {
534 switch (_gameCase2Cpt) {
535 case 15:
536 // Give hint about ALTered dice
537 _commandHandler->addCommand(kCmdSay, 20003, 20021, NULL);
538 break;
539 case 30:
540 case 45:
541 case 60:
542 case 75:
543 // Tell to use ALT key
544 _commandHandler->addCommand(kCmdSay, 20003, 20022, NULL);
545 break;
546 }
547 _gameCase2Cpt++;
548 }
549
550 switch (spr->_ref) {
551 case 1:
552 _commandHandler->addCommand(kCmdSay, 20001, 20011, NULL); // Say "It'a my turn"
553 _commandHandler->addCommand(kCmdSeq, 20001, 1, NULL); // Throw dice
554 _commandHandler->addCommand(kCmdWait, 20001, 1, NULL); // wait
555 _commandHandler->addCommand(kCmdSetZ, 20700, 2, NULL); // hide dice
556 _commandHandler->addCommand(kCmdHide, 20007, 1, NULL); // hide dice
557 _commandHandler->addCommand(kCmdWait, 20001, 16, NULL); // wait
558 _commandHandler->addCommand(kCmdSeq, 20007, 1, NULL); // Start dice animation (20kosci)
559 _commandHandler->addCommand(kCmdHide, 20007, 0, NULL); // unhide
560 _commandHandler->addCommand(kCmdSound, 20007, 20001, NULL); // Play Dice sound
561 _commandHandler->addCommand(kCmdWait, 20007, -1, NULL); // the end
562 _commandHandler->addCommand(kCmdGame, 20001, 2, NULL); // again!
563 break;
564
565 case 20001:
566 _commandHandler->addCommand(kCmdSay, 20002, 20012, NULL); // Say "Now it's mine"
567 _commandHandler->addCommand(kCmdSeq, 20002, 1, NULL); // Throw dice
568 _commandHandler->addCommand(kCmdWait, 20002, 3, NULL); // wait
569 _commandHandler->addCommand(kCmdSetZ, 20700, 2, NULL); // hide dice
570 _commandHandler->addCommand(kCmdHide, 20007, 1, NULL); // hide dice
571 _commandHandler->addCommand(kCmdWait, 20002, 10, NULL); // wait
572 _commandHandler->addCommand(kCmdSeq, 20007, 2, NULL); // Start dice animation (20kosci)
573 _commandHandler->addCommand(kCmdHide, 20007, 0, NULL); // unhide
574 _commandHandler->addCommand(kCmdSound, 20007, 20001, NULL); // Play Dice sound
575 _commandHandler->addCommand(kCmdWait, 20007, -1, NULL); // the end
576 _commandHandler->addCommand(kCmdGame, 20002, 2, NULL); // again!
577 break;
578
579 case 20002:
580 _commandHandler->addCommand(kCmdSay, 20002, 20010, NULL); // "Roll the bones!"
581 _commandHandler->addCommand(kCmdWalk, 20005, -1, NULL); // Walk to table
582 _commandHandler->addCommand(kCmdWait, 1, -1, NULL); // Wait
583 _commandHandler->addCommand(kCmdCover, 1, 20101, NULL); // grasol ??
584 _commandHandler->addCommand(kCmdSeq, 20101, 1, NULL); // Start Chief animation (20solgra)
585 _commandHandler->addCommand(kCmdWait, 20101, 5, NULL); // Wait
586 _commandHandler->addCommand(kCmdSetZ, 20700, 2, NULL); // Hide dice
587 _commandHandler->addCommand(kCmdHide, 20007, 1, NULL); // Hide dice
588 _commandHandler->addCommand(kCmdWait, 20101, 15, NULL); // wait
589 _commandHandler->addCommand(kCmdSeq, 20007, 1, NULL); // Start dice animation (20kosci)
590 _commandHandler->addCommand(kCmdHide, 20007, 0, NULL); // Unhide
591 _commandHandler->addCommand(kCmdSound, 20007, 20001, NULL); // Play Dice sound
592 _commandHandler->addCommand(kCmdWait, 20101, -1, NULL); // the end
593 _commandHandler->addCommand(kCmdUncover, 1, 20101, NULL); // SDS ??
594 _commandHandler->addCommand(kCmdGame, 1, 2, NULL); // again!
595 break;
596 }
597 }
598 }
599
600 void CGEEngine::expandSprite(Sprite *spr) {
601 debugC(5, kCGEDebugEngine, "CGEEngine::expandSprite(spr)");
602
603 if (spr)
604 _vga->_showQ->insert(_vga->_spareQ->remove(spr));
605 }
606
607 void CGEEngine::contractSprite(Sprite *spr) {
608 debugC(1, kCGEDebugEngine, "CGEEngine::contractSprite(spr)");
609
610 if (spr)
611 _vga->_spareQ->append(_vga->_showQ->remove(spr));
612 }
613
614 /**
615 * Check if an item is in the inventory, and returns its position
616 * @param spr Sprite pointer
617 * @return -1 if not found, else index.
618 */
619 int CGEEngine::findPocket(Sprite *spr) {
620 debugC(1, kCGEDebugEngine, "CGEEngine::findPocket(spr)");
621
622 for (int i = 0; i < kPocketNX; i++)
623 if (_pocket[i] == spr)
624 return i;
625 return -1;
626 }
627
628 /**
629 * Check if an item is in the inventory, and returns its position
630 * @param Inventory slot number Sprite pointer
631 */
632 void CGEEngine::selectPocket(int n) {
633 debugC(1, kCGEDebugEngine, "CGEEngine::selectPocket(%d)", n);
634
635 if (n < 0 || (_pocLight->_seqPtr && _pocPtr == n)) {
636 // If no slot specified, or another slot already selected
637 // stop the blinking animation
638 _pocLight->step(0);
639 n = findPocket(NULL);
640 if (n >= 0)
641 _pocPtr = n;
642 } else {
643 // If slot specified, check if the slot if used.
644 // Is so, start the blinking animation
645 if (_pocket[n] != NULL) {
646 _pocPtr = n;
647 _pocLight->step(1);
648 }
649 }
650 _pocLight->gotoxy(kPocketX + _pocPtr * kPocketDX + kPocketSX, kPocketY + kPocketSY);
651 }
652
653 /**
654 * Logic used when all the inventory slots are full and the user tries to pick
655 * another object.
656 * @param Inventory slot number Sprite pointer
657 */
658 void CGEEngine::pocFul() {
659 debugC(1, kCGEDebugEngine, "CGEEngine::pocFul()");
660
661 if (!_hero)
662 error("pocFul - Unexpected null _hero");
663
664 _hero->park();
665 _commandHandler->addCommand(kCmdWait, -1, -1, _hero);
666 _commandHandler->addCommand(kCmdSeq, -1, kSeqPocketFull, _hero);
667 _commandHandler->addCommand(kCmdSound, -1, 2, _hero); // Play the 'hum-hum" sound (fx00002)
668 _commandHandler->addCommand(kCmdWait, -1, -1, _hero);
669 _commandHandler->addCommand(kCmdSay, 1, kPocketFull, _hero);
670 }
671
672 void CGEEngine::hide1(Sprite *spr) {
673 debugC(1, kCGEDebugEngine, "CGEEngine::hide1(spr)");
674
675 _commandHandlerTurbo->addCommand(kCmdGhost, -1, 0, spr->ghost());
676 }
677
678 void CGEEngine::snGhost(Bitmap *bmp) {
679 debugC(1, kCGEDebugEngine, "CGEEngine::snGhost(bmp)");
680
681 bmp->hide(bmp->_map & 0xFFFF, bmp->_map >> 16);
682 bmp->_m = NULL;
683 bmp->_map = 0;
684 delete bmp;
685 }
686
687 void CGEEngine::feedSnail(Sprite *spr, SnList snq) {
688 debugC(1, kCGEDebugEngine, "CGEEngine::feedSnail(spr, snq)");
689
690 if (!spr || !spr->active())
691 return;
692
693 uint8 ptr = (snq == kTake) ? spr->_takePtr : spr->_nearPtr;
694
695 if (ptr == kNoPtr)
696 return;
697
698 CommandHandler::Command *comtab = spr->snList(snq);
699 CommandHandler::Command *c = comtab + ptr;
700
701 if (findPocket(NULL) < 0) { // no empty pockets?
702 CommandHandler::Command *p;
703 for (p = c; p->_commandType != kCmdNext; p++) { // find KEEP command
704 if (p->_commandType == kCmdKeep) {
705 pocFul();
706 return;
707 }
708 if (p->_spritePtr)
709 break;
710 }
711 }
712 while (true) {
713 if (c->_commandType == kCmdTalk) {
714 if ((_commandHandler->_talkEnable = (c->_val != 0)) == false)
715 killText();
716 }
717 if (c->_commandType == kCmdNext) {
718 Sprite *s = (c->_ref < 0) ? spr : locate(c->_ref);
719 if (s) {
720 uint8 *idx = (snq == kTake) ? &s->_takePtr : &s->_nearPtr;
721 if (*idx != kNoPtr) {
722 int v;
723 switch (c->_val) {
724 case -1 :
725 v = c - comtab + 1;
726 break;
727 case -2 :
728 v = c - comtab;
729 break;
730 case -3 :
731 v = -1;
732 break;
733 default :
734 v = c->_val;
735 break;
736 }
737 if (v >= 0)
738 *idx = v;
739 }
740 }
741 if (s == spr)
742 break;
743 }
744 if (c->_commandType == kCmdIf) {
745 Sprite *s = (c->_ref < 0) ? spr : locate(c->_ref);
746 if (s) { // sprite extsts
747 if (! s->seqTest(-1))
748 c = comtab + c->_val; // not parked
749 else
750 ++c;
751 } else
752 ++c;
753 } else {
754 _commandHandler->addCommand(c->_commandType, c->_ref, c->_val, spr);
755 if (c->_spritePtr)
756 break;
757 else
758 c++;
759 }
760 }
761 }
762
763 void CGEEngine::snNNext(Sprite *spr, int p) {
764 debugC(1, kCGEDebugEngine, "CGEEngine::snNNext(spr, %d)", p);
765
766 if (spr)
767 if (spr->_nearPtr != kNoPtr)
768 spr->_nearPtr = p;
769 }
770
771 void CGEEngine::snTNext(Sprite *spr, int p) {
772 debugC(1, kCGEDebugEngine, "CGEEngine::snTNext(spr, %d)", p);
773
774 if (spr)
775 if (spr->_takePtr != kNoPtr)
776 spr->_takePtr = p;
777 }
778
779 void CGEEngine::snRNNext(Sprite *spr, int p) {
780 debugC(1, kCGEDebugEngine, "CGEEngine::snRNNext(spr, %d)", p);
781
782 if (spr)
783 if (spr->_nearPtr != kNoPtr)
784 spr->_nearPtr += p;
785 }
786
787
788 void CGEEngine::snRTNext(Sprite *spr, int p) {
789 debugC(1, kCGEDebugEngine, "CGEEngine::snRTNext(spr, %d)", p);
790
791 if (spr)
792 if (spr->_takePtr != kNoPtr)
793 spr->_takePtr += p;
794 }
795
796 void CGEEngine::snZTrim(Sprite *spr) {
797 debugC(4, kCGEDebugEngine, "CGEEngine::snZTrim(spr)");
798
799 if (!spr || !spr->active())
800 return;
801
802 Sprite *s = (spr->_flags._shad) ? spr->_prev : NULL;
803 _vga->_showQ->insert(_vga->_showQ->remove(spr));
804 if (s) {
805 s->_z = spr->_z;
806 _vga->_showQ->insert(_vga->_showQ->remove(s), spr);
807 }
808 }
809
810 void CGEEngine::snHide(Sprite *spr, int val) {
811 debugC(1, kCGEDebugEngine, "CGEEngine::snHide(spr, %d)", val);
812
813 if (spr) {
814 spr->_flags._hide = (val >= 0) ? (val != 0) : (!spr->_flags._hide);
815 if (spr->_flags._shad)
816 spr->_prev->_flags._hide = spr->_flags._hide;
817 }
818 }
819
820 void CGEEngine::snRmNear(Sprite *spr) {
821 debugC(1, kCGEDebugEngine, "CGEEngine::snRmNear(spr)");
822
823 if (spr)
824 spr->_nearPtr = kNoPtr;
825 }
826
827 void CGEEngine::snRmTake(Sprite *spr) {
828 debugC(1, kCGEDebugEngine, "CGEEngine::snRmTake(spr)");
829
830 if (spr)
831 spr->_takePtr = kNoPtr;
832 }
833
834 void CGEEngine::snSeq(Sprite *spr, int val) {
835 debugC(1, kCGEDebugEngine, "CGEEngine::snSeq(spr, %d)", val);
836
837 if (spr) {
838 if (spr == _hero && val == 0)
839 _hero->park();
840 else
841 spr->step(val);
842 }
843 }
844
845 void CGEEngine::snRSeq(Sprite *spr, int val) {
846 debugC(1, kCGEDebugEngine, "CGEEngine::snRSeq(spr, %d)", val);
847
848 if (spr)
849 snSeq(spr, spr->_seqPtr + val);
850 }
851
852 void CGEEngine::snSend(Sprite *spr, int val) {
853 debugC(1, kCGEDebugEngine, "CGEEngine::snSend(spr, %d)", val);
854
855 if (!spr)
856 return;
857
858 int was = spr->_scene;
859 bool was1 = (was == 0 || was == _now);
860 bool val1 = (val == 0 || val == _now);
861 spr->_scene = val;
862 if (val1 != was1) {
863 if (was1) {
864 if (spr->_flags._kept) {
865 int n = findPocket(spr);
866 if (n >= 0)
867 _pocket[n] = NULL;
868 }
869 hide1(spr);
870 contractSprite(spr);
871 spr->_flags._slav = false;
872 } else {
873 if (spr->_ref % 1000 == 0)
874 _bitmapPalette = _vga->_sysPal;
875 if (spr->_flags._back)
876 spr->backShow(true);
877 else
878 expandSprite(spr);
879 _bitmapPalette = NULL;
880 }
881 }
882 }
883
884 void CGEEngine::snSwap(Sprite *spr, int xref) {
885 debugC(1, kCGEDebugEngine, "CGEEngine::snSwap(spr, %d)", xref);
886
887 Sprite *xspr = locate(xref);
888 if (!spr || !xspr)
889 return;
890
891 int was = spr->_scene;
892 int xwas = xspr->_scene;
893 bool was1 = (was == 0 || was == _now);
894 bool xwas1 = (xwas == 0 || xwas == _now);
895
896 SWAP(spr->_scene, xspr->_scene);
897 SWAP(spr->_x, xspr->_x);
898 SWAP(spr->_y, xspr->_y);
899 SWAP(spr->_z, xspr->_z);
900 if (spr->_flags._kept) {
901 int n = findPocket(spr);
902 if (n >= 0)
903 _pocket[n] = xspr;
904 xspr->_flags._kept = true;
905 xspr->_flags._port = false;
906 }
907 if (xwas1 != was1) {
908 if (was1) {
909 hide1(spr);
910 contractSprite(spr);
911 } else
912 expandSprite(spr);
913 if (xwas1) {
914 hide1(xspr);
915 contractSprite(xspr);
916 } else
917 expandSprite(xspr);
918 }
919 }
920
921 void CGEEngine::snCover(Sprite *spr, int xref) {
922 debugC(1, kCGEDebugEngine, "CGEEngine::snCover(spr, %d)", xref);
923
924 Sprite *xspr = locate(xref);
925 if (!spr || !xspr)
926 return;
927
928 spr->_flags._hide = true;
929 xspr->_z = spr->_z;
930 xspr->_scene = spr->_scene;
931 xspr->gotoxy(spr->_x, spr->_y);
932 expandSprite(xspr);
933 if ((xspr->_flags._shad = spr->_flags._shad) == 1) {
934 _vga->_showQ->insert(_vga->_showQ->remove(spr->_prev), xspr);
935 spr->_flags._shad = false;
936 }
937 feedSnail(xspr, kNear);
938 }
939
940 void CGEEngine::snUncover(Sprite *spr, Sprite *xspr) {
941 debugC(1, kCGEDebugEngine, "CGEEngine::snUncover(spr, xspr)");
942
943 if (!spr || !xspr)
944 return;
945
946 spr->_flags._hide = false;
947 spr->_scene = xspr->_scene;
948 spr->gotoxy(xspr->_x, xspr->_y);
949 if ((spr->_flags._shad = xspr->_flags._shad) == 1) {
950 _vga->_showQ->insert(_vga->_showQ->remove(xspr->_prev), spr);
951 xspr->_flags._shad = false;
952 }
953 spr->_z = xspr->_z;
954 snSend(xspr, -1);
955 if (spr->_time == 0)
956 spr->_time++;
957 }
958
959 void CGEEngine::snSetX0(int scene, int x0) {
960 debugC(1, kCGEDebugEngine, "CGEEngine::snSetX0(%d, %d)", scene, x0);
961
962 _heroXY[scene - 1].x = x0;
963 }
964
965 void CGEEngine::snSetY0(int scene, int y0) {
966 debugC(1, kCGEDebugEngine, "CGEEngine::snSetY0(%d, %d)", scene, y0);
967
968 _heroXY[scene - 1].y = y0;
969 }
970
971 void CGEEngine::snSetXY(Sprite *spr, uint16 xy) {
972 debugC(1, kCGEDebugEngine, "CGEEngine::snSetXY(spr, %d)", xy);
973
974 if (spr)
975 spr->gotoxy(xy % kScrWidth, xy / kScrWidth);
976 }
977
978 void CGEEngine::snRelX(Sprite *spr, int x) {
979 debugC(1, kCGEDebugEngine, "CGEEngine::snRelX(spr, %d)", x);
980
981 if (spr && _hero)
982 spr->gotoxy(_hero->_x + x, spr->_y);
983 }
984
985 void CGEEngine::snRelY(Sprite *spr, int y) {
986 debugC(1, kCGEDebugEngine, "CGEEngine::snRelY(spr, %d)", y);
987
988 if (spr && _hero)
989 spr->gotoxy(spr->_x, _hero->_y + y);
990 }
991
992 void CGEEngine::snRelZ(Sprite *spr, int z) {
993 debugC(1, kCGEDebugEngine, "CGEEngine::snRelZ(spr, %d)", z);
994
995 if (spr && _hero) {
996 spr->_z = _hero->_z + z;
997 snZTrim(spr);
998 }
999 }
1000
1001 void CGEEngine::snSetX(Sprite *spr, int x) {
1002 debugC(1, kCGEDebugEngine, "CGEEngine::snSetX(spr, %d)", x);
1003
1004 if (spr)
1005 spr->gotoxy(x, spr->_y);
1006 }
1007
1008 void CGEEngine::snSetY(Sprite *spr, int y) {
1009 debugC(1, kCGEDebugEngine, "CGEEngine::snSetY(spr, %d)", y);
1010
1011 if (spr)
1012 spr->gotoxy(spr->_x, y);
1013 }
1014
1015 void CGEEngine::snSetZ(Sprite *spr, int z) {
1016 debugC(1, kCGEDebugEngine, "CGEEngine::snSetZ(spr, %d)", z);
1017
1018 if (spr) {
1019 spr->_z = z;
1020 snZTrim(spr);
1021 }
1022 }
1023
1024 void CGEEngine::snSlave(Sprite *spr, int ref) {
1025 debugC(1, kCGEDebugEngine, "CGEEngine::snSlave(spr, %d)", ref);
1026
1027 Sprite *slv = locate(ref);
1028 if (spr && slv) {
1029 if (spr->active()) {
1030 snSend(slv, spr->_scene);
1031 slv->_flags._slav = true;
1032 slv->_z = spr->_z;
1033 _vga->_showQ->insert(_vga->_showQ->remove(slv), spr->_next);
1034 }
1035 }
1036 }
1037
1038 void CGEEngine::snTrans(Sprite *spr, int trans) {
1039 debugC(1, kCGEDebugEngine, "CGEEngine::snTrans(spr, %d)", trans);
1040
1041 if (spr)
1042 spr->_flags._tran = (trans < 0) ? !spr->_flags._tran : (trans != 0);
1043 }
1044
1045 void CGEEngine::snPort(Sprite *spr, int port) {
1046 debugC(1, kCGEDebugEngine, "CGEEngine::snPort(spr, %d)", port);
1047
1048 if (spr)
1049 spr->_flags._port = (port < 0) ? !spr->_flags._port : (port != 0);
1050 }
1051
1052 void CGEEngine::snKill(Sprite *spr) {
1053 debugC(1, kCGEDebugEngine, "CGEEngine::snKill(spr)");
1054
1055 if (!spr)
1056 return;
1057
1058 if (spr->_flags._kept) {
1059 int n = findPocket(spr);
1060 if (n >= 0)
1061 _pocket[n] = NULL;
1062 }
1063 Sprite *nx = spr->_next;
1064 hide1(spr);
1065 _vga->_showQ->remove(spr);
1066 _eventManager->clearEvent(spr);
1067 if (spr->_flags._kill) {
1068 delete spr;
1069 } else {
1070 spr->_scene = -1;
1071 _vga->_spareQ->append(spr);
1072 }
1073 if (nx) {
1074 if (nx->_flags._slav)
1075 snKill(nx);
1076 }
1077 }
1078
1079 /**
1080 * Play a FX sound
1081 * @param spr Sprite pointer
1082 * @param wav FX index
1083 */
1084 void CGEEngine::snSound(Sprite *spr, int wav) {
1085 debugC(1, kCGEDebugEngine, "CGEEngine::snSound(spr, %d)", wav);
1086
1087 if (wav == -1)
1088 _sound->stop();
1089 else
1090 _sound->play((*_fx)[wav], (spr) ? ((spr->_x + spr->_w / 2) / (kScrWidth / 16)) : 8);
1091
1092 _sound->setRepeat(1);
1093 }
1094
1095 void CGEEngine::snKeep(Sprite *spr, int stp) {
1096 debugC(1, kCGEDebugEngine, "CGEEngine::snKeep(spr, %d)", stp);
1097
1098 selectPocket(-1);
1099 if (spr && ! spr->_flags._kept && _pocket[_pocPtr] == NULL) {
1100 int16 oldRepeat = _sound->getRepeat();
1101 _sound->setRepeat(1);
1102 snSound(spr, 3);
1103 _sound->setRepeat(oldRepeat);
1104 _pocket[_pocPtr] = spr;
1105 spr->_scene = 0;
1106 spr->_flags._kept = true;
1107 spr->gotoxy(kPocketX + kPocketDX * _pocPtr + kPocketDX / 2 - spr->_w / 2,
1108 kPocketY + kPocketDY / 2 - spr->_h / 2);
1109 if (stp >= 0)
1110 spr->step(stp);
1111 }
1112 selectPocket(-1);
1113 }
1114
1115 /**
1116 * Remove an object from the inventory and (if specified) trigger an animation
1117 * @param spr Inventory item
1118 * @param stp Animation
1119 */
1120 void CGEEngine::snGive(Sprite *spr, int stp) {
1121 debugC(1, kCGEDebugEngine, "CGEEngine::snGive(spr, %d)", stp);
1122
1123 if (spr) {
1124 int p = findPocket(spr);
1125 if (p >= 0) {
1126 _pocket[p] = NULL;
1127 spr->_scene = _now;
1128 spr->_flags._kept = false;
1129 if (stp >= 0)
1130 spr->step(stp);
1131 }
1132 }
1133 selectPocket(-1);
1134 }
1135
1136 void CGEEngine::snBackPt(Sprite *spr, int stp) {
1137 debugC(1, kCGEDebugEngine, "CGEEngine::snBackPt(spr, %d)", stp);
1138
1139 if (spr) {
1140 if (stp >= 0)
1141 spr->step(stp);
1142 spr->backShow(true);
1143 }
1144 }
1145
1146 void CGEEngine::snLevel(Sprite *spr, int lev) {
1147 debugC(1, kCGEDebugEngine, "CGEEngine::snLevel(spr, %d)", lev);
1148
1149 assert((lev >= 0) && (lev < 5));
1150
1151 for (int i = 0; i < 5; i++) {
1152 spr = _vga->_spareQ->locate(100 + i);
1153 if (spr) {
1154 if (i <= lev) {
1155 spr->backShow(true);
1156 spr->_scene = 0;
1157 spr->_flags._hide = false;
1158 } else {
1159 spr->_flags._hide = true;
1160 spr->_scene = -1;
1161 }
1162 } else {
1163 warning("SPR not found! ref: %d", 100 + i);
1164 }
1165 }
1166
1167 _lev = lev;
1168 _maxScene = _maxSceneArr[_lev];
1169 }
1170
1171 /**
1172 * Set a flag to a value
1173 * @param indx Flag index
1174 * @param val Flag value
1175 */
1176 void CGEEngine::snFlag(int indx, bool val) {
1177 _flag[indx] = val;
1178 }
1179
1180 void CGEEngine::snSetRef(Sprite *spr, int nr) {
1181 debugC(1, kCGEDebugEngine, "CGEEngine::snSetRef(spr, %d)", nr);
1182
1183 if (spr)
1184 spr->_ref = nr;
1185 }
1186
1187 void CGEEngine::snFlash(bool on) {
1188 debugC(1, kCGEDebugEngine, "CGEEngine::snFlash(%s)", on ? "true" : "false");
1189
1190 if (on) {
1191 Dac *pal = (Dac *)malloc(sizeof(Dac) * kPalCount);
1192 if (pal) {
1193 memcpy(pal, _vga->_sysPal, kPalSize);
1194 for (int i = 0; i < kPalCount; i++) {
1195 int c;
1196 c = pal[i]._r << 1;
1197 pal[i]._r = (c < 64) ? c : 63;
1198 c = pal[i]._g << 1;
1199 pal[i]._g = (c < 64) ? c : 63;
1200 c = pal[i]._b << 1;
1201 pal[i]._b = (c < 64) ? c : 63;
1202 }
1203 _vga->setColors(pal, 64);
1204 }
1205
1206 free(pal);
1207 } else
1208 _vga->setColors(_vga->_sysPal, 64);
1209 _dark = false;
1210 }
1211
1212 void CGEEngine::snLight(bool in) {
1213 debugC(1, kCGEDebugEngine, "CGEEngine::snLight(%s)", in ? "true" : "false");
1214
1215 if (in)
1216 _vga->sunrise(_vga->_sysPal);
1217 else
1218 _vga->sunset();
1219 _dark = !in;
1220 }
1221
1222 /**
1223 * Set an horizontal boundary
1224 * @param scene Scene number
1225 * @param barX Horizontal boundary value
1226 */
1227 void CGEEngine::snHBarrier(const int scene, const int barX) {
1228 debugC(1, kCGEDebugEngine, "CGEEngine::snHBarrier(%d, %d)", scene, barX);
1229
1230 _barriers[(scene > 0) ? scene : _now]._horz = barX;
1231 }
1232
1233 /**
1234 * Set a vertical boundary
1235 * @param scene Scene number
1236 * @param barY Vertical boundary value
1237 */
1238 void CGEEngine::snVBarrier(const int scene, const int barY) {
1239 debugC(1, kCGEDebugEngine, "CGEEngine::snVBarrier(%d, %d)", scene, barY);
1240
1241 _barriers[(scene > 0) ? scene : _now]._vert = barY;
1242 }
1243
1244 void CGEEngine::snWalk(Sprite *spr, int x, int y) {
1245 debugC(1, kCGEDebugEngine, "CGEEngine::snWalk(spr, %d, %d)", x, y);
1246
1247 if (_hero) {
1248 if (spr && y < 0)
1249 _hero->findWay(spr);
1250 else
1251 _hero->findWay(XZ(x, y));
1252 }
1253 }
1254
1255 void CGEEngine::snReach(Sprite *spr, int mode) {
1256 debugC(1, kCGEDebugEngine, "CGEEngine::snReach(spr, %d)", mode);
1257
1258 if (_hero)
1259 _hero->reach(spr, mode);
1260 }
1261
1262 void CGEEngine::snMouse(bool on) {
1263 debugC(1, kCGEDebugEngine, "CGEEngine::snMouse(%s)", on ? "true" : "false");
1264
1265 if (on)
1266 _mouse->on();
1267 else
1268 _mouse->off();
1269 }
1270
1271 } // End of namespace CGE
1272