Ticket #9038: recorder.patch

File recorder.patch, 47.2 KB (added by lordhoto, 12 years ago)

Patch against r42180 with applied "events.patch".

  • backends/events/default/default-events.cpp

    diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp
    index 0e32ff9..2efaec3 100644
    a b  
    3535#include "engines/engine.h"
    3636#include "gui/message.h"
    3737
    38 #define RECORD_SIGNATURE 0x54455354
    39 #define RECORD_VERSION 1
    40 
    41 void readRecord(Common::InSaveFile *inFile, uint32 &diff, Common::Event &event) {
    42         diff = inFile->readUint32LE();
    43 
    44         event.type = (Common::EventType)inFile->readUint32LE();
    45 
    46         switch(event.type) {
    47         case Common::EVENT_KEYDOWN:
    48         case Common::EVENT_KEYUP:
    49                 event.kbd.keycode = (Common::KeyCode)inFile->readSint32LE();
    50                 event.kbd.ascii = inFile->readUint16LE();
    51                 event.kbd.flags = inFile->readByte();
    52                 break;
    53         case Common::EVENT_MOUSEMOVE:
    54         case Common::EVENT_LBUTTONDOWN:
    55         case Common::EVENT_LBUTTONUP:
    56         case Common::EVENT_RBUTTONDOWN:
    57         case Common::EVENT_RBUTTONUP:
    58         case Common::EVENT_WHEELUP:
    59         case Common::EVENT_WHEELDOWN:
    60                 event.mouse.x = inFile->readSint16LE();
    61                 event.mouse.y = inFile->readSint16LE();
    62                 break;
    63         default:
    64                 break;
    65         }
    66 }
    67 
    68 void writeRecord(Common::OutSaveFile *outFile, uint32 diff, Common::Event &event) {
    69         outFile->writeUint32LE(diff);
    70 
    71         outFile->writeUint32LE((uint32)event.type);
    72 
    73         switch(event.type) {
    74         case Common::EVENT_KEYDOWN:
    75         case Common::EVENT_KEYUP:
    76                 outFile->writeSint32LE(event.kbd.keycode);
    77                 outFile->writeUint16LE(event.kbd.ascii);
    78                 outFile->writeByte(event.kbd.flags);
    79                 break;
    80         case Common::EVENT_MOUSEMOVE:
    81         case Common::EVENT_LBUTTONDOWN:
    82         case Common::EVENT_LBUTTONUP:
    83         case Common::EVENT_RBUTTONDOWN:
    84         case Common::EVENT_RBUTTONUP:
    85         case Common::EVENT_WHEELUP:
    86         case Common::EVENT_WHEELDOWN:
    87                 outFile->writeSint16LE(event.mouse.x);
    88                 outFile->writeSint16LE(event.mouse.y);
    89                 break;
    90         default:
    91                 break;
    92         }
    93 }
    94 
    9538DefaultEventManager::DefaultEventManager(Common::EventSource *boss) :
    9639        _buttonState(0),
    9740        _modifierState(0),
    DefaultEventManager::DefaultEventManager(Common::EventSource *boss) :  
    10649
    10750        _dispatcher.registerObserver(this, kEventManPriority, false);
    10851
    109         _recordFile = NULL;
    110         _recordTimeFile = NULL;
    111         _playbackFile = NULL;
    112         _playbackTimeFile = NULL;
    113         _timeMutex = g_system->createMutex();
    114         _recorderMutex = g_system->createMutex();
    115 
    116         _eventCount = 0;
    117         _lastEventCount = 0;
    118         _lastMillis = 0;
    119 
    120         Common::String recordModeString = ConfMan.get("record_mode");
    121         if (recordModeString.compareToIgnoreCase("record") == 0) {
    122                 _recordMode = kRecorderRecord;
    123         } else {
    124                 if (recordModeString.compareToIgnoreCase("playback") == 0) {
    125                         _recordMode = kRecorderPlayback;
    126                 } else {
    127                         _recordMode = kPassthrough;
    128                 }
    129         }
    130 
    131         _recordFileName = ConfMan.get("record_file_name");
    132         if (_recordFileName.empty()) {
    133                 _recordFileName = "record.bin";
    134         }
    135         _recordTempFileName = ConfMan.get("record_temp_file_name");
    136         if (_recordTempFileName.empty()) {
    137                 _recordTempFileName = "record.tmp";
    138         }
    139         _recordTimeFileName = ConfMan.get("record_time_file_name");
    140         if (_recordTimeFileName.empty()) {
    141                 _recordTimeFileName = "record.time";
    142         }
    143 
    14452        // Reset key repeat
    14553        _currentKeyDown.keycode = 0;
    14654
    147         // recorder stuff
    148         if (_recordMode == kRecorderRecord) {
    149                 _recordCount = 0;
    150                 _recordTimeCount = 0;
    151                 _recordFile = g_system->getSavefileManager()->openForSaving(_recordTempFileName);
    152                 _recordTimeFile = g_system->getSavefileManager()->openForSaving(_recordTimeFileName);
    153                 _recordSubtitles = ConfMan.getBool("subtitles");
    154         }
    155 
    156         uint32 sign;
    157         uint32 version;
    158         uint32 randomSourceCount;
    159         if (_recordMode == kRecorderPlayback) {
    160                 _playbackCount = 0;
    161                 _playbackTimeCount = 0;
    162                 _playbackFile = g_system->getSavefileManager()->openForLoading(_recordFileName);
    163                 _playbackTimeFile = g_system->getSavefileManager()->openForLoading(_recordTimeFileName);
    164 
    165                 if (!_playbackFile) {
    166                         warning("Cannot open playback file %s. Playback was switched off", _recordFileName.c_str());
    167                         _recordMode = kPassthrough;
    168                 }
    169 
    170                 if (!_playbackTimeFile) {
    171                         warning("Cannot open playback time file %s. Playback was switched off", _recordTimeFileName.c_str());
    172                         _recordMode = kPassthrough;
    173                 }
    174         }
    175 
    176         if (_recordMode == kRecorderPlayback) {
    177                 sign = _playbackFile->readUint32LE();
    178                 if (sign != RECORD_SIGNATURE) {
    179                         error("Unknown record file signature");
    180                 }
    181                 version = _playbackFile->readUint32LE();
    182 
    183                 // conf vars
    184                 ConfMan.setBool("subtitles", _playbackFile->readByte() != 0);
    185 
    186                 _recordCount = _playbackFile->readUint32LE();
    187                 _recordTimeCount = _playbackFile->readUint32LE();
    188                 randomSourceCount = _playbackFile->readUint32LE();
    189                 for (uint i = 0; i < randomSourceCount; ++i) {
    190                         RandomSourceRecord rec;
    191                         rec.name = "";
    192                         uint32 sLen = _playbackFile->readUint32LE();
    193                         for (uint j = 0; j < sLen; ++j) {
    194                                 char c = _playbackFile->readSByte();
    195                                 rec.name += c;
    196                         }
    197                         rec.seed = _playbackFile->readUint32LE();
    198                         _randomSourceRecords.push_back(rec);
    199                 }
    200 
    201                 _hasPlaybackEvent = false;
    202         }
    203 
    20455#ifdef ENABLE_VKEYBD
    20556        _vk = new Common::VirtualKeyboard();
    20657#endif
    DefaultEventManager::~DefaultEventManager() {  
    21667#ifdef ENABLE_VKEYBD
    21768        delete _vk;
    21869#endif
    219         g_system->lockMutex(_timeMutex);
    220         g_system->lockMutex(_recorderMutex);
    221         _recordMode = kPassthrough;
    222         g_system->unlockMutex(_timeMutex);
    223         g_system->unlockMutex(_recorderMutex);
    224 
    225         if (_playbackFile != NULL) {
    226                 delete _playbackFile;
    227         }
    228         if (_playbackTimeFile != NULL) {
    229                 delete _playbackTimeFile;
    230         }
    231 
    232         if (_recordFile != NULL) {
    233                 _recordFile->finalize();
    234                 delete _recordFile;
    235                 _recordTimeFile->finalize();
    236                 delete _recordTimeFile;
    237 
    238                 _playbackFile = g_system->getSavefileManager()->openForLoading(_recordTempFileName);
    239 
    240                 assert(_playbackFile);
    241 
    242                 _recordFile = g_system->getSavefileManager()->openForSaving(_recordFileName);
    243                 _recordFile->writeUint32LE(RECORD_SIGNATURE);
    244                 _recordFile->writeUint32LE(RECORD_VERSION);
    245 
    246                 // conf vars
    247                 _recordFile->writeByte(_recordSubtitles ? 1 : 0);
    248 
    249                 _recordFile->writeUint32LE(_recordCount);
    250                 _recordFile->writeUint32LE(_recordTimeCount);
    251 
    252                 _recordFile->writeUint32LE(_randomSourceRecords.size());
    253                 for (uint i = 0; i < _randomSourceRecords.size(); ++i) {
    254                         _recordFile->writeUint32LE(_randomSourceRecords[i].name.size());
    255                         _recordFile->writeString(_randomSourceRecords[i].name);
    256                         _recordFile->writeUint32LE(_randomSourceRecords[i].seed);
    257                 }
    258 
    259                 for (uint i = 0; i < _recordCount; ++i) {
    260                         uint32 tempDiff;
    261                         Common::Event tempEvent;
    262                         readRecord(_playbackFile, tempDiff, tempEvent);
    263                         writeRecord(_recordFile, tempDiff, tempEvent);
    264                 }
    265 
    266                 _recordFile->finalize();
    267                 delete _recordFile;
    268                 delete _playbackFile;
    269 
    270                 //TODO: remove recordTempFileName'ed file
    271         }
    272         g_system->deleteMutex(_timeMutex);
    273         g_system->deleteMutex(_recorderMutex);
    27470}
    27571
    27672void DefaultEventManager::init() {
    void DefaultEventManager::init() {  
    28379#endif
    28480}
    28581
    286 bool DefaultEventManager::playback(Common::Event &event) {
    287 
    288         if (!_hasPlaybackEvent) {
    289                 if (_recordCount > _playbackCount) {
    290                         readRecord(_playbackFile, const_cast<uint32&>(_playbackDiff), _playbackEvent);
    291                         _playbackCount++;
    292                         _hasPlaybackEvent = true;
    293                 }
    294         }
    295 
    296         if (_hasPlaybackEvent) {
    297                 if (_playbackDiff <= (_eventCount - _lastEventCount)) {
    298                         switch(_playbackEvent.type) {
    299                         case Common::EVENT_MOUSEMOVE:
    300                         case Common::EVENT_LBUTTONDOWN:
    301                         case Common::EVENT_LBUTTONUP:
    302                         case Common::EVENT_RBUTTONDOWN:
    303                         case Common::EVENT_RBUTTONUP:
    304                         case Common::EVENT_WHEELUP:
    305                         case Common::EVENT_WHEELDOWN:
    306                                 g_system->warpMouse(_playbackEvent.mouse.x, _playbackEvent.mouse.y);
    307                                 break;
    308                         default:
    309                                 break;
    310                         }
    311                         event = _playbackEvent;
    312                         _hasPlaybackEvent = false;
    313                         _lastEventCount = _eventCount;
    314                         return true;
    315                 }
    316         }
    317 
    318         return false;
    319 }
    320 
    321 void DefaultEventManager::record(Common::Event &event) {
    322         writeRecord(_recordFile, _eventCount - _lastEventCount, event);
    323 
    324         _recordCount++;
    325         _lastEventCount = _eventCount;
    326 }
    327 
    328 void DefaultEventManager::registerRandomSource(Common::RandomSource &rnd, const char *name) {
    329 
    330         if (_recordMode == kRecorderRecord) {
    331                 RandomSourceRecord rec;
    332                 rec.name = name;
    333                 rec.seed = rnd.getSeed();
    334                 _randomSourceRecords.push_back(rec);
    335         }
    336 
    337         if (_recordMode == kRecorderPlayback) {
    338                 for (uint i = 0; i < _randomSourceRecords.size(); ++i) {
    339                         if (_randomSourceRecords[i].name == name) {
    340                                 rnd.setSeed(_randomSourceRecords[i].seed);
    341                                 _randomSourceRecords.remove_at(i);
    342                                 break;
    343                         }
    344                 }
    345         }
    346 }
    347 
    348 void DefaultEventManager::processMillis(uint32 &millis) {
    349         uint32 d;
    350         if (_recordMode == kPassthrough) {
    351                 return;
    352         }
    353 
    354         g_system->lockMutex(_timeMutex);
    355         if (_recordMode == kRecorderRecord) {
    356                 //Simple RLE compression
    357                 d = millis - _lastMillis;
    358                 if (d >= 0xff) {
    359                         _recordTimeFile->writeByte(0xff);
    360                         _recordTimeFile->writeUint32LE(d);
    361                 } else {
    362                         _recordTimeFile->writeByte(d);
    363                 }
    364                 _recordTimeCount++;
    365         }
    366 
    367         if (_recordMode == kRecorderPlayback) {
    368                 if (_recordTimeCount > _playbackTimeCount) {
    369                         d = _playbackTimeFile->readByte();
    370                         if (d == 0xff) {
    371                                 d = _playbackTimeFile->readUint32LE();
    372                         }
    373                         millis = _lastMillis + d;
    374                         _playbackTimeCount++;
    375                 }
    376         }
    377 
    378         _lastMillis = millis;
    379         g_system->unlockMutex(_timeMutex);
    380 }
    381 
    38282bool DefaultEventManager::pollEvent(Common::Event &event) {
    38383        uint32 time = g_system->getMillis();
    38484        bool result = false;
    bool DefaultEventManager::pollEvent(Common::Event &event) {  
    38989                result = true;
    39090        }
    39191
    392         if (_recordMode != kPassthrough)  {
    393 
    394                 g_system->lockMutex(_recorderMutex);
    395                 _eventCount++;
    396 
    397                 if (_recordMode == kRecorderPlayback)  {
    398                         if (event.type != Common::EVENT_QUIT) {
    399                                 result = playback(event);
    400                         }
    401                 } else {
    402                         if (_recordMode == kRecorderRecord) {
    403                                 if (result) {
    404                                         record(event);
    405                                 }
    406                         }
    407                 }
    408                 g_system->unlockMutex(_recorderMutex);
    409         }
    410 
    41192        if (result) {
    41293                event.synthetic = false;
    41394                switch (event.type) {
  • backends/events/default/default-events.h

    diff --git a/backends/events/default/default-events.h b/backends/events/default/default-events.h
    index 963706a..9f028c0 100644
    a b  
    2727#define BACKEND_EVENTS_DEFAULT_H
    2828
    2929#include "common/events.h"
    30 #include "common/savefile.h"
    31 #include "common/mutex.h"
    3230#include "common/queue.h"
    3331
    3432namespace Common {
    class DefaultEventManager : public Common::EventManager, Common::EventObserver {  
    6664        bool _shouldRTL;
    6765        bool _confirmExitDialogActive;
    6866
    69         class RandomSourceRecord {
    70         public:
    71                 Common::String name;
    72                 uint32 seed;
    73         };
    74         Common::Array<RandomSourceRecord> _randomSourceRecords;
    75 
    76         bool _recordSubtitles;
    77         volatile uint32 _recordCount;
    78         volatile uint32 _lastRecordEvent;
    79         volatile uint32 _recordTimeCount;
    80         Common::OutSaveFile *_recordFile;
    81         Common::OutSaveFile *_recordTimeFile;
    82         Common::MutexRef _timeMutex;
    83         Common::MutexRef _recorderMutex;
    84         volatile uint32 _lastMillis;
    85 
    86         volatile uint32 _playbackCount;
    87         volatile uint32 _playbackDiff;
    88         volatile bool _hasPlaybackEvent;
    89         volatile uint32 _playbackTimeCount;
    90         Common::Event _playbackEvent;
    91         Common::InSaveFile *_playbackFile;
    92         Common::InSaveFile *_playbackTimeFile;
    93 
    94         volatile uint32 _eventCount;
    95         volatile uint32 _lastEventCount;
    96 
    97         enum RecordMode {
    98                 kPassthrough = 0,
    99                 kRecorderRecord = 1,
    100                 kRecorderPlayback = 2
    101         };
    102         volatile RecordMode _recordMode;
    103         Common::String _recordFileName;
    104         Common::String _recordTempFileName;
    105         Common::String _recordTimeFileName;
    106 
    10767        // for continuous events (keyDown)
    10868        enum {
    10969                kKeyRepeatInitialDelay = 400,
    class DefaultEventManager : public Common::EventManager, Common::EventObserver {  
    11676                int keycode;
    11777        } _currentKeyDown;
    11878        uint32 _keyRepeatTime;
    119 
    120         void record(Common::Event &event);
    121         bool playback(Common::Event &event);
    12279public:
    12380        DefaultEventManager(Common::EventSource *boss);
    12481        ~DefaultEventManager();
    public:  
    12683        virtual void init();
    12784        virtual bool pollEvent(Common::Event &event);
    12885        virtual void pushEvent(const Common::Event &event);
    129         virtual void registerRandomSource(Common::RandomSource &rnd, const char *name);
    130         virtual void processMillis(uint32 &millis);
    13186
    13287        virtual Common::Point getMousePos() const { return _mousePos; }
    13388        virtual int getButtonState() const { return _buttonState; }
  • backends/platform/sdl/sdl.cpp

    diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
    index b353c79..8972234 100644
    a b  
    3333#include "common/archive.h"
    3434#include "common/config-manager.h"
    3535#include "common/debug.h"
    36 #include "common/events.h"
     36#include "common/EventRecorder.h"
    3737#include "common/util.h"
    3838
    3939#ifdef UNIX
    OSystem_SDL::~OSystem_SDL() {  
    257257
    258258uint32 OSystem_SDL::getMillis() {
    259259        uint32 millis = SDL_GetTicks();
    260         getEventManager()->processMillis(millis);
     260        g_eventRec.processMillis(millis);
    261261        return millis;
    262262}
    263263
  • base/main.cpp

    diff --git a/base/main.cpp b/base/main.cpp
    index a091c58..43838bf 100644
    a b  
    4141#include "common/config-manager.h"
    4242#include "common/debug.h"
    4343#include "common/events.h"
     44#include "common/EventRecorder.h"
    4445#include "common/file.h"
    4546#include "common/fs.h"
    4647#include "common/system.h"
    extern "C" int scummvm_main(int argc, const char * const argv[]) {  
    355356        // take place after the backend is initiated and the screen has been setup
    356357        system.getEventManager()->init();
    357358
     359        // Directly after initializing the event manager, we will initialize our
     360        // event recorder.
     361        //
     362        // TODO: This is just to match the current behavior, when we further extend
     363        // our event recorder, we might do this at another place. Or even change
     364        // the whole API for that ;-).
     365        g_eventRec.init();
     366
    358367        // Now as the event manager is created, setup the keymapper
    359368        setupKeymapper(system);
    360369
  • new file common/EventRecorder.cpp

    diff --git a/common/EventRecorder.cpp b/common/EventRecorder.cpp
    new file mode 100644
    index 0000000..3d5eee3
    - +  
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL$
     22 * $Id$
     23 *
     24 */
     25
     26#include "common/EventRecorder.h"
     27
     28#include "common/config-manager.h"
     29
     30DECLARE_SINGLETON(Common::EventRecorder);
     31
     32namespace Common {
     33
     34#define RECORD_SIGNATURE 0x54455354
     35#define RECORD_VERSION 1
     36
     37void readRecord(Common::InSaveFile *inFile, uint32 &diff, Common::Event &event) {
     38        diff = inFile->readUint32LE();
     39
     40        event.type = (Common::EventType)inFile->readUint32LE();
     41
     42        switch(event.type) {
     43        case Common::EVENT_KEYDOWN:
     44        case Common::EVENT_KEYUP:
     45                event.kbd.keycode = (Common::KeyCode)inFile->readSint32LE();
     46                event.kbd.ascii = inFile->readUint16LE();
     47                event.kbd.flags = inFile->readByte();
     48                break;
     49        case Common::EVENT_MOUSEMOVE:
     50        case Common::EVENT_LBUTTONDOWN:
     51        case Common::EVENT_LBUTTONUP:
     52        case Common::EVENT_RBUTTONDOWN:
     53        case Common::EVENT_RBUTTONUP:
     54        case Common::EVENT_WHEELUP:
     55        case Common::EVENT_WHEELDOWN:
     56                event.mouse.x = inFile->readSint16LE();
     57                event.mouse.y = inFile->readSint16LE();
     58                break;
     59        default:
     60                break;
     61        }
     62}
     63
     64void writeRecord(Common::OutSaveFile *outFile, uint32 diff, const Common::Event &event) {
     65        outFile->writeUint32LE(diff);
     66
     67        outFile->writeUint32LE((uint32)event.type);
     68
     69        switch(event.type) {
     70        case Common::EVENT_KEYDOWN:
     71        case Common::EVENT_KEYUP:
     72                outFile->writeSint32LE(event.kbd.keycode);
     73                outFile->writeUint16LE(event.kbd.ascii);
     74                outFile->writeByte(event.kbd.flags);
     75                break;
     76        case Common::EVENT_MOUSEMOVE:
     77        case Common::EVENT_LBUTTONDOWN:
     78        case Common::EVENT_LBUTTONUP:
     79        case Common::EVENT_RBUTTONDOWN:
     80        case Common::EVENT_RBUTTONUP:
     81        case Common::EVENT_WHEELUP:
     82        case Common::EVENT_WHEELDOWN:
     83                outFile->writeSint16LE(event.mouse.x);
     84                outFile->writeSint16LE(event.mouse.y);
     85                break;
     86        default:
     87                break;
     88        }
     89}
     90
     91EventRecorder::EventRecorder() {
     92        _recordFile = NULL;
     93        _recordTimeFile = NULL;
     94        _playbackFile = NULL;
     95        _playbackTimeFile = NULL;
     96        _timeMutex = g_system->createMutex();
     97        _recorderMutex = g_system->createMutex();
     98
     99        _eventCount = 0;
     100        _lastEventCount = 0;
     101        _lastMillis = 0;
     102
     103}
     104
     105EventRecorder::~EventRecorder() {
     106        deinit();
     107}
     108
     109void EventRecorder::init() {
     110        Common::String recordModeString = ConfMan.get("record_mode");
     111        if (recordModeString.compareToIgnoreCase("record") == 0) {
     112                _recordMode = kRecorderRecord;
     113        } else {
     114                if (recordModeString.compareToIgnoreCase("playback") == 0) {
     115                        _recordMode = kRecorderPlayback;
     116                } else {
     117                        _recordMode = kPassthrough;
     118                }
     119        }
     120
     121        _recordFileName = ConfMan.get("record_file_name");
     122        if (_recordFileName.empty()) {
     123                _recordFileName = "record.bin";
     124        }
     125        _recordTempFileName = ConfMan.get("record_temp_file_name");
     126        if (_recordTempFileName.empty()) {
     127                _recordTempFileName = "record.tmp";
     128        }
     129        _recordTimeFileName = ConfMan.get("record_time_file_name");
     130        if (_recordTimeFileName.empty()) {
     131                _recordTimeFileName = "record.time";
     132        }
     133
     134        // recorder stuff
     135        if (_recordMode == kRecorderRecord) {
     136                _recordCount = 0;
     137                _recordTimeCount = 0;
     138                _recordFile = g_system->getSavefileManager()->openForSaving(_recordTempFileName);
     139                _recordTimeFile = g_system->getSavefileManager()->openForSaving(_recordTimeFileName);
     140                _recordSubtitles = ConfMan.getBool("subtitles");
     141        }
     142
     143        uint32 sign;
     144        uint32 version;
     145        uint32 randomSourceCount;
     146        if (_recordMode == kRecorderPlayback) {
     147                _playbackCount = 0;
     148                _playbackTimeCount = 0;
     149                _playbackFile = g_system->getSavefileManager()->openForLoading(_recordFileName);
     150                _playbackTimeFile = g_system->getSavefileManager()->openForLoading(_recordTimeFileName);
     151
     152                if (!_playbackFile) {
     153                        warning("Cannot open playback file %s. Playback was switched off", _recordFileName.c_str());
     154                        _recordMode = kPassthrough;
     155                }
     156
     157                if (!_playbackTimeFile) {
     158                        warning("Cannot open playback time file %s. Playback was switched off", _recordTimeFileName.c_str());
     159                        _recordMode = kPassthrough;
     160                }
     161        }
     162
     163        if (_recordMode == kRecorderPlayback) {
     164                sign = _playbackFile->readUint32LE();
     165                if (sign != RECORD_SIGNATURE) {
     166                        error("Unknown record file signature");
     167                }
     168                version = _playbackFile->readUint32LE();
     169
     170                // conf vars
     171                ConfMan.setBool("subtitles", _playbackFile->readByte() != 0);
     172
     173                _recordCount = _playbackFile->readUint32LE();
     174                _recordTimeCount = _playbackFile->readUint32LE();
     175                randomSourceCount = _playbackFile->readUint32LE();
     176                for (uint i = 0; i < randomSourceCount; ++i) {
     177                        RandomSourceRecord rec;
     178                        rec.name = "";
     179                        uint32 sLen = _playbackFile->readUint32LE();
     180                        for (uint j = 0; j < sLen; ++j) {
     181                                char c = _playbackFile->readSByte();
     182                                rec.name += c;
     183                        }
     184                        rec.seed = _playbackFile->readUint32LE();
     185                        _randomSourceRecords.push_back(rec);
     186                }
     187
     188                _hasPlaybackEvent = false;
     189        }
     190
     191        g_system->getEventManager()->getEventDispatcher()->registerSource(this, false);
     192        g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 1, false);
     193}
     194
     195void EventRecorder::deinit() {
     196        g_system->getEventManager()->getEventDispatcher()->unregisterSource(this);
     197        g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
     198
     199        g_system->lockMutex(_timeMutex);
     200        g_system->lockMutex(_recorderMutex);
     201        _recordMode = kPassthrough;
     202        g_system->unlockMutex(_timeMutex);
     203        g_system->unlockMutex(_recorderMutex);
     204
     205        if (_playbackFile != NULL) {
     206                delete _playbackFile;
     207        }
     208        if (_playbackTimeFile != NULL) {
     209                delete _playbackTimeFile;
     210        }
     211
     212        if (_recordFile != NULL) {
     213                _recordFile->finalize();
     214                delete _recordFile;
     215                _recordTimeFile->finalize();
     216                delete _recordTimeFile;
     217
     218                _playbackFile = g_system->getSavefileManager()->openForLoading(_recordTempFileName);
     219
     220                assert(_playbackFile);
     221
     222                _recordFile = g_system->getSavefileManager()->openForSaving(_recordFileName);
     223                _recordFile->writeUint32LE(RECORD_SIGNATURE);
     224                _recordFile->writeUint32LE(RECORD_VERSION);
     225
     226                // conf vars
     227                _recordFile->writeByte(_recordSubtitles ? 1 : 0);
     228
     229                _recordFile->writeUint32LE(_recordCount);
     230                _recordFile->writeUint32LE(_recordTimeCount);
     231
     232                _recordFile->writeUint32LE(_randomSourceRecords.size());
     233                for (uint i = 0; i < _randomSourceRecords.size(); ++i) {
     234                        _recordFile->writeUint32LE(_randomSourceRecords[i].name.size());
     235                        _recordFile->writeString(_randomSourceRecords[i].name);
     236                        _recordFile->writeUint32LE(_randomSourceRecords[i].seed);
     237                }
     238
     239                for (uint i = 0; i < _recordCount; ++i) {
     240                        uint32 tempDiff;
     241                        Common::Event tempEvent;
     242                        readRecord(_playbackFile, tempDiff, tempEvent);
     243                        writeRecord(_recordFile, tempDiff, tempEvent);
     244                }
     245
     246                _recordFile->finalize();
     247                delete _recordFile;
     248                delete _playbackFile;
     249
     250                //TODO: remove recordTempFileName'ed file
     251        }
     252
     253        g_system->deleteMutex(_timeMutex);
     254        g_system->deleteMutex(_recorderMutex);
     255}
     256
     257void EventRecorder::registerRandomSource(Common::RandomSource &rnd, const char *name) {
     258        if (_recordMode == kRecorderRecord) {
     259                RandomSourceRecord rec;
     260                rec.name = name;
     261                rec.seed = rnd.getSeed();
     262                _randomSourceRecords.push_back(rec);
     263        }
     264
     265        if (_recordMode == kRecorderPlayback) {
     266                for (uint i = 0; i < _randomSourceRecords.size(); ++i) {
     267                        if (_randomSourceRecords[i].name == name) {
     268                                rnd.setSeed(_randomSourceRecords[i].seed);
     269                                _randomSourceRecords.remove_at(i);
     270                                break;
     271                        }
     272                }
     273        }
     274}
     275
     276void EventRecorder::processMillis(uint32 &millis) {
     277        uint32 d;
     278        if (_recordMode == kPassthrough) {
     279                return;
     280        }
     281
     282        g_system->lockMutex(_timeMutex);
     283        if (_recordMode == kRecorderRecord) {
     284                //Simple RLE compression
     285                d = millis - _lastMillis;
     286                if (d >= 0xff) {
     287                        _recordTimeFile->writeByte(0xff);
     288                        _recordTimeFile->writeUint32LE(d);
     289                } else {
     290                        _recordTimeFile->writeByte(d);
     291                }
     292                _recordTimeCount++;
     293        }
     294
     295        if (_recordMode == kRecorderPlayback) {
     296                if (_recordTimeCount > _playbackTimeCount) {
     297                        d = _playbackTimeFile->readByte();
     298                        if (d == 0xff) {
     299                                d = _playbackTimeFile->readUint32LE();
     300                        }
     301                        millis = _lastMillis + d;
     302                        _playbackTimeCount++;
     303                }
     304        }
     305
     306        _lastMillis = millis;
     307        g_system->unlockMutex(_timeMutex);
     308}
     309
     310bool EventRecorder::notifyEvent(const Common::Event &ev) {
     311        if (_recordMode != kRecorderRecord)
     312                return false;
     313
     314        Common::StackLock lock(_recorderMutex);
     315        ++_eventCount;
     316
     317        writeRecord(_recordFile, _eventCount - _lastEventCount, ev);
     318
     319        _recordCount++;
     320        _lastEventCount = _eventCount;
     321
     322        return false;
     323}
     324
     325bool EventRecorder::pollEvent(Common::Event &ev) {
     326        if (_recordMode != kRecorderPlayback)
     327                return false;
     328
     329        Common::StackLock lock(_recorderMutex);
     330        ++_eventCount;
     331
     332        if (!_hasPlaybackEvent) {
     333                if (_recordCount > _playbackCount) {
     334                        readRecord(_playbackFile, const_cast<uint32&>(_playbackDiff), _playbackEvent);
     335                        _playbackCount++;
     336                        _hasPlaybackEvent = true;
     337                }
     338        }
     339
     340        if (_hasPlaybackEvent) {
     341                if (_playbackDiff <= (_eventCount - _lastEventCount)) {
     342                        switch(_playbackEvent.type) {
     343                        case Common::EVENT_MOUSEMOVE:
     344                        case Common::EVENT_LBUTTONDOWN:
     345                        case Common::EVENT_LBUTTONUP:
     346                        case Common::EVENT_RBUTTONDOWN:
     347                        case Common::EVENT_RBUTTONUP:
     348                        case Common::EVENT_WHEELUP:
     349                        case Common::EVENT_WHEELDOWN:
     350                                g_system->warpMouse(_playbackEvent.mouse.x, _playbackEvent.mouse.y);
     351                                break;
     352                        default:
     353                                break;
     354                        }
     355                        ev = _playbackEvent;
     356                        _hasPlaybackEvent = false;
     357                        _lastEventCount = _eventCount;
     358                        return true;
     359                }
     360        }
     361
     362        return false;
     363}
     364
     365} // end of namespace Common
     366
  • new file common/EventRecorder.h

    diff --git a/common/EventRecorder.h b/common/EventRecorder.h
    new file mode 100644
    index 0000000..e6ea961
    - +  
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL$
     22 * $Id$
     23 *
     24 */
     25
     26#ifndef COMMON_EVENTRECORDER_H
     27#define COMMON_EVENTRECORDER_H
     28
     29#include "common/scummsys.h"
     30#include "common/events.h"
     31#include "common/singleton.h"
     32#include "common/savefile.h"
     33#include "common/mutex.h"
     34#include "common/array.h"
     35
     36#define g_eventRec (Common::EventRecorder::instance())
     37
     38namespace Common {
     39
     40/**
     41 * Our generic event recorder.
     42 *
     43 * TODO: Add more documentation.
     44 */
     45class EventRecorder : private EventSource, private EventObserver, public Singleton<EventRecorder> {
     46        friend class Common::Singleton<SingletonBaseType>;
     47        EventRecorder();
     48        ~EventRecorder();
     49public:
     50        void init();
     51        void deinit();
     52
     53        /** Register random source so it can be serialized in game test purposes */
     54        void registerRandomSource(Common::RandomSource &rnd, const char *name);
     55
     56        /** TODO: Add documentation, this is only used by the backend */
     57        void processMillis(uint32 &millis);
     58
     59private:
     60        bool notifyEvent(const Common::Event &ev);
     61        bool pollEvent(Common::Event &ev);
     62        bool allowMapping() const { return false; }
     63
     64        class RandomSourceRecord {
     65        public:
     66                Common::String name;
     67                uint32 seed;
     68        };
     69        Common::Array<RandomSourceRecord> _randomSourceRecords;
     70
     71        bool _recordSubtitles;
     72        volatile uint32 _recordCount;
     73        volatile uint32 _lastRecordEvent;
     74        volatile uint32 _recordTimeCount;
     75        Common::OutSaveFile *_recordFile;
     76        Common::OutSaveFile *_recordTimeFile;
     77        Common::MutexRef _timeMutex;
     78        Common::MutexRef _recorderMutex;
     79        volatile uint32 _lastMillis;
     80
     81        volatile uint32 _playbackCount;
     82        volatile uint32 _playbackDiff;
     83        volatile bool _hasPlaybackEvent;
     84        volatile uint32 _playbackTimeCount;
     85        Common::Event _playbackEvent;
     86        Common::InSaveFile *_playbackFile;
     87        Common::InSaveFile *_playbackTimeFile;
     88
     89        volatile uint32 _eventCount;
     90        volatile uint32 _lastEventCount;
     91
     92        enum RecordMode {
     93                kPassthrough = 0,
     94                kRecorderRecord = 1,
     95                kRecorderPlayback = 2
     96        };
     97        volatile RecordMode _recordMode;
     98        Common::String _recordFileName;
     99        Common::String _recordTempFileName;
     100        Common::String _recordTimeFileName;
     101};
     102
     103} // end of namespace Common
     104
     105#endif
     106
  • common/events.h

    diff --git a/common/events.h b/common/events.h
    index f4f5ffd..55ebae2 100644
    a b public:  
    348348         */
    349349        virtual void pushEvent(const Common::Event &event) = 0;
    350350
    351         /** Register random source so it can be serialized in game test purposes **/
    352         virtual void registerRandomSource(Common::RandomSource &rnd, const char *name) = 0;
    353 
    354         virtual void processMillis(uint32 &millis) = 0;
    355 
    356351        /** Return the current mouse position */
    357352        virtual Common::Point getMousePos() const = 0;
    358353
  • common/module.mk

    diff --git a/common/module.mk b/common/module.mk
    index 798fe4f..3ed7cec 100644
    a b MODULE_OBJS := \  
    66        config-manager.o \
    77        debug.o \
    88        events.o \
     9        EventRecorder.o \
    910        file.o \
    1011        fs.o \
    1112        hashmap.o \
  • engines/agi/agi.cpp

    diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
    index e373dd3..e440625 100644
    a b  
    2525
    2626#include "common/md5.h"
    2727#include "common/events.h"
     28#include "common/EventRecorder.h"
    2829#include "common/file.h"
    2930#include "common/savefile.h"
    3031#include "common/config-manager.h"
    AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas  
    671672        parseFeatures();
    672673
    673674        _rnd = new Common::RandomSource();
    674         syst->getEventManager()->registerRandomSource(*_rnd, "agi");
     675        g_eventRec.registerRandomSource(*_rnd, "agi");
    675676
    676677        Common::addDebugChannel(kDebugLevelMain, "Main", "Generic debug level");
    677678        Common::addDebugChannel(kDebugLevelResources, "Resources", "Resources debugging");
  • engines/agos/agos.cpp

    diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
    index 9903952..0e53698 100644
    a b  
    2727#include "common/file.h"
    2828#include "common/system.h"
    2929#include "common/events.h"
     30#include "common/EventRecorder.h"
    3031
    3132#include "agos/debugger.h"
    3233#include "agos/intern.h"
    AGOSEngine::AGOSEngine(OSystem *syst)  
    528529        File::addDefaultDirectory(_gameDataDir.getChild("speech"));
    529530        File::addDefaultDirectory(_gameDataDir.getChild("SPEECH"));
    530531
    531         syst->getEventManager()->registerRandomSource(_rnd, "agos");
     532        g_eventRec.registerRandomSource(_rnd, "agos");
    532533}
    533534
    534535Common::Error AGOSEngine::init() {
  • engines/cine/cine.cpp

    diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
    index 64a9a9d..aa73b3a 100644
    a b  
    2424 */
    2525
    2626#include "common/events.h"
     27#include "common/EventRecorder.h"
    2728#include "common/file.h"
    2829#include "common/savefile.h"
    2930#include "common/config-manager.h"
    CineEngine::CineEngine(OSystem *syst, const CINEGameDescription *gameDesc) : Eng  
    6465
    6566        g_cine = this;
    6667
    67         syst->getEventManager()->registerRandomSource(_rnd, "cine");
     68        g_eventRec.registerRandomSource(_rnd, "cine");
    6869}
    6970
    7071CineEngine::~CineEngine() {
  • engines/cruise/cruise.cpp

    diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp
    index 4656704..28c5b4d 100644
    a b  
    2424 */
    2525
    2626#include "common/events.h"
     27#include "common/EventRecorder.h"
    2728#include "common/file.h"
    2829#include "common/savefile.h"
    2930#include "common/config-manager.h"
    CruiseEngine::CruiseEngine(OSystem * syst, const CRUISEGameDescription *gameDesc  
    6566        _debugger = new Debugger();
    6667        _sound = new PCSound(_mixer, this);
    6768
    68         syst->getEventManager()->registerRandomSource(_rnd, "cruise");
     69        g_eventRec.registerRandomSource(_rnd, "cruise");
    6970}
    7071
    7172CruiseEngine::~CruiseEngine() {
  • engines/drascula/drascula.cpp

    diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
    index a3c56be..84c2dd8 100644
    a b  
    2424 */
    2525
    2626#include "common/events.h"
     27#include "common/EventRecorder.h"
    2728#include "common/keyboard.h"
    2829#include "common/file.h"
    2930#include "common/savefile.h"
    DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam  
    9293        *textName = 0;
    9394
    9495        _rnd = new Common::RandomSource();
    95         syst->getEventManager()->registerRandomSource(*_rnd, "drascula");
     96        g_eventRec.registerRandomSource(*_rnd, "drascula");
    9697
    9798        int cd_num = ConfMan.getInt("cdrom");
    9899        if (cd_num >= 0)
  • engines/gob/gob.cpp

    diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
    index 8605dfb..7feefee 100644
    a b  
    2525
    2626#include "common/endian.h"
    2727#include "common/events.h"
     28#include "common/EventRecorder.h"
    2829
    2930#include "base/plugins.h"
    3031#include "common/config-manager.h"
    GobEngine::GobEngine(OSystem *syst) : Engine(syst) {  
    129130        Common::addDebugChannel(kDebugHotspots, "Hotspots", "Hotspots debug level");
    130131        Common::addDebugChannel(kDebugDemo, "Demo", "Demo script debug level");
    131132
    132         syst->getEventManager()->registerRandomSource(_rnd, "gob");
     133        g_eventRec.registerRandomSource(_rnd, "gob");
    133134}
    134135
    135136GobEngine::~GobEngine() {
  • engines/gob/sound/bgatmosphere.cpp

    diff --git a/engines/gob/sound/bgatmosphere.cpp b/engines/gob/sound/bgatmosphere.cpp
    index 6ce1841..f0977aa 100644
    a b  
    2525
    2626#include "common/system.h"
    2727#include "common/events.h"
     28#include "common/EventRecorder.h"
    2829
    2930#include "gob/sound/bgatmosphere.h"
    3031#include "gob/sound/sounddesc.h"
    BackgroundAtmosphere::BackgroundAtmosphere(Audio::Mixer &mixer) :  
    3940        _shaded = false;
    4041        _shadable = true;
    4142
    42         g_system->getEventManager()->registerRandomSource(_rnd, "gobBA");
     43        g_eventRec.registerRandomSource(_rnd, "gobBA");
    4344}
    4445
    4546BackgroundAtmosphere::~BackgroundAtmosphere() {
  • engines/groovie/script.cpp

    diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp
    index eb53842..f9c50ad 100644
    a b  
    3333#include "common/config-manager.h"
    3434#include "common/endian.h"
    3535#include "common/events.h"
     36#include "common/EventRecorder.h"
    3637
    3738#define NUM_OPCODES 90
    3839
    Script::Script(GroovieEngine *vm, EngineVersion version) :  
    7374        }
    7475
    7576        // Initialize the random source
    76         _vm->_system->getEventManager()->registerRandomSource(_random, "GroovieScripts");
     77        g_eventRec.registerRandomSource(_random, "GroovieScripts");
    7778
    7879        // Prepare the variables
    7980        _bitflags = 0;
  • engines/kyra/kyra_v1.cpp

    diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
    index 8087287..fd50201 100644
    a b  
    2424 */
    2525
    2626#include "common/config-manager.h"
     27#include "common/EventRecorder.h"
    2728
    2829#include "sound/mididrv.h"
    2930#include "sound/mixer.h"
    KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)  
    8182        Common::addDebugChannel(kDebugLevelMovie, "Movie", "Movie debug level");
    8283        Common::addDebugChannel(kDebugLevelTimer, "Timer", "Timer debug level");
    8384
    84         _eventMan->registerRandomSource(_rnd, "kyra");
     85        g_eventRec.registerRandomSource(_rnd, "kyra");
    8586}
    8687
    8788::GUI::Debugger *KyraEngine_v1::getDebugger() {
  • engines/kyra/sprites.cpp

    diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp
    index 3cc632a..456dcc0 100644
    a b  
    2828#include "common/stream.h"
    2929#include "common/util.h"
    3030#include "common/system.h"
     31#include "common/EventRecorder.h"
     32
    3133#include "kyra/screen.h"
    3234#include "kyra/kyra_lok.h"
    3335#include "kyra/sprites.h"
    Sprites::Sprites(KyraEngine_LoK *vm, OSystem *system) {  
    4749        _spriteDefStart = 0;
    4850        memset(_drawLayerTable, 0, sizeof(_drawLayerTable));
    4951        _sceneAnimatorBeaconFlag = 0;
    50         _vm->getEventManager()->registerRandomSource(_rnd, "kyraSprites");
     52        g_eventRec.registerRandomSource(_rnd, "kyraSprites");
    5153}
    5254
    5355Sprites::~Sprites() {
  • engines/lure/hotspots.cpp

    diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
    index 969d821..968bc8b 100644
    a b  
    3838#include "lure/sound.h"
    3939#include "lure/lure.h"
    4040#include "common/endian.h"
     41#include "common/EventRecorder.h"
    4142
    4243namespace Lure {
    4344
    void Hotspot::setRandomDest() {  
    600601        Common::RandomSource rnd;
    601602        int16 xp, yp;
    602603
    603         g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
     604        g_eventRec.registerRandomSource(rnd, "lureHotspots");
    604605
    605606        if (currentActions().isEmpty())
    606607                currentActions().addFront(START_WALKING, roomNumber());
    void HotspotTickHandlers::followerAnimHandler(Hotspot &h) {  
    31353136        Common::RandomSource rnd;
    31363137        RandomActionType actionType;
    31373138        uint16 scheduleId;
    3138         g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
     3139        g_eventRec.registerRandomSource(rnd, "lureHotspots");
    31393140
    31403141        int actionIndex = rnd.getRandomNumber(set->numActions() - 1);
    31413142        set->getEntry(actionIndex, actionType, scheduleId);
    void HotspotTickHandlers::prisonerAnimHandler(Hotspot &h) {  
    33253326        ValueTableData &fields = Resources::getReference().fieldList();
    33263327        Common::RandomSource rnd;
    33273328
    3328         g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
     3329        g_eventRec.registerRandomSource(rnd, "lureHotspots");
    33293330
    33303331        h.handleTalkDialog();
    33313332        if (h.frameCtr() > 0) {
    void HotspotTickHandlers::morkusAnimHandler(Hotspot &h) {  
    33683369        if (h.executeScript()) {
    33693370                // Script is done - set new script to one of two alternates randomly
    33703371                Common::RandomSource rnd;
    3371                 g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
     3372                g_eventRec.registerRandomSource(rnd, "lureHotspots");
    33723373
    33733374                h.setHotspotScript(rnd.getRandomNumber(100) >= 50 ? 0x54 : 0);
    33743375                h.setFrameCtr(20 + rnd.getRandomNumber(63));
    void HotspotTickHandlers::barmanAnimHandler(Hotspot &h) {  
    36683669        Common::RandomSource rnd;
    36693670        static bool ewanXOffset = false;
    36703671
    3671         g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
     3672        g_eventRec.registerRandomSource(rnd, "lureHotspots");
    36723673
    36733674        h.handleTalkDialog();
    36743675        if (h.delayCtr() > 0) {
  • engines/lure/res.cpp

    diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp
    index 95cb0a2..7eb76ca 100644
    a b  
    3030#include "lure/lure.h"
    3131#include "common/endian.h"
    3232#include "common/events.h"
     33#include "common/EventRecorder.h"
    3334
    3435namespace Lure {
    3536
    Resources &Resources::getReference() {  
    4243}
    4344
    4445Resources::Resources() {
    45         g_system->getEventManager()->registerRandomSource(_rnd, "lureResources");
     46        g_eventRec.registerRandomSource(_rnd, "lureResources");
    4647        int_resources = this;
    4748        reloadData();
    4849
  • engines/lure/scripts.cpp

    diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp
    index 391147e..f9d854a 100644
    a b  
    3434#include "lure/sound.h"
    3535#include "common/stack.h"
    3636#include "common/endian.h"
     37#include "common/EventRecorder.h"
    3738
    3839namespace Lure {
    3940
    void Script::addActions(uint16 hotspotId, uint16 actions, uint16 v3) {  
    739740
    740741void Script::randomToGeneral(uint16 maxVal, uint16 minVal, uint16 v3) {
    741742        Common::RandomSource rnd;
    742         g_system->getEventManager()->registerRandomSource(rnd, "lureScripts");
     743        g_eventRec.registerRandomSource(rnd, "lureScripts");
    743744        uint16 v = minVal + rnd.getRandomNumber(maxVal - minVal);
    744745        Resources::getReference().fieldList().setField(GENERAL, v);
    745746}
  • engines/m4/m4.cpp

    diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp
    index c27f151..b497300 100644
    a b  
    5353
    5454#include "common/file.h"
    5555#include "common/events.h"
     56#include "common/EventRecorder.h"
    5657#include "common/endian.h"
    5758#include "common/system.h"
    5859#include "common/config-manager.h"
    Common::Error M4Engine::run() {  
    192193        _animation = new Animation(this);
    193194        //_callbacks = new Callbacks(this);
    194195        _random = new Common::RandomSource();
    195         g_system->getEventManager()->registerRandomSource(*_random, "m4");
     196        g_eventRec.registerRandomSource(*_random, "m4");
    196197
    197198        if (isM4())
    198199                return goM4();
  • engines/made/made.cpp

    diff --git a/engines/made/made.cpp b/engines/made/made.cpp
    index 50a14c3..c83f7aa 100644
    a b  
    2424 */
    2525
    2626#include "common/events.h"
     27#include "common/EventRecorder.h"
    2728#include "common/keyboard.h"
    2829#include "common/file.h"
    2930#include "common/savefile.h"
    MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng  
    7475                        _gameId = g->id;
    7576
    7677        _rnd = new Common::RandomSource();
    77         syst->getEventManager()->registerRandomSource(*_rnd, "made");
     78        g_eventRec.registerRandomSource(*_rnd, "made");
    7879
    7980        int cd_num = ConfMan.getInt("cdrom");
    8081        if (cd_num >= 0)
  • engines/parallaction/parallaction.cpp

    diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
    index 7aee966..8fadd4e 100644
    a b  
    2525
    2626#include "common/config-manager.h"
    2727#include "common/events.h"
     28#include "common/EventRecorder.h"
    2829#include "common/file.h"
    2930#include "common/util.h"
    3031#include "common/system.h"
    Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam  
    7071        Common::addDebugChannel(kDebugMenu, "menu", "Menu debug level");
    7172        Common::addDebugChannel(kDebugInventory, "inventory", "Inventory debug level");
    7273
    73         syst->getEventManager()->registerRandomSource(_rnd, "parallaction");
     74        g_eventRec.registerRandomSource(_rnd, "parallaction");
    7475}
    7576
    7677
  • engines/queen/display.cpp

    diff --git a/engines/queen/display.cpp b/engines/queen/display.cpp
    index bac7c5f..ae223ff 100644
    a b  
    2525
    2626
    2727#include "common/system.h"
     28#include "common/EventRecorder.h"
    2829#include "common/events.h"
    2930
    3031#include "graphics/cursorman.h"
    Display::Display(QueenEngine *vm, OSystem *system)  
    7475        memset(&_dynalum, 0, sizeof(_dynalum));
    7576
    7677        setupInkColors();
    77         system->getEventManager()->registerRandomSource(_rnd, "queenDisplay");
     78        g_eventRec.registerRandomSource(_rnd, "queenDisplay");
    7879}
    7980
    8081Display::~Display() {
  • engines/queen/music.cpp

    diff --git a/engines/queen/music.cpp b/engines/queen/music.cpp
    index 8a50ae6..3d5bfbd 100644
    a b  
    2525
    2626#include "common/config-manager.h"
    2727#include "common/events.h"
     28#include "common/EventRecorder.h"
    2829
    2930#include "queen/music.h"
    3031#include "queen/queen.h"
    MidiMusic::MidiMusic(QueenEngine *vm)  
    8485        _parser->setMidiDriver(this);
    8586        _parser->setTimerRate(_driver->getBaseTempo());
    8687
    87         vm->getEventManager()->registerRandomSource(_rnd, "queenMusic");
     88        g_eventRec.registerRandomSource(_rnd, "queenMusic");
    8889}
    8990
    9091MidiMusic::~MidiMusic() {
  • engines/queen/queen.cpp

    diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp
    index ec07419..7c35184 100644
    a b  
    3131#include "common/savefile.h"
    3232#include "common/system.h"
    3333#include "common/events.h"
     34#include "common/EventRecorder.h"
    3435
    3536#include "queen/queen.h"
    3637#include "queen/bankman.h"
    namespace Queen {  
    193194
    194195QueenEngine::QueenEngine(OSystem *syst)
    195196        : Engine(syst), _debugger(0) {
    196         syst->getEventManager()->registerRandomSource(randomizer, "queen");
     197        g_eventRec.registerRandomSource(randomizer, "queen");
    197198}
    198199
    199200QueenEngine::~QueenEngine() {
  • engines/saga/saga.cpp

    diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp
    index 4acf93d..2a2a4b9 100644
    a b  
    2929#include "common/config-manager.h"
    3030#include "common/system.h"
    3131#include "common/events.h"
     32#include "common/EventRecorder.h"
    3233
    3334#include "sound/mixer.h"
    3435
    SagaEngine::SagaEngine(OSystem *syst, const SAGAGameDescription *gameDesc)  
    114115        Common::File::addDefaultDirectory(_gameDataDir.getChild("video"));
    115116
    116117        _displayClip.left = _displayClip.top = 0;
    117         syst->getEventManager()->registerRandomSource(_rnd, "saga");
     118        g_eventRec.registerRandomSource(_rnd, "saga");
    118119}
    119120
    120121SagaEngine::~SagaEngine() {
  • engines/scumm/scumm.cpp

    diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
    index dcbf95e..ebee61a 100644
    a b  
    2626#include "common/config-manager.h"
    2727#include "common/md5.h"
    2828#include "common/events.h"
     29#include "common/EventRecorder.h"
    2930#include "common/system.h"
    3031
    3132#include "gui/message.h"
    ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)  
    538539        for (int i = 0; i < ARRAYSIZE(debugChannels); ++i)
    539540                Common::addDebugChannel(debugChannels[i].flag,  debugChannels[i].channel, debugChannels[i].desc);
    540541
    541         syst->getEventManager()->registerRandomSource(_rnd, "scumm");
     542        g_eventRec.registerRandomSource(_rnd, "scumm");
    542543}
    543544
    544545
  • engines/sky/logic.cpp

    diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
    index ccfbfbb..67924d9 100644
    a b  
    2727#include "common/endian.h"
    2828#include "common/rect.h"
    2929#include "common/events.h"
     30#include "common/EventRecorder.h"
    3031#include "common/system.h"
    3132
    3233#include "sky/autoroute.h"
    void Logic::setupLogicTable() {  
    7374}
    7475
    7576Logic::Logic(SkyCompact *skyCompact, Screen *skyScreen, Disk *skyDisk, Text *skyText, MusicBase *skyMusic, Mouse *skyMouse, Sound *skySound) {
    76         g_system->getEventManager()->registerRandomSource(_rnd, "sky");
     77        g_eventRec.registerRandomSource(_rnd, "sky");
    7778
    7879        _skyCompact = skyCompact;
    7980        _skyScreen = skyScreen;
  • engines/sword1/logic.cpp

    diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
    index 7e911bd..be3797b 100644
    a b  
    2828#include "common/util.h"
    2929#include "common/system.h"
    3030#include "common/events.h"
     31#include "common/EventRecorder.h"
    3132
    3233#include "sword1/logic.h"
    3334#include "sword1/text.h"
    namespace Sword1 {  
    5556uint32 Logic::_scriptVars[NUM_SCRIPT_VARS];
    5657
    5758Logic::Logic(SwordEngine *vm, ObjectMan *pObjMan, ResMan *resMan, Screen *pScreen, Mouse *pMouse, Sound *pSound, Music *pMusic, Menu *pMenu, OSystem *system, Audio::Mixer *mixer) {
    58         g_system->getEventManager()->registerRandomSource(_rnd, "sword1");
     59        g_eventRec.registerRandomSource(_rnd, "sword1");
    5960
    6061        _vm = vm;
    6162        _objMan = pObjMan;
  • engines/sword1/sound.cpp

    diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp
    index 5577c66..ec79c29 100644
    a b  
    2828
    2929#include "common/util.h"
    3030#include "common/events.h"
     31#include "common/EventRecorder.h"
    3132#include "common/system.h"
    3233
    3334#include "sword1/sound.h"
    namespace Sword1 {  
    4748#define SPEECH_FLAGS (Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_LITTLE_ENDIAN)
    4849
    4950Sound::Sound(const char *searchPath, Audio::Mixer *mixer, ResMan *pResMan) {
    50         g_system->getEventManager()->registerRandomSource(_rnd, "sword1sound");
     51        g_eventRec.registerRandomSource(_rnd, "sword1sound");
    5152        strcpy(_filePath, searchPath);
    5253        _mixer = mixer;
    5354        _resMan = pResMan;
  • engines/sword2/sword2.cpp

    diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp
    index cf44b4c..e368f25 100644
    a b  
    3333#include "common/file.h"
    3434#include "common/fs.h"
    3535#include "common/events.h"
     36#include "common/EventRecorder.h"
    3637#include "common/savefile.h"
    3738#include "common/system.h"
    3839
    Sword2Engine::Sword2Engine(OSystem *syst) : Engine(syst) {  
    305306
    306307        _gmmLoadSlot = -1; // Used to manage GMM Loading
    307308
    308         syst->getEventManager()->registerRandomSource(_rnd, "sword2");
     309        g_eventRec.registerRandomSource(_rnd, "sword2");
    309310}
    310311
    311312Sword2Engine::~Sword2Engine() {
  • engines/tinsel/tinsel.cpp

    diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
    index 95541e3..5f05635 100644
    a b  
    2626#include "common/endian.h"
    2727#include "common/error.h"
    2828#include "common/events.h"
     29#include "common/EventRecorder.h"
    2930#include "common/keyboard.h"
    3031#include "common/file.h"
    3132#include "common/savefile.h"
    Common::Error TinselEngine::run() {  
    934935                _screenSurface.create(320, 200, 1);
    935936        }
    936937
    937         g_system->getEventManager()->registerRandomSource(_random, "tinsel");
     938        g_eventRec.registerRandomSource(_random, "tinsel");
    938939
    939940        _console = new Console();
    940941
  • engines/touche/touche.cpp

    diff --git a/engines/touche/touche.cpp b/engines/touche/touche.cpp
    index 5d79e0f..1a6546c 100644
    a b  
    2626
    2727#include "common/config-manager.h"
    2828#include "common/events.h"
     29#include "common/EventRecorder.h"
    2930#include "common/system.h"
    3031
    3132#include "graphics/cursorman.h"
    ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)  
    7374        Common::addDebugChannel(kDebugOpcodes,  "Opcodes",  "Opcodes debug level");
    7475        Common::addDebugChannel(kDebugMenu,     "Menu",     "Menu debug level");
    7576
    76         _eventMan->registerRandomSource(_rnd, "touche");
     77        g_eventRec.registerRandomSource(_rnd, "touche");
    7778}
    7879
    7980ToucheEngine::~ToucheEngine() {