[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