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 
25 #ifdef ENABLE_AGOS2
26 
27 #include "common/system.h"
28 
29 #include "agos/agos.h"
30 
31 namespace AGOS {
32 
33 #define OPCODE(x)	_OPCODE(AGOSEngine_PuzzlePack, x)
34 
setupOpcodes()35 void AGOSEngine_PuzzlePack::setupOpcodes() {
36 	static const OpcodeEntryPuzzlePack opcodes[] = {
37 		/* 00 */
38 		OPCODE(o_invalid),
39 		OPCODE(o_at),
40 		OPCODE(o_notAt),
41 		OPCODE(o_invalid),
42 		/* 04 */
43 		OPCODE(o_invalid),
44 		OPCODE(o_carried),
45 		OPCODE(o_notCarried),
46 		OPCODE(o_isAt),
47 		/* 08 */
48 		OPCODE(o_invalid),
49 		OPCODE(o_invalid),
50 		OPCODE(o_invalid),
51 		OPCODE(o_zero),
52 		/* 12 */
53 		OPCODE(o_notZero),
54 		OPCODE(o_eq),
55 		OPCODE(o_notEq),
56 		OPCODE(o_gt),
57 		/* 16 */
58 		OPCODE(o_lt),
59 		OPCODE(o_eqf),
60 		OPCODE(o_notEqf),
61 		OPCODE(o_ltf),
62 		/* 20 */
63 		OPCODE(o_gtf),
64 		OPCODE(o_invalid),
65 		OPCODE(o_invalid),
66 		OPCODE(off_chance),
67 		/* 24 */
68 		OPCODE(o_invalid),
69 		OPCODE(o_isRoom),
70 		OPCODE(o_isObject),
71 		OPCODE(o_state),
72 		/* 28 */
73 		OPCODE(o_oflag),
74 		OPCODE(o_invalid),
75 		OPCODE(opp_iconifyWindow),
76 		OPCODE(o_destroy),
77 		/* 32 */
78 		OPCODE(opp_restoreOopsPosition),
79 		OPCODE(o_place),
80 		OPCODE(o_invalid),
81 		OPCODE(o_invalid),
82 		/* 36 */
83 		OPCODE(o_copyff),
84 		OPCODE(o_invalid),
85 		OPCODE(opp_loadMouseImage),
86 		OPCODE(o_invalid),
87 		/* 40 */
88 		OPCODE(o_invalid),
89 		OPCODE(o_clear),
90 		OPCODE(o_let),
91 		OPCODE(o_add),
92 		/* 44 */
93 		OPCODE(o_sub),
94 		OPCODE(o_addf),
95 		OPCODE(o_subf),
96 		OPCODE(o_mul),
97 		/* 48 */
98 		OPCODE(o_div),
99 		OPCODE(o_mulf),
100 		OPCODE(o_divf),
101 		OPCODE(o_mod),
102 		/* 52 */
103 		OPCODE(o_modf),
104 		OPCODE(o_random),
105 		OPCODE(o_invalid),
106 		OPCODE(o_goto),
107 		/* 56 */
108 		OPCODE(o_oset),
109 		OPCODE(o_oclear),
110 		OPCODE(o_putBy),
111 		OPCODE(o_inc),
112 		/* 60 */
113 		OPCODE(o_dec),
114 		OPCODE(o_setState),
115 		OPCODE(o_print),
116 		OPCODE(opp_message),
117 		/* 64 */
118 		OPCODE(o_msg),
119 		OPCODE(off_addTextBox),
120 		OPCODE(opp_setShortText),
121 		OPCODE(oww_setLongText),
122 		/* 68 */
123 		OPCODE(o_end),
124 		OPCODE(o_done),
125 		OPCODE(off_printLongText),
126 		OPCODE(o_process),
127 		/* 72 */
128 		OPCODE(o_invalid),
129 		OPCODE(o_invalid),
130 		OPCODE(o_invalid),
131 		OPCODE(o_invalid),
132 		/* 76 */
133 		OPCODE(o_when),
134 		OPCODE(o_if1),
135 		OPCODE(o_if2),
136 		OPCODE(o_isCalled),
137 		/* 80 */
138 		OPCODE(o_is),
139 		OPCODE(o_invalid),
140 		OPCODE(o_debug),
141 		OPCODE(os2_rescan),
142 		/* 84 */
143 		OPCODE(o_invalid),
144 		OPCODE(o_invalid),
145 		OPCODE(o_invalid),
146 		OPCODE(o_comment),
147 		/* 88 */
148 		OPCODE(o_invalid),
149 		OPCODE(o_invalid),
150 		OPCODE(o_getParent),
151 		OPCODE(o_getNext),
152 		/* 92 */
153 		OPCODE(o_getChildren),
154 		OPCODE(o_invalid),
155 		OPCODE(o_invalid),
156 		OPCODE(o_invalid),
157 		/* 96 */
158 		OPCODE(o_picture),
159 		OPCODE(o_loadZone),
160 		OPCODE(os2_animate),
161 		OPCODE(os2_stopAnimate),
162 		/* 100 */
163 		OPCODE(o_killAnimate),
164 		OPCODE(o_defWindow),
165 		OPCODE(o_window),
166 		OPCODE(o_cls),
167 		/* 104 */
168 		OPCODE(o_closeWindow),
169 		OPCODE(opp_loadHiScores),
170 		OPCODE(opp_checkHiScores),
171 		OPCODE(off_addBox),
172 		/* 108 */
173 		OPCODE(o_delBox),
174 		OPCODE(o_enableBox),
175 		OPCODE(o_disableBox),
176 		OPCODE(o_moveBox),
177 		/* 112 */
178 		OPCODE(o_invalid),
179 		OPCODE(o_invalid),
180 		OPCODE(o_doIcons),
181 		OPCODE(o_isClass),
182 		/* 116 */
183 		OPCODE(o_setClass),
184 		OPCODE(o_unsetClass),
185 		OPCODE(o_invalid),
186 		OPCODE(o_waitSync),
187 		/* 120 */
188 		OPCODE(opp_sync),
189 		OPCODE(o_defObj),
190 		OPCODE(off_oracleTextDown),
191 		OPCODE(off_oracleTextUp),
192 		/* 124 */
193 		OPCODE(off_ifTime),
194 		OPCODE(o_here),
195 		OPCODE(o_doClassIcons),
196 		OPCODE(o_invalid),
197 		/* 128 */
198 		OPCODE(o_invalid),
199 		OPCODE(o_invalid),
200 		OPCODE(o_setAdjNoun),
201 		OPCODE(off_setTime),
202 		/* 132 */
203 		OPCODE(opp_saveUserGame),
204 		OPCODE(opp_loadUserGame),
205 		OPCODE(off_listSaveGames),
206 		OPCODE(o_invalid),
207 		/* 136 */
208 		OPCODE(o_copysf),
209 		OPCODE(o_restoreIcons),
210 		OPCODE(o_freezeZones),
211 		OPCODE(o_placeNoIcons),
212 		/* 140 */
213 		OPCODE(o_clearTimers),
214 		OPCODE(o_setDollar),
215 		OPCODE(o_isBox),
216 		OPCODE(oe2_doTable),
217 		/* 144 */
218 		OPCODE(o_invalid),
219 		OPCODE(o_invalid),
220 		OPCODE(o_invalid),
221 		OPCODE(o_invalid),
222 		/* 148 */
223 		OPCODE(o_invalid),
224 		OPCODE(o_invalid),
225 		OPCODE(o_invalid),
226 		OPCODE(oe2_storeItem),
227 		/* 152 */
228 		OPCODE(oe2_getItem),
229 		OPCODE(oe2_bSet),
230 		OPCODE(oe2_bClear),
231 		OPCODE(oe2_bZero),
232 		/* 156 */
233 		OPCODE(oe2_bNotZero),
234 		OPCODE(oe2_getOValue),
235 		OPCODE(oe2_setOValue),
236 		OPCODE(o_invalid),
237 		/* 160 */
238 		OPCODE(oe2_ink),
239 		OPCODE(off_screenTextBox),
240 		OPCODE(opp_playTune),
241 		OPCODE(o_invalid),
242 		/* 164 */
243 		OPCODE(oe2_getDollar2),
244 		OPCODE(off_isAdjNoun),
245 		OPCODE(o_invalid),
246 		OPCODE(o_invalid),
247 		/* 168 */
248 		OPCODE(o_invalid),
249 		OPCODE(o_invalid),
250 		OPCODE(o_invalid),
251 		OPCODE(off_hyperLinkOn),
252 		/* 172 */
253 		OPCODE(off_hyperLinkOff),
254 		OPCODE(opp_saveOopsPosition),
255 		OPCODE(o_invalid),
256 		OPCODE(oww_lockZones),
257 		/* 176 */
258 		OPCODE(oww_unlockZones),
259 		OPCODE(off_screenTextPObj),
260 		OPCODE(os1_getPathPosn),
261 		OPCODE(os1_scnTxtLongText),
262 		/* 180 */
263 		OPCODE(os1_mouseOn),
264 		OPCODE(off_mouseOff),
265 		OPCODE(o_invalid),
266 		OPCODE(o_invalid),
267 		/* 184 */
268 		OPCODE(os1_unloadZone),
269 		OPCODE(o_invalid),
270 		OPCODE(os1_unfreezeZones),
271 		OPCODE(opp_resetGameTime),
272 		/* 188 */
273 		OPCODE(os2_isShortText),
274 		OPCODE(os2_clearMarks),
275 		OPCODE(os2_waitMark),
276 		OPCODE(opp_resetPVCount),
277 		/* 192 */
278 		OPCODE(opp_setPathValues),
279 		OPCODE(off_restartClock),
280 		OPCODE(opp_pauseClock),
281 		OPCODE(off_setColor),
282 	};
283 
284 	_opcodesPuzzlePack = opcodes;
285 	_numOpcodes = 196;
286 }
287 
executeOpcode(int opcode)288 void AGOSEngine_PuzzlePack::executeOpcode(int opcode) {
289 	OpcodeProcPuzzlePack op = _opcodesPuzzlePack[opcode].proc;
290 	(this->*op) ();
291 }
292 
293 // -----------------------------------------------------------------------
294 // Puzzle Pack Opcodes
295 // -----------------------------------------------------------------------
296 
opp_iconifyWindow()297 void AGOSEngine_PuzzlePack::opp_iconifyWindow() {
298 	// 30
299 	getNextWord();
300 	if (_clockStopped != 0)
301 		_gameTime += getTime() - _clockStopped;
302 	_clockStopped = 0;
303 	_system->setFeatureState(OSystem::kFeatureIconifyWindow, true);
304 }
305 
opp_restoreOopsPosition()306 void AGOSEngine_PuzzlePack::opp_restoreOopsPosition() {
307 	// 32: restore oops position
308 	uint i;
309 
310 	getNextWord();
311 	getNextWord();
312 
313 	if (_oopsValid) {
314 		for (i = 0; i < _numVars; i++) {
315 			_variableArray[i] = _variableArray2[i];
316 		}
317 		i = _variableArray[999] * 100 + 11;
318 		setWindowImage(4,i);
319 		_gameTime += 10;
320 		// Swampy adventures
321 		if (!getBitFlag(110))
322 			_gameTime += 20;
323 		_oopsValid = false;
324 	}
325 }
326 
opp_loadMouseImage()327 void AGOSEngine_PuzzlePack::opp_loadMouseImage() {
328 	// 38: load mouse image
329 	getNextWord();
330 	getVarOrByte();
331 	loadMouseImage();
332 }
333 
opp_message()334 void AGOSEngine_PuzzlePack::opp_message() {
335 	// 63: show string nl
336 	const byte *stringPtr = getStringPtrByID(getNextStringID());
337 	if (getBitFlag(105)) {
338 		// Swampy adventures
339 		printInfoText((const char *)stringPtr);
340 	} else {
341 		showMessageFormat("%s\n", stringPtr);
342 	}
343 }
344 
opp_setShortText()345 void AGOSEngine_PuzzlePack::opp_setShortText() {
346 	// 66: set item name
347 	uint var = getVarOrByte();
348 	uint stringId = getNextStringID();
349 	if (var < _numTextBoxes) {
350 		_shortText[var] = stringId;
351 		_shortTextX[var] = getVarOrWord();
352 		_shortTextY[var] = getVarOrWord();
353 	}
354 }
355 
opp_loadHiScores()356 void AGOSEngine_PuzzlePack::opp_loadHiScores() {
357 	// 105: load high scores
358 	getVarOrByte();
359 	//loadHiScores();
360 }
361 
opp_checkHiScores()362 void AGOSEngine_PuzzlePack::opp_checkHiScores() {
363 	// 106: check high scores
364 	getVarOrByte();
365 	getVarOrByte();
366 	//checkHiScores();
367 }
368 
opp_sync()369 void AGOSEngine_PuzzlePack::opp_sync() {
370 	// 120: sync
371 	uint a = getVarOrWord();
372 	if (a == 8001 || a == 8101 || a == 8201 || a == 8301 || a == 8401) {
373 		_marks &= ~(1 << 2);
374 	}
375 	sendSync(a);
376 }
377 
opp_saveUserGame()378 void AGOSEngine_PuzzlePack::opp_saveUserGame() {
379 	// 132: save game
380 	if (_clockStopped != 0)
381 		_gameTime += getTime() - _clockStopped;
382 	_clockStopped = 0;
383 
384 	if (!getBitFlag(110)) {
385 		// Swampy adventures
386 		saveGame(1, NULL);
387 	}
388 	//saveHiScores()
389 }
390 
opp_loadUserGame()391 void AGOSEngine_PuzzlePack::opp_loadUserGame() {
392 	// 133: load usergame
393 
394 	// NoPatience or Jumble
395 	if (getBitFlag(110)) {
396 		//getHiScoreName();
397 		return;
398 	}
399 
400 	// XXX
401 	loadGame(genSaveName(1));
402 }
403 
opp_playTune()404 void AGOSEngine_PuzzlePack::opp_playTune() {
405 	// 162: play tune
406 	getVarOrByte();
407 	getVarOrByte();
408 	getNextWord();
409 
410 	uint16 music = (uint16)getVarOrWord();
411 	if (music != _lastMusicPlayed) {
412 		_lastMusicPlayed = music;
413 		playSpeech(music, 1);
414 	}
415 }
416 
opp_saveOopsPosition()417 void AGOSEngine_PuzzlePack::opp_saveOopsPosition() {
418 	// 173: save oops position
419 	if (!isVgaQueueEmpty()) {
420 		_oopsValid = true;
421 		for (uint i = 0; i < _numVars; i++) {
422 			_variableArray2[i] = _variableArray[i];
423 		}
424 	} else {
425 		_oopsValid = false;
426 	}
427 }
428 
opp_resetGameTime()429 void AGOSEngine_PuzzlePack::opp_resetGameTime() {
430 	// 187: reset game time
431 	_gameTime = 0;
432 }
433 
opp_resetPVCount()434 void AGOSEngine_PuzzlePack::opp_resetPVCount() {
435 	// 191
436 	_PVCount = 0;
437 	_GPVCount = 0;
438 }
439 
opp_setPathValues()440 void AGOSEngine_PuzzlePack::opp_setPathValues() {
441 	// 192
442 	_pathValues[_PVCount++] = getVarOrByte();
443 	_pathValues[_PVCount++] = getVarOrByte();
444 	_pathValues[_PVCount++] = getVarOrByte();
445 	_pathValues[_PVCount++] = getVarOrByte();
446 }
447 
opp_pauseClock()448 void AGOSEngine_PuzzlePack::opp_pauseClock() {
449 	// 194: pause clock
450 	if (_clockStopped == 0)
451 		_clockStopped = getTime();
452 }
453 
454 } // End of namespace AGOS
455 
456 #endif // ENABLE_AGOS2
457