Moved Goblin::interFunc() to Inter_v1::o1_goblinFunc(), converting its switch() into an array of function pointers + lookup table

svn-id: r19969
This commit is contained in:
Sven Hesse 2006-01-10 11:30:23 +00:00
parent 17a9edaf25
commit 71af473b76
6 changed files with 1360 additions and 899 deletions

View file

@ -2376,886 +2376,4 @@ int16 Goblin::treatItem(int16 action) {
} }
} }
void Goblin::interFunc(void) {
int16 cmd;
int16 extraData = 0;
Gob_Object *objDesc = NULL;
Gob_Object *gobDesc;
int16 xPos;
int16 yPos;
int16 x;
int16 y;
int16 item;
int16 val;
int16 layer;
int16 state;
int32 *retVarPtr;
bool objDescSet = false;
retVarPtr = (int32 *)VAR_ADDRESS(59);
cmd = _vm->_inter->load16();
_vm->_global->_inter_execPtr += 2;
if (cmd > 0 && cmd < 17) {
extraData = _vm->_inter->load16();
objDesc = _objects[extraData];
objDescSet = true;
extraData = _vm->_inter->load16();
}
if (cmd > 90 && cmd < 107) {
extraData = _vm->_inter->load16();
objDesc = _goblins[extraData];
objDescSet = true;
extraData = _vm->_inter->load16();
cmd -= 90;
}
if (cmd > 110 && cmd < 128) {
extraData = _vm->_inter->load16();
objDesc = _goblins[extraData];
objDescSet = true;
cmd -= 90;
} else if (cmd > 20 && cmd < 38) {
extraData = _vm->_inter->load16();
objDesc = _objects[extraData];
objDescSet = true;
}
/*
NB: The original gobliiins engine did not initialize the objDesc
variable, so we manually check if objDesc is properly set before
checking if it is zero. If it was not set, we do not return. This
fixes a crash in the EGA version if the life bar is depleted, because
interFunc is called multiple times with cmd == 39.
Bug #1324814
*/
if (cmd < 40 && objDescSet && objDesc == 0)
return;
debug(5, "cmd = %d", cmd);
switch (cmd) {
case 1:
objDesc->state = extraData;
if (objDesc == _actDestItemDesc)
*_destItemStateVarPtr = extraData;
break;
case 2:
objDesc->curFrame = extraData;
if (objDesc == _actDestItemDesc)
*_destItemFrameVarPtr = extraData;
break;
case 3:
objDesc->nextState = extraData;
if (objDesc == _actDestItemDesc)
*_destItemNextStateVarPtr = extraData;
break;
case 4:
objDesc->multState = extraData;
if (objDesc == _actDestItemDesc)
*_destItemMultStateVarPtr = extraData;
break;
case 5:
objDesc->order = extraData;
if (objDesc == _actDestItemDesc)
*_destItemOrderVarPtr = extraData;
break;
case 6:
objDesc->actionStartState = extraData;
if (objDesc == _actDestItemDesc)
*_destItemActStartStVarPtr = extraData;
break;
case 7:
objDesc->curLookDir = extraData;
if (objDesc == _actDestItemDesc)
*_destItemLookDirVarPtr = extraData;
break;
case 8:
objDesc->type = extraData;
if (objDesc == _actDestItemDesc)
*_destItemTypeVarPtr = extraData;
if (extraData == 0)
objDesc->toRedraw = 1;
break;
case 9:
objDesc->noTick = extraData;
if (objDesc == _actDestItemDesc)
*_destItemNoTickVarPtr = extraData;
break;
case 10:
objDesc->pickable = extraData;
if (objDesc == _actDestItemDesc)
*_destItemPickableVarPtr = extraData;
break;
case 12:
objDesc->xPos = extraData;
if (objDesc == _actDestItemDesc)
*_destItemScrXVarPtr = extraData;
break;
case 13:
objDesc->yPos = extraData;
if (objDesc == _actDestItemDesc)
*_destItemScrYVarPtr = extraData;
break;
case 14:
objDesc->doAnim = extraData;
if (objDesc == _actDestItemDesc)
*_destItemDoAnimVarPtr = extraData;
break;
case 15:
objDesc->relaxTime = extraData;
if (objDesc == _actDestItemDesc)
*_destItemRelaxVarPtr = extraData;
break;
case 16:
objDesc->maxTick = extraData;
if (objDesc == _actDestItemDesc)
*_destItemMaxTickVarPtr = extraData;
break;
case 21:
*retVarPtr = objDesc->state;
break;
case 22:
*retVarPtr = objDesc->curFrame;
break;
case 23:
*retVarPtr = objDesc->nextState;
break;
case 24:
*retVarPtr = objDesc->multState;
break;
case 25:
*retVarPtr = objDesc->order;
break;
case 26:
*retVarPtr = objDesc->actionStartState;
break;
case 27:
*retVarPtr = objDesc->curLookDir;
break;
case 28:
*retVarPtr = objDesc->type;
break;
case 29:
*retVarPtr = objDesc->noTick;
break;
case 30:
*retVarPtr = objDesc->pickable;
break;
case 32:
*retVarPtr = getObjMaxFrame(objDesc);
break;
case 33:
*retVarPtr = objDesc->xPos;
break;
case 34:
*retVarPtr = objDesc->yPos;
break;
case 35:
*retVarPtr = objDesc->doAnim;
break;
case 36:
*retVarPtr = objDesc->relaxTime;
break;
case 37:
*retVarPtr = objDesc->maxTick;
break;
case 40:
case 42:
xPos = _vm->_inter->load16();
yPos = _vm->_inter->load16();
item = _vm->_inter->load16();
if (cmd == 42) {
xPos = VAR(xPos);
yPos = VAR(yPos);
item = VAR(item);
}
for (y = 0; y < Map::kMapHeight; y++) {
for (x = 0; x < Map::kMapWidth; x++) {
if ((_vm->_map->_itemsMap[y][x] & 0xff) == item) {
_vm->_map->_itemsMap[y][x] &= 0xff00;
} else if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8)
== item) {
_vm->_map->_itemsMap[y][x] &= 0xff;
}
}
}
if (xPos < Map::kMapWidth - 1) {
if (yPos > 0) {
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 ||
(_vm->_map->_itemsMap[yPos - 1][xPos] & 0xff00) !=
0
|| (_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff00) != 0
|| (_vm->_map->_itemsMap[yPos - 1][xPos +
1] & 0xff00) != 0) {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff00)
+ item;
_vm->_map->_itemsMap[yPos - 1][xPos] =
(_vm->_map->_itemsMap[yPos -
1][xPos] & 0xff00) + item;
_vm->_map->_itemsMap[yPos][xPos + 1] =
(_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff00) + item;
_vm->_map->_itemsMap[yPos - 1][xPos + 1] =
(_vm->_map->_itemsMap[yPos - 1][xPos +
1] & 0xff00) + item;
} else {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff) +
(item << 8);
_vm->_map->_itemsMap[yPos - 1][xPos] =
(_vm->_map->_itemsMap[yPos -
1][xPos] & 0xff) + (item << 8);
_vm->_map->_itemsMap[yPos][xPos + 1] =
(_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff) + (item << 8);
_vm->_map->_itemsMap[yPos - 1][xPos + 1] =
(_vm->_map->_itemsMap[yPos - 1][xPos +
1] & 0xff) + (item << 8);
}
} else {
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 ||
(_vm->_map->_itemsMap[yPos][xPos + 1] & 0xff00) !=
0) {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff00)
+ item;
_vm->_map->_itemsMap[yPos][xPos + 1] =
(_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff00) + item;
} else {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff) +
(item << 8);
_vm->_map->_itemsMap[yPos][xPos + 1] =
(_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff) + (item << 8);
}
}
} else {
if (yPos > 0) {
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 ||
(_vm->_map->_itemsMap[yPos - 1][xPos] & 0xff00) !=
0) {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff00)
+ item;
_vm->_map->_itemsMap[yPos - 1][xPos] =
(_vm->_map->_itemsMap[yPos -
1][xPos] & 0xff00) + item;
} else {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff) +
(item << 8);
_vm->_map->_itemsMap[yPos - 1][xPos] =
(_vm->_map->_itemsMap[yPos -
1][xPos] & 0xff) + (item << 8);
}
} else {
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0) {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff00)
+ item;
} else {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff) +
(item << 8);
}
}
}
if (item < 0 || item >= 20)
break;
if (xPos > 1 && _vm->_map->_passMap[yPos][xPos - 2] == 1) {
_vm->_map->_itemPoses[item].x = xPos - 2;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 4;
break;
}
if (xPos < Map::kMapWidth - 2 && _vm->_map->_passMap[yPos][xPos + 2] == 1) {
_vm->_map->_itemPoses[item].x = xPos + 2;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 0;
break;
}
if (xPos < Map::kMapWidth - 1 && _vm->_map->_passMap[yPos][xPos + 1] == 1) {
_vm->_map->_itemPoses[item].x = xPos + 1;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 0;
break;
}
if (xPos > 0 && _vm->_map->_passMap[yPos][xPos - 1] == 1) {
_vm->_map->_itemPoses[item].x = xPos - 1;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 4;
break;
}
break;
case 41:
case 43:
xPos = _vm->_inter->load16();
yPos = _vm->_inter->load16();
if (cmd == 43) {
xPos = VAR(xPos);
yPos = VAR(yPos);
}
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0) {
*retVarPtr = (_vm->_map->_itemsMap[yPos][xPos] & 0xff00) >> 8;
} else {
*retVarPtr = _vm->_map->_itemsMap[yPos][xPos];
}
break;
case 44:
xPos = _vm->_inter->load16();
yPos = _vm->_inter->load16();
val = _vm->_inter->load16();
_vm->_map->_passMap[yPos][xPos] = val;
break;
case 50:
item = _vm->_inter->load16();
xPos = _vm->_inter->load16();
yPos = _vm->_inter->load16();
_gobPositions[item].x = xPos * 2;
_gobPositions[item].y = yPos * 2;
objDesc = _goblins[item];
objDesc->nextState = 21;
nextLayer(objDesc);
layer = objDesc->stateMach[objDesc->state][0]->layer;
_vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0,
objDesc->xPos, objDesc->yPos, 0);
objDesc->yPos =
(_gobPositions[item].y * 6 + 6) - (_vm->_scenery->_toRedrawBottom -
_vm->_scenery->_animTop);
objDesc->xPos =
_gobPositions[item].x * 12 - (_vm->_scenery->_toRedrawLeft -
_vm->_scenery->_animLeft);
objDesc->curFrame = 0;
objDesc->state = 21;
if (_currentGoblin == item) {
*_curGobScrXVarPtr = objDesc->xPos;
*_curGobScrYVarPtr = objDesc->yPos;
*_curGobFrameVarPtr = 0;
*_curGobStateVarPtr = 18;
_pressedMapX = _gobPositions[item].x;
_pressedMapY = _gobPositions[item].y;
}
break;
case 52:
item = _vm->_inter->load16();
*retVarPtr = _gobPositions[item].x >> 1;
break;
case 53:
item = _vm->_inter->load16();
*retVarPtr = _gobPositions[item].y >> 1;
break;
case 150:
item = _vm->_inter->load16();
xPos = _vm->_inter->load16();
yPos = _vm->_inter->load16();
objDesc = _goblins[item];
if (yPos == 0) {
objDesc->multState = xPos;
objDesc->nextState = xPos;
nextLayer(objDesc);
layer = objDesc->stateMach[objDesc->state][0]->layer;
objDesc->xPos =
_vm->_scenery->_animations[objDesc->animation].layers[layer]->
posX;
objDesc->yPos =
_vm->_scenery->_animations[objDesc->animation].layers[layer]->
posY;
*_curGobScrXVarPtr = objDesc->xPos;
*_curGobScrYVarPtr = objDesc->yPos;
*_curGobFrameVarPtr = 0;
*_curGobStateVarPtr = objDesc->state;
*_curGobNextStateVarPtr = objDesc->nextState;
*_curGobMultStateVarPtr = objDesc->multState;
*_curGobMaxFrameVarPtr =
getObjMaxFrame(objDesc);
_noPick = 1;
break;
}
objDesc->multState = 21;
objDesc->nextState = 21;
objDesc->state = 21;
nextLayer(objDesc);
layer = objDesc->stateMach[objDesc->state][0]->layer;
_vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0,
objDesc->xPos, objDesc->yPos, 0);
objDesc->yPos =
(yPos * 6 + 6) - (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop);
objDesc->xPos =
xPos * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft);
_gobPositions[item].x = xPos;
_pressedMapX = xPos;
_vm->_map->_curGoblinX = xPos;
_gobPositions[item].y = yPos;
_pressedMapY = yPos;
_vm->_map->_curGoblinY = yPos;
*_curGobScrXVarPtr = objDesc->xPos;
*_curGobScrYVarPtr = objDesc->yPos;
*_curGobFrameVarPtr = 0;
*_curGobStateVarPtr = 21;
*_curGobNextStateVarPtr = 21;
*_curGobMultStateVarPtr = -1;
_noPick = 0;
break;
case 250:
item = _vm->_inter->load16();
xPos = _vm->_inter->load16();
yPos = _vm->_inter->load16();
_gobPositions[item].x = xPos;
_gobPositions[item].y = yPos;
objDesc = _goblins[item];
objDesc->nextState = 21;
nextLayer(objDesc);
layer = objDesc->stateMach[objDesc->state][0]->layer;
_vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0,
objDesc->xPos, objDesc->yPos, 0);
objDesc->yPos =
(yPos * 6 + 6) - (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop);
objDesc->xPos =
xPos * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft);
objDesc->curFrame = 0;
objDesc->state = 21;
if (_currentGoblin == item) {
*_curGobScrXVarPtr = objDesc->xPos;
*_curGobScrYVarPtr = objDesc->yPos;
*_curGobFrameVarPtr = 0;
*_curGobStateVarPtr = 18;
_pressedMapX = _gobPositions[item].x;
_pressedMapY = _gobPositions[item].y;
}
break;
case 251:
item = _vm->_inter->load16();
state = _vm->_inter->load16();
objDesc = _goblins[item];
objDesc->nextState = state;
nextLayer(objDesc);
layer = objDesc->stateMach[objDesc->state][0]->layer;
objDesc->xPos =
_vm->_scenery->_animations[objDesc->animation].layers[layer]->posX;
objDesc->yPos =
_vm->_scenery->_animations[objDesc->animation].layers[layer]->posY;
if (item == _currentGoblin) {
*_curGobScrXVarPtr = objDesc->xPos;
*_curGobScrYVarPtr = objDesc->yPos;
*_curGobFrameVarPtr = 0;
*_curGobStateVarPtr = objDesc->state;
*_curGobMultStateVarPtr = objDesc->multState;
}
break;
case 252:
item = _vm->_inter->load16();
state = _vm->_inter->load16();
objDesc = _objects[item];
objDesc->nextState = state;
nextLayer(objDesc);
layer = objDesc->stateMach[objDesc->state][0]->layer;
objDesc->xPos =
_vm->_scenery->_animations[objDesc->animation].layers[layer]->posX;
objDesc->yPos =
_vm->_scenery->_animations[objDesc->animation].layers[layer]->posY;
objDesc->toRedraw = 1;
objDesc->type = 0;
if (objDesc == _actDestItemDesc) {
*_destItemScrXVarPtr = objDesc->xPos;
*_destItemScrYVarPtr = objDesc->yPos;
*_destItemStateVarPtr = objDesc->state;
*_destItemNextStateVarPtr = -1;
*_destItemMultStateVarPtr = -1;
*_destItemFrameVarPtr = 0;
}
break;
case 152:
item = _vm->_inter->load16();
val = _vm->_inter->load16();
objDesc = _objects[item];
objDesc->unk14 = val;
break;
case 200:
_itemIdInPocket = _vm->_inter->load16();
break;
case 201:
_itemIndInPocket = _vm->_inter->load16();
break;
case 202:
*retVarPtr = _itemIdInPocket;
break;
case 203:
*retVarPtr = _itemIndInPocket;
break;
case 204:
item = _vm->_inter->load16();
xPos = _vm->_inter->load16();
yPos = _vm->_inter->load16();
val = _vm->_inter->load16();
_vm->_map->_itemPoses[item].x = xPos;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = val;
break;
case 500:
extraData = _vm->_inter->load16();
objDesc = _objects[extraData];
objDesc->relaxTime--;
if (objDesc->relaxTime < 0 &&
getObjMaxFrame(objDesc) == objDesc->curFrame) {
objDesc->relaxTime = _vm->_util->getRandom(100) + 50;
objDesc->curFrame = 0;
objDesc->toRedraw = 1;
}
break;
case 502:
item = _vm->_inter->load16();
*retVarPtr = _gobPositions[item].x;
break;
case 503:
item = _vm->_inter->load16();
*retVarPtr = _gobPositions[item].y;
break;
case 600:
_pathExistence = 0;
break;
case 601:
extraData = _vm->_inter->load16();
_goblins[extraData]->visible = 1;
break;
case 602:
extraData = _vm->_inter->load16();
_goblins[extraData]->visible = 0;
break;
case 603:
extraData = _vm->_inter->load16();
item = _vm->_inter->load16();
objDesc = _objects[extraData];
if (objIntersected(objDesc, _goblins[item]) != 0)
*retVarPtr = 1;
else
*retVarPtr = 0;
break;
case 604:
extraData = _vm->_inter->load16();
item = _vm->_inter->load16();
objDesc = _goblins[extraData];
if (objIntersected(objDesc, _goblins[item]) != 0)
*retVarPtr = 1;
else
*retVarPtr = 0;
break;
case 605:
item = _vm->_inter->load16();
xPos = _vm->_inter->load16();
yPos = _vm->_inter->load16();
val = _vm->_inter->load16();
_vm->_map->_itemPoses[item].x = xPos;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = val;
break;
case 1000:
extraData = _vm->_inter->load16();
if (_vm->_game->_extHandle >= 0)
_vm->_dataio->closeData(_vm->_game->_extHandle);
loadObjects((char *)VAR_ADDRESS(extraData));
_vm->_game->_extHandle = _vm->_dataio->openData(_vm->_game->_curExtFile);
break;
case 1001:
freeAllObjects();
break;
case 1002:
animateObjects();
break;
case 1003:
drawObjects();
if (_vm->_features & GF_MAC)
_vm->_music->playBgMusic();
else if (_vm->_cdrom->getTrackPos() == -1)
_vm->_cdrom->playBgMusic();
break;
case 1004:
_vm->_map->loadMapsInitGobs();
break;
case 1005:
extraData = _vm->_inter->load16();
xPos = _vm->_inter->load16();
if ((uint16)VAR(xPos) == 0) {
item =
doMove(_goblins[_currentGoblin], 1,
(uint16)VAR(extraData));
} else {
item =
doMove(_goblins[_currentGoblin], 1, 3);
}
if (item != 0)
switchGoblin(item);
break;
case 1006:
switchGoblin(0);
break;
case 1008:
loadGobDataFromVars();
break;
case 1009:
extraData = _vm->_inter->load16();
cmd = _vm->_inter->load16();
xPos = _vm->_inter->load16();
if ((uint16)VAR(xPos) == 0) {
WRITE_VAR(cmd, treatItem((uint16)VAR(extraData)));
break;
}
WRITE_VAR(cmd, treatItem(3));
break;
case 1010:
doMove(_goblins[_currentGoblin], 0, 0);
break;
case 1011:
extraData = _vm->_inter->load16();
if (VAR(extraData) != 0)
_goesAtTarget = 1;
else
_goesAtTarget = 0;
break;
case 1015:
extraData = _vm->_inter->load16();
extraData = VAR(extraData);
_objects[10]->xPos = extraData;
extraData = _vm->_inter->load16();
extraData = VAR(extraData);
_objects[10]->yPos = extraData;
break;
case 2005:
gobDesc = _goblins[0];
if (_currentGoblin != 0) {
_goblins[_currentGoblin]->doAnim = 1;
_goblins[_currentGoblin]->nextState = 21;
nextLayer(_goblins[_currentGoblin]);
_currentGoblin = 0;
gobDesc->doAnim = 0;
gobDesc->type = 0;
gobDesc->toRedraw = 1;
_pressedMapX = _gobPositions[0].x;
_vm->_map->_destX = _gobPositions[0].x;
_gobDestX = _gobPositions[0].x;
_pressedMapY = _gobPositions[0].y;
_vm->_map->_destY = _gobPositions[0].y;
_gobDestY = _gobPositions[0].y;
*_curGobVarPtr = 0;
_pathExistence = 0;
_readyToAct = 0;
}
if (gobDesc->state != 10 && _itemIndInPocket != -1 &&
getObjMaxFrame(gobDesc) == gobDesc->curFrame) {
gobDesc->stateMach = gobDesc->realStateMach;
xPos = _gobPositions[0].x;
yPos = _gobPositions[0].y;
gobDesc->nextState = 10;
layer = nextLayer(gobDesc);
_vm->_scenery->updateAnim(layer, 0, gobDesc->animation, 0,
gobDesc->xPos, gobDesc->yPos, 0);
gobDesc->yPos =
(yPos * 6 + 6) - (_vm->_scenery->_toRedrawBottom -
_vm->_scenery->_animTop);
gobDesc->xPos =
xPos * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft);
}
if (gobDesc->state != 10)
break;
if (_itemIndInPocket == -1)
break;
if (gobDesc->curFrame != 10)
break;
objDesc = _objects[_itemIndInPocket];
objDesc->type = 0;
objDesc->toRedraw = 1;
objDesc->curFrame = 0;
objDesc->order = gobDesc->order;
objDesc->animation =
objDesc->stateMach[objDesc->state][0]->animation;
layer = objDesc->stateMach[objDesc->state][0]->layer;
_vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0,
objDesc->xPos, objDesc->yPos, 0);
objDesc->yPos +=
(_gobPositions[0].y * 6 + 5) - _vm->_scenery->_toRedrawBottom;
if (gobDesc->curLookDir == 4) {
objDesc->xPos += _gobPositions[0].x * 12 + 14
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
} else {
objDesc->xPos += _gobPositions[0].x * 12
- (_vm->_scenery->_toRedrawLeft + _vm->_scenery->_toRedrawRight) / 2;
}
_itemIndInPocket = -1;
_itemIdInPocket = -1;
_vm->_util->beep(50);
break;
default:
warning("interFunc: Unknown command %d!", cmd);
_vm->_global->_inter_execPtr -= 2;
cmd = _vm->_inter->load16();
_vm->_global->_inter_execPtr += cmd * 2;
break;
}
return;
}
} // End of namespace Gob } // End of namespace Gob

