From 68a20e2aba09dd366341ab62bbdfb05cd3f04534 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 16 Jan 2009 23:20:17 +0000 Subject: - Removed _gameVersion, engine versions are set in the game detection entries now - Renamed ProjectReader -> ResourceReader - Added some WIP code for the EGA version of the Manhole (still not working/disabled) - The resource reader now closes the files it has opened correctly when it's deleted svn-id: r35877 --- engines/made/detection.cpp | 46 ++++++++++++++------ engines/made/made.cpp | 44 ++++++++++++++----- engines/made/made.h | 8 +--- engines/made/resource.cpp | 105 ++++++++++++++++++++++++++++++++------------- engines/made/resource.h | 38 +++++++++++++--- 5 files changed, 176 insertions(+), 65 deletions(-) diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp index afc1fdd9a3..17bad6af12 100644 --- a/engines/made/detection.cpp +++ b/engines/made/detection.cpp @@ -92,7 +92,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_CD, - 0, + 3, }, { @@ -109,7 +109,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_CD_COMPRESSED, - 0, + 3, }, { @@ -125,7 +125,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_CD, - 0, + 3, }, { @@ -141,7 +141,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_CD_COMPRESSED, - 0, + 3, }, { @@ -158,7 +158,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_CD, - 0, + 3, }, { @@ -174,7 +174,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_CD_COMPRESSED, - 0, + 3, }, { @@ -192,7 +192,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_CD, - 0, + 3, }, { @@ -210,7 +210,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_CD_COMPRESSED, - 0, + 3, }, { @@ -226,7 +226,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_FLOPPY, - 0, + 3, }, { @@ -242,7 +242,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RTZ, 0, GF_DEMO, - 0, + 3, }, { @@ -258,9 +258,27 @@ static const MadeGameDescription gameDescriptions[] = { GID_MANHOLE, 0, GF_CD, - 0, + 2, }, +#if 0 + { + // The Manhole (EGA, 5.25") + { + "manhole", + "EGA", + AD_ENTRY1("manhole.dat", "2b1658292599a861c4cd3cf6cdb3c581"), + Common::EN_ANY, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GID_MANHOLE, + 0, + GF_FLOPPY, + 1, + }, +#endif + { // Leather Goddesses of Phobos 2 { @@ -274,7 +292,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_LGOP2, 0, GF_FLOPPY, - 0, + 2, }, { @@ -290,7 +308,7 @@ static const MadeGameDescription gameDescriptions[] = { GID_RODNEY, 0, GF_FLOPPY, - 0, + 2, }, { AD_TABLE_END_MARKER, 0, 0, 0, 0 } @@ -382,7 +400,7 @@ const Common::ADGameDescription *MadeMetaEngine::fallbackDetect(const Common::FS // Set default values for the fallback descriptor's MadeGameDescription part. Made::g_fallbackDesc.gameID = 0; Made::g_fallbackDesc.features = 0; - Made::g_fallbackDesc.version = 0; + Made::g_fallbackDesc.version = 3; //return (const Common::ADGameDescription *)&Made::g_fallbackDesc; return NULL; diff --git a/engines/made/made.cpp b/engines/made/made.cpp index 4baed339d5..d28f3b0bea 100644 --- a/engines/made/made.cpp +++ b/engines/made/made.cpp @@ -81,7 +81,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng _system->openCD(cd_num); _pmvPlayer = new PmvPlayer(this, _mixer); - _res = new ProjectReader(); + _res = new ResourceReader(); _screen = new Screen(this); if (getGameID() == GID_LGOP2 || getGameID() == GID_MANHOLE || getGameID() == GID_RODNEY) { @@ -107,15 +107,22 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng //_music->setAdlib(adlib); // Set default sound frequency - // Return to Zork sets it itself via a script funtion - if (getGameID() == GID_MANHOLE || getGameID() == GID_RODNEY) { + switch (getGameID()) { + case GID_RODNEY: _soundRate = 11025; - } else { + break; + case GID_MANHOLE: + _soundRate = getVersion() == 2 ? 11025 : 4000; + break; + case GID_LGOP2: _soundRate = 8000; + break; + case GID_RTZ: + // Return to Zork sets it itself via a script funtion + break; } syncSoundSettings(); - } MadeEngine::~MadeEngine() { @@ -245,7 +252,6 @@ Common::Error MadeEngine::go() { resetAllTimers(); if (getGameID() == GID_RTZ) { - _engineVersion = 3; if (getFeatures() & GF_DEMO) { _dat->open("demo.dat"); _res->open("demo.prj"); @@ -262,15 +268,17 @@ Common::Error MadeEngine::go() { error("Unknown RTZ game features"); } } else if (getGameID() == GID_MANHOLE) { - _engineVersion = 2; _dat->open("manhole.dat"); - _res->open("manhole.prj"); + + if (getVersion() == 2) { + _res->open("manhole.prj"); + } else { + _res->openResourceBlocks(); + } } else if (getGameID() == GID_LGOP2) { - _engineVersion = 2; _dat->open("lgop2.dat"); _res->open("lgop2.prj"); } else if (getGameID() == GID_RODNEY) { - _engineVersion = 2; _dat->open("rodneys.dat"); _res->open("rodneys.prj"); } else { @@ -280,6 +288,22 @@ Common::Error MadeEngine::go() { _autoStopSound = false; _eventNum = _eventKey = _eventMouseX = _eventMouseY = 0; +#if 0 + // V1 test code + if (getVersion() == 1) { + // Music test (works) + _music->playSMF(_res->getMidi(1)); + + // SFX test (not working) + Audio::SoundHandle audioStreamHandle; + SoundResource *soundRes = _res->getSound(1); + _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &audioStreamHandle, + soundRes->getAudioStream(_soundRate, false)); + + quitGame(); + } +#endif + #ifdef DUMP_SCRIPTS _script->dumpAllScripts(); #else diff --git a/engines/made/made.h b/engines/made/made.h index 297c253698..f6044f29c6 100644 --- a/engines/made/made.h +++ b/engines/made/made.h @@ -67,7 +67,7 @@ const uint32 kTimerResolution = 40; struct MadeGameDescription; -class ProjectReader; +class ResourceReader; class PmvPlayer; class Screen; class ScriptInterpreter; @@ -105,7 +105,7 @@ public: private: public: PmvPlayer *_pmvPlayer; - ProjectReader *_res; + ResourceReader *_res; Screen *_screen; GameDatabase *_dat; ScriptInterpreter *_script; @@ -120,10 +120,6 @@ public: uint _soundEnergyIndex; SoundEnergyArray *_soundEnergyArray; - // 2 = LGOP2, Manhole N&E - // 3 = Return to Zork - int _engineVersion; - int32 _timers[50]; int16 getTicks(); int16 getTimer(int16 timerNum); diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp index d549dca70f..3086e71edd 100644 --- a/engines/made/resource.cpp +++ b/engines/made/resource.cpp @@ -103,7 +103,6 @@ AnimationResource::~AnimationResource() { } void AnimationResource::load(byte *source, int size) { - Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size); sourceS->readUint32LE(); @@ -148,7 +147,6 @@ void AnimationResource::load(byte *source, int size) { } delete sourceS; - } /* SoundResource */ @@ -162,7 +160,6 @@ SoundResource::~SoundResource() { } void SoundResource::load(byte *source, int size) { - uint16 chunkCount = READ_LE_UINT16(source + 8); uint16 chunkSize = READ_LE_UINT16(source + 12); @@ -172,7 +169,6 @@ void SoundResource::load(byte *source, int size) { _soundEnergyArray = new SoundEnergyArray; decompressSound(source + 14, _soundData, chunkSize, chunkCount, _soundEnergyArray); - } Audio::AudioStream *SoundResource::getAudioStream(int soundRate, bool loop) { @@ -183,6 +179,14 @@ Audio::AudioStream *SoundResource::getAudioStream(int soundRate, bool loop) { return Audio::makeLinearInputStream(_soundData, _soundSize, soundRate, flags, 0, 0); } +void SoundResourceV1::load(byte *source, int size) { + // TODO: This is all wrong. Seems like the sound is compressed + // but where is the compression info? (chunks, chunk size) + _soundSize = size; + _soundData = new byte[_soundSize]; + memcpy(_soundData, source, _soundSize); +} + /* MenuResource */ MenuResource::MenuResource() { @@ -281,16 +285,24 @@ void GenericResource::load(byte *source, int size) { memcpy(_data, source, size); } -/* ProjectReader */ +/* ResourceReader */ -ProjectReader::ProjectReader() { +ResourceReader::ResourceReader() { + _isV1 = false; } -ProjectReader::~ProjectReader() { +ResourceReader::~ResourceReader() { + if (!_isV1) { + delete _fd; + } else { + delete _fdPics; + delete _fdSounds; + delete _fdMusic; + } } -void ProjectReader::open(const char *filename) { - +// V2 +void ResourceReader::open(const char *filename) { _fd = new Common::File(); _fd->open(filename); @@ -326,38 +338,72 @@ void ProjectReader::open(const char *filename) { } _cacheCount = 0; +} +// V1 +void ResourceReader::openResourceBlocks() { + _isV1 = true; + _fdPics = new Common::File(); + _fdSounds = new Common::File(); + _fdMusic = new Common::File(); + + openResourceBlock("pics.blk", _fdPics, kResFLEX); + openResourceBlock("snds.blk", _fdSounds, kResSNDS); + openResourceBlock("music.blk", _fdMusic, kResMIDI); } -PictureResource *ProjectReader::getPicture(int index) { +void ResourceReader::openResourceBlock(const char *filename, Common::File *blockFile, uint32 resType) { + blockFile->open(filename); + + blockFile->readUint16LE(); // Skip unused + uint16 count = blockFile->readUint16LE(); + blockFile->readUint16LE(); // Skip unused + uint32 type = blockFile->readUint32BE(); + if (type != kResFLEX) + warning("openResourceBlocks: resource header is not 'FLEX'"); + + _resSlots[resType] = new ResourceSlots(); + + for (uint16 i = 0; i < count; i++) { + uint32 offset = blockFile->readUint32LE(); + blockFile->readUint32LE(); + uint32 size = blockFile->readUint32LE(); + _resSlots[resType]->push_back(ResourceSlot(offset, size)); + } +} + +PictureResource *ResourceReader::getPicture(int index) { return createResource(kResFLEX, index); } -AnimationResource *ProjectReader::getAnimation(int index) { +AnimationResource *ResourceReader::getAnimation(int index) { return createResource(kResANIM, index); } -SoundResource *ProjectReader::getSound(int index) { - return createResource(kResSNDS, index); +SoundResource *ResourceReader::getSound(int index) { + if (!_isV1) + return createResource(kResSNDS, index); + else + return createResource(kResSNDS, index); } -MenuResource *ProjectReader::getMenu(int index) { +MenuResource *ResourceReader::getMenu(int index) { return createResource(kResMENU, index); } -FontResource *ProjectReader::getFont(int index) { +FontResource *ResourceReader::getFont(int index) { return createResource(kResFONT, index); } -GenericResource *ProjectReader::getXmidi(int index) { +GenericResource *ResourceReader::getXmidi(int index) { return createResource(kResXMID, index); } -GenericResource *ProjectReader::getMidi(int index) { +GenericResource *ResourceReader::getMidi(int index) { return createResource(kResMIDI, index); } -void ProjectReader::loadIndex(ResourceSlots *slots) { +void ResourceReader::loadIndex(ResourceSlots *slots) { _fd->readUint32LE(); // skip INDX _fd->readUint32LE(); // skip index size _fd->readUint32LE(); // skip unknown @@ -372,16 +418,17 @@ void ProjectReader::loadIndex(ResourceSlots *slots) { } } -void ProjectReader::freeResource(Resource *resource) { +void ResourceReader::freeResource(Resource *resource) { tossResourceFromCache(resource->slot); } -bool ProjectReader::loadResource(ResourceSlot *slot, byte *&buffer, uint32 &size) { +bool ResourceReader::loadResource(ResourceSlot *slot, byte *&buffer, uint32 &size) { + int offset = !_isV1 ? 62 : 0; if (slot && slot->size > 0) { - size = slot->size - 62; + size = slot->size - offset; buffer = new byte[size]; - debug(2, "ProjectReader::loadResource() %08X", slot->offs + 62); - _fd->seek(slot->offs + 62); + debug(2, "ResourceReader::loadResource() %08X", slot->offs + offset); + _fd->seek(slot->offs + offset); _fd->read(buffer, size); return true; } else { @@ -389,7 +436,7 @@ bool ProjectReader::loadResource(ResourceSlot *slot, byte *&buffer, uint32 &size } } -ResourceSlot *ProjectReader::getResourceSlot(uint32 resType, uint index) { +ResourceSlot *ResourceReader::getResourceSlot(uint32 resType, uint index) { ResourceSlots *slots = _resSlots[resType]; if (index >= 1 && index < slots->size()) { return &slots->operator[](index); @@ -398,13 +445,13 @@ ResourceSlot *ProjectReader::getResourceSlot(uint32 resType, uint index) { } } -Resource *ProjectReader::getResourceFromCache(ResourceSlot *slot) { +Resource *ResourceReader::getResourceFromCache(ResourceSlot *slot) { if (slot->res) slot->refCount++; return slot->res; } -void ProjectReader::addResourceToCache(ResourceSlot *slot, Resource *res) { +void ResourceReader::addResourceToCache(ResourceSlot *slot, Resource *res) { if (_cacheCount >= kMaxResourceCacheCount) purgeCache(); slot->res = res; @@ -412,13 +459,13 @@ void ProjectReader::addResourceToCache(ResourceSlot *slot, Resource *res) { _cacheCount++; } -void ProjectReader::tossResourceFromCache(ResourceSlot *slot) { +void ResourceReader::tossResourceFromCache(ResourceSlot *slot) { if (slot->res) slot->refCount--; } -void ProjectReader::purgeCache() { - debug(2, "ProjectReader::purgeCache()"); +void ResourceReader::purgeCache() { + debug(2, "ResourceReader::purgeCache()"); for (ResMap::const_iterator resTypeIter = _resSlots.begin(); resTypeIter != _resSlots.end(); ++resTypeIter) { ResourceSlots *slots = (*resTypeIter)._value; for (ResourceSlots::iterator slotIter = slots->begin(); slotIter != slots->end(); ++slotIter) { diff --git a/engines/made/resource.h b/engines/made/resource.h index 9151b2ad97..a57c9d5cc9 100644 --- a/engines/made/resource.h +++ b/engines/made/resource.h @@ -103,8 +103,8 @@ protected: class SoundResource : public Resource { public: SoundResource(); - ~SoundResource(); - void load(byte *source, int size); + virtual ~SoundResource(); + virtual void load(byte *source, int size); Audio::AudioStream *getAudioStream(int soundRate, bool loop = false); SoundEnergyArray *getSoundEnergyArray() const { return _soundEnergyArray; } protected: @@ -113,6 +113,13 @@ protected: SoundEnergyArray *_soundEnergyArray; }; +class SoundResourceV1 : public SoundResource { +public: + SoundResourceV1() {} + ~SoundResourceV1() {} + void load(byte *source, int size); +}; + class MenuResource : public Resource { public: MenuResource(); @@ -162,13 +169,13 @@ struct ResourceSlot { } }; -class ProjectReader { +class ResourceReader { public: - - ProjectReader(); - ~ProjectReader(); + ResourceReader(); + ~ResourceReader(); void open(const char *filename); + void openResourceBlocks(); PictureResource *getPicture(int index); AnimationResource *getAnimation(int index); @@ -183,9 +190,12 @@ public: protected: Common::File *_fd; + Common::File *_fdPics, *_fdSounds, *_fdMusic; // V1 + bool _isV1; typedef Common::Array ResourceSlots; typedef Common::HashMap ResMap; + void openResourceBlock(const char *filename, Common::File *blockFile, uint32 resType); ResMap _resSlots; int _cacheCount; @@ -201,6 +211,22 @@ protected: if (!res) { byte *buffer; uint32 size; + + // Read from the correct file for V1 games + if (_isV1) { + switch (resType) { + case kResSNDS: + _fd = _fdSounds; + break; + case kResMIDI: + _fd = _fdMusic; + break; + default: + _fd = _fdPics; + break; + } + } + if (loadResource(slot, buffer, size)) { res = new T(); res->slot = slot; -- cgit v1.2.3