diff options
-rw-r--r-- | engines/m4/globals.cpp | 25 | ||||
-rw-r--r-- | engines/m4/globals.h | 9 | ||||
-rw-r--r-- | engines/m4/graphics.cpp | 5 | ||||
-rw-r--r-- | engines/m4/graphics.h | 1 | ||||
-rw-r--r-- | engines/m4/mads_logic.cpp | 108 | ||||
-rw-r--r-- | engines/m4/mads_logic.h | 54 | ||||
-rw-r--r-- | engines/m4/module.mk | 1 | ||||
-rw-r--r-- | engines/m4/resource.cpp | 65 | ||||
-rw-r--r-- | engines/m4/resource.h | 6 | ||||
-rw-r--r-- | engines/m4/scene.cpp | 7 | ||||
-rw-r--r-- | engines/m4/scene.h | 6 | ||||
-rw-r--r-- | engines/m4/sound.cpp | 4 | ||||
-rw-r--r-- | engines/m4/sound.h | 1 |
13 files changed, 289 insertions, 3 deletions
diff --git a/engines/m4/globals.cpp b/engines/m4/globals.cpp index 39226f0ebc..856c1bb817 100644 --- a/engines/m4/globals.cpp +++ b/engines/m4/globals.cpp @@ -278,6 +278,8 @@ bool Globals::isInterfaceVisible() { MadsGlobals::MadsGlobals(MadsEngine *vm): Globals(vm) { _vm = vm; + + playerSpriteChanged = false; } MadsGlobals::~MadsGlobals() { @@ -408,6 +410,29 @@ const char *MadsGlobals::loadMessage(uint index) { return (char*)buffer; } +/** + * Adds the specified scene number to list of scenes previously visited + */ +void MadsGlobals::addVisitedScene(int sceneNumber) { + if (!isSceneVisited(sceneNumber)) + _visitedScenes.push_back(sceneNumber); +} + +/** + * Returns true if the specified scene has been previously visited + */ +bool MadsGlobals::isSceneVisited(int sceneNumber) { + Common::List<int>::iterator i; + for (i = _visitedScenes.begin(); i != _visitedScenes.end(); ++i) + if (*i == sceneNumber) + return true; + return false; +} + +void MadsGlobals::removeVisitedScene(int sceneNumber) { + _visitedScenes.remove(sceneNumber); +} + /*--------------------------------------------------------------------------*/ M4Globals::M4Globals(M4Engine *vm): Globals(vm) { diff --git a/engines/m4/globals.h b/engines/m4/globals.h index 8d9f3118b4..aee0e6fa9c 100644 --- a/engines/m4/globals.h +++ b/engines/m4/globals.h @@ -206,6 +206,8 @@ public: bool invSuppressClickSound; }; +enum RexPlayerSex { SEX_MALE = 0, SEX_FEMALE = 2, SEX_UNKNOWN = 1}; + class MadsGlobals : public Globals { private: struct MessageItem { @@ -220,15 +222,18 @@ private: Common::Array<char* > _madsQuotes; Common::Array<MessageItem* > _madsMessages; MadsObjectArray _madsObjects; + Common::List<int> _visitedScenes; public: MadsGlobals(MadsEngine *vm); ~MadsGlobals(); // MADS variables + int _globals[TOTAL_NUM_VARIABLES]; bool easyMouse; bool invObjectsStill; bool textWindowStill; int storyMode; + bool playerSpriteChanged; void loadMadsVocab(); uint32 getVocabSize() { return _madsVocab.size(); } @@ -250,6 +255,10 @@ public: void loadMadsObjects(); uint32 getObjectsSize() { return _madsObjects.size(); } MadsObject *getObject(uint32 index) { return _madsObjects[index].get(); } + + void addVisitedScene(int sceneNumber); + bool isSceneVisited(int sceneNumber); + void removeVisitedScene(int sceneNumber); }; #define PLAYER_FIELD_LENGTH 40 diff --git a/engines/m4/graphics.cpp b/engines/m4/graphics.cpp index da288cc3bc..9e663fcb05 100644 --- a/engines/m4/graphics.cpp +++ b/engines/m4/graphics.cpp @@ -767,6 +767,11 @@ void Palette::grabPalette(byte *colors, uint start, uint num) { reset(); } +void Palette::setEntry(uint index, uint8 r, uint8 g, uint8 b) { + uint32 c = (r << 16) | (g << 8) || b; + g_system->setPalette((const byte *)&c, index, 1); +} + uint8 Palette::palIndexFromRgb(byte r, byte g, byte b, RGB8 *paletteData) { byte index = 0; int32 minDist = 0x7fffffff; diff --git a/engines/m4/graphics.h b/engines/m4/graphics.h index b88e9f3616..e286c6ae55 100644 --- a/engines/m4/graphics.h +++ b/engines/m4/graphics.h @@ -190,6 +190,7 @@ public: void grabPalette(RGB8 *colors, uint start, uint num) { grabPalette((byte *)colors, start, num); } + void setEntry(uint index, uint8 r, uint8 g, uint8 b); uint8 palIndexFromRgb(byte r, byte g, byte b, RGB8 *paletteData = NULL); void fadeToGreen(int numSteps, uint delayAmount); diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp new file mode 100644 index 0000000000..2199a05d52 --- /dev/null +++ b/engines/m4/mads_logic.cpp @@ -0,0 +1,108 @@ +/* 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/mads_logic.h" +#include "m4/scene.h" + +namespace M4 { + +/*--------------------------------------------------------------------------*/ + +const char *MadsSceneLogic::formAnimName(char sepChar, int suffixNum) { + return MADSResourceManager::getResourceName(sepChar, _sceneNumber, EXTTYPE_NONE, NULL, suffixNum); +} + +void MadsSceneLogic::getSceneSpriteSet() { + char *setName = _madsVm->scene()->_playerSpriteName; + char oldName[100]; + strcpy(oldName, setName); + + // Room change sound + _madsVm->_sound->playSound(5); + + // Set up sprite set prefix to use + if ((_sceneNumber <= 103) || (_sceneNumber == 111)) { + if (_madsVm->globals()->_globals[0] == SEX_FEMALE) + strcpy(setName, "ROX"); + else + strcpy(setName, "RXM"); + } else if (_sceneNumber <= 110) { + strcpy(setName, "RXSW"); + _madsVm->globals()->_globals[0] = SEX_UNKNOWN; + } else if (_sceneNumber == 112) + strcpy(setName, ""); + + if (strcmp(setName, oldName) != 0) + _madsVm->globals()->playerSpriteChanged = true; + + if ((_sceneNumber == 105)/* || ((_sceneNumber == 109) && (word_84800 != 0))*/) + _madsVm->globals()->playerSpriteChanged = true; + + _vm->_palette->setEntry(16, 0x38, 0xFF, 0xFF); + _vm->_palette->setEntry(17, 0x38, 0xb4, 0xb4); +} + +void MadsSceneLogic::getAnimName() { + const char *newName = MADSResourceManager::getAAName( + ((_sceneNumber <= 103) || (_sceneNumber > 111)) ? 0 : 1); + strcpy(_madsVm->scene()->_aaName, newName); +} + +/*--------------------------------------------------------------------------*/ + +/** + * FIXME: + * Currently I'm only working at providing manual implementation of the first Rex Nebular scene. + * It will make more sense to convert the remaining game logic from the games into some + * kind of bytecode scripts + */ + +void MadsSceneLogic::selectScene(int sceneNum) { + assert(sceneNum == 101); + _sceneNumber = sceneNum; + + +} + +void MadsSceneLogic::setupScene() { + // FIXME: This is the hardcoded logic for Rex scene 101 only + const char *animName = formAnimName('A', -1); +warning("anim - %s\n", animName); +// sub_1e754(animName, 3); + + getSceneSpriteSet(); + getAnimName(); +} + +void MadsSceneLogic::enterScene() { + +} + +void MadsSceneLogic::doAction() { + +} + +} diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h new file mode 100644 index 0000000000..7c8b1b8054 --- /dev/null +++ b/engines/m4/mads_logic.h @@ -0,0 +1,54 @@ +/* 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$ + * + * The MADS game logic is all hard-coded into the games, although for Rex at least + * it seems to use only a fairly basic set of instructions and function calls, so it should be + * possible + */ + +#ifndef M4_MADS_LOGIC_H +#define M4_MADS_LOGIC_H + +namespace M4 { + +class MadsSceneLogic { +private: + // Library interface methods +private: + int _sceneNumber; + + // Support functions + const char *formAnimName(char sepChar, int suffixNum); + void getSceneSpriteSet(); + void getAnimName(); +public: + void selectScene(int sceneNum); + + void setupScene(); + void enterScene(); + void doAction(); +}; + +} + +#endif diff --git a/engines/m4/module.mk b/engines/m4/module.mk index f6b9fa01cc..d88536fa1a 100644 --- a/engines/m4/module.mk +++ b/engines/m4/module.mk @@ -19,6 +19,7 @@ MODULE_OBJS = \ m4_menus.o \ m4_views.o \ mads_anim.o \ + mads_logic.o \ mads_menus.o \ mads_views.o \ midi.o \ diff --git a/engines/m4/resource.cpp b/engines/m4/resource.cpp index c8b71dd7ef..747077ac74 100644 --- a/engines/m4/resource.cpp +++ b/engines/m4/resource.cpp @@ -310,6 +310,71 @@ const char *MADSResourceManager::getResourceFilename(const char *resourceName) { return outputFilename; } +/** + * Forms a resource name based on the passed specifiers + */ +const char *MADSResourceManager::getResourceName(char asciiCh, int prefix, ExtensionType extType, + const char *suffix, int index) { + static char resourceName[100]; + + if (prefix <= 0) + strcpy(resourceName, "*"); + else { + if (prefix < 100) + strcpy(resourceName, "*SC"); + else + strcpy(resourceName, "*RM"); + sprintf(resourceName + 3, "%.3d", prefix); + } + + // Append the specified ascii prefix character + char asciiStr[2]; + asciiStr[0] = asciiCh; + asciiStr[1] = '\0'; + strcat(resourceName, asciiStr); + + // Add in the index specified + if (index > 0) + sprintf(resourceName + strlen(resourceName), "%d", index); + + // Add in any suffix + if (suffix) + strcat(resourceName, suffix); + + // Handle extension types + switch (extType) { + case EXTTYPE_SS: + strcat(resourceName, ".SS"); + break; + case EXTTYPE_AA: + strcat(resourceName, ".AA"); + break; + case EXTTYPE_DAT: + strcat(resourceName, ".DAT"); + break; + case EXTTYPE_HH: + strcat(resourceName, ".HH"); + break; + case EXTTYPE_ART: + strcat(resourceName, ".ART"); + break; + case EXTTYPE_INT: + strcat(resourceName, ".INT"); + break; + default: + break; + } + + return &resourceName[0]; +} + +/** + * Forms an AA resource name based on the given passed index + */ +const char *MADSResourceManager::getAAName(int index) { + return getResourceName('I', 0, EXTTYPE_AA, NULL, index); +} + Common::SeekableReadStream *MADSResourceManager::loadResource(const char *resourceName, bool loadFlag) { Common::File hagFile; uint32 offset = 0, size = 0; diff --git a/engines/m4/resource.h b/engines/m4/resource.h index b243362fbb..2c6bacced6 100644 --- a/engines/m4/resource.h +++ b/engines/m4/resource.h @@ -112,6 +112,9 @@ public: enum ResourceType {RESTYPE_ROOM, RESTYPE_SC, RESTYPE_TEXT, RESTYPE_QUO, RESTYPE_I, RESTYPE_OB, RESTYPE_FONT, RESTYPE_SOUND, RESTYPE_SPEECH, RESTYPE_HAS_EXT, RESTYPE_NO_EXT}; +enum ExtensionType {EXTTYPE_SS = 1, EXTTYPE_AA = 2, EXTTYPE_DAT = 3, EXTTYPE_HH = 4, EXTTYPE_ART = 5, + EXTTYPE_INT = 6, EXTTYPE_NONE = -1}; + class MADSResourceManager : public ResourceManager { private: ResourceType getResourceType(const char *resourceName); @@ -121,6 +124,9 @@ protected: public: MADSResourceManager(MadsM4Engine *vm): ResourceManager(vm) {}; bool resourceExists(const char *resourceName); + + static const char *getResourceName(char asciiCh, int prefix, ExtensionType extType, const char *suffix, int index); + static const char *getAAName(int index); }; class M4ResourceManager : public ResourceManager { diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp index 6d4c4ae64d..610b6191f5 100644 --- a/engines/m4/scene.cpp +++ b/engines/m4/scene.cpp @@ -603,6 +603,7 @@ MadsScene::MadsScene(MadsEngine *vm): Scene(vm) { _vm = vm; strcpy(_statusText, ""); + strcpy(_playerSpriteName, ""); _interfaceSurface = new MadsInterfaceView(vm); _currentAction = kVerbNone; } @@ -617,9 +618,9 @@ void MadsScene::loadScene(int sceneNumber) { // Handle common scene setting Scene::loadScene(sceneNumber); - - // TODO: Check if we were loading a game - + _sceneLogic.selectScene(sceneNumber); + _vm->globals()->addVisitedScene(sceneNumber); + _sceneLogic.setupScene(); // Set system palette entries _vm->_palette->blockRange(0, 7); diff --git a/engines/m4/scene.h b/engines/m4/scene.h index f452fb1485..d97d43de0d 100644 --- a/engines/m4/scene.h +++ b/engines/m4/scene.h @@ -34,6 +34,7 @@ class View; #include "m4/viewmgr.h" #include "m4/gui.h" #include "m4/m4_views.h" +#include "m4/mads_logic.h" #include "m4/mads_views.h" namespace M4 { @@ -163,6 +164,11 @@ private: int _currentAction; char _statusText[100]; + MadsSceneLogic _sceneLogic; + SpriteAsset *_playerSprites; +public: + char _playerSpriteName[100]; + char _aaName[100]; public: MadsScene(MadsEngine *vm); virtual ~MadsScene() {}; diff --git a/engines/m4/sound.cpp b/engines/m4/sound.cpp index 37fe36cf2b..6c8c9edb82 100644 --- a/engines/m4/sound.cpp +++ b/engines/m4/sound.cpp @@ -99,6 +99,10 @@ void Sound::playSound(const char *soundName, int volume, bool loop, int channel) _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &handle->handle, stream, -1, volume); } +void Sound::playSound(int soundNum) { + warning("TODO: playSound(%d)", soundNum); +} + void Sound::pauseSound() { for (int i = 0; i < SOUND_HANDLES; i++) { if (_handles[i].type == kEffectHandle) diff --git a/engines/m4/sound.h b/engines/m4/sound.h index 7ae6103d26..7d442a73cc 100644 --- a/engines/m4/sound.h +++ b/engines/m4/sound.h @@ -77,6 +77,7 @@ public: ~Sound(); void playSound(const char *soundName, int volume, bool loop, int channel = -1); + void playSound(int soundNum); void pauseSound(); void resumeSound(); void stopSound(int channel = -1); |