Files
scummvm-cursorfix/engines/twine/script/script_move_v2.cpp
2026-02-02 04:50:13 +01:00

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