Initial commit
This commit is contained in:
2137
engines/twine/script/script_life.cpp
Normal file
2137
engines/twine/script/script_life.cpp
Normal file
File diff suppressed because it is too large
Load Diff
190
engines/twine/script/script_life.h
Normal file
190
engines/twine/script/script_life.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWINE_SCRIPTLIFE_H
|
||||
#define TWINE_SCRIPTLIFE_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "twine/scene/actor.h"
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
struct LifeScriptContext {
|
||||
int32 actorIdx;
|
||||
ActorStruct *actor;
|
||||
Common::MemorySeekableReadWriteStream stream;
|
||||
uint8 *opcodePtr; // local opcode script pointer
|
||||
|
||||
LifeScriptContext(int32 _actorIdx, ActorStruct *_actor) : actorIdx(_actorIdx), actor(_actor), stream(_actor->_lifeScript, _actor->_lifeScriptSize) {
|
||||
assert(actor->_offsetLife >= 0);
|
||||
stream.skip(_actor->_offsetLife);
|
||||
updateOpcodePos();
|
||||
}
|
||||
|
||||
void setOpcode(uint8 opcode) {
|
||||
*opcodePtr = opcode;
|
||||
}
|
||||
|
||||
void updateOpcodePos() {
|
||||
opcodePtr = actor->_lifeScript + stream.pos();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns @c -1 Need implementation, @c 0 Condition false, @c 1 - Condition true
|
||||
*/
|
||||
typedef int32 ScriptLifeFunc(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
|
||||
struct ScriptLifeFunction {
|
||||
const char *name;
|
||||
ScriptLifeFunc *function;
|
||||
};
|
||||
|
||||
/** Script condition operators */
|
||||
enum LifeScriptOperators {
|
||||
/*==*/kEqualTo = 0,
|
||||
/*> */kGreaterThan = 1,
|
||||
/*< */kLessThan = 2,
|
||||
/*>=*/kGreaterThanOrEqualTo = 3,
|
||||
/*<=*/kLessThanOrEqualTo = 4,
|
||||
/*!=*/kNotEqualTo = 5
|
||||
};
|
||||
|
||||
class ScriptLife {
|
||||
private:
|
||||
TwinEEngine *_engine;
|
||||
const ScriptLifeFunction* _functionMap;
|
||||
size_t _functionMapSize;
|
||||
|
||||
public:
|
||||
static int32 lEMPTY(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lEND(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lNOP(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSNIF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lOFFSET(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lNEVERIF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lNO_IF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lLABEL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lRETURN(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lIF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSWIF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lONEIF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lELSE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBODY(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBODY_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lANIM(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lANIM_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_LIFE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_LIFE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_TRACK(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_TRACK_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lMESSAGE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFALLABLE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_DIRMODE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_DIRMODE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lCAM_FOLLOW(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_BEHAVIOUR(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_FLAG_CUBE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lCOMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_COMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_COMPORTEMENT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lEND_COMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lKILL_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSUICIDE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lUSE_ONE_LITTLE_KEY(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lGIVE_GOLD_PIECES(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lEND_LIFE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSTOP_L_TRACK(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lRESTORE_L_TRACK(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lMESSAGE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lINC_CHAPTER(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFOUND_OBJECT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_DOOR_LEFT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_DOOR_RIGHT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_DOOR_UP(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_DOOR_DOWN(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lGIVE_BONUS(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lCHANGE_CUBE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lOBJ_COL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBRICK_COL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lOR_IF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lINVISIBLE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lZOOM(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPOS_POINT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_MAGIC_LEVEL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSUB_MAGIC_POINT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_LIFE_POINT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSUB_LIFE_POINT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lHIT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPLAY_FLA(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lINC_CLOVER_BOX(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_USED_INVENTORY(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lADD_CHOICE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lASK_CHOICE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBIG_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lINIT_PINGOUIN(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_HOLO_POS(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lCLR_HOLO_POS(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lADD_FUEL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSUB_FUEL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_GRM(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSAY_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFULL_POINT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBETA(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lGRM_OFF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFADE_PAL_RED(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFADE_ALARM_RED(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFADE_ALARM_PAL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFADE_RED_PAL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFADE_RED_ALARM(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFADE_PAL_ALARM(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lEXPLODE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
|
||||
static int32 lASK_CHOICE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_DARK_PAL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_NORMAL_PAL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lMESSAGE_SENDELL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lANIM_SET(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lHOLOMAP_TRAJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lGAME_OVER(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lTHE_END(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPLAY_CD_TRACK(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPROJ_ISO(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPROJ_3D(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lTEXT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lCLEAR_TEXT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBRUTAL_EXIT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
|
||||
public:
|
||||
ScriptLife(TwinEEngine *engine, const ScriptLifeFunction* functionMap, size_t entries);
|
||||
|
||||
virtual ~ScriptLife() {}
|
||||
/**
|
||||
* Process actor life script
|
||||
* @param actorIdx Current processed actor index
|
||||
*/
|
||||
void doLife(int32 actorIdx);
|
||||
};
|
||||
|
||||
} // namespace TwinE
|
||||
|
||||
#endif
|
||||
196
engines/twine/script/script_life_v1.cpp
Normal file
196
engines/twine/script/script_life_v1.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "twine/script/script_life_v1.h"
|
||||
#include "common/debug.h"
|
||||
#include "twine/twine.h"
|
||||
#include "twine/text.h"
|
||||
#include "twine/audio/music.h"
|
||||
#include "twine/scene/gamestate.h"
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
/**
|
||||
* Turn on bubbles while actors talk.
|
||||
* @note Opcode @c 0x59
|
||||
*/
|
||||
int32 ScriptLifeV1::lBUBBLE_ON(TwinEEngine *engine, LifeScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsLife, "LIFE::BUBBLE_ON()");
|
||||
engine->_text->_showDialogueBubble = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off bubbles while actors talk.
|
||||
* @note Opcode @c 0x5A
|
||||
*/
|
||||
int32 ScriptLifeV1::lBUBBLE_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsLife, "LIFE::BUBBLE_OFF()");
|
||||
engine->_text->_showDialogueBubble = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play Midis (Parameter = Midis Index)
|
||||
* @note Opcode @c 0x41
|
||||
*/
|
||||
int32 ScriptLifeV1::lPLAY_MIDI(TwinEEngine *engine, LifeScriptContext &ctx) {
|
||||
const int32 midiIdx = ctx.stream.readByte();
|
||||
engine->_music->playMusic(midiIdx);
|
||||
debugC(3, kDebugLevels::kDebugScriptsLife, "LIFE::PLAY_MIDI(%i)", (int)midiIdx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the current played midi.
|
||||
* @note Opcode @c 0x63
|
||||
*/
|
||||
int32 ScriptLifeV1::lMIDI_OFF(TwinEEngine *engine, LifeScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsLife, "LIFE::MIDI_OFF()");
|
||||
engine->_music->stopMusicMidi();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new value for the game flag (Paramter = Game Flag Index, Parameter = Value)
|
||||
* @note Opcode @c 0x24
|
||||
*/
|
||||
int32 ScriptLifeV1::lSET_FLAG_GAME(TwinEEngine *engine, LifeScriptContext &ctx) {
|
||||
const uint8 flagIdx = ctx.stream.readByte();
|
||||
const uint8 flagValue = ctx.stream.readByte();
|
||||
debugC(3, kDebugLevels::kDebugScriptsLife, "LIFE::SET_FLAG_GAME(%i, %i)", (int)flagIdx, (int)flagValue);
|
||||
engine->_gameState->setGameFlag(flagIdx, flagValue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const ScriptLifeFunction function_map[] = {
|
||||
{"END", ScriptLifeV1::lEND},
|
||||
{"NOP", ScriptLifeV1::lNOP},
|
||||
{"SNIF", ScriptLifeV1::lSNIF},
|
||||
{"OFFSET", ScriptLifeV1::lOFFSET},
|
||||
{"NEVERIF", ScriptLifeV1::lNEVERIF},
|
||||
{"", ScriptLifeV1::lEMPTY}, // unused
|
||||
{"NO_IF", ScriptLifeV1::lNO_IF},
|
||||
{"", ScriptLifeV1::lEMPTY}, // unused
|
||||
{"", ScriptLifeV1::lEMPTY}, // unused
|
||||
{"", ScriptLifeV1::lEMPTY}, // unused
|
||||
{"LABEL", ScriptLifeV1::lLABEL},
|
||||
{"RETURN", ScriptLifeV1::lRETURN},
|
||||
{"IF", ScriptLifeV1::lIF},
|
||||
{"SWIF", ScriptLifeV1::lSWIF},
|
||||
{"ONEIF", ScriptLifeV1::lONEIF},
|
||||
{"ELSE", ScriptLifeV1::lELSE},
|
||||
{"ENDIF", ScriptLifeV1::lEMPTY}, // End of a conditional statement (e.g. IF)
|
||||
{"BODY", ScriptLifeV1::lBODY},
|
||||
{"BODY_OBJ", ScriptLifeV1::lBODY_OBJ},
|
||||
{"ANIM", ScriptLifeV1::lANIM},
|
||||
{"ANIM_OBJ", ScriptLifeV1::lANIM_OBJ},
|
||||
{"SET_LIFE", ScriptLifeV1::lSET_LIFE},
|
||||
{"SET_LIFE_OBJ", ScriptLifeV1::lSET_LIFE_OBJ},
|
||||
{"SET_TRACK", ScriptLifeV1::lSET_TRACK},
|
||||
{"SET_TRACK_OBJ", ScriptLifeV1::lSET_TRACK_OBJ},
|
||||
{"MESSAGE", ScriptLifeV1::lMESSAGE},
|
||||
{"FALLABLE", ScriptLifeV1::lFALLABLE},
|
||||
{"SET_DIRMODE", ScriptLifeV1::lSET_DIRMODE},
|
||||
{"SET_DIRMODE_OBJ", ScriptLifeV1::lSET_DIRMODE_OBJ},
|
||||
{"CAM_FOLLOW", ScriptLifeV1::lCAM_FOLLOW},
|
||||
{"SET_BEHAVIOUR", ScriptLifeV1::lSET_BEHAVIOUR},
|
||||
{"SET_FLAG_CUBE", ScriptLifeV1::lSET_FLAG_CUBE},
|
||||
{"COMPORTEMENT", ScriptLifeV1::lCOMPORTEMENT},
|
||||
{"SET_COMPORTEMENT", ScriptLifeV1::lSET_COMPORTEMENT},
|
||||
{"SET_COMPORTEMENT_OBJ", ScriptLifeV1::lSET_COMPORTEMENT_OBJ},
|
||||
{"END_COMPORTEMENT", ScriptLifeV1::lEND_COMPORTEMENT},
|
||||
{"SET_FLAG_GAME", ScriptLifeV1::lSET_FLAG_GAME},
|
||||
{"KILL_OBJ", ScriptLifeV1::lKILL_OBJ},
|
||||
{"SUICIDE", ScriptLifeV1::lSUICIDE},
|
||||
{"USE_ONE_LITTLE_KEY", ScriptLifeV1::lUSE_ONE_LITTLE_KEY},
|
||||
{"GIVE_GOLD_PIECES", ScriptLifeV1::lGIVE_GOLD_PIECES},
|
||||
{"END_LIFE", ScriptLifeV1::lEND_LIFE},
|
||||
{"STOP_L_TRACK", ScriptLifeV1::lSTOP_L_TRACK},
|
||||
{"RESTORE_L_TRACK", ScriptLifeV1::lRESTORE_L_TRACK},
|
||||
{"MESSAGE_OBJ", ScriptLifeV1::lMESSAGE_OBJ},
|
||||
{"INC_CHAPTER", ScriptLifeV1::lINC_CHAPTER},
|
||||
{"FOUND_OBJECT", ScriptLifeV1::lFOUND_OBJECT},
|
||||
{"SET_DOOR_LEFT", ScriptLifeV1::lSET_DOOR_LEFT},
|
||||
{"SET_DOOR_RIGHT", ScriptLifeV1::lSET_DOOR_RIGHT},
|
||||
{"SET_DOOR_UP", ScriptLifeV1::lSET_DOOR_UP},
|
||||
{"SET_DOOR_DOWN", ScriptLifeV1::lSET_DOOR_DOWN},
|
||||
{"GIVE_BONUS", ScriptLifeV1::lGIVE_BONUS},
|
||||
{"CHANGE_CUBE", ScriptLifeV1::lCHANGE_CUBE},
|
||||
{"OBJ_COL", ScriptLifeV1::lOBJ_COL},
|
||||
{"BRICK_COL", ScriptLifeV1::lBRICK_COL},
|
||||
{"OR_IF", ScriptLifeV1::lOR_IF},
|
||||
{"INVISIBLE", ScriptLifeV1::lINVISIBLE},
|
||||
{"ZOOM", ScriptLifeV1::lZOOM},
|
||||
{"POS_POINT", ScriptLifeV1::lPOS_POINT},
|
||||
{"SET_MAGIC_LEVEL", ScriptLifeV1::lSET_MAGIC_LEVEL},
|
||||
{"SUB_MAGIC_POINT", ScriptLifeV1::lSUB_MAGIC_POINT},
|
||||
{"SET_LIFE_POINT_OBJ", ScriptLifeV1::lSET_LIFE_POINT_OBJ},
|
||||
{"SUB_LIFE_POINT_OBJ", ScriptLifeV1::lSUB_LIFE_POINT_OBJ},
|
||||
{"HIT_OBJ", ScriptLifeV1::lHIT_OBJ},
|
||||
{"PLAY_FLA", ScriptLifeV1::lPLAY_FLA},
|
||||
{"PLAY_MIDI", ScriptLifeV1::lPLAY_MIDI},
|
||||
{"INC_CLOVER_BOX", ScriptLifeV1::lINC_CLOVER_BOX},
|
||||
{"SET_USED_INVENTORY", ScriptLifeV1::lSET_USED_INVENTORY},
|
||||
{"ADD_CHOICE", ScriptLifeV1::lADD_CHOICE},
|
||||
{"ASK_CHOICE", ScriptLifeV1::lASK_CHOICE},
|
||||
{"BIG_MESSAGE", ScriptLifeV1::lBIG_MESSAGE},
|
||||
{"INIT_PINGOUIN", ScriptLifeV1::lINIT_PINGOUIN},
|
||||
{"SET_HOLO_POS", ScriptLifeV1::lSET_HOLO_POS},
|
||||
{"CLR_HOLO_POS", ScriptLifeV1::lCLR_HOLO_POS},
|
||||
{"ADD_FUEL", ScriptLifeV1::lADD_FUEL},
|
||||
{"SUB_FUEL", ScriptLifeV1::lSUB_FUEL},
|
||||
{"SET_GRM", ScriptLifeV1::lSET_GRM},
|
||||
{"SAY_MESSAGE", ScriptLifeV1::lSAY_MESSAGE},
|
||||
{"SAY_MESSAGE_OBJ", ScriptLifeV1::lSAY_MESSAGE_OBJ},
|
||||
{"FULL_POINT", ScriptLifeV1::lFULL_POINT},
|
||||
{"BETA", ScriptLifeV1::lBETA},
|
||||
{"GRM_OFF", ScriptLifeV1::lGRM_OFF},
|
||||
{"FADE_PAL_RED", ScriptLifeV1::lFADE_PAL_RED},
|
||||
{"FADE_ALARM_RED", ScriptLifeV1::lFADE_ALARM_RED},
|
||||
{"FADE_ALARM_PAL", ScriptLifeV1::lFADE_ALARM_PAL},
|
||||
{"FADE_RED_PAL", ScriptLifeV1::lFADE_RED_PAL},
|
||||
{"FADE_RED_ALARM", ScriptLifeV1::lFADE_RED_ALARM},
|
||||
{"FADE_PAL_ALARM", ScriptLifeV1::lFADE_PAL_ALARM},
|
||||
{"EXPLODE_OBJ", ScriptLifeV1::lEXPLODE_OBJ},
|
||||
{"BUBBLE_ON", ScriptLifeV1::lBUBBLE_ON},
|
||||
{"BUBBLE_OFF", ScriptLifeV1::lBUBBLE_OFF},
|
||||
{"ASK_CHOICE_OBJ", ScriptLifeV1::lASK_CHOICE_OBJ},
|
||||
{"SET_DARK_PAL", ScriptLifeV1::lSET_DARK_PAL},
|
||||
{"SET_NORMAL_PAL", ScriptLifeV1::lSET_NORMAL_PAL},
|
||||
{"MESSAGE_SENDELL", ScriptLifeV1::lMESSAGE_SENDELL},
|
||||
{"ANIM_SET", ScriptLifeV1::lANIM_SET},
|
||||
{"HOLOMAP_TRAJ", ScriptLifeV1::lHOLOMAP_TRAJ},
|
||||
{"GAME_OVER", ScriptLifeV1::lGAME_OVER},
|
||||
{"THE_END", ScriptLifeV1::lTHE_END},
|
||||
{"MIDI_OFF", ScriptLifeV1::lMIDI_OFF},
|
||||
{"PLAY_CD_TRACK", ScriptLifeV1::lPLAY_CD_TRACK},
|
||||
{"PROJ_ISO", ScriptLifeV1::lPROJ_ISO},
|
||||
{"PROJ_3D", ScriptLifeV1::lPROJ_3D},
|
||||
{"TEXT", ScriptLifeV1::lTEXT},
|
||||
{"CLEAR_TEXT", ScriptLifeV1::lCLEAR_TEXT},
|
||||
{"BRUTAL_EXIT", ScriptLifeV1::lBRUTAL_EXIT}
|
||||
};
|
||||
|
||||
ScriptLifeV1::ScriptLifeV1(TwinEEngine *engine) : ScriptLife(engine, function_map, ARRAYSIZE(function_map)) {
|
||||
}
|
||||
|
||||
} // namespace TwinE
|
||||
44
engines/twine/script/script_life_v1.h
Normal file
44
engines/twine/script/script_life_v1.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWINE_SCRIPTLIFEV1_H
|
||||
#define TWINE_SCRIPTLIFEV1_H
|
||||
|
||||
#include "twine/script/script_life.h"
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
class TwinEEngine;
|
||||
|
||||
class ScriptLifeV1 : public ScriptLife {
|
||||
public:
|
||||
static int32 lBUBBLE_ON(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBUBBLE_OFF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPLAY_MIDI(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lMIDI_OFF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_FLAG_GAME(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
|
||||
ScriptLifeV1(TwinEEngine *engine);
|
||||
};
|
||||
|
||||
} // namespace TwinE
|
||||
|
||||
#endif
|
||||
1147
engines/twine/script/script_life_v2.cpp
Normal file
1147
engines/twine/script/script_life_v2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
120
engines/twine/script/script_life_v2.h
Normal file
120
engines/twine/script/script_life_v2.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWINE_SCRIPTLIFEV2_H
|
||||
#define TWINE_SCRIPTLIFEV2_H
|
||||
|
||||
#include "twine/script/script_life.h"
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
class TwinEEngine;
|
||||
|
||||
class ScriptLifeV2 : public ScriptLife {
|
||||
private:
|
||||
static int16 searchOffsetTrack(ActorStruct *ptrobj, uint8 label);
|
||||
static void cleanTrack(ActorStruct *ptrobj);
|
||||
|
||||
public:
|
||||
static int32 lPLAY_MUSIC(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lTRACK_TO_VAR_GAME(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lVAR_GAME_TO_TRACK(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lANIM_TEXTURE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lADD_MESSAGE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lADD_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBUBBLE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lNO_CHOC(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSAVE_HERO(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lRESTORE_HERO(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lCINEMA_MODE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lESCALATOR(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lRAIN(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lCAMERA_CENTER(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_CAMERA(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSHADOW_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPLAY_ACF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lECLAIR(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lINIT_BUGGY(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lMEMO_ARDOISE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_CHANGE_CUBE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lMESSAGE_ZOE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFADE_TO_PAL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lACTION(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_FRAME(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_SPRITE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_FRAME_3DS(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lIMPACT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lIMPACT_POINT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPALETTE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lLADDER(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_ARMOR(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_ARMOR_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lADD_LIFE_POINT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSTATE_INVENTORY(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lAND_IF(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSWITCH(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lOR_CASE (TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lCASE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lDEFAULT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBREAK(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lEND_SWITCH(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_HIT_ZONE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSAVE_COMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lRESTORE_COMPORTEMENT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSAMPLE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSAMPLE_RND(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSAMPLE_ALWAYS(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSAMPLE_STOP (TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lREPEAT_SAMPLE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lBACKGROUND(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lADD_VAR_GAME(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSUB_VAR_GAME(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lADD_VAR_CUBE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSUB_VAR_CUBE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_RAIL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lINVERSE_BETA(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lNO_BODY(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSTOP_L_TRACK_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lRESTORE_L_TRACK_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSAVE_COMPORTEMENT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lRESTORE_COMPORTEMENT_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSPY(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lDEBUG(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lDEBUG_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPOPCORN(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFLOW_POINT(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lFLOW_OBJ (TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_ANIM_DIAL(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPCX(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lEND_MESSAGE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lEND_MESSAGE_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPARM_SAMPLE(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lNEW_SAMPLE (TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPOS_OBJ_AROUND(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lPCX_MESS_OBJ(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
static int32 lSET_FLAG_GAME(TwinEEngine *engine, LifeScriptContext &ctx);
|
||||
|
||||
ScriptLifeV2(TwinEEngine *engine);
|
||||
};
|
||||
|
||||
} // namespace TwinE
|
||||
|
||||
#endif
|
||||
671
engines/twine/script/script_move.cpp
Normal file
671
engines/twine/script/script_move.cpp
Normal file
@@ -0,0 +1,671 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "twine/script/script_move.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/util.h"
|
||||
#include "twine/scene/animations.h"
|
||||
#include "twine/audio/sound.h"
|
||||
#include "twine/movies.h"
|
||||
#include "twine/scene/movements.h"
|
||||
#include "twine/renderer/redraw.h"
|
||||
#include "twine/renderer/renderer.h"
|
||||
#include "twine/renderer/screens.h"
|
||||
#include "twine/scene/scene.h"
|
||||
#include "twine/twine.h"
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
/**
|
||||
* For unused opcodes
|
||||
*/
|
||||
int32 ScriptMove::mEMPTY(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::EMPTY()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of Actor Move Script
|
||||
* @note Opcode @c 0x00
|
||||
*/
|
||||
int32 ScriptMove::mEND(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::END()");
|
||||
ctx.actor->_offsetTrack = -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* No Operation
|
||||
* @note Opcode @c 0x01
|
||||
*/
|
||||
int32 ScriptMove::mNOP(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::NOP()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose new body for the current actor (Parameter = File3D Body Instance)
|
||||
* @note Opcode @c 0x02
|
||||
*/
|
||||
int32 ScriptMove::mBODY(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
BodyType bodyIdx = (BodyType)ctx.stream.readByte();
|
||||
engine->_actor->initBody(bodyIdx, ctx.actorIdx);
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::BODY(%i)", (int)bodyIdx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose new animation for the current actor (Parameter = File3D Animation Instance)
|
||||
* @note Opcode @c 0x03
|
||||
*/
|
||||
int32 ScriptMove::mANIM(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
AnimationTypes animIdx = (AnimationTypes)ctx.stream.readByte();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::ANIM(%i)", (int)animIdx);
|
||||
if (engine->_animations->initAnim(animIdx, AnimType::kAnimationTypeRepeat, AnimationTypes::kStanding, ctx.actorIdx)) {
|
||||
return 0;
|
||||
}
|
||||
ctx.undo(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the actor to go to a new position (Parameter = Track Index)
|
||||
* @note Opcode @c 0x04
|
||||
*/
|
||||
int32 ScriptMove::mGOTO_POINT(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
engine->_scene->_currentScriptValue = ctx.stream.readByte();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::GOTO_POINT(%i)", (int)engine->_scene->_currentScriptValue);
|
||||
|
||||
const IVec3 &sp = engine->_scene->_sceneTracks[engine->_scene->_currentScriptValue];
|
||||
const int32 newAngle = engine->_movements->getAngle(ctx.actor->_posObj.x, ctx.actor->_posObj.z, sp.x, sp.z);
|
||||
|
||||
if (ctx.actor->_flags.bSprite3D) {
|
||||
ctx.actor->_beta = newAngle;
|
||||
} else {
|
||||
engine->_movements->initRealAngleConst(ctx.actor->_beta, newAngle, ctx.actor->_srot, &ctx.actor->realAngle);
|
||||
}
|
||||
|
||||
if (engine->_movements->_targetActorDistance > 500) {
|
||||
ctx.undo(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait the end of the current animation
|
||||
* @note Opcode @c 0x05
|
||||
*/
|
||||
int32 ScriptMove::mWAIT_ANIM(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::WAIT_ANIM()");
|
||||
if (!ctx.actor->_workFlags.bAnimEnded) {
|
||||
ctx.undo(0);
|
||||
} else {
|
||||
engine->_movements->clearRealAngle(ctx.actor);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop a certain label (Parameter = Label Number)
|
||||
* @note Opcode @c 0x06
|
||||
*/
|
||||
int32 ScriptMove::mLOOP(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
ctx.actor->_offsetTrack = 0;
|
||||
ctx.stream.seek(0);
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::LOOP()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the actor turn around
|
||||
* @note Opcode @c 0x07
|
||||
*/
|
||||
int32 ScriptMove::mANGLE(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int16 angle = ToAngle(ctx.stream.readSint16LE());
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::ANGLE(%i)", (int)angle);
|
||||
if (ctx.actor->_flags.bSprite3D) {
|
||||
return 0;
|
||||
}
|
||||
engine->_scene->_currentScriptValue = angle;
|
||||
if (ctx.actor->realAngle.timeValue == 0) {
|
||||
engine->_movements->initRealAngleConst(ctx.actor->_beta, angle, ctx.actor->_srot, &ctx.actor->realAngle);
|
||||
}
|
||||
if (ctx.actor->_beta == angle) {
|
||||
engine->_movements->clearRealAngle(ctx.actor);
|
||||
return 0;
|
||||
}
|
||||
ctx.undo(2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new position for the current actor (Parameter = Track Index)
|
||||
* @note Opcode @c 0x08
|
||||
*/
|
||||
int32 ScriptMove::mPOS_POINT(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
engine->_scene->_currentScriptValue = ctx.stream.readByte();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::POS_POINT(%i)", (int)engine->_scene->_currentScriptValue);
|
||||
|
||||
const IVec3 &sp = engine->_scene->_sceneTracks[engine->_scene->_currentScriptValue];
|
||||
if (ctx.actor->_flags.bSprite3D) {
|
||||
ctx.actor->_srot = 0;
|
||||
}
|
||||
|
||||
ctx.actor->_posObj = sp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a new label (Parameter = Label Number)
|
||||
* @note Opcode @c 0x09
|
||||
*/
|
||||
int32 ScriptMove::mLABEL(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
ctx.actor->_labelTrack = ctx.stream.readByte();
|
||||
ctx.actor->_offsetLabelTrack = ctx.stream.pos() - 2;
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::LABEL(%i)", (int)ctx.actor->_labelTrack);
|
||||
if (engine->_scene->_numCube == LBA1SceneId::Proxima_Island_Museum && ctx.actor->_actorIdx == 2 &&
|
||||
(ctx.actor->_labelTrack == 0 || ctx.actor->_labelTrack == 1)) {
|
||||
engine->unlockAchievement("LBA_ACH_004");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to a certain label (Parameter = Label Number)
|
||||
* @note Opcode @c 0x0A
|
||||
*/
|
||||
int32 ScriptMove::mGOTO(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int16 pos = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::GOTO(%i)", (int)pos);
|
||||
if (pos == -1) {
|
||||
ctx.actor->_offsetTrack = -1;
|
||||
return 1;
|
||||
}
|
||||
ctx.stream.seek(pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the actor to stop the current animation
|
||||
* @note Opcode @c 0x0B
|
||||
*/
|
||||
int32 ScriptMove::mSTOP(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::STOP()");
|
||||
ctx.actor->_offsetTrack = -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the actor to go to a symbolic point
|
||||
* @note Opcode @c 0x0C
|
||||
*/
|
||||
int32 ScriptMove::mGOTO_SYM_POINT(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
engine->_scene->_currentScriptValue = ctx.stream.readByte();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::GOTO_SYM_POINT(%i)", (int)engine->_scene->_currentScriptValue);
|
||||
|
||||
const IVec3 &sp = engine->_scene->_sceneTracks[engine->_scene->_currentScriptValue];
|
||||
const int32 newAngle = LBAAngles::ANGLE_180 + engine->_movements->getAngle(ctx.actor->_posObj, sp);
|
||||
|
||||
if (ctx.actor->_flags.bSprite3D) {
|
||||
ctx.actor->_beta = newAngle;
|
||||
} else {
|
||||
engine->_movements->initRealAngleConst(ctx.actor->_beta, newAngle, ctx.actor->_srot, &ctx.actor->realAngle);
|
||||
}
|
||||
|
||||
if (engine->_movements->_targetActorDistance > 500) {
|
||||
ctx.undo(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait a certain number of frame update in the current animation
|
||||
* @note Opcode @c 0x0D
|
||||
*/
|
||||
int32 ScriptMove::mWAIT_NUM_ANIM(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
bool abortMove = false;
|
||||
const int32 animRepeats = ctx.stream.readByte();
|
||||
int32 animPos = ctx.stream.readByte();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::WAIT_NUM_ANIM(%i, %i)", (int)animRepeats, animPos);
|
||||
if (ctx.actor->_workFlags.bAnimEnded) {
|
||||
animPos++;
|
||||
|
||||
if (animPos == animRepeats) {
|
||||
animPos = 0;
|
||||
} else {
|
||||
abortMove = true;
|
||||
}
|
||||
|
||||
ctx.stream.rewind(1);
|
||||
ctx.stream.writeByte(animPos);
|
||||
} else {
|
||||
abortMove = true;
|
||||
}
|
||||
|
||||
if (abortMove) {
|
||||
ctx.undo(2);
|
||||
}
|
||||
|
||||
return abortMove ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play a sample (Parameter = Sample index)
|
||||
* @note Opcode @c 0x0E
|
||||
*/
|
||||
int32 ScriptMove::mSAMPLE(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 sampleIdx = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SAMPLE(%i)", (int)sampleIdx);
|
||||
engine->_sound->mixSample3D(sampleIdx, 0x1000, 1, ctx.actor->posObj(), ctx.actorIdx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the actor to go to a new position (Parameter = Track Index)
|
||||
* @note Opcode @c 0x0F
|
||||
*/
|
||||
int32 ScriptMove::mGOTO_POINT_3D(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int32 trackId = ctx.stream.readByte();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::GOTO_POINT_3D(%i)", (int)trackId);
|
||||
if (!ctx.actor->_flags.bSprite3D) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
engine->_scene->_currentScriptValue = trackId;
|
||||
|
||||
const IVec3 &sp = engine->_scene->_sceneTracks[engine->_scene->_currentScriptValue];
|
||||
ctx.actor->_beta = engine->_movements->getAngle(ctx.actor->_posObj.x, ctx.actor->_posObj.z, sp.x, sp.z);
|
||||
ctx.actor->_spriteActorRotation = engine->_movements->getAngle(ctx.actor->_posObj.y, 0, sp.y, engine->_movements->_targetActorDistance);
|
||||
|
||||
if (engine->_movements->_targetActorDistance > 100) {
|
||||
ctx.undo(1);
|
||||
return 1;
|
||||
}
|
||||
ctx.actor->_posObj = sp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a new rotation speed for the current actor (Parameter = Rotation speed) [ 0 means fast, 32767 means slow ]
|
||||
* @note Opcode @c 0x10
|
||||
*/
|
||||
int32 ScriptMove::mSPEED(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
ctx.actor->_srot = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SPEED(%i)", (int)ctx.actor->_srot);
|
||||
|
||||
if (ctx.actor->_flags.bSprite3D) {
|
||||
engine->_movements->initRealValue(LBAAngles::ANGLE_0, ctx.actor->_srot, LBAAngles::ANGLE_17, &ctx.actor->realAngle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set actor as background (Parameter = 1 (true); = 0 (false))
|
||||
* @note Opcode @c 0x11
|
||||
*/
|
||||
int32 ScriptMove::mBACKGROUND(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const uint8 val = ctx.stream.readByte();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::BACKGROUND(%i)", (int)val);
|
||||
if (val != 0) {
|
||||
if (!ctx.actor->_flags.bIsBackgrounded) {
|
||||
ctx.actor->_flags.bIsBackgrounded = 1;
|
||||
if (ctx.actor->_workFlags.bWasDrawn) {
|
||||
engine->_redraw->_firstTime = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ctx.actor->_flags.bIsBackgrounded) {
|
||||
ctx.actor->_flags.bIsBackgrounded = 0;
|
||||
if (ctx.actor->_workFlags.bWasDrawn) {
|
||||
engine->_redraw->_firstTime = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number os seconds to wait.
|
||||
* @note Opcode @c 0x12
|
||||
*/
|
||||
int32 ScriptMove::mWAIT_NUM_SECOND(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int32 numSeconds = ctx.stream.readByte();
|
||||
int32 currentTime = ctx.stream.readSint32LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::WAIT_NUM_SECOND(%i, %i)", (int)numSeconds, currentTime);
|
||||
|
||||
if (currentTime == 0) {
|
||||
currentTime = engine->timerRef + engine->toSeconds(numSeconds);
|
||||
ctx.stream.rewind(4);
|
||||
ctx.stream.writeSint32LE(currentTime);
|
||||
}
|
||||
|
||||
if (engine->timerRef < currentTime) {
|
||||
ctx.undo(5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctx.stream.rewind(4);
|
||||
ctx.stream.writeSint32LE(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* To not use Bodies.
|
||||
* @note Opcode @c 0x13
|
||||
*/
|
||||
int32 ScriptMove::mNO_BODY(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::NO_BODY()");
|
||||
engine->_actor->initBody(BodyType::btNone, ctx.actorIdx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change actor orientation. (Parameter = New Angle)
|
||||
* @note Opcode @c 0x14
|
||||
*/
|
||||
int32 ScriptMove::mBETA(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int16 beta = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::BETA(%i)", (int)beta);
|
||||
|
||||
ctx.actor->_beta = beta;
|
||||
|
||||
if (!ctx.actor->_flags.bSprite3D) {
|
||||
engine->_movements->clearRealAngle(ctx.actor);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMove::mOPEN_GENERIC(TwinEEngine *engine, MoveScriptContext &ctx, int32 angle) {
|
||||
const int16 doorStatus = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::OPEN(%i, %i)", (int)doorStatus, angle);
|
||||
if (ctx.actor->_flags.bSprite3D && ctx.actor->_flags.bSpriteClip) {
|
||||
ctx.actor->_beta = angle;
|
||||
ctx.actor->_doorWidth = doorStatus;
|
||||
ctx.actor->_workFlags.bIsSpriteMoving = 1;
|
||||
ctx.actor->_srot = 1000;
|
||||
engine->_movements->initRealValue(LBAAngles::ANGLE_0, LBAAngles::ANGLE_351, LBAAngles::ANGLE_17, &ctx.actor->realAngle);
|
||||
}
|
||||
if (engine->_scene->_numCube == LBA1SceneId::Proxima_Island_Museum && ctx.actor->_actorIdx == 16) {
|
||||
engine->unlockAchievement("LBA_ACH_009");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the door (left way) (Parameter = distance to open).
|
||||
* @note Opcode @c 0x15
|
||||
*/
|
||||
int32 ScriptMove::mOPEN_LEFT(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
return mOPEN_GENERIC(engine, ctx, LBAAngles::ANGLE_270);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the door (right way) (Parameter = distance to open).
|
||||
* @note Opcode @c 0x16
|
||||
*/
|
||||
int32 ScriptMove::mOPEN_RIGHT(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
return mOPEN_GENERIC(engine, ctx, LBAAngles::ANGLE_90);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the door (up way) (Parameter = distance to open).
|
||||
* @note Opcode @c 0x17
|
||||
*/
|
||||
int32 ScriptMove::mOPEN_UP(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
return mOPEN_GENERIC(engine, ctx, LBAAngles::ANGLE_180);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the door (down way) (Parameter = distance to open).
|
||||
* @note Opcode @c 0x18
|
||||
*/
|
||||
int32 ScriptMove::mOPEN_DOWN(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
return mOPEN_GENERIC(engine, ctx, LBAAngles::ANGLE_0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the door.
|
||||
* @note Opcode @c 0x19
|
||||
*/
|
||||
int32 ScriptMove::mCLOSE(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::CLOSE()");
|
||||
if (ctx.actor->_flags.bSprite3D && ctx.actor->_flags.bSpriteClip) {
|
||||
ctx.actor->_doorWidth = 0;
|
||||
ctx.actor->_workFlags.bIsSpriteMoving = 1;
|
||||
ctx.actor->_srot = -1000;
|
||||
engine->_movements->initRealValue(LBAAngles::ANGLE_0, -LBAAngles::ANGLE_351, LBAAngles::ANGLE_17, &ctx.actor->realAngle);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait till door close.
|
||||
* @note Opcode @c 0x1A
|
||||
*/
|
||||
int32 ScriptMove::mWAIT_DOOR(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::WAIT_DOOR()");
|
||||
if (ctx.actor->_flags.bSprite3D && ctx.actor->_flags.bSpriteClip) {
|
||||
if (ctx.actor->_srot) {
|
||||
ctx.undo(0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random sample.
|
||||
* @note Opcode @c 0x1B
|
||||
*/
|
||||
int32 ScriptMove::mSAMPLE_RND(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 sampleIdx = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SAMPLE_RND(%i)", (int)sampleIdx);
|
||||
const uint16 pitchbend = 0x800 + engine->getRandomNumber(0x800);
|
||||
engine->_sound->mixSample3D(sampleIdx, pitchbend, 1, ctx.actor->posObj(), ctx.actorIdx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play always the sample (Parameter = Sample index)
|
||||
* @note Opcode @c 0x1C
|
||||
*/
|
||||
int32 ScriptMove::mSAMPLE_ALWAYS(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 sampleIdx = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SAMPLE_ALWAYS(%i)", (int)sampleIdx);
|
||||
if (!engine->_sound->isSamplePlaying(sampleIdx)) { // if its not playing
|
||||
engine->_sound->mixSample3D(sampleIdx, 0x1000, 0, ctx.actor->posObj(), ctx.actorIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop playing the sample
|
||||
* @note Opcode @c 0x1D
|
||||
*/
|
||||
int32 ScriptMove::mSAMPLE_STOP(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 sampleIdx = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SAMPLE_STOP(%i)", (int)sampleIdx);
|
||||
engine->_sound->stopSample(sampleIdx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play FLA cutscenes (Parameter = Cutscene Name)
|
||||
* @note Opcode @c 0x1E
|
||||
*/
|
||||
int32 ScriptMove::mPLAY_FLA(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int strIdx = 0;
|
||||
char movie[64];
|
||||
do {
|
||||
const byte c = ctx.stream.readByte();
|
||||
movie[strIdx++] = c;
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
if (strIdx >= ARRAYSIZE(movie)) {
|
||||
error("Max string size exceeded for fla name");
|
||||
}
|
||||
} while (true);
|
||||
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::PLAY_FLA(%s)", movie);
|
||||
engine->saveTimer(false);
|
||||
engine->_screens->fadeToBlack(engine->_screens->_ptrPal);
|
||||
engine->_movie->playMovie(movie);
|
||||
engine->_screens->_flagFade = true;
|
||||
engine->restoreTimer();
|
||||
engine->_redraw->drawScene(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeat sample (Parameter = Sample index).
|
||||
* @note Opcode @c 0x1F
|
||||
*/
|
||||
int32 ScriptMove::mREPEAT_SAMPLE(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
ctx.bigSampleRepeat = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::REPEAT_SAMPLE(%i)", (int)ctx.bigSampleRepeat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play a sample (Parameter = Sample index)
|
||||
* @note Opcode @c 0x20
|
||||
*/
|
||||
int32 ScriptMove::mSIMPLE_SAMPLE(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 sampleIdx = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SIMPLE_SAMPLE(%i)", (int)sampleIdx);
|
||||
engine->_sound->mixSample(sampleIdx, 0x1000, ctx.bigSampleRepeat, 128, 128);
|
||||
ctx.bigSampleRepeat = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actor rotate to Twinsen direction (Parameter = -1 (near); = 0 (far))
|
||||
* @note Opcode @c 0x21
|
||||
*/
|
||||
int32 ScriptMove::mFACE_HERO(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int16 angle = ToAngle(ctx.stream.readSint16LE());
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::FACE_HERO(%i)", (int)angle);
|
||||
if (ctx.actor->_flags.bSprite3D) {
|
||||
return 0;
|
||||
}
|
||||
engine->_scene->_currentScriptValue = angle;
|
||||
if (engine->_scene->_currentScriptValue == -1 && ctx.actor->realAngle.timeValue == 0) {
|
||||
engine->_scene->_currentScriptValue = engine->_movements->getAngle(ctx.actor->posObj(), engine->_scene->_sceneHero->posObj());
|
||||
engine->_movements->initRealAngleConst(ctx.actor->_beta, engine->_scene->_currentScriptValue, ctx.actor->_srot, &ctx.actor->realAngle);
|
||||
ctx.stream.rewind(2);
|
||||
ctx.stream.writeSint16LE(engine->_scene->_currentScriptValue);
|
||||
}
|
||||
|
||||
if (ctx.actor->_beta != engine->_scene->_currentScriptValue) {
|
||||
ctx.undo(2);
|
||||
return 1;
|
||||
}
|
||||
engine->_movements->clearRealAngle(ctx.actor);
|
||||
ctx.stream.rewind(2);
|
||||
ctx.stream.writeSint16LE(-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random angle for the current actor
|
||||
* @note Opcode @c 0x22
|
||||
*/
|
||||
int32 ScriptMove::mANGLE_RND(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int16 val1 = ctx.stream.readSint16LE();
|
||||
const int16 val2 = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::LBAAngles::ANGLE_RND(%i, %i)", (int)val1, (int)val2);
|
||||
if (ctx.actor->_flags.bSprite3D) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
engine->_scene->_currentScriptValue = val2;
|
||||
|
||||
if (engine->_scene->_currentScriptValue == -1 && ctx.actor->realAngle.timeValue == 0) {
|
||||
if (engine->getRandomNumber() & 1) {
|
||||
const int32 newAngle = ctx.actor->_beta + LBAAngles::ANGLE_90 + (ABS(val1) >> 1);
|
||||
engine->_scene->_currentScriptValue = ClampAngle(newAngle - engine->getRandomNumber(val1));
|
||||
} else {
|
||||
const int32 newAngle = ctx.actor->_beta - LBAAngles::ANGLE_90 + (ABS(val1) >> 1);
|
||||
engine->_scene->_currentScriptValue = ClampAngle(newAngle - engine->getRandomNumber(val1));
|
||||
}
|
||||
|
||||
engine->_movements->initRealAngleConst(ctx.actor->_beta, engine->_scene->_currentScriptValue, ctx.actor->_srot, &ctx.actor->realAngle);
|
||||
ctx.stream.rewind(2);
|
||||
ctx.stream.writeSint16LE(engine->_scene->_currentScriptValue);
|
||||
}
|
||||
|
||||
if (ctx.actor->_beta != engine->_scene->_currentScriptValue) {
|
||||
ctx.undo(4);
|
||||
return 1;
|
||||
}
|
||||
engine->_movements->clearRealAngle(ctx.actor);
|
||||
ctx.stream.rewind(2);
|
||||
ctx.stream.writeSint16LE(-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ScriptMove::ScriptMove(TwinEEngine *engine, const ScriptMoveFunction *functionMap, size_t entries) : _engine(engine), _functionMap(functionMap), _functionMapSize(entries) {
|
||||
}
|
||||
|
||||
void ScriptMove::doTrack(int32 actorIdx) {
|
||||
ActorStruct *actor = _engine->_scene->getActor(actorIdx);
|
||||
|
||||
int32 end = -2;
|
||||
|
||||
MoveScriptContext ctx(actorIdx, actor);
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::BEGIN(%i)", actorIdx);
|
||||
do {
|
||||
const byte scriptOpcode = ctx.stream.readByte();
|
||||
if (scriptOpcode < _functionMapSize) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::EXEC(%s, %i)", _functionMap[scriptOpcode].name, actorIdx);
|
||||
end = _functionMap[scriptOpcode].function(_engine, ctx);
|
||||
} else {
|
||||
error("Actor %d with wrong offset/opcode in move script - Offset: %d/%d (opcode: %u)", actorIdx, (int)ctx.stream.pos() - 1, (int)ctx.stream.size(), scriptOpcode);
|
||||
}
|
||||
|
||||
if (end < 0) {
|
||||
warning("Actor %d Life script [%s] not implemented", actorIdx, _functionMap[scriptOpcode].name);
|
||||
} else if (end == 1) {
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::BREAK(%i)", actorIdx);
|
||||
}
|
||||
|
||||
if (ctx.actor->_offsetTrack != -1) {
|
||||
actor->_offsetTrack = ctx.stream.pos();
|
||||
}
|
||||
} while (end != 1);
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::END(%i)", actorIdx);
|
||||
}
|
||||
|
||||
} // namespace TwinE
|
||||
116
engines/twine/script/script_move.h
Normal file
116
engines/twine/script/script_move.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWINE_SCRIPTMOVE_H
|
||||
#define TWINE_SCRIPTMOVE_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "twine/scene/actor.h"
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
struct MoveScriptContext {
|
||||
int32 actorIdx;
|
||||
ActorStruct *actor;
|
||||
int32 bigSampleRepeat = 1;
|
||||
|
||||
Common::MemorySeekableReadWriteStream stream;
|
||||
|
||||
MoveScriptContext(int32 _actorIdx, ActorStruct *_actor) : actorIdx(_actorIdx), actor(_actor), stream(actor->_ptrTrack, actor->_moveScriptSize) {
|
||||
assert(actor->_offsetTrack >= 0);
|
||||
stream.skip(actor->_offsetTrack);
|
||||
}
|
||||
|
||||
void undo(int32 bytes) {
|
||||
assert(bytes >= 0);
|
||||
// the additional 1 byte is for the opcode
|
||||
stream.rewind(bytes + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns @c -1 Need implementation, @c 0 Condition false, @c 1 - Condition true
|
||||
*/
|
||||
typedef int32 ScriptMoveFunc(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
|
||||
struct ScriptMoveFunction {
|
||||
const char *name;
|
||||
ScriptMoveFunc *function;
|
||||
};
|
||||
|
||||
class ScriptMove {
|
||||
private:
|
||||
TwinEEngine *_engine;
|
||||
const ScriptMoveFunction* _functionMap;
|
||||
size_t _functionMapSize;
|
||||
|
||||
public:
|
||||
static int32 mEMPTY(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mEND(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mNOP(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mBODY(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mANIM(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mGOTO_POINT(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mWAIT_ANIM(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mLOOP(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mANGLE(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mPOS_POINT(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mLABEL(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mGOTO(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSTOP(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mGOTO_SYM_POINT(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mWAIT_NUM_ANIM(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSAMPLE(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mGOTO_POINT_3D(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSPEED(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mBACKGROUND(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mWAIT_NUM_SECOND(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mNO_BODY(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mBETA(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mOPEN_GENERIC(TwinEEngine *engine, MoveScriptContext &ctx, int32 angle);
|
||||
static int32 mOPEN_LEFT(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mOPEN_RIGHT(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mOPEN_UP(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mOPEN_DOWN(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mCLOSE(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mWAIT_DOOR(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSAMPLE_RND(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSAMPLE_ALWAYS(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSAMPLE_STOP(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mPLAY_FLA(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mREPEAT_SAMPLE(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSIMPLE_SAMPLE(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mFACE_HERO(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mANGLE_RND(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
|
||||
public:
|
||||
ScriptMove(TwinEEngine *engine, const ScriptMoveFunction* functionMap, size_t entries);
|
||||
virtual ~ScriptMove() {}
|
||||
/**
|
||||
* Process actor move script
|
||||
* @param actorIdx Current processed actor index
|
||||
*/
|
||||
void doTrack(int32 actorIdx);
|
||||
};
|
||||
|
||||
} // namespace TwinE
|
||||
|
||||
#endif
|
||||
68
engines/twine/script/script_move_v1.cpp
Normal file
68
engines/twine/script/script_move_v1.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "twine/script/script_move_v1.h"
|
||||
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
static const ScriptMoveFunction function_map[] = {
|
||||
{"END", ScriptMove::mEND},
|
||||
{"NOP", ScriptMove::mNOP},
|
||||
{"BODY", ScriptMove::mBODY},
|
||||
{"ANIM", ScriptMove::mANIM},
|
||||
{"GOTO_POINT", ScriptMove::mGOTO_POINT},
|
||||
{"WAIT_ANIM", ScriptMove::mWAIT_ANIM},
|
||||
{"LOOP", ScriptMove::mLOOP},
|
||||
{"ANGLE", ScriptMove::mANGLE},
|
||||
{"POS_POINT", ScriptMove::mPOS_POINT},
|
||||
{"LABEL", ScriptMove::mLABEL},
|
||||
{"GOTO", ScriptMove::mGOTO},
|
||||
{"STOP", ScriptMove::mSTOP},
|
||||
{"GOTO_SYM_POINT", ScriptMove::mGOTO_SYM_POINT},
|
||||
{"WAIT_NUM_ANIM", ScriptMove::mWAIT_NUM_ANIM},
|
||||
{"SAMPLE", ScriptMove::mSAMPLE},
|
||||
{"GOTO_POINT_3D", ScriptMove::mGOTO_POINT_3D},
|
||||
{"SPEED", ScriptMove::mSPEED},
|
||||
{"BACKGROUND", ScriptMove::mBACKGROUND},
|
||||
{"WAIT_NUM_SECOND", ScriptMove::mWAIT_NUM_SECOND},
|
||||
{"NO_BODY", ScriptMove::mNO_BODY},
|
||||
{"BETA", ScriptMove::mBETA},
|
||||
{"OPEN_LEFT", ScriptMove::mOPEN_LEFT},
|
||||
{"OPEN_RIGHT", ScriptMove::mOPEN_RIGHT},
|
||||
{"OPEN_UP", ScriptMove::mOPEN_UP},
|
||||
{"OPEN_DOWN", ScriptMove::mOPEN_DOWN},
|
||||
{"CLOSE", ScriptMove::mCLOSE},
|
||||
{"WAIT_DOOR", ScriptMove::mWAIT_DOOR},
|
||||
{"SAMPLE_RND", ScriptMove::mSAMPLE_RND},
|
||||
{"SAMPLE_ALWAYS", ScriptMove::mSAMPLE_ALWAYS},
|
||||
{"SAMPLE_STOP", ScriptMove::mSAMPLE_STOP},
|
||||
{"PLAY_FLA", ScriptMove::mPLAY_FLA},
|
||||
{"REPEAT_SAMPLE", ScriptMove::mREPEAT_SAMPLE},
|
||||
{"SIMPLE_SAMPLE", ScriptMove::mSIMPLE_SAMPLE},
|
||||
{"FACE_HERO", ScriptMove::mFACE_HERO},
|
||||
{"ANGLE_RND", ScriptMove::mANGLE_RND}
|
||||
};
|
||||
|
||||
ScriptMoveV1::ScriptMoveV1(TwinEEngine *engine) : ScriptMove(engine, function_map, ARRAYSIZE(function_map)) {
|
||||
}
|
||||
|
||||
} // namespace TwinE
|
||||
38
engines/twine/script/script_move_v1.h
Normal file
38
engines/twine/script/script_move_v1.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWINE_SCRIPTMOVEV1_H
|
||||
#define TWINE_SCRIPTMOVEV1_H
|
||||
|
||||
#include "twine/script/script_move.h"
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
class TwinEEngine;
|
||||
|
||||
class ScriptMoveV1 : public ScriptMove {
|
||||
public:
|
||||
ScriptMoveV1(TwinEEngine *engine);
|
||||
};
|
||||
|
||||
} // namespace TwinE
|
||||
|
||||
#endif
|
||||
285
engines/twine/script/script_move_v2.cpp
Normal file
285
engines/twine/script/script_move_v2.cpp
Normal file
@@ -0,0 +1,285 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "twine/script/script_move_v2.h"
|
||||
#include "twine/audio/sound.h"
|
||||
#include "twine/resources/resources.h"
|
||||
#include "twine/twine.h"
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
static const ScriptMoveFunction function_map[] = {
|
||||
{"END", ScriptMove::mEND},
|
||||
{"NOP", ScriptMove::mNOP},
|
||||
{"BODY", ScriptMove::mBODY},
|
||||
{"ANIM", ScriptMove::mANIM},
|
||||
{"GOTO_POINT", ScriptMove::mGOTO_POINT},
|
||||
{"WAIT_ANIM", ScriptMove::mWAIT_ANIM},
|
||||
{"LOOP", ScriptMove::mLOOP},
|
||||
{"ANGLE", ScriptMove::mANGLE},
|
||||
{"POS_POINT", ScriptMove::mPOS_POINT},
|
||||
{"LABEL", ScriptMove::mLABEL},
|
||||
{"GOTO", ScriptMove::mGOTO},
|
||||
{"STOP", ScriptMove::mSTOP},
|
||||
{"GOTO_SYM_POINT", ScriptMove::mGOTO_SYM_POINT},
|
||||
{"WAIT_NUM_ANIM", ScriptMove::mWAIT_NUM_ANIM},
|
||||
{"SAMPLE", ScriptMove::mSAMPLE},
|
||||
{"GOTO_POINT_3D", ScriptMove::mGOTO_POINT_3D},
|
||||
{"SPEED", ScriptMove::mSPEED},
|
||||
{"BACKGROUND", ScriptMove::mBACKGROUND},
|
||||
{"WAIT_NUM_SECOND", ScriptMove::mWAIT_NUM_SECOND},
|
||||
{"NO_BODY", ScriptMove::mNO_BODY},
|
||||
{"BETA", ScriptMove::mBETA},
|
||||
{"OPEN_LEFT", ScriptMove::mOPEN_LEFT},
|
||||
{"OPEN_RIGHT", ScriptMove::mOPEN_RIGHT},
|
||||
{"OPEN_UP", ScriptMove::mOPEN_UP},
|
||||
{"OPEN_DOWN", ScriptMove::mOPEN_DOWN},
|
||||
{"CLOSE", ScriptMove::mCLOSE},
|
||||
{"WAIT_DOOR", ScriptMove::mWAIT_DOOR},
|
||||
{"SAMPLE_RND", ScriptMove::mSAMPLE_RND},
|
||||
{"SAMPLE_ALWAYS", ScriptMoveV2::mSAMPLE_ALWAYS},
|
||||
{"SAMPLE_STOP", ScriptMove::mSAMPLE_STOP},
|
||||
{"PLAY_FLA", ScriptMove::mPLAY_FLA},
|
||||
{"REPEAT_SAMPLE", ScriptMove::mREPEAT_SAMPLE},
|
||||
{"SIMPLE_SAMPLE", ScriptMove::mSIMPLE_SAMPLE},
|
||||
{"FACE_HERO", ScriptMove::mFACE_HERO},
|
||||
{"ANGLE_RND", ScriptMove::mANGLE_RND},
|
||||
{"REM", ScriptMove::mEMPTY}, // unused
|
||||
{"WAIT_NB_DIZIEME", ScriptMoveV2::mWAIT_NB_DIZIEME},
|
||||
{"DO", ScriptMove::mEMPTY}, // unused
|
||||
{"SPRITE", ScriptMoveV2::mSPRITE},
|
||||
{"WAIT_NB_SECOND_RND", ScriptMoveV2::mWAIT_NB_SECOND_RND},
|
||||
{"AFF_TIMER", ScriptMove::mEMPTY}, // unused
|
||||
{"SET_FRAME", ScriptMoveV2::mSET_FRAME},
|
||||
{"SET_FRAME_3DS", ScriptMoveV2::mSET_FRAME_3DS},
|
||||
{"SET_START_3DS", ScriptMoveV2::mSET_START_3DS},
|
||||
{"SET_END_3DS", ScriptMoveV2::mSET_END_3DS},
|
||||
{"START_ANIM_3DS", ScriptMoveV2::mSTART_ANIM_3DS},
|
||||
{"STOP_ANIM_3DS", ScriptMoveV2::mSTOP_ANIM_3DS},
|
||||
{"WAIT_ANIM_3DS", ScriptMoveV2::mWAIT_ANIM_3DS},
|
||||
{"WAIT_FRAME_3DS", ScriptMoveV2::mWAIT_FRAME_3DS},
|
||||
{"WAIT_NB_DIZIEME_RND", ScriptMoveV2::mWAIT_NB_DIZIEME_RND},
|
||||
{"DECALAGE", ScriptMoveV2::mOFFSET},
|
||||
{"FREQUENCY", ScriptMoveV2::mFREQUENCY},
|
||||
{"VOLUME", ScriptMoveV2::mVOLUME}
|
||||
};
|
||||
|
||||
int32 ScriptMoveV2::mWAIT_NB_DIZIEME(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int32 numSeconds = ctx.stream.readByte();
|
||||
int32 currentTime = ctx.stream.readSint32LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::WAIT_NB_DIZIEME(%i, %i)", (int)numSeconds, currentTime);
|
||||
|
||||
if (currentTime == 0) {
|
||||
currentTime = engine->timerRef + engine->toSeconds(numSeconds) / 10;
|
||||
ctx.stream.rewind(4);
|
||||
ctx.stream.writeSint32LE(currentTime);
|
||||
}
|
||||
|
||||
if (engine->timerRef < currentTime) {
|
||||
ctx.undo(5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctx.stream.rewind(4);
|
||||
ctx.stream.writeSint32LE(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mWAIT_NB_DIZIEME_RND(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int32 numSeconds = engine->getRandomNumber(ctx.stream.readByte());
|
||||
int32 currentTime = ctx.stream.readSint32LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::WAIT_NB_DIZIEME(%i, %i)", (int)numSeconds, currentTime);
|
||||
|
||||
if (currentTime == 0) {
|
||||
currentTime = engine->timerRef + engine->toSeconds(numSeconds) / 10;
|
||||
ctx.stream.rewind(4);
|
||||
ctx.stream.writeSint32LE(currentTime);
|
||||
}
|
||||
|
||||
if (engine->timerRef < currentTime) {
|
||||
ctx.undo(5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctx.stream.rewind(4);
|
||||
ctx.stream.writeSint32LE(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mWAIT_NB_SECOND_RND(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int32 numSeconds = engine->getRandomNumber(ctx.stream.readByte());
|
||||
int32 currentTime = ctx.stream.readSint32LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::WAIT_NB_SECOND_RND(%i, %i)", (int)numSeconds, currentTime);
|
||||
|
||||
if (currentTime == 0) {
|
||||
currentTime = engine->timerRef + engine->toSeconds(numSeconds);
|
||||
ctx.stream.rewind(4);
|
||||
ctx.stream.writeSint32LE(currentTime);
|
||||
}
|
||||
|
||||
if (engine->timerRef < currentTime) {
|
||||
ctx.undo(5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ctx.stream.rewind(4);
|
||||
ctx.stream.writeSint32LE(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mSPRITE(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int16 num = ctx.stream.readSint16LE();
|
||||
if (ctx.actor->_flags.bSprite3D) {
|
||||
engine->_actor->initSprite(num, ctx.actorIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mSAMPLE_ALWAYS(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 sampleIdx = ctx.stream.readSint16LE();
|
||||
debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SAMPLE_ALWAYS(%i)", (int)sampleIdx);
|
||||
if (!engine->_sound->isSamplePlaying(sampleIdx)) {
|
||||
engine->_sound->mixSample3D(sampleIdx, engine->_sound->_parmSampleFrequence, engine->_sound->_parmSampleVolume, ctx.actor->posObj(), ctx.actorIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mSET_FRAME(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const uint8 num = ctx.stream.readByte();
|
||||
if (!ctx.actor->_flags.bSprite3D) {
|
||||
engine->_actor->setFrame(ctx.actorIdx, num);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mSET_FRAME_3DS(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 num = ctx.stream.readByte();
|
||||
if (ctx.actor->_flags.bHasSpriteAnim3D) {
|
||||
const T_ANIM_3DS *anim = engine->_resources->getAnim(ctx.actor->A3DS.Num);
|
||||
if (num > (anim->Fin - anim->Deb)) {
|
||||
num = anim->Fin - anim->Deb;
|
||||
}
|
||||
|
||||
num += anim->Deb;
|
||||
|
||||
engine->_actor->initSprite(num, ctx.actorIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mSET_START_3DS(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 num = ctx.stream.readByte();
|
||||
if (ctx.actor->_flags.bHasSpriteAnim3D) {
|
||||
const T_ANIM_3DS *anim = engine->_resources->getAnim(ctx.actor->A3DS.Num);
|
||||
if (num > (anim->Fin - anim->Deb)) {
|
||||
num = anim->Fin - anim->Deb;
|
||||
}
|
||||
|
||||
num += anim->Deb;
|
||||
|
||||
ctx.actor->A3DS.Deb = num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mSET_END_3DS(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 num = ctx.stream.readByte();
|
||||
if (ctx.actor->_flags.bHasSpriteAnim3D) {
|
||||
const T_ANIM_3DS *anim = engine->_resources->getAnim(ctx.actor->A3DS.Num);
|
||||
if (num > (anim->Fin - anim->Deb)) {
|
||||
num = anim->Fin - anim->Deb;
|
||||
}
|
||||
|
||||
num += anim->Deb;
|
||||
|
||||
ctx.actor->A3DS.Fin = num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mSTART_ANIM_3DS(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
const int32 num = ctx.stream.readByte(); // NbFps
|
||||
if (ctx.actor->_flags.bHasSpriteAnim3D) {
|
||||
engine->_actor->initSprite(ctx.actor->A3DS.Deb, ctx.actorIdx);
|
||||
ctx.actor->SizeSHit = (int16)num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mSTOP_ANIM_3DS(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
if (ctx.actor->_flags.bHasSpriteAnim3D) {
|
||||
ctx.actor->SizeSHit = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mWAIT_ANIM_3DS(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
if (ctx.actor->_flags.bHasSpriteAnim3D) {
|
||||
if (ctx.actor->_sprite != ctx.actor->A3DS.Fin && ctx.actor->SizeSHit != 0) {
|
||||
ctx.undo(1); // OffsetTrack--
|
||||
return 1; // wait
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mWAIT_FRAME_3DS(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
int32 num = ctx.stream.readByte();
|
||||
if (ctx.actor->_flags.bHasSpriteAnim3D) {
|
||||
const T_ANIM_3DS *anim = engine->_resources->getAnim(ctx.actor->A3DS.Num);
|
||||
if (num > (anim->Fin - anim->Deb)) {
|
||||
num = anim->Fin - anim->Deb;
|
||||
}
|
||||
|
||||
num += anim->Deb;
|
||||
|
||||
if (ctx.actor->_sprite != num) {
|
||||
ctx.undo(2); // OffsetTrack -= 2
|
||||
return 1; // wait
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// DECALAGE
|
||||
int32 ScriptMoveV2::mOFFSET(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
engine->_sound->_parmSampleDecalage = ctx.stream.readSint16LE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FREQUENCE
|
||||
int32 ScriptMoveV2::mFREQUENCY(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
engine->_sound->_parmSampleFrequence = ctx.stream.readSint16LE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ScriptMoveV2::mVOLUME(TwinEEngine *engine, MoveScriptContext &ctx) {
|
||||
engine->_sound->_parmSampleVolume = ctx.stream.readByte();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ScriptMoveV2::ScriptMoveV2(TwinEEngine *engine) : ScriptMove(engine, function_map, ARRAYSIZE(function_map)) {
|
||||
}
|
||||
|
||||
} // namespace TwinE
|
||||
55
engines/twine/script/script_move_v2.h
Normal file
55
engines/twine/script/script_move_v2.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TWINE_SCRIPTMOVEV2_H
|
||||
#define TWINE_SCRIPTMOVEV2_H
|
||||
|
||||
#include "twine/script/script_move.h"
|
||||
|
||||
namespace TwinE {
|
||||
|
||||
class TwinEEngine;
|
||||
|
||||
class ScriptMoveV2 : public ScriptMove {
|
||||
public:
|
||||
static int32 mWAIT_NB_DIZIEME(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSPRITE(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mWAIT_NB_SECOND_RND(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSAMPLE_ALWAYS(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSET_FRAME(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSET_FRAME_3DS(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSET_START_3DS(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSET_END_3DS(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSTART_ANIM_3DS(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mSTOP_ANIM_3DS(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mWAIT_ANIM_3DS(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mWAIT_FRAME_3DS(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mWAIT_NB_DIZIEME_RND(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mOFFSET(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mFREQUENCY(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
static int32 mVOLUME(TwinEEngine *engine, MoveScriptContext &ctx);
|
||||
|
||||
ScriptMoveV2(TwinEEngine *engine);
|
||||
};
|
||||
|
||||
} // namespace TwinE
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user