2007-05-30 21:56:52 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
2003-04-20 16:04:50 +00:00
|
|
|
*
|
|
|
|
* 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.
|
2014-02-18 01:34:24 +00:00
|
|
|
*
|
2003-04-20 16:04:50 +00:00
|
|
|
* 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.
|
2014-02-18 01:34:24 +00:00
|
|
|
*
|
2003-04-20 16:04:50 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* 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.
|
2003-04-20 16:04:50 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2003-09-11 10:32:15 +00:00
|
|
|
#include "scumm/actor.h"
|
|
|
|
#include "scumm/charset.h"
|
|
|
|
#include "scumm/object.h"
|
2011-05-11 14:03:50 +00:00
|
|
|
#include "scumm/resource.h"
|
2009-03-20 16:33:58 +00:00
|
|
|
#include "scumm/scumm_v2.h"
|
2003-09-11 10:32:15 +00:00
|
|
|
#include "scumm/sound.h"
|
2005-04-10 12:59:17 +00:00
|
|
|
#include "scumm/util.h"
|
2003-09-11 10:32:15 +00:00
|
|
|
#include "scumm/verbs.h"
|
2003-04-20 16:04:50 +00:00
|
|
|
|
2003-10-03 18:33:57 +00:00
|
|
|
namespace Scumm {
|
|
|
|
|
2017-02-14 07:35:12 +00:00
|
|
|
// Helper functions for ManiacMansion workarounds
|
|
|
|
#define MM_SCRIPT(script) (script + (_game.version == 0 ? 0 : 5))
|
|
|
|
#define MM_VALUE(v0,v1) (_game.version == 0 ? v0 : v1)
|
|
|
|
|
2009-04-16 09:26:37 +00:00
|
|
|
#define OPCODE(i, x) _opcodes[i]._OPCODE(ScummEngine_v2, x)
|
2003-04-20 16:04:50 +00:00
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::setupOpcodes() {
|
2009-04-16 09:26:37 +00:00
|
|
|
/* 00 */
|
|
|
|
OPCODE(0x00, o5_stopObjectCode);
|
|
|
|
OPCODE(0x01, o2_putActor);
|
|
|
|
OPCODE(0x02, o5_startMusic);
|
|
|
|
OPCODE(0x03, o5_getActorRoom);
|
|
|
|
/* 04 */
|
|
|
|
OPCODE(0x04, o2_isGreaterEqual);
|
|
|
|
OPCODE(0x05, o2_drawObject);
|
|
|
|
OPCODE(0x06, o2_getActorElevation);
|
|
|
|
OPCODE(0x07, o2_setState08);
|
|
|
|
/* 08 */
|
|
|
|
OPCODE(0x08, o5_isNotEqual);
|
|
|
|
OPCODE(0x09, o5_faceActor);
|
|
|
|
OPCODE(0x0a, o2_assignVarWordIndirect);
|
|
|
|
OPCODE(0x0b, o2_setObjPreposition);
|
|
|
|
/* 0C */
|
|
|
|
OPCODE(0x0c, o2_resourceRoutines);
|
|
|
|
OPCODE(0x0d, o5_walkActorToActor);
|
|
|
|
OPCODE(0x0e, o2_putActorAtObject);
|
|
|
|
OPCODE(0x0f, o2_ifNotState08);
|
|
|
|
/* 10 */
|
|
|
|
OPCODE(0x10, o5_getObjectOwner);
|
|
|
|
OPCODE(0x11, o5_animateActor);
|
|
|
|
OPCODE(0x12, o2_panCameraTo);
|
|
|
|
OPCODE(0x13, o2_actorOps);
|
|
|
|
/* 14 */
|
|
|
|
OPCODE(0x14, o5_print);
|
|
|
|
OPCODE(0x15, o2_actorFromPos);
|
|
|
|
OPCODE(0x16, o5_getRandomNr);
|
|
|
|
OPCODE(0x17, o2_clearState02);
|
|
|
|
/* 18 */
|
|
|
|
OPCODE(0x18, o5_jumpRelative);
|
|
|
|
OPCODE(0x19, o2_doSentence);
|
|
|
|
OPCODE(0x1a, o5_move);
|
|
|
|
OPCODE(0x1b, o2_setBitVar);
|
|
|
|
/* 1C */
|
|
|
|
OPCODE(0x1c, o5_startSound);
|
|
|
|
OPCODE(0x1d, o2_ifClassOfIs);
|
|
|
|
OPCODE(0x1e, o2_walkActorTo);
|
|
|
|
OPCODE(0x1f, o2_ifState02);
|
|
|
|
/* 20 */
|
|
|
|
OPCODE(0x20, o5_stopMusic);
|
|
|
|
OPCODE(0x21, o2_putActor);
|
2009-04-19 01:01:54 +00:00
|
|
|
OPCODE(0x22, o4_saveLoadGame);
|
2009-04-16 09:26:37 +00:00
|
|
|
OPCODE(0x23, o2_getActorY);
|
|
|
|
/* 24 */
|
|
|
|
OPCODE(0x24, o2_loadRoomWithEgo);
|
|
|
|
OPCODE(0x25, o2_drawObject);
|
|
|
|
OPCODE(0x26, o5_setVarRange);
|
|
|
|
OPCODE(0x27, o2_setState04);
|
|
|
|
/* 28 */
|
|
|
|
OPCODE(0x28, o5_equalZero);
|
|
|
|
OPCODE(0x29, o2_setOwnerOf);
|
|
|
|
OPCODE(0x2a, o2_addIndirect);
|
|
|
|
OPCODE(0x2b, o5_delayVariable);
|
|
|
|
/* 2C */
|
|
|
|
OPCODE(0x2c, o2_assignVarByte);
|
|
|
|
OPCODE(0x2d, o2_putActorInRoom);
|
|
|
|
OPCODE(0x2e, o2_delay);
|
|
|
|
OPCODE(0x2f, o2_ifNotState04);
|
|
|
|
/* 30 */
|
2009-04-19 01:00:31 +00:00
|
|
|
OPCODE(0x30, o3_setBoxFlags);
|
2009-04-16 09:26:37 +00:00
|
|
|
OPCODE(0x31, o2_getBitVar);
|
|
|
|
OPCODE(0x32, o2_setCameraAt);
|
|
|
|
OPCODE(0x33, o2_roomOps);
|
|
|
|
/* 34 */
|
|
|
|
OPCODE(0x34, o5_getDist);
|
|
|
|
OPCODE(0x35, o2_findObject);
|
|
|
|
OPCODE(0x36, o2_walkActorToObject);
|
|
|
|
OPCODE(0x37, o2_setState01);
|
|
|
|
/* 38 */
|
|
|
|
OPCODE(0x38, o2_isLessEqual);
|
|
|
|
OPCODE(0x39, o2_doSentence);
|
|
|
|
OPCODE(0x3a, o2_subtract);
|
|
|
|
OPCODE(0x3b, o2_waitForActor);
|
|
|
|
/* 3C */
|
|
|
|
OPCODE(0x3c, o5_stopSound);
|
|
|
|
OPCODE(0x3d, o2_setActorElevation);
|
|
|
|
OPCODE(0x3e, o2_walkActorTo);
|
|
|
|
OPCODE(0x3f, o2_ifNotState01);
|
|
|
|
/* 40 */
|
|
|
|
OPCODE(0x40, o2_cutscene);
|
|
|
|
OPCODE(0x41, o2_putActor);
|
|
|
|
OPCODE(0x42, o2_startScript);
|
|
|
|
OPCODE(0x43, o2_getActorX);
|
|
|
|
/* 44 */
|
|
|
|
OPCODE(0x44, o2_isLess);
|
|
|
|
OPCODE(0x45, o2_drawObject);
|
|
|
|
OPCODE(0x46, o5_increment);
|
|
|
|
OPCODE(0x47, o2_clearState08);
|
|
|
|
/* 48 */
|
|
|
|
OPCODE(0x48, o5_isEqual);
|
|
|
|
OPCODE(0x49, o5_faceActor);
|
|
|
|
OPCODE(0x4a, o2_chainScript);
|
|
|
|
OPCODE(0x4b, o2_setObjPreposition);
|
|
|
|
/* 4C */
|
|
|
|
OPCODE(0x4c, o2_waitForSentence);
|
|
|
|
OPCODE(0x4d, o5_walkActorToActor);
|
|
|
|
OPCODE(0x4e, o2_putActorAtObject);
|
|
|
|
OPCODE(0x4f, o2_ifState08);
|
|
|
|
/* 50 */
|
|
|
|
OPCODE(0x50, o2_pickupObject);
|
|
|
|
OPCODE(0x51, o5_animateActor);
|
|
|
|
OPCODE(0x52, o5_actorFollowCamera);
|
|
|
|
OPCODE(0x53, o2_actorOps);
|
|
|
|
/* 54 */
|
|
|
|
OPCODE(0x54, o5_setObjectName);
|
|
|
|
OPCODE(0x55, o2_actorFromPos);
|
|
|
|
OPCODE(0x56, o5_getActorMoving);
|
|
|
|
OPCODE(0x57, o2_setState02);
|
|
|
|
/* 58 */
|
|
|
|
OPCODE(0x58, o2_beginOverride);
|
|
|
|
OPCODE(0x59, o2_doSentence);
|
|
|
|
OPCODE(0x5a, o2_add);
|
|
|
|
OPCODE(0x5b, o2_setBitVar);
|
|
|
|
/* 5C */
|
|
|
|
OPCODE(0x5c, o2_dummy);
|
|
|
|
OPCODE(0x5d, o2_ifClassOfIs);
|
|
|
|
OPCODE(0x5e, o2_walkActorTo);
|
|
|
|
OPCODE(0x5f, o2_ifNotState02);
|
|
|
|
/* 60 */
|
|
|
|
OPCODE(0x60, o2_cursorCommand);
|
|
|
|
OPCODE(0x61, o2_putActor);
|
|
|
|
OPCODE(0x62, o2_stopScript);
|
|
|
|
OPCODE(0x63, o5_getActorFacing);
|
|
|
|
/* 64 */
|
|
|
|
OPCODE(0x64, o2_loadRoomWithEgo);
|
|
|
|
OPCODE(0x65, o2_drawObject);
|
|
|
|
OPCODE(0x66, o5_getClosestObjActor);
|
|
|
|
OPCODE(0x67, o2_clearState04);
|
|
|
|
/* 68 */
|
|
|
|
OPCODE(0x68, o5_isScriptRunning);
|
|
|
|
OPCODE(0x69, o2_setOwnerOf);
|
|
|
|
OPCODE(0x6a, o2_subIndirect);
|
|
|
|
OPCODE(0x6b, o2_dummy);
|
|
|
|
/* 6C */
|
|
|
|
OPCODE(0x6c, o2_getObjPreposition);
|
|
|
|
OPCODE(0x6d, o2_putActorInRoom);
|
|
|
|
OPCODE(0x6e, o2_dummy);
|
|
|
|
OPCODE(0x6f, o2_ifState04);
|
|
|
|
/* 70 */
|
|
|
|
OPCODE(0x70, o2_lights);
|
|
|
|
OPCODE(0x71, o5_getActorCostume);
|
|
|
|
OPCODE(0x72, o5_loadRoom);
|
|
|
|
OPCODE(0x73, o2_roomOps);
|
|
|
|
/* 74 */
|
|
|
|
OPCODE(0x74, o5_getDist);
|
|
|
|
OPCODE(0x75, o2_findObject);
|
|
|
|
OPCODE(0x76, o2_walkActorToObject);
|
|
|
|
OPCODE(0x77, o2_clearState01);
|
|
|
|
/* 78 */
|
|
|
|
OPCODE(0x78, o2_isGreater);
|
|
|
|
OPCODE(0x79, o2_doSentence);
|
|
|
|
OPCODE(0x7a, o2_verbOps);
|
|
|
|
OPCODE(0x7b, o2_getActorWalkBox);
|
|
|
|
/* 7C */
|
|
|
|
OPCODE(0x7c, o5_isSoundRunning);
|
|
|
|
OPCODE(0x7d, o2_setActorElevation);
|
|
|
|
OPCODE(0x7e, o2_walkActorTo);
|
|
|
|
OPCODE(0x7f, o2_ifState01);
|
|
|
|
/* 80 */
|
|
|
|
OPCODE(0x80, o5_breakHere);
|
|
|
|
OPCODE(0x81, o2_putActor);
|
|
|
|
OPCODE(0x82, o5_startMusic);
|
|
|
|
OPCODE(0x83, o5_getActorRoom);
|
|
|
|
/* 84 */
|
|
|
|
OPCODE(0x84, o2_isGreaterEqual);
|
|
|
|
OPCODE(0x85, o2_drawObject);
|
|
|
|
OPCODE(0x86, o2_getActorElevation);
|
|
|
|
OPCODE(0x87, o2_setState08);
|
|
|
|
/* 88 */
|
|
|
|
OPCODE(0x88, o5_isNotEqual);
|
|
|
|
OPCODE(0x89, o5_faceActor);
|
|
|
|
OPCODE(0x8a, o2_assignVarWordIndirect);
|
|
|
|
OPCODE(0x8b, o2_setObjPreposition);
|
|
|
|
/* 8C */
|
|
|
|
OPCODE(0x8c, o2_resourceRoutines);
|
|
|
|
OPCODE(0x8d, o5_walkActorToActor);
|
|
|
|
OPCODE(0x8e, o2_putActorAtObject);
|
|
|
|
OPCODE(0x8f, o2_ifNotState08);
|
|
|
|
/* 90 */
|
|
|
|
OPCODE(0x90, o5_getObjectOwner);
|
|
|
|
OPCODE(0x91, o5_animateActor);
|
|
|
|
OPCODE(0x92, o2_panCameraTo);
|
|
|
|
OPCODE(0x93, o2_actorOps);
|
|
|
|
/* 94 */
|
|
|
|
OPCODE(0x94, o5_print);
|
|
|
|
OPCODE(0x95, o2_actorFromPos);
|
|
|
|
OPCODE(0x96, o5_getRandomNr);
|
|
|
|
OPCODE(0x97, o2_clearState02);
|
|
|
|
/* 98 */
|
|
|
|
OPCODE(0x98, o2_restart);
|
|
|
|
OPCODE(0x99, o2_doSentence);
|
|
|
|
OPCODE(0x9a, o5_move);
|
|
|
|
OPCODE(0x9b, o2_setBitVar);
|
|
|
|
/* 9C */
|
|
|
|
OPCODE(0x9c, o5_startSound);
|
|
|
|
OPCODE(0x9d, o2_ifClassOfIs);
|
|
|
|
OPCODE(0x9e, o2_walkActorTo);
|
|
|
|
OPCODE(0x9f, o2_ifState02);
|
|
|
|
/* A0 */
|
|
|
|
OPCODE(0xa0, o5_stopObjectCode);
|
|
|
|
OPCODE(0xa1, o2_putActor);
|
2009-04-19 01:01:54 +00:00
|
|
|
OPCODE(0xa2, o4_saveLoadGame);
|
2009-04-16 09:26:37 +00:00
|
|
|
OPCODE(0xa3, o2_getActorY);
|
|
|
|
/* A4 */
|
|
|
|
OPCODE(0xa4, o2_loadRoomWithEgo);
|
|
|
|
OPCODE(0xa5, o2_drawObject);
|
|
|
|
OPCODE(0xa6, o5_setVarRange);
|
|
|
|
OPCODE(0xa7, o2_setState04);
|
|
|
|
/* A8 */
|
|
|
|
OPCODE(0xa8, o5_notEqualZero);
|
|
|
|
OPCODE(0xa9, o2_setOwnerOf);
|
|
|
|
OPCODE(0xaa, o2_addIndirect);
|
|
|
|
OPCODE(0xab, o2_switchCostumeSet);
|
|
|
|
/* AC */
|
|
|
|
OPCODE(0xac, o2_drawSentence);
|
|
|
|
OPCODE(0xad, o2_putActorInRoom);
|
|
|
|
OPCODE(0xae, o2_waitForMessage);
|
|
|
|
OPCODE(0xaf, o2_ifNotState04);
|
|
|
|
/* B0 */
|
2009-04-19 01:00:31 +00:00
|
|
|
OPCODE(0xb0, o3_setBoxFlags);
|
2009-04-16 09:26:37 +00:00
|
|
|
OPCODE(0xb1, o2_getBitVar);
|
|
|
|
OPCODE(0xb2, o2_setCameraAt);
|
|
|
|
OPCODE(0xb3, o2_roomOps);
|
|
|
|
/* B4 */
|
|
|
|
OPCODE(0xb4, o5_getDist);
|
|
|
|
OPCODE(0xb5, o2_findObject);
|
|
|
|
OPCODE(0xb6, o2_walkActorToObject);
|
|
|
|
OPCODE(0xb7, o2_setState01);
|
|
|
|
/* B8 */
|
|
|
|
OPCODE(0xb8, o2_isLessEqual);
|
|
|
|
OPCODE(0xb9, o2_doSentence);
|
|
|
|
OPCODE(0xba, o2_subtract);
|
|
|
|
OPCODE(0xbb, o2_waitForActor);
|
|
|
|
/* BC */
|
|
|
|
OPCODE(0xbc, o5_stopSound);
|
|
|
|
OPCODE(0xbd, o2_setActorElevation);
|
|
|
|
OPCODE(0xbe, o2_walkActorTo);
|
|
|
|
OPCODE(0xbf, o2_ifNotState01);
|
|
|
|
/* C0 */
|
|
|
|
OPCODE(0xc0, o2_endCutscene);
|
|
|
|
OPCODE(0xc1, o2_putActor);
|
|
|
|
OPCODE(0xc2, o2_startScript);
|
|
|
|
OPCODE(0xc3, o2_getActorX);
|
|
|
|
/* C4 */
|
|
|
|
OPCODE(0xc4, o2_isLess);
|
|
|
|
OPCODE(0xc5, o2_drawObject);
|
|
|
|
OPCODE(0xc6, o5_decrement);
|
|
|
|
OPCODE(0xc7, o2_clearState08);
|
|
|
|
/* C8 */
|
|
|
|
OPCODE(0xc8, o5_isEqual);
|
|
|
|
OPCODE(0xc9, o5_faceActor);
|
|
|
|
OPCODE(0xca, o2_chainScript);
|
|
|
|
OPCODE(0xcb, o2_setObjPreposition);
|
|
|
|
/* CC */
|
|
|
|
OPCODE(0xcc, o5_pseudoRoom);
|
|
|
|
OPCODE(0xcd, o5_walkActorToActor);
|
|
|
|
OPCODE(0xce, o2_putActorAtObject);
|
|
|
|
OPCODE(0xcf, o2_ifState08);
|
|
|
|
/* D0 */
|
|
|
|
OPCODE(0xd0, o2_pickupObject);
|
|
|
|
OPCODE(0xd1, o5_animateActor);
|
|
|
|
OPCODE(0xd2, o5_actorFollowCamera);
|
|
|
|
OPCODE(0xd3, o2_actorOps);
|
|
|
|
/* D4 */
|
|
|
|
OPCODE(0xd4, o5_setObjectName);
|
|
|
|
OPCODE(0xd5, o2_actorFromPos);
|
|
|
|
OPCODE(0xd6, o5_getActorMoving);
|
|
|
|
OPCODE(0xd7, o2_setState02);
|
|
|
|
/* D8 */
|
|
|
|
OPCODE(0xd8, o5_printEgo);
|
|
|
|
OPCODE(0xd9, o2_doSentence);
|
|
|
|
OPCODE(0xda, o2_add);
|
|
|
|
OPCODE(0xdb, o2_setBitVar);
|
|
|
|
/* DC */
|
|
|
|
OPCODE(0xdc, o2_dummy);
|
|
|
|
OPCODE(0xdd, o2_ifClassOfIs);
|
|
|
|
OPCODE(0xde, o2_walkActorTo);
|
|
|
|
OPCODE(0xdf, o2_ifNotState02);
|
|
|
|
/* E0 */
|
|
|
|
OPCODE(0xe0, o2_cursorCommand);
|
|
|
|
OPCODE(0xe1, o2_putActor);
|
|
|
|
OPCODE(0xe2, o2_stopScript);
|
|
|
|
OPCODE(0xe3, o5_getActorFacing);
|
|
|
|
/* E4 */
|
|
|
|
OPCODE(0xe4, o2_loadRoomWithEgo);
|
|
|
|
OPCODE(0xe5, o2_drawObject);
|
|
|
|
OPCODE(0xe6, o5_getClosestObjActor);
|
|
|
|
OPCODE(0xe7, o2_clearState04);
|
|
|
|
/* E8 */
|
|
|
|
OPCODE(0xe8, o5_isScriptRunning);
|
|
|
|
OPCODE(0xe9, o2_setOwnerOf);
|
|
|
|
OPCODE(0xea, o2_subIndirect);
|
|
|
|
OPCODE(0xeb, o2_dummy);
|
|
|
|
/* EC */
|
|
|
|
OPCODE(0xec, o2_getObjPreposition);
|
|
|
|
OPCODE(0xed, o2_putActorInRoom);
|
|
|
|
OPCODE(0xee, o2_dummy);
|
|
|
|
OPCODE(0xef, o2_ifState04);
|
|
|
|
/* F0 */
|
|
|
|
OPCODE(0xf0, o2_lights);
|
|
|
|
OPCODE(0xf1, o5_getActorCostume);
|
|
|
|
OPCODE(0xf2, o5_loadRoom);
|
|
|
|
OPCODE(0xf3, o2_roomOps);
|
|
|
|
/* F4 */
|
|
|
|
OPCODE(0xf4, o5_getDist);
|
|
|
|
OPCODE(0xf5, o2_findObject);
|
|
|
|
OPCODE(0xf6, o2_walkActorToObject);
|
|
|
|
OPCODE(0xf7, o2_clearState01);
|
|
|
|
/* F8 */
|
|
|
|
OPCODE(0xf8, o2_isGreater);
|
|
|
|
OPCODE(0xf9, o2_doSentence);
|
|
|
|
OPCODE(0xfa, o2_verbOps);
|
|
|
|
OPCODE(0xfb, o2_getActorWalkBox);
|
|
|
|
/* FC */
|
|
|
|
OPCODE(0xfc, o5_isSoundRunning);
|
|
|
|
OPCODE(0xfd, o2_setActorElevation);
|
|
|
|
OPCODE(0xfe, o2_walkActorTo);
|
|
|
|
OPCODE(0xff, o2_ifState01);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-05-16 01:56:06 +00:00
|
|
|
#define SENTENCE_SCRIPT 2
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
int ScummEngine_v2::getVar() {
|
2003-05-05 09:19:15 +00:00
|
|
|
return readVar(fetchScriptByte());
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::decodeParseString() {
|
2003-08-16 08:55:29 +00:00
|
|
|
byte buffer[512];
|
2003-05-04 02:10:49 +00:00
|
|
|
byte *ptr = buffer;
|
|
|
|
byte c;
|
2003-05-14 14:22:15 +00:00
|
|
|
bool insertSpace = false;
|
|
|
|
|
2003-05-04 02:10:49 +00:00
|
|
|
while ((c = fetchScriptByte())) {
|
2003-05-14 14:22:15 +00:00
|
|
|
|
|
|
|
insertSpace = (c & 0x80) != 0;
|
|
|
|
c &= 0x7f;
|
|
|
|
|
|
|
|
if (c < 8) {
|
2003-05-04 02:10:49 +00:00
|
|
|
// Special codes as seen in CHARSET_1 etc. My guess is that they
|
|
|
|
// have a similar function as the corresponding embedded stuff in modern
|
|
|
|
// games. Hence for now we convert them to the modern format.
|
|
|
|
// This might allow us to reuse the existing code.
|
|
|
|
*ptr++ = 0xFF;
|
|
|
|
*ptr++ = c;
|
|
|
|
if (c > 3) {
|
|
|
|
*ptr++ = fetchScriptByte();
|
2003-05-22 14:22:35 +00:00
|
|
|
*ptr++ = 0;
|
2003-05-04 02:10:49 +00:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
*ptr++ = c;
|
2003-05-14 14:22:15 +00:00
|
|
|
|
|
|
|
if (insertSpace)
|
|
|
|
*ptr++ = ' ';
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2003-05-04 02:10:49 +00:00
|
|
|
}
|
|
|
|
*ptr = 0;
|
|
|
|
|
2003-05-14 13:32:43 +00:00
|
|
|
int textSlot = 0;
|
2003-05-14 13:30:52 +00:00
|
|
|
_string[textSlot].xpos = 0;
|
|
|
|
_string[textSlot].ypos = 0;
|
2006-05-14 10:40:06 +00:00
|
|
|
_string[textSlot].right = _screenWidth - 1;
|
2003-05-14 13:30:52 +00:00
|
|
|
_string[textSlot].center = false;
|
|
|
|
_string[textSlot].overhead = false;
|
2003-08-16 05:45:19 +00:00
|
|
|
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.id == GID_MANIAC && _actorToPrintStrFor == 0xFF) {
|
2012-02-04 17:34:08 +00:00
|
|
|
if (_game.version == 0) {
|
2005-05-19 01:54:37 +00:00
|
|
|
_string[textSlot].color = 14;
|
2006-04-23 00:08:18 +00:00
|
|
|
} else if (_game.features & GF_DEMO) {
|
2006-02-20 16:51:30 +00:00
|
|
|
_string[textSlot].color = (_game.version == 2) ? 15 : 1;
|
2005-05-19 01:54:37 +00:00
|
|
|
}
|
2004-03-03 03:14:22 +00:00
|
|
|
}
|
2003-05-14 13:30:52 +00:00
|
|
|
|
2004-03-15 03:09:48 +00:00
|
|
|
actorTalk(buffer);
|
2003-05-04 02:10:49 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
int ScummEngine_v2::readVar(uint var) {
|
2012-01-29 05:20:16 +00:00
|
|
|
if (_game.version >= 1 && var >= 14 && var <= 16)
|
2003-05-08 15:48:50 +00:00
|
|
|
var = _scummVars[var];
|
2003-05-04 02:10:49 +00:00
|
|
|
|
2006-09-16 13:38:43 +00:00
|
|
|
assertRange(0, var, _numVariables - 1, "variable (reading)");
|
2004-08-22 09:30:08 +00:00
|
|
|
debugC(DEBUG_VARS, "readvar(%d) = %d", var, _scummVars[var]);
|
2003-05-08 15:48:50 +00:00
|
|
|
return _scummVars[var];
|
2003-05-04 02:10:49 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::writeVar(uint var, int value) {
|
2006-09-16 13:38:43 +00:00
|
|
|
assertRange(0, var, _numVariables - 1, "variable (writing)");
|
2004-08-22 09:30:08 +00:00
|
|
|
debugC(DEBUG_VARS, "writeVar(%d) = %d", var, value);
|
2004-03-13 12:55:40 +00:00
|
|
|
|
2005-11-20 09:10:18 +00:00
|
|
|
if (VAR_CUTSCENEEXIT_KEY != 0xFF && var == VAR_CUTSCENEEXIT_KEY) {
|
|
|
|
// Remap the cutscene exit key in earlier games
|
|
|
|
if (value == 4 || value == 13 || value == 64)
|
|
|
|
value = 27;
|
|
|
|
}
|
|
|
|
|
2003-05-21 14:25:14 +00:00
|
|
|
_scummVars[var] = value;
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::getResultPosIndirect() {
|
2003-05-08 15:48:50 +00:00
|
|
|
_resultVarNumber = _scummVars[fetchScriptByte()];
|
2003-05-04 02:27:22 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::getResultPos() {
|
2003-05-04 02:27:22 +00:00
|
|
|
_resultVarNumber = fetchScriptByte();
|
|
|
|
}
|
|
|
|
|
2009-04-20 12:35:17 +00:00
|
|
|
int ScummEngine_v2::getActiveObject() {
|
|
|
|
return getVarOrDirectWord(PARAM_1);
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::setStateCommon(byte type) {
|
2009-04-20 12:35:17 +00:00
|
|
|
int obj = getActiveObject();
|
2003-04-21 08:50:16 +00:00
|
|
|
putState(obj, getState(obj) | type);
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::clearStateCommon(byte type) {
|
2009-04-20 12:35:17 +00:00
|
|
|
int obj = getActiveObject();
|
2003-04-21 12:31:08 +00:00
|
|
|
putState(obj, getState(obj) & ~type);
|
2003-04-21 08:50:16 +00:00
|
|
|
}
|
|
|
|
|
2009-04-20 12:35:17 +00:00
|
|
|
void ScummEngine_v2::ifStateCommon(byte type) {
|
|
|
|
int obj = getActiveObject();
|
|
|
|
|
|
|
|
jumpRelative((getState(obj) & type) != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScummEngine_v2::ifNotStateCommon(byte type) {
|
|
|
|
int obj = getActiveObject();
|
|
|
|
|
|
|
|
jumpRelative((getState(obj) & type) == 0);
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_setState08() {
|
2009-04-20 12:35:17 +00:00
|
|
|
int obj = getActiveObject();
|
2006-10-29 14:45:31 +00:00
|
|
|
putState(obj, getState(obj) | kObjectState_08);
|
2004-01-11 20:42:40 +00:00
|
|
|
markObjectRectAsDirty(obj);
|
2003-04-20 16:04:50 +00:00
|
|
|
clearDrawObjectQueue();
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_clearState08() {
|
2009-04-20 12:35:17 +00:00
|
|
|
int obj = getActiveObject();
|
2006-10-29 14:45:31 +00:00
|
|
|
putState(obj, getState(obj) & ~kObjectState_08);
|
2004-01-11 20:42:40 +00:00
|
|
|
markObjectRectAsDirty(obj);
|
2003-04-20 16:04:50 +00:00
|
|
|
clearDrawObjectQueue();
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_setState04() {
|
2006-10-29 14:45:31 +00:00
|
|
|
setStateCommon(kObjectStateLocked);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_clearState04() {
|
2006-10-29 14:45:31 +00:00
|
|
|
clearStateCommon(kObjectStateLocked);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_setState02() {
|
2006-10-29 14:45:31 +00:00
|
|
|
setStateCommon(kObjectStateUntouchable);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_clearState02() {
|
2006-10-29 14:45:31 +00:00
|
|
|
clearStateCommon(kObjectStateUntouchable);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_setState01() {
|
2006-10-29 14:45:31 +00:00
|
|
|
setStateCommon(kObjectStatePickupable);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_clearState01() {
|
2006-10-29 14:45:31 +00:00
|
|
|
clearStateCommon(kObjectStatePickupable);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_assignVarWordIndirect() {
|
2003-05-04 02:27:22 +00:00
|
|
|
getResultPosIndirect();
|
2003-11-16 18:34:33 +00:00
|
|
|
setResult(getVarOrDirectWord(PARAM_1));
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_assignVarByte() {
|
2003-04-20 16:04:50 +00:00
|
|
|
getResultPos();
|
2003-04-27 07:52:26 +00:00
|
|
|
setResult(fetchScriptByte());
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_setObjPreposition() {
|
2003-11-16 18:34:33 +00:00
|
|
|
int obj = getVarOrDirectWord(PARAM_1);
|
2003-05-20 16:13:34 +00:00
|
|
|
int unk = fetchScriptByte();
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES)
|
2005-04-07 21:13:01 +00:00
|
|
|
return;
|
2003-04-20 16:04:50 +00:00
|
|
|
|
|
|
|
if (whereIsObject(obj) != WIO_NOT_FOUND) {
|
2003-05-22 15:27:44 +00:00
|
|
|
// FIXME: this might not work properly the moment we save and restore the game.
|
|
|
|
byte *ptr = getOBCDFromObject(obj) + 12;
|
|
|
|
*ptr &= 0x1F;
|
|
|
|
*ptr |= unk << 5;
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_getObjPreposition() {
|
2003-04-21 12:59:57 +00:00
|
|
|
getResultPos();
|
2003-11-16 18:34:33 +00:00
|
|
|
int obj = getVarOrDirectWord(PARAM_1);
|
2003-04-20 16:04:50 +00:00
|
|
|
|
|
|
|
if (whereIsObject(obj) != WIO_NOT_FOUND) {
|
2003-05-22 15:27:44 +00:00
|
|
|
byte *ptr = getOBCDFromObject(obj) + 12;
|
|
|
|
setResult(*ptr >> 5);
|
2003-04-20 16:04:50 +00:00
|
|
|
} else {
|
2003-04-30 11:15:11 +00:00
|
|
|
setResult(0xFF);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_setBitVar() {
|
2003-05-21 14:25:14 +00:00
|
|
|
int var = fetchScriptWord();
|
2003-11-16 18:34:33 +00:00
|
|
|
byte a = getVarOrDirectByte(PARAM_1);
|
2003-04-20 16:04:50 +00:00
|
|
|
|
2003-05-09 00:57:10 +00:00
|
|
|
int bit_var = var + a;
|
2003-04-20 16:04:50 +00:00
|
|
|
int bit_offset = bit_var & 0x0f;
|
2003-04-27 09:39:52 +00:00
|
|
|
bit_var >>= 4;
|
2003-04-20 16:04:50 +00:00
|
|
|
|
2003-11-16 18:34:33 +00:00
|
|
|
if (getVarOrDirectByte(PARAM_2))
|
2003-05-08 15:48:50 +00:00
|
|
|
_scummVars[bit_var] |= (1 << bit_offset);
|
2003-04-20 16:04:50 +00:00
|
|
|
else
|
2003-05-08 15:48:50 +00:00
|
|
|
_scummVars[bit_var] &= ~(1 << bit_offset);
|
2003-05-21 14:25:14 +00:00
|
|
|
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_getBitVar() {
|
2003-04-20 16:04:50 +00:00
|
|
|
getResultPos();
|
2003-05-21 14:25:14 +00:00
|
|
|
int var = fetchScriptWord();
|
2003-11-16 18:34:33 +00:00
|
|
|
byte a = getVarOrDirectByte(PARAM_1);
|
2003-04-20 16:04:50 +00:00
|
|
|
|
2003-05-09 00:57:10 +00:00
|
|
|
int bit_var = var + a;
|
2003-04-20 16:04:50 +00:00
|
|
|
int bit_offset = bit_var & 0x0f;
|
2003-04-27 09:39:52 +00:00
|
|
|
bit_var >>= 4;
|
2003-04-20 16:04:50 +00:00
|
|
|
|
2003-11-26 08:53:53 +00:00
|
|
|
setResult((_scummVars[bit_var] & (1 << bit_offset)) ? 1 : 0);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_ifState08() {
|
2006-10-29 14:45:31 +00:00
|
|
|
ifStateCommon(kObjectState_08);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_ifNotState08() {
|
2006-10-29 14:45:31 +00:00
|
|
|
ifNotStateCommon(kObjectState_08);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_ifState04() {
|
2006-10-29 14:45:31 +00:00
|
|
|
ifStateCommon(kObjectStateLocked);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_ifNotState04() {
|
2006-10-29 14:45:31 +00:00
|
|
|
ifNotStateCommon(kObjectStateLocked);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_ifState02() {
|
2006-10-29 14:45:31 +00:00
|
|
|
ifStateCommon(kObjectStateUntouchable);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_ifNotState02() {
|
2006-10-29 14:45:31 +00:00
|
|
|
ifNotStateCommon(kObjectStateUntouchable);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_ifState01() {
|
2006-10-29 14:45:31 +00:00
|
|
|
ifStateCommon(kObjectStatePickupable);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_ifNotState01() {
|
2006-10-29 14:45:31 +00:00
|
|
|
ifNotStateCommon(kObjectStatePickupable);
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_addIndirect() {
|
2003-04-20 16:04:50 +00:00
|
|
|
int a;
|
2003-05-04 02:27:22 +00:00
|
|
|
getResultPosIndirect();
|
2003-11-16 18:34:33 +00:00
|
|
|
a = getVarOrDirectWord(PARAM_1);
|
2003-05-08 15:48:50 +00:00
|
|
|
_scummVars[_resultVarNumber] += a;
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_subIndirect() {
|
2003-04-20 16:04:50 +00:00
|
|
|
int a;
|
2003-05-04 02:27:22 +00:00
|
|
|
getResultPosIndirect();
|
2003-11-16 18:34:33 +00:00
|
|
|
a = getVarOrDirectWord(PARAM_1);
|
2003-05-08 15:48:50 +00:00
|
|
|
_scummVars[_resultVarNumber] -= a;
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_add() {
|
2003-05-22 22:42:44 +00:00
|
|
|
int a;
|
|
|
|
getResultPos();
|
2003-11-16 18:34:33 +00:00
|
|
|
a = getVarOrDirectWord(PARAM_1);
|
2003-05-22 22:42:44 +00:00
|
|
|
_scummVars[_resultVarNumber] += a;
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_subtract() {
|
2003-05-22 22:42:44 +00:00
|
|
|
int a;
|
|
|
|
getResultPos();
|
2003-11-16 18:34:33 +00:00
|
|
|
a = getVarOrDirectWord(PARAM_1);
|
2003-05-22 22:42:44 +00:00
|
|
|
_scummVars[_resultVarNumber] -= a;
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_waitForActor() {
|
2003-11-16 18:34:33 +00:00
|
|
|
Actor *a = derefActor(getVarOrDirectByte(PARAM_1), "o2_waitForActor");
|
2005-03-11 01:10:06 +00:00
|
|
|
if (a->_moving) {
|
2003-04-21 12:59:57 +00:00
|
|
|
_scriptPointer -= 2;
|
2003-04-20 16:04:50 +00:00
|
|
|
o5_breakHere();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_waitForMessage() {
|
2003-05-08 15:48:50 +00:00
|
|
|
if (VAR(VAR_HAVE_MSG)) {
|
2003-05-04 17:39:25 +00:00
|
|
|
_scriptPointer--;
|
|
|
|
o5_breakHere();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_waitForSentence() {
|
2003-05-28 13:28:43 +00:00
|
|
|
if (!_sentenceNum && !isScriptInUse(SENTENCE_SCRIPT))
|
2003-05-04 17:39:25 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
_scriptPointer--;
|
|
|
|
o5_breakHere();
|
|
|
|
}
|
|
|
|
|
2003-11-10 08:46:40 +00:00
|
|
|
void ScummEngine_v2::o2_actorOps() {
|
2003-11-16 18:34:33 +00:00
|
|
|
int act = getVarOrDirectByte(PARAM_1);
|
|
|
|
int arg = getVarOrDirectByte(PARAM_2);
|
2003-05-23 12:07:36 +00:00
|
|
|
Actor *a;
|
2003-04-21 09:03:17 +00:00
|
|
|
int i;
|
2003-04-20 17:07:25 +00:00
|
|
|
|
2003-05-04 02:10:49 +00:00
|
|
|
_opcode = fetchScriptByte();
|
2003-05-23 12:07:36 +00:00
|
|
|
if (act == 0 && _opcode == 5) {
|
|
|
|
// This case happens in the Zak/MM bootscripts, to set the default talk color (9).
|
|
|
|
_string[0].color = arg;
|
2003-04-20 17:07:25 +00:00
|
|
|
return;
|
2003-05-03 06:48:26 +00:00
|
|
|
}
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-11-10 09:16:41 +00:00
|
|
|
a = derefActor(act, "actorOps");
|
2003-04-20 16:59:52 +00:00
|
|
|
|
2003-05-04 02:10:49 +00:00
|
|
|
switch (_opcode) {
|
2008-01-28 00:14:17 +00:00
|
|
|
case 1: // SO_SOUND
|
2005-03-11 01:10:06 +00:00
|
|
|
a->_sound[0] = arg;
|
2003-09-24 06:33:59 +00:00
|
|
|
break;
|
2003-11-10 09:16:41 +00:00
|
|
|
case 2: // SO_PALETTE
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.version == 1)
|
2003-09-24 06:33:59 +00:00
|
|
|
i = act;
|
|
|
|
else
|
|
|
|
i = fetchScriptByte();
|
|
|
|
|
2004-01-05 16:30:00 +00:00
|
|
|
a->setPalette(i, arg);
|
2003-09-24 06:33:59 +00:00
|
|
|
break;
|
2003-11-10 09:16:41 +00:00
|
|
|
case 3: // SO_ACTOR_NAME
|
2005-03-11 01:10:06 +00:00
|
|
|
loadPtrToResource(rtActorName, a->_number, NULL);
|
2003-09-24 06:33:59 +00:00
|
|
|
break;
|
2003-11-10 09:16:41 +00:00
|
|
|
case 4: // SO_COSTUME
|
2003-09-24 06:33:59 +00:00
|
|
|
a->setActorCostume(arg);
|
|
|
|
break;
|
2003-11-10 09:16:41 +00:00
|
|
|
case 5: // SO_TALK_COLOR
|
2006-04-23 00:08:18 +00:00
|
|
|
if (_game.id == GID_MANIAC && _game.version == 2 && (_game.features & GF_DEMO) && arg == 1)
|
2005-03-11 01:10:06 +00:00
|
|
|
a->_talkColor = 15;
|
2003-09-24 06:33:59 +00:00
|
|
|
else
|
2005-03-11 01:10:06 +00:00
|
|
|
a->_talkColor = arg;
|
2003-09-24 06:33:59 +00:00
|
|
|
break;
|
|
|
|
default:
|
2005-08-14 01:41:52 +00:00
|
|
|
error("o2_actorOps: opcode %d not yet supported", _opcode);
|
2003-04-20 16:59:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_restart() {
|
2003-06-02 02:25:24 +00:00
|
|
|
restart();
|
2003-04-20 16:04:50 +00:00
|
|
|
}
|
2003-04-20 16:59:52 +00:00
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_drawObject() {
|
2003-04-21 12:31:08 +00:00
|
|
|
int obj, idx, i;
|
|
|
|
ObjectData *od;
|
|
|
|
uint16 x, y, w, h;
|
|
|
|
int xpos, ypos;
|
2003-04-20 16:59:52 +00:00
|
|
|
|
2003-11-16 18:34:33 +00:00
|
|
|
obj = getVarOrDirectWord(PARAM_1);
|
|
|
|
xpos = getVarOrDirectByte(PARAM_2);
|
|
|
|
ypos = getVarOrDirectByte(PARAM_3);
|
2003-04-21 12:31:08 +00:00
|
|
|
|
|
|
|
idx = getObjectIndex(obj);
|
|
|
|
if (idx == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
od = &_objs[idx];
|
|
|
|
if (xpos != 0xFF) {
|
2003-11-16 20:52:57 +00:00
|
|
|
od->walk_x += (xpos * 8) - od->x_pos;
|
|
|
|
od->x_pos = xpos * 8;
|
|
|
|
od->walk_y += (ypos * 8) - od->y_pos;
|
|
|
|
od->y_pos = ypos * 8;
|
2003-04-21 12:31:08 +00:00
|
|
|
}
|
|
|
|
addObjectToDrawQue(idx);
|
|
|
|
|
|
|
|
x = od->x_pos;
|
|
|
|
y = od->y_pos;
|
|
|
|
w = od->width;
|
|
|
|
h = od->height;
|
|
|
|
|
|
|
|
i = _numLocalObjects;
|
2003-05-10 21:35:06 +00:00
|
|
|
while (i--) {
|
2003-04-21 12:31:08 +00:00
|
|
|
if (_objs[i].obj_nr && _objs[i].x_pos == x && _objs[i].y_pos == y && _objs[i].width == w && _objs[i].height == h)
|
2006-10-29 14:45:31 +00:00
|
|
|
putState(_objs[i].obj_nr, getState(_objs[i].obj_nr) & ~kObjectState_08);
|
2003-05-10 21:35:06 +00:00
|
|
|
}
|
2003-04-21 12:31:08 +00:00
|
|
|
|
2006-10-29 14:45:31 +00:00
|
|
|
putState(obj, getState(od->obj_nr) | kObjectState_08);
|
2003-04-21 12:31:08 +00:00
|
|
|
}
|
2003-04-21 14:09:16 +00:00
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_resourceRoutines() {
|
2011-05-13 12:02:53 +00:00
|
|
|
const ResType resTypes[] = {
|
|
|
|
rtInvalid,
|
|
|
|
rtInvalid,
|
2003-11-16 18:34:33 +00:00
|
|
|
rtCostume,
|
|
|
|
rtRoom,
|
2011-05-13 12:02:53 +00:00
|
|
|
rtInvalid,
|
2003-11-16 18:34:33 +00:00
|
|
|
rtScript,
|
|
|
|
rtSound
|
|
|
|
};
|
|
|
|
int resid = getVarOrDirectByte(PARAM_1);
|
2003-04-21 14:20:18 +00:00
|
|
|
int opcode = fetchScriptByte();
|
2003-04-21 14:09:16 +00:00
|
|
|
|
2011-05-13 12:02:53 +00:00
|
|
|
ResType type = rtInvalid;
|
2003-05-08 14:14:37 +00:00
|
|
|
if (0 <= (opcode >> 4) && (opcode >> 4) < (int)ARRAYSIZE(resTypes))
|
|
|
|
type = resTypes[opcode >> 4];
|
|
|
|
|
2011-05-13 12:02:53 +00:00
|
|
|
if ((opcode & 0x0f) == 0 || type == rtInvalid)
|
2003-05-08 14:14:37 +00:00
|
|
|
return;
|
|
|
|
|
2004-03-03 08:17:21 +00:00
|
|
|
// HACK V2 Maniac Mansion tries to load an invalid sound resource in demo script.
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.id == GID_MANIAC && _game.version == 2 && vm.slot[_currentScript].number == 9 && type == rtSound && resid == 1)
|
2004-03-03 08:17:21 +00:00
|
|
|
return;
|
|
|
|
|
2003-09-06 08:46:36 +00:00
|
|
|
if ((opcode & 0x0f) == 1) {
|
|
|
|
ensureResourceLoaded(type, resid);
|
2003-04-21 14:20:18 +00:00
|
|
|
} else {
|
2003-09-06 08:46:36 +00:00
|
|
|
if (opcode & 1)
|
2006-09-17 20:36:48 +00:00
|
|
|
_res->lock(type, resid);
|
2003-09-06 08:46:36 +00:00
|
|
|
else
|
2006-09-17 20:36:48 +00:00
|
|
|
_res->unlock(type, resid);
|
2003-04-21 14:20:18 +00:00
|
|
|
}
|
2003-04-21 14:09:16 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_verbOps() {
|
2003-05-14 12:26:23 +00:00
|
|
|
int verb = fetchScriptByte();
|
|
|
|
int slot, state;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2003-05-14 12:26:23 +00:00
|
|
|
switch (verb) {
|
2003-11-10 09:16:41 +00:00
|
|
|
case 0: // SO_DELETE_VERBS
|
2003-11-16 18:34:33 +00:00
|
|
|
slot = getVarOrDirectByte(PARAM_1) + 1;
|
2003-12-26 23:11:35 +00:00
|
|
|
assert(0 < slot && slot < _numVerbs);
|
2003-05-08 22:44:46 +00:00
|
|
|
killVerb(slot);
|
2003-05-04 20:07:32 +00:00
|
|
|
break;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2003-04-21 14:09:16 +00:00
|
|
|
case 0xFF: // Verb On/Off
|
2003-05-08 22:44:46 +00:00
|
|
|
verb = fetchScriptByte();
|
2003-04-21 14:09:16 +00:00
|
|
|
state = fetchScriptByte();
|
2003-05-08 22:44:46 +00:00
|
|
|
slot = getVerbSlot(verb, 0);
|
|
|
|
_verbs[slot].curmode = state;
|
2003-05-04 20:07:32 +00:00
|
|
|
break;
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-04-21 14:09:16 +00:00
|
|
|
default: { // New Verb
|
2003-11-16 20:52:57 +00:00
|
|
|
int x = fetchScriptByte() * 8;
|
|
|
|
int y = fetchScriptByte() * 8;
|
2003-11-16 18:34:33 +00:00
|
|
|
slot = getVarOrDirectByte(PARAM_1) + 1;
|
2003-08-05 16:43:33 +00:00
|
|
|
int prep = fetchScriptByte(); // Only used in V1?
|
2003-07-14 06:00:17 +00:00
|
|
|
// V1 Maniac verbs are relative to the 'verb area' - under the sentence
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES)
|
2005-04-01 01:41:20 +00:00
|
|
|
x += 8;
|
2006-02-20 16:51:30 +00:00
|
|
|
else if ((_game.id == GID_MANIAC) && (_game.version == 1))
|
2005-03-15 04:16:25 +00:00
|
|
|
y += 8;
|
2003-07-09 14:57:15 +00:00
|
|
|
|
2003-05-08 22:44:46 +00:00
|
|
|
VerbSlot *vs;
|
2003-12-26 23:11:35 +00:00
|
|
|
assert(0 < slot && slot < _numVerbs);
|
2003-05-14 12:26:23 +00:00
|
|
|
|
2003-05-08 22:44:46 +00:00
|
|
|
vs = &_verbs[slot];
|
|
|
|
vs->verbid = verb;
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES) {
|
2005-03-21 23:51:48 +00:00
|
|
|
vs->color = 1;
|
|
|
|
vs->hicolor = 1;
|
|
|
|
vs->dimcolor = 1;
|
2006-02-20 16:51:30 +00:00
|
|
|
} else if (_game.version == 1) {
|
2006-04-23 00:08:18 +00:00
|
|
|
vs->color = (_game.id == GID_MANIAC && (_game.features & GF_DEMO)) ? 16 : 5;
|
2003-07-13 15:13:43 +00:00
|
|
|
vs->hicolor = 7;
|
|
|
|
vs->dimcolor = 11;
|
|
|
|
} else {
|
2006-04-23 00:08:18 +00:00
|
|
|
vs->color = (_game.id == GID_MANIAC && (_game.features & GF_DEMO)) ? 13 : 2;
|
2003-07-13 15:13:43 +00:00
|
|
|
vs->hicolor = 14;
|
|
|
|
vs->dimcolor = 8;
|
|
|
|
}
|
2003-05-08 22:44:46 +00:00
|
|
|
vs->type = kTextVerbType;
|
2004-04-05 23:54:58 +00:00
|
|
|
vs->charset_nr = _string[0]._default.charset;
|
2003-05-08 22:44:46 +00:00
|
|
|
vs->curmode = 1;
|
|
|
|
vs->saveid = 0;
|
|
|
|
vs->key = 0;
|
|
|
|
vs->center = 0;
|
|
|
|
vs->imgindex = 0;
|
2003-08-05 16:43:33 +00:00
|
|
|
vs->prep = prep;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-01-15 19:25:17 +00:00
|
|
|
vs->curRect.left = x;
|
|
|
|
vs->curRect.top = y;
|
2005-03-21 23:51:48 +00:00
|
|
|
|
2007-02-15 10:40:20 +00:00
|
|
|
// FIXME: these keyboard map depends on the language of the game.
|
2003-05-21 23:46:02 +00:00
|
|
|
// E.g. a german keyboard has 'z' and 'y' swapped, while a french
|
2007-02-18 17:53:44 +00:00
|
|
|
// keyboard starts with "azerty", etc.
|
2007-02-15 10:40:20 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES) {
|
|
|
|
static const char keyboard[] = {
|
|
|
|
'q','w','e','r',
|
|
|
|
'a','s','d','f',
|
|
|
|
'z','x','c','v'
|
|
|
|
};
|
|
|
|
if (1 <= slot && slot <= ARRAYSIZE(keyboard))
|
|
|
|
vs->key = keyboard[slot - 1];
|
|
|
|
} else {
|
|
|
|
static const char keyboard[] = {
|
|
|
|
'q','w','e','r','t',
|
|
|
|
'a','s','d','f','g',
|
|
|
|
'z','x','c','v','b'
|
|
|
|
};
|
|
|
|
if (1 <= slot && slot <= ARRAYSIZE(keyboard))
|
|
|
|
vs->key = keyboard[slot - 1];
|
|
|
|
}
|
2003-05-08 22:44:46 +00:00
|
|
|
|
|
|
|
// It follows the verb name
|
|
|
|
loadPtrToResource(rtVerb, slot, NULL);
|
2003-05-04 20:07:32 +00:00
|
|
|
}
|
|
|
|
break;
|
2003-04-21 14:09:16 +00:00
|
|
|
}
|
2003-05-08 22:44:46 +00:00
|
|
|
|
2003-09-19 14:13:24 +00:00
|
|
|
// Force redraw of the modified verb slot
|
2003-05-08 22:44:46 +00:00
|
|
|
drawVerb(slot, 0);
|
|
|
|
verbMouseOver(0);
|
2003-04-21 14:09:16 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_doSentence() {
|
2003-04-21 14:59:19 +00:00
|
|
|
int a;
|
|
|
|
SentenceTab *st;
|
|
|
|
|
2003-11-16 18:34:33 +00:00
|
|
|
a = getVarOrDirectByte(PARAM_1);
|
2003-05-21 04:09:20 +00:00
|
|
|
if (a == 0xFC) {
|
2003-04-21 14:59:19 +00:00
|
|
|
_sentenceNum = 0;
|
2003-05-20 20:58:26 +00:00
|
|
|
stopScript(SENTENCE_SCRIPT);
|
2003-04-21 14:59:19 +00:00
|
|
|
return;
|
|
|
|
}
|
2003-05-21 04:09:20 +00:00
|
|
|
if (a == 0xFB) {
|
2012-02-13 19:26:43 +00:00
|
|
|
resetSentence();
|
2003-04-21 14:59:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-08-21 10:52:07 +00:00
|
|
|
assert(_sentenceNum < NUM_SENTENCE);
|
2003-04-21 14:59:19 +00:00
|
|
|
st = &_sentence[_sentenceNum++];
|
|
|
|
|
2003-04-28 03:13:49 +00:00
|
|
|
st->verb = a;
|
2003-11-16 18:34:33 +00:00
|
|
|
st->objectA = getVarOrDirectWord(PARAM_2);
|
|
|
|
st->objectB = getVarOrDirectWord(PARAM_3);
|
2003-05-22 14:10:20 +00:00
|
|
|
st->preposition = (st->objectB != 0);
|
2003-04-21 14:59:19 +00:00
|
|
|
st->freezeCount = 0;
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-09-10 15:02:58 +00:00
|
|
|
// Execute or print the sentence
|
|
|
|
_opcode = fetchScriptByte();
|
2004-10-22 10:25:56 +00:00
|
|
|
switch (_opcode) {
|
2003-09-10 15:02:58 +00:00
|
|
|
case 0:
|
|
|
|
// Do nothing (besides setting up the sentence above)
|
|
|
|
break;
|
2003-04-21 14:59:19 +00:00
|
|
|
case 1:
|
2003-05-16 01:56:06 +00:00
|
|
|
// Execute the sentence
|
2003-05-11 11:13:24 +00:00
|
|
|
_sentenceNum--;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2003-07-15 00:23:18 +00:00
|
|
|
if (st->verb == 254) {
|
2003-10-02 22:42:03 +00:00
|
|
|
ScummEngine::stopObjectScript(st->objectA);
|
2003-09-10 15:02:58 +00:00
|
|
|
} else {
|
2003-09-10 17:15:44 +00:00
|
|
|
bool isBackgroundScript;
|
|
|
|
bool isSpecialVerb;
|
|
|
|
if (st->verb != 253 && st->verb != 250) {
|
|
|
|
VAR(VAR_ACTIVE_VERB) = st->verb;
|
2005-07-30 21:11:48 +00:00
|
|
|
VAR(VAR_ACTIVE_OBJECT1) = st->objectA;
|
2003-09-10 17:15:44 +00:00
|
|
|
VAR(VAR_ACTIVE_OBJECT2) = st->objectB;
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-09-10 17:15:44 +00:00
|
|
|
isBackgroundScript = false;
|
|
|
|
isSpecialVerb = false;
|
|
|
|
} else {
|
|
|
|
isBackgroundScript = (st->verb == 250);
|
|
|
|
isSpecialVerb = true;
|
|
|
|
st->verb = 253;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if an object script for this object is already running. If
|
|
|
|
// so, reuse its script slot. Note that we abuse two script flags:
|
|
|
|
// freezeResistant and recursive. We use them to track two
|
|
|
|
// script flags used in V1/V2 games. The main reason we do it this
|
|
|
|
// ugly evil way is to avoid having to introduce yet another save
|
|
|
|
// game revision.
|
|
|
|
int slot = -1;
|
|
|
|
ScriptSlot *ss;
|
|
|
|
int i;
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-09-10 17:15:44 +00:00
|
|
|
ss = vm.slot;
|
|
|
|
for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
|
|
|
|
if (st->objectA == ss->number &&
|
|
|
|
ss->freezeResistant == isBackgroundScript &&
|
|
|
|
ss->recursive == isSpecialVerb &&
|
|
|
|
(ss->where == WIO_ROOM || ss->where == WIO_INVENTORY || ss->where == WIO_FLOBJECT)) {
|
|
|
|
slot = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
runObjectScript(st->objectA, st->verb, isBackgroundScript, isSpecialVerb, NULL, slot);
|
2003-09-10 15:02:58 +00:00
|
|
|
}
|
2003-04-21 14:59:19 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2003-05-16 02:16:59 +00:00
|
|
|
// Print the sentence
|
2003-05-11 11:13:24 +00:00
|
|
|
_sentenceNum--;
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-05-21 14:00:19 +00:00
|
|
|
VAR(VAR_SENTENCE_VERB) = st->verb;
|
|
|
|
VAR(VAR_SENTENCE_OBJECT1) = st->objectA;
|
|
|
|
VAR(VAR_SENTENCE_OBJECT2) = st->objectB;
|
2003-05-17 06:04:22 +00:00
|
|
|
|
2003-05-16 02:16:59 +00:00
|
|
|
o2_drawSentence();
|
2003-04-21 14:59:19 +00:00
|
|
|
break;
|
2003-09-10 15:02:58 +00:00
|
|
|
default:
|
|
|
|
error("o2_doSentence: unknown subopcode %d", _opcode);
|
2003-04-21 14:59:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-03 21:10:50 +00:00
|
|
|
void ScummEngine_v2::drawPreposition(int index) {
|
|
|
|
// The prepositions, like the fonts, were hard code in the engine. Thus
|
|
|
|
// we have to do that, too, and provde localized versions for all the
|
|
|
|
// languages MM/Zak are available in.
|
|
|
|
const char *prepositions[][5] = {
|
|
|
|
{ " ", " in", " with", " on", " to" }, // English
|
|
|
|
{ " ", " mit", " mit", " mit", " zu" }, // German
|
|
|
|
{ " ", " dans", " avec", " sur", " <" }, // French
|
|
|
|
{ " ", " in", " con", " su", " a" }, // Italian
|
|
|
|
{ " ", " en", " con", " en", " a" }, // Spanish
|
2016-01-10 01:48:57 +00:00
|
|
|
{ " ", " \x7f", " \x7f", " na", " \x7f" },// Russian
|
2012-01-03 21:10:50 +00:00
|
|
|
};
|
|
|
|
int lang;
|
|
|
|
switch (_language) {
|
|
|
|
case Common::DE_DEU:
|
|
|
|
lang = 1;
|
|
|
|
break;
|
|
|
|
case Common::FR_FRA:
|
|
|
|
lang = 2;
|
|
|
|
break;
|
|
|
|
case Common::IT_ITA:
|
|
|
|
lang = 3;
|
|
|
|
break;
|
|
|
|
case Common::ES_ESP:
|
|
|
|
lang = 4;
|
|
|
|
break;
|
2016-01-10 01:48:57 +00:00
|
|
|
case Common::RU_RUS:
|
|
|
|
lang = 5;
|
|
|
|
break;
|
2012-01-03 21:10:50 +00:00
|
|
|
default:
|
|
|
|
lang = 0; // Default to english
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_game.platform == Common::kPlatformNES) {
|
|
|
|
_sentenceBuf += (const char *)(getResourceAddress(rtCostume, 78) + VAR(VAR_SENTENCE_PREPOSITION) * 8 + 2);
|
|
|
|
} else
|
|
|
|
_sentenceBuf += prepositions[lang][index];
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_drawSentence() {
|
2003-10-02 17:43:02 +00:00
|
|
|
Common::Rect sentenceline;
|
2003-05-21 18:09:49 +00:00
|
|
|
const byte *temp;
|
2003-11-08 21:59:32 +00:00
|
|
|
int slot = getVerbSlot(VAR(VAR_SENTENCE_VERB), 0);
|
2003-08-05 16:51:40 +00:00
|
|
|
|
2012-09-26 02:17:31 +00:00
|
|
|
if (!((_userState & USERSTATE_IFACE_SENTENCE) ||
|
2012-02-04 13:49:44 +00:00
|
|
|
(_game.platform == Common::kPlatformNES && (_userState & USERSTATE_IFACE_ALL))))
|
2003-05-21 06:14:02 +00:00
|
|
|
return;
|
|
|
|
|
2003-05-22 11:40:20 +00:00
|
|
|
if (getResourceAddress(rtVerb, slot))
|
2010-05-05 20:43:22 +00:00
|
|
|
_sentenceBuf = (char *)getResourceAddress(rtVerb, slot);
|
2003-05-22 11:40:20 +00:00
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
2003-05-21 14:00:19 +00:00
|
|
|
if (VAR(VAR_SENTENCE_OBJECT1) > 0) {
|
|
|
|
temp = getObjOrActorName(VAR(VAR_SENTENCE_OBJECT1));
|
2003-05-21 11:22:03 +00:00
|
|
|
if (temp) {
|
2010-05-05 20:43:22 +00:00
|
|
|
_sentenceBuf += " ";
|
|
|
|
_sentenceBuf += (const char *)temp;
|
2003-05-21 10:13:06 +00:00
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2003-08-05 17:58:38 +00:00
|
|
|
// For V1 games, the engine must compute the preposition.
|
|
|
|
// In all other Scumm versions, this is done by the sentence script.
|
2006-02-20 16:51:30 +00:00
|
|
|
if ((_game.id == GID_MANIAC && _game.version == 1 && !(_game.platform == Common::kPlatformNES)) && (VAR(VAR_SENTENCE_PREPOSITION) == 0)) {
|
2003-08-05 17:58:38 +00:00
|
|
|
if (_verbs[slot].prep == 0xFF) {
|
|
|
|
byte *ptr = getOBCDFromObject(VAR(VAR_SENTENCE_OBJECT1));
|
|
|
|
assert(ptr);
|
2003-11-08 21:59:32 +00:00
|
|
|
VAR(VAR_SENTENCE_PREPOSITION) = (*(ptr + 12) >> 5);
|
2003-08-05 17:58:38 +00:00
|
|
|
} else
|
|
|
|
VAR(VAR_SENTENCE_PREPOSITION) = _verbs[slot].prep;
|
2003-08-05 16:51:40 +00:00
|
|
|
}
|
2003-05-16 12:58:49 +00:00
|
|
|
}
|
|
|
|
|
2003-05-25 18:56:20 +00:00
|
|
|
if (0 < VAR(VAR_SENTENCE_PREPOSITION) && VAR(VAR_SENTENCE_PREPOSITION) <= 4) {
|
2012-01-03 21:10:50 +00:00
|
|
|
drawPreposition(VAR(VAR_SENTENCE_PREPOSITION));
|
2003-05-21 23:46:02 +00:00
|
|
|
}
|
|
|
|
|
2003-05-21 14:00:19 +00:00
|
|
|
if (VAR(VAR_SENTENCE_OBJECT2) > 0) {
|
|
|
|
temp = getObjOrActorName(VAR(VAR_SENTENCE_OBJECT2));
|
2003-05-21 11:22:03 +00:00
|
|
|
if (temp) {
|
2010-05-05 20:43:22 +00:00
|
|
|
_sentenceBuf += " ";
|
|
|
|
_sentenceBuf += (const char *)temp;
|
2003-05-21 10:13:06 +00:00
|
|
|
}
|
2003-05-16 12:58:49 +00:00
|
|
|
}
|
|
|
|
|
2003-05-21 06:00:16 +00:00
|
|
|
_string[2].charset = 1;
|
2007-09-08 11:15:27 +00:00
|
|
|
_string[2].ypos = _virtscr[kVerbVirtScreen].topline;
|
2003-05-21 06:00:16 +00:00
|
|
|
_string[2].xpos = 0;
|
2007-09-08 11:15:27 +00:00
|
|
|
_string[2].right = _virtscr[kVerbVirtScreen].w - 1;
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES) {
|
2005-04-01 01:41:20 +00:00
|
|
|
_string[2].xpos = 16;
|
2005-03-21 23:51:48 +00:00
|
|
|
_string[2].color = 0;
|
2006-02-20 16:51:30 +00:00
|
|
|
} else if (_game.version == 1)
|
2003-12-15 14:54:35 +00:00
|
|
|
_string[2].color = 16;
|
2005-07-30 21:11:48 +00:00
|
|
|
else
|
2003-07-14 06:19:06 +00:00
|
|
|
_string[2].color = 13;
|
2003-05-21 06:00:16 +00:00
|
|
|
|
2005-11-01 11:27:41 +00:00
|
|
|
byte string[80];
|
2010-05-05 20:43:22 +00:00
|
|
|
const char *ptr = _sentenceBuf.c_str();
|
2005-11-01 11:27:41 +00:00
|
|
|
int i = 0, len = 0;
|
2003-07-23 14:33:57 +00:00
|
|
|
|
2005-11-01 11:27:41 +00:00
|
|
|
// Maximum length of printable characters
|
2006-05-14 10:40:06 +00:00
|
|
|
int maxChars = (_game.platform == Common::kPlatformNES) ? 60 : 40;
|
2003-07-23 14:36:18 +00:00
|
|
|
while (*ptr) {
|
2003-07-23 14:33:57 +00:00
|
|
|
if (*ptr != '@')
|
2005-11-01 11:27:41 +00:00
|
|
|
len++;
|
|
|
|
if (len > maxChars) {
|
2003-07-23 14:33:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2005-11-01 11:27:41 +00:00
|
|
|
|
|
|
|
string[i++] = *ptr++;
|
|
|
|
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES && len == 30) {
|
2005-11-01 11:27:41 +00:00
|
|
|
string[i++] = 0xFF;
|
|
|
|
string[i++] = 8;
|
|
|
|
}
|
2003-07-23 14:33:57 +00:00
|
|
|
}
|
2005-11-01 11:27:41 +00:00
|
|
|
string[i] = 0;
|
2003-07-23 14:33:57 +00:00
|
|
|
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES) {
|
2007-09-08 11:15:27 +00:00
|
|
|
sentenceline.top = _virtscr[kVerbVirtScreen].topline;
|
|
|
|
sentenceline.bottom = _virtscr[kVerbVirtScreen].topline + 16;
|
2005-04-01 01:41:20 +00:00
|
|
|
sentenceline.left = 16;
|
2007-09-08 11:15:27 +00:00
|
|
|
sentenceline.right = _virtscr[kVerbVirtScreen].w - 1;
|
2005-04-01 01:41:20 +00:00
|
|
|
} else {
|
2007-09-08 11:15:27 +00:00
|
|
|
sentenceline.top = _virtscr[kVerbVirtScreen].topline;
|
|
|
|
sentenceline.bottom = _virtscr[kVerbVirtScreen].topline + 8;
|
2005-04-01 01:41:20 +00:00
|
|
|
sentenceline.left = 0;
|
2007-09-08 11:15:27 +00:00
|
|
|
sentenceline.right = _virtscr[kVerbVirtScreen].w - 1;
|
2005-04-01 01:41:20 +00:00
|
|
|
}
|
2006-09-17 23:35:09 +00:00
|
|
|
restoreBackground(sentenceline);
|
2003-05-21 06:00:16 +00:00
|
|
|
|
2010-05-05 20:43:22 +00:00
|
|
|
drawString(2, (byte *)string);
|
2003-05-16 01:56:06 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_ifClassOfIs() {
|
2003-11-16 18:34:33 +00:00
|
|
|
int obj = getVarOrDirectWord(PARAM_1);
|
|
|
|
int clsop = getVarOrDirectByte(PARAM_2);
|
2009-04-20 12:35:17 +00:00
|
|
|
|
|
|
|
|
2003-05-23 01:14:29 +00:00
|
|
|
byte *obcd = getOBCDFromObject(obj);
|
2003-04-21 15:25:29 +00:00
|
|
|
|
2003-05-23 01:14:29 +00:00
|
|
|
if (obcd == 0) {
|
2003-04-21 15:25:29 +00:00
|
|
|
o5_jumpRelative();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-05-22 13:57:34 +00:00
|
|
|
byte cls = *(obcd + 6);
|
2009-04-20 12:35:17 +00:00
|
|
|
jumpRelative((cls & clsop) == clsop);
|
2003-04-21 15:25:29 +00:00
|
|
|
}
|
2003-04-21 15:42:55 +00:00
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_walkActorTo() {
|
2003-04-21 15:42:55 +00:00
|
|
|
int x, y;
|
|
|
|
Actor *a;
|
2005-10-23 13:34:06 +00:00
|
|
|
|
|
|
|
int act = getVarOrDirectByte(PARAM_1);
|
|
|
|
|
2006-01-22 20:46:51 +00:00
|
|
|
// WORKAROUND bug #1252606
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.id == GID_ZAK && _game.version == 1 && vm.slot[_currentScript].number == 115 && act == 249) {
|
2005-10-23 13:34:06 +00:00
|
|
|
act = VAR(VAR_EGO);
|
|
|
|
}
|
|
|
|
|
|
|
|
a = derefActor(act, "o2_walkActorTo");
|
2003-05-23 00:22:41 +00:00
|
|
|
|
2007-02-04 01:24:43 +00:00
|
|
|
x = getVarOrDirectByte(PARAM_2);
|
|
|
|
y = getVarOrDirectByte(PARAM_3);
|
2003-05-11 00:03:03 +00:00
|
|
|
|
2003-05-18 23:46:30 +00:00
|
|
|
a->startWalkActor(x, y, -1);
|
2003-04-21 15:42:55 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_putActor() {
|
2003-11-16 18:34:33 +00:00
|
|
|
int act = getVarOrDirectByte(PARAM_1);
|
2003-04-21 15:42:55 +00:00
|
|
|
int x, y;
|
|
|
|
Actor *a;
|
|
|
|
|
2003-05-23 13:24:41 +00:00
|
|
|
a = derefActor(act, "o2_putActor");
|
2007-02-04 01:24:43 +00:00
|
|
|
x = getVarOrDirectByte(PARAM_2);
|
|
|
|
y = getVarOrDirectByte(PARAM_3);
|
2003-04-21 15:42:55 +00:00
|
|
|
|
2006-11-19 00:39:48 +00:00
|
|
|
a->putActor(x, y);
|
2003-04-21 15:42:55 +00:00
|
|
|
}
|
2003-04-23 05:13:26 +00:00
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_startScript() {
|
2003-11-16 18:34:33 +00:00
|
|
|
int script = getVarOrDirectByte(PARAM_1);
|
2003-11-26 08:53:53 +00:00
|
|
|
|
2003-12-11 06:08:43 +00:00
|
|
|
if (!_copyProtection) {
|
|
|
|
// The enhanced version of Zak McKracken included in the
|
|
|
|
// SelectWare Classic Collection bundle used CD check instead
|
|
|
|
// of the usual key code check at airports.
|
2006-02-20 16:51:30 +00:00
|
|
|
if ((_game.id == GID_ZAK) && (script == 15) && (_roomResource == 45))
|
2003-12-11 06:08:43 +00:00
|
|
|
return;
|
|
|
|
}
|
2003-11-26 08:58:00 +00:00
|
|
|
|
2010-12-02 00:27:46 +00:00
|
|
|
// WORKAROUND bug #1447058: In Maniac Mansion, when the door bell
|
|
|
|
// rings, then this normally causes Ted Edison to leave his room.
|
|
|
|
// This is controlled by script 87. On the other hand, when the
|
|
|
|
// player enters Ted's room while Ted is in it, then Ted captures
|
|
|
|
// the player and puts his active ego into the cellar prison.
|
|
|
|
//
|
|
|
|
// Unfortunately, the two events can collide: If the cutscene is
|
|
|
|
// playing in which Ted captures the player (controlled by script
|
|
|
|
// 88) and simultaneously the door bell rings (due to package
|
|
|
|
// delivery...) then this leads to an assertion (in ScummVM, due to
|
|
|
|
// its stricter validity checking), or to unexpected / strange
|
|
|
|
// behavior (in the original engine). The script writers apparently
|
|
|
|
// anticipated the possibility of the door bell ringing: Before
|
|
|
|
// script 91 starts script 88, it explicitly stops script 87.
|
|
|
|
// Unfortunately, this is not quite enough, as script 87 can be
|
|
|
|
// started while script 88 is already running -- specifically, by
|
|
|
|
// the package delivery sequence.
|
|
|
|
//
|
|
|
|
// Now, one can easily suppress this particular assertion, but then
|
|
|
|
// one still gets odd behavior: Ted is in the process of
|
|
|
|
// incarcerating the player, when the door bell rings; Ted promptly
|
|
|
|
// leaves to get the package, leaving the player alone (!), but then
|
|
|
|
// moments later we cut to the cellar, where Ted just put the
|
|
|
|
// player. That seems weird and irrational (the Edisons may be mad,
|
|
|
|
// but they are not stupid when it comes to putting people into
|
|
|
|
// their dungeon ;)
|
|
|
|
//
|
|
|
|
// To avoid this, we use a somewhat more elaborate workaround: If
|
|
|
|
// script 88 or 89 are running (which control the capture resp.
|
|
|
|
// imprisonment of the player), then any attempt to start script 87
|
|
|
|
// (which makes Ted go answer the door bell) is simply ignored. This
|
|
|
|
// way, the door bell still chimes, but Ted ignores it.
|
2012-01-29 06:07:38 +00:00
|
|
|
if (_game.id == GID_MANIAC) {
|
2017-02-14 07:35:12 +00:00
|
|
|
if (script == MM_SCRIPT(82)) {
|
|
|
|
if (isScriptRunning(MM_SCRIPT(83)) || isScriptRunning(MM_SCRIPT(84)))
|
2012-01-29 06:07:38 +00:00
|
|
|
return;
|
2010-12-02 00:27:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-20 20:36:40 +00:00
|
|
|
// WORKAROUND bug #4556: Purple Tentacle can appear in the lab, after being
|
2017-02-13 06:49:26 +00:00
|
|
|
// chased out and end up stuck in the room. This bug is triggered if the player
|
|
|
|
// enters the lab within 45 minutes of first entering the mansion and has chased Purple Tentacle
|
|
|
|
// out. Eventually the cutscene with Purple Tentacle chasing Sandy in the lab
|
|
|
|
// will play. This script leaves Purple Tentacle in the room causing him to become
|
|
|
|
// a permanent resident.
|
|
|
|
// Our fix is simply to prevent the Cutscene playing, if the lab has already been stormed
|
|
|
|
if (_game.id == GID_MANIAC) {
|
|
|
|
if (_game.version >= 1 && script == 155) {
|
|
|
|
if (VAR(120) == 1)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Script numbers are different in V0
|
|
|
|
if (_game.version == 0 && script == 150) {
|
|
|
|
if (VAR(104) == 1)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-26 16:37:35 +00:00
|
|
|
runScript(script, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|
2012-01-03 21:58:25 +00:00
|
|
|
void ScummEngine_v2::stopScriptCommon(int script) {
|
2017-02-14 07:28:58 +00:00
|
|
|
// WORKAROUND bug #4112: If you enter the lab while Dr. Fred has the powered turned off
|
|
|
|
// to repair the Zom-B-Matic, the script will be stopped and the power will never turn
|
2018-05-20 20:36:40 +00:00
|
|
|
// back on. This fix forces the power on, when the player enters the lab,
|
2017-02-14 07:28:58 +00:00
|
|
|
// if the script which turned it off is running
|
|
|
|
if (_game.id == GID_MANIAC && _roomResource == 4 && isScriptRunning(MM_SCRIPT(138))) {
|
|
|
|
|
|
|
|
if (vm.slot[_currentScript].number == MM_VALUE(130, 163)) {
|
|
|
|
|
|
|
|
if (script == MM_SCRIPT(138)) {
|
|
|
|
|
|
|
|
int obj = MM_VALUE(124, 157);
|
2017-02-14 07:35:12 +00:00
|
|
|
putState(obj, getState(obj) & ~kObjectState_08);
|
2017-02-14 07:28:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-04 04:46:15 +00:00
|
|
|
if (_game.id == GID_MANIAC && _roomResource == 26 && vm.slot[_currentScript].number == 10001) {
|
|
|
|
// FIXME: Nasty hack for bug #915575
|
|
|
|
// Don't let the exit script for room 26 stop the script (116), when
|
|
|
|
// switching to the dungeon (script 89)
|
2017-02-14 07:35:12 +00:00
|
|
|
if (script == MM_SCRIPT(111) && isScriptRunning(MM_SCRIPT(84)))
|
2006-03-04 04:46:15 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-02-22 16:08:13 +00:00
|
|
|
if (script == 0)
|
|
|
|
script = vm.slot[_currentScript].number;
|
|
|
|
|
2004-02-23 09:21:22 +00:00
|
|
|
if (_currentScript != 0 && vm.slot[_currentScript].number == script)
|
|
|
|
stopObjectCode();
|
|
|
|
else
|
2004-02-23 01:10:05 +00:00
|
|
|
stopScript(script);
|
2004-02-22 16:08:13 +00:00
|
|
|
}
|
|
|
|
|
2012-01-03 21:58:25 +00:00
|
|
|
void ScummEngine_v2::o2_stopScript() {
|
|
|
|
stopScriptCommon(getVarOrDirectByte(PARAM_1));
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_panCameraTo() {
|
2006-10-19 00:26:55 +00:00
|
|
|
panCameraTo(getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER, 0);
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
|
2012-01-08 22:51:13 +00:00
|
|
|
void ScummEngine_v2::walkActorToObject(int actor, int obj) {
|
|
|
|
int x, y, dir;
|
|
|
|
getObjectXYPos(obj, x, y, dir);
|
2003-04-26 16:37:35 +00:00
|
|
|
|
2012-01-08 22:51:13 +00:00
|
|
|
Actor *a = derefActor(actor, "walkActorToObject");
|
|
|
|
AdjustBoxResult r = a->adjustXYToBeInBox(x, y);
|
|
|
|
x = r.x;
|
|
|
|
y = r.y;
|
|
|
|
|
|
|
|
a->startWalkActor(x, y, dir);
|
|
|
|
}
|
2010-10-25 08:03:55 +00:00
|
|
|
|
2012-01-08 22:51:13 +00:00
|
|
|
void ScummEngine_v2::o2_walkActorToObject() {
|
|
|
|
int actor = getVarOrDirectByte(PARAM_1);
|
|
|
|
int obj = getVarOrDirectWord(PARAM_2);
|
|
|
|
if (whereIsObject(obj) != WIO_NOT_FOUND) {
|
|
|
|
walkActorToObject(actor, obj);
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_putActorAtObject() {
|
2003-04-26 16:37:35 +00:00
|
|
|
int obj, x, y;
|
|
|
|
Actor *a;
|
|
|
|
|
2003-11-16 18:34:33 +00:00
|
|
|
a = derefActor(getVarOrDirectByte(PARAM_1), "o2_putActorAtObject");
|
|
|
|
obj = getVarOrDirectWord(PARAM_2);
|
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
|
|
|
if (whereIsObject(obj) != WIO_NOT_FOUND) {
|
2003-04-26 16:37:35 +00:00
|
|
|
getObjectXYPos(obj, x, y);
|
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
|
|
|
AdjustBoxResult r = a->adjustXYToBeInBox(x, y);
|
|
|
|
x = r.x;
|
|
|
|
y = r.y;
|
|
|
|
} else {
|
2007-02-04 01:24:43 +00:00
|
|
|
x = 30;
|
|
|
|
y = 60;
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
2003-05-23 00:04:17 +00:00
|
|
|
|
2006-11-19 00:39:48 +00:00
|
|
|
a->putActor(x, y);
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
|
2006-07-24 12:49:58 +00:00
|
|
|
void ScummEngine_v2::o2_putActorInRoom() {
|
|
|
|
Actor *a;
|
|
|
|
int act = getVarOrDirectByte(PARAM_1);
|
|
|
|
int room = getVarOrDirectByte(PARAM_2);
|
|
|
|
|
|
|
|
a = derefActor(act, "o2_putActorInRoom");
|
|
|
|
|
|
|
|
a->_room = room;
|
|
|
|
if (!room) {
|
|
|
|
if (_game.id == GID_MANIAC && _game.version <= 1 && _game.platform != Common::kPlatformNES)
|
|
|
|
a->setFacing(180);
|
|
|
|
|
|
|
|
a->putActor(0, 0, 0);
|
|
|
|
}
|
2016-12-27 22:23:54 +00:00
|
|
|
|
|
|
|
// WORKAROUND bug #2285: Caponians dont disguise after using blue crystal
|
|
|
|
// This is for a game scripting oversight.
|
|
|
|
// After first using the blue crystal, a cutscene of the two Caponians plays (script-96),
|
|
|
|
// locking object 344 (which prevents the cutscene playing again) and setting Var[245] to 0x18.
|
|
|
|
// script-5 uses this variable to set the Caponian costume
|
|
|
|
// On first apperance after using the blue crystal, the Caponians now will have the disguise on
|
|
|
|
//
|
|
|
|
// If you visit the spacecraft and ring the doorbell, Var[245] will be set to 0x1C (Disguise off)
|
|
|
|
// Using the blue crystal again, will result in the Caponian appearing without his disguise
|
|
|
|
// as Var[245] is never set back to 0x18. This WORKAROUND fixes the problem by ensuring
|
|
|
|
// Var[245] is set to have the Disguise on in most situations
|
|
|
|
//
|
|
|
|
// We don't touch the variable in the following situations
|
2018-05-20 20:36:40 +00:00
|
|
|
// If the Caponian is being put into the space ship room, or the current room is the
|
2016-12-27 22:23:54 +00:00
|
|
|
// space ship and the Caponian is being put into the backroom of the telephone company (you didnt show your fan club card)
|
|
|
|
if (_game.id == GID_ZAK && _game.version <= 2 && act == 7) {
|
|
|
|
// Is script-96 cutscene done
|
|
|
|
if ((getState(344) & kObjectStateLocked)) {
|
|
|
|
// Not 'putting' in the space ship
|
|
|
|
if (room != 10) {
|
|
|
|
// not putting in telephone back room, and not in space ship
|
|
|
|
if (room != 16 && _currentRoom != 10) {
|
|
|
|
// Set caponian costume to 'disguise on'
|
|
|
|
writeVar(245, 0x18);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-07-24 12:49:58 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_getActorElevation() {
|
2003-07-02 11:26:13 +00:00
|
|
|
getResultPos();
|
2003-11-16 18:34:33 +00:00
|
|
|
int act = getVarOrDirectByte(PARAM_1);
|
2003-07-02 11:26:13 +00:00
|
|
|
Actor *a = derefActor(act, "o2_getActorElevation");
|
2007-02-04 01:24:43 +00:00
|
|
|
setResult(a->getElevation());
|
2003-07-01 04:20:41 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_setActorElevation() {
|
2003-11-16 18:34:33 +00:00
|
|
|
int act = getVarOrDirectByte(PARAM_1);
|
|
|
|
int elevation = (int8)getVarOrDirectByte(PARAM_2);
|
2003-04-27 11:38:38 +00:00
|
|
|
|
2003-05-23 13:24:41 +00:00
|
|
|
Actor *a = derefActor(act, "o2_setActorElevation");
|
2007-02-04 01:24:43 +00:00
|
|
|
a->setElevation(elevation);
|
2003-04-27 11:38:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_actorFromPos() {
|
2003-04-26 16:37:35 +00:00
|
|
|
int x, y;
|
|
|
|
getResultPos();
|
2006-10-19 00:26:55 +00:00
|
|
|
x = getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER;
|
|
|
|
y = getVarOrDirectByte(PARAM_2) * V12_Y_MULTIPLIER;
|
2003-04-30 11:15:11 +00:00
|
|
|
setResult(getActorFromPos(x, y));
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_findObject() {
|
2005-04-20 23:53:29 +00:00
|
|
|
int obj;
|
2003-05-11 00:03:03 +00:00
|
|
|
getResultPos();
|
2006-10-19 00:26:55 +00:00
|
|
|
int x = getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER;
|
|
|
|
int y = getVarOrDirectByte(PARAM_2) * V12_Y_MULTIPLIER;
|
2005-04-20 23:53:29 +00:00
|
|
|
obj = findObject(x, y);
|
2012-01-29 16:03:37 +00:00
|
|
|
if (obj == 0 && (_game.platform == Common::kPlatformNES) && (_userState & USERSTATE_IFACE_INVENTORY)) {
|
2005-04-20 23:53:29 +00:00
|
|
|
if (_mouseOverBoxV2 >= 0 && _mouseOverBoxV2 < 4)
|
|
|
|
obj = findInventory(VAR(VAR_EGO), _mouseOverBoxV2 + _inventoryOffset + 1);
|
|
|
|
}
|
|
|
|
setResult(obj);
|
2003-05-11 00:03:03 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_getActorX() {
|
2003-04-26 16:37:35 +00:00
|
|
|
int a;
|
|
|
|
getResultPos();
|
|
|
|
|
2003-11-16 18:34:33 +00:00
|
|
|
a = getVarOrDirectByte(PARAM_1);
|
2012-01-22 21:58:10 +00:00
|
|
|
setResult(getObjX(actorToObj(a)));
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_getActorY() {
|
2003-04-26 16:37:35 +00:00
|
|
|
int a;
|
|
|
|
getResultPos();
|
|
|
|
|
2003-11-16 18:34:33 +00:00
|
|
|
a = getVarOrDirectByte(PARAM_1);
|
2012-01-22 21:58:10 +00:00
|
|
|
setResult(getObjY(actorToObj(a)));
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_isGreater() {
|
2003-07-14 19:57:44 +00:00
|
|
|
uint16 a = getVar();
|
2003-11-16 18:34:33 +00:00
|
|
|
uint16 b = getVarOrDirectWord(PARAM_1);
|
2009-04-20 12:35:17 +00:00
|
|
|
jumpRelative(b > a);
|
2003-07-14 19:57:44 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_isGreaterEqual() {
|
2003-07-14 19:57:44 +00:00
|
|
|
uint16 a = getVar();
|
2003-11-16 18:34:33 +00:00
|
|
|
uint16 b = getVarOrDirectWord(PARAM_1);
|
2009-04-20 12:35:17 +00:00
|
|
|
jumpRelative(b >= a);
|
2003-07-14 19:57:44 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_isLess() {
|
2003-07-14 19:57:44 +00:00
|
|
|
uint16 a = getVar();
|
2003-11-16 18:34:33 +00:00
|
|
|
uint16 b = getVarOrDirectWord(PARAM_1);
|
2003-07-14 19:57:44 +00:00
|
|
|
|
2009-04-20 12:35:17 +00:00
|
|
|
jumpRelative(b < a);
|
2003-07-14 19:57:44 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_isLessEqual() {
|
2003-07-14 19:57:44 +00:00
|
|
|
uint16 a = getVar();
|
2003-11-16 18:34:33 +00:00
|
|
|
uint16 b = getVarOrDirectWord(PARAM_1);
|
2009-04-20 12:35:17 +00:00
|
|
|
jumpRelative(b <= a);
|
2003-07-14 19:57:44 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_lights() {
|
2003-08-18 10:46:42 +00:00
|
|
|
int a, b, c;
|
|
|
|
|
2003-11-16 18:34:33 +00:00
|
|
|
a = getVarOrDirectByte(PARAM_1);
|
2003-08-18 10:46:42 +00:00
|
|
|
b = fetchScriptByte();
|
|
|
|
c = fetchScriptByte();
|
|
|
|
|
|
|
|
if (c == 0) {
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.id == GID_MANIAC && _game.version == 1 && !(_game.platform == Common::kPlatformNES)) {
|
2003-08-18 10:46:42 +00:00
|
|
|
// Convert older light mode values into
|
2006-10-19 00:06:59 +00:00
|
|
|
// equivalent values of later games.
|
2003-08-18 10:46:42 +00:00
|
|
|
// 0 Darkness
|
|
|
|
// 1 Flashlight
|
|
|
|
// 2 Lighted area
|
2005-04-07 21:13:01 +00:00
|
|
|
if (a == 2)
|
2005-07-30 21:11:48 +00:00
|
|
|
VAR(VAR_CURRENT_LIGHTS) = 11;
|
2005-04-07 21:13:01 +00:00
|
|
|
else if (a == 1)
|
2003-08-18 10:46:42 +00:00
|
|
|
VAR(VAR_CURRENT_LIGHTS) = 4;
|
2005-07-30 21:11:48 +00:00
|
|
|
else
|
2003-08-18 10:46:42 +00:00
|
|
|
VAR(VAR_CURRENT_LIGHTS) = 0;
|
2003-11-10 09:16:41 +00:00
|
|
|
} else
|
2003-08-18 10:46:42 +00:00
|
|
|
VAR(VAR_CURRENT_LIGHTS) = a;
|
|
|
|
} else if (c == 1) {
|
|
|
|
_flashlight.xStrips = a;
|
|
|
|
_flashlight.yStrips = b;
|
|
|
|
}
|
2005-08-06 14:34:40 +00:00
|
|
|
_fullRedraw = true;
|
2003-08-18 10:46:42 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_loadRoomWithEgo() {
|
2003-04-26 16:37:35 +00:00
|
|
|
Actor *a;
|
2003-09-11 14:11:31 +00:00
|
|
|
int obj, room, x, y, x2, y2, dir;
|
2003-04-26 16:37:35 +00:00
|
|
|
|
2003-11-16 18:34:33 +00:00
|
|
|
obj = getVarOrDirectWord(PARAM_1);
|
|
|
|
room = getVarOrDirectByte(PARAM_2);
|
2003-04-26 16:37:35 +00:00
|
|
|
|
2003-05-23 13:24:41 +00:00
|
|
|
a = derefActor(VAR(VAR_EGO), "o2_loadRoomWithEgo");
|
2003-04-26 16:37:35 +00:00
|
|
|
|
2014-11-21 23:21:32 +00:00
|
|
|
// The original interpreter sets the actors new room X/Y to the last rooms X/Y
|
|
|
|
// This fixes a problem with MM: script 161 in room 12, the 'Oomph!' script
|
|
|
|
// This scripts runs before the actor position is set to the correct room entry location
|
|
|
|
if ((_game.id == GID_MANIAC) && (_game.platform != Common::kPlatformNES)) {
|
|
|
|
a->putActor(a->getPos().x, a->getPos().y, room);
|
|
|
|
} else {
|
|
|
|
a->putActor(0, 0, room);
|
|
|
|
}
|
2003-04-26 16:37:35 +00:00
|
|
|
_egoPositioned = false;
|
|
|
|
|
2007-02-04 01:24:43 +00:00
|
|
|
x = (int8)fetchScriptByte();
|
|
|
|
y = (int8)fetchScriptByte();
|
2003-04-26 16:37:35 +00:00
|
|
|
|
2005-03-11 01:10:06 +00:00
|
|
|
startScene(a->_room, a, obj);
|
2003-04-26 16:37:35 +00:00
|
|
|
|
2003-09-11 14:11:31 +00:00
|
|
|
getObjectXYPos(obj, x2, y2, dir);
|
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
|
|
|
AdjustBoxResult r = a->adjustXYToBeInBox(x2, y2);
|
|
|
|
x2 = r.x;
|
|
|
|
y2 = r.y;
|
2003-09-11 14:11:31 +00:00
|
|
|
a->putActor(x2, y2, _currentRoom);
|
2003-09-12 00:07:42 +00:00
|
|
|
a->setDirection(dir + 180);
|
2003-09-11 14:11:31 +00:00
|
|
|
|
2006-11-19 00:39:48 +00:00
|
|
|
camera._dest.x = camera._cur.x = a->getPos().x;
|
|
|
|
setCameraAt(a->getPos().x, a->getPos().y);
|
2003-04-26 16:37:35 +00:00
|
|
|
setCameraFollows(a);
|
|
|
|
|
2005-08-06 14:34:40 +00:00
|
|
|
_fullRedraw = true;
|
2003-04-26 16:37:35 +00:00
|
|
|
|
2012-02-13 19:26:43 +00:00
|
|
|
resetSentence();
|
2003-05-18 12:52:27 +00:00
|
|
|
|
2003-07-02 14:21:13 +00:00
|
|
|
if (x >= 0 && y >= 0) {
|
2003-04-26 16:37:35 +00:00
|
|
|
a->startWalkActor(x, y, -1);
|
|
|
|
}
|
|
|
|
runScript(5, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_setOwnerOf() {
|
2003-04-26 16:37:35 +00:00
|
|
|
int obj, owner;
|
|
|
|
|
2003-11-16 18:34:33 +00:00
|
|
|
obj = getVarOrDirectWord(PARAM_1);
|
|
|
|
owner = getVarOrDirectByte(PARAM_2);
|
2003-04-26 16:37:35 +00:00
|
|
|
|
|
|
|
setOwnerOf(obj, owner);
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_delay() {
|
2003-05-04 00:41:52 +00:00
|
|
|
int delay = fetchScriptByte();
|
|
|
|
delay |= fetchScriptByte() << 8;
|
|
|
|
delay |= fetchScriptByte() << 16;
|
|
|
|
delay = 0xFFFFFF - delay;
|
|
|
|
|
|
|
|
vm.slot[_currentScript].delay = delay;
|
2005-04-07 21:13:01 +00:00
|
|
|
vm.slot[_currentScript].status = ssPaused;
|
2003-05-04 00:41:52 +00:00
|
|
|
o5_breakHere();
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_setCameraAt() {
|
2006-10-19 00:26:55 +00:00
|
|
|
setCameraAtEx(getVarOrDirectByte(PARAM_1) * V12_X_MULTIPLIER);
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_roomOps() {
|
2003-11-16 18:34:33 +00:00
|
|
|
int a = getVarOrDirectByte(PARAM_1);
|
|
|
|
int b = getVarOrDirectByte(PARAM_2);
|
2003-04-26 16:37:35 +00:00
|
|
|
|
|
|
|
_opcode = fetchScriptByte();
|
|
|
|
switch (_opcode & 0x1F) {
|
2003-11-10 09:16:41 +00:00
|
|
|
case 1: // SO_ROOM_SCROLL
|
2003-05-24 17:18:23 +00:00
|
|
|
a *= 8;
|
|
|
|
b *= 8;
|
2003-05-10 21:49:59 +00:00
|
|
|
if (a < (_screenWidth / 2))
|
|
|
|
a = (_screenWidth / 2);
|
|
|
|
if (b < (_screenWidth / 2))
|
|
|
|
b = (_screenWidth / 2);
|
|
|
|
if (a > _roomWidth - (_screenWidth / 2))
|
|
|
|
a = _roomWidth - (_screenWidth / 2);
|
|
|
|
if (b > _roomWidth - (_screenWidth / 2))
|
|
|
|
b = _roomWidth - (_screenWidth / 2);
|
2003-05-08 15:48:50 +00:00
|
|
|
VAR(VAR_CAMERA_MIN_X) = a;
|
|
|
|
VAR(VAR_CAMERA_MAX_X) = b;
|
2003-04-26 16:37:35 +00:00
|
|
|
break;
|
2003-11-10 09:16:41 +00:00
|
|
|
case 2: // SO_ROOM_COLOR
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.version == 1) {
|
2003-08-29 06:46:12 +00:00
|
|
|
// V1 zak needs to know when room color is changed
|
2003-08-27 01:12:18 +00:00
|
|
|
_roomPalette[0] = 255;
|
|
|
|
_roomPalette[1] = a;
|
|
|
|
_roomPalette[2] = b;
|
2003-08-26 15:56:37 +00:00
|
|
|
} else {
|
2003-08-27 01:12:18 +00:00
|
|
|
_roomPalette[b] = a;
|
2003-08-26 15:56:37 +00:00
|
|
|
}
|
2003-09-11 12:48:02 +00:00
|
|
|
_fullRedraw = true;
|
2003-04-26 16:37:35 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_cutscene() {
|
2003-07-12 22:00:59 +00:00
|
|
|
vm.cutSceneData[0] = _userState | (_userPut ? 16 : 0);
|
2003-07-02 14:21:13 +00:00
|
|
|
vm.cutSceneData[1] = (int16)VAR(VAR_CURSORSTATE);
|
2003-05-21 14:00:19 +00:00
|
|
|
vm.cutSceneData[2] = _currentRoom;
|
|
|
|
vm.cutSceneData[3] = camera._mode;
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-05-21 14:00:19 +00:00
|
|
|
VAR(VAR_CURSORSTATE) = 200;
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-07-12 22:00:59 +00:00
|
|
|
// Hide inventory, freeze scripts, hide cursor
|
2012-09-26 02:17:31 +00:00
|
|
|
setUserState(USERSTATE_SET_IFACE |
|
|
|
|
USERSTATE_SET_CURSOR |
|
2012-01-29 16:03:37 +00:00
|
|
|
USERSTATE_SET_FREEZE | USERSTATE_FREEZE_ON);
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-05-17 18:30:47 +00:00
|
|
|
_sentenceNum = 0;
|
2003-05-20 20:58:26 +00:00
|
|
|
stopScript(SENTENCE_SCRIPT);
|
2012-02-13 19:26:43 +00:00
|
|
|
resetSentence();
|
2003-05-21 14:00:19 +00:00
|
|
|
|
|
|
|
vm.cutScenePtr[0] = 0;
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_endCutscene() {
|
2003-05-21 14:00:19 +00:00
|
|
|
vm.cutSceneStackPointer = 0;
|
|
|
|
|
|
|
|
VAR(VAR_OVERRIDE) = 0;
|
|
|
|
vm.cutSceneScript[0] = 0;
|
|
|
|
vm.cutScenePtr[0] = 0;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2003-05-21 14:00:19 +00:00
|
|
|
VAR(VAR_CURSORSTATE) = vm.cutSceneData[1];
|
|
|
|
|
2003-07-12 22:00:59 +00:00
|
|
|
// Reset user state to values before cutscene
|
2012-01-29 16:03:37 +00:00
|
|
|
setUserState(vm.cutSceneData[0] | USERSTATE_SET_IFACE | USERSTATE_SET_CURSOR | USERSTATE_SET_FREEZE);
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2006-02-20 16:51:30 +00:00
|
|
|
if ((_game.id == GID_MANIAC) && !(_game.platform == Common::kPlatformNES)) {
|
2003-05-21 17:34:01 +00:00
|
|
|
camera._mode = (byte) vm.cutSceneData[3];
|
2004-01-03 21:22:07 +00:00
|
|
|
if (camera._mode == kFollowActorCameraMode) {
|
2003-05-21 14:00:19 +00:00
|
|
|
actorFollowCamera(VAR(VAR_EGO));
|
|
|
|
} else if (vm.cutSceneData[2] != _currentRoom) {
|
|
|
|
startScene(vm.cutSceneData[2], 0, 0);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
actorFollowCamera(VAR(VAR_EGO));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_beginOverride() {
|
2003-05-21 14:00:19 +00:00
|
|
|
vm.cutScenePtr[0] = _scriptPointer - _scriptOrgPointer;
|
|
|
|
vm.cutSceneScript[0] = _currentScript;
|
|
|
|
|
|
|
|
// Skip the jump instruction following the override instruction
|
|
|
|
fetchScriptByte();
|
2012-01-29 16:11:54 +00:00
|
|
|
ScummEngine::fetchScriptWord();
|
2003-04-26 20:03:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_chainScript() {
|
2010-12-02 00:27:46 +00:00
|
|
|
int script = getVarOrDirectByte(PARAM_1);
|
2003-07-24 17:44:00 +00:00
|
|
|
stopScript(vm.slot[_currentScript].number);
|
2003-04-26 16:37:35 +00:00
|
|
|
_currentScript = 0xFF;
|
2010-12-02 00:27:46 +00:00
|
|
|
runScript(script, 0, 0, 0);
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_pickupObject() {
|
2003-11-16 18:34:33 +00:00
|
|
|
int obj = getVarOrDirectWord(PARAM_1);
|
2003-04-26 16:37:35 +00:00
|
|
|
|
|
|
|
if (obj < 1) {
|
|
|
|
error("pickupObject received invalid index %d (script %d)", obj, vm.slot[_currentScript].number);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getObjectIndex(obj) == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (whereIsObject(obj) == WIO_INVENTORY) /* Don't take an */
|
|
|
|
return; /* object twice */
|
|
|
|
|
|
|
|
addObjectToInventory(obj, _roomResource);
|
2004-01-11 20:42:40 +00:00
|
|
|
markObjectRectAsDirty(obj);
|
2003-05-08 15:48:50 +00:00
|
|
|
putOwner(obj, VAR(VAR_EGO));
|
2006-10-29 14:45:31 +00:00
|
|
|
putState(obj, getState(obj) | kObjectState_08 | kObjectStateUntouchable);
|
2003-04-26 16:37:35 +00:00
|
|
|
clearDrawObjectQueue();
|
2003-05-21 06:00:16 +00:00
|
|
|
|
2003-06-14 12:23:30 +00:00
|
|
|
runInventoryScript(1);
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES)
|
2005-03-27 21:21:05 +00:00
|
|
|
_sound->addSoundToQueue(51); // play 'pickup' sound
|
2003-04-26 16:37:35 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_cursorCommand() { // TODO: Define the magic numbers
|
2003-11-16 18:34:33 +00:00
|
|
|
uint16 cmd = getVarOrDirectWord(PARAM_1);
|
2003-07-12 22:00:59 +00:00
|
|
|
byte state = cmd >> 8;
|
2003-05-04 04:30:49 +00:00
|
|
|
|
2003-05-21 20:34:21 +00:00
|
|
|
if (cmd & 0xFF) {
|
2003-05-21 14:00:19 +00:00
|
|
|
VAR(VAR_CURSORSTATE) = cmd & 0xFF;
|
2003-05-18 12:52:27 +00:00
|
|
|
}
|
2003-11-08 21:59:32 +00:00
|
|
|
|
2003-07-12 22:00:59 +00:00
|
|
|
setUserState(state);
|
|
|
|
}
|
2003-05-21 06:14:02 +00:00
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::setUserState(byte state) {
|
2012-01-29 16:03:37 +00:00
|
|
|
if (state & USERSTATE_SET_IFACE) { // Userface
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES)
|
2012-01-29 16:03:37 +00:00
|
|
|
_userState = (_userState & ~USERSTATE_IFACE_ALL) | (state & USERSTATE_IFACE_ALL);
|
2005-03-27 21:21:05 +00:00
|
|
|
else
|
2012-01-29 16:03:37 +00:00
|
|
|
_userState = state & USERSTATE_IFACE_ALL;
|
2003-05-21 07:22:43 +00:00
|
|
|
}
|
2003-05-04 04:30:49 +00:00
|
|
|
|
2012-01-29 16:03:37 +00:00
|
|
|
if (state & USERSTATE_SET_FREEZE) { // Freeze
|
|
|
|
if (state & USERSTATE_FREEZE_ON)
|
2003-05-04 04:30:49 +00:00
|
|
|
freezeScripts(0);
|
|
|
|
else
|
|
|
|
unfreezeScripts();
|
|
|
|
}
|
|
|
|
|
2012-01-29 16:03:37 +00:00
|
|
|
if (state & USERSTATE_SET_CURSOR) { // Cursor Show/Hide
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES)
|
2012-01-29 16:03:37 +00:00
|
|
|
_userState = (_userState & ~USERSTATE_CURSOR_ON) | (state & USERSTATE_CURSOR_ON);
|
|
|
|
if (state & USERSTATE_CURSOR_ON) {
|
2003-05-21 07:22:43 +00:00
|
|
|
_userPut = 1;
|
2003-05-10 23:47:39 +00:00
|
|
|
_cursor.state = 1;
|
2003-05-21 07:22:43 +00:00
|
|
|
} else {
|
|
|
|
_userPut = 0;
|
2003-05-10 23:47:39 +00:00
|
|
|
_cursor.state = 0;
|
2003-05-21 07:22:43 +00:00
|
|
|
}
|
2003-05-04 04:30:49 +00:00
|
|
|
}
|
2003-08-24 01:47:45 +00:00
|
|
|
|
|
|
|
// Hide all verbs and inventory
|
2003-10-02 17:43:02 +00:00
|
|
|
Common::Rect rect;
|
2007-09-08 11:15:27 +00:00
|
|
|
rect.top = _virtscr[kVerbVirtScreen].topline;
|
|
|
|
rect.bottom = _virtscr[kVerbVirtScreen].topline + 8 * 88;
|
|
|
|
rect.right = _virtscr[kVerbVirtScreen].w - 1;
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES) {
|
2005-04-01 01:41:20 +00:00
|
|
|
rect.left = 16;
|
|
|
|
} else {
|
|
|
|
rect.left = 0;
|
|
|
|
}
|
2006-09-17 23:35:09 +00:00
|
|
|
restoreBackground(rect);
|
2003-08-24 01:47:45 +00:00
|
|
|
|
|
|
|
// Draw all verbs and inventory
|
|
|
|
redrawVerbs();
|
|
|
|
runInventoryScript(1);
|
2003-04-26 20:03:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_getActorWalkBox() {
|
2003-04-26 20:03:38 +00:00
|
|
|
Actor *a;
|
|
|
|
getResultPos();
|
2003-11-16 18:34:33 +00:00
|
|
|
a = derefActor(getVarOrDirectByte(PARAM_1), "o2_getActorWalkbox");
|
2009-05-26 01:25:44 +00:00
|
|
|
setResult(a->isInCurrentRoom() ? a->_walkbox: 0xFF);
|
2003-04-26 20:03:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_dummy() {
|
2009-04-19 01:00:31 +00:00
|
|
|
// Opcode 0xEE is used in maniac and zak but has no purpose
|
|
|
|
if (_opcode != 0xEE)
|
2003-08-18 10:46:42 +00:00
|
|
|
warning("o2_dummy invoked (opcode %d)", _opcode);
|
2003-05-04 00:29:52 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
void ScummEngine_v2::o2_switchCostumeSet() {
|
2003-08-14 11:40:50 +00:00
|
|
|
// NES version of maniac uses this to switch between the two
|
|
|
|
// groups of costumes it has
|
2006-02-20 16:51:30 +00:00
|
|
|
if (_game.platform == Common::kPlatformNES)
|
2005-03-24 03:22:32 +00:00
|
|
|
NES_loadCostumeSet(fetchScriptByte());
|
2006-02-20 16:51:30 +00:00
|
|
|
else if (_game.platform == Common::kPlatformC64)
|
2005-05-18 00:46:30 +00:00
|
|
|
fetchScriptByte();
|
2005-03-13 23:18:59 +00:00
|
|
|
else
|
2003-08-14 11:40:50 +00:00
|
|
|
o2_dummy();
|
|
|
|
}
|
|
|
|
|
2012-02-13 19:26:43 +00:00
|
|
|
void ScummEngine_v2::resetSentence() {
|
2006-03-02 12:14:06 +00:00
|
|
|
VAR(VAR_SENTENCE_VERB) = VAR(VAR_BACKUP_VERB);
|
|
|
|
VAR(VAR_SENTENCE_OBJECT1) = 0;
|
|
|
|
VAR(VAR_SENTENCE_OBJECT2) = 0;
|
|
|
|
VAR(VAR_SENTENCE_PREPOSITION) = 0;
|
2003-05-18 12:52:27 +00:00
|
|
|
}
|
2003-10-03 18:33:57 +00:00
|
|
|
|
2005-04-20 23:53:29 +00:00
|
|
|
void ScummEngine_v2::runInventoryScript(int i) {
|
|
|
|
redrawV2Inventory();
|
|
|
|
}
|
|
|
|
|
2003-10-03 18:33:57 +00:00
|
|
|
} // End of namespace Scumm
|