2005-04-05 18:08:02 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
|
|
|
* Copyright (C) 2004 Ivan Dubrov
|
|
|
|
* Copyright (C) 2004-2005 The ScummVM project
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2005-04-09 19:19:54 +00:00
|
|
|
* along with this program; if not, write to the Free Software
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2005-04-05 18:08:02 +00:00
|
|
|
*
|
|
|
|
* $Header$
|
|
|
|
*
|
|
|
|
*/
|
2005-04-05 15:07:40 +00:00
|
|
|
#include "gob/gob.h"
|
|
|
|
#include "gob/global.h"
|
|
|
|
#include "gob/inter.h"
|
|
|
|
#include "gob/util.h"
|
2005-04-09 19:32:29 +00:00
|
|
|
#include "gob/scenery.h"
|
2005-04-05 15:07:40 +00:00
|
|
|
#include "gob/parse.h"
|
|
|
|
#include "gob/game.h"
|
|
|
|
#include "gob/draw.h"
|
|
|
|
#include "gob/mult.h"
|
|
|
|
#include "gob/goblin.h"
|
2005-04-13 18:27:29 +00:00
|
|
|
#include "gob/cdrom.h"
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
namespace Gob {
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
Inter::Inter(GobEngine *vm) : _vm(vm) {
|
2006-01-04 01:23:20 +00:00
|
|
|
_terminate = false;
|
|
|
|
_breakFlag = false;
|
|
|
|
_animPalLowIndex = 0;
|
|
|
|
_animPalHighIndex = 0;
|
|
|
|
_animPalDir = 0;
|
|
|
|
_soundEndTimeKey = 0;
|
|
|
|
_soundStopVal = 0;
|
|
|
|
_breakFromLevel = 0;
|
|
|
|
_nestLevel = 0;
|
2006-01-03 23:14:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int16 Inter::load16(void) {
|
2006-01-04 01:48:15 +00:00
|
|
|
int16 tmp = (int16)READ_LE_UINT16(_vm->_global->_inter_execPtr);
|
|
|
|
_vm->_global->_inter_execPtr += 2;
|
2005-04-05 15:07:40 +00:00
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
char Inter::evalExpr(int16 *pRes) {
|
2005-04-05 15:07:40 +00:00
|
|
|
byte token;
|
|
|
|
|
|
|
|
//
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_parse->printExpr(99);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_parse->parseExpr(99, &token);
|
2005-04-05 15:07:40 +00:00
|
|
|
if (pRes == 0)
|
|
|
|
return token;
|
|
|
|
|
|
|
|
switch (token) {
|
|
|
|
case 20:
|
2006-01-04 01:48:15 +00:00
|
|
|
*pRes = _vm->_global->_inter_resVal;
|
2005-04-05 15:07:40 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 22:
|
|
|
|
case 23:
|
|
|
|
*pRes = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 24:
|
|
|
|
*pRes = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return token;
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
char Inter::evalBoolResult() {
|
2005-04-05 15:07:40 +00:00
|
|
|
byte token;
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_parse->printExpr(99);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_parse->parseExpr(99, &token);
|
2006-01-04 01:48:15 +00:00
|
|
|
if (token == 24 || (token == 20 && _vm->_global->_inter_resVal != 0))
|
2005-04-05 15:07:40 +00:00
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Inter::animPalette(void) {
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 i;
|
2006-01-03 23:14:39 +00:00
|
|
|
Video::Color col;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-04 01:23:20 +00:00
|
|
|
if (_animPalDir == 0)
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
2006-01-04 01:48:15 +00:00
|
|
|
_vm->_video->waitRetrace(_vm->_global->_videoMode);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-04 01:23:20 +00:00
|
|
|
if (_animPalDir == -1) {
|
|
|
|
col = _vm->_draw->vgaSmallPalette[_animPalLowIndex];
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-04 01:23:20 +00:00
|
|
|
for (i = _animPalLowIndex; i < _animPalHighIndex; i++)
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_draw->vgaSmallPalette[i] = _vm->_draw->vgaSmallPalette[i + 1];
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_draw->vgaSmallPalette[_animPalHighIndex] = col;
|
2005-04-05 15:07:40 +00:00
|
|
|
} else {
|
2006-01-04 01:23:20 +00:00
|
|
|
col = _vm->_draw->vgaSmallPalette[_animPalHighIndex];
|
|
|
|
for (i = _animPalHighIndex; i > _animPalLowIndex; i--)
|
2006-01-03 23:14:39 +00:00
|
|
|
_vm->_draw->vgaSmallPalette[i] = _vm->_draw->vgaSmallPalette[i - 1];
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-04 01:23:20 +00:00
|
|
|
_vm->_draw->vgaSmallPalette[_animPalLowIndex] = col;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-04 01:48:15 +00:00
|
|
|
_vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->vgaSmallPalette;
|
|
|
|
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
void Inter::funcBlock(int16 retFlag) {
|
|
|
|
char cmdCount;
|
|
|
|
int16 counter;
|
|
|
|
byte cmd;
|
|
|
|
byte cmd2;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (_vm->_global->_inter_execPtr == 0)
|
|
|
|
return;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
_breakFlag = false;
|
|
|
|
_vm->_global->_inter_execPtr++;
|
|
|
|
cmdCount = *_vm->_global->_inter_execPtr++;
|
|
|
|
_vm->_global->_inter_execPtr += 2;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (cmdCount == 0) {
|
|
|
|
_vm->_global->_inter_execPtr = 0;
|
|
|
|
return;
|
|
|
|
}
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
counter = 0;
|
|
|
|
do {
|
|
|
|
if (_terminate)
|
|
|
|
break;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
cmd = (byte)*_vm->_global->_inter_execPtr;
|
|
|
|
if ((cmd >> 4) >= 12) {
|
|
|
|
cmd2 = 16 - (cmd >> 4);
|
|
|
|
cmd &= 0xf;
|
|
|
|
} else
|
|
|
|
cmd2 = 0;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
_vm->_global->_inter_execPtr++;
|
|
|
|
counter++;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
// debug(4, "funcBlock(%d, %d)", cmd2, cmd);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if(cmd2 == 0)
|
|
|
|
cmd >>= 4;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if(executeFuncOpcode(cmd2, cmd, cmdCount, counter, retFlag))
|
|
|
|
return;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (_breakFlag) {
|
|
|
|
if (retFlag != 2)
|
|
|
|
break;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (*_breakFromLevel == -1)
|
|
|
|
_breakFlag = false;
|
|
|
|
break;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
2006-01-05 16:06:55 +00:00
|
|
|
} while (counter != cmdCount);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
_vm->_global->_inter_execPtr = 0;
|
|
|
|
return;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
void Inter::storeKey(int16 key) {
|
|
|
|
WRITE_VAR(12, _vm->_util->getTimeKey() - _vm->_game->startTimeKey);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
WRITE_VAR(2, _vm->_global->_inter_mouseX);
|
|
|
|
WRITE_VAR(3, _vm->_global->_inter_mouseY);
|
|
|
|
WRITE_VAR(4, _vm->_game->mouseButtons);
|
|
|
|
WRITE_VAR(1, _vm->_snd->_playingSound);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (key == 0x4800)
|
|
|
|
key = 0x0b;
|
|
|
|
else if (key == 0x5000)
|
|
|
|
key = 0x0a;
|
|
|
|
else if (key == 0x4d00)
|
|
|
|
key = 0x09;
|
|
|
|
else if (key == 0x4b00)
|
|
|
|
key = 0x08;
|
|
|
|
else if (key == 0x011b)
|
|
|
|
key = 0x1b;
|
|
|
|
else if ((key & 0xff) != 0)
|
|
|
|
key &= 0xff;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
WRITE_VAR(0, key);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (key != 0)
|
|
|
|
_vm->_util->waitKey();
|
|
|
|
}
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
void Inter::checkSwitchTable(char **ppExec) {
|
|
|
|
int16 i;
|
|
|
|
int16 len;
|
|
|
|
char found;
|
|
|
|
int32 value;
|
|
|
|
char notFound;
|
|
|
|
char defFlag;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
found = 0;
|
|
|
|
notFound = 1;
|
|
|
|
*ppExec = 0;
|
|
|
|
value = _vm->_parse->parseVarIndex();
|
|
|
|
value = VAR_OFFSET(value);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
do {
|
|
|
|
len = *(int8*)_vm->_global->_inter_execPtr++; // must be a signed char typ and char is not default signed on all platforms.
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (len == -5)
|
|
|
|
break;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
for (i = 0; i < len; i++) {
|
2006-01-03 23:14:39 +00:00
|
|
|
evalExpr(0);
|
2005-08-10 15:48:50 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (_terminate)
|
|
|
|
return;
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (_vm->_global->_inter_resVal == value) {
|
|
|
|
found = 1;
|
|
|
|
notFound = 0;
|
|
|
|
}
|
2005-07-19 09:10:05 +00:00
|
|
|
}
|
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (found != 0)
|
|
|
|
*ppExec = _vm->_global->_inter_execPtr;
|
2005-04-11 19:34:51 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
_vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2;
|
|
|
|
found = 0;
|
|
|
|
} while (len != -5);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (len != -5)
|
|
|
|
_vm->_global->_inter_execPtr++;
|
2005-04-11 19:34:51 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
defFlag = *_vm->_global->_inter_execPtr;
|
|
|
|
defFlag >>= 4;
|
|
|
|
if (defFlag != 4)
|
|
|
|
return;
|
|
|
|
_vm->_global->_inter_execPtr++;
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if (notFound)
|
|
|
|
*ppExec = _vm->_global->_inter_execPtr;
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
_vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2;
|
|
|
|
}
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
void Inter::callSub(int16 retFlag) {
|
|
|
|
int16 block;
|
|
|
|
while (_vm->_global->_inter_execPtr != 0 && (char *)_vm->_global->_inter_execPtr != _vm->_game->totFileData) {
|
|
|
|
block = *_vm->_global->_inter_execPtr;
|
|
|
|
if (block == 1) {
|
|
|
|
funcBlock(retFlag);
|
|
|
|
} else if (block == 2) {
|
|
|
|
_vm->_game->collisionsBlock();
|
2005-07-19 09:10:05 +00:00
|
|
|
}
|
2006-01-05 16:06:55 +00:00
|
|
|
}
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
if ((char *)_vm->_global->_inter_execPtr == _vm->_game->totFileData)
|
|
|
|
_terminate = true;
|
|
|
|
}
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
void Inter::initControlVars(void) {
|
|
|
|
*_nestLevel = 0;
|
|
|
|
*_breakFromLevel = -1;
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
*_vm->_scenery->pCaptureCounter = 0;
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
_breakFlag = false;
|
|
|
|
_terminate = false;
|
|
|
|
_animPalDir = 0;
|
|
|
|
_soundEndTimeKey = 0;
|
|
|
|
}
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
void Inter::renewTimeInVars(void) {
|
|
|
|
struct tm *t;
|
|
|
|
time_t now = time(NULL);
|
2005-07-19 09:10:05 +00:00
|
|
|
|
2006-01-05 16:06:55 +00:00
|
|
|
t = localtime(&now);
|
2005-04-12 23:45:15 +00:00
|
|
|
|
|
|
|
WRITE_VAR(5, 1900 + t->tm_year);
|
|
|
|
WRITE_VAR(6, t->tm_mon);
|
|
|
|
WRITE_VAR(7, 0);
|
|
|
|
WRITE_VAR(8, t->tm_mday);
|
|
|
|
WRITE_VAR(9, t->tm_hour);
|
|
|
|
WRITE_VAR(10, t->tm_min);
|
|
|
|
WRITE_VAR(11, t->tm_sec);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // End of namespace Gob
|