286 lines
8.7 KiB
C++
286 lines
8.7 KiB
C++
/* 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
|