Initial commit
This commit is contained in:
573
engines/wintermute/base/gfx/xfile_loader.h
Normal file
573
engines/wintermute/base/gfx/xfile_loader.h
Normal file
@@ -0,0 +1,573 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Partially based on XFile parser code from Wine sources.
|
||||
* Copyright 2008 Christian Costa
|
||||
*/
|
||||
|
||||
#ifndef WINTERMUTE_XFILE_LOADER_H
|
||||
#define WINTERMUTE_XFILE_LOADER_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/stack.h"
|
||||
|
||||
namespace Wintermute {
|
||||
|
||||
enum XTokenType : uint16 {
|
||||
XTOKEN_ERROR = 0xffff,
|
||||
XTOKEN_NONE = 0,
|
||||
XTOKEN_NAME = 1,
|
||||
XTOKEN_STRING = 2,
|
||||
XTOKEN_INTEGER = 3,
|
||||
XTOKEN_GUID = 5,
|
||||
XTOKEN_INTEGER_LIST = 6,
|
||||
XTOKEN_FLOAT_LIST = 7,
|
||||
XTOKEN_OBRACE = 10,
|
||||
XTOKEN_CBRACE = 11,
|
||||
XTOKEN_OPAREN = 12,
|
||||
XTOKEN_CPAREN = 13,
|
||||
XTOKEN_OBRACKET = 14,
|
||||
XTOKEN_CBRACKET = 15,
|
||||
XTOKEN_OANGLE = 16,
|
||||
XTOKEN_CANGLE = 17,
|
||||
XTOKEN_DOT = 18,
|
||||
XTOKEN_COMMA = 19,
|
||||
XTOKEN_SEMICOLON = 20,
|
||||
XTOKEN_TEMPLATE = 31,
|
||||
XTOKEN_WORD = 40,
|
||||
XTOKEN_DWORD = 41,
|
||||
XTOKEN_FLOAT = 42,
|
||||
XTOKEN_DOUBLE = 43,
|
||||
XTOKEN_CHAR = 44,
|
||||
XTOKEN_UCHAR = 45,
|
||||
XTOKEN_SWORD = 46,
|
||||
XTOKEN_SDWORD = 47,
|
||||
XTOKEN_VOID = 48,
|
||||
XTOKEN_LPSTR = 49,
|
||||
XTOKEN_UNICODE = 50,
|
||||
XTOKEN_CSTRING = 51,
|
||||
XTOKEN_ARRAY = 52
|
||||
};
|
||||
|
||||
#define XMAX_NAME_LEN 120
|
||||
#define XMAX_STRING_LEN 500
|
||||
|
||||
struct XToken {
|
||||
XTokenType _type;
|
||||
char _textVal[XMAX_STRING_LEN];
|
||||
uint32 _integerVal;
|
||||
float _floatVal;
|
||||
};
|
||||
|
||||
struct XVector3 {
|
||||
float _x;
|
||||
float _y;
|
||||
float _z;
|
||||
};
|
||||
|
||||
struct XVector4 {
|
||||
float _x;
|
||||
float _y;
|
||||
float _z;
|
||||
float _w;
|
||||
};
|
||||
|
||||
struct XCoords2d {
|
||||
float _u;
|
||||
float _v;
|
||||
};
|
||||
|
||||
struct XMeshFace {
|
||||
uint32 _numFaceVertexIndices;
|
||||
uint32 _faceVertexIndices[4];
|
||||
};
|
||||
|
||||
struct XTimedFloatKeys {
|
||||
float _time;
|
||||
uint32 _numTfkeys;
|
||||
float _tfkeys[16];
|
||||
};
|
||||
|
||||
struct XIndexedColor {
|
||||
uint32 _index;
|
||||
float _indexColorR;
|
||||
float _indexColorG;
|
||||
float _indexColorB;
|
||||
float _indexColorA;
|
||||
};
|
||||
|
||||
struct XVertexElement {
|
||||
uint32 _type;
|
||||
uint32 _method;
|
||||
uint32 _usage;
|
||||
uint32 _usageIndex;
|
||||
};
|
||||
|
||||
struct XMeshMaterialListObject {
|
||||
uint32 _nMaterials;
|
||||
uint32 _numFaceIndexes;
|
||||
uint32 *_faceIndexes{};
|
||||
|
||||
~XMeshMaterialListObject() {
|
||||
delete[] _faceIndexes;
|
||||
}
|
||||
};
|
||||
|
||||
struct XVertexDuplicationIndicesObject {
|
||||
uint32 _nOriginalVertices;
|
||||
uint32 _numIndices;
|
||||
uint32 *_indices{};
|
||||
|
||||
~XVertexDuplicationIndicesObject() {
|
||||
delete[] _indices;
|
||||
}
|
||||
};
|
||||
|
||||
struct XSkinMeshHeaderObject{
|
||||
uint32 _nMaxSkinWeightsPerVertex;
|
||||
uint32 _nMaxSkinWeightsPerFace;
|
||||
uint32 _nBones;
|
||||
};
|
||||
|
||||
struct XSkinWeightsObject {
|
||||
char _transformNodeName[XMAX_NAME_LEN];
|
||||
uint32 _numVertexIndices;
|
||||
uint32 *_vertexIndices{};
|
||||
uint32 _numWeights;
|
||||
float *_weights{};
|
||||
float _matrixOffset[16];
|
||||
|
||||
~XSkinWeightsObject() {
|
||||
delete[] _vertexIndices;
|
||||
delete[] _weights;
|
||||
}
|
||||
};
|
||||
|
||||
struct XMeshObject {
|
||||
uint32 _numVertices;
|
||||
XVector3 *_vertices{};
|
||||
uint32 _numFaces;
|
||||
XMeshFace *_faces{};
|
||||
|
||||
~XMeshObject() {
|
||||
delete[] _vertices;
|
||||
delete[] _faces;
|
||||
}
|
||||
};
|
||||
|
||||
struct XMeshNormalsObject {
|
||||
uint32 _numNormals;
|
||||
XVector3 *_normals{};
|
||||
uint32 _numFaceNormals;
|
||||
XMeshFace *_faceNormals{};
|
||||
|
||||
~XMeshNormalsObject() {
|
||||
delete[] _normals;
|
||||
delete[] _faceNormals;
|
||||
}
|
||||
};
|
||||
|
||||
struct XMeshVertexColorsObject {
|
||||
uint32 _numVertexColors;
|
||||
XIndexedColor *_vertexColors{};
|
||||
|
||||
~XMeshVertexColorsObject() {
|
||||
delete[] _vertexColors;
|
||||
}
|
||||
};
|
||||
|
||||
struct XMeshTextureCoordsObject {
|
||||
uint32 _numTextureCoords;
|
||||
XCoords2d *_textureCoords{};
|
||||
|
||||
~XMeshTextureCoordsObject() {
|
||||
delete[] _textureCoords;
|
||||
}
|
||||
};
|
||||
|
||||
struct XMaterialObject {
|
||||
float _colorR;
|
||||
float _colorG;
|
||||
float _colorB;
|
||||
float _colorA;
|
||||
float _power;
|
||||
float _specularR;
|
||||
float _specularG;
|
||||
float _specularB;
|
||||
float _emissiveR;
|
||||
float _emissiveG;
|
||||
float _emissiveB;
|
||||
};
|
||||
|
||||
struct XTextureFilenameObject {
|
||||
char _filename[XMAX_NAME_LEN];
|
||||
};
|
||||
|
||||
struct XAnimTicksPerSecondObject {
|
||||
uint32 _animTicksPerSecond;
|
||||
};
|
||||
|
||||
struct XAnimationSetObject{
|
||||
};
|
||||
|
||||
struct XAnimationObject{
|
||||
};
|
||||
|
||||
struct XAnimationKeyObject {
|
||||
uint32 _keyType;
|
||||
uint32 _numKeys;
|
||||
XTimedFloatKeys *_keys{};
|
||||
|
||||
~XAnimationKeyObject() {
|
||||
delete[] _keys;
|
||||
}
|
||||
};
|
||||
|
||||
struct XAnimationOptionsObject {
|
||||
uint32 _openclosed;
|
||||
uint32 _positionquality;
|
||||
};
|
||||
|
||||
struct XFrameObject {
|
||||
};
|
||||
|
||||
struct XFrameTransformMatrixObject {
|
||||
float _frameMatrix[16];
|
||||
};
|
||||
|
||||
struct XDeclDataObject {
|
||||
uint32 _numElements;
|
||||
XVertexElement *_elements{};
|
||||
uint32 _numData;
|
||||
uint32 *_data{};
|
||||
|
||||
~XDeclDataObject() {
|
||||
delete[] _elements;
|
||||
delete[] _data;
|
||||
}
|
||||
};
|
||||
|
||||
struct XFVFDataObject {
|
||||
uint32 _dwFVF;
|
||||
uint32 _numData;
|
||||
uint32 *_data{};
|
||||
|
||||
~XFVFDataObject() {
|
||||
delete[] _data;
|
||||
}
|
||||
};
|
||||
|
||||
enum XClassType {
|
||||
kXClassUnknown = 0,
|
||||
kXClassAnimTicksPerSecond,
|
||||
kXClassFrameTransformMatrix,
|
||||
kXClassFrame,
|
||||
kXClassMesh,
|
||||
kXClassMeshNormals,
|
||||
kXClassMeshVertexColors,
|
||||
kXClassMeshTextureCoords,
|
||||
kXClassMeshMaterialList,
|
||||
kXClassVertexDuplicationIndices,
|
||||
kXClassMaterial,
|
||||
kXClassTextureFilename,
|
||||
kXClassSkinMeshHeader,
|
||||
kXClassSkinWeights,
|
||||
kXClassAnimationSet,
|
||||
kXClassAnimation,
|
||||
kXClassAnimationKey,
|
||||
kXClassAnimationOptions,
|
||||
kXClassDeclData,
|
||||
kXClassFVFData,
|
||||
};
|
||||
|
||||
class XFileEnumObject;
|
||||
|
||||
class XObject {
|
||||
friend class XFileLoader;
|
||||
friend class XFileData;
|
||||
friend class XFileEnumObject;
|
||||
|
||||
private:
|
||||
|
||||
Common::String _name;
|
||||
XClassType _classType{};
|
||||
void *_object{};
|
||||
XObject *_targetObject{};
|
||||
Common::Stack<XObject *> _children;
|
||||
|
||||
public:
|
||||
|
||||
void deinit() {
|
||||
switch (_classType) {
|
||||
case kXClassAnimTicksPerSecond:
|
||||
delete (XAnimTicksPerSecondObject *)_object;
|
||||
break;
|
||||
case kXClassAnimationKey:
|
||||
delete (XAnimationKeyObject *)_object;
|
||||
break;
|
||||
case kXClassAnimation:
|
||||
delete (XAnimationObject *)_object;
|
||||
break;
|
||||
case kXClassAnimationOptions:
|
||||
delete (XAnimationOptionsObject *)_object;
|
||||
break;
|
||||
case kXClassAnimationSet:
|
||||
delete (XAnimationSetObject *)_object;
|
||||
break;
|
||||
case kXClassDeclData:
|
||||
delete (XDeclDataObject *)_object;
|
||||
break;
|
||||
case kXClassFrame:
|
||||
delete (XFrameObject *)_object;
|
||||
break;
|
||||
case kXClassFrameTransformMatrix:
|
||||
delete (XFrameTransformMatrixObject *)_object;
|
||||
break;
|
||||
case kXClassFVFData:
|
||||
delete (XFVFDataObject *)_object;
|
||||
break;
|
||||
case kXClassMaterial:
|
||||
delete (XMaterialObject *)_object;
|
||||
break;
|
||||
case kXClassMesh:
|
||||
delete (XMeshObject *)_object;
|
||||
break;
|
||||
case kXClassMeshMaterialList:
|
||||
delete (XMeshMaterialListObject *)_object;
|
||||
break;
|
||||
case kXClassMeshNormals:
|
||||
delete (XMeshNormalsObject *)_object;
|
||||
break;
|
||||
case kXClassMeshVertexColors:
|
||||
delete (XMeshVertexColorsObject *)_object;
|
||||
break;
|
||||
case kXClassMeshTextureCoords:
|
||||
delete (XMeshTextureCoordsObject *)_object;
|
||||
break;
|
||||
case kXClassSkinMeshHeader:
|
||||
delete (XSkinMeshHeaderObject *)_object;
|
||||
break;
|
||||
case kXClassSkinWeights:
|
||||
delete (XSkinWeightsObject *)_object;
|
||||
break;
|
||||
case kXClassVertexDuplicationIndices:
|
||||
delete (XVertexDuplicationIndicesObject *)_object;
|
||||
break;
|
||||
case kXClassTextureFilename:
|
||||
delete (XTextureFilenameObject *)_object;
|
||||
break;
|
||||
case kXClassUnknown:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class XFileLoader {
|
||||
friend class XFileEnumObject;
|
||||
|
||||
private:
|
||||
|
||||
const int kCabBlockSize = 0x8000;
|
||||
const int kCabInputmax = kCabBlockSize + 12;
|
||||
|
||||
bool _initialised{};
|
||||
XToken _currentToken{};
|
||||
byte *_decompBuffer{};
|
||||
byte *_buffer{};
|
||||
uint32 _bufferLeft;
|
||||
bool _isText;
|
||||
uint32 _listNbElements;
|
||||
bool _listTypeFloat;
|
||||
bool _listSeparator;
|
||||
bool _tokenPresent;
|
||||
|
||||
Common::Stack<XObject *> _xobjects;
|
||||
|
||||
public:
|
||||
|
||||
XFileLoader();
|
||||
~XFileLoader();
|
||||
bool load(byte *buffer, uint32 bufferSize);
|
||||
bool createEnumObject(XFileEnumObject &xobj);
|
||||
|
||||
private:
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
FORCEINLINE bool readChar(char &c);
|
||||
FORCEINLINE void rewindBytes(uint32 size);
|
||||
bool readBytes(void *data, uint32 size);
|
||||
bool readLE16(uint16 *data);
|
||||
bool readLE32(uint32 *data);
|
||||
bool readBE32(uint32 *data);
|
||||
|
||||
FORCEINLINE bool getInteger(uint32 &value);
|
||||
FORCEINLINE bool getFloat(float &value);
|
||||
FORCEINLINE bool getString(char *str, uint maxLen);
|
||||
FORCEINLINE bool skipSemicolonComma();
|
||||
|
||||
FORCEINLINE bool isSpace(char c);
|
||||
FORCEINLINE bool isOperator(char c);
|
||||
FORCEINLINE bool isSeparator(char c);
|
||||
FORCEINLINE bool isPrimitiveType(XTokenType token);
|
||||
FORCEINLINE bool isGuid();
|
||||
FORCEINLINE bool isName();
|
||||
FORCEINLINE bool isFloat();
|
||||
FORCEINLINE bool isInteger();
|
||||
FORCEINLINE bool isString();
|
||||
FORCEINLINE bool isKeyword(const char *keyword, uint len);
|
||||
FORCEINLINE XTokenType getKeywordToken();
|
||||
FORCEINLINE XTokenType checkToken();
|
||||
XTokenType getToken();
|
||||
void parseToken();
|
||||
|
||||
bool decompressMsZipData();
|
||||
|
||||
bool parseHeader();
|
||||
|
||||
bool parseTemplate();
|
||||
bool parseTemplateParts();
|
||||
bool parseTemplateOptionInfo();
|
||||
bool parseTemplateMembersList();
|
||||
XObject *resolveChildObject(XObject *object, const Common::String &referenceName);
|
||||
bool resolveObject(XObject *referenceObject, const Common::String &referenceName);
|
||||
bool parseObject(XObject *object);
|
||||
bool parseChildObjects(XObject *object);
|
||||
bool parseObjectParts(XObject *object);
|
||||
};
|
||||
|
||||
class XFileData {
|
||||
friend class XFileEnumObject;
|
||||
|
||||
private:
|
||||
|
||||
XObject *_xobject{};
|
||||
bool _reference{};
|
||||
|
||||
public:
|
||||
|
||||
bool getChild(uint id, XFileData &child) {
|
||||
if (_xobject) {
|
||||
if (id < _xobject->_children.size()) {
|
||||
child._xobject = _xobject->_children[id];
|
||||
if (child._xobject->_targetObject) {
|
||||
child._xobject = child._xobject->_targetObject;
|
||||
child._reference = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getChildren(uint32 &num) {
|
||||
if (_xobject) {
|
||||
num = _xobject->_children.size();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getName(Common::String &name) {
|
||||
if (_xobject) {
|
||||
name = _xobject->_name;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getType(XClassType &classType) {
|
||||
if (_xobject) {
|
||||
classType = _xobject->_classType;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isReference() {
|
||||
if (_xobject) {
|
||||
return _reference;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define GET_OBJECT_FUNC(objectName) \
|
||||
objectName *get ## objectName() { \
|
||||
if (_xobject) \
|
||||
return static_cast<objectName *>(_xobject->_object); \
|
||||
else \
|
||||
return nullptr; \
|
||||
}
|
||||
|
||||
GET_OBJECT_FUNC(XAnimTicksPerSecondObject)
|
||||
GET_OBJECT_FUNC(XAnimationKeyObject)
|
||||
GET_OBJECT_FUNC(XAnimationObject)
|
||||
GET_OBJECT_FUNC(XAnimationOptionsObject)
|
||||
GET_OBJECT_FUNC(XAnimationSetObject)
|
||||
GET_OBJECT_FUNC(XDeclDataObject)
|
||||
GET_OBJECT_FUNC(XFrameObject)
|
||||
GET_OBJECT_FUNC(XFrameTransformMatrixObject)
|
||||
GET_OBJECT_FUNC(XFVFDataObject)
|
||||
GET_OBJECT_FUNC(XMaterialObject)
|
||||
GET_OBJECT_FUNC(XMeshObject)
|
||||
GET_OBJECT_FUNC(XMeshMaterialListObject)
|
||||
GET_OBJECT_FUNC(XMeshNormalsObject)
|
||||
GET_OBJECT_FUNC(XMeshVertexColorsObject)
|
||||
GET_OBJECT_FUNC(XMeshTextureCoordsObject)
|
||||
GET_OBJECT_FUNC(XSkinMeshHeaderObject)
|
||||
GET_OBJECT_FUNC(XSkinWeightsObject)
|
||||
GET_OBJECT_FUNC(XVertexDuplicationIndicesObject)
|
||||
GET_OBJECT_FUNC(XTextureFilenameObject)
|
||||
};
|
||||
|
||||
class XFileEnumObject {
|
||||
friend class XFileLoader;
|
||||
|
||||
private:
|
||||
|
||||
XFileLoader *_file{};
|
||||
|
||||
public:
|
||||
|
||||
bool getChild(uint id, XFileData &child) {
|
||||
if (_file) {
|
||||
if (id < _file->_xobjects.size()) {
|
||||
child._xobject = _file->_xobjects[id];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getChildren(uint32 &num) {
|
||||
if (_file) {
|
||||
num = _file->_xobjects.size();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Wintermute
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user