Skip to content

Commit

Permalink
MOHAWK: Switch timers to script commands
Browse files Browse the repository at this point in the history
  • Loading branch information
bgK authored and sev- committed Jul 3, 2017
1 parent ee70244 commit ea303ab
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 62 deletions.
26 changes: 1 addition & 25 deletions engines/mohawk/riven.cpp
Expand Up @@ -72,8 +72,6 @@ MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescriptio

DebugMan.addDebugChannel(kRivenDebugScript, "Script", "Track Script Execution");

removeTimer();

// NOTE: We can never really support CD swapping. All of the music files
// (*_Sounds.mhk) are stored on disc 1. They are copied to the hard drive
// during install and used from there. The same goes for the extras.mhk
Expand Down Expand Up @@ -195,7 +193,6 @@ Common::Error MohawkEngine_Riven::run() {

void MohawkEngine_Riven::doFrame() {
// Update background running things
checkTimer();
_sound->updateSLST();
_video->updateMovies();

Expand Down Expand Up @@ -425,7 +422,7 @@ void MohawkEngine_Riven::changeToCard(uint16 dest) {

void MohawkEngine_Riven::refreshCard() {
// Clear any timer still floating around
removeTimer();
_stack->removeTimer();

_card->enter(true);

Expand Down Expand Up @@ -471,27 +468,6 @@ Common::Error MohawkEngine_Riven::saveGameState(int slot, const Common::String &
return _saveLoad->saveGame(slot, desc);
}

void MohawkEngine_Riven::installTimer(TimerProc *proc, uint32 time) {
removeTimer();
_timerProc = Common::SharedPtr<TimerProc>(proc);
_timerTime = time + getTotalPlayTime();
}

void MohawkEngine_Riven::checkTimer() {
if (!_timerProc)
return;

// NOTE: If the specified timer function is called, it is its job to remove the timer!
if (getTotalPlayTime() >= _timerTime) {
(*_timerProc)();
}
}

void MohawkEngine_Riven::removeTimer() {
_timerProc.reset();
_timerTime = 0;
}

void MohawkEngine_Riven::addZipVisitedCard(uint16 cardId, uint16 cardNameId) {
Common::String cardName = getStack()->getName(kCardNames, cardNameId);
if (cardName.empty())
Expand Down
14 changes: 0 additions & 14 deletions engines/mohawk/riven.h
Expand Up @@ -99,11 +99,6 @@ class MohawkEngine_Riven : public MohawkEngine {
Common::Error saveGameState(int slot, const Common::String &desc);
bool hasFeature(EngineFeature f) const;

typedef Common::Functor0<void> TimerProc;

#define TIMER(cls, method) \
new Common::Functor0Mem<void, cls>(this, &cls::method)

void doFrame();

private:
Expand All @@ -123,10 +118,6 @@ class MohawkEngine_Riven : public MohawkEngine {
// Variables
void initVars();

// Timer
Common::SharedPtr<TimerProc> _timerProc;
uint32 _timerTime;

void pauseEngineIntern(bool) override;
public:
// Stack/card/script funtions
Expand All @@ -153,11 +144,6 @@ class MohawkEngine_Riven : public MohawkEngine {
bool _activatedSLST;
void runLoadDialog();
void delay(uint32 ms);

// Timer
void installTimer(TimerProc *proc, uint32 time);
void checkTimer();
void removeTimer();
};

} // End of namespace Mohawk
Expand Down
15 changes: 15 additions & 0 deletions engines/mohawk/riven_scripts.cpp
Expand Up @@ -817,4 +817,19 @@ void RivenStackChangeCommand::dump(byte tabs) {
debugN("changeStack(%d, %d);\n", _stackId, _cardId);
}

RivenTimerCommand::RivenTimerCommand(MohawkEngine_Riven *vm, const Common::SharedPtr<RivenStack::TimerProc> &timerProc) :
RivenCommand(vm),
_timerProc(timerProc) {

}

void RivenTimerCommand::execute() {
(*_timerProc)();
}

void RivenTimerCommand::dump(byte tabs) {
printTabs(tabs);
debugN("doTimer();\n");
}

} // End of namespace Mohawk
15 changes: 15 additions & 0 deletions engines/mohawk/riven_scripts.h
Expand Up @@ -23,6 +23,8 @@
#ifndef RIVEN_SCRIPTS_H
#define RIVEN_SCRIPTS_H

#include "mohawk/riven_stack.h"

#include "common/str-array.h"
#include "common/ptr.h"
#include "common/textconsole.h"
Expand Down Expand Up @@ -91,6 +93,7 @@ enum RivenCommandType {
class MohawkEngine_Riven;
class RivenCommand;
class RivenScript;
class RivenScriptManager;
struct MLSTRecord;

typedef Common::SharedPtr<RivenScript> RivenScriptPtr;
Expand Down Expand Up @@ -362,6 +365,18 @@ class RivenStackChangeCommand : public RivenCommand {
bool _byStackId; // Otherwise by stack name id
};

class RivenTimerCommand : public RivenCommand {
public:
RivenTimerCommand(MohawkEngine_Riven *vm, const Common::SharedPtr<RivenStack::TimerProc> &timerProc);

// RivenCommand API
virtual void dump(byte tabs) override;
virtual void execute() override;

private:
Common::SharedPtr<RivenStack::TimerProc> _timerProc;
};

} // End of namespace Mohawk

#undef DECLARE_OPCODE
Expand Down
31 changes: 31 additions & 0 deletions engines/mohawk/riven_stack.cpp
Expand Up @@ -40,6 +40,8 @@ RivenStack::RivenStack(MohawkEngine_Riven *vm, uint16 id) :
_id(id),
_mouseIsDown(false),
_keyPressed(Common::KEYCODE_INVALID) {
removeTimer();

loadResourceNames();
loadCardIdMap();
setCurrentStackVariable();
Expand Down Expand Up @@ -282,6 +284,8 @@ void RivenStack::onFrame() {
return;
}

checkTimer();

_vm->_gfx->updateEffects();

RivenScriptPtr script(new RivenScript());
Expand Down Expand Up @@ -315,6 +319,33 @@ Common::Point RivenStack::getMouseDragStartPosition() const {
return _mouseDragStartPosition;
}

void RivenStack::installTimer(TimerProc *proc, uint32 time) {
removeTimer();
_timerProc = Common::SharedPtr<TimerProc>(proc);
_timerTime = time + _vm->getTotalPlayTime();
}

void RivenStack::checkTimer() {
if (!_timerProc) {
return;
}

// NOTE: If the specified timer function is called, it is its job to remove the timer!

// Timers are queued as script commands so that they don't run when the doFrame method
// is called from an inner game loop.
if (_vm->getTotalPlayTime() >= _timerTime) {
RivenScriptPtr script = _vm->_scriptMan->createScriptWithCommand(
new RivenTimerCommand(_vm, _timerProc));
_vm->_scriptMan->runScript(script, true);
}
}

void RivenStack::removeTimer() {
_timerProc.reset();
_timerTime = 0;
}

RivenNameList::RivenNameList() {

}
Expand Down
16 changes: 16 additions & 0 deletions engines/mohawk/riven_stack.h
Expand Up @@ -81,6 +81,8 @@ class RivenStack {
RivenStack(MohawkEngine_Riven *vm, uint16 id);
virtual ~RivenStack();

typedef Common::Functor0<void> TimerProc;

/** Get the id of the stack */
uint16 getId() const;

Expand Down Expand Up @@ -112,6 +114,9 @@ class RivenStack {
/** Install a timer for the current card if one is defined */
virtual void installCardTimer();

/** Clear any currently installed timer */
void removeTimer();

/** Handle a mouse down event */
void onMouseDown(const Common::Point &mouse);

Expand Down Expand Up @@ -162,6 +167,9 @@ class RivenStack {
/** Register an external command for use by the scripts */
void registerCommand(const Common::String &name, ExternalCommand *command);

/** Register a proc for planned execution */
void installTimer(TimerProc *proc, uint32 time);

private:
typedef Common::HashMap<Common::String, Common::SharedPtr<ExternalCommand>, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CommandsMap;

Expand All @@ -170,9 +178,13 @@ class RivenStack {
#method, new Common::Functor2Mem<uint16, uint16 *, void, cls>(this, &cls::method) \
)

#define TIMER(cls, method) \
new Common::Functor0Mem<void, cls>(this, &cls::method)

void loadResourceNames();
void loadCardIdMap();
void setCurrentStackVariable();
void checkTimer();

uint16 _id;

Expand All @@ -192,6 +204,10 @@ class RivenStack {
bool _mouseIsDown;
Common::Point _mousePosition;
Common::Point _mouseDragStartPosition;

// Timer
Common::SharedPtr<TimerProc> _timerProc;
uint32 _timerTime;
};

namespace RivenStacks {
Expand Down
6 changes: 3 additions & 3 deletions engines/mohawk/riven_stacks/bspit.cpp
Expand Up @@ -282,7 +282,7 @@ void BSpit::xbupdateboiler(uint16 argc, uint16 *argv) {

void BSpit::ytramTrapTimer() {
// Remove this timer
_vm->removeTimer();
removeTimer();

// Check if we've caught a Ytram
checkYtramCatch(true);
Expand All @@ -296,7 +296,7 @@ void BSpit::xbsettrap(uint16 argc, uint16 *argv) {
_vm->_vars["bytramtime"] = timeUntilCatch + _vm->getTotalPlayTime();

// And set the timer too
_vm->installTimer(TIMER(BSpit, ytramTrapTimer), timeUntilCatch);
installTimer(TIMER(BSpit, ytramTrapTimer), timeUntilCatch);
}

void BSpit::checkYtramCatch(bool playSound) {
Expand All @@ -307,7 +307,7 @@ void BSpit::checkYtramCatch(bool playSound) {
// If the trap still has not gone off, reinstall our timer
// This is in case you set the trap, walked away, and returned
if (_vm->getTotalPlayTime() < ytramTime) {
_vm->installTimer(TIMER(BSpit, ytramTrapTimer), ytramTime - _vm->getTotalPlayTime());
installTimer(TIMER(BSpit, ytramTrapTimer), ytramTime - _vm->getTotalPlayTime());
return;
}

Expand Down
6 changes: 3 additions & 3 deletions engines/mohawk/riven_stacks/gspit.cpp
Expand Up @@ -425,7 +425,7 @@ void GSpit::catherineViewerIdleTimer() {
video->play();

// Reset the timer
_vm->installTimer(TIMER(GSpit, catherineViewerIdleTimer), video->getDuration() + _vm->_rnd->getRandomNumber(60) * 1000);
installTimer(TIMER(GSpit, catherineViewerIdleTimer), video->getDuration() + _vm->_rnd->getRandomNumber(60) * 1000);
}

void GSpit::xglview_prisonon(uint16 argc, uint16 *argv) {
Expand Down Expand Up @@ -473,7 +473,7 @@ void GSpit::xglview_prisonon(uint16 argc, uint16 *argv) {
}

// Create the timer for the next video
_vm->installTimer(TIMER(GSpit, catherineViewerIdleTimer), timeUntilNextMovie);
installTimer(TIMER(GSpit, catherineViewerIdleTimer), timeUntilNextMovie);
}

void GSpit::xglview_prisonoff(uint16 argc, uint16 *argv) {
Expand All @@ -483,7 +483,7 @@ void GSpit::xglview_prisonoff(uint16 argc, uint16 *argv) {
_vm->_vars["glview"] = 0;

// Remove the timer we set in xglview_prisonon()
_vm->removeTimer();
removeTimer();

// Play the 'turn off' movie after stopping any videos still playing
_vm->_video->closeVideos();
Expand Down
24 changes: 12 additions & 12 deletions engines/mohawk/riven_stacks/jspit.cpp
Expand Up @@ -570,7 +570,7 @@ void JSpit::sunnersPlayVideo(RivenVideo *video, uint32 destCardGlobalId, bool su
void JSpit::sunnersTopStairsTimer() {
// If the sunners are gone, we have no video to play
if (_vm->_vars["jsunners"] != 0) {
_vm->removeTimer();
removeTimer();
return;
}

Expand All @@ -595,13 +595,13 @@ void JSpit::sunnersTopStairsTimer() {
sunnerTime = timerTime + _vm->getTotalPlayTime();
}

_vm->installTimer(TIMER(JSpit, sunnersTopStairsTimer), timerTime);
installTimer(TIMER(JSpit, sunnersTopStairsTimer), timerTime);
}

void JSpit::sunnersMidStairsTimer() {
// If the sunners are gone, we have no video to play
if (_vm->_vars["jsunners"] != 0) {
_vm->removeTimer();
removeTimer();
return;
}

Expand Down Expand Up @@ -634,13 +634,13 @@ void JSpit::sunnersMidStairsTimer() {
sunnerTime = timerTime + _vm->getTotalPlayTime();
}

_vm->installTimer(TIMER(JSpit, sunnersMidStairsTimer), timerTime);
installTimer(TIMER(JSpit, sunnersMidStairsTimer), timerTime);
}

void JSpit::sunnersLowerStairsTimer() {
// If the sunners are gone, we have no video to play
if (_vm->_vars["jsunners"] != 0) {
_vm->removeTimer();
removeTimer();
return;
}

Expand All @@ -665,13 +665,13 @@ void JSpit::sunnersLowerStairsTimer() {
sunnerTime = timerTime + _vm->getTotalPlayTime();
}

_vm->installTimer(TIMER(JSpit, sunnersLowerStairsTimer), timerTime);
installTimer(TIMER(JSpit, sunnersLowerStairsTimer), timerTime);
}

void JSpit::sunnersBeachTimer() {
// If the sunners are gone, we have no video to play
if (_vm->_vars["jsunners"] != 0) {
_vm->removeTimer();
removeTimer();
return;
}

Expand Down Expand Up @@ -700,7 +700,7 @@ void JSpit::sunnersBeachTimer() {
sunnerTime = timerTime + _vm->getTotalPlayTime();
}

_vm->installTimer(TIMER(JSpit, sunnersBeachTimer), timerTime);
installTimer(TIMER(JSpit, sunnersBeachTimer), timerTime);
}

void JSpit::xjschool280_resetleft(uint16 argc, uint16 *argv) {
Expand Down Expand Up @@ -786,16 +786,16 @@ void JSpit::xjatboundary(uint16 argc, uint16 *argv) {
void JSpit::installCardTimer() {
switch (getCurrentCardGlobalId()) {
case 0x77d6: // Sunners, top of stairs
_vm->installTimer(TIMER(JSpit, sunnersTopStairsTimer), 500);
installTimer(TIMER(JSpit, sunnersTopStairsTimer), 500);
break;
case 0x79bd: // Sunners, middle of stairs
_vm->installTimer(TIMER(JSpit, sunnersMidStairsTimer), 500);
installTimer(TIMER(JSpit, sunnersMidStairsTimer), 500);
break;
case 0x7beb: // Sunners, bottom of stairs
_vm->installTimer(TIMER(JSpit, sunnersLowerStairsTimer), 500);
installTimer(TIMER(JSpit, sunnersLowerStairsTimer), 500);
break;
case 0xb6ca: // Sunners, shoreline
_vm->installTimer(TIMER(JSpit, sunnersBeachTimer), 500);
installTimer(TIMER(JSpit, sunnersBeachTimer), 500);
break;
default:
RivenStack::installCardTimer();
Expand Down

0 comments on commit ea303ab

Please sign in to comment.