diff options
author | Paul Gilbert | 2012-02-24 19:38:46 +1100 |
---|---|---|
committer | Paul Gilbert | 2012-02-24 19:38:46 +1100 |
commit | eba87458d399382e639d81e91d6acb3ce13f2252 (patch) | |
tree | 795f6fe6d7886f34b2b5aa9fae12376dfaedf207 | |
parent | 54c87f20e344568bc1dedebcc0706b2151f94076 (diff) | |
download | scummvm-rg350-eba87458d399382e639d81e91d6acb3ce13f2252.tar.gz scummvm-rg350-eba87458d399382e639d81e91d6acb3ce13f2252.tar.bz2 scummvm-rg350-eba87458d399382e639d81e91d6acb3ce13f2252.zip |
TSAGE: More properly implemented resource streaming for R2R animation player
-rw-r--r-- | engines/tsage/resources.cpp | 154 | ||||
-rw-r--r-- | engines/tsage/resources.h | 9 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_logic.cpp | 87 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_logic.h | 32 | ||||
-rw-r--r-- | engines/tsage/ringworld2/ringworld2_scenes0.cpp | 10 |
5 files changed, 204 insertions, 88 deletions
diff --git a/engines/tsage/resources.cpp b/engines/tsage/resources.cpp index f6f870be20..0afae0042f 100644 --- a/engines/tsage/resources.cpp +++ b/engines/tsage/resources.cpp @@ -166,37 +166,7 @@ void TLib::loadSection(uint32 fileOffset) { _file.seek(fileOffset); _sections.fileOffset = fileOffset; - loadSection(_file, _resources); -} - -/** - * Inner logic for decoding a section index into a passed resource list object - */ -void TLib::loadSection(Common::File &f, ResourceList &resources) { - if (f.readUint32BE() != 0x544D492D) - error("Data block is not valid Rlb data"); - - /*uint8 unknown1 = */f.readByte(); - uint16 numEntries = f.readByte(); - - for (uint i = 0; i < numEntries; ++i) { - uint16 id = f.readUint16LE(); - uint16 size = f.readUint16LE(); - uint16 uncSize = f.readUint16LE(); - uint8 sizeHi = f.readByte(); - uint8 type = f.readByte() >> 5; - assert(type <= 1); - uint32 offset = f.readUint32LE(); - - ResourceEntry re; - re.id = id; - re.fileOffset = offset; - re.isCompressed = type != 0; - re.size = ((sizeHi & 0xF) << 16) | size; - re.uncompressedSize = ((sizeHi & 0xF0) << 12) | uncSize; - - resources.push_back(re); - } + ResourceManager::loadSection(_file, _resources); } struct DecodeReference { @@ -342,6 +312,40 @@ byte *TLib::getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool return getResource(rlbNum, suppressErrors); } +/** + * Gets the offset of the start of a resource in the resource file + */ +uint32 TLib::getResourceStart(ResourceType resType, uint16 resNum, uint16 rlbNum, ResourceEntry &entry) { + // Find the correct section + SectionList::iterator i = _sections.begin(); + while ((i != _sections.end()) && ((*i).resType != resType || (*i).resNum != resNum)) + ++i; + if (i == _sections.end()) { + error("Unknown resource type %d num %d", resType, resNum); + } + + // Load in the section index + loadSection((*i).fileOffset); + + // Scan for an entry for the given Id + ResourceEntry *re = NULL; + ResourceList::iterator iter; + for (iter = _resources.begin(); iter != _resources.end(); ++iter) { + if ((*iter).id == rlbNum) { + re = &(*iter); + break; + } + } + + // Throw an error if no resource was found, or the resource is compressed + if (!re || re->isCompressed) + error("Invalid resource Id #%d", rlbNum); + + // Return the resource entry as well as the file offset + entry = *re; + return _sections.fileOffset + entry.fileOffset; +} + void TLib::loadIndex() { uint16 resNum, configId, fileOffset; @@ -453,36 +457,6 @@ bool TLib::getMessage(int resNum, int lineNum, Common::String &result, bool supp /*--------------------------------------------------------------------------*/ -/** - * Open up the main resource file and get an entry from the root section - */ -bool TLib::getSectionEntry(Common::File &f, ResourceType resType, int rlbNum, int resNum, - ResourceEntry &resEntry) { - // Try and open the resource file - if (!f.open(_filename)) - return false; - - // Load the root section index - ResourceList resList; - loadSection(f, resList); - - // Loop through the index for the desired entry - ResourceList::iterator iter; - for (iter = _resources.begin(); iter != _resources.end(); ++iter) { - ResourceEntry &re = *iter; - if (re.id == resNum) { - // Found it, so exit - resEntry = re; - return true; - } - } - - // No matching entry found - return false; -} - -/*--------------------------------------------------------------------------*/ - ResourceManager::~ResourceManager() { for (uint idx = 0; idx < _libList.size(); ++idx) delete _libList[idx]; @@ -557,4 +531,62 @@ Common::String ResourceManager::getMessage(int resNum, int lineNum, bool suppres return Common::String(); } +/*--------------------------------------------------------------------------*/ + +/** + * Open up the given resource file using a passed file object. If the desired entry is found + * in the index, return the index entry for it, and move the file to the start of the resource + */ +bool ResourceManager::scanIndex(Common::File &f, ResourceType resType, int rlbNum, int resNum, + ResourceEntry &resEntry) { + // Load the root section index + ResourceList resList; + loadSection(f, resList); + + // Loop through the index for the desired entry + ResourceList::iterator iter; + for (iter = resList.begin(); iter != resList.end(); ++iter) { + ResourceEntry &re = *iter; + if (re.id == resNum) { + // Found it, so exit + resEntry = re; + f.seek(re.fileOffset); + return true; + } + } + + // No matching entry found + return false; +} + +/** + * Inner logic for decoding a section index into a passed resource list object + */ +void ResourceManager::loadSection(Common::File &f, ResourceList &resources) { + if (f.readUint32BE() != 0x544D492D) + error("Data block is not valid Rlb data"); + + /*uint8 unknown1 = */f.readByte(); + uint16 numEntries = f.readByte(); + + for (uint i = 0; i < numEntries; ++i) { + uint16 id = f.readUint16LE(); + uint16 size = f.readUint16LE(); + uint16 uncSize = f.readUint16LE(); + uint8 sizeHi = f.readByte(); + uint8 type = f.readByte() >> 5; + assert(type <= 1); + uint32 offset = f.readUint32LE(); + + ResourceEntry re; + re.id = id; + re.fileOffset = offset; + re.isCompressed = type != 0; + re.size = ((sizeHi & 0xF) << 16) | size; + re.uncompressedSize = ((sizeHi & 0xF0) << 12) | uncSize; + + resources.push_back(re); + } +} + } // end of namespace TsAGE diff --git a/engines/tsage/resources.h b/engines/tsage/resources.h index 2b5561b184..45cecf8521 100644 --- a/engines/tsage/resources.h +++ b/engines/tsage/resources.h @@ -150,19 +150,19 @@ private: SectionList _sections; void loadSection(uint32 fileOffset); - void loadSection(Common::File &f, ResourceList &resources); void loadIndex(); public: TLib(MemoryManager &memManager, const Common::String &filename); ~TLib(); + const Common::String &getFilename() { return _filename; } + const SectionList &getSections() { return _sections; } byte *getResource(uint16 id, bool suppressErrors = false); byte *getResource(ResourceType resType, uint16 resNum, uint16 rlbNum, bool suppressErrors = false); + uint32 getResourceStart(ResourceType resType, uint16 resNum, uint16 rlbNum, ResourceEntry &entry); bool getPalette(int paletteNum, byte *palData, uint *startNum, uint *numEntries); byte *getSubResource(int resNum, int rlbNum, int index, uint *size, bool suppressErrors = false); bool getMessage(int resNum, int lineNum, Common::String &result, bool suppressErrors = false); - - bool getSectionEntry(Common::File &f, ResourceType resType, int rlbNum, int resNum, ResourceEntry &resEntry); }; class ResourceManager { @@ -179,6 +179,9 @@ public: byte *getSubResource(int resNum, int rlbNum, int index, uint *size, bool suppressErrors = false); Common::String getMessage(int resNum, int lineNum, bool suppressErrors = false); TLib &first() { return **_libList.begin(); } + + static bool scanIndex(Common::File &f, ResourceType resType, int rlbNum, int resNum, ResourceEntry &resEntry); + static void loadSection(Common::File &f, ResourceList &resources); }; diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp index 89cf831088..d5cbde81be 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.cpp +++ b/engines/tsage/ringworld2/ringworld2_logic.cpp @@ -1551,6 +1551,27 @@ void Scene1200::sub9DAD6(int indx) { /*--------------------------------------------------------------------------*/ +void AnimationPlayerSubData::load(Common::File &f) { + f.skip(6); + _field6 = f.readUint16LE(); + f.skip(2); + _fieldA = f.readUint16LE(); + _fieldC = f.readUint16LE(); + f.skip(4); + _field12 = f.readUint16LE(); + _field14 = f.readUint16LE(); + _field16 = f.readUint16LE(); + f.skip(4); + _palStart = f.readUint16LE(); + _palSize = f.readUint16LE(); + f.read(_palData, 768); + _field320 = f.readSint32LE(); + f.skip(12); + f.read(_field330, 96); +} + +/*--------------------------------------------------------------------------*/ + AnimationPlayer::AnimationPlayer(): EventHandler() { _endAction = NULL; @@ -1586,7 +1607,7 @@ void AnimationPlayer::remove() { void AnimationPlayer::process(Event &event) { if ((event.eventType == EVENT_KEYPRESS) && (event.kbd.keycode == Common::KEYCODE_ESCAPE) && (_field3A)) { - _field90C = _field576; + _field90C = _subData._field6; } } @@ -1595,9 +1616,9 @@ void AnimationPlayer::dispatch() { uint32 gameDiff = (gameFrame > _gameFrame) ? gameFrame - _gameFrame : _gameFrame - gameFrame; if (gameDiff >= _field910) { - drawFrame(_field904 % _field57C); + drawFrame(_field904 % _subData._fieldC); ++_field904; - _field90C = _field904 / _field57C; + _field90C = _field904 / _subData._fieldC; if (_field90C == _field90E) method2(); @@ -1607,18 +1628,63 @@ void AnimationPlayer::dispatch() { } } -bool AnimationPlayer::load(int rlbNum, Action *endAction) { - ResourceEntry resEntry; - if (!g_resourceManager->first().getSectionEntry(_resourceFile, RES_IMAGE, rlbNum, 0, resEntry)) { - warning("Couldn't find resource index"); - // TODO: Complete animation loading +bool AnimationPlayer::load(int animId, Action *endAction) { + // Open up the main resource file for access + TLib &libFile = g_resourceManager->first(); + if (!_resourceFile.open(libFile.getFilename())) + error("Could not open resource"); + + // Get the offset of the given resource and seek to it in the player's file reference + ResourceEntry entry; + uint32 fileOffset = libFile.getResourceStart(RES_IMAGE, animId, 0, entry); + _resourceFile.seek(fileOffset); + + // At this point, the file is pointing to the start of the resource data + + // Set the end action + _endAction = endAction; + + // Load the sub data block + _subData.load(_resourceFile); + + // Set other properties + _field908 = -1; + _field904 = 0; + _field910 = 60 / _subData._fieldA; + _gameFrame = R2_GLOBALS._events.getFrameNumber() - _field910; + + if (_subData._field320) { + _field900 = _subData._field320; + } else { + int v = (_subData._field12 + 2) * _subData._field14 * _subData._fieldC; + _field900 = (_subData._field16 / _subData._fieldC) + v + 96; } + + _animData = _fieldA = new byte[_field900]; + + if (_subData._fieldC <= 1) { + _subData._field16 = NULL; + _animPtr = _animData; + } else { + _field16 = new byte[_field900]; + _animPtr = _field16; + } + + _field90C = 0; + _field90E = 1; + + // TODO: Stuff + + if (_field3C) { + + } + - _resourceFile.close(); return false; } void AnimationPlayer::drawFrame(int frameIndex) { +/* uint32 v = READ_LE_UINT32(_dataP); warning("v = %d", v); //TODO @@ -1634,6 +1700,7 @@ warning("v = %d", v); R2_GLOBALS._scenePalette.refresh(); } } +*/ } void AnimationPlayer::method2() { @@ -1641,7 +1708,7 @@ void AnimationPlayer::method2() { } bool AnimationPlayer::method3() { - return (_field90C >= _field576); + return (_field90C >= _subData._field6); } void AnimationPlayer::method4() { diff --git a/engines/tsage/ringworld2/ringworld2_logic.h b/engines/tsage/ringworld2/ringworld2_logic.h index 98fcaae981..651cfec763 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.h +++ b/engines/tsage/ringworld2/ringworld2_logic.h @@ -325,24 +325,38 @@ public: virtual Common::String getClassName() { return "UnkObject1200"; } }; +class AnimationPlayerSubData { +public: + int _field6; + int _fieldA; + int _fieldC; + int _field12; + int _field14; + int _field16; + int _palStart; + int _palSize; + byte _palData[256 * 3]; + int32 _field320; + byte _field330[96]; +public: + void load(Common::File &f); +}; + class AnimationPlayer: public EventHandler { public: + byte *_fieldA; + byte *_field16; + byte *_animData, *_animPtr; Common::File _resourceFile; - void *_fieldA; - void *_field16; - - byte *_dataP; Rect _rect1, _screenBounds; int _field38; int _field3A, _field3C; int _field56; int _field58, _field5A; ScenePalette _palette; - byte _palData[256 * 3]; + AnimationPlayerSubData _subData; Action *_endAction; - int _field576; - int _field57C; - int _palStart, _palSize; + int _field900; int _field904; int _field908; int _field90C; @@ -361,7 +375,7 @@ public: virtual void changePane() {} virtual void proc14() {} - bool load(int rlbNum, Action *endAction = NULL); + bool load(int animId, Action *endAction = NULL); void drawFrame(int frameIndex); void method2(); bool method3(); diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp index dab9afb269..9af4c7b534 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp @@ -1561,7 +1561,7 @@ void Scene180::signal() { R2_GLOBALS._scene180Mode = 1; _animationPlayer.load(1, NULL); - R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._palData, 0, 256); + R2_GLOBALS._scenePalette.loadPalette(_animationPlayer._subData._palData, 0, 256); R2_GLOBALS._sound1.play(1); break; @@ -1605,7 +1605,7 @@ void Scene180::signal() { _animationPlayer.load(2); _field412 = 1; - R2_GLOBALS._scenePalette.addFader(_animationPlayer._palData, 256, 6, NULL); + R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 6, NULL); R2_GLOBALS._sound1.play(2); break; @@ -1806,7 +1806,7 @@ void Scene180::signal() { R2_GLOBALS._scene180Mode = 4; if (_animationPlayer.load(4)) { _animationPlayer.dispatch(); - R2_GLOBALS._scenePalette.addFader(_animationPlayer._palData, 256, 8, this); + R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 8, this); } else { _sceneMode = 43; setFrameInc(1); @@ -1834,7 +1834,7 @@ void Scene180::signal() { break; case 45: - R2_GLOBALS._scenePalette.addFader(_animationPlayer._palData, 256, 28, this); + R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 28, this); break; case 48: @@ -1846,7 +1846,7 @@ void Scene180::signal() { _animationPlayer.load(15, NULL); R2_GLOBALS._sound1.play(9); - R2_GLOBALS._scenePalette.addFader(_animationPlayer._palData, 256, 6, NULL); + R2_GLOBALS._scenePalette.addFader(_animationPlayer._subData._palData, 256, 6, NULL); break; case 49: |