aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction/commands.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction/commands.cpp')
-rw-r--r--engines/parallaction/commands.cpp345
1 files changed, 345 insertions, 0 deletions
diff --git a/engines/parallaction/commands.cpp b/engines/parallaction/commands.cpp
new file mode 100644
index 0000000000..aa726edaad
--- /dev/null
+++ b/engines/parallaction/commands.cpp
@@ -0,0 +1,345 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "parallaction/parallaction.h"
+#include "parallaction/parser.h"
+#include "parallaction/commands.h"
+#include "parallaction/zone.h"
+
+namespace Parallaction {
+
+#define CMD_SET 1
+#define CMD_CLEAR 2
+#define CMD_START 3
+#define CMD_SPEAK 4
+#define CMD_GET 5
+#define CMD_LOCATION 6
+#define CMD_OPEN 7
+#define CMD_CLOSE 8
+#define CMD_ON 9
+#define CMD_OFF 10
+#define CMD_CALL 11
+#define CMD_TOGGLE 12
+#define CMD_DROP 13
+#define CMD_QUIT 14
+#define CMD_MOVE 15
+#define CMD_STOP 16
+
+extern char *_callableNames[];
+
+
+Command *parseCommands(ArchivedFile *file) {
+// printf("parseCommands()\n");
+
+ Node root;
+ memset(&root, 0, sizeof(root));
+
+ parseFillBuffers();
+
+ while (scumm_stricmp(_tokens[0], "ENDCOMMANDS") && scumm_stricmp(_tokens[0], "ENDZONE")) {
+// printf("token[0] = %s\n", _tokens[0]);
+
+ Command *cmd = (Command*)memAlloc(sizeof(Command));
+ memset(cmd, 0, sizeof(Command));
+
+ cmd->_id = _vm->searchTable(_tokens[0], commands_names);
+ uint16 _si = 1;
+
+// printf("cmd id = %i\n", cmd->_id);
+
+ switch (cmd->_id) {
+ case CMD_SET: // set
+ case CMD_CLEAR: // clear
+ case CMD_TOGGLE: // toggle
+ if (_vm->searchTable(_tokens[1], _globalTable) == -1) {
+ do {
+ char _al = _vm->searchTable(_tokens[_si], _localFlagNames);
+ _si++;
+ cmd->u._flags |= 1 << (_al - 1);
+ } while (!scumm_stricmp(_tokens[_si++], "|"));
+ _si--;
+ } else {
+ cmd->u._flags |= kFlagsGlobal;
+ do {
+ char _al = _vm->searchTable(_tokens[1], _globalTable);
+ _si++;
+ cmd->u._flags |= 1 << (_al - 1);
+ } while (!scumm_stricmp(_tokens[_si++], "|"));
+ _si--;
+ }
+ break;
+
+ case CMD_START: // start
+ case CMD_STOP: // stop
+ cmd->u._animation = findAnimation(_tokens[_si]);
+ _si++;
+ if (cmd->u._animation == NULL) {
+ strcpy(_forwardedAnimationNames[_numForwards], _tokens[_si-1]);
+ _forwardedCommands[_numForwards] = cmd;
+ _numForwards++;
+ }
+ break;
+
+ case CMD_SPEAK: // speak
+ case CMD_GET: // get
+ case CMD_OPEN: // open
+ case CMD_CLOSE: // close
+ case CMD_ON: // on
+ case CMD_OFF: // off
+ cmd->u._zone = findZone(_tokens[_si]);
+ _si++;
+ break;
+
+ case CMD_LOCATION: // location
+ cmd->u._string = (char*)memAlloc(strlen(_tokens[_si])+1);
+ strcpy(cmd->u._string, _tokens[_si]);
+ _si++;
+ break;
+
+ case CMD_CALL: // call
+ cmd->u._callable = _vm->searchTable(_tokens[_si], _callableNames) - 1;
+ _si++;
+ break;
+
+ case CMD_DROP: // drop
+ cmd->u._object = _vm->searchTable(_tokens[_si], _objectsNames);
+ _si++;
+ break;
+
+ case CMD_QUIT: // quit
+ break;
+
+ case CMD_MOVE: // move
+ cmd->u._move._x = atoi(_tokens[_si]);
+ _si++;
+ cmd->u._move._y = atoi(_tokens[_si]);
+ _si++;
+ break;
+
+ }
+
+ if (!scumm_stricmp(_tokens[_si], "flags")) {
+ _si++;
+
+ do {
+ if (!scumm_stricmp(_tokens[_si], "exit") || !scumm_stricmp(_tokens[_si], "exittrap")) {
+ cmd->_flagsOn |= kFlagsExit;
+ } else
+ if (!scumm_stricmp(_tokens[_si], "enter") || !scumm_stricmp(_tokens[_si], "entertrap")) {
+ cmd->_flagsOn |= kFlagsEnter;
+ } else
+ if (!scumm_strnicmp(_tokens[_si], "no", 2)) {
+ byte _al = _vm->searchTable(&_tokens[_si][2], _localFlagNames);
+ cmd->_flagsOff |= 1 << (_al - 1);
+ } else {
+ byte _al = _vm->searchTable(_tokens[_si], _localFlagNames);
+ cmd->_flagsOn |= 1 << (_al - 1);
+ }
+
+ _si++;
+
+ } while (!scumm_stricmp(_tokens[_si++], "|"));
+
+ }
+
+ if (!scumm_stricmp(_tokens[_si], "gflags")) {
+ _si++;
+ cmd->_flagsOn |= kFlagsGlobal;
+
+ do {
+ if (!scumm_stricmp(_tokens[_si], "exit")) {
+ cmd->_flagsOn |= kFlagsExit;
+ } else
+ if (!scumm_stricmp(_tokens[_si], "enter")) {
+ cmd->_flagsOn |= kFlagsEnter;
+ } else
+ if (!scumm_strnicmp(_tokens[_si], "no", 2)) {
+ byte _al = _vm->searchTable(&_tokens[_si][2], _globalTable);
+ cmd->_flagsOff |= 1 << (_al - 1);
+ } else {
+ byte _al = _vm->searchTable(_tokens[_si], _localFlagNames);
+ cmd->_flagsOn |= 1 << (_al - 1);
+ }
+
+ _si++;
+
+ } while (!scumm_stricmp(_tokens[_si++], "|"));
+
+ }
+
+ addNode(&root, &cmd->_node);
+ parseFillBuffers();
+
+ }
+
+ return (Command*)root._next;
+}
+
+
+void freeCommands(Command *list) {
+
+ Command *cmd = list;
+
+ while (cmd) {
+ Command *v4 = (Command*)cmd->_node._next;
+
+ if (cmd->_id == 6) memFree(cmd->u._zone); // open
+ memFree(cmd);
+
+ cmd = v4;
+ }
+
+ return;
+}
+
+
+
+void runCommands(Command *list, Zone *z) {
+// printf("runCommands()\n");
+
+ Command *cmd = list;
+ for ( ; cmd; cmd = (Command*)cmd->_node._next) {
+ CommandData *u = &cmd->u;
+ uint32 v8 = _localFlags[_vm->_currentLocationIndex];
+
+ if (_engineFlags & kEngineQuit)
+ break;
+
+ if (cmd->_flagsOn & kFlagsGlobal) {
+ v8 = _commandFlags | kFlagsGlobal;
+ }
+
+ if ((cmd->_flagsOn & v8) != cmd->_flagsOn) continue;
+ if ((cmd->_flagsOff & ~v8) != cmd->_flagsOff) continue;
+
+// printf("localflags: %x\n", v8);
+// printf("%s (on flags: %x, off flags: %x)\n", commands_names[cmd->_id-1], cmd->_flagsOn, cmd->_flagsOff);
+
+ switch (cmd->_id) {
+
+ case CMD_SET: // set
+ if (cmd->u._flags & kFlagsGlobal) {
+ cmd->u._flags &= ~kFlagsGlobal;
+ _commandFlags |= cmd->u._flags;
+ } else {
+ _localFlags[_vm->_currentLocationIndex] |= cmd->u._flags;
+ }
+ break;
+
+ case CMD_CLEAR: // clear
+ if (cmd->u._flags & kFlagsGlobal) {
+ cmd->u._flags &= ~kFlagsGlobal;
+ _commandFlags &= ~cmd->u._flags;
+ } else {
+ _localFlags[_vm->_currentLocationIndex] &= ~cmd->u._flags;
+ }
+ break;
+
+ case CMD_TOGGLE: // toggle
+ if (cmd->u._flags & kFlagsGlobal) {
+ cmd->u._flags &= ~kFlagsGlobal;
+ _commandFlags ^= cmd->u._flags;
+ } else {
+ _localFlags[_vm->_currentLocationIndex] ^= cmd->u._flags;
+ }
+ break;
+
+ case CMD_START: // start
+ cmd->u._zone->_flags |= kFlagsActing;
+ break;
+
+ case CMD_STOP: // stop
+ cmd->u._zone->_flags &= ~kFlagsActing;
+ break;
+
+ case CMD_SPEAK: // speak
+ _activeZone = u->_zone;
+ break;
+
+ case CMD_GET: // get
+ u->_zone->_flags &= ~kFlagsFixed;
+ if (!runZone(u->_zone)) {
+ runCommands(u->_zone->_commands);
+ }
+ break;
+
+ case CMD_DROP: // drop
+ dropItem( u->_object );
+ break;
+
+ case CMD_OPEN: // open
+ u->_zone->_flags &= ~kFlagsClosed;
+ if (u->_zone->u.door->_cnv._count != 0) {
+ addJob(&jobToggleDoor, (void*)u->_zone, JOBPRIORITY_TOGGLEDOOR );
+ }
+ break;
+
+ case CMD_CLOSE: // close
+ u->_zone->_flags |= kFlagsClosed;
+ break;
+
+ case CMD_ON: // on
+ u->_zone->_flags &= ~kFlagsRemove;
+ u->_zone->_flags |= kFlagsActive;
+ if ((u->_zone->_type & 0xFFFF) == kZoneGet) {
+ addJob(&jobDisplayDroppedItem, u->_zone, JOBPRIORITY_ADDREMOVEITEMS );
+ }
+ break;
+
+ case CMD_OFF: // off
+ u->_zone->_flags |= kFlagsRemove;
+ break;
+
+ case CMD_LOCATION: // location
+ strcpy(_location, u->_string);
+ _engineFlags |= kEngineChangeLocation;
+ break;
+
+ case CMD_CALL: // call
+ _callables[u->_callable](z);
+ break;
+
+ case CMD_QUIT: // quit
+ _engineFlags |= kEngineQuit;
+ break;
+
+ case CMD_MOVE: { // move
+ if ((_yourself._zone._flags & kFlagsRemove) || (_yourself._zone._flags & kFlagsActive) == 0) {
+ continue;
+ }
+
+ WalkNode *vC = buildWalkPath(u->_move._x, u->_move._y);
+
+ addJob(&jobWalk, vC, JOBPRIORITY_WALK );
+ _engineFlags |= kEngineWalking;
+ }
+ break;
+
+ }
+ }
+
+ return;
+
+}
+
+} // namespace Parallaction
+