[Scummvm-git-logs] scummvm master -> 0541c5f602285a3d41a4159f4885b95259bd1259

mgerhardy martin.gerhardy at gmail.com
Wed Dec 30 21:22:43 UTC 2020


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

Summary:
b591d9e0e3 TWINE: use Common::Rect
0a97afc141 TWINE: optimized rendering inventory items for drawcalls
9bb1739dc5 TWINE: reduced scope of title rect vars
aaad819269 TWINE: reduced drawcalls
32427c733c TWINE: added new debug command to modify the magic level
b0ab44995d TWINE: fixed assert when rendering the info menu without having magic levels set
c01584e4ce TWINE: only give 1 item with the debug command
5bbb781c73 TWINE: improved magic points rendering
e0bd6ae9d8 TWINE: ensure that we don't exceed the max allowed values via debug cmd
82a0dc4c92 TWINE: more default joystick bindings
0541c5f602 TWINE: fixed missing ui keymap in Text::displayText


Commit: b591d9e0e37512177ce515764598f9768028d863
    https://github.com/scummvm/scummvm/commit/b591d9e0e37512177ce515764598f9768028d863
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T14:22:45+01:00

Commit Message:
TWINE: use Common::Rect

Changed paths:
    engines/twine/renderer/redraw.cpp
    engines/twine/renderer/redraw.h


diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index 0b18086dae..c8bdbeee89 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -44,66 +44,46 @@
 
 namespace TwinE {
 
-void Redraw::addRedrawCurrentArea(int32 left, int32 top, int32 right, int32 bottom) {
-	int32 i = 0;
-
-	const int32 area = (right - left) * (bottom - top);
-
-	while (i < numOfRedrawBox) {
-		int32 leftValue;
-		if (currentRedrawList[i].left >= left) {
-			leftValue = left;
-		} else {
-			leftValue = currentRedrawList[i].left;
-		}
-
-		int32 rightValue;
-		if (currentRedrawList[i].right <= right) {
-			rightValue = right;
-		} else {
-			rightValue = currentRedrawList[i].right;
-		}
-
-		int32 topValue;
-		if (currentRedrawList[i].top >= top) {
-			topValue = top;
-		} else {
-			topValue = currentRedrawList[i].top;
-		}
-
-		int32 bottomValue;
-		if (currentRedrawList[i].bottom <= bottom) {
-			bottomValue = bottom;
-		} else {
-			bottomValue = currentRedrawList[i].bottom;
-		}
-
-		if ((rightValue - leftValue) * (bottomValue - topValue) < ((currentRedrawList[i].bottom - currentRedrawList[i].top) * (currentRedrawList[i].right - currentRedrawList[i].left) + area)) {
-			currentRedrawList[i].left = leftValue;
-			currentRedrawList[i].top = topValue;
-			currentRedrawList[i].right = rightValue;
-			currentRedrawList[i].bottom = MIN<int32>(SCREEN_TEXTLIMIT_BOTTOM, bottomValue);
-
-			assert(currentRedrawList[i].left <= currentRedrawList[i].right);
-			assert(currentRedrawList[i].top <= currentRedrawList[i].bottom);
+void Redraw::addRedrawCurrentArea(const Common::Rect &redrawArea) {
+	const int32 area = (redrawArea.right - redrawArea.left) * (redrawArea.bottom - redrawArea.top);
+
+	for (int32 i = 0; i < numOfRedrawBox; ++i) {
+		Common::Rect &rect = currentRedrawList[i];
+		const int32 leftValue = MIN<int32>(redrawArea.left, rect.left);
+		const int32 rightValue = MAX<int32>(redrawArea.right, rect.right);
+		const int32 topValue = MIN<int32>(redrawArea.top, rect.top);
+		const int32 bottomValue = MAX<int32>(redrawArea.bottom, rect.bottom);
+
+		const int32 areaValue = (rightValue - leftValue) * (bottomValue - topValue);
+		const int32 areaValueDiff = ((rect.right - rect.left) * (rect.bottom - rect.top) + area);
+		if (areaValue < areaValueDiff) {
+			rect.left = leftValue;
+			rect.top = topValue;
+			rect.right = rightValue;
+			rect.bottom = MIN<int32>(SCREEN_TEXTLIMIT_BOTTOM, bottomValue);
+
+			assert(rect.left <= rect.right);
+			assert(rect.top <= rect.bottom);
 			return;
 		}
-
-		i++;
 	}
 
-	currentRedrawList[i].left = left;
-	currentRedrawList[i].top = top;
-	currentRedrawList[i].right = right;
-	currentRedrawList[i].bottom = MIN<int32>(SCREEN_TEXTLIMIT_BOTTOM, bottom);
+	Common::Rect &rect = currentRedrawList[numOfRedrawBox];
+	rect.left = redrawArea.left;
+	rect.top = redrawArea.top;
+	rect.right = redrawArea.right;
+	rect.bottom = MIN<int32>(SCREEN_TEXTLIMIT_BOTTOM, redrawArea.bottom);
 
-	assert(currentRedrawList[i].left <= currentRedrawList[i].right);
-	assert(currentRedrawList[i].top <= currentRedrawList[i].bottom);
+	assert(rect.left <= rect.right);
+	assert(rect.top <= rect.bottom);
 
 	numOfRedrawBox++;
 }
 
 void Redraw::addRedrawArea(const Common::Rect &rect) {
+	if (!rect.isValidRect()) {
+		return;
+	}
 	addRedrawArea(rect.left, rect.top, rect.right, rect.bottom);
 }
 
@@ -125,21 +105,22 @@ void Redraw::addRedrawArea(int32 left, int32 top, int32 right, int32 bottom) {
 		return;
 	}
 
-	nextRedrawList[currNumOfRedrawBox].left = left;
-	nextRedrawList[currNumOfRedrawBox].top = top;
-	nextRedrawList[currNumOfRedrawBox].right = right;
-	nextRedrawList[currNumOfRedrawBox].bottom = bottom;
+	Common::Rect &rect = nextRedrawList[currNumOfRedrawBox];
+	rect.left = left;
+	rect.top = top;
+	rect.right = right;
+	rect.bottom = bottom;
 
 	currNumOfRedrawBox++;
 
-	addRedrawCurrentArea(left, top, right, bottom);
+	addRedrawCurrentArea(rect);
 }
 
 void Redraw::moveNextAreas() {
 	numOfRedrawBox = 0;
 
 	for (int32 i = 0; i < currNumOfRedrawBox; i++) {
-		addRedrawCurrentArea(nextRedrawList[i].left, nextRedrawList[i].top, nextRedrawList[i].right, nextRedrawList[i].bottom);
+		addRedrawCurrentArea(nextRedrawList[i]);
 	}
 }
 
@@ -151,7 +132,7 @@ void Redraw::flipRedrawAreas() {
 	numOfRedrawBox = 0;
 
 	for (int32 i = 0; i < currNumOfRedrawBox; i++) { //setup the redraw areas for next display
-		addRedrawCurrentArea(nextRedrawList[i].left, nextRedrawList[i].top, nextRedrawList[i].right, nextRedrawList[i].bottom);
+		addRedrawCurrentArea(nextRedrawList[i]);
 	}
 }
 
@@ -349,7 +330,7 @@ void Redraw::processDrawListShadows(const DrawListStruct &drawCmd) {
 
 	_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
 
-	addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+	addRedrawArea(_engine->_interface->textWindow);
 
 	// show clipping area
 	//drawBox(_engine->_renderer->renderRect.left, _engine->_renderer->renderRect.top, _engine->_renderer->renderRect.right, _engine->_renderer->renderRect.bottom);
@@ -401,11 +382,10 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
 			renderRect.bottom = _engine->_interface->textWindow.bottom = _engine->_actor->cropBottomScreen + 10;
 		}
 
-		const Common::Rect rect(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
-		addRedrawArea(rect);
+		addRedrawArea(_engine->_interface->textWindow);
 
 		if (actor->staticFlags.bIsBackgrounded && bgRedraw) {
-			_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
+			_engine->_interface->blitBox(_engine->_interface->textWindow, _engine->frontVideoBuffer, _engine->workVideoBuffer);
 		}
 
 		_engine->_debugScene->drawClip(renderRect);
@@ -502,7 +482,7 @@ void Redraw::processDrawListExtras(const DrawListStruct &drawCmd) {
 		const int32 tmpZ = (drawCmd.z + BRICK_HEIGHT) / BRICK_SIZE;
 
 		_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
-		addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+		addRedrawArea(_engine->_interface->textWindow);
 
 		// show clipping area
 		//drawBox(renderRect);
@@ -584,9 +564,7 @@ void Redraw::renderOverlays() {
 
 				_engine->_grid->drawSprite(renderRect.left, renderRect.top, spritePtr);
 
-				if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-					addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
-				}
+				addRedrawArea(_engine->_interface->textWindow);
 				break;
 			}
 			case OverlayType::koNumber: {
@@ -607,9 +585,7 @@ void Redraw::renderOverlays() {
 
 				_engine->_text->drawText(renderRect.left, renderRect.top, text);
 
-				if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-					addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
-				}
+				addRedrawArea(_engine->_interface->textWindow);
 				break;
 			}
 			case OverlayType::koNumberRange: {
@@ -632,9 +608,7 @@ void Redraw::renderOverlays() {
 
 				_engine->_text->drawText(renderRect.left, renderRect.top, text);
 
-				if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-					addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
-				}
+				addRedrawArea(_engine->_interface->textWindow);
 				break;
 			}
 			case OverlayType::koInventoryItem: {
@@ -690,9 +664,7 @@ void Redraw::renderOverlays() {
 
 				_engine->_text->drawText(renderRect.left, renderRect.top, text);
 
-				if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-					addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
-				}
+				addRedrawArea(_engine->_interface->textWindow);
 				break;
 			}
 			}
diff --git a/engines/twine/renderer/redraw.h b/engines/twine/renderer/redraw.h
index d25d679477..d766edfd8d 100644
--- a/engines/twine/renderer/redraw.h
+++ b/engines/twine/renderer/redraw.h
@@ -86,12 +86,9 @@ private:
 	int16 overlayRotation = 0;
 	/**
 	 * Add a certain region to the current redraw list array
-	 * @param left start width to redraw the region
-	 * @param top start height to redraw the region
-	 * @param right end width to redraw the region
-	 * @param bottom end height to redraw the region
+	 * @param redrawArea redraw the region
 	 */
-	void addRedrawCurrentArea(int32 left, int32 top, int32 right, int32 bottom);
+	void addRedrawCurrentArea(const Common::Rect &redrawArea);
 	/** Move next regions to the current redraw list */
 	void moveNextAreas();
 	/**


Commit: 0a97afc1414a17b9edbaf09889bc75bf035b651c
    https://github.com/scummvm/scummvm/commit/0a97afc1414a17b9edbaf09889bc75bf035b651c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T14:28:46+01:00

Commit Message:
TWINE: optimized rendering inventory items for drawcalls

Changed paths:
    engines/twine/menu/menu.cpp
    engines/twine/menu/menu.h


diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index 6490bb3ec5..4537eaf4b2 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -1046,7 +1046,7 @@ void Menu::drawMagicItemsBox(int32 left, int32 top, int32 right, int32 bottom, i
 	_engine->_interface->drawLine(++left, bottom, right, bottom, color);                      // bottom line
 }
 
-void Menu::drawItem(int32 item) {
+void Menu::drawItem(int32 item, Common::Rect &dirtyRect) {
 	const int32 itemX = (item / 4) * 85 + 64;
 	const int32 itemY = (item & 3) * 75 + 52;
 
@@ -1070,7 +1070,11 @@ void Menu::drawItem(int32 item) {
 	}
 
 	drawBox(rect);
-	_engine->copyBlockPhys(rect);
+	if (dirtyRect.isEmpty()) {
+		dirtyRect = rect;
+	} else {
+		dirtyRect.extend(rect);
+	}
 }
 
 void Menu::drawInventoryItems() {
@@ -1080,8 +1084,12 @@ void Menu::drawInventoryItems() {
 	drawMagicItemsBox(110, 18, 188, 311, 75);
 	_engine->copyBlockPhys(rect);
 
+	Common::Rect dirtyRect;
 	for (int32 item = 0; item < NUM_INVENTORY_ITEMS; item++) {
-		drawItem(item);
+		drawItem(item, dirtyRect);
+	}
+	if (!dirtyRect.isEmpty()) {
+		_engine->copyBlockPhys(dirtyRect);
 	}
 }
 
@@ -1129,33 +1137,34 @@ void Menu::processInventoryMenu() {
 		const bool cursorLeft = _engine->_input->toggleActionIfActive(TwinEActionType::UILeft);
 		const bool cursorRight = _engine->_input->toggleActionIfActive(TwinEActionType::UIRight);
 
+		Common::Rect dirtyRect;
 		if (cursorDown) {
 			inventorySelectedItem++;
 			if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
 				inventorySelectedItem = 0;
 			}
-			drawItem(prevSelectedItem);
+			drawItem(prevSelectedItem, dirtyRect);
 			updateItemText = true;
 		} else if (cursorUp) {
 			inventorySelectedItem--;
 			if (inventorySelectedItem < 0) {
 				inventorySelectedItem = NUM_INVENTORY_ITEMS - 1;
 			}
-			drawItem(prevSelectedItem);
+			drawItem(prevSelectedItem, dirtyRect);
 			updateItemText = true;
 		} else if (cursorLeft) {
 			inventorySelectedItem -= 4;
 			if (inventorySelectedItem < 0) {
 				inventorySelectedItem += NUM_INVENTORY_ITEMS;
 			}
-			drawItem(prevSelectedItem);
+			drawItem(prevSelectedItem, dirtyRect);
 			updateItemText = true;
 		} else if (cursorRight) {
 			inventorySelectedItem += 4;
 			if (inventorySelectedItem >= NUM_INVENTORY_ITEMS) {
 				inventorySelectedItem -= NUM_INVENTORY_ITEMS;
 			}
-			drawItem(prevSelectedItem);
+			drawItem(prevSelectedItem, dirtyRect);
 			updateItemText = true;
 		}
 
@@ -1185,14 +1194,21 @@ void Menu::processInventoryMenu() {
 			}
 		}
 
-		drawItem(inventorySelectedItem);
+		drawItem(inventorySelectedItem, dirtyRect);
 
 		if (inventorySelectedItem < NUM_INVENTORY_ITEMS && _engine->_input->toggleActionIfActive(TwinEActionType::UIEnter) && _engine->_gameState->hasItem((InventoryItems)inventorySelectedItem) && !_engine->_gameState->inventoryDisabled()) {
 			_engine->loopInventoryItem = inventorySelectedItem;
 			inventorySelectedColor = 91;
-			drawItem(inventorySelectedItem);
+			drawItem(inventorySelectedItem, dirtyRect);
+			if (!dirtyRect.isEmpty()) {
+				_engine->copyBlockPhys(dirtyRect);
+			}
 			break;
 		}
+
+		if (!dirtyRect.isEmpty()) {
+			_engine->copyBlockPhys(dirtyRect);
+		}
 	}
 
 	_engine->_text->_hasValidTextHandle = false;
diff --git a/engines/twine/menu/menu.h b/engines/twine/menu/menu.h
index 6532d15c1d..80a69b00b0 100644
--- a/engines/twine/menu/menu.h
+++ b/engines/twine/menu/menu.h
@@ -171,7 +171,7 @@ private:
 	void drawInventoryItems();
 	void prepareAndDrawBehaviour(int32 angle, HeroBehaviourType behaviour);
 	void drawBehaviourMenu(int32 angle);
-	void drawItem(int32 item);
+	void drawItem(int32 item, Common::Rect &dirtyRect);
 	/**
 	 * Draw the entire button box
 	 * @param left start width to draw the button


Commit: 9bb1739dc57fb1dc776c492828ca1a0d6eab1bf8
    https://github.com/scummvm/scummvm/commit/9bb1739dc57fb1dc776c492828ca1a0d6eab1bf8
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T14:34:25+01:00

Commit Message:
TWINE: reduced scope of title rect vars

Changed paths:
    engines/twine/menu/menu.cpp


diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index 4537eaf4b2..21c8099090 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -877,13 +877,6 @@ bool Menu::isBehaviourHovered(HeroBehaviourType behaviour) const {
 
 void Menu::drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDrawBox) {
 	const Common::Rect &boxRect = calcBehaviourRect(behaviour);
-	const int titleOffset = 10;
-	const int titleHeight = 40;
-	const int32 titleBoxLeft = 110;
-	const int32 titleBoxRight = 540;
-	const int32 titleBoxTop = boxRect.bottom + titleOffset;
-	const int32 titleBoxBottom = titleBoxTop + titleHeight;
-	const Common::Rect titleRect(titleBoxLeft, titleBoxTop, titleBoxRight, titleBoxBottom);
 
 	const uint8 *currentAnim = _engine->_resources->animTable[_engine->_actor->heroAnimIdx[(byte)behaviour]];
 	int16 currentAnimState = behaviourAnimState[(byte)behaviour];
@@ -906,9 +899,17 @@ void Menu::drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDraw
 	_engine->_interface->resetClip();
 
 	if (behaviour == _engine->_actor->heroBehaviour) {
+		const int titleOffset = 10;
+		const int titleHeight = 40;
+		const int32 titleBoxLeft = 110;
+		const int32 titleBoxRight = 540;
+		const int32 titleBoxTop = boxRect.bottom + titleOffset;
+		const int32 titleBoxBottom = titleBoxTop + titleHeight;
+
 		_engine->_interface->drawSplittedBox(boxRect, 69);
 
 		// behaviour menu title
+		const Common::Rect titleRect(titleBoxLeft, titleBoxTop, titleBoxRight, titleBoxBottom);
 		_engine->_interface->drawSplittedBox(titleRect, 0);
 		drawBox(titleRect);
 
@@ -918,6 +919,7 @@ void Menu::drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDraw
 		_engine->_text->getMenuText(_engine->_actor->getTextIdForBehaviour(), dialText, sizeof(dialText));
 
 		_engine->_text->drawText(SCREEN_WIDTH / 2 - _engine->_text->getTextSize(dialText) / 2, titleBoxTop + 1, dialText);
+		_engine->copyBlockPhys(titleRect);
 	} else {
 		_engine->_interface->drawSplittedBox(boxRect, 0);
 	}
@@ -925,7 +927,6 @@ void Menu::drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDraw
 	_engine->_renderer->renderBehaviourModel(boxRect, -600, angle, behaviourEntity);
 
 	_engine->copyBlockPhys(boxRect);
-	_engine->copyBlockPhys(titleRect);
 
 	_engine->_interface->loadClip();
 }


Commit: aaad819269880fee601fc77a7cdd03fe5f566265
    https://github.com/scummvm/scummvm/commit/aaad819269880fee601fc77a7cdd03fe5f566265
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T14:41:31+01:00

Commit Message:
TWINE: reduced drawcalls

Changed paths:
    engines/twine/menu/menu.cpp
    engines/twine/menu/menu.h


diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index 21c8099090..c83df0fdee 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -875,7 +875,7 @@ bool Menu::isBehaviourHovered(HeroBehaviourType behaviour) const {
 	return _engine->_input->isMouseHovering(boxRect);
 }
 
-void Menu::drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDrawBox) {
+void Menu::drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDrawBox, Common::Rect &dirtyRect) {
 	const Common::Rect &boxRect = calcBehaviourRect(behaviour);
 
 	const uint8 *currentAnim = _engine->_resources->animTable[_engine->_actor->heroAnimIdx[(byte)behaviour]];
@@ -926,14 +926,18 @@ void Menu::drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDraw
 
 	_engine->_renderer->renderBehaviourModel(boxRect, -600, angle, behaviourEntity);
 
-	_engine->copyBlockPhys(boxRect);
+	if (dirtyRect.isEmpty()) {
+		dirtyRect = boxRect;
+	} else {
+		dirtyRect.extend(boxRect);
+	}
 
 	_engine->_interface->loadClip();
 }
 
-void Menu::prepareAndDrawBehaviour(int32 angle, HeroBehaviourType behaviour) {
+void Menu::prepareAndDrawBehaviour(int32 angle, HeroBehaviourType behaviour, Common::Rect &dirtyRect) {
 	_engine->_animations->setAnimAtKeyframe(behaviourAnimState[(byte)behaviour], _engine->_resources->animTable[_engine->_actor->heroAnimIdx[(byte)behaviour]], behaviourEntity, &behaviourAnimData[(byte)behaviour]);
-	drawBehaviour(behaviour, angle, false);
+	drawBehaviour(behaviour, angle, false, dirtyRect);
 }
 
 void Menu::drawBehaviourMenu(int32 angle) {
@@ -944,14 +948,15 @@ void Menu::drawBehaviourMenu(int32 angle) {
 	boxRect.grow(-1);
 	_engine->_interface->drawTransparentBox(boxRect, 2);
 
-	prepareAndDrawBehaviour(angle, HeroBehaviourType::kNormal);
-	prepareAndDrawBehaviour(angle, HeroBehaviourType::kAthletic);
-	prepareAndDrawBehaviour(angle, HeroBehaviourType::kAggressive);
-	prepareAndDrawBehaviour(angle, HeroBehaviourType::kDiscrete);
-
-	drawInfoMenu(titleRect.left, titleRect.bottom + 10);
+	Common::Rect ignoreRect;
+	prepareAndDrawBehaviour(angle, HeroBehaviourType::kNormal, ignoreRect);
+	prepareAndDrawBehaviour(angle, HeroBehaviourType::kAthletic, ignoreRect);
+	prepareAndDrawBehaviour(angle, HeroBehaviourType::kAggressive, ignoreRect);
+	prepareAndDrawBehaviour(angle, HeroBehaviourType::kDiscrete, ignoreRect);
 
 	_engine->copyBlockPhys(titleRect);
+
+	drawInfoMenu(titleRect.left, titleRect.bottom + 10);
 }
 
 void Menu::processBehaviourMenu() {
@@ -1019,14 +1024,18 @@ void Menu::processBehaviourMenu() {
 
 		_engine->_actor->heroBehaviour = (HeroBehaviourType)heroBehaviour;
 
+		Common::Rect dirtyRect;
 		if (tmpHeroBehaviour != _engine->_actor->heroBehaviour) {
-			drawBehaviour(tmpHeroBehaviour, _engine->_scene->sceneHero->angle, true);
+			drawBehaviour(tmpHeroBehaviour, _engine->_scene->sceneHero->angle, true, dirtyRect);
 			tmpHeroBehaviour = _engine->_actor->heroBehaviour;
 			_engine->_movements->setActorAngleSafe(_engine->_scene->sceneHero->angle, _engine->_scene->sceneHero->angle - ANGLE_90, 50, &moveMenu);
 			_engine->_animations->setAnimAtKeyframe(behaviourAnimState[(byte)_engine->_actor->heroBehaviour], _engine->_resources->animTable[_engine->_actor->heroAnimIdx[(byte)_engine->_actor->heroBehaviour]], behaviourEntity, &behaviourAnimData[(byte)_engine->_actor->heroBehaviour]);
 		}
 
-		drawBehaviour(_engine->_actor->heroBehaviour, -1, true);
+		drawBehaviour(_engine->_actor->heroBehaviour, -1, true, dirtyRect);
+		if (!dirtyRect.isEmpty()) {
+			_engine->copyBlockPhys(dirtyRect);
+		}
 
 		_engine->lbaTime++;
 	}
diff --git a/engines/twine/menu/menu.h b/engines/twine/menu/menu.h
index 80a69b00b0..c718c91bcd 100644
--- a/engines/twine/menu/menu.h
+++ b/engines/twine/menu/menu.h
@@ -167,9 +167,9 @@ private:
 	void drawInfoMenu(int16 left, int16 top);
 	Common::Rect calcBehaviourRect(HeroBehaviourType behaviour) const;
 	bool isBehaviourHovered(HeroBehaviourType behaviour) const;
-	void drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDrawBox);
+	void drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDrawBox, Common::Rect &dirtyRect);
 	void drawInventoryItems();
-	void prepareAndDrawBehaviour(int32 angle, HeroBehaviourType behaviour);
+	void prepareAndDrawBehaviour(int32 angle, HeroBehaviourType behaviour, Common::Rect &dirtyRect);
 	void drawBehaviourMenu(int32 angle);
 	void drawItem(int32 item, Common::Rect &dirtyRect);
 	/**


Commit: 32427c733cd2bfa416a768a4720d7c40e39efc83
    https://github.com/scummvm/scummvm/commit/32427c733cd2bfa416a768a4720d7c40e39efc83
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T15:09:19+01:00

Commit Message:
TWINE: added new debug command to modify the magic level

Changed paths:
    engines/twine/debugger/console.cpp
    engines/twine/debugger/console.h


diff --git a/engines/twine/debugger/console.cpp b/engines/twine/debugger/console.cpp
index 1fd170a433..04fe63a46b 100644
--- a/engines/twine/debugger/console.cpp
+++ b/engines/twine/debugger/console.cpp
@@ -22,6 +22,7 @@
 
 #include "twine/debugger/console.h"
 #include "common/scummsys.h"
+#include "common/util.h"
 #include "twine/debugger/debug_grid.h"
 #include "twine/debugger/debug_scene.h"
 #include "twine/scene/gamestate.h"
@@ -35,6 +36,7 @@ TwinEConsole::TwinEConsole(TwinEEngine *engine) : _engine(engine), GUI::Debugger
 	registerCmd("give_allitems", WRAP_METHOD(TwinEConsole, doGiveAllItems));
 	registerCmd("give_key", WRAP_METHOD(TwinEConsole, doGiveKey));
 	registerCmd("change_scene", WRAP_METHOD(TwinEConsole, doChangeScene));
+	registerCmd("magic_points", WRAP_METHOD(TwinEConsole, doAddMagicPoints));
 	registerCmd("list_menutext", WRAP_METHOD(TwinEConsole, doListMenuText));
 	registerCmd("toggle_debug", WRAP_METHOD(TwinEConsole, doToggleDebug));
 	registerCmd("toggle_zones", WRAP_METHOD(TwinEConsole, doToggleZoneRendering));
@@ -73,6 +75,17 @@ bool TwinEConsole::doToggleClipRendering(int argc, const char **argv) {
 	return true;
 }
 
+bool TwinEConsole::doAddMagicPoints(int argc, const char **argv) {
+	if (argc < 2) {
+		debugPrintf("Usage: specify the magic points\n");
+		return false;
+	}
+	const int16 magicPoints = atoi(argv[1]);
+	_engine->_gameState->magicLevelIdx = CLIP<int16>(magicPoints, 0, 4);
+	_engine->_gameState->inventoryMagicPoints = _engine->_gameState->magicLevelIdx * 20;
+	return true;
+}
+
 bool TwinEConsole::doSkipSceneActorsBut(int argc, const char **argv) {
 	if (argc < 2) {
 		debugPrintf("Usage: give actor id of scene or -1 to disable\n");
diff --git a/engines/twine/debugger/console.h b/engines/twine/debugger/console.h
index 401093f319..c7e2db2b36 100644
--- a/engines/twine/debugger/console.h
+++ b/engines/twine/debugger/console.h
@@ -48,6 +48,7 @@ private:
 	bool doSkipSceneActorsBut(int argc, const char **argv);
 	bool doSetGameFlag(int argc, const char **argv);
 	bool doSetInventoryFlag(int argc, const char **argv);
+	bool doAddMagicPoints(int argc, const char **argv);
 public:
 	TwinEConsole(TwinEEngine *engine);
 	~TwinEConsole() override;


Commit: b0ab44995de504526037b9d814e619285dcbeef6
    https://github.com/scummvm/scummvm/commit/b0ab44995de504526037b9d814e619285dcbeef6
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T15:10:46+01:00

Commit Message:
TWINE: fixed assert when rendering the info menu without having magic levels set

Changed paths:
    engines/twine/menu/menu.cpp
    engines/twine/menu/menu.h


diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index c83df0fdee..03264dbcc6 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -794,26 +794,25 @@ int32 Menu::giveupMenu() {
 	return 0;
 }
 
-void Menu::drawInfoMenu(int16 left, int16 top) {
+void Menu::drawInfoMenu(int16 left, int16 top, int16 width) {
 	_engine->_interface->resetClip();
-	const int32 width = 450;
-	const int32 height = 80;
+	const int16 height = 80;
 	const Common::Rect rect(left, top, left + width, top + height);
 	drawBox(rect);
 	Common::Rect splittedBoxRect(rect);
 	splittedBoxRect.grow(-1);
 	_engine->_interface->drawSplittedBox(splittedBoxRect, 0);
 
-	int32 newBoxLeft2 = left + 9;
+	const int32 newBoxLeft2 = left + 9;
 
 	_engine->_grid->drawSprite(newBoxLeft2, top + 13, _engine->_resources->spriteData[SPRITEHQR_LIFEPOINTS]);
 
-	int32 boxRight = left + 325;
-	int32 newBoxLeft = left + 25;
+	const int32 boxRight = left + 325;
+	const int32 newBoxLeft = left + 25;
 	int32 boxLeft = _engine->_screens->crossDot(newBoxLeft, boxRight, 50, _engine->_scene->sceneHero->life);
 
-	int32 boxTop = top + 10;
-	int32 boxBottom = top + 25;
+	const int32 boxTop = top + 10;
+	const int32 boxBottom = top + 25;
 	_engine->_interface->drawSplittedBox(Common::Rect(newBoxLeft, boxTop, boxLeft, boxBottom), 91);
 	drawBox(newBoxLeft, boxTop, left + 324, boxTop + 14);
 
@@ -822,7 +821,9 @@ void Menu::drawInfoMenu(int16 left, int16 top) {
 		if (_engine->_gameState->magicLevelIdx > 0) {
 			_engine->_interface->drawSplittedBox(Common::Rect(newBoxLeft, top + 35, _engine->_screens->crossDot(newBoxLeft, boxRight, 80, _engine->_gameState->inventoryMagicPoints), top + 50), 75);
 		}
-		drawBox(newBoxLeft, top + 35, left + _engine->_gameState->magicLevelIdx * 80 + 20, top + 35 + 15);
+		if (_engine->_gameState->magicLevelIdx > 0) {
+			drawBox(newBoxLeft, top + 35, left + _engine->_gameState->magicLevelIdx * 80 + 20, top + 35 + 15);
+		}
 	}
 
 	boxLeft = left + 340;
@@ -956,7 +957,7 @@ void Menu::drawBehaviourMenu(int32 angle) {
 
 	_engine->copyBlockPhys(titleRect);
 
-	drawInfoMenu(titleRect.left, titleRect.bottom + 10);
+	drawInfoMenu(titleRect.left, titleRect.bottom + 10, titleRect.width());
 }
 
 void Menu::processBehaviourMenu() {
diff --git a/engines/twine/menu/menu.h b/engines/twine/menu/menu.h
index c718c91bcd..699122a43d 100644
--- a/engines/twine/menu/menu.h
+++ b/engines/twine/menu/menu.h
@@ -164,7 +164,7 @@ private:
 	int32 volumeMenu();
 	/** Used to run the save game management menu */
 	int32 savemanageMenu();
-	void drawInfoMenu(int16 left, int16 top);
+	void drawInfoMenu(int16 left, int16 top, int16 width);
 	Common::Rect calcBehaviourRect(HeroBehaviourType behaviour) const;
 	bool isBehaviourHovered(HeroBehaviourType behaviour) const;
 	void drawBehaviour(HeroBehaviourType behaviour, int32 angle, bool cantDrawBox, Common::Rect &dirtyRect);


Commit: c01584e4ceb9c4655e260f8dec587e52100eb798
    https://github.com/scummvm/scummvm/commit/c01584e4ceb9c4655e260f8dec587e52100eb798
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T15:14:54+01:00

Commit Message:
TWINE: only give 1 item with the debug command

10 already exceeds the max allowed values for some of them

Changed paths:
    engines/twine/debugger/console.cpp


diff --git a/engines/twine/debugger/console.cpp b/engines/twine/debugger/console.cpp
index 04fe63a46b..2a5038f164 100644
--- a/engines/twine/debugger/console.cpp
+++ b/engines/twine/debugger/console.cpp
@@ -217,7 +217,7 @@ bool TwinEConsole::doGiveAllItems(int argc, const char **argv) {
 		_engine->_gameState->inventoryFlags[i] = 1;
 	}
 	_engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED] = 0;
-	int amount = 10;
+	int amount = 1;
 	if (argc >= 2) {
 		amount = atoi(argv[1]);
 	}


Commit: 5bbb781c739864903441cf6636b230ff369a6c4b
    https://github.com/scummvm/scummvm/commit/5bbb781c739864903441cf6636b230ff369a6c4b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T15:27:22+01:00

Commit Message:
TWINE: improved magic points rendering

Changed paths:
    engines/twine/menu/menu.cpp


diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index 03264dbcc6..65acf73106 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -819,10 +819,10 @@ void Menu::drawInfoMenu(int16 left, int16 top, int16 width) {
 	if (!_engine->_gameState->inventoryDisabled() && _engine->_gameState->hasItem(InventoryItems::kiTunic)) {
 		_engine->_grid->drawSprite(newBoxLeft2, top + 36, _engine->_resources->spriteData[SPRITEHQR_MAGICPOINTS]);
 		if (_engine->_gameState->magicLevelIdx > 0) {
-			_engine->_interface->drawSplittedBox(Common::Rect(newBoxLeft, top + 35, _engine->_screens->crossDot(newBoxLeft, boxRight, 80, _engine->_gameState->inventoryMagicPoints), top + 50), 75);
-		}
-		if (_engine->_gameState->magicLevelIdx > 0) {
-			drawBox(newBoxLeft, top + 35, left + _engine->_gameState->magicLevelIdx * 80 + 20, top + 35 + 15);
+			const int32 pointBoxRight = _engine->_screens->crossDot(newBoxLeft, boxRight, 80, _engine->_gameState->inventoryMagicPoints);
+			const Common::Rect pointsRect(newBoxLeft, top + 35, pointBoxRight, top + 50);
+			_engine->_interface->drawSplittedBox(pointsRect, 75);
+			drawBox(newBoxLeft, top + 35, newBoxLeft + _engine->_gameState->magicLevelIdx * 80, top + 35 + 15);
 		}
 	}
 


Commit: e0bd6ae9d89d3f6f866c99c176080efcf80741de
    https://github.com/scummvm/scummvm/commit/e0bd6ae9d89d3f6f866c99c176080efcf80741de
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T19:14:13+01:00

Commit Message:
TWINE: ensure that we don't exceed the max allowed values via debug cmd

Changed paths:
    engines/twine/debugger/console.cpp


diff --git a/engines/twine/debugger/console.cpp b/engines/twine/debugger/console.cpp
index 2a5038f164..2998f0b36d 100644
--- a/engines/twine/debugger/console.cpp
+++ b/engines/twine/debugger/console.cpp
@@ -212,21 +212,43 @@ bool TwinEConsole::doChangeScene(int argc, const char **argv) {
 }
 
 bool TwinEConsole::doGiveAllItems(int argc, const char **argv) {
+	GameState* state = _engine->_gameState;
 	for (int32 i = 0; i < NUM_INVENTORY_ITEMS; ++i) {
-		_engine->_gameState->gameFlags[i] = 1;
-		_engine->_gameState->inventoryFlags[i] = 1;
+		state->gameFlags[i] = 1;
+		state->inventoryFlags[i] = 1;
 	}
 	_engine->_gameState->gameFlags[GAMEFLAG_INVENTORY_DISABLED] = 0;
 	int amount = 1;
 	if (argc >= 2) {
 		amount = atoi(argv[1]);
 	}
-	_engine->_gameState->inventoryNumKeys += amount;
-	_engine->_gameState->inventoryNumKashes += amount;
-	_engine->_gameState->inventoryNumLeafsBox += amount;
-	_engine->_gameState->inventoryNumLeafs += amount;
-	_engine->_gameState->inventoryMagicPoints += amount;
-	_engine->_gameState->inventoryNumGas += amount;
+	state->inventoryNumKeys += amount;
+	state->inventoryNumKashes += amount;
+	state->inventoryNumLeafsBox += amount;
+	state->inventoryNumLeafs += amount;
+	state->inventoryMagicPoints += amount;
+	state->inventoryNumGas += amount;
+
+	if (state->inventoryNumKashes > 999) {
+		state->inventoryNumKashes = 999;
+	}
+
+	if (state->inventoryNumLeafsBox > 10) {
+		state->inventoryNumLeafsBox = 10;
+	}
+
+	if (state->inventoryNumLeafs > state->inventoryNumLeafsBox) {
+		state->inventoryNumLeafs = state->inventoryNumLeafsBox;
+	}
+
+	if (state->inventoryNumGas > 100) {
+		state->inventoryNumGas = 100;
+	}
+
+	if (state->inventoryMagicPoints > state->magicLevelIdx * 20) {
+		state->inventoryMagicPoints = state->magicLevelIdx * 20;
+	}
+
 	return true;
 }
 


Commit: 82a0dc4c92110bd2bd5045f641f909fe1741890e
    https://github.com/scummvm/scummvm/commit/82a0dc4c92110bd2bd5045f641f909fe1741890e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T21:44:16+01:00

Commit Message:
TWINE: more default joystick bindings

Changed paths:
    engines/twine/metaengine.cpp


diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index b6bbf29dd8..ca1ebd9f0b 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -156,6 +156,17 @@ const ExtraGuiOptions TwinEMetaEngine::getExtraGuiOptions(const Common::String &
 	return options;
 }
 
+//
+// unused:
+// JOY_LEFT_TRIGGER
+// JOY_RIGHT_TRIGGER
+// JOY_RIGHT_SHOULDER
+//
+// JOY_RIGHT_STICK_X
+// JOY_RIGHT_STICK_Y
+// JOY_LEFT_STICK_X
+// JOY_LEFT_STICK_Y
+//
 Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 	using namespace Common;
 	Action *act;
@@ -275,6 +286,7 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->setCustomEngineActionEvent(TwinEActionType::BehaviourMenu);
 		act->addDefaultInputMapping("LCTRL");
 		act->addDefaultInputMapping("RCTRL");
+		act->addDefaultInputMapping("JOY_X");
 		gameKeyMap->addAction(act);
 
 		act = new Action("OPTIONSMENU", _("Options Menu"));
@@ -286,6 +298,7 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->setCustomEngineActionEvent(TwinEActionType::RecenterScreenOnTwinsen);
 		act->addDefaultInputMapping("RETURN");
 		act->addDefaultInputMapping("KP_ENTER");
+		act->addDefaultInputMapping("JOY_RIGHT_STICK");
 		gameKeyMap->addAction(act);
 
 		act = new Action("USESELECTEDOBJECT", _("Use Selected Object"));
@@ -298,30 +311,35 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->setCustomEngineActionEvent(TwinEActionType::ThrowMagicBall);
 		act->addDefaultInputMapping("LALT");
 		act->addDefaultInputMapping("RALT");
+		act->addDefaultInputMapping("JOY_LEFT_STICK");
 		gameKeyMap->addAction(act);
 
 		act = new Action("MOVEFORWARD", _("Move Forward"));
 		act->setCustomEngineActionEvent(TwinEActionType::MoveForward);
 		act->addDefaultInputMapping("UP");
 		act->addDefaultInputMapping("KP8");
+		act->addDefaultInputMapping("JOY_UP");
 		gameKeyMap->addAction(act);
 
 		act = new Action("MOVEBACKWARD", _("Move Backward"));
 		act->setCustomEngineActionEvent(TwinEActionType::MoveBackward);
 		act->addDefaultInputMapping("DOWN");
 		act->addDefaultInputMapping("KP2");
+		act->addDefaultInputMapping("JOY_DOWN");
 		gameKeyMap->addAction(act);
 
 		act = new Action("TURNRIGHT", _("Turn Right"));
 		act->setCustomEngineActionEvent(TwinEActionType::TurnRight);
 		act->addDefaultInputMapping("RIGHT");
 		act->addDefaultInputMapping("KP6");
+		act->addDefaultInputMapping("JOY_RIGHT");
 		gameKeyMap->addAction(act);
 
 		act = new Action("TURNLEFT", _("Turn Left"));
 		act->setCustomEngineActionEvent(TwinEActionType::TurnLeft);
 		act->addDefaultInputMapping("LEFT");
 		act->addDefaultInputMapping("KP4");
+		act->addDefaultInputMapping("JOY_LEFT");
 		gameKeyMap->addAction(act);
 
 		act = new Action("USEPROTOPACK", _("Use Protopack"));
@@ -338,17 +356,21 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->setCustomEngineActionEvent(TwinEActionType::InventoryMenu);
 		act->addDefaultInputMapping("LSHIFT");
 		act->addDefaultInputMapping("RSHIFT");
+		act->addDefaultInputMapping("JOY_Y");
 		act->addDefaultInputMapping("i");
 		gameKeyMap->addAction(act);
 
 		act = new Action("SPECIALACTION", _("Special Action"));
 		act->setCustomEngineActionEvent(TwinEActionType::SpecialAction);
 		act->addDefaultInputMapping("w");
+		act->addDefaultInputMapping("JOY_LEFT_SHOULDER");
 		gameKeyMap->addAction(act);
 
 		act = new Action("ESCAPE", _("Escape"));
 		act->setCustomEngineActionEvent(TwinEActionType::Escape);
 		act->addDefaultInputMapping("ESCAPE");
+		act->addDefaultInputMapping("JOY_B");
+		act->addDefaultInputMapping("JOY_BACK");
 		gameKeyMap->addAction(act);
 
 		array[0] = gameKeyMap;
@@ -362,24 +384,29 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->addDefaultInputMapping("RETURN");
 		act->addDefaultInputMapping("KP_ENTER");
 		act->addDefaultInputMapping("MOUSE_LEFT");
+		act->addDefaultInputMapping("JOY_A");
 		uiKeyMap->addAction(act);
 
 		act = new Action("ABORT", _("Abort"));
 		act->setCustomEngineActionEvent(TwinEActionType::UIAbort);
 		act->addDefaultInputMapping("ESCAPE");
 		act->addDefaultInputMapping("MOUSE_RIGHT");
+		act->addDefaultInputMapping("JOY_BACK");
+		act->addDefaultInputMapping("JOY_B");
 		uiKeyMap->addAction(act);
 
 		act = new Action("UP", _("Up"));
 		act->setCustomEngineActionEvent(TwinEActionType::UIUp);
 		act->addDefaultInputMapping("UP");
 		act->addDefaultInputMapping("KP8");
+		act->addDefaultInputMapping("JOY_UP");
 		uiKeyMap->addAction(act);
 
 		act = new Action("DOWN", _("Down"));
 		act->setCustomEngineActionEvent(TwinEActionType::UIDown);
 		act->addDefaultInputMapping("DOWN");
 		act->addDefaultInputMapping("KP2");
+		act->addDefaultInputMapping("JOY_DOWN");
 		uiKeyMap->addAction(act);
 
 		act = new Action("RIGHT", _("Right"));
@@ -387,6 +414,7 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->addDefaultInputMapping("RIGHT");
 		act->addDefaultInputMapping("KP6");
 		act->addDefaultInputMapping("MOUSE_WHEEL_UP");
+		act->addDefaultInputMapping("JOY_RIGHT");
 		uiKeyMap->addAction(act);
 
 		act = new Action("LEFT", _("Left"));
@@ -394,12 +422,15 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->addDefaultInputMapping("LEFT");
 		act->addDefaultInputMapping("KP4");
 		act->addDefaultInputMapping("MOUSE_WHEEL_DOWN");
+		act->addDefaultInputMapping("JOY_LEFT");
 		uiKeyMap->addAction(act);
 
 		act = new Action("NEXTPAGE", _("Next Page"));
 		act->setCustomEngineActionEvent(TwinEActionType::UINextPage);
 		act->addDefaultInputMapping("SPACE");
 		act->addDefaultInputMapping("PAGEDOWN");
+		act->addDefaultInputMapping("JOY_B");
+		act->addDefaultInputMapping("JOY_BACK");
 		uiKeyMap->addAction(act);
 
 		array[1] = uiKeyMap;
@@ -414,6 +445,8 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->addDefaultInputMapping("KP_ENTER");
 		act->addDefaultInputMapping("ESCAPE");
 		act->addDefaultInputMapping("SPACE");
+		act->addDefaultInputMapping("JOY_B");
+		act->addDefaultInputMapping("JOY_BACK");
 		cutsceneKeyMap->addAction(act);
 
 		array[2] = cutsceneKeyMap;
@@ -428,6 +461,8 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act = new Action("ABORT", _("Abort"));
 		act->setCustomEngineActionEvent(TwinEActionType::HolomapAbort);
 		act->addDefaultInputMapping("ESCAPE");
+		act->addDefaultInputMapping("JOY_B");
+		act->addDefaultInputMapping("JOY_BACK");
 		holomapKeyMap->addAction(act);
 
 		act = new Action("UP", _("Up"));
@@ -435,6 +470,7 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->addDefaultInputMapping("UP");
 		act->addDefaultInputMapping("KP8");
 		act->addDefaultInputMapping("MOUSE_WHEEL_UP");
+		act->addDefaultInputMapping("JOY_UP");
 		holomapKeyMap->addAction(act);
 
 		act = new Action("DOWN", _("Down"));
@@ -442,18 +478,21 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		act->addDefaultInputMapping("DOWN");
 		act->addDefaultInputMapping("KP2");
 		act->addDefaultInputMapping("MOUSE_WHEEL_DOWN");
+		act->addDefaultInputMapping("JOY_DOWN");
 		holomapKeyMap->addAction(act);
 
 		act = new Action("RIGHT", _("Right"));
 		act->setCustomEngineActionEvent(TwinEActionType::HolomapRight);
 		act->addDefaultInputMapping("RIGHT");
 		act->addDefaultInputMapping("KP6");
+		act->addDefaultInputMapping("JOY_RIGHT");
 		holomapKeyMap->addAction(act);
 
 		act = new Action("LEFT", _("Left"));
 		act->setCustomEngineActionEvent(TwinEActionType::HolomapLeft);
 		act->addDefaultInputMapping("LEFT");
 		act->addDefaultInputMapping("KP4");
+		act->addDefaultInputMapping("JOY_LEFT");
 		holomapKeyMap->addAction(act);
 
 		array[3] = holomapKeyMap;


Commit: 0541c5f602285a3d41a4159f4885b95259bd1259
    https://github.com/scummvm/scummvm/commit/0541c5f602285a3d41a4159f4885b95259bd1259
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-30T22:09:11+01:00

Commit Message:
TWINE: fixed missing ui keymap in Text::displayText

this fixes https://bugs.scummvm.org/ticket/12031 and https://bugs.scummvm.org/ticket/11982

Changed paths:
    engines/twine/text.cpp


diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 90b19b9415..deb98b836d 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -565,7 +565,7 @@ ProgressiveTextState Text::updateProgressiveText() {
 	_dialTextYPos += lineHeight;
 	_dialTextXPos = _dialTextBox.left + 8;
 
-	if (_dialTextBoxCurrentLine > _dialTextBoxLines) {
+	if (_dialTextBoxCurrentLine >= _dialTextBoxLines) {
 		renderContinueReadingTriangle();
 		return ProgressiveTextState::NextPage;
 	}
@@ -588,6 +588,7 @@ bool Text::displayText(int32 index, bool showText, bool playVox) {
 		initText(index);
 		initDialogueBox();
 
+		ScopedKeyMap uiKeyMap(_engine, uiKeyMapId);
 		ProgressiveTextState textState = ProgressiveTextState::ContinueRunning;
 		for (;;) {
 			ScopedFPS scopedFps(66);




More information about the Scummvm-git-logs mailing list