diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/cge/detection.cpp | 74 | ||||
-rw-r--r-- | engines/cge2/cge2_main.cpp | 3 | ||||
-rw-r--r-- | engines/cge2/detection.cpp | 77 | ||||
-rw-r--r-- | engines/mads/animation.cpp | 25 | ||||
-rw-r--r-- | engines/mads/animation.h | 19 | ||||
-rw-r--r-- | engines/mads/msurface.h | 5 | ||||
-rw-r--r-- | engines/mads/nebular/menu_nebular.cpp | 162 | ||||
-rw-r--r-- | engines/mads/nebular/menu_nebular.h | 47 | ||||
-rw-r--r-- | engines/mads/phantom/game_phantom.cpp | 15 | ||||
-rw-r--r-- | engines/mads/user_interface.h | 2 | ||||
-rw-r--r-- | engines/scumm/detection.cpp | 6 | ||||
-rw-r--r-- | engines/scumm/detection_tables.h | 11 | ||||
-rw-r--r-- | engines/scumm/object.cpp | 1 | ||||
-rw-r--r-- | engines/sword1/sound.cpp | 75 | ||||
-rw-r--r-- | engines/sword1/sound.h | 1 | ||||
-rw-r--r-- | engines/sword1/sword1.cpp | 2 | ||||
-rw-r--r-- | engines/sword25/kernel/persistenceservice.cpp | 2 | ||||
-rw-r--r-- | engines/sword25/util/pluto/pluto.cpp | 29 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_logic.cpp | 5 |
19 files changed, 374 insertions, 187 deletions
diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp index 022ff4df95..ee67fb839b 100644 --- a/engines/cge/detection.cpp +++ b/engines/cge/detection.cpp @@ -28,35 +28,19 @@ #include "base/plugins.h" #include "graphics/thumbnail.h" #include "cge/cge.h" +#include "cge/fileio.h" namespace CGE { -struct CgeGameDescription { - ADGameDescription desc; -}; - #define GAMEOPTION_COLOR_BLIND_DEFAULT_OFF GUIO_GAMEOPTIONS1 -} // End of namespace CGE - static const PlainGameDescriptor CGEGames[] = { { "soltys", "Soltys" }, { 0, 0 } }; -namespace CGE { - static const ADGameDescription gameDescriptions[] = { { - "soltys", "", - { - {"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176}, - {"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437572}, - AD_LISTEND - }, - Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0() - }, - { "soltys", "Freeware", { {"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176}, @@ -114,12 +98,6 @@ static const ADGameDescription gameDescriptions[] = { AD_TABLE_END_MARKER }; -static const ADFileBasedFallback fileBasedFallback[] = { - { &gameDescriptions[0], { "vol.cat", "vol.dat", 0 } }, - { 0, { 0 } } -}; -} // End of namespace CGE - static const ADExtraGuiOptionsMap optionsList[] = { { GAMEOPTION_COLOR_BLIND_DEFAULT_OFF, @@ -136,14 +114,10 @@ static const ADExtraGuiOptionsMap optionsList[] = { class CGEMetaEngine : public AdvancedMetaEngine { public: - CGEMetaEngine() : AdvancedMetaEngine(CGE::gameDescriptions, sizeof(CGE::CgeGameDescription), CGEGames, optionsList) { + CGEMetaEngine() : AdvancedMetaEngine(CGE::gameDescriptions, sizeof(ADGameDescription), CGEGames, optionsList) { _singleid = "soltys"; } - virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { - return detectGameFilebased(allFiles, fslist, CGE::fileBasedFallback); - } - virtual const char *getName() const { return "CGE"; } @@ -152,6 +126,7 @@ public: return "Soltys (c) 1994-1996 L.K. Avalon"; } + virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const; virtual bool hasFeature(MetaEngineFeature f) const; virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; virtual int getMaximumSaveSlot() const; @@ -160,6 +135,44 @@ public: virtual void removeSaveState(const char *target, int slot) const; }; +static const ADFileBasedFallback fileBasedFallback[] = { + { &gameDescriptions[0], { "vol.cat", "vol.dat", 0 } }, + { 0, { 0 } } +}; + +static ADGameDescription s_fallbackDesc = { + "Soltys", + "Unknown version", + AD_ENTRY1(0, 0), // This should always be AD_ENTRY1(0, 0) in the fallback descriptor + Common::UNK_LANG, + Common::kPlatformDOS, + ADGF_NO_FLAGS, + GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF) +}; + +const ADGameDescription *CGEMetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { + ADFilePropertiesMap filesProps; + + const ADGameDescription *game; + game = detectGameFilebased(allFiles, fslist, CGE::fileBasedFallback, &filesProps); + + if (!game) + return 0; + + SearchMan.clear(); + SearchMan.addDirectory(fslist.begin()->getParent().getPath(), fslist.begin()->getParent()); + ResourceManager *resman; + resman = new ResourceManager(); + bool result = resman->exist("CGE.SAY"); + delete resman; + + if (!result) + return 0; + + reportUnknown(fslist.begin()->getParent(), filesProps); + return &s_fallbackDesc; +} + bool CGEMetaEngine::hasFeature(MetaEngineFeature f) const { return (f == kSupportsListSaves) || @@ -269,9 +282,10 @@ bool CGEMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD } return desc != 0; } +} // End of namespace CGE #if PLUGIN_ENABLED_DYNAMIC(CGE) - REGISTER_PLUGIN_DYNAMIC(CGE, PLUGIN_TYPE_ENGINE, CGEMetaEngine); +REGISTER_PLUGIN_DYNAMIC(CGE, PLUGIN_TYPE_ENGINE, CGE::CGEMetaEngine); #else - REGISTER_PLUGIN_STATIC(CGE, PLUGIN_TYPE_ENGINE, CGEMetaEngine); +REGISTER_PLUGIN_STATIC(CGE, PLUGIN_TYPE_ENGINE, CGE::CGEMetaEngine); #endif diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp index 1057b00089..3e3d615a91 100644 --- a/engines/cge2/cge2_main.cpp +++ b/engines/cge2/cge2_main.cpp @@ -722,10 +722,9 @@ void CGE2Engine::loadTab() { if (_resman->exist(kTabName)) { EncryptedStream f(this, kTabName); - uint32 v; for (int i = 0; i < kSceneMax; i++) { - v = f.readUint32LE(); + uint32 v = f.readUint32LE(); _eyeTab[i]->_x = FXP(v >> 8, static_cast<int>((int8)(v & 0xff))); v = f.readUint32LE(); diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp index 605a3fe377..c05ce70c3d 100644 --- a/engines/cge2/detection.cpp +++ b/engines/cge2/detection.cpp @@ -26,6 +26,7 @@ */ #include "cge2/cge2.h" +#include "cge2/fileio.h" #include "engines/advancedDetector.h" #include "common/translation.h" #include "graphics/surface.h" @@ -60,6 +61,16 @@ static const ADGameDescription gameDescriptions[] = { Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF) }, + { + "sfinx", "Freeware v0.3", + { + {"vol.cat", 0, "f158e469dccbebc5a632eb848df89779", 129024}, + {"vol.dat", 0, "d40a6b4ae173d6930be54ba56bee15d5", 34183430}, + AD_LISTEND + }, + Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF) + }, + AD_TABLE_END_MARKER }; @@ -91,16 +102,55 @@ public: return "Sfinx (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon"; } + virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const; virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; virtual bool hasFeature(MetaEngineFeature f) const; virtual int getMaximumSaveSlot() const; virtual SaveStateList listSaves(const char *target) const; SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; virtual void removeSaveState(const char *target, int slot) const; +}; + +static const ADFileBasedFallback fileBasedFallback[] = { + { &gameDescriptions[0], { "vol.cat", "vol.dat", 0 } }, + { 0, { 0 } } +}; - const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const; +static ADGameDescription s_fallbackDesc = { + "Sfinx", + "Unknown version", + AD_ENTRY1(0, 0), // This should always be AD_ENTRY1(0, 0) in the fallback descriptor + Common::UNK_LANG, + Common::kPlatformDOS, + ADGF_NO_FLAGS, + GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF) }; +// This fallback detection looks identical to the one used for CGE. In fact, the difference resides +// in the ResourceManager which handles a different archive format. The rest of the detection is identical. +const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { + ADFilePropertiesMap filesProps; + + const ADGameDescription *game; + game = detectGameFilebased(allFiles, fslist, CGE2::fileBasedFallback, &filesProps); + + if (!game) + return 0; + + SearchMan.clear(); + SearchMan.addDirectory(fslist.begin()->getParent().getPath(), fslist.begin()->getParent()); + ResourceManager *resman; + resman = new ResourceManager(); + bool result = resman->exist("CGE.SAY"); + delete resman; + + if (!result) + return 0; + + reportUnknown(fslist.begin()->getParent(), filesProps); + return &s_fallbackDesc; +} + bool CGE2MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { if (desc) *engine = new CGE2::CGE2Engine(syst, desc); @@ -118,31 +168,6 @@ bool CGE2MetaEngine::hasFeature(MetaEngineFeature f) const { (f == kSupportsLoadingDuringStartup); } -const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { - static ADGameDescription desc; - - for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { - if (file->isDirectory()) - continue; - - if (file->getName().equalsIgnoreCase("lang.eng")) { - Common::File dataFile; - if (!dataFile.open(*file)) - continue; - - desc.gameid = "sfinx"; - desc.extra = "Translation Alpha v0.3"; - desc.language = Common::EN_ANY; - desc.platform = Common::kPlatformDOS; - desc.flags = ADGF_NO_FLAGS; - desc.guioptions = GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF); - - return (const ADGameDescription *)&desc; - } - } - return 0; -} - int CGE2MetaEngine::getMaximumSaveSlot() const { return 99; } diff --git a/engines/mads/animation.cpp b/engines/mads/animation.cpp index 512a3979f9..9b2c097004 100644 --- a/engines/mads/animation.cpp +++ b/engines/mads/animation.cpp @@ -32,10 +32,8 @@ void AAHeader::load(Common::SeekableReadStream *f) { _miscEntriesCount = f->readUint16LE(); _frameEntriesCount = f->readUint16LE(); _messagesCount = f->readUint16LE(); - f->skip(1); - _flags = f->readByte(); - - f->skip(2); + _loadFlags = f->readUint16LE(); + _charSpacing = f->readSint16LE(); _bgType = (AnimBgType)f->readUint16LE(); _roomNumber = f->readUint16LE(); f->skip(2); @@ -49,7 +47,7 @@ void AAHeader::load(Common::SeekableReadStream *f) { char buffer[FILENAME_SIZE]; f->read(buffer, FILENAME_SIZE); buffer[FILENAME_SIZE - 1] = '\0'; - _interfaceFile = Common::String(buffer); + _backgroundFile = Common::String(buffer); for (int i = 0; i < 50; ++i) { f->read(buffer, FILENAME_SIZE); @@ -134,7 +132,8 @@ void AnimMiscEntry::load(Common::SeekableReadStream *f) { _numTicks = f->readUint16LE(); _posAdjust.x = f->readSint16LE(); _posAdjust.y = f->readSint16LE(); - _field8 = f->readUint16LE(); + _scroll.x = f->readSByte(); + _scroll.y = f->readSByte(); } /*------------------------------------------------------------------------*/ @@ -189,7 +188,7 @@ Animation::~Animation() { } } -void Animation::load(UserInterface &interfaceSurface, DepthSurface &depthSurface, +void Animation::load(MSurface &backSurface, DepthSurface &depthSurface, const Common::String &resName, int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo) { Common::String resourceName = resName; @@ -207,7 +206,7 @@ void Animation::load(UserInterface &interfaceSurface, DepthSurface &depthSurface flags |= PALFLAG_RESERVED; if (flags & ANIMFLAG_LOAD_BACKGROUND) { - loadInterface(interfaceSurface, depthSurface, _header, flags, palCycles, sceneInfo); + loadBackground(backSurface, depthSurface, _header, flags, palCycles, sceneInfo); } if (flags & ANIMFLAG_LOAD_BACKGROUND_ONLY) { // No data @@ -275,7 +274,7 @@ void Animation::load(UserInterface &interfaceSurface, DepthSurface &depthSurface // If the animation specifies a font, then load it for access delete _font; - if (_header._flags & ANIMFLAG_CUSTOM_FONT) { + if (_header._loadFlags & ANIMFLAG_CUSTOM_FONT) { Common::String fontName = "*" + _header._fontResource; _font = _vm->_font->getFont(fontName.c_str()); } else { @@ -385,12 +384,12 @@ bool Animation::drawFrame(SpriteAsset &spriteSet, const Common::Point &pt, int f return 0; } -void Animation::loadInterface(UserInterface &interfaceSurface, DepthSurface &depthSurface, +void Animation::loadBackground(MSurface &backSurface, DepthSurface &depthSurface, AAHeader &header, int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo) { _scene->_depthStyle = 0; if (header._bgType <= ANIMBG_FULL_SIZE) { _vm->_palette->_paletteUsage.setEmpty(); - sceneInfo->load(header._roomNumber, flags, header._interfaceFile, 0, depthSurface, interfaceSurface); + sceneInfo->load(header._roomNumber, 0, header._backgroundFile, flags, depthSurface, backSurface); _scene->_depthStyle = sceneInfo->_depthStyle == 2 ? 1 : 0; if (palCycles) { palCycles->clear(); @@ -399,8 +398,8 @@ void Animation::loadInterface(UserInterface &interfaceSurface, DepthSurface &dep } } else if (header._bgType == ANIMBG_INTERFACE) { // Load a scene interface - Common::String resourceName = "*" + header._interfaceFile; - interfaceSurface.load(resourceName); + Common::String resourceName = "*" + header._backgroundFile; + backSurface.load(resourceName); if (palCycles) palCycles->clear(); diff --git a/engines/mads/animation.h b/engines/mads/animation.h index 15086d3e41..917d899ec5 100644 --- a/engines/mads/animation.h +++ b/engines/mads/animation.h @@ -34,8 +34,8 @@ namespace MADS { enum AnimFlag { - ANIMFLAG_DITHER = 0x0001, // Dither to 16 colors - ANIMFLAG_CUSTOM_FONT = 0x0020, // Load ccustom font + ANIMFLAG_DITHER = 0x1000, // Dither to 16 colors + ANIMFLAG_CUSTOM_FONT = 0x2000, // Load ccustom font ANIMFLAG_LOAD_BACKGROUND = 0x0100, // Load background ANIMFLAG_LOAD_BACKGROUND_ONLY = 0x0200 // Load background only }; @@ -82,7 +82,7 @@ public: int _msgIndex; int _numTicks; Common::Point _posAdjust; - int _field8; + Common::Point _scroll; /** * Loads data for the record @@ -116,14 +116,15 @@ public: int _miscEntriesCount; int _frameEntriesCount; int _messagesCount; - byte _flags; + int _loadFlags; + int _charSpacing; AnimBgType _bgType; int _roomNumber; bool _manualFlag; int _spritesIndex; Common::Point _scrollPosition; uint32 _scrollTicks; - Common::String _interfaceFile; + Common::String _backgroundFile; Common::StringArray _spriteSetNames; Common::String _lbmFilename; Common::String _spritesFilename; @@ -166,9 +167,9 @@ private: bool drawFrame(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber); /** - * Load the user interface display for an animation + * Load the user interface display or background for an animation */ - void loadInterface(UserInterface &interfaceSurface, DepthSurface &depthSurface, + void loadBackground(MSurface &backSurface, DepthSurface &depthSurface, AAHeader &header, int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo); /** @@ -196,7 +197,7 @@ public: /** * Loads animation data */ - void load(UserInterface &interfaceSurface, DepthSurface &depthSurface, const Common::String &resName, + void load(MSurface &backSurface, DepthSurface &depthSurface, const Common::String &resName, int flags, Common::Array<PaletteCycle> *palCycles, SceneInfo *sceneInfo); /** @@ -223,6 +224,8 @@ public: int roomNumber() const { return _header._roomNumber; } void resetSpriteSetsCount() { _header._spriteSetsCount = 0; } // CHECKME: See if it doesn't leak the memory when the destructor is called + + SpriteAsset *getSpriteSet(int idx) { return _spriteSets[idx]; } }; } // End of namespace MADS diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h index 3a5bf22eed..ebfb1f437a 100644 --- a/engines/mads/msurface.h +++ b/engines/mads/msurface.h @@ -64,6 +64,11 @@ public: * Helper method for calculating new dimensions when scaling a sprite */ static int scaleValue(int value, int scale, int err); + + /** + * Base method for descendents to load their contents + */ + virtual void load(const Common::String &resName) {} public: /** * Basic constructor diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index 4d3beb3382..7f4eaaeec3 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -796,13 +796,31 @@ AnimationView::AnimationView(MADSEngine *vm) : MenuView(vm) { _soundDriverLoaded = false; _previousUpdate = 0; _screenId = -1; - _showWhiteBars = true; _resetPalette = false; _resyncMode = NEVER; + _v1 = 0; + _v2 = -1; + _resourceIndex = -1; + _currentAnimation = nullptr; + _sfx = 0; + _soundFlag = _bgLoadFlag = true; + _showWhiteBars = true; + _manualFrameNumber = 0; + _manualSpriteSet = nullptr; + _manualStartFrame = _manualEndFrame = 0; + _manualFrame2 = 0; + _hasManual = false; + _animFrameNumber = 0; + _sceneInfo = SceneInfo::init(_vm); load(); } +AnimationView::~AnimationView() { + delete _currentAnimation; + delete _sceneInfo; +} + void AnimationView::load() { Common::String resName(_resourceName); if (!resName.hasSuffix(".")) @@ -814,6 +832,17 @@ void AnimationView::load() { processLines(); } +void AnimationView::display() { + _vm->_palette->initPalette(); + Common::fill(&_vm->_palette->_cyclingPalette[0], &_vm->_palette->_cyclingPalette[PALETTE_SIZE], 0); + + _vm->_palette->resetGamePalette(1, 8); + _vm->_game->_scene._spriteSlots.reset(); + _vm->_game->_scene._paletteCycles.clear(); + + MenuView::display(); +} + bool AnimationView::onEvent(Common::Event &event) { // Wait for the Escape key or a mouse press if (((event.type == Common::EVENT_KEYDOWN) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) || @@ -826,39 +855,69 @@ bool AnimationView::onEvent(Common::Event &event) { } void AnimationView::doFrame() { +// Scene &scene = _vm->_game->_scene; + + // TODO: Or when current animation is finished + if (_resourceIndex == -1) { + if (++_resourceIndex == (int)_resources.size()) + scriptDone(); + else + loadNextResource(); + } +} + +void AnimationView::loadNextResource() { Scene &scene = _vm->_game->_scene; - int bgNumber = 0; + ResourceEntry &resEntry = _resources[_resourceIndex]; - // Only update state if wait period has expired - if (_previousUpdate > 0) { - if (g_system->getMillis() - _previousUpdate < 3000) { - return; - } else { - // time for an update - _previousUpdate = g_system->getMillis(); - } - } else { - _previousUpdate = g_system->getMillis(); - return; + if (resEntry._bgFlag) + _vm->_palette->resetGamePalette(1, 8); + + delete _currentAnimation; + _currentAnimation = Animation::init(_vm, &scene); + _currentAnimation->load(scene._backgroundSurface, scene._depthSurface, + resEntry._resourceName, resEntry._bgFlag ? 0x100 : 0, + nullptr, _sceneInfo); + + // If a sound driver has been specified, then load the correct one + if (!_currentAnimation->_header._soundName.empty()) { + const char *chP = strchr(_currentAnimation->_header._soundName.c_str(), '.'); + assert(chP); + + int driverNum = atoi(chP + 1); + _vm->_sound->init(driverNum); } - /* - char bgFile[10]; - strncpy(bgFile, _currentFile, 5); - bgFile[0] = bgFile[2]; - bgFile[1] = bgFile[3]; - bgFile[2] = bgFile[4]; - bgFile[3] = '\0'; - bgNumber = atoi(bgFile); - sprintf(bgFile, "rm%i.art", bgNumber); - - // Not all scenes have a background. If there is one, refresh it - if (Common::File::exists(bgFile)) { - _vm->_palette->resetGamePalette(4, 8); - SceneInfo *sceneInfo = SceneInfo::init(_vm); - sceneInfo->load(bgNumber, 0, Common::String(), 0, scene._depthSurface, - scene._backgroundSurface); + + // Handle any manual setup + if (_currentAnimation->_header._manualFlag) { + _manualFrameNumber = _currentAnimation->_header._spritesIndex; + _manualSpriteSet = _currentAnimation->getSpriteSet(_manualFrameNumber); + _hasManual = true; } - */ + + // Set the sound data for the animation + _vm->_sound->setEnabled(resEntry._soundFlag); + + Common::String dsrName = _currentAnimation->_header._dsrName; + if (!dsrName.empty()) + _vm->_audio->setSoundGroup(dsrName); + + // Initial frames scan loop + bool foundFrame = false; + for (int frameCtr = 0; frameCtr < (int)_currentAnimation->_frameEntries.size(); ++frameCtr) { + int spritesIdx = _currentAnimation->_spriteListIndexes[_manualFrameNumber]; + AnimFrameEntry &frame = _currentAnimation->_frameEntries[frameCtr]; + + if (frame._spriteSlot._spritesIndex == spritesIdx) { + _animFrameNumber = frame._frameNumber; + _manualStartFrame = _animFrameNumber; + _manualEndFrame = _manualSpriteSet->getCount() - 1; + _manualFrame2 = _manualStartFrame - 1; + break; + } + } + if (!foundFrame) + _hasManual = false; } void AnimationView::scriptDone() { @@ -896,8 +955,8 @@ void AnimationView::processLines() { resName += c; } - _resources.push_back(ResourceEntry(resName, _sfx)); - _sfx = 0; + _resources.push_back(ResourceEntry(resName, _sfx, _soundFlag, + _bgLoadFlag, _showWhiteBars)); } // Skip any spaces @@ -914,6 +973,9 @@ void AnimationView::processCommand() { // Handle the command switch (commandChar) { + case 'B': + _soundFlag = !_soundFlag; + break; case 'H': // -h[:ex] Disable EMS / XMS high memory support if (_currentLine.hasPrefix(":")) @@ -980,6 +1042,42 @@ int AnimationView::getParameter() { return result; } +void AnimationView::checkResource(const Common::String &resourceName) { + //bool hasSuffix = false; + +} + +int AnimationView::scanResourceIndex(const Common::String &resourceName) { + int foundIndex = -1; + + if (_v1) { + const char *chP = strchr(resourceName.c_str(), '\\'); + if (!chP) { + chP = strchr(resourceName.c_str(), '*'); + } + + Common::String resName = chP ? Common::String(chP + 1) : resourceName; + + if (_v2 != 3) { + assert(_resIndex.size() == 0); + } + + // Scan for the resource name + for (uint resIndex = 0; resIndex < _resIndex.size(); ++resIndex) { + ResIndexEntry &resEntry = _resIndex[resIndex]; + if (resEntry._resourceName.compareToIgnoreCase(resourceName)) { + foundIndex = resIndex; + break; + } + } + } + + if (foundIndex >= 0) { + // TODO + } + return -1; +} + } // End of namespace Nebular diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h index 7abe3c8892..2ffc0d6d07 100644 --- a/engines/mads/nebular/menu_nebular.h +++ b/engines/mads/nebular/menu_nebular.h @@ -230,15 +230,30 @@ enum ResyncMode { NEVER, ALWAYS, BEGINNING }; struct ResourceEntry { Common::String _resourceName; - int _sfx; + int _fx; + bool _soundFlag; + bool _bgFlag; + bool _showWhiteBars; ResourceEntry() {} - ResourceEntry(const Common::String &resName, int sfx) { + ResourceEntry(const Common::String &resName, int fx, bool soundFlag, + bool bgFlag, bool showWhiteBars) { _resourceName = resName; - _sfx = sfx; + _fx = fx; + _soundFlag = soundFlag; + _bgFlag = bgFlag; + _showWhiteBars = showWhiteBars; } }; +struct ResIndexEntry { + int _id; + int _v; + Common::String _resourceName; + + ResIndexEntry() {} +}; + /** * Animation cutscene view */ @@ -250,12 +265,30 @@ private: uint32 _previousUpdate; Common::String _currentLine; bool _soundDriverLoaded; - bool _showWhiteBars; bool _resetPalette; ResyncMode _resyncMode; int _sfx; + bool _soundFlag; + bool _bgLoadFlag; + bool _showWhiteBars; Common::Array<ResourceEntry> _resources; + Common::Array<ResIndexEntry> _resIndex; + int _v1; + int _v2; + int _resourceIndex; + SceneInfo *_sceneInfo; + Animation *_currentAnimation; + int _manualFrameNumber; + SpriteAsset *_manualSpriteSet; + int _manualStartFrame, _manualEndFrame; + int _manualFrame2; + bool _hasManual; + int _animFrameNumber; private: + void checkResource(const Common::String &resourceName); + + int scanResourceIndex(const Common::String &resourceName); + void load(); void processLines(); @@ -265,7 +298,11 @@ private: int getParameter(); void scriptDone(); + + void loadNextResource(); protected: + virtual void display(); + virtual void doFrame(); virtual bool onEvent(Common::Event &event); @@ -277,7 +314,7 @@ public: AnimationView(MADSEngine *vm); - virtual ~AnimationView() {} + virtual ~AnimationView(); }; } // End of namespace Nebular diff --git a/engines/mads/phantom/game_phantom.cpp b/engines/mads/phantom/game_phantom.cpp index ba2179fcbf..0b2531ef65 100644 --- a/engines/mads/phantom/game_phantom.cpp +++ b/engines/mads/phantom/game_phantom.cpp @@ -50,11 +50,12 @@ void GamePhantom::startGame() { } void GamePhantom::initializeGlobals() { - //int count, count2; - //int bad; - _globals.reset(); - //_globals[kTalkInanimateCount] = 8; + + warning("TODO: sub_316DA()"); + + _player._facing = FACING_NORTH; + _player._turnToFacing = FACING_NORTH; /* Section #1 variables */ // TODO @@ -74,11 +75,7 @@ void GamePhantom::initializeGlobals() { /* Section #9 variables */ // TODO - _player._facing = FACING_NORTH; - _player._turnToFacing = FACING_NORTH; - - //Player::preloadSequences("RXM", 1); - //Player::preloadSequences("ROX", 1); + Player::preloadSequences("RAL", 1); } void GamePhantom::setSectionHandler() { diff --git a/engines/mads/user_interface.h b/engines/mads/user_interface.h index f251441e40..89044c9bf1 100644 --- a/engines/mads/user_interface.h +++ b/engines/mads/user_interface.h @@ -225,7 +225,7 @@ public: /** * Loads an interface from a specified resource */ - void load(const Common::String &resName); + virtual void load(const Common::String &resName); /** * Set up the interface diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index 7cd50e1f4c..a7922b232e 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -504,12 +504,6 @@ static void computeGameSettingsFromMD5(const Common::FSList &fslist, const GameF dr.extra = "V1 Demo"; } - // HACK: If 'Demo' occurs in the extra string, set the GF_DEMO flag, - // required by some game demos (e.g. Dig, FT and COMI). - if (dr.extra && strstr(dr.extra, "Demo")) { - dr.game.features |= GF_DEMO; - } - // HACK: Try to detect languages for translated games if (dr.language == UNK_LANG) { dr.language = detectLanguage(fslist, dr.game.id); diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index ae334c201c..791963e237 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -260,13 +260,16 @@ static const GameSettings gameVariantsTable[] = { {"samnmax", "Floppy", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_GM, GF_USE_KEY, UNK, GUIO1(GUIO_NOSPEECH)}, #ifdef ENABLE_SCUMM_7_8 - {"ft", 0, 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)}, + {"ft", "", 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)}, + {"ft", "Demo", 0, GID_FT, 7, 0, MDT_NONE, GF_DEMO, UNK, GUIO1(GUIO_NOMIDI)}, - {"dig", "", 0, GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)}, + {"dig", "", 0, GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)}, + {"dig", "Demo", 0, GID_DIG, 7, 0, MDT_NONE, GF_DEMO, UNK, GUIO1(GUIO_NOMIDI)}, {"dig", "Steam", "steam", GID_DIG, 7, 0, MDT_NONE, 0, UNK, GUIO1(GUIO_NOMIDI)}, - {"comi", 0, 0, GID_CMI, 8, 0, MDT_NONE, 0, Common::kPlatformWindows, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)}, -#endif + {"comi", "", 0, GID_CMI, 8, 0, MDT_NONE, 0, Common::kPlatformWindows, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)}, + {"comi", "Demo", 0, GID_CMI, 8, 0, MDT_NONE, GF_DEMO, Common::kPlatformWindows, GUIO2(GUIO_NOMIDI, GUIO_NOASPECT)}, + #endif // Humongous Entertainment Scumm Version 6 {"activity", "", 0, GID_HEGAME, 6, 62, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO1(GUIO_NOLAUNCHLOAD)}, diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index 7919075d0b..db836467ef 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -1013,7 +1013,6 @@ void ScummEngine::resetRoomObject(ObjectData *od, const byte *room, const byte * od->actordir = (byte)READ_LE_UINT16(&imhd->v7.actordir); } else if (_game.version == 6) { - assert(imhd); od->obj_nr = READ_LE_UINT16(&(cdhd->v6.obj_id)); od->width = READ_LE_UINT16(&cdhd->v6.w); diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp index ef4a2ee025..9140bddb65 100644 --- a/engines/sword1/sound.cpp +++ b/engines/sword1/sound.cpp @@ -126,51 +126,44 @@ void Sound::checkSpeechFileEndianness() { if (sampleSize) { uint32 size; // Compute average of difference between two consecutive samples for both BE and LE - // The way uncompressSpeech works we may get un incorrect number of identical consecutive samples - // when using the wrong endianess. To avoid biasing the result we this we skip all duplicate values. _bigEndianSpeech = false; int16 *data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); - if (data) { - uint32 max_cpt = size > 2000 ? 2000 : size; - double le_diff_sum = 0.; - uint32 le_cpt = 0; - for (uint32 i = 1; i < size && le_cpt < max_cpt; ++i) { - if (data[i] != data[i-1]) { - le_diff_sum += fabs((double)(data[i] - data[i - 1])); - ++le_cpt; - } - } - le_diff_sum /= le_cpt; - delete[] data; - _bigEndianSpeech = true; - data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); - if (data) { - double be_diff_sum = 0.; - uint32 be_cpt = 0; - for (uint32 i = 1; i < size && be_cpt < le_cpt; ++i) { - if (data[i] != data[i-1]) { - be_diff_sum += fabs((double)(data[i] - data[i - 1])); - ++be_cpt; - } - } - be_diff_sum /= be_cpt; - delete [] data; - // Set the big endian flag - // uncompreesSpeech gives data in little endian, so on big endian systems the heuristic is actually reversed -#ifdef SCUMM_BIG_ENDIAN - _bigEndianSpeech = (le_diff_sum < be_diff_sum); -#else - _bigEndianSpeech = (be_diff_sum < le_diff_sum); -#endif - if (_bigEndianSpeech) - debug(6, "Mac version: using big endian speech file"); - else - debug(6, "Mac version: using little endian speech file"); - debug(8, "Speech endianness heuristic: average = %f for BE (%d samples) and %f for LE (%d samples)", be_diff_sum, be_cpt, le_diff_sum, le_cpt); - } else - _bigEndianSpeech = false; + uint32 maxSamples = size > 2000 ? 2000 : size; + double le_diff = endiannessHeuristicValue(data, size, maxSamples); + delete[] data; + _bigEndianSpeech = true; + data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); + double be_diff = endiannessHeuristicValue(data, size, maxSamples); + delete [] data; + // Set the big endian flag + _bigEndianSpeech = (be_diff < le_diff); + if (_bigEndianSpeech) + debug(6, "Mac version: using big endian speech file"); + else + debug(6, "Mac version: using little endian speech file"); + debug(8, "Speech endianness heuristic: average = %f for BE and %f for LE (%d samples)", be_diff, le_diff, maxSamples); + } +} + +double Sound::endiannessHeuristicValue(int16* data, uint32 dataSize, uint32 &maxSamples) { + if (!data) + return 50000.; // the heuristic value for the wrong endianess is about 21000 (1/3rd of the 16 bits range) + + double diff_sum = 0.; + uint32 cpt = 0; + int16 prev_value = (int16)FROM_LE_16(*((uint16 *)(data))); + for (uint32 i = 1; i < dataSize && cpt < maxSamples; ++i) { + int16 value = (int16)FROM_LE_16(*((uint16 *)(data + i))); + if (value != prev_value) { + diff_sum += fabs((double)(value - prev_value)); + ++cpt; + prev_value = value; } } + if (cpt == 0) + return 50000.; + maxSamples = cpt; + return diff_sum / cpt; } diff --git a/engines/sword1/sound.h b/engines/sword1/sound.h index 54006bd8b4..e65e797934 100644 --- a/engines/sword1/sound.h +++ b/engines/sword1/sound.h @@ -102,6 +102,7 @@ public: void engine(); void checkSpeechFileEndianness(); + double endiannessHeuristicValue(int16* data, uint32 dataSize, uint32 &maxSamples); private: uint8 _sfxVolL, _sfxVolR, _speechVolL, _speechVolR; diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp index 08ea02f32d..1e9b7f70f4 100644 --- a/engines/sword1/sword1.cpp +++ b/engines/sword1/sword1.cpp @@ -774,6 +774,8 @@ void SwordEngine::reinitRes() { _logic->newScreen(Logic::_scriptVars[NEW_SCREEN]); _sound->newScreen(Logic::_scriptVars[NEW_SCREEN]); Logic::_scriptVars[SCREEN] = Logic::_scriptVars[NEW_SCREEN]; + _logic->engine(); + _logic->updateScreenParams(); _screen->fullRefresh(); _screen->draw(); } diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp index fb83b7f941..7d68081593 100644 --- a/engines/sword25/kernel/persistenceservice.cpp +++ b/engines/sword25/kernel/persistenceservice.cpp @@ -52,7 +52,7 @@ static const uint SLOT_COUNT = 18; static const uint FILE_COPY_BUFFER_SIZE = 1024 * 10; static const char *VERSIONIDOLD = "SCUMMVM1"; static const char *VERSIONID = "SCUMMVM2"; -static const int VERSIONNUM = 2; +static const int VERSIONNUM = 3; #define MAX_SAVEGAME_SIZE 100 diff --git a/engines/sword25/util/pluto/pluto.cpp b/engines/sword25/util/pluto/pluto.cpp index fb477c1687..78b0a815e8 100644 --- a/engines/sword25/util/pluto/pluto.cpp +++ b/engines/sword25/util/pluto/pluto.cpp @@ -835,7 +835,15 @@ static void persistthread(PersistInfo *pi) #endif write_size(pi, &stackbase); write_size(pi, &stacktop); + + // ptrdiff_t changes sizes based on 32/64 bit + // Hard cast to 64 bit size if SIZE64 is defined +#ifdef SIZES64 + uint64 ptrIndex = static_cast<uint64>(L2->errfunc); + pi_write(pi, &ptrIndex, sizeof(uint64), pi->ud); +#else pi_write(pi, &L2->errfunc, sizeof(ptrdiff_t), pi->ud); +#endif //write_size(pi, (size_t *)&L2->errfunc); } @@ -944,12 +952,6 @@ static void persist(PersistInfo *pi) if(!lua_isnil(pi->L, -1)) { /* perms reftbl ... obj ref */ int zero = 0; - // FIXME: Casting a pointer to an integer data type is a bad idea we - // should really get rid of this by fixing the design of this code. - // For now casting to size_t should silence most (all?) compilers, - // since size_t is supposedly the same size as a pointer on most - // (modern) architectures. - int ref = (int)(size_t)lua_touserdata(pi->L, -1); pi_write(pi, &zero, sizeof(int), pi->ud); if (humanReadable) { snprintf(hrBuf, hrBufSize, "persist_seenobject\n"); @@ -958,7 +960,8 @@ static void persist(PersistInfo *pi) #ifdef TOTEXT printf("persist_seenobject\n"); #endif - pi_write(pi, &ref, sizeof(int), pi->ud); + int *ref = (int *)lua_touserdata(pi->L, -1); + pi_write(pi, ref, sizeof(int), pi->ud); if (humanReadable) { snprintf(hrBuf, hrBufSize, "persist_touserdata_ref %d\n", ref); hrOut(pi); @@ -1011,7 +1014,8 @@ static void persist(PersistInfo *pi) } lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ - lua_pushlightuserdata(pi->L, (void *)(++(pi->counter))); + int *ref = (int *)lua_newuserdata(pi->L, sizeof(int)); + *ref = ++(pi->counter); /* perms reftbl ... obj obj ref */ lua_rawset(pi->L, 2); /* perms reftbl ... obj */ @@ -1737,7 +1741,16 @@ static void unpersistthread(int ref, UnpersistInfo *upi) verify(LIF(Z,read)(&upi->zio, &L2->status, sizeof(lu_byte)) == 0); read_size(&upi->zio, &stackbase); read_size(&upi->zio, &stacktop); + +#ifdef SIZES64 + uint64 value; + verify(LIF(Z,read)(&upi->zio, &value, sizeof(uint64)) == 0); + + L2->errfunc = static_cast<ptrdiff_t>(value); +#else verify(LIF(Z,read)(&upi->zio, &L2->errfunc, sizeof(ptrdiff_t)) == 0); +#endif + //read_size(&upi->zio, (size_t *)&L2->errfunc); L2->base = L2->stack + stackbase; L2->top = L2->stack + stacktop; diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp index 99188c1ab6..99913d87b0 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.cpp +++ b/engines/tsage/ringworld2/ringworld2_logic.cpp @@ -355,6 +355,11 @@ SceneExt::SceneExt(): Scene() { // to make inter-scene debugging easier, I'm explicitly resetting the _animationCtr // on scene start, since scene objects aren't drawn while it's non-zero R2_GLOBALS._animationCtr = 0; + + // WORKAROUND: We had a case where at some point the number of modal dialogs + // open became incorrect. So reset it on scene changes to fix the problem if + // it ever happens + R2_GLOBALS._insetUp = 0; } void SceneExt::synchronize(Serializer &s) { |