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

dreammaster noreply at scummvm.org
Sat Feb 24 04:59:34 UTC 2024


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

Summary:
037131d977 KEYMAPPER: Add method isEnabled to Common::Keymapper
816d1c6d8c ULTIMA: NUVIE: Fix KEYINPUT_MODE keymapper regression
a609f91a6e ULTIMA: NUVIE: Fix widgets deleting self in event handler
696aea82e6 ULTIMA: NUVIE: Fix crash when selecting spell to enchant with
382abb7dad ULTIMA: NUVIE: Fix SpellViewGump deleting self/crashing on RMB
46221f1dbd ULTIMA: NUVIE: Fix enchant crash during spell selection
e2a9b6be4d ULTIMA: NUVIE: Fix loss of focus when dragging SpellViewGump
702ddabdec ULTIMA: NUVIE: Lock input to spellbook when looking at it
e807f89573 ULTIMA: NUVIE: Fix Wizard Eye keyboard control


Commit: 037131d977792257996e59fa29d59a95c3fc6bc9
    https://github.com/scummvm/scummvm/commit/037131d977792257996e59fa29d59a95c3fc6bc9
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2024-02-23T18:59:27-10:00

Commit Message:
KEYMAPPER: Add method isEnabled to Common::Keymapper

Changed paths:
    backends/keymapper/keymapper.h


diff --git a/backends/keymapper/keymapper.h b/backends/keymapper/keymapper.h
index cfe2f528fab..1ffb30ad25a 100644
--- a/backends/keymapper/keymapper.h
+++ b/backends/keymapper/keymapper.h
@@ -124,6 +124,11 @@ public:
 	 */
 	void setEnabled(bool enabled) { _enabled = enabled; }
 
+	/**
+	 * Return the keymapper's enabled state
+	 */
+	bool isEnabled() const { return _enabled; }
+
 	/**
 	 * Clear all the keymaps and hardware input sets
 	 */


Commit: 816d1c6d8c360cf8ca0001664b856413a44768c7
    https://github.com/scummvm/scummvm/commit/816d1c6d8c360cf8ca0001664b856413a44768c7
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2024-02-23T18:59:27-10:00

Commit Message:
ULTIMA: NUVIE: Fix KEYINPUT_MODE keymapper regression

Disable the keymapper when entering KEYINPUT_MODE and restore
its previous state when changing mode.

Makes Events::key_redirect() work again.

The key_redirect method should cause all keyboard input to be
sent to a callback, but it was broken since commit
12a47d956ee00f62ed235c4009eb57ad0dbda19d
 "Add support for ScummVM keymapper".

This caused problems with spellcasting:

1. Keymapper-bound actions (including movement) were still
 possible while the spellbook was open

2. Spell syllables whose keys were bound via the keymapper
 could not be entered.

Fixes #14959

Changed paths:
    engines/ultima/nuvie/core/events.cpp
    engines/ultima/nuvie/core/events.h


diff --git a/engines/ultima/nuvie/core/events.cpp b/engines/ultima/nuvie/core/events.cpp
index 276e017f28d..f6c6403cea6 100644
--- a/engines/ultima/nuvie/core/events.cpp
+++ b/engines/ultima/nuvie/core/events.cpp
@@ -55,6 +55,7 @@
 #include "ultima/nuvie/script/script.h"
 
 #include "common/system.h"
