mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 14:51:40 +00:00
GRIM: Make KeyFrame load from a stream instead of a data Block
This commit is contained in:
parent
49071ee661
commit
5ca6e3f9e1
@ -30,63 +30,79 @@
|
||||
#include "engines/grim/colormap.h"
|
||||
#include "engines/grim/resource.h"
|
||||
#include "engines/grim/model.h"
|
||||
#include "common/memstream.h"
|
||||
|
||||
namespace Grim {
|
||||
|
||||
KeyframeAnim::KeyframeAnim(const Common::String &fname, const char *data, int len) :
|
||||
KeyframeAnim::KeyframeAnim(const Common::String &fname, Common::SeekableReadStream *data) :
|
||||
Object(), _fname(fname) {
|
||||
|
||||
if (len >= 4 && READ_BE_UINT32(data) == MKTAG('F','Y','E','K'))
|
||||
loadBinary(data, len);
|
||||
uint32 tag = data->readUint32BE();
|
||||
if (tag == MKTAG('F','Y','E','K'))
|
||||
loadBinary(data);
|
||||
else {
|
||||
Common::SeekableReadStream *st = new Common::MemoryReadStream((byte*)data, len);
|
||||
TextSplitter ts(st);
|
||||
data->seek(0, SEEK_SET);
|
||||
TextSplitter ts(data);
|
||||
loadText(ts);
|
||||
}
|
||||
delete data;
|
||||
}
|
||||
|
||||
void KeyframeAnim::loadBinary(const char *data, int len) {
|
||||
void KeyframeAnim::loadBinary(Common::SeekableReadStream *data) {
|
||||
// First four bytes are the FYEK Keyframe identifier code
|
||||
// Next 36 bytes are the filename
|
||||
Debug::debug(Debug::Keyframes, "Loading Keyframe '%s'.", _fname.c_str());
|
||||
// Next four bytes are the flags
|
||||
_flags = READ_LE_UINT32(data + 40);
|
||||
data->seek(40, SEEK_SET);
|
||||
_flags = data->readUint32LE();
|
||||
// Next four bytes are a duplicate of _numJoints (?)
|
||||
// Next four bytes are the type
|
||||
_type = READ_LE_UINT32(data + 48);
|
||||
data->readUint32LE();
|
||||
_type = data->readUint32LE();
|
||||
// Next four bytes are the frames per second
|
||||
// The fps value seems to be ignored and causes the animation the first time manny
|
||||
// enters the kitchen of the Blue Casket to go out of sync. So we force it to 15.
|
||||
// _fps = get_float(data + 52);
|
||||
_fps = 15.;
|
||||
// Next four bytes are the number of frames
|
||||
_numFrames = READ_LE_UINT32(data + 56);
|
||||
data->seek(56, SEEK_SET);
|
||||
_numFrames = data->readUint32LE();
|
||||
// Next four bytes are the number of joints
|
||||
_numJoints = READ_LE_UINT32(data + 60);
|
||||
_numJoints = data->readUint32LE();
|
||||
// Next four bytes are unknown (?)
|
||||
// Next four bytes are the number of markers
|
||||
_numMarkers = READ_LE_UINT32(data + 68);
|
||||
data->readUint32LE();
|
||||
_numMarkers = data->readUint32LE();
|
||||
_markers = new Marker[_numMarkers];
|
||||
data->seek(72, SEEK_SET);
|
||||
for (int i = 0; i < _numMarkers; i++) {
|
||||
_markers[i].frame = get_float(data + 72 + 4 * i);
|
||||
_markers[i].val = READ_LE_UINT32(data + 104 + 4 * i);
|
||||
char f[4];
|
||||
data->read(f, 4);
|
||||
_markers[i].frame = get_float(f);
|
||||
}
|
||||
|
||||
data->seek(104, SEEK_SET);
|
||||
for (int i = 0; i < _numMarkers; i++)
|
||||
_markers[i].val = data->readUint32LE();
|
||||
|
||||
_nodes = new KeyframeNode *[_numJoints];
|
||||
for (int i = 0; i < _numJoints; i++)
|
||||
_nodes[i] = NULL;
|
||||
const char *dataEnd = data + len;
|
||||
// The first 136 bytes are for the header, this was originally
|
||||
// listed as 180 bytes since the first operation is usually a
|
||||
// "null" key, however ma_card_hold.key showed that this is
|
||||
// not always the case so we should not skip this operation
|
||||
data += 136;
|
||||
while (data < dataEnd) {
|
||||
data->seek(136, SEEK_SET);
|
||||
for (int i = 0; i < _numJoints; i++) {
|
||||
_nodes[i] = NULL;
|
||||
int nodeNum;
|
||||
// The first 32 bytes (of a keyframe) are the name handle
|
||||
char nameHandle[32];
|
||||
data->read(nameHandle, 32);
|
||||
// If the name handle is entirely null (like ma_rest.key)
|
||||
// then we shouldn't try to set the name
|
||||
if(nameHandle[0] == 0)
|
||||
memcpy(nameHandle, "(null)", 7);
|
||||
|
||||
// The next four bytes are the node number identifier
|
||||
nodeNum = READ_LE_UINT32(data + 32);
|
||||
nodeNum = data->readUint32LE();
|
||||
|
||||
// Because of the issue above ma_card_hold.key used to crash
|
||||
// at this part without checking to make sure nodeNum is a
|
||||
@ -99,11 +115,11 @@ void KeyframeAnim::loadBinary(const char *data, int len) {
|
||||
}
|
||||
if (_nodes[nodeNum]) {
|
||||
// Null node. Usually 7, 13 and 27 are null nodes.
|
||||
data += 44;
|
||||
data->seek(8, SEEK_CUR);
|
||||
continue;
|
||||
}
|
||||
_nodes[nodeNum] = new KeyframeNode;
|
||||
_nodes[nodeNum]->loadBinary(data);
|
||||
_nodes[nodeNum] = new KeyframeNode();
|
||||
_nodes[nodeNum]->loadBinary(data, nameHandle);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,7 +198,7 @@ int KeyframeAnim::getMarker(float startTime, float stopTime) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KeyframeAnim::KeyframeEntry::loadBinary(const char *&data) {
|
||||
void KeyframeAnim::KeyframeEntry::loadBinary(const char *data) {
|
||||
_frame = get_float(data);
|
||||
_flags = READ_LE_UINT32(data + 4);
|
||||
_pos = Math::Vector3d::get_vector3d(data + 8);
|
||||
@ -193,21 +209,19 @@ void KeyframeAnim::KeyframeEntry::loadBinary(const char *&data) {
|
||||
_dpitch = get_float(data + 44);
|
||||
_dyaw = get_float(data + 48);
|
||||
_droll = get_float(data + 52);
|
||||
data += 56;
|
||||
}
|
||||
|
||||
void KeyframeAnim::KeyframeNode::loadBinary(const char *&data) {
|
||||
// If the name handle is entirely null (like ma_rest.key)
|
||||
// then we shouldn't try to set the name
|
||||
if (READ_LE_UINT32(data) == 0)
|
||||
memcpy(_meshName, "(null)", 7);
|
||||
else
|
||||
memcpy(_meshName, data, 32);
|
||||
_numEntries = READ_LE_UINT32(data + 36);
|
||||
data += 44;
|
||||
void KeyframeAnim::KeyframeNode::loadBinary(Common::SeekableReadStream *data, char *meshName) {
|
||||
memcpy(_meshName, meshName, 32);
|
||||
|
||||
_numEntries = data->readUint32LE();
|
||||
data->seek(4, SEEK_CUR);
|
||||
_entries = new KeyframeEntry[_numEntries];
|
||||
for (int i = 0; i < _numEntries; i++)
|
||||
_entries[i].loadBinary(data);
|
||||
char kfEntry[56];
|
||||
for (int i = 0; i < _numEntries; i++) {
|
||||
data->read(kfEntry, 56);
|
||||
_entries[i].loadBinary(kfEntry);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeAnim::KeyframeNode::loadText(TextSplitter &ts) {
|
||||
|
@ -27,6 +27,10 @@
|
||||
|
||||
#include "engines/grim/object.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
}
|
||||
|
||||
namespace Grim {
|
||||
|
||||
class ModelNode;
|
||||
@ -34,10 +38,10 @@ class TextSplitter;
|
||||
|
||||
class KeyframeAnim : public Object {
|
||||
public:
|
||||
KeyframeAnim(const Common::String &filename, const char *data, int len);
|
||||
KeyframeAnim(const Common::String &filename, Common::SeekableReadStream *data);
|
||||
~KeyframeAnim();
|
||||
|
||||
void loadBinary(const char *data, int len);
|
||||
void loadBinary(Common::SeekableReadStream *data);
|
||||
void loadText(TextSplitter &ts);
|
||||
bool animate(ModelNode *nodes, int num, float time, float fade, bool tagged) const;
|
||||
int getMarker(float startTime, float stopTime) const;
|
||||
@ -66,7 +70,7 @@ private:
|
||||
Marker *_markers;
|
||||
|
||||
struct KeyframeEntry {
|
||||
void loadBinary(const char *&data);
|
||||
void loadBinary(const char *data);
|
||||
|
||||
float _frame;
|
||||
int _flags;
|
||||
@ -75,7 +79,7 @@ private:
|
||||
};
|
||||
|
||||
struct KeyframeNode {
|
||||
void loadBinary(const char *&data);
|
||||
void loadBinary(Common::SeekableReadStream *data, char *meshName);
|
||||
void loadText(TextSplitter &ts);
|
||||
~KeyframeNode();
|
||||
|
||||
|
@ -279,15 +279,13 @@ Font *ResourceLoader::loadFont(const Common::String &filename) {
|
||||
}
|
||||
|
||||
KeyframeAnim *ResourceLoader::loadKeyframe(const Common::String &filename) {
|
||||
Block *b = getFileFromCache(filename);
|
||||
if (!b) {
|
||||
b = getFileBlock(filename);
|
||||
if (!b)
|
||||
error("Could not find keyframe file %s", filename.c_str());
|
||||
putIntoCache(filename, b);
|
||||
}
|
||||
Common::SeekableReadStream *stream;
|
||||
|
||||
KeyframeAnim *result = new KeyframeAnim(filename, b->getData(), b->getLen());
|
||||
stream = openNewStreamFile(filename.c_str());
|
||||
if(!stream)
|
||||
error("Could not find keyframe file %s", filename.c_str());
|
||||
|
||||
KeyframeAnim *result = new KeyframeAnim(filename, stream);
|
||||
_keyframeAnims.push_back(result);
|
||||
|
||||
return result;
|
||||
|
Loading…
x
Reference in New Issue
Block a user