View file

@ -201,7 +201,7 @@ public:
void swapItems(int16 indexToPick, int16 idToPick); void swapItems(int16 indexToPick, int16 idToPick);
void treatItemPick(int16 itemId); void treatItemPick(int16 itemId);
int16 treatItem(int16 action); int16 treatItem(int16 action);
void interFunc(void); int16 doMove(Gob_Object *gobDesc, int16 cont, int16 action);
Goblin(GobEngine *vm); Goblin(GobEngine *vm);
@ -224,7 +224,6 @@ protected:
void moveTreatRopeStairs(Gob_Object *gobDesc); void moveTreatRopeStairs(Gob_Object *gobDesc);
void movePathFind(Gob_Object *gobDesc, int16 nextAct); void movePathFind(Gob_Object *gobDesc, int16 nextAct);
void moveAdvance(Gob_Object *gobDesc, int16 nextAct, int16 framesCount); void moveAdvance(Gob_Object *gobDesc, int16 nextAct, int16 framesCount);
int16 doMove(Gob_Object *gobDesc, int16 cont, int16 action);
}; };
} // End of namespace Gob } // End of namespace Gob

View file

@ -30,6 +30,7 @@
#include "gob/mult.h" #include "gob/mult.h"
#include "gob/goblin.h" #include "gob/goblin.h"
#include "gob/cdrom.h" #include "gob/cdrom.h"
#include "gob/map.h"
namespace Gob { namespace Gob {
@ -297,4 +298,145 @@ void Inter::renewTimeInVars(void) {
WRITE_VAR(11, t->tm_sec); WRITE_VAR(11, t->tm_sec);
} }
void Inter::manipulateMap(int16 xPos, int16 yPos, int16 item) {
for (int16 y = 0; y < Map::kMapHeight; y++) {
for (int16 x = 0; x < Map::kMapWidth; x++) {
if ((_vm->_map->_itemsMap[y][x] & 0xff) == item) {
_vm->_map->_itemsMap[y][x] &= 0xff00;
} else if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8)
== item) {
_vm->_map->_itemsMap[y][x] &= 0xff;
}
}
}
if (xPos < Map::kMapWidth - 1) {
if (yPos > 0) {
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 ||
(_vm->_map->_itemsMap[yPos - 1][xPos] & 0xff00) !=
0
|| (_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff00) != 0
|| (_vm->_map->_itemsMap[yPos - 1][xPos +
1] & 0xff00) != 0) {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff00)
+ item;
_vm->_map->_itemsMap[yPos - 1][xPos] =
(_vm->_map->_itemsMap[yPos -
1][xPos] & 0xff00) + item;
_vm->_map->_itemsMap[yPos][xPos + 1] =
(_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff00) + item;
_vm->_map->_itemsMap[yPos - 1][xPos + 1] =
(_vm->_map->_itemsMap[yPos - 1][xPos +
1] & 0xff00) + item;
} else {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff) +
(item << 8);
_vm->_map->_itemsMap[yPos - 1][xPos] =
(_vm->_map->_itemsMap[yPos -
1][xPos] & 0xff) + (item << 8);
_vm->_map->_itemsMap[yPos][xPos + 1] =
(_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff) + (item << 8);
_vm->_map->_itemsMap[yPos - 1][xPos + 1] =
(_vm->_map->_itemsMap[yPos - 1][xPos +
1] & 0xff) + (item << 8);
}
} else {
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 ||
(_vm->_map->_itemsMap[yPos][xPos + 1] & 0xff00) !=
0) {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff00)
+ item;
_vm->_map->_itemsMap[yPos][xPos + 1] =
(_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff00) + item;
} else {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff) +
(item << 8);
_vm->_map->_itemsMap[yPos][xPos + 1] =
(_vm->_map->_itemsMap[yPos][xPos +
1] & 0xff) + (item << 8);
}
}
} else {
if (yPos > 0) {
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 ||
(_vm->_map->_itemsMap[yPos - 1][xPos] & 0xff00) !=
0) {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff00)
+ item;
_vm->_map->_itemsMap[yPos - 1][xPos] =
(_vm->_map->_itemsMap[yPos -
1][xPos] & 0xff00) + item;
} else {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff) +
(item << 8);
_vm->_map->_itemsMap[yPos - 1][xPos] =
(_vm->_map->_itemsMap[yPos -
1][xPos] & 0xff) + (item << 8);
}
} else {
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0) {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff00)
+ item;
} else {
_vm->_map->_itemsMap[yPos][xPos] =
(_vm->_map->_itemsMap[yPos][xPos] & 0xff) +
(item << 8);
}
}
}
if (item < 0 || item >= 20)
return;
if (xPos > 1 && _vm->_map->_passMap[yPos][xPos - 2] == 1) {
_vm->_map->_itemPoses[item].x = xPos - 2;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 4;
return;
}
if (xPos < Map::kMapWidth - 2 && _vm->_map->_passMap[yPos][xPos + 2] == 1) {
_vm->_map->_itemPoses[item].x = xPos + 2;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 0;
return;
}
if (xPos < Map::kMapWidth - 1 && _vm->_map->_passMap[yPos][xPos + 1] == 1) {
_vm->_map->_itemPoses[item].x = xPos + 1;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 0;
return;
}
if (xPos > 0 && _vm->_map->_passMap[yPos][xPos - 1] == 1) {
_vm->_map->_itemPoses[item].x = xPos - 1;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 4;
return;
}
}
} // End of namespace Gob } // End of namespace Gob

