aboutsummaryrefslogtreecommitdiff
path: root/engines/dreamweb/monitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/dreamweb/monitor.cpp')
-rw-r--r--engines/dreamweb/monitor.cpp705
1 files changed, 705 insertions, 0 deletions
diff --git a/engines/dreamweb/monitor.cpp b/engines/dreamweb/monitor.cpp
new file mode 100644
index 0000000000..95aa400c3a
--- /dev/null
+++ b/engines/dreamweb/monitor.cpp
@@ -0,0 +1,705 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+
+namespace DreamWeb {
+
+struct MonitorKeyEntry {
+ uint8 keyAssigned;
+ char username[12];
+ char password[12];
+};
+
+// New monitor key list
+static MonitorKeyEntry monitorKeyEntries[4] = {
+ { 1, "PUBLIC", "PUBLIC" },
+ { 0, "RYAN", "BLACKDRAGON" },
+ { 0, "LOUIS", "HENDRIX" },
+ { 0, "BECKETT", "SEPTIMUS" }
+};
+
+void DreamWebEngine::useMon() {
+ _vars._lastTrigger = 0;
+ _currentFile[0] = 34;
+ memset(_currentFile+1, ' ', 12);
+ _currentFile[13] = 0;
+
+ monitorKeyEntries[0].keyAssigned = 1;
+ monitorKeyEntries[1].keyAssigned = 0;
+ monitorKeyEntries[2].keyAssigned = 0;
+ monitorKeyEntries[3].keyAssigned = 0;
+
+ createPanel();
+ showPanel();
+ showIcon();
+ drawFloor();
+ getRidOfAll();
+ loadGraphicsFile(_monitorGraphics, "G03"); // mon. graphic name
+ loadPersonal();
+ loadNews();
+ loadCart();
+ loadGraphicsFile(_monitorCharset, "C01"); // character set 2
+ printOuterMon();
+ initialMonCols();
+ printLogo();
+ workToScreen();
+ turnOnPower();
+ fadeUpYellows();
+ fadeUpMonFirst();
+ _monAdX = 76;
+ _monAdY = 141;
+ monMessage(1);
+ hangOnCurs(120);
+ monMessage(2);
+ randomAccess(60);
+ monMessage(3);
+ hangOnCurs(100);
+ printLogo();
+ scrollMonitor();
+ _bufferIn = 0;
+ _bufferOut = 0;
+ bool stop = false;
+ do {
+ uint16 oldMonadx = _monAdX;
+ uint16 oldMonady = _monAdY;
+ input();
+ _monAdX = oldMonadx;
+ _monAdY = oldMonady;
+ stop = execCommand();
+ if (_quitRequested) //TODO : Check why it crashes when put before the execcommand
+ break;
+ } while (!stop);
+ _monitorGraphics.clear();
+ _monitorCharset.clear();
+
+ _textFile1.clear();
+ _textFile2.clear();
+ _textFile3.clear();
+
+ _getBack = 1;
+ playChannel1(26);
+ _manIsOffScreen = 0;
+ restoreAll();
+ redrawMainScrn();
+ workToScreenM();
+}
+
+bool DreamWebEngine::execCommand() {
+ static const char *comlist[] = {
+ "EXIT",
+ "HELP",
+ "LIST",
+ "READ",
+ "LOGON",
+ "KEYS"
+ };
+
+ if (_inputLine[0] == 0) {
+ // No input
+ scrollMonitor();
+ return false;
+ }
+
+ int cmd;
+ bool done = false;
+ // Loop over all commands in the list and see if we get a match
+ for (cmd = 0; cmd < ARRAYSIZE(comlist); ++cmd) {
+ const char *cmdStr = comlist[cmd];
+ const char *inputStr = _inputLine;
+ // Compare the command, char by char, to see if we get a match.
+ // We only care about the prefix matching, though.
+ char inputChar, cmdChar;
+ do {
+ inputChar = *inputStr; inputStr += 2;
+ cmdChar = *cmdStr++;
+ if (cmdChar == 0) {
+ done = true;
+ break;
+ }
+ } while (inputChar == cmdChar);
+
+ if (done)
+ break;
+ }
+
+ // Execute the selected command
+ switch (cmd) {
+ case 0:
+ return true;
+ case 1:
+ monMessage(6);
+ break;
+ case 2:
+ dirCom();
+ break;
+ case 3:
+ read();
+ break;
+ case 4:
+ signOn();
+ break;
+ case 5:
+ showKeys();
+ break;
+ default:
+ netError();
+ break;
+ }
+ return false;
+}
+
+
+
+void DreamWebEngine::monitorLogo() {
+ if (_logoNum != _oldLogoNum) {
+ _oldLogoNum = _logoNum;
+ //fadeDownMon(); // FIXME: Commented out in ASM
+ printLogo();
+ printUnderMonitor();
+ workToScreen();
+ printLogo();
+ //fadeUpMon(); // FIXME: Commented out in ASM
+ printLogo();
+ playChannel1(26);
+ randomAccess(20);
+ } else {
+ printLogo();
+ }
+}
+
+void DreamWebEngine::printLogo() {
+ showFrame(_monitorGraphics, 56, 32, 0, 0);
+ showCurrentFile();
+}
+
+void DreamWebEngine::input() {
+ memset(_inputLine, 0, 64);
+ _curPos = 0;
+ printChar(_monitorCharset, _monAdX, _monAdY, '>', 0, NULL, NULL);
+ multiDump(_monAdX, _monAdY, 6, 8);
+ _monAdX += 6;
+ _cursLocX = _monAdX;
+ _cursLocY = _monAdY;
+ while (true) {
+ printCurs();
+ vSync();
+ delCurs();
+ readKey();
+ if (_quitRequested)
+ return;
+ uint8 currentKey = _currentKey;
+ if (currentKey == 0)
+ continue;
+ if (currentKey == 13)
+ return;
+ if (currentKey == 8) {
+ if (_curPos > 0)
+ delChar();
+ continue;
+ }
+ if (_curPos == 28)
+ continue;
+ if ((currentKey == 32) && (_curPos == 0))
+ continue;
+ currentKey = makeCaps(currentKey);
+ _inputLine[_curPos * 2 + 0] = currentKey;
+ if (currentKey > 'Z')
+ continue;
+ multiGet(_mapStore + _curPos * 256, _monAdX, _monAdY, 8, 8);
+ uint8 charWidth;
+ printChar(_monitorCharset, _monAdX, _monAdY, currentKey, 0, &charWidth, NULL);
+ _inputLine[_curPos * 2 + 1] = charWidth;
+ _monAdX += charWidth;
+ ++_curPos;
+ _cursLocX += charWidth;
+ }
+}
+
+byte DreamWebEngine::makeCaps(byte c) {
+ // TODO: Replace calls to this by toupper() ?
+ if (c >= 'a')
+ c -= 'a' - 'A'; // = 32
+ return c;
+}
+
+void DreamWebEngine::delChar() {
+ --_curPos;
+ _inputLine[_curPos * 2] = 0;
+ uint8 width = _inputLine[_curPos * 2 + 1];
+ _monAdX -= width;
+ _cursLocX -= width;
+ uint16 offset = _curPos;
+ offset = ((offset & 0x00ff) << 8) | ((offset & 0xff00) >> 8);
+ multiPut(_mapStore + offset, _monAdX, _monAdY, 8, 8);
+ multiDump(_monAdX, _monAdY, 8, 8);
+}
+
+void DreamWebEngine::printCurs() {
+ uint16 x = _cursLocX;
+ uint16 y = _cursLocY;
+ uint16 height;
+ if (_foreignRelease) {
+ y -= 3;
+ height = 11;
+ } else
+ height = 8;
+ multiGet(_textUnder, x, y, 6, height);
+ ++_mainTimer;
+ if ((_mainTimer & 16) == 0)
+ showFrame(_monitorCharset, x, y, '/' - 32, 0);
+ multiDump(x - 6, y, 12, height);
+}
+
+void DreamWebEngine::delCurs() {
+ uint16 x = _cursLocX;
+ uint16 y = _cursLocY;
+ uint16 width = 6;
+ uint16 height;
+ if (_foreignRelease) {
+ y -= 3;
+ height = 11;
+ } else
+ height = 8;
+ multiPut(_textUnder, x, y, width, height);
+ multiDump(x, y, width, height);
+}
+
+void DreamWebEngine::scrollMonitor() {
+ printLogo();
+ printUnderMonitor();
+ workToScreen();
+ playChannel1(25);
+}
+
+void DreamWebEngine::showCurrentFile() {
+ uint16 x;
+ // Monitor Frame position differs between Floppy and CD version
+ if (isCD())
+ x = 178;
+ else
+ x = 199;
+ const char *currentFile = _currentFile + 1;
+ while (*currentFile) {
+ char c = *currentFile++;
+ c = modifyChar(c);
+ printChar(_monitorCharset, &x, 37, c, 0, NULL, NULL);
+ }
+}
+
+void DreamWebEngine::accessLightOn() {
+ showFrame(_monitorGraphics, 74, 182, 8, 0);
+ multiDump(74, 182, 12, 8);
+}
+
+void DreamWebEngine::accessLightOff() {
+ showFrame(_monitorGraphics, 74, 182, 7, 0);
+ multiDump(74, 182, 12, 8);
+}
+
+void DreamWebEngine::randomAccess(uint16 count) {
+ for (uint16 i = 0; i < count; ++i) {
+ vSync();
+ vSync();
+ uint16 v = _rnd.getRandomNumber(15);
+ if (v < 10)
+ accessLightOff();
+ else
+ accessLightOn();
+ }
+ accessLightOff();
+}
+
+void DreamWebEngine::monMessage(uint8 index) {
+ assert(index > 0);
+ const char *string = _textFile1._text;
+ for (uint8 i = 0; i < index; ++i) {
+ while (*string++ != '+') {
+ }
+ }
+ monPrint(string);
+}
+
+void DreamWebEngine::netError() {
+ monMessage(5);
+ scrollMonitor();
+}
+
+void DreamWebEngine::powerLightOn() {
+ showFrame(_monitorGraphics, 257+4, 182, 6, 0);
+ multiDump(257+4, 182, 12, 8);
+}
+
+void DreamWebEngine::powerLightOff() {
+ showFrame(_monitorGraphics, 257+4, 182, 5, 0);
+ multiDump(257+4, 182, 12, 8);
+}
+
+void DreamWebEngine::lockLightOn() {
+ showFrame(_monitorGraphics, 56, 182, 10, 0);
+ multiDump(58, 182, 12, 8);
+}
+
+void DreamWebEngine::lockLightOff() {
+ showFrame(_monitorGraphics, 56, 182, 9, 0);
+ multiDump(58, 182, 12, 8);
+}
+
+void DreamWebEngine::turnOnPower() {
+ for (size_t i = 0; i < 3; ++i) {
+ powerLightOn();
+ hangOn(30);
+ powerLightOff();
+ hangOn(30);
+ }
+ powerLightOn();
+}
+
+void DreamWebEngine::printOuterMon() {
+ showFrame(_monitorGraphics, 40, 32, 1, 0);
+ showFrame(_monitorGraphics, 264, 32, 2, 0);
+ showFrame(_monitorGraphics, 40, 12, 3, 0);
+ showFrame(_monitorGraphics, 40, 164, 4, 0);
+}
+
+void DreamWebEngine::loadPersonal() {
+ if (_vars._location == 0 || _vars._location == 42)
+ loadTextFile(_textFile1, "T01"); // monitor file 1
+ else
+ loadTextFile(_textFile1, "T02"); // monitor file 2
+}
+
+void DreamWebEngine::loadNews() {
+ // textfile2 holds information accessible by anyone
+ if (_vars._newsItem == 0)
+ loadTextFile(_textFile2, "T10"); // monitor file 10
+ else if (_vars._newsItem == 1)
+ loadTextFile(_textFile2, "T11"); // monitor file 11
+ else if (_vars._newsItem == 2)
+ loadTextFile(_textFile2, "T12"); // monitor file 12
+ else
+ loadTextFile(_textFile2, "T13"); // monitor file 13
+}
+
+void DreamWebEngine::loadCart() {
+ byte cartridgeId = 0;
+ uint16 objectIndex = findSetObject("INTF");
+ uint16 cartridgeIndex = checkInside(objectIndex, 1);
+ if (cartridgeIndex != kNumexobjects)
+ cartridgeId = getExAd(cartridgeIndex)->objId[3] + 1;
+
+ if (cartridgeId == 0)
+ loadTextFile(_textFile3, "T20"); // monitor file 20
+ else if (cartridgeId == 1)
+ loadTextFile(_textFile3, "T21"); // monitor file 21
+ else if (cartridgeId == 2)
+ loadTextFile(_textFile3, "T22"); // monitor file 22
+ else if (cartridgeId == 3)
+ loadTextFile(_textFile3, "T23"); // monitor file 23
+ else
+ loadTextFile(_textFile3, "T24"); // monitor file 24
+}
+
+void DreamWebEngine::showKeys() {
+ randomAccess(10);
+ scrollMonitor();
+ monMessage(18);
+
+ for (int i = 0; i < 4; i++) {
+ if (monitorKeyEntries[i].keyAssigned)
+ monPrint(monitorKeyEntries[i].username);
+ }
+
+ scrollMonitor();
+}
+
+const char *DreamWebEngine::getKeyAndLogo(const char *foundString) {
+ byte newLogo = foundString[1] - 48;
+ byte keyNum = foundString[3] - 48;
+
+ if (monitorKeyEntries[keyNum].keyAssigned == 1) {
+ // Key OK
+ _logoNum = newLogo;
+ return foundString + 4;
+ } else {
+ monMessage(12); // "Access denied, key required -"
+ monPrint(monitorKeyEntries[keyNum].username);
+ scrollMonitor();
+ return 0;
+ }
+}
+
+const char *DreamWebEngine::searchForString(const char *topic, const char *text) {
+ char delim = *topic;
+
+ while (true) {
+ const char *s = topic;
+ int delimCount = 0;
+
+ char c;
+ do {
+ c = makeCaps(*text++);
+
+ if (c == '*' || (delim == '=' && c == 34))
+ return 0;
+
+ if (c == delim) {
+ delimCount++;
+ if (delimCount == 2)
+ return text;
+ }
+
+ } while (c == *s++);
+ }
+}
+
+void DreamWebEngine::dirCom() {
+ randomAccess(30);
+
+ const char *dirname = parser();
+ if (dirname[1]) {
+ dirFile(dirname);
+ return;
+ }
+
+ _logoNum = 0;
+ memcpy(_currentFile+1, "ROOT ", 12);
+ monitorLogo();
+ scrollMonitor();
+ monMessage(9);
+ searchForFiles(_textFile1._text);
+ searchForFiles(_textFile2._text);
+ searchForFiles(_textFile3._text);
+ scrollMonitor();
+}
+
+void DreamWebEngine::dirFile(const char *dirName) {
+ char topic[14];
+
+ memcpy(topic, dirName, 14);
+ topic[0] = 34;
+
+ const char *text = _textFile1._text;
+ const char *found = searchForString(topic, text);
+ if (!found) {
+ text = _textFile2._text;
+ found = searchForString(topic, text);
+ if (!found) {
+ text = _textFile3._text;
+ found = searchForString(topic, text);
+ }
+ }
+
+ if (found) {
+ found = getKeyAndLogo(found);
+ if (!found)
+ return; // not logged in
+ } else {
+ monMessage(7);
+ return;
+ }
+
+ // "keyok2"
+ memcpy(_currentFile+1, dirName+1, 12);
+ monitorLogo();
+ scrollMonitor();
+ monMessage(10);
+
+ while (true) {
+ byte curChar = *found++;
+ if (curChar == 34 || curChar == '*') {
+ // "endofdir2"
+ scrollMonitor();
+ return;
+ }
+
+ if (curChar == '=')
+ found = monPrint(found);
+ }
+}
+
+void DreamWebEngine::read() {
+ randomAccess(40);
+ const char *name = parser();
+ if (name[1] == 0) {
+ netError();
+ return;
+ }
+
+ const char *topic = _currentFile;
+
+ const char *text = _textFile1._text;
+ const char *found = searchForString(topic, text);
+ if (!found) {
+ text = _textFile2._text;
+ found = searchForString(topic, text);
+ if (!found) {
+ text = _textFile3._text;
+ found = searchForString(topic, text);
+ }
+ }
+
+ if (found) {
+ if (!getKeyAndLogo(found))
+ return;
+ } else {
+ monMessage(7);
+ return;
+ }
+
+ // "keyok1"
+ found = searchForString(name, found);
+ if (!found) {
+ _logoNum = _oldLogoNum;
+ monMessage(11);
+ return;
+ }
+
+ // "findtopictext"
+ monitorLogo();
+ scrollMonitor();
+
+ found++;
+
+ while (true) {
+ found = monPrint(found);
+ if (found[0] == 34 || found[0] == '=' || found[0] == '*') {
+ // "endoftopic"
+ scrollMonitor();
+ return;
+ }
+
+ processTrigger();
+ randomAccess(24);
+ }
+}
+
+void DreamWebEngine::signOn() {
+ const char *name = parser();
+
+ int8 foundIndex = -1;
+ Common::String inputLine = name + 1;
+ inputLine.trim();
+
+ for (byte i = 0; i < 4; i++) {
+ if (inputLine.equalsIgnoreCase(monitorKeyEntries[i].username)) {
+ // Check if the key has already been assigned
+ if (monitorKeyEntries[i].keyAssigned) {
+ monMessage(17);
+ return;
+ } else {
+ foundIndex = i;
+ break;
+ }
+ }
+ }
+
+ if (foundIndex == -1) {
+ monMessage(13);
+ return;
+ }
+
+ monMessage(15);
+
+ uint16 prevX = _monAdX;
+ uint16 prevY = _monAdY;
+ input(); // password input
+ _monAdX = prevX;
+ _monAdY = prevY;
+
+ inputLine = (const char *)_inputLine;
+ inputLine.toUppercase();
+
+ // The entered line has zeroes in-between each character
+ uint32 len = strlen(monitorKeyEntries[foundIndex].password);
+ bool found = true;
+
+ for (uint32 i = 0; i < len; i++) {
+ if (monitorKeyEntries[foundIndex].password[i] != inputLine[i * 2]) {
+ found = false;
+ break;
+ }
+ }
+
+ if (!found) {
+ scrollMonitor();
+ monMessage(16);
+ } else {
+ monMessage(14);
+ monPrint(monitorKeyEntries[foundIndex].username);
+ scrollMonitor();
+ monitorKeyEntries[foundIndex].keyAssigned = 1;
+ }
+}
+
+void DreamWebEngine::searchForFiles(const char *filesString) {
+ byte curChar;
+
+ while (true) {
+ curChar = filesString[0];
+ filesString++;
+ if (curChar == '*')
+ return; // "endofdir"
+ if (curChar == 34)
+ filesString = monPrint(filesString);
+ }
+}
+
+const char *DreamWebEngine::parser() {
+ char *output = _operand1;
+
+ memset(output, 0, 14);
+
+ *output++ = '=';
+
+ const char *in = _inputLine;
+
+ uint8 c;
+
+ // skip command
+ do {
+ c = *in++;
+ in++;
+
+ if (!c)
+ return output;
+ } while (c != 32);
+
+ // skip spaces between command and operand
+ do {
+ c = *in++;
+ in++;
+ } while (c == 32);
+
+ // copy first operand
+ do {
+ *output++ = c;
+ c = *in++;
+ in++;
+ if (!c)
+ return _operand1;
+ } while (c != 32);
+
+ return _operand1;
+}
+
+} // End of namespace DreamWeb