diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/kernel.h | 6 | ||||
-rw-r--r-- | engines/sci/engine/kevent.cpp | 15 | ||||
-rw-r--r-- | engines/sci/engine/kgraphics.cpp | 7 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 3 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 42 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 2 |
6 files changed, 51 insertions, 24 deletions
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 83b43542d4..6a275a9adb 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -402,12 +402,6 @@ List *lookup_list(EngineState *s, reg_t addr); #define _K_SOUND_STATUS_PLAYING 3 - -/* Kernel optimization flags */ -#define KERNEL_OPT_FLAG_GOT_EVENT (1<<0) -#define KERNEL_OPT_FLAG_GOT_2NDEVENT (1<<1) - - /******************** Kernel functions ********************/ // New kernel functions diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index c4b3f5d71a..5ac09e6c76 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -42,12 +42,6 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { int oldx, oldy; int modifier_mask = s->_version <= SCI_VERSION_0 ? SCI_EVM_ALL : SCI_EVM_NO_FOOLOCK; - if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_2NDEVENT) { - // Penalty time- too many requests to this function without waiting! - int delay = s->script_000->locals_block->_locals[SCI_VARIABLE_GAME_SPEED].offset; - gfxop_sleep(s->gfx_state, delay * 1000 / 60); - } - // If there's a simkey pending, and the game wants a keyboard event, use the // simkey instead of a normal event if (g_debug_simulated_key && (mask & SCI_EVT_KEYBOARD)) { @@ -71,15 +65,6 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { //gfxop_set_pointer_position(s->gfx_state, Common::Point(s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y)); - if (e.type) - s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT); - else { - if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_EVENT) - s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_2NDEVENT; - else - s->kernel_opt_flags |= KERNEL_OPT_FLAG_GOT_EVENT; - } - switch (e.type) { case SCI_EVT_QUIT: quit_vm(); diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index c7086ddef7..915b07e8a3 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -664,12 +664,13 @@ reg_t kWait(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->r_acc = make_reg(0, ((long)time - (long)s->last_wait_time) * 60 / 1000); s->last_wait_time = time; - // Reset optimization flags: Game is playing along nicely anyway - s->kernel_opt_flags &= ~(KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT); - sleep_time *= g_debug_sleeptime_factor; GFX_ASSERT(gfxop_sleep(s->gfx_state, sleep_time * 1000 / 60)); + // Reset speed throttler: Game is playing along nicely anyway + if (sleep_time > 0) + s->speedThrottler->reset(); + return s->r_acc; } diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 405c9ec66f..f0e9863068 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -114,9 +114,12 @@ EngineState::EngineState(ResourceManager *res, sci_version_t version, uint32 fla gc_countdown = 0; successor = 0; + + speedThrottler = new SpeedThrottler(version); } EngineState::~EngineState() { + delete speedThrottler; } uint16 EngineState::currentRoomNumber() const { diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 3db926ab3d..a814a20df8 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -119,6 +119,46 @@ public: bool isOpen() const; }; + +class SpeedThrottler { +public: + enum { + kSegmentLength = 20 /**< Time segment length in ms */ + }; + + SpeedThrottler(sci_version_t version) { + if (version >= SCI_VERSION_1_1) + _maxInstructions = 3300; + else if (version >= SCI_VERSION_1) + _maxInstructions = 2200; + else + _maxInstructions = 1100; + reset(); + } + + void postInstruction() { + if (++_curInstructions >= _maxInstructions) { + uint32 time = g_system->getMillis(); + uint32 elapsed = time - _timestamp; + + if (elapsed < kSegmentLength) + g_system->delayMillis(kSegmentLength - elapsed); + + reset(); + } + } + + void reset() { + _timestamp = g_system->getMillis(); + _curInstructions = 0; + } + +private: + uint32 _timestamp; /**< Timestamp of current time segment */ + uint32 _maxInstructions; /**< Maximum amount of instructions per time segment */ + uint32 _curInstructions; /**< Amount of instructions executed in current time segment */ +}; + struct EngineState : public Common::Serializable { public: EngineState(ResourceManager *res, sci_version_t version, uint32 flags); @@ -258,6 +298,8 @@ public: MessageState _msgState; + SpeedThrottler *speedThrottler; + EngineState *successor; /**< Successor of this state: Used for restoring */ private: diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 02c287a99a..ae07c314d4 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -1424,6 +1424,8 @@ void run_vm(EngineState *s, int restoring) { } //#endif ++script_step_counter; + + s->speedThrottler->postInstruction(); } } |