[Scummvm-git-logs] scummvm master -> 093b84863f797c3adc0e92a0aa584b6073b3a0eb

mduggan noreply at scummvm.org
Sun Mar 2 03:52:07 UTC 2025


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:
093b84863f DGDS: Implement Willy Beamish main menu help


Commit: 093b84863f797c3adc0e92a0aa584b6073b3a0eb
    https://github.com/scummvm/scummvm/commit/093b84863f797c3adc0e92a0aa584b6073b3a0eb
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2025-03-02T14:52:01+11:00

Commit Message:
DGDS: Implement Willy Beamish main menu help

Changed paths:
    engines/dgds/dgds.cpp
    engines/dgds/menu.cpp
    engines/dgds/menu.h
    engines/dgds/scene_op.cpp


diff --git a/engines/dgds/dgds.cpp b/engines/dgds/dgds.cpp
index edeac06148b..1fdc6d7bde7 100644
--- a/engines/dgds/dgds.cpp
+++ b/engines/dgds/dgds.cpp
@@ -445,7 +445,7 @@ void DgdsEngine::loadGameFiles() {
 		reqParser.parse(&invRequestData, "WINV.REQ");
 		reqParser.parse(&vcrRequestData, "WVCR.REQ");
 		if (!_isDemo)
-			_menu->readRESData("WVCR.RES");
+			_menu->loadVCRHelp("WVCR.RES");
 
 		break;
 	case GID_QUARKY:
diff --git a/engines/dgds/menu.cpp b/engines/dgds/menu.cpp
index cdb0f2bf2be..e79fc39236f 100644
--- a/engines/dgds/menu.cpp
+++ b/engines/dgds/menu.cpp
@@ -47,6 +47,7 @@ enum MenuButtonIds {
 	kMainMenuWillyLoad = 111,
 	kMainMenuWillyRestart = 112,
 	kMainMenuWillyQuit = 113,
+	kMainMenuWillyVCRHelp = 114,
 	kMainMenuWillyHelp = 120,
 	kMainMenuWillySoundsOnOff = 115,
 	kMainMenuWillyMusicOnOff = 116,
@@ -138,10 +139,13 @@ enum MenuButtonIds {
 	// Tank/train menu in Heart of China
 	kMenuTankTrainSkipArcade = 153,
 	kMenuTankTrainPlayArcade = 154,
+
+	kMenuButtonNone = 0,
 };
 
-Menu::Menu() : _curMenu(kMenuNone), _dragGadget(nullptr), _selectedItem(0), _numSelectable(0), _creditsOffset(0) {
-	_screenBuffer.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
+Menu::Menu() : _curMenu(kMenuNone), _dragGadget(nullptr), _selectedItem(0), _numSelectable(0), _creditsOffset(0),
+	_vcrHelpMode(false) {
+_screenBuffer.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
 }
 
 Menu::~Menu() {
@@ -154,20 +158,36 @@ void Menu::setRequestData(const REQFileData &data) {
 	}
 }
 
-void Menu::readRESData(const char *fname) {
+void Menu::loadVCRHelp(const char *fname) {
 	DgdsEngine *engine = DgdsEngine::getInstance();
 	Common::SeekableReadStream *s = engine->getResourceManager()->getResource(fname);
 
 	if (!s)
 		error("Couldn't open RES file for menu help %s", fname);
 
+	static const MenuButtonIds helpIds[] = {
+		kMenuButtonNone, // Help not available right now
+		kMainMenuWillySave,
+		kMainMenuWillyLoad,
+		kMainMenuWillyRestart,
+		kMainMenuWillyQuit,
+		kMainMenuWillyVCRHelp,
+		kMainMenuWillySoundsOnOff,
+		kMainMenuWillyMusicOnOff,
+		kMainMenuWillyHelp,
+		kMenuMainCalibrate, // Same ID as Credits in Willy Beamish
+		kMenuMainFiles, 	// Same ID as Resume in Willy Beamish
+	};
+
+	int menuId = 0;
 	_helpStrings.clear();
 	Common::Array<Common::String> message;
 	while (!s->eos() && !s->err()) {
 		Common::String str = s->readLine();
 		if (str == "!" || s->eos()) {
-			_helpStrings.push_back(message);
+			_helpStrings[helpIds[menuId]] = message;
 			message.clear();
+			menuId++;
 		} else {
 			message.push_back(str);
 		}
@@ -282,14 +302,15 @@ void Menu::onTick() {
 		drawMenu(kMenuWillyCredits);
 }
 
-void Menu::drawMenu(MenuId menu) {
+void Menu::drawMenu(MenuId menu, bool clearScreen /* = true*/) {
 	bool firstDraw = (_curMenu != menu);
 	_curMenu = menu;
 
 	Common::Array<Common::SharedPtr<Gadget> > gadgets = _menuRequests[_curMenu]._gadgets;
 
 	// Restore background when drawing submenus
-	g_system->copyRectToScreen(_screenBuffer.getPixels(), _screenBuffer.pitch, 0, 0, _screenBuffer.w, _screenBuffer.h);
+	if (clearScreen)
+		g_system->copyRectToScreen(_screenBuffer.getPixels(), _screenBuffer.pitch, 0, 0, _screenBuffer.w, _screenBuffer.h);
 
 	// This is not very efficient, but it only happens once when the menu is opened.
 	Graphics::Surface *screen = g_system->lockScreen();
@@ -324,6 +345,14 @@ void Menu::drawMenu(MenuId menu) {
 	g_system->updateScreen();
 }
 
+void Menu::hideMenu() {
+	_curMenu = kMenuNone;
+	if (_vcrHelpMode) {
+		_vcrHelpMode = false;
+		DgdsEngine::getInstance()->setMouseCursor(-1);
+	}
+}
+
 Gadget *Menu::getSelectedItem() {
 	int item = 0;
 	Common::Array<Common::SharedPtr<Gadget> > gadgets = _menuRequests[_curMenu]._gadgets;
@@ -476,11 +505,11 @@ void Menu::onMouseLUp(const Common::Point &mouse) {
 		return;
 
 	// Click animation
-	if (dynamic_cast<ButtonGadget *>(gadget)) {
+	if (dynamic_cast<ButtonGadget *>(gadget) && !_vcrHelpMode) {
 		gadget->toggle(false);
 		if (_curMenu == kMenuOptions)
 			isToggle = updateOptionsGadget(gadget);
-		drawMenu(_curMenu);
+		drawMenu(_curMenu, false);
 		g_system->delayMillis(300);
 		gadget->toggle(true);
 		isToggle = true;
@@ -517,6 +546,11 @@ bool Menu::handleClick(const Common::Point &mouse) {
 	Gadget *gadget = getClickedMenuItem(mouse);
 	int16 clickedMenuItem = gadget->_gadgetNo;
 
+	if (_vcrHelpMode) {
+		doVcrHelp(clickedMenuItem);
+		return false;
+	}
+
 	switch (clickedMenuItem) {
 	case kMenuMainPlay:
 	case kMenuControlsPlay:
@@ -545,7 +579,6 @@ bool Menu::handleClick(const Common::Point &mouse) {
 		break;
 	case kMenuMainCalibrate: // same as credits button in Willy Beamish
 		if (engine->getGameId() == GID_WILLY) {
-			debug("TODO: Implement willy beamish credits");
 			hideMenu();
 			loadCredits();
 			drawMenu(kMenuWillyCredits);
@@ -577,6 +610,9 @@ bool Menu::handleClick(const Common::Point &mouse) {
 	case kMenuMainQuit:
 		drawMenu(kMenuReallyQuit);
 		break;
+	case kMainMenuWillyVCRHelp:
+		startVcrHelp();
+		break;
 	//case kMenuCalibrateVCR: // NOTE: same ID as kMenuIntroPlay
 	case kMenuIntroPlay:
 		drawMenu(kMenuMain);
@@ -725,9 +761,11 @@ bool Menu::handleClick(const Common::Point &mouse) {
 		updateOptionsGadget(gadget);
 		break;
 	case kMenuWillyCreditsDone:
-	case kMenuWillyHelpDone:
 		hideMenu();
 		break;
+	case kMenuWillyHelpDone:
+		drawMenu(kMenuMain, false);
+		break;
 	default:
 		debug(1, "Clicked ID %d", clickedMenuItem);
 		break;
@@ -735,6 +773,51 @@ bool Menu::handleClick(const Common::Point &mouse) {
 	return true;
 }
 
+void Menu::startVcrHelp() {
+	_vcrHelpMode = true;
+	Common::SharedPtr<Graphics::ManagedSurface> iconSurf = RequestData::getCorners()->getSurface(37);
+	int hotspotX = iconSurf->w / 2;
+	int hotspotY = iconSurf->h / 2;
+	CursorMan.replaceCursor(*(iconSurf->surfacePtr()), hotspotX, hotspotY, 0, 0);
+}
+
+void Menu::doVcrHelp(int16 button) {
+	if (_helpStrings.contains(button)) {
+		RequestData &helpRequest = _menuRequests[kMenuWillyVCRHelp];
+		const Common::Array<Common::String> msg = _helpStrings[button];
+		const DgdsFont *font = RequestData::getMenuFont();
+		const Gadget *doneButton = helpRequest.findGadgetByNumWithFlags3Not0x40(174);
+		int16 msgHeight = font->getFontHeight() * msg.size();
+		int16 msgAreaTop = helpRequest._textItemList.front()._y + font->getFontHeight();
+		int16 msgAreaHeight = doneButton->_y - msgAreaTop;
+		int16 msgAreaLeft = 0;
+		int16 msgAreaWidth = helpRequest._rect.width;
+
+		// Vertically centre the message
+		int16 msgTop = msgAreaTop + (msgAreaHeight - msgHeight) / 2;
+
+		while (helpRequest._textItemList.size() > 1)
+			helpRequest._textItemList.pop_back();
+
+		for (const Common::String &line : msg) {
+			TextItem helpText;
+			int msgLen = font->getStringWidth(line);
+			// Horizontally centre the line
+			helpText._x = msgAreaLeft + (msgAreaWidth - msgLen) / 2;
+			helpText._y = msgTop;
+			helpText._txt = line;
+			msgTop += font->getFontHeight();
+			helpRequest._textItemList.push_back(helpText);
+		}
+
+		// HACK: Set a different cursor to force an update.
+		DgdsEngine::getInstance()->setMouseCursor(1);
+		DgdsEngine::getInstance()->setMouseCursor(-1);
+		drawMenu(kMenuWillyVCRHelp, false);
+		_vcrHelpMode = false;
+	}
+}
+
 void Menu::handleClickOptionsMenu(const Common::Point &mouse) {
 	Gadget *gadget = getClickedMenuItem(mouse);
 	int16 clickedMenuItem = gadget->_gadgetNo;
diff --git a/engines/dgds/menu.h b/engines/dgds/menu.h
index 81e835e0370..fdccd0acba8 100644
--- a/engines/dgds/menu.h
+++ b/engines/dgds/menu.h
@@ -68,7 +68,7 @@ enum MenuId {
 	kMenuArcadeFrustrated = 47,
 	kMenuSkipPlayIntro = 50,
 	kMenuSkipArcade = 52,
-	kMenuWillyHelp = 54,
+	kMenuWillyVCRHelp = 54,
 	kMenuWillyCredits = 56,
 };
 
@@ -82,15 +82,15 @@ public:
 	virtual ~Menu();
 
 	void setScreenBuffer();
-	void drawMenu(MenuId menu = kMenuMain);
+	void drawMenu(MenuId menu = kMenuMain, bool clearScreen = true);
 	void onMouseLUp(const Common::Point &mouse);
 	void onMouseLDown(const Common::Point &mouse);
 	void onMouseMove(const Common::Point &mouse);
 	bool menuShown() const { return _curMenu != kMenuNone; }
-	void hideMenu() { _curMenu = kMenuNone; }
+	void hideMenu();
 
 	void setRequestData(const REQFileData &data);
-	void readRESData(const char *fname);
+	void loadVCRHelp(const char *fname);
 	void prevChoice();
 	void nextChoice();
 	void activateChoice();
@@ -107,13 +107,15 @@ private:
 	void handleClickOptionsMenu(const Common::Point &mouse);
 	void handleClickSkipPlayIntroMenu(const Common::Point &mouse);
 	void loadCredits();
+	void startVcrHelp();
+	void doVcrHelp(int16 button);
 
 	void putMouseOnSelectedItem();
 	Gadget *getSelectedItem();
 
 	Common::HashMap<int, RequestData> _menuRequests;
 
-	Common::Array<Common::Array<Common::String>> _helpStrings;
+	Common::HashMap<int16, Common::Array<Common::String>> _helpStrings;
 	Common::Array<Common::String> _credits;
 
 	SliderGadget *_dragGadget;
@@ -121,6 +123,7 @@ private:
 	int _selectedItem;
 	int _numSelectable;
 	int _creditsOffset;
+	bool _vcrHelpMode;
 };
 
 } // End of namespace Dgds
diff --git a/engines/dgds/scene_op.cpp b/engines/dgds/scene_op.cpp
index 09ff7216a97..b39ad80c40e 100644
--- a/engines/dgds/scene_op.cpp
+++ b/engines/dgds/scene_op.cpp
@@ -419,7 +419,6 @@ Common::String ConditionalSceneOp::dump(const Common::String &indent) const {
 
 	str += DebugUtil::dumpStructList(indent, "conditionList", _conditionList);
 	if (!_conditionList.empty()) {
-		str += "\n";
 		str += indent;
 	}
 	str += DebugUtil::dumpStructList(indent, "opList", _opList);




More information about the Scummvm-git-logs mailing list