[Scummvm-cvs-logs] scummvm master -> e6466b20fa510187aaa277756a86ebc71ebf96b8

m-kiewitz m_kiewitz at users.sourceforge.net
Sun Feb 28 15:50:16 CET 2016


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:
e6466b20fa AGI: Add optional "pause, when entering commands" feature


Commit: e6466b20fa510187aaa277756a86ebc71ebf96b8
    https://github.com/scummvm/scummvm/commit/e6466b20fa510187aaa277756a86ebc71ebf96b8
Author: Martin Kiewitz (m_kiewitz at users.sourceforge.net)
Date: 2016-02-28T15:50:25+01:00

Commit Message:
AGI: Add optional "pause, when entering commands" feature

Shows a prompt window and pauses the game (just like original AGI
did, but original AGI only did it in Hercules rendering mode).

Changed paths:
    engines/agi/detection.cpp
    engines/agi/detection_tables.h
    engines/agi/systemui.cpp
    engines/agi/systemui.h
    engines/agi/text.cpp
    engines/agi/text.h
    engines/agi/words.cpp
    engines/agi/words.h



diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 308489a..7127584 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -181,6 +181,16 @@ static const ADExtraGuiOptionsMap optionsList[] = {
 		}
 	},
 
+	{
+		GAMEOPTION_COMMAND_PROMPT_WINDOW,
+		{
+			_s("Pause, when entering commands"),
+			_s("Shows a command prompt window and pauses the game (like in SCI) instead of a real-time prompt."),
+			"commandpromptwindow",
+			false
+		}
+	},
+
 	AD_EXTRA_GUI_OPTIONS_TERMINATOR
 };
 
diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h
index 87da0c2..0938e9d 100644
--- a/engines/agi/detection_tables.h
+++ b/engines/agi/detection_tables.h
@@ -26,11 +26,12 @@ namespace Agi {
 #define GAMEOPTION_AMIGA_ALTERNATIVE_PALETTE  GUIO_GAMEOPTIONS2
 #define GAMEOPTION_DISABLE_MOUSE              GUIO_GAMEOPTIONS3
 #define GAMEOPTION_USE_HERCULES_FONT          GUIO_GAMEOPTIONS4
+#define GAMEOPTION_COMMAND_PROMPT_WINDOW      GUIO_GAMEOPTIONS5
 // TODO: properly implement GAMEOPTIONs
 
-#define GAMEOPTIONS_DEFAULT                   GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD,GAMEOPTION_DISABLE_MOUSE,GAMEOPTION_USE_HERCULES_FONT)
-#define GAMEOPTIONS_AMIGA                     GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD,GAMEOPTION_AMIGA_ALTERNATIVE_PALETTE,GAMEOPTION_USE_HERCULES_FONT)
-#define GAMEOPTIONS_FANMADE_MOUSE             GUIO2(GAMEOPTION_ORIGINAL_SAVELOAD,GAMEOPTION_USE_HERCULES_FONT)
+#define GAMEOPTIONS_DEFAULT                   GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD,GAMEOPTION_DISABLE_MOUSE,GAMEOPTION_USE_HERCULES_FONT,GAMEOPTION_COMMAND_PROMPT_WINDOW)
+#define GAMEOPTIONS_AMIGA                     GUIO4(GAMEOPTION_ORIGINAL_SAVELOAD,GAMEOPTION_AMIGA_ALTERNATIVE_PALETTE,GAMEOPTION_USE_HERCULES_FONT,GAMEOPTION_COMMAND_PROMPT_WINDOW)
+#define GAMEOPTIONS_FANMADE_MOUSE             GUIO3(GAMEOPTION_ORIGINAL_SAVELOAD,GAMEOPTION_USE_HERCULES_FONT,GAMEOPTION_COMMAND_PROMPT_WINDOW)
 
 #define GAME_LVFPN(id,extra,fname,md5,size,lang,ver,features,gid,platform,interp,guioptions) { \
 		{ \
diff --git a/engines/agi/systemui.cpp b/engines/agi/systemui.cpp
index 7aa2613..aeb1ded 100644
--- a/engines/agi/systemui.cpp
+++ b/engines/agi/systemui.cpp
@@ -44,6 +44,8 @@ SystemUI::SystemUI(AgiEngine *vm, GfxMgr *gfx, TextMgr *text) {
 	_textStatusSoundOn = "Sound:on";
 	_textStatusSoundOff = "Sound:off";
 
+	_textEnterCommand = "Enter input\n\n";
+
 	_textPause = "      Game paused.\nPress Enter to continue.";
 	_textPauseButton = nullptr;
 
@@ -214,6 +216,47 @@ const char *SystemUI::getInventoryTextReturnToGame() {
 	return _textInventoryReturnToGame;
 }
 
+bool SystemUI::askForCommand(Common::String &commandText) {
+	// Let user enter the command (this was originally only available for Hercules rendering, we allow it everywhere)
+	bool previousEditState = _text->inputGetEditStatus();
+	byte previousEditCursor = _text->inputGetCursorChar();
+
+	_text->drawMessageBox(_textEnterCommand, 0, 36, true);
+
+	_text->inputEditOn();
+
+	_text->charPos_Push();
+	_text->charAttrib_Push();
+
+	_text->charPos_SetInsideWindow(2, 0);
+	_text->charAttrib_Set(15, 0);
+	_text->clearBlockInsideWindow(2, 0, 36, 0); // input line is supposed to be black
+	_text->inputSetCursorChar('_');
+
+	_text->stringSet(commandText.c_str()); // Set current command text (may be a command recall)
+
+	_vm->cycleInnerLoopActive(CYCLE_INNERLOOP_GETSTRING);
+	_text->stringEdit(35); // only allow up to 35 characters
+
+	_text->charAttrib_Pop();
+	_text->charPos_Pop();
+	_text->inputSetCursorChar(previousEditCursor);
+	if (!previousEditState) {
+		_text->inputEditOff();
+	}
+
+	_text->closeWindow();
+
+	if (!_text->stringWasEntered()) {
+		// User cancelled? exit now
+		return false;
+	}
+
+	commandText.clear();
+	commandText += (char *)_text->_inputString;
+	return true;
+}
+
 int16 SystemUI::figureOutAutomaticSaveGameSlot(const char *automaticSaveDescription) {
 	int16 matchedGameSlotId = -1;
 	int16 freshGameSlotId   = -1;
diff --git a/engines/agi/systemui.h b/engines/agi/systemui.h
index ffb1238..283de87 100644
--- a/engines/agi/systemui.h
+++ b/engines/agi/systemui.h
@@ -77,6 +77,8 @@ public:
 	const char *getInventoryTextSelectItems();
 	const char *getInventoryTextReturnToGame();
 
+	bool askForCommand(Common::String &commandText);
+
 	int16 figureOutAutomaticSaveGameSlot(const char *automaticSaveDescription);
 	int16 figureOutAutomaticRestoreGameSlot(const char *automaticSaveDescription);
 
@@ -130,6 +132,8 @@ private:
 	const char *_textStatusSoundOn;
 	const char *_textStatusSoundOff;
 
+	const char *_textEnterCommand;
+
 	const char *_textPause;
 	const char *_textPauseButton;
 	const char *_textRestart;
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index 18254d8..0cacce2 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -20,6 +20,7 @@
  *
  */
 
+#include "common/config-manager.h"
 #include "agi/agi.h"
 #include "agi/sprite.h"     // for commit_both()
 #include "agi/graphics.h"
@@ -74,6 +75,12 @@ TextMgr::TextMgr(AgiEngine *vm, Words *words, GfxMgr *gfx) {
 	configureScreen(2);
 
 	_messageBoxCancelled = false;
+
+	_optionCommandPromptWindow = false;
+
+	if (ConfMan.getBool("commandpromptwindow")) {
+		_optionCommandPromptWindow = true;
+	}
 }
 
 TextMgr::~TextMgr() {
@@ -671,6 +678,30 @@ void TextMgr::promptKeyPress(uint16 newKey) {
 	int16 maxChars = 0;
 	int16 scriptsInputLen = _vm->getVar(VM_VAR_MAX_INPUT_CHARACTERS);
 
+	bool acceptableInput = false;
+
+	// FEATURE: Sierra didn't check for valid characters (filtered out umlauts etc.)
+	// In text-mode this sort of worked at least with the DOS interpreter
+	// but as soon as invalid characters were used in graphics mode they weren't properly shown
+	switch (_vm->getLanguage()) {
+	case Common::RU_RUS:
+		if (newKey >= 0x20)
+			acceptableInput = true;
+		break;
+	default:
+		if ((newKey >= 0x20) && (newKey <= 0x7f))
+			acceptableInput = true;
+		break;
+	}
+
+	if (_optionCommandPromptWindow) {
+		// Forward to command prompt window, using last command
+		if (acceptableInput) {
+			promptCommandWindow(false, newKey);
+		}
+		return;
+	}
+
 	if (_messageState.dialogue_Open) {
 		maxChars = TEXT_STRING_MAX_SIZE - 4;
 	} else {
@@ -715,22 +746,6 @@ void TextMgr::promptKeyPress(uint16 newKey) {
 	}
 	default:
 		if (maxChars > _promptCursorPos) {
-			bool acceptableInput = false;
-
-			// FEATURE: Sierra didn't check for valid characters (filtered out umlauts etc.)
-			// In text-mode this sort of worked at least with the DOS interpreter
-			// but as soon as invalid characters were used in graphics mode they weren't properly shown
-			switch (_vm->getLanguage()) {
-			case Common::RU_RUS:
-				if (newKey >= 0x20)
-					acceptableInput = true;
-				break;
-			default:
-				if ((newKey >= 0x20) && (newKey <= 0x7f))
-					acceptableInput = true;
-				break;
-			}
-
 			if (acceptableInput) {
 				_prompt[_promptCursorPos] = newKey;
 				_promptCursorPos++;
@@ -747,6 +762,11 @@ void TextMgr::promptKeyPress(uint16 newKey) {
 }
 
 void TextMgr::promptCancelLine() {
+	if (_optionCommandPromptWindow) {
+		// Abort, in case command prompt window is active
+		return;
+	}
+
 	while (_promptCursorPos) {
 		promptKeyPress(0x08); // Backspace until prompt is empty
 	}
@@ -755,6 +775,12 @@ void TextMgr::promptCancelLine() {
 void TextMgr::promptEchoLine() {
 	int16 previousLen = strlen((char *)_promptPrevious);
 
+	if (_optionCommandPromptWindow) {
+		// Forward to command prompt window, using last command
+		promptCommandWindow(true, 0);
+		return;
+	}
+
 	if (_promptCursorPos < previousLen) {
 		inputEditOn();
 
@@ -771,6 +797,11 @@ void TextMgr::promptRedraw() {
 	char *textPtr = nullptr;
 
 	if (_promptEnabled) {
+		if (_optionCommandPromptWindow) {
+			// Abort, in case command prompt window is active
+			return;
+		}
+
 		inputEditOn();
 		clearLine(_promptRow, _textAttrib.background);
 		charPos_Set(_promptRow, 0);
@@ -788,6 +819,10 @@ void TextMgr::promptRedraw() {
 
 // for AGI1
 void TextMgr::promptClear() {
+	if (_optionCommandPromptWindow) {
+		// Abort, in case command prompt window is active
+		return;
+	}
 	clearLine(_promptRow, _textAttrib.background);
 }
 
@@ -797,6 +832,35 @@ void TextMgr::promptRememberForAutoComplete(bool entered) {
 #endif
 }
 
+void TextMgr::promptCommandWindow(bool recallLastCommand, uint16 newKey) {
+	Common::String commandText;
+
+	if (recallLastCommand) {
+		commandText += Common::String((char *)_promptPrevious);
+	}
+	if (newKey) {
+		if (newKey != ' ') {
+			// Only add char, when it's not a space.
+			// Original AGI did not filter space, but it makes no sense to start with a space.
+			// Space would get filtered anyway during dictionary parsing.
+			commandText += newKey;
+		}
+	}
+
+	if (_systemUI->askForCommand(commandText)) {
+		if (commandText.size()) {
+			// Something actually was entered?
+			strncpy((char *)&_prompt, commandText.c_str(), sizeof(_prompt));
+			promptRememberForAutoComplete(true);
+			memcpy(&_promptPrevious, &_prompt, sizeof(_prompt));
+			// parse text
+			_vm->_words->parseUsingDictionary((char *)&_prompt);
+
+			_prompt[0] = 0;
+		}
+	}
+}
+
 bool TextMgr::stringWasEntered() {
 	return _inputStringEntered;
 }
diff --git a/engines/agi/text.h b/engines/agi/text.h
index 7e9228e..f0aeab7 100644
--- a/engines/agi/text.h
+++ b/engines/agi/text.h
@@ -163,6 +163,8 @@ public:
 	bool  _inputEditEnabled;
 	byte  _inputCursorChar;
 
+	bool  _optionCommandPromptWindow;
+
 	bool  _promptEnabled;
 	int16 _promptRow;
 	int16 _promptCursorPos;
@@ -189,6 +191,8 @@ public:
 	void promptClear(); // for AGI1
 	void promptRememberForAutoComplete(bool entered = false); // for auto-completion
 
+	void promptCommandWindow(bool recallLastCommand, uint16 newKey);
+
 	int16 _inputStringRow;
 	int16 _inputStringColumn;
 	bool  _inputStringEntered;
diff --git a/engines/agi/words.cpp b/engines/agi/words.cpp
index 32fa4cb..7072f00 100644
--- a/engines/agi/words.cpp
+++ b/engines/agi/words.cpp
@@ -293,7 +293,7 @@ int16 Words::findWordInDictionary(const Common::String &userInputLowcased, uint1
 	return wordId;
 }
 
-void Words::parseUsingDictionary(char *rawUserInput) {
+void Words::parseUsingDictionary(const char *rawUserInput) {
 	Common::String userInput;
 	Common::String userInputLowcased;
 	const char *userInputPtr = nullptr;
diff --git a/engines/agi/words.h b/engines/agi/words.h
index c7bf482..96dafae 100644
--- a/engines/agi/words.h
+++ b/engines/agi/words.h
@@ -57,7 +57,7 @@ public:
 	void unloadDictionary();
 
 	void clearEgoWords();
-	void parseUsingDictionary(char *rawUserInput);
+	void parseUsingDictionary(const char *rawUserInput);
 
 private:
 	void  cleanUpInput(const char *userInput, Common::String &cleanInput);






More information about the Scummvm-git-logs mailing list