MYST3: Partial implementation of opcode 127 - drag lever

Also contains a build fix for older GCC versions
This commit is contained in:
Bastien Bouclet 2012-01-17 15:54:37 +01:00
parent cffb466b69
commit 077d79d059
5 changed files with 89 additions and 3 deletions

View file

@ -212,7 +212,7 @@ void ScriptedMovie::update() {
if (_nextFrameReadVar) {
int32 nextFrame = _vm->_state->getVar(_nextFrameReadVar);
if (nextFrame > 0) {
if (_bink.getCurFrame() != nextFrame) {
if (_bink.getCurFrame() != nextFrame - 1) {
_bink.seekToFrame(nextFrame - 1);
drawNextFrameToTexture();
}

View file

@ -160,6 +160,7 @@ Script::Script(Myst3Engine *vm):
OP_2(124, ifPitchInRange, kValue, kValue );
OP_4(125, ifHeadingPitchInRect, kValue, kValue, kValue, kValue );
OP_4(126, ifMouseIsInRect, kValue, kValue, kValue, kValue );
OP_5(127, leverDrag, kValue, kValue, kValue, kValue, kVar ); // Six args
OP_5(134, runScriptWhileDragging, kVar, kVar, kValue, kValue, kVar ); // Eight args
OP_3(135, chooseNextNode, kCondition, kValue, kValue );
OP_2(136, goToNodeTransition, kValue, kValue );
@ -1197,7 +1198,7 @@ void Script::varRatioToPercents(Context &c, const Opcode &cmd) {
int32 value = _vm->_state->getVar(cmd.args[0]);
value = 100 * (cmd.args[2] - abs(value - cmd.args[1])) / cmd.args[2];
value = MAX(0, value);
value = MAX<int32>(0, value);
_vm->_state->setVar(cmd.args[0], value);
}
@ -1496,6 +1497,80 @@ void Script::ifMouseIsInRect(Context &c, const Opcode &cmd) {
goToElse(c);
}
void Script::leverDrag(Context &c, const Opcode &cmd) {
debugC(kDebugScript, "Opcode %d: Drag lever for var %d wit script %d", cmd.op, cmd.args[4], cmd.args[6]);
int16 minPosX = cmd.args[0];
int16 minPosY = cmd.args[1];
int16 maxPosX = cmd.args[2];
int16 maxPosY = cmd.args[3];
int16 var = cmd.args[4];
int16 numPositions = cmd.args[5];
int16 script = cmd.args[6];
int16 topOffset = _vm->_state->getViewType() != kMenu ? 30 : 0;
if (_vm->_state->getViewType() == kCube) {
warning("Opcode 127 is not implemented for the cube view.");
return;
}
if (script > 0) {
warning("Opcode 127 is not implemented for positive script cases.");
return;
}
_vm->_cursor->changeCursor(2);
bool mousePressed = true;
while (true) {
Common::Point mouse = _vm->_cursor->getPosition();
int16 amplitude;
int16 pixelPosition;
if (minPosX == maxPosX) {
// Vertical slider
amplitude = maxPosY - minPosY;
pixelPosition = mouse.y - minPosY - topOffset;
} else {
// Horizontal slider
amplitude = maxPosX - minPosX;
pixelPosition = mouse.x - minPosX;
}
float ratioPosition = pixelPosition / (float) amplitude;
int16 position = ratioPosition * (numPositions + 1);
position = CLIP<int16>(position, 1, numPositions);
if (_vm->_state->getDragLeverLimited()) {
int16 minPosition = _vm->_state->getDragLeverLimitMin();
int16 maxPosition = _vm->_state->getDragLeverLimitMax();
position = CLIP(position, minPosition, maxPosition);
}
// Set new lever position
_vm->_state->setVar(var, position);
// Draw a frame
_vm->processInput(true);
_vm->drawFrame();
mousePressed = _vm->getEventManager()->getButtonState() & Common::EventManager::LBUTTON;
_vm->_state->setDragEnded(!mousePressed);
if (script) {
_vm->_state->setVar(var, position);
_vm->runScriptsFromNode(abs(script));
}
if (!mousePressed)
break;
}
_vm->_state->setDragLeverLimited(0);
_vm->_state->setDragLeverSpeed(0);
}
void Script::runScriptWhileDragging(Context &c, const Opcode &cmd) {
debugC(kDebugScript, "Opcode %d: While dragging lever, run script %d", cmd.op, cmd.args[7]);
@ -1786,7 +1861,7 @@ void Script::runScriptForVarDrawFramesHelper(uint16 var, int32 startValue, int32
while (1) {
if ((positiveDirection && (currentValue >= endValue))
|| (!positiveDirection && (currentValue <= startValue)))
|| (!positiveDirection && (currentValue <= endValue)))
break;
_vm->_state->setVar(var, currentValue);

View file

@ -211,6 +211,7 @@ private:
DECLARE_OPCODE(ifPitchInRange);
DECLARE_OPCODE(ifHeadingPitchInRect);
DECLARE_OPCODE(ifMouseIsInRect);
DECLARE_OPCODE(leverDrag);
DECLARE_OPCODE(runScriptWhileDragging);
DECLARE_OPCODE(chooseNextNode);
DECLARE_OPCODE(goToNodeTransition);

View file

@ -32,6 +32,7 @@ GameState::GameState(Myst3Engine *vm):
#define VAR(var, x, unk) _descriptions.setVal(var, Description(var, #x, unk));
VAR(57, DragEnded, true)
VAR(58, DragLeverSpeed, false)
VAR(59, DragPositionFound, true)
VAR(60, DragLeverPositionChanged, true)
@ -115,6 +116,10 @@ GameState::GameState(Myst3Engine *vm):
VAR(1352, MenuSaveLoadSelectedItem, false)
VAR(1353, MenuSaveLoadCurrentPage, false)
VAR(1399, DragLeverLimited, true)
VAR(1400, DragLeverLimitMin, true)
VAR(1401, DragLeverLimitMax, true)
#undef VAR
newGame();

View file

@ -60,6 +60,7 @@ public:
const Common::String describeCondition(int16 condition);
DECLARE_VAR(57, DragEnded)
DECLARE_VAR(58, DragLeverSpeed)
DECLARE_VAR(59, DragPositionFound)
DECLARE_VAR(60, DragLeverPositionChanged)
@ -127,6 +128,10 @@ public:
DECLARE_VAR(1352, MenuSaveLoadSelectedItem)
DECLARE_VAR(1353, MenuSaveLoadCurrentPage)
DECLARE_VAR(1399, DragLeverLimited)
DECLARE_VAR(1400, DragLeverLimitMin)
DECLARE_VAR(1401, DragLeverLimitMax)
uint getFrameCount() { return _data.currentFrame; }
void incFrameCount() { _data.currentFrame++; }