aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2012-02-24 19:38:46 +1100
committerPaul Gilbert2012-02-24 19:38:46 +1100
commiteba87458d399382e639d81e91d6acb3ce13f2252 (patch)
tree795f6fe6d7886f34b2b5aa9fae12376dfaedf207
parent54c87f20e344568bc1dedebcc0706b2151f94076 (diff)
downloadscummvm-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.cpp154
-rw-r--r--engines/tsage/resources.h9
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp87
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.h32
-rw-r--r--engines/tsage/ringworld2/ringworld2_scenes0.cpp10
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: