Things which are missing: (a) mouse support due to incomplete interface implementation (b) arrows do not pop up by same reason mentioned above (c) scrolling does not work (d) kReplyOnce flag is missing due to wrong threads memory implementation svn-id: r16589
1549 lines
37 KiB
C++
1549 lines
37 KiB
C++
/* ScummVM - Scumm Interpreter
|
|
* Copyright (C) 2004-2005 The ScummVM project
|
|
*
|
|
* The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* $Header$
|
|
*
|
|
*/
|
|
|
|
// Scripting module script function component
|
|
|
|
#include "saga/saga.h"
|
|
|
|
#include "saga/gfx.h"
|
|
#include "saga/actor.h"
|
|
#include "saga/animation.h"
|
|
#include "saga/console.h"
|
|
#include "saga/events.h"
|
|
#include "saga/font.h"
|
|
#include "saga/interface.h"
|
|
#include "saga/music.h"
|
|
#include "saga/objectdata.h"
|
|
#include "saga/render.h"
|
|
#include "saga/sound.h"
|
|
#include "saga/sndres.h"
|
|
|
|
#include "saga/script.h"
|
|
|
|
#include "saga/scene.h"
|
|
|
|
namespace Saga {
|
|
|
|
#define OPCODE(x) {&Script::x, #x}
|
|
|
|
void Script::setupScriptFuncList(void) {
|
|
static const ScriptFunctionDescription scriptFunctionsList[SCRIPT_FUNCTION_MAX] = {
|
|
OPCODE(SF_putString),
|
|
OPCODE(sfWait),
|
|
OPCODE(SF_takeObject),
|
|
OPCODE(SF_objectIsCarried),
|
|
OPCODE(sfStatusBar),
|
|
OPCODE(SF_mainMode),
|
|
OPCODE(sfScriptWalkTo),
|
|
OPCODE(SF_doAction),
|
|
OPCODE(sfSetActorFacing),
|
|
OPCODE(sfStartBgdAnim),
|
|
OPCODE(sfStopBgdAnim),
|
|
OPCODE(sfLockUser),
|
|
OPCODE(SF_preDialog),
|
|
OPCODE(SF_killActorThreads),
|
|
OPCODE(sfFaceTowards),
|
|
OPCODE(sfSetFollower),
|
|
OPCODE(SF_gotoScene),
|
|
OPCODE(SF_setObjImage),
|
|
OPCODE(SF_setObjName),
|
|
OPCODE(SF_getObjImage),
|
|
OPCODE(SF_getNumber),
|
|
OPCODE(sfScriptOpenDoor),
|
|
OPCODE(sfScriptCloseDoor),
|
|
OPCODE(sfSetBgdAnimSpeed),
|
|
OPCODE(SF_cycleColors),
|
|
OPCODE(sfDoCenterActor),
|
|
OPCODE(sfStartBgdAnimSpeed),
|
|
OPCODE(sfScriptWalkToAsync),
|
|
OPCODE(SF_enableZone),
|
|
OPCODE(sfSetActorState),
|
|
OPCODE(scriptMoveTo),
|
|
OPCODE(SF_sceneEq),
|
|
OPCODE(SF_dropObject),
|
|
OPCODE(sfFinishBgdAnim),
|
|
OPCODE(sfSwapActors),
|
|
OPCODE(sfSimulSpeech),
|
|
OPCODE(sfScriptWalk),
|
|
OPCODE(sfCycleFrames),
|
|
OPCODE(sfSetFrame),
|
|
OPCODE(sfSetPortrait),
|
|
OPCODE(sfSetProtagPortrait),
|
|
OPCODE(sfChainBgdAnim),
|
|
OPCODE(SF_scriptSpecialWalk),
|
|
OPCODE(sfPlaceActor),
|
|
OPCODE(SF_checkUserInterrupt),
|
|
OPCODE(SF_walkRelative),
|
|
OPCODE(SF_moveRelative),
|
|
OPCODE(SF_simulSpeech2),
|
|
OPCODE(sfPlacard),
|
|
OPCODE(sfPlacardOff),
|
|
OPCODE(SF_setProtagState),
|
|
OPCODE(sfResumeBgdAnim),
|
|
OPCODE(SF_throwActor),
|
|
OPCODE(SF_waitWalk),
|
|
OPCODE(SF_sceneID),
|
|
OPCODE(SF_changeActorScene),
|
|
OPCODE(SF_climb),
|
|
OPCODE(sfSetDoorState),
|
|
OPCODE(SF_setActorZ),
|
|
OPCODE(SF_text),
|
|
OPCODE(SF_getActorX),
|
|
OPCODE(SF_getActorY),
|
|
OPCODE(SF_eraseDelta),
|
|
OPCODE(sfPlayMusic),
|
|
OPCODE(SF_pickClimbOutPos),
|
|
OPCODE(SF_tossRif),
|
|
OPCODE(SF_showControls),
|
|
OPCODE(SF_showMap),
|
|
OPCODE(SF_puzzleWon),
|
|
OPCODE(sfEnableEscape),
|
|
OPCODE(sfPlaySound),
|
|
OPCODE(SF_playLoopedSound),
|
|
OPCODE(SF_getDeltaFrame),
|
|
OPCODE(SF_showProtect),
|
|
OPCODE(SF_protectResult),
|
|
OPCODE(sfRand),
|
|
OPCODE(SF_fadeMusic),
|
|
OPCODE(SF_playVoice)
|
|
};
|
|
_scriptFunctionsList = scriptFunctionsList;
|
|
}
|
|
|
|
// Script function #0 (0x00)
|
|
// Print a debugging message
|
|
int Script::SF_putString(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
|
|
_vm->_console->DebugPrintf(getScriptString(param));
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #1 (0x01) blocking
|
|
// Param1: time in ticks
|
|
int Script::sfWait(SCRIPTFUNC_PARAMS) {
|
|
int time;
|
|
time = getUWord(thread->pop());
|
|
|
|
if (!_skipSpeeches) {
|
|
thread->waitDelay(ticksToMSec(time)); // put thread to sleep
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #2 (0x02)
|
|
int Script::SF_takeObject(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
int index = param & 0x1FFF;
|
|
|
|
if (index >= ARRAYSIZE(ObjectTable)) {
|
|
return FAILURE;
|
|
}
|
|
|
|
if (ObjectTable[index].sceneIndex != -1) {
|
|
ObjectTable[index].sceneIndex = -1;
|
|
_vm->_interface->addToInventory(index);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #3 (0x03)
|
|
// Check if an object is carried.
|
|
int Script::SF_objectIsCarried(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
int index = param & 0x1FFF;
|
|
|
|
if (index >= ARRAYSIZE(ObjectTable)) {
|
|
thread->retVal = 0;
|
|
return FAILURE;
|
|
}
|
|
|
|
thread->retVal = (ObjectTable[index].sceneIndex == -1) ? 1 : 0;
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #4 (0x04) nonblocking
|
|
// Set the command display to the specified text string
|
|
// Param1: dialogue index of string
|
|
int Script::sfStatusBar(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
|
|
return _vm->_interface->setStatusText(getScriptString(param));
|
|
}
|
|
|
|
// Script function #5 (0x05)
|
|
int Script::SF_mainMode(SCRIPTFUNC_PARAMS) {
|
|
; // center actor
|
|
; // show verb
|
|
_vm->_interface->activate();
|
|
_vm->_interface->setMode(kPanelInventory);
|
|
; // set pointer verb
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #6 (0x06) blocking
|
|
// Param1: actor id
|
|
// Param2: actor x
|
|
// Param3: actor y
|
|
int Script::sfScriptWalkTo(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
Location actorLocation;
|
|
ActorData *actor;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
actorLocation.x = getSWord(thread->pop());
|
|
actorLocation.y = getSWord(thread->pop());
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
actorLocation.z = actor->location.z;
|
|
|
|
actor->flags &= ~kFollower;
|
|
|
|
if (_vm->_actor->actorWalkTo(actorId, actorLocation)) {
|
|
thread->waitWalk(actor);
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #7 (0x07)
|
|
int Script::SF_doAction(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord actor_parm = thread->pop();
|
|
ScriptDataWord action_parm = thread->pop();
|
|
ScriptDataWord obj_parm = thread->pop();
|
|
ScriptDataWord withobj_parm = thread->pop();
|
|
|
|
// The parameters correspond with the thread variables.
|
|
|
|
debug(1, "stub: SF_doAction(%d, %d, %d, %d)", actor_parm, action_parm, obj_parm, withobj_parm);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #8 (0x08) nonblocking
|
|
// Param1: actor id
|
|
// Param2: actor orientation
|
|
int Script::sfSetActorFacing(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
int actorDirection;
|
|
ActorData *actor;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
actorDirection = getSWord(thread->pop());
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
actor->facingDirection = actor->actionDirection = actorDirection;
|
|
actor->targetObject = ID_NOTHING;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #9 (0x09)
|
|
int Script::sfStartBgdAnim(SCRIPTFUNC_PARAMS) {
|
|
int animId = getSWord(thread->pop());
|
|
int cycles = getSWord(thread->pop());
|
|
|
|
_vm->_anim->setCycles(animId, cycles);
|
|
_vm->_anim->play(animId, kRepeatSpeed);
|
|
|
|
debug(1, "sfStartBgdAnim(%d, %d)", animId, cycles);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #10 (0x0A)
|
|
int Script::sfStopBgdAnim(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord animId = getSWord(thread->pop());
|
|
|
|
_vm->_anim->stop(animId);
|
|
|
|
debug(1, "sfStopBgdAnim(%d)", animId);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #11 (0x0B) nonblocking
|
|
// If the parameter is true, the user interface is disabled while script
|
|
// continues to run. If the parameter is false, the user interface is
|
|
// reenabled.
|
|
// Param1: boolean
|
|
int Script::sfLockUser(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord b_param;
|
|
|
|
b_param = thread->pop();
|
|
|
|
if (b_param) {
|
|
_vm->_interface->deactivate();
|
|
} else {
|
|
_vm->_interface->activate();
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #12 (0x0C)
|
|
// Disables mouse input, etc.
|
|
int Script::SF_preDialog(SCRIPTFUNC_PARAMS) {
|
|
_vm->_interface->deactivate();
|
|
; // clear converse text
|
|
if (_vm->_interface->isInMainMode())
|
|
_vm->_interface->setMode(kPanelConverse);
|
|
else
|
|
; // display zero text
|
|
_vm->_interface->setMode(kPanelNull);
|
|
|
|
debug(1, "stub: SF_preDialog()");
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #13 (0x0D)
|
|
int Script::SF_killActorThreads(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_killActorThreads(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #14 (0x0E)
|
|
// Param1: actor id
|
|
// Param2: object id
|
|
int Script::sfFaceTowards(SCRIPTFUNC_PARAMS) {
|
|
int16 actorId;
|
|
int16 targetObject;
|
|
ActorData *actor;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
targetObject = getSWord(thread->pop());
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
actor->targetObject = targetObject;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #15 (0x0F)
|
|
// Param1: actor id
|
|
// Param2: target object
|
|
int Script::sfSetFollower(SCRIPTFUNC_PARAMS) {
|
|
int16 actorId;
|
|
int16 targetObject;
|
|
|
|
ActorData *actor;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
targetObject = getSWord(thread->pop());
|
|
|
|
debug(1, "sfSetFollower(%d, %d) [%d]", actorId, targetObject, _vm->_actor->actorIdToIndex(actorId));
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
actor->targetObject = targetObject;
|
|
if (targetObject != ID_NOTHING) {
|
|
actor->flags |= kFollower;
|
|
actor->actorFlags &= ~kActorNoFollow;
|
|
} else {
|
|
actor->flags &= ~kFollower;
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static struct SceneSubstitutes {
|
|
int sceneId;
|
|
const char *message;
|
|
const char *name;
|
|
const char *image;
|
|
} sceneSubstitutes[] = {
|
|
{
|
|
7,
|
|
"Tycho says he knows much about the northern lands. Can Rif convince "
|
|
"the Dog to share this knowledge?",
|
|
"The Home of Tycho Northpaw",
|
|
"tycho.bbm"
|
|
},
|
|
|
|
{
|
|
27,
|
|
"The scene of the crime may hold many clues, but will the servants of "
|
|
"the Sanctuary trust Rif?",
|
|
"The Sanctuary of the Orb",
|
|
"sanctuar.bbm"
|
|
},
|
|
|
|
{
|
|
5,
|
|
"The Rats hold many secrets that could guide Rif on his quest -- assuming "
|
|
"he can get past the doorkeeper.",
|
|
"The Rat Complex",
|
|
"ratdoor.bbm"
|
|
},
|
|
|
|
{
|
|
2,
|
|
"The Ferrets enjoy making things and have the materials to do so. How can "
|
|
"that help Rif?",
|
|
"The Ferret Village",
|
|
"ferrets.bbm"
|
|
},
|
|
|
|
{
|
|
67,
|
|
"What aid can the noble King of the Elks provide to Rif and his companions?",
|
|
"The Realm of the Forest King",
|
|
"elkenter.bbm"
|
|
},
|
|
|
|
{
|
|
3,
|
|
"The King holds Rif's sweetheart hostage. Will the Boar provide any "
|
|
"assistance to Rif?",
|
|
"The Great Hall of the Boar King",
|
|
"boarhall.bbm"
|
|
}
|
|
};
|
|
|
|
// Script function #16 (0x10)
|
|
int Script::SF_gotoScene(SCRIPTFUNC_PARAMS) {
|
|
int16 sceneNum = getSWord(thread->pop());
|
|
int16 entrance = getSWord(thread->pop());
|
|
|
|
for (int i = 0; i < ARRAYSIZE(sceneSubstitutes); i++)
|
|
if (sceneSubstitutes[i].sceneId == sceneNum)
|
|
debug(0, "Scene %d substitute exists", sceneNum);
|
|
|
|
debug(1, "stub: SF_gotoScene(%d, %d)", sceneNum, entrance);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #17 (0x11)
|
|
int Script::SF_setObjImage(SCRIPTFUNC_PARAMS) {
|
|
int16 obj_param = getSWord(thread->pop());
|
|
int16 sprite_param = getSWord(thread->pop());
|
|
|
|
int index = obj_param & 0x1FFF;
|
|
|
|
if (index >= ARRAYSIZE(ObjectTable)) {
|
|
return FAILURE;
|
|
}
|
|
|
|
ObjectTable[index].spritelistRn = sprite_param + 9;
|
|
_vm->_interface->draw();
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #18 (0x12)
|
|
int Script::SF_setObjName(SCRIPTFUNC_PARAMS) {
|
|
int obj_param = getSWord(thread->pop());
|
|
int name_param = getSWord(thread->pop());
|
|
|
|
int index = obj_param & 0x1FFF;
|
|
|
|
if (index >= ARRAYSIZE(ObjectTable)) {
|
|
return FAILURE;
|
|
}
|
|
|
|
ObjectTable[index].nameIndex = name_param;
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #19 (0x13)
|
|
int Script::SF_getObjImage(SCRIPTFUNC_PARAMS) {
|
|
int param = getSWord(thread->pop());
|
|
int index = param & 0x1FFF;
|
|
|
|
if (index >= ARRAYSIZE(ObjectTable)) {
|
|
thread->retVal = 0;
|
|
return FAILURE;
|
|
}
|
|
|
|
thread->retVal = ObjectTable[index].spritelistRn;
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #20 (0x14)
|
|
int Script::SF_getNumber(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_getNumber(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #21 (0x15)
|
|
// Param1: door #
|
|
int Script::sfScriptOpenDoor(SCRIPTFUNC_PARAMS) {
|
|
int doorNumber;
|
|
doorNumber = getUWord(thread->pop());
|
|
|
|
if (_vm->_scene->getFlags() & kSceneFlagISO) {
|
|
//todo: it
|
|
} else {
|
|
_vm->_scene->setDoorState(doorNumber, 0);
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #22 (0x16)
|
|
// Param1: door #
|
|
int Script::sfScriptCloseDoor(SCRIPTFUNC_PARAMS) {
|
|
int doorNumber;
|
|
doorNumber = getUWord(thread->pop());
|
|
|
|
if (_vm->_scene->getFlags() & kSceneFlagISO) {
|
|
//todo: it
|
|
} else {
|
|
_vm->_scene->setDoorState(doorNumber, 0xff);
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #23 (0x17)
|
|
int Script::sfSetBgdAnimSpeed(SCRIPTFUNC_PARAMS) {
|
|
int animId = getSWord(thread->pop());
|
|
int speed = getSWord(thread->pop());
|
|
|
|
_vm->_anim->setFrameTime(animId, ticksToMSec(speed));
|
|
debug(1, "sfSetBgdAnimSpeed(%d, %d)", animId, speed);
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #24 (0x18)
|
|
int Script::SF_cycleColors(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_cycleColors(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #25 (0x19)
|
|
// Param1: actor id
|
|
int Script::sfDoCenterActor(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
actorId = getSWord(thread->pop());
|
|
|
|
_vm->_actor->_centerActor = _vm->_actor->getActor(actorId);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #26 (0x1A) nonblocking
|
|
// Starts the specified animation
|
|
int Script::sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS) {
|
|
int animId = getSWord(thread->pop());
|
|
int cycles = getSWord(thread->pop());
|
|
int speed = getSWord(thread->pop());
|
|
|
|
_vm->_anim->setCycles(animId, cycles);
|
|
_vm->_anim->play(animId, ticksToMSec(speed));
|
|
|
|
debug(1, "sfStartBgdAnimSpeed(%d, %d, %d)", animId, cycles, speed);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #27 (0x1B) nonblocking
|
|
// Param1: actor id
|
|
// Param2: actor x
|
|
// Param3: actor y
|
|
int Script::sfScriptWalkToAsync(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
Location actorLocation;
|
|
ActorData *actor;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
actorLocation.x = getSWord(thread->pop());
|
|
actorLocation.y = getSWord(thread->pop());
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
actorLocation.z = actor->location.z;
|
|
|
|
actor->flags &= ~kFollower;
|
|
|
|
_vm->_actor->actorWalkTo(actorId, actorLocation);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #28 (0x1C)
|
|
int Script::SF_enableZone(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_enableZone(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #29 (0x1D)
|
|
// Param1: actor id
|
|
// Param2: current action
|
|
int Script::sfSetActorState(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
int currentAction;
|
|
ActorData *actor;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
currentAction = getSWord(thread->pop());
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
|
|
if ((currentAction >= kActionWalkToPoint) && (currentAction <= kActionWalkToPoint)) {
|
|
wakeUpActorThread(kWaitTypeWalk, actor);
|
|
}
|
|
actor->currentAction = currentAction;
|
|
actor->actorFlags &= ~kActorBackwards;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #30 (0x1E) nonblocking
|
|
// Param1: actor id
|
|
// Param2: actor pos x
|
|
// Param3: actor pos y
|
|
int Script::scriptMoveTo(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
Location actorLocation;
|
|
ActorData *actor;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
actorLocation.x = getSWord(thread->pop());
|
|
actorLocation.y = getSWord(thread->pop());
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
|
|
actor->location.x = actorLocation.x;
|
|
actor->location.y = actorLocation.y;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #31 (0x21)
|
|
int Script::SF_sceneEq(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
|
|
if (_vm->_scene->getSceneLUT(param) == _vm->_scene->currentSceneNumber())
|
|
thread->retVal = 1;
|
|
else
|
|
thread->retVal = 0;
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #32 (0x20)
|
|
int Script::SF_dropObject(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord obj_param = thread->pop();
|
|
ScriptDataWord sprite_param = thread->pop();
|
|
ScriptDataWord x_param = thread->pop();
|
|
ScriptDataWord y_param = thread->pop();
|
|
|
|
int index = obj_param & 0x1FFF;
|
|
|
|
if (index >= ARRAYSIZE(ObjectTable)) {
|
|
return FAILURE;
|
|
}
|
|
|
|
if (ObjectTable[index].sceneIndex == -1) {
|
|
_vm->_interface->removeFromInventory(index);
|
|
}
|
|
|
|
ObjectTable[index].sceneIndex = _vm->_scene->currentSceneNumber();
|
|
ObjectTable[index].spritelistRn = 9 + sprite_param;
|
|
ObjectTable[index].x = x_param;
|
|
ObjectTable[index].y = y_param;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #33 (0x21)
|
|
int Script::sfFinishBgdAnim(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord animId = getSWord(thread->pop());
|
|
|
|
_vm->_anim->finish(animId);
|
|
|
|
debug(1, "sfFinishBgdAnim(%d)", animId);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #34 (0x22)
|
|
// Param1: actor id 1
|
|
// Param2: actor id 2
|
|
int Script::sfSwapActors(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId1;
|
|
uint16 actorId2;
|
|
ActorData *actor1;
|
|
ActorData *actor2;
|
|
Location location;
|
|
|
|
actorId1 = getSWord(thread->pop());
|
|
actorId2 = getSWord(thread->pop());
|
|
|
|
actor1 = _vm->_actor->getActor(actorId1);
|
|
actor2 = _vm->_actor->getActor(actorId2);
|
|
location = actor1->location;
|
|
actor1->location = actor2->location;
|
|
actor2->location = location;
|
|
|
|
|
|
if (actor1->flags & kProtagonist) {
|
|
actor1->flags &= ~kProtagonist;
|
|
actor2->flags |= kProtagonist;
|
|
_vm->_actor->_protagonist = _vm->_actor->_centerActor = actor2;
|
|
} else {
|
|
if (actor2->flags & kProtagonist) {
|
|
actor2->flags &= ~kProtagonist;
|
|
actor1->flags |= kProtagonist;
|
|
_vm->_actor->_protagonist = _vm->_actor->_centerActor = actor1;
|
|
}
|
|
}
|
|
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #35 (0x23)
|
|
// Param1: string rid
|
|
// Param2: actorscount
|
|
// Param3: actor id1
|
|
///....
|
|
// Param3: actor idN
|
|
int Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord stringId;
|
|
int actorsCount;
|
|
int i;
|
|
uint16 actorsIds[ACTOR_SPEECH_ACTORS_MAX];
|
|
const char *string;
|
|
|
|
stringId = thread->pop();
|
|
actorsCount = getSWord(thread->pop());
|
|
|
|
if (actorsCount > ACTOR_SPEECH_ACTORS_MAX)
|
|
error("sfSimulSpeech actorsCount=0x%X exceed ACTOR_SPEECH_ACTORS_MAX", actorsCount);
|
|
|
|
for (i = 0; i < actorsCount; i++)
|
|
actorsIds[i] = getSWord(thread->pop());
|
|
|
|
string = getScriptString(stringId);
|
|
|
|
_vm->_actor->simulSpeech(string, actorsIds, actorsCount, 0);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #36 (0x24) ?
|
|
// Param1: actor id
|
|
// Param2: actor x
|
|
// Param3: actor y
|
|
// Param4: actor walk flag
|
|
int Script::sfScriptWalk(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
Location actorLocation;
|
|
ActorData *actor;
|
|
uint16 walkFlags;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
actorLocation.x = getSWord(thread->pop());
|
|
actorLocation.y = getSWord(thread->pop());
|
|
walkFlags = getUWord(thread->pop());
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
actorLocation.z = actor->location.z;
|
|
|
|
_vm->_actor->realLocation(actorLocation, ID_NOTHING, walkFlags);
|
|
|
|
actor->flags &= ~kFollower;
|
|
|
|
if (_vm->_actor->actorWalkTo(actorId, actorLocation) && !(walkFlags & kWalkAsync)) {
|
|
thread->waitWalk(actor);
|
|
}
|
|
|
|
if (walkFlags & kWalkBackPedal) {
|
|
actor->actorFlags |= kActorBackwards;
|
|
}
|
|
|
|
actor->actorFlags = (actor->actorFlags & ~kActorFacingMask) | (walkFlags & kActorFacingMask);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #37 (0x25) nonblocking
|
|
// Param1: actor id
|
|
// Param2: flags telling how to cycle the frames
|
|
// Param3: cycle frame number
|
|
// Param4: cycle delay
|
|
int Script::sfCycleFrames(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
int flags;
|
|
int cycleFrameSequence;
|
|
int cycleDelay;
|
|
ActorData *actor;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
flags = getUWord(thread->pop());
|
|
cycleFrameSequence = getUWord(thread->pop());
|
|
cycleDelay = getUWord(thread->pop());
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
|
|
if (flags & kCyclePong) {
|
|
actor->currentAction = kActionPongFrames;
|
|
} else {
|
|
actor->currentAction = kActionCycleFrames;
|
|
}
|
|
|
|
actor->actorFlags &= ~(kActorContinuous | kActorRandom | kActorBackwards);
|
|
|
|
if (!(flags & kCycleOnce)) {
|
|
actor->actorFlags |= kActorContinuous;
|
|
}
|
|
if (flags & kCycleRandom) {
|
|
actor->actorFlags |= kActorRandom;
|
|
}
|
|
if (flags & kCycleReverse) {
|
|
actor->actorFlags |= kActorBackwards;
|
|
}
|
|
|
|
actor->cycleFrameSequence = cycleFrameSequence;
|
|
actor->cycleTimeCount = 0;
|
|
actor->cycleDelay = cycleDelay;
|
|
actor->actionCycle = 0;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #38 (0x26) nonblocking
|
|
// Param1: actor id
|
|
// Param2: frame type
|
|
// Param3: frame offset
|
|
int Script::sfSetFrame(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
int frameType;
|
|
int frameOffset;
|
|
ActorData *actor;
|
|
ActorFrameRange *frameRange;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
frameType = getSWord(thread->pop());
|
|
frameOffset = getSWord(thread->pop());
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
|
|
frameRange = _vm->_actor->getActorFrameRange(actorId, frameType);
|
|
|
|
if (frameRange->frameCount <= frameOffset) {
|
|
// frameRange = _vm->_actor->getActorFrameRange(actorId, frameType);
|
|
|
|
error("Wrong frameOffset 0x%X", frameOffset);
|
|
}
|
|
actor->frameNumber = frameRange->frameIndex + frameOffset;
|
|
|
|
if (actor->currentAction != kActionFall) {
|
|
actor->currentAction = kActionFreeze;
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #39 (0x27)
|
|
// Sets the right-hand portrait
|
|
int Script::sfSetPortrait(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
|
|
return _vm->_interface->setRightPortrait(param);
|
|
}
|
|
|
|
// Script function #40 (0x28)
|
|
// Sets the left-hand portrait
|
|
int Script::sfSetProtagPortrait(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
|
|
return _vm->_interface->setLeftPortrait(param);
|
|
}
|
|
|
|
// Script function #41 (0x29) nonblocking
|
|
// Links the specified animations for playback
|
|
|
|
// Param1: ?
|
|
// Param2: total linked frame count
|
|
// Param3: animation id link target
|
|
// Param4: animation id link source
|
|
int Script::sfChainBgdAnim(SCRIPTFUNC_PARAMS) {
|
|
int animId1 = getSWord(thread->pop());
|
|
int animId = getSWord(thread->pop());
|
|
int cycles = getSWord(thread->pop());
|
|
int speed = getSWord(thread->pop());
|
|
|
|
if (speed >= 0) {
|
|
_vm->_anim->setCycles(animId, cycles);
|
|
_vm->_anim->stop(animId);
|
|
_vm->_anim->setFrameTime(animId, ticksToMSec(speed));
|
|
}
|
|
|
|
_vm->_anim->link(animId1, animId);
|
|
debug(1, "sfChainBgdAnim(%d, %d, %d, %d)", animId1, animId, cycles, speed);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #42 (0x2A)
|
|
int Script::SF_scriptSpecialWalk(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param1 = thread->pop();
|
|
ScriptDataWord param2 = thread->pop();
|
|
ScriptDataWord param3 = thread->pop();
|
|
ScriptDataWord param4 = thread->pop();
|
|
|
|
debug(1, "stub: SF_scriptSpecialWalk(%d, %d, %d, %d)", param1, param2, param3, param4);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #43 (0x2B) nonblocking
|
|
// Param1: actor id
|
|
// Param2: actor x
|
|
// Param3: actor y
|
|
// Param4: actor direction
|
|
// Param5: actor action
|
|
// Param6: actor frame number
|
|
int Script::sfPlaceActor(SCRIPTFUNC_PARAMS) {
|
|
uint16 actorId;
|
|
Location actorLocation;
|
|
int actorDirection;
|
|
int frameType;
|
|
int frameOffset;
|
|
ActorData *actor;
|
|
ActorFrameRange *frameRange;
|
|
|
|
actorId = getSWord(thread->pop());
|
|
actorLocation.x = getSWord(thread->pop());
|
|
actorLocation.y = getSWord(thread->pop());
|
|
actorDirection = getSWord(thread->pop());
|
|
frameType = getSWord(thread->pop());
|
|
frameOffset = getSWord(thread->pop());
|
|
|
|
debug(1, "sfPlaceActor(%d, %d, %d, %d, %d, %d)", actorId, actorLocation.x,
|
|
actorLocation.y, actorDirection, frameType, frameOffset);
|
|
|
|
if (_vm->getGameType() == GType_IHNM) {
|
|
warning("Actors aren't implemented for IHNM yet");
|
|
return SUCCESS;
|
|
}
|
|
|
|
actor = _vm->_actor->getActor(actorId);
|
|
actor->location.x = actorLocation.x;
|
|
actor->location.y = actorLocation.y;
|
|
actor->facingDirection = actor->actionDirection = actorDirection;
|
|
|
|
if (frameType >= 0) {
|
|
frameRange = _vm->_actor->getActorFrameRange(actorId, frameType);
|
|
|
|
if (frameRange->frameCount <= frameOffset)
|
|
error("Wrong frameOffset 0x%X", frameOffset);
|
|
|
|
actor->frameNumber = frameRange->frameIndex + frameOffset;
|
|
actor->currentAction = kActionFreeze;
|
|
} else {
|
|
actor->currentAction = kActionWait;
|
|
}
|
|
|
|
actor->targetObject = ID_NOTHING;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #44 (0x2C) nonblocking
|
|
// Checks to see if the user has interrupted a currently playing
|
|
// game cinematic. Pushes a zero or positive value if the game
|
|
// has not been interrupted.
|
|
int Script::SF_checkUserInterrupt(SCRIPTFUNC_PARAMS) {
|
|
thread->retVal = (_skipSpeeches == true);
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #45 (0x2D)
|
|
int Script::SF_walkRelative(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param1 = thread->pop();
|
|
ScriptDataWord param2 = thread->pop();
|
|
ScriptDataWord param3 = thread->pop();
|
|
ScriptDataWord param4 = thread->pop();
|
|
ScriptDataWord param5 = thread->pop();
|
|
|
|
debug(1, "stub: SF_walkRelative(%d, %d, %d, %d, %d)", param1, param2, param3, param4, param5);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #46 (0x2E)
|
|
int Script::SF_moveRelative(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param1 = thread->pop();
|
|
ScriptDataWord param2 = thread->pop();
|
|
ScriptDataWord param3 = thread->pop();
|
|
ScriptDataWord param4 = thread->pop();
|
|
ScriptDataWord param5 = thread->pop();
|
|
|
|
debug(1, "stub: SF_moveRelative(%d, %d, %d, %d, %d)", param1, param2, param3, param4, param5);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #47 (0x2F)
|
|
int Script::SF_simulSpeech2(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_simulSpeech2(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
static TEXTLIST_ENTRY *placardTextEntry;
|
|
|
|
// Script function #48 (0x30)
|
|
// Param1: string rid
|
|
int Script::sfPlacard(SCRIPTFUNC_PARAMS) {
|
|
int stringId;
|
|
SURFACE *back_buf = _vm->_gfx->getBackBuffer();
|
|
static PALENTRY cur_pal[PAL_ENTRIES];
|
|
PALENTRY *pal;
|
|
EVENT event;
|
|
EVENT *q_event;
|
|
|
|
thread->wait(kWaitTypePlacard);
|
|
|
|
_vm->_interface->rememberMode();
|
|
_vm->_interface->setMode(kPanelPlacard);
|
|
|
|
stringId = thread->pop();
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = CURSOR_EVENT;
|
|
event.op = EVENT_HIDE;
|
|
|
|
q_event = _vm->_events->queue(&event);
|
|
|
|
_vm->_gfx->getCurrentPal(cur_pal);
|
|
|
|
event.type = IMMEDIATE_EVENT;
|
|
event.code = PAL_EVENT;
|
|
event.op = EVENT_PALTOBLACK;
|
|
event.time = 0;
|
|
event.duration = kNormalFadeDuration;
|
|
event.data = cur_pal;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = INTERFACE_EVENT;
|
|
event.op = EVENT_CLEAR_STATUS;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = GRAPHICS_EVENT;
|
|
event.op = EVENT_SETFLAG;
|
|
event.param = RF_PLACARD;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = GRAPHICS_EVENT;
|
|
event.op = EVENT_FILL_RECT;
|
|
event.data = back_buf;
|
|
event.param = 138;
|
|
event.param2 = 0;
|
|
event.param3 = _vm->getSceneHeight();
|
|
event.param4 = 0;
|
|
event.param5 = _vm->getDisplayWidth();
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
// Put the text in the center of the viewport, assuming it will fit on
|
|
// one line. If we cannot make that assumption we'll need to extend
|
|
// the text drawing function so that it can center text around a point.
|
|
// It doesn't end up in exactly the same spot as the original did it,
|
|
// but it's close enough for now at least.
|
|
|
|
TEXTLIST_ENTRY text_entry;
|
|
SCENE_INFO scene_info;
|
|
|
|
_vm->_scene->getInfo(&scene_info);
|
|
|
|
text_entry.color = _vm->_gfx->getWhite();
|
|
text_entry.effect_color = _vm->_gfx->getBlack();
|
|
text_entry.text_x = _vm->getDisplayWidth() / 2;
|
|
text_entry.text_y = (_vm->getSceneHeight() - _vm->_font->getHeight(MEDIUM_FONT_ID)) / 2;
|
|
text_entry.font_id = MEDIUM_FONT_ID;
|
|
text_entry.flags = FONT_OUTLINE | FONT_CENTERED;
|
|
text_entry.string = getScriptString(stringId);
|
|
|
|
placardTextEntry = _vm->textAddEntry(scene_info.text_list, &text_entry);
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = TEXT_EVENT;
|
|
event.op = EVENT_DISPLAY;
|
|
event.data = placardTextEntry;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
_vm->_scene->getBGPal(&pal);
|
|
|
|
event.type = IMMEDIATE_EVENT;
|
|
event.code = PAL_EVENT;
|
|
event.op = EVENT_BLACKTOPAL;
|
|
event.time = 0;
|
|
event.duration = kNormalFadeDuration;
|
|
event.data = pal;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = SCRIPT_EVENT;
|
|
event.op = EVENT_THREAD_WAKE;
|
|
event.param = kWaitTypePlacard;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #49 (0x31)
|
|
int Script::sfPlacardOff(SCRIPTFUNC_PARAMS) {
|
|
static PALENTRY cur_pal[PAL_ENTRIES];
|
|
PALENTRY *pal;
|
|
EVENT event;
|
|
EVENT *q_event;
|
|
|
|
thread->wait(kWaitTypePlacard);
|
|
|
|
_vm->_interface->restoreMode();
|
|
|
|
_vm->_gfx->getCurrentPal(cur_pal);
|
|
|
|
event.type = IMMEDIATE_EVENT;
|
|
event.code = PAL_EVENT;
|
|
event.op = EVENT_PALTOBLACK;
|
|
event.time = 0;
|
|
event.duration = kNormalFadeDuration;
|
|
event.data = cur_pal;
|
|
|
|
q_event = _vm->_events->queue(&event);
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = GRAPHICS_EVENT;
|
|
event.op = EVENT_CLEARFLAG;
|
|
event.param = RF_PLACARD;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = TEXT_EVENT;
|
|
event.op = EVENT_REMOVE;
|
|
event.data = placardTextEntry;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
_vm->_scene->getBGPal(&pal);
|
|
|
|
event.type = IMMEDIATE_EVENT;
|
|
event.code = PAL_EVENT;
|
|
event.op = EVENT_BLACKTOPAL;
|
|
event.time = 0;
|
|
event.duration = kNormalFadeDuration;
|
|
event.data = pal;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = CURSOR_EVENT;
|
|
event.op = EVENT_SHOW;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
event.type = ONESHOT_EVENT;
|
|
event.code = SCRIPT_EVENT;
|
|
event.op = EVENT_THREAD_WAKE;
|
|
event.param = kWaitTypePlacard;
|
|
|
|
q_event = _vm->_events->chain(q_event, &event);
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #50 (0x32)
|
|
int Script::SF_setProtagState(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_setProtagState(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #51 (0x33)
|
|
int Script::sfResumeBgdAnim(SCRIPTFUNC_PARAMS) {
|
|
int animId = getSWord(thread->pop());
|
|
int cycles = getSWord(thread->pop());
|
|
|
|
_vm->_anim->resume(animId, cycles);
|
|
debug(1, "sfResumeBgdAnimSpeed(%d, %d)", animId, cycles);
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #52 (0x34)
|
|
int Script::SF_throwActor(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param1 = thread->pop();
|
|
ScriptDataWord param2 = thread->pop();
|
|
ScriptDataWord param3 = thread->pop();
|
|
ScriptDataWord param4 = thread->pop();
|
|
ScriptDataWord param5 = thread->pop();
|
|
ScriptDataWord param6 = thread->pop();
|
|
|
|
debug(1, "stub: SF_throwActor(%d, %d, %d, %d, %d, %d)", param1, param2, param3, param4, param5, param6);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #53 (0x35)
|
|
int Script::SF_waitWalk(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
|
|
debug(1, "stub: SF_waitWalk(%d)", param);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #54 (0x36)
|
|
int Script::SF_sceneID(SCRIPTFUNC_PARAMS) {
|
|
thread->retVal = _vm->_scene->currentSceneNumber();
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #55 (0x37)
|
|
int Script::SF_changeActorScene(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param1 = thread->pop();
|
|
ScriptDataWord param2 = thread->pop();
|
|
|
|
debug(1, "stub: SF_changeActorScene(%d, %d)", param1, param2);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #56 (0x38)
|
|
int Script::SF_climb(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param1 = thread->pop();
|
|
ScriptDataWord param2 = thread->pop();
|
|
ScriptDataWord param3 = thread->pop();
|
|
ScriptDataWord param4 = thread->pop();
|
|
|
|
debug(1, "stub: SF_climb(%d, %d, %d, %d)", param1, param2, param3, param4);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #57 (0x39)
|
|
// Param1: door #
|
|
// Param2: door state
|
|
int Script::sfSetDoorState(SCRIPTFUNC_PARAMS) {
|
|
int doorNumber;
|
|
int doorState;
|
|
doorNumber = getUWord(thread->pop());
|
|
doorState = getUWord(thread->pop());
|
|
|
|
if (_vm->_scene->getFlags() & kSceneFlagISO) {
|
|
//todo: it
|
|
} else {
|
|
_vm->_scene->setDoorState(doorNumber, doorState);
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #58 (0x3A)
|
|
int Script::SF_setActorZ(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param1 = thread->pop();
|
|
ScriptDataWord param2 = thread->pop();
|
|
|
|
debug(1, "stub: SF_setActorZ(%d, %d)", param1, param2);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #59 (0x3B)
|
|
int Script::SF_text(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_text(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #60 (0x3C)
|
|
int Script::SF_getActorX(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
|
|
debug(1, "stub: SF_getActorX(%d)", param);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #61 (0x3D)
|
|
int Script::SF_getActorY(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
|
|
debug(1, "stub: SF_getActorY(%d)", param);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #62 (0x3E)
|
|
int Script::SF_eraseDelta(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_eraseDelta(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #63 (0x3F)
|
|
int Script::sfPlayMusic(SCRIPTFUNC_PARAMS) {
|
|
if (_vm->getGameType() == GType_ITE) {
|
|
ScriptDataWord param = thread->pop() + 9;
|
|
|
|
if (param >= 9 && param <= 34)
|
|
_vm->_music->play(param);
|
|
else
|
|
_vm->_music->stop();
|
|
} else {
|
|
ScriptDataWord param1 = thread->pop();
|
|
ScriptDataWord param2 = thread->pop();
|
|
|
|
debug(1, "Stub: sfPlayMusic(%d, %d)", param1, param2);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #64 (0x40)
|
|
int Script::SF_pickClimbOutPos(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_pickClimbOutPos(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #65 (0x41)
|
|
int Script::SF_tossRif(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_tossRif(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #66 (0x42)
|
|
int Script::SF_showControls(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_showControls(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #67 (0x43)
|
|
int Script::SF_showMap(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_showMap(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #68 (0x44)
|
|
int Script::SF_puzzleWon(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_puzzleWon(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #69 (0x45)
|
|
int Script::sfEnableEscape(SCRIPTFUNC_PARAMS) {
|
|
if (thread->pop())
|
|
_abortEnabled = true;
|
|
else {
|
|
_skipSpeeches = false;
|
|
_abortEnabled = false;
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static struct {
|
|
int res;
|
|
int vol;
|
|
} sfxTable[] = {
|
|
{ FX_DOOR_OPEN, 127 },
|
|
{ FX_DOOR_CLOSE, 127 },
|
|
{ FX_RUSH_WATER, 63 }, // Floppy volume: 127
|
|
{ FX_RUSH_WATER, 26 }, // Floppy volume: 40
|
|
{ FX_CRICKET, 64 },
|
|
{ FX_PORTICULLIS, 84 }, // Floppy volume: 127
|
|
{ FX_CLOCK_1, 64 },
|
|
{ FX_CLOCK_2, 64 },
|
|
{ FX_DAM_MACHINE, 64 },
|
|
{ FX_DAM_MACHINE, 40 },
|
|
{ FX_HUM1, 64 },
|
|
{ FX_HUM2, 64 },
|
|
{ FX_HUM3, 64 },
|
|
{ FX_HUM4, 64 },
|
|
{ FX_WATER_LOOP_S, 32 }, // Floppy volume: 64
|
|
{ FX_SURF, 42 }, // Floppy volume: 127
|
|
{ FX_SURF, 32 }, // Floppy volume: 64
|
|
{ FX_FIRELOOP, 64 }, // Floppy volume: 96
|
|
{ FX_SCRAPING, 84 }, // Floppy volume: 127
|
|
{ FX_BEE_SWARM, 64 }, // Floppy volume: 96
|
|
{ FX_BEE_SWARM, 26 }, // Floppy volume: 40
|
|
{ FX_SQUEAKBOARD, 64 },
|
|
{ FX_KNOCK, 127 },
|
|
{ FX_COINS, 32 }, // Floppy volume: 48
|
|
{ FX_STORM, 84 }, // Floppy volume: 127
|
|
{ FX_DOOR_CLOSE_2, 84 }, // Floppy volume: 127
|
|
{ FX_ARCWELD, 84 }, // Floppy volume: 127
|
|
{ FX_RETRACT_ORB, 127 },
|
|
{ FX_DRAGON, 127 },
|
|
{ FX_SNORES, 127 },
|
|
{ FX_SPLASH, 127 },
|
|
{ FX_LOBBY_DOOR, 127 },
|
|
{ FX_CHIRP_LOOP, 26 }, // Floppy volume: 40
|
|
{ FX_DOOR_CREAK, 96 },
|
|
{ FX_SPOON_DIG, 64 },
|
|
{ FX_CROW, 96 },
|
|
{ FX_COLDWIND, 42 }, // Floppy volume: 64
|
|
{ FX_TOOL_SND_1, 96 },
|
|
{ FX_TOOL_SND_2, 127 },
|
|
{ FX_TOOL_SND_3, 64 },
|
|
{ FX_DOOR_METAL, 96 },
|
|
{ FX_WATER_LOOP_S, 32 },
|
|
{ FX_WATER_LOOP_L, 32 }, // Floppy volume: 64
|
|
{ FX_DOOR_OPEN_2, 127 },
|
|
{ FX_JAIL_DOOR, 64 },
|
|
{ FX_KILN_FIRE, 53 }, // Floppy volume: 80
|
|
|
|
// Only in the CD version
|
|
{ FX_CROWD_01, 64 },
|
|
{ FX_CROWD_02, 64 },
|
|
{ FX_CROWD_03, 64 },
|
|
{ FX_CROWD_04, 64 },
|
|
{ FX_CROWD_05, 64 },
|
|
{ FX_CROWD_06, 64 },
|
|
{ FX_CROWD_07, 64 },
|
|
{ FX_CROWD_08, 64 },
|
|
{ FX_CROWD_09, 64 },
|
|
{ FX_CROWD_10, 64 },
|
|
{ FX_CROWD_11, 64 },
|
|
{ FX_CROWD_12, 64 },
|
|
{ FX_CROWD_13, 64 },
|
|
{ FX_CROWD_14, 64 },
|
|
{ FX_CROWD_15, 64 },
|
|
{ FX_CROWD_16, 64 },
|
|
{ FX_CROWD_17, 64 }
|
|
};
|
|
|
|
// Script function #70 (0x46)
|
|
int Script::sfPlaySound(SCRIPTFUNC_PARAMS) {
|
|
int param = getSWord(thread->pop());
|
|
int res;
|
|
|
|
if (param < ARRAYSIZE(sfxTable)) {
|
|
res = sfxTable[param].res;
|
|
if (_vm->getFeatures() & GF_CD_FX)
|
|
res -= 14;
|
|
|
|
_vm->_sndRes->playSound(res, sfxTable[param].vol, false);
|
|
} else {
|
|
_vm->_sound->stopSound();
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #71 (0x47)
|
|
int Script::SF_playLoopedSound(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_playLoopedSound(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #72 (0x48)
|
|
int Script::SF_getDeltaFrame(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_getDeltaFrame(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #73 (0x49)
|
|
int Script::SF_showProtect(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_showProtect(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #74 (0x4A)
|
|
int Script::SF_protectResult(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_protectResult(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #75 (0x4d)
|
|
int Script::sfRand(SCRIPTFUNC_PARAMS) {
|
|
ScriptDataWord param = thread->pop();
|
|
|
|
thread->retVal = (_vm->_rnd.getRandomNumber(param));
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #76 (0x4c)
|
|
int Script::SF_fadeMusic(SCRIPTFUNC_PARAMS) {
|
|
debug(1, "stub: SF_fadeMusic()");
|
|
return SUCCESS;
|
|
}
|
|
|
|
// Script function #77 (0x4d)
|
|
int Script::SF_playVoice(SCRIPTFUNC_PARAMS) {
|
|
for (int i = 0; i < nArgs; i++)
|
|
thread->pop();
|
|
|
|
debug(1, "stub: SF_playVoice(), %d args", nArgs);
|
|
return SUCCESS;
|
|
}
|
|
|
|
void Script::finishDialog(int replyID, int flags, int bitOffset) {
|
|
if (_conversingThread) {
|
|
_vm->_interface->setMode(kPanelNull);
|
|
|
|
_conversingThread->flags &= ~kTFlagWaiting;
|
|
|
|
_conversingThread->push(replyID);
|
|
|
|
if (flags & kReplyOnce) {
|
|
// TODO:
|
|
}
|
|
}
|
|
|
|
_conversingThread = NULL;
|
|
wakeUpThreads(kWaitTypeDialogBegin);
|
|
}
|
|
|
|
} // End of namespace Saga
|