[Scummvm-cvs-logs] scummvm master -> 82b2b2d65d0398cb1f3a17f421cbf78f52286faa

dreammaster dreammaster at scummvm.org
Thu Sep 4 04:10:52 CEST 2014


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:
82b2b2d65d MADS: Properly implement drawing to a subset of the screen


Commit: 82b2b2d65d0398cb1f3a17f421cbf78f52286faa
    https://github.com/scummvm/scummvm/commit/82b2b2d65d0398cb1f3a17f421cbf78f52286faa
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2014-09-03T22:09:50-04:00

Commit Message:
MADS: Properly implement drawing to a subset of the screen

Changed paths:
    engines/mads/messages.cpp
    engines/mads/msurface.h
    engines/mads/nebular/dialogs_nebular.cpp
    engines/mads/nebular/dialogs_nebular.h
    engines/mads/nebular/menu_nebular.cpp
    engines/mads/scene.cpp
    engines/mads/scene.h
    engines/mads/screen.cpp
    engines/mads/screen.h
    engines/mads/sprites.cpp



diff --git a/engines/mads/messages.cpp b/engines/mads/messages.cpp
index d416960..e83b69d 100644
--- a/engines/mads/messages.cpp
+++ b/engines/mads/messages.cpp
@@ -546,8 +546,7 @@ void TextDisplayList::draw(MSurface *s) {
 	for (uint idx = 0; idx < size(); ++idx) {
 		TextDisplay &td = (*this)[idx];
 		if (td._active && (td._expire >= 0)) {
-			Common::Point destPos(td._bounds.left + _vm->_screen._offset.x,
-				td._bounds.top + _vm->_screen._offset.y);
+			Common::Point destPos(td._bounds.left, td._bounds.top);
 			td._font->setColors(0xFF, td._color1, td._color2, 0);
 			td._font->writeString(s, td._msg, destPos, td._spacing, td._bounds.width());
 		}
diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h
index cd6bde1..3a5bf22 100644
--- a/engines/mads/msurface.h
+++ b/engines/mads/msurface.h
@@ -51,10 +51,9 @@ struct SpriteInfo {
  * MADS graphics surface
  */
 class MSurface : public Graphics::Surface {
-private:
-	bool _freeFlag;
 protected:
 	static MADSEngine *_vm;
+	bool _freeFlag;
 public:
 	/**
 	 * Sets the engine refrence used all surfaces
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp
index 5b0fb7b..ff11953 100644
--- a/engines/mads/nebular/dialogs_nebular.cpp
+++ b/engines/mads/nebular/dialogs_nebular.cpp
@@ -346,7 +346,6 @@ void DialogsNebular::showScummVMSaveDialog() {
 		}
 
 		scene->_spriteSlots.reset();
-		_vm->_screen._offset.y = 0;
 		scene->loadScene(scene->_currentSceneId, game._aaName, true);
 		scene->_userInterface.noInventoryAnim();
 		game._scene.drawElements(kTransitionFadeIn, false);
@@ -560,7 +559,8 @@ FullScreenDialog::FullScreenDialog(MADSEngine *vm) : _vm(vm) {
 }
 
 FullScreenDialog::~FullScreenDialog() {
-	_vm->_screen._offset.y = 0;
+	_vm->_screen.resetClipBounds();
+	_vm->_game->_scene.restrictScene();
 }
 
 void FullScreenDialog::display() {
@@ -577,7 +577,6 @@ void FullScreenDialog::display() {
 	scene._currentSceneId = currentSceneId;
 	scene._nextSceneId = nextSceneId;
 
-	_vm->_screen._offset.y = 22;
 	_vm->_events->initVars();
 	game._kernelMode = KERNEL_ROOM_INIT;
 
@@ -590,11 +589,7 @@ void FullScreenDialog::display() {
 		_vm->_palette->fadeOut(pal, nullptr, 0, PALETTE_COUNT, 0, 1, 1, 16);
 	}
 
-	_vm->_screen.empty();
-	_vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2);
-	_vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2);
-	game._scene._spriteSlots.fullRefresh();
-
+	// Set Fx state and palette entries
 	game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ? kTransitionFadeIn : kCenterVertTransition;
 	game._trigger = 0;
 
@@ -604,6 +599,18 @@ void FullScreenDialog::display() {
 	_vm->_palette->setEntry(13, 45, 45, 0);
 	_vm->_palette->setEntry(14, 63, 63, 63);
 	_vm->_palette->setEntry(15, 45, 45, 45);
+
+
+	// Clear the screen and draw the upper and lower horizontal lines
+	_vm->_screen.empty();
+	_vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2);
+	_vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2);
+	_vm->_screen.copyRectToScreen(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
+
+	// Restrict the screen to the area between the two lines
+	_vm->_screen.setClipBounds(Common::Rect(0, DIALOG_TOP, MADS_SCREEN_WIDTH,
+		DIALOG_TOP + MADS_SCENE_HEIGHT));
+	_vm->_game->_scene.restrictScene();
 }
 
 /*------------------------------------------------------------------------*/
@@ -667,7 +674,7 @@ void GameDialog::display() {
 }
 
 GameDialog::~GameDialog() {
-	_vm->_screen._offset.y = 0;
+	_vm->_screen.resetClipBounds();
 }
 
 void GameDialog::clearLines() {
@@ -868,10 +875,11 @@ void GameDialog::handleEvents() {
 	_vm->_events->pollEvents();
 
 	// Scan for objects in the dialog
-	int objIndex = screenObjects.scan(events.currentPos() - _vm->_screen._offset, LAYER_GUI);
+	Common::Point mousePos = events.currentPos() - Common::Point(0, DIALOG_TOP);
+	int objIndex = screenObjects.scan(mousePos, LAYER_GUI);
 
 	if (_movedFlag) {
-		int yp = events.currentPos().y - _vm->_screen._offset.y;
+		int yp = mousePos.y;
 		if (yp < screenObjects[1]._bounds.top) {
 			if (!events._mouseReleased)
 				_lines[1]._state = DLGSTATE_SELECTED;
diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h
index 1468db3..f64f992 100644
--- a/engines/mads/nebular/dialogs_nebular.h
+++ b/engines/mads/nebular/dialogs_nebular.h
@@ -31,6 +31,8 @@ namespace MADS {
 
 namespace Nebular {
 
+#define DIALOG_TOP 22
+
 enum CapitalizationMode { kUppercase = 0, kLowercase = 1, kUpperAndLower = 2 };
 
 class DialogsNebular : public Dialogs {
diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp
index b0b0c5e..d5a1d85 100644
--- a/engines/mads/nebular/menu_nebular.cpp
+++ b/engines/mads/nebular/menu_nebular.cpp
@@ -35,7 +35,6 @@ namespace Nebular {
 #define NEBULAR_MENUSCREEN 990
 #define MADS_MENU_Y ((MADS_SCREEN_HEIGHT - MADS_SCENE_HEIGHT) / 2)
 #define MADS_MENU_ANIM_DELAY 70
-#define DIALOG_TOP 22
 
 MenuView::MenuView(MADSEngine *vm) : FullScreenDialog(vm) {
 	_breakFlag = false;
@@ -57,7 +56,6 @@ void MenuView::show() {
 	while (!_breakFlag && !_vm->shouldQuit()) {
 		if (_redrawFlag) {
 			_vm->_game->_scene.drawElements(_vm->_game->_fx, _vm->_game->_fx);
-			_vm->_screen.copyRectToScreen(Common::Rect(0, 0, 320, 200));
 			_redrawFlag = false;
 		}
 
@@ -111,10 +109,10 @@ void MainMenu::display() {
 		// Register the menu item area in the screen objects
 		MSprite *frame0 = _menuItems[i]->getFrame(0);
 		Common::Point pt(frame0->_offset.x - (frame0->w / 2),
-			frame0->_offset.y - frame0->h + _vm->_screen._offset.y);
+			frame0->_offset.y - frame0->h);
 		screenObjects.add(
-			Common::Rect(pt.x, pt.y, pt.x + frame0->w, pt.y + frame0->h),
-			LAYER_GUI, CAT_COMMAND, i);
+			Common::Rect(pt.x, pt.y + DIALOG_TOP, pt.x + frame0->w, 
+			pt.y + frame0->h + DIALOG_TOP), LAYER_GUI, CAT_COMMAND, i);
 	}
 
 	// Set the cursor for when it's shown
diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp
index cb68d38..ad24dd4 100644
--- a/engines/mads/scene.cpp
+++ b/engines/mads/scene.cpp
@@ -63,8 +63,7 @@ Scene::Scene(MADSEngine *vm)
 	_paletteUsageF.push_back(PaletteUsage::UsageEntry(0xF));
 
 	// Set up a scene surface that maps to our physical screen drawing surface
-	_sceneSurface.init(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT, MADS_SCREEN_WIDTH,
-		_vm->_screen.getPixels(), Graphics::PixelFormat::createFormatCLUT8());
+	restrictScene();
 
 	// Set up the verb list
 	_verbList.push_back(VerbInit(VERB_LOOK, VERB_THAT, PREP_NONE));
@@ -85,6 +84,11 @@ Scene::~Scene() {
 	delete _animationData;
 }
 
+void Scene::restrictScene() {
+	_sceneSurface.init(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT, MADS_SCREEN_WIDTH,
+		_vm->_screen.getPixels(), Graphics::PixelFormat::createFormatCLUT8());
+}
+
 void Scene::clearVocab() {
 	_activeVocabs.clear();
 }
@@ -511,7 +515,7 @@ void  Scene::drawElements(ScreenTransition transitionType, bool surfaceFlag) {
 		_vm->_sound->startQueuedCommands();
 	} else {
 		// Copy dirty areas to the screen
-		_dirtyAreas.copyToScreen(_vm->_screen._offset);
+		_dirtyAreas.copyToScreen();
 	}
 
 	_spriteSlots.cleanUp();
diff --git a/engines/mads/scene.h b/engines/mads/scene.h
index 407d70d..ee7864c 100644
--- a/engines/mads/scene.h
+++ b/engines/mads/scene.h
@@ -142,6 +142,8 @@ public:
 	 */
 	~Scene();
 
+	void restrictScene();
+
 	/**
 	 * Clear the vocabulary list
 	 */
diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp
index ab5dff5..590e63a 100644
--- a/engines/mads/screen.cpp
+++ b/engines/mads/screen.cpp
@@ -212,8 +212,7 @@ void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common:
 
 		Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
 			srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
-		Common::Point destPos(bounds.left + _vm->_screen._offset.x,
-			bounds.top + _vm->_screen._offset.y);
+		Common::Point destPos(bounds.left, bounds.top);
 
 		if ((*this)[i]._active && bounds.isValidRect()) {
 			srcSurface->copyTo(destSurface, bounds, destPos);
@@ -221,17 +220,14 @@ void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common:
 	}
 }
 
-void DirtyAreas::copyToScreen(const Common::Point &posAdjust) {
+void DirtyAreas::copyToScreen() {
 	for (uint i = 0; i < size(); ++i) {
-		const Common::Rect &srcBounds = (*this)[i]._bounds;
+		const Common::Rect &bounds = (*this)[i]._bounds;
 
 		// Check if this is a sane rectangle before attempting to create it
-		if (srcBounds.left >= srcBounds.right || srcBounds.top >= srcBounds.bottom)
+		if (bounds.left >= bounds.right || bounds.top >= bounds.bottom)
 			continue;
 
-		Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
-			srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
-
 		if ((*this)[i]._active && (*this)[i]._bounds.isValidRect()) {
 			_vm->_screen.copyRectToScreen(bounds);
 		}
@@ -561,23 +557,32 @@ void ScreenObjects::synchronize(Common::Serializer &s) {
 ScreenSurface::ScreenSurface() {
 	_shakeCountdown = -1;
 	_random = 0x4D2;
+	_surfacePixels = nullptr;
 }
 
 void ScreenSurface::init() {
-	setSize(g_system->getWidth(), g_system->getHeight());
-}
+	// Set the size for the screen
+	setSize(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT);
 
-void ScreenSurface::copyRectToScreen(const Common::Point &destPos,
-		const Common::Rect &bounds) {
-	const byte *buf = getBasePtr(destPos.x, destPos.y);
+	// Store a copy of the raw pixels pointer for the screen, since the surface
+	// itself may be later changed to only a subset of the screen
+	_surfacePixels = (byte *)getPixels();
+	_freeFlag = false;
+}
 
-	if (bounds.width() != 0 && bounds.height() != 0)
-		g_system->copyRectToScreen(buf, this->pitch, bounds.left, bounds.top,
-			bounds.width(), bounds.height());
+ScreenSurface::~ScreenSurface() {
+	delete[] _surfacePixels;
 }
 
 void ScreenSurface::copyRectToScreen(const Common::Rect &bounds) {
-	copyRectToScreen(Common::Point(bounds.left, bounds.top), bounds);
+	const byte *buf = getBasePtr(bounds.left, bounds.top);
+
+	Common::Rect destBounds = bounds;
+	destBounds.translate(_clipBounds.left, _clipBounds.top);
+
+	if (bounds.width() != 0 && bounds.height() != 0)
+		g_system->copyRectToScreen(buf, this->pitch, destBounds.left, destBounds.top,
+		destBounds.width(), destBounds.height());
 }
 
 void ScreenSurface::updateScreen() {
@@ -659,4 +664,15 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag
 	}
 }
 
+void ScreenSurface::setClipBounds(const Common::Rect &r) {
+	_clipBounds = r;
+	setPixels(_surfacePixels + pitch * r.top + r.left, r.width(), r.height());
+	this->pitch = MADS_SCREEN_WIDTH;
+}
+
+void ScreenSurface::resetClipBounds() {
+	setClipBounds(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
+}
+
+
 } // End of namespace MADS
diff --git a/engines/mads/screen.h b/engines/mads/screen.h
index 7937e15..9d01ca8 100644
--- a/engines/mads/screen.h
+++ b/engines/mads/screen.h
@@ -117,8 +117,8 @@ public:
 	/**
 	* Use the lsit of dirty areas to copy areas of the screen surface to
 	* the physical screen
-	* @param posAdjust		Position adjustment	 */
-	void copyToScreen(const Common::Point &posAdjust);
+	*/
+	void copyToScreen();
 
 	void reset();
 };
@@ -205,8 +205,9 @@ public:
 class ScreenSurface : public MSurface {
 private:
 	uint16 _random;
+	byte *_surfacePixels;
+	Common::Rect _clipBounds;
 public:
-	Common::Point _offset;
 	int _shakeCountdown;
 public:
 	/**
@@ -215,17 +216,14 @@ public:
 	ScreenSurface();
 
 	/**
-	 * Initialize the surface
+	 * Destructor
 	 */
-	void init();
+	~ScreenSurface();
 
 	/**
-	 * Copys an area of the screen surface to a given destination position on
-	 * the ScummVM physical screen buffer
-	 * @param destPos	Destination position
-	 * @param bounds	Area of screen surface to copy
+	 * Initialize the surface
 	 */
-	void copyRectToScreen(const Common::Point &destPos, const Common::Rect &bounds);
+	void init();
 
 	/**
 	 * Copys an area of the screen surface to the ScmmVM physical screen buffer
@@ -239,6 +237,12 @@ public:
 	void updateScreen();
 
 	void transition(ScreenTransition transitionType, bool surfaceFlag);
+
+	void setClipBounds(const Common::Rect &r);
+
+	void resetClipBounds();
+
+	const Common::Rect &getClipBounds() { return _clipBounds; }
 };
 
 } // End of namespace MADS
diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp
index 2bf13ee..cd35807 100644
--- a/engines/mads/sprites.cpp
+++ b/engines/mads/sprites.cpp
@@ -331,8 +331,6 @@ void SpriteSlots::drawSprites(MSurface *s) {
 				xp = slot._position.x - (sprite->w / 2) - scene._posAdjust.x;
 				yp = slot._position.y - sprite->h - scene._posAdjust.y + 1;
 			}
-			xp += _vm->_screen._offset.x;
-			yp += _vm->_screen._offset.y;
 
 			if (slot._depth > 1) {
 				// Draw the frame with depth processing






More information about the Scummvm-git-logs mailing list