aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2011-08-08 15:38:27 +0100
committerEugene Sandulenko2011-08-08 20:01:07 +0100
commita4029a8e94a3dbbe03c0aa4571215e9a5b00058d (patch)
treea18d45985ba3d452cfe68fe3a1408b6aa910ff38
parent4144fef5a7404bfab8dd127cc9d09694de89e997 (diff)
downloadscummvm-rg350-a4029a8e94a3dbbe03c0aa4571215e9a5b00058d.tar.gz
scummvm-rg350-a4029a8e94a3dbbe03c0aa4571215e9a5b00058d.tar.bz2
scummvm-rg350-a4029a8e94a3dbbe03c0aa4571215e9a5b00058d.zip
RECORDER: Restore event recorder functionality.
It was badly broken after refactoring into EventObserver. Fitst, deinit() method was never called which lead to bad record files. Then, the concept of counting pollEvent() calls was ignored. Introduced dispatchPoll() method of EventObserver which is implemented in EventRecorder. It counts calls so is able to inject events at more proper time. Additionally now event times are recorded.
-rw-r--r--base/main.cpp4
-rw-r--r--common/EventDispatcher.cpp13
-rw-r--r--common/EventRecorder.cpp67
-rw-r--r--common/EventRecorder.h2
-rw-r--r--common/events.h15
5 files changed, 81 insertions, 20 deletions
diff --git a/base/main.cpp b/base/main.cpp
index 717ccb3344..780015d307 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -419,6 +419,10 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
// Try to run the game
Common::Error result = runGame(plugin, system, specialDebug);
+ // Flush Event recorder file. The recorder does not get reinitialized for next game
+ // which is intentional. Only single game per session is allowed.
+ g_eventRec.deinit();
+
#if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES)
// do our best to prevent fragmentation by unloading as soon as we can
PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false);
diff --git a/common/EventDispatcher.cpp b/common/EventDispatcher.cpp
index ce1ef0c1c8..4e3f671cfd 100644
--- a/common/EventDispatcher.cpp
+++ b/common/EventDispatcher.cpp
@@ -45,6 +45,8 @@ EventDispatcher::~EventDispatcher() {
void EventDispatcher::dispatch() {
Event event;
+ dispatchPoll();
+
for (List<SourceEntry>::iterator i = _sources.begin(); i != _sources.end(); ++i) {
const bool allowMapping = i->source->allowMapping();
@@ -94,12 +96,13 @@ void EventDispatcher::unregisterSource(EventSource *source) {
}
}
-void EventDispatcher::registerObserver(EventObserver *obs, uint priority, bool autoFree) {
+void EventDispatcher::registerObserver(EventObserver *obs, uint priority, bool autoFree, bool notifyPoll) {
ObserverEntry newEntry;
newEntry.observer = obs;
newEntry.priority = priority;
newEntry.autoFree = autoFree;
+ newEntry.poll = notifyPoll;
for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
if (i->priority < priority) {
@@ -130,4 +133,12 @@ void EventDispatcher::dispatchEvent(const Event &event) {
}
}
+void EventDispatcher::dispatchPoll() {
+ for (List<ObserverEntry>::iterator i = _observers.begin(); i != _observers.end(); ++i) {
+ if (i->poll == true)
+ if (i->observer->notifyPoll())
+ break;
+ }
+}
+
} // End of namespace Common
diff --git a/common/EventRecorder.cpp b/common/EventRecorder.cpp
index f5d8641bd3..4be3ca41ec 100644
--- a/common/EventRecorder.cpp
+++ b/common/EventRecorder.cpp
@@ -34,7 +34,28 @@ DECLARE_SINGLETON(EventRecorder);
#define RECORD_SIGNATURE 0x54455354
#define RECORD_VERSION 1
-void readRecord(SeekableReadStream *inFile, uint32 &diff, Event &event) {
+uint32 readTime(ReadStream *inFile) {
+ uint32 d = inFile->readByte();
+ if (d == 0xff) {
+ d = inFile->readUint32LE();
+ }
+
+ return d;
+}
+
+void writeTime(WriteStream *outFile, uint32 d) {
+ //Simple RLE compression
+ if (d >= 0xff) {
+ outFile->writeByte(0xff);
+ outFile->writeUint32LE(d);
+ } else {
+ outFile->writeByte(d);
+ }
+}
+
+void readRecord(SeekableReadStream *inFile, uint32 &diff, Event &event, uint32 &millis) {
+ millis = readTime(inFile);
+
diff = inFile->readUint32LE();
event.type = (EventType)inFile->readUint32LE();
@@ -61,7 +82,9 @@ void readRecord(SeekableReadStream *inFile, uint32 &diff, Event &event) {
}
}
-void writeRecord(WriteStream *outFile, uint32 diff, const Event &event) {
+void writeRecord(WriteStream *outFile, uint32 diff, const Event &event, uint32 millis) {
+ writeTime(outFile, millis);
+
outFile->writeUint32LE(diff);
outFile->writeUint32LE((uint32)event.type);
@@ -99,6 +122,7 @@ EventRecorder::EventRecorder() {
_eventCount = 0;
_lastEventCount = 0;
_lastMillis = 0;
+ _lastEventMillis = 0;
_recordMode = kPassthrough;
}
@@ -177,6 +201,7 @@ void EventRecorder::init() {
_recordCount = _playbackFile->readUint32LE();
_recordTimeCount = _playbackFile->readUint32LE();
+
randomSourceCount = _playbackFile->readUint32LE();
for (uint i = 0; i < randomSourceCount; ++i) {
RandomSourceRecord rec;
@@ -194,7 +219,7 @@ void EventRecorder::init() {
}
g_system->getEventManager()->getEventDispatcher()->registerSource(this, false);
- g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 1, false);
+ g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 1, false, true);
}
void EventRecorder::deinit() {
@@ -242,8 +267,9 @@ void EventRecorder::deinit() {
for (uint i = 0; i < _recordCount; ++i) {
uint32 tempDiff;
Event tempEvent;
- readRecord(_playbackFile, tempDiff, tempEvent);
- writeRecord(_recordFile, tempDiff, tempEvent);
+ uint32 millis;
+ readRecord(_playbackFile, tempDiff, tempEvent, millis);
+ writeRecord(_recordFile, tempDiff, tempEvent, millis);
}
_recordFile->finalize();
@@ -284,23 +310,16 @@ void EventRecorder::processMillis(uint32 &millis) {
g_system->lockMutex(_timeMutex);
if (_recordMode == kRecorderRecord) {
- //Simple RLE compression
d = millis - _lastMillis;
- if (d >= 0xff) {
- _recordTimeFile->writeByte(0xff);
- _recordTimeFile->writeUint32LE(d);
- } else {
- _recordTimeFile->writeByte(d);
- }
+ writeTime(_recordTimeFile, d);
+
_recordTimeCount++;
}
if (_recordMode == kRecorderPlayback) {
if (_recordTimeCount > _playbackTimeCount) {
- d = _playbackTimeFile->readByte();
- if (d == 0xff) {
- d = _playbackTimeFile->readUint32LE();
- }
+ d = readTime(_playbackTimeFile);
+
millis = _lastMillis + d;
_playbackTimeCount++;
}
@@ -321,15 +340,27 @@ bool EventRecorder::notifyEvent(const Event &ev) {
StackLock lock(_recorderMutex);
++_eventCount;
- writeRecord(_recordFile, _eventCount - _lastEventCount, ev);
+ writeRecord(_recordFile, _eventCount - _lastEventCount, ev, _lastMillis - _lastEventMillis);
_recordCount++;
_lastEventCount = _eventCount;
+ _lastEventMillis = _lastMillis;
+
+ return false;
+}
+
+bool EventRecorder::notifyPoll() {
+ if (_recordMode != kRecorderRecord)
+ return false;
+
+ ++_eventCount;
return false;
}
bool EventRecorder::pollEvent(Event &ev) {
+ uint32 millis;
+
if (_recordMode != kRecorderPlayback)
return false;
@@ -338,7 +369,7 @@ bool EventRecorder::pollEvent(Event &ev) {
if (!_hasPlaybackEvent) {
if (_recordCount > _playbackCount) {
- readRecord(_playbackFile, const_cast<uint32&>(_playbackDiff), _playbackEvent);
+ readRecord(_playbackFile, const_cast<uint32&>(_playbackDiff), _playbackEvent, millis);
_playbackCount++;
_hasPlaybackEvent = true;
}
diff --git a/common/EventRecorder.h b/common/EventRecorder.h
index e20419695a..43a08b08cd 100644
--- a/common/EventRecorder.h
+++ b/common/EventRecorder.h
@@ -61,6 +61,7 @@ public:
private:
bool notifyEvent(const Event &ev);
+ bool notifyPoll();
bool pollEvent(Event &ev);
bool allowMapping() const { return false; }
@@ -75,6 +76,7 @@ private:
volatile uint32 _recordCount;
volatile uint32 _lastRecordEvent;
volatile uint32 _recordTimeCount;
+ volatile uint32 _lastEventMillis;
WriteStream *_recordFile;
WriteStream *_recordTimeFile;
MutexRef _timeMutex;
diff --git a/common/events.h b/common/events.h
index 7df2731687..d48060f314 100644
--- a/common/events.h
+++ b/common/events.h
@@ -184,6 +184,14 @@ public:
* false otherwise.
*/
virtual bool notifyEvent(const Event &event) = 0;
+
+ /**
+ * Notifies the observer of pollEvent() query.
+ *
+ * @return true if the event should not be passed to other observers,
+ * false otherwise.
+ */
+ virtual bool notifyPoll() { return false; }
};
/**
@@ -255,8 +263,11 @@ public:
/**
* Registers a new EventObserver with the Dispatcher.
+ *
+ * @param listenPools if set, then all pollEvent() calls are passed to observer
+ * currently it is used by keyMapper
*/
- void registerObserver(EventObserver *obs, uint priority, bool autoFree);
+ void registerObserver(EventObserver *obs, uint priority, bool autoFree, bool listenPolls = false);
/**
* Unregisters a EventObserver.
@@ -280,11 +291,13 @@ private:
struct ObserverEntry : public Entry {
uint priority;
EventObserver *observer;
+ bool poll;
};
List<ObserverEntry> _observers;
void dispatchEvent(const Event &event);
+ void dispatchPoll();
};
class Keymapper;