Initial commit
This commit is contained in:
721
engines/mohawk/myst_stacks/channelwood.cpp
Normal file
721
engines/mohawk/myst_stacks/channelwood.cpp
Normal file
@@ -0,0 +1,721 @@
|
||||
/* 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 "mohawk/cursors.h"
|
||||
#include "mohawk/myst.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/myst_card.h"
|
||||
#include "mohawk/myst_graphics.h"
|
||||
#include "mohawk/myst_state.h"
|
||||
#include "mohawk/myst_sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/channelwood.h"
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/system.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
Channelwood::Channelwood(MohawkEngine_Myst *vm) :
|
||||
MystScriptParser(vm, kChannelwoodStack),
|
||||
_state(vm->_gameState->_channelwood),
|
||||
_valveVar(0),
|
||||
_siriusDrawerState(0),
|
||||
_doorOpened(0),
|
||||
_leverPulled(false),
|
||||
_leverAction(nullptr) {
|
||||
setupOpcodes();
|
||||
}
|
||||
|
||||
Channelwood::~Channelwood() {
|
||||
}
|
||||
|
||||
void Channelwood::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
REGISTER_OPCODE(100, Channelwood, o_bridgeToggle);
|
||||
REGISTER_OPCODE(101, Channelwood, o_pipeExtend);
|
||||
REGISTER_OPCODE(102, Channelwood, o_drawImageChangeCardAndVolume);
|
||||
REGISTER_OPCODE(104, Channelwood, o_waterTankValveOpen);
|
||||
REGISTER_OPCODE(105, Channelwood, o_leverStartMove);
|
||||
REGISTER_OPCODE(106, Channelwood, o_leverEndMove);
|
||||
REGISTER_OPCODE(107, Channelwood, o_leverMoveFail);
|
||||
REGISTER_OPCODE(108, Channelwood, o_leverMove);
|
||||
REGISTER_OPCODE(109, Channelwood, o_stairsDoorToggle);
|
||||
REGISTER_OPCODE(110, Channelwood, o_valveHandleMove1);
|
||||
REGISTER_OPCODE(111, Channelwood, o_valveHandleMoveStart1);
|
||||
REGISTER_OPCODE(112, Channelwood, o_valveHandleMoveStop);
|
||||
REGISTER_OPCODE(113, Channelwood, o_valveHandleMove2);
|
||||
REGISTER_OPCODE(114, Channelwood, o_valveHandleMoveStart2);
|
||||
REGISTER_OPCODE(115, Channelwood, o_valveHandleMove3);
|
||||
REGISTER_OPCODE(116, Channelwood, o_valveHandleMoveStart3);
|
||||
REGISTER_OPCODE(117, Channelwood, o_hologramMonitor);
|
||||
REGISTER_OPCODE(118, Channelwood, o_drawerOpen);
|
||||
REGISTER_OPCODE(119, Channelwood, o_hologramTemple);
|
||||
REGISTER_OPCODE(120, Channelwood, o_leverElev3StartMove);
|
||||
REGISTER_OPCODE(121, Channelwood, o_leverElev3EndMove);
|
||||
REGISTER_OPCODE(122, Channelwood, o_waterTankValveClose);
|
||||
REGISTER_OPCODE(123, Channelwood, o_executeMouseUp);
|
||||
REGISTER_OPCODE(124, Channelwood, o_leverEndMoveWithSound);
|
||||
REGISTER_OPCODE(125, Channelwood, o_pumpLeverMove);
|
||||
REGISTER_OPCODE(126, Channelwood, o_pumpLeverEndMove);
|
||||
REGISTER_OPCODE(127, Channelwood, o_elevatorMovies);
|
||||
REGISTER_OPCODE(128, Channelwood, o_leverEndMoveResumeBackground);
|
||||
REGISTER_OPCODE(129, Channelwood, o_soundReplace);
|
||||
|
||||
// "Init" Opcodes
|
||||
REGISTER_OPCODE(201, Channelwood, o_lever_init);
|
||||
REGISTER_OPCODE(202, Channelwood, o_pipeValve_init);
|
||||
REGISTER_OPCODE(203, Channelwood, o_drawer_init);
|
||||
|
||||
// "Exit" Opcodes
|
||||
REGISTER_OPCODE(300, Channelwood, NOP);
|
||||
}
|
||||
|
||||
void Channelwood::disablePersistentScripts() {
|
||||
|
||||
}
|
||||
|
||||
void Channelwood::runPersistentScripts() {
|
||||
|
||||
}
|
||||
|
||||
uint16 Channelwood::getVar(uint16 var) {
|
||||
switch(var) {
|
||||
case 1: // Water Pump Bridge Raised
|
||||
return _state.waterPumpBridgeState;
|
||||
case 2: // Lower Walkway to Upper Walkway Elevator Raised
|
||||
return _state.elevatorState;
|
||||
case 3: // Water Flowing To Lower Walkway To Upper Walkway Elevator
|
||||
return (_state.waterValveStates & 0xc0) == 0xc0;
|
||||
case 4: // Water Flowing To Book Room Elevator
|
||||
return ((_state.waterValveStates & 0xf8) == 0xb0 && _state.pipeState) ? 1 : 0;
|
||||
case 5: // Lower Walkway to Upper Walkway Spiral Stair Lower Door State
|
||||
return _state.stairsLowerDoorState;
|
||||
case 6: // Pipe Bridge Extended
|
||||
return _state.pipeState;
|
||||
case 7: // Water Flowing To Water Pump For Bridge
|
||||
return ((_state.waterValveStates & 0xe2) == 0x82 || (_state.waterValveStates & 0xf4) == 0xa0) ? 1 : 0;
|
||||
case 8: // Water Tank Valve
|
||||
return (_state.waterValveStates & 0x80) ? 1 : 0;
|
||||
case 9: // State of First Water Valve
|
||||
return (_state.waterValveStates & 0x40) ? 1 : 0;
|
||||
case 10: // State of Second Water Valve
|
||||
return (_state.waterValveStates & 0x20) ? 1 : 0;
|
||||
case 11: // State of Right Third Water Valve
|
||||
return (_state.waterValveStates & 0x10) ? 1 : 0;
|
||||
case 12: // State of Right-Right Fourth Water Valve
|
||||
return (_state.waterValveStates & 0x08) ? 1 : 0;
|
||||
case 13: // State of Right-Left Fourth Water Valve
|
||||
return (_state.waterValveStates & 0x04) ? 1 : 0;
|
||||
case 14: // State of Left Third Water Valve
|
||||
return (_state.waterValveStates & 0x02) ? 1 : 0;
|
||||
case 15: // Water Flowing To Lower Walkway To Upper Walkway Elevator
|
||||
return ((_state.waterValveStates & 0xf8) == 0xb8) ? 1 : 0;
|
||||
case 16: // Channelwood Lower Walkway to Upper Walkway Spiral Stair Upper Door State
|
||||
return _state.stairsUpperDoorState;
|
||||
case 17: // Achenar's Holoprojector Selection
|
||||
return _state.holoprojectorSelection;
|
||||
case 18: // Sirrus's Room Bed Drawer Open
|
||||
return _siriusDrawerState;
|
||||
case 19: // Sound - Water Tank Valve
|
||||
return (_state.waterValveStates & 0x80) ? 1 : 0;
|
||||
case 20: // Sound - First Water Valve Water Flowing To Left
|
||||
return ((_state.waterValveStates & 0xc0) == 0x80) ? 1 : 0;
|
||||
case 21: // Sound - Second Water Valve Water Flowing To Right
|
||||
return ((_state.waterValveStates & 0xe0) == 0xa0) ? 1 : 0;
|
||||
case 22: // Sound - Right Third Water Valve Water Flowing To Right
|
||||
return ((_state.waterValveStates & 0xf0) == 0xb0) ? 1 : 0;
|
||||
case 23: // Sound - Right Third Water Valve Water Flowing To Left
|
||||
return ((_state.waterValveStates & 0xf0) == 0xa0) ? 1 : 0;
|
||||
case 24: // Sound - Second Water Valve Water Flowing To Left
|
||||
return ((_state.waterValveStates & 0xe0) == 0x80) ? 1 : 0;
|
||||
case 25: // Sound - Right-Right Fourth Valve Water Flowing To Left (To Pipe Bridge)
|
||||
return ((_state.waterValveStates & 0xf8) == 0xb0) ? 1 : 0;
|
||||
case 26: // Sound - Right-Left Fourth Valve Water Flowing To Right (To Pipe Down Tree)
|
||||
return ((_state.waterValveStates & 0xf4) == 0xa4) ? 1 : 0;
|
||||
case 27: // Sound - Right-Left Fourth Valve Water Flowing To Left (To Pipe Fork)
|
||||
return ((_state.waterValveStates & 0xf4) == 0xa0) ? 1 : 0;
|
||||
case 28: // Sound - Left Third Water Valve Flowing To Right (To Pipe Fork)
|
||||
return ((_state.waterValveStates & 0xe2) == 0x82) ? 1 : 0;
|
||||
case 29: // Sound - Left Third Water Valve Flowing To Left (To Pipe In Water)
|
||||
return ((_state.waterValveStates & 0xe2) == 0x80) ? 1 : 0;
|
||||
case 30: // Door State
|
||||
return _doorOpened;
|
||||
case 31: // Water flowing in pipe fork ?
|
||||
// 0 -> keep sound.
|
||||
// 1 -> not flowing.
|
||||
// 2 --> flowing.
|
||||
if ((_state.waterValveStates & 0xe2) == 0x82) // From left.
|
||||
return 2;
|
||||
if ((_state.waterValveStates & 0xf4) == 0xa0) // From right.
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
case 32: // Sound - Water Flowing in Pipe to Book Room Elevator
|
||||
if ((_state.waterValveStates & 0xf8) == 0xb0)
|
||||
return _state.pipeState ? 2 : 1;
|
||||
|
||||
return 0;
|
||||
case 33: // Channelwood Lower Walkway to Upper Walkway Spiral Stair Upper Door State
|
||||
if (_state.stairsUpperDoorState) {
|
||||
if (_tempVar == 1)
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case 102: // Sirrus's Desk Drawer / Red Page State
|
||||
if (_siriusDrawerState) {
|
||||
if(!(_globals.redPagesInBook & 16) && (_globals.heldPage != kRedChannelwoodPage))
|
||||
return 2; // Drawer Open, Red Page Present
|
||||
else
|
||||
return 1; // Drawer Open, Red Page Taken
|
||||
} else {
|
||||
return 0; // Drawer Closed
|
||||
}
|
||||
case 103: // Blue Page Present
|
||||
return !(_globals.bluePagesInBook & 16) && (_globals.heldPage != kBlueChannelwoodPage);
|
||||
default:
|
||||
return MystScriptParser::getVar(var);
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::toggleVar(uint16 var) {
|
||||
switch(var) {
|
||||
case 1: // Water Pump Bridge Raised
|
||||
_state.waterPumpBridgeState ^= 1;
|
||||
break;
|
||||
case 6: // Pipe Bridge Extended
|
||||
_state.pipeState ^= 1;
|
||||
break;
|
||||
case 16: // Channelwood Lower Walkway to Upper Walkway Spiral Stair Upper Door State
|
||||
_state.stairsUpperDoorState ^= 1;
|
||||
break;
|
||||
case 102: // Red page
|
||||
if (!(_globals.redPagesInBook & 16)) {
|
||||
if (_globals.heldPage == kRedChannelwoodPage)
|
||||
_globals.heldPage = kNoPage;
|
||||
else
|
||||
_globals.heldPage = kRedChannelwoodPage;
|
||||
}
|
||||
break;
|
||||
case 103: // Blue page
|
||||
if (!(_globals.bluePagesInBook & 16)) {
|
||||
if (_globals.heldPage == kBlueChannelwoodPage)
|
||||
_globals.heldPage = kNoPage;
|
||||
else
|
||||
_globals.heldPage = kBlueChannelwoodPage;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MystScriptParser::toggleVar(var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Channelwood::setVarValue(uint16 var, uint16 value) {
|
||||
bool refresh = false;
|
||||
|
||||
switch (var) {
|
||||
case 2: // Lower Walkway to Upper Walkway Elevator Raised
|
||||
if (_state.elevatorState != value) {
|
||||
_state.elevatorState = value;
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 5: // Lower Walkway to Upper Walkway Spiral Stair Lower Door State
|
||||
if (_state.stairsLowerDoorState != value) {
|
||||
_state.stairsLowerDoorState = value;
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
refresh = pipeChangeValve(value, 0x40);
|
||||
break;
|
||||
case 10:
|
||||
refresh = pipeChangeValve(value, 0x20);
|
||||
break;
|
||||
case 11:
|
||||
refresh = pipeChangeValve(value, 0x10);
|
||||
break;
|
||||
case 12:
|
||||
refresh = pipeChangeValve(value, 0x08);
|
||||
break;
|
||||
case 13:
|
||||
refresh = pipeChangeValve(value, 0x04);
|
||||
break;
|
||||
case 14:
|
||||
refresh = pipeChangeValve(value, 0x02);
|
||||
break;
|
||||
case 18: // Sirrus's Room Bed Drawer Open
|
||||
if (_siriusDrawerState != value) {
|
||||
_siriusDrawerState = value;
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 30: // Door opened
|
||||
_doorOpened = value;
|
||||
break;
|
||||
default:
|
||||
refresh = MystScriptParser::setVarValue(var, value);
|
||||
break;
|
||||
}
|
||||
|
||||
return refresh;
|
||||
}
|
||||
|
||||
bool Channelwood::pipeChangeValve(bool open, uint16 mask) {
|
||||
if (open) {
|
||||
if (!(_state.waterValveStates & mask)) {
|
||||
_state.waterValveStates |= mask;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (_state.waterValveStates & mask) {
|
||||
_state.waterValveStates &= ~mask;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Channelwood::o_bridgeToggle(uint16 var, const ArgumentsArray &args) {
|
||||
VideoEntryPtr bridge = _vm->playMovie("bridge", kChannelwoodStack);
|
||||
bridge->moveTo(292, 203);
|
||||
|
||||
// Toggle bridge state
|
||||
if (_state.waterPumpBridgeState)
|
||||
bridge->setBounds(Audio::Timestamp(0, 3050, 600), Audio::Timestamp(0, 6100, 600));
|
||||
else
|
||||
bridge->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 3050, 600));
|
||||
|
||||
_vm->waitUntilMovieEnds(bridge);
|
||||
}
|
||||
|
||||
void Channelwood::o_pipeExtend(uint16 var, const ArgumentsArray &args) {
|
||||
uint16 soundId = args[0];
|
||||
debugC(kDebugScript, "\tsoundId: %d", soundId);
|
||||
|
||||
_vm->_sound->playEffect(soundId);
|
||||
VideoEntryPtr pipe = _vm->playMovie("pipebrid", kChannelwoodStack);
|
||||
pipe->moveTo(267, 170);
|
||||
|
||||
// Toggle pipe state
|
||||
if (_state.pipeState)
|
||||
pipe->setBounds(Audio::Timestamp(0, 3040, 600), Audio::Timestamp(0, 6080, 600));
|
||||
else
|
||||
pipe->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 3040, 600));
|
||||
|
||||
_vm->waitUntilMovieEnds(pipe);
|
||||
_vm->_sound->resumeBackground();
|
||||
}
|
||||
|
||||
void Channelwood::o_drawImageChangeCardAndVolume(uint16 var, const ArgumentsArray &args) {
|
||||
uint16 imageId = args[0];
|
||||
uint16 cardId = args[1];
|
||||
uint16 volume = args.size() == 3 ? args[2] : 0;
|
||||
|
||||
debugC(kDebugScript, "\timageId: %d", imageId);
|
||||
debugC(kDebugScript, "\tcardId: %d", cardId);
|
||||
|
||||
_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
|
||||
_vm->wait(200);
|
||||
|
||||
_vm->changeToCard(cardId, kTransitionPartToLeft);
|
||||
|
||||
if (volume) {
|
||||
_vm->_sound->changeBackgroundVolume(volume);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Channelwood::o_waterTankValveOpen(uint16 var, const ArgumentsArray &args) {
|
||||
Common::Rect rect = getInvokingResource<MystArea>()->getRect();
|
||||
|
||||
for (uint i = 0; i < 2; i++)
|
||||
for (uint16 imageId = 3601; imageId >= 3595; imageId--) {
|
||||
_vm->_gfx->copyImageToScreen(imageId, rect);
|
||||
_vm->doFrame();
|
||||
}
|
||||
|
||||
pipeChangeValve(true, 0x80);
|
||||
}
|
||||
|
||||
void Channelwood::o_leverStartMove(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
lever->drawFrame(0);
|
||||
_vm->_cursor->setCursor(700);
|
||||
_leverPulled = false;
|
||||
}
|
||||
|
||||
void Channelwood::o_leverMove(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
if (lever->pullLeverV()) {
|
||||
if (!_leverPulled) {
|
||||
_leverPulled = true;
|
||||
_leverAction->handleMouseUp();
|
||||
}
|
||||
} else {
|
||||
_leverPulled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::o_leverMoveFail(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
if (lever->pullLeverV()) {
|
||||
if (!_leverPulled) {
|
||||
_leverPulled = true;
|
||||
uint16 soundId = lever->getList2(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId);
|
||||
}
|
||||
} else {
|
||||
_leverPulled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::o_leverEndMove(uint16 var, const ArgumentsArray &args) {
|
||||
// Get current lever frame
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Release lever
|
||||
lever->releaseLeverV();
|
||||
|
||||
uint16 soundId = lever->getList3(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId);
|
||||
|
||||
_vm->refreshCursor();
|
||||
}
|
||||
|
||||
void Channelwood::o_leverEndMoveResumeBackground(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_sound->resumeBackground();
|
||||
o_leverEndMove(var, args);
|
||||
}
|
||||
|
||||
void Channelwood::o_leverEndMoveWithSound(uint16 var, const ArgumentsArray &args) {
|
||||
o_leverEndMove(var, args);
|
||||
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
uint16 soundId = lever->getList3(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId);
|
||||
}
|
||||
|
||||
void Channelwood::o_leverElev3StartMove(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_gfx->copyImageToScreen(3970, Common::Rect(544, 333));
|
||||
_vm->doFrame();
|
||||
o_leverStartMove(var, args);
|
||||
}
|
||||
|
||||
void Channelwood::o_leverElev3EndMove(uint16 var, const ArgumentsArray &args) {
|
||||
o_leverEndMove(var, args);
|
||||
_vm->_gfx->copyImageToScreen(3265, Common::Rect(544, 333));
|
||||
_vm->doFrame();
|
||||
_vm->_sound->playEffect(5265);
|
||||
}
|
||||
|
||||
void Channelwood::o_pumpLeverMove(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
if (lever->pullLeverV()) {
|
||||
uint16 soundId = lever->getList2(0);
|
||||
_vm->_sound->playBackground(soundId, 38400);
|
||||
} else {
|
||||
uint16 soundId = lever->getList2(1);
|
||||
_vm->_sound->playBackground(soundId, 36864);
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::o_pumpLeverEndMove(uint16 var, const ArgumentsArray &args) {
|
||||
o_leverEndMove(var, args);
|
||||
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
uint16 soundId = lever->getList3(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playBackground(soundId, 36864);
|
||||
}
|
||||
|
||||
void Channelwood::o_stairsDoorToggle(uint16 var, const ArgumentsArray &args) {
|
||||
MystAreaVideo *movie = getInvokingResource<MystAreaVideo>();
|
||||
|
||||
if (_state.stairsUpperDoorState) {
|
||||
// Close door, play the open movie backwards
|
||||
movie->setDirection(-1);
|
||||
movie->playMovie();
|
||||
} else {
|
||||
// Open door
|
||||
movie->setDirection(1);
|
||||
movie->playMovie();
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::o_valveHandleMove1(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
|
||||
if (handle->getRect().contains(mouse)) {
|
||||
// Compute frame to draw
|
||||
_tempVar = (mouse.x - 250) / 4;
|
||||
_tempVar = CLIP<int16>(_tempVar, 1, handle->getStepsH() - 2);
|
||||
|
||||
// Draw frame
|
||||
handle->drawFrame(_tempVar);
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::o_valveHandleMoveStart1(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
|
||||
uint16 soundId = handle->getList1(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId);
|
||||
_vm->_cursor->setCursor(700);
|
||||
|
||||
o_valveHandleMove1(var, args);
|
||||
}
|
||||
|
||||
void Channelwood::o_valveHandleMoveStop(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Update state with valve position
|
||||
if (_tempVar <= 5)
|
||||
setVarValue(_valveVar, 1);
|
||||
else
|
||||
setVarValue(_valveVar, 0);
|
||||
|
||||
// Play release sound
|
||||
uint16 soundId = handle->getList3(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId);
|
||||
|
||||
// Redraw valve
|
||||
_vm->getCard()->redrawArea(_valveVar);
|
||||
|
||||
// Restore cursor
|
||||
_vm->refreshCursor();
|
||||
}
|
||||
|
||||
void Channelwood::o_valveHandleMove2(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
|
||||
if (handle->getRect().contains(mouse)) {
|
||||
// Compute frame to draw
|
||||
_tempVar = handle->getStepsH() - (mouse.x - 234) / 4;
|
||||
_tempVar = CLIP<int16>(_tempVar, 1, handle->getStepsH() - 2);
|
||||
|
||||
// Draw frame
|
||||
handle->drawFrame(_tempVar);
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::o_valveHandleMoveStart2(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
|
||||
uint16 soundId = handle->getList1(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId);
|
||||
_vm->_cursor->setCursor(700);
|
||||
|
||||
o_valveHandleMove2(var, args);
|
||||
}
|
||||
|
||||
void Channelwood::o_valveHandleMove3(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
|
||||
if (handle->getRect().contains(mouse)) {
|
||||
// Compute frame to draw
|
||||
_tempVar = handle->getStepsH() - (mouse.x - 250) / 4;
|
||||
_tempVar = CLIP<int16>(_tempVar, 1, handle->getStepsH() - 2);
|
||||
|
||||
// Draw frame
|
||||
handle->drawFrame(_tempVar);
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::o_valveHandleMoveStart3(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *handle = getInvokingResource<MystVideoInfo>();
|
||||
uint16 soundId = handle->getList1(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId);
|
||||
_vm->_cursor->setCursor(700);
|
||||
|
||||
o_valveHandleMove3(var, args);
|
||||
}
|
||||
|
||||
void Channelwood::o_hologramMonitor(uint16 var, const ArgumentsArray &args) {
|
||||
// Used on Card 3012 (Temple Hologram Monitor)
|
||||
uint16 button = args[0]; // 0 to 3
|
||||
|
||||
if (_state.holoprojectorSelection != button || !_vm->_video->isVideoPlaying()) {
|
||||
_state.holoprojectorSelection = button;
|
||||
_vm->getCard()->redrawArea(17);
|
||||
|
||||
_vm->_video->stopVideos();
|
||||
|
||||
VideoEntryPtr video;
|
||||
|
||||
switch (button) {
|
||||
case 0:
|
||||
video = _vm->playMovie("monalgh", kChannelwoodStack);
|
||||
video->moveTo(227, 70);
|
||||
break;
|
||||
case 1:
|
||||
video = _vm->playMovie("monamth", kChannelwoodStack);
|
||||
video->moveTo(227, 70);
|
||||
break;
|
||||
case 2:
|
||||
video = _vm->playMovie("monasirs", kChannelwoodStack);
|
||||
video->moveTo(227, 70);
|
||||
break;
|
||||
case 3:
|
||||
video = _vm->playMovie("monsmsg", kChannelwoodStack);
|
||||
video->moveTo(226, 68);
|
||||
break;
|
||||
default:
|
||||
warning("Opcode o_hologramMonitor Control Variable Out of Range");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::o_drawerOpen(uint16 var, const ArgumentsArray &args) {
|
||||
_siriusDrawerState = 1;
|
||||
_vm->getCard()->redrawArea(18, false);
|
||||
_vm->getCard()->redrawArea(102, false);
|
||||
}
|
||||
|
||||
void Channelwood::o_hologramTemple(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_sound->pauseBackground();
|
||||
|
||||
// Used on Card 3333 (Temple Hologram)
|
||||
switch (_state.holoprojectorSelection) {
|
||||
case 0:
|
||||
_vm->playMovieBlocking("holoalgh", kChannelwoodStack, 139, 64);
|
||||
break;
|
||||
case 1:
|
||||
_vm->playMovieBlocking("holoamth", kChannelwoodStack, 127, 73);
|
||||
break;
|
||||
case 2:
|
||||
_vm->playMovieBlocking("holoasir", kChannelwoodStack, 139, 64);
|
||||
break;
|
||||
case 3:
|
||||
_vm->playMovieBlocking("holosmsg", kChannelwoodStack, 127, 45);
|
||||
break;
|
||||
default:
|
||||
warning("Opcode o_hologramTemple Control Variable Out of Range");
|
||||
break;
|
||||
}
|
||||
|
||||
_vm->_sound->resumeBackground();
|
||||
}
|
||||
|
||||
void Channelwood::o_executeMouseUp(uint16 var, const ArgumentsArray &args) {
|
||||
// Clear the clicked resource so the mouse up event is not called a second time.
|
||||
_vm->getCard()->resetClickedResource();
|
||||
|
||||
MystArea *resource = _vm->getCard()->getResource<MystArea>(args[0]);
|
||||
resource->handleMouseUp();
|
||||
}
|
||||
|
||||
void Channelwood::o_waterTankValveClose(uint16 var, const ArgumentsArray &args) {
|
||||
Common::Rect rect = getInvokingResource<MystArea>()->getRect();
|
||||
|
||||
for (uint i = 0; i < 2; i++)
|
||||
for (uint16 imageId = 3595; imageId <= 3601; imageId++) {
|
||||
_vm->_gfx->copyImageToScreen(imageId, rect);
|
||||
_vm->doFrame();
|
||||
}
|
||||
|
||||
pipeChangeValve(false, 0x80);
|
||||
}
|
||||
|
||||
void Channelwood::o_elevatorMovies(uint16 var, const ArgumentsArray &args) {
|
||||
// Used by Card 3262 (Elevator)
|
||||
uint16 elevator = args[0];
|
||||
uint16 direction = args[1];
|
||||
|
||||
Common::String movie;
|
||||
uint16 x;
|
||||
uint16 y;
|
||||
|
||||
switch (elevator) {
|
||||
case 1:
|
||||
x = 214;
|
||||
y = 106;
|
||||
if (direction == 1)
|
||||
movie = "welev1up";
|
||||
else
|
||||
movie = "welev1dn";
|
||||
break;
|
||||
case 2:
|
||||
x = 215;
|
||||
y = 117;
|
||||
if (direction == 1)
|
||||
movie = "welev2up";
|
||||
else
|
||||
movie = "welev2dn";
|
||||
break;
|
||||
case 3:
|
||||
x = 213;
|
||||
y = 98;
|
||||
if (direction == 1)
|
||||
movie = "welev3up";
|
||||
else
|
||||
movie = "welev3dn";
|
||||
break;
|
||||
default:
|
||||
error("Unknown elevator state %d in o_elevatorMovies", elevator);
|
||||
}
|
||||
|
||||
_vm->_sound->pauseBackground();
|
||||
_vm->playMovieBlocking(movie, kChannelwoodStack, x, y);
|
||||
_vm->_sound->resumeBackground();
|
||||
}
|
||||
|
||||
void Channelwood::o_soundReplace(uint16 var, const ArgumentsArray &args) {
|
||||
uint16 soundId = args[0];
|
||||
|
||||
if (!_vm->_sound->isEffectPlaying()) {
|
||||
_vm->_sound->playEffect(soundId);
|
||||
}
|
||||
}
|
||||
|
||||
void Channelwood::o_lever_init(uint16 var, const ArgumentsArray &args) {
|
||||
_leverAction = getInvokingResource<MystArea>();
|
||||
}
|
||||
|
||||
void Channelwood::o_pipeValve_init(uint16 var, const ArgumentsArray &args) {
|
||||
_valveVar = var;
|
||||
}
|
||||
|
||||
void Channelwood::o_drawer_init(uint16 var, const ArgumentsArray &args) {
|
||||
_siriusDrawerState = 0;
|
||||
}
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
106
engines/mohawk/myst_stacks/channelwood.h
Normal file
106
engines/mohawk/myst_stacks/channelwood.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* 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 MYST_SCRIPTS_CHANNELWOOD_H
|
||||
#define MYST_SCRIPTS_CHANNELWOOD_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Channelwood : public MystScriptParser {
|
||||
public:
|
||||
explicit Channelwood(MohawkEngine_Myst *vm);
|
||||
~Channelwood() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
uint16 getVar(uint16 var) override;
|
||||
void toggleVar(uint16 var) override;
|
||||
bool setVarValue(uint16 var, uint16 value) override;
|
||||
|
||||
uint16 getMap() override { return 9932; }
|
||||
|
||||
DECLARE_OPCODE(o_bridgeToggle);
|
||||
DECLARE_OPCODE(o_pipeExtend);
|
||||
DECLARE_OPCODE(o_drawImageChangeCardAndVolume);
|
||||
DECLARE_OPCODE(o_waterTankValveOpen);
|
||||
DECLARE_OPCODE(o_leverStartMove);
|
||||
DECLARE_OPCODE(o_leverMove);
|
||||
DECLARE_OPCODE(o_leverMoveFail);
|
||||
DECLARE_OPCODE(o_leverEndMove);
|
||||
DECLARE_OPCODE(o_leverEndMoveResumeBackground);
|
||||
DECLARE_OPCODE(o_leverEndMoveWithSound);
|
||||
DECLARE_OPCODE(o_leverElev3StartMove);
|
||||
DECLARE_OPCODE(o_leverElev3EndMove);
|
||||
DECLARE_OPCODE(o_pumpLeverMove);
|
||||
DECLARE_OPCODE(o_pumpLeverEndMove);
|
||||
DECLARE_OPCODE(o_stairsDoorToggle);
|
||||
DECLARE_OPCODE(o_valveHandleMove1);
|
||||
DECLARE_OPCODE(o_valveHandleMoveStart1);
|
||||
DECLARE_OPCODE(o_valveHandleMoveStop);
|
||||
DECLARE_OPCODE(o_valveHandleMove2);
|
||||
DECLARE_OPCODE(o_valveHandleMoveStart2);
|
||||
DECLARE_OPCODE(o_valveHandleMove3);
|
||||
DECLARE_OPCODE(o_valveHandleMoveStart3);
|
||||
DECLARE_OPCODE(o_hologramMonitor);
|
||||
DECLARE_OPCODE(o_drawerOpen);
|
||||
DECLARE_OPCODE(o_hologramTemple);
|
||||
DECLARE_OPCODE(o_executeMouseUp);
|
||||
DECLARE_OPCODE(o_waterTankValveClose);
|
||||
DECLARE_OPCODE(o_elevatorMovies);
|
||||
DECLARE_OPCODE(o_soundReplace);
|
||||
|
||||
DECLARE_OPCODE(o_lever_init);
|
||||
DECLARE_OPCODE(o_pipeValve_init);
|
||||
DECLARE_OPCODE(o_drawer_init);
|
||||
|
||||
MystGameState::Channelwood &_state;
|
||||
|
||||
uint16 _valveVar; // 64
|
||||
|
||||
uint16 _siriusDrawerState; // 66
|
||||
|
||||
uint16 _doorOpened; // 68
|
||||
|
||||
bool _leverPulled;
|
||||
MystArea *_leverAction; // 72
|
||||
|
||||
bool pipeChangeValve(bool open, uint16 mask);
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
104
engines/mohawk/myst_stacks/credits.cpp
Normal file
104
engines/mohawk/myst_stacks/credits.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/* 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 "mohawk/myst.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/myst_card.h"
|
||||
#include "mohawk/myst_graphics.h"
|
||||
#include "mohawk/cursors.h"
|
||||
#include "mohawk/sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/credits.h"
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
// NOTE: Credits Start Card is 10000
|
||||
|
||||
Credits::Credits(MohawkEngine_Myst *vm) :
|
||||
MystScriptParser(vm, kCreditsStack),
|
||||
_creditsRunning(false),
|
||||
_curImage(0) {
|
||||
setupOpcodes();
|
||||
}
|
||||
|
||||
Credits::~Credits() {
|
||||
}
|
||||
|
||||
void Credits::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
REGISTER_OPCODE(100, Credits, o_quit);
|
||||
|
||||
// "Init" Opcodes
|
||||
REGISTER_OPCODE(200, Credits, o_runCredits);
|
||||
}
|
||||
|
||||
void Credits::disablePersistentScripts() {
|
||||
_creditsRunning = false;
|
||||
}
|
||||
|
||||
void Credits::runPersistentScripts() {
|
||||
if (!_creditsRunning)
|
||||
return;
|
||||
|
||||
if (_vm->getTotalPlayTime() - _startTime >= 7 * 1000) {
|
||||
_curImage++;
|
||||
|
||||
// After the 6th image has shown, it's time to quit
|
||||
if (_curImage == 7) {
|
||||
_vm->quitGame();
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw next image
|
||||
_vm->getCard()->drawBackground();
|
||||
_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
|
||||
|
||||
_startTime = _vm->getTotalPlayTime();
|
||||
}
|
||||
}
|
||||
|
||||
uint16 Credits::getVar(uint16 var) {
|
||||
switch(var) {
|
||||
case 0: // Credits Image Control
|
||||
return _curImage;
|
||||
case 1: // Credits Music Control (Good / bad ending)
|
||||
return _globals.ending != kBooksDestroyed;
|
||||
default:
|
||||
return MystScriptParser::getVar(var);
|
||||
}
|
||||
}
|
||||
|
||||
void Credits::o_runCredits(uint16 var, const ArgumentsArray &args) {
|
||||
// The credits stack does not have all the cursors, reset to the default cursor.
|
||||
_globals.heldPage = kNoPage;
|
||||
_vm->setMainCursor(kDefaultMystCursor);
|
||||
|
||||
// Activate the credits
|
||||
_creditsRunning = true;
|
||||
_curImage = 0;
|
||||
_startTime = _vm->getTotalPlayTime();
|
||||
}
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
60
engines/mohawk/myst_stacks/credits.h
Normal file
60
engines/mohawk/myst_stacks/credits.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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 MYST_SCRIPTS_CREDITS_H
|
||||
#define MYST_SCRIPTS_CREDITS_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Credits : public MystScriptParser {
|
||||
public:
|
||||
explicit Credits(MohawkEngine_Myst *vm);
|
||||
~Credits() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
uint16 getVar(uint16 var) override;
|
||||
|
||||
DECLARE_OPCODE(o_runCredits);
|
||||
|
||||
bool _creditsRunning;
|
||||
uint16 _curImage; // 56
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
116
engines/mohawk/myst_stacks/demo.cpp
Normal file
116
engines/mohawk/myst_stacks/demo.cpp
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mohawk/cursors.h"
|
||||
#include "mohawk/myst.h"
|
||||
#include "mohawk/myst_graphics.h"
|
||||
#include "mohawk/myst_stacks/demo.h"
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
Demo::Demo(MohawkEngine_Myst *vm) :
|
||||
Intro(vm, kDemoStack),
|
||||
_returnToMenuRunning(false),
|
||||
_returnToMenuStep(0),
|
||||
_returnToMenuNextTime(0) {
|
||||
setupOpcodes();
|
||||
}
|
||||
|
||||
Demo::~Demo() {
|
||||
}
|
||||
|
||||
void Demo::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
OVERRIDE_OPCODE(100, Demo, o_stopIntro);
|
||||
REGISTER_OPCODE(101, Demo, o_fadeFromBlack);
|
||||
REGISTER_OPCODE(102, Demo, o_fadeToBlack);
|
||||
|
||||
// "Init" Opcodes
|
||||
OVERRIDE_OPCODE(201, Demo, o_returnToMenu_init);
|
||||
}
|
||||
|
||||
void Demo::disablePersistentScripts() {
|
||||
Intro::disablePersistentScripts();
|
||||
|
||||
_returnToMenuRunning = false;
|
||||
}
|
||||
|
||||
void Demo::runPersistentScripts() {
|
||||
Intro::runPersistentScripts();
|
||||
|
||||
if (_returnToMenuRunning) {
|
||||
returnToMenu_run();
|
||||
}
|
||||
}
|
||||
|
||||
void Demo::o_stopIntro(uint16 var, const ArgumentsArray &args) {
|
||||
// The original also seems to stop the movies. Not needed with this engine.
|
||||
_vm->_gfx->fadeToBlack();
|
||||
}
|
||||
|
||||
void Demo::o_fadeFromBlack(uint16 var, const ArgumentsArray &args) {
|
||||
// FIXME: This glitches when enabled. The backbuffer is drawn to screen,
|
||||
// and then the fading occurs, causing the background to appear for one frame.
|
||||
// _vm->_gfx->fadeFromBlack();
|
||||
}
|
||||
|
||||
void Demo::o_fadeToBlack(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_gfx->fadeToBlack();
|
||||
}
|
||||
|
||||
void Demo::returnToMenu_run() {
|
||||
uint32 time = _vm->getTotalPlayTime();
|
||||
|
||||
if (time < _returnToMenuNextTime)
|
||||
return;
|
||||
|
||||
switch (_returnToMenuStep) {
|
||||
case 0:
|
||||
_vm->_gfx->fadeToBlack();
|
||||
_vm->changeToCard(2003, kNoTransition);
|
||||
_vm->_gfx->fadeFromBlack();
|
||||
|
||||
_returnToMenuStep++;
|
||||
break;
|
||||
case 1:
|
||||
_vm->_gfx->fadeToBlack();
|
||||
_vm->changeToCard(2001, kNoTransition);
|
||||
_vm->_gfx->fadeFromBlack();
|
||||
_vm->_cursor->showCursor();
|
||||
|
||||
_returnToMenuStep++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Demo::o_returnToMenu_init(uint16 var, const ArgumentsArray &args) {
|
||||
// Used on Card 2001, 2002 and 2003
|
||||
_returnToMenuNextTime = _vm->getTotalPlayTime() + 5000;
|
||||
_returnToMenuRunning = true;
|
||||
}
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
66
engines/mohawk/myst_stacks/demo.h
Normal file
66
engines/mohawk/myst_stacks/demo.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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 MYST_SCRIPTS_DEMO_H
|
||||
#define MYST_SCRIPTS_DEMO_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_stacks/intro.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Demo : public Intro {
|
||||
public:
|
||||
explicit Demo(MohawkEngine_Myst *vm);
|
||||
~Demo() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
|
||||
DECLARE_OPCODE(o_stopIntro);
|
||||
DECLARE_OPCODE(o_fadeFromBlack);
|
||||
DECLARE_OPCODE(o_fadeToBlack);
|
||||
|
||||
DECLARE_OPCODE(o_returnToMenu_init);
|
||||
|
||||
bool _returnToMenuRunning;
|
||||
uint16 _returnToMenuStep; // 42
|
||||
uint32 _returnToMenuNextTime; // 6
|
||||
|
||||
void returnToMenu_run();
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
210
engines/mohawk/myst_stacks/dni.cpp
Normal file
210
engines/mohawk/myst_stacks/dni.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/* 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 "mohawk/myst.h"
|
||||
#include "mohawk/cursors.h"
|
||||
#include "mohawk/graphics.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/dni.h"
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
Dni::Dni(MohawkEngine_Myst *vm) :
|
||||
MystScriptParser(vm, kDniStack),
|
||||
_notSeenAtrus(true),
|
||||
_atrusRunning(false),
|
||||
_waitForLoop(false),
|
||||
_atrusLeft(false),
|
||||
_atrusLeftTime(0),
|
||||
_loopStart(0),
|
||||
_loopEnd(0) {
|
||||
setupOpcodes();
|
||||
}
|
||||
|
||||
Dni::~Dni() {
|
||||
}
|
||||
|
||||
void Dni::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
REGISTER_OPCODE(100, Dni, NOP);
|
||||
REGISTER_OPCODE(101, Dni, o_handPage);
|
||||
|
||||
// "Init" Opcodes
|
||||
REGISTER_OPCODE(200, Dni, o_atrus_init);
|
||||
|
||||
// "Exit" Opcodes
|
||||
REGISTER_OPCODE(300, Dni, NOP);
|
||||
}
|
||||
|
||||
void Dni::disablePersistentScripts() {
|
||||
_atrusRunning = false;
|
||||
_waitForLoop = false;
|
||||
_atrusLeft = false;
|
||||
}
|
||||
|
||||
void Dni::runPersistentScripts() {
|
||||
if (_atrusRunning)
|
||||
atrus_run();
|
||||
|
||||
if (_waitForLoop)
|
||||
loopVideo_run();
|
||||
|
||||
if (_atrusLeft)
|
||||
atrusLeft_run();
|
||||
}
|
||||
|
||||
uint16 Dni::getVar(uint16 var) {
|
||||
switch(var) {
|
||||
case 0: // Atrus Gone (from across room)
|
||||
return _globals.ending == kAtrusLeaves;
|
||||
case 1: // Myst Book Status
|
||||
if (_globals.ending != kBooksDestroyed)
|
||||
return _globals.ending == kForgotPage;
|
||||
else
|
||||
return 2; // Linkable
|
||||
case 2: // Music Type
|
||||
if (_notSeenAtrus) {
|
||||
_notSeenAtrus = false;
|
||||
return _globals.ending != kBooksDestroyed && _globals.heldPage != kWhitePage;
|
||||
} else
|
||||
return 2;
|
||||
default:
|
||||
return MystScriptParser::getVar(var);
|
||||
}
|
||||
}
|
||||
|
||||
void Dni::o_handPage(uint16 var, const ArgumentsArray &args) {
|
||||
// Used in Card 5014 (Atrus)
|
||||
|
||||
// Find Atrus movie
|
||||
VideoEntryPtr atrus = _vm->findVideo(_video, kDniStack);
|
||||
|
||||
// Good ending and Atrus asked to give page
|
||||
if (_globals.ending == kAtrusWantsPage && atrus && atrus->getTime() > (uint)Audio::Timestamp(0, 6801, 600).msecs()) {
|
||||
_globals.ending = kAtrusLeaves;
|
||||
_globals.heldPage = kNoPage;
|
||||
_vm->setMainCursor(kDefaultMystCursor);
|
||||
|
||||
// Play movie end (atrus leaving)
|
||||
atrus->setBounds(Audio::Timestamp(0, 14813, 600), atrus->getDuration());
|
||||
atrus->setLooping(false);
|
||||
|
||||
_atrusLeft = true;
|
||||
_waitForLoop = false;
|
||||
_atrusLeftTime = _vm->getTotalPlayTime();
|
||||
}
|
||||
}
|
||||
|
||||
void Dni::atrusLeft_run() {
|
||||
if (_vm->getTotalPlayTime() > _atrusLeftTime + 63333) {
|
||||
_video = "atrus2";
|
||||
_videoPos = Common::Point(215, 77);
|
||||
VideoEntryPtr atrus = _vm->playMovie(_video, kDniStack);
|
||||
atrus->moveTo(_videoPos.x, _videoPos.y);
|
||||
atrus->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 98000, 600));
|
||||
|
||||
_atrusRunning = false;
|
||||
_waitForLoop = true;
|
||||
_loopStart = 73095;
|
||||
_loopEnd = 98000;
|
||||
|
||||
// Good ending
|
||||
_globals.ending = kBooksDestroyed;
|
||||
_globals.bluePagesInBook = 63;
|
||||
_globals.redPagesInBook = 63;
|
||||
|
||||
_atrusLeft = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Dni::loopVideo_run() {
|
||||
if (!_vm->_video->isVideoPlaying()) {
|
||||
VideoEntryPtr atrus = _vm->playMovie(_video, kDniStack);
|
||||
atrus->moveTo(_videoPos.x, _videoPos.y);
|
||||
atrus->setBounds(Audio::Timestamp(0, _loopStart, 600), Audio::Timestamp(0, _loopEnd, 600));
|
||||
atrus->setLooping(true);
|
||||
|
||||
_waitForLoop = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Dni::atrus_run() {
|
||||
if (_globals.ending == kAtrusLeaves) {
|
||||
// Wait for atrus to come back
|
||||
_atrusLeft = true;
|
||||
} else if (_globals.ending == kAtrusWantsPage) {
|
||||
// Atrus asking for page
|
||||
if (!_vm->_video->isVideoPlaying()) {
|
||||
_video = "atr1page";
|
||||
_videoPos = Common::Point(215, 76);
|
||||
VideoEntryPtr atrus = _vm->playMovie(_video, kDniStack);
|
||||
atrus->moveTo(_videoPos.x, _videoPos.y);
|
||||
atrus->setLooping(true);
|
||||
atrus->setBounds(Audio::Timestamp(0, 7388, 600), Audio::Timestamp(0, 14700, 600));
|
||||
}
|
||||
} else if (_globals.ending != kForgotPage && _globals.ending != kBooksDestroyed) {
|
||||
if (_globals.heldPage == kWhitePage) {
|
||||
_video = "atr1page";
|
||||
_videoPos = Common::Point(215, 76);
|
||||
VideoEntryPtr atrus = _vm->playMovie(_video, kDniStack);
|
||||
atrus->moveTo(_videoPos.x, _videoPos.y);
|
||||
atrus->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 14700, 600));
|
||||
|
||||
_waitForLoop = true;
|
||||
_loopStart = 7388;
|
||||
_loopEnd = 14700;
|
||||
|
||||
// Wait for page
|
||||
_globals.ending = kAtrusWantsPage;
|
||||
|
||||
} else {
|
||||
_video = "atr1nopg";
|
||||
_videoPos = Common::Point(215, 77);
|
||||
VideoEntryPtr atrus = _vm->playMovie(_video, kDniStack);
|
||||
atrus->moveTo(_videoPos.x, _videoPos.y);
|
||||
atrus->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 46175, 600));
|
||||
|
||||
_atrusRunning = false;
|
||||
_waitForLoop = true;
|
||||
_loopStart = 30656;
|
||||
_loopEnd = 46175;
|
||||
|
||||
// Bad ending
|
||||
_globals.ending = kForgotPage;
|
||||
}
|
||||
} else if (!_vm->_video->isVideoPlaying()) {
|
||||
VideoEntryPtr atrus = _vm->playMovie("atrwrite", kDniStack);
|
||||
atrus->moveTo(215, 77);
|
||||
atrus->setLooping(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Dni::o_atrus_init(uint16 var, const ArgumentsArray &args) {
|
||||
_atrusRunning = true;
|
||||
}
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
75
engines/mohawk/myst_stacks/dni.h
Normal file
75
engines/mohawk/myst_stacks/dni.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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 MYST_SCRIPTS_DNI_H
|
||||
#define MYST_SCRIPTS_DNI_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Dni : public MystScriptParser {
|
||||
public:
|
||||
explicit Dni(MohawkEngine_Myst *vm);
|
||||
~Dni() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
uint16 getVar(uint16 var) override;
|
||||
|
||||
void atrus_run();
|
||||
void loopVideo_run();
|
||||
void atrusLeft_run();
|
||||
|
||||
DECLARE_OPCODE(o_handPage);
|
||||
|
||||
DECLARE_OPCODE(o_atrus_init);
|
||||
|
||||
bool _atrusRunning;
|
||||
bool _notSeenAtrus; // 56
|
||||
uint32 _atrusLeftTime; // 60
|
||||
|
||||
Common::String _video; // 64
|
||||
Common::Point _videoPos;
|
||||
|
||||
bool _waitForLoop;
|
||||
uint32 _loopStart; // 72
|
||||
uint32 _loopEnd; // 76
|
||||
bool _atrusLeft; // 80
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
167
engines/mohawk/myst_stacks/intro.cpp
Normal file
167
engines/mohawk/myst_stacks/intro.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/* 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 "mohawk/myst.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/myst_graphics.h"
|
||||
#include "mohawk/myst_state.h"
|
||||
#include "mohawk/sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/intro.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
Intro::Intro(MohawkEngine_Myst *vm, MystStack stackId) :
|
||||
MystScriptParser(vm, stackId),
|
||||
_introMoviesRunning(false),
|
||||
_introStep(0),
|
||||
_linkBookRunning(false),
|
||||
_linkBookMovie(nullptr) {
|
||||
setupOpcodes();
|
||||
}
|
||||
|
||||
Intro::~Intro() {
|
||||
}
|
||||
|
||||
void Intro::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
REGISTER_OPCODE(100, Intro, o_useLinkBook);
|
||||
|
||||
// "Init" Opcodes
|
||||
REGISTER_OPCODE(200, Intro, o_playIntroMovies);
|
||||
REGISTER_OPCODE(201, Intro, o_mystLinkBook_init);
|
||||
|
||||
// "Exit" Opcodes
|
||||
REGISTER_OPCODE(300, Intro, NOP);
|
||||
}
|
||||
|
||||
void Intro::disablePersistentScripts() {
|
||||
_introMoviesRunning = false;
|
||||
_linkBookRunning = false;
|
||||
}
|
||||
|
||||
void Intro::runPersistentScripts() {
|
||||
if (_introMoviesRunning)
|
||||
introMovies_run();
|
||||
|
||||
if (_linkBookRunning)
|
||||
mystLinkBook_run();
|
||||
}
|
||||
|
||||
uint16 Intro::getVar(uint16 var) {
|
||||
switch(var) {
|
||||
case 0:
|
||||
if (_globals.currentAge == kSirrusEnding || _globals.currentAge == kAchenarEnding)
|
||||
return 2;
|
||||
else
|
||||
return _globals.currentAge;
|
||||
default:
|
||||
return MystScriptParser::getVar(var);
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::o_useLinkBook(uint16 var, const ArgumentsArray &args) {
|
||||
// Hard coded SoundId valid only for Intro Stack.
|
||||
// Other stacks use Opcode 40, which takes SoundId values as arguments.
|
||||
const uint16 soundIdLinkSrc = 5;
|
||||
const uint16 soundIdLinkDst[] = { 2282, 3029, 6396, 7122, 3137, 0, 9038, 5134, 0, 4739, 4741 };
|
||||
|
||||
// Change to dest stack
|
||||
_vm->changeToStack(_stackMap[_globals.currentAge], _startCard[_globals.currentAge], soundIdLinkSrc, soundIdLinkDst[_globals.currentAge]);
|
||||
}
|
||||
|
||||
void Intro::introMovies_run() {
|
||||
// Play Intro Movies
|
||||
// This is all quite messy...
|
||||
|
||||
VideoEntryPtr video;
|
||||
|
||||
switch (_introStep) {
|
||||
case 0:
|
||||
_introStep = 1;
|
||||
video = _vm->playMovieFullscreen("broder", kIntroStack);
|
||||
break;
|
||||
case 1:
|
||||
if (!_vm->_video->isVideoPlaying())
|
||||
_introStep = 2;
|
||||
break;
|
||||
case 2:
|
||||
_introStep = 3;
|
||||
video = _vm->playMovieFullscreen("cyanlogo", kIntroStack);
|
||||
break;
|
||||
case 3:
|
||||
if (!_vm->_video->isVideoPlaying())
|
||||
_introStep = 4;
|
||||
break;
|
||||
case 4:
|
||||
_introStep = 5;
|
||||
|
||||
if (!_vm->isGameVariant(GF_DEMO)) { // The demo doesn't have the intro video
|
||||
video = _vm->playMovieFullscreen("intro", kIntroStack);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (!_vm->_video->isVideoPlaying())
|
||||
_introStep = 6;
|
||||
break;
|
||||
default:
|
||||
if (_vm->isGameVariant(GF_DEMO))
|
||||
_vm->changeToCard(2001, kTransitionRightToLeft);
|
||||
else
|
||||
_vm->changeToCard(2, kTransitionRightToLeft);
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::o_playIntroMovies(uint16 var, const ArgumentsArray &args) {
|
||||
_introMoviesRunning = true;
|
||||
|
||||
if (_vm->isGameVariant(GF_25TH)) {
|
||||
// In the 25th anniversary version, the Broderbund / Cyan Logo were already shown
|
||||
// before the main menu. No need to play them again here.
|
||||
_introStep = 4;
|
||||
} else {
|
||||
_introStep = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::mystLinkBook_run() {
|
||||
if (_startTime == 1) {
|
||||
_startTime = 0;
|
||||
|
||||
if (!_vm->wait(5000, true)) {
|
||||
_linkBookMovie->playMovie();
|
||||
_vm->_gfx->copyImageToBackBuffer(4, Common::Rect(544, 333));
|
||||
_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
|
||||
}
|
||||
} else if (!_linkBookMovie->isPlaying()) {
|
||||
_vm->changeToCard(5, kTransitionRightToLeft);
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::o_mystLinkBook_init(uint16 var, const ArgumentsArray &args) {
|
||||
_linkBookMovie = getInvokingResource<MystAreaVideo>();
|
||||
_startTime = 1;
|
||||
_linkBookRunning = true;
|
||||
}
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
70
engines/mohawk/myst_stacks/intro.h
Normal file
70
engines/mohawk/myst_stacks/intro.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* 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 MYST_SCRIPTS_INTRO_H
|
||||
#define MYST_SCRIPTS_INTRO_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
class MystAreaVideo;
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Intro : public MystScriptParser {
|
||||
public:
|
||||
explicit Intro(MohawkEngine_Myst *vm, MystStack stackId = kIntroStack);
|
||||
~Intro() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
uint16 getVar(uint16 var) override;
|
||||
|
||||
DECLARE_OPCODE(o_useLinkBook);
|
||||
|
||||
DECLARE_OPCODE(o_playIntroMovies);
|
||||
DECLARE_OPCODE(o_mystLinkBook_init);
|
||||
|
||||
void introMovies_run();
|
||||
void mystLinkBook_run();
|
||||
|
||||
bool _introMoviesRunning;
|
||||
uint16 _introStep;
|
||||
|
||||
bool _linkBookRunning;
|
||||
MystAreaVideo *_linkBookMovie;
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
52
engines/mohawk/myst_stacks/makingof.cpp
Normal file
52
engines/mohawk/myst_stacks/makingof.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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 "mohawk/myst.h"
|
||||
#include "mohawk/graphics.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/makingof.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
MakingOf::MakingOf(MohawkEngine_Myst *vm) :
|
||||
MystScriptParser(vm, kMakingOfStack) {
|
||||
setupOpcodes();
|
||||
}
|
||||
|
||||
MakingOf::~MakingOf() {
|
||||
}
|
||||
|
||||
void MakingOf::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
REGISTER_OPCODE(100, MakingOf, o_quit);
|
||||
}
|
||||
|
||||
void MakingOf::disablePersistentScripts() {
|
||||
}
|
||||
|
||||
void MakingOf::runPersistentScripts() {
|
||||
}
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
54
engines/mohawk/myst_stacks/makingof.h
Normal file
54
engines/mohawk/myst_stacks/makingof.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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 MYST_SCRIPTS_MAKINGOF_H
|
||||
#define MYST_SCRIPTS_MAKINGOF_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class MakingOf : public MystScriptParser {
|
||||
public:
|
||||
explicit MakingOf(MohawkEngine_Myst *vm);
|
||||
~MakingOf() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
989
engines/mohawk/myst_stacks/mechanical.cpp
Normal file
989
engines/mohawk/myst_stacks/mechanical.cpp
Normal file
@@ -0,0 +1,989 @@
|
||||
/* 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 "mohawk/cursors.h"
|
||||
#include "mohawk/myst.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/myst_card.h"
|
||||
#include "mohawk/myst_graphics.h"
|
||||
#include "mohawk/myst_state.h"
|
||||
#include "mohawk/myst_sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/mechanical.h"
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
Mechanical::Mechanical(MohawkEngine_Myst *vm) :
|
||||
MystScriptParser(vm, kMechanicalStack),
|
||||
_state(vm->_gameState->_mechanical) {
|
||||
setupOpcodes();
|
||||
|
||||
_elevatorGoingMiddle = false;
|
||||
_elevatorPosition = 0;
|
||||
_elevatorGoingDown = 0;
|
||||
_elevatorRotationSpeed = 0;
|
||||
_elevatorRotationGearPosition = 0;
|
||||
_elevatorRotationSoundId = 0;
|
||||
_elevatorRotationLeverMoving = false;
|
||||
_elevatorTooLate = false;
|
||||
_elevatorInCabin = false;
|
||||
_elevatorTopCounter = 0;
|
||||
_elevatorNextTime = 0;
|
||||
|
||||
_crystalLit = 0;
|
||||
|
||||
_mystStaircaseState = false;
|
||||
_fortressDirection = kSouth;
|
||||
_gearsWereRunning = false;
|
||||
|
||||
_fortressRotationShortMovieWorkaround = false;
|
||||
_fortressRotationShortMovieCount = 0;
|
||||
_fortressRotationShortMovieLast = 0;
|
||||
|
||||
_fortressRotationRunning = false;
|
||||
_fortressRotationSpeed = 0;
|
||||
_fortressRotationBrake = 0;
|
||||
_fortressRotationGears = nullptr;
|
||||
|
||||
_fortressSimulationRunning = false;
|
||||
_fortressSimulationInit = false;
|
||||
_fortressSimulationSpeed = 0;
|
||||
_fortressSimulationBrake = 0;
|
||||
_fortressSimulationStartSound1 = 0;
|
||||
_fortressSimulationStartSound2 = 0;
|
||||
_fortressSimulationHolo = nullptr;
|
||||
_fortressSimulationStartup = nullptr;
|
||||
_fortressSimulationHoloRate = 0;
|
||||
|
||||
_birdSinging = false;
|
||||
_birdCrankStartTime = 0;
|
||||
_birdSingEndTime = 0;
|
||||
_bird = nullptr;
|
||||
|
||||
_snakeBox = nullptr;
|
||||
}
|
||||
|
||||
Mechanical::~Mechanical() {
|
||||
}
|
||||
|
||||
void Mechanical::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
REGISTER_OPCODE(100, Mechanical, o_throneEnablePassage);
|
||||
REGISTER_OPCODE(101, Mechanical, o_birdCrankStart);
|
||||
REGISTER_OPCODE(102, Mechanical, NOP);
|
||||
REGISTER_OPCODE(103, Mechanical, o_birdCrankStop);
|
||||
REGISTER_OPCODE(104, Mechanical, o_snakeBoxTrigger);
|
||||
REGISTER_OPCODE(105, Mechanical, o_fortressStaircaseMovie);
|
||||
REGISTER_OPCODE(106, Mechanical, o_elevatorRotationStart);
|
||||
REGISTER_OPCODE(107, Mechanical, o_elevatorRotationMove);
|
||||
REGISTER_OPCODE(108, Mechanical, o_elevatorRotationStop);
|
||||
REGISTER_OPCODE(109, Mechanical, o_fortressRotationSpeedStart);
|
||||
REGISTER_OPCODE(110, Mechanical, o_fortressRotationSpeedMove);
|
||||
REGISTER_OPCODE(111, Mechanical, o_fortressRotationSpeedStop);
|
||||
REGISTER_OPCODE(112, Mechanical, o_fortressRotationBrakeStart);
|
||||
REGISTER_OPCODE(113, Mechanical, o_fortressRotationBrakeMove);
|
||||
REGISTER_OPCODE(114, Mechanical, o_fortressRotationBrakeStop);
|
||||
REGISTER_OPCODE(115, Mechanical, o_fortressSimulationSpeedStart);
|
||||
REGISTER_OPCODE(116, Mechanical, o_fortressSimulationSpeedMove);
|
||||
REGISTER_OPCODE(117, Mechanical, o_fortressSimulationSpeedStop);
|
||||
REGISTER_OPCODE(118, Mechanical, o_fortressSimulationBrakeStart);
|
||||
REGISTER_OPCODE(119, Mechanical, o_fortressSimulationBrakeMove);
|
||||
REGISTER_OPCODE(120, Mechanical, o_fortressSimulationBrakeStop);
|
||||
REGISTER_OPCODE(121, Mechanical, o_elevatorWindowMovie);
|
||||
REGISTER_OPCODE(122, Mechanical, o_elevatorGoMiddle);
|
||||
REGISTER_OPCODE(123, Mechanical, o_elevatorTopMovie);
|
||||
REGISTER_OPCODE(124, Mechanical, o_fortressRotationSetPosition);
|
||||
REGISTER_OPCODE(125, Mechanical, o_mystStaircaseMovie);
|
||||
REGISTER_OPCODE(126, Mechanical, o_elevatorWaitTimeout);
|
||||
REGISTER_OPCODE(127, Mechanical, o_crystalEnterYellow);
|
||||
REGISTER_OPCODE(128, Mechanical, o_crystalLeaveYellow);
|
||||
REGISTER_OPCODE(129, Mechanical, o_crystalEnterGreen);
|
||||
REGISTER_OPCODE(130, Mechanical, o_crystalLeaveGreen);
|
||||
REGISTER_OPCODE(131, Mechanical, o_crystalEnterRed);
|
||||
REGISTER_OPCODE(132, Mechanical, o_crystalLeaveRed);
|
||||
|
||||
// "Init" Opcodes
|
||||
REGISTER_OPCODE(200, Mechanical, o_throne_init);
|
||||
REGISTER_OPCODE(201, Mechanical, o_fortressStaircase_init);
|
||||
REGISTER_OPCODE(202, Mechanical, o_bird_init);
|
||||
REGISTER_OPCODE(203, Mechanical, o_snakeBox_init);
|
||||
REGISTER_OPCODE(204, Mechanical, o_elevatorRotation_init);
|
||||
REGISTER_OPCODE(205, Mechanical, o_fortressRotation_init);
|
||||
REGISTER_OPCODE(206, Mechanical, o_fortressSimulation_init);
|
||||
REGISTER_OPCODE(209, Mechanical, o_fortressSimulationStartup_init);
|
||||
|
||||
// "Exit" Opcodes
|
||||
REGISTER_OPCODE(300, Mechanical, NOP);
|
||||
}
|
||||
|
||||
void Mechanical::disablePersistentScripts() {
|
||||
_fortressSimulationRunning = false;
|
||||
_elevatorRotationLeverMoving = false;
|
||||
_birdSinging = false;
|
||||
_fortressRotationRunning = false;
|
||||
}
|
||||
|
||||
void Mechanical::runPersistentScripts() {
|
||||
if (_birdSinging)
|
||||
birdSing_run();
|
||||
|
||||
if (_elevatorRotationLeverMoving)
|
||||
elevatorRotation_run();
|
||||
|
||||
if (_elevatorGoingMiddle)
|
||||
elevatorGoMiddle_run();
|
||||
|
||||
if (_fortressRotationRunning)
|
||||
fortressRotation_run();
|
||||
|
||||
if (_fortressSimulationRunning)
|
||||
fortressSimulation_run();
|
||||
}
|
||||
|
||||
uint16 Mechanical::getVar(uint16 var) {
|
||||
switch(var) {
|
||||
case 0: // Achenar's Secret Panel State
|
||||
return _state.achenarPanelState;
|
||||
case 1: // Sirrus's Secret Panel State
|
||||
return _state.sirrusPanelState;
|
||||
case 2: // Achenar's Secret Room Crate Lid Open and Blue Page Present
|
||||
if (_state.achenarCrateOpened) {
|
||||
if (_globals.bluePagesInBook & 4 || _globals.heldPage == kBlueMechanicalPage)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
} else {
|
||||
return _globals.bluePagesInBook & 4 || _globals.heldPage == kBlueMechanicalPage;
|
||||
}
|
||||
case 3: // Achenar's Secret Room Crate State
|
||||
return _state.achenarCrateOpened;
|
||||
case 4: // Myst Book Room Staircase State
|
||||
return _mystStaircaseState;
|
||||
case 5: // Fortress Position
|
||||
return _fortressDirection;
|
||||
case 6: // Fortress Position - Big Cog Visible Through Doorway
|
||||
return _fortressDirection == kSouth;
|
||||
case 7: // Fortress Elevator Open
|
||||
if (_state.elevatorRotation == 4)
|
||||
return 1; // Open
|
||||
else
|
||||
return 0; // Closed
|
||||
case 10: // Fortress Staircase State
|
||||
return _state.staircaseState;
|
||||
case 11: // Fortress Elevator Rotation Position
|
||||
return _state.elevatorRotation;
|
||||
case 12: // Fortress Elevator Rotation Cog Position
|
||||
return 5 - (uint16)(_elevatorRotationGearPosition + 0.5) % 6;
|
||||
case 13: // Elevator position
|
||||
return _elevatorPosition;
|
||||
case 14: // Elevator going down when at top
|
||||
if (_elevatorGoingDown && _elevatorTooLate)
|
||||
return 2;
|
||||
else
|
||||
return _elevatorGoingDown;
|
||||
case 15: // Code Lock Execute Button Script
|
||||
if (_mystStaircaseState)
|
||||
return 0;
|
||||
else if (_state.codeShape[0] == 2 && _state.codeShape[1] == 8
|
||||
&& _state.codeShape[2] == 5 && _state.codeShape[3] == 1)
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
case 16: // Code Lock Shape #1 - Left
|
||||
case 17: // Code Lock Shape #2
|
||||
case 18: // Code Lock Shape #3
|
||||
case 19: // Code Lock Shape #4 - Right
|
||||
return _state.codeShape[var - 16];
|
||||
case 20: // Crystal Lit Flag - Yellow
|
||||
return _crystalLit == 3;
|
||||
case 21: // Crystal Lit Flag - Green
|
||||
return _crystalLit == 1;
|
||||
case 22: // Crystal Lit Flag - Red
|
||||
return _crystalLit == 2;
|
||||
case 102: // Red page
|
||||
return !(_globals.redPagesInBook & 4) && (_globals.heldPage != kRedMechanicalPage);
|
||||
case 103: // Blue page
|
||||
return !(_globals.bluePagesInBook & 4) && (_globals.heldPage != kBlueMechanicalPage);
|
||||
default:
|
||||
return MystScriptParser::getVar(var);
|
||||
}
|
||||
}
|
||||
|
||||
void Mechanical::toggleVar(uint16 var) {
|
||||
switch(var) {
|
||||
case 0: // Achenar's Secret Panel State
|
||||
_state.achenarPanelState ^= 1;
|
||||
break;
|
||||
case 1: // Sirrus's Secret Panel State
|
||||
_state.sirrusPanelState ^= 1;
|
||||
break;
|
||||
case 3: // Achenar's Secret Room Crate State
|
||||
_state.achenarCrateOpened ^= 1;
|
||||
break;
|
||||
case 4: // Myst Book Room Staircase State
|
||||
_mystStaircaseState ^= 1;
|
||||
break;
|
||||
case 10: // Fortress Staircase State
|
||||
_state.staircaseState ^= 1;
|
||||
break;
|
||||
case 16: // Code Lock Shape #1 - Left
|
||||
case 17: // Code Lock Shape #2
|
||||
case 18: // Code Lock Shape #3
|
||||
case 19: // Code Lock Shape #4 - Right
|
||||
_state.codeShape[var - 16] = (_state.codeShape[var - 16] + 1) % 10;
|
||||
break;
|
||||
case 23: // Elevator player is in cabin
|
||||
_elevatorInCabin = false;
|
||||
break;
|
||||
case 102: // Red page
|
||||
if (!(_globals.redPagesInBook & 4)) {
|
||||
if (_globals.heldPage == kRedMechanicalPage)
|
||||
_globals.heldPage = kNoPage;
|
||||
else
|
||||
_globals.heldPage = kRedMechanicalPage;
|
||||
}
|
||||
break;
|
||||
case 103: // Blue page
|
||||
if (!(_globals.bluePagesInBook & 4)) {
|
||||
if (_globals.heldPage == kBlueMechanicalPage)
|
||||
_globals.heldPage = kNoPage;
|
||||
else
|
||||
_globals.heldPage = kBlueMechanicalPage;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MystScriptParser::toggleVar(var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Mechanical::setVarValue(uint16 var, uint16 value) {
|
||||
bool refresh = false;
|
||||
|
||||
switch (var) {
|
||||
case 13:
|
||||
_elevatorPosition = value;
|
||||
break;
|
||||
case 14: // Elevator going down when at top
|
||||
_elevatorGoingDown = value;
|
||||
break;
|
||||
default:
|
||||
refresh = MystScriptParser::setVarValue(var, value);
|
||||
break;
|
||||
}
|
||||
|
||||
return refresh;
|
||||
}
|
||||
|
||||
void Mechanical::o_throneEnablePassage(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->getCard()->getResource<MystArea>(args[0])->setEnabled(getVar(var));
|
||||
}
|
||||
|
||||
void Mechanical::o_birdCrankStart(uint16 var, const ArgumentsArray &args) {
|
||||
MystAreaDrag *crank = getInvokingResource<MystAreaDrag>();
|
||||
|
||||
uint16 crankSoundId = crank->getList2(0);
|
||||
_vm->_sound->playEffect(crankSoundId, true);
|
||||
|
||||
_birdSingEndTime = 0;
|
||||
_birdCrankStartTime = _vm->getTotalPlayTime();
|
||||
|
||||
MystAreaVideo *crankMovie = static_cast<MystAreaVideo *>(crank->getSubResource(0));
|
||||
crankMovie->playMovie();
|
||||
}
|
||||
|
||||
void Mechanical::o_birdCrankStop(uint16 var, const ArgumentsArray &args) {
|
||||
MystAreaDrag *crank = getInvokingResource<MystAreaDrag>();
|
||||
|
||||
MystAreaVideo *crankMovie = static_cast<MystAreaVideo *>(crank->getSubResource(0));
|
||||
crankMovie->pauseMovie(true);
|
||||
|
||||
uint16 crankSoundId = crank->getList2(1);
|
||||
_vm->_sound->playEffect(crankSoundId);
|
||||
|
||||
_birdSingEndTime = 2 * _vm->getTotalPlayTime() - _birdCrankStartTime;
|
||||
_birdSinging = true;
|
||||
|
||||
_bird->playMovie();
|
||||
}
|
||||
|
||||
void Mechanical::o_snakeBoxTrigger(uint16 var, const ArgumentsArray &args) {
|
||||
// Used on Mechanical Card 6043 (Weapons Rack with Snake Box)
|
||||
_snakeBox->playMovie();
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressStaircaseMovie(uint16 var, const ArgumentsArray &args) {
|
||||
VideoEntryPtr staircase = _vm->playMovie("hhstairs", kMechanicalStack);
|
||||
staircase->moveTo(174, 222);
|
||||
|
||||
if (_state.staircaseState) {
|
||||
staircase->setBounds(Audio::Timestamp(0, 840, 600), Audio::Timestamp(0, 1680, 600));
|
||||
} else {
|
||||
staircase->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 840, 600));
|
||||
}
|
||||
|
||||
_vm->waitUntilMovieEnds(staircase);
|
||||
}
|
||||
|
||||
void Mechanical::o_elevatorRotationStart(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
lever->drawFrame(0);
|
||||
|
||||
_elevatorRotationLeverMoving = true;
|
||||
_elevatorRotationSpeed = 0;
|
||||
|
||||
_vm->_sound->stopBackground();
|
||||
|
||||
_vm->_cursor->setCursor(700);
|
||||
}
|
||||
|
||||
void Mechanical::o_elevatorRotationMove(uint16 var, const ArgumentsArray &args) {
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Make the handle follow the mouse
|
||||
int16 maxStep = lever->getNumFrames() - 1;
|
||||
Common::Rect rect = lever->getRect();
|
||||
int16 step = ((rect.bottom - mouse.y) * lever->getNumFrames()) / rect.height();
|
||||
step = CLIP<int16>(step, 0, maxStep);
|
||||
|
||||
_elevatorRotationSpeed = step * 0.1f;
|
||||
|
||||
// Draw current frame
|
||||
lever->drawFrame(step);
|
||||
}
|
||||
|
||||
void Mechanical::o_elevatorRotationStop(uint16 var, const ArgumentsArray &args) {
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Get current lever frame
|
||||
int16 maxStep = lever->getNumFrames() - 1;
|
||||
Common::Rect rect = lever->getRect();
|
||||
int16 step = ((rect.bottom - mouse.y) * lever->getNumFrames()) / rect.height();
|
||||
step = CLIP<int16>(step, 0, maxStep);
|
||||
|
||||
// Release lever
|
||||
for (int i = step; i >= 0; i--) {
|
||||
lever->drawFrame(i);
|
||||
_vm->doFrame();
|
||||
}
|
||||
|
||||
// Stop persistent script
|
||||
_elevatorRotationLeverMoving = false;
|
||||
|
||||
float speed = _elevatorRotationSpeed * 10;
|
||||
|
||||
if (speed > 0) {
|
||||
|
||||
// Decrease speed
|
||||
while (speed > 2) {
|
||||
speed -= 0.5f;
|
||||
|
||||
_elevatorRotationGearPosition += speed * 0.1f;
|
||||
|
||||
if (_elevatorRotationGearPosition > 12)
|
||||
break;
|
||||
|
||||
_vm->getCard()->redrawArea(12);
|
||||
_vm->wait(100);
|
||||
}
|
||||
|
||||
// Increment position
|
||||
_state.elevatorRotation = (_state.elevatorRotation + 1) % 10;
|
||||
|
||||
_vm->_sound->playEffect(_elevatorRotationSoundId);
|
||||
_vm->getCard()->redrawArea(11);
|
||||
}
|
||||
|
||||
_vm->refreshCursor();
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressRotationSpeedStart(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_cursor->setCursor(700);
|
||||
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
lever->drawFrame(0);
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressRotationSpeedMove(uint16 var, const ArgumentsArray &args) {
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Make the handle follow the mouse
|
||||
int16 maxStep = lever->getNumFrames() - 1;
|
||||
Common::Rect rect = lever->getRect();
|
||||
int16 step = ((rect.top + 65 - mouse.y) * lever->getNumFrames()) / 65;
|
||||
step = CLIP<int16>(step, 0, maxStep);
|
||||
|
||||
_fortressRotationSpeed = step;
|
||||
|
||||
// Draw current frame
|
||||
lever->drawFrame(step);
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressRotationSpeedStop(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Release lever
|
||||
for (int i = _fortressRotationSpeed; i >= 0; i--) {
|
||||
lever->drawFrame(i);
|
||||
_vm->doFrame();
|
||||
}
|
||||
|
||||
_fortressRotationSpeed = 0;
|
||||
|
||||
_vm->refreshCursor();
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressRotationBrakeStart(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_cursor->setCursor(700);
|
||||
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
lever->drawFrame(_fortressRotationBrake);
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressRotationBrakeMove(uint16 var, const ArgumentsArray &args) {
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Make the handle follow the mouse
|
||||
int16 maxStep = lever->getNumFrames() - 1;
|
||||
Common::Rect rect = lever->getRect();
|
||||
int16 step = ((rect.top + 65 - mouse.y) * lever->getNumFrames()) / 65;
|
||||
step = CLIP<int16>(step, 0, maxStep);
|
||||
|
||||
_fortressRotationBrake = step;
|
||||
|
||||
// Draw current frame
|
||||
lever->drawFrame(step);
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressRotationBrakeStop(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
lever->drawFrame(_fortressRotationBrake);
|
||||
|
||||
_vm->refreshCursor();
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressSimulationSpeedStart(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_cursor->setCursor(700);
|
||||
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
lever->drawFrame(0);
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressSimulationSpeedMove(uint16 var, const ArgumentsArray &args) {
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Make the handle follow the mouse
|
||||
int16 maxStep = lever->getNumFrames() - 1;
|
||||
Common::Rect rect = lever->getRect();
|
||||
int16 step = ((rect.bottom - mouse.y) * lever->getNumFrames()) / rect.height();
|
||||
step = CLIP<int16>(step, 0, maxStep);
|
||||
|
||||
_fortressSimulationSpeed = step;
|
||||
|
||||
// Draw current frame
|
||||
lever->drawFrame(step);
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressSimulationSpeedStop(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Release lever
|
||||
for (int i = _fortressSimulationSpeed; i >= 0; i--) {
|
||||
lever->drawFrame(i);
|
||||
_vm->doFrame();
|
||||
}
|
||||
|
||||
_fortressSimulationSpeed = 0;
|
||||
|
||||
_vm->refreshCursor();
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressSimulationBrakeStart(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_cursor->setCursor(700);
|
||||
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
lever->drawFrame(_fortressSimulationBrake);
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressSimulationBrakeMove(uint16 var, const ArgumentsArray &args) {
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
|
||||
// Make the handle follow the mouse
|
||||
int16 maxStep = lever->getNumFrames() - 1;
|
||||
Common::Rect rect = lever->getRect();
|
||||
int16 step = ((rect.bottom - mouse.y) * lever->getNumFrames()) / rect.height();
|
||||
step = CLIP<int16>(step, 0, maxStep);
|
||||
|
||||
_fortressSimulationBrake = step;
|
||||
|
||||
// Draw current frame
|
||||
lever->drawFrame(step);
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressSimulationBrakeStop(uint16 var, const ArgumentsArray &args) {
|
||||
MystVideoInfo *lever = getInvokingResource<MystVideoInfo>();
|
||||
lever->drawFrame(_fortressSimulationBrake);
|
||||
|
||||
_vm->refreshCursor();
|
||||
}
|
||||
|
||||
void Mechanical::o_elevatorWindowMovie(uint16 var, const ArgumentsArray &args) {
|
||||
uint16 startTime = args[0];
|
||||
uint16 endTime = args[1];
|
||||
|
||||
VideoEntryPtr window = _vm->playMovie("ewindow", kMechanicalStack);
|
||||
window->moveTo(253, 0);
|
||||
window->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
|
||||
|
||||
_vm->waitUntilMovieEnds(window);
|
||||
}
|
||||
|
||||
void Mechanical::o_elevatorGoMiddle(uint16 var, const ArgumentsArray &args) {
|
||||
_elevatorTooLate = false;
|
||||
_elevatorTopCounter = 5;
|
||||
_elevatorGoingMiddle = true;
|
||||
_elevatorInCabin = true;
|
||||
_elevatorNextTime = _vm->getTotalPlayTime() + 1000;
|
||||
}
|
||||
|
||||
void Mechanical::elevatorGoMiddle_run() {
|
||||
uint32 time = _vm->getTotalPlayTime();
|
||||
if (_elevatorNextTime < time) {
|
||||
_elevatorNextTime = time + 1000;
|
||||
_elevatorTopCounter--;
|
||||
|
||||
if (_elevatorTopCounter > 0) {
|
||||
// Draw button pressed
|
||||
if (_elevatorInCabin) {
|
||||
_vm->_gfx->copyImageSectionToScreen(6332, Common::Rect(0, 35, 51, 63), Common::Rect(10, 137, 61, 165));
|
||||
}
|
||||
|
||||
// Blip
|
||||
_vm->playSoundBlocking(14120);
|
||||
|
||||
// Restore button
|
||||
if (_elevatorInCabin) {
|
||||
_vm->_gfx->copyBackBufferToScreen(Common::Rect(10, 137, 61, 165));
|
||||
}
|
||||
} else {
|
||||
_elevatorTooLate = true;
|
||||
_elevatorGoingMiddle = false;
|
||||
|
||||
if (_elevatorInCabin) {
|
||||
|
||||
// Elevator going to middle animation
|
||||
_vm->_cursor->hideCursor();
|
||||
_vm->playSoundBlocking(11120);
|
||||
_vm->_gfx->copyImageToBackBuffer(6118, Common::Rect(544, 333));
|
||||
_vm->_sound->playEffect(12120);
|
||||
_vm->_gfx->runTransition(kTransitionSlideToLeft, Common::Rect(177, 0, 370, 333), 25, 0);
|
||||
_vm->playSoundBlocking(13120);
|
||||
_vm->_sound->playEffect(8120);
|
||||
_vm->_gfx->copyImageToBackBuffer(6327, Common::Rect(544, 333));
|
||||
_vm->wait(500);
|
||||
_vm->_sound->playEffect(9120);
|
||||
static uint16 moviePos[2] = { 3540, 5380 };
|
||||
o_elevatorWindowMovie(0, ArgumentsArray(moviePos, ARRAYSIZE(moviePos)));
|
||||
_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
|
||||
_vm->_sound->playEffect(10120);
|
||||
_vm->_cursor->showCursor();
|
||||
|
||||
_elevatorPosition = 1;
|
||||
|
||||
_vm->changeToCard(6327, kTransitionRightToLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Mechanical::o_elevatorTopMovie(uint16 var, const ArgumentsArray &args) {
|
||||
uint16 startTime = args[0];
|
||||
uint16 endTime = args[1];
|
||||
|
||||
VideoEntryPtr window = _vm->playMovie("hcelev", kMechanicalStack);
|
||||
window->moveTo(206, 38);
|
||||
window->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
|
||||
|
||||
_vm->waitUntilMovieEnds(window);
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressRotationSetPosition(uint16 var, const ArgumentsArray &args) {
|
||||
// The fortress direction is already set in fortressRotation_run() so we don't do it here
|
||||
// Stop the gears video so that it does not play while the elevator is going up
|
||||
_fortressRotationGears->getVideo()->stop();
|
||||
}
|
||||
|
||||
void Mechanical::o_mystStaircaseMovie(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->playMovieBlocking("sstairs", kMechanicalStack, 199, 108);
|
||||
}
|
||||
|
||||
void Mechanical::o_elevatorWaitTimeout(uint16 var, const ArgumentsArray &args) {
|
||||
// Wait while the elevator times out
|
||||
while (_elevatorGoingMiddle) {
|
||||
runPersistentScripts();
|
||||
_vm->doFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void Mechanical::o_crystalEnterYellow(uint16 var, const ArgumentsArray &args) {
|
||||
_crystalLit = 3;
|
||||
_vm->getCard()->redrawArea(20);
|
||||
}
|
||||
|
||||
void Mechanical::o_crystalEnterGreen(uint16 var, const ArgumentsArray &args) {
|
||||
_crystalLit = 1;
|
||||
_vm->getCard()->redrawArea(21);
|
||||
}
|
||||
|
||||
void Mechanical::o_crystalEnterRed(uint16 var, const ArgumentsArray &args) {
|
||||
_crystalLit = 2;
|
||||
_vm->getCard()->redrawArea(22);
|
||||
}
|
||||
|
||||
void Mechanical::o_crystalLeaveYellow(uint16 var, const ArgumentsArray &args) {
|
||||
_crystalLit = 0;
|
||||
_vm->getCard()->redrawArea(20);
|
||||
}
|
||||
|
||||
void Mechanical::o_crystalLeaveGreen(uint16 var, const ArgumentsArray &args) {
|
||||
_crystalLit = 0;
|
||||
_vm->getCard()->redrawArea(21);
|
||||
}
|
||||
|
||||
void Mechanical::o_crystalLeaveRed(uint16 var, const ArgumentsArray &args) {
|
||||
_crystalLit = 0;
|
||||
_vm->getCard()->redrawArea(22);
|
||||
}
|
||||
|
||||
void Mechanical::o_throne_init(uint16 var, const ArgumentsArray &args) {
|
||||
// Used on Card 6238 (Sirrus' Throne) and Card 6027 (Achenar's Throne)
|
||||
getInvokingResource<MystArea>()->setEnabled(getVar(var));
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressStaircase_init(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->getCard()->getResource<MystArea>(args[0])->setEnabled(!_state.staircaseState);
|
||||
_vm->getCard()->getResource<MystArea>(args[1])->setEnabled(!_state.staircaseState);
|
||||
_vm->getCard()->getResource<MystArea>(args[2])->setEnabled(_state.staircaseState);
|
||||
}
|
||||
|
||||
void Mechanical::birdSing_run() {
|
||||
// Used for Card 6220 (Sirrus' Mechanical Bird)
|
||||
uint32 time = _vm->getTotalPlayTime();
|
||||
if (_birdSingEndTime < time) {
|
||||
_bird->pauseMovie(true);
|
||||
_vm->_sound->stopEffect();
|
||||
_birdSinging = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Mechanical::o_bird_init(uint16 var, const ArgumentsArray &args) {
|
||||
_birdSinging = false;
|
||||
_birdSingEndTime = 0;
|
||||
_bird = getInvokingResource<MystAreaVideo>();
|
||||
}
|
||||
|
||||
void Mechanical::o_snakeBox_init(uint16 var, const ArgumentsArray &args) {
|
||||
_snakeBox = getInvokingResource<MystAreaVideo>();
|
||||
}
|
||||
|
||||
void Mechanical::elevatorRotation_run() {
|
||||
_vm->getCard()->redrawArea(12);
|
||||
|
||||
_elevatorRotationGearPosition += _elevatorRotationSpeed;
|
||||
|
||||
if (_elevatorRotationGearPosition > 12) {
|
||||
uint16 position = (uint16)_elevatorRotationGearPosition;
|
||||
_elevatorRotationGearPosition = _elevatorRotationGearPosition - position + position % 6;
|
||||
|
||||
_state.elevatorRotation = (_state.elevatorRotation + 1) % 10;
|
||||
|
||||
_vm->_sound->playEffect(_elevatorRotationSoundId);
|
||||
_vm->getCard()->redrawArea(11);
|
||||
_vm->wait(100);
|
||||
}
|
||||
}
|
||||
|
||||
void Mechanical::o_elevatorRotation_init(uint16 var, const ArgumentsArray &args) {
|
||||
_elevatorRotationSoundId = args[0];
|
||||
_elevatorRotationGearPosition = 0;
|
||||
_elevatorRotationLeverMoving = false;
|
||||
}
|
||||
|
||||
void Mechanical::fortressRotation_run() {
|
||||
VideoEntryPtr gears = _fortressRotationGears->getVideo();
|
||||
|
||||
double oldRate = gears->getRate().toDouble();
|
||||
uint32 moviePosition = Audio::Timestamp(gears->getTime(), 600).totalNumberOfFrames();
|
||||
|
||||
// Myst ME short movie workaround, explained in o_fortressRotation_init
|
||||
if (_fortressRotationShortMovieWorkaround) {
|
||||
// Detect if we just looped
|
||||
if (ABS<int32>(_fortressRotationShortMovieLast - 3680) < 50
|
||||
&& ABS<int32>(moviePosition) < 50) {
|
||||
_fortressRotationShortMovieCount++;
|
||||
}
|
||||
|
||||
_fortressRotationShortMovieLast = moviePosition;
|
||||
|
||||
// Simulate longer movie
|
||||
moviePosition += 3600 * _fortressRotationShortMovieCount;
|
||||
}
|
||||
|
||||
int32 positionInQuarter = 900 - (moviePosition + 900) % 1800;
|
||||
|
||||
// Are the gears moving?
|
||||
if (oldRate >= 0.1 || ABS<int32>(positionInQuarter) >= 30 || _fortressRotationBrake) {
|
||||
|
||||
double newRate = oldRate;
|
||||
if (_fortressRotationBrake && (double)_fortressRotationBrake * 0.2 > oldRate) {
|
||||
newRate += 0.1;
|
||||
}
|
||||
|
||||
// Don't let the gears get stuck between two fortress positions
|
||||
if (ABS<double>(oldRate) <= 0.05) {
|
||||
if (oldRate <= 0.0) {
|
||||
newRate += oldRate;
|
||||
} else {
|
||||
newRate -= oldRate;
|
||||
}
|
||||
} else {
|
||||
if (oldRate <= 0.0) {
|
||||
newRate += 0.05;
|
||||
} else {
|
||||
newRate -= 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust speed accordingly to acceleration lever
|
||||
newRate += (double) (positionInQuarter / 1500.0)
|
||||
* (double) (9 - _fortressRotationSpeed) / 9.0;
|
||||
|
||||
newRate = CLIP<double>(newRate, -2.5, 2.5);
|
||||
|
||||
gears->setRate(Common::Rational((int)(newRate * 1000.0), 1000));
|
||||
|
||||
_gearsWereRunning = true;
|
||||
} else if (_gearsWereRunning) {
|
||||
// The fortress has stopped. Set its new position
|
||||
_fortressDirection = (moviePosition + 900) / 1800 % 4;
|
||||
|
||||
gears->setRate(0);
|
||||
|
||||
if (!_fortressRotationShortMovieWorkaround) {
|
||||
gears->seek(Audio::Timestamp(0, 1800 * _fortressDirection, 600));
|
||||
} else {
|
||||
gears->seek(Audio::Timestamp(0, 1800 * (_fortressDirection % 2), 600));
|
||||
}
|
||||
|
||||
_vm->playSoundBlocking(_fortressRotationSounds[_fortressDirection]);
|
||||
|
||||
_gearsWereRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressRotation_init(uint16 var, const ArgumentsArray &args) {
|
||||
_fortressRotationGears = getInvokingResource<MystAreaVideo>();
|
||||
|
||||
VideoEntryPtr gears = _fortressRotationGears->playMovie();
|
||||
gears->setLooping(true);
|
||||
|
||||
// WORKAROUND for the tower rotation bug in Myst ME.
|
||||
// The original engine only allowed to visit two out of the three small islands,
|
||||
// preventing the game from being fully completable.
|
||||
// The fortress rotation is computed from the current position in the movie
|
||||
// hcgears.mov. The version of this movie that shipped with the ME edition is
|
||||
// too short to allow to visit all the islands.
|
||||
// ScummVM simulates a longer movie by counting the number of times the movie
|
||||
// looped and adding that time to the current movie position.
|
||||
// Hence allowing the fortress position to be properly computed.
|
||||
uint32 movieDuration = gears->getDuration().convertToFramerate(600).totalNumberOfFrames();
|
||||
_fortressRotationShortMovieWorkaround = movieDuration == 3680;
|
||||
|
||||
if (!_fortressRotationShortMovieWorkaround) {
|
||||
gears->seek(Audio::Timestamp(0, 1800 * _fortressDirection, 600));
|
||||
} else {
|
||||
_fortressRotationShortMovieLast = 1800 * (_fortressDirection % 2);
|
||||
_fortressRotationShortMovieCount = _fortressDirection >= 2 ? 1 : 0;
|
||||
gears->seek(Audio::Timestamp(0, _fortressRotationShortMovieLast, 600));
|
||||
}
|
||||
|
||||
gears->setRate(0);
|
||||
|
||||
_fortressRotationSounds[0] = args[0];
|
||||
_fortressRotationSounds[1] = args[1];
|
||||
_fortressRotationSounds[2] = args[2];
|
||||
_fortressRotationSounds[3] = args[3];
|
||||
|
||||
_fortressRotationBrake = 0;
|
||||
|
||||
_fortressRotationRunning = true;
|
||||
_gearsWereRunning = false;
|
||||
}
|
||||
|
||||
void Mechanical::fortressSimulation_run() {
|
||||
if (_fortressSimulationInit) {
|
||||
// Init sequence
|
||||
_vm->_sound->playBackground(_fortressSimulationStartSound1, 65535);
|
||||
_vm->wait(5000, true);
|
||||
|
||||
VideoEntryPtr startup = _fortressSimulationStartup->playMovie();
|
||||
_vm->playSoundBlocking(_fortressSimulationStartSound2);
|
||||
_vm->_sound->playBackground(_fortressSimulationStartSound1, 65535);
|
||||
_vm->waitUntilMovieEnds(startup);
|
||||
_vm->_sound->stopBackground();
|
||||
_vm->_sound->playEffect(_fortressSimulationStartSound2);
|
||||
|
||||
|
||||
Common::Rect src = Common::Rect(0, 0, 176, 176);
|
||||
Common::Rect dst = Common::Rect(187, 3, 363, 179);
|
||||
_vm->_gfx->copyImageSectionToBackBuffer(6046, src, dst);
|
||||
_vm->_gfx->copyBackBufferToScreen(dst);
|
||||
|
||||
_fortressSimulationStartup->pauseMovie(true);
|
||||
VideoEntryPtr holo = _fortressSimulationHolo->playMovie();
|
||||
holo->setLooping(true);
|
||||
holo->setRate(0);
|
||||
|
||||
// HACK: Support negative rates with edit lists
|
||||
_fortressSimulationHoloRate = 0;
|
||||
// END HACK
|
||||
|
||||
_vm->_cursor->showCursor();
|
||||
|
||||
_fortressSimulationInit = false;
|
||||
} else {
|
||||
VideoEntryPtr holo = _fortressSimulationHolo->getVideo();
|
||||
|
||||
double oldRate = holo->getRate().toDouble();
|
||||
|
||||
// HACK: Support negative rates with edit lists
|
||||
oldRate = _fortressSimulationHoloRate;
|
||||
// END HACK
|
||||
|
||||
uint32 moviePosition = Audio::Timestamp(holo->getTime(), 600).totalNumberOfFrames();
|
||||
|
||||
int32 positionInQuarter = 900 - (moviePosition + 900) % 1800;
|
||||
|
||||
// Are the gears moving?
|
||||
if (oldRate >= 0.1 || ABS<int32>(positionInQuarter) >= 30 || _fortressSimulationBrake) {
|
||||
|
||||
double newRate = oldRate;
|
||||
if (_fortressSimulationBrake && (double)_fortressSimulationBrake * 0.2 > oldRate) {
|
||||
newRate += 0.1;
|
||||
}
|
||||
|
||||
// Don't let the gears get stuck between two fortress positions
|
||||
if (ABS<double>(oldRate) <= 0.05) {
|
||||
if (oldRate <= 0.0) {
|
||||
newRate += oldRate;
|
||||
} else {
|
||||
newRate -= oldRate;
|
||||
}
|
||||
} else {
|
||||
if (oldRate <= 0.0) {
|
||||
newRate += 0.05;
|
||||
} else {
|
||||
newRate -= 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust speed accordingly to acceleration lever
|
||||
newRate += (double) (positionInQuarter / 1500.0)
|
||||
* (double) (9 - _fortressSimulationSpeed) / 9.0;
|
||||
|
||||
newRate = CLIP<double>(newRate, -2.5, 2.5);
|
||||
|
||||
// HACK: Support negative rates with edit lists
|
||||
|
||||
// Our current QuickTime implementation does not support negative
|
||||
// playback rates for movies using edit lists.
|
||||
// The fortress rotation simulator movie this code handles is the
|
||||
// only movie in the game requiring that feature.
|
||||
|
||||
// This hack approximates the next frame to display when the rate
|
||||
// is negative, and seeks to it. It's not intended to be precise.
|
||||
|
||||
_fortressSimulationHoloRate = newRate;
|
||||
|
||||
if (_fortressSimulationHoloRate < 0) {
|
||||
double newMoviePosition = moviePosition + _fortressSimulationHoloRate * 10;
|
||||
holo->setRate(0);
|
||||
holo->seek(Audio::Timestamp(0, (uint)newMoviePosition, 600));
|
||||
} else {
|
||||
holo->setRate(Common::Rational((int)(newRate * 1000.0), 1000));
|
||||
}
|
||||
// END HACK
|
||||
|
||||
_gearsWereRunning = true;
|
||||
} else if (_gearsWereRunning) {
|
||||
// The fortress has stopped. Set its new position
|
||||
uint16 simulationPosition = (moviePosition + 900) / 1800 % 4;
|
||||
|
||||
holo->setRate(0);
|
||||
|
||||
// HACK: Support negative rates with edit lists
|
||||
_fortressSimulationHoloRate = 0;
|
||||
// END HACK
|
||||
|
||||
holo->seek(Audio::Timestamp(0, 1800 * simulationPosition, 600));
|
||||
_vm->playSoundBlocking( _fortressRotationSounds[simulationPosition]);
|
||||
|
||||
_gearsWereRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressSimulation_init(uint16 var, const ArgumentsArray &args) {
|
||||
_fortressSimulationHolo = getInvokingResource<MystAreaVideo>();
|
||||
|
||||
_fortressSimulationStartSound1 = args[0];
|
||||
_fortressSimulationStartSound2 = args[1];
|
||||
|
||||
_fortressRotationSounds[0] = args[2];
|
||||
_fortressRotationSounds[1] = args[3];
|
||||
_fortressRotationSounds[2] = args[4];
|
||||
_fortressRotationSounds[3] = args[5];
|
||||
|
||||
_fortressSimulationBrake = 0;
|
||||
|
||||
_fortressSimulationRunning = true;
|
||||
_gearsWereRunning = false;
|
||||
_fortressSimulationInit = true;
|
||||
|
||||
_vm->_cursor->hideCursor();
|
||||
}
|
||||
|
||||
void Mechanical::o_fortressSimulationStartup_init(uint16 var, const ArgumentsArray &args) {
|
||||
_fortressSimulationStartup = getInvokingResource<MystAreaVideo>();
|
||||
}
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
167
engines/mohawk/myst_stacks/mechanical.h
Normal file
167
engines/mohawk/myst_stacks/mechanical.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/* 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 MYST_SCRIPTS_MECHANICAL_H
|
||||
#define MYST_SCRIPTS_MECHANICAL_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Mechanical : public MystScriptParser {
|
||||
public:
|
||||
explicit Mechanical(MohawkEngine_Myst *vm);
|
||||
~Mechanical() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
uint16 getVar(uint16 var) override;
|
||||
void toggleVar(uint16 var) override;
|
||||
bool setVarValue(uint16 var, uint16 value) override;
|
||||
|
||||
uint16 getMap() override { return 9931; }
|
||||
|
||||
void birdSing_run();
|
||||
void elevatorRotation_run();
|
||||
void elevatorGoMiddle_run();
|
||||
void fortressRotation_run();
|
||||
void fortressSimulation_run();
|
||||
|
||||
enum Direction {
|
||||
kSouth = 0, // Starting Island with Myst linking book
|
||||
kEast = 1, // Island with right half of code
|
||||
kNorth = 2, // Island with left half of code
|
||||
kWest = 3 // No island, just water
|
||||
};
|
||||
|
||||
DECLARE_OPCODE(o_throneEnablePassage);
|
||||
DECLARE_OPCODE(o_birdCrankStart);
|
||||
DECLARE_OPCODE(o_birdCrankStop);
|
||||
DECLARE_OPCODE(o_snakeBoxTrigger);
|
||||
DECLARE_OPCODE(o_fortressStaircaseMovie);
|
||||
DECLARE_OPCODE(o_elevatorRotationStart);
|
||||
DECLARE_OPCODE(o_elevatorRotationMove);
|
||||
DECLARE_OPCODE(o_elevatorRotationStop);
|
||||
DECLARE_OPCODE(o_fortressRotationSpeedStart);
|
||||
DECLARE_OPCODE(o_fortressRotationSpeedMove);
|
||||
DECLARE_OPCODE(o_fortressRotationSpeedStop);
|
||||
DECLARE_OPCODE(o_fortressRotationBrakeStart);
|
||||
DECLARE_OPCODE(o_fortressRotationBrakeMove);
|
||||
DECLARE_OPCODE(o_fortressRotationBrakeStop);
|
||||
DECLARE_OPCODE(o_fortressSimulationSpeedStart);
|
||||
DECLARE_OPCODE(o_fortressSimulationSpeedMove);
|
||||
DECLARE_OPCODE(o_fortressSimulationSpeedStop);
|
||||
DECLARE_OPCODE(o_fortressSimulationBrakeStart);
|
||||
DECLARE_OPCODE(o_fortressSimulationBrakeMove);
|
||||
DECLARE_OPCODE(o_fortressSimulationBrakeStop);
|
||||
DECLARE_OPCODE(o_elevatorWindowMovie);
|
||||
DECLARE_OPCODE(o_elevatorGoMiddle);
|
||||
DECLARE_OPCODE(o_elevatorTopMovie);
|
||||
DECLARE_OPCODE(o_fortressRotationSetPosition); // Rotator control button (above elevator) has been pressed
|
||||
DECLARE_OPCODE(o_mystStaircaseMovie);
|
||||
DECLARE_OPCODE(o_elevatorWaitTimeout);
|
||||
DECLARE_OPCODE(o_crystalEnterYellow);
|
||||
DECLARE_OPCODE(o_crystalEnterGreen);
|
||||
DECLARE_OPCODE(o_crystalEnterRed);
|
||||
DECLARE_OPCODE(o_crystalLeaveYellow);
|
||||
DECLARE_OPCODE(o_crystalLeaveGreen);
|
||||
DECLARE_OPCODE(o_crystalLeaveRed);
|
||||
|
||||
DECLARE_OPCODE(o_throne_init);
|
||||
DECLARE_OPCODE(o_fortressStaircase_init);
|
||||
DECLARE_OPCODE(o_bird_init);
|
||||
DECLARE_OPCODE(o_snakeBox_init);
|
||||
DECLARE_OPCODE(o_elevatorRotation_init);
|
||||
DECLARE_OPCODE(o_fortressRotation_init);
|
||||
DECLARE_OPCODE(o_fortressSimulation_init);
|
||||
DECLARE_OPCODE(o_fortressSimulationStartup_init);
|
||||
|
||||
MystGameState::Mechanical &_state;
|
||||
|
||||
bool _mystStaircaseState; // 76
|
||||
|
||||
bool _fortressRotationRunning;
|
||||
bool _gearsWereRunning;
|
||||
uint16 _fortressRotationSpeed; // 78
|
||||
uint16 _fortressRotationBrake; // 80
|
||||
uint16 _fortressDirection; // 82
|
||||
uint16 _fortressRotationSounds[4]; // 86 to 92
|
||||
MystAreaVideo *_fortressRotationGears; // 172
|
||||
|
||||
bool _fortressRotationShortMovieWorkaround;
|
||||
uint32 _fortressRotationShortMovieCount;
|
||||
uint32 _fortressRotationShortMovieLast;
|
||||
|
||||
bool _fortressSimulationRunning;
|
||||
bool _fortressSimulationInit; // 94
|
||||
uint16 _fortressSimulationSpeed; // 96
|
||||
uint16 _fortressSimulationBrake; // 98
|
||||
uint16 _fortressSimulationStartSound1; // 102
|
||||
uint16 _fortressSimulationStartSound2; // 100
|
||||
MystAreaVideo *_fortressSimulationHolo; // 160
|
||||
MystAreaVideo *_fortressSimulationStartup; // 164
|
||||
|
||||
// HACK: Support negative rates with edit lists
|
||||
double _fortressSimulationHoloRate;
|
||||
// END HACK
|
||||
|
||||
uint16 _elevatorGoingDown; // 112
|
||||
|
||||
float _elevatorRotationSpeed; // 120
|
||||
float _elevatorRotationGearPosition; // 124
|
||||
uint16 _elevatorRotationSoundId; // 128
|
||||
bool _elevatorRotationLeverMoving; // 184
|
||||
|
||||
bool _elevatorGoingMiddle; // 148
|
||||
bool _elevatorTooLate;
|
||||
uint16 _elevatorPosition; // 104
|
||||
bool _elevatorInCabin; // 108
|
||||
uint16 _elevatorTopCounter;
|
||||
uint32 _elevatorNextTime;
|
||||
|
||||
uint16 _crystalLit; // 130
|
||||
|
||||
bool _birdSinging; // 144
|
||||
uint32 _birdCrankStartTime; // 136
|
||||
uint32 _birdSingEndTime; // 140
|
||||
MystAreaVideo *_bird; // 152
|
||||
|
||||
|
||||
MystAreaVideo *_snakeBox; // 156
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
391
engines/mohawk/myst_stacks/menu.cpp
Normal file
391
engines/mohawk/myst_stacks/menu.cpp
Normal file
@@ -0,0 +1,391 @@
|
||||
/* 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 "mohawk/myst.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/myst_card.h"
|
||||
#include "mohawk/myst_graphics.h"
|
||||
#include "mohawk/myst_state.h"
|
||||
#include "mohawk/cursors.h"
|
||||
#include "mohawk/sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/menu.h"
|
||||
|
||||
#include "common/translation.h"
|
||||
#include "graphics/cursorman.h"
|
||||
#include "gui/message.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
Menu::Menu(MohawkEngine_Myst *vm) :
|
||||
MystScriptParser(vm, kMenuStack),
|
||||
_inGame(false),
|
||||
_canSave(false),
|
||||
_wasCursorVisible(true),
|
||||
_introMoviesRunning(false) {
|
||||
|
||||
for (uint i = 0; i < ARRAYSIZE(_menuItemHovered); i++) {
|
||||
_menuItemHovered[i] = false;
|
||||
}
|
||||
|
||||
setupOpcodes();
|
||||
}
|
||||
|
||||
Menu::~Menu() {
|
||||
}
|
||||
|
||||
void Menu::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
REGISTER_OPCODE(150, Menu, o_menuItemEnter);
|
||||
REGISTER_OPCODE(151, Menu, o_menuItemLeave);
|
||||
REGISTER_OPCODE(152, Menu, o_menuResume);
|
||||
REGISTER_OPCODE(153, Menu, o_menuLoad);
|
||||
REGISTER_OPCODE(154, Menu, o_menuSave);
|
||||
REGISTER_OPCODE(155, Menu, o_menuNew);
|
||||
REGISTER_OPCODE(156, Menu, o_menuOptions);
|
||||
REGISTER_OPCODE(157, Menu, o_menuQuit);
|
||||
|
||||
// "Init" Opcodes
|
||||
REGISTER_OPCODE(200, Menu, o_playIntroMovies);
|
||||
REGISTER_OPCODE(201, Menu, o_menuInit);
|
||||
|
||||
// "Exit" Opcodes
|
||||
REGISTER_OPCODE(300, Menu, NOP);
|
||||
REGISTER_OPCODE(301, Menu, o_menuExit);
|
||||
}
|
||||
|
||||
void Menu::disablePersistentScripts() {
|
||||
_introMoviesRunning = false;
|
||||
}
|
||||
|
||||
void Menu::runPersistentScripts() {
|
||||
if (_introMoviesRunning)
|
||||
introMovies_run();
|
||||
}
|
||||
|
||||
uint16 Menu::getVar(uint16 var) {
|
||||
switch (var) {
|
||||
case 1000: // New game
|
||||
case 1001: // Load
|
||||
case 1004: // Quit
|
||||
case 1005: // Options
|
||||
return _menuItemHovered[var - 1000] ? 1 : 0;
|
||||
case 1002: // Save
|
||||
if (_canSave) {
|
||||
return _menuItemHovered[var - 1000] ? 1 : 0;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
case 1003: // Resume
|
||||
if (_inGame) {
|
||||
return _menuItemHovered[var - 1000] ? 1 : 0;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
default:
|
||||
return MystScriptParser::getVar(var);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::o_menuInit(uint16 var, const ArgumentsArray &args) {
|
||||
_pauseToken = _vm->pauseEngine();
|
||||
|
||||
if (_inGame) {
|
||||
_wasCursorVisible = CursorMan.isVisible();
|
||||
}
|
||||
|
||||
if (!_wasCursorVisible) {
|
||||
CursorMan.showMouse(true);
|
||||
}
|
||||
|
||||
struct MenuButton {
|
||||
uint16 highlightedIndex;
|
||||
uint16 disabledIndex;
|
||||
Graphics::TextAlign align;
|
||||
};
|
||||
|
||||
static const MenuButton buttons[] = {
|
||||
{ 1, 0, Graphics::kTextAlignRight },
|
||||
{ 1, 0, Graphics::kTextAlignRight },
|
||||
{ 1, 2, Graphics::kTextAlignRight },
|
||||
{ 1, 2, Graphics::kTextAlignRight },
|
||||
{ 1, 0, Graphics::kTextAlignRight },
|
||||
{ 1, 0, Graphics::kTextAlignLeft }
|
||||
};
|
||||
|
||||
const char **buttonCaptions = getButtonCaptions();
|
||||
|
||||
for (uint i = 0; i < ARRAYSIZE(buttons); i++) {
|
||||
MystAreaImageSwitch *image = _vm->getCard()->getResource<MystAreaImageSwitch>(2 * i + 0);
|
||||
MystAreaHover *hover = _vm->getCard()->getResource<MystAreaHover> (2 * i + 1);
|
||||
|
||||
Common::U32String str = Common::convertUtf8ToUtf32(buttonCaptions[i]);
|
||||
drawButtonImages(str, image, buttons[i].align, buttons[i].highlightedIndex, buttons[i].disabledIndex);
|
||||
hover->setRect(image->getRect());
|
||||
}
|
||||
}
|
||||
|
||||
const char **Menu::getButtonCaptions() const {
|
||||
static const char *buttonCaptionsEnglish[] = {
|
||||
"NEW GAME",
|
||||
"LOAD GAME",
|
||||
"SAVE GAME",
|
||||
"RESUME",
|
||||
"QUIT",
|
||||
"OPTIONS"
|
||||
};
|
||||
|
||||
static const char *buttonCaptionsFrench[] = {
|
||||
"NOUVEAU",
|
||||
"CHARGER",
|
||||
"SAUVER",
|
||||
"REPRENDRE",
|
||||
"QUITTER",
|
||||
"OPTIONS"
|
||||
};
|
||||
|
||||
static const char *buttonCaptionsGerman[] = {
|
||||
"NEUES SPIEL",
|
||||
"SPIEL LADEN",
|
||||
"SPIEL SPEICHERN",
|
||||
"FORTSETZEN",
|
||||
"BEENDEN",
|
||||
"OPTIONEN"
|
||||
};
|
||||
|
||||
static const char *buttonCaptionsSpanish[] = {
|
||||
"JUEGO NUEVO",
|
||||
"CARGAR JUEGO",
|
||||
"GUARDAR JUEGO",
|
||||
"CONTINUAR",
|
||||
"SALIR",
|
||||
"OPCIONES"
|
||||
};
|
||||
|
||||
static const char *buttonCaptionsPolish[] = {
|
||||
"NOWA GRA",
|
||||
"ZAŁADUJ GRĘ",
|
||||
"ZAPISZ GRĘ",
|
||||
"POWRÓT",
|
||||
"WYJŚCIE",
|
||||
"OPCJE"
|
||||
};
|
||||
|
||||
switch (_vm->getLanguage()) {
|
||||
case Common::FR_FRA:
|
||||
return buttonCaptionsFrench;
|
||||
case Common::DE_DEU:
|
||||
return buttonCaptionsGerman;
|
||||
case Common::ES_ESP:
|
||||
return buttonCaptionsSpanish;
|
||||
case Common::PL_POL:
|
||||
return buttonCaptionsPolish;
|
||||
case Common::EN_ANY:
|
||||
default:
|
||||
return buttonCaptionsEnglish;
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::drawButtonImages(const Common::U32String &text, MystAreaImageSwitch *area, Graphics::TextAlign align, uint16 highlightedIndex, uint16 disabledIndex) const {
|
||||
Common::Rect backgroundRect = area->getRect();
|
||||
Common::Rect textBoundingBox = _vm->_gfx->getTextBoundingBox(text, backgroundRect, align);
|
||||
|
||||
// Restrict the rectangle to the portion were the text will be drawn
|
||||
if (align == Graphics::kTextAlignLeft) {
|
||||
backgroundRect.right = textBoundingBox.right;
|
||||
} else if (align == Graphics::kTextAlignRight) {
|
||||
backgroundRect.left = textBoundingBox.left;
|
||||
} else {
|
||||
error("Unexpected align: %d", align);
|
||||
}
|
||||
|
||||
// Update the area with the new background rect
|
||||
area->setRect(backgroundRect);
|
||||
|
||||
MystAreaImageSwitch::SubImage idle = area->getSubImage(0);
|
||||
area->setSubImageRect(0, Common::Rect(backgroundRect.left, idle.rect.top, backgroundRect.right, idle.rect.bottom));
|
||||
|
||||
// Align the text to the top of the destination rectangles
|
||||
int16 deltaY;
|
||||
if (_vm->getLanguage() == Common::PL_POL) {
|
||||
deltaY = -2;
|
||||
} else {
|
||||
deltaY = backgroundRect.top - textBoundingBox.top;
|
||||
}
|
||||
|
||||
if (highlightedIndex) {
|
||||
replaceButtonSubImageWithText(text, align, area, highlightedIndex, backgroundRect, deltaY, 215, 216, 219);
|
||||
}
|
||||
|
||||
if (disabledIndex) {
|
||||
replaceButtonSubImageWithText(text, align, area, disabledIndex, backgroundRect, deltaY, 136, 140, 145);
|
||||
}
|
||||
|
||||
uint16 cardBackground = _vm->getCard()->getBackgroundImageId();
|
||||
_vm->_gfx->drawText(cardBackground, text, backgroundRect, 181, 184, 189, align, deltaY);
|
||||
}
|
||||
|
||||
void Menu::replaceButtonSubImageWithText(const Common::U32String &text, const Graphics::TextAlign &align, MystAreaImageSwitch *area,
|
||||
uint16 subimageIndex, const Common::Rect &backgroundRect, int16 deltaY,
|
||||
uint8 r, uint8 g, uint8 b) const {
|
||||
uint16 cardBackground = _vm->getCard()->getBackgroundImageId();
|
||||
|
||||
MystAreaImageSwitch::SubImage highlighted = area->getSubImage(subimageIndex);
|
||||
Common::Rect subImageRect(0, 0, backgroundRect.width(), backgroundRect.height());
|
||||
|
||||
// Create an image exactly the size of the rendered text with the backdrop as a background
|
||||
_vm->_gfx->replaceImageWithRect(highlighted.wdib, cardBackground, backgroundRect);
|
||||
area->setSubImageRect(subimageIndex, subImageRect);
|
||||
|
||||
// Draw the text in the subimage
|
||||
_vm->_gfx->drawText(highlighted.wdib, text, subImageRect, r, g, b, align, deltaY);
|
||||
}
|
||||
|
||||
void Menu::o_menuItemEnter(uint16 var, const ArgumentsArray &args) {
|
||||
_menuItemHovered[var - 1000] = true;
|
||||
_vm->getCard()->redrawArea(var);
|
||||
}
|
||||
|
||||
void Menu::o_menuItemLeave(uint16 var, const ArgumentsArray &args) {
|
||||
_menuItemHovered[var - 1000] = false;
|
||||
_vm->getCard()->redrawArea(var);
|
||||
}
|
||||
|
||||
void Menu::o_menuResume(uint16 var, const ArgumentsArray &args) {
|
||||
if (!_inGame) {
|
||||
return;
|
||||
}
|
||||
|
||||
_vm->resumeFromMainMenu();
|
||||
}
|
||||
|
||||
void Menu::o_menuLoad(uint16 var, const ArgumentsArray &args) {
|
||||
if (!showConfirmationDialog(_("Are you sure you want to load a saved game? All unsaved progress will be lost."),
|
||||
_("Load game"), _("Cancel"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
_vm->loadGameDialog();
|
||||
}
|
||||
|
||||
void Menu::o_menuSave(uint16 var, const ArgumentsArray &args) {
|
||||
if (!_canSave) {
|
||||
return;
|
||||
}
|
||||
|
||||
_vm->saveGameDialog();
|
||||
}
|
||||
|
||||
void Menu::o_menuNew(uint16 var, const ArgumentsArray &args) {
|
||||
if (!showConfirmationDialog(_("Are you sure you want to start a new game? All unsaved progress will be lost."),
|
||||
_("New game"), _("Cancel"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
_vm->_gameState->reset();
|
||||
_vm->setTotalPlayTime(0);
|
||||
_vm->setMainCursor(kDefaultMystCursor);
|
||||
_vm->changeToStack(kIntroStack, 1, 0, 0);
|
||||
}
|
||||
|
||||
void Menu::o_menuOptions(uint16 var, const ArgumentsArray &args) {
|
||||
resetButtons();
|
||||
|
||||
_vm->runOptionsDialog();
|
||||
}
|
||||
|
||||
void Menu::o_menuQuit(uint16 var, const ArgumentsArray &args) {
|
||||
if (!showConfirmationDialog(_("Are you sure you want to quit? All unsaved progress will be lost."), _("Quit"),
|
||||
_("Cancel"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
_vm->changeToStack(kCreditsStack, 10000, 0, 0);
|
||||
}
|
||||
|
||||
void Menu::o_menuExit(uint16 var, const ArgumentsArray &args) {
|
||||
if (_inGame) {
|
||||
_vm->_gfx->restoreStateForMainMenu();
|
||||
}
|
||||
|
||||
CursorMan.showMouse(_wasCursorVisible);
|
||||
|
||||
_pauseToken.clear();
|
||||
}
|
||||
|
||||
void Menu::o_playIntroMovies(uint16 var, const ArgumentsArray &args) {
|
||||
_introMoviesRunning = true;
|
||||
_introStep = 0;
|
||||
}
|
||||
|
||||
void Menu::introMovies_run() {
|
||||
// Play Intro Movies
|
||||
// This is all quite messy...
|
||||
|
||||
VideoEntryPtr video;
|
||||
|
||||
switch (_introStep) {
|
||||
case 0:
|
||||
_introStep = 1;
|
||||
video = _vm->playMovieFullscreen("broder", kIntroStack);
|
||||
break;
|
||||
case 1:
|
||||
if (!_vm->_video->isVideoPlaying())
|
||||
_introStep = 2;
|
||||
break;
|
||||
case 2:
|
||||
_introStep = 3;
|
||||
video = _vm->playMovieFullscreen("cyanlogo", kIntroStack);
|
||||
break;
|
||||
case 3:
|
||||
if (!_vm->_video->isVideoPlaying())
|
||||
_introStep = 4;
|
||||
break;
|
||||
default:
|
||||
_vm->changeToCard(1000, kTransitionCopy);
|
||||
}
|
||||
}
|
||||
|
||||
bool Menu::showConfirmationDialog(const Common::U32String &message, const Common::U32String &confirmButton, const Common::U32String &cancelButton) {
|
||||
if (!_inGame) {
|
||||
return true;
|
||||
}
|
||||
|
||||
resetButtons();
|
||||
|
||||
GUI::MessageDialog dialog(message, confirmButton, cancelButton);
|
||||
|
||||
return dialog.runModal() == GUI::kMessageOK;
|
||||
}
|
||||
|
||||
void Menu::resetButtons() {
|
||||
for (uint i = 0; i < ARRAYSIZE(_menuItemHovered); i++) {
|
||||
_menuItemHovered[i] = false;
|
||||
_vm->getCard()->redrawArea(1000 + i);
|
||||
}
|
||||
|
||||
_vm->doFrame();
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
100
engines/mohawk/myst_stacks/menu.h
Normal file
100
engines/mohawk/myst_stacks/menu.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/* 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 MYST_SCRIPTS_MENU_H
|
||||
#define MYST_SCRIPTS_MENU_H
|
||||
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
|
||||
#include "graphics/font.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
class MystAreaVideo;
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Menu : public MystScriptParser {
|
||||
public:
|
||||
explicit Menu(MohawkEngine_Myst *vm);
|
||||
~Menu() override;
|
||||
|
||||
void setInGame(bool inGame) {
|
||||
_inGame = inGame;
|
||||
}
|
||||
|
||||
void setCanSave(bool canSave) {
|
||||
_canSave = canSave;
|
||||
}
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
uint16 getVar(uint16 var) override;
|
||||
|
||||
DECLARE_OPCODE(o_playIntroMovies);
|
||||
DECLARE_OPCODE(o_menuItemEnter);
|
||||
DECLARE_OPCODE(o_menuItemLeave);
|
||||
DECLARE_OPCODE(o_menuResume);
|
||||
DECLARE_OPCODE(o_menuLoad);
|
||||
DECLARE_OPCODE(o_menuSave);
|
||||
DECLARE_OPCODE(o_menuNew);
|
||||
DECLARE_OPCODE(o_menuOptions);
|
||||
DECLARE_OPCODE(o_menuQuit);
|
||||
DECLARE_OPCODE(o_menuInit);
|
||||
DECLARE_OPCODE(o_menuExit);
|
||||
|
||||
bool _inGame;
|
||||
bool _canSave;
|
||||
bool _menuItemHovered[6];
|
||||
bool _wasCursorVisible;
|
||||
|
||||
bool _introMoviesRunning;
|
||||
int _introStep;
|
||||
void introMovies_run();
|
||||
|
||||
bool showConfirmationDialog(const Common::U32String &message, const Common::U32String &confirmButton, const Common::U32String &cancelButton);
|
||||
|
||||
void drawButtonImages(const Common::U32String &text, MystAreaImageSwitch *area, Graphics::TextAlign align, uint16 highlightedIndex, uint16 disabledIndex) const;
|
||||
void replaceButtonSubImageWithText(const Common::U32String &text, const Graphics::TextAlign &align, MystAreaImageSwitch *area,
|
||||
uint16 subimageIndex, const Common::Rect &backgroundRect, int16 deltaY,
|
||||
uint8 r, uint8 g, uint8 b) const;
|
||||
const char **getButtonCaptions() const;
|
||||
void resetButtons();
|
||||
|
||||
PauseToken _pauseToken;
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
3836
engines/mohawk/myst_stacks/myst.cpp
Normal file
3836
engines/mohawk/myst_stacks/myst.cpp
Normal file
File diff suppressed because it is too large
Load Diff
373
engines/mohawk/myst_stacks/myst.h
Normal file
373
engines/mohawk/myst_stacks/myst.h
Normal file
@@ -0,0 +1,373 @@
|
||||
/* 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 MYST_SCRIPTS_MYST_H
|
||||
#define MYST_SCRIPTS_MYST_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Myst : public MystScriptParser {
|
||||
public:
|
||||
explicit Myst(MohawkEngine_Myst *vm, MystStack stackId = kMystStack);
|
||||
~Myst() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
protected:
|
||||
void setupOpcodes();
|
||||
uint16 getVar(uint16 var) override;
|
||||
void toggleVar(uint16 var) override;
|
||||
bool setVarValue(uint16 var, uint16 value) override;
|
||||
|
||||
uint16 getMap() override { return 9934; }
|
||||
|
||||
void towerRotationMap_run();
|
||||
virtual void libraryBookcaseTransform_run();
|
||||
void generatorControlRoom_run();
|
||||
void libraryCombinationBook_run();
|
||||
void libraryBook_run();
|
||||
void clockWheel_run();
|
||||
void matchBurn_run();
|
||||
void boilerPressureIncrease_run();
|
||||
void boilerPressureDecrease_run();
|
||||
void basementPressureIncrease_run();
|
||||
void basementPressureDecrease_run();
|
||||
void tree_run();
|
||||
void imagerValidation_run();
|
||||
void imager_run();
|
||||
void observatory_run();
|
||||
void observatoryMonthChange_run();
|
||||
void observatoryDayChange_run();
|
||||
void observatoryYearChange_run();
|
||||
void observatoryTimeChange_run();
|
||||
void greenBook_run();
|
||||
void clockGears_run();
|
||||
void gullsFly1_run();
|
||||
void gullsFly2_run();
|
||||
void gullsFly3_run();
|
||||
|
||||
DECLARE_OPCODE(o_libraryBookPageTurnLeft);
|
||||
DECLARE_OPCODE(o_libraryBookPageTurnRight);
|
||||
DECLARE_OPCODE(o_fireplaceToggleButton);
|
||||
DECLARE_OPCODE(o_fireplaceRotation);
|
||||
DECLARE_OPCODE(o_courtyardBoxesCheckSolution);
|
||||
DECLARE_OPCODE(o_towerRotationStart);
|
||||
DECLARE_OPCODE(o_towerRotationEnd);
|
||||
DECLARE_OPCODE(o_imagerChangeSelection);
|
||||
DECLARE_OPCODE(o_dockVaultOpen);
|
||||
DECLARE_OPCODE(o_dockVaultClose);
|
||||
DECLARE_OPCODE(o_bookGivePage);
|
||||
DECLARE_OPCODE(o_clockWheelsExecute);
|
||||
DECLARE_OPCODE(o_imagerPlayButton);
|
||||
DECLARE_OPCODE(o_imagerEraseButton);
|
||||
DECLARE_OPCODE(o_towerElevatorAnimation);
|
||||
DECLARE_OPCODE(o_generatorButtonPressed);
|
||||
DECLARE_OPCODE(o_cabinSafeChangeDigit);
|
||||
DECLARE_OPCODE(o_cabinSafeHandleStartMove);
|
||||
DECLARE_OPCODE(o_cabinSafeHandleMove);
|
||||
DECLARE_OPCODE(o_cabinSafeHandleEndMove);
|
||||
DECLARE_OPCODE(o_treePressureReleaseStart);
|
||||
DECLARE_OPCODE(o_observatoryMonthChangeStartIncrease);
|
||||
DECLARE_OPCODE(o_observatoryMonthChangeStartDecrease);
|
||||
DECLARE_OPCODE(o_observatoryDayChangeStartIncrease);
|
||||
DECLARE_OPCODE(o_observatoryDayChangeStartDecrease);
|
||||
DECLARE_OPCODE(o_observatoryGoButton);
|
||||
DECLARE_OPCODE(o_observatoryMonthSliderMove);
|
||||
DECLARE_OPCODE(o_observatoryDaySliderMove);
|
||||
DECLARE_OPCODE(o_observatoryYearSliderMove);
|
||||
DECLARE_OPCODE(o_observatoryTimeSliderMove);
|
||||
DECLARE_OPCODE(o_circuitBreakerStartMove);
|
||||
DECLARE_OPCODE(o_circuitBreakerMove);
|
||||
DECLARE_OPCODE(o_circuitBreakerEndMove);
|
||||
DECLARE_OPCODE(o_boilerIncreasePressureStart);
|
||||
DECLARE_OPCODE(o_boilerLightPilot);
|
||||
DECLARE_OPCODE(o_boilerIncreasePressureStop);
|
||||
DECLARE_OPCODE(o_boilerDecreasePressureStart);
|
||||
DECLARE_OPCODE(o_boilerDecreasePressureStop);
|
||||
DECLARE_OPCODE(o_basementIncreasePressureStart);
|
||||
DECLARE_OPCODE(o_basementIncreasePressureStop);
|
||||
DECLARE_OPCODE(o_basementDecreasePressureStart);
|
||||
DECLARE_OPCODE(o_basementDecreasePressureStop);
|
||||
DECLARE_OPCODE(o_rocketPianoStart);
|
||||
DECLARE_OPCODE(o_rocketPianoMove);
|
||||
DECLARE_OPCODE(o_rocketPianoStop);
|
||||
DECLARE_OPCODE(o_rocketSoundSliderStartMove);
|
||||
DECLARE_OPCODE(o_rocketSoundSliderMove);
|
||||
DECLARE_OPCODE(o_rocketSoundSliderEndMove);
|
||||
DECLARE_OPCODE(o_rocketLeverStartMove);
|
||||
DECLARE_OPCODE(o_rocketOpenBook);
|
||||
DECLARE_OPCODE(o_rocketLeverMove);
|
||||
DECLARE_OPCODE(o_rocketLeverEndMove);
|
||||
DECLARE_OPCODE(o_cabinLeave);
|
||||
DECLARE_OPCODE(o_treePressureReleaseStop);
|
||||
DECLARE_OPCODE(o_observatoryMonthSliderStartMove);
|
||||
DECLARE_OPCODE(o_observatoryMonthSliderEndMove);
|
||||
DECLARE_OPCODE(o_observatoryDaySliderStartMove);
|
||||
DECLARE_OPCODE(o_observatoryDaySliderEndMove);
|
||||
DECLARE_OPCODE(o_observatoryYearSliderStartMove);
|
||||
DECLARE_OPCODE(o_observatoryYearSliderEndMove);
|
||||
DECLARE_OPCODE(o_observatoryTimeSliderStartMove);
|
||||
DECLARE_OPCODE(o_observatoryTimeSliderEndMove);
|
||||
DECLARE_OPCODE(o_libraryBookPageTurnStartLeft);
|
||||
DECLARE_OPCODE(o_libraryBookPageTurnStartRight);
|
||||
DECLARE_OPCODE(o_libraryCombinationBookStop);
|
||||
DECLARE_OPCODE(o_cabinMatchLight);
|
||||
DECLARE_OPCODE(o_courtyardBoxEnter);
|
||||
DECLARE_OPCODE(o_courtyardBoxLeave);
|
||||
DECLARE_OPCODE(o_clockMinuteWheelStartTurn);
|
||||
DECLARE_OPCODE(o_clockWheelEndTurn);
|
||||
DECLARE_OPCODE(o_clockHourWheelStartTurn);
|
||||
DECLARE_OPCODE(o_clockLeverStartMove);
|
||||
DECLARE_OPCODE(o_clockLeverMoveLeft);
|
||||
DECLARE_OPCODE(o_clockLeverMoveRight);
|
||||
DECLARE_OPCODE(o_clockLeverEndMove);
|
||||
DECLARE_OPCODE(o_clockResetLeverStartMove);
|
||||
DECLARE_OPCODE(o_clockResetLeverMove);
|
||||
DECLARE_OPCODE(o_clockResetLeverEndMove);
|
||||
|
||||
DECLARE_OPCODE(o_libraryCombinationBookStartRight);
|
||||
DECLARE_OPCODE(o_libraryCombinationBookStartLeft);
|
||||
DECLARE_OPCODE(o_observatoryTimeChangeStartIncrease);
|
||||
DECLARE_OPCODE(o_observatoryTimeChangeStartDecrease);
|
||||
DECLARE_OPCODE(o_observatoryChangeSettingStop);
|
||||
DECLARE_OPCODE(o_observatoryYearChangeStartIncrease);
|
||||
DECLARE_OPCODE(o_observatoryYearChangeStartDecrease);
|
||||
DECLARE_OPCODE(o_dockVaultForceClose);
|
||||
DECLARE_OPCODE(o_imagerEraseStop);
|
||||
|
||||
DECLARE_OPCODE(o_libraryBook_init);
|
||||
DECLARE_OPCODE(o_courtyardBox_init);
|
||||
DECLARE_OPCODE(o_towerRotationMap_init);
|
||||
DECLARE_OPCODE(o_forechamberDoor_init);
|
||||
DECLARE_OPCODE(o_shipAccess_init);
|
||||
DECLARE_OPCODE(o_butterflies_init);
|
||||
DECLARE_OPCODE(o_imager_init);
|
||||
DECLARE_OPCODE(o_libraryBookcaseTransform_init);
|
||||
DECLARE_OPCODE(o_generatorControlRoom_init);
|
||||
DECLARE_OPCODE(o_fireplace_init);
|
||||
DECLARE_OPCODE(o_clockGears_init);
|
||||
DECLARE_OPCODE(o_gulls1_init);
|
||||
DECLARE_OPCODE(o_observatory_init);
|
||||
DECLARE_OPCODE(o_gulls2_init);
|
||||
DECLARE_OPCODE(o_treeCard_init);
|
||||
DECLARE_OPCODE(o_treeEntry_init);
|
||||
DECLARE_OPCODE(o_boilerMovies_init);
|
||||
DECLARE_OPCODE(o_rocketSliders_init);
|
||||
DECLARE_OPCODE(o_rocketLinkVideo_init);
|
||||
DECLARE_OPCODE(o_greenBook_init);
|
||||
DECLARE_OPCODE(o_gulls3_init);
|
||||
|
||||
DECLARE_OPCODE(o_bookAddSpecialPage_exit);
|
||||
DECLARE_OPCODE(o_treeCard_exit);
|
||||
DECLARE_OPCODE(o_treeEntry_exit);
|
||||
DECLARE_OPCODE(o_boiler_exit);
|
||||
DECLARE_OPCODE(o_generatorControlRoom_exit);
|
||||
DECLARE_OPCODE(o_rocketSliders_exit);
|
||||
|
||||
|
||||
MystGameState::Myst &_state;
|
||||
|
||||
bool _generatorControlRoomRunning;
|
||||
uint16 _generatorVoltage; // 58
|
||||
|
||||
uint16 _rocketPianoSound; // 292
|
||||
MystAreaSlider *_rocketSlider1; // 248
|
||||
MystAreaSlider *_rocketSlider2; // 252
|
||||
MystAreaSlider *_rocketSlider3; // 256
|
||||
MystAreaSlider *_rocketSlider4; // 260
|
||||
MystAreaSlider *_rocketSlider5; // 264
|
||||
uint16 _rocketSliderSound; // 294
|
||||
uint16 _rocketLeverPosition; // 296
|
||||
VideoEntryPtr _rocketLinkBook; // 268
|
||||
|
||||
bool _libraryBookPagesTurning;
|
||||
bool _libraryCombinationBookPagesTurning;
|
||||
int16 _libraryBookPage; // 86
|
||||
uint16 _libraryBookNumPages; // 88
|
||||
uint16 _libraryBookBaseImage; // 90
|
||||
|
||||
bool _butterfliesMoviePlayed; // 100
|
||||
|
||||
bool _gullsFlying1;
|
||||
bool _gullsFlying2;
|
||||
bool _gullsFlying3;
|
||||
uint32 _gullsNextTime; // 216
|
||||
|
||||
bool _libraryBookcaseMoving;
|
||||
MystAreaVideo *_libraryBookcaseMovie; // 104
|
||||
uint16 _libraryBookcaseSoundId; // 284
|
||||
bool _libraryBookcaseChanged; // 288
|
||||
uint16 _libraryBookSound1; // 298
|
||||
uint16 _libraryBookSound2; // 300
|
||||
|
||||
uint16 _courtyardBoxSound; // 302
|
||||
|
||||
bool _imagerValidationRunning;
|
||||
MystAreaImageSwitch *_imagerRedButton; // 304
|
||||
uint16 _imagerSound[4]; // 308 to 314
|
||||
uint16 _imagerValidationCard; // 316
|
||||
uint16 _imagerValidationStep; // 318
|
||||
|
||||
bool _imagerRunning;
|
||||
MystAreaVideo *_imagerMovie; // 64
|
||||
|
||||
uint16 _fireplaceLines[6]; // 74 to 84
|
||||
|
||||
uint16 _clockTurningWheel;
|
||||
|
||||
VideoEntryPtr _clockGearsVideos[3]; // 148 to 156
|
||||
VideoEntryPtr _clockWeightVideo; // 160
|
||||
uint16 _clockGearsPositions[3]; // 164 to 168
|
||||
uint16 _clockWeightPosition; // 172
|
||||
bool _clockMiddleGearMovedAlone; // 176
|
||||
bool _clockLeverPulled; // 328
|
||||
|
||||
uint16 _dockVaultState; // 92
|
||||
|
||||
bool _towerRotationMapRunning;
|
||||
bool _towerRotationBlinkLabel;
|
||||
uint16 _towerRotationBlinkLabelCount;
|
||||
uint16 _towerRotationMapInitialized; // 292
|
||||
MystAreaImageSwitch *_towerRotationMapTower; // 108
|
||||
MystAreaImageSwitch *_towerRotationMapLabel; // 112
|
||||
uint16 _towerRotationSpeed; // 124
|
||||
bool _towerRotationMapClicked; // 132
|
||||
bool _towerRotationOverSpot; // 136
|
||||
const Common::Point _towerRotationCenter;
|
||||
|
||||
bool _matchBurning;
|
||||
uint16 _matchGoOutCnt;
|
||||
uint16 _cabinDoorOpened; // 56
|
||||
uint16 _cabinHandleDown; // 344
|
||||
uint16 _cabinMatchState; // 60
|
||||
uint32 _matchGoOutTime; // 144
|
||||
|
||||
VideoEntryPtr _cabinFireMovie; // 240
|
||||
|
||||
bool _cabinGaugeMovieEnabled;
|
||||
VideoEntryPtr _cabinGaugeMovie; // 244
|
||||
|
||||
bool _boilerPressureIncreasing;
|
||||
bool _boilerPressureDecreasing;
|
||||
bool _basementPressureIncreasing;
|
||||
bool _basementPressureDecreasing;
|
||||
|
||||
bool _treeStopped; // 236
|
||||
MystAreaImageSwitch *_tree; // 220
|
||||
MystArea *_treeAlcove; // 224
|
||||
uint16 _treeMinPosition; // 228
|
||||
uint16 _treeMinAccessiblePosition; // 230
|
||||
uint16 _treeMaxAccessiblePosition; // 232
|
||||
|
||||
bool _observatoryRunning;
|
||||
bool _observatoryMonthChanging;
|
||||
bool _observatoryDayChanging;
|
||||
bool _observatoryYearChanging;
|
||||
bool _observatoryTimeChanging;
|
||||
MystAreaImageSwitch *_observatoryVisualizer; // 184
|
||||
MystAreaImageSwitch *_observatoryGoButton; // 188
|
||||
MystAreaSlider *_observatoryDaySlider; // 192
|
||||
MystAreaSlider *_observatoryMonthSlider; // 196
|
||||
MystAreaSlider *_observatoryYearSlider; // 200
|
||||
MystAreaSlider *_observatoryTimeSlider; // 204
|
||||
uint32 _observatoryLastTime; // 208
|
||||
bool _observatoryNotInitialized; // 212
|
||||
int16 _observatoryIncrement; // 346
|
||||
MystAreaSlider *_observatoryCurrentSlider; // 348
|
||||
|
||||
bool _greenBookRunning;
|
||||
|
||||
void generatorRedrawRocket();
|
||||
void generatorButtonValue(MystArea *button, uint16 &offset, uint16 &value);
|
||||
|
||||
void rocketSliderMove();
|
||||
uint16 rocketSliderGetSound(uint16 pos);
|
||||
uint16 rocketCheckIfSoundMatches(uint16 sound1, uint16 sound2);
|
||||
void rocketCheckSolution();
|
||||
|
||||
void libraryBookPageTurnLeft();
|
||||
void libraryBookPageTurnRight();
|
||||
void libraryCombinationBookTurnRight();
|
||||
void libraryCombinationBookTurnLeft();
|
||||
|
||||
uint16 bookCountPages(uint16 var);
|
||||
|
||||
void clockWheelStartTurn(uint16 wheel);
|
||||
void clockWheelTurn(uint16 var);
|
||||
|
||||
void clockLeverMove(bool leftLever);
|
||||
void clockGearForwardOneStep(uint16 gear);
|
||||
void clockWeightDownOneStep();
|
||||
void clockGearsCheckSolution();
|
||||
void clockReset();
|
||||
void clockResetWeight();
|
||||
void clockResetGear(uint16 gear);
|
||||
|
||||
void towerRotationMapRotate();
|
||||
void towerRotationMapRedraw();
|
||||
void towerRotationDrawBuildings();
|
||||
uint16 towerRotationMapComputeAngle();
|
||||
Common::Point towerRotationMapComputeCoords(uint16 angle);
|
||||
void towerRotationMapDrawLine(const Common::Point &end, bool rotationLabelVisible);
|
||||
|
||||
void boilerFireInit();
|
||||
void boilerFireUpdate(bool init);
|
||||
void boilerGaugeInit();
|
||||
Common::Rational boilerComputeGaugeRate(uint16 pressure, uint32 delay);
|
||||
void boilerResetGauge(const Common::Rational &rate);
|
||||
|
||||
void treeSetAlcoveAccessible();
|
||||
uint32 treeNextMoveDelay(uint16 pressure);
|
||||
|
||||
bool observatoryIsDDMMYYYY2400();
|
||||
void observatorySetTargetToSetting();
|
||||
void observatoryUpdateVisualizer(uint16 x, uint16 y);
|
||||
void observatoryMonthChangeStart(bool increase);
|
||||
void observatoryDayChangeStart(bool increase);
|
||||
void observatoryYearChangeStart(bool increase);
|
||||
void observatoryTimeChangeStart(bool increase);
|
||||
void observatoryIncrementMonth(int16 increment);
|
||||
void observatoryIncrementDay(int16 increment);
|
||||
void observatoryIncrementYear(int16 increment);
|
||||
void observatoryIncrementTime(int16 increment);
|
||||
void observatoryUpdateMonth();
|
||||
void observatoryUpdateDay();
|
||||
void observatoryUpdateYear();
|
||||
void observatoryUpdateTime();
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
247
engines/mohawk/myst_stacks/preview.cpp
Normal file
247
engines/mohawk/myst_stacks/preview.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
/* 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 "mohawk/cursors.h"
|
||||
#include "mohawk/myst.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/myst_graphics.h"
|
||||
#include "mohawk/myst_sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/preview.h"
|
||||
|
||||
#include "common/system.h"
|
||||
#include "common/translation.h"
|
||||
#include "gui/message.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
Preview::Preview(MohawkEngine_Myst *vm) :
|
||||
Myst(vm, kDemoPreviewStack) {
|
||||
setupOpcodes();
|
||||
_vm->_cursor->hideCursor();
|
||||
|
||||
_libraryState = 0;
|
||||
_library = nullptr;
|
||||
|
||||
_speechRunning = false;
|
||||
_speechStep = 0;
|
||||
_currentCue = 0;
|
||||
_speechNextTime = 0;
|
||||
}
|
||||
|
||||
Preview::~Preview() {
|
||||
}
|
||||
|
||||
void Preview::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
OVERRIDE_OPCODE(196, Preview, o_fadeToBlack);
|
||||
OVERRIDE_OPCODE(197, Preview, o_fadeFromBlack);
|
||||
OVERRIDE_OPCODE(198, Preview, o_stayHere);
|
||||
OVERRIDE_OPCODE(199, Preview, o_speechStop);
|
||||
|
||||
// "Init" Opcodes
|
||||
OVERRIDE_OPCODE(209, Preview, o_libraryBookcaseTransformDemo_init);
|
||||
REGISTER_OPCODE(298, Preview, o_speech_init);
|
||||
REGISTER_OPCODE(299, Preview, o_library_init);
|
||||
}
|
||||
|
||||
void Preview::disablePersistentScripts() {
|
||||
Myst::disablePersistentScripts();
|
||||
}
|
||||
|
||||
void Preview::runPersistentScripts() {
|
||||
Myst::runPersistentScripts();
|
||||
|
||||
if (_speechRunning)
|
||||
speech_run();
|
||||
}
|
||||
|
||||
void Preview::o_fadeToBlack(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_gfx->fadeToBlack();
|
||||
}
|
||||
|
||||
void Preview::o_fadeFromBlack(uint16 var, const ArgumentsArray &args) {
|
||||
|
||||
_vm->_gfx->fadeFromBlack();
|
||||
}
|
||||
|
||||
void Preview::o_stayHere(uint16 var, const ArgumentsArray &args) {
|
||||
// Nuh-uh! No leaving the library in the demo!
|
||||
GUI::MessageDialog dialog(_("You can't leave the library in the demo."));
|
||||
dialog.runModal();
|
||||
}
|
||||
|
||||
void Preview::o_speechStop(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_sound->stopSpeech();
|
||||
_speechRunning = false;
|
||||
_globals.currentAge = kMystLibrary;
|
||||
}
|
||||
|
||||
void Preview::speechUpdateCue() {
|
||||
// This is a callback in the original, handling audio events.
|
||||
if (!_vm->_sound->isSpeechPlaying()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint samples = _vm->_sound->getSpeechNumSamplesPlayed();
|
||||
for (int16 i = 0; i < _cueList.pointCount; i++) {
|
||||
if (_cueList.points[i].sampleFrame > samples)
|
||||
return;
|
||||
if (i > _currentCue - 1) {
|
||||
_currentCue++;
|
||||
debugC(kDebugScript, "Sneak speech advanced to cue %d", _currentCue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Preview::speech_run() {
|
||||
uint32 time = _vm->getTotalPlayTime();
|
||||
|
||||
// Update current speech sound cue
|
||||
speechUpdateCue();
|
||||
|
||||
switch (_speechStep) {
|
||||
case 0: // Start Voice Over... which controls book opening
|
||||
_currentCue = 0;
|
||||
_vm->_sound->playSpeech(3001, &_cueList);
|
||||
|
||||
_speechStep++;
|
||||
break;
|
||||
case 1: // Open book
|
||||
if (_currentCue >= 1) {
|
||||
_vm->changeToCard(3001, kTransitionDissolve);
|
||||
|
||||
_speechStep++;
|
||||
}
|
||||
break;
|
||||
case 2: // Go to Myst
|
||||
if (_currentCue >= 2) {
|
||||
_vm->_gfx->fadeToBlack();
|
||||
_vm->changeToCard(3002, kNoTransition);
|
||||
_vm->_gfx->fadeFromBlack();
|
||||
|
||||
_speechStep++;
|
||||
}
|
||||
break;
|
||||
case 3: // Start blinking the library
|
||||
if (_currentCue >= 3) {
|
||||
_libraryState = 1;
|
||||
_speechNextTime = 0;
|
||||
_speechStep++;
|
||||
}
|
||||
break;
|
||||
case 4: // Library blinking, zoom in library
|
||||
if (_currentCue >= 4) {
|
||||
_library->drawConditionalDataToScreen(0);
|
||||
|
||||
_vm->changeToCard(3003, kTransitionDissolve);
|
||||
|
||||
_speechNextTime = time + 2000;
|
||||
_speechStep++;
|
||||
} else {
|
||||
if (time < _speechNextTime)
|
||||
break;
|
||||
|
||||
_library->drawConditionalDataToScreen(_libraryState);
|
||||
_libraryState = (_libraryState + 1) % 2;
|
||||
_speechNextTime = time + 500;
|
||||
}
|
||||
break;
|
||||
case 5: // Go to library near view
|
||||
if (time < _speechNextTime)
|
||||
break;
|
||||
|
||||
_vm->changeToCard(3004, kTransitionDissolve);
|
||||
_speechNextTime = time + 2000;
|
||||
_speechStep++;
|
||||
break;
|
||||
case 6: // Fade to courtyard
|
||||
if (time < _speechNextTime)
|
||||
break;
|
||||
|
||||
_vm->_gfx->fadeToBlack();
|
||||
_vm->changeToCard(3005, kNoTransition);
|
||||
_vm->_gfx->fadeFromBlack();
|
||||
_speechNextTime = time + 1000;
|
||||
_speechStep++;
|
||||
break;
|
||||
case 7: // Walk to library
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
if (time < _speechNextTime)
|
||||
break;
|
||||
|
||||
_vm->changeToCard(3006 + _speechStep - 7, kTransitionDissolve);
|
||||
_speechNextTime = time + 2000;
|
||||
_speechStep++;
|
||||
break;
|
||||
case 14: // Go to playable library card
|
||||
if (time < _speechNextTime)
|
||||
break;
|
||||
|
||||
_vm->changeToCard(4329, kTransitionDissolve);
|
||||
|
||||
_speechRunning = false;
|
||||
_globals.currentAge = kMystLibrary;
|
||||
|
||||
_vm->_cursor->showCursor();
|
||||
break;
|
||||
default:
|
||||
warning("Unknown speech step");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Preview::o_speech_init(uint16 var, const ArgumentsArray &args) {
|
||||
// Used for Card 3000 (Closed Myst Book)
|
||||
_speechStep = 0;
|
||||
_speechRunning = true;
|
||||
}
|
||||
|
||||
void Preview::o_library_init(uint16 var, const ArgumentsArray &args) {
|
||||
// Used for Card 3002 (Myst Island Overview)
|
||||
_library = getInvokingResource<MystAreaImageSwitch>();
|
||||
}
|
||||
|
||||
void Preview::o_libraryBookcaseTransformDemo_init(uint16 var, const ArgumentsArray &args) {
|
||||
if (_libraryBookcaseChanged) {
|
||||
MystAreaActionSwitch *resource = getInvokingResource<MystAreaActionSwitch>();
|
||||
_libraryBookcaseMovie = static_cast<MystAreaVideo *>(resource->getSubResource(getVar(303)));
|
||||
_libraryBookcaseSoundId = args[0];
|
||||
_libraryBookcaseMoving = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Preview::libraryBookcaseTransform_run() {
|
||||
if (_libraryBookcaseChanged)
|
||||
_state.libraryBookcaseDoor = !_state.libraryBookcaseDoor;
|
||||
|
||||
Myst::libraryBookcaseTransform_run();
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
79
engines/mohawk/myst_stacks/preview.h
Normal file
79
engines/mohawk/myst_stacks/preview.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 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 MYST_SCRIPTS_PREVIEW_H
|
||||
#define MYST_SCRIPTS_PREVIEW_H
|
||||
|
||||
#include "mohawk/sound.h"
|
||||
#include "mohawk/myst_stacks/myst.h"
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Preview : public Myst {
|
||||
public:
|
||||
explicit Preview(MohawkEngine_Myst *vm);
|
||||
~Preview() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
|
||||
DECLARE_OPCODE(o_fadeToBlack);
|
||||
DECLARE_OPCODE(o_fadeFromBlack);
|
||||
DECLARE_OPCODE(o_stayHere);
|
||||
DECLARE_OPCODE(o_speechStop);
|
||||
|
||||
DECLARE_OPCODE(o_libraryBookcaseTransformDemo_init);
|
||||
DECLARE_OPCODE(o_speech_init);
|
||||
DECLARE_OPCODE(o_library_init);
|
||||
|
||||
uint16 _libraryState; // 4
|
||||
MystAreaImageSwitch *_library; // 32
|
||||
|
||||
bool _speechRunning;
|
||||
uint _speechStep;
|
||||
CueList _cueList;
|
||||
int16 _currentCue;
|
||||
uint32 _speechNextTime; // 6
|
||||
|
||||
void speech_run();
|
||||
void speechUpdateCue();
|
||||
|
||||
void libraryBookcaseTransform_run() override;
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
1773
engines/mohawk/myst_stacks/selenitic.cpp
Normal file
1773
engines/mohawk/myst_stacks/selenitic.cpp
Normal file
File diff suppressed because it is too large
Load Diff
152
engines/mohawk/myst_stacks/selenitic.h
Normal file
152
engines/mohawk/myst_stacks/selenitic.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/* 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 MYST_SCRIPTS_SELENITIC_H
|
||||
#define MYST_SCRIPTS_SELENITIC_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
class MystAreaImageSwitch;
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Selenitic : public MystScriptParser {
|
||||
public:
|
||||
explicit Selenitic(MohawkEngine_Myst *vm);
|
||||
~Selenitic() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
uint16 getVar(uint16 var) override;
|
||||
void toggleVar(uint16 var) override;
|
||||
bool setVarValue(uint16 var, uint16 value) override;
|
||||
|
||||
uint16 getMap() override { return 9930; }
|
||||
|
||||
DECLARE_OPCODE(o_mazeRunnerMove);
|
||||
DECLARE_OPCODE(o_mazeRunnerSoundRepeat);
|
||||
DECLARE_OPCODE(o_soundReceiverSigma);
|
||||
DECLARE_OPCODE(o_soundReceiverRight);
|
||||
DECLARE_OPCODE(o_soundReceiverLeft);
|
||||
DECLARE_OPCODE(o_soundReceiverSource);
|
||||
DECLARE_OPCODE(o_mazeRunnerDoorButton);
|
||||
DECLARE_OPCODE(o_soundReceiverUpdateSound);
|
||||
DECLARE_OPCODE(o_soundLockMove);
|
||||
DECLARE_OPCODE(o_soundLockStartMove);
|
||||
DECLARE_OPCODE(o_soundLockEndMove);
|
||||
DECLARE_OPCODE(o_soundLockButton);
|
||||
DECLARE_OPCODE(o_soundReceiverEndMove);
|
||||
|
||||
DECLARE_OPCODE(o_mazeRunnerCompass_init);
|
||||
DECLARE_OPCODE(o_mazeRunnerWindow_init);
|
||||
DECLARE_OPCODE(o_mazeRunnerLight_init);
|
||||
DECLARE_OPCODE(o_soundReceiver_init);
|
||||
DECLARE_OPCODE(o_soundLock_init);
|
||||
DECLARE_OPCODE(o_mazeRunnerRight_init);
|
||||
DECLARE_OPCODE(o_mazeRunnerLeft_init);
|
||||
|
||||
enum SoundReceiverSpeed {
|
||||
kSoundReceiverSpeedStill = 0,
|
||||
kSoundReceiverSpeedSlow = 1,
|
||||
kSoundReceiverSpeedNormal = 5, // The original has this at 10
|
||||
kSoundReceiverSpeedFast = 10, // The original has this at 50 too fast!
|
||||
kSoundReceiverSpeedFaster = 13 // The original has this at 100, way too fast!
|
||||
};
|
||||
|
||||
void soundReceiver_run();
|
||||
|
||||
MystGameState::Selenitic &_state;
|
||||
|
||||
bool _soundReceiverRunning;
|
||||
bool _soundReceiverSigmaPressed; // 6
|
||||
MystAreaImageSwitch *_soundReceiverSources[5]; // 92 -> 108
|
||||
MystAreaImageSwitch *_soundReceiverCurrentSource; // 112
|
||||
uint16 *_soundReceiverPosition; // 116
|
||||
uint16 _soundReceiverDirection; // 120
|
||||
SoundReceiverSpeed _soundReceiverSpeed; // 122
|
||||
uint32 _soundReceiverStartTime; //124
|
||||
uint _soundReceiverNearBlinkCounter;
|
||||
MystAreaImageSwitch *_soundReceiverViewer; // 128
|
||||
MystAreaImageSwitch *_soundReceiverRightButton; // 132
|
||||
MystAreaImageSwitch *_soundReceiverLeftButton; // 136
|
||||
MystAreaImageSwitch *_soundReceiverAngle1; // 140
|
||||
MystAreaImageSwitch *_soundReceiverAngle2; // 144
|
||||
MystAreaImageSwitch *_soundReceiverAngle3; // 148
|
||||
MystAreaImageSwitch *_soundReceiverAngle4; // 152
|
||||
MystAreaImageSwitch *_soundReceiverSigmaButton; // 156
|
||||
|
||||
static const uint16 _mazeRunnerMap[300][4];
|
||||
static const uint8 _mazeRunnerVideos[300][4];
|
||||
|
||||
uint16 _mazeRunnerPosition; // 56
|
||||
uint16 _mazeRunnerDirection; // 58
|
||||
MystAreaImageSwitch *_mazeRunnerWindow; // 68
|
||||
MystAreaImageSwitch *_mazeRunnerCompass; // 72
|
||||
MystAreaImageSwitch *_mazeRunnerLight; // 76
|
||||
MystAreaImageSwitch *_mazeRunnerRightButton; // 80
|
||||
MystAreaImageSwitch *_mazeRunnerLeftButton; // 84
|
||||
bool _mazeRunnerDoorOpened; // 160
|
||||
|
||||
uint16 _soundLockSoundId;
|
||||
MystAreaSlider *_soundLockSlider1; // 164
|
||||
MystAreaSlider *_soundLockSlider2; // 168
|
||||
MystAreaSlider *_soundLockSlider3; // 172
|
||||
MystAreaSlider *_soundLockSlider4; // 176
|
||||
MystAreaSlider *_soundLockSlider5; // 180
|
||||
MystAreaImageSwitch *_soundLockButton; // 184
|
||||
|
||||
void soundReceiverLeftRight(uint direction);
|
||||
void soundReceiverUpdate();
|
||||
void soundReceiverSetSubimageRect() const;
|
||||
void soundReceiverDrawView();
|
||||
void soundReceiverDrawAngle();
|
||||
void soundReceiverIncreaseSpeed();
|
||||
void soundReceiverUpdateSound();
|
||||
uint16 soundReceiverCurrentSound(uint16 source, uint16 position);
|
||||
void soundReceiverSolution(uint16 source, uint16 &solution, bool &enabled);
|
||||
|
||||
uint16 soundLockCurrentSound(uint16 position, bool pixels);
|
||||
MystAreaSlider *soundLockSliderFromVar(uint16 var);
|
||||
void soundLockCheckSolution(MystAreaSlider *slider, uint16 value, uint16 solution, bool &solved);
|
||||
|
||||
bool mazeRunnerForwardAllowed(uint16 position);
|
||||
void mazeRunnerUpdateCompass();
|
||||
void mazeRunnerPlaySoundHelp();
|
||||
void mazeRunnerPlayVideo(uint16 video, uint16 pos);
|
||||
void mazeRunnerBacktrack(uint16 &oldPosition);
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
}
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
85
engines/mohawk/myst_stacks/slides.cpp
Normal file
85
engines/mohawk/myst_stacks/slides.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/* 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 "mohawk/cursors.h"
|
||||
#include "mohawk/myst.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/myst_graphics.h"
|
||||
#include "mohawk/sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/slides.h"
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
Slides::Slides(MohawkEngine_Myst *vm) :
|
||||
MystScriptParser(vm, kDemoSlidesStack) {
|
||||
setupOpcodes();
|
||||
|
||||
_vm->_cursor->hideCursor();
|
||||
|
||||
_cardSwapEnabled = false;
|
||||
_nextCardID = 0;
|
||||
_nextCardTime = 0;
|
||||
}
|
||||
|
||||
Slides::~Slides() {
|
||||
}
|
||||
|
||||
void Slides::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
REGISTER_OPCODE(100, Slides, o_returnToMenu);
|
||||
|
||||
// "Init" Opcodes
|
||||
REGISTER_OPCODE(200, Slides, o_setCardSwap);
|
||||
}
|
||||
|
||||
void Slides::disablePersistentScripts() {
|
||||
_cardSwapEnabled = false;
|
||||
}
|
||||
|
||||
void Slides::runPersistentScripts() {
|
||||
if (_cardSwapEnabled) {
|
||||
// Used on Cards...
|
||||
if (_vm->getTotalPlayTime() > _nextCardTime) {
|
||||
_vm->_gfx->fadeToBlack();
|
||||
_vm->changeToCard(_nextCardID, kNoTransition);
|
||||
_vm->_gfx->fadeFromBlack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Slides::o_returnToMenu(uint16 var, const ArgumentsArray &args) {
|
||||
// Go to the information screens of the menu
|
||||
_vm->changeToStack(kDemoStack, 2002, 0, 0);
|
||||
}
|
||||
|
||||
void Slides::o_setCardSwap(uint16 var, const ArgumentsArray &args) {
|
||||
_nextCardID = args[0];
|
||||
|
||||
_nextCardTime = _vm->getTotalPlayTime() + 5000;
|
||||
_cardSwapEnabled = true;
|
||||
}
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
62
engines/mohawk/myst_stacks/slides.h
Normal file
62
engines/mohawk/myst_stacks/slides.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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 MYST_SCRIPTS_SLIDES_H
|
||||
#define MYST_SCRIPTS_SLIDES_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Slides : public MystScriptParser {
|
||||
public:
|
||||
explicit Slides(MohawkEngine_Myst *vm);
|
||||
~Slides() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
|
||||
DECLARE_OPCODE(o_returnToMenu);
|
||||
|
||||
DECLARE_OPCODE(o_setCardSwap);
|
||||
|
||||
bool _cardSwapEnabled;
|
||||
uint16 _nextCardID;
|
||||
uint32 _nextCardTime;
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
966
engines/mohawk/myst_stacks/stoneship.cpp
Normal file
966
engines/mohawk/myst_stacks/stoneship.cpp
Normal file
@@ -0,0 +1,966 @@
|
||||
/* 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 "mohawk/cursors.h"
|
||||
#include "mohawk/myst.h"
|
||||
#include "mohawk/myst_areas.h"
|
||||
#include "mohawk/myst_card.h"
|
||||
#include "mohawk/myst_graphics.h"
|
||||
#include "mohawk/myst_state.h"
|
||||
#include "mohawk/myst_sound.h"
|
||||
#include "mohawk/video.h"
|
||||
#include "mohawk/myst_stacks/stoneship.h"
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/system.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
namespace Mohawk {
|
||||
namespace MystStacks {
|
||||
|
||||
Stoneship::Stoneship(MohawkEngine_Myst *vm) :
|
||||
MystScriptParser(vm, kStoneshipStack),
|
||||
_state(vm->_gameState->_stoneship) {
|
||||
setupOpcodes();
|
||||
|
||||
_tunnelRunning = false;
|
||||
_tunnelNextTime = 0;
|
||||
_tunnelAlarmSound = 0;
|
||||
_tunnelImagesCount = 0;
|
||||
|
||||
_state.lightState = 0;
|
||||
_state.generatorDepletionTime = 0;
|
||||
_state.generatorDuration = 0;
|
||||
_cabinMystBookPresent = 0;
|
||||
_siriusDrawerDrugsOpen = 0;
|
||||
_chestDrawersOpen = 0;
|
||||
_chestAchenarBottomDrawerClosed = 1;
|
||||
|
||||
_brotherDoorOpen = 0;
|
||||
|
||||
// Drop key
|
||||
if (_state.trapdoorKeyState == 1)
|
||||
_state.trapdoorKeyState = 2;
|
||||
|
||||
// Power is not available when loading
|
||||
if (_state.sideDoorOpened)
|
||||
_state.generatorPowerAvailable = 2;
|
||||
else
|
||||
_state.generatorPowerAvailable = 0;
|
||||
|
||||
_batteryCharging = false;
|
||||
_batteryDepleting = false;
|
||||
_batteryNextTime = 0;
|
||||
_batteryLastCharge = 0;
|
||||
_batteryGaugeRunning = false;
|
||||
_batteryGauge = nullptr;
|
||||
|
||||
_hologramTurnedOn = 0;
|
||||
_hologramDisplay = nullptr;
|
||||
_hologramSelection = nullptr;
|
||||
_hologramDisplayPos = 0;
|
||||
|
||||
_telescopeRunning = false;
|
||||
_telescopePosition = 0;
|
||||
_telescopePanorama = 0;
|
||||
_telescopeOldMouse = 0;
|
||||
_telescopeLighthouseOff = 0;
|
||||
_telescopeLighthouseOn = 0;
|
||||
_telescopeLighthouseState = false;
|
||||
_telescopeNexTime = 0;
|
||||
|
||||
_cloudOrbMovie = nullptr;
|
||||
_cloudOrbSound = 0;
|
||||
_cloudOrbStopSound = 0;
|
||||
}
|
||||
|
||||
Stoneship::~Stoneship() {
|
||||
}
|
||||
|
||||
void Stoneship::setupOpcodes() {
|
||||
// "Stack-Specific" Opcodes
|
||||
REGISTER_OPCODE(100, Stoneship, o_pumpTurnOff);
|
||||
REGISTER_OPCODE(101, Stoneship, o_brotherDoorOpen);
|
||||
REGISTER_OPCODE(102, Stoneship, o_cabinBookMovie);
|
||||
REGISTER_OPCODE(103, Stoneship, o_drawerOpenSirius);
|
||||
REGISTER_OPCODE(104, Stoneship, o_drawerClose);
|
||||
REGISTER_OPCODE(105, Stoneship, o_telescopeStart);
|
||||
REGISTER_OPCODE(106, Stoneship, o_telescopeMove);
|
||||
REGISTER_OPCODE(107, Stoneship, o_telescopeStop);
|
||||
REGISTER_OPCODE(108, Stoneship, o_generatorStart);
|
||||
REGISTER_OPCODE(109, Stoneship, NOP);
|
||||
REGISTER_OPCODE(110, Stoneship, o_generatorStop);
|
||||
REGISTER_OPCODE(111, Stoneship, o_drawerOpenAchenar);
|
||||
REGISTER_OPCODE(112, Stoneship, o_hologramPlayback);
|
||||
REGISTER_OPCODE(113, Stoneship, o_hologramSelectionStart);
|
||||
REGISTER_OPCODE(114, Stoneship, o_hologramSelectionMove);
|
||||
REGISTER_OPCODE(115, Stoneship, o_hologramSelectionStop);
|
||||
REGISTER_OPCODE(116, Stoneship, o_compassButton);
|
||||
REGISTER_OPCODE(117, Stoneship, o_chestValveVideos);
|
||||
REGISTER_OPCODE(118, Stoneship, o_chestDropKey);
|
||||
REGISTER_OPCODE(119, Stoneship, o_trapLockOpen);
|
||||
REGISTER_OPCODE(120, Stoneship, o_sideDoorsMovies);
|
||||
REGISTER_OPCODE(121, Stoneship, o_cloudOrbEnter);
|
||||
REGISTER_OPCODE(122, Stoneship, o_cloudOrbLeave);
|
||||
REGISTER_OPCODE(125, Stoneship, o_drawerCloseOpened);
|
||||
|
||||
// "Init" Opcodes
|
||||
REGISTER_OPCODE(200, Stoneship, o_hologramDisplay_init);
|
||||
REGISTER_OPCODE(201, Stoneship, o_hologramSelection_init);
|
||||
REGISTER_OPCODE(202, Stoneship, o_battery_init);
|
||||
REGISTER_OPCODE(203, Stoneship, o_tunnelEnter_init);
|
||||
REGISTER_OPCODE(204, Stoneship, o_batteryGauge_init);
|
||||
REGISTER_OPCODE(205, Stoneship, o_tunnel_init);
|
||||
REGISTER_OPCODE(206, Stoneship, o_tunnelLeave_init);
|
||||
REGISTER_OPCODE(207, Stoneship, o_chest_init);
|
||||
REGISTER_OPCODE(208, Stoneship, o_telescope_init);
|
||||
REGISTER_OPCODE(209, Stoneship, o_achenarDrawers_init);
|
||||
REGISTER_OPCODE(210, Stoneship, o_cloudOrb_init);
|
||||
|
||||
// "Exit" Opcodes
|
||||
REGISTER_OPCODE(300, Stoneship, NOP);
|
||||
}
|
||||
|
||||
void Stoneship::disablePersistentScripts() {
|
||||
_batteryCharging = false;
|
||||
_batteryDepleting = false;
|
||||
_batteryGaugeRunning = false;
|
||||
_telescopeRunning = false;
|
||||
}
|
||||
|
||||
void Stoneship::runPersistentScripts() {
|
||||
if (_batteryCharging)
|
||||
chargeBattery_run();
|
||||
|
||||
if (_telescopeRunning)
|
||||
telescope_run();
|
||||
|
||||
if (_batteryGaugeRunning)
|
||||
batteryGauge_run();
|
||||
|
||||
if (_batteryDepleting)
|
||||
batteryDeplete_run();
|
||||
|
||||
if (_tunnelRunning)
|
||||
tunnel_run();
|
||||
}
|
||||
|
||||
uint16 Stoneship::getVar(uint16 var) {
|
||||
switch(var) {
|
||||
case 0: // Water Drained From Lighthouse / Right Button Of Pump
|
||||
return _state.pumpState == 4;
|
||||
case 1: // Water Drained From Tunnels To Brothers' Rooms / Middle Button Of Pump
|
||||
return _state.pumpState == 2;
|
||||
case 2: // Water Drained From Ship Cabin Tunnel / Left Button Of Pump
|
||||
return _state.pumpState == 1;
|
||||
case 3: // Lighthouse Chest Floating
|
||||
return _state.pumpState != 4 && !_state.chestValveState && !_state.chestWaterState;
|
||||
case 4: // Lighthouse State - Close Up
|
||||
if (_state.pumpState == 4) {
|
||||
return 1; // Drained
|
||||
} else {
|
||||
if (_state.chestValveState || _state.chestWaterState)
|
||||
return 0; // Flooded
|
||||
else
|
||||
return 2; // Flooded, Chest Floating
|
||||
}
|
||||
case 5: // Lighthouse Trapdoor State
|
||||
return _state.trapdoorState;
|
||||
case 6: // Chest valve state
|
||||
return _state.chestValveState;
|
||||
case 7: // Lighthouse Chest Unlocked
|
||||
return _state.chestOpenState;
|
||||
case 8: // Lighthouse Chest Key Position
|
||||
return _state.trapdoorKeyState;
|
||||
case 11: // Lighthouse Key State
|
||||
if (_state.chestOpenState) {
|
||||
if (_state.trapdoorKeyState == 1)
|
||||
return 1;
|
||||
else if (_state.trapdoorKeyState == 2)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case 12: // Trapdoor can be unlocked
|
||||
return _state.trapdoorKeyState == 1 && _state.trapdoorState == 2;
|
||||
case 13: // State Of Tunnels To Brothers' Rooms - Close Up
|
||||
if (_state.generatorPowerAvailable != 1) {
|
||||
if (_state.pumpState != 2)
|
||||
return 0; // Dark, Flooded
|
||||
else
|
||||
return 1; // Dark, Drained
|
||||
} else {
|
||||
if (_state.pumpState != 2)
|
||||
return 2; // Lit, Flooded
|
||||
else
|
||||
return 3; // Lit, Drained
|
||||
}
|
||||
case 14: // State Of Tunnels lights To Brothers' Rooms - Far
|
||||
return _state.generatorPowerAvailable;
|
||||
case 15: // Side Door in Tunnels To Brother's Rooms Open
|
||||
if (_state.generatorPowerAvailable == 1)
|
||||
return _state.sideDoorOpened;
|
||||
else
|
||||
return 0;
|
||||
case 16: // Ship Chamber Light State
|
||||
return _state.lightState;
|
||||
case 17: // Sirrus' Room Drawer with Drugs Open
|
||||
return _siriusDrawerDrugsOpen;
|
||||
case 18: // Brother Room Door Open
|
||||
return _brotherDoorOpen;
|
||||
case 19: // Brother Room Door State
|
||||
if (_brotherDoorOpen) {
|
||||
if (_state.lightState)
|
||||
return 2; // Open, Light On
|
||||
else
|
||||
return 1; // Open, Light Off
|
||||
} else {
|
||||
return 0; // Closed
|
||||
}
|
||||
case 20: // Ship Chamber Table/Book State
|
||||
return _cabinMystBookPresent;
|
||||
case 21: // Brothers Rooms' Chest Of Drawers Drawer State
|
||||
return _chestDrawersOpen;
|
||||
case 28: // Telescope Angle Position
|
||||
return 0;
|
||||
case 29: // Achenar's Room Rose/Skull Hologram Button Lit
|
||||
return _hologramTurnedOn;
|
||||
case 30: // Light State in Tunnel to Compass Rose Room
|
||||
if (_state.generatorPowerAvailable == 1) {
|
||||
if (_state.lightState)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
case 31: // Lighthouse Lamp Room Battery Pack Indicator Light
|
||||
return batteryRemainingCharge() >= 10;
|
||||
case 32: // Lighthouse Lamp Room Battery Pack Meter Level
|
||||
return 0;
|
||||
case 33: // State of Side Door in Tunnels to Compass Rose Room
|
||||
if (_state.sideDoorOpened)
|
||||
return 2;
|
||||
else
|
||||
return _state.generatorPowerAvailable == 1;
|
||||
case 34: // Achenar's Room Drawer with Torn Note Closed
|
||||
return _chestAchenarBottomDrawerClosed;
|
||||
case 35: // Sirrus' Room Drawer #4 (Bottom) Open and Red Page State
|
||||
if (_chestDrawersOpen == 4)
|
||||
return getVar(102);
|
||||
else
|
||||
return 2;
|
||||
case 36: // Ship Chamber Door State
|
||||
if (_tempVar) {
|
||||
if (_state.lightState)
|
||||
return 2; // Open, Light On
|
||||
else
|
||||
return 1; // Open, Light Off
|
||||
} else {
|
||||
return 0; // Closed
|
||||
}
|
||||
case 102: // Red page
|
||||
return !(_globals.redPagesInBook & 8) && (_globals.heldPage != kRedStoneshipPage);
|
||||
case 103: // Blue page
|
||||
return !(_globals.bluePagesInBook & 8) && (_globals.heldPage != kBlueStoneshipPage);
|
||||
default:
|
||||
return MystScriptParser::getVar(var);
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::toggleVar(uint16 var) {
|
||||
switch(var) {
|
||||
case 0: // Water Drained From Lighthouse / Right Button Of Pump
|
||||
if (_state.pumpState == 4)
|
||||
_state.pumpState = 0;
|
||||
else
|
||||
_state.pumpState = 4;
|
||||
break;
|
||||
case 1: // Water Drained From Tunnels To Brothers' Rooms / Middle Button Of Pump
|
||||
if (_state.pumpState == 2)
|
||||
_state.pumpState = 0;
|
||||
else
|
||||
_state.pumpState = 2;
|
||||
break;
|
||||
case 2: // Water Drained From Ship Cabin Tunnel / Left Button Of Pump
|
||||
if (_state.pumpState == 1)
|
||||
_state.pumpState = 0;
|
||||
else
|
||||
_state.pumpState = 1;
|
||||
break;
|
||||
case 6: // Chest valve state
|
||||
_state.chestValveState = (_state.chestValveState + 1) % 2;
|
||||
break;
|
||||
case 8: // Lighthouse Chest Key Position
|
||||
if (_state.trapdoorKeyState) {
|
||||
if (_state.trapdoorKeyState == 1)
|
||||
_state.trapdoorKeyState = 2;
|
||||
else
|
||||
_state.trapdoorKeyState = 1;
|
||||
}
|
||||
break;
|
||||
case 10: // Chest water state
|
||||
_state.chestWaterState = 0;
|
||||
break;
|
||||
case 11:
|
||||
if (_state.chestOpenState)
|
||||
_state.trapdoorKeyState = _state.trapdoorKeyState != 1;
|
||||
break;
|
||||
case 20: // Ship Chamber Table/Book State
|
||||
_cabinMystBookPresent = (_cabinMystBookPresent + 1) % 2;
|
||||
break;
|
||||
case 29: // Achenar's Room Rose/Skull Hologram Button Lit
|
||||
_hologramTurnedOn = (_hologramTurnedOn + 1) % 2;
|
||||
break;
|
||||
case 102: // Red page
|
||||
if (!(_globals.redPagesInBook & 8)) {
|
||||
if (_globals.heldPage == kRedStoneshipPage)
|
||||
_globals.heldPage = kNoPage;
|
||||
else
|
||||
_globals.heldPage = kRedStoneshipPage;
|
||||
}
|
||||
break;
|
||||
case 103: // Blue page
|
||||
if (!(_globals.bluePagesInBook & 8)) {
|
||||
if (_globals.heldPage == kBlueStoneshipPage)
|
||||
_globals.heldPage = kNoPage;
|
||||
else
|
||||
_globals.heldPage = kBlueStoneshipPage;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MystScriptParser::toggleVar(var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Stoneship::setVarValue(uint16 var, uint16 value) {
|
||||
bool refresh = false;
|
||||
|
||||
switch (var) {
|
||||
case 5: // Lighthouse Trapdoor State
|
||||
_state.trapdoorState = value;
|
||||
break;
|
||||
case 7:
|
||||
if (_state.chestOpenState != value)
|
||||
_state.chestOpenState = value;
|
||||
break;
|
||||
case 8: // Lighthouse Chest Key Position
|
||||
_state.trapdoorKeyState = value;
|
||||
break;
|
||||
case 15: // Side Door in Tunnels To Brother's Rooms Open
|
||||
if (_state.sideDoorOpened != value) {
|
||||
if (!value && _state.generatorPowerAvailable == 2)
|
||||
_state.generatorPowerAvailable = 0;
|
||||
_state.sideDoorOpened = value;
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 17: // Sirrus' Room Drawer with Drugs Open
|
||||
if (_siriusDrawerDrugsOpen != value) {
|
||||
_siriusDrawerDrugsOpen = value;
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 18: // Brother Room Door Open
|
||||
if (_brotherDoorOpen != value) {
|
||||
_brotherDoorOpen = value;
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 21: // Brothers Rooms' Chest Of Drawers Drawer State
|
||||
if (_chestDrawersOpen != value) {
|
||||
_chestDrawersOpen = value;
|
||||
refresh = true;
|
||||
}
|
||||
break;
|
||||
case 29: // Achenar's Room Rose/Skull Hologram Button Lit
|
||||
_hologramTurnedOn = value;
|
||||
break;
|
||||
case 34: // Achenar's Room Drawer with Torn Note Closed
|
||||
_chestAchenarBottomDrawerClosed = value;
|
||||
break;
|
||||
default:
|
||||
refresh = MystScriptParser::setVarValue(var, value);
|
||||
break;
|
||||
}
|
||||
|
||||
return refresh;
|
||||
}
|
||||
|
||||
void Stoneship::o_pumpTurnOff(uint16 var, const ArgumentsArray &args) {
|
||||
if (_state.pumpState) {
|
||||
uint16 buttonVar = 0;
|
||||
|
||||
switch (_state.pumpState) {
|
||||
case 1:
|
||||
buttonVar = 2;
|
||||
break;
|
||||
case 2:
|
||||
buttonVar = 1;
|
||||
break;
|
||||
case 4:
|
||||
buttonVar = 0;
|
||||
break;
|
||||
default:
|
||||
warning("Incorrect pump state");
|
||||
}
|
||||
|
||||
for (uint i = 0; i < _vm->getCard()->_resources.size(); i++) {
|
||||
MystArea *resource = _vm->getCard()->_resources[i];
|
||||
if (resource->hasType(kMystAreaImageSwitch) && resource->getImageSwitchVar() == buttonVar) {
|
||||
static_cast<MystAreaImageSwitch *>(resource)->drawConditionalDataToScreen(0, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::o_brotherDoorOpen(uint16 var, const ArgumentsArray &args) {
|
||||
_brotherDoorOpen = 1;
|
||||
_vm->getCard()->redrawArea(19, 0);
|
||||
animatedUpdate(args, 5);
|
||||
}
|
||||
|
||||
void Stoneship::o_cabinBookMovie(uint16 var, const ArgumentsArray &args) {
|
||||
uint16 startTime = args[0];
|
||||
uint16 endTime = args[1];
|
||||
|
||||
VideoEntryPtr book = _vm->playMovie("bkroom", kStoneshipStack);
|
||||
book->moveTo(159, 99);
|
||||
book->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, endTime, 600));
|
||||
|
||||
_vm->waitUntilMovieEnds(book);
|
||||
}
|
||||
|
||||
void Stoneship::o_drawerOpenSirius(uint16 var, const ArgumentsArray &args) {
|
||||
MystAreaImageSwitch *drawer = _vm->getCard()->getResource<MystAreaImageSwitch>(args[0]);
|
||||
|
||||
if (drawer->getImageSwitchVar() == 35) {
|
||||
drawer->drawConditionalDataToScreen(getVar(102), 0);
|
||||
} else {
|
||||
drawer->drawConditionalDataToScreen(0, 0);
|
||||
}
|
||||
|
||||
TransitionType transition = kTransitionTopToBottom;
|
||||
if (args.size() == 2 && args[1])
|
||||
transition = kTransitionCopy;
|
||||
|
||||
_vm->_gfx->runTransition(transition, drawer->getRect(), 25, 5);
|
||||
}
|
||||
|
||||
void Stoneship::o_drawerClose(uint16 var, const ArgumentsArray &args) {
|
||||
drawerClose(args[0]);
|
||||
}
|
||||
|
||||
void Stoneship::o_telescopeStart(uint16 var, const ArgumentsArray &args) {
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
_telescopeOldMouse = mouse.x;
|
||||
_vm->_cursor->setCursor(700);
|
||||
}
|
||||
|
||||
void Stoneship::o_telescopeMove(uint16 var, const ArgumentsArray &args) {
|
||||
MystAreaDrag *display = getInvokingResource<MystAreaDrag>();
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
|
||||
// Compute telescope position
|
||||
_telescopePosition = (_telescopePosition - (mouse.x - _telescopeOldMouse) / 2 + 3240) % 3240;
|
||||
_telescopeOldMouse = mouse.x;
|
||||
|
||||
// Copy image to screen
|
||||
Common::Rect src = Common::Rect(_telescopePosition, 0, _telescopePosition + 112, 112);
|
||||
_vm->_gfx->copyImageSectionToScreen(_telescopePanorama, src, display->getRect());
|
||||
|
||||
// Draw lighthouse
|
||||
telescopeLighthouseDraw();
|
||||
}
|
||||
|
||||
void Stoneship::o_telescopeStop(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->refreshCursor();
|
||||
}
|
||||
|
||||
void Stoneship::o_generatorStart(uint16 var, const ArgumentsArray &args) {
|
||||
MystAreaDrag *handle = getInvokingResource<MystAreaDrag>();
|
||||
|
||||
uint16 soundId = handle->getList1(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId);
|
||||
|
||||
if (_state.generatorDuration)
|
||||
_state.generatorDuration -= _vm->getTotalPlayTime() - _state.generatorDepletionTime;
|
||||
|
||||
// Start charging the battery
|
||||
_batteryDepleting = false;
|
||||
_batteryCharging = true;
|
||||
_batteryNextTime = _vm->getTotalPlayTime() + 1000;
|
||||
|
||||
// Start handle movie
|
||||
MystAreaVideo *movie = static_cast<MystAreaVideo *>(handle->getSubResource(0));
|
||||
movie->playMovie();
|
||||
|
||||
soundId = handle->getList2(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId, true);
|
||||
}
|
||||
|
||||
void Stoneship::o_generatorStop(uint16 var, const ArgumentsArray &args) {
|
||||
_batteryCharging = false;
|
||||
|
||||
if (_state.generatorDuration) {
|
||||
// Clip battery power
|
||||
if (_state.generatorDuration > 600000)
|
||||
_state.generatorDuration = 600000;
|
||||
|
||||
// Start depleting power
|
||||
_state.generatorDepletionTime = _vm->getTotalPlayTime() + _state.generatorDuration;
|
||||
_state.generatorPowerAvailable = 1;
|
||||
_batteryDepleting = true;
|
||||
_batteryNextTime = _vm->getTotalPlayTime() + 60000;
|
||||
}
|
||||
|
||||
// Pause handle movie
|
||||
MystAreaDrag *handle = getInvokingResource<MystAreaDrag>();
|
||||
MystAreaVideo *movie = static_cast<MystAreaVideo *>(handle->getSubResource(0));
|
||||
movie->pauseMovie(true);
|
||||
|
||||
uint16 soundId = handle->getList3(0);
|
||||
if (soundId)
|
||||
_vm->_sound->playEffect(soundId);
|
||||
}
|
||||
|
||||
void Stoneship::chargeBattery_run() {
|
||||
uint32 time = _vm->getTotalPlayTime();
|
||||
|
||||
if (time > _batteryNextTime) {
|
||||
_batteryNextTime = time + 1000;
|
||||
_state.generatorDuration += 30000;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 Stoneship::batteryRemainingCharge() {
|
||||
uint32 time = _vm->getTotalPlayTime();
|
||||
|
||||
if (_state.generatorDepletionTime > time) {
|
||||
return (_state.generatorDepletionTime - time) / 7500;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::batteryDeplete_run() {
|
||||
uint32 time = _vm->getTotalPlayTime();
|
||||
|
||||
if (time > _batteryNextTime) {
|
||||
if (_state.generatorDuration > 60000) {
|
||||
_state.generatorDuration -= 60000;
|
||||
_batteryNextTime = time + 60000;
|
||||
} else { // Battery depleted
|
||||
_state.generatorDuration = 0;
|
||||
_state.generatorDepletionTime = 0;
|
||||
|
||||
if (_state.sideDoorOpened)
|
||||
_state.generatorPowerAvailable = 2;
|
||||
else
|
||||
_state.generatorPowerAvailable = 0;
|
||||
|
||||
_batteryDepleting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::o_drawerOpenAchenar(uint16 var, const ArgumentsArray &args) {
|
||||
MystAreaImageSwitch *drawer = _vm->getCard()->getResource<MystAreaImageSwitch>(args[0]);
|
||||
drawer->drawConditionalDataToScreen(0, 0);
|
||||
_vm->_gfx->runTransition(kTransitionTopToBottom, drawer->getRect(), 25, 5);
|
||||
}
|
||||
|
||||
void Stoneship::o_hologramPlayback(uint16 var, const ArgumentsArray &args) {
|
||||
// Used for Card 2013 (Achenar's Rose-Skull Hologram)
|
||||
uint16 startPoint = args[0];
|
||||
uint16 endPoint = args[1];
|
||||
// uint16 direction = args[2];
|
||||
|
||||
_hologramDisplay->setBlocking(false);
|
||||
VideoEntryPtr displayMovie = _hologramDisplay->playMovie();
|
||||
|
||||
if (_hologramTurnedOn) {
|
||||
if (_hologramDisplayPos)
|
||||
endPoint = _hologramDisplayPos;
|
||||
displayMovie->setBounds(Audio::Timestamp(0, startPoint, 600), Audio::Timestamp(0, endPoint, 600));
|
||||
} else {
|
||||
displayMovie->setBounds(Audio::Timestamp(0, startPoint, 600), Audio::Timestamp(0, endPoint, 600));
|
||||
}
|
||||
|
||||
_vm->waitUntilMovieEnds(displayMovie);
|
||||
}
|
||||
|
||||
void Stoneship::o_hologramSelectionStart(uint16 var, const ArgumentsArray &args) {
|
||||
//_vm->_cursor->setCursor(0);
|
||||
}
|
||||
|
||||
void Stoneship::o_hologramSelectionMove(uint16 var, const ArgumentsArray &args) {
|
||||
MystAreaDrag *handle = getInvokingResource<MystAreaDrag>();
|
||||
const Common::Point &mouse = _vm->_system->getEventManager()->getMousePos();
|
||||
|
||||
if (handle->getRect().contains(mouse)) {
|
||||
int16 position = mouse.x - 143;
|
||||
position = CLIP<int16>(position, 0, 242);
|
||||
|
||||
// Draw handle movie frame
|
||||
uint16 selectionPos = position * 1500 / 243;
|
||||
|
||||
VideoEntryPtr handleMovie = _hologramSelection->playMovie();
|
||||
_vm->_video->drawVideoFrame(handleMovie, Audio::Timestamp(0, selectionPos, 600));
|
||||
|
||||
_hologramDisplayPos = position * 1450 / 243 + 350;
|
||||
|
||||
// Draw display movie frame
|
||||
if (_hologramTurnedOn) {
|
||||
_hologramDisplay->setBlocking(false);
|
||||
VideoEntryPtr displayMovie = _hologramDisplay->playMovie();
|
||||
_vm->_video->drawVideoFrame(displayMovie, Audio::Timestamp(0, _hologramDisplayPos, 600));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::o_hologramSelectionStop(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->refreshCursor();
|
||||
}
|
||||
|
||||
void Stoneship::o_compassButton(uint16 var, const ArgumentsArray &args) {
|
||||
// Used on Card 2111 (Compass Rose)
|
||||
// Called when Button Clicked.
|
||||
uint16 correctButton = args[0];
|
||||
|
||||
if (correctButton) {
|
||||
// Correct Button -> Light On Logic
|
||||
_state.lightState = 1;
|
||||
} else {
|
||||
// Wrong Button -> Power Failure Logic
|
||||
_state.generatorPowerAvailable = 2;
|
||||
_state.lightState = 0;
|
||||
_state.generatorDepletionTime = 0;
|
||||
_state.generatorDuration = 0;
|
||||
|
||||
_batteryDepleting = false;
|
||||
}
|
||||
|
||||
o_redrawCard(var, args);
|
||||
}
|
||||
|
||||
void Stoneship::o_chestValveVideos(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_sound->playEffect(2132);
|
||||
|
||||
if (_state.chestValveState) {
|
||||
// Valve closing
|
||||
VideoEntryPtr valve = _vm->playMovie("ligspig", kStoneshipStack);
|
||||
valve->moveTo(97, 267);
|
||||
valve->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 350, 600));
|
||||
|
||||
_vm->waitUntilMovieEnds(valve);
|
||||
} else if (_state.chestWaterState) {
|
||||
// Valve opening, spilling water
|
||||
VideoEntryPtr valve = _vm->playMovie("ligspig", kStoneshipStack);
|
||||
valve->moveTo(97, 267);
|
||||
valve->setBounds(Audio::Timestamp(0, 350, 600), Audio::Timestamp(0, 650, 600));
|
||||
|
||||
_vm->waitUntilMovieEnds(valve);
|
||||
|
||||
_vm->_sound->playEffect(3132);
|
||||
|
||||
for (uint i = 0; i < 25; i++) {
|
||||
valve = _vm->playMovie("ligspig", kStoneshipStack);
|
||||
valve->moveTo(97, 267);
|
||||
valve->setBounds(Audio::Timestamp(0, 650, 600), Audio::Timestamp(0, 750, 600));
|
||||
_vm->waitUntilMovieEnds(valve);
|
||||
}
|
||||
|
||||
_vm->_sound->resumeBackground();
|
||||
} else {
|
||||
// Valve opening
|
||||
VideoEntryPtr valve = _vm->playMovie("ligspig", kStoneshipStack);
|
||||
valve->moveTo(97, 267);
|
||||
valve->seek(Audio::Timestamp(0, 350, 600));
|
||||
valve->setRate(-1);
|
||||
|
||||
_vm->waitUntilMovieEnds(valve);
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::o_chestDropKey(uint16 var, const ArgumentsArray &args) {
|
||||
// If holding Key to Lamp Room Trapdoor, drop to bottom of
|
||||
// Lighthouse...
|
||||
if (_state.trapdoorKeyState == 1) {
|
||||
_vm->setMainCursor(_savedCursorId);
|
||||
_state.trapdoorKeyState = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::o_trapLockOpen(uint16 var, const ArgumentsArray &args) {
|
||||
VideoEntryPtr lock = _vm->playMovie("openloc", kStoneshipStack);
|
||||
lock->moveTo(187, 71);
|
||||
lock->setBounds(Audio::Timestamp(0, 0, 600), Audio::Timestamp(0, 750, 600));
|
||||
_vm->waitUntilMovieEnds(lock);
|
||||
|
||||
_vm->_sound->playEffect(2143);
|
||||
|
||||
lock = _vm->playMovie("openloc", kStoneshipStack);
|
||||
lock->moveTo(187, 71);
|
||||
lock->setBounds(Audio::Timestamp(0, 750, 600), Audio::Timestamp(0, 10000, 600));
|
||||
_vm->waitUntilMovieEnds(lock);
|
||||
|
||||
if (_state.pumpState != 4)
|
||||
_vm->_sound->playEffect(4143);
|
||||
}
|
||||
|
||||
void Stoneship::o_sideDoorsMovies(uint16 var, const ArgumentsArray &args) {
|
||||
// Used for Cards 2285, 2289, 2247, 2251 (Side Doors in Tunnels Down To Brothers Rooms)
|
||||
uint16 movieId = args[0];
|
||||
|
||||
_vm->_cursor->hideCursor();
|
||||
_vm->_sound->pauseBackground();
|
||||
|
||||
switch (movieId) {
|
||||
case 0:
|
||||
// Card 2251
|
||||
_vm->playMovieBlocking("tunaup", kStoneshipStack, 149, 161);
|
||||
break;
|
||||
case 1:
|
||||
// Card 2247
|
||||
_vm->playMovieBlocking("tunadown", kStoneshipStack, 218, 150);
|
||||
break;
|
||||
case 2:
|
||||
// Card 2289
|
||||
_vm->playMovieBlocking("tuncup", kStoneshipStack, 259, 161);
|
||||
break;
|
||||
case 3:
|
||||
// Card 2285
|
||||
_vm->playMovieBlocking("tuncdown", kStoneshipStack, 166, 150);
|
||||
break;
|
||||
default:
|
||||
warning("Opcode 120 MovieId Out Of Range");
|
||||
break;
|
||||
}
|
||||
|
||||
_vm->_sound->resumeBackground();
|
||||
_vm->_cursor->showCursor();
|
||||
}
|
||||
|
||||
void Stoneship::o_cloudOrbEnter(uint16 var, const ArgumentsArray &args) {
|
||||
_vm->_sound->playEffect(_cloudOrbSound, true);
|
||||
_cloudOrbMovie->playMovie();
|
||||
}
|
||||
|
||||
void Stoneship::o_cloudOrbLeave(uint16 var, const ArgumentsArray &args) {
|
||||
_cloudOrbMovie->pauseMovie(true);
|
||||
_vm->_sound->playEffect(_cloudOrbStopSound);
|
||||
_vm->_gfx->runTransition(kTransitionTopToBottom, getInvokingResource<MystArea>()->getRect(), 4, 0);
|
||||
}
|
||||
|
||||
void Stoneship::o_drawerCloseOpened(uint16 var, const ArgumentsArray &args) {
|
||||
uint16 drawerOpen = getVar(var);
|
||||
if (drawerOpen)
|
||||
drawerClose(args[0] + drawerOpen - 1);
|
||||
}
|
||||
|
||||
void Stoneship::drawerClose(uint16 drawer) {
|
||||
_chestDrawersOpen = 0;
|
||||
_vm->getCard()->drawBackground();
|
||||
_vm->getCard()->drawResourceImages();
|
||||
|
||||
MystArea *res = _vm->getCard()->getResource<MystArea>(drawer);
|
||||
_vm->_gfx->runTransition(kTransitionBottomToTop, res->getRect(), 25, 5);
|
||||
}
|
||||
|
||||
void Stoneship::o_hologramDisplay_init(uint16 var, const ArgumentsArray &args) {
|
||||
_hologramDisplay = getInvokingResource<MystAreaVideo>();
|
||||
|
||||
_hologramDisplayPos = 0;
|
||||
}
|
||||
|
||||
void Stoneship::o_hologramSelection_init(uint16 var, const ArgumentsArray &args) {
|
||||
_hologramSelection = getInvokingResource<MystAreaVideo>();
|
||||
}
|
||||
|
||||
void Stoneship::batteryGaugeUpdate() {
|
||||
uint16 charge = 0;
|
||||
|
||||
if (_state.generatorDepletionTime) {
|
||||
charge = batteryRemainingCharge();
|
||||
}
|
||||
|
||||
Common::Rect rect = _batteryGauge->getRect();
|
||||
|
||||
rect.top = rect.bottom - charge;
|
||||
|
||||
_batteryGauge->setRect(rect);
|
||||
}
|
||||
|
||||
void Stoneship::o_battery_init(uint16 var, const ArgumentsArray &args) {
|
||||
// Used for Card 2160 (Lighthouse Battery Pack Closeup)
|
||||
_batteryGauge = getInvokingResource<MystAreaImageSwitch>();
|
||||
|
||||
batteryGaugeUpdate();
|
||||
}
|
||||
|
||||
void Stoneship::o_tunnelEnter_init(uint16 var, const ArgumentsArray &args) {
|
||||
o_tunnel_init(var, args);
|
||||
|
||||
_tunnelRunning = true;
|
||||
_tunnelNextTime = _vm->getTotalPlayTime() + 1500;
|
||||
}
|
||||
|
||||
void Stoneship::o_batteryGauge_init(uint16 var, const ArgumentsArray &args) {
|
||||
_batteryLastCharge = batteryRemainingCharge();
|
||||
_batteryGaugeRunning = true;
|
||||
}
|
||||
|
||||
void Stoneship::batteryGauge_run() {
|
||||
uint16 batteryCharge = batteryRemainingCharge();
|
||||
|
||||
if (batteryCharge != _batteryLastCharge) {
|
||||
batteryGaugeUpdate();
|
||||
|
||||
_batteryLastCharge = batteryCharge;
|
||||
|
||||
// Redraw card
|
||||
_vm->getCard()->drawBackground();
|
||||
_vm->getCard()->drawResourceImages();
|
||||
_vm->_gfx->copyBackBufferToScreen(Common::Rect(544, 333));
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::o_tunnel_init(uint16 var, const ArgumentsArray &args) {
|
||||
_tunnelImagesCount = args[0];
|
||||
|
||||
assert(_tunnelImagesCount <= 2 && "Too many images");
|
||||
|
||||
for (uint i = 0; i < _tunnelImagesCount; i++) {
|
||||
_tunnelImages[i] = args[i + 1];
|
||||
}
|
||||
|
||||
_tunnelAlarmSound = args[args.size() - 1];
|
||||
|
||||
debugC(kDebugScript, "\timage count: %d", _tunnelImagesCount);
|
||||
debugC(kDebugScript, "\tsoundIdAlarm: %d", _tunnelAlarmSound);
|
||||
}
|
||||
|
||||
void Stoneship::tunnel_run() {
|
||||
uint32 time = _vm->getTotalPlayTime();
|
||||
|
||||
if (time > _tunnelNextTime) {
|
||||
_tunnelNextTime = time + 1500;
|
||||
if (_state.generatorPowerAvailable == 2) {
|
||||
// Draw tunnel black
|
||||
if (_tunnelImagesCount) {
|
||||
_vm->_gfx->copyImageToScreen(_tunnelImages[1], Common::Rect(544, 333));
|
||||
}
|
||||
|
||||
_vm->_sound->playEffect(_tunnelAlarmSound);
|
||||
|
||||
// Draw tunnel dark
|
||||
if (_tunnelImagesCount) {
|
||||
_vm->_gfx->copyImageToScreen(_tunnelImages[0], Common::Rect(544, 333));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::o_tunnelLeave_init(uint16 var, const ArgumentsArray &args) {
|
||||
_tunnelRunning = false;
|
||||
}
|
||||
|
||||
void Stoneship::o_chest_init(uint16 var, const ArgumentsArray &args) {
|
||||
_state.chestOpenState = 0;
|
||||
}
|
||||
|
||||
void Stoneship::o_telescope_init(uint16 var, const ArgumentsArray &args) {
|
||||
// Used in Card 2218 (Telescope view)
|
||||
_telescopePanorama = args[0];
|
||||
_telescopeLighthouseOff = args[1];
|
||||
_telescopeLighthouseOn = args[2];
|
||||
_telescopePosition = 0;
|
||||
|
||||
_telescopeRunning = true;
|
||||
_telescopeLighthouseState = false;
|
||||
_telescopeNexTime = _vm->getTotalPlayTime() + 1000;
|
||||
}
|
||||
|
||||
void Stoneship::telescope_run() {
|
||||
uint32 time = _vm->getTotalPlayTime();
|
||||
|
||||
if (time > _telescopeNexTime) {
|
||||
|
||||
_telescopeNexTime = time + 1000;
|
||||
_telescopeLighthouseState = !_telescopeLighthouseState;
|
||||
|
||||
telescopeLighthouseDraw();
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::telescopeLighthouseDraw() {
|
||||
if (_telescopePosition > 1137 && _telescopePosition < 1294) {
|
||||
uint16 imageId = _telescopeLighthouseOff;
|
||||
|
||||
if (_state.generatorPowerAvailable == 1 && _telescopeLighthouseState)
|
||||
imageId = _telescopeLighthouseOn;
|
||||
|
||||
Common::Rect src(1205, 0, 1205 + 131, 112);
|
||||
src.clip(Common::Rect(_telescopePosition, 0, _telescopePosition + 112, 112));
|
||||
src.translate(-1205, 0);
|
||||
src.clip(131, 112);
|
||||
|
||||
Common::Rect dest(_telescopePosition, 0, _telescopePosition + 112, 112);
|
||||
dest.clip(Common::Rect(1205, 0, 1205 + 131, 112));
|
||||
dest.translate(-_telescopePosition, 0);
|
||||
dest.clip(112, 112);
|
||||
dest.translate(222, 112);
|
||||
|
||||
_vm->_gfx->copyImageSectionToScreen(imageId, src, dest);
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::o_achenarDrawers_init(uint16 var, const ArgumentsArray &args) {
|
||||
// Used for Card 2004 (Achenar's Room Drawers)
|
||||
if (!_chestAchenarBottomDrawerClosed) {
|
||||
uint16 count1 = args[0];
|
||||
for (uint16 i = 0; i < count1; i++) {
|
||||
debugC(kDebugScript, "Disable hotspot index %d", args[i + 1]);
|
||||
_vm->getCard()->setResourceEnabled(args[i + 1], false);
|
||||
}
|
||||
uint16 count2 = args[count1 + 1];
|
||||
for (uint16 i = 0; i < count2; i++) {
|
||||
debugC(kDebugScript, "Enable hotspot index %d", args[i + count1 + 2]);
|
||||
_vm->getCard()->setResourceEnabled(args[i + count1 + 2], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Stoneship::o_cloudOrb_init(uint16 var, const ArgumentsArray &args) {
|
||||
_cloudOrbMovie = getInvokingResource<MystAreaVideo>();
|
||||
_cloudOrbSound = args[0];
|
||||
_cloudOrbStopSound = args[1];
|
||||
}
|
||||
|
||||
} // End of namespace MystStacks
|
||||
} // End of namespace Mohawk
|
||||
149
engines/mohawk/myst_stacks/stoneship.h
Normal file
149
engines/mohawk/myst_stacks/stoneship.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/* 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 MYST_SCRIPTS_STONESHIP_H
|
||||
#define MYST_SCRIPTS_STONESHIP_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/util.h"
|
||||
#include "mohawk/myst_scripts.h"
|
||||
|
||||
namespace Mohawk {
|
||||
|
||||
struct MystScriptEntry;
|
||||
|
||||
namespace MystStacks {
|
||||
|
||||
#define DECLARE_OPCODE(x) void x(uint16 var, const ArgumentsArray &args)
|
||||
|
||||
class Stoneship : public MystScriptParser {
|
||||
public:
|
||||
explicit Stoneship(MohawkEngine_Myst *vm);
|
||||
~Stoneship() override;
|
||||
|
||||
void disablePersistentScripts() override;
|
||||
void runPersistentScripts() override;
|
||||
|
||||
private:
|
||||
void setupOpcodes();
|
||||
uint16 getVar(uint16 var) override;
|
||||
void toggleVar(uint16 var) override;
|
||||
bool setVarValue(uint16 var, uint16 value) override;
|
||||
|
||||
uint16 getMap() override { return 9933; }
|
||||
|
||||
DECLARE_OPCODE(o_pumpTurnOff);
|
||||
DECLARE_OPCODE(o_brotherDoorOpen);
|
||||
DECLARE_OPCODE(o_cabinBookMovie);
|
||||
DECLARE_OPCODE(o_drawerOpenSirius);
|
||||
DECLARE_OPCODE(o_drawerClose);
|
||||
DECLARE_OPCODE(o_telescopeStart);
|
||||
DECLARE_OPCODE(o_telescopeMove);
|
||||
DECLARE_OPCODE(o_telescopeStop);
|
||||
DECLARE_OPCODE(o_generatorStart);
|
||||
DECLARE_OPCODE(o_generatorStop);
|
||||
DECLARE_OPCODE(o_drawerOpenAchenar);
|
||||
DECLARE_OPCODE(o_hologramPlayback);
|
||||
DECLARE_OPCODE(o_hologramSelectionStart);
|
||||
DECLARE_OPCODE(o_hologramSelectionMove);
|
||||
DECLARE_OPCODE(o_hologramSelectionStop);
|
||||
DECLARE_OPCODE(o_compassButton);
|
||||
DECLARE_OPCODE(o_chestValveVideos);
|
||||
DECLARE_OPCODE(o_chestDropKey);
|
||||
DECLARE_OPCODE(o_trapLockOpen);
|
||||
DECLARE_OPCODE(o_sideDoorsMovies);
|
||||
DECLARE_OPCODE(o_cloudOrbEnter);
|
||||
DECLARE_OPCODE(o_cloudOrbLeave);
|
||||
DECLARE_OPCODE(o_drawerCloseOpened);
|
||||
|
||||
DECLARE_OPCODE(o_hologramDisplay_init);
|
||||
DECLARE_OPCODE(o_hologramSelection_init);
|
||||
DECLARE_OPCODE(o_battery_init);
|
||||
DECLARE_OPCODE(o_tunnelEnter_init);
|
||||
DECLARE_OPCODE(o_batteryGauge_init);
|
||||
DECLARE_OPCODE(o_tunnel_init);
|
||||
DECLARE_OPCODE(o_tunnelLeave_init);
|
||||
DECLARE_OPCODE(o_chest_init);
|
||||
DECLARE_OPCODE(o_telescope_init);
|
||||
DECLARE_OPCODE(o_achenarDrawers_init);
|
||||
DECLARE_OPCODE(o_cloudOrb_init);
|
||||
|
||||
void chargeBattery_run();
|
||||
void batteryDeplete_run();
|
||||
|
||||
MystGameState::Stoneship &_state;
|
||||
|
||||
bool _batteryCharging;
|
||||
bool _batteryDepleting;
|
||||
uint32 _batteryNextTime;
|
||||
|
||||
bool _batteryGaugeRunning;
|
||||
uint16 _batteryLastCharge; // 92
|
||||
MystAreaImageSwitch *_batteryGauge; // 96
|
||||
void batteryGaugeUpdate();
|
||||
void batteryGauge_run();
|
||||
|
||||
uint16 _cabinMystBookPresent; // 64
|
||||
|
||||
uint16 _siriusDrawerDrugsOpen; // 72
|
||||
|
||||
uint16 _brotherDoorOpen; // 76
|
||||
|
||||
uint16 _chestDrawersOpen; // 78
|
||||
uint16 _chestAchenarBottomDrawerClosed; // 144
|
||||
void drawerClose(uint16 drawer);
|
||||
|
||||
uint16 _hologramTurnedOn; // 80
|
||||
MystAreaVideo *_hologramDisplay; // 84
|
||||
MystAreaVideo *_hologramSelection; // 88
|
||||
uint16 _hologramDisplayPos;
|
||||
|
||||
bool _tunnelRunning;
|
||||
uint32 _tunnelNextTime;
|
||||
uint16 _tunnelAlarmSound; // 100
|
||||
uint16 _tunnelImagesCount; // 22
|
||||
uint16 _tunnelImages[2]; // 32
|
||||
void tunnel_run();
|
||||
|
||||
uint16 _telescopePosition; // 112
|
||||
uint16 _telescopePanorama;
|
||||
uint16 _telescopeOldMouse;
|
||||
uint16 _telescopeLighthouseOff; // 130
|
||||
uint16 _telescopeLighthouseOn; // 128
|
||||
bool _telescopeLighthouseState; // 124
|
||||
bool _telescopeRunning;
|
||||
uint32 _telescopeNexTime;
|
||||
void telescope_run();
|
||||
void telescopeLighthouseDraw();
|
||||
|
||||
MystAreaVideo *_cloudOrbMovie; // 136
|
||||
uint16 _cloudOrbSound; // 140
|
||||
uint16 _cloudOrbStopSound; // 142
|
||||
|
||||
uint16 batteryRemainingCharge();
|
||||
};
|
||||
|
||||
} // End of namespace MystStacks
|
||||
}
|
||||
|
||||
#undef DECLARE_OPCODE
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user