[Scummvm-git-logs] scummvm master -> d472339369647c81216015acee5f7e655e64820e

mduggan noreply at scummvm.org
Sat Jul 20 03:57:07 UTC 2024


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:
dbb1b856ce DGDS: Implement HoC inventory give-to and swap-char buttons
d472339369 DGDS: Clear background when opening HoC inventory zoom


Commit: dbb1b856ce65647627498c3abd1e68a5a490f45f
    https://github.com/scummvm/scummvm/commit/dbb1b856ce65647627498c3abd1e68a5a490f45f
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-07-20T13:56:04+10:00

Commit Message:
DGDS: Implement HoC inventory give-to and swap-char buttons

A little closer to the original rendering, still need to fix the buttons
themselves.

Changed paths:
    engines/dgds/dgds.cpp
    engines/dgds/dgds.h
    engines/dgds/inventory.cpp
    engines/dgds/inventory.h
    engines/dgds/request.cpp
    engines/dgds/request.h
    engines/dgds/scene.cpp


diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index 26f7b96d846..e43f0a572e5 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -73,6 +73,10 @@
 
 namespace Dgds {
 
+/*static*/
+const byte DgdsEngine::HOC_CHAR_SWAP_ICONS[] = { 0, 20, 21, 22 };
+
+
 DgdsEngine::DgdsEngine(OSystem *syst, const ADGameDescription *gameDesc)
 	: Engine(syst), _fontManager(nullptr), _console(nullptr), _inventory(nullptr),
 	_soundPlayer(nullptr), _decompressor(nullptr), _scene(nullptr),
@@ -276,7 +280,6 @@ void DgdsEngine::checkDrawInventoryButton() {
 		int16 otherChar = _gdsScene->getGlobal(0x34);
 		if (otherChar) {
 			// FIXME: This list repeated in scene too
-			static const byte HOC_CHAR_SWAP_ICONS[] = { 0, 20, 21, 22 };
 			int16 swapCharIcon = HOC_CHAR_SWAP_ICONS[otherChar];
 			int sy = SCREEN_HEIGHT - _icons->height(swapCharIcon) - 5;
 			_icons->drawBitmap(swapCharIcon, 5, sy, drawWin, _compositionBuffer);
diff --git a/engines/dgds/dgds.h b/engines/dgds/dgds.h
index 00913c14bbb..1bb81b461f9 100644
--- a/engines/dgds/dgds.h
+++ b/engines/dgds/dgds.h
@@ -94,6 +94,8 @@ public:
 	Sound *_soundPlayer;
 	Graphics::ManagedSurface _compositionBuffer;
 
+	static const byte HOC_CHAR_SWAP_ICONS[];
+
 private:
 	Console *_console;
 
diff --git a/engines/dgds/inventory.cpp b/engines/dgds/inventory.cpp
index fdc76ebfff3..e7343c22ccc 100644
--- a/engines/dgds/inventory.cpp
+++ b/engines/dgds/inventory.cpp
@@ -30,6 +30,9 @@
 
 namespace Dgds {
 
+/*static*/ const byte Inventory::HOC_CHARACTER_QUALS[] = { 0, 9, 7, 8 };
+
+
 Inventory::Inventory() : _isOpen(false), _prevPageBtn(nullptr), _nextPageBtn(nullptr),
 	_invClock(nullptr), _itemZoomBox(nullptr), _exitButton(nullptr), _clockSkipMinBtn(nullptr),
 	_itemArea(nullptr), _clockSkipHrBtn(nullptr), _dropBtn(nullptr), _itemBox(nullptr),
@@ -127,53 +130,51 @@ void Inventory::draw(Graphics::ManagedSurface &surf, int itemCount) {
 	DgdsGameId gameId = engine->getGameId();
 
 	if (_showZoomBox) {
-		_itemZoomBox->_flags3 &= ~0x40;
+		_itemZoomBox->setVisible(true);
 		boxreq._rect.width = _fullWidth;
 	} else {
-		_itemZoomBox->_flags3 |= 0x40;
+		_itemZoomBox->setVisible(false);
 		boxreq._rect.width = _itemBox->_width + _itemBox->_x * 2;
 	}
 
 	//
 	// Decide whether the nextpage/prevpage buttons should be visible
 	//
-	if ((_itemArea->_width / _itemArea->_xStep) *
-			(_itemArea->_height / _itemArea->_yStep) > itemCount) {
-		// not visible.
-		_prevPageBtn->_flags3 |= 0x40;
-		_nextPageBtn->_flags3 |= 0x40;
-	} else {
-		// clear flag 0x40 - visible.
-		_prevPageBtn->_flags3 &= ~0x40;
-		_nextPageBtn->_flags3 &= ~0x40;
-	}
+	bool needPageButtons =
+		(_itemArea->_width / _itemArea->_xStep) *
+			(_itemArea->_height / _itemArea->_yStep) < itemCount;
+	_prevPageBtn->setVisible(needPageButtons);
+	_nextPageBtn->setVisible(needPageButtons);
 
 	//
 	// Decide whether the time buttons should be visible (only in Dragon)
 	//
 	if (gameId != GID_DRAGON) {
 		if (_clockSkipMinBtn)
-			_clockSkipMinBtn->_flags3 |= 0x40;
+			_clockSkipMinBtn->setVisible(false);
 		if (_clockSkipHrBtn)
-			_clockSkipHrBtn->_flags3 |= 0x40;
+			_clockSkipHrBtn->setVisible(false);
 	}
 
 	//
 	// Decide whether the give-to and swap char buttons should be visible (only in China)
 	//
+	int16 otherChar = 0;
 	if (gameId == GID_HOC) {
-		if (engine->getGDSScene()->getGlobal(0x34) != 0) {
-			// other char available, buttons visible
-			_giveToBtn->_flags3 &= ~0x40;
-			_changeCharBtn->_flags3 &= ~0x40;
-		} else {
-			_giveToBtn->_flags3 |= 0x40;
-			_changeCharBtn->_flags3 |= 0x40;
-		}
+		otherChar = engine->getGDSScene()->getGlobal(0x34);
+		_giveToBtn->setVisible(otherChar != 0);
+		// This is only used to give the location so it's always false.
+		_changeCharBtn->setVisible(false);
 	}
 
 	boxreq.drawInvType(&surf);
 
+	if (gameId == GID_HOC && otherChar != 0) {
+		int16 swapCharIcon = DgdsEngine::HOC_CHAR_SWAP_ICONS[otherChar];
+		Common::Point pt = _changeCharBtn->topLeft();
+		engine->getIcons()->drawBitmap(swapCharIcon, pt.x, pt.y, boxreq._rect.toCommonRect(), surf);
+	}
+
 	drawHeader(surf);
 	drawTime(surf);
 	drawItems(surf);
@@ -305,10 +306,9 @@ bool Inventory::isItemInInventory(GameItem &item) {
 	DgdsGameId gameId = engine->getGameId();
 	bool result = item._inSceneNum == 2; // && (item._flags & 4)
 	if (gameId == GID_HOC) {
-		byte gameCharacterQuality[] = { 0, 9, 7, 8 };	// TODO: Move this elsewhere?
 		int16 currentCharacter = engine->getGDSScene()->getGlobal(0x33);
 		assert(currentCharacter < 4);
-		result = result && item._quality == gameCharacterQuality[currentCharacter];
+		result = result && item._quality == HOC_CHARACTER_QUALS[currentCharacter];
 	}
 
 	return result;
@@ -346,12 +346,14 @@ void Inventory::mouseLUp(const Common::Point &pt) {
 		return;
 	}
 
+	GDSScene *gds = engine->getGDSScene();
+
 	engine->setMouseCursor(0);
 
 	int itemsPerPage = (_itemArea->_width / _itemArea->_xStep) * (_itemArea->_height / _itemArea->_yStep);
 	if (_exitButton->containsPoint(pt)) {
 		close();
-	} else if (_nextPageBtn->containsPoint(pt) && !(_nextPageBtn->_flags3 & 0x40)) {
+	} else if (_nextPageBtn->containsPoint(pt) && _nextPageBtn->isVisible()) {
 		int numInvItems = 0;
 		Common::Array<GameItem> &items = engine->getGDSScene()->getGameItems();
 		for (auto &item: items) {
@@ -360,13 +362,25 @@ void Inventory::mouseLUp(const Common::Point &pt) {
 		}
 		if (_itemOffset < numInvItems)
 			_itemOffset += itemsPerPage;
-	} else if (_prevPageBtn->containsPoint(pt) && !(_prevPageBtn->_flags3 & 0x40)) {
+	} else if (_prevPageBtn->containsPoint(pt) && _prevPageBtn->isVisible()) {
 		if (_itemOffset > 0)
 			_itemOffset -= itemsPerPage;
-	} else if (_clockSkipMinBtn && _clockSkipMinBtn->containsPoint(pt)) {
+	} else if (_clockSkipMinBtn && _clockSkipMinBtn->isVisible() && _clockSkipMinBtn->containsPoint(pt)) {
 		engine->getClock().addGameTime(1);
-	} else if (_clockSkipHrBtn && _clockSkipHrBtn->containsPoint(pt)) {
+	} else if (_clockSkipHrBtn && _clockSkipHrBtn->isVisible() && _clockSkipHrBtn->containsPoint(pt)) {
 		engine->getClock().addGameTime(60);
+	} else if (_giveToBtn && _giveToBtn->isVisible() && _giveToBtn->containsPoint(pt)) {
+		Common::Array<GameItem> &items = engine->getGDSScene()->getGameItems();
+		for (auto &item: items) {
+			if (item._num == _highlightItemNo) {
+				item._quality = HOC_CHARACTER_QUALS[gds->getGlobal(0x34)];
+				break;
+			}
+		}
+	} else if (_changeCharBtn && _changeCharBtn->isVisible() && _changeCharBtn->containsPoint(pt)) {
+		int16 prevChar = gds->getGlobal(0x33);
+		gds->setGlobal(0x33, gds->getGlobal(0x34));
+		gds->setGlobal(0x34, prevChar);
 	} else if (_dropBtn && _dropBtn->containsPoint(pt) && _highlightItemNo >= 0) {
 		Common::Array<GameItem> &items = engine->getGDSScene()->getGameItems();
 		for (auto &item: items) {
diff --git a/engines/dgds/inventory.h b/engines/dgds/inventory.h
index 657f6acda3b..5a8c0ee3aba 100644
--- a/engines/dgds/inventory.h
+++ b/engines/dgds/inventory.h
@@ -57,6 +57,7 @@ public:
 
 	Common::Error syncState(Common::Serializer &s);
 
+	static const byte HOC_CHARACTER_QUALS[];
 private:
 	GameItem *itemUnderMouse(const Common::Point &pt);
 	bool isItemInInventory(GameItem &item);
diff --git a/engines/dgds/request.cpp b/engines/dgds/request.cpp
index 83bbcfcec59..34197adcc9b 100644
--- a/engines/dgds/request.cpp
+++ b/engines/dgds/request.cpp
@@ -319,6 +319,13 @@ bool Gadget::containsPoint(const Common::Point &pt) {
 	return gadgetRect.contains(pt);
 }
 
+void Gadget::setVisible(bool visible) {
+	if (visible)
+		_flags3 &= ~0x40;
+	else
+		_flags3 |= 0x40;
+}
+
 void ButtonGadget::draw(Graphics::ManagedSurface *dst) const {
 	// TODO: Bounds calculation here might depend on parent.
 
diff --git a/engines/dgds/request.h b/engines/dgds/request.h
index 200ad4b4e22..ca423f46d21 100644
--- a/engines/dgds/request.h
+++ b/engines/dgds/request.h
@@ -101,6 +101,8 @@ public:
 	virtual void toggle(bool enable) {}
 
 	bool containsPoint(const Common::Point &pt);
+	bool isVisible() const { return !(_flags3 & 0x40); }
+	void setVisible(bool visible);
 
 	Common::Point topLeft() const;
 	Common::Point midPoint() const;
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index 5e422131607..4ffe277ce52 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -1764,14 +1764,11 @@ void SDSScene::onDragFinish(const Common::Point &pt) {
 		if (!_isInRect(pt, area._rect))
 			continue;
 
-		// FIXME: This is copied in inventory too
-		static const byte HOC_CHARACTER_QUALS[] = {0, 9, 7, 8};
-
 		if (area._num == 0) {
 			debug("Item %d dropped on inventory.", dragItem->_num);
 			dragItem->_inSceneNum = 2;
 			if (engine->getGameId() == GID_HOC)
-				dragItem->_quality = HOC_CHARACTER_QUALS[gdsScene->getGlobal(0x33)];
+				dragItem->_quality = Inventory::HOC_CHARACTER_QUALS[gdsScene->getGlobal(0x33)];
 
 			const ObjectInteraction *i = _findInteraction(scene->getObjInteractions1(), dragItem->_num, 0xffff);
 			if (i) {
@@ -1783,7 +1780,7 @@ void SDSScene::onDragFinish(const Common::Point &pt) {
 			debug("Item %d dropped on other character button.", dragItem->_num);
 			dragItem->_inSceneNum = 2;
 			if (engine->getGameId() == GID_HOC)
-				dragItem->_quality = HOC_CHARACTER_QUALS[gdsScene->getGlobal(0x34)];
+				dragItem->_quality = Inventory::HOC_CHARACTER_QUALS[gdsScene->getGlobal(0x34)];
 
 			const ObjectInteraction *i = _findInteraction(scene->getObjInteractions1(), dragItem->_num, 0xffff);
 			if (i) {
@@ -1914,10 +1911,8 @@ void SDSScene::addInvButtonToHotAreaList() {
 
 	// Add swap character button for HoC
 	if (engine->getGameId() == GID_HOC && engine->getGDSScene()->getGlobal(0x34) != 0) {
-		static const byte HOC_CHAR_SWAP_ICONS[] = { 0, 20, 21, 22 };
 		int16 charNum = engine->getGDSScene()->getGlobal(0x34);
-		assert(charNum < ARRAYSIZE(HOC_CHAR_SWAP_ICONS));
-		int16 iconNum = HOC_CHAR_SWAP_ICONS[charNum];
+		int16 iconNum = DgdsEngine::HOC_CHAR_SWAP_ICONS[charNum];
 		HotArea area2;
 		area2._num = 0xffff;
 		area2._cursorNum = 0;


Commit: d472339369647c81216015acee5f7e655e64820e
    https://github.com/scummvm/scummvm/commit/d472339369647c81216015acee5f7e655e64820e
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-07-20T13:56:04+10:00

Commit Message:
DGDS: Clear background when opening HoC inventory zoom

This is also done in the original because the zoom box uses a different palette
to the game.

Changed paths:
    engines/dgds/dgds.cpp
    engines/dgds/inventory.cpp
    engines/dgds/scene.cpp


diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index e43f0a572e5..cf75726e6af 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -168,9 +168,11 @@ bool DgdsEngine::changeScene(int sceneNum) {
 
 	_gameGlobals->setLastSceneNum(sceneNum);
 
-	// Save the current foreground if we are going to the inventory, clear it otherwise.
-	if (sceneNum == 2) {
-		// Slight hack - draw the inv button here to keep it in the scene
+	// Save the current foreground if we are going to the inventory,
+	// *except* for HoC zoomed inventory - that also clears background
+	// because it uses a different palette for the zoomed item view.
+	if (sceneNum == 2 && (!(getGameId() == GID_HOC && _inventory->isZoomVisible()))) {
+		// Force-draw the inv button here to keep it in background
 		checkDrawInventoryButton();
 		_backgroundBuffer.blitFrom(_compositionBuffer);
 	} else {
diff --git a/engines/dgds/inventory.cpp b/engines/dgds/inventory.cpp
index e7343c22ccc..c5dfc2a76cb 100644
--- a/engines/dgds/inventory.cpp
+++ b/engines/dgds/inventory.cpp
@@ -27,6 +27,7 @@
 #include "dgds/image.h"
 #include "dgds/font.h"
 #include "dgds/request.h"
+#include "dgds/includes.h"
 
 namespace Dgds {
 
@@ -398,6 +399,13 @@ void Inventory::mouseRUp(const Common::Point &pt) {
 		GameItem *underMouse = itemUnderMouse(pt);
 		if (underMouse) {
 			setShowZoomBox(true);
+			if (engine->getGameId() == GID_HOC) {
+				// Slight hack - blank the background if zooming in HOC because it uses
+				// different palettes for zoomed items (original does this too)
+				// We also do this on scene transition, but need to do it again
+				// here for zooming within the box.
+				engine->getBackgroundBuffer().fillRect(Common::Rect(SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+			}
 			engine->getScene()->runOps(underMouse->onRClickOps);
 		}
 	} else {
diff --git a/engines/dgds/scene.cpp b/engines/dgds/scene.cpp
index 4ffe277ce52..fb5f6e124be 100644
--- a/engines/dgds/scene.cpp
+++ b/engines/dgds/scene.cpp
@@ -711,7 +711,7 @@ bool Scene::runDragonOp(const SceneOp &op) {
 	case kSceneOpMeanwhile:
 		// TODO: Should we draw "meanwhile" like the original? it just gets overwritten with the image anyway.
 		// Probably need to do something here to avoid flashing..
-		//engine->_compositionBuffer.fillRect(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+		//engine->_compositionBuffer.fillRect(Common::Rect(SCREEN_WIDTH, SCREEN_HEIGHT), 0);
 		break;
 	case kSceneOpOpenGameOverMenu:
 		engine->setMenuToTrigger(kMenuGameOver);
@@ -2103,7 +2103,7 @@ bool GDSScene::loadRestart(const Common::String &filename, ResourceManager *reso
 		triggers[i] = file->readUint16LE();
 	}
 
-	engine->_compositionBuffer.fillRect(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+	engine->_compositionBuffer.fillRect(Common::Rect(SCREEN_WIDTH, SCREEN_HEIGHT), 0);
 	// TODO: FIXME: What should this scene num be? For now hacked to work with Dragon.
 	engine->changeScene(3);
 	SDSScene *scene = engine->getScene();




More information about the Scummvm-git-logs mailing list