From 7164016b34d86329a26c8b47ec986ff810ff7b73 Mon Sep 17 00:00:00 2001 From: Jaromir Wysoglad Date: Tue, 2 Jul 2019 20:59:32 +0200 Subject: SUPERNOVA: Refactor .dat file access --- engines/supernova/graphics.cpp | 121 ++++++---------------------------------- engines/supernova/graphics.h | 6 +- engines/supernova/resman.cpp | 42 +++++++------- engines/supernova/resman.h | 6 +- engines/supernova/supernova.cpp | 80 +++++--------------------- 5 files changed, 60 insertions(+), 195 deletions(-) (limited to 'engines/supernova') diff --git a/engines/supernova/graphics.cpp b/engines/supernova/graphics.cpp index fb248e3e81..e8b4ce1679 100644 --- a/engines/supernova/graphics.cpp +++ b/engines/supernova/graphics.cpp @@ -36,8 +36,8 @@ namespace Supernova { -MSNImage::MSNImage(int MSPart) - : _MSPart(MSPart) { +MSNImage::MSNImage(SupernovaEngine *vm) + : _vm(vm) { _palette = nullptr; _encodedImage = nullptr; _filenumber = -1; @@ -71,14 +71,14 @@ MSNImage::~MSNImage() { bool MSNImage::init(int filenumber) { Common::File file; _filenumber = filenumber; - if (_MSPart == 1) { + if (_vm->_MSPart == 1) { if (!file.open(Common::String::format("msn_data.%03d", filenumber))) { warning("Image data file msn_data.%03d could not be read!", filenumber); return false; } loadStream(file); } - else if (_MSPart == 2) { + else if (_vm->_MSPart == 2) { if (!loadFromEngineDataFile()) { if (!file.open(Common::String::format("ms2_data.%03d", filenumber))) { warning("Image data file ms2_data.%03d could not be read!", filenumber); @@ -93,125 +93,38 @@ bool MSNImage::init(int filenumber) { bool MSNImage::loadPbmFromEngineDataFile() { Common::String name; - Common::File f; - char id[5], lang[5]; - id[4] = lang[4] = '\0'; - if (_MSPart == 2) + if (_vm->_MSPart == 2) return false; if (_filenumber == 1) name = "IMG1"; else if (_filenumber == 2) name = "IMG2"; else - - return false; - if (!f.open(SUPERNOVA_DAT)) return false; - - f.read(id, 3); - if (strncmp(id, "MSN", 3) != 0) + Common::SeekableReadStream *stream = _vm->getBlockFromDatFile(name); + if (stream == nullptr) return false; - int version = f.readByte(); - if (version != SUPERNOVA_DAT_VERSION) - return false; - - Common::String cur_lang = ConfMan.get("language"); - - // Note: we don't print any warning or errors here if we cannot find the file - // or the format is not as expected. We will get those warning when reading the - // strings anyway (actually the engine will even refuse to start). - - int part; - uint32 gameBlockSize; - while (!f.eos()) { - part = f.readByte(); - gameBlockSize = f.readUint32LE(); - if (f.eos()){ - return false; - } - if (part == _MSPart) { - break; - } else - f.skip(gameBlockSize); - } - - uint32 readSize = 0; - - while (readSize < gameBlockSize) { - f.read(id, 4); - f.read(lang, 4); - uint32 size = f.readUint32LE(); - if (f.eos()) - break; - if (name == id && cur_lang == lang) { - return f.read(_encodedImage, size) == size; - } else { - f.skip(size); - readSize += size; - } - } - - return false; + stream->read(_encodedImage, stream->size()); + return true; } bool MSNImage::loadFromEngineDataFile() { Common::String name; - Common::File f; - char id[5], lang[5]; - id[4] = lang[4] = '\0'; - if (_MSPart == 1) { + if (_vm->_MSPart == 1) { return false; - } else if (_MSPart == 2) { + } else if (_vm->_MSPart == 2) { if (_filenumber == 15) name = "M015"; else if (_filenumber == 28) name = "M028"; else return false; - - if (!f.open(SUPERNOVA_DAT)) - return false; - - f.read(id, 3); - if (strncmp(id, "MSN", 3) != 0) - return false; - int version = f.readByte(); - if (version != SUPERNOVA_DAT_VERSION) - return false; } - Common::String cur_lang = ConfMan.get("language"); - - int part; - uint32 gameBlockSize; - while (!f.eos()) { - part = f.readByte(); - gameBlockSize = f.readUint32LE(); - if (f.eos()){ - return false; - } - if (part == _MSPart) { - break; - } else - f.skip(gameBlockSize); - } - - uint32 readSize = 0; - while (readSize < gameBlockSize) { - f.read(id, 4); - f.read(lang, 4); - uint32 size = f.readUint32LE(); - if (f.eos()) - break; - if (name == id && cur_lang == lang) { - return loadStream(*f.readStream(size)); - } else { - f.skip(size); - readSize += size; - } - } - - return false; + Common::SeekableReadStream *stream = _vm->getBlockFromDatFile(name); + if (stream == nullptr) + return false; + return loadStream(*stream); } bool MSNImage::loadStream(Common::SeekableReadStream &stream) { @@ -312,8 +225,8 @@ bool MSNImage::loadStream(Common::SeekableReadStream &stream) { } bool MSNImage::loadSections() { - bool isNewspaper = (_MSPart == 1 && (_filenumber == 1 || _filenumber == 2)) || - (_MSPart == 2 && _filenumber == 38); + bool isNewspaper = (_vm->_MSPart == 1 && (_filenumber == 1 || _filenumber == 2)) || + (_vm->_MSPart == 2 && _filenumber == 38); int imageWidth = isNewspaper ? 640 : 320; int imageHeight = isNewspaper ? 480 : 200; _pitch = imageWidth; diff --git a/engines/supernova/graphics.h b/engines/supernova/graphics.h index c69d650a80..060bb99fcd 100644 --- a/engines/supernova/graphics.h +++ b/engines/supernova/graphics.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "image/image_decoder.h" +#include "supernova/supernova.h" namespace Common { class SeekableReadStream; @@ -35,10 +36,11 @@ struct Surface; } namespace Supernova { +class SupernovaEngine; class MSNImage : public Image::ImageDecoder { public: - MSNImage(int MSPart); + MSNImage(SupernovaEngine *vm); virtual ~MSNImage(); virtual void destroy(); @@ -79,7 +81,7 @@ public: } _clickField[kMaxClickFields]; private: - int _MSPart; + SupernovaEngine *_vm; bool loadFromEngineDataFile(); bool loadPbmFromEngineDataFile(); bool loadSections(); diff --git a/engines/supernova/resman.cpp b/engines/supernova/resman.cpp index e827ba358c..d16cf39e1e 100644 --- a/engines/supernova/resman.cpp +++ b/engines/supernova/resman.cpp @@ -114,22 +114,22 @@ static const byte mouseWait[64] = { }; -ResourceManager::ResourceManager(int MSPart) +ResourceManager::ResourceManager(SupernovaEngine *vm) : _audioRate(11931) - , _MSPart(MSPart) { - if (MSPart == 1) + , _vm(vm) { + if (_vm->_MSPart == 1) _soundSamples = new Common::ScopedPtr[kAudioNumSamples1]; - else if (MSPart == 2) + else if (_vm->_MSPart == 2) _soundSamples = new Common::ScopedPtr[kAudioNumSamples2]; initGraphics(); } ResourceManager::~ResourceManager() { - if (_MSPart == 1) { + if (_vm->_MSPart == 1) { for (int i = 0; i < 44; i++) delete _images[i]; } - if (_MSPart == 2) { + if (_vm->_MSPart == 2) { for (int i = 0; i < 47; i++) delete _images[i]; } @@ -140,9 +140,9 @@ ResourceManager::~ResourceManager() { void ResourceManager::initGraphics() { Screen::initPalette(); initCursorGraphics(); - if (_MSPart == 1) + if (_vm->_MSPart == 1) initImages1(); - else if (_MSPart == 2) + else if (_vm->_MSPart == 2) initImages2(); } @@ -238,18 +238,18 @@ void ResourceManager::loadSound2(AudioId id) { } void ResourceManager::loadImage(int filenumber) { - if (_MSPart == 1) { + if (_vm->_MSPart == 1) { if (filenumber < 44) { - _images[filenumber] = new MSNImage(_MSPart); + _images[filenumber] = new MSNImage(_vm); if (!_images[filenumber]->init(filenumber)) error("Failed reading image file msn_data.%03d", filenumber); } else { - _images[44] = new MSNImage(_MSPart); + _images[44] = new MSNImage(_vm); if (!_images[44]->init(filenumber)) error("Failed reading image file msn_data.%03d", filenumber); } - } else if (_MSPart == 2) { - _images[filenumber] = new MSNImage(_MSPart); + } else if (_vm->_MSPart == 2) { + _images[filenumber] = new MSNImage(_vm); if (!_images[filenumber]->init(filenumber)) error("Failed reading image file ms2_data.%03d", filenumber); } @@ -257,9 +257,9 @@ void ResourceManager::loadImage(int filenumber) { Audio::SeekableAudioStream *ResourceManager::getSoundStream(AudioId index) { if (!_soundSamples[index]) { - if (_MSPart == 1) + if (_vm->_MSPart == 1) loadSound1(index); - else if (_MSPart == 2) + else if (_vm->_MSPart == 2) loadSound2(index); } Audio::SeekableAudioStream *stream; @@ -273,9 +273,9 @@ Audio::AudioStream *ResourceManager::getSoundStream(MusicId index) { switch (index) { case kMusicIntro: if (!_musicIntroBuffer) { - if (_MSPart == 1) + if (_vm->_MSPart == 1) _musicIntroBuffer.reset(convertToMod("msn_data.052", 1)); - else if (_MSPart == 2) + else if (_vm->_MSPart == 2) _musicIntroBuffer.reset(convertToMod("ms2_data.052", 2)); } _musicIntro.reset(Audio::makeProtrackerStream(_musicIntroBuffer.get())); @@ -284,9 +284,9 @@ Audio::AudioStream *ResourceManager::getSoundStream(MusicId index) { // fall through case kMusicOutro: if (!_musicOutroBuffer) { - if (_MSPart == 1) + if (_vm->_MSPart == 1) _musicOutroBuffer.reset(convertToMod("msn_data.049", 1)); - else if (_MSPart == 2) + else if (_vm->_MSPart == 2) _musicOutroBuffer.reset(convertToMod("ms2_data.056", 2)); } _musicOutro.reset(Audio::makeProtrackerStream(_musicOutroBuffer.get())); @@ -304,9 +304,9 @@ Audio::AudioStream *ResourceManager::getSirenStream() { MSNImage *ResourceManager::getImage(int filenumber) { //check array boundaries - if (_MSPart == 1 && filenumber > 43 && filenumber != 55) + if (_vm->_MSPart == 1 && filenumber > 43 && filenumber != 55) return nullptr; - if (_MSPart == 2 && filenumber > 46) + if (_vm->_MSPart == 2 && filenumber > 46) return nullptr; if (filenumber == 55) { diff --git a/engines/supernova/resman.h b/engines/supernova/resman.h index 9a4f739dea..5fbb3cd973 100644 --- a/engines/supernova/resman.h +++ b/engines/supernova/resman.h @@ -29,6 +29,7 @@ #include "supernova/graphics.h" #include "supernova/sound.h" +#include "supernova/supernova.h" namespace Common { @@ -36,6 +37,7 @@ class MemoryReadStream; } namespace Supernova { +class SupernovaEngine; class ResourceManager { public: @@ -49,7 +51,7 @@ public: static const int kNumImageFiles2 = 47; public: - ResourceManager(int MSPart); + ResourceManager(SupernovaEngine *vm); ~ResourceManager(); Audio::SeekableAudioStream *getSoundStream(AudioId index); @@ -77,7 +79,7 @@ private: Common::ScopedPtr _musicIntro; Common::ScopedPtr _musicOutro; Common::ScopedPtr _sirenStream; - int _MSPart; + SupernovaEngine *_vm; int _audioRate; MSNImage **_images; byte _cursorNormal[256]; diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp index 16569cf83a..10a460a7e7 100644 --- a/engines/supernova/supernova.cpp +++ b/engines/supernova/supernova.cpp @@ -148,7 +148,7 @@ void SupernovaEngine::init() { if (status.getCode() != Common::kNoError) error("Failed reading game strings"); - _resMan = new ResourceManager(_MSPart); + _resMan = new ResourceManager(this); _sound = new Sound(_mixer, _resMan); _screen = new Screen(this, _resMan); if (_MSPart == 1) @@ -185,78 +185,26 @@ void SupernovaEngine::pauseEngineIntern(bool pause) { } Common::Error SupernovaEngine::loadGameStrings() { - Common::String cur_lang = ConfMan.get("language"); Common::String string_id("TEXT"); - // Note: we don't print any warning or errors here if we cannot find the file - // or the format is not as expected. We will get those warning when reading the - // strings anyway (actually the engine will even refuse to start). - + Common::SeekableReadStream *stream = getBlockFromDatFile(string_id); - // Validate the data file header - Common::File f; - char id[5], lang[5]; - id[4] = lang[4] = '\0'; - if (!f.open(SUPERNOVA_DAT)) { - GUIErrorMessageFormat(_("Unable to locate the '%s' engine data file."), SUPERNOVA_DAT); - return Common::kReadingFailed; - } - f.read(id, 3); - if (strncmp(id, "MSN", 3) != 0) { - GUIErrorMessageFormat(_("The '%s' engine data file is corrupt."), SUPERNOVA_DAT); + if (stream == nullptr) { + Common::Language l = Common::parseLanguage(ConfMan.get("language")); + GUIErrorMessageFormat(_("Unable to locate the text for %s language in engine data file."), Common::getLanguageDescription(l)); return Common::kReadingFailed; } - int version = f.readByte(); - if (version != SUPERNOVA_DAT_VERSION) { - GUIErrorMessageFormat( - _("Incorrect version of the '%s' engine data file found. Expected %d but got %d."), - SUPERNOVA_DAT, SUPERNOVA_DAT_VERSION, version); - return Common::kReadingFailed; + int size = stream->size(); + while (size > 0) { + Common::String s; + char ch; + while ((ch = (char)stream->readByte()) != '\0') + s += ch; + _gameStrings.push_back(s); + size -= s.size() + 1; } - - int part; - uint32 gameBlockSize; - while (!f.eos()) { - part = f.readByte(); - gameBlockSize = f.readUint32LE(); - if (f.eos()){ - GUIErrorMessageFormat(_("Unable to find block for part %d"), _MSPart); - return Common::kReadingFailed; - } - if (part == _MSPart) { - break; - } else - f.skip(gameBlockSize); - } - - uint32 readSize = 0; - - while (readSize < gameBlockSize) { - f.read(id, 4); - f.read(lang, 4); - uint32 size = f.readUint32LE(); - if (f.eos()) - break; - if (string_id == id && cur_lang == lang) { - while (size > 0) { - Common::String s; - char ch; - while ((ch = (char)f.readByte()) != '\0') - s += ch; - _gameStrings.push_back(s); - size -= s.size() + 1; - } - return Common::kNoError; - } else { - f.skip(size); - readSize += size; - } - } - - Common::Language l = Common::parseLanguage(cur_lang); - GUIErrorMessageFormat(_("Unable to locate the text for %s language in engine data file."), Common::getLanguageDescription(l)); - return Common::kReadingFailed; + return Common::kNoError; } const Common::String &SupernovaEngine::getGameString(int idx) const { -- cgit v1.2.3