[Scummvm-cvs-logs] scummvm master -> f621f6a5059ec619ae9ea1045548e62a27e99ab4

dhewg dhewg at wiibrew.org
Mon Feb 14 10:26:34 CET 2011


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
f621f6a505 SKY: get rid of timer based gfx updates


Commit: f621f6a5059ec619ae9ea1045548e62a27e99ab4
    https://github.com/scummvm/scummvm/commit/f621f6a5059ec619ae9ea1045548e62a27e99ab4
Author: dhewg (dhewg at wiibrew.org)
Date: 2011-02-14T01:18:38-08:00

Commit Message:
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.

Changed paths:
    engines/sky/intro.cpp
    engines/sky/screen.cpp
    engines/sky/screen.h
    engines/sky/sky.cpp
    engines/sky/sky.h



diff --git a/engines/sky/intro.cpp b/engines/sky/intro.cpp
index 129de9c..6455f3b 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 76b4b24..ab4ba1e 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 e587958..048f5c1 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 14d5746..c42bb63 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 58c9d1d..29e7c9a 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();
 };
 






More information about the Scummvm-git-logs mailing list