[Scummvm-cvs-logs] SF.net SVN: scummvm:[35723] scummvm/trunk/engines/parallaction

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Sun Jan 4 15:23:21 CET 2009


Revision: 35723
          http://scummvm.svn.sourceforge.net/scummvm/?rev=35723&view=rev
Author:   peres001
Date:     2009-01-04 14:23:20 +0000 (Sun, 04 Jan 2009)

Log Message:
-----------
Implemented counters in BRA. Only valid answer options are shown, and counter calculations in scripts are performed.

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/dialogue.cpp
    scummvm/trunk/engines/parallaction/exec_br.cpp
    scummvm/trunk/engines/parallaction/objects.cpp
    scummvm/trunk/engines/parallaction/objects.h
    scummvm/trunk/engines/parallaction/parallaction.h
    scummvm/trunk/engines/parallaction/parallaction_br.cpp
    scummvm/trunk/engines/parallaction/parser.h
    scummvm/trunk/engines/parallaction/parser_br.cpp
    scummvm/trunk/engines/parallaction/parser_ns.cpp

Modified: scummvm/trunk/engines/parallaction/dialogue.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/dialogue.cpp	2009-01-04 13:14:11 UTC (rev 35722)
+++ scummvm/trunk/engines/parallaction/dialogue.cpp	2009-01-04 14:23:20 UTC (rev 35723)
@@ -102,7 +102,7 @@
 
 public:
 	DialogueManager(Parallaction *vm, ZonePtr z);
-	~DialogueManager();
+	virtual ~DialogueManager();
 
 	bool isOver() {
 		return _state == DIALOGUE_OVER;
@@ -115,7 +115,8 @@
 protected:
 	bool displayQuestion();
 	bool displayAnswers();
-	bool displayAnswer(uint16 i);
+	bool testAnswerFlags(Answer *a);
+	virtual bool canDisplayAnswer(Answer *a) = 0;
 
 	int16 selectAnswer1();
 	int16 selectAnswerN();
@@ -132,6 +133,46 @@
 	void accumPassword(uint16 ascii);
 };
 
