mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 14:18:37 +00:00
SUPERNOVA: Refactor .dat file access
This commit is contained in:
parent
0e31a6163d
commit
7164016b34
@ -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))
|
||||
Common::SeekableReadStream *stream = _vm->getBlockFromDatFile(name);
|
||||
if (stream == nullptr)
|
||||
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");
|
||||
|
||||
// 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;
|
||||
|
@ -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();
|
||||
|
@ -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<Audio::SeekableAudioStream>[kAudioNumSamples1];
|
||||
else if (MSPart == 2)
|
||||
else if (_vm->_MSPart == 2)
|
||||
_soundSamples = new Common::ScopedPtr<Audio::SeekableAudioStream>[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) {
|
||||
|
@ -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<Audio::AudioStream> _musicIntro;
|
||||
Common::ScopedPtr<Audio::AudioStream> _musicOutro;
|
||||
Common::ScopedPtr<Audio::AudioStream> _sirenStream;
|
||||
int _MSPart;
|
||||
SupernovaEngine *_vm;
|
||||
int _audioRate;
|
||||
MSNImage **_images;
|
||||
byte _cursorNormal[256];
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user