View file

@ -22,6 +22,8 @@
#ifndef GOB_INTERPRET_H #ifndef GOB_INTERPRET_H
#define GOB_INTERPRET_H #define GOB_INTERPRET_H
#include "gob/goblin.h"
namespace Gob { namespace Gob {
// This is to help devices with small memory (PDA, smartphones, ...) // This is to help devices with small memory (PDA, smartphones, ...)
@ -57,6 +59,7 @@ public:
void callSub(int16 retFlag); void callSub(int16 retFlag);
void initControlVars(void); void initControlVars(void);
void renewTimeInVars(void); void renewTimeInVars(void);
void manipulateMap(int16 xPos, int16 yPos, int16 item);
Inter(GobEngine *vm); Inter(GobEngine *vm);
virtual ~Inter() {}; virtual ~Inter() {};
@ -67,8 +70,10 @@ protected:
virtual void setupOpcodes(void) = 0; virtual void setupOpcodes(void) = 0;
virtual void executeDrawOpcode(byte i) = 0; virtual void executeDrawOpcode(byte i) = 0;
virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) = 0; virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) = 0;
virtual void executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) = 0;
virtual const char *getOpcodeDrawDesc(byte i) = 0; virtual const char *getOpcodeDrawDesc(byte i) = 0;
virtual const char *getOpcodeFuncDesc(byte i, byte j) = 0; virtual const char *getOpcodeFuncDesc(byte i, byte j) = 0;
virtual const char *getOpcodeGoblinDesc(byte i) = 0;
}; };
class Inter_v1 : public Inter { class Inter_v1 : public Inter {
@ -79,6 +84,7 @@ public:
protected: protected:
typedef void (Inter_v1::*OpcodeDrawProcV1)(void); typedef void (Inter_v1::*OpcodeDrawProcV1)(void);
typedef bool (Inter_v1::*OpcodeFuncProcV1)(char &, int16 &, int16 &); typedef bool (Inter_v1::*OpcodeFuncProcV1)(char &, int16 &, int16 &);
typedef void (Inter_v1::*OpcodeGoblinProcV1)(int16 &, int32 *, Goblin::Gob_Object *);
struct OpcodeDrawEntryV1 { struct OpcodeDrawEntryV1 {
OpcodeDrawProcV1 proc; OpcodeDrawProcV1 proc;
const char *desc; const char *desc;
@ -87,14 +93,22 @@ protected:
OpcodeFuncProcV1 proc; OpcodeFuncProcV1 proc;
const char *desc; const char *desc;
}; };
struct OpcodeGoblinEntryV1 {
OpcodeGoblinProcV1 proc;
const char *desc;
};
const OpcodeDrawEntryV1 *_opcodesDrawV1; const OpcodeDrawEntryV1 *_opcodesDrawV1;
const OpcodeFuncEntryV1 *_opcodesFuncV1; const OpcodeFuncEntryV1 *_opcodesFuncV1;
const OpcodeGoblinEntryV1 *_opcodesGoblinV1;
static const int _goblinFuncLookUp[][2];
virtual void setupOpcodes(void); virtual void setupOpcodes(void);
virtual void executeDrawOpcode(byte i); virtual void executeDrawOpcode(byte i);
virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag); virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag);
virtual void executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
virtual const char *getOpcodeDrawDesc(byte i); virtual const char *getOpcodeDrawDesc(byte i);
virtual const char *getOpcodeFuncDesc(byte i, byte j); virtual const char *getOpcodeFuncDesc(byte i, byte j);
virtual const char *getOpcodeGoblinDesc(byte i);
void o1_loadMult(void); void o1_loadMult(void);
void o1_playMult(void); void o1_playMult(void);
@ -169,7 +183,7 @@ protected:
bool o1_return(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_return(char &cmdCount, int16 &counter, int16 &retFlag);
bool o1_speakerOn(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_speakerOn(char &cmdCount, int16 &counter, int16 &retFlag);
bool o1_speakerOff(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_speakerOff(char &cmdCount, int16 &counter, int16 &retFlag);
bool o1_func(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag);
bool o1_returnTo(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_returnTo(char &cmdCount, int16 &counter, int16 &retFlag);
bool o1_setBackDelta(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_setBackDelta(char &cmdCount, int16 &counter, int16 &retFlag);
bool o1_loadSound(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_loadSound(char &cmdCount, int16 &counter, int16 &retFlag);
@ -178,6 +192,76 @@ protected:
bool o1_animatePalette(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_animatePalette(char &cmdCount, int16 &counter, int16 &retFlag);
bool o1_animateCursor(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_animateCursor(char &cmdCount, int16 &counter, int16 &retFlag);
bool o1_blitCursor(char &cmdCount, int16 &counter, int16 &retFlag); bool o1_blitCursor(char &cmdCount, int16 &counter, int16 &retFlag);
void o1_setState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setCurFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setNextState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setOrder(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setActionStartState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setCurLookDir(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setType(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setNoTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setXPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setYPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setDoAnim(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setMaxTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getCurFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getNextState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getOrder(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getActionStartState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getCurLookDir(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getType(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getNoTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getObjMaxFrame(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getXPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getYPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getDoAnim(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getMaxTick(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_manipulateMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getItem(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_manipulateMapIndirect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getItemIndirect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setPassMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getGoblinPosXH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getGoblinPosYH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinMultState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinState(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinStateRedraw(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinUnk14(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setItemIdInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setItemIndInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getItemIdInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getItemIndInPocket(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setItemPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_decRelaxTime(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getGoblinPosX(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getGoblinPosY(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_clearPathExistence(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinVisible(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinInvisible(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getObjectIntersect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_getGoblinIntersect(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_loadObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_freeObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_animateObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_drawObjects(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_loadMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_moveGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_switchGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_loadGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_writeTreatItem(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_moveGoblin0(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinTarget(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_setGoblinObjectsPos(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
void o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
}; };
class Inter_v2 : public Inter_v1 { class Inter_v2 : public Inter_v1 {
@ -188,6 +272,7 @@ public:
protected: protected:
typedef void (Inter_v2::*OpcodeDrawProcV2)(void); typedef void (Inter_v2::*OpcodeDrawProcV2)(void);
typedef bool (Inter_v2::*OpcodeFuncProcV2)(char &, int16 &, int16 &); typedef bool (Inter_v2::*OpcodeFuncProcV2)(char &, int16 &, int16 &);
typedef void (Inter_v2::*OpcodeGoblinProcV2)(int16 &, int32 *, Goblin::Gob_Object *);
struct OpcodeDrawEntryV2 { struct OpcodeDrawEntryV2 {
OpcodeDrawProcV2 proc; OpcodeDrawProcV2 proc;
const char *desc; const char *desc;
@ -196,14 +281,22 @@ protected:
OpcodeFuncProcV2 proc; OpcodeFuncProcV2 proc;
const char *desc; const char *desc;
}; };
struct OpcodeGoblinEntryV2 {
OpcodeGoblinProcV2 proc;
const char *desc;
};
const OpcodeDrawEntryV2 *_opcodesDrawV2; const OpcodeDrawEntryV2 *_opcodesDrawV2;
const OpcodeFuncEntryV2 *_opcodesFuncV2; const OpcodeFuncEntryV2 *_opcodesFuncV2;
const OpcodeGoblinEntryV2 *_opcodesGoblinV2;
static const int _goblinFuncLookUp[][2];
virtual void setupOpcodes(void); virtual void setupOpcodes(void);
virtual void executeDrawOpcode(byte i); virtual void executeDrawOpcode(byte i);
virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag); virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag);
virtual void executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
virtual const char *getOpcodeDrawDesc(byte i); virtual const char *getOpcodeDrawDesc(byte i);
virtual const char *getOpcodeFuncDesc(byte i, byte j); virtual const char *getOpcodeFuncDesc(byte i, byte j);
virtual const char *getOpcodeGoblinDesc(byte i);
void o2_drawStub(void) { warning("Gob2 stub"); } void o2_drawStub(void) { warning("Gob2 stub"); }
}; };

File diff suppressed because it is too large Load diff

View file

@ -35,6 +35,80 @@ namespace Gob {
#define OPCODE(x) _OPCODE(Inter_v2, x) #define OPCODE(x) _OPCODE(Inter_v2, x)
const int Inter_v2::_goblinFuncLookUp[][2] = {
{1, 0},
{2, 1},
{3, 2},
{4, 3},
{5, 4},
{6, 5},
{7, 6},
{8, 7},
{9, 8},
{10, 9},
{12, 10},
{13, 11},
{14, 12},
{15, 13},
{16, 14},
{21, 15},
{22, 16},
{23, 17},
{24, 18},
{25, 19},
{26, 20},
{27, 21},
{28, 22},
{29, 23},
{30, 24},
{32, 25},
{33, 26},
{34, 27},
{35, 28},
{36, 29},
{37, 30},
{40, 31},
{41, 32},
{42, 33},
{43, 34},
{44, 35},
{50, 36},
{52, 37},
{53, 38},
{150, 39},
{152, 40},
{200, 41},
{201, 42},
{202, 43},
{203, 44},
{204, 45},
{250, 46},
{251, 47},
{252, 48},
{500, 49},
{502, 50},
{503, 51},
{600, 52},
{601, 53},
{602, 54},
{603, 55},
{604, 56},
{605, 57},
{1000, 58},
{1001, 59},
{1002, 60},
{1003, 61},
{1004, 62},
{1005, 63},
{1006, 64},
{1008, 65},
{1009, 66},
{1010, 67},
{1011, 68},
{1015, 69},
{2005, 70}
};
Inter_v2::Inter_v2(GobEngine *vm) : Inter_v1(vm) { Inter_v2::Inter_v2(GobEngine *vm) : Inter_v1(vm) {
setupOpcodes(); setupOpcodes();
} }
@ -411,7 +485,7 @@ void Inter_v2::setupOpcodes(void) {
OPCODE(o1_speakerOff), OPCODE(o1_speakerOff),
/* 24 */ /* 24 */
OPCODE(o1_putPixel), OPCODE(o1_putPixel),
OPCODE(o1_func), OPCODE(o1_goblinFunc),
OPCODE(o1_createSprite), OPCODE(o1_createSprite),
OPCODE(o1_freeSprite), OPCODE(o1_freeSprite),
/* 28 */ /* 28 */
@ -466,8 +540,101 @@ void Inter_v2::setupOpcodes(void) {
OPCODE(o1_manageDataFile), OPCODE(o1_manageDataFile),
}; };
static const OpcodeGoblinEntryV2 opcodesGoblin[71] = {
/* 00 */
OPCODE(o1_setState),
OPCODE(o1_setCurFrame),
OPCODE(o1_setNextState),
OPCODE(o1_setMultState),
/* 04 */
OPCODE(o1_setOrder),
OPCODE(o1_setActionStartState),
OPCODE(o1_setCurLookDir),
OPCODE(o1_setType),
/* 08 */
OPCODE(o1_setNoTick),
OPCODE(o1_setPickable),
OPCODE(o1_setXPos),
OPCODE(o1_setYPos),
/* 0C */
OPCODE(o1_setDoAnim),
OPCODE(o1_setRelaxTime),
OPCODE(o1_setMaxTick),
OPCODE(o1_getState),
/* 10 */
OPCODE(o1_getCurFrame),
OPCODE(o1_getNextState),
OPCODE(o1_getMultState),
OPCODE(o1_getOrder),
/* 14 */
OPCODE(o1_getActionStartState),
OPCODE(o1_getCurLookDir),
OPCODE(o1_getType),
OPCODE(o1_getNoTick),
/* 18 */
OPCODE(o1_getPickable),
OPCODE(o1_getObjMaxFrame),
OPCODE(o1_getXPos),
OPCODE(o1_getYPos),
/* 1C */
OPCODE(o1_getDoAnim),
OPCODE(o1_getRelaxTime),
OPCODE(o1_getMaxTick),
OPCODE(o1_manipulateMap),
/* 20 */
OPCODE(o1_getItem),
OPCODE(o1_manipulateMapIndirect),
OPCODE(o1_getItemIndirect),
OPCODE(o1_setPassMap),
/* 24 */
OPCODE(o1_setGoblinPosH),
OPCODE(o1_getGoblinPosXH),
OPCODE(o1_getGoblinPosYH),
OPCODE(o1_setGoblinMultState),
/* 28 */
OPCODE(o1_setGoblinUnk14),
OPCODE(o1_setItemIdInPocket),
OPCODE(o1_setItemIndInPocket),
OPCODE(o1_getItemIdInPocket),
/* 2C */
OPCODE(o1_getItemIndInPocket),
OPCODE(o1_setItemPos),
OPCODE(o1_setGoblinPos),
OPCODE(o1_setGoblinState),
/* 30 */
OPCODE(o1_setGoblinStateRedraw),
OPCODE(o1_decRelaxTime),
OPCODE(o1_getGoblinPosX),
OPCODE(o1_getGoblinPosY),
/* 34 */
OPCODE(o1_clearPathExistence),
OPCODE(o1_setGoblinVisible),
OPCODE(o1_setGoblinInvisible),
OPCODE(o1_getObjectIntersect),
/* 38 */
OPCODE(o1_getGoblinIntersect),
OPCODE(o1_setItemPos),
OPCODE(o1_loadObjects),
OPCODE(o1_freeObjects),
/* 3C */
OPCODE(o1_animateObjects),
OPCODE(o1_drawObjects),
OPCODE(o1_loadMap),
OPCODE(o1_moveGoblin),
/* 40 */
OPCODE(o1_switchGoblin),
OPCODE(o1_loadGoblin),
OPCODE(o1_writeTreatItem),
OPCODE(o1_moveGoblin0),
/* 44 */
OPCODE(o1_setGoblinTarget),
OPCODE(o1_setGoblinObjectsPos),
OPCODE(o1_initGoblin)
};
_opcodesDrawV2 = opcodesDraw; _opcodesDrawV2 = opcodesDraw;
_opcodesFuncV2 = opcodesFunc; _opcodesFuncV2 = opcodesFunc;
_opcodesGoblinV2 = opcodesGoblin;
} }
void Inter_v2::executeDrawOpcode(byte i) { void Inter_v2::executeDrawOpcode(byte i) {
@ -498,6 +665,26 @@ bool Inter_v2::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter,
return false; return false;
} }
void Inter_v2::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {
debug(4, "opcodeGoblin %d (%s)", i, getOpcodeGoblinDesc(i));
OpcodeGoblinProcV2 op = NULL;
for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++)
if (_goblinFuncLookUp[j][0] == i) {
op = _opcodesGoblinV2[_goblinFuncLookUp[j][1]].proc;
break;
}
if (op == NULL) {
warning("unimplemented opcodeGoblin: %d", i);
_vm->_global->_inter_execPtr -= 2;
_vm->_global->_inter_execPtr += load16() * 2;
}
else
(this->*op) (extraData, retVarPtr, objDesc);
}
const char *Inter_v2::getOpcodeDrawDesc(byte i) { const char *Inter_v2::getOpcodeDrawDesc(byte i) {
return _opcodesDrawV2[i].desc; return _opcodesDrawV2[i].desc;
} }
@ -510,5 +697,11 @@ const char *Inter_v2::getOpcodeFuncDesc(byte i, byte j)
return _opcodesFuncV2[i*16 + j].desc; return _opcodesFuncV2[i*16 + j].desc;
} }
const char *Inter_v2::getOpcodeGoblinDesc(byte i) {
for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++)
if (_goblinFuncLookUp[j][0] == i)
return _opcodesGoblinV2[_goblinFuncLookUp[j][1]].desc;
return "";
}
} // End of namespace Gob } // End of namespace Gob