mirror of
https://github.com/BlackMATov/unity-flash-tools.git
synced 2025-12-16 14:11:19 +07:00
going to open source
This commit is contained in:
9
Assets/FlashTools/Scripts/Editor.meta
Normal file
9
Assets/FlashTools/Scripts/Editor.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 375e159432167410dac4df7b3aaa8fe7
|
||||
folderAsset: yes
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/FlashTools/Scripts/Editor/FTEditor.meta
Normal file
9
Assets/FlashTools/Scripts/Editor/FTEditor.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 292a672830f014d76b53010b24758fbc
|
||||
folderAsset: yes
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/FlashTools/Scripts/Editor/FTEditor/Editors.meta
Normal file
9
Assets/FlashTools/Scripts/Editor/FTEditor/Editors.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba8836e9d384f4971947dcafb1aea47f
|
||||
folderAsset: yes
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,155 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor.Editors {
|
||||
[CustomEditor(typeof(SwfAsset)), CanEditMultipleObjects]
|
||||
class SwfAssetEditor : Editor {
|
||||
List<SwfAsset> _assets = new List<SwfAsset>();
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
static SwfSettings _settingsHolder = null;
|
||||
static SwfSettings GetSettingsHolder() {
|
||||
if ( !_settingsHolder ) {
|
||||
_settingsHolder = SwfEditorUtils.GetSettingsHolder();
|
||||
}
|
||||
return _settingsHolder;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
static void RevertOverriddenSettings(SwfAsset asset) {
|
||||
asset.Overridden = asset.Settings;
|
||||
}
|
||||
|
||||
static void OverriddenSettingsToDefault(SwfAsset asset) {
|
||||
asset.Overridden = GetSettingsHolder().Settings;
|
||||
}
|
||||
|
||||
static void ApplyOverriddenSettings(SwfAsset asset) {
|
||||
asset.Settings = asset.Overridden;
|
||||
ReconvertAsset(asset);
|
||||
}
|
||||
|
||||
static void ReconvertAsset(SwfAsset asset) {
|
||||
asset.Converting = new SwfAsset.ConvertingState();
|
||||
AssetDatabase.ImportAsset(
|
||||
AssetDatabase.GetAssetPath(asset));
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void AllAssetsForeach(System.Action<SwfAsset> act) {
|
||||
foreach ( var asset in _assets ) {
|
||||
act(asset);
|
||||
}
|
||||
}
|
||||
|
||||
void AllOverriddenSettingsToDefault() {
|
||||
AllAssetsForeach(p => OverriddenSettingsToDefault(p));
|
||||
}
|
||||
|
||||
void RevertAllOverriddenSettings() {
|
||||
AllAssetsForeach(p => RevertOverriddenSettings(p));
|
||||
}
|
||||
|
||||
void ApplyAllOverriddenSettings() {
|
||||
AllAssetsForeach(p => ApplyOverriddenSettings(p));
|
||||
}
|
||||
|
||||
void ReconvertAllAsset() {
|
||||
AllAssetsForeach(p => ReconvertAsset(p));
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void ShowUnappliedDialog() {
|
||||
var unapplied = _assets
|
||||
.Where(p => !p.Settings.CheckEquals(p.Overridden))
|
||||
.ToArray();
|
||||
if ( unapplied.Length > 0 ) {
|
||||
var title =
|
||||
"Unapplied swf asset settings";
|
||||
var message = unapplied.Length == 1
|
||||
? string.Format(
|
||||
"Unapplied swf asset settings for '{0}'",
|
||||
AssetDatabase.GetAssetPath(unapplied[0]))
|
||||
: string.Format(
|
||||
"Unapplied multiple({0}) swf asset settings",
|
||||
unapplied.Length);
|
||||
if ( EditorUtility.DisplayDialog(title, message, "Apply", "Revert") ) {
|
||||
ApplyAllOverriddenSettings();
|
||||
} else {
|
||||
RevertAllOverriddenSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGUISettingsControls() {
|
||||
var prop = SwfEditorUtils.GetPropertyByName(serializedObject, "Overridden");
|
||||
if ( prop.isExpanded ) {
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
if ( GUILayout.Button("Reconvert") ) {
|
||||
ReconvertAllAsset();
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
var default_settings = GetSettingsHolder().Settings;
|
||||
SwfEditorUtils.DoWithEnabledGUI(
|
||||
_assets.Any(p => !p.Overridden.CheckEquals(default_settings)), () => {
|
||||
if ( GUILayout.Button("Default") ) {
|
||||
AllOverriddenSettingsToDefault();
|
||||
}
|
||||
});
|
||||
SwfEditorUtils.DoWithEnabledGUI(
|
||||
_assets.Any(p => !p.Overridden.CheckEquals(p.Settings)), () => {
|
||||
if ( GUILayout.Button("Revert") ) {
|
||||
RevertAllOverriddenSettings();
|
||||
}
|
||||
if ( GUILayout.Button("Apply") ) {
|
||||
ApplyAllOverriddenSettings();
|
||||
}
|
||||
});
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Messages
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void OnEnable() {
|
||||
_assets = targets.OfType<SwfAsset>().ToList();
|
||||
}
|
||||
|
||||
void OnDisable() {
|
||||
ShowUnappliedDialog();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
serializedObject.Update();
|
||||
DrawDefaultInspector();
|
||||
DrawGUISettingsControls();
|
||||
if ( GUI.changed ) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d55bf9e0b44904ca59050d854a38c7ee
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,160 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor.Editors {
|
||||
[CustomEditor(typeof(SwfClipAsset)), CanEditMultipleObjects]
|
||||
class SwfClipAssetEditor : Editor {
|
||||
List<SwfClipAsset> _clips = new List<SwfClipAsset>();
|
||||
|
||||
static string GetClipPath(SwfClipAsset clip) {
|
||||
return clip
|
||||
? AssetDatabase.GetAssetPath(clip)
|
||||
: string.Empty;
|
||||
}
|
||||
|
||||
static string GetPrefabPath(SwfClipAsset clip) {
|
||||
var clip_path = GetClipPath(clip);
|
||||
return string.IsNullOrEmpty(clip_path)
|
||||
? string.Empty
|
||||
: Path.ChangeExtension(clip_path, ".prefab");
|
||||
}
|
||||
|
||||
static int GetFrameCount(SwfClipAsset clip) {
|
||||
return clip != null ? clip.Sequences.Aggregate(0, (acc, seq) => {
|
||||
return seq.Frames.Count + acc;
|
||||
}) : 0;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
static GameObject CreateClipGO(SwfClipAsset clip) {
|
||||
if ( clip ) {
|
||||
var clip_go = new GameObject(clip.name);
|
||||
clip_go.AddComponent<MeshFilter>();
|
||||
clip_go.AddComponent<MeshRenderer>();
|
||||
clip_go.AddComponent<SwfClip>().clip = clip;
|
||||
clip_go.AddComponent<SwfClipController>();
|
||||
return clip_go;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static GameObject CreateClipPrefab(SwfClipAsset clip) {
|
||||
GameObject result = null;
|
||||
var clip_go = CreateClipGO(clip);
|
||||
if ( clip_go ) {
|
||||
var prefab_path = GetPrefabPath(clip);
|
||||
if ( !string.IsNullOrEmpty(prefab_path) ) {
|
||||
var prefab = AssetDatabase.LoadMainAssetAtPath(prefab_path);
|
||||
if ( !prefab ) {
|
||||
prefab = PrefabUtility.CreateEmptyPrefab(prefab_path);
|
||||
}
|
||||
result = PrefabUtility.ReplacePrefab(
|
||||
clip_go,
|
||||
prefab,
|
||||
ReplacePrefabOptions.ConnectToPrefab);
|
||||
}
|
||||
GameObject.DestroyImmediate(clip_go, true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static GameObject CreateClipOnScene(SwfClipAsset clip) {
|
||||
var clip_go = CreateClipGO(clip);
|
||||
if ( clip_go ) {
|
||||
Undo.RegisterCreatedObjectUndo(clip_go, "Instance SwfClip");
|
||||
}
|
||||
return clip_go;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void CreateAllClipsPrefabs() {
|
||||
Selection.objects = _clips
|
||||
.Select (p => CreateClipPrefab(p))
|
||||
.Where (p => !!p)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
void CreateAllClipsOnScene() {
|
||||
Selection.objects = _clips
|
||||
.Select (p => CreateClipOnScene(p))
|
||||
.Where (p => !!p)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void DrawGUIFrameCount() {
|
||||
var counts = _clips.Select(p => GetFrameCount(p));
|
||||
var mixed_value = counts.GroupBy(p => p).Count() > 1;
|
||||
SwfEditorUtils.DoWithEnabledGUI(false, () => {
|
||||
SwfEditorUtils.DoWithMixedValue(
|
||||
mixed_value, () => {
|
||||
EditorGUILayout.IntField("Frame count", counts.First());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void DrawGUISequences() {
|
||||
SwfEditorUtils.DoWithEnabledGUI(false, () => {
|
||||
var sequences_prop = SwfEditorUtils.GetPropertyByName(
|
||||
serializedObject, "Sequences");
|
||||
if ( sequences_prop.isArray ) {
|
||||
SwfEditorUtils.DoWithMixedValue(
|
||||
sequences_prop.hasMultipleDifferentValues, () => {
|
||||
EditorGUILayout.IntField("Sequence count", sequences_prop.arraySize);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DrawGUIControls() {
|
||||
SwfEditorUtils.DoHorizontalGUI(() => {
|
||||
if ( GUILayout.Button("Create prefab") ) {
|
||||
CreateAllClipsPrefabs();
|
||||
}
|
||||
if ( GUILayout.Button("Instance to scene") ) {
|
||||
CreateAllClipsOnScene();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Messages
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void OnEnable() {
|
||||
_clips = targets.OfType<SwfClipAsset>().ToList();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
serializedObject.Update();
|
||||
DrawDefaultInspector();
|
||||
DrawGUIFrameCount();
|
||||
DrawGUISequences();
|
||||
DrawGUIControls();
|
||||
if ( GUI.changed ) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RequiresConstantRepaint() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26665058b9a1e41898442585e385c3f3
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,181 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.Linq;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor.Editors {
|
||||
[CustomPreview(typeof(SwfClipAsset))]
|
||||
class SwfClipAssetPreview : ObjectPreview {
|
||||
int _sequence = 0;
|
||||
static MaterialPropertyBlock _matPropBlock = null;
|
||||
static PreviewRenderUtility _previewUtils = null;
|
||||
|
||||
Texture2D targetAtlas {
|
||||
get {
|
||||
var clip = target as SwfClipAsset;
|
||||
return clip.Atlas;
|
||||
}
|
||||
}
|
||||
|
||||
int targetSequenceCount {
|
||||
get {
|
||||
var clip = target as SwfClipAsset;
|
||||
return clip && clip.Sequences != null
|
||||
? clip.Sequences.Count
|
||||
: 0;
|
||||
}
|
||||
}
|
||||
|
||||
SwfClipAsset.Frame targetFrame {
|
||||
get {
|
||||
var clip = target as SwfClipAsset;
|
||||
return GetFrameForClip(clip, _sequence);
|
||||
}
|
||||
}
|
||||
|
||||
SwfClipAsset.Sequence targetSequence {
|
||||
get {
|
||||
var clip = target as SwfClipAsset;
|
||||
return GetSequenceForClip(clip, _sequence);
|
||||
}
|
||||
}
|
||||
|
||||
bool isTargetValidForPreview {
|
||||
get {
|
||||
var atlas = targetAtlas;
|
||||
var frame = targetFrame;
|
||||
var sequence = targetSequence;
|
||||
return
|
||||
atlas &&
|
||||
frame != null &&
|
||||
sequence != null &&
|
||||
frame.CachedMesh && frame.CachedMesh.vertexCount > 0;
|
||||
}
|
||||
}
|
||||
|
||||
static SwfClipAsset.Frame GetFrameForClip(SwfClipAsset clip, int sequence_index) {
|
||||
var sequence = GetSequenceForClip(clip, sequence_index);
|
||||
var frames = sequence != null && sequence.Frames != null && sequence.Frames.Count > 0
|
||||
? sequence.Frames
|
||||
: null;
|
||||
var frame_time = (float)(EditorApplication.timeSinceStartup * clip.FrameRate);
|
||||
return frames != null
|
||||
? frames[Mathf.FloorToInt(frame_time) % frames.Count]
|
||||
: null;
|
||||
}
|
||||
|
||||
static SwfClipAsset.Sequence GetSequenceForClip(SwfClipAsset clip, int sequence_index) {
|
||||
return clip && clip.Sequences != null && clip.Sequences.Count > 0
|
||||
? clip.Sequences[Mathf.Abs(sequence_index) % clip.Sequences.Count]
|
||||
: null;
|
||||
}
|
||||
|
||||
static Bounds CalculateBoundsForSequence(SwfClipAsset.Sequence sequence) {
|
||||
var bounds = sequence != null && sequence.Frames != null && sequence.Frames.Count > 0
|
||||
? sequence.Frames
|
||||
.Where (p => !!p.CachedMesh)
|
||||
.Select(p => p.CachedMesh.bounds)
|
||||
: new Bounds[0];
|
||||
var result = bounds.Any() ? bounds.First() : new Bounds();
|
||||
foreach ( var bound in bounds ) {
|
||||
result.Encapsulate(bound);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ConfigureCameraForSequence(Camera camera, SwfClipAsset.Sequence sequence) {
|
||||
var bounds = CalculateBoundsForSequence(sequence);
|
||||
camera.orthographic = true;
|
||||
camera.orthographicSize = Mathf.Max(
|
||||
Mathf.Abs(bounds.extents.x),
|
||||
Mathf.Abs(bounds.extents.y));
|
||||
camera.transform.position = new Vector3(
|
||||
bounds.center.x,
|
||||
bounds.center.y,
|
||||
-10.0f);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Functions
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
public void SetCurrentSequence(string sequence_name) {
|
||||
var clip = target as SwfClipAsset;
|
||||
_sequence = clip && clip.Sequences != null
|
||||
? Mathf.Max(0, clip.Sequences.FindIndex(p => p.Name == sequence_name))
|
||||
: 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Messages
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
public override void Initialize(Object[] targets) {
|
||||
base.Initialize(targets);
|
||||
if ( _matPropBlock == null ) {
|
||||
_matPropBlock = new MaterialPropertyBlock();
|
||||
}
|
||||
if ( _previewUtils == null ) {
|
||||
_previewUtils = new PreviewRenderUtility();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HasPreviewGUI() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnPreviewSettings() {
|
||||
var any_multi_sequences = m_Targets
|
||||
.OfType<SwfClipAsset>()
|
||||
.Any(p => p.Sequences != null && p.Sequences.Count > 1);
|
||||
if ( any_multi_sequences && GUILayout.Button("<", EditorStyles.miniButton) ) {
|
||||
--_sequence;
|
||||
}
|
||||
var sequence_names = m_Targets
|
||||
.OfType<SwfClipAsset>()
|
||||
.Select (p => GetSequenceForClip(p, _sequence))
|
||||
.Where (p => p != null && !string.IsNullOrEmpty(p.Name))
|
||||
.Select (p => p.Name)
|
||||
.ToArray();
|
||||
var label_text = string.Empty;
|
||||
for ( int i = 0, e = sequence_names.Length; i < e; ++i ) {
|
||||
label_text += string.Format(
|
||||
i < e - 1 ? "{0}, " : "{0}",
|
||||
sequence_names[i]);
|
||||
}
|
||||
GUILayout.Label(label_text, EditorStyles.whiteLabel);
|
||||
if ( any_multi_sequences && GUILayout.Button(">", EditorStyles.miniButton) ) {
|
||||
++_sequence;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPreviewGUI(Rect r, GUIStyle background) {
|
||||
if ( Event.current.type == EventType.Repaint ) {
|
||||
if ( isTargetValidForPreview ) {
|
||||
_previewUtils.BeginPreview(r, background);
|
||||
{
|
||||
_matPropBlock.SetTexture("_MainTex", targetAtlas);
|
||||
ConfigureCameraForSequence(_previewUtils.m_Camera, targetSequence);
|
||||
var frame = targetFrame;
|
||||
for ( var i = 0; i < frame.Materials.Length; ++i ) {
|
||||
_previewUtils.DrawMesh(
|
||||
frame.CachedMesh,
|
||||
Matrix4x4.identity,
|
||||
frame.Materials[i],
|
||||
i,
|
||||
_matPropBlock);
|
||||
}
|
||||
_previewUtils.m_Camera.Render();
|
||||
}
|
||||
_previewUtils.EndAndDrawPreview(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fa4b268ac7aa477c9124c699ed8c587
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,59 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor.Editors {
|
||||
[CustomEditor(typeof(SwfClipController)), CanEditMultipleObjects]
|
||||
class SwfClipControllerEditor : Editor {
|
||||
List<SwfClipController> _controllers = new List<SwfClipController>();
|
||||
|
||||
void AllControllersForeach(System.Action<SwfClipController> act) {
|
||||
foreach ( var controller in _controllers ) {
|
||||
act(controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawClipControls() {
|
||||
SwfEditorUtils.DoRightHorizontalGUI(() => {
|
||||
if ( GUILayout.Button("Stop") ) {
|
||||
AllControllersForeach(ctrl => ctrl.Stop(ctrl.isStopped));
|
||||
}
|
||||
if ( GUILayout.Button("Play") ) {
|
||||
AllControllersForeach(ctrl => {
|
||||
var rewind =
|
||||
ctrl.isPlaying ||
|
||||
(ctrl.clip && (
|
||||
ctrl.clip.currentFrame == 0 ||
|
||||
ctrl.clip.currentFrame == ctrl.clip.frameCount - 1));
|
||||
ctrl.Play(rewind);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Messages
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void OnEnable() {
|
||||
_controllers = targets.OfType<SwfClipController>().ToList();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
serializedObject.Update();
|
||||
DrawDefaultInspector();
|
||||
if ( Application.isPlaying ) {
|
||||
DrawClipControls();
|
||||
}
|
||||
if ( GUI.changed ) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f581647bb7c7410ba28f97fd2814e7f
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,183 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor.Editors {
|
||||
[CustomEditor(typeof(SwfClip)), CanEditMultipleObjects]
|
||||
class SwfClipEditor : Editor {
|
||||
List<SwfClip> _clips = new List<SwfClip>();
|
||||
Dictionary<SwfClip, SwfClipAssetPreview> _previews = new Dictionary<SwfClip, SwfClipAssetPreview>();
|
||||
|
||||
void AllClipsForeachWithUndo(System.Action<SwfClip> act) {
|
||||
Undo.RecordObjects(_clips.ToArray(), "Inspector");
|
||||
foreach ( var clip in _clips ) {
|
||||
act(clip);
|
||||
EditorUtility.SetDirty(clip);
|
||||
}
|
||||
}
|
||||
|
||||
int GetMinClipsFrameCount() {
|
||||
return _clips.Count > 0
|
||||
? _clips.Min(clip => clip.frameCount)
|
||||
: 0;
|
||||
}
|
||||
|
||||
string GetClipsFrameCountStr() {
|
||||
return _clips.Aggregate(string.Empty, (acc, clip) => {
|
||||
var frame_count = clip.frameCount > 0 ? clip.frameCount - 1 : 0;
|
||||
var frame_count_str = frame_count.ToString();
|
||||
return string.IsNullOrEmpty(acc)
|
||||
? frame_count_str
|
||||
: (acc != frame_count_str ? "--" : acc);
|
||||
});
|
||||
}
|
||||
|
||||
string GetClipsCurrentFrameStr() {
|
||||
return _clips.Aggregate(string.Empty, (acc, clip) => {
|
||||
var current_frame = clip.currentFrame;
|
||||
var current_frame_str = current_frame.ToString();
|
||||
return string.IsNullOrEmpty(acc)
|
||||
? current_frame_str
|
||||
: (acc != current_frame_str ? "--" : acc);
|
||||
});
|
||||
}
|
||||
|
||||
List<string> GetAllSequences(bool include_empty) {
|
||||
var result = new List<string>();
|
||||
var result_clips = _clips
|
||||
.Where (p => p.clip && p.clip.Sequences.Count > 0)
|
||||
.Select(p => p.clip.Sequences)
|
||||
.Where (p => p.All(s => !string.IsNullOrEmpty(s.Name)))
|
||||
.ToList();
|
||||
if ( result_clips.Count > 0 ) {
|
||||
result = result_clips.First()
|
||||
.Select(p => p.Name)
|
||||
.ToList();
|
||||
var sequences_enum = result_clips
|
||||
.Select(p => p.Select(s => s.Name));
|
||||
foreach ( var sequences in sequences_enum ) {
|
||||
result = result
|
||||
.Where(p => sequences.Contains(p))
|
||||
.ToList();
|
||||
}
|
||||
if ( include_empty ) {
|
||||
result.Add(string.Empty);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DrawSequence() {
|
||||
var all_sequences = GetAllSequences(true);
|
||||
if ( all_sequences.Count > 0 ) {
|
||||
var sequence_prop = SwfEditorUtils.GetPropertyByName(serializedObject, "_sequence");
|
||||
SwfEditorUtils.DoWithMixedValue(
|
||||
sequence_prop.hasMultipleDifferentValues, () => {
|
||||
var sequence_index = EditorGUILayout.Popup(
|
||||
"Sequence",
|
||||
sequence_prop.hasMultipleDifferentValues
|
||||
? all_sequences.FindIndex(p => string.IsNullOrEmpty(p))
|
||||
: all_sequences.FindIndex(p => p == sequence_prop.stringValue),
|
||||
all_sequences.ToArray());
|
||||
if ( sequence_index >= 0 && sequence_index < all_sequences.Count ) {
|
||||
var new_sequence = all_sequences[sequence_index];
|
||||
if ( !string.IsNullOrEmpty(new_sequence) ) {
|
||||
if ( sequence_prop.hasMultipleDifferentValues ) {
|
||||
sequence_prop.stringValue = string.Empty;
|
||||
}
|
||||
sequence_prop.stringValue = new_sequence;
|
||||
sequence_prop.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCurrentFrame() {
|
||||
var min_frame_count = GetMinClipsFrameCount();
|
||||
if ( min_frame_count > 1 ) {
|
||||
EditorGUILayout.IntSlider(
|
||||
SwfEditorUtils.GetPropertyByName(serializedObject, "_currentFrame"),
|
||||
0,
|
||||
min_frame_count - 1,
|
||||
"Current frame");
|
||||
DrawClipControls();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawClipControls() {
|
||||
EditorGUILayout.Space();
|
||||
SwfEditorUtils.DoCenterHorizontalGUI(() => {
|
||||
if ( GUILayout.Button(new GUIContent("<<", "to begin frame")) ) {
|
||||
AllClipsForeachWithUndo(p => p.ToBeginFrame());
|
||||
}
|
||||
if ( GUILayout.Button(new GUIContent("<", "to prev frame")) ) {
|
||||
AllClipsForeachWithUndo(p => p.ToPrevFrame());
|
||||
}
|
||||
GUILayout.Label(string.Format(
|
||||
"{0}/{1}",
|
||||
GetClipsCurrentFrameStr(), GetClipsFrameCountStr()));
|
||||
if ( GUILayout.Button(new GUIContent(">", "to next frame")) ) {
|
||||
AllClipsForeachWithUndo(p => p.ToNextFrame());
|
||||
}
|
||||
if ( GUILayout.Button(new GUIContent(">>", "to end frame")) ) {
|
||||
AllClipsForeachWithUndo(p => p.ToEndFrame());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SetupPreviews() {
|
||||
_previews.Clear();
|
||||
foreach ( var clip in _clips.Where(p => !!p.clip) ) {
|
||||
var preview = new SwfClipAssetPreview();
|
||||
preview.Initialize(new Object[]{clip.clip});
|
||||
_previews.Add(clip, preview);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Messages
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void OnEnable() {
|
||||
_clips = targets.OfType<SwfClip>().ToList();
|
||||
SetupPreviews();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
serializedObject.Update();
|
||||
DrawDefaultInspector();
|
||||
DrawSequence();
|
||||
DrawCurrentFrame();
|
||||
if ( GUI.changed ) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
SetupPreviews();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RequiresConstantRepaint() {
|
||||
return _previews.Count > 0;
|
||||
}
|
||||
|
||||
public override bool HasPreviewGUI() {
|
||||
return _previews.Count > 0;
|
||||
}
|
||||
|
||||
public override void OnPreviewGUI(Rect r, GUIStyle background) {
|
||||
if ( Event.current.type == EventType.Repaint ) {
|
||||
SwfClipAssetPreview preview;
|
||||
var clip = target as SwfClip;
|
||||
if ( _previews.TryGetValue(clip, out preview) ) {
|
||||
preview.SetCurrentSequence(clip.sequence);
|
||||
preview.DrawPreview(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e0ef7f54bc3b41dfabc308afe051fd2
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,101 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor.Editors {
|
||||
[CustomEditor(typeof(SwfManager))]
|
||||
class SwfManagerEditor : Editor {
|
||||
SwfManager _manager = null;
|
||||
List<SwfClipController> _controllers = new List<SwfClipController>();
|
||||
bool _groupsFoldout = true;
|
||||
|
||||
void DrawCounts() {
|
||||
SwfEditorUtils.DoWithEnabledGUI(false, () => {
|
||||
EditorGUILayout.IntField(
|
||||
"Clip count",
|
||||
_manager.clipCount);
|
||||
EditorGUILayout.IntField(
|
||||
"Controller count",
|
||||
_manager.controllerCount);
|
||||
});
|
||||
}
|
||||
|
||||
void DrawControls() {
|
||||
SwfEditorUtils.DoRightHorizontalGUI(() => {
|
||||
if ( _manager.isPaused && GUILayout.Button("Resume") ) {
|
||||
_manager.Resume();
|
||||
}
|
||||
if ( _manager.isPlaying && GUILayout.Button("Pause") ) {
|
||||
_manager.Pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DrawGroupControls() {
|
||||
var group_names = GetAllGroupNames();
|
||||
if ( group_names.Count > 0 ) {
|
||||
_groupsFoldout = EditorGUILayout.Foldout(_groupsFoldout, "Groups");
|
||||
if ( _groupsFoldout ) {
|
||||
foreach ( var group_name in group_names ) {
|
||||
SwfEditorUtils.DoWithEnabledGUI(false, () => {
|
||||
EditorGUILayout.TextField("Name", group_name);
|
||||
});
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var new_rate_scale = EditorGUILayout.FloatField(
|
||||
"Rate Scale", _manager.GetGroupRateScale(group_name));
|
||||
if ( EditorGUI.EndChangeCheck() ) {
|
||||
_manager.SetGroupRateScale(group_name, new_rate_scale);
|
||||
}
|
||||
SwfEditorUtils.DoRightHorizontalGUI(() => {
|
||||
if ( _manager.IsGroupPaused(group_name) && GUILayout.Button("Resume") ) {
|
||||
_manager.ResumeGroup(group_name);
|
||||
}
|
||||
if ( _manager.IsGroupPlaying(group_name) && GUILayout.Button("Pause") ) {
|
||||
_manager.PauseGroup(group_name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<string> GetAllGroupNames() {
|
||||
var result = new HashSet<string>();
|
||||
for ( int i = 0, e = _controllers.Count; i < e; ++i ) {
|
||||
var ctrl = _controllers[i];
|
||||
if ( !string.IsNullOrEmpty(ctrl.groupName) ) {
|
||||
result.Add(ctrl.groupName);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Messages
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
void OnEnable() {
|
||||
_manager = target as SwfManager;
|
||||
_controllers = FindObjectsOfType<SwfClipController>().ToList();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
serializedObject.Update();
|
||||
DrawDefaultInspector();
|
||||
DrawCounts();
|
||||
if ( Application.isPlaying ) {
|
||||
DrawControls();
|
||||
DrawGroupControls();
|
||||
}
|
||||
if ( GUI.changed ) {
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07f1613b2510442e7bd34a0536c758cd
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ae552573a6744241b163082c98af911
|
||||
folderAsset: yes
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,473 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor.Postprocessors {
|
||||
class SwfAssetPostprocessor : AssetPostprocessor {
|
||||
static void OnPostprocessAllAssets(
|
||||
string[] imported_assets,
|
||||
string[] deleted_assets,
|
||||
string[] moved_assets,
|
||||
string[] moved_from_asset_paths)
|
||||
{
|
||||
var asset_paths = imported_assets
|
||||
.Where(p => Path.GetExtension(p).ToLower().Equals(".asset"));
|
||||
foreach ( var asset_path in asset_paths ) {
|
||||
var asset = AssetDatabase.LoadAssetAtPath<SwfAsset>(asset_path);
|
||||
if ( asset ) {
|
||||
SwfAssetProcess(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SwfAssetProcess(SwfAsset asset) {
|
||||
try {
|
||||
if ( asset.Converting.Stage == 0 ) {
|
||||
var new_data = ConfigureBitmaps(
|
||||
asset,
|
||||
SwfEditorUtils.DecompressAsset<SwfAssetData>(asset.Data));
|
||||
asset.Data = SwfEditorUtils.CompressAsset(new_data);
|
||||
++asset.Converting.Stage;
|
||||
EditorUtility.SetDirty(asset);
|
||||
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(asset));
|
||||
} else if ( asset.Converting.Stage == 1 ) {
|
||||
asset.Atlas = LoadAssetAtlas(asset);
|
||||
if ( asset.Atlas ) {
|
||||
ConfigureAtlas(asset);
|
||||
ConfigureClips(
|
||||
asset,
|
||||
SwfEditorUtils.DecompressAsset<SwfAssetData>(asset.Data));
|
||||
}
|
||||
++asset.Converting.Stage;
|
||||
EditorUtility.SetDirty(asset);
|
||||
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(asset));
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
Debug.LogErrorFormat(
|
||||
"<b>[FlashTools]</b> Postprocess swf asset error: {0}",
|
||||
e.Message);
|
||||
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(asset));
|
||||
} finally {
|
||||
if ( asset ) {
|
||||
UpdateAssetClips(asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Texture2D LoadAssetAtlas(SwfAsset asset) {
|
||||
return AssetDatabase.LoadAssetAtPath<Texture2D>(
|
||||
GetAtlasPath(asset));
|
||||
}
|
||||
|
||||
static string GetAtlasPath(SwfAsset asset) {
|
||||
if ( asset.Atlas ) {
|
||||
return AssetDatabase.GetAssetPath(asset.Atlas);
|
||||
} else {
|
||||
var asset_path = AssetDatabase.GetAssetPath(asset);
|
||||
return Path.ChangeExtension(asset_path, "._Atlas_.png");
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// ConfigureBitmaps
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static SwfAssetData ConfigureBitmaps(SwfAsset asset, SwfAssetData data) {
|
||||
var textures = data.Bitmaps
|
||||
.Where (p => p.Redirect == 0)
|
||||
.Select (p => new KeyValuePair<ushort, Texture2D>(
|
||||
p.Id,
|
||||
LoadTextureFromData(p)))
|
||||
.ToList();
|
||||
var rects = PackAndSaveBitmapsAtlas(
|
||||
GetAtlasPath(asset),
|
||||
textures.Select(p => p.Value).ToArray(),
|
||||
asset.Settings);
|
||||
for ( var i = 0; i < data.Bitmaps.Count; ++i ) {
|
||||
var bitmap = data.Bitmaps[i];
|
||||
var texture_key = bitmap.Redirect > 0 ? bitmap.Redirect : bitmap.Id;
|
||||
bitmap.SourceRect = SwfRectData.FromURect(
|
||||
rects[textures.FindIndex(p => p.Key == texture_key)]);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static Texture2D LoadTextureFromData(SwfBitmapData bitmap) {
|
||||
var texture = new Texture2D(
|
||||
bitmap.RealWidth, bitmap.RealHeight,
|
||||
TextureFormat.ARGB32, false);
|
||||
texture.LoadRawTextureData(bitmap.ARGB32);
|
||||
return texture;
|
||||
}
|
||||
|
||||
struct BitmapsAtlasInfo {
|
||||
public Texture2D Atlas;
|
||||
public Rect[] Rects;
|
||||
}
|
||||
|
||||
static Rect[] PackAndSaveBitmapsAtlas(
|
||||
string atlas_path, Texture2D[] textures, SwfSettingsData settings)
|
||||
{
|
||||
var atlas_info = PackBitmapsAtlas(textures, settings);
|
||||
RevertTexturePremultipliedAlpha(atlas_info.Atlas);
|
||||
File.WriteAllBytes(atlas_path, atlas_info.Atlas.EncodeToPNG());
|
||||
GameObject.DestroyImmediate(atlas_info.Atlas, true);
|
||||
AssetDatabase.ImportAsset(atlas_path);
|
||||
return atlas_info.Rects;
|
||||
}
|
||||
|
||||
static BitmapsAtlasInfo PackBitmapsAtlas(
|
||||
Texture2D[] textures, SwfSettingsData settings)
|
||||
{
|
||||
var atlas_padding = Mathf.Max(0, settings.AtlasPadding);
|
||||
var max_atlas_size = Mathf.Max(32, settings.AtlasPowerOfTwo
|
||||
? Mathf.ClosestPowerOfTwo(settings.MaxAtlasSize)
|
||||
: settings.MaxAtlasSize);
|
||||
var atlas = new Texture2D(0, 0);
|
||||
var rects = atlas.PackTextures(textures, atlas_padding, max_atlas_size);
|
||||
while ( rects == null ) {
|
||||
max_atlas_size = Mathf.NextPowerOfTwo(max_atlas_size + 1);
|
||||
rects = atlas.PackTextures(textures, atlas_padding, max_atlas_size);
|
||||
}
|
||||
return settings.AtlasForceSquare && atlas.width != atlas.height
|
||||
? BitmapsAtlasToSquare(atlas, rects)
|
||||
: new BitmapsAtlasInfo{Atlas = atlas, Rects = rects};
|
||||
}
|
||||
|
||||
static BitmapsAtlasInfo BitmapsAtlasToSquare(Texture2D atlas, Rect[] rects) {
|
||||
var atlas_size = Mathf.Max(atlas.width, atlas.height);
|
||||
var atlas_scale = new Vector2(atlas.width, atlas.height) / atlas_size;
|
||||
var new_atlas = new Texture2D(atlas_size, atlas_size, TextureFormat.ARGB32, false);
|
||||
for ( var i = 0; i < rects.Length; ++i ) {
|
||||
var new_position = rects[i].position;
|
||||
new_position.Scale(atlas_scale);
|
||||
var new_size = rects[i].size;
|
||||
new_size.Scale(atlas_scale);
|
||||
rects[i] = new Rect(new_position, new_size);
|
||||
}
|
||||
var fill_pixels = new Color32[atlas_size * atlas_size];
|
||||
for ( var i = 0; i < atlas_size * atlas_size; ++i ) {
|
||||
fill_pixels[i] = new Color(1,1,1,0);
|
||||
}
|
||||
new_atlas.SetPixels32(fill_pixels);
|
||||
new_atlas.SetPixels32(0, 0, atlas.width, atlas.height, atlas.GetPixels32());
|
||||
new_atlas.Apply();
|
||||
GameObject.DestroyImmediate(atlas, true);
|
||||
return new BitmapsAtlasInfo{
|
||||
Atlas = new_atlas,
|
||||
Rects = rects};
|
||||
}
|
||||
|
||||
static void RevertTexturePremultipliedAlpha(Texture2D texture) {
|
||||
var pixels = texture.GetPixels();
|
||||
for ( var i = 0; i < pixels.Length; ++i ) {
|
||||
var c = pixels[i];
|
||||
if ( c.a > 0 ) {
|
||||
c.r /= c.a;
|
||||
c.g /= c.a;
|
||||
c.b /= c.a;
|
||||
}
|
||||
pixels[i] = c;
|
||||
}
|
||||
texture.SetPixels(pixels);
|
||||
texture.Apply();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// ConfigureAtlas
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static void ConfigureAtlas(SwfAsset asset) {
|
||||
var atlas_path = AssetDatabase.GetAssetPath(asset.Atlas);
|
||||
var atlas_importer = GetBitmapsAtlasImporter(asset);
|
||||
atlas_importer.spritesheet = new SpriteMetaData[0];
|
||||
atlas_importer.textureType = TextureImporterType.Sprite;
|
||||
atlas_importer.spriteImportMode = SpriteImportMode.Multiple;
|
||||
atlas_importer.spritePixelsPerUnit = asset.Settings.PixelsPerUnit;
|
||||
atlas_importer.mipmapEnabled = asset.Settings.GenerateMipMaps;
|
||||
atlas_importer.filterMode = SwfAtlasFilterToImporterFilter(asset.Settings.AtlasTextureFilter);
|
||||
atlas_importer.textureFormat = SwfAtlasFormatToImporterFormat(asset.Settings.AtlasTextureFormat);
|
||||
AssetDatabase.WriteImportSettingsIfDirty(atlas_path);
|
||||
AssetDatabase.ImportAsset(atlas_path);
|
||||
}
|
||||
|
||||
static TextureImporter GetBitmapsAtlasImporter(SwfAsset asset) {
|
||||
var atlas_path = AssetDatabase.GetAssetPath(asset.Atlas);
|
||||
var atlas_importer = AssetImporter.GetAtPath(atlas_path) as TextureImporter;
|
||||
if ( !atlas_importer ) {
|
||||
throw new UnityException(string.Format(
|
||||
"atlas texture importer not found ({0})",
|
||||
atlas_path));
|
||||
}
|
||||
return atlas_importer;
|
||||
}
|
||||
|
||||
static FilterMode SwfAtlasFilterToImporterFilter(
|
||||
SwfSettingsData.AtlasFilter filter)
|
||||
{
|
||||
switch ( filter ) {
|
||||
case SwfSettingsData.AtlasFilter.Point:
|
||||
return FilterMode.Point;
|
||||
case SwfSettingsData.AtlasFilter.Bilinear:
|
||||
return FilterMode.Bilinear;
|
||||
case SwfSettingsData.AtlasFilter.Trilinear:
|
||||
return FilterMode.Trilinear;
|
||||
default:
|
||||
throw new UnityException(string.Format(
|
||||
"incorrect swf atlas filter ({0})",
|
||||
filter));
|
||||
}
|
||||
}
|
||||
|
||||
static TextureImporterFormat SwfAtlasFormatToImporterFormat(
|
||||
SwfSettingsData.AtlasFormat format)
|
||||
{
|
||||
switch ( format ) {
|
||||
case SwfSettingsData.AtlasFormat.AutomaticCompressed:
|
||||
return TextureImporterFormat.AutomaticCompressed;
|
||||
case SwfSettingsData.AtlasFormat.Automatic16bit:
|
||||
return TextureImporterFormat.Automatic16bit;
|
||||
case SwfSettingsData.AtlasFormat.AutomaticTruecolor:
|
||||
return TextureImporterFormat.AutomaticTruecolor;
|
||||
case SwfSettingsData.AtlasFormat.AutomaticCrunched:
|
||||
return TextureImporterFormat.AutomaticCrunched;
|
||||
default:
|
||||
throw new UnityException(string.Format(
|
||||
"incorrect swf atlas format ({0})",
|
||||
format));
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// ConfigureClips
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static SwfAssetData ConfigureClips(SwfAsset asset, SwfAssetData data) {
|
||||
asset.Clips = asset.Clips.Where(p => !!p).Distinct().ToList();
|
||||
foreach ( var symbol in data.Symbols ) {
|
||||
ConfigureClip(asset, data, symbol);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static void ConfigureClip(SwfAsset asset, SwfAssetData data, SwfSymbolData symbol) {
|
||||
var clip_asset = asset.Clips.FirstOrDefault(p => p.Name == symbol.Name);
|
||||
if ( clip_asset ) {
|
||||
ConfigureClipAsset(clip_asset, asset, data, symbol);
|
||||
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(clip_asset));
|
||||
} else {
|
||||
var asset_path = AssetDatabase.GetAssetPath(asset);
|
||||
var clip_asset_path = Path.ChangeExtension(asset_path, symbol.Name + ".asset");
|
||||
SwfEditorUtils.LoadOrCreateAsset<SwfClipAsset>(clip_asset_path, (new_clip_asset, created) => {
|
||||
ConfigureClipAsset(new_clip_asset, asset, data, symbol);
|
||||
asset.Clips.Add(new_clip_asset);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void ConfigureClipAsset(
|
||||
SwfClipAsset clip_asset, SwfAsset asset, SwfAssetData data, SwfSymbolData symbol)
|
||||
{
|
||||
clip_asset.Name = symbol.Name;
|
||||
clip_asset.Atlas = asset.Atlas;
|
||||
clip_asset.FrameRate = data.FrameRate;
|
||||
clip_asset.Sequences = LoadClipSequences(asset, data, symbol);
|
||||
}
|
||||
|
||||
static List<SwfClipAsset.Sequence> LoadClipSequences(
|
||||
SwfAsset asset, SwfAssetData data, SwfSymbolData symbol)
|
||||
{
|
||||
var sequences = new List<SwfClipAsset.Sequence>();
|
||||
if ( IsValidAssetsForFrame(asset, symbol) ) {
|
||||
foreach ( var frame in symbol.Frames ) {
|
||||
var baked_frame = BakeClipFrame(asset, data, frame);
|
||||
if ( !string.IsNullOrEmpty(frame.Name) &&
|
||||
(sequences.Count < 1 || sequences.Last().Name != frame.Name) )
|
||||
{
|
||||
sequences.Add(new SwfClipAsset.Sequence{Name = frame.Name});
|
||||
} else if ( sequences.Count < 1 ) {
|
||||
sequences.Add(new SwfClipAsset.Sequence{Name = "Default"});
|
||||
}
|
||||
sequences.Last().Frames.Add(baked_frame);
|
||||
}
|
||||
}
|
||||
return sequences;
|
||||
}
|
||||
|
||||
static bool IsValidAssetsForFrame(
|
||||
SwfAsset asset, SwfSymbolData symbol)
|
||||
{
|
||||
return
|
||||
asset && asset.Atlas && asset.Data != null &&
|
||||
symbol != null && symbol.Frames != null;
|
||||
}
|
||||
|
||||
class BakedGroup {
|
||||
public SwfInstanceData.Types Type;
|
||||
public SwfBlendModeData.Types BlendMode;
|
||||
public int ClipDepth;
|
||||
public int StartVertex;
|
||||
public int TriangleCount;
|
||||
public Material Material;
|
||||
}
|
||||
|
||||
static SwfClipAsset.Frame BakeClipFrame(
|
||||
SwfAsset asset, SwfAssetData data, SwfFrameData frame)
|
||||
{
|
||||
List<uint> baked_uvs = new List<uint>();
|
||||
List<uint> baked_mulcolors = new List<uint>();
|
||||
List<uint> baked_addcolors = new List<uint>();
|
||||
List<Vector2> baked_vertices = new List<Vector2>();
|
||||
List<BakedGroup> baked_groups = new List<BakedGroup>();
|
||||
List<Material> baked_materials = new List<Material>();
|
||||
|
||||
foreach ( var inst in frame.Instances ) {
|
||||
var bitmap = inst != null
|
||||
? FindBitmapFromAssetData(data, inst.Bitmap)
|
||||
: null;
|
||||
if ( bitmap != null && IsVisibleInstance(inst) ) {
|
||||
var width = bitmap.RealWidth / 20.0f;
|
||||
var height = bitmap.RealHeight / 20.0f;
|
||||
|
||||
var v0 = new Vector2( 0, 0);
|
||||
var v1 = new Vector2(width, 0);
|
||||
var v2 = new Vector2(width, height);
|
||||
var v3 = new Vector2( 0, height);
|
||||
|
||||
var matrix =
|
||||
Matrix4x4.Scale(
|
||||
new Vector3(1.0f, -1.0f, 1.0f) /
|
||||
asset.Settings.PixelsPerUnit) *
|
||||
inst.Matrix.ToUMatrix();
|
||||
|
||||
baked_vertices.Add(matrix.MultiplyPoint3x4(v0));
|
||||
baked_vertices.Add(matrix.MultiplyPoint3x4(v1));
|
||||
baked_vertices.Add(matrix.MultiplyPoint3x4(v2));
|
||||
baked_vertices.Add(matrix.MultiplyPoint3x4(v3));
|
||||
|
||||
var source_rect = bitmap.SourceRect;
|
||||
baked_uvs.Add(SwfEditorUtils.PackUV(source_rect.xMin, source_rect.yMin));
|
||||
baked_uvs.Add(SwfEditorUtils.PackUV(source_rect.xMax, source_rect.yMax));
|
||||
|
||||
uint mul_pack0, mul_pack1;
|
||||
SwfEditorUtils.PackFColorToUInts(
|
||||
inst.ColorTrans.mulColor.ToUVector4(),
|
||||
out mul_pack0, out mul_pack1);
|
||||
baked_mulcolors.Add(mul_pack0);
|
||||
baked_mulcolors.Add(mul_pack1);
|
||||
|
||||
uint add_pack0, add_pack1;
|
||||
SwfEditorUtils.PackFColorToUInts(
|
||||
inst.ColorTrans.addColor.ToUVector4(),
|
||||
out add_pack0, out add_pack1);
|
||||
baked_addcolors.Add(add_pack0);
|
||||
baked_addcolors.Add(add_pack1);
|
||||
|
||||
if ( baked_groups.Count == 0 ||
|
||||
baked_groups[baked_groups.Count - 1].Type != inst.Type ||
|
||||
baked_groups[baked_groups.Count - 1].BlendMode != inst.BlendMode.type ||
|
||||
baked_groups[baked_groups.Count - 1].ClipDepth != inst.ClipDepth )
|
||||
{
|
||||
baked_groups.Add(new BakedGroup{
|
||||
Type = inst.Type,
|
||||
BlendMode = inst.BlendMode.type,
|
||||
ClipDepth = inst.ClipDepth,
|
||||
StartVertex = baked_vertices.Count - 4,
|
||||
TriangleCount = 0,
|
||||
Material = null
|
||||
});
|
||||
}
|
||||
|
||||
baked_groups.Last().TriangleCount += 6;
|
||||
}
|
||||
}
|
||||
|
||||
for ( var i = 0; i < baked_groups.Count; ++i ) {
|
||||
var group = baked_groups[i];
|
||||
switch ( group.Type ) {
|
||||
case SwfInstanceData.Types.Mask:
|
||||
group.Material = SwfMaterialCache.GetIncrMaskMaterial();
|
||||
break;
|
||||
case SwfInstanceData.Types.Group:
|
||||
group.Material = SwfMaterialCache.GetSimpleMaterial(group.BlendMode);
|
||||
break;
|
||||
case SwfInstanceData.Types.Masked:
|
||||
group.Material = SwfMaterialCache.GetMaskedMaterial(group.BlendMode, group.ClipDepth);
|
||||
break;
|
||||
case SwfInstanceData.Types.MaskReset:
|
||||
group.Material = SwfMaterialCache.GetDecrMaskMaterial();
|
||||
break;
|
||||
default:
|
||||
throw new UnityException(string.Format(
|
||||
"SwfAssetPostprocessor. Incorrect instance type: {0}",
|
||||
group.Type));
|
||||
}
|
||||
if ( group.Material ) {
|
||||
baked_materials.Add(group.Material);
|
||||
} else {
|
||||
throw new UnityException(string.Format(
|
||||
"SwfAssetPostprocessor. Material for baked group ({0}) not found",
|
||||
group.Type));
|
||||
}
|
||||
}
|
||||
|
||||
var mesh_data = new SwfClipAsset.MeshData{
|
||||
SubMeshes = baked_groups
|
||||
.Select(p => new SwfClipAsset.SubMeshData{
|
||||
StartVertex = p.StartVertex,
|
||||
IndexCount = p.TriangleCount})
|
||||
.ToArray(),
|
||||
Vertices = baked_vertices .ToArray(),
|
||||
UVs = baked_uvs .ToArray(),
|
||||
AddColors = baked_addcolors.ToArray(),
|
||||
MulColors = baked_mulcolors.ToArray()};
|
||||
|
||||
return new SwfClipAsset.Frame(
|
||||
mesh_data,
|
||||
baked_materials.ToArray());
|
||||
}
|
||||
|
||||
static SwfBitmapData FindBitmapFromAssetData(SwfAssetData data, int bitmap_id) {
|
||||
for ( var i = 0; i < data.Bitmaps.Count; ++i ) {
|
||||
var bitmap = data.Bitmaps[i];
|
||||
if ( bitmap.Id == bitmap_id ) {
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static bool IsVisibleInstance(SwfInstanceData inst) {
|
||||
var result_color = inst.ColorTrans.ApplyToColor(Color.white);
|
||||
return result_color.a >= 0.01f;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// UpdateAssetClips
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static void UpdateAssetClips(SwfAsset asset) {
|
||||
var clips = GameObject.FindObjectsOfType<SwfClip>();
|
||||
foreach ( var clip in clips ) {
|
||||
if ( clip && clip.clip && asset.Clips.Contains(clip.clip) ) {
|
||||
clip.Internal_UpdateAllProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8344a58599edb42cc92b9e64ea6e5082
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,382 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
using FTSwfTools;
|
||||
using FTSwfTools.SwfTags;
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTEditor.Postprocessors {
|
||||
class SwfPostprocessor : AssetPostprocessor {
|
||||
static void OnPostprocessAllAssets(
|
||||
string[] imported_assets,
|
||||
string[] deleted_assets,
|
||||
string[] moved_assets,
|
||||
string[] moved_from_asset_paths)
|
||||
{
|
||||
var swf_paths = imported_assets
|
||||
.Where(p => Path.GetExtension(p).ToLower().Equals(".swf"));
|
||||
if ( swf_paths.Any() && SwfEditorUtils.IsDemoEnded ) {
|
||||
var title = "Demo version";
|
||||
var message =
|
||||
"This demo is for evaluation purpose only. " +
|
||||
"It means that you can't have more than 5 animation assets in the project.";
|
||||
EditorUtility.DisplayDialog(title, message, "Ok");
|
||||
} else {
|
||||
foreach ( var swf_path in swf_paths ) {
|
||||
SwfFileProcess(swf_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SwfFileProcess(string swf_path) {
|
||||
var swf_asset_path = Path.ChangeExtension(swf_path, ".asset");
|
||||
SwfEditorUtils.LoadOrCreateAsset<SwfAsset>(swf_asset_path, (swf_asset, created) => {
|
||||
if ( created ) {
|
||||
var default_settings = SwfEditorUtils.GetSettingsHolder().Settings;
|
||||
swf_asset.Settings = default_settings;
|
||||
swf_asset.Overridden = default_settings;
|
||||
}
|
||||
return SafeLoadSwfAsset(swf_path, swf_asset);
|
||||
});
|
||||
}
|
||||
|
||||
static bool SafeLoadSwfAsset(string swf_path, SwfAsset swf_asset) {
|
||||
try {
|
||||
var new_data = LoadSwfAssetData(swf_path);
|
||||
swf_asset.Data = SwfEditorUtils.CompressAsset(new_data);
|
||||
swf_asset.Converting = new SwfAsset.ConvertingState();
|
||||
return true;
|
||||
} catch ( Exception e ) {
|
||||
Debug.LogErrorFormat(
|
||||
"<b>[FlashTools]</b> Parsing swf error: {0}",
|
||||
e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static SwfAssetData LoadSwfAssetData(string swf_path) {
|
||||
var library = new SwfLibrary();
|
||||
var decoder = new SwfDecoder(swf_path);
|
||||
return new SwfAssetData{
|
||||
FrameRate = decoder.UncompressedHeader.FrameRate,
|
||||
Symbols = LoadSymbols(library, decoder),
|
||||
Bitmaps = LoadBitmaps(library)};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// LoadSymbols
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static List<SwfSymbolData> LoadSymbols(
|
||||
SwfLibrary library, SwfDecoder decoder)
|
||||
{
|
||||
var symbols = new List<SwfSymbolData>();
|
||||
symbols.Add(LoadSymbol("_Stage_", library, decoder.Tags));
|
||||
var sprite_defs = library.Defines.Values
|
||||
.OfType<SwfLibrarySpriteDefine>()
|
||||
.Where(p => !string.IsNullOrEmpty(p.ExportName));
|
||||
foreach ( var sprite_def in sprite_defs ) {
|
||||
var name = sprite_def.ExportName;
|
||||
var tags = sprite_def.ControlTags.Tags;
|
||||
symbols.Add(LoadSymbol(name, library, tags));
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
||||
static SwfSymbolData LoadSymbol(
|
||||
string symbol_name, SwfLibrary library, List<SwfTagBase> tags)
|
||||
{
|
||||
var disp_lst = new SwfDisplayList();
|
||||
var executer = new SwfContextExecuter(library, 0, warning_msg => {
|
||||
Debug.LogWarningFormat("<b>[FlashTools]</b> {0}", warning_msg);
|
||||
});
|
||||
var symbol_frames = new List<SwfFrameData>();
|
||||
while ( executer.NextFrame(tags, disp_lst) ) {
|
||||
symbol_frames.Add(LoadSymbolFrameData(library, disp_lst));
|
||||
}
|
||||
return new SwfSymbolData{
|
||||
Name = symbol_name,
|
||||
Frames = symbol_frames};
|
||||
}
|
||||
|
||||
static SwfFrameData LoadSymbolFrameData(
|
||||
SwfLibrary library, SwfDisplayList display_list)
|
||||
{
|
||||
var frame = new SwfFrameData();
|
||||
frame.Name = display_list.FrameName;
|
||||
return AddDisplayListToFrame(
|
||||
library,
|
||||
display_list,
|
||||
Matrix4x4.identity,
|
||||
SwfBlendModeData.identity,
|
||||
SwfColorTransData.identity,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
frame);
|
||||
}
|
||||
|
||||
static SwfFrameData AddDisplayListToFrame(
|
||||
SwfLibrary library,
|
||||
SwfDisplayList display_list,
|
||||
Matrix4x4 parent_matrix,
|
||||
SwfBlendModeData parent_blend_mode,
|
||||
SwfColorTransData parent_color_transform,
|
||||
ushort parent_masked,
|
||||
ushort parent_mask,
|
||||
List<SwfInstanceData> parent_masks,
|
||||
SwfFrameData frame)
|
||||
{
|
||||
var inst_filter_types = display_list.Instances.Values
|
||||
.Where(p => p.Visible && p.FilterList.Filters.Count > 0)
|
||||
.SelectMany(p => p.FilterList.Filters)
|
||||
.Select(p => p.Type)
|
||||
.Distinct();
|
||||
foreach ( var filter_type in inst_filter_types ) {
|
||||
Debug.LogWarningFormat(
|
||||
"<b>[FlashTools]</b> SwfSurfaceFilters. Unsupported filter type '{0}'",
|
||||
filter_type);
|
||||
}
|
||||
var self_masks = new List<SwfInstanceData>();
|
||||
foreach ( var inst in display_list.Instances.Values.Where(p => p.Visible) ) {
|
||||
CheckSelfMasks(self_masks, inst.Depth, frame);
|
||||
var child_matrix = parent_matrix * inst.Matrix .ToUMatrix();
|
||||
var child_blend_mode = parent_blend_mode * inst.BlendMode .ToBlendModeData();
|
||||
var child_color_transform = parent_color_transform * inst.ColorTransform.ToColorTransData();
|
||||
switch ( inst.Type ) {
|
||||
case SwfDisplayInstanceType.Shape:
|
||||
AddShapeInstanceToFrame(
|
||||
library,
|
||||
inst as SwfDisplayShapeInstance,
|
||||
child_matrix,
|
||||
child_blend_mode,
|
||||
child_color_transform,
|
||||
parent_masked,
|
||||
parent_mask,
|
||||
parent_masks,
|
||||
self_masks,
|
||||
frame);
|
||||
break;
|
||||
case SwfDisplayInstanceType.Sprite:
|
||||
AddSpriteInstanceToFrame(
|
||||
library,
|
||||
inst as SwfDisplaySpriteInstance,
|
||||
child_matrix,
|
||||
child_blend_mode,
|
||||
child_color_transform,
|
||||
parent_masked,
|
||||
parent_mask,
|
||||
parent_masks,
|
||||
self_masks,
|
||||
frame);
|
||||
break;
|
||||
default:
|
||||
throw new UnityException(string.Format(
|
||||
"unsupported SwfDisplayInstanceType: {0}", inst.Type));
|
||||
}
|
||||
}
|
||||
CheckSelfMasks(self_masks, ushort.MaxValue, frame);
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void AddShapeInstanceToFrame(
|
||||
SwfLibrary library,
|
||||
SwfDisplayShapeInstance inst,
|
||||
Matrix4x4 inst_matrix,
|
||||
SwfBlendModeData inst_blend_mode,
|
||||
SwfColorTransData inst_color_transform,
|
||||
ushort parent_masked,
|
||||
ushort parent_mask,
|
||||
List<SwfInstanceData> parent_masks,
|
||||
List<SwfInstanceData> self_masks,
|
||||
SwfFrameData frame)
|
||||
{
|
||||
var shape_def = library.FindDefine<SwfLibraryShapeDefine>(inst.Id);
|
||||
if ( shape_def != null ) {
|
||||
for ( var i = 0; i < shape_def.Bitmaps.Length; ++i ) {
|
||||
var bitmap_id = shape_def.Bitmaps[i];
|
||||
var bitmap_matrix = i < shape_def.Matrices.Length ? shape_def.Matrices[i] : SwfMatrix.identity;
|
||||
var bitmap_def = library.FindDefine<SwfLibraryBitmapDefine>(bitmap_id);
|
||||
if ( bitmap_def != null ) {
|
||||
var frame_inst_type =
|
||||
(parent_mask > 0 || inst.ClipDepth > 0)
|
||||
? SwfInstanceData.Types.Mask
|
||||
: (parent_masked > 0 || self_masks.Count > 0)
|
||||
? SwfInstanceData.Types.Masked
|
||||
: SwfInstanceData.Types.Group;
|
||||
var frame_inst_clip_depth =
|
||||
(parent_mask > 0)
|
||||
? parent_mask
|
||||
: (inst.ClipDepth > 0)
|
||||
? inst.ClipDepth
|
||||
: parent_masked + self_masks.Count;
|
||||
frame.Instances.Add(new SwfInstanceData{
|
||||
Type = frame_inst_type,
|
||||
ClipDepth = (ushort)frame_inst_clip_depth,
|
||||
Bitmap = bitmap_id,
|
||||
Matrix = SwfMatrixData.FromUMatrix(inst_matrix * bitmap_matrix.ToUMatrix()),
|
||||
BlendMode = inst_blend_mode,
|
||||
ColorTrans = inst_color_transform});
|
||||
if ( parent_mask > 0 ) {
|
||||
parent_masks.Add(frame.Instances[frame.Instances.Count - 1]);
|
||||
} else if ( inst.ClipDepth > 0 ) {
|
||||
self_masks.Add(frame.Instances[frame.Instances.Count - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void AddSpriteInstanceToFrame(
|
||||
SwfLibrary library,
|
||||
SwfDisplaySpriteInstance inst,
|
||||
Matrix4x4 inst_matrix,
|
||||
SwfBlendModeData inst_blend_mode,
|
||||
SwfColorTransData inst_color_transform,
|
||||
ushort parent_masked,
|
||||
ushort parent_mask,
|
||||
List<SwfInstanceData> parent_masks,
|
||||
List<SwfInstanceData> self_masks,
|
||||
SwfFrameData frame)
|
||||
{
|
||||
var sprite_def = library.FindDefine<SwfLibrarySpriteDefine>(inst.Id);
|
||||
if ( sprite_def != null ) {
|
||||
AddDisplayListToFrame(
|
||||
library,
|
||||
inst.DisplayList,
|
||||
inst_matrix,
|
||||
inst_blend_mode,
|
||||
inst_color_transform,
|
||||
(ushort)(parent_masked + self_masks.Count),
|
||||
(ushort)(parent_mask > 0
|
||||
? parent_mask
|
||||
: (inst.ClipDepth > 0
|
||||
? inst.ClipDepth
|
||||
: (ushort)0)),
|
||||
parent_mask > 0
|
||||
? parent_masks
|
||||
: (inst.ClipDepth > 0
|
||||
? self_masks
|
||||
: null),
|
||||
frame);
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckSelfMasks(
|
||||
List<SwfInstanceData> masks,
|
||||
ushort depth,
|
||||
SwfFrameData frame)
|
||||
{
|
||||
foreach ( var mask in masks ) {
|
||||
if ( mask.ClipDepth < depth ) {
|
||||
frame.Instances.Add(new SwfInstanceData{
|
||||
Type = SwfInstanceData.Types.MaskReset,
|
||||
ClipDepth = 0,
|
||||
Bitmap = mask.Bitmap,
|
||||
Matrix = mask.Matrix,
|
||||
BlendMode = mask.BlendMode,
|
||||
ColorTrans = mask.ColorTrans});
|
||||
}
|
||||
}
|
||||
masks.RemoveAll(p => p.ClipDepth < depth);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// LoadBitmaps
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static List<SwfBitmapData> LoadBitmaps(SwfLibrary library) {
|
||||
return library.Defines
|
||||
.Where (p => p.Value.Type == SwfLibraryDefineType.Bitmap)
|
||||
.ToDictionary(p => p.Key, p => p.Value as SwfLibraryBitmapDefine)
|
||||
.Select (p => new SwfBitmapData{
|
||||
Id = p.Key,
|
||||
ARGB32 = p.Value.ARGB32,
|
||||
Redirect = p.Value.Redirect,
|
||||
RealWidth = p.Value.Width,
|
||||
RealHeight = p.Value.Height})
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Extensions
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static class SwfExtensions {
|
||||
public static Matrix4x4 ToUMatrix(this SwfMatrix self) {
|
||||
var mat = Matrix4x4.identity;
|
||||
mat.m00 = self.ScaleX;
|
||||
mat.m10 = self.RotateSkew0;
|
||||
mat.m01 = self.RotateSkew1;
|
||||
mat.m11 = self.ScaleY;
|
||||
mat.m03 = self.TranslateX;
|
||||
mat.m13 = self.TranslateY;
|
||||
return mat;
|
||||
}
|
||||
|
||||
public static SwfBlendModeData ToBlendModeData(this SwfBlendMode self) {
|
||||
switch ( self.Value ) {
|
||||
case SwfBlendMode.Mode.Normal:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Normal);
|
||||
case SwfBlendMode.Mode.Layer:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Layer);
|
||||
case SwfBlendMode.Mode.Multiply:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Multiply);
|
||||
case SwfBlendMode.Mode.Screen:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Screen);
|
||||
case SwfBlendMode.Mode.Lighten:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Lighten);
|
||||
case SwfBlendMode.Mode.Darken:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Darken);
|
||||
case SwfBlendMode.Mode.Difference:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Difference);
|
||||
case SwfBlendMode.Mode.Add:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Add);
|
||||
case SwfBlendMode.Mode.Subtract:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Subtract);
|
||||
case SwfBlendMode.Mode.Invert:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Invert);
|
||||
case SwfBlendMode.Mode.Hardlight:
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Hardlight);
|
||||
default:
|
||||
Debug.LogWarningFormat(
|
||||
"<b>[FlashTools]</b> SwfBlendMode. Unsupported blend mode '{0}'",
|
||||
self.Value);
|
||||
return new SwfBlendModeData(SwfBlendModeData.Types.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
public static SwfColorTransData ToColorTransData(this SwfColorTransform self) {
|
||||
var trans = SwfColorTransData.identity;
|
||||
if ( self.HasAdd ) {
|
||||
trans.addColor = new SwfVec4Data(
|
||||
self.RAdd / 256.0f,
|
||||
self.GAdd / 256.0f,
|
||||
self.BAdd / 256.0f,
|
||||
self.AAdd / 256.0f);
|
||||
}
|
||||
if ( self.HasMul ) {
|
||||
trans.mulColor = new SwfVec4Data(
|
||||
self.RMul / 256.0f,
|
||||
self.GMul / 256.0f,
|
||||
self.BMul / 256.0f,
|
||||
self.AMul / 256.0f);
|
||||
}
|
||||
return trans;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed0eb44dfd3664ec285a25c6d03aae05
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
234
Assets/FlashTools/Scripts/Editor/FTEditor/SwfAssetData.cs
Normal file
234
Assets/FlashTools/Scripts/Editor/FTEditor/SwfAssetData.cs
Normal file
@@ -0,0 +1,234 @@
|
||||
using UnityEngine;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FTEditor {
|
||||
[System.Serializable]
|
||||
struct SwfVec2Data {
|
||||
public float x;
|
||||
public float y;
|
||||
|
||||
public SwfVec2Data(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Vector2 ToUVector2() {
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
public static SwfVec2Data one {
|
||||
get { return new SwfVec2Data(1.0f, 1.0f); }
|
||||
}
|
||||
|
||||
public static SwfVec2Data zero {
|
||||
get { return new SwfVec2Data(0.0f, 0.0f); }
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
struct SwfVec4Data {
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
public float w;
|
||||
|
||||
public SwfVec4Data(float x, float y, float z, float w) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
public Vector4 ToUVector4() {
|
||||
return new Vector4(x, y, z, w);
|
||||
}
|
||||
|
||||
public static SwfVec4Data one {
|
||||
get { return new SwfVec4Data(1.0f, 1.0f, 1.0f, 1.0f); }
|
||||
}
|
||||
|
||||
public static SwfVec4Data zero {
|
||||
get { return new SwfVec4Data(0.0f, 0.0f, 0.0f, 0.0f); }
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
struct SwfRectData {
|
||||
public float xMin;
|
||||
public float xMax;
|
||||
public float yMin;
|
||||
public float yMax;
|
||||
|
||||
public static SwfRectData identity {
|
||||
get {
|
||||
return new SwfRectData{
|
||||
xMin = 0.0f,
|
||||
xMax = 0.0f,
|
||||
yMin = 0.0f,
|
||||
yMax = 0.0f};
|
||||
}
|
||||
}
|
||||
|
||||
public static SwfRectData FromURect(Rect rect) {
|
||||
return new SwfRectData{
|
||||
xMin = rect.xMin,
|
||||
xMax = rect.xMax,
|
||||
yMin = rect.yMin,
|
||||
yMax = rect.yMax};
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
struct SwfMatrixData {
|
||||
public SwfVec2Data sc;
|
||||
public SwfVec2Data sk;
|
||||
public SwfVec2Data tr;
|
||||
|
||||
public static SwfMatrixData identity {
|
||||
get {
|
||||
return new SwfMatrixData{
|
||||
sc = SwfVec2Data.one,
|
||||
sk = SwfVec2Data.zero,
|
||||
tr = SwfVec2Data.zero};
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix4x4 ToUMatrix() {
|
||||
var mat = Matrix4x4.identity;
|
||||
mat.m00 = sc.x;
|
||||
mat.m11 = sc.y;
|
||||
mat.m10 = sk.x;
|
||||
mat.m01 = sk.y;
|
||||
mat.m03 = tr.x;
|
||||
mat.m13 = tr.y;
|
||||
return mat;
|
||||
}
|
||||
|
||||
public static SwfMatrixData FromUMatrix(Matrix4x4 mat) {
|
||||
return new SwfMatrixData{
|
||||
sc = new SwfVec2Data(mat.m00, mat.m11),
|
||||
sk = new SwfVec2Data(mat.m10, mat.m01),
|
||||
tr = new SwfVec2Data(mat.m03, mat.m13)};
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
struct SwfBlendModeData {
|
||||
public enum Types : byte {
|
||||
Normal,
|
||||
Layer,
|
||||
Multiply,
|
||||
Screen,
|
||||
Lighten,
|
||||
Darken, // GrabPass
|
||||
Difference, // GrabPass
|
||||
Add,
|
||||
Subtract,
|
||||
Invert, // GrabPass
|
||||
Overlay, // GrabPass
|
||||
Hardlight // GrabPass
|
||||
}
|
||||
public Types type;
|
||||
|
||||
public SwfBlendModeData(Types type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static SwfBlendModeData identity {
|
||||
get {
|
||||
return new SwfBlendModeData{
|
||||
type = Types.Normal};
|
||||
}
|
||||
}
|
||||
|
||||
public static SwfBlendModeData operator*(
|
||||
SwfBlendModeData a, SwfBlendModeData b)
|
||||
{
|
||||
return (a.type == Types.Normal || a.type == Types.Layer) ? b : a;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
struct SwfColorTransData {
|
||||
public SwfVec4Data mulColor;
|
||||
public SwfVec4Data addColor;
|
||||
|
||||
public Color ApplyToColor(Color color) {
|
||||
return new Color(
|
||||
Mathf.Clamp01(color.r * mulColor.x + addColor.x),
|
||||
Mathf.Clamp01(color.g * mulColor.y + addColor.y),
|
||||
Mathf.Clamp01(color.b * mulColor.z + addColor.z),
|
||||
Mathf.Clamp01(color.a * mulColor.w + addColor.w));
|
||||
}
|
||||
|
||||
public static SwfColorTransData identity {
|
||||
get {
|
||||
return new SwfColorTransData{
|
||||
mulColor = SwfVec4Data.one,
|
||||
addColor = SwfVec4Data.zero};
|
||||
}
|
||||
}
|
||||
|
||||
public static SwfColorTransData operator*(
|
||||
SwfColorTransData a, SwfColorTransData b)
|
||||
{
|
||||
return new SwfColorTransData{
|
||||
mulColor = new SwfVec4Data(
|
||||
b.mulColor.x * a.mulColor.x,
|
||||
b.mulColor.y * a.mulColor.y,
|
||||
b.mulColor.z * a.mulColor.z,
|
||||
b.mulColor.w * a.mulColor.w),
|
||||
addColor = new SwfVec4Data(
|
||||
b.addColor.x * a.mulColor.x + a.addColor.x,
|
||||
b.addColor.y * a.mulColor.y + a.addColor.y,
|
||||
b.addColor.z * a.mulColor.z + a.addColor.z,
|
||||
b.addColor.w * a.mulColor.w + a.addColor.w)};
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
class SwfInstanceData {
|
||||
public enum Types {
|
||||
Mask,
|
||||
Group,
|
||||
Masked,
|
||||
MaskReset
|
||||
}
|
||||
public Types Type = Types.Group;
|
||||
public ushort ClipDepth = 0;
|
||||
public ushort Bitmap = 0;
|
||||
public SwfMatrixData Matrix = SwfMatrixData.identity;
|
||||
public SwfBlendModeData BlendMode = SwfBlendModeData.identity;
|
||||
public SwfColorTransData ColorTrans = SwfColorTransData.identity;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
class SwfFrameData {
|
||||
public string Name = string.Empty;
|
||||
public List<SwfInstanceData> Instances = new List<SwfInstanceData>();
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
class SwfSymbolData {
|
||||
public string Name = string.Empty;
|
||||
public List<SwfFrameData> Frames = new List<SwfFrameData>();
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
class SwfBitmapData {
|
||||
public ushort Id = 0;
|
||||
public byte[] ARGB32 = new byte[0];
|
||||
public ushort Redirect = 0;
|
||||
public int RealWidth = 0;
|
||||
public int RealHeight = 0;
|
||||
public SwfRectData SourceRect = SwfRectData.identity;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
class SwfAssetData {
|
||||
public float FrameRate = 0.0f;
|
||||
public List<SwfSymbolData> Symbols = new List<SwfSymbolData>();
|
||||
public List<SwfBitmapData> Bitmaps = new List<SwfBitmapData>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f0cc1765946b4a178442797df0acaf7
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
274
Assets/FlashTools/Scripts/Editor/FTEditor/SwfEditorUtils.cs
Normal file
274
Assets/FlashTools/Scripts/Editor/FTEditor/SwfEditorUtils.cs
Normal file
@@ -0,0 +1,274 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
using Ionic.Zlib;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor {
|
||||
static class SwfEditorUtils {
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Packing
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
const ushort UShortMax = ushort.MaxValue;
|
||||
const float FColorPrecision = 1.0f / 512.0f;
|
||||
|
||||
public static uint PackUV(float u, float v) {
|
||||
var uu = (uint)(Mathf.Clamp01(u) * UShortMax);
|
||||
var vv = (uint)(Mathf.Clamp01(v) * UShortMax);
|
||||
return (uu << 16) + vv;
|
||||
}
|
||||
|
||||
public static ushort PackFloatColorToUShort(float v) {
|
||||
return (ushort)Mathf.Clamp(
|
||||
v * (1.0f / FColorPrecision),
|
||||
short.MinValue,
|
||||
short.MaxValue);
|
||||
}
|
||||
|
||||
public static uint PackUShortsToUInt(ushort x, ushort y) {
|
||||
var xx = (uint)x;
|
||||
var yy = (uint)y;
|
||||
return (xx << 16) + yy;
|
||||
}
|
||||
|
||||
public static void PackFColorToUInts(
|
||||
Color v,
|
||||
out uint pack0, out uint pack1)
|
||||
{
|
||||
PackFColorToUInts(v.r, v.g, v.b, v.a, out pack0, out pack1);
|
||||
}
|
||||
|
||||
public static void PackFColorToUInts(
|
||||
Vector4 v,
|
||||
out uint pack0, out uint pack1)
|
||||
{
|
||||
PackFColorToUInts(v.x, v.y, v.z, v.w, out pack0, out pack1);
|
||||
}
|
||||
|
||||
public static void PackFColorToUInts(
|
||||
float v0, float v1, float v2, float v3,
|
||||
out uint pack0, out uint pack1)
|
||||
{
|
||||
pack0 = PackUShortsToUInt(
|
||||
PackFloatColorToUShort(v0),
|
||||
PackFloatColorToUShort(v1));
|
||||
pack1 = PackUShortsToUInt(
|
||||
PackFloatColorToUShort(v2),
|
||||
PackFloatColorToUShort(v3));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Inspector
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
public static void DoWithMixedValue(bool mixed, System.Action act) {
|
||||
var last_show_mixed_value = EditorGUI.showMixedValue;
|
||||
EditorGUI.showMixedValue = mixed;
|
||||
try {
|
||||
act();
|
||||
} finally {
|
||||
EditorGUI.showMixedValue = last_show_mixed_value;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoWithEnabledGUI(bool enabled, System.Action act) {
|
||||
EditorGUI.BeginDisabledGroup(!enabled);
|
||||
try {
|
||||
act();
|
||||
} finally {
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoHorizontalGUI(System.Action act) {
|
||||
GUILayout.BeginHorizontal();
|
||||
try {
|
||||
act();
|
||||
} finally {
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoRightHorizontalGUI(System.Action act) {
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
try {
|
||||
act();
|
||||
} finally {
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoCenterHorizontalGUI(System.Action act) {
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
try {
|
||||
act();
|
||||
} finally {
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
public static SerializedProperty GetPropertyByName(SerializedObject obj, string name) {
|
||||
var prop = obj.FindProperty(name);
|
||||
if ( prop == null ) {
|
||||
throw new UnityException(string.Format(
|
||||
"SwfEditorUtils. Not found property: {0}",
|
||||
name));
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Assets
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
public static SwfSettings GetSettingsHolder() {
|
||||
var holder = LoadFirstAssetByFilter<SwfSettings>("t:SwfSettings");
|
||||
if ( !holder ) {
|
||||
throw new UnityException(
|
||||
"SwfEditorUtils. SwfSettings asset not found");
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
|
||||
public static T LoadOrCreateAsset<T>(string asset_path, System.Func<T, bool, bool> act) where T : ScriptableObject {
|
||||
var asset = AssetDatabase.LoadAssetAtPath<T>(asset_path);
|
||||
if ( asset ) {
|
||||
if ( act(asset, false) ) {
|
||||
EditorUtility.SetDirty(asset);
|
||||
AssetDatabase.ImportAsset(asset_path);
|
||||
}
|
||||
} else {
|
||||
asset = ScriptableObject.CreateInstance<T>();
|
||||
if ( act(asset, true) ) {
|
||||
AssetDatabase.CreateAsset(asset, asset_path);
|
||||
AssetDatabase.ImportAsset(asset_path);
|
||||
} else {
|
||||
ScriptableObject.DestroyImmediate(asset);
|
||||
}
|
||||
}
|
||||
return asset;
|
||||
}
|
||||
|
||||
public static T LoadFirstAssetByFilter<T>(string filter) where T : UnityEngine.Object {
|
||||
var guids = AssetDatabase.FindAssets(filter);
|
||||
foreach ( var guid in guids ) {
|
||||
var path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
var asset = AssetDatabase.LoadAssetAtPath<T>(path);
|
||||
if ( asset ) {
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] CompressAsset<T>(T asset) {
|
||||
var bytes = AssetToBytes(asset);
|
||||
var result = ZlibStream.CompressBuffer(bytes);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T DecompressAsset<T>(byte[] data) {
|
||||
var bytes = ZlibStream.UncompressBuffer(data);
|
||||
var result = BytesToAsset<T>(bytes);
|
||||
return result;
|
||||
}
|
||||
|
||||
static byte[] AssetToBytes<T>(T asset) {
|
||||
var formatter = new BinaryFormatter();
|
||||
using ( var stream = new MemoryStream() ) {
|
||||
formatter.Serialize(stream, asset);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
static T BytesToAsset<T>(byte[] bytes) {
|
||||
var formatter = new BinaryFormatter();
|
||||
using ( var stream = new MemoryStream(bytes) ) {
|
||||
return (T)formatter.Deserialize(stream);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Demo
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
#if FT_VERSION_DEMO
|
||||
public static bool IsDemoEnded {
|
||||
get {
|
||||
var guids = AssetDatabase.FindAssets("t:SwfAsset");
|
||||
return guids.Length >= 5;
|
||||
}
|
||||
}
|
||||
#else
|
||||
public static bool IsDemoEnded {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
[MenuItem("Tools/FlashTools/Open settings...")]
|
||||
static void Tools_FlashTools_OpenSettings() {
|
||||
var settings_holder = SwfEditorUtils.GetSettingsHolder();
|
||||
Selection.objects = new Object[]{settings_holder};
|
||||
}
|
||||
|
||||
[MenuItem("Tools/FlashTools/Reimport all swf files")]
|
||||
static void Tools_FlashTools_ReimportAllSwfFiles() {
|
||||
var swf_paths = GetAllSwfFilePaths();
|
||||
var title = "Reimport";
|
||||
var message = string.Format(
|
||||
"Do you really want to reimport all ({0}) swf files?",
|
||||
swf_paths.Length);
|
||||
if ( EditorUtility.DisplayDialog(title, message, "Ok", "Cancel") ) {
|
||||
foreach ( var swf_path in swf_paths ) {
|
||||
AssetDatabase.ImportAsset(swf_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Tools/FlashTools/Pregenerate all materials")]
|
||||
static void PregenerateAllMaterials() {
|
||||
var blend_modes = System.Enum.GetValues(typeof(SwfBlendModeData.Types));
|
||||
foreach ( SwfBlendModeData.Types blend_mode in blend_modes ) {
|
||||
SwfMaterialCache.GetSimpleMaterial(blend_mode);
|
||||
for ( var i = 0; i < 10; ++i ) {
|
||||
SwfMaterialCache.GetMaskedMaterial(blend_mode, i);
|
||||
}
|
||||
}
|
||||
SwfMaterialCache.GetIncrMaskMaterial();
|
||||
SwfMaterialCache.GetDecrMaskMaterial();
|
||||
}
|
||||
|
||||
static string[] GetAllSwfFilePaths() {
|
||||
return AssetDatabase.GetAllAssetPaths()
|
||||
.Where(p => Path.GetExtension(p).ToLower().Equals(".swf"))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb433da59d3a7419dad8ad592185cb69
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
252
Assets/FlashTools/Scripts/Editor/FTEditor/SwfMaterialCache.cs
Normal file
252
Assets/FlashTools/Scripts/Editor/FTEditor/SwfMaterialCache.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEditor;
|
||||
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor {
|
||||
class SwfMaterialCache {
|
||||
|
||||
const string SwfSimpleShaderName = "SwfSimpleShader";
|
||||
const string SwfMaskedShaderName = "SwfMaskedShader";
|
||||
const string SwfSimpleGrabShaderName = "SwfSimpleGrabShader";
|
||||
const string SwfMaskedGrabShaderName = "SwfMaskedGrabShader";
|
||||
const string SwfIncrMaskShaderName = "SwfIncrMaskShader";
|
||||
const string SwfDecrMaskShaderName = "SwfDecrMaskShader";
|
||||
|
||||
static Dictionary<string, Shader> ShaderCache = new Dictionary<string, Shader>();
|
||||
static Shader GetShaderByName(string shader_name) {
|
||||
Shader shader;
|
||||
if ( !ShaderCache.TryGetValue(shader_name, out shader) || !shader ) {
|
||||
shader = SafeLoadShader(shader_name);
|
||||
ShaderCache.Add(shader_name, shader);
|
||||
}
|
||||
shader.hideFlags = HideFlags.HideInInspector;
|
||||
return shader;
|
||||
}
|
||||
|
||||
static Dictionary<string, Material> MaterialCache = new Dictionary<string, Material>();
|
||||
static Material GetMaterialByPath(
|
||||
string material_path,
|
||||
Shader material_shader,
|
||||
System.Func<Material, Material> fill_material)
|
||||
{
|
||||
Material material;
|
||||
if ( !MaterialCache.TryGetValue(material_path, out material) || !material ) {
|
||||
material = SafeLoadMaterial(material_path, material_shader, fill_material);
|
||||
MaterialCache.Add(material_path, material);
|
||||
}
|
||||
material.hideFlags = HideFlags.HideInInspector;
|
||||
return material;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Functions
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
public static Material GetSimpleMaterial(
|
||||
SwfBlendModeData.Types blend_mode)
|
||||
{
|
||||
return LoadOrCreateMaterial(
|
||||
SelectShader(false, blend_mode),
|
||||
(dir_path, filename) => {
|
||||
return string.Format(
|
||||
"{0}/{1}_{2}.mat",
|
||||
dir_path, filename, blend_mode);
|
||||
},
|
||||
material => FillMaterial(material, blend_mode, 0));
|
||||
}
|
||||
|
||||
public static Material GetMaskedMaterial(
|
||||
SwfBlendModeData.Types blend_mode,
|
||||
int stencil_id)
|
||||
{
|
||||
return LoadOrCreateMaterial(
|
||||
SelectShader(true, blend_mode),
|
||||
(dir_path, filename) => {
|
||||
return string.Format(
|
||||
"{0}/{1}_{2}_{3}.mat",
|
||||
dir_path, filename, blend_mode, stencil_id);
|
||||
},
|
||||
material => FillMaterial(material, blend_mode, stencil_id));
|
||||
}
|
||||
|
||||
public static Material GetIncrMaskMaterial() {
|
||||
return LoadOrCreateMaterial(
|
||||
GetShaderByName(SwfIncrMaskShaderName),
|
||||
(dir_path, filename) => {
|
||||
return string.Format(
|
||||
"{0}/{1}.mat",
|
||||
dir_path, filename);
|
||||
},
|
||||
material => material);
|
||||
}
|
||||
|
||||
public static Material GetDecrMaskMaterial() {
|
||||
return LoadOrCreateMaterial(
|
||||
GetShaderByName(SwfDecrMaskShaderName),
|
||||
(dir_path, filename) => {
|
||||
return string.Format(
|
||||
"{0}/{1}.mat",
|
||||
dir_path, filename);
|
||||
},
|
||||
material => material);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Private
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
static Shader SafeLoadShader(string shader_name) {
|
||||
var filter = string.Format("t:Shader {0}", shader_name);
|
||||
var shader = SwfEditorUtils.LoadFirstAssetByFilter<Shader>(filter);
|
||||
if ( !shader ) {
|
||||
throw new UnityException(string.Format(
|
||||
"SwfMaterialCache. Shader not found: {0}",
|
||||
shader_name));
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
static Material SafeLoadMaterial(
|
||||
string material_path,
|
||||
Shader material_shader,
|
||||
System.Func<Material, Material> fill_material)
|
||||
{
|
||||
var material = AssetDatabase.LoadAssetAtPath<Material>(material_path);
|
||||
if ( !material ) {
|
||||
material = fill_material(new Material(material_shader));
|
||||
material.hideFlags = HideFlags.HideInInspector;
|
||||
AssetDatabase.CreateAsset(material, material_path);
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
static Material LoadOrCreateMaterial(
|
||||
Shader shader,
|
||||
System.Func<string, string, string> path_factory,
|
||||
System.Func<Material, Material> fill_material)
|
||||
{
|
||||
var shader_path = AssetDatabase.GetAssetPath(shader);
|
||||
var shader_dir = Path.GetDirectoryName(shader_path);
|
||||
var generated_dir = Path.Combine(shader_dir, "Generated");
|
||||
if ( !AssetDatabase.IsValidFolder(generated_dir) ) {
|
||||
AssetDatabase.CreateFolder(shader_dir, "Generated");
|
||||
}
|
||||
var material_path = path_factory(
|
||||
generated_dir,
|
||||
Path.GetFileNameWithoutExtension(shader_path));
|
||||
return GetMaterialByPath(material_path, shader, fill_material);
|
||||
}
|
||||
|
||||
static Shader SelectShader(bool masked, SwfBlendModeData.Types blend_mode) {
|
||||
switch ( blend_mode ) {
|
||||
case SwfBlendModeData.Types.Normal:
|
||||
case SwfBlendModeData.Types.Layer:
|
||||
case SwfBlendModeData.Types.Multiply:
|
||||
case SwfBlendModeData.Types.Screen:
|
||||
case SwfBlendModeData.Types.Lighten:
|
||||
case SwfBlendModeData.Types.Add:
|
||||
case SwfBlendModeData.Types.Subtract:
|
||||
return GetShaderByName(masked ? SwfMaskedShaderName : SwfSimpleShaderName);
|
||||
case SwfBlendModeData.Types.Darken:
|
||||
case SwfBlendModeData.Types.Difference:
|
||||
case SwfBlendModeData.Types.Invert:
|
||||
case SwfBlendModeData.Types.Overlay:
|
||||
case SwfBlendModeData.Types.Hardlight:
|
||||
return GetShaderByName(masked ? SwfMaskedGrabShaderName : SwfSimpleGrabShaderName);
|
||||
default:
|
||||
throw new UnityException(string.Format(
|
||||
"SwfMaterialCache. Incorrect blend mode: {0}",
|
||||
blend_mode));
|
||||
}
|
||||
}
|
||||
|
||||
static Material FillMaterial(
|
||||
Material material,
|
||||
SwfBlendModeData.Types blend_mode,
|
||||
int stencil_id)
|
||||
{
|
||||
switch ( blend_mode ) {
|
||||
case SwfBlendModeData.Types.Normal:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Layer:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Multiply:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.DstColor);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Screen:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.OneMinusDstColor);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.One);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Lighten:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Max);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Darken:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_DARKEN_BLEND");
|
||||
break;
|
||||
case SwfBlendModeData.Types.Difference:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_DIFFERENCE_BLEND");
|
||||
break;
|
||||
case SwfBlendModeData.Types.Add:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.One);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Subtract:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.ReverseSubtract);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.One);
|
||||
break;
|
||||
case SwfBlendModeData.Types.Invert:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_INVERT_BLEND");
|
||||
break;
|
||||
case SwfBlendModeData.Types.Overlay:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_OVERLAY_BLEND");
|
||||
break;
|
||||
case SwfBlendModeData.Types.Hardlight:
|
||||
material.SetInt("_BlendOp" , (int)BlendOp.Add);
|
||||
material.SetInt("_SrcBlend", (int)BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha);
|
||||
material.EnableKeyword("SWF_HARDLIGHT_BLEND");
|
||||
break;
|
||||
default:
|
||||
throw new UnityException(string.Format(
|
||||
"SwfMaterialCache. Incorrect blend mode: {0}",
|
||||
blend_mode));
|
||||
}
|
||||
material.SetInt("_StencilID", stencil_id);
|
||||
return material;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae9572b206be64e4db019852a5022e42
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
258
Assets/FlashTools/Scripts/Editor/FTEditor/SwfPropertyDrawers.cs
Normal file
258
Assets/FlashTools/Scripts/Editor/FTEditor/SwfPropertyDrawers.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTRuntime;
|
||||
|
||||
namespace FTEditor {
|
||||
|
||||
//
|
||||
// SwfIntRange
|
||||
//
|
||||
|
||||
[CustomPropertyDrawer(typeof(SwfIntRangeAttribute))]
|
||||
class SwfIntRangeDrawer : PropertyDrawer {
|
||||
static void ValidateProperty(SerializedProperty property, int min, int max) {
|
||||
if ( !property.hasMultipleDifferentValues ) {
|
||||
if ( property.propertyType == SerializedPropertyType.Integer ) {
|
||||
var clamp = Mathf.Clamp(property.intValue, min, max);
|
||||
if ( clamp != property.intValue ) {
|
||||
property.intValue = clamp;
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void OnGUI(
|
||||
Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
var attr = attribute as SwfIntRangeAttribute;
|
||||
ValidateProperty(property, attr.Min, attr.Max);
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SwfFloatRange
|
||||
//
|
||||
|
||||
[CustomPropertyDrawer(typeof(SwfFloatRangeAttribute))]
|
||||
class SwfFloatRangeDrawer : PropertyDrawer {
|
||||
static void ValidateProperty(SerializedProperty property, float min, float max) {
|
||||
if ( !property.hasMultipleDifferentValues ) {
|
||||
if ( property.propertyType == SerializedPropertyType.Float ) {
|
||||
var clamp = Mathf.Clamp(property.floatValue, min, max);
|
||||
if ( clamp != property.floatValue ) {
|
||||
property.floatValue = clamp;
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void OnGUI(
|
||||
Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
var attr = attribute as SwfFloatRangeAttribute;
|
||||
ValidateProperty(property, attr.Min, attr.Max);
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SwfSortingLayerDrawer
|
||||
//
|
||||
|
||||
[CustomPropertyDrawer(typeof(SwfSortingLayerAttribute))]
|
||||
class SwfSortingLayerDrawer : PropertyDrawer {
|
||||
|
||||
const string DefaultLayerName = "Default";
|
||||
|
||||
static List<string> GetAllSortingLayers(bool include_empty) {
|
||||
var result = new List<string>();
|
||||
var tag_assets = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset");
|
||||
if ( tag_assets.Length > 0 ) {
|
||||
var layers = SwfEditorUtils.GetPropertyByName(
|
||||
new SerializedObject(tag_assets[0]),
|
||||
"m_SortingLayers");
|
||||
if ( layers.isArray ) {
|
||||
for ( var i = 0; i < layers.arraySize; ++i ) {
|
||||
var layer_prop = layers.GetArrayElementAtIndex(i);
|
||||
var layer_prop_name = layer_prop != null
|
||||
? layer_prop.FindPropertyRelative("name")
|
||||
: null;
|
||||
var layer_name = layer_prop_name != null && layer_prop_name.propertyType == SerializedPropertyType.String
|
||||
? layer_prop_name.stringValue
|
||||
: string.Empty;
|
||||
if ( !string.IsNullOrEmpty(layer_name) ) {
|
||||
result.Add(layer_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !result.Contains(DefaultLayerName) ) {
|
||||
result.Add(DefaultLayerName);
|
||||
}
|
||||
if ( include_empty ) {
|
||||
result.Add(string.Empty);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ValidateProperty(SerializedProperty property) {
|
||||
if ( !property.hasMultipleDifferentValues ) {
|
||||
if ( property.propertyType == SerializedPropertyType.String ) {
|
||||
var all_sorting_layers = GetAllSortingLayers(false);
|
||||
if ( !all_sorting_layers.Contains(property.stringValue) ) {
|
||||
property.stringValue = string.Empty;
|
||||
property.stringValue = DefaultLayerName;
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGUI(
|
||||
Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if ( property.propertyType == SerializedPropertyType.String ) {
|
||||
ValidateProperty(property);
|
||||
SwfEditorUtils.DoWithMixedValue(
|
||||
property.hasMultipleDifferentValues, () => {
|
||||
label = EditorGUI.BeginProperty(position, label, property);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var all_sorting_layers = GetAllSortingLayers(true);
|
||||
var sorting_layer_index = EditorGUI.Popup(
|
||||
position,
|
||||
label,
|
||||
property.hasMultipleDifferentValues
|
||||
? all_sorting_layers.FindIndex(p => string.IsNullOrEmpty(p))
|
||||
: all_sorting_layers.FindIndex(p => p == property.stringValue),
|
||||
all_sorting_layers.Select(p => new GUIContent(p)).ToArray());
|
||||
if ( EditorGUI.EndChangeCheck() ) {
|
||||
if ( sorting_layer_index >= 0 && sorting_layer_index < all_sorting_layers.Count ) {
|
||||
var new_value = all_sorting_layers[sorting_layer_index];
|
||||
if ( !string.IsNullOrEmpty(new_value) ) {
|
||||
if ( property.hasMultipleDifferentValues ) {
|
||||
property.stringValue = string.Empty;
|
||||
}
|
||||
property.stringValue = new_value;
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUI.EndProperty();
|
||||
});
|
||||
} else {
|
||||
EditorGUI.LabelField(position, label.text, "Use SwfSortingLayer with string attribute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SwfPowerOfTwoIfDrawer
|
||||
//
|
||||
|
||||
[CustomPropertyDrawer(typeof(SwfPowerOfTwoIfAttribute))]
|
||||
class SwfPowerOfTwoIfDrawer : PropertyDrawer {
|
||||
|
||||
static SerializedProperty FindNextBoolProperty(SerializedProperty property, string next_prop) {
|
||||
var prop = property.Copy();
|
||||
while ( prop.Next(false) ) {
|
||||
if ( prop.name == next_prop && prop.propertyType == SerializedPropertyType.Boolean ) {
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static int GetPowerOfTwo(int value) {
|
||||
return Mathf.RoundToInt(Mathf.Pow(2, value));
|
||||
}
|
||||
|
||||
static int[] GenPowerOfTwoValues(int min_pow2, int max_pow2) {
|
||||
var values = new List<int>();
|
||||
while ( min_pow2 <= max_pow2 ) {
|
||||
values.Add(GetPowerOfTwo(min_pow2));
|
||||
++min_pow2;
|
||||
}
|
||||
return values.ToArray();
|
||||
}
|
||||
|
||||
static void ValidateProperty(SerializedProperty property, bool need_pow2, int min_pow2, int max_pow2) {
|
||||
if ( !property.hasMultipleDifferentValues ) {
|
||||
if ( property.propertyType == SerializedPropertyType.Integer ) {
|
||||
var last_value = property.intValue;
|
||||
if ( need_pow2 && !Mathf.IsPowerOfTwo(property.intValue) ) {
|
||||
property.intValue = Mathf.ClosestPowerOfTwo(property.intValue);
|
||||
}
|
||||
property.intValue = Mathf.Clamp(
|
||||
property.intValue,
|
||||
GetPowerOfTwo(min_pow2),
|
||||
GetPowerOfTwo(max_pow2));
|
||||
if ( last_value != property.intValue ) {
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGUI(
|
||||
Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if ( property.propertyType == SerializedPropertyType.Integer ) {
|
||||
var attr = attribute as SwfPowerOfTwoIfAttribute;
|
||||
var bool_prop = FindNextBoolProperty(property, attr.BoolProp);
|
||||
var need_pow2 = (bool_prop != null && (bool_prop.boolValue || bool_prop.hasMultipleDifferentValues));
|
||||
ValidateProperty(property, need_pow2, attr.MinPow2, attr.MaxPow2);
|
||||
SwfEditorUtils.DoWithMixedValue(
|
||||
property.hasMultipleDifferentValues, () => {
|
||||
if ( need_pow2 ) {
|
||||
var values = GenPowerOfTwoValues(attr.MinPow2, attr.MaxPow2);
|
||||
var vnames = values.Select(p => new GUIContent(p.ToString())).ToArray();
|
||||
EditorGUI.IntPopup(position, property, vnames, values, label);
|
||||
} else {
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
EditorGUI.LabelField(position, label.text, "Use SwfPowerOfTwoIf with integer attribute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SwfReadOnlyDrawer
|
||||
//
|
||||
|
||||
[CustomPropertyDrawer(typeof(SwfReadOnlyAttribute))]
|
||||
class SwfReadOnlyDrawer : PropertyDrawer {
|
||||
public override void OnGUI(
|
||||
Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
SwfEditorUtils.DoWithEnabledGUI(false, () => {
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SwfDisplayNameDrawer
|
||||
//
|
||||
|
||||
[CustomPropertyDrawer(typeof(SwfDisplayNameAttribute))]
|
||||
class SwfDisplayNameDrawer : PropertyDrawer {
|
||||
public override void OnGUI(
|
||||
Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
var new_label = new GUIContent(label);
|
||||
new_label.text = (attribute as SwfDisplayNameAttribute).DisplayName;
|
||||
if ( EditorGUI.PropertyField(position, property, new_label) ) {
|
||||
foreach ( SerializedProperty child in property ) {
|
||||
EditorGUILayout.PropertyField(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5b45193bd087497eb8e208376c129ea
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/FlashTools/Scripts/Editor/FTSwfTools.meta
Normal file
9
Assets/FlashTools/Scripts/Editor/FTSwfTools.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58ce6b8fae3184a029f6bc3535e3cdb1
|
||||
folderAsset: yes
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
114
Assets/FlashTools/Scripts/Editor/FTSwfTools/SwfContext.cs
Normal file
114
Assets/FlashTools/Scripts/Editor/FTSwfTools/SwfContext.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System.Collections.Generic;
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools {
|
||||
|
||||
using LibraryDefines = SortedDictionary<ushort, SwfLibraryDefine>;
|
||||
using DisplayInstances = SortedDictionary<ushort, SwfDisplayInstance>;
|
||||
|
||||
//
|
||||
// SwfLibrary
|
||||
//
|
||||
|
||||
public enum SwfLibraryDefineType {
|
||||
Shape,
|
||||
Bitmap,
|
||||
Sprite
|
||||
}
|
||||
|
||||
public abstract class SwfLibraryDefine {
|
||||
public string ExportName = string.Empty;
|
||||
public abstract SwfLibraryDefineType Type { get; }
|
||||
}
|
||||
|
||||
public class SwfLibraryShapeDefine : SwfLibraryDefine {
|
||||
public ushort[] Bitmaps = new ushort[0];
|
||||
public SwfMatrix[] Matrices = new SwfMatrix[0];
|
||||
|
||||
public override SwfLibraryDefineType Type {
|
||||
get { return SwfLibraryDefineType.Shape; }
|
||||
}
|
||||
}
|
||||
|
||||
public class SwfLibraryBitmapDefine : SwfLibraryDefine {
|
||||
public int Width = 0;
|
||||
public int Height = 0;
|
||||
public byte[] ARGB32 = new byte[0];
|
||||
public ushort Redirect = 0;
|
||||
|
||||
public override SwfLibraryDefineType Type {
|
||||
get { return SwfLibraryDefineType.Bitmap; }
|
||||
}
|
||||
}
|
||||
|
||||
public class SwfLibrarySpriteDefine : SwfLibraryDefine {
|
||||
public SwfControlTags ControlTags = SwfControlTags.identity;
|
||||
|
||||
public override SwfLibraryDefineType Type {
|
||||
get { return SwfLibraryDefineType.Sprite; }
|
||||
}
|
||||
}
|
||||
|
||||
public class SwfLibrary {
|
||||
public LibraryDefines Defines = new LibraryDefines();
|
||||
|
||||
public bool HasDefine<T>(ushort define_id) where T : SwfLibraryDefine {
|
||||
return FindDefine<T>(define_id) != null;
|
||||
}
|
||||
|
||||
public T FindDefine<T>(ushort define_id) where T : SwfLibraryDefine {
|
||||
SwfLibraryDefine def;
|
||||
if ( Defines.TryGetValue(define_id, out def) ) {
|
||||
return def as T;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SwfDisplayList
|
||||
//
|
||||
|
||||
public enum SwfDisplayInstanceType {
|
||||
Shape,
|
||||
Sprite
|
||||
}
|
||||
|
||||
public abstract class SwfDisplayInstance {
|
||||
public abstract SwfDisplayInstanceType Type { get; }
|
||||
|
||||
public ushort Id;
|
||||
public ushort Depth;
|
||||
public ushort ClipDepth;
|
||||
public bool Visible;
|
||||
public SwfMatrix Matrix;
|
||||
public SwfBlendMode BlendMode;
|
||||
public SwfSurfaceFilters FilterList;
|
||||
public SwfColorTransform ColorTransform;
|
||||
}
|
||||
|
||||
public class SwfDisplayShapeInstance : SwfDisplayInstance {
|
||||
public override SwfDisplayInstanceType Type {
|
||||
get { return SwfDisplayInstanceType.Shape; }
|
||||
}
|
||||
}
|
||||
|
||||
public class SwfDisplaySpriteInstance : SwfDisplayInstance {
|
||||
public int CurrentTag = 0;
|
||||
public SwfDisplayList DisplayList = new SwfDisplayList();
|
||||
|
||||
public override SwfDisplayInstanceType Type {
|
||||
get { return SwfDisplayInstanceType.Sprite; }
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
CurrentTag = 0;
|
||||
DisplayList = new SwfDisplayList();
|
||||
}
|
||||
}
|
||||
|
||||
public class SwfDisplayList {
|
||||
public string FrameName = string.Empty;
|
||||
public DisplayInstances Instances = new DisplayInstances();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af4763cc4d7f44668be4fc2d77620d16
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,378 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTSwfTools.SwfTags;
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools {
|
||||
public class SwfContextExecuter : SwfTagVisitor<SwfDisplayList, SwfDisplayList> {
|
||||
public SwfLibrary Library = null;
|
||||
public int CurrentTag = 0;
|
||||
public System.Action<string> WarningLog = null;
|
||||
|
||||
public SwfContextExecuter(SwfLibrary library, int current_tag, System.Action<string> warning_log) {
|
||||
Library = library;
|
||||
CurrentTag = current_tag;
|
||||
WarningLog = warning_log;
|
||||
}
|
||||
|
||||
public bool NextFrame(List<SwfTagBase> tags, SwfDisplayList dl) {
|
||||
dl.FrameName = string.Empty;
|
||||
while ( CurrentTag < tags.Count ) {
|
||||
var tag = tags[CurrentTag++];
|
||||
tag.AcceptVistor(this, dl);
|
||||
if ( tag.TagType == SwfTagType.ShowFrame ) {
|
||||
ChildrenNextFrameLooped(dl);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ChildrenNextFrameLooped(dl);
|
||||
return false;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(PlaceObjectTag tag, SwfDisplayList dl) {
|
||||
var is_shape = Library.HasDefine<SwfLibraryShapeDefine >(tag.CharacterId);
|
||||
var is_sprite = Library.HasDefine<SwfLibrarySpriteDefine>(tag.CharacterId);
|
||||
SwfDisplayInstance new_inst = null;
|
||||
if ( is_shape ) {
|
||||
new_inst = new SwfDisplayShapeInstance();
|
||||
} else if ( is_sprite ) {
|
||||
new_inst = new SwfDisplaySpriteInstance();
|
||||
}
|
||||
if ( new_inst != null ) {
|
||||
new_inst.Id = tag.CharacterId;
|
||||
new_inst.Depth = tag.Depth;
|
||||
new_inst.ClipDepth = 0;
|
||||
new_inst.Visible = true;
|
||||
new_inst.Matrix = tag.Matrix;
|
||||
new_inst.BlendMode = SwfBlendMode.identity;
|
||||
new_inst.FilterList = SwfSurfaceFilters.identity;
|
||||
new_inst.ColorTransform = tag.ColorTransform;
|
||||
dl.Instances.Add(new_inst.Depth, new_inst);
|
||||
}
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(PlaceObject2Tag tag, SwfDisplayList dl) {
|
||||
var is_shape = tag.HasCharacter && Library.HasDefine<SwfLibraryShapeDefine >(tag.CharacterId);
|
||||
var is_sprite = tag.HasCharacter && Library.HasDefine<SwfLibrarySpriteDefine>(tag.CharacterId);
|
||||
if ( tag.HasCharacter ) {
|
||||
SwfDisplayInstance old_inst = null;
|
||||
if ( tag.Move ) { // replace character
|
||||
if ( dl.Instances.TryGetValue(tag.Depth, out old_inst) ) {
|
||||
dl.Instances.Remove(tag.Depth);
|
||||
}
|
||||
}
|
||||
// new character
|
||||
SwfDisplayInstance new_inst = null;
|
||||
if ( is_shape ) {
|
||||
new_inst = new SwfDisplayShapeInstance();
|
||||
} else if ( is_sprite ) {
|
||||
new_inst = new SwfDisplaySpriteInstance();
|
||||
}
|
||||
if ( new_inst != null ) {
|
||||
new_inst.Id = tag.CharacterId;
|
||||
new_inst.Depth = tag.Depth;
|
||||
new_inst.ClipDepth = tag.HasClipDepth ? tag.ClipDepth : (old_inst != null ? old_inst.ClipDepth : (ushort)0);
|
||||
new_inst.Visible = true;
|
||||
new_inst.Matrix = tag.HasMatrix ? tag.Matrix : (old_inst != null ? old_inst.Matrix : SwfMatrix.identity);
|
||||
new_inst.BlendMode = SwfBlendMode.identity;
|
||||
new_inst.FilterList = SwfSurfaceFilters.identity;
|
||||
new_inst.ColorTransform = tag.HasColorTransform ? tag.ColorTransform : (old_inst != null ? old_inst.ColorTransform : SwfColorTransform.identity);
|
||||
dl.Instances.Add(new_inst.Depth, new_inst);
|
||||
}
|
||||
} else if ( tag.Move ) { // move character
|
||||
SwfDisplayInstance inst;
|
||||
if ( dl.Instances.TryGetValue(tag.Depth, out inst) ) {
|
||||
if ( tag.HasClipDepth ) {
|
||||
inst.ClipDepth = tag.ClipDepth;
|
||||
}
|
||||
if ( tag.HasMatrix ) {
|
||||
inst.Matrix = tag.Matrix;
|
||||
}
|
||||
if ( tag.HasColorTransform ) {
|
||||
inst.ColorTransform = tag.ColorTransform;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(PlaceObject3Tag tag, SwfDisplayList dl) {
|
||||
var is_shape = tag.HasCharacter && Library.HasDefine<SwfLibraryShapeDefine >(tag.CharacterId);
|
||||
var is_sprite = tag.HasCharacter && Library.HasDefine<SwfLibrarySpriteDefine>(tag.CharacterId);
|
||||
if ( tag.HasCharacter ) {
|
||||
SwfDisplayInstance old_inst = null;
|
||||
if ( tag.Move ) { // replace character
|
||||
if ( dl.Instances.TryGetValue(tag.Depth, out old_inst) ) {
|
||||
dl.Instances.Remove(tag.Depth);
|
||||
}
|
||||
}
|
||||
// new character
|
||||
SwfDisplayInstance new_inst = null;
|
||||
if ( is_shape ) {
|
||||
new_inst = new SwfDisplayShapeInstance();
|
||||
} else if ( is_sprite ) {
|
||||
new_inst = new SwfDisplaySpriteInstance();
|
||||
}
|
||||
if ( new_inst != null ) {
|
||||
new_inst.Id = tag.CharacterId;
|
||||
new_inst.Depth = tag.Depth;
|
||||
new_inst.ClipDepth = tag.HasClipDepth ? tag.ClipDepth : (old_inst != null ? old_inst.ClipDepth : (ushort)0);
|
||||
new_inst.Visible = tag.HasVisible ? tag.Visible : (old_inst != null ? old_inst.Visible : true);
|
||||
new_inst.Matrix = tag.HasMatrix ? tag.Matrix : (old_inst != null ? old_inst.Matrix : SwfMatrix.identity);
|
||||
new_inst.BlendMode = tag.HasBlendMode ? tag.BlendMode : (old_inst != null ? old_inst.BlendMode : SwfBlendMode.identity);
|
||||
new_inst.FilterList = tag.HasFilterList ? tag.SurfaceFilters : (old_inst != null ? old_inst.FilterList : SwfSurfaceFilters.identity);
|
||||
new_inst.ColorTransform = tag.HasColorTransform ? tag.ColorTransform : (old_inst != null ? old_inst.ColorTransform : SwfColorTransform.identity);
|
||||
dl.Instances.Add(new_inst.Depth, new_inst);
|
||||
}
|
||||
} else if ( tag.Move ) { // move character
|
||||
SwfDisplayInstance inst;
|
||||
if ( dl.Instances.TryGetValue(tag.Depth, out inst) ) {
|
||||
if ( tag.HasClipDepth ) {
|
||||
inst.ClipDepth = tag.ClipDepth;
|
||||
}
|
||||
if ( tag.HasVisible ) {
|
||||
inst.Visible = tag.Visible;
|
||||
}
|
||||
if ( tag.HasMatrix ) {
|
||||
inst.Matrix = tag.Matrix;
|
||||
}
|
||||
if ( tag.HasBlendMode ) {
|
||||
inst.BlendMode = tag.BlendMode;
|
||||
}
|
||||
if ( tag.HasFilterList ) {
|
||||
inst.FilterList = tag.SurfaceFilters;
|
||||
}
|
||||
if ( tag.HasColorTransform ) {
|
||||
inst.ColorTransform = tag.ColorTransform;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(RemoveObjectTag tag, SwfDisplayList dl) {
|
||||
dl.Instances.Remove(tag.Depth);
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(RemoveObject2Tag tag, SwfDisplayList dl) {
|
||||
dl.Instances.Remove(tag.Depth);
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(ShowFrameTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(SetBackgroundColorTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(FrameLabelTag tag, SwfDisplayList dl) {
|
||||
dl.FrameName = tag.Name.Trim();
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(ProtectTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(EndTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(ExportAssetsTag tag, SwfDisplayList dl) {
|
||||
foreach ( var asset_tag in tag.AssetTags ) {
|
||||
var define = Library.FindDefine<SwfLibraryDefine>(asset_tag.Tag);
|
||||
if ( define != null ) {
|
||||
define.ExportName = asset_tag.Name.Trim();
|
||||
}
|
||||
}
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(EnableDebuggerTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(EnableDebugger2Tag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(ScriptLimitsTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(SymbolClassTag tag, SwfDisplayList dl) {
|
||||
foreach ( var symbol_tag in tag.SymbolTags ) {
|
||||
var define = Library.FindDefine<SwfLibraryDefine>(symbol_tag.Tag);
|
||||
if ( define != null ) {
|
||||
define.ExportName = symbol_tag.Name.Trim();
|
||||
}
|
||||
}
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(MetadataTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DefineSceneAndFrameLabelDataTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DoABCTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DefineShapeTag tag, SwfDisplayList dl) {
|
||||
AddShapesToLibrary(tag.ShapeId, tag.Shapes);
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DefineShape2Tag tag, SwfDisplayList dl) {
|
||||
AddShapesToLibrary(tag.ShapeId, tag.Shapes);
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DefineShape3Tag tag, SwfDisplayList dl) {
|
||||
AddShapesToLibrary(tag.ShapeId, tag.Shapes);
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DefineShape4Tag tag, SwfDisplayList dl) {
|
||||
AddShapesToLibrary(tag.ShapeId, tag.Shapes);
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DefineBitsLosslessTag tag, SwfDisplayList dl) {
|
||||
AddBitmapToLibrary(
|
||||
tag.CharacterId,
|
||||
tag.BitmapWidth,
|
||||
tag.BitmapHeight,
|
||||
tag.ToARGB32());
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DefineBitsLossless2Tag tag, SwfDisplayList dl) {
|
||||
AddBitmapToLibrary(
|
||||
tag.CharacterId,
|
||||
tag.BitmapWidth,
|
||||
tag.BitmapHeight,
|
||||
tag.ToARGB32());
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DefineSpriteTag tag, SwfDisplayList dl) {
|
||||
AddSpriteToLibrary(
|
||||
tag.SpriteId,
|
||||
tag.ControlTags);
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(FileAttributesTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(EnableTelemetryTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(DefineBinaryDataTag tag, SwfDisplayList dl) {
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(UnknownTag tag, SwfDisplayList dl) {
|
||||
TagToWarningLog(tag);
|
||||
return dl;
|
||||
}
|
||||
|
||||
public SwfDisplayList Visit(UnsupportedTag tag, SwfDisplayList dl) {
|
||||
TagToWarningLog(tag);
|
||||
return dl;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void TagToWarningLog(SwfTagBase tag) {
|
||||
if ( WarningLog != null ) {
|
||||
WarningLog(string.Format("SwfContextExecuter: {0}", tag));
|
||||
}
|
||||
}
|
||||
|
||||
void AddShapesToLibrary(ushort define_id, SwfShapesWithStyle shapes) {
|
||||
var bitmap_styles = shapes.FillStyles.Where(p => p.Type.IsBitmapType);
|
||||
var define = new SwfLibraryShapeDefine{
|
||||
Bitmaps = bitmap_styles.Select(p => p.BitmapId ).ToArray(),
|
||||
Matrices = bitmap_styles.Select(p => p.BitmapMatrix).ToArray()
|
||||
};
|
||||
Library.Defines.Add(define_id, define);
|
||||
}
|
||||
|
||||
void AddBitmapToLibrary(ushort define_id, int width, int height, byte[] argb32) {
|
||||
var duplicated = FindDuplicatedBitmap(argb32);
|
||||
var define = new SwfLibraryBitmapDefine{
|
||||
Width = width,
|
||||
Height = height,
|
||||
ARGB32 = duplicated > 0 ? new byte[0] : argb32,
|
||||
Redirect = duplicated};
|
||||
Library.Defines.Add(define_id, define);
|
||||
}
|
||||
|
||||
void AddSpriteToLibrary(ushort define_id, SwfControlTags control_tags) {
|
||||
var define = new SwfLibrarySpriteDefine{
|
||||
ControlTags = control_tags
|
||||
};
|
||||
Library.Defines.Add(define_id, define);
|
||||
}
|
||||
|
||||
ushort FindDuplicatedBitmap(byte[] argb32) {
|
||||
foreach ( var define in Library.Defines ) {
|
||||
var bitmap = define.Value as SwfLibraryBitmapDefine;
|
||||
if ( bitmap != null && bitmap.ARGB32.Length == argb32.Length ) {
|
||||
if ( bitmap.ARGB32.SequenceEqual(argb32) ) {
|
||||
return define.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsSpriteTimelineEnd(SwfDisplaySpriteInstance sprite) {
|
||||
var sprite_def = Library.FindDefine<SwfLibrarySpriteDefine>(sprite.Id);
|
||||
if ( sprite_def != null && sprite.CurrentTag < sprite_def.ControlTags.Tags.Count ) {
|
||||
return false;
|
||||
}
|
||||
var children = sprite.DisplayList.Instances.Values
|
||||
.Where (p => p.Type == SwfDisplayInstanceType.Sprite)
|
||||
.Select(p => p as SwfDisplaySpriteInstance);
|
||||
foreach ( var child in children ) {
|
||||
if ( !IsSpriteTimelineEnd(child) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChildrenNextFrameLooped(SwfDisplayList dl) {
|
||||
var sprites = dl.Instances.Values
|
||||
.Where (p => p.Type == SwfDisplayInstanceType.Sprite)
|
||||
.Select(p => p as SwfDisplaySpriteInstance);
|
||||
foreach ( var sprite in sprites ) {
|
||||
var sprite_def = Library.FindDefine<SwfLibrarySpriteDefine>(sprite.Id);
|
||||
if ( sprite_def != null ) {
|
||||
if ( IsSpriteTimelineEnd(sprite) ) {
|
||||
sprite.Reset();
|
||||
}
|
||||
var sprite_executer = new SwfContextExecuter(Library, sprite.CurrentTag, WarningLog);
|
||||
sprite_executer.NextFrame(sprite_def.ControlTags.Tags, sprite.DisplayList);
|
||||
sprite.CurrentTag = sprite_executer.CurrentTag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 040f74af26980417a98238cea1e511c1
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
54
Assets/FlashTools/Scripts/Editor/FTSwfTools/SwfDecoder.cs
Normal file
54
Assets/FlashTools/Scripts/Editor/FTSwfTools/SwfDecoder.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using FTSwfTools.SwfTags;
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools {
|
||||
public class SwfDecoder {
|
||||
public SwfShortHeader OriginalHeader;
|
||||
public SwfLongHeader UncompressedHeader;
|
||||
public List<SwfTagBase> Tags = new List<SwfTagBase>();
|
||||
|
||||
public SwfDecoder(string swf_path) {
|
||||
var raw_data = File.ReadAllBytes(swf_path);
|
||||
var uncompressed_stream = DecompressSwfData(raw_data);
|
||||
DecodeSwf(new SwfStreamReader(uncompressed_stream));
|
||||
}
|
||||
|
||||
MemoryStream DecompressSwfData(byte[] raw_swf_data) {
|
||||
var raw_reader = new SwfStreamReader(raw_swf_data);
|
||||
OriginalHeader = SwfShortHeader.Read(raw_reader);
|
||||
switch ( OriginalHeader.Format ) {
|
||||
case "FWS":
|
||||
return new MemoryStream(raw_swf_data);
|
||||
case "CWS":
|
||||
var rest_stream = SwfStreamReader.DecompressZBytes(
|
||||
raw_reader.ReadRest());
|
||||
var new_short_header = new SwfShortHeader{
|
||||
Format = "FWS",
|
||||
Version = OriginalHeader.Version,
|
||||
FileLength = OriginalHeader.FileLength};
|
||||
var uncompressed_stream = new MemoryStream();
|
||||
SwfShortHeader.Write(new_short_header, uncompressed_stream);
|
||||
rest_stream.WriteTo(uncompressed_stream);
|
||||
uncompressed_stream.Position = 0;
|
||||
return uncompressed_stream;
|
||||
default:
|
||||
throw new System.Exception(string.Format(
|
||||
"Unsupported swf format: {0}", OriginalHeader.Format));
|
||||
}
|
||||
}
|
||||
|
||||
void DecodeSwf(SwfStreamReader reader) {
|
||||
UncompressedHeader = SwfLongHeader.Read(reader);
|
||||
while ( !reader.IsEOF ) {
|
||||
var tag = SwfTagBase.Read(reader);
|
||||
if ( tag.TagType == SwfTagType.End ) {
|
||||
break;
|
||||
}
|
||||
Tags.Add(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f2dd573cc07b49589bdefd5eea5026b
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
201
Assets/FlashTools/Scripts/Editor/FTSwfTools/SwfStreamReader.cs
Normal file
201
Assets/FlashTools/Scripts/Editor/FTSwfTools/SwfStreamReader.cs
Normal file
@@ -0,0 +1,201 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Ionic.Zlib;
|
||||
|
||||
namespace FTSwfTools {
|
||||
public class SwfStreamReader {
|
||||
struct BitContext {
|
||||
public byte CachedByte;
|
||||
public byte BitIndex;
|
||||
}
|
||||
BitContext _bitContext;
|
||||
BinaryReader _binaryReader;
|
||||
|
||||
long Length {
|
||||
get { return _binaryReader.BaseStream.Length; }
|
||||
}
|
||||
|
||||
long Position {
|
||||
get { return _binaryReader.BaseStream.Position; }
|
||||
}
|
||||
|
||||
long BytesLeft {
|
||||
get { return Length - Position; }
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Public
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
public SwfStreamReader(byte[] data) {
|
||||
var memory_stream = new MemoryStream(data);
|
||||
_binaryReader = new BinaryReader(memory_stream);
|
||||
}
|
||||
|
||||
public SwfStreamReader(Stream stream) {
|
||||
_binaryReader = new BinaryReader(stream);
|
||||
}
|
||||
|
||||
public bool IsEOF {
|
||||
get { return Position >= Length; }
|
||||
}
|
||||
|
||||
public void AlignToByte() {
|
||||
_bitContext.BitIndex = 0;
|
||||
_bitContext.CachedByte = 0;
|
||||
}
|
||||
|
||||
public byte[] ReadRest() {
|
||||
return ReadBytes((int)BytesLeft);
|
||||
}
|
||||
|
||||
public bool ReadBit() {
|
||||
var bit_index = _bitContext.BitIndex & 0x07;
|
||||
if ( bit_index == 0 ) {
|
||||
_bitContext.CachedByte = ReadByte();
|
||||
}
|
||||
++_bitContext.BitIndex;
|
||||
return ((_bitContext.CachedByte << bit_index) & 0x80) != 0;
|
||||
}
|
||||
|
||||
public byte ReadByte() {
|
||||
return _binaryReader.ReadByte();
|
||||
}
|
||||
|
||||
public byte[] ReadBytes(int count) {
|
||||
return count <= 0
|
||||
? new byte[0]
|
||||
: _binaryReader.ReadBytes(count);
|
||||
}
|
||||
|
||||
public char ReadChar() {
|
||||
return _binaryReader.ReadChar();
|
||||
}
|
||||
|
||||
public char[] ReadChars(int count) {
|
||||
return count <= 0
|
||||
? new char[0]
|
||||
: _binaryReader.ReadChars(count);
|
||||
}
|
||||
|
||||
public short ReadInt16() {
|
||||
return _binaryReader.ReadInt16();
|
||||
}
|
||||
|
||||
public int ReadInt32() {
|
||||
return _binaryReader.ReadInt32();
|
||||
}
|
||||
|
||||
public ushort ReadUInt16() {
|
||||
return _binaryReader.ReadUInt16();
|
||||
}
|
||||
|
||||
public uint ReadUInt32() {
|
||||
return _binaryReader.ReadUInt32();
|
||||
}
|
||||
|
||||
public float ReadFloat32() {
|
||||
return _binaryReader.ReadSingle();
|
||||
}
|
||||
|
||||
public double ReadDouble64() {
|
||||
return _binaryReader.ReadDouble();
|
||||
}
|
||||
|
||||
public int ReadSignedBits(uint count) {
|
||||
if ( count == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
bool sign = ReadBit();
|
||||
var res = sign ? uint.MaxValue : 0;
|
||||
--count;
|
||||
for ( var i = 0; i < count; ++i ) {
|
||||
var bit = ReadBit();
|
||||
res = (res << 1 | (bit ? 1u : 0u));
|
||||
}
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
public uint ReadUnsignedBits(uint count) {
|
||||
if ( count == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
uint res = 0;
|
||||
for ( var i = 0; i < count; ++i ) {
|
||||
var bit = ReadBit();
|
||||
res = (res << 1 | (bit ? 1u : 0u));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public string ReadString() {
|
||||
var bytes = new List<byte>();
|
||||
while ( true ) {
|
||||
var bt = ReadByte();
|
||||
if ( bt == 0 ) {
|
||||
break;
|
||||
}
|
||||
bytes.Add(bt);
|
||||
}
|
||||
return Encoding.UTF8.GetString(bytes.ToArray());
|
||||
}
|
||||
|
||||
public float ReadFixedPoint_8_8() {
|
||||
var value = ReadInt16();
|
||||
return value / 256.0f;
|
||||
}
|
||||
|
||||
public float ReadFixedPoint_16_16() {
|
||||
var value = ReadInt32();
|
||||
return value / 65536.0f;
|
||||
}
|
||||
|
||||
public float ReadFixedPoint16(uint bits) {
|
||||
var value = ReadSignedBits(bits);
|
||||
return value / 65536.0f;
|
||||
}
|
||||
|
||||
public uint ReadEncodedU32() {
|
||||
uint val = 0;
|
||||
var bt = ReadByte();
|
||||
val |= bt & 0x7Fu;
|
||||
if ( (bt & 0x80) == 0 ) {
|
||||
return val;
|
||||
}
|
||||
bt = ReadByte();
|
||||
val |= (bt & 0x7Fu) << 7;
|
||||
if ( (bt & 0x80) == 0 ) {
|
||||
return val;
|
||||
}
|
||||
bt = ReadByte();
|
||||
val |= (bt & 0x7Fu) << 14;
|
||||
if ( (bt & 0x80) == 0 ) {
|
||||
return val;
|
||||
}
|
||||
bt = ReadByte();
|
||||
val |= (bt & 0x7Fu) << 21;
|
||||
if ( (bt & 0x80) == 0 ) {
|
||||
return val;
|
||||
}
|
||||
bt = ReadByte();
|
||||
val |= (bt & 0x7Fu) << 28;
|
||||
return val;
|
||||
}
|
||||
|
||||
static public MemoryStream DecompressZBytes(byte[] compressed_bytes) {
|
||||
var target = new MemoryStream();
|
||||
var zip_stream = new ZlibStream(target, CompressionMode.Decompress);
|
||||
zip_stream.Write(compressed_bytes, 0, compressed_bytes.Length);
|
||||
target.Position = 0;
|
||||
return target;
|
||||
}
|
||||
|
||||
static public SwfStreamReader DecompressZBytesToReader(byte[] compressd_bytes) {
|
||||
return new SwfStreamReader(DecompressZBytes(compressd_bytes));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f74479d84178d4e99b36548fea8c9018
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/FlashTools/Scripts/Editor/FTSwfTools/SwfTags.meta
Normal file
9
Assets/FlashTools/Scripts/Editor/FTSwfTools/SwfTags.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 016bcd9f9a8854239a74a42b6cc97d6e
|
||||
folderAsset: yes
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DefineBinaryDataTag : SwfTagBase {
|
||||
public ushort Tag;
|
||||
public byte[] Data;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DefineBinaryData; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return "DefineBinaryDataTag.";
|
||||
}
|
||||
|
||||
public static DefineBinaryDataTag Create(SwfStreamReader reader) {
|
||||
var tag = reader.ReadUInt16();
|
||||
reader.ReadUInt32(); // reserved
|
||||
var data = reader.ReadRest();
|
||||
return new DefineBinaryDataTag{
|
||||
Tag = tag,
|
||||
Data = data};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f575b02b14ea14619a6494cdc7f3c45c
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,79 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DefineBitsLossless2Tag : SwfTagBase {
|
||||
public ushort CharacterId;
|
||||
public byte BitmapFormat;
|
||||
public ushort BitmapWidth;
|
||||
public ushort BitmapHeight;
|
||||
public ushort BitmapColorTableSize;
|
||||
public byte[] ZlibBitmapData;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DefineBitsLossless2; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"DefineBitsLossless2Tag. " +
|
||||
"CharacterId: {0}, BitmapFormat: {1}, Width: {2}, Height: {3}",
|
||||
CharacterId, BitmapFormat, BitmapWidth, BitmapHeight);
|
||||
}
|
||||
|
||||
public static DefineBitsLossless2Tag Create(SwfStreamReader reader) {
|
||||
var tag = new DefineBitsLossless2Tag();
|
||||
tag.CharacterId = reader.ReadUInt16();
|
||||
tag.BitmapFormat = reader.ReadByte();
|
||||
tag.BitmapWidth = reader.ReadUInt16();
|
||||
tag.BitmapHeight = reader.ReadUInt16();
|
||||
if ( tag.BitmapFormat == 3 ) {
|
||||
tag.BitmapColorTableSize = (ushort)(reader.ReadByte() + 1);
|
||||
}
|
||||
tag.ZlibBitmapData = reader.ReadRest();
|
||||
return tag;
|
||||
}
|
||||
|
||||
public byte[] ToARGB32() {
|
||||
var result = new byte[BitmapWidth * BitmapHeight * 4];
|
||||
var swf_reader = SwfStreamReader.DecompressZBytesToReader(ZlibBitmapData);
|
||||
if ( BitmapFormat == 3 ) {
|
||||
var palette = new SwfColor[BitmapColorTableSize];
|
||||
for ( var i = 0; i < palette.Length; ++i ) {
|
||||
palette[i] = SwfColor.Read(swf_reader, true);
|
||||
}
|
||||
var palette_pitch = BitmapWidth % 4 == 0
|
||||
? BitmapWidth
|
||||
: BitmapWidth + (4 - BitmapWidth % 4);
|
||||
var palette_indices = swf_reader.ReadRest();
|
||||
for ( var i = 0; i < BitmapHeight; ++i ) {
|
||||
for ( var j = 0; j < BitmapWidth; ++j ) {
|
||||
var result_index = j + i * BitmapWidth;
|
||||
var palette_index = palette_indices[j + i * palette_pitch];
|
||||
var palette_color = palette[palette_index];
|
||||
result[result_index * 4 + 0] = palette_color.A;
|
||||
result[result_index * 4 + 1] = palette_color.R;
|
||||
result[result_index * 4 + 2] = palette_color.G;
|
||||
result[result_index * 4 + 3] = palette_color.B;
|
||||
}
|
||||
}
|
||||
} else if ( BitmapFormat == 5 ) {
|
||||
for ( var i = 0; i < BitmapWidth * BitmapHeight; ++i ) {
|
||||
var pix32 = swf_reader.ReadUInt32();
|
||||
result[i * 4 + 0] = (byte)((pix32 ) & 0xFF);
|
||||
result[i * 4 + 1] = (byte)((pix32 >> 8) & 0xFF);
|
||||
result[i * 4 + 2] = (byte)((pix32 >> 16) & 0xFF);
|
||||
result[i * 4 + 3] = (byte)((pix32 >> 24) & 0xFF);
|
||||
}
|
||||
} else {
|
||||
throw new System.Exception(string.Format(
|
||||
"Incorrect DefineBitsLossless2 format: {0}",
|
||||
BitmapFormat));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74973cd8013ce40de91d3075a8975933
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,79 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DefineBitsLosslessTag : SwfTagBase {
|
||||
public ushort CharacterId;
|
||||
public byte BitmapFormat;
|
||||
public ushort BitmapWidth;
|
||||
public ushort BitmapHeight;
|
||||
public ushort BitmapColorTableSize;
|
||||
public byte[] ZlibBitmapData;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DefineBitsLossless; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"DefineBitsLosslessTag. " +
|
||||
"CharacterId: {0}, BitmapFormat: {1}, Width: {2}, Height: {3}",
|
||||
CharacterId, BitmapFormat, BitmapWidth, BitmapHeight);
|
||||
}
|
||||
|
||||
public static DefineBitsLosslessTag Create(SwfStreamReader reader) {
|
||||
var tag = new DefineBitsLosslessTag();
|
||||
tag.CharacterId = reader.ReadUInt16();
|
||||
tag.BitmapFormat = reader.ReadByte();
|
||||
tag.BitmapWidth = reader.ReadUInt16();
|
||||
tag.BitmapHeight = reader.ReadUInt16();
|
||||
if ( tag.BitmapFormat == 3 ) {
|
||||
tag.BitmapColorTableSize = (ushort)(reader.ReadByte() + 1);
|
||||
}
|
||||
tag.ZlibBitmapData = reader.ReadRest();
|
||||
return tag;
|
||||
}
|
||||
|
||||
public byte[] ToARGB32() {
|
||||
var result = new byte[BitmapWidth * BitmapHeight * 4];
|
||||
var swf_reader = SwfStreamReader.DecompressZBytesToReader(ZlibBitmapData);
|
||||
if ( BitmapFormat == 3 ) {
|
||||
var palette = new SwfColor[BitmapColorTableSize];
|
||||
for ( var i = 0; i < palette.Length; ++i ) {
|
||||
palette[i] = SwfColor.Read(swf_reader, false);
|
||||
}
|
||||
var palette_pitch = BitmapWidth % 4 == 0
|
||||
? BitmapWidth
|
||||
: BitmapWidth + (4 - BitmapWidth % 4);
|
||||
var palette_indices = swf_reader.ReadRest();
|
||||
for ( var i = 0; i < BitmapHeight; ++i ) {
|
||||
for ( var j = 0; j < BitmapWidth; ++j ) {
|
||||
var result_index = j + i * BitmapWidth;
|
||||
var palette_index = palette_indices[j + i * palette_pitch];
|
||||
var palette_color = palette[palette_index];
|
||||
result[result_index * 4 + 0] = palette_color.A;
|
||||
result[result_index * 4 + 1] = palette_color.R;
|
||||
result[result_index * 4 + 2] = palette_color.G;
|
||||
result[result_index * 4 + 3] = palette_color.B;
|
||||
}
|
||||
}
|
||||
} else if ( BitmapFormat == 5 ) {
|
||||
for ( var i = 0; i < BitmapWidth * BitmapHeight; ++i ) {
|
||||
var pix24 = swf_reader.ReadUInt32();
|
||||
result[i * 4 + 0] = 255;
|
||||
result[i * 4 + 1] = (byte)((pix24 >> 8) & 0xFF);
|
||||
result[i * 4 + 2] = (byte)((pix24 >> 16) & 0xFF);
|
||||
result[i * 4 + 3] = (byte)((pix24 >> 24) & 0xFF);
|
||||
}
|
||||
} else {
|
||||
throw new System.Exception(string.Format(
|
||||
"Incorrect DefineBitsLossless format: {0}",
|
||||
BitmapFormat));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 429c6687a02d14d3085500f077ff530d
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DefineSceneAndFrameLabelDataTag : SwfTagBase {
|
||||
public struct SceneOffsetData {
|
||||
public uint Offset;
|
||||
public string Name;
|
||||
}
|
||||
|
||||
public struct FrameLabelData {
|
||||
public uint Number;
|
||||
public string Label;
|
||||
}
|
||||
|
||||
public List<SceneOffsetData> Scenes;
|
||||
public List<FrameLabelData> Frames;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DefineSceneAndFrameLabelData; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"DefineSceneAndFrameLabelDataTag. " +
|
||||
"Scenes: {0}, Frames: {1}",
|
||||
Scenes.Count, Frames.Count);
|
||||
}
|
||||
|
||||
public static DefineSceneAndFrameLabelDataTag Create(SwfStreamReader reader) {
|
||||
var scene_count = reader.ReadEncodedU32();
|
||||
var scenes = new List<SceneOffsetData>((int)scene_count);
|
||||
for ( var i = 0; i < scene_count; ++i ) {
|
||||
scenes.Add(new SceneOffsetData{
|
||||
Offset = reader.ReadEncodedU32(),
|
||||
Name = reader.ReadString()});
|
||||
}
|
||||
var frame_count = reader.ReadEncodedU32();
|
||||
var frames = new List<FrameLabelData>((int)frame_count);
|
||||
for ( var i = 0; i < frame_count; ++i ) {
|
||||
frames.Add(new FrameLabelData{
|
||||
Number = reader.ReadEncodedU32(),
|
||||
Label = reader.ReadString()});
|
||||
}
|
||||
return new DefineSceneAndFrameLabelDataTag{
|
||||
Scenes = scenes,
|
||||
Frames = frames};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efa7367c5fcb442d59b7404a65305362
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DefineShape2Tag : SwfTagBase {
|
||||
public ushort ShapeId;
|
||||
public SwfRect ShapeBounds;
|
||||
public SwfShapesWithStyle Shapes;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DefineShape2; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"DefineShape2Tag. " +
|
||||
"ShapeId: {0}, ShapeBounds: {1}, Shapes: {2}",
|
||||
ShapeId, ShapeBounds, Shapes);
|
||||
}
|
||||
|
||||
public static DefineShape2Tag Create(SwfStreamReader reader) {
|
||||
var tag = new DefineShape2Tag();
|
||||
tag.ShapeId = reader.ReadUInt16();
|
||||
tag.ShapeBounds = SwfRect.Read(reader);
|
||||
tag.Shapes = SwfShapesWithStyle.Read(reader, SwfShapesWithStyle.ShapeStyleType.Shape2);
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 624f880cc6a9e4ff3b9535188f765ce6
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DefineShape3Tag : SwfTagBase {
|
||||
public ushort ShapeId;
|
||||
public SwfRect ShapeBounds;
|
||||
public SwfShapesWithStyle Shapes;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DefineShape3; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"DefineShape3Tag. " +
|
||||
"ShapeId: {0}, ShapeBounds: {1}, Shapes: {2}",
|
||||
ShapeId, ShapeBounds, Shapes);
|
||||
}
|
||||
|
||||
public static DefineShape3Tag Create(SwfStreamReader reader) {
|
||||
var tag = new DefineShape3Tag();
|
||||
tag.ShapeId = reader.ReadUInt16();
|
||||
tag.ShapeBounds = SwfRect.Read(reader);
|
||||
tag.Shapes = SwfShapesWithStyle.Read(reader, SwfShapesWithStyle.ShapeStyleType.Shape3);
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f9097ce9a09c4654af48a4dc68b2cfa
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DefineShape4Tag : SwfTagBase {
|
||||
public ushort ShapeId;
|
||||
public SwfRect ShapeBounds;
|
||||
public SwfRect EdgeBounds;
|
||||
public byte Flags;
|
||||
public SwfShapesWithStyle Shapes;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DefineShape4; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"DefineShape4Tag. " +
|
||||
"ShapeId: {0}, ShapeBounds: {1}, EdgeBounds: {2}, Flags: {3}, Shapes: {4}",
|
||||
ShapeId, ShapeBounds, EdgeBounds, Flags, Shapes);
|
||||
}
|
||||
|
||||
public static DefineShape4Tag Create(SwfStreamReader reader) {
|
||||
var tag = new DefineShape4Tag();
|
||||
tag.ShapeId = reader.ReadUInt16();
|
||||
tag.ShapeBounds = SwfRect.Read(reader);
|
||||
tag.EdgeBounds = SwfRect.Read(reader);
|
||||
tag.Flags = reader.ReadByte();
|
||||
tag.Shapes = SwfShapesWithStyle.Read(reader, SwfShapesWithStyle.ShapeStyleType.Shape4);
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 484dd3b5e4c0e4b3e9b3573b801655a0
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DefineShapeTag : SwfTagBase {
|
||||
public ushort ShapeId;
|
||||
public SwfRect ShapeBounds;
|
||||
public SwfShapesWithStyle Shapes;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DefineShape; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"DefineShapeTag. " +
|
||||
"ShapeId: {0}, ShapeBounds: {1}, Shapes: {2}",
|
||||
ShapeId, ShapeBounds, Shapes);
|
||||
}
|
||||
|
||||
public static DefineShapeTag Create(SwfStreamReader reader) {
|
||||
var tag = new DefineShapeTag();
|
||||
tag.ShapeId = reader.ReadUInt16();
|
||||
tag.ShapeBounds = SwfRect.Read(reader);
|
||||
tag.Shapes = SwfShapesWithStyle.Read(reader, SwfShapesWithStyle.ShapeStyleType.Shape);
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df23a741e649246b7889385d79ec793a
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DefineSpriteTag : SwfTagBase {
|
||||
public ushort SpriteId;
|
||||
public ushort FrameCount;
|
||||
public SwfControlTags ControlTags;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DefineSprite; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"DefineSpriteTag. " +
|
||||
"SpriteId: {0}, FrameCount: {1}, ControlTags: {2}",
|
||||
SpriteId, FrameCount, ControlTags.Tags.Count);
|
||||
}
|
||||
|
||||
public static DefineSpriteTag Create(SwfStreamReader reader) {
|
||||
var tag = new DefineSpriteTag();
|
||||
tag.SpriteId = reader.ReadUInt16();
|
||||
tag.FrameCount = reader.ReadUInt16();
|
||||
tag.ControlTags = SwfControlTags.Read(reader);
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4da706943c48d454eaf95512ea8825e4
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class DoABCTag : SwfTagBase {
|
||||
public bool ExecuteImmediately;
|
||||
public string Name;
|
||||
public byte[] ABCBytes;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.DoABC; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return "DoABCTag.";
|
||||
}
|
||||
|
||||
public static DoABCTag Create(SwfStreamReader reader) {
|
||||
const int kDoAbcLazyInitializeFlag = 1;
|
||||
var flags = reader.ReadUInt32();
|
||||
var name = reader.ReadString();
|
||||
var abc_bytes = reader.ReadRest();
|
||||
return new DoABCTag{
|
||||
ExecuteImmediately = (flags & kDoAbcLazyInitializeFlag) == 0,
|
||||
Name = name,
|
||||
ABCBytes = abc_bytes};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c874808021d1a4194a23b69769b55d5c
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class EnableDebugger2Tag : SwfTagBase {
|
||||
public string MD5PasswordHash;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.EnableDebugger2; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"EnableDebugger2Tag. " +
|
||||
"MD5PasswordHash: {0}",
|
||||
MD5PasswordHash.Length > 0);
|
||||
}
|
||||
|
||||
public static EnableDebugger2Tag Create(SwfStreamReader reader) {
|
||||
reader.ReadUInt16(); // reserved
|
||||
var md5 = reader.IsEOF
|
||||
? string.Empty
|
||||
: reader.ReadString();
|
||||
return new EnableDebugger2Tag{
|
||||
MD5PasswordHash = md5};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d07d2048281e74edca14d2ac53e6cc34
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class EnableDebuggerTag : SwfTagBase {
|
||||
public string MD5PasswordHash;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.EnableDebugger; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"EnableDebuggerTag. " +
|
||||
"MD5PasswordHash: {0}",
|
||||
MD5PasswordHash.Length > 0);
|
||||
}
|
||||
|
||||
public static EnableDebuggerTag Create(SwfStreamReader reader) {
|
||||
var md5 = reader.IsEOF
|
||||
? string.Empty
|
||||
: reader.ReadString();
|
||||
return new EnableDebuggerTag{
|
||||
MD5PasswordHash = md5};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b305abbd617034eb6be6228c4ba97aaa
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class EnableTelemetryTag : SwfTagBase {
|
||||
public byte[] SHA256PasswordHash;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.EnableTelemetry; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"EnableTelemetryTag. " +
|
||||
"SHA256PasswordHash: {0}",
|
||||
SHA256PasswordHash.Length > 0);
|
||||
}
|
||||
|
||||
public static EnableTelemetryTag Create(SwfStreamReader reader) {
|
||||
reader.ReadUInt16(); // reserved
|
||||
var sha256 = reader.IsEOF
|
||||
? new byte[0]
|
||||
: reader.ReadBytes(32);
|
||||
return new EnableTelemetryTag{
|
||||
SHA256PasswordHash = sha256};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb93cef115e0a4462bf445423c7bf545
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class EndTag : SwfTagBase {
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.End; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return "EndTag.";
|
||||
}
|
||||
|
||||
public static EndTag Create(SwfStreamReader reader) {
|
||||
return new EndTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4dfe3d96dd2254aa29e9d3b19eff4c57
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class ExportAssetsTag : SwfTagBase {
|
||||
public struct AssetTagData {
|
||||
public ushort Tag;
|
||||
public string Name;
|
||||
}
|
||||
|
||||
public List<AssetTagData> AssetTags;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.ExportAssets; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"ExportAssetsTag. " +
|
||||
"AssetTags: {0}",
|
||||
AssetTags.Count);
|
||||
}
|
||||
|
||||
public static ExportAssetsTag Create(SwfStreamReader reader) {
|
||||
var asset_tag_count = reader.ReadUInt16();
|
||||
var asset_tags = new List<AssetTagData>(asset_tag_count);
|
||||
for ( var i = 0; i < asset_tag_count; ++i ) {
|
||||
asset_tags.Add(new AssetTagData{
|
||||
Tag = reader.ReadUInt16(),
|
||||
Name = reader.ReadString()});
|
||||
}
|
||||
return new ExportAssetsTag{
|
||||
AssetTags = asset_tags};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 450da2d3976cb486cb31981e872e7d15
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class FileAttributesTag : SwfTagBase {
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.FileAttributes; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return "FileAttributesTag.";
|
||||
}
|
||||
|
||||
public static FileAttributesTag Create(SwfStreamReader reader) {
|
||||
return new FileAttributesTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3b52b843860243b9a934470d126def2
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class FrameLabelTag : SwfTagBase {
|
||||
public string Name;
|
||||
public byte AnchorFlag;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.FrameLabel; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"FrameLabelTag. " +
|
||||
"Name: {0}, AnchorFlag: {1}",
|
||||
Name, AnchorFlag);
|
||||
}
|
||||
|
||||
public static FrameLabelTag Create(SwfStreamReader reader) {
|
||||
var tag = new FrameLabelTag();
|
||||
tag.Name = reader.ReadString();
|
||||
tag.AnchorFlag = reader.IsEOF ? (byte)0 : reader.ReadByte();
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92d6c40c2bc2a4fa99fb91012d8b5508
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class MetadataTag : SwfTagBase {
|
||||
public string Metadata;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.Metadata; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"MetadataTag." +
|
||||
"Metadata: {0}",
|
||||
Metadata.Length);
|
||||
}
|
||||
|
||||
public static MetadataTag Create(SwfStreamReader reader) {
|
||||
return new MetadataTag{
|
||||
Metadata = reader.ReadString()};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00480b7b8728846b7a0e6bc464459cf0
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,102 @@
|
||||
using System.Text;
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class PlaceObject2Tag : SwfTagBase {
|
||||
public bool HasClipActions;
|
||||
public bool HasClipDepth;
|
||||
public bool HasName;
|
||||
public bool HasRatio;
|
||||
public bool HasColorTransform;
|
||||
public bool HasMatrix;
|
||||
public bool HasCharacter;
|
||||
public bool Move;
|
||||
public ushort Depth;
|
||||
public ushort CharacterId;
|
||||
public SwfMatrix Matrix;
|
||||
public SwfColorTransform ColorTransform;
|
||||
public ushort Ratio;
|
||||
public string Name;
|
||||
public ushort ClipDepth;
|
||||
public SwfClipActions ClipActions;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.PlaceObject2; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
var sb = new StringBuilder(1024);
|
||||
sb.Append("PlaceObject2Tag. ");
|
||||
sb.AppendFormat("Move: {0} Depth: {1}", Move, Depth);
|
||||
if ( HasCharacter ) {
|
||||
sb.AppendFormat(", CharacterId: {0}", CharacterId);
|
||||
}
|
||||
if ( HasMatrix ) {
|
||||
sb.AppendFormat(", Matrix: {0}", Matrix);
|
||||
}
|
||||
if ( HasColorTransform ) {
|
||||
sb.AppendFormat(", ColorTransform: {0}", ColorTransform);
|
||||
}
|
||||
if ( HasRatio ) {
|
||||
sb.AppendFormat(", Ratio: {0}", Ratio);
|
||||
}
|
||||
if ( HasName ) {
|
||||
sb.AppendFormat(", Name: {0}", Name);
|
||||
}
|
||||
if ( HasClipDepth ) {
|
||||
sb.AppendFormat(", ClipDepth: {0}", ClipDepth);
|
||||
}
|
||||
if ( HasClipActions ) {
|
||||
sb.AppendFormat(", ClipActions: {0}", ClipActions);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static PlaceObject2Tag Create(SwfStreamReader reader) {
|
||||
var tag = new PlaceObject2Tag();
|
||||
tag.HasClipActions = reader.ReadBit();
|
||||
tag.HasClipDepth = reader.ReadBit();
|
||||
tag.HasName = reader.ReadBit();
|
||||
tag.HasRatio = reader.ReadBit();
|
||||
tag.HasColorTransform = reader.ReadBit();
|
||||
tag.HasMatrix = reader.ReadBit();
|
||||
tag.HasCharacter = reader.ReadBit();
|
||||
tag.Move = reader.ReadBit();
|
||||
tag.Depth = reader.ReadUInt16();
|
||||
|
||||
tag.CharacterId = tag.HasCharacter
|
||||
? reader.ReadUInt16()
|
||||
: (ushort)0;
|
||||
|
||||
tag.Matrix = tag.HasMatrix
|
||||
? SwfMatrix.Read(reader, false)
|
||||
: SwfMatrix.identity;
|
||||
|
||||
tag.ColorTransform = tag.HasColorTransform
|
||||
? SwfColorTransform.Read(reader, true)
|
||||
: SwfColorTransform.identity;
|
||||
|
||||
tag.Ratio = tag.HasRatio
|
||||
? reader.ReadUInt16()
|
||||
: (ushort)0;
|
||||
|
||||
tag.Name = tag.HasName
|
||||
? reader.ReadString()
|
||||
: string.Empty;
|
||||
|
||||
tag.ClipDepth = tag.HasClipDepth
|
||||
? reader.ReadUInt16()
|
||||
: (ushort)0;
|
||||
|
||||
tag.ClipActions = tag.HasClipActions
|
||||
? SwfClipActions.Read(reader)
|
||||
: SwfClipActions.identity;
|
||||
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 747d4152ec9144997889ce384f3bf595
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,159 @@
|
||||
using System.Text;
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class PlaceObject3Tag : SwfTagBase {
|
||||
public bool HasClipActions;
|
||||
public bool HasClipDepth;
|
||||
public bool HasName;
|
||||
public bool HasRatio;
|
||||
public bool HasColorTransform;
|
||||
public bool HasMatrix;
|
||||
public bool HasCharacter;
|
||||
public bool Move;
|
||||
public bool OpaqueBackground;
|
||||
public bool HasVisible;
|
||||
public bool HasImage;
|
||||
public bool HasClassName;
|
||||
public bool HasCacheAsBitmap;
|
||||
public bool HasBlendMode;
|
||||
public bool HasFilterList;
|
||||
public ushort Depth;
|
||||
public string ClassName;
|
||||
public ushort CharacterId;
|
||||
public SwfMatrix Matrix;
|
||||
public SwfColorTransform ColorTransform;
|
||||
public ushort Ratio;
|
||||
public string Name;
|
||||
public ushort ClipDepth;
|
||||
public SwfSurfaceFilters SurfaceFilters;
|
||||
public SwfBlendMode BlendMode;
|
||||
public bool BitmapCache;
|
||||
public bool Visible;
|
||||
public SwfColor BackgroundColor;
|
||||
public SwfClipActions ClipActions;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.PlaceObject3; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
var sb = new StringBuilder(1024);
|
||||
sb.Append("PlaceObject3Tag. ");
|
||||
sb.AppendFormat("Move: {0} Depth: {1}", Move, Depth);
|
||||
if ( HasCharacter ) {
|
||||
sb.AppendFormat(", CharacterId: {0}", CharacterId);
|
||||
}
|
||||
if ( HasMatrix ) {
|
||||
sb.AppendFormat(", Matrix: {0}", Matrix);
|
||||
}
|
||||
if ( HasColorTransform ) {
|
||||
sb.AppendFormat(", ColorTransform: {0}", ColorTransform);
|
||||
}
|
||||
if ( HasRatio ) {
|
||||
sb.AppendFormat(", Ratio: {0}", Ratio);
|
||||
}
|
||||
if ( HasName ) {
|
||||
sb.AppendFormat(", Name: {0}", Name);
|
||||
}
|
||||
if ( HasClipDepth ) {
|
||||
sb.AppendFormat(", ClipDepth: {0}", ClipDepth);
|
||||
}
|
||||
if ( HasFilterList ) {
|
||||
sb.AppendFormat(", SurfaceFilters: {0}", SurfaceFilters);
|
||||
}
|
||||
if ( HasBlendMode ) {
|
||||
sb.AppendFormat(", BlendMode: {0}", BlendMode);
|
||||
}
|
||||
if ( HasCacheAsBitmap ) {
|
||||
sb.AppendFormat(", BitmapCache: {0}", BitmapCache);
|
||||
}
|
||||
if ( HasVisible ) {
|
||||
sb.AppendFormat(", Visible: {0}", Visible);
|
||||
}
|
||||
if ( HasClipActions ) {
|
||||
sb.AppendFormat(", ClipActions: {0}", ClipActions);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static PlaceObject3Tag Create(SwfStreamReader reader) {
|
||||
var tag = new PlaceObject3Tag();
|
||||
tag.HasClipActions = reader.ReadBit();
|
||||
tag.HasClipDepth = reader.ReadBit();
|
||||
tag.HasName = reader.ReadBit();
|
||||
tag.HasRatio = reader.ReadBit();
|
||||
tag.HasColorTransform = reader.ReadBit();
|
||||
tag.HasMatrix = reader.ReadBit();
|
||||
tag.HasCharacter = reader.ReadBit();
|
||||
tag.Move = reader.ReadBit();
|
||||
reader.ReadBit(); // reserved
|
||||
tag.OpaqueBackground = reader.ReadBit();
|
||||
tag.HasVisible = reader.ReadBit();
|
||||
tag.HasImage = reader.ReadBit();
|
||||
tag.HasClassName = reader.ReadBit();
|
||||
tag.HasCacheAsBitmap = reader.ReadBit();
|
||||
tag.HasBlendMode = reader.ReadBit();
|
||||
tag.HasFilterList = reader.ReadBit();
|
||||
tag.Depth = reader.ReadUInt16();
|
||||
|
||||
tag.ClassName = (tag.HasClassName || (tag.HasImage && tag.HasCharacter))
|
||||
? reader.ReadString()
|
||||
: string.Empty;
|
||||
|
||||
tag.CharacterId = tag.HasCharacter
|
||||
? reader.ReadUInt16()
|
||||
: (ushort)0;
|
||||
|
||||
tag.Matrix = tag.HasMatrix
|
||||
? SwfMatrix.Read(reader, false)
|
||||
: SwfMatrix.identity;
|
||||
|
||||
tag.ColorTransform = tag.HasColorTransform
|
||||
? SwfColorTransform.Read(reader, true)
|
||||
: SwfColorTransform.identity;
|
||||
|
||||
tag.Ratio = tag.HasRatio
|
||||
? reader.ReadUInt16()
|
||||
: (ushort)0;
|
||||
|
||||
tag.Name = tag.HasName
|
||||
? reader.ReadString()
|
||||
: string.Empty;
|
||||
|
||||
tag.ClipDepth = tag.HasClipDepth
|
||||
? reader.ReadUInt16()
|
||||
: (ushort)0;
|
||||
|
||||
tag.SurfaceFilters = tag.HasFilterList
|
||||
? SwfSurfaceFilters.Read(reader)
|
||||
: SwfSurfaceFilters.identity;
|
||||
|
||||
tag.BlendMode = tag.HasBlendMode
|
||||
? SwfBlendMode.Read(reader)
|
||||
: SwfBlendMode.identity;
|
||||
|
||||
tag.BitmapCache = tag.HasCacheAsBitmap
|
||||
? (0 != reader.ReadByte())
|
||||
: false;
|
||||
|
||||
tag.Visible = tag.HasVisible && !reader.IsEOF
|
||||
? (0 != reader.ReadByte())
|
||||
: true;
|
||||
|
||||
tag.BackgroundColor = tag.HasVisible && !reader.IsEOF
|
||||
? SwfColor.Read(reader, true)
|
||||
: SwfColor.identity;
|
||||
|
||||
tag.ClipActions = tag.HasClipActions && !reader.IsEOF
|
||||
? SwfClipActions.Read(reader)
|
||||
: SwfClipActions.identity;
|
||||
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1da3c123a8a1d440292ef39f5421c9db
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class PlaceObjectTag : SwfTagBase {
|
||||
public ushort CharacterId;
|
||||
public ushort Depth;
|
||||
public SwfMatrix Matrix;
|
||||
public SwfColorTransform ColorTransform;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.PlaceObject; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"PlaceObjectTag. " +
|
||||
"CharacterId: {0}, Depth: {1}, Matrix: {2}, ColorTransform: {3}",
|
||||
CharacterId, Depth, Matrix, ColorTransform);
|
||||
}
|
||||
|
||||
public static PlaceObjectTag Create(SwfStreamReader reader) {
|
||||
var tag = new PlaceObjectTag();
|
||||
tag.CharacterId = reader.ReadUInt16();
|
||||
tag.Depth = reader.ReadUInt16();
|
||||
tag.Matrix = SwfMatrix.Read(reader, false);
|
||||
tag.ColorTransform = reader.IsEOF
|
||||
? SwfColorTransform.identity
|
||||
: SwfColorTransform.Read(reader, false);
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c6707734beef4d66bd42d9a97492ea3
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class ProtectTag : SwfTagBase {
|
||||
public string MD5Password;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.Protect; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"ProtectTag. " +
|
||||
"MD5Password: {0}",
|
||||
MD5Password);
|
||||
}
|
||||
|
||||
public static ProtectTag Create(SwfStreamReader reader) {
|
||||
var md5_password = reader.IsEOF
|
||||
? string.Empty
|
||||
: reader.ReadString();
|
||||
return new ProtectTag{
|
||||
MD5Password = md5_password};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 187040004fd5a4b6d8baae9c8fa0a4bd
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class RemoveObject2Tag : SwfTagBase {
|
||||
public ushort Depth;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.RemoveObject2; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"RemoveObject2Tag. " +
|
||||
"Depth: {0}",
|
||||
Depth);
|
||||
}
|
||||
|
||||
public static RemoveObject2Tag Create(SwfStreamReader reader) {
|
||||
return new RemoveObject2Tag{
|
||||
Depth = reader.ReadUInt16()};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 921fd18e30cdc4bfe959cb56d98dc4b1
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class RemoveObjectTag : SwfTagBase {
|
||||
public ushort CharacterId;
|
||||
public ushort Depth;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.RemoveObject; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"RemoveObjectTag. " +
|
||||
"CharacterId: {0}, Depth: {1}",
|
||||
CharacterId, Depth);
|
||||
}
|
||||
|
||||
public static RemoveObjectTag Create(SwfStreamReader reader) {
|
||||
return new RemoveObjectTag{
|
||||
CharacterId = reader.ReadUInt16(),
|
||||
Depth = reader.ReadUInt16()};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 101a7703fc0ba4b778035c09aa49ef1d
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class ScriptLimitsTag : SwfTagBase {
|
||||
public ushort MaxRecursionDepth;
|
||||
public ushort ScriptTimeoutSeconds;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.ScriptLimits; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"ScriptLimitsTag. " +
|
||||
"MaxRecursionDepth: {0}, ScriptTimeoutSeconds: {1}",
|
||||
MaxRecursionDepth, ScriptTimeoutSeconds);
|
||||
}
|
||||
|
||||
public static ScriptLimitsTag Create(SwfStreamReader reader) {
|
||||
return new ScriptLimitsTag{
|
||||
MaxRecursionDepth = reader.ReadUInt16(),
|
||||
ScriptTimeoutSeconds = reader.ReadUInt16()};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3dfd5e1c9e9994bfb9dd7a986793731a
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
using FTSwfTools.SwfTypes;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class SetBackgroundColorTag : SwfTagBase {
|
||||
public SwfColor BackgroundColor;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.SetBackgroundColor; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"SetBackgroundColorTag. " +
|
||||
"BackgroundColor: {0}",
|
||||
BackgroundColor);
|
||||
}
|
||||
|
||||
public static SetBackgroundColorTag Create(SwfStreamReader reader) {
|
||||
return new SetBackgroundColorTag{
|
||||
BackgroundColor = SwfColor.Read(reader, false)};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 208e93968679148b0ac90e47e2123b83
|
||||
timeCreated: 1480698333
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class ShowFrameTag : SwfTagBase {
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.ShowFrame; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return "ShowFrameTag.";
|
||||
}
|
||||
|
||||
public static ShowFrameTag Create(SwfStreamReader reader) {
|
||||
return new ShowFrameTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b770aef24ab1493ebc280b28dd74352
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,215 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public enum SwfTagType {
|
||||
// -----------------------------
|
||||
// Display list
|
||||
// -----------------------------
|
||||
|
||||
PlaceObject = 4,
|
||||
PlaceObject2 = 26,
|
||||
PlaceObject3 = 70,
|
||||
RemoveObject = 5,
|
||||
RemoveObject2 = 28,
|
||||
ShowFrame = 1,
|
||||
|
||||
// -----------------------------
|
||||
// Control
|
||||
// -----------------------------
|
||||
|
||||
SetBackgroundColor = 9,
|
||||
FrameLabel = 43,
|
||||
Protect = 24,
|
||||
End = 0,
|
||||
ExportAssets = 56,
|
||||
ImportAssets = 57, // Unsupported
|
||||
EnableDebugger = 58,
|
||||
EnableDebugger2 = 64,
|
||||
ScriptLimits = 65,
|
||||
SetTabIndex = 66, // Unsupported
|
||||
ImportAssets2 = 71, // Unsupported
|
||||
SymbolClass = 76,
|
||||
Metadata = 77,
|
||||
DefineScalingGrid = 78, // Unsupported
|
||||
DefineSceneAndFrameLabelData = 86,
|
||||
|
||||
// -----------------------------
|
||||
// Actions
|
||||
// -----------------------------
|
||||
|
||||
DoAction = 12, // Unsupported
|
||||
DoInitAction = 59, // Unsupported
|
||||
DoABC = 82,
|
||||
|
||||
// -----------------------------
|
||||
// Shape
|
||||
// -----------------------------
|
||||
|
||||
DefineShape = 2,
|
||||
DefineShape2 = 22,
|
||||
DefineShape3 = 32,
|
||||
DefineShape4 = 83,
|
||||
|
||||
// -----------------------------
|
||||
// Bitmaps
|
||||
// -----------------------------
|
||||
|
||||
DefineBits = 6, // Unsupported
|
||||
JPEGTables = 8, // Unsupported
|
||||
DefineBitsJPEG2 = 21, // Unsupported
|
||||
DefineBitsJPEG3 = 35, // Unsupported
|
||||
DefineBitsLossless = 20,
|
||||
DefineBitsLossless2 = 36,
|
||||
DefineBitsJPEG4 = 90, // Unsupported
|
||||
|
||||
// -----------------------------
|
||||
// Shape Morphing
|
||||
// -----------------------------
|
||||
|
||||
DefineMorphShape = 46, // Unsupported
|
||||
DefineMorphShape2 = 84, // Unsupported
|
||||
|
||||
// -----------------------------
|
||||
// Fonts and Text
|
||||
// -----------------------------
|
||||
|
||||
//DefineFont = 10,
|
||||
//DefineFontInfo = 13,
|
||||
//DefineFontInfo2 = 62,
|
||||
//DefineFont2 = 48,
|
||||
//DefineFont3 = 75,
|
||||
//DefineFontAlignZones = 73,
|
||||
//DefineFontName = 88,
|
||||
//DefineText = 11,
|
||||
//DefineText2 = 33,
|
||||
//DefineEditText = 37,
|
||||
//CSMTextSettings = 74,
|
||||
//DefineFont4 = 91,
|
||||
|
||||
// -----------------------------
|
||||
// Sounds
|
||||
// -----------------------------
|
||||
|
||||
//DefineSound = 14,
|
||||
//StartSound = 15,
|
||||
//StartSound2 = 89,
|
||||
//SoundStreamHead = 18,
|
||||
//SoundStreamHead2 = 45,
|
||||
//SoundStreamBlock = 19,
|
||||
|
||||
// -----------------------------
|
||||
// Buttons
|
||||
// -----------------------------
|
||||
|
||||
//DefineButton = 7,
|
||||
//DefineButton2 = 34,
|
||||
//DefineButtonCxform = 23,
|
||||
//DefineButtonSound = 17,
|
||||
|
||||
// -----------------------------
|
||||
// Sprites and Movie Clips
|
||||
// -----------------------------
|
||||
|
||||
DefineSprite = 39,
|
||||
|
||||
// -----------------------------
|
||||
// Video
|
||||
// -----------------------------
|
||||
|
||||
DefineVideoStream = 60, // Unsupported
|
||||
VideoFrame = 61, // Unsupported
|
||||
|
||||
// -----------------------------
|
||||
// Metadata
|
||||
// -----------------------------
|
||||
|
||||
FileAttributes = 69,
|
||||
EnableTelemetry = 93,
|
||||
DefineBinaryData = 87,
|
||||
|
||||
// -----------------------------
|
||||
// Unknown
|
||||
// -----------------------------
|
||||
|
||||
Unknown
|
||||
}
|
||||
|
||||
public abstract class SwfTagBase {
|
||||
struct SwfTagData {
|
||||
public int TagId;
|
||||
public byte[] TagData;
|
||||
}
|
||||
|
||||
public abstract SwfTagType TagType { get; }
|
||||
public abstract TResult AcceptVistor<TArg, TResult>(
|
||||
SwfTagVisitor<TArg, TResult> visitor, TArg arg);
|
||||
|
||||
public static SwfTagBase Read(SwfStreamReader reader) {
|
||||
var type_and_size = reader.ReadUInt16();
|
||||
var tag_id = type_and_size >> 6;
|
||||
var short_size = type_and_size & 0x3f;
|
||||
var size = short_size < 0x3f ? short_size : reader.ReadInt32();
|
||||
var tag_data = reader.ReadBytes(size);
|
||||
return Create(new SwfTagData{
|
||||
TagId = tag_id,
|
||||
TagData = tag_data});
|
||||
}
|
||||
|
||||
static SwfTagBase Create(SwfTagData tag_data) {
|
||||
var reader = new SwfStreamReader(tag_data.TagData);
|
||||
switch ( tag_data.TagId ) {
|
||||
// Display list
|
||||
case (int)SwfTagType.PlaceObject: return PlaceObjectTag.Create(reader);
|
||||
case (int)SwfTagType.PlaceObject2: return PlaceObject2Tag.Create(reader);
|
||||
case (int)SwfTagType.PlaceObject3: return PlaceObject3Tag.Create(reader);
|
||||
case (int)SwfTagType.RemoveObject: return RemoveObjectTag.Create(reader);
|
||||
case (int)SwfTagType.RemoveObject2: return RemoveObject2Tag.Create(reader);
|
||||
case (int)SwfTagType.ShowFrame: return ShowFrameTag.Create(reader);
|
||||
// Control
|
||||
case (int)SwfTagType.SetBackgroundColor: return SetBackgroundColorTag.Create(reader);
|
||||
case (int)SwfTagType.FrameLabel: return FrameLabelTag.Create(reader);
|
||||
case (int)SwfTagType.Protect: return ProtectTag.Create(reader);
|
||||
case (int)SwfTagType.End: return EndTag.Create(reader);
|
||||
case (int)SwfTagType.ExportAssets: return ExportAssetsTag.Create(reader);
|
||||
case (int)SwfTagType.ImportAssets: return UnsupportedTag.Create(SwfTagType.ImportAssets);
|
||||
case (int)SwfTagType.EnableDebugger: return EnableDebuggerTag.Create(reader);
|
||||
case (int)SwfTagType.EnableDebugger2: return EnableDebugger2Tag.Create(reader);
|
||||
case (int)SwfTagType.ScriptLimits: return ScriptLimitsTag.Create(reader);
|
||||
case (int)SwfTagType.SetTabIndex: return UnsupportedTag.Create(SwfTagType.SetTabIndex);
|
||||
case (int)SwfTagType.ImportAssets2: return UnsupportedTag.Create(SwfTagType.ImportAssets2);
|
||||
case (int)SwfTagType.SymbolClass: return SymbolClassTag.Create(reader);
|
||||
case (int)SwfTagType.Metadata: return MetadataTag.Create(reader);
|
||||
case (int)SwfTagType.DefineScalingGrid: return UnsupportedTag.Create(SwfTagType.DefineScalingGrid);
|
||||
case (int)SwfTagType.DefineSceneAndFrameLabelData: return DefineSceneAndFrameLabelDataTag.Create(reader);
|
||||
// Actions
|
||||
case (int)SwfTagType.DoAction: return UnsupportedTag.Create(SwfTagType.DoAction);
|
||||
case (int)SwfTagType.DoInitAction: return UnsupportedTag.Create(SwfTagType.DoInitAction);
|
||||
case (int)SwfTagType.DoABC: return DoABCTag.Create(reader);
|
||||
// Shape
|
||||
case (int)SwfTagType.DefineShape: return DefineShapeTag.Create(reader);
|
||||
case (int)SwfTagType.DefineShape2: return DefineShape2Tag.Create(reader);
|
||||
case (int)SwfTagType.DefineShape3: return DefineShape3Tag.Create(reader);
|
||||
case (int)SwfTagType.DefineShape4: return DefineShape4Tag.Create(reader);
|
||||
// Bitmaps
|
||||
case (int)SwfTagType.DefineBits: return UnsupportedTag.Create(SwfTagType.DefineBits);
|
||||
case (int)SwfTagType.JPEGTables: return UnsupportedTag.Create(SwfTagType.JPEGTables);
|
||||
case (int)SwfTagType.DefineBitsJPEG2: return UnsupportedTag.Create(SwfTagType.DefineBitsJPEG2);
|
||||
case (int)SwfTagType.DefineBitsJPEG3: return UnsupportedTag.Create(SwfTagType.DefineBitsJPEG3);
|
||||
case (int)SwfTagType.DefineBitsLossless: return DefineBitsLosslessTag.Create(reader);
|
||||
case (int)SwfTagType.DefineBitsLossless2: return DefineBitsLossless2Tag.Create(reader);
|
||||
case (int)SwfTagType.DefineBitsJPEG4: return UnsupportedTag.Create(SwfTagType.DefineBitsJPEG4);
|
||||
// Shape Morphing
|
||||
case (int)SwfTagType.DefineMorphShape: return UnsupportedTag.Create(SwfTagType.DefineMorphShape);
|
||||
case (int)SwfTagType.DefineMorphShape2: return UnsupportedTag.Create(SwfTagType.DefineMorphShape2);
|
||||
// Sprites and Movie Clips
|
||||
case (int)SwfTagType.DefineSprite: return DefineSpriteTag.Create(reader);
|
||||
// Video
|
||||
case (int)SwfTagType.DefineVideoStream: return UnsupportedTag.Create(SwfTagType.DefineVideoStream);
|
||||
case (int)SwfTagType.VideoFrame: return UnsupportedTag.Create(SwfTagType.VideoFrame);
|
||||
// Metadata
|
||||
case (int)SwfTagType.FileAttributes: return FileAttributesTag.Create(reader);
|
||||
case (int)SwfTagType.EnableTelemetry: return EnableTelemetryTag.Create(reader);
|
||||
case (int)SwfTagType.DefineBinaryData: return DefineBinaryDataTag.Create(reader);
|
||||
default: return UnknownTag.Create(tag_data.TagId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc1cdfaed54624bf5901949f3a6e1de8
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,41 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public interface SwfTagVisitor<TArg, TResult> {
|
||||
TResult Visit(PlaceObjectTag tag, TArg arg);
|
||||
TResult Visit(PlaceObject2Tag tag, TArg arg);
|
||||
TResult Visit(PlaceObject3Tag tag, TArg arg);
|
||||
TResult Visit(RemoveObjectTag tag, TArg arg);
|
||||
TResult Visit(RemoveObject2Tag tag, TArg arg);
|
||||
TResult Visit(ShowFrameTag tag, TArg arg);
|
||||
|
||||
TResult Visit(SetBackgroundColorTag tag, TArg arg);
|
||||
TResult Visit(FrameLabelTag tag, TArg arg);
|
||||
TResult Visit(ProtectTag tag, TArg arg);
|
||||
TResult Visit(EndTag tag, TArg arg);
|
||||
TResult Visit(ExportAssetsTag tag, TArg arg);
|
||||
TResult Visit(EnableDebuggerTag tag, TArg arg);
|
||||
TResult Visit(EnableDebugger2Tag tag, TArg arg);
|
||||
TResult Visit(ScriptLimitsTag tag, TArg arg);
|
||||
TResult Visit(SymbolClassTag tag, TArg arg);
|
||||
TResult Visit(MetadataTag tag, TArg arg);
|
||||
TResult Visit(DefineSceneAndFrameLabelDataTag tag, TArg arg);
|
||||
|
||||
TResult Visit(DoABCTag tag, TArg arg);
|
||||
|
||||
TResult Visit(DefineShapeTag tag, TArg arg);
|
||||
TResult Visit(DefineShape2Tag tag, TArg arg);
|
||||
TResult Visit(DefineShape3Tag tag, TArg arg);
|
||||
TResult Visit(DefineShape4Tag tag, TArg arg);
|
||||
|
||||
TResult Visit(DefineBitsLosslessTag tag, TArg arg);
|
||||
TResult Visit(DefineBitsLossless2Tag tag, TArg arg);
|
||||
|
||||
TResult Visit(DefineSpriteTag tag, TArg arg);
|
||||
|
||||
TResult Visit(FileAttributesTag tag, TArg arg);
|
||||
TResult Visit(EnableTelemetryTag tag, TArg arg);
|
||||
TResult Visit(DefineBinaryDataTag tag, TArg arg);
|
||||
|
||||
TResult Visit(UnknownTag tag, TArg arg);
|
||||
TResult Visit(UnsupportedTag tag, TArg arg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed5748da6df1441499430064aebbe281
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class SymbolClassTag : SwfTagBase {
|
||||
public struct SymbolTagData {
|
||||
public ushort Tag;
|
||||
public string Name;
|
||||
}
|
||||
|
||||
public List<SymbolTagData> SymbolTags;
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.SymbolClass; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"SymbolClassTag. " +
|
||||
"SymbolTags: {0}",
|
||||
SymbolTags.Count);
|
||||
}
|
||||
|
||||
public static SymbolClassTag Create(SwfStreamReader reader) {
|
||||
var symbol_tag_count = reader.ReadUInt16();
|
||||
var symbol_tags = new List<SymbolTagData>(symbol_tag_count);
|
||||
for ( var i = 0; i < symbol_tag_count; ++i ) {
|
||||
symbol_tags.Add(new SymbolTagData{
|
||||
Tag = reader.ReadUInt16(),
|
||||
Name = reader.ReadString()});
|
||||
}
|
||||
return new SymbolClassTag{
|
||||
SymbolTags = symbol_tags};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 839ce6f050cc84d9cbe230bae1ed1d0c
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace FTSwfTools.SwfTags {
|
||||
public class UnknownTag : SwfTagBase {
|
||||
public int _tagId;
|
||||
|
||||
public int TagId {
|
||||
get { return _tagId; }
|
||||
}
|
||||
|
||||
public override SwfTagType TagType {
|
||||
get { return SwfTagType.Unknown; }
|
||||
}
|
||||
|
||||
public override TResult AcceptVistor<TArg, TResult>(SwfTagVisitor<TArg, TResult> visitor, TArg arg) {
|
||||
return visitor.Visit(this, arg);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format(
|
||||
"UnknownTag. " +
|
||||
"TagId: {0}",
|
||||
TagId);
|
||||
}
|
||||
|
||||
public static UnknownTag Create(int tag_id) {
|
||||
return new UnknownTag{
|
||||
_tagId = tag_id};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 990d254d413d44d0f94f6636605cd558
|
||||
timeCreated: 1480698334
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user