aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authordhewg2011-02-14 01:12:40 +0100
committerdhewg2011-02-14 10:18:38 +0100
commitf621f6a5059ec619ae9ea1045548e62a27e99ab4 (patch)
treec060868c9e9b9ed03d09234240c63da5de253a21 /engines
parent1e989c44ed13e63cd1d128be2250bd1eddaf3e40 (diff)
downloadscummvm-rg350-f621f6a5059ec619ae9ea1045548e62a27e99ab4.tar.gz
scummvm-rg350-f621f6a5059ec619ae9ea1045548e62a27e99ab4.tar.bz2
scummvm-rg350-f621f6a5059ec619ae9ea1045548e62a27e99ab4.zip
SKY: get rid of timer based gfx updates
on most platforms timers are implemented using threads. never ever make gfx updates from another thread other than the main one. seriously. replace the whole timer crap in sky with timestamp based updates. this fixes crashes when OpenGL is enabled (android included). needs more testing.
Diffstat (limited to 'engines')
-rw-r--r--engines/sky/intro.cpp14
-rw-r--r--engines/sky/screen.cpp62
-rw-r--r--engines/sky/screen.h6
-rw-r--r--engines/sky/sky.cpp14
-rw-r--r--engines/sky/sky.h2
5 files changed, 57 insertions, 41 deletions
diff --git a/engines/sky/intro.cpp b/engines/sky/intro.cpp
index 129de9c129..6455f3b15b 100644
--- a/engines/sky/intro.cpp
+++ b/engines/sky/intro.cpp
@@ -644,6 +644,7 @@ Intro::Intro(Disk *disk, Screen *screen, MusicBase *music, Sound *sound, Text *t
Intro::~Intro() {
if (_skyScreen->sequenceRunning())
_skyScreen->stopSequence();
+
free(_textBuf);
free(_saveBuf);
free(_bgBuf);
@@ -658,6 +659,7 @@ bool Intro::doIntro(bool floppyIntro) {
if (!escDelay(3000))
return false;
+
if (floppyIntro)
_skyMusic->startMusic(1);
@@ -817,6 +819,7 @@ bool Intro::floppyScrollFlirt() {
bool Intro::commandFlirt(uint16 *&data) {
_skyScreen->startSequence(*data++);
+
while ((*data != COMMANDEND) || _skyScreen->sequenceRunning()) {
while ((_skyScreen->seqFramesLeft() < *data)) {
data++;
@@ -844,11 +847,13 @@ bool Intro::commandFlirt(uint16 *&data) {
error("Unknown FLIRT command %X", command);
}
}
+
if (!escDelay(50)) {
_skyScreen->stopSequence();
return false;
}
}
+
data++; // move pointer over "COMMANDEND"
return true;
}
@@ -893,6 +898,7 @@ void Intro::restoreScreen() {
bool Intro::escDelay(uint32 msecs) {
Common::EventManager *eventMan = _system->getEventManager();
Common::Event event;
+
if (_relDelay == 0) // first call, init with system time
_relDelay = (int32)_system->getMillis();
@@ -911,11 +917,13 @@ bool Intro::escDelay(uint32 msecs) {
nDelay = _relDelay - _system->getMillis();
if (nDelay < 0)
nDelay = 0;
- else if (nDelay > 40)
- nDelay = 40;
+ else if (nDelay > 10)
+ nDelay = 10;
_system->delayMillis(nDelay);
+ _skyScreen->processSequence();
_system->updateScreen();
- } while (nDelay == 40);
+ } while (nDelay == 10);
+
return true;
}
diff --git a/engines/sky/screen.cpp b/engines/sky/screen.cpp
index 76b4b24f51..ab4ba1eb2a 100644
--- a/engines/sky/screen.cpp
+++ b/engines/sky/screen.cpp
@@ -86,7 +86,7 @@ Screen::Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact) {
_system->getPaletteManager()->setPalette(tmpPal, 0, VGA_COLOURS);
_currentPalette = 0;
- _seqInfo.framesLeft = 0;
+ _seqInfo.nextFrame = _seqInfo.framesLeft = 0;
_seqInfo.seqData = _seqInfo.seqDataPos = NULL;
_seqInfo.running = false;
}
@@ -348,7 +348,7 @@ void Screen::fnFadeUp(uint32 palNum, uint32 scroll) {
scrOldPtr += GAME_SCREEN_WIDTH;
}
showScreen(_scrollScreen);
- waitForTimer();
+ waitForTick();
}
showScreen(_currentScreen);
} else if (scroll == 321) { // scroll right (going left)
@@ -364,7 +364,7 @@ void Screen::fnFadeUp(uint32 palNum, uint32 scroll) {
scrOldPtr += GAME_SCREEN_WIDTH;
}
showScreen(_scrollScreen);
- waitForTimer();
+ waitForTick();
}
showScreen(_currentScreen);
}
@@ -374,37 +374,49 @@ void Screen::fnFadeUp(uint32 palNum, uint32 scroll) {
}
}
-void Screen::waitForTimer() {
+void Screen::waitForTick() {
+ uint32 start = _system->getMillis();
+ uint32 end = start + 20 - (start % 20);
+ uint32 remain;
+
Common::EventManager *eventMan = _system->getEventManager();
- _gotTick = false;
- while (!_gotTick) {
- Common::Event event;
+ Common::Event event;
+
+ while (true) {
+ start = _system->getMillis();
+
+ if (start >= end)
+ return;
- _system->delayMillis(10);
while (eventMan->pollEvent(event))
;
+
+ remain = end - start;
+ if (remain < 10) {
+ _system->delayMillis(remain);
+ return;
+ }
+
+ _system->delayMillis(10);
}
}
void Screen::waitForSequence() {
Common::EventManager *eventMan = _system->getEventManager();
+ Common::Event event;
+
while (_seqInfo.running) {
- Common::Event event;
+ processSequence();
- _system->delayMillis(20);
+ _system->delayMillis(10);
while (eventMan->pollEvent(event))
;
}
}
-void Screen::handleTimer() {
- _gotTick = true;
- if (_seqInfo.running)
- processSequence();
-}
-
void Screen::startSequence(uint16 fileNum) {
_seqInfo.seqData = _skyDisk->loadFile(fileNum);
+ _seqInfo.nextFrame = _system->getMillis();
_seqInfo.framesLeft = _seqInfo.seqData[0];
_seqInfo.seqDataPos = _seqInfo.seqData + 1;
_seqInfo.delay = SEQ_DELAY;
@@ -414,6 +426,7 @@ void Screen::startSequence(uint16 fileNum) {
void Screen::startSequenceItem(uint16 itemNum) {
_seqInfo.seqData = (uint8 *)SkyEngine::fetchItem(itemNum);
+ _seqInfo.nextFrame = _system->getMillis();
_seqInfo.framesLeft = _seqInfo.seqData[0] - 1;
_seqInfo.seqDataPos = _seqInfo.seqData + 1;
_seqInfo.delay = SEQ_DELAY;
@@ -423,21 +436,29 @@ void Screen::startSequenceItem(uint16 itemNum) {
void Screen::stopSequence() {
_seqInfo.running = false;
- waitForTimer();
- waitForTimer();
- _seqInfo.framesLeft = 0;
+ waitForTick();
+ waitForTick();
+ _seqInfo.nextFrame = _seqInfo.framesLeft = 0;
free(_seqInfo.seqData);
_seqInfo.seqData = _seqInfo.seqDataPos = NULL;
}
void Screen::processSequence() {
- uint32 screenPos = 0;
+ if (!_seqInfo.running)
+ return;
+
+ if (_system->getMillis() < _seqInfo.nextFrame)
+ return;
_seqInfo.delay--;
if (_seqInfo.delay == 0) {
_seqInfo.delay = SEQ_DELAY;
+ _seqInfo.nextFrame += 20 * SEQ_DELAY;
+
memset(_seqGrid, 0, 12 * 20);
+ uint32 screenPos = 0;
+
uint8 nrToSkip, nrToDo, cnt;
do {
do {
@@ -445,6 +466,7 @@ void Screen::processSequence() {
_seqInfo.seqDataPos++;
screenPos += nrToSkip;
} while (nrToSkip == 0xFF);
+
do {
nrToDo = _seqInfo.seqDataPos[0];
_seqInfo.seqDataPos++;
diff --git a/engines/sky/screen.h b/engines/sky/screen.h
index e587958c7b..048f5c1e3e 100644
--- a/engines/sky/screen.h
+++ b/engines/sky/screen.h
@@ -75,6 +75,7 @@ public:
void startSequenceItem(uint16 itemNum);
void stopSequence();
bool sequenceRunning() { return _seqInfo.running; }
+ void processSequence();
void waitForSequence();
uint32 seqFramesLeft() { return _seqInfo.framesLeft; }
uint8 *giveCurrent() { return _currentScreen; }
@@ -105,14 +106,13 @@ private:
uint32 _currentPalette;
uint8 _seqGrid[20 * 12];
- bool volatile _gotTick;
- void waitForTimer();
- void processSequence();
+ void waitForTick();
uint8 *_gameGrid;
uint8 *_currentScreen;
uint8 *_scrollScreen;
struct {
+ uint32 nextFrame;
uint32 framesLeft;
uint32 delay;
uint8 *seqData;
diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp
index 14d57465af..c42bb6301e 100644
--- a/engines/sky/sky.cpp
+++ b/engines/sky/sky.cpp
@@ -84,8 +84,6 @@ SkyEngine::SkyEngine(OSystem *syst)
}
SkyEngine::~SkyEngine() {
- _timer->removeTimerProc(&timerHandler);
-
delete _skyLogic;
delete _skySound;
delete _skyMusic;
@@ -207,6 +205,7 @@ Common::Error SkyEngine::go() {
}
_skyLogic->engine();
+ _skyScreen->processSequence();
_skyScreen->recreate();
_skyScreen->spriteEngine();
if (_debugger->showGrid()) {
@@ -300,9 +299,6 @@ Common::Error SkyEngine::init() {
_skyLogic = new Logic(_skyCompact, _skyScreen, _skyDisk, _skyText, _skyMusic, _skyMouse, _skySound);
_skyMouse->useLogicInstance(_skyLogic);
- // initialize timer *after* _skyScreen has been initialized.
- _timer->installTimerProc(&timerHandler, 1000000 / 50, this); //call 50 times per second
-
_skyControl = new Control(_saveFileMan, _skyScreen, _skyDisk, _skyMouse, _skyText, _skyMusic, _skyLogic, _skySound, _skyCompact, _system);
_skyLogic->useControlInstance(_skyControl);
@@ -386,14 +382,6 @@ void *SkyEngine::fetchItem(uint32 num) {
return _itemList[num];
}
-void SkyEngine::timerHandler(void *refCon) {
- ((SkyEngine *)refCon)->gotTimerTick();
-}
-
-void SkyEngine::gotTimerTick() {
- _skyScreen->handleTimer();
-}
-
void SkyEngine::delay(int32 amount) {
Common::Event event;
diff --git a/engines/sky/sky.h b/engines/sky/sky.h
index 58c9d1de11..29e7c9ab42 100644
--- a/engines/sky/sky.h
+++ b/engines/sky/sky.h
@@ -121,8 +121,6 @@ protected:
void initItemList();
void initVirgin();
- static void timerHandler(void *ptr);
- void gotTimerTick();
void loadFixedItems();
};