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

sylvaintv sylvaintv at gmail.com
Tue Mar 8 01:08:20 CET 2011


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

Summary:
53d6a4f831 TOON: Decrease CPU usage
b2a72da651 Merge branch 'master' of github.com:scummvm/scummvm


Commit: 53d6a4f831c9e7c7de594cdaed3c8546b41ea2e2
    https://github.com/scummvm/scummvm/commit/53d6a4f831c9e7c7de594cdaed3c8546b41ea2e2
Author: sylvaintv (sylvaintv at gmail.com)
Date: 2011-03-07T15:51:21-08:00

Commit Message:
TOON: Decrease CPU usage

Added dirty rects
Reduced the max FPS from 60 to 30

Changed paths:
    engines/toon/anim.cpp
    engines/toon/font.cpp
    engines/toon/movie.cpp
    engines/toon/picture.cpp
    engines/toon/picture.h
    engines/toon/script_func.cpp
    engines/toon/toon.cpp
    engines/toon/toon.h



diff --git a/engines/toon/anim.cpp b/engines/toon/anim.cpp
index 2e63d89..6d0d75f 100644
--- a/engines/toon/anim.cpp
+++ b/engines/toon/anim.cpp
@@ -151,6 +151,8 @@ void Animation::drawFrame(Graphics::Surface &surface, int32 frame, int32 xx, int
 	int32 offsX = 0;
 	int32 offsY = 0;
 
+	_vm->addDirtyRect(xx + _x1 + _frames[frame]._x1, yy + _y1 + _frames[frame]._y1, xx + rectX + _x1 + _frames[frame]._x1 , yy + rectY + _y1 + _frames[frame]._y1);
+
 	if (xx + _x1 + _frames[frame]._x1 < 0) {
 		offsX = -(xx + _x1 + _frames[frame]._x1);
 	}
@@ -212,6 +214,7 @@ void Animation::drawFrameWithMaskAndScale(Graphics::Surface &surface, int32 fram
 	int32 finalWidth = rectX * scale / 1024;
 	int32 finalHeight = rectY * scale / 1024;
 
+
 	// compute final x1,y1,x2,y2
 	int32 xx1 = xx + _x1 + _frames[frame]._x1 * scale / 1024;
 	int32 yy1 = yy + _y1 + _frames[frame]._y1 * scale / 1024;
@@ -221,6 +224,9 @@ void Animation::drawFrameWithMaskAndScale(Graphics::Surface &surface, int32 fram
 // Strangerke - Commented (not used)
 //	int32 h = _frames[frame]._y2 - _frames[frame]._y1;
 
+	_vm->addDirtyRect(xx1,yy1,xx2,yy2);
+
+
 	int32 destPitch = surface.pitch;
 	int32 destPitchMask = mask->getWidth();
 	uint8 *c = _frames[frame]._data;
diff --git a/engines/toon/font.cpp b/engines/toon/font.cpp
index 8455ca7..53786f8 100644
--- a/engines/toon/font.cpp
+++ b/engines/toon/font.cpp
@@ -81,6 +81,8 @@ void FontRenderer::renderText(int32 x, int32 y, Common::String origText, int32 m
 		x -= xx / 2;
 	}
 
+	_vm->addDirtyRect(x,y,x+xx,y+yy);
+
 	int32 curX = x;
 	int32 curY = y;
 	int32 height = 0;
@@ -270,9 +272,13 @@ void FontRenderer::renderMultiLineText(int32 x, int32 y, Common::String origText
 	int32 curX = x;
 	int32 curY = y;
 
+
+
 	for (int32 i = 0; i < numLines; i++) {
 		const byte *line = lines[i];
 		curX = x - lineSize[i] / 2;
+		_vm->addDirtyRect(curX + _vm->state()->_currentScrollValue, y, curX + lineSize[i] + _vm->state()->_currentScrollValue, curY + height);
+		
 		while (*line) {
 			byte curChar = textToFont(*line);
 			if (curChar != 32) _currentFont->drawFontFrame(_vm->getMainSurface(), curChar, curX + _vm->state()->_currentScrollValue, curY, _currentFontColor);
diff --git a/engines/toon/movie.cpp b/engines/toon/movie.cpp
index bf4b663..68c09fb 100644
--- a/engines/toon/movie.cpp
+++ b/engines/toon/movie.cpp
@@ -135,11 +135,13 @@ bool Movie::playVideo(bool isFirstIntroVideo) {
 		Common::Event event;
 		while (_vm->getSystem()->getEventManager()->pollEvent(event))
 			if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
+				_vm->dirtyAllScreen();
 				return false;
 			}
 
 		_vm->getSystem()->delayMillis(10);
 	}
+	_vm->dirtyAllScreen();
 	return !_vm->shouldQuit();
 }
 
diff --git a/engines/toon/picture.cpp b/engines/toon/picture.cpp
index 18e6a8c..fce7117 100644
--- a/engines/toon/picture.cpp
+++ b/engines/toon/picture.cpp
@@ -187,6 +187,44 @@ void Picture::drawMask(Graphics::Surface &surface, int32 x, int32 y, int32 dx, i
 	}
 }
 
+void Picture::drawWithRectList(Graphics::Surface& surface, int32 x, int32 y, int32 dx, int32 dy, Common::Array<Common::Rect>& rectArray) {
+
+	int32 rx = MIN(_width, surface.w - x);
+	int32 ry = MIN(_height, surface.h - y);
+
+	if (rx < 0 || ry < 0)
+		return;
+
+	int32 destPitch = surface.pitch;
+	int32 srcPitch = _width;
+
+	for (uint32 i = 0; i < rectArray.size(); i++) {
+
+		Common::Rect rect = rectArray[i];
+
+		int32 fillRx = MIN<int32>(rx, rect.right - rect.left);
+		int32 fillRy = MIN<int32>(ry, rect.bottom - rect.top);
+
+		uint8 *c = _data + _width * (dy + rect.top) + (dx + rect.left);
+		uint8 *curRow = (uint8 *)surface.pixels + (y + rect.top) * destPitch + (x + rect.left);
+
+		for (int32 yy = 0; yy < fillRy; yy++) {
+			uint8 *curSrc = c;
+			uint8 *cur = curRow;
+			for (int32 xx = 0; xx < fillRx; xx++) {
+				*cur = *curSrc;
+				curSrc++;
+				cur++;
+			}
+			curRow += destPitch;
+			c += srcPitch;
+		}
+
+	}
+
+	
+}
+
 void Picture::draw(Graphics::Surface &surface, int32 x, int32 y, int32 dx, int32 dy) {
 	debugC(6, kDebugPicture, "draw(surface, %d, %d, %d, %d)", x, y, dx, dy);
 
diff --git a/engines/toon/picture.h b/engines/toon/picture.h
index 1b0fd7f..6aca408 100644
--- a/engines/toon/picture.h
+++ b/engines/toon/picture.h
@@ -44,6 +44,7 @@ public:
 	bool loadPicture(Common::String file, bool totalPalette = false);
 	void setupPalette();
 	void draw(Graphics::Surface &surface, int32 x, int32 y, int32 dx, int32 dy);
+	void drawWithRectList(Graphics::Surface& surface, int32 x, int32 y, int32 dx, int32 dy, Common::Array<Common::Rect>& rectArray);
 	void drawMask(Graphics::Surface &surface, int32 x, int32 y, int32 dx, int32 dy);
 	void drawLineOnMask(int32 x, int32 y, int32 x2, int32 y2, bool walkable);
 	void floodFillNotWalkableOnMask(int32 x, int32 y);
diff --git a/engines/toon/script_func.cpp b/engines/toon/script_func.cpp
index adf3a1c..84225ec 100644
--- a/engines/toon/script_func.cpp
+++ b/engines/toon/script_func.cpp
@@ -1028,7 +1028,7 @@ int32 ScriptFunc::sys_Cmd_Draw_Scene_Anim_WSA_Frame(EMCState *state) {
 		else if (animId == 20 || animId == 15 || animId == 21 || animId == 16 || animId == 17 || animId == 18)
 			_vm->pauseSceneAnimationScript(_vm->getCurrentUpdatingSceneAnimation(), 1);
 		else if (animId == 9) {
-			_vm->pauseSceneAnimationScript(_vm->getCurrentUpdatingSceneAnimation(), 6);
+			_vm->pauseSceneAnimationScript(_vm->getCurrentUpdatingSceneAnimation(), 3);
 		}
 	}
 
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp
index cc694cb..b4335d7 100644
--- a/engines/toon/toon.cpp
+++ b/engines/toon/toon.cpp
@@ -378,10 +378,21 @@ void ToonEngine::updateTimer(int32 timeIncrement) {
 }
 
 void ToonEngine::render() {
-	if (_gameState->_inCutaway)
-		_currentCutaway->draw(*_mainSurface, 0, 0, 0, 0);
-	else
-		_currentPicture->draw(*_mainSurface, 0, 0, 0, 0);
+
+	if (_dirtyAll) {
+		if (_gameState->_inCutaway)
+			_currentCutaway->draw(*_mainSurface, 0, 0, 0, 0);
+		else
+			_currentPicture->draw(*_mainSurface, 0, 0, 0, 0);
+		_dirtyRects.push_back(Common::Rect(0, 0, 1280, 400));
+	} else {
+		if (_gameState->_inCutaway)
+			_currentCutaway->drawWithRectList(*_mainSurface, 0, 0, 0, 0, _dirtyRects);
+		else
+			_currentPicture->drawWithRectList(*_mainSurface, 0, 0, 0, 0, _dirtyRects);
+	}
+
+	clearDirtyRects();
 
 	//_currentMask->drawMask(*_mainSurface,0,0,0,0);
 	_animationManager->render();
@@ -422,8 +433,8 @@ void ToonEngine::render() {
 	// add a little sleep here
 	int32 newMillis = (int32)_system->getMillis();
 	int32 sleepMs = 1; // Minimum delay to allow thread scheduling
-	if ((newMillis - _lastRenderTime)  < _tickLength)
-		sleepMs = _tickLength - (newMillis - _lastRenderTime);
+	if ((newMillis - _lastRenderTime)  < _tickLength * 2)
+		sleepMs = _tickLength * 2 - (newMillis - _lastRenderTime);
 	assert(sleepMs >= 0);
 	_system->delayMillis(sleepMs);
 	_lastRenderTime = _system->getMillis();
@@ -484,7 +495,51 @@ void ToonEngine::copyToVirtualScreen(bool updateScreen) {
 		_cursorAnimationInstance->setPosition(_mouseX - 40 + state()->_currentScrollValue - _cursorOffsetX, _mouseY - 40 - _cursorOffsetY, 0, false);
 		_cursorAnimationInstance->render();
 	}
-	_system->copyRectToScreen((byte *)_mainSurface->pixels + state()->_currentScrollValue, 1280, 0, 0, 640, 400);
+	
+
+	// Handle dirty rects here
+	static int32 lastScroll = 0;
+
+	if (_dirtyAll || _gameState->_currentScrollValue != lastScroll) {
+		// we have to refresh everything in case of scrolling.
+		_system->copyRectToScreen((byte *)_mainSurface->pixels + state()->_currentScrollValue, 1280, 0, 0, 640, 400);
+	} else {
+
+		int32 offX = 0;
+		for (uint i = 0; i < _oldDirtyRects.size(); i++) {
+			Common::Rect rect = _oldDirtyRects[i];
+			rect.translate(-state()->_currentScrollValue,0);
+			offX = 0;
+			if(rect.right <= 0) 
+				continue;
+			if (rect.left < 0) {
+				offX = -rect.left;
+				rect.left = 0;
+			}
+			rect.clip(640, 400);
+			if (rect.left >= 0 && rect.top >= 0 && rect.right - rect.left > 0 && rect.bottom - rect.top > 0) {
+				_system->copyRectToScreen((byte *)_mainSurface->pixels + _oldDirtyRects[i].left + offX + _oldDirtyRects[i].top * 1280, 1280, rect.left , rect.top, rect.right - rect.left, rect.bottom - rect.top);
+			}
+		}
+
+		for (uint i = 0; i < _dirtyRects.size(); i++) {
+			Common::Rect rect = _dirtyRects[i];
+			rect.translate(-state()->_currentScrollValue,0);
+			offX = 0;
+			if (rect.right <= 0) 
+				continue;
+			if (rect.left < 0) {
+				offX = -rect.left;
+				rect.left = 0;
+			}
+			rect.clip(640, 400);
+			if (rect.left >= 0 && rect.top >= 0 && rect.right - rect.left > 0 && rect.bottom - rect.top > 0) {
+				_system->copyRectToScreen((byte *)_mainSurface->pixels + _dirtyRects[i].left + offX + _dirtyRects[i].top * 1280, 1280, rect.left , rect.top, rect.right - rect.left, rect.bottom - rect.top);
+			}
+		}
+	}
+	lastScroll = _gameState->_currentScrollValue;
+
 	if (updateScreen) {
 		_system->updateScreen();
 		_shouldQuit = shouldQuit();	// update game quit flag - this shouldn't be called all the time, as it's a virtual function
@@ -589,6 +644,7 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
 	bool musicPlaying = false;
 
 	_gameState->_inMenu = true;
+	dirtyAllScreen();
 
 	while (!doExit) {
 		clickingOn = MAINMENUHOTSPOT_NONE;
@@ -607,7 +663,15 @@ bool ToonEngine::showMainmenu(bool &loadedGame) {
 		}
 
 		while (!clickRelease) {
-			mainmenuPicture->draw(*_mainSurface, 0, 0, 0, 0);
+			
+			if(_dirtyAll) {
+				mainmenuPicture->draw(*_mainSurface, 0, 0, 0, 0);
+				addDirtyRect(0,0,640,400);
+			} else {
+				mainmenuPicture->drawWithRectList(*_mainSurface, 0, 0, 0, 0, _dirtyRects);
+			}
+
+			clearDirtyRects();
 
 			for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; entryNr++) {
 				if (entries[entryNr].menuMask & menuMask) {
@@ -1211,6 +1275,9 @@ void ToonEngine::loadScene(int32 SceneId, bool forGameLoad) {
 
 	state()->_mouseHidden = false;
 
+	clearDirtyRects();
+	dirtyAllScreen();
+
 	if (!forGameLoad) {
 
 		_script->start(&_scriptState[0], 0);
@@ -2562,7 +2629,13 @@ void ToonEngine::renderInventory() {
 	if (!_gameState->_inInventory)
 		return;
 
-	_inventoryPicture->draw(*_mainSurface, 0, 0, 0, 0);
+	if (!_dirtyAll) {
+		_inventoryPicture->drawWithRectList(*_mainSurface, 0, 0, 0, 0, _dirtyRects);
+	} else {
+		_inventoryPicture->draw(*_mainSurface, 0, 0, 0, 0);
+		_dirtyRects.push_back(Common::Rect(0,0,640,400));
+	}
+	clearDirtyRects();
 
 	// draw items on screen
 	for (int32 i = 0; i < _gameState->_numInventoryItems; i++) {
@@ -2597,6 +2670,7 @@ int32 ToonEngine::showInventory() {
 	fadeOut(5);
 	_inventoryPicture->loadPicture("SACK128.CPS", true);
 	_inventoryPicture->setupPalette();
+	dirtyAllScreen();
 
 	if (_gameState->_mouseState >= 0) {
 		setCursor(_gameState->_mouseState, true, -18, -14);
@@ -2710,6 +2784,7 @@ int32 ToonEngine::showInventory() {
 		setupGeneralPalette();
 	}
 	flushPalette();
+	dirtyAllScreen();
 	_firstFrame = true;
 
 	return 0;
@@ -2784,6 +2859,7 @@ void ToonEngine::showCutaway(Common::String cutawayPicture) {
 	_currentCutaway->setupPalette();
 	_oldScrollValue = _gameState->_currentScrollValue;
 	_gameState->_currentScrollValue = 0;
+	dirtyAllScreen();
 	flushPalette();
 }
 
@@ -2794,6 +2870,7 @@ void ToonEngine::hideCutaway() {
 	_gameState->_currentScrollValue = _oldScrollValue;
 	_currentCutaway = 0;
 	_currentPicture->setupPalette();
+	dirtyAllScreen();
 	flushPalette();
 }
 
@@ -4673,6 +4750,47 @@ void ToonEngine::playRoomMusic() {
 	_audioManager->playMusic(_gameState->_locations[_gameState->_currentScene]._name, _gameState->_locations[_gameState->_currentScene]._music);
 }
 
+void ToonEngine::dirtyAllScreen()
+{
+	_dirtyRects.clear();
+	_dirtyAll = true;
+}
+
+void ToonEngine::addDirtyRect( int32 left, int32 top, int32 right, int32 bottom ) {
+	left = MAX<int32>(left, 0);
+	right = MIN<int32>(right, 1280);
+	top = MAX<int32>(top, 0);
+	bottom = MIN<int32>(bottom, 400);
+
+	Common::Rect rect(left,top,right,bottom);
+
+	if (bottom - top <= 0 || right - left <= 0) 
+		return;
+
+	for (uint32 i = 0; i < _dirtyRects.size(); i++) {
+		if (_dirtyRects[i].contains(rect))
+			return;
+		if (rect.contains(_dirtyRects[i])) {
+			_dirtyRects.remove_at(i);
+			i--;
+		}
+	}
+
+	// check also in the old rect (of the old frame)
+	for (int32 i = _oldDirtyRects.size() - 1 ; i >= 0; i--) {
+		if (rect.contains(_oldDirtyRects[i])) {
+			_oldDirtyRects.remove_at(i);
+		}
+	}
+
+	_dirtyRects.push_back(rect);
+}
+
+void ToonEngine::clearDirtyRects() {
+	_oldDirtyRects = _dirtyRects;
+	_dirtyRects.clear();
+	_dirtyAll = false;
+}
 void SceneAnimation::save(ToonEngine *vm, Common::WriteStream *stream) {
 	stream->writeByte(_active);
 	stream->writeSint32BE(_id);
diff --git a/engines/toon/toon.h b/engines/toon/toon.h
index f3370ae..dca6bfe 100644
--- a/engines/toon/toon.h
+++ b/engines/toon/toon.h
@@ -334,6 +334,10 @@ public:
 			(f == kSupportsSavingDuringRuntime);
 	}
 
+	void dirtyAllScreen();
+	void addDirtyRect(int32 left, int32 top, int32 right, int32 bottom);
+	void clearDirtyRects();
+
 protected:
 	OSystem *_system;
 	int32 _tickLength;
@@ -371,6 +375,11 @@ protected:
 	bool _updatingSceneScriptRunFlag;
 
 	Graphics::Surface *_mainSurface;
+	Common::Array<Common::Rect> _dirtyRects;
+	Common::Array<Common::Rect> _oldDirtyRects;
+
+	bool _dirtyAll;
+	
 
 	AnimationInstance *_cursorAnimationInstance;
 	Animation *_cursorAnimation;


Commit: b2a72da6518b30a58a1257ff7217185ae5683628
    https://github.com/scummvm/scummvm/commit/b2a72da6518b30a58a1257ff7217185ae5683628
Author: sylvaintv (sylvaintv at gmail.com)
Date: 2011-03-07T15:54:40-08:00

Commit Message:
Merge branch 'master' of github.com:scummvm/scummvm

Changed paths:
  A common/winexe.cpp
  A common/winexe.h
  A common/winexe_ne.cpp
  A common/winexe_ne.h
  A common/winexe_pe.cpp
  A common/winexe_pe.h
  A graphics/wincursor.cpp
  A graphics/wincursor.h
  R common/ne_exe.cpp
  R common/ne_exe.h
  R engines/mohawk/riven_cursors.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/platform/android/android.cpp
    backends/platform/android/android.h
    backends/platform/android/gfx.cpp
    backends/platform/android/jni.cpp
    backends/platform/android/texture.cpp
    backends/platform/android/texture.h
    common/macresman.cpp
    common/macresman.h
    common/module.mk
    engines/hugo/detection.cpp
    engines/hugo/file.cpp
    engines/hugo/hugo.cpp
    engines/hugo/hugo.h
    engines/hugo/intro.cpp
    engines/hugo/menu.cpp
    engines/hugo/parser.cpp
    engines/hugo/parser_v1d.cpp
    engines/hugo/parser_v1w.cpp
    engines/hugo/parser_v2d.cpp
    engines/hugo/parser_v3d.cpp
    engines/mohawk/cursors.cpp
    engines/mohawk/cursors.h
    engines/mohawk/myst.cpp
    engines/mohawk/myst.h
    engines/mohawk/riven.cpp
    engines/mohawk/riven_external.cpp
    engines/mohawk/riven_scripts.cpp
    engines/sci/console.cpp
    engines/sci/engine/gc.cpp
    engines/sci/engine/kmisc.cpp
    engines/sci/engine/vm_types.cpp
    engines/sci/engine/workarounds.cpp
    engines/sci/graphics/cursor.cpp
    engines/sci/graphics/helpers.h
    engines/sci/graphics/palette.cpp
    engines/sci/graphics/picture.cpp
    engines/sci/graphics/view.cpp
    engines/sci/resource.cpp
    engines/scumm/he/resource_he.cpp
    engines/scumm/he/resource_he.h
    graphics/fonts/winfont.cpp
    graphics/fonts/winfont.h
    graphics/module.mk









More information about the Scummvm-git-logs mailing list