diff options
author | Filippos Karapetis | 2008-04-20 14:47:37 +0000 |
---|---|---|
committer | Filippos Karapetis | 2008-04-20 14:47:37 +0000 |
commit | 7ca439f410ac1c46a387567b30271ae4e4a2ed30 (patch) | |
tree | 4d4154169b074293581ad6a11ee821290418f4fb /engines/m4/globals.cpp | |
parent | d0590a09eac68d5cde64d37fb2e5bbd1471a676a (diff) | |
download | scummvm-rg350-7ca439f410ac1c46a387567b30271ae4e4a2ed30.tar.gz scummvm-rg350-7ca439f410ac1c46a387567b30271ae4e4a2ed30.tar.bz2 scummvm-rg350-7ca439f410ac1c46a387567b30271ae4e4a2ed30.zip |
Initial import of the work in progress M4 engine
svn-id: r31600
Diffstat (limited to 'engines/m4/globals.cpp')
-rw-r--r-- | engines/m4/globals.cpp | 447 |
1 files changed, 447 insertions, 0 deletions
diff --git a/engines/m4/globals.cpp b/engines/m4/globals.cpp new file mode 100644 index 0000000000..12d9a24d37 --- /dev/null +++ b/engines/m4/globals.cpp @@ -0,0 +1,447 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "m4/m4.h" +#include "m4/globals.h" +#include "m4/graphics.h" +#include "m4/gui.h" +#include "m4/viewmgr.h" +#include "m4/script.h" +#include "m4/m4_views.h" +#include "m4/compression.h" + +namespace M4 { + +Kernel::Kernel(M4Engine *vm) : _vm(vm) { + daemonTriggerAvailable = true; + firstFadeColorIndex = 0; + paused = false; + betweenRooms = false; + currentSection = 0; + newSection = 0; + previousSection = 0; + currentRoom = 0; + newRoom = 0; + previousRoom = 0; + trigger = 0; + triggerMode = KT_DAEMON; + + _globalDaemonFn = NULL; + _globalParserFn = NULL; + + _sectionInitFn = NULL; + _sectionDaemonFn = NULL; + _sectionParserFn = NULL; + + _roomInitFn = NULL; + _roomDaemonFn = NULL; + _roomPreParserFn = NULL; + _roomParserFn = NULL; + +} + +int32 Kernel::createTrigger(int32 triggerNum) { + if (triggerNum < 0) + return triggerNum; + else + return triggerNum | (currentRoom << 16) | (triggerMode << 28); +} + +bool Kernel::sendTrigger(int32 triggerNum) { + return handleTrigger(createTrigger(triggerNum)); +} + +bool Kernel::handleTrigger(int32 triggerNum) { + + printf("betweenRooms = %d; triggerNum = %08X\n", betweenRooms, triggerNum); + + if (betweenRooms) + return true; + + if (triggerNum < 0) + return false; + + KernelTriggerType saveTriggerMode = triggerMode; + int32 saveTrigger = trigger; + bool result = false; + + int room = (triggerNum >> 16) & 0xFFF; + + printf("room = %d; currentRoom = %d\n", room, currentRoom); fflush(stdout); + + if (room != currentRoom) { + printf("Kernel::handleTrigger() Trigger from another room\n"); + return false; + } + + trigger = triggerNum & 0xFFFF; + KernelTriggerType mode = (KernelTriggerType)(triggerNum >> 28); + + switch (mode) { + + case KT_PREPARSE: + if (trigger < 32000) { + triggerMode = KT_PREPARSE; + roomPreParser(); + result = true; + } + break; + + case KT_PARSE: + if (trigger < 32000) { + triggerMode = KT_PARSE; + // TODO player.commandReady = TRUE; + roomParser(); + /* TODO + if (player.commandReady) + globalParser(); + */ + result = true; + } + break; + + case KT_DAEMON: + printf("KT_DAEMON\n"); + fflush(stdout); + triggerMode = KT_DAEMON; + daemonTriggerAvailable = false; + roomDaemon(); + if (daemonTriggerAvailable) { + daemonTriggerAvailable = false; + sectionDaemon(); + } + if (daemonTriggerAvailable) { + daemonTriggerAvailable = false; + globalDaemon(); + } + + break; + + default: + printf("Kernel::handleTrigger() Unknown trigger mode %d\n", mode); + + } + + triggerMode = saveTriggerMode; + trigger = saveTrigger; + + return result; +} + +void Kernel::loadGlobalScriptFunctions() { + _globalDaemonFn = _vm->_script->loadFunction("global_daemon"); + _globalParserFn = _vm->_script->loadFunction("global_parser"); +} + +void Kernel::loadSectionScriptFunctions() { + char tempFnName[128]; + snprintf(tempFnName, 128, "section_init_%d", currentSection); + _sectionInitFn = _vm->_script->loadFunction(tempFnName); + snprintf(tempFnName, 128, "section_daemon_%d", currentSection); + _sectionDaemonFn = _vm->_script->loadFunction(tempFnName); + snprintf(tempFnName, 128, "section_parser_%d", currentSection); + _sectionParserFn = _vm->_script->loadFunction(tempFnName); +} + +void Kernel::loadRoomScriptFunctions() { + char tempFnName[128]; + snprintf(tempFnName, 128, "room_init_%d", currentRoom); + _roomInitFn = _vm->_script->loadFunction(tempFnName); + snprintf(tempFnName, 128, "room_daemon_%d", currentRoom); + _roomDaemonFn = _vm->_script->loadFunction(tempFnName); + snprintf(tempFnName, 128, "room_pre_parser_%d", currentRoom); + _roomPreParserFn = _vm->_script->loadFunction(tempFnName); + snprintf(tempFnName, 128, "room_parser_%d", currentRoom); + _roomParserFn = _vm->_script->loadFunction(tempFnName); +} + +void Kernel::globalDaemon() { + if (_globalDaemonFn) + _vm->_script->runFunction(_globalDaemonFn); + else { + printf("Kernel::globalDaemon() _globalDaemonFn is NULL\n"); + } +} + +void Kernel::globalParser() { + if (_globalParserFn) + _vm->_script->runFunction(_globalParserFn); + else { + printf("Kernel::globalParser() _globalParserFn is NULL\n"); + } +} + +void Kernel::sectionInit() { + if (_sectionInitFn) + _vm->_script->runFunction(_sectionInitFn); + else { + printf("Kernel::sectionInit() _sectionInitFn is NULL\n"); + } +} + +void Kernel::sectionDaemon() { + if (_sectionDaemonFn) + _vm->_script->runFunction(_sectionDaemonFn); + else { + printf("Kernel::sectionDaemon() _sectionDaemonFn is NULL\n"); + } +} + +void Kernel::sectionParser() { + if (_sectionParserFn) + _vm->_script->runFunction(_sectionParserFn); + else { + printf("Kernel::sectionParser() _sectionParserFn is NULL\n"); + } +} + +void Kernel::roomInit() { + if (_roomInitFn) + _vm->_script->runFunction(_roomInitFn); + else { + printf("Kernel::roomInit() _roomInitFn is NULL\n"); + } +} + +void Kernel::roomDaemon() { + if (_roomDaemonFn) + _vm->_script->runFunction(_roomDaemonFn); + else { + printf("Kernel::roomDaemon() _roomDaemonFn is NULL\n"); + } +} + +void Kernel::roomPreParser() { + if (_roomPreParserFn) + _vm->_script->runFunction(_roomPreParserFn); + else { + printf("Kernel::roomPreParser() _roomPreParserFn is NULL\n"); + } +} + +void Kernel::roomParser() { + if (_roomParserFn) + _vm->_script->runFunction(_roomParserFn); + else { + printf("Kernel::roomParser() _roomParserFn is NULL\n"); + } +} + +void Kernel::pauseGame(bool value) { + paused = value; + + if (paused) pauseEngines(); + else unpauseEngines(); +} + +void Kernel::pauseEngines() { + // TODO: A proper implementation of game pausing. At the moment I'm using a hard-coded + // check in events.cpp on Kernel::paused to prevent any events going to the scene +} + +void Kernel::unpauseEngines() { + // TODO: A proper implementation of game unpausing +} + +//-------------------------------------------------------------------------- + +Globals::Globals(M4Engine *vm): _vm(vm) { +} + +Globals::~Globals() { + for(uint32 i = 0; i < _madsVocab.size(); i++) + free(_madsVocab[i]); + _madsVocab.clear(); + + for(uint32 i = 0; i < _madsQuotes.size(); i++) + free(_madsQuotes[i]); + _madsQuotes.clear(); + + _madsMessages.clear(); +} + +bool Globals::isInterfaceVisible() { + return _vm->_interfaceView->isVisible(); +} + +void Globals::loadMadsVocab() { + Common::SeekableReadStream *vocabS = _vm->res()->get("vocab.dat"); + int curPos = 0; + + char buffer[30]; + strcpy(buffer, ""); + + while(!vocabS->eos()) { + buffer[curPos++] = vocabS->readByte(); + if (buffer[curPos - 1] == '\0') { + // end of string, add it to the strings list + _madsVocab.push_back(strdup(buffer)); + curPos = 0; + strcpy(buffer, ""); + } + } + + _vm->res()->toss("vocab.dat"); +} + +void Globals::loadMadsQuotes() { + Common::SeekableReadStream *quoteS = _vm->res()->get("quotes.dat"); + int curPos = 0; + + char buffer[128]; + strcpy(buffer, ""); + + while(!quoteS->eos()) { + buffer[curPos++] = quoteS->readByte(); + if (buffer[curPos - 1] == '\0') { + // end of string, add it to the strings list + _madsQuotes.push_back(strdup(buffer)); + curPos = 0; + strcpy(buffer, ""); + } + } + + _vm->res()->toss("quotes.dat"); +} + +void Globals::loadMadsMessagesInfo() { + Common::SeekableReadStream *messageS = _vm->res()->get("messages.dat"); + + int16 count = messageS->readUint16LE(); + //printf("%i messages\n", count); + + for (int i = 0; i < count; i++) { + MessageItem *curMessage = new MessageItem(); + curMessage->id = messageS->readUint32LE(); + curMessage->offset = messageS->readUint32LE(); + curMessage->uncompSize = messageS->readUint16LE(); + + if (i > 0) + _madsMessages[i - 1]->compSize = curMessage->offset - _madsMessages[i - 1]->offset; + + if (i == count - 1) + curMessage->compSize = messageS->size() - curMessage->offset; + + //printf("id: %i, offset: %i, uncomp size: %i\n", curMessage->id, curMessage->offset, curMessage->uncompSize); + _madsMessages.push_back(curMessage); + } + + _vm->res()->toss("messages.dat"); +} + +char* Globals::loadMessage(uint32 index) { + if (index > _madsMessages.size() - 1) { + warning("Invalid message index: %i", index); + return NULL; + } + + FabDecompressor fab; + byte *compData = new byte[_madsMessages[index]->compSize]; + byte *buffer = new byte[_madsMessages[index]->uncompSize]; + + Common::SeekableReadStream *messageS = _vm->res()->get("messages.dat"); + messageS->seek(_madsMessages[index]->offset, SEEK_SET); + messageS->read(compData, _madsMessages[index]->compSize); + fab.decompress(compData, _madsMessages[index]->compSize, buffer, _madsMessages[index]->uncompSize); + + for (int i = 0; i < _madsMessages[index]->uncompSize - 1; i++) + if (buffer[i] == '\0') buffer[i] = '\n'; + + _vm->res()->toss("messages.dat"); + + return (char*)buffer; +} + +//-------------------------------------------------------------------------- + +Player::Player(M4Engine *vm) : _vm(vm) { + commandsAllowed = true; + needToWalk = false; + readyToWalk = false; + waitingForWalk = false; + commandReady = false; + strcpy(verb, ""); + strcpy(noun, ""); + strcpy(prep, ""); + strcpy(object, ""); +} + +void Player::setCommandsAllowed(bool value) { + setCommandsAllowedFlag = true; + commandsAllowed = value; + if (value) { + // Player commands are enabled again + _vm->_mouse->lockCursor(CURSOR_ARROW); + //_vm->_interfaceView->cancelSentence(); + } else { + // Player commands are disabled, so show hourglass cursor + _vm->_mouse->lockCursor(CURSOR_HOURGLASS); + } +} + +bool Player::said(const char *word1, const char *word2, const char *word3) { + const char *words[3]; + words[0] = word1; + words[1] = word2; + words[2] = word2; + for (int i = 0; i < 3; i++) { + if (words[i]) + if ((scumm_stricmp(noun, words[i])) && + (scumm_stricmp(object, words[i])) && + (scumm_stricmp(verb, words[i]))) + return false; + } + return true; +} + +bool Player::saidAny(const char *word1, const char *word2, const char *word3, + const char *word4, const char *word5, const char *word6, const char *word7, + const char *word8, const char *word9, const char *word10) { + const char *words[10]; + words[0] = word1; + words[1] = word2; + words[2] = word3; + words[3] = word4; + words[4] = word5; + words[5] = word6; + words[6] = word7; + words[7] = word8; + words[8] = word9; + words[9] = word10; + for (int i = 0; i < 10; i++) { + if (words[i]) { + if (!scumm_stricmp(noun, words[i])) + return true; + if (!scumm_stricmp(object, words[i])) + return true; + if (!scumm_stricmp(verb, words[i])) + return true; + } + } + return false; +} + + +} // End of namespace M4 |