[Scummvm-git-logs] scummvm master -> 6a3251649010e0488046c5c994b600b5c831a209

dreammaster dreammaster at scummvm.org
Sat Apr 7 17:04:22 CEST 2018


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:
6a32516490 XEEN: Cache mouse clicks as well as keyboard in EventsManager


Commit: 6a3251649010e0488046c5c994b600b5c831a209
    https://github.com/scummvm/scummvm/commit/6a3251649010e0488046c5c994b600b5c831a209
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-04-07T11:02:09-04:00

Commit Message:
XEEN: Cache mouse clicks as well as keyboard in EventsManager

This allows the well open door/gate, shoot at enemies, then close
to work with the mouse as well as the keyboard. The pending event
queue has also been limited to 5 pending events. Trust me, you
don't want to spent time spamming Shoot at a high level monster
that can't reach you, only for when it's killed to have to wait
several minutes whilst your party keeps shooting.

Changed paths:
    engines/xeen/dialogs/dialogs.cpp
    engines/xeen/dialogs/dialogs_input.cpp
    engines/xeen/events.cpp
    engines/xeen/events.h
    engines/xeen/interface.cpp
    engines/xeen/scripts.cpp
    engines/xeen/worldofxeen/worldofxeen_menu.cpp


diff --git a/engines/xeen/dialogs/dialogs.cpp b/engines/xeen/dialogs/dialogs.cpp
index f404996..1b99ec6 100644
--- a/engines/xeen/dialogs/dialogs.cpp
+++ b/engines/xeen/dialogs/dialogs.cpp
@@ -66,51 +66,55 @@ bool ButtonContainer::checkEvents(XeenEngine *vm) {
 	EventsManager &events = *vm->_events;
 	Party &party = *vm->_party;
 	Windows &windows = *_vm->_windows;
+	PendingEvent event;
+	const Common::Rect WAIT_BOUNDS(8, 8, 224, 140);
 	_buttonValue = 0;
 
-	if (events._leftButton) {
-		Common::Point pt = events._mousePos;
-
-		// Check for party member glyphs being clicked
-		Common::Rect r(0, 0, 32, 32);
-		for (uint idx = 0; idx < party._activeParty.size(); ++idx) {
-			r.moveTo(Res.CHAR_FACES_X[idx], 150);
-			if (r.contains(pt)) {
-				_buttonValue = Common::KEYCODE_F1 + idx;
-				break;
+	if (events.getEvent(event)) {
+		if (event._leftButton) {
+			Common::Point pt = events._mousePos;
+
+			// Check for party member glyphs being clicked
+			Common::Rect r(0, 0, 32, 32);
+			for (uint idx = 0; idx < party._activeParty.size(); ++idx) {
+				r.moveTo(Res.CHAR_FACES_X[idx], 150);
+				if (r.contains(pt)) {
+					_buttonValue = Common::KEYCODE_F1 + idx;
+					break;
+				}
 			}
-		}
 
-		// Check whether any button is selected
-		for (uint i = 0; i < _buttons.size(); ++i) {
-			if (_buttons[i]._bounds.contains(pt)) {
-				events.debounceMouse();
+			// Check whether any button is selected
+			for (uint i = 0; i < _buttons.size(); ++i) {
+				if (_buttons[i]._bounds.contains(pt)) {
+					events.debounceMouse();
 
-				_buttonValue = _buttons[i]._value;
-				break;
+					_buttonValue = _buttons[i]._value;
+					break;
+				}
+			}
+
+			if (!_buttonValue && WAIT_BOUNDS.contains(pt)) {
+				_buttonValue = Common::KEYCODE_SPACE;
+				return true;
 			}
-		}
 
-		if (!_buttonValue && Common::Rect(8, 8, 224, 135).contains(pt)) {
-			_buttonValue = 1;
-			return true;
+		} else if (event.isKeyboard()) {
+			const Common::KeyCode &keycode = event._keyState.keycode;
+
+			if (keycode == Common::KEYCODE_KP8)
+				_buttonValue = Common::KEYCODE_UP;
+			else if (keycode == Common::KEYCODE_KP2)
+				_buttonValue = Common::KEYCODE_DOWN;
+			else if (keycode == Common::KEYCODE_KP_ENTER)
+				_buttonValue = Common::KEYCODE_RETURN;
+			else if (keycode != Common::KEYCODE_LCTRL && keycode != Common::KEYCODE_RCTRL
+					&& keycode != Common::KEYCODE_LALT && keycode != Common::KEYCODE_RALT)
+				_buttonValue = keycode;
+
+			if (_buttonValue)
+				_buttonValue |= (event._keyState.flags & ~Common::KBD_STICKY) << 16;
 		}
-	} else if (events.isKeyPending()) {
-		Common::KeyState keyState;
-		events.getKey(keyState);
-
-		if (keyState.keycode == Common::KEYCODE_KP8)
-			_buttonValue = Common::KEYCODE_UP;
-		else if (keyState.keycode == Common::KEYCODE_KP2)
-			_buttonValue = Common::KEYCODE_DOWN;
-		else if (keyState.keycode == Common::KEYCODE_KP_ENTER)
-			_buttonValue = Common::KEYCODE_RETURN;
-		else if (keyState.keycode != Common::KEYCODE_LCTRL && keyState.keycode != Common::KEYCODE_RCTRL
-				&& keyState.keycode != Common::KEYCODE_LALT && keyState.keycode != Common::KEYCODE_RALT)
-			_buttonValue = keyState.keycode;
-
-		if (_buttonValue)
-			_buttonValue |= (keyState.flags & ~Common::KBD_STICKY) << 16;
 	}
 
 	if (_buttonValue) {
diff --git a/engines/xeen/dialogs/dialogs_input.cpp b/engines/xeen/dialogs/dialogs_input.cpp
index b259908..214aa28 100644
--- a/engines/xeen/dialogs/dialogs_input.cpp
+++ b/engines/xeen/dialogs/dialogs_input.cpp
@@ -86,7 +86,7 @@ Common::KeyState Input::waitForKey(const Common::String &msg) {
 	bool flag = !_vm->_startupWindowActive && !windows[25]._enabled
 		&& _vm->_mode != MODE_FF && _vm->_mode != MODE_17;
 
-	Common::KeyState ks;
+	PendingEvent pe;
 	while (!_vm->shouldExit()) {
 		events.updateGameCounter();
 
@@ -100,11 +100,8 @@ Common::KeyState Input::waitForKey(const Common::String &msg) {
 			windows[3].update();
 
 		events.wait(1);
-
-		if (events.isKeyPending()) {
-			events.getKey(ks);
+		if (events.getEvent(pe) && pe.isKeyboard())
 			break;
-		}
 	}
 
 	_window->writeString("");
@@ -113,7 +110,7 @@ Common::KeyState Input::waitForKey(const Common::String &msg) {
 	intf._tillMove = oldTillMove;
 	intf._upDoorText = oldUpDoorText;
 
-	return ks;
+	return pe._keyState;
 }
 
 void Input::animateCursor() {
diff --git a/engines/xeen/events.cpp b/engines/xeen/events.cpp
index 6ceef44..7a0a512 100644
--- a/engines/xeen/events.cpp
+++ b/engines/xeen/events.cpp
@@ -33,7 +33,7 @@ namespace Xeen {
 
 EventsManager::EventsManager(XeenEngine *vm) : _vm(vm), _playTime(0),
 		_frameCounter(0), _priorFrameCounterTime(0), _gameCounter(0),
-		_leftButton(false), _rightButton(false), _sprites("mouse.icn") {
+		_mousePressed(false), _sprites("mouse.icn") {
 	Common::fill(&_gameCounters[0], &_gameCounters[6], 0);
 }
 
@@ -80,24 +80,23 @@ void EventsManager::pollEvents() {
 				_vm->_debugger->attach();
 				_vm->_debugger->onFrame();
 			} else {
-				_keys.push(event.kbd);
+				addEvent(event.kbd);
 			}
 			break;
 		case Common::EVENT_MOUSEMOVE:
 			_mousePos = event.mouse;
 			break;
 		case Common::EVENT_LBUTTONDOWN:
-			_leftButton = true;
-			return;
-		case Common::EVENT_LBUTTONUP:
-			_leftButton = false;
+			_mousePressed = true;
+			addEvent(true, false);
 			return;
 		case Common::EVENT_RBUTTONDOWN:
-			_rightButton = true;
-			return;
+			_mousePressed = true;
+			addEvent(false, true);
+		case Common::EVENT_LBUTTONUP:
 		case Common::EVENT_RBUTTONUP:
-			_rightButton = false;
-			break;
+			_mousePressed = false;
+			return;
 		default:
  			break;
 		}
@@ -110,31 +109,38 @@ void EventsManager::pollEventsAndWait() {
 }
 
 void EventsManager::clearEvents() {
-	_keys.clear();
-	_leftButton = _rightButton = false;
-
+	_pendingEvents.clear();
+	_mousePressed = false;
 }
 
 void EventsManager::debounceMouse() {
-	while (_leftButton && !_vm->shouldExit()) {
+	while (_mousePressed && !_vm->shouldExit()) {
 		pollEventsAndWait();
 	}
 }
-bool EventsManager::getKey(Common::KeyState &key) {
-	if (_keys.empty()) {
+
+void EventsManager::addEvent(const Common::KeyState &keyState) {
+	if (_pendingEvents.size() < MAX_PENDING_EVENTS)
+		_pendingEvents.push(PendingEvent(keyState));
+}
+
+void EventsManager::addEvent(bool leftButton, bool rightButton) {
+	if (_pendingEvents.size() < MAX_PENDING_EVENTS)
+		_pendingEvents.push(PendingEvent(leftButton, rightButton));
+}
+
+
+bool EventsManager::getEvent(PendingEvent &pe) {
+	if (_pendingEvents.empty()) {
 		return false;
 	} else {
-		key = _keys.pop();
+		pe = _pendingEvents.pop();
 		return true;
 	}
 }
 
-bool EventsManager::isKeyPending() const {
-	return !_keys.empty();
-}
-
 bool EventsManager::isKeyMousePressed() {
-	bool result = _leftButton || _rightButton || isKeyPending();
+	bool result = isEventPending();
 	debounceMouse();
 	clearEvents();
 
@@ -144,7 +150,7 @@ bool EventsManager::isKeyMousePressed() {
 bool EventsManager::wait(uint numFrames, bool interruptable) {
 	while (!_vm->shouldExit() && timeElapsed() < numFrames) {
 		pollEventsAndWait();
-		if (interruptable && (_leftButton || _rightButton || isKeyPending()))
+		if (interruptable && isEventPending())
 			return true;
 	}
 
diff --git a/engines/xeen/events.h b/engines/xeen/events.h
index 0ef2c3a..80ce83a 100644
--- a/engines/xeen/events.h
+++ b/engines/xeen/events.h
@@ -32,9 +32,30 @@ namespace Xeen {
 
 #define GAME_FRAME_RATE (1000 / 50)
 #define GAME_FRAME_TIME 50
+#define MAX_PENDING_EVENTS 5
 
 class XeenEngine;
 
+struct PendingEvent {
+	Common::KeyState _keyState;
+	bool _leftButton;
+	bool _rightButton;
+
+	PendingEvent() : _leftButton(false), _rightButton(false) {}
+	PendingEvent(const Common::KeyState &keyState) : _keyState(keyState), _leftButton(false), _rightButton(false) {}
+	PendingEvent(bool leftButton, bool rightButton) : _leftButton(leftButton), _rightButton(rightButton) {}
+
+	/**
+	 * Returns true if a keyboard event is pending
+	 */
+	bool isKeyboard() const { return _keyState.keycode != Common::KEYCODE_INVALID; }
+
+	/**
+	 * Returns ture if a mouse button event is pending
+	 */
+	bool isMouse() const { return _leftButton || _rightButton; }
+};
+
 class EventsManager {
 private:
 	XeenEngine *_vm;
@@ -43,19 +64,18 @@ private:
 	uint32 _gameCounter;
 	uint32 _gameCounters[6];
 	uint32 _playTime;
-	Common::Queue<Common::KeyState> _keys;
+	Common::Queue<PendingEvent> _pendingEvents;
 	SpriteResource _sprites;
+	bool _mousePressed;
 
 	/**
 	 * Handles moving to the next game frame
 	 */
 	void nextFrame();
 public:
-	bool _leftButton, _rightButton;
 	Common::Point _mousePos;
 public:
 	EventsManager(XeenEngine *vm);
-
 	~EventsManager();
 
 	/*
@@ -78,17 +98,45 @@ public:
 	 */
 	bool isCursorVisible();
 
+	/**
+	 * Polls the ScummVM backend for any pending events
+	 */
 	void pollEvents();
 
+	/**
+	 * Polls for events, and wait a slight delay. This ensures the game doesn't use up 100% of the CPU
+	 */
 	void pollEventsAndWait();
 
+	/**
+	 * Clears all pending events
+	 */
 	void clearEvents();
 
+	/**
+	 * Waits for a mouse press to be released
+	 */
 	void debounceMouse();
 
-	bool getKey(Common::KeyState &key);
+	/**
+	 * Adds a keyboard event to the queue
+	 */
+	void addEvent(const Common::KeyState &keyState);
+
+	/**
+	 * Adds a mouse button event to the queue
+	 */
+	void addEvent(bool leftButton, bool rightButton);
 
-	bool isKeyPending() const;
+	/**
+	 * Returns the next pending key/mouse press, if any
+	 */
+	bool getEvent(PendingEvent &pe);
+
+	/**
+	 * Returns true if a key or mouse event is pending
+	 */
+	bool isEventPending() const { return !_pendingEvents.empty(); }
 
 	/**
 	 * Returns true if a key or mouse press is pending
diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp
index 8e52aae..88b33c4 100644
--- a/engines/xeen/interface.cpp
+++ b/engines/xeen/interface.cpp
@@ -262,7 +262,6 @@ void Interface::perform() {
 	Party &party = *_vm->_party;
 	Scripts &scripts = *_vm->_scripts;
 	Sound &sound = *_vm->_sound;
-	const Common::Rect WAIT_BOUNDS(8, 8, 224, 140);
 
 	do {
 		// Draw the next frame
@@ -276,10 +275,7 @@ void Interface::perform() {
 			if (g_vm->shouldExit() || g_vm->isLoadPending() || party._dead)
 				return;
 
-			if (events._leftButton && WAIT_BOUNDS.contains(events._mousePos))
-				_buttonValue = Common::KEYCODE_SPACE;
-			else
-				checkEvents(g_vm);
+			checkEvents(g_vm);
 		} while (!_buttonValue && events.timeElapsed() < 1);
 	} while (!_buttonValue);
 
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index 92204fc..7d36b83 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -214,7 +214,7 @@ int Scripts::checkEvents() {
 		MazeObject &selectedObj = map._mobData._objects[intf._objNumber];
 
 		if (selectedObj._spriteId == (ccNum ? 15 : 16)) {
-			for (uint idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) {
+			for (int idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) {
 				MazeObject &obj = map._mobData._objects[idx];
 				if (obj._spriteId == (ccNum ? 62 : 57)) {
 					selectedObj._id = idx;
@@ -223,7 +223,7 @@ int Scripts::checkEvents() {
 				}
 			}
 		} else if (selectedObj._spriteId == 73) {
-			for (uint idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) {
+			for (int idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) {
 				MazeObject &obj = map._mobData._objects[idx];
 				if (obj._spriteId == 119) {
 					selectedObj._id = idx;
diff --git a/engines/xeen/worldofxeen/worldofxeen_menu.cpp b/engines/xeen/worldofxeen/worldofxeen_menu.cpp
index 8356794..a4a4b02 100644
--- a/engines/xeen/worldofxeen/worldofxeen_menu.cpp
+++ b/engines/xeen/worldofxeen/worldofxeen_menu.cpp
@@ -110,11 +110,9 @@ void MainMenuContainer::execute() {
 			} else {
 				// No active dialog. If Escape pressed, exit game entirely. Otherwise,
 				// open up the main menu dialog
-				if (events.isKeyPending()) {
-					Common::KeyState key;
-					if (events.getKey(key) && key.keycode == Common::KEYCODE_ESCAPE)
-						g_vm->_gameMode = GMODE_QUIT;
-				}
+				PendingEvent pe;
+				if (events.getEvent(pe) && pe._keyState.keycode == Common::KEYCODE_ESCAPE)
+					g_vm->_gameMode = GMODE_QUIT;
 
 				events.clearEvents();
 				showMenuDialog();





More information about the Scummvm-git-logs mailing list