+class DialogueManager_ns : public DialogueManager {
+	Parallaction_ns *_vm;
+
+public:
+	DialogueManager_ns(Parallaction_ns *vm, ZonePtr z) : DialogueManager(vm, z), _vm(vm) {
+	}
+
+	virtual bool canDisplayAnswer(Answer *a) {
+		return testAnswerFlags(a);
+	}
+};
+
+class DialogueManager_br : public DialogueManager {
+	Parallaction_br *_vm;
+
+	bool testAnswerCounter(Answer *a) {
+		if (!a->_hasCounterCondition) {
+			return true;
+		}
+		_vm->testCounterCondition(a->_counterName, a->_counterOp, a->_counterValue);
+		return (_vm->getLocationFlags() & kFlagsTestTrue) != 0;
+	}
+
+public:
+	DialogueManager_br(Parallaction_br *vm, ZonePtr z) : DialogueManager(vm, z), _vm(vm) {
+	}
+
+	virtual bool canDisplayAnswer(Answer *a) {
+		if (!a)
+			return false;
+
+		if (testAnswerFlags(a)) {
+			return true;
+		}
+
+		return testAnswerCounter(a);
+	}
+};
+
+
 DialogueManager::DialogueManager(Parallaction *vm, ZonePtr z) : _vm(vm), _z(z) {
 	int gtype = vm->getGameType();
 	if (gtype == GType_Nippon) {
@@ -163,46 +204,42 @@
 	_z = nullZonePtr;
 }
 
-bool DialogueManager::displayAnswer(uint16 i) {
 
-	Answer *a = _q->_answers[i];
-
+bool DialogueManager::testAnswerFlags(Answer *a) {
 	uint32 flags = _vm->getLocationFlags();
 	if (a->_yesFlags & kFlagsGlobal)
 		flags = _globalFlags | kFlagsGlobal;
+	return ((a->_yesFlags & flags) == a->_yesFlags) && ((a->_noFlags & ~flags) == a->_noFlags);
+}
 
-	// display suitable answers
-	if (((a->_yesFlags & flags) == a->_yesFlags) && ((a->_noFlags & ~flags) == a->_noFlags)) {
+bool DialogueManager::displayAnswers() {
 
+	_numVisAnswers = 0;
+
+	Answer *a;
+	for (int i = 0; i < NUM_ANSWERS && _q->_answers[i]; i++) {
+		a = _q->_answers[i];
+		if (!canDisplayAnswer(a)) {
+			continue;
+		}
+
 		int id = _vm->_balloonMan->setDialogueBalloon(a->_text.c_str(), 1, BalloonManager::kUnselectedColor);
 		assert(id >= 0);
 		_visAnswers[id] = i;
+		_askPassword = a->_text.contains("%P");
 
-		_askPassword = a->_text.contains("%P");
 		_numVisAnswers++;
-
-		return true;
 	}
 
-	return false;
-}
-
-bool DialogueManager::displayAnswers() {
-
-	_numVisAnswers = 0;
-
-	for (int i = 0; i < NUM_ANSWERS && _q->_answers[i]; i++) {
-		displayAnswer(i);
-	}
-
 	int mood = 0;
 
 	if (_askPassword) {
 		resetPassword();
 	} else
 	if (_numVisAnswers == 1) {
-		mood = _q->_answers[0]->_mood & 0xF;
-		_vm->_balloonMan->setBalloonText(0, _q->_answers[_visAnswers[0]]->_text.c_str(), BalloonManager::kNormalColor);
+		Answer *a = _q->_answers[_visAnswers[0]];
+		mood = a->_mood & 0xF;
+		_vm->_balloonMan->setBalloonText(0, a->_text.c_str(), BalloonManager::kNormalColor);
 	} else
 	if (_numVisAnswers > 1) {
 		mood = _q->_answers[_visAnswers[0]]->_mood & 0xF;
@@ -273,9 +310,12 @@
 }
 
 int16 DialogueManager::selectAnswer1() {
+	if (!_q->_answers[_visAnswers[0]]->_text.compareToIgnoreCase("null")) {
+		return _visAnswers[0];
+	}
 
 	if (_mouseButtons == kMouseLeftUp) {
-		return 0;
+		return _visAnswers[0];
 	}
 
 	return -1;
@@ -400,7 +440,7 @@
 
 void Parallaction::enterDialogueMode(ZonePtr z) {
 	debugC(1, kDebugDialogue, "Parallaction::enterDialogueMode(%s)", z->u.speak->_name);
-	_dialogueMan = new DialogueManager(this, z);
+	_dialogueMan = _vm->createDialogueManager(z);
 	_input->_inputMode = Input::kInputModeDialogue;
 }
 
@@ -436,5 +476,12 @@
 	return;
 }
 
+DialogueManager *Parallaction_ns::createDialogueManager(ZonePtr z) {
+	return new DialogueManager_ns(this, z);
+}
 
+DialogueManager *Parallaction_br::createDialogueManager(ZonePtr z) {
+	return new DialogueManager_br(this, z);
+}
+
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/exec_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/exec_br.cpp	2009-01-04 13:14:11 UTC (rev 35722)
+++ scummvm/trunk/engines/parallaction/exec_br.cpp	2009-01-04 14:23:20 UTC (rev 35723)
@@ -199,42 +199,36 @@
 
 
 DECLARE_COMMAND_OPCODE(inc) {
-	_vm->_counters[_ctxt.cmd->u._lvalue] += _ctxt.cmd->u._rvalue;
+	int v = _vm->getCounterValue(_ctxt.cmd->u._counterName);
+	_vm->setCounterValue(_ctxt.cmd->u._counterName, v + _ctxt.cmd->u._counterValue);
 }
 
 
 DECLARE_COMMAND_OPCODE(dec) {
-	_vm->_counters[_ctxt.cmd->u._lvalue] -= _ctxt.cmd->u._rvalue;
+	int v = _vm->getCounterValue(_ctxt.cmd->u._counterName);
+	_vm->setCounterValue(_ctxt.cmd->u._counterName, v - _ctxt.cmd->u._counterValue);
 }
 
+// these definitions must match those in parser_br.cpp
+#define CMD_TEST		25
+#define CMD_TEST_GT		26
+#define CMD_TEST_LT		27
 
 DECLARE_COMMAND_OPCODE(ifeq) {
-	if (_vm->_counters[_ctxt.cmd->u._lvalue] == _ctxt.cmd->u._rvalue) {
-		_vm->setLocationFlags(kFlagsTestTrue);
-	} else {
-		_vm->clearLocationFlags(kFlagsTestTrue);
-	}
+	_vm->testCounterCondition(_ctxt.cmd->u._counterName, CMD_TEST, _ctxt.cmd->u._counterValue);
 }
 
 DECLARE_COMMAND_OPCODE(iflt) {
-	if (_vm->_counters[_ctxt.cmd->u._lvalue] < _ctxt.cmd->u._rvalue) {
-		_vm->setLocationFlags(kFlagsTestTrue);
-	} else {
-		_vm->clearLocationFlags(kFlagsTestTrue);
-	}
+	_vm->testCounterCondition(_ctxt.cmd->u._counterName, CMD_TEST_LT, _ctxt.cmd->u._counterValue);
 }
 
 DECLARE_COMMAND_OPCODE(ifgt) {
-	if (_vm->_counters[_ctxt.cmd->u._lvalue] > _ctxt.cmd->u._rvalue) {
-		_vm->setLocationFlags(kFlagsTestTrue);
-	} else {
-		_vm->clearLocationFlags(kFlagsTestTrue);
-	}
+	_vm->testCounterCondition(_ctxt.cmd->u._counterName, CMD_TEST_GT, _ctxt.cmd->u._counterValue);
 }
 
 
 DECLARE_COMMAND_OPCODE(let) {
-	_vm->_counters[_ctxt.cmd->u._lvalue] = _ctxt.cmd->u._rvalue;
+	_vm->setCounterValue(_ctxt.cmd->u._counterName, _ctxt.cmd->u._counterValue);
 }
 
 
@@ -545,4 +539,5 @@
 ProgramExec_br::~ProgramExec_br() {
 }
 
+
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/objects.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/objects.cpp	2009-01-04 13:14:11 UTC (rev 35722)
+++ scummvm/trunk/engines/parallaction/objects.cpp	2009-01-04 14:23:20 UTC (rev 35723)
@@ -249,6 +249,7 @@
 	_followingQuestion =  NULL;
 	_noFlags = 0;
 	_yesFlags = 0;
+	_hasCounterCondition = false;
 }
 
 Question::Question() {

Modified: scummvm/trunk/engines/parallaction/objects.h
===================================================================
--- scummvm/trunk/engines/parallaction/objects.h	2009-01-04 13:14:11 UTC (rev 35722)
+++ scummvm/trunk/engines/parallaction/objects.h	2009-01-04 14:23:20 UTC (rev 35723)
@@ -123,8 +123,8 @@
 	// BRA specific
 	Common::Point	_startPos;
 	Common::Point	_startPos2;
-	uint			_lvalue;
-	int				_rvalue;
+	Common::String	_counterName;
+	int				_counterValue;
 	int				_zeta0;
 	int				_zeta1;
 	int				_zeta2;
@@ -171,6 +171,12 @@
 	uint32		_noFlags;
 	uint32		_yesFlags;
 
+	// BRA specific
+	bool _hasCounterCondition;
+	Common::String	_counterName;
+	int	_counterValue;
+	int	_counterOp;
+
 	Answer();
 };
 

Modified: scummvm/trunk/engines/parallaction/parallaction.h
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.h	2009-01-04 13:14:11 UTC (rev 35722)
+++ scummvm/trunk/engines/parallaction/parallaction.h	2009-01-04 14:23:20 UTC (rev 35723)
@@ -362,6 +362,7 @@
 	virtual	void callFunction(uint index, void* parm) = 0;
 	virtual void runPendingZones() = 0;
 	virtual void cleanupGame() = 0;
+	virtual DialogueManager *createDialogueManager(ZonePtr z) = 0;
 };
 
 
@@ -384,6 +385,8 @@
 	virtual void 	runPendingZones();
 	virtual void 	cleanupGame();
 
+	virtual DialogueManager *createDialogueManager(ZonePtr z);
+
 	void 	switchBackground(const char* background, const char* mask);
 
 private:
@@ -474,11 +477,18 @@
 	virtual void runPendingZones();
 	virtual void cleanupGame();
 
+	virtual DialogueManager *createDialogueManager(ZonePtr z);
+
 	void setupSubtitles(char *s, char *s2, int y);
 	void clearSubtitles();
 
+	void testCounterCondition(const Common::String &name, int op, int value);
+
 public:
-	Table		*_countersNames;
+	bool	counterExists(const Common::String &name);
+	int		getCounterValue(const Common::String &name);
+	void	setCounterValue(const Common::String &name, int value);
+
 	const char **_audioCommandsNamesRes;
 	static const char *_partNames[];
 	int			_part;
@@ -489,7 +499,6 @@
 	int			_subtitleY;
 	int			_subtitle[2];
 	ZonePtr		_activeZone2;
-	int32		_counters[32];
 	uint32		_zoneFlags[NUM_LOCATIONS][NUM_ZONES];
 
 
@@ -497,6 +506,9 @@
 	LocationParser_br		*_locationParser;
 	ProgramParser_br		*_programParser;
 
+	int32		_counters[32];
+	Table		*_countersNames;
+
 private:
 	void	initResources();
 	void	initFonts();

Modified: scummvm/trunk/engines/parallaction/parallaction_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction_br.cpp	2009-01-04 13:14:11 UTC (rev 35722)
+++ scummvm/trunk/engines/parallaction/parallaction_br.cpp	2009-01-04 14:23:20 UTC (rev 35723)
@@ -326,6 +326,64 @@
 	_char._ani->_flags |= kFlagsActive;
 }
 
+bool Parallaction_br::counterExists(const Common::String &name) {
+	return Table::notFound != _countersNames->lookup(name.c_str());
+}
 
+int	Parallaction_br::getCounterValue(const Common::String &name) {
+	int index = _countersNames->lookup(name.c_str());
+	if (index != Table::notFound) {
+		return _counters[index - 1];
+	}
+	return 0;
+}
 
+void Parallaction_br::setCounterValue(const Common::String &name, int value) {
+	int index = _countersNames->lookup(name.c_str());
+	if (index != Table::notFound) {
+		_counters[index - 1] = value;
+	}
+}
+
+void Parallaction_br::testCounterCondition(const Common::String &name, int op, int value) {
+	int index = _countersNames->lookup(name.c_str());
+	if (index == Table::notFound) {
+		clearLocationFlags(kFlagsTestTrue);
+		return;
+	}
+
+	int c = _counters[index - 1];
+
+// these definitions must match those in parser_br.cpp
+#define CMD_TEST		25
+#define CMD_TEST_GT		26
+#define CMD_TEST_LT		27
+
+	bool res = false;
+	switch (op) {
+	case CMD_TEST:
+		res = (c == value);
+		break;
+
+	case CMD_TEST_GT:
+		res = (c > value);
+		break;
+
+	case CMD_TEST_LT:
+		res = (c < value);
+		break;
+
+	default:
+		error("unknown operator in testCounterCondition");
+	}
+
+	if (res) {
+		setLocationFlags(kFlagsTestTrue);
+	} else {
+		clearLocationFlags(kFlagsTestTrue);
+	}
+}
+
+
+
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/parser.h
===================================================================
--- scummvm/trunk/engines/parallaction/parser.h	2009-01-04 13:14:11 UTC (rev 35722)
+++ scummvm/trunk/engines/parallaction/parser.h	2009-01-04 14:23:20 UTC (rev 35723)
@@ -189,8 +189,9 @@
 	Common::String	parseDialogueString();
 	Dialogue	*parseDialogue();
 	void		resolveDialogueForwards(Dialogue *dialogue, uint numQuestions, Table &forwards);
-	Answer		*parseAnswer();
-	void 		parseAnswerVariants(Answer *answer);
+	virtual Answer *parseAnswer();
+	void 		parseAnswerFlags(Answer *answer);
+	void 		parseAnswerBody(Answer *answer);
 	Question	*parseQuestion();
 
 	void		parseZone(ZoneList &list, char *name);
@@ -306,6 +307,8 @@
 	virtual void	parseZoneTypeBlock(ZonePtr z);
 	void			parsePathData(ZonePtr z);
 	void 			parseGetData(ZonePtr z);
+	void 			parseAnswerCounter(Answer *answer);
+	virtual Answer *parseAnswer();
 
 public:
 	LocationParser_br(Parallaction_br *vm) : LocationParser_ns((Parallaction_ns*)vm), _vm(vm),

Modified: scummvm/trunk/engines/parallaction/parser_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parser_br.cpp	2009-01-04 13:14:11 UTC (rev 35722)
+++ scummvm/trunk/engines/parallaction/parser_br.cpp	2009-01-04 14:23:20 UTC (rev 35723)
@@ -564,9 +564,13 @@
 
 	createCommand(_parser->_lookup);
 
-	ctxt.cmd->u._lvalue = _vm->_countersNames->lookup(_tokens[1]);
+	if (!_vm->counterExists(_tokens[1])) {
+		error("counter '%s' doesn't exists", _tokens[1]);
+	}
+
+	ctxt.cmd->u._counterName = _tokens[1];
 	ctxt.nextToken++;
-	ctxt.cmd->u._rvalue = atoi(_tokens[2]);
+	ctxt.cmd->u._counterValue = atoi(_tokens[2]);
 	ctxt.nextToken++;
 
 	parseCommandFlags();
@@ -578,19 +582,17 @@
 	debugC(7, kDebugParser, "COMMAND_PARSER(test) ");
 
 	createCommand(_parser->_lookup);
-
-	uint counter = _vm->_countersNames->lookup(_tokens[1]);
 	ctxt.nextToken++;
 
-	if (counter == Table::notFound) {
+	if (!_vm->counterExists(_tokens[1])) {
 		if (!scumm_stricmp("SFX", _tokens[1])) {
 			ctxt.cmd->_id = CMD_TEST_SFX;
 		} else {
 			error("unknown counter '%s' in test opcode", _tokens[1]);
 		}
 	} else {
-		ctxt.cmd->u._lvalue = counter;
-		ctxt.cmd->u._rvalue = atoi(_tokens[3]);
+		ctxt.cmd->u._counterName = _tokens[1];
+		ctxt.cmd->u._counterValue = atoi(_tokens[3]);
 		ctxt.nextToken++;
 
 		if (_tokens[2][0] == '>') {
@@ -704,7 +706,7 @@
 
 	createCommand(_parser->_lookup);
 
-	ctxt.cmd->u._rvalue = atoi(_tokens[1]);
+	ctxt.cmd->u._counterValue = atoi(_tokens[1]);
 	ctxt.nextToken++;
 
 	parseCommandFlags();
@@ -895,14 +897,53 @@
 }
 
 
+void LocationParser_br::parseAnswerCounter(Answer *answer) {
+	if (!_tokens[1][0]) {
+		return;
+	}
 
+	if (scumm_stricmp(_tokens[1], "counter")) {
+		return;
+	}
 
+	if (!_vm->counterExists(_tokens[2])) {
+		error("unknown counter '%s' in dialogue", _tokens[2]);
+	}
 
+	answer->_hasCounterCondition = true;
 
+	answer->_counterName = _tokens[2];
+	answer->_counterValue = atoi(_tokens[4]);
 
+	if (_tokens[3][0] == '>') {
+		answer->_counterOp = CMD_TEST_GT;
+	} else
+	if (_tokens[3][0] == '<') {
+		answer->_counterOp = CMD_TEST_LT;
+	} else {
+		answer->_counterOp = CMD_TEST;
+	}
 
+}
 
 
+
+Answer *LocationParser_br::parseAnswer() {
+	Answer *answer = new Answer;
+	assert(answer);
+	parseAnswerFlags(answer);
+	parseAnswerCounter(answer);
+	parseAnswerBody(answer);
+	return answer;
+}
+
+
+
+
+
+
+
+
 DECLARE_INSTRUCTION_PARSER(zone)  {
 	debugC(7, kDebugParser, "INSTRUCTION_PARSER(zone) ");
 

Modified: scummvm/trunk/engines/parallaction/parser_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parser_ns.cpp	2009-01-04 13:14:11 UTC (rev 35722)
+++ scummvm/trunk/engines/parallaction/parser_ns.cpp	2009-01-04 14:23:20 UTC (rev 35723)
@@ -862,53 +862,7 @@
 	return question;
 }
 
-void LocationParser_ns::parseAnswerVariants(Answer *answer) {
-	if (!_tokens[1][0]) {
-		return;
-	}
-
-	if (!scumm_stricmp(_tokens[1], "counter")) {
-		// TODO: parse the counter and the condition. This is done creating a new
-		// Command and usng the command parser for CMD_TEST in the original.
-
-	} else {
-
-		Table* flagNames;
-		uint16 token;
-
-		if (!scumm_stricmp(_tokens[1], "global")) {
-			token = 2;
-			flagNames = _vm->_globalFlagsNames;
-			answer->_yesFlags |= kFlagsGlobal;
-		} else {
-			token = 1;
-			flagNames = _vm->_localFlagNames;
-		}
-
-		do {
-
-			if (!scumm_strnicmp(_tokens[token], "no", 2)) {
-				byte _al = flagNames->lookup(_tokens[token]+2);
-				answer->_noFlags |= 1 << (_al - 1);
-			} else {
-				byte _al = flagNames->lookup(_tokens[token]);
-				answer->_yesFlags |= 1 << (_al - 1);
-			}
-
-			token++;
-
-		} while (!scumm_stricmp(_tokens[token++], "|"));
-
-	}
-}
-
-Answer *LocationParser_ns::parseAnswer() {
-
-	Answer *answer = new Answer;
-	assert(answer);
-
-	parseAnswerVariants(answer);
-
+void LocationParser_ns::parseAnswerBody(Answer *answer) {
 	answer->_text = parseDialogueString();
 
 	_script->readLineToken(true);
@@ -927,7 +881,45 @@
 
 		_script->readLineToken(true);
 	}
+}
 
+void LocationParser_ns::parseAnswerFlags(Answer *answer) {
+	if (!_tokens[1][0]) {
+		return;
+	}
+
+	Table* flagNames;
+	uint16 token;
+
+	if (!scumm_stricmp(_tokens[1], "global")) {
+		token = 2;
+		flagNames = _vm->_globalFlagsNames;
+		answer->_yesFlags |= kFlagsGlobal;
+	} else {
+		token = 1;
+		flagNames = _vm->_localFlagNames;
+	}
+
+	do {
+
+		if (!scumm_strnicmp(_tokens[token], "no", 2)) {
+			byte _al = flagNames->lookup(_tokens[token]+2);
+			answer->_noFlags |= 1 << (_al - 1);
+		} else {
+			byte _al = flagNames->lookup(_tokens[token]);
+			answer->_yesFlags |= 1 << (_al - 1);
+		}
+
+		token++;
+
+	} while (!scumm_stricmp(_tokens[token++], "|"));
+}
+
+Answer *LocationParser_ns::parseAnswer() {
+	Answer *answer = new Answer;
+	assert(answer);
+	parseAnswerFlags(answer);
+	parseAnswerBody(answer);
 	return answer;
 }
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list