aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/kernel.h6
-rw-r--r--engines/sci/engine/kevent.cpp15
-rw-r--r--engines/sci/engine/kgraphics.cpp7
-rw-r--r--engines/sci/engine/state.cpp3
-rw-r--r--engines/sci/engine/state.h42
-rw-r--r--engines/sci/engine/vm.cpp2
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();
}
}