+#include "backends/keymapper/keymapper.h"
 
 namespace Ultima {
 namespace Nuvie {
@@ -165,6 +166,7 @@ bool Events::init(ObjManager *om, MapWindow *mw, MsgScroll *ms, Player *p, Magic
 	gui->AddWidget(fps_counter_widget);
 	fps_counter_widget->Hide();
 	scriptThread = nullptr;
+	_keymapperStateBeforeKEYINPUT = true;
 
 	return true;
 }
@@ -3495,6 +3497,10 @@ bool Events::newAction(EventMode new_mode) {
  * This clears visible cursors, and resets all variables used by actions.
  */
 void Events::endAction(bool prompt) {
+	if (mode == KEYINPUT_MODE)
+		// Leaving KEYINPUT_MODE: restore keymapper state.
+		g_system->getEventManager()->getKeymapper()->setEnabled(_keymapperStateBeforeKEYINPUT);
+
 	if (prompt) {
 		scroll->display_string("\n");
 		scroll->display_prompt();
@@ -3554,6 +3560,18 @@ void Events::set_mode(EventMode new_mode) {
 	      print_mode(new_mode),
 	      print_mode(mode),
 	      print_mode(last_mode));
+
+	Common::Keymapper *const keymapper = g_system->getEventManager()->getKeymapper();
+	if (mode == KEYINPUT_MODE)
+		// Switching away from KEYINPUT_MODE: restore keymapper state.
+		keymapper->setEnabled(_keymapperStateBeforeKEYINPUT);
+
+	if (new_mode == KEYINPUT_MODE) {
+		// Switching to KEYINPUT_MODE: save keymapper state and disable.
+		_keymapperStateBeforeKEYINPUT = keymapper->isEnabled();
+		keymapper->setEnabled(false);
+	}
+
 	if (new_mode == WAIT_MODE && (last_mode == EQUIP_MODE || last_mode == REST_MODE))
 		last_mode = mode;
 	else if ((new_mode == INPUT_MODE || new_mode == KEYINPUT_MODE))
diff --git a/engines/ultima/nuvie/core/events.h b/engines/ultima/nuvie/core/events.h
index 0267cdb23e3..5700c4f86aa 100644
--- a/engines/ultima/nuvie/core/events.h
+++ b/engines/ultima/nuvie/core/events.h
@@ -225,6 +225,7 @@ private:
 	bool in_control_cheat;
 	bool looking_at_spellbook;
 	bool direction_selects_target;
+	bool _keymapperStateBeforeKEYINPUT;
 
 	uint32 fps_timestamp;
 	uint16 fps_counter;


Commit: a609f91a6ef7fbb054dcc94318400f81378ac005
    https://github.com/scummvm/scummvm/commit/a609f91a6ef7fbb054dcc94318400f81378ac005
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2024-02-23T18:59:27-10:00

Commit Message:
ULTIMA: NUVIE: Fix widgets deleting self in event handler

Do not delete widgets marked for deletion in GUI::AddWidget, so it
can safely be used from widget event handlers.

Fixes the following crashes in enhanced mode:

Using the look action on a spellbook in inventory eventually causes
a call to Events::look(Obj *obj) from ContainerWidget::try_click().

For spellbooks, look() then calls view_manager->close_all_gumps().
This closes all open gumps and marks them for deletion, including
the inventory ContainerWidget.

When the spellbook gump gets added via addWidget, this executes
the deletion.

Once control returns to ContainerWidget::try_click(), the
ContainerWidget has been deleted and the game will crash when it
tries to assign to member variable ready_obj.

A similar crash happens when selecting a staff in inventory
as the target for the enchant spell.

Fixes #14957

Changed paths:
    engines/ultima/nuvie/gui/gui.cpp


diff --git a/engines/ultima/nuvie/gui/gui.cpp b/engines/ultima/nuvie/gui/gui.cpp
index 0728f126f3d..952a873e8c5 100644
--- a/engines/ultima/nuvie/gui/gui.cpp
+++ b/engines/ultima/nuvie/gui/gui.cpp
@@ -71,31 +71,34 @@ GUI::~GUI() {
    The widget will be automatically deleted when the GUI is deleted.
  */
 int GUI::AddWidget(GUI_Widget *widget) {
-	int i;
+	int i = numwidgets;
 
+	// This is commented out because it makes it unsafe to call AddWidget
+	// from a widget's event handler: It could delete the calling widget
+	// if it was marked for deletion during event handling.
 	/* Look for deleted widgets */
-	for (i = 0; i < numwidgets; ++i) {
-		if (widgets[i]->Status() == WIDGET_DELETED) {
-			delete widgets[i];
-			break;
-		}
-	}
-	if (i == numwidgets) {
-		/* Expand the widgets array if necessary */
-		if (numwidgets == maxwidgets) {
-			GUI_Widget **newarray;
-			int maxarray;
-
-			maxarray = maxwidgets + WIDGET_ARRAYCHUNK;
-			if ((newarray = (GUI_Widget **)realloc(widgets,
-			                                       maxarray * sizeof(*newarray))) == nullptr) {
-				return -1;
-			}
-			widgets = newarray;
-			maxwidgets = maxarray;
+	// for (i = 0; i < numwidgets; ++i) {
+	// 	if (widgets[i]->Status() == WIDGET_DELETED) {
+	// 		delete widgets[i];
+	// 		break;
+	// 	}
+	// }
+	// if (i == numwidgets) {
+	/* Expand the widgets array if necessary */
+	if (numwidgets == maxwidgets) {
+		GUI_Widget **newarray;
+		int maxarray;
+
+		maxarray = maxwidgets + WIDGET_ARRAYCHUNK;
+		if ((newarray = (GUI_Widget **)realloc(widgets,
+		                                       maxarray * sizeof(*newarray))) == nullptr) {
+			return -1;
 		}
-		++numwidgets;
+		widgets = newarray;
+		maxwidgets = maxarray;
 	}
+	++numwidgets;
+	// }
 	widgets[i] = widget;
 	widget->PlaceOnScreen(screen, gui_drag_manager, 0, 0);
 


Commit: 696aea82e615c4f08231ba50014fd863df638aa9
    https://github.com/scummvm/scummvm/commit/696aea82e615c4f08231ba50014fd863df638aa9
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2024-02-23T18:59:27-10:00

Commit Message:
ULTIMA: NUVIE: Fix crash when selecting spell to enchant with

When casting enchant in new-style mode, after selecting an object
to enchant, the spellbook is opened to choose a spell.

While the book was open, walking and other actions were still
possible. This could lead to crashes, e.g. when pressing c to cast
instead of selecting a spell.

To prevent this, lock input to the spellbook's SpellViewGump and
unlock it again in endAction().

Changed paths:
    engines/ultima/nuvie/core/events.cpp


diff --git a/engines/ultima/nuvie/core/events.cpp b/engines/ultima/nuvie/core/events.cpp
index f6c6403cea6..1a04097e19b 100644
--- a/engines/ultima/nuvie/core/events.cpp
+++ b/engines/ultima/nuvie/core/events.cpp
@@ -3213,6 +3213,7 @@ void Events::doAction() {
 			get_inventory_obj(magic->get_actor_from_script());
 		} else if (magic->is_waiting_for_spell()) {
 			get_spell_num(player->get_actor(), magic->get_spellbook_obj());
+			gui->lock_input(view_manager->get_spell_view());
 		} else {
 			endAction(true);
 		}
@@ -3501,6 +3502,10 @@ void Events::endAction(bool prompt) {
 		// Leaving KEYINPUT_MODE: restore keymapper state.
 		g_system->getEventManager()->getKeymapper()->setEnabled(_keymapperStateBeforeKEYINPUT);
 
+	// Finished selecting a spell for enchant: undo spellbook input locking.
+	if (mode == CAST_MODE && gui->get_locked_widget() && gui->get_locked_widget() == view_manager->get_spell_view())
+		gui->unlock_input();
+
 	if (prompt) {
 		scroll->display_string("\n");
 		scroll->display_prompt();


Commit: 382abb7dad64dd6a62f8ccc80644de5d36cb1ce8
    https://github.com/scummvm/scummvm/commit/382abb7dad64dd6a62f8ccc80644de5d36cb1ce8
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2024-02-23T18:59:27-10:00

Commit Message:
ULTIMA: NUVIE: Fix SpellViewGump deleting self/crashing on RMB

Close spellbook in cancelAction when resuming magic.

Additionally, as a precaution, do not propagate RMB events
from SpellViewGump to DraggableView.

On an RMB-down event, SpellViewGump::MouseDown() calls
Events::close_spellbook(), which uses cancelAction() to actually
close the spellbook.

However, this skipped doing so if Magic::is_waiting_to_resume() was
true.

In that case, the still open SpellViewGump received the RMB-up event,
which lead to it getting closed and deleted from
DraggableView::MouseUp().

This resulted in a crash, since the book's SpellViewGump is not
expected to be deleted during gameplay.

To reproduce:

1. Start/load a game in enhanced-mode

2. Acquire a spellbook (obj num 57)

3. Acquire a staff (obj num 78)

4. Enable cheats (CTRL+c)

5. Enable unlimited casting (ALT+w)

6. (C)ast enchant

7. Select the staff as target

8. When prompted to select a spell, press RMB instead

Changed paths:
    engines/ultima/nuvie/core/events.cpp
    engines/ultima/nuvie/views/spell_view_gump.cpp


diff --git a/engines/ultima/nuvie/core/events.cpp b/engines/ultima/nuvie/core/events.cpp
index 1a04097e19b..0b29c706245 100644
--- a/engines/ultima/nuvie/core/events.cpp
+++ b/engines/ultima/nuvie/core/events.cpp
@@ -3340,8 +3340,8 @@ void Events::cancelAction() {
 		else {
 
 			scroll->display_string("nothing\n");
-			view_manager->close_spell_mode();
 		}
+		view_manager->close_spell_mode();
 	} else if (mode == USE_MODE) {
 		if (usecode->is_script_running()) {
 			usecode->get_running_script()->resume_with_nil();
diff --git a/engines/ultima/nuvie/views/spell_view_gump.cpp b/engines/ultima/nuvie/views/spell_view_gump.cpp
index 4fbabb35615..a1b27e64c93 100644
--- a/engines/ultima/nuvie/views/spell_view_gump.cpp
+++ b/engines/ultima/nuvie/views/spell_view_gump.cpp
@@ -326,6 +326,9 @@ GUI_status SpellViewGump::MouseDown(int x, int y, Shared::MouseButton button) {
 }
 
 GUI_status SpellViewGump::MouseUp(int x, int y, Shared::MouseButton button) {
+	if (button == Shared::BUTTON_RIGHT)
+		return GUI_YUM;
+
 	sint16 spell = getSpell(x, y);
 
 	if (spell != -1 && spell == selected_spell) {


Commit: 46221f1dbd2db0bb5b9d176fb70d8036fcf6ea8d
    https://github.com/scummvm/scummvm/commit/46221f1dbd2db0bb5b9d176fb70d8036fcf6ea8d
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2024-02-23T18:59:27-10:00

Commit Message:
ULTIMA: NUVIE: Fix enchant crash during spell selection

SpellViewGump and SpellView:
When handling a MouseDown event, do not call target_spell() if
event_mode is set, as Events expects us to select a spell in that case.

Prevents calling Events::target_spell() with callback_target set to
nullptr and subsequentially crashing the game.

To reproduce:

1. Start/load a game

2. Acquire a spellbook (obj num 57)

3. Acquire a staff (obj num 78)

4. Enable cheats (CTRL+c)

5. Enable unlimited casting (ALT+w)

6. (C)ast enchant

7. Select the staff as target

8. When prompted to select a spell, press LMB somewhere on the map
 instead

Changed paths:
    engines/ultima/nuvie/views/spell_view.cpp
    engines/ultima/nuvie/views/spell_view_gump.cpp


diff --git a/engines/ultima/nuvie/views/spell_view.cpp b/engines/ultima/nuvie/views/spell_view.cpp
index 95353677f6b..95afc903a03 100644
--- a/engines/ultima/nuvie/views/spell_view.cpp
+++ b/engines/ultima/nuvie/views/spell_view.cpp
@@ -431,7 +431,7 @@ GUI_status SpellView::MouseDown(int x, int y, Shared::MouseButton button) {
 	if (button == Shared::BUTTON_RIGHT)
 		return cancel_spell();
 
-	if (selecting_spell_target) { // cast selected spell on the map
+	if (selecting_spell_target && !event_mode) { // cast selected spell on the map
 		if (event->is_looking_at_spellbook()) {
 			close_look();
 			return GUI_YUM;
diff --git a/engines/ultima/nuvie/views/spell_view_gump.cpp b/engines/ultima/nuvie/views/spell_view_gump.cpp
index a1b27e64c93..5f046786c65 100644
--- a/engines/ultima/nuvie/views/spell_view_gump.cpp
+++ b/engines/ultima/nuvie/views/spell_view_gump.cpp
@@ -314,7 +314,8 @@ GUI_status SpellViewGump::MouseDown(int x, int y, Shared::MouseButton button) {
 			close_spellbook();
 			return GUI_YUM;
 		}
-		event->target_spell(); //Simulate a global key down event.
+		if (!event_mode)
+			event->target_spell(); //Simulate a global key down event.
 		if (event->get_mode() == INPUT_MODE)
 			Game::get_game()->get_map_window()->select_target(x, y);
 		if (event->get_mode() != MOVE_MODE)


Commit: e2a9b6be4dbdd7934df090eee9f84bfc50b608d7
    https://github.com/scummvm/scummvm/commit/e2a9b6be4dbdd7934df090eee9f84bfc50b608d7
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2024-02-23T18:59:27-10:00

Commit Message:
ULTIMA: NUVIE: Fix loss of focus when dragging SpellViewGump

Changed paths:
    engines/ultima/nuvie/views/spell_view_gump.cpp


diff --git a/engines/ultima/nuvie/views/spell_view_gump.cpp b/engines/ultima/nuvie/views/spell_view_gump.cpp
index 5f046786c65..f4ecd91c99f 100644
--- a/engines/ultima/nuvie/views/spell_view_gump.cpp
+++ b/engines/ultima/nuvie/views/spell_view_gump.cpp
@@ -347,7 +347,9 @@ GUI_status SpellViewGump::MouseUp(int x, int y, Shared::MouseButton button) {
 	}
 
 
-	return DraggableView::MouseUp(x, y, button);
+	auto ret = DraggableView::MouseUp(x, y, button);
+	grab_focus(); // Dragging releases focus, grab it again
+	return ret;
 }
 
 } // End of namespace Nuvie


Commit: 702ddabdecab40038653802c57deba26a91984e2
    https://github.com/scummvm/scummvm/commit/702ddabdecab40038653802c57deba26a91984e2
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2024-02-23T18:59:27-10:00

Commit Message:
ULTIMA: NUVIE: Lock input to spellbook when looking at it

Undo the lock in Events::endAction().

Allows navigating the book using the cursor keys in new-style.

Changed paths:
    engines/ultima/nuvie/core/events.cpp


diff --git a/engines/ultima/nuvie/core/events.cpp b/engines/ultima/nuvie/core/events.cpp
index 0b29c706245..21081c4c4e5 100644
--- a/engines/ultima/nuvie/core/events.cpp
+++ b/engines/ultima/nuvie/core/events.cpp
@@ -1020,6 +1020,7 @@ bool Events::look(Obj *obj) {
 					reader = player->get_actor();
 				view_manager->close_all_gumps();
 				view_manager->set_spell_mode(reader, obj, false);
+				gui->lock_input(view_manager->get_current_view());
 				view_manager->get_current_view()->grab_focus();
 				return false;
 			}
@@ -3502,9 +3503,12 @@ void Events::endAction(bool prompt) {
 		// Leaving KEYINPUT_MODE: restore keymapper state.
 		g_system->getEventManager()->getKeymapper()->setEnabled(_keymapperStateBeforeKEYINPUT);
 
-	// Finished selecting a spell for enchant: undo spellbook input locking.
-	if (mode == CAST_MODE && gui->get_locked_widget() && gui->get_locked_widget() == view_manager->get_spell_view())
-		gui->unlock_input();
+	// Finished selecting a spell for enchant or looking at spellbook: undo spellbook input locking.
+	if (mode == CAST_MODE || (mode == LOOK_MODE && !is_looking_at_spellbook())) {
+		const GUI_Widget *const lockedWidget = gui->get_locked_widget();
+		if (lockedWidget && lockedWidget == view_manager->get_spell_view())
+			gui->unlock_input();
+	}
 
 	if (prompt) {
 		scroll->display_string("\n");


Commit: e807f895737e3cc2b71b848c443ad902de1a6f76
    https://github.com/scummvm/scummvm/commit/e807f895737e3cc2b71b848c443ad902de1a6f76
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2024-02-23T18:59:27-10:00

Commit Message:
ULTIMA: NUVIE: Fix Wizard Eye keyboard control

Disable keymapper during Wizard Eye (spell and crystal ball effect)
so it can be controlled via the cursor keys again.

This was a regression introduced in
12a47d956ee00f62ed235c4009eb57ad0dbda19d
"Add support for ScummVM keymapper".

Changed paths:
    engines/ultima/nuvie/core/effect.cpp


diff --git a/engines/ultima/nuvie/core/effect.cpp b/engines/ultima/nuvie/core/effect.cpp
index 284a2a89ff0..d12f3ad19ca 100644
--- a/engines/ultima/nuvie/core/effect.cpp
+++ b/engines/ultima/nuvie/core/effect.cpp
@@ -38,6 +38,8 @@
 #include "ultima/nuvie/core/effect.h"
 #include "ultima/nuvie/core/player.h"
 
+#include "backends/keymapper/keymapper.h"
+
 namespace Ultima {
 namespace Nuvie {
 
@@ -1629,12 +1631,17 @@ uint16 PauseEffect::callback(uint16 msg, CallBack *caller, void *data) {
 }
 
 WizardEyeEffect::WizardEyeEffect(const MapCoord &location, uint16 duration) {
+	// Disable keymapper so Wizard Eye can receive keyboard input.
+	// FIXME: Remove this once the effect can use keymapper-bound keys.
+	g_system->getEventManager()->getKeymapper()->setEnabled(false);
 	game->get_map_window()->wizard_eye_start(location, duration, this);
 }
 
 uint16 WizardEyeEffect::callback(uint16 msg, CallBack *caller, void *data) {
 	if (msg == MESG_EFFECT_COMPLETE) {
 		delete_self();
+		// FIXME: Remove this once the effect can use keymapper-bound keys.
+		g_system->getEventManager()->getKeymapper()->setEnabled(true);
 	}
 
 	return 0;




More information about the Scummvm-git-logs mailing list