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/translation.h"
24 
25 #include "gui/message.h"
26 
27 #include "gob/gob.h"
28 #include "gob/inter.h"
29 #include "gob/global.h"
30 #include "gob/game.h"
31 #include "gob/script.h"
32 #include "gob/draw.h"
33 #include "gob/save/saveload.h"
34 
35 namespace Gob {
36 
37 #define OPCODEVER Inter_v5
38 #define OPCODEDRAW(i, x)  _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x)
39 #define OPCODEFUNC(i, x)  _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x)
40 #define OPCODEGOB(i, x)   _opcodesGob[i]._OPCODEGOB(OPCODEVER, x)
41 
Inter_v5(GobEngine * vm)42 Inter_v5::Inter_v5(GobEngine *vm) : Inter_v4(vm) {
43 }
44 
setupOpcodesDraw()45 void Inter_v5::setupOpcodesDraw() {
46 	Inter_v4::setupOpcodesDraw();
47 
48 	OPCODEDRAW(0x61, o5_deleteFile);
49 	OPCODEDRAW(0x80, o5_initScreen);
50 }
51 
setupOpcodesFunc()52 void Inter_v5::setupOpcodesFunc() {
53 	Inter_v4::setupOpcodesFunc();
54 
55 	OPCODEFUNC(0x45, o5_istrlen);
56 }
57 
setupOpcodesGob()58 void Inter_v5::setupOpcodesGob() {
59 	OPCODEGOB(  0, o5_spaceShooter);
60 	OPCODEGOB(  1, o5_spaceShooter);
61 	OPCODEGOB(  2, o5_spaceShooter);
62 	OPCODEGOB(  3, o5_spaceShooter);
63 
64 	OPCODEGOB( 33, o5_spaceShooter);
65 
66 	OPCODEGOB( 34, o5_spaceShooter);
67 	OPCODEGOB( 37, o5_spaceShooter);
68 
69 	OPCODEGOB( 80, o5_getSystemCDSpeed);
70 	OPCODEGOB( 81, o5_getSystemRAM);
71 	OPCODEGOB( 82, o5_getSystemCPUSpeed);
72 	OPCODEGOB( 83, o5_getSystemDrawSpeed);
73 	OPCODEGOB( 84, o5_totalSystemSpecs);
74 
75 	OPCODEGOB( 85, o5_saveSystemSpecs);
76 	OPCODEGOB( 86, o5_loadSystemSpecs);
77 
78 	OPCODEGOB( 87, o5_spaceShooter);
79 	OPCODEGOB( 88, o5_spaceShooter);
80 	OPCODEGOB( 89, o5_spaceShooter);
81 	OPCODEGOB( 90, o5_spaceShooter);
82 
83 	OPCODEGOB( 91, o5_spaceShooter);
84 	OPCODEGOB( 92, o5_gob92);
85 	OPCODEGOB( 93, o5_spaceShooter);
86 	OPCODEGOB( 94, o5_spaceShooter);
87 
88 	OPCODEGOB( 95, o5_gob95);
89 	OPCODEGOB( 96, o5_gob96);
90 	OPCODEGOB( 97, o5_gob97);
91 	OPCODEGOB( 98, o5_gob98);
92 
93 	OPCODEGOB( 99, o5_spaceShooter);
94 	OPCODEGOB(100, o5_gob100);
95 	OPCODEGOB(200, o5_gob200);
96 }
97 
o5_deleteFile()98 void Inter_v5::o5_deleteFile() {
99 	const char *file =_vm->_game->_script->evalString();
100 
101 	debugC(2, kDebugFileIO, "Delete file \"%s\"", file);
102 
103 	SaveLoad::SaveMode mode = _vm->_saveLoad->getSaveMode(file);
104 	if (mode == SaveLoad::kSaveModeSave) {
105 
106 		if (!_vm->_saveLoad->deleteFile(file)) {
107 			GUI::MessageDialog dialog(_("Failed to delete file."));
108 			dialog.runModal();
109 		}
110 
111 	} else if (mode == SaveLoad::kSaveModeNone)
112 		warning("Attempted to delete file \"%s\"", file);
113 }
114 
o5_initScreen()115 void Inter_v5::o5_initScreen() {
116 	int16 offY;
117 	int16 videoMode;
118 	int16 width, height;
119 
120 	offY = _vm->_game->_script->readInt16();
121 
122 	videoMode = offY & 0xFF;
123 	offY = (offY >> 8) & 0xFF;
124 
125 	width = _vm->_game->_script->readValExpr();
126 	height = _vm->_game->_script->readValExpr();
127 
128 	if (videoMode == 0)
129 		videoMode = 0x14;
130 
131 	_vm->_video->clearScreen();
132 
133 	if (videoMode == 0x13) {
134 
135 		if (width == -1)
136 			width = 320;
137 		if (height == -1)
138 			height = 200;
139 
140 		_vm->_width = 320;
141 		_vm->_height = 200;
142 
143 		_vm->_video->setSize();
144 
145 	} else if (_vm->_global->_videoMode == 0x13) {
146 		width = _vm->_width = 640;
147 		height = _vm->_height = 480;
148 
149 		_vm->_video->setSize();
150 	}
151 
152 	_vm->_global->_fakeVideoMode = videoMode;
153 
154 	// Some versions require this
155 	if (videoMode == 0x18)
156 		_vm->_global->_fakeVideoMode = 0x37;
157 
158 	if ((videoMode == _vm->_global->_videoMode) && (width == -1))
159 		return;
160 
161 	if (width > 0)
162 		_vm->_video->_surfWidth = width;
163 	if (height > 0)
164 		_vm->_video->_surfHeight = height;
165 
166 	_vm->_video->_screenDeltaX = 0;
167 	if (_vm->_video->_surfWidth < _vm->_width)
168 		_vm->_video->_screenDeltaX = (_vm->_width - _vm->_video->_surfWidth) / 2;
169 
170 	_vm->_global->_mouseMinX = _vm->_video->_screenDeltaX;
171 	_vm->_global->_mouseMaxX = _vm->_video->_screenDeltaX + _vm->_video->_surfWidth - 1;
172 
173 	_vm->_video->_splitStart = _vm->_video->_surfHeight - offY;
174 
175 	_vm->_video->_splitHeight1 = MIN<int16>(_vm->_height, _vm->_video->_surfHeight);
176 	_vm->_video->_splitHeight2 = offY;
177 
178 	if ((_vm->_video->_surfHeight + offY) < _vm->_height)
179 		_vm->_video->_screenDeltaY = (_vm->_height - (_vm->_video->_surfHeight + offY)) / 2;
180 	else
181 		_vm->_video->_screenDeltaY = 0;
182 
183 	_vm->_global->_mouseMaxY = (_vm->_video->_surfHeight + _vm->_video->_screenDeltaY) - offY - 1;
184 	_vm->_global->_mouseMinY = _vm->_video->_screenDeltaY;
185 
186 	_vm->_draw->closeScreen();
187 	_vm->_util->clearPalette();
188 	memset(_vm->_global->_redPalette, 0, 256);
189 	memset(_vm->_global->_greenPalette, 0, 256);
190 	memset(_vm->_global->_bluePalette, 0, 256);
191 
192 	_vm->_video->_splitSurf.reset();
193 	_vm->_draw->_spritesArray[24].reset();
194 	_vm->_draw->_spritesArray[25].reset();
195 
196 	_vm->_global->_videoMode = videoMode;
197 	_vm->_video->initPrimary(videoMode);
198 	WRITE_VAR(15, _vm->_global->_fakeVideoMode);
199 
200 	_vm->_global->_setAllPalette = true;
201 
202 	_vm->_util->setMousePos(_vm->_global->_inter_mouseX,
203 			_vm->_global->_inter_mouseY);
204 	_vm->_util->clearPalette();
205 
206 	_vm->_draw->initScreen();
207 
208 	_vm->_util->setScrollOffset();
209 
210 	if (offY > 0) {
211 		_vm->_draw->_spritesArray[24] = SurfacePtr(new Surface(_vm->_width, offY, _vm->getPixelFormat().bytesPerPixel));
212 		_vm->_draw->_spritesArray[25] = SurfacePtr(new Surface(_vm->_width, offY, _vm->getPixelFormat().bytesPerPixel));
213 		_vm->_video->_splitSurf = _vm->_draw->_spritesArray[25];
214 	}
215 }
216 
o5_istrlen(OpFuncParams & params)217 void Inter_v5::o5_istrlen(OpFuncParams &params) {
218 	int16 strVar1, strVar2;
219 	int16 len;
220 	uint16 type;
221 
222 	if (_vm->_game->_script->peekByte() == 0x80) {
223 		_vm->_game->_script->skip(1);
224 
225 		strVar1 = _vm->_game->_script->readVarIndex();
226 		strVar2 = _vm->_game->_script->readVarIndex(0, &type);
227 
228 		len = _vm->_draw->stringLength(GET_VARO_STR(strVar1), READ_VARO_UINT16(strVar2));
229 
230 	} else {
231 
232 		strVar1 = _vm->_game->_script->readVarIndex();
233 		strVar2 = _vm->_game->_script->readVarIndex(0, &type);
234 
235 		if (_vm->_global->_language == 10) {
236 			// Extra handling for Japanese strings
237 
238 			for (len = 0; READ_VARO_UINT8(strVar1) != 0; strVar1++, len++)
239 				if (READ_VARO_UINT8(strVar1) >= 128)
240 					strVar1++;
241 
242 		} else
243 			len = strlen(GET_VARO_STR(strVar1));
244 	}
245 
246 	writeVar(strVar2, type, (int32) len);
247 }
248 
o5_spaceShooter(OpGobParams & params)249 void Inter_v5::o5_spaceShooter(OpGobParams &params) {
250 	warning("Dynasty Stub: Space shooter: %d, %d, %s",
251 			params.extraData, params.paramCount, _vm->_game->_curTotFile.c_str());
252 
253 	if (params.paramCount < 4) {
254 		warning("Space shooter variable counter < 4");
255 		_vm->_game->_script->skip(params.paramCount * 2);
256 		return;
257 	}
258 
259 	uint32 var1 = _vm->_game->_script->readInt16() * 4;
260 	uint32 var2 = _vm->_game->_script->readInt16() * 4;
261 
262 	_vm->_game->_script->readInt16();
263 	_vm->_game->_script->readInt16();
264 
265 	if (params.extraData != 0) {
266 		// we need to return 1 for the shooter mission 34. There is only one planet to choose from in the map.
267 		WRITE_VARO_UINT32(var1,(params.extraData == 34) ? 1 : 2);
268 		WRITE_VARO_UINT32(var2,0);
269 	} else {
270 		if (params.paramCount < 5) {
271 			warning("Space shooter variable counter < 5");
272 			return;
273 		}
274 
275 		_vm->_game->_script->skip((params.paramCount - 4) * 2);
276 	}
277 }
278 
o5_getSystemCDSpeed(OpGobParams & params)279 void Inter_v5::o5_getSystemCDSpeed(OpGobParams &params) {
280 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
281 
282 	Font *font;
283 	if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
284 		font->drawString("100 %", 402, 89, 112, 144, 0, *_vm->_draw->_backSurface);
285 		_vm->_draw->forceBlit();
286 
287 		delete font;
288 	}
289 }
290 
o5_getSystemRAM(OpGobParams & params)291 void Inter_v5::o5_getSystemRAM(OpGobParams &params) {
292 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
293 
294 	Font *font;
295 	if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
296 		font->drawString("100 %", 402, 168, 112, 144, 0, *_vm->_draw->_backSurface);
297 		_vm->_draw->forceBlit();
298 
299 		delete font;
300 	}
301 }
302 
o5_getSystemCPUSpeed(OpGobParams & params)303 void Inter_v5::o5_getSystemCPUSpeed(OpGobParams &params) {
304 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
305 
306 	Font *font;
307 	if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
308 		font->drawString("100 %", 402, 248, 112, 144, 0, *_vm->_draw->_backSurface);
309 		_vm->_draw->forceBlit();
310 
311 		delete font;
312 	}
313 }
314 
o5_getSystemDrawSpeed(OpGobParams & params)315 void Inter_v5::o5_getSystemDrawSpeed(OpGobParams &params) {
316 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
317 
318 	Font *font;
319 	if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
320 		font->drawString("100 %", 402, 326, 112, 144, 0, *_vm->_draw->_backSurface);
321 		_vm->_draw->forceBlit();
322 
323 		delete font;
324 	}
325 }
326 
o5_totalSystemSpecs(OpGobParams & params)327 void Inter_v5::o5_totalSystemSpecs(OpGobParams &params) {
328 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
329 
330 	Font *font;
331 	if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
332 		font->drawString("100 %", 402, 405, 112, 144, 0, *_vm->_draw->_backSurface);
333 		_vm->_draw->forceBlit();
334 
335 		delete font;
336 	}
337 }
338 
o5_saveSystemSpecs(OpGobParams & params)339 void Inter_v5::o5_saveSystemSpecs(OpGobParams &params) {
340 	warning("Dynasty Stub: Saving system specifications");
341 
342 /*
343 	FILE *f = fopen("SAVE\\SPEED.INF", w);
344 	fwrite(&_cdSpeed,   sizeof(_cdSpeed),   1, f);
345 	fwrite(&_ram,       sizeof(_ram),       1, f);
346 	fwrite(&_cpuSpeed,  sizeof(_cpuSpeed),  1, f);
347 	fwrite(&_drawSpeed, sizeof(_drawSpeed), 1, f);
348 	fwrite(&_total,     sizeof(_total),     1, f);
349 	fclose(f);
350 */
351 }
352 
o5_loadSystemSpecs(OpGobParams & params)353 void Inter_v5::o5_loadSystemSpecs(OpGobParams &params) {
354 	warning("Dynasty Stub: Loading system specifications");
355 
356 /*
357 	FILE *f = fopen("SAVE\\SPEED.INF", r);
358 	fread(&_cdSpeed,   sizeof(_cdSpeed),   1, f);
359 	fread(&_ram,       sizeof(_ram),       1, f);
360 	fread(&_cpuSpeed,  sizeof(_cpuSpeed),  1, f);
361 	fread(&_drawSpeed, sizeof(_drawSpeed), 1, f);
362 	fread(&_total,     sizeof(_total),     1, f);
363 	fclose(f);
364 */
365 
366 /*
367 	speedSum = MAX(_cdSpeed, 150);
368 	speedSum += (_ram << 3);
369 	speedSum += (_cpuSpeed << 3);
370 	speedSum /= 17;
371 
372 	needThrottle2 = (speedSum > 81) ? 1 : 0;
373 	needThrottle1 = (_total >= 95) ? 1 : 0;
374 
375 	if (needThrottle1 == 1) {
376 		speedThrottle1 = 100;
377 		speedThrottle2 = 1;
378 		speedThrottle3 = 1;
379 		speedThrottle4 = 0;
380 	} else {
381 		speedThrottle1 = 0;
382 		speedThrottle2 = 0;
383 		speedThrottle3 = 0;
384 		speedThrottle4 = 40;
385 	}
386 */
387 }
388 
o5_gob92(OpGobParams & params)389 void Inter_v5::o5_gob92(OpGobParams &params) {
390 	warning("Dynasty Stub: GobFunc 92");
391 
392 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int8) _gob92_1)) */);
393 }
394 
o5_gob95(OpGobParams & params)395 void Inter_v5::o5_gob95(OpGobParams &params) {
396 	warning("Dynasty Stub: GobFunc 95");
397 
398 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int16) speedThrottle4)) */);
399 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int8)  speedThrottle3)) */);
400 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int8)  speedThrottle2)) */);
401 	WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int16) speedThrottle1)) */);
402 }
403 
o5_gob96(OpGobParams & params)404 void Inter_v5::o5_gob96(OpGobParams &params) {
405 	int16 speedThrottle4, speedThrottle1;
406 	byte speedThrottle3, speedThrottle2;
407 
408 	speedThrottle4 = READ_VAR_UINT16(_vm->_game->_script->readInt16());
409 	speedThrottle3 = READ_VAR_UINT8(_vm->_game->_script->readInt16());
410 	speedThrottle2 = READ_VAR_UINT8(_vm->_game->_script->readInt16());
411 	speedThrottle1 = READ_VAR_UINT16(_vm->_game->_script->readInt16());
412 
413 	warning("Dynasty Stub: GobFunc 96: %d, %d, %d, %d",
414 			speedThrottle4, speedThrottle3, speedThrottle2, speedThrottle1);
415 
416 	// TODO
417 }
418 
o5_gob97(OpGobParams & params)419 void Inter_v5::o5_gob97(OpGobParams &params) {
420 	_gob_97_98_val = 1;
421 }
422 
o5_gob98(OpGobParams & params)423 void Inter_v5::o5_gob98(OpGobParams &params) {
424 	_gob_97_98_val = 0;
425 }
426 
o5_gob100(OpGobParams & params)427 void Inter_v5::o5_gob100(OpGobParams &params) {
428 	uint16 var1 = READ_VAR_UINT16(_vm->_game->_script->readInt16());
429 	uint16 var2 = READ_VAR_UINT16(_vm->_game->_script->readInt16());
430 	uint16 var3 = READ_VAR_UINT16(_vm->_game->_script->readInt16());
431 	uint16 var4 = READ_VAR_UINT16(_vm->_game->_script->readInt16());
432 
433 	warning("Dynasty Stub: GobFunc 100: %d, %d, %d, %d", var1, var2, var3, var4);
434 
435 	var3 = (var3 + var1) - 1;
436 	var4 = (var4 + var2) - 1;
437 }
438 
o5_gob200(OpGobParams & params)439 void Inter_v5::o5_gob200(OpGobParams &params) {
440 	uint16 var1 = _vm->_game->_script->readUint16(); // index into the spritesArray
441 	uint16 var2 = _vm->_game->_script->readUint16();
442 	uint16 var3 = _vm->_game->_script->readUint16();
443 
444 	warning("Dynasty Stub: GobFunc 200: %d, %d, %d", var1, var2, var3);
445 }
446 
447 } // End of namespace Gob
448