mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
MTROPOLIS: Add mToon assets and elements and fix some things
This commit is contained in:
committed by
Eugene Sandulenko
parent
7b48322af5
commit
ea7eaa4a15
@@ -65,6 +65,8 @@ IAssetFactory *getAssetFactoryForDataObjectType(const Data::DataObjectTypes::Dat
|
||||
return AssetFactory<MovieAsset, Data::MovieAsset>::getInstance();
|
||||
case Data::DataObjectTypes::kImageAsset:
|
||||
return AssetFactory<ImageAsset, Data::ImageAsset>::getInstance();
|
||||
case Data::DataObjectTypes::kMToonAsset:
|
||||
return AssetFactory<MToonAsset, Data::MToonAsset>::getInstance();
|
||||
case Data::DataObjectTypes::kTextAsset:
|
||||
return AssetFactory<TextAsset, Data::TextAsset>::getInstance();
|
||||
|
||||
|
||||
@@ -194,6 +194,62 @@ ImageAsset::ImageFormat ImageAsset::getImageFormat() const {
|
||||
return _imageFormat;
|
||||
}
|
||||
|
||||
bool MToonAsset::load(AssetLoaderContext &context, const Data::MToonAsset &data) {
|
||||
if (data.haveMacPart)
|
||||
_imageFormat = kImageFormatMac;
|
||||
else if (data.haveWinPart)
|
||||
_imageFormat = kImageFormatWindows;
|
||||
else
|
||||
return false;
|
||||
|
||||
_frameDataPosition = data.frameDataPosition;
|
||||
_sizeOfFrameData = data.sizeOfFrameData;
|
||||
|
||||
if (!_rect.load(data.rect))
|
||||
return false;
|
||||
|
||||
_bitsPerPixel = data.bitsPerPixel;
|
||||
_codecID = data.codecID;
|
||||
|
||||
_frames.resize(data.frames.size());
|
||||
for (size_t i = 0; i < _frames.size(); i++) {
|
||||
if (!_frames[i].load(context, data.frames[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
_frameRanges.resize(data.frameRangesPart.frameRanges.size());
|
||||
for (size_t i = 0; i < _frameRanges.size(); i++) {
|
||||
if (!_frameRanges[i].load(context, data.frameRangesPart.frameRanges[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
_codecData = data.codecData;
|
||||
}
|
||||
|
||||
AssetType MToonAsset::getAssetType() const {
|
||||
return kAssetTypeMToon;
|
||||
}
|
||||
|
||||
bool MToonAsset::FrameDef::load(AssetLoaderContext &context, const Data::MToonAsset::FrameDef &data) {
|
||||
compressedSize = data.compressedSize;
|
||||
dataOffset = data.dataOffset;
|
||||
decompressedBytesPerRow = data.decompressedBytesPerRow;
|
||||
decompressedSize = data.decompressedSize;
|
||||
isKeyFrame = (data.keyframeFlag != 0);
|
||||
if (!rect.load(data.rect1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MToonAsset::FrameRangeDef::load(AssetLoaderContext &context, const Data::MToonAsset::FrameRangeDef &data) {
|
||||
name = data.name;
|
||||
startFrame = data.startFrame;
|
||||
endFrame = data.endFrame;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextAsset::load(AssetLoaderContext &context, const Data::TextAsset &data) {
|
||||
_assetID = data.assetID;
|
||||
|
||||
|
||||
@@ -105,6 +105,8 @@ public:
|
||||
size_t getStreamIndex() const;
|
||||
ImageFormat getImageFormat() const;
|
||||
|
||||
const Common::SharedPtr<Graphics::Surface> &loadContent();
|
||||
|
||||
private:
|
||||
Rect16 _rect;
|
||||
ColorDepthMode _colorDepth;
|
||||
@@ -112,6 +114,54 @@ private:
|
||||
uint32 _size;
|
||||
size_t _streamIndex;
|
||||
ImageFormat _imageFormat;
|
||||
|
||||
Common::SharedPtr<Graphics::Surface> _surface;
|
||||
};
|
||||
|
||||
|
||||
struct MToonAsset : public Asset {
|
||||
public:
|
||||
bool load(AssetLoaderContext &context, const Data::MToonAsset &data);
|
||||
AssetType getAssetType() const override;
|
||||
|
||||
enum ImageFormat {
|
||||
kImageFormatMac,
|
||||
kImageFormatWindows,
|
||||
};
|
||||
|
||||
struct FrameDef {
|
||||
Rect16 rect;
|
||||
uint32 dataOffset;
|
||||
uint32 compressedSize;
|
||||
uint32 decompressedSize;
|
||||
uint16 decompressedBytesPerRow;
|
||||
bool isKeyFrame;
|
||||
|
||||
bool load(AssetLoaderContext &context, const Data::MToonAsset::FrameDef &data);
|
||||
};
|
||||
|
||||
struct FrameRangeDef {
|
||||
uint32 startFrame;
|
||||
uint32 endFrame;
|
||||
|
||||
Common::String name;
|
||||
|
||||
bool load(AssetLoaderContext &context, const Data::MToonAsset::FrameRangeDef &data);
|
||||
};
|
||||
|
||||
private:
|
||||
ImageFormat _imageFormat;
|
||||
|
||||
uint32 _frameDataPosition;
|
||||
uint32 _sizeOfFrameData;
|
||||
|
||||
Rect16 _rect;
|
||||
uint16 _bitsPerPixel;
|
||||
uint32 _codecID;
|
||||
|
||||
Common::Array<FrameDef> _frames;
|
||||
Common::Array<FrameRangeDef> _frameRanges;
|
||||
Common::Array<uint8> _codecData;
|
||||
};
|
||||
|
||||
class TextAsset : public Asset {
|
||||
|
||||
+108
-2
@@ -853,7 +853,7 @@ DataReadErrorCode MToonElement::load(DataReader &reader) {
|
||||
if (!reader.readU32(structuralFlags) || !reader.readU32(sizeIncludingTag) || !reader.readU32(guid)
|
||||
|| !reader.readU16(lengthOfName) || !reader.readU32(elementFlags) || !reader.readU16(layer)
|
||||
|| !reader.readU32(animationFlags) || !reader.readBytes(unknown4) || !reader.readU16(sectionID)
|
||||
|| !rect1.load(reader) || !rect2.load(reader) || !reader.readU32(unknown5)
|
||||
|| !rect1.load(reader) || !rect2.load(reader) || !reader.readU32(assetID)
|
||||
|| !reader.readU32(rateTimes10000) || !reader.readU32(streamLocator) || !reader.readU32(unknown6)
|
||||
|| !reader.readTerminatedStr(name, lengthOfName))
|
||||
return kDataReadErrorReadFailed;
|
||||
@@ -1032,6 +1032,20 @@ DataReadErrorCode MiniscriptModifier::load(DataReader &reader) {
|
||||
return kDataReadErrorNone;
|
||||
}
|
||||
|
||||
DataReadErrorCode SaveAndRestoreModifier::load(DataReader &reader) {
|
||||
if (_revision != 0x3e9)
|
||||
return kDataReadErrorUnsupportedRevision;
|
||||
|
||||
if (!modHeader.load(reader) || !reader.readBytes(unknown1) || !saveWhen.load(reader) || !restoreWhen.load(reader)
|
||||
|| !saveOrRestoreValue.load(reader) || !reader.readBytes(unknown5) || !reader.readU8(lengthOfFilePath)
|
||||
|| !reader.readU8(lengthOfFileName) || !reader.readU8(lengthOfVariableName) || !reader.readU8(lengthOfVariableString)
|
||||
|| !reader.readNonTerminatedStr(varName, lengthOfVariableName) || !reader.readNonTerminatedStr(varString, lengthOfVariableString)
|
||||
|| !reader.readNonTerminatedStr(filePath, lengthOfFilePath) || !reader.readNonTerminatedStr(fileName, lengthOfFileName))
|
||||
return kDataReadErrorReadFailed;
|
||||
|
||||
return kDataReadErrorNone;
|
||||
}
|
||||
|
||||
DataReadErrorCode MessengerModifier::load(DataReader &reader) {
|
||||
if (_revision != 0x3ea)
|
||||
return kDataReadErrorUnsupportedRevision;
|
||||
@@ -1629,6 +1643,95 @@ DataReadErrorCode ImageAsset::load(DataReader &reader) {
|
||||
return kDataReadErrorNone;
|
||||
}
|
||||
|
||||
DataReadErrorCode MToonAsset::load(DataReader &reader) {
|
||||
if (_revision != 1)
|
||||
return kDataReadErrorUnsupportedRevision;
|
||||
|
||||
if (!reader.readU32(marker) || !reader.readBytes(unknown1) || !reader.readU32(assetID))
|
||||
return kDataReadErrorReadFailed;
|
||||
|
||||
haveMacPart = false;
|
||||
haveWinPart = false;
|
||||
|
||||
if (reader.getProjectFormat() == kProjectFormatMacintosh) {
|
||||
haveMacPart = true;
|
||||
|
||||
if (!reader.readBytes(platform.mac.unknown10))
|
||||
return kDataReadErrorReadFailed;
|
||||
} else if (reader.getProjectFormat() == kProjectFormatWindows) {
|
||||
haveWinPart = true;
|
||||
|
||||
if (!reader.readBytes(platform.win.unknown11))
|
||||
return kDataReadErrorReadFailed;
|
||||
} else
|
||||
return kDataReadErrorUnrecognized;
|
||||
|
||||
if (!reader.readU32(frameDataPosition) || !reader.readU32(sizeOfFrameData) || !reader.readU32(mtoonHeader[0])
|
||||
|| !reader.readU32(mtoonHeader[1]) || !reader.readU16(version) || !reader.readBytes(unknown2)
|
||||
|| !reader.readU32(encodingFlags) || !rect.load(reader) || !reader.readU16(numFrames)
|
||||
|| !reader.readBytes(unknown3) || !reader.readU16(bitsPerPixel) || !reader.readU32(codecID)
|
||||
|| !reader.readBytes(unknown4_1) || !reader.readU32(codecDataSize) || !reader.readBytes(unknown4_2))
|
||||
return kDataReadErrorReadFailed;
|
||||
|
||||
if (mtoonHeader[0] != 0 || mtoonHeader[1] != 0x546f6f6e)
|
||||
return kDataReadErrorUnrecognized;
|
||||
|
||||
if (numFrames > 0) {
|
||||
frames.resize(numFrames);
|
||||
for (size_t i = 0; i < numFrames; i++) {
|
||||
FrameDef &frame = frames[i];
|
||||
|
||||
if (!reader.readBytes(frame.unknown12) || !frame.rect1.load(reader) || !reader.readU32(frame.dataOffset)
|
||||
|| !reader.readBytes(frame.unknown13) || !reader.readU32(frame.compressedSize) || !reader.readU8(frame.unknown14)
|
||||
|| !reader.readU8(frame.keyframeFlag) || !reader.readU8(frame.platformBit) || !reader.readU8(frame.unknown15)
|
||||
|| !frame.rect2.load(reader) || !reader.readU32(frame.hdpiFixed) || !reader.readU32(frame.vdpiFixed)
|
||||
|| !reader.readU16(frame.bitsPerPixel) || !reader.readU32(frame.unknown16) || !reader.readU16(frame.decompressedBytesPerRow))
|
||||
return kDataReadErrorReadFailed;
|
||||
|
||||
if (reader.getProjectFormat() == kProjectFormatMacintosh) {
|
||||
if (!reader.readBytes(frame.platform.mac.unknown17))
|
||||
return kDataReadErrorReadFailed;
|
||||
} else if (reader.getProjectFormat() == kProjectFormatWindows) {
|
||||
if (!reader.readBytes(frame.platform.win.unknown18))
|
||||
return kDataReadErrorReadFailed;
|
||||
} else
|
||||
return kDataReadErrorUnrecognized;
|
||||
|
||||
if (!reader.readU32(frame.decompressedSize))
|
||||
return kDataReadErrorReadFailed;
|
||||
}
|
||||
}
|
||||
|
||||
if (codecDataSize > 0) {
|
||||
codecData.resize(codecDataSize);
|
||||
if (!reader.read(&codecData[0], codecDataSize))
|
||||
return kDataReadErrorReadFailed;
|
||||
}
|
||||
|
||||
if (encodingFlags & kEncodingFlag_HasRanges) {
|
||||
if (!reader.readU32(frameRangesPart.tag) || !reader.readU32(frameRangesPart.sizeIncludingTag) || !reader.readU32(frameRangesPart.numFrameRanges))
|
||||
return kDataReadErrorReadFailed;
|
||||
|
||||
if (frameRangesPart.tag != 1)
|
||||
return kDataReadErrorUnrecognized;
|
||||
|
||||
if (frameRangesPart.numFrameRanges > 0) {
|
||||
frameRangesPart.frameRanges.resize(frameRangesPart.numFrameRanges);
|
||||
for (size_t i = 0; i < frameRangesPart.numFrameRanges; i++) {
|
||||
FrameRangeDef &frameRange = frameRangesPart.frameRanges[i];
|
||||
|
||||
if (!reader.readU32(frameRange.startFrame) || !reader.readU32(frameRange.endFrame) || !reader.readU8(frameRange.lengthOfName) || !reader.readU8(frameRange.unknown14))
|
||||
return kDataReadErrorReadFailed;
|
||||
|
||||
if (!reader.readTerminatedStr(frameRange.name, frameRange.lengthOfName))
|
||||
return kDataReadErrorReadFailed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return kDataReadErrorNone;
|
||||
}
|
||||
|
||||
DataReadErrorCode TextAsset::load(DataReader &reader) {
|
||||
if (_revision != 3)
|
||||
return kDataReadErrorReadFailed;
|
||||
@@ -1775,6 +1878,9 @@ DataReadErrorCode loadDataObject(const PlugInModifierRegistry ®istry, DataRea
|
||||
case DataObjectTypes::kMiniscriptModifier:
|
||||
dataObject = new MiniscriptModifier();
|
||||
break;
|
||||
case DataObjectTypes::kSaveAndRestoreModifier:
|
||||
dataObject = new SaveAndRestoreModifier();
|
||||
break;
|
||||
case DataObjectTypes::kMessengerModifier:
|
||||
dataObject = new MessengerModifier();
|
||||
break;
|
||||
@@ -1871,7 +1977,7 @@ DataReadErrorCode loadDataObject(const PlugInModifierRegistry ®istry, DataRea
|
||||
break;
|
||||
|
||||
case DataObjectTypes::kMToonAsset:
|
||||
//dataObject = new MToonAsset();
|
||||
dataObject = new MToonAsset();
|
||||
break;
|
||||
|
||||
case DataObjectTypes::kTextAsset:
|
||||
|
||||
+144
-15
@@ -122,7 +122,7 @@ enum DataObjectType {
|
||||
kCursorModifierV1 = 0x3ca, // NYI - Obsolete version
|
||||
kGradientModifier = 0x4b0, // NYI
|
||||
kColorTableModifier = 0x4c4, // NYI
|
||||
kSaveAndRestoreModifier = 0x4d8, // NYI
|
||||
kSaveAndRestoreModifier = 0x4d8,
|
||||
|
||||
kCompoundVariableModifier = 0x2c7,
|
||||
kBooleanVariableModifier = 0x321,
|
||||
@@ -272,7 +272,7 @@ struct Label {
|
||||
//
|
||||
// InternalTypeTaggedValue is used by internal modifiers for messenger payloads and set modifiers
|
||||
// and seems to match Miniscript ops too.
|
||||
// InternalTypeTaggedValue is always 44 bytes in size and stores string data elsewhere in the containing structure.
|
||||
// InternalTypeTaggedValue is always 46 bytes in size and stores string data elsewhere in the containing structure.
|
||||
//
|
||||
// PlugInTypeTaggedValue is used by plug-ins and is fully self-contained.
|
||||
//
|
||||
@@ -394,7 +394,7 @@ struct ProjectLabelMap : public DataObject {
|
||||
|
||||
Common::String name;
|
||||
|
||||
uint32_t numChildren;
|
||||
uint32 numChildren;
|
||||
LabelTree *children;
|
||||
};
|
||||
|
||||
@@ -407,7 +407,7 @@ struct ProjectLabelMap : public DataObject {
|
||||
uint32 unknown2;
|
||||
Common::String name;
|
||||
|
||||
uint32_t numChildren;
|
||||
uint32 numChildren;
|
||||
LabelTree *tree;
|
||||
};
|
||||
|
||||
@@ -678,7 +678,7 @@ struct MToonElement : public StructuralDef {
|
||||
uint16 sectionID;
|
||||
Rect rect1;
|
||||
Rect rect2;
|
||||
uint32 unknown5;
|
||||
uint32 assetID;
|
||||
uint32 rateTimes10000;
|
||||
uint32 streamLocator;
|
||||
uint32 unknown6;
|
||||
@@ -814,7 +814,6 @@ struct TypicalModifierHeader {
|
||||
};
|
||||
|
||||
struct MiniscriptModifier : public DataObject {
|
||||
|
||||
TypicalModifierHeader modHeader;
|
||||
Event enableWhen;
|
||||
uint8 unknown6[11];
|
||||
@@ -826,6 +825,30 @@ protected:
|
||||
DataReadErrorCode load(DataReader &reader) override;
|
||||
};
|
||||
|
||||
|
||||
struct SaveAndRestoreModifier : public DataObject {
|
||||
TypicalModifierHeader modHeader;
|
||||
uint8 unknown1[4];
|
||||
Event saveWhen;
|
||||
Event restoreWhen;
|
||||
InternalTypeTaggedValue saveOrRestoreValue;
|
||||
|
||||
uint8 unknown5[8];
|
||||
|
||||
uint8 lengthOfFilePath;
|
||||
uint8 lengthOfFileName;
|
||||
uint8 lengthOfVariableName;
|
||||
uint8 lengthOfVariableString;
|
||||
|
||||
Common::String varName;
|
||||
Common::String varString;
|
||||
Common::String filePath;
|
||||
Common::String fileName;
|
||||
|
||||
protected:
|
||||
DataReadErrorCode load(DataReader &reader) override;
|
||||
};
|
||||
|
||||
enum MessageFlags {
|
||||
kMessageFlagNoRelay = 0x20000000,
|
||||
kMessageFlagNoCascade = 0x40000000,
|
||||
@@ -936,15 +959,15 @@ struct DragMotionModifier : public DataObject {
|
||||
Event disableWhen;
|
||||
|
||||
struct WinPart {
|
||||
uint8_t unknown2;
|
||||
uint8_t constrainHorizontal;
|
||||
uint8_t constrainVertical;
|
||||
uint8_t constrainToParent;
|
||||
uint8 unknown2;
|
||||
uint8 constrainHorizontal;
|
||||
uint8 constrainVertical;
|
||||
uint8 constrainToParent;
|
||||
};
|
||||
|
||||
struct MacPart {
|
||||
uint8_t flags;
|
||||
uint8_t unknown3;
|
||||
uint8 flags;
|
||||
uint8 unknown3;
|
||||
|
||||
enum Flags {
|
||||
kConstrainToParent = 0x10,
|
||||
@@ -963,7 +986,7 @@ struct DragMotionModifier : public DataObject {
|
||||
bool haveMacPart;
|
||||
bool haveWinPart;
|
||||
Rect constraintMargin;
|
||||
uint16_t unknown1;
|
||||
uint16 unknown1;
|
||||
|
||||
protected:
|
||||
DataReadErrorCode load(DataReader &reader) override;
|
||||
@@ -1205,7 +1228,7 @@ struct TextStyleModifier : public DataObject {
|
||||
uint16 unknown3;
|
||||
Event applyWhen;
|
||||
Event removeWhen;
|
||||
uint16_t lengthOfFontFamilyName;
|
||||
uint16 lengthOfFontFamilyName;
|
||||
|
||||
Common::String fontFamilyName;
|
||||
|
||||
@@ -1497,7 +1520,7 @@ struct ImageAsset : public DataObject {
|
||||
|
||||
uint32 persistFlags;
|
||||
uint32 unknown1;
|
||||
uint8_t unknown2[4];
|
||||
uint8 unknown2[4];
|
||||
uint32 assetID;
|
||||
uint32 unknown3;
|
||||
|
||||
@@ -1520,6 +1543,112 @@ protected:
|
||||
DataReadErrorCode load(DataReader &reader) override;
|
||||
};
|
||||
|
||||
struct MToonAsset : public DataObject {
|
||||
struct MacPart {
|
||||
uint8 unknown10[88];
|
||||
};
|
||||
|
||||
struct WinPart {
|
||||
uint8 unknown11[54];
|
||||
};
|
||||
|
||||
struct FrameDef {
|
||||
struct MacPart {
|
||||
uint8 unknown17[4];
|
||||
};
|
||||
|
||||
struct WinPart {
|
||||
uint8 unknown18[2];
|
||||
};
|
||||
|
||||
union PlatformUnion {
|
||||
MacPart mac;
|
||||
WinPart win;
|
||||
};
|
||||
|
||||
uint8 unknown12[4];
|
||||
Rect rect1;
|
||||
uint32 dataOffset;
|
||||
uint8 unknown13[2];
|
||||
uint32 compressedSize;
|
||||
uint8 unknown14;
|
||||
uint8 keyframeFlag;
|
||||
uint8 platformBit;
|
||||
uint8 unknown15;
|
||||
Rect rect2;
|
||||
uint32 hdpiFixed;
|
||||
uint32 vdpiFixed;
|
||||
uint16 bitsPerPixel;
|
||||
uint32 unknown16;
|
||||
uint16 decompressedBytesPerRow;
|
||||
uint32 decompressedSize;
|
||||
|
||||
PlatformUnion platform;
|
||||
};
|
||||
|
||||
struct FrameRangeDef {
|
||||
uint32 startFrame;
|
||||
uint32 endFrame;
|
||||
uint8 lengthOfName;
|
||||
uint8 unknown14;
|
||||
|
||||
Common::String name; // Null terminated
|
||||
};
|
||||
|
||||
enum {
|
||||
kEncodingFlag_TemporalCompression = 0x80,
|
||||
kEncodingFlag_HasRanges = 0x20000000,
|
||||
kEncodingFlag_Trimming = 0x08,
|
||||
};
|
||||
|
||||
uint32 marker;
|
||||
uint8 unknown1[8];
|
||||
uint32 assetID;
|
||||
|
||||
bool haveMacPart;
|
||||
bool haveWinPart;
|
||||
|
||||
union PlatformUnion {
|
||||
MacPart mac;
|
||||
WinPart win;
|
||||
} platform;
|
||||
|
||||
uint32 frameDataPosition;
|
||||
uint32 sizeOfFrameData;
|
||||
|
||||
// mToon data
|
||||
uint32 mtoonHeader[2];
|
||||
uint16 version;
|
||||
uint8 unknown2[4];
|
||||
uint32 encodingFlags;
|
||||
Rect rect;
|
||||
|
||||
uint16 numFrames;
|
||||
uint8 unknown3[14];
|
||||
uint16 bitsPerPixel;
|
||||
uint32 codecID;
|
||||
uint8 unknown4_1[8];
|
||||
uint32 codecDataSize;
|
||||
uint8 unknown4_2[4];
|
||||
|
||||
Common::Array<FrameDef> frames;
|
||||
|
||||
Common::Array<uint8> codecData;
|
||||
|
||||
struct FrameRangePart {
|
||||
uint32 tag;
|
||||
uint32 sizeIncludingTag;
|
||||
|
||||
uint32 numFrameRanges;
|
||||
Common::Array<FrameRangeDef> frameRanges;
|
||||
};
|
||||
|
||||
FrameRangePart frameRangesPart;
|
||||
|
||||
protected:
|
||||
DataReadErrorCode load(DataReader &reader) override;
|
||||
};
|
||||
|
||||
struct TextAsset : public DataObject {
|
||||
struct MacFormattingSpan {
|
||||
uint8 unknown9[2];
|
||||
|
||||
@@ -66,6 +66,8 @@ IElementFactory *getElementFactoryForDataObjectType(const Data::DataObjectTypes:
|
||||
return ElementFactory<MovieElement, Data::MovieElement>::getInstance();
|
||||
case Data::DataObjectTypes::kImageElement:
|
||||
return ElementFactory<ImageElement, Data::ImageElement>::getInstance();
|
||||
case Data::DataObjectTypes::kMToonElement:
|
||||
return ElementFactory<MToonElement, Data::MToonElement>::getInstance();
|
||||
case Data::DataObjectTypes::kTextLabelElement:
|
||||
return ElementFactory<TextLabelElement, Data::TextLabelElement>::getInstance();
|
||||
case Data::DataObjectTypes::kSoundElement:
|
||||
|
||||
@@ -284,7 +284,7 @@ void ImageElement::activate() {
|
||||
pixelFmt = Graphics::PixelFormat::createFormatCLUT8();
|
||||
break;
|
||||
case kColorDepthMode16Bit:
|
||||
bytesPerRow = width * 2;
|
||||
bytesPerRow = (width * 2 + 3) / 4 * 4;
|
||||
pixelFmt = Graphics::createPixelFormat<1555>();
|
||||
break;
|
||||
case kColorDepthMode32Bit:
|
||||
@@ -402,6 +402,43 @@ void ImageElement::render(Window *window) {
|
||||
}
|
||||
}
|
||||
|
||||
MToonElement::MToonElement() {
|
||||
}
|
||||
|
||||
MToonElement::~MToonElement() {
|
||||
}
|
||||
|
||||
bool MToonElement::load(ElementLoaderContext &context, const Data::MToonElement &data) {
|
||||
if (!loadCommon(data.name, data.guid, data.rect1, data.elementFlags, data.layer, data.streamLocator, data.sectionID))
|
||||
return false;
|
||||
|
||||
_cacheBitmap = ((data.elementFlags & Data::ElementFlags::kCacheBitmap) != 0);
|
||||
_paused = ((data.elementFlags & Data::ElementFlags::kPaused) != 0);
|
||||
_loop = ((data.animationFlags & Data::AnimationFlags::kLoop) != 0);
|
||||
_maintainRate = ((data.elementFlags & Data::AnimationFlags::kPlayEveryFrame) == 0); // NOTE: Inverted intentionally
|
||||
_assetID = data.assetID;
|
||||
_runtime = context.runtime;
|
||||
_rateTimes10000 = data.rateTimes10000;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MToonElement::activate() {
|
||||
}
|
||||
|
||||
void MToonElement::deactivate() {
|
||||
_renderSurface.reset();
|
||||
}
|
||||
|
||||
void MToonElement::render(Window *window) {
|
||||
if (_renderSurface) {
|
||||
Common::Rect srcRect(_renderSurface->w, _renderSurface->h);
|
||||
Common::Rect destRect(_cachedAbsoluteOrigin.x, _cachedAbsoluteOrigin.y, _cachedAbsoluteOrigin.x + _rect.getWidth(), _cachedAbsoluteOrigin.y + _rect.getHeight());
|
||||
window->getSurface()->blitFrom(*_renderSurface, srcRect, destRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TextLabelElement::TextLabelElement() : _needsRender(false), _isBitmap(false) {
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +128,37 @@ private:
|
||||
Runtime *_runtime;
|
||||
};
|
||||
|
||||
class MToonElement : public VisualElement {
|
||||
public:
|
||||
MToonElement();
|
||||
~MToonElement();
|
||||
|
||||
bool load(ElementLoaderContext &context, const Data::MToonElement &data);
|
||||
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
|
||||
void render(Window *window) override;
|
||||
|
||||
#ifdef MTROPOLIS_DEBUG_ENABLE
|
||||
const char *debugGetTypeName() const override { return "mToon Element"; }
|
||||
SupportStatus debugGetSupportStatus() const override { return kSupportStatusPartial; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool _cacheBitmap;
|
||||
bool _loop;
|
||||
|
||||
// If set, then carry over residual frame time and display at the desired rate. If not set, reset residual each frame for smoother animation.
|
||||
bool _maintainRate;
|
||||
|
||||
uint32 _assetID;
|
||||
Runtime *_runtime;
|
||||
uint32 _rateTimes10000;
|
||||
|
||||
Common::SharedPtr<Graphics::Surface> _renderSurface;
|
||||
};
|
||||
|
||||
class TextLabelElement : public VisualElement {
|
||||
public:
|
||||
TextLabelElement();
|
||||
|
||||
@@ -56,6 +56,23 @@ void MiniscriptReferences::linkInternalReferences(ObjectLinkingScope *scope) {
|
||||
}
|
||||
}
|
||||
|
||||
void MiniscriptReferences::visitInternalReferences(IStructuralReferenceVisitor *visitor) {
|
||||
for (LocalRef &ref : _localRefs) {
|
||||
Common::SharedPtr<RuntimeObject> obj = ref.resolution.lock();
|
||||
if (obj) {
|
||||
if (obj->isModifier()) {
|
||||
Common::WeakPtr<Modifier> mod = obj.staticCast<Modifier>();
|
||||
visitor->visitWeakModifierRef(mod);
|
||||
ref.resolution = mod;
|
||||
} else if (obj->isStructural()) {
|
||||
Common::WeakPtr<Structural> struc = obj.staticCast<Structural>();
|
||||
visitor->visitWeakStructuralRef(struc);
|
||||
ref.resolution = struc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Common::WeakPtr<RuntimeObject> MiniscriptReferences::getRefByIndex(uint index) const {
|
||||
if (index >= _localRefs.size())
|
||||
return Common::WeakPtr<RuntimeObject>();
|
||||
@@ -1075,16 +1092,18 @@ MiniscriptInstructionOutcome BuiltinFunc::executeNum2Str(MiniscriptThread *threa
|
||||
const DynamicValue &inputDynamicValue = thread->getStackValueFromTop(0).value;
|
||||
switch (inputDynamicValue.getType()) {
|
||||
case DynamicValueTypes::kInteger:
|
||||
result.format("%i", static_cast<int>(inputDynamicValue.getInt()));
|
||||
result = Common::String::format("%i", static_cast<int>(inputDynamicValue.getInt()));
|
||||
break;
|
||||
case DynamicValueTypes::kFloat:
|
||||
result.format("%g", static_cast<double>(inputDynamicValue.getFloat()));
|
||||
result = Common::String::format("%g", static_cast<double>(inputDynamicValue.getFloat()));
|
||||
break;
|
||||
default:
|
||||
thread->error("Invalid input value to num2str");
|
||||
return kMiniscriptInstructionOutcomeFailed;
|
||||
}
|
||||
|
||||
returnValue->setString(result);
|
||||
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
explicit MiniscriptReferences(const Common::Array<LocalRef> &localRefs);
|
||||
|
||||
void linkInternalReferences(ObjectLinkingScope *scope);
|
||||
void visitInternalReferences(IStructuralReferenceVisitor *visitor);
|
||||
|
||||
Common::WeakPtr<RuntimeObject> getRefByIndex(uint index) const;
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@ IModifierFactory *getModifierFactoryForDataObjectType(const Data::DataObjectType
|
||||
return ModifierFactory<BehaviorModifier, Data::BehaviorModifier>::getInstance();
|
||||
case Data::DataObjectTypes::kMiniscriptModifier:
|
||||
return ModifierFactory<MiniscriptModifier, Data::MiniscriptModifier>::getInstance();
|
||||
case Data::DataObjectTypes::kSaveAndRestoreModifier:
|
||||
return ModifierFactory<SaveAndRestoreModifier, Data::SaveAndRestoreModifier>::getInstance();
|
||||
case Data::DataObjectTypes::kAliasModifier:
|
||||
return ModifierFactory<AliasModifier, Data::AliasModifier>::getInstance();
|
||||
case Data::DataObjectTypes::kChangeSceneModifier:
|
||||
|
||||
@@ -132,6 +132,10 @@ Common::SharedPtr<Modifier> BehaviorModifier::shallowClone() const {
|
||||
return Common::SharedPtr<Modifier>(new BehaviorModifier(*this));
|
||||
}
|
||||
|
||||
void BehaviorModifier::linkInternalReferences(ObjectLinkingScope *scope) {
|
||||
Modifier::linkInternalReferences(scope);
|
||||
}
|
||||
|
||||
void BehaviorModifier::visitInternalReferences(IStructuralReferenceVisitor* visitor) {
|
||||
for (Common::Array<Common::SharedPtr<Modifier> >::iterator it = _children.begin(), itEnd = _children.end(); it != itEnd; ++it) {
|
||||
visitor->visitChildModifierRef(*it);
|
||||
@@ -176,6 +180,49 @@ void MiniscriptModifier::linkInternalReferences(ObjectLinkingScope* scope) {
|
||||
_references->linkInternalReferences(scope);
|
||||
}
|
||||
|
||||
void MiniscriptModifier::visitInternalReferences(IStructuralReferenceVisitor *visitor) {
|
||||
_references->visitInternalReferences(visitor);
|
||||
}
|
||||
|
||||
bool SaveAndRestoreModifier::load(ModifierLoaderContext &context, const Data::SaveAndRestoreModifier &data) {
|
||||
if (!loadTypicalHeader(data.modHeader))
|
||||
return false;
|
||||
|
||||
if (!_saveWhen.load(data.saveWhen) || !_restoreWhen.load(data.restoreWhen))
|
||||
return false;
|
||||
|
||||
if (!_saveOrRestoreValue.load(data.saveOrRestoreValue, data.varName, data.varString))
|
||||
return false;
|
||||
|
||||
_filePath = data.filePath;
|
||||
_fileName = data.fileName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveAndRestoreModifier::respondsToEvent(const Event &evt) const {
|
||||
if (_saveWhen.respondsTo(evt) || _restoreWhen.respondsTo(evt))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
VThreadState SaveAndRestoreModifier::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
|
||||
if (_saveWhen.respondsTo(msg->getEvent())) {
|
||||
error("Saves not implemented yet");
|
||||
return kVThreadReturn;
|
||||
} else if (_restoreWhen.respondsTo(msg->getEvent())) {
|
||||
error("Restores not implemented yet");
|
||||
return kVThreadReturn;
|
||||
}
|
||||
|
||||
return kVThreadError;
|
||||
}
|
||||
|
||||
Common::SharedPtr<Modifier> SaveAndRestoreModifier::shallowClone() const {
|
||||
return Common::SharedPtr<Modifier>(new SaveAndRestoreModifier(*this));
|
||||
}
|
||||
|
||||
bool MessengerModifier::load(ModifierLoaderContext &context, const Data::MessengerModifier &data) {
|
||||
if (!loadTypicalHeader(data.modHeader))
|
||||
return false;
|
||||
|
||||
@@ -71,6 +71,7 @@ private:
|
||||
VThreadState propagateTask(const PropagateTaskData &taskData);
|
||||
|
||||
Common::SharedPtr<Modifier> shallowClone() const override;
|
||||
void linkInternalReferences(ObjectLinkingScope *scope) override;
|
||||
void visitInternalReferences(IStructuralReferenceVisitor *visitor) override;
|
||||
|
||||
Common::Array<Common::SharedPtr<Modifier> > _children;
|
||||
@@ -96,6 +97,7 @@ public:
|
||||
private:
|
||||
Common::SharedPtr<Modifier> shallowClone() const override;
|
||||
void linkInternalReferences(ObjectLinkingScope *scope) override;
|
||||
void visitInternalReferences(IStructuralReferenceVisitor *visitor) override;
|
||||
|
||||
Event _enableWhen;
|
||||
|
||||
@@ -103,6 +105,30 @@ private:
|
||||
Common::SharedPtr<MiniscriptReferences> _references;
|
||||
};
|
||||
|
||||
class SaveAndRestoreModifier : public Modifier {
|
||||
public:
|
||||
bool load(ModifierLoaderContext &context, const Data::SaveAndRestoreModifier &data);
|
||||
|
||||
bool respondsToEvent(const Event &evt) const override;
|
||||
VThreadState consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) override;
|
||||
|
||||
#ifdef MTROPOLIS_DEBUG_ENABLE
|
||||
const char *debugGetTypeName() const override { return "Save And Restore Modifier"; }
|
||||
SupportStatus debugGetSupportStatus() const override { return kSupportStatusPartial; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
Common::SharedPtr<Modifier> shallowClone() const override;
|
||||
|
||||
Event _saveWhen;
|
||||
Event _restoreWhen;
|
||||
|
||||
DynamicValue _saveOrRestoreValue;
|
||||
|
||||
Common::String _filePath;
|
||||
Common::String _fileName;
|
||||
};
|
||||
|
||||
class MessengerModifier : public Modifier {
|
||||
public:
|
||||
bool load(ModifierLoaderContext &context, const Data::MessengerModifier &data);
|
||||
|
||||
@@ -3391,7 +3391,7 @@ void Runtime::loadScene(const Common::SharedPtr<Structural>& scene) {
|
||||
scene->materializeDescendents(this, subsection->getSceneLoadMaterializeScope());
|
||||
debug(1, "Scene materialized OK");
|
||||
recursiveActivateStructural(scene.get());
|
||||
debug(1, "Scene added to renderer OK");
|
||||
debug(1, "Structural elements activated OK");
|
||||
|
||||
#ifdef MTROPOLIS_DEBUG_ENABLE
|
||||
if (_debugger) {
|
||||
@@ -4767,6 +4767,9 @@ bool VisualElement::readAttribute(MiniscriptThread *thread, DynamicValue &result
|
||||
} else if (attrib == "height") {
|
||||
result.setInt(_rect.bottom - _rect.top);
|
||||
return true;
|
||||
} else if (attrib == "globalposition") {
|
||||
result.setPoint(getGlobalPosition());
|
||||
return true;
|
||||
}
|
||||
|
||||
return Element::readAttribute(thread, result, attrib);
|
||||
@@ -4791,6 +4794,21 @@ const Rect16 &VisualElement::getRelativeRect() const {
|
||||
return _rect;
|
||||
}
|
||||
|
||||
Point16 VisualElement::getGlobalPosition() const {
|
||||
Point16 pos = Point16::create(0, 0);
|
||||
if (_parent && _parent->isElement()) {
|
||||
Element *element = static_cast<Element *>(_parent);
|
||||
if (element->isVisual()) {
|
||||
pos = static_cast<VisualElement *>(element)->getGlobalPosition();
|
||||
}
|
||||
}
|
||||
|
||||
pos.x += _rect.left;
|
||||
pos.y += _rect.top;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
const Point16 &VisualElement::getCachedAbsoluteOrigin() const {
|
||||
return _cachedAbsoluteOrigin;
|
||||
}
|
||||
|
||||
@@ -1958,6 +1958,7 @@ public:
|
||||
bool readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) override;
|
||||
MiniscriptInstructionOutcome writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &writeProxy, const Common::String &attrib) override;
|
||||
|
||||
Point16 getGlobalPosition() const;
|
||||
const Rect16 &getRelativeRect() const;
|
||||
|
||||
// The cached absolute origin is from the last time the element was rendered.
|
||||
@@ -2055,7 +2056,7 @@ protected:
|
||||
bool loadTypicalHeader(const Data::TypicalModifierHeader &typicalHeader);
|
||||
|
||||
// Links any references contained in the object, resolving static GUIDs to runtime object references.
|
||||
// If you override this, you must override visitInternalReferences too.
|
||||
// If you override this, you should override visitInternalReferences too
|
||||
virtual void linkInternalReferences(ObjectLinkingScope *scope);
|
||||
|
||||
Structural *findStructuralOwner() const;
|
||||
@@ -2096,6 +2097,7 @@ enum AssetType {
|
||||
kAssetTypeColorTable,
|
||||
kAssetTypeImage,
|
||||
kAssetTypeText,
|
||||
kAssetTypeMToon,
|
||||
};
|
||||
|
||||
class Asset {
|
||||
|
||||
Reference in New Issue
Block a user