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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
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 ¶ms) {
420 _gob_97_98_val = 1;
421 }
422
o5_gob98(OpGobParams & params)423 void Inter_v5::o5_gob98(OpGobParams ¶ms) {
424 _gob_97_98_val = 0;
425 }
426
o5_gob100(OpGobParams & params)427 void Inter_v5::o5_gob100(OpGobParams ¶ms) {
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 ¶ms) {
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