Compare commits
85 Commits
Author | SHA1 | Date | |
---|---|---|---|
d510fec57b | |||
c5214dd477 | |||
a2391aeb22 | |||
2207c80951 | |||
bf578d7cb9 | |||
0bc57c368f | |||
b64f85aaa2 | |||
93fa2f2d7e | |||
d72216de8b | |||
df5133a91a | |||
88b959a118 | |||
310bf91fbd | |||
699f47f98d | |||
24e881b138 | |||
2eef1b5c4e | |||
c18ceb50d4 | |||
27ca1a7292 | |||
dc59176eac | |||
aec7470ff8 | |||
983cba6843 | |||
871782e73f | |||
9aaa96fe10 | |||
22190a29c1 | |||
613ca467d0 | |||
536a3066b2 | |||
43488cd002 | |||
a11ccbd39c | |||
76df4929a7 | |||
505b826627 | |||
26a8675922 | |||
b89e1f983e | |||
717e77b47e | |||
2f10c79dee | |||
55f7790f89 | |||
ae5f4a8c16 | |||
1851bd3c54 | |||
6d74685cb7 | |||
03fd7f6d01 | |||
28c878f3e5 | |||
7736eba14d | |||
2e54b38d2b | |||
da60dc0903 | |||
215f72b3b5 | |||
a93c081dd8 | |||
456782930a | |||
ba3cbbd64c | |||
dfc3e9ca06 | |||
f567a2b78e | |||
c7e7bd8a77 | |||
67720fd0e1 | |||
1a30149942 | |||
a755cc13bd | |||
9a51cf1b56 | |||
256c656e9c | |||
2ac7f05316 | |||
28d46dbabe | |||
18b3e0bc84 | |||
23f2e7c1f2 | |||
998713b41f | |||
3561354231 | |||
0cccb170c1 | |||
d2480b8a6f | |||
6837d3f7ee | |||
3ecf3b4bfc | |||
1da8647ff1 | |||
2f19e8daad | |||
07f62c7aeb | |||
39db8dfa45 | |||
f04cd370f1 | |||
5c4acd54ce | |||
82dbc5c479 | |||
1f1663d714 | |||
a3c5392caa | |||
6c983cc2cb | |||
3bf3fdac3d | |||
f2f3dba098 | |||
3728360dd2 | |||
887837bb3d | |||
99b4c2dfc1 | |||
e59769158a | |||
ba3238614b | |||
a115999aab | |||
393947db9f | |||
e9b2a7f894 | |||
9c73455761 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -68,3 +68,4 @@ crashlytics-build.properties
|
||||
/UserSettings
|
||||
/*.zip
|
||||
*.lnk
|
||||
/HybridCLRData
|
||||
|
8
Assets/Cryville/Common/Collections.meta
Normal file
8
Assets/Cryville/Common/Collections.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4ef48e4a4983de4e9c31483df2a918e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Cryville/Common/Collections/Generic.meta
Normal file
8
Assets/Cryville/Common/Collections/Generic.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ec674235c0dd6744af2dab2b58dd53c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Cryville/Common/Collections/Generic/IPairList.cs
Normal file
8
Assets/Cryville/Common/Collections/Generic/IPairList.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Common.Collections.Generic {
|
||||
public interface IPairList<TKey, TValue> : IList<KeyValuePair<TKey, TValue>> {
|
||||
void Add(TKey key, TValue value);
|
||||
void Insert(int index, TKey key, TValue value);
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Collections/Generic/IPairList.cs.meta
Normal file
11
Assets/Cryville/Common/Collections/Generic/IPairList.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73fb17b484b343242bcce27c15ed7d44
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
46
Assets/Cryville/Common/Collections/Generic/PairCollection.cs
Normal file
46
Assets/Cryville/Common/Collections/Generic/PairCollection.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cryville.Common.Collections.Generic {
|
||||
[DebuggerDisplay("Count = {Count}"), DebuggerTypeProxy(typeof(PairCollectionDebugView<,>))]
|
||||
public struct PairCollection<TKey, TValue> : IDisposable {
|
||||
public void Dispose() { }
|
||||
readonly IPairList<TKey, TValue> _pairList;
|
||||
readonly IDictionary<TKey, TValue> _dictionary;
|
||||
public PairCollection(object collection) : this() {
|
||||
var type = collection.GetType();
|
||||
if (typeof(IPairList<TKey, TValue>).IsAssignableFrom(type)) _pairList = (IPairList<TKey, TValue>)collection;
|
||||
else if (typeof(IDictionary<TKey, TValue>).IsAssignableFrom(type)) _dictionary = (IDictionary<TKey, TValue>)collection;
|
||||
else throw new ArgumentException("Parameter is not a pair collection");
|
||||
}
|
||||
public int Count {
|
||||
get {
|
||||
if (_pairList != null) return _pairList.Count;
|
||||
else return _dictionary.Count;
|
||||
}
|
||||
}
|
||||
public void Add(TKey key, TValue value) {
|
||||
if (_pairList != null) _pairList.Add(key, value);
|
||||
else _dictionary.Add(key, value);
|
||||
}
|
||||
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index) {
|
||||
if (_pairList != null) _pairList.CopyTo(array, index);
|
||||
else _dictionary.CopyTo(array, index);
|
||||
}
|
||||
}
|
||||
internal class PairCollectionDebugView<TKey, TValue> {
|
||||
readonly PairCollection<TKey, TValue> _self;
|
||||
public PairCollectionDebugView(PairCollection<TKey, TValue> self) {
|
||||
_self = self;
|
||||
}
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePair<TKey, TValue>[] Items {
|
||||
get {
|
||||
KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[_self.Count];
|
||||
_self.CopyTo(array, 0);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2517e8f040bd36f46948e5fafaf5335c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
48
Assets/Cryville/Common/Collections/Generic/PairList.cs
Normal file
48
Assets/Cryville/Common/Collections/Generic/PairList.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cryville.Common.Collections.Generic {
|
||||
[DebuggerDisplay("Count = {Count}"), DebuggerTypeProxy(typeof(PairListDebugView<,>))]
|
||||
public class PairList<TKey, TValue> : List<KeyValuePair<TKey, TValue>>, IPairList<TKey, TValue>, IPairList {
|
||||
public void Add(TKey key, TValue value) {
|
||||
Add(new KeyValuePair<TKey, TValue>(key, value));
|
||||
}
|
||||
|
||||
public void Add(object key, object value) {
|
||||
try {
|
||||
Add((TKey)key, (TValue)value);
|
||||
}
|
||||
catch (InvalidCastException) {
|
||||
throw new ArgumentException("Wrong key type or value type");
|
||||
}
|
||||
}
|
||||
|
||||
public void Insert(int index, TKey key, TValue value) {
|
||||
Insert(index, new KeyValuePair<TKey, TValue>(key, value));
|
||||
}
|
||||
|
||||
public void Insert(int index, object key, object value) {
|
||||
try {
|
||||
Insert(index, (TKey)key, (TValue)value);
|
||||
}
|
||||
catch (InvalidCastException) {
|
||||
throw new ArgumentException("Wrong key type or value type");
|
||||
}
|
||||
}
|
||||
}
|
||||
internal class PairListDebugView<TKey, TValue> {
|
||||
readonly PairList<TKey, TValue> _self;
|
||||
public PairListDebugView(PairList<TKey, TValue> self) {
|
||||
_self = self;
|
||||
}
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePair<TKey, TValue>[] Items {
|
||||
get {
|
||||
KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[_self.Count];
|
||||
_self.CopyTo(array, 0);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Collections/Generic/PairList.cs.meta
Normal file
11
Assets/Cryville/Common/Collections/Generic/PairList.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9ed5ea8b7b1a934287e7ec5971166c0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Cryville/Common/Collections/IPairList.cs
Normal file
8
Assets/Cryville/Common/Collections/IPairList.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using System.Collections;
|
||||
|
||||
namespace Cryville.Common.Collections {
|
||||
public interface IPairList : IList {
|
||||
void Add(object key, object value);
|
||||
void Insert(int index, object key, object value);
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Collections/IPairList.cs.meta
Normal file
11
Assets/Cryville/Common/Collections/IPairList.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 046617672d437de4ab7e644a55defd3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
47
Assets/Cryville/Common/Collections/PairCollection.cs
Normal file
47
Assets/Cryville/Common/Collections/PairCollection.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cryville.Common.Collections {
|
||||
[DebuggerDisplay("Count = {Count}"), DebuggerTypeProxy(typeof(PairCollectionDebugView))]
|
||||
public struct PairCollection : IDisposable {
|
||||
public void Dispose() { }
|
||||
readonly IPairList _pairList;
|
||||
readonly IDictionary _dictionary;
|
||||
public PairCollection(object collection) : this() {
|
||||
var type = collection.GetType();
|
||||
if (typeof(IPairList).IsAssignableFrom(type)) _pairList = (IPairList)collection;
|
||||
else if (typeof(IDictionary).IsAssignableFrom(type)) _dictionary = (IDictionary)collection;
|
||||
else throw new ArgumentException("Parameter is not a pair collection");
|
||||
}
|
||||
public int Count {
|
||||
get {
|
||||
if (_pairList != null) return _pairList.Count;
|
||||
else return _dictionary.Count;
|
||||
}
|
||||
}
|
||||
public void Add(object key, object value) {
|
||||
if (_pairList != null) _pairList.Add(key, value);
|
||||
else _dictionary.Add(key, value);
|
||||
}
|
||||
public void CopyTo(KeyValuePair<object, object>[] array, int index) {
|
||||
if (_pairList != null) _pairList.CopyTo(array, index);
|
||||
else _dictionary.CopyTo(array, index);
|
||||
}
|
||||
}
|
||||
internal class PairCollectionDebugView {
|
||||
readonly PairCollection _self;
|
||||
public PairCollectionDebugView(PairCollection self) {
|
||||
_self = self;
|
||||
}
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePair<object, object>[] Items {
|
||||
get {
|
||||
KeyValuePair<object, object>[] array = new KeyValuePair<object, object>[_self.Count];
|
||||
_self.CopyTo(array, 0);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Collections/PairCollection.cs.meta
Normal file
11
Assets/Cryville/Common/Collections/PairCollection.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f87dfb8f6a1f5640b6deae741cd715c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
29
Assets/Cryville/Common/Collections/PairList.cs
Normal file
29
Assets/Cryville/Common/Collections/PairList.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cryville.Common.Collections {
|
||||
[DebuggerDisplay("Count = {Count}"), DebuggerTypeProxy(typeof(PairListDebugView))]
|
||||
public class PairList : List<KeyValuePair<object, object>>, IPairList {
|
||||
public void Add(object key, object value) {
|
||||
Add(new KeyValuePair<object, object>(key, value));
|
||||
}
|
||||
|
||||
public void Insert(int index, object key, object value) {
|
||||
Insert(index, new KeyValuePair<object, object>(key, value));
|
||||
}
|
||||
}
|
||||
internal class PairListDebugView {
|
||||
readonly PairList _self;
|
||||
public PairListDebugView(PairList self) {
|
||||
_self = self;
|
||||
}
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePair<object, object>[] Items {
|
||||
get {
|
||||
KeyValuePair<object, object>[] array = new KeyValuePair<object, object>[_self.Count];
|
||||
_self.CopyTo(array, 0);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Collections/PairList.cs.meta
Normal file
11
Assets/Cryville/Common/Collections/PairList.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57fc9f037c1fda5449e2a365a835c82c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -45,7 +45,7 @@ namespace Cryville.Common.Font {
|
||||
return tableDirectoryOffsets;
|
||||
}
|
||||
public override TableDirectory GetSubTable(UInt32 item) {
|
||||
var i = (UInt32)item;
|
||||
var i = item;
|
||||
return new TableDirectory(Reader, i);
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Cryville.Common {
|
||||
public struct Identifier : IEquatable<Identifier> {
|
||||
public static Identifier Empty = new Identifier(0);
|
||||
public int Key { get; private set; }
|
||||
public object Name { get { return IdentifierManager.SharedInstance.Retrieve(Key); } }
|
||||
public Identifier(int key) {
|
||||
|
44
Assets/Cryville/Common/Math/CubicBezier.cs
Normal file
44
Assets/Cryville/Common/Math/CubicBezier.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using SMath = System.Math;
|
||||
|
||||
namespace Cryville.Common.Math {
|
||||
// Ported from https://github.com/arian/cubic-bezier/blob/master/index.js
|
||||
public static class CubicBezier {
|
||||
public static float Evaluate(float t, float x1, float y1, float x2, float y2, float epsilon) {
|
||||
float x = t, t0, t1, t2, tx, d2, i;
|
||||
for (t2 = x, i = 0; i < 8; i++) {
|
||||
tx = CurveX(t2, x1, x2) - x;
|
||||
if (SMath.Abs(tx) < epsilon) return CurveY(t2, y1, y2);
|
||||
d2 = DerivativeCurveX(t2, x1, x2);
|
||||
if (SMath.Abs(d2) < 1e-6) break;
|
||||
t2 -= tx / d2;
|
||||
}
|
||||
|
||||
t0 = 0; t1 = 1; t2 = x;
|
||||
|
||||
if (t2 < t0) return CurveY(t0, y1, y2);
|
||||
if (t2 > t1) return CurveY(t1, y1, y2);
|
||||
|
||||
while (t0 < t1) {
|
||||
tx = CurveX(t2, x1, x2);
|
||||
if (SMath.Abs(tx - x) < epsilon) return CurveY(t2, y1, y2);
|
||||
if (x > tx) t0 = t2;
|
||||
else t1 = t2;
|
||||
t2 = (t1 - t0) * .5f + t0;
|
||||
}
|
||||
|
||||
return CurveY(t2, y1, y2);
|
||||
}
|
||||
static float CurveX(float t, float x1, float x2) {
|
||||
float v = 1 - t;
|
||||
return 3 * v * v * t * x1 + 3 * v * t * t * x2 + t * t * t;
|
||||
}
|
||||
static float CurveY(float t, float y1, float y2) {
|
||||
float v = 1 - t;
|
||||
return 3 * v * v * t * y1 + 3 * v * t * t * y2 + t * t * t;
|
||||
}
|
||||
static float DerivativeCurveX(float t, float x1, float x2) {
|
||||
float v = 1 - t;
|
||||
return 3 * (2 * (t - 1) * t + v * v) * x1 + 3 * (-t * t * t + 2 * v * t) * x2;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Math/CubicBezier.cs.meta
Normal file
11
Assets/Cryville/Common/Math/CubicBezier.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17dd6f775fc965f43960da7166b55b87
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -12,12 +12,12 @@ namespace Cryville.Common.Math {
|
||||
/// <param name="error">The error.</param>
|
||||
/// <param name="n">The numerator.</param>
|
||||
/// <param name="d">The denominator.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is less than 0 or <paramref name="error" /> is not greater than 0 or not less than 1.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is less than 0 or <paramref name="error" /> is not greater than 0 or greater than 1.</exception>
|
||||
public static void ToFraction(double value, double error, out int n, out int d) {
|
||||
if (value < 0.0)
|
||||
throw new ArgumentOutOfRangeException("value", "Must be >= 0.");
|
||||
if (error <= 0.0 || error >= 1.0)
|
||||
throw new ArgumentOutOfRangeException("accuracy", "Must be > 0 and < 1.");
|
||||
if (error <= 0.0 || error > 1.0)
|
||||
throw new ArgumentOutOfRangeException("error", "Must be > 0 and <= 1.");
|
||||
|
||||
int num = (int)System.Math.Floor(value);
|
||||
value -= num;
|
||||
|
@@ -5,7 +5,7 @@ namespace Cryville.Common.Pdt {
|
||||
/// Indicates that the attributed member is an element list.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>An element list is a <see cref="System.Collections.IDictionary" /> that represents a collection of PDT elements. There must be at most one element list in a class.</para>
|
||||
/// <para>An element list is a <see cref="System.Collections.IDictionary" /> or <see cref="Cryville.Common.Collections.Generic.IPairList" /> that represents a collection of PDT elements. There must be at most one element list in a class.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class ElementListAttribute : Attribute { }
|
||||
@@ -14,7 +14,7 @@ namespace Cryville.Common.Pdt {
|
||||
/// Indicates that the attributed member is a property list.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>A property list is a <see cref="System.Collections.IDictionary" /> that represents a collection of PDT properties. There must be at most one property list in a class.</para>
|
||||
/// <para>A property list is a <see cref="System.Collections.IDictionary" /> or <see cref="Cryville.Common.Collections.Generic.IPairList" /> that represents a collection of PDT properties. There must be at most one property list in a class.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class PropertyListAttribute : Attribute { }
|
||||
|
@@ -92,7 +92,7 @@ namespace Cryville.Common.Pdt {
|
||||
}
|
||||
}
|
||||
public partial class PdtInterpreter {
|
||||
readonly static Dictionary<char, int> OP_PRIORITY = new Dictionary<char, int> {
|
||||
static readonly Dictionary<char, int> OP_PRIORITY = new Dictionary<char, int> {
|
||||
{ '@', 7 },
|
||||
{ '*', 6 }, { '/', 6 }, { '%', 6 },
|
||||
{ '+', 5 }, { '-', 5 },
|
||||
@@ -103,7 +103,7 @@ namespace Cryville.Common.Pdt {
|
||||
{ ',', 0 },
|
||||
{ '$', -1 },
|
||||
};
|
||||
readonly static Dictionary<char, int> OP_TYPE = new Dictionary<char, int> {
|
||||
static readonly Dictionary<char, int> OP_TYPE = new Dictionary<char, int> {
|
||||
{ '@', 0 },
|
||||
{ '*', 0 }, { '/', 0 }, { '%', 0 },
|
||||
{ '+', 0 }, { '-', 0 },
|
||||
@@ -115,7 +115,7 @@ namespace Cryville.Common.Pdt {
|
||||
{ '$', -1 },
|
||||
};
|
||||
|
||||
readonly static PdtExpression _emptyexp;
|
||||
static readonly PdtExpression _emptyexp;
|
||||
static PdtInterpreter() {
|
||||
var ins = new LinkedList<PdtInstruction>();
|
||||
ins.AddLast(new PdtInstruction.PushConstant(
|
||||
@@ -143,7 +143,7 @@ namespace Cryville.Common.Pdt {
|
||||
public override string ToString() {
|
||||
return string.Format("0x{0:x4}: {1}", Type, Value);
|
||||
}
|
||||
public readonly static PdtExpToken EmptyOperator = new PdtExpToken {
|
||||
public static readonly PdtExpToken EmptyOperator = new PdtExpToken {
|
||||
Type = 0x0080,
|
||||
Value = "$",
|
||||
};
|
||||
|
@@ -6,30 +6,30 @@
|
||||
/// <summary>
|
||||
/// Error type.
|
||||
/// </summary>
|
||||
public readonly static int Error = 0x00525245;
|
||||
public const int Error = 0x00525245;
|
||||
/// <summary>
|
||||
/// Array of a same variable-length type, with a suffix indicating the element count and the element type.
|
||||
/// </summary>
|
||||
public readonly static int Array = 0x00525241;
|
||||
public const int Array = 0x00525241;
|
||||
/// <summary>
|
||||
/// Null type.
|
||||
/// </summary>
|
||||
public readonly static int Null = 0x4c4c554e;
|
||||
public const int Null = 0x4c4c554e;
|
||||
/// <summary>
|
||||
/// IEEE 754 32-bit floating-point number.
|
||||
/// </summary>
|
||||
public readonly static int Number = 0x004d554e;
|
||||
public const int Number = 0x004d554e;
|
||||
/// <summary>
|
||||
/// A sequence of UTF-16 code units, with a prefix indicating the number of the code units.
|
||||
/// </summary>
|
||||
public readonly static int String = 0x00525453;
|
||||
public const int String = 0x00525453;
|
||||
/// <summary>
|
||||
/// A sequence of UTF-16 code units, with a prefix indicating the number of the code units, representing the name of an undefined variable.
|
||||
/// </summary>
|
||||
public readonly static int Undefined = 0x00444e55;
|
||||
public const int Undefined = 0x00444e55;
|
||||
/// <summary>
|
||||
/// Vector of a same constant-length type, with a suffix indicating the element type.
|
||||
/// </summary>
|
||||
public readonly static int Vector = 0x00434556;
|
||||
public const int Vector = 0x00434556;
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Cryville.Common.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -27,7 +28,7 @@ namespace Cryville.Common.Pdt {
|
||||
/// <item><term><c>0x1000</c></term><description>End of Key</description></item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
readonly static int[] cm = new int[] {
|
||||
static readonly int[] cm = new int[] {
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
@@ -255,13 +256,13 @@ namespace Cryville.Common.Pdt {
|
||||
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
||||
Type ptype = ReflectionHelper.GetMemberType(prop);
|
||||
if (flag) {
|
||||
if (!typeof(IDictionary).IsAssignableFrom(ptype))
|
||||
throw new InvalidOperationException("Internal error: Element list is not a dictionary");
|
||||
var ktype = ptype.GetGenericArguments()[0];
|
||||
var vtype = ptype.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = InterpretObject(vtype);
|
||||
((IDictionary)ReflectionHelper.GetValue(prop, result)).Add(key, value);
|
||||
using (var collection = new PairCollection(ReflectionHelper.GetValue(prop, result))) {
|
||||
var ktype = ptype.GetGenericArguments()[0];
|
||||
var vtype = ptype.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = InterpretObject(vtype);
|
||||
collection.Add(key, value);
|
||||
}
|
||||
}
|
||||
else ReflectionHelper.SetValue(prop, result, InterpretObject(ptype));
|
||||
}
|
||||
@@ -284,13 +285,13 @@ namespace Cryville.Common.Pdt {
|
||||
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
||||
var ptype = ReflectionHelper.GetMemberType(prop);
|
||||
if (flag) {
|
||||
if (!typeof(IDictionary).IsAssignableFrom(ptype))
|
||||
throw new InvalidOperationException("Internal error: Property list is not a dictionary");
|
||||
var ktype = ptype.GetGenericArguments()[0];
|
||||
var vtype = ptype.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = _binder.ChangeType(exp, vtype, null);
|
||||
((IDictionary)ReflectionHelper.GetValue(prop, result)).Add(key, value);
|
||||
using (var collection = new PairCollection(ReflectionHelper.GetValue(prop, result))) {
|
||||
var ktype = ptype.GetGenericArguments()[0];
|
||||
var vtype = ptype.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = _binder.ChangeType(exp, vtype, null);
|
||||
collection.Add(key, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
object value = _binder.ChangeType(exp, ptype, null);
|
||||
|
@@ -4,7 +4,7 @@ namespace Cryville.Common.Pdt {
|
||||
/// <summary>
|
||||
/// PDT operator.
|
||||
/// </summary>
|
||||
public unsafe abstract class PdtOperator {
|
||||
public abstract unsafe class PdtOperator {
|
||||
byte* _prmem;
|
||||
int _loadindex;
|
||||
readonly PdtVariableMemory[] _operands;
|
||||
|
@@ -3,6 +3,6 @@ using UnityEngine;
|
||||
namespace Cryville.Common.Unity.UI {
|
||||
public abstract class SetParameterBehaviour : StateMachineBehaviour {
|
||||
[SerializeField] protected string m_name;
|
||||
public override abstract void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex);
|
||||
public abstract override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex);
|
||||
}
|
||||
}
|
||||
|
@@ -9,11 +9,11 @@ namespace Cryville.Crtr.Browsing {
|
||||
public override object Value {
|
||||
get {
|
||||
float s_value = GetDisplayValue();
|
||||
return IntegerMode ? (object)(int)s_value : (object)s_value;
|
||||
return IntegerMode ? (int)s_value : (object)s_value;
|
||||
}
|
||||
set {
|
||||
if (value is double) m_value = (double)value;
|
||||
else m_value = IntegerMode ? (double)(int)value : (double)(float)value;
|
||||
else m_value = IntegerMode ? (int)value : (double)(float)value;
|
||||
float s_value = GetDisplayValue();
|
||||
m_text.text = s_value.ToString();
|
||||
if (Range != null && MaxStep == 0) {
|
||||
|
@@ -6,6 +6,7 @@ using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnsafeIL;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
[JsonConverter(typeof(BeatTimeConverter))]
|
||||
@@ -154,6 +155,10 @@ namespace Cryville.Crtr {
|
||||
protected ChartEvent() {
|
||||
PropSrcs = new Dictionary<int, PropSrc>();
|
||||
PropOps = new Dictionary<int, PropOp>();
|
||||
SubmitPropSrc("event", new PropSrc.Float(() => {
|
||||
int hash = GetHashCode();
|
||||
return Unsafe.As<int, float>(ref hash);
|
||||
}));
|
||||
SubmitPropSrc("long", new PropSrc.Boolean(() => IsLong));
|
||||
SubmitPropSrc("time", new PropSrc.BeatTime(() => time.Value));
|
||||
SubmitPropSrc("endtime", new PropSrc.BeatTime(() => endtime.Value));
|
||||
@@ -320,7 +325,7 @@ namespace Cryville.Crtr {
|
||||
else {
|
||||
AbsoluteValue = Vector.Construct(registry.Type, m.Groups[11].Value);
|
||||
}
|
||||
SubmitPropSrc("value", VectorSrc.Construct(() => {
|
||||
SubmitPropSrc("value", new VectorSrc(() => {
|
||||
if (RelativeNode != null) return RelativeNode.Value;
|
||||
else return AbsoluteValue;
|
||||
}));
|
||||
|
@@ -24,7 +24,7 @@ namespace Cryville.Crtr {
|
||||
#region Fields
|
||||
Chart chart;
|
||||
Skin skin;
|
||||
PdtSkin pskin;
|
||||
public static PdtSkin pskin;
|
||||
Ruleset ruleset;
|
||||
PdtRuleset pruleset;
|
||||
Dictionary<string, Texture2D> texs;
|
||||
@@ -175,16 +175,21 @@ namespace Cryville.Crtr {
|
||||
string url = texLoader.url;
|
||||
string name = StringUtils.TrimExt(url.Substring(url.LastIndexOfAny(new char[] {'/', '\\'}) + 1));
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
if (texHandler.isDone) {
|
||||
var tex = texHandler.texture;
|
||||
tex.wrapMode = TextureWrapMode.Clamp;
|
||||
if (frames.ContainsKey(name)) {
|
||||
Logger.Log("main", 3, "Load/Prehandle", "Duplicated texture name: {0}", name);
|
||||
if (texLoader.isDone) {
|
||||
if (texHandler.isDone) {
|
||||
var tex = texHandler.texture;
|
||||
tex.wrapMode = TextureWrapMode.Clamp;
|
||||
if (frames.ContainsKey(name)) {
|
||||
Logger.Log("main", 3, "Load/Prehandle", "Duplicated texture name: {0}", name);
|
||||
}
|
||||
else {
|
||||
frames.Add(name, new SpriteFrame(tex));
|
||||
}
|
||||
texs.Add(name, tex);
|
||||
}
|
||||
else {
|
||||
frames.Add(name, new SpriteFrame(tex));
|
||||
Logger.Log("main", 4, "Load/Prehandle", "Unable to load texture: {0}", name);
|
||||
}
|
||||
texs.Add(name, tex);
|
||||
texLoader.Dispose();
|
||||
texHandler.Dispose();
|
||||
texLoader = null;
|
||||
@@ -468,6 +473,8 @@ namespace Cryville.Crtr {
|
||||
Logger.Log("main", 0, "Load/Prehandle", "Cleaning up");
|
||||
GC.Collect();
|
||||
if (disableGC) GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
|
||||
cbus.ForwardByTime(startOffset);
|
||||
bbus.ForwardByTime(startOffset);
|
||||
timer.Stop();
|
||||
Logger.Log("main", 1, "Load/Prehandle", "Prehandling done ({0}ms)", timer.Elapsed.TotalMilliseconds);
|
||||
if (Settings.Default.ClearLogOnPlay) {
|
||||
@@ -478,7 +485,6 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
Game.AudioSequencer.Playing = true;
|
||||
atime0 = Game.AudioClient.BufferPosition;
|
||||
Thread.Sleep((int)((atime0 - Game.AudioClient.Position) * 1000));
|
||||
inputProxy.SyncTime(cbus.Time);
|
||||
started = true;
|
||||
}
|
||||
|
@@ -2,8 +2,15 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Components {
|
||||
[DisallowMultipleComponent]
|
||||
public abstract class MeshBase : SkinComponent {
|
||||
public MeshBase() {
|
||||
SubmitProperty("color", new PropOp.Color(v => Color = v));
|
||||
SubmitProperty("opacity", new PropOp.Float(v => {
|
||||
var c = Color;
|
||||
c.a *= v;
|
||||
Color = c;
|
||||
}));
|
||||
SubmitProperty("zindex", new PropOp.Integer(v => ZIndex = (short)v));
|
||||
}
|
||||
|
||||
@@ -28,12 +35,32 @@ namespace Cryville.Crtr.Components {
|
||||
mat.renderQueue = _zindex;
|
||||
}
|
||||
}
|
||||
|
||||
Color _color = Color.white;
|
||||
public Color Color {
|
||||
get { return _color; }
|
||||
set {
|
||||
_color = value;
|
||||
UpdateColor();
|
||||
}
|
||||
}
|
||||
protected void UpdateColor() {
|
||||
if (!mesh.Initialized) return;
|
||||
foreach (var mat in materials) {
|
||||
mat.color = _color;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDestroy() {
|
||||
if (materials != null)
|
||||
foreach (var mat in materials) {
|
||||
Material.Destroy(mat);
|
||||
}
|
||||
DestroyMaterials();
|
||||
mesh.Destroy();
|
||||
}
|
||||
|
||||
protected void DestroyMaterials() {
|
||||
if (materials == null) return;
|
||||
foreach (var mat in materials) {
|
||||
Material.Destroy(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -72,7 +72,7 @@ namespace Cryville.Crtr.Components {
|
||||
public op_set_shape(PolygonSGO self) : base(1) {
|
||||
_self = self;
|
||||
}
|
||||
protected unsafe override void Execute() {
|
||||
protected override unsafe void Execute() {
|
||||
var o = GetOperand(0);
|
||||
if (o.Type != PdtInternalType.Vector) throw new ArgumentException("Not a vector");
|
||||
_self._shapeLength = (o.Length - sizeof(int)) / sizeof(Vector2);
|
||||
@@ -107,7 +107,7 @@ namespace Cryville.Crtr.Components {
|
||||
base.Init();
|
||||
mesh.Init(transform);
|
||||
|
||||
mesh.Renderer.materials = materials = new Material[] {
|
||||
mesh.Renderer.sharedMaterials = materials = new Material[] {
|
||||
MeshWrapper.NewMaterial(),
|
||||
MeshWrapper.NewMaterial(),
|
||||
MeshWrapper.NewMaterial(),
|
||||
|
@@ -1,5 +1,89 @@
|
||||
namespace Cryville.Crtr.Components {
|
||||
using Cryville.Common;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Logger = Cryville.Common.Logger;
|
||||
|
||||
namespace Cryville.Crtr.Components {
|
||||
public class SkinAnimation : SkinComponent {
|
||||
public SkinAnimation() {
|
||||
SubmitProperty("name", new PropOp.Identifier(v => Name = v));
|
||||
SubmitProperty("duration", new PropOp.Float(v => Duration = v));
|
||||
SubmitProperty("iteration", new PropOp.Float(v => Iteration = v));
|
||||
SubmitProperty("direction", new PropOp.Enum<AnimationDirection>(v => Direction = v, v => (AnimationDirection)v));
|
||||
SubmitProperty("delay", new PropOp.Float(v => Delay = v));
|
||||
Iteration = 1;
|
||||
}
|
||||
|
||||
SkinContext _skinContext;
|
||||
Transform _writeTransform;
|
||||
|
||||
AnimationSpan _anim;
|
||||
int _name;
|
||||
public int Name {
|
||||
set {
|
||||
if (_name == value) return;
|
||||
_name = value;
|
||||
if (value == 0) {
|
||||
_anim = null;
|
||||
}
|
||||
else {
|
||||
var id = new Identifier(value);
|
||||
AnimationSpan anim;
|
||||
if (!ChartPlayer.pskin.animations.TryGetValue(id, out anim)) {
|
||||
Logger.Log("main", 4, "Skin", "Animation {0} not found", id.Name);
|
||||
_anim = null;
|
||||
return;
|
||||
}
|
||||
_anim = anim;
|
||||
}
|
||||
}
|
||||
}
|
||||
public float Duration { get; private set; }
|
||||
public float Iteration { get; private set; }
|
||||
public AnimationDirection Direction { get; private set; }
|
||||
public float Delay { get; private set; }
|
||||
|
||||
double _startTime;
|
||||
|
||||
public override void Init() {
|
||||
_skinContext = new SkinContext(transform);
|
||||
}
|
||||
public override void Rewind(double time, Transform target) {
|
||||
_startTime = time;
|
||||
if (target == null) target = transform;
|
||||
_writeTransform = target;
|
||||
}
|
||||
public override void Tick(SkinContainer c, double time) {
|
||||
float _rtime = (float)(time - _startTime - Delay) / Duration;
|
||||
if (_rtime < 0) _rtime = 0;
|
||||
else if (_rtime > Iteration) {
|
||||
if (Direction.HasFlag(AnimationDirection.alternate)) {
|
||||
_rtime = Iteration % 2;
|
||||
if (_rtime > 1) _rtime = 2 - _rtime;
|
||||
}
|
||||
else {
|
||||
_rtime = Iteration % 1;
|
||||
if (_rtime == 0) _rtime = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Direction.HasFlag(AnimationDirection.alternate)) {
|
||||
_rtime %= 2;
|
||||
if (_rtime > 1) _rtime = 2 - _rtime;
|
||||
}
|
||||
else {
|
||||
_rtime %= 1;
|
||||
}
|
||||
}
|
||||
if (Direction.HasFlag(AnimationDirection.reverse)) _rtime = 1 - _rtime;
|
||||
if (_anim != null) c.MatchAnimation(_anim, _rtime, new RuntimeSkinContext(_skinContext, _writeTransform));
|
||||
}
|
||||
protected override void OnDestroy() { }
|
||||
}
|
||||
[Flags]
|
||||
public enum AnimationDirection {
|
||||
normal = 0,
|
||||
reverse = 1,
|
||||
alternate = 2,
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,8 @@ namespace Cryville.Crtr.Components {
|
||||
}
|
||||
|
||||
public virtual void Init() { }
|
||||
public virtual void Rewind(double time, Transform target) { }
|
||||
public virtual void Tick(SkinContainer c, double time) { }
|
||||
protected abstract void OnDestroy();
|
||||
}
|
||||
public struct SkinProperty {
|
||||
|
@@ -88,8 +88,9 @@ namespace Cryville.Crtr.Components {
|
||||
|
||||
protected void InternalInit(string meshName = "quad") {
|
||||
mesh.Init(transform);
|
||||
mesh.Renderer.materials = materials = new Material[] { MeshWrapper.NewMaterial() };
|
||||
mesh.Renderer.sharedMaterials = materials = new Material[] { MeshWrapper.NewMaterial() };
|
||||
mesh.Mesh = GenericResources.Meshes[meshName];
|
||||
UpdateColor();
|
||||
UpdateScale();
|
||||
UpdateZIndex();
|
||||
}
|
||||
|
@@ -60,7 +60,7 @@ namespace Cryville.Crtr.Components {
|
||||
SubmitProperty("frames", new PropOp.StringArray(v => Frames = v));
|
||||
SubmitProperty("index", new PropOp.Integer(v => Index = v));
|
||||
SubmitProperty("fit", new PropOp.Enum<FitMode>(v => Fit = v, v => (FitMode)v));
|
||||
SubmitProperty("opacity", new PropOp.Float(v => Opacity = v));
|
||||
SubmitProperty("shader", new PropOp.String(v => Shader = v));
|
||||
}
|
||||
|
||||
static Vector2[] _origuv;
|
||||
@@ -122,9 +122,21 @@ namespace Cryville.Crtr.Components {
|
||||
return;
|
||||
}
|
||||
mesh.Renderer.enabled = true;
|
||||
mesh.Renderer.material.mainTexture = frame.Frame.Texture;
|
||||
mesh.Renderer.sharedMaterial.mainTexture = frame.Frame.Texture;
|
||||
UpdateUV();
|
||||
UpdateScale();
|
||||
}
|
||||
Shader m_shader;
|
||||
public string Shader {
|
||||
set {
|
||||
m_shader = GenericResources.Shaders[value];
|
||||
UpdateShader();
|
||||
}
|
||||
}
|
||||
void UpdateShader() {
|
||||
if (!mesh.Initialized) return;
|
||||
if (m_shader == null) m_shader = GenericResources.Shaders["default"];
|
||||
mesh.Renderer.sharedMaterial.shader = m_shader;
|
||||
UpdateZIndex();
|
||||
}
|
||||
readonly Vector2[] _uvs = new Vector2[4];
|
||||
@@ -138,21 +150,6 @@ namespace Cryville.Crtr.Components {
|
||||
mesh.Mesh.uv = _uvs;
|
||||
}
|
||||
|
||||
float _opacity = 1;
|
||||
public float Opacity {
|
||||
get { return _opacity; }
|
||||
set {
|
||||
_opacity = value;
|
||||
UpdateOpacity();
|
||||
}
|
||||
}
|
||||
protected void UpdateOpacity() {
|
||||
if (!mesh.Initialized) return;
|
||||
var c = mesh.Renderer.material.color;
|
||||
c.a = _opacity;
|
||||
mesh.Renderer.material.color = c;
|
||||
}
|
||||
|
||||
private FitMode m_fit = FitMode.height;
|
||||
public FitMode Fit {
|
||||
get { return m_fit; }
|
||||
@@ -185,7 +182,7 @@ namespace Cryville.Crtr.Components {
|
||||
public override void Init() {
|
||||
InternalInit();
|
||||
OnFrameUpdate();
|
||||
UpdateOpacity();
|
||||
UpdateShader();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,22 +2,7 @@
|
||||
|
||||
namespace Cryville.Crtr.Components {
|
||||
public class SpriteRect : SpriteBase {
|
||||
public SpriteRect() {
|
||||
SubmitProperty("color", new PropOp.Color(v => Color = v));
|
||||
}
|
||||
|
||||
Color _color;
|
||||
public Color Color {
|
||||
get { return _color; }
|
||||
set {
|
||||
_color = value;
|
||||
OnColorUpdate();
|
||||
}
|
||||
}
|
||||
void OnColorUpdate() {
|
||||
if (!mesh.Initialized) return;
|
||||
mesh.Renderer.material.SetColor("_Color", _color);
|
||||
}
|
||||
public SpriteRect() { }
|
||||
|
||||
protected override Vector3 BaseScale {
|
||||
get { return Vector3.one; }
|
||||
@@ -25,7 +10,6 @@ namespace Cryville.Crtr.Components {
|
||||
|
||||
public override void Init() {
|
||||
InternalInit();
|
||||
OnColorUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,12 +8,12 @@ namespace Cryville.Crtr.Components {
|
||||
SubmitProperty("border", new PropOp.Vector2(v => Border = v));
|
||||
}
|
||||
|
||||
readonly static Dictionary<float, int> uvrefl
|
||||
static readonly Dictionary<float, int> uvrefl
|
||||
= new Dictionary<float, int>() {
|
||||
{-0.5f, 0}, {-0.4f, 1}, {0.4f, 2}, {0.5f, 3},
|
||||
};
|
||||
static Vector2[] _origuv;
|
||||
protected new static Vector2[] OriginalUV {
|
||||
protected static new Vector2[] OriginalUV {
|
||||
get {
|
||||
if (_origuv == null) {
|
||||
var m = GenericResources.Meshes["quad_scale3h"];
|
||||
@@ -84,7 +84,6 @@ namespace Cryville.Crtr.Components {
|
||||
public override void Init() {
|
||||
InternalInit("quad_scale3h");
|
||||
OnFrameUpdate();
|
||||
UpdateOpacity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@ namespace Cryville.Crtr.Components {
|
||||
SubmitProperty("value", new PropOp.TargetString(() => Value));
|
||||
SubmitProperty("size", new PropOp.Float(v => Size = v));
|
||||
SubmitProperty("spacing", new PropOp.Float(v => Spacing = v));
|
||||
SubmitProperty("opacity", new PropOp.Float(v => Opacity = v));
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
@@ -20,7 +19,7 @@ namespace Cryville.Crtr.Components {
|
||||
public op_set_frames(SpriteText self) : base(2) {
|
||||
_self = self;
|
||||
}
|
||||
protected unsafe override void Execute() {
|
||||
protected override unsafe void Execute() {
|
||||
var keys = GetOperand(0).AsString();
|
||||
var values = GetOperand(1);
|
||||
int arrtype; int len;
|
||||
@@ -47,7 +46,7 @@ namespace Cryville.Crtr.Components {
|
||||
Dictionary<char, SpriteInfo> m_frames;
|
||||
public Dictionary<char, SpriteInfo> Frames {
|
||||
get { return m_frames; }
|
||||
set { m_frames = value; UpdateFrames(); UpdateScale(); }
|
||||
set { m_frames = value; UpdateFrames(); }
|
||||
}
|
||||
|
||||
readonly TargetString m_value = new TargetString();
|
||||
@@ -78,7 +77,11 @@ namespace Cryville.Crtr.Components {
|
||||
meshes.Clear();
|
||||
verts.Clear();
|
||||
uvs.Clear();
|
||||
DestroyMaterials();
|
||||
materials = new Material[m_frames.Count];
|
||||
int i = 0;
|
||||
foreach (var f in m_frames) {
|
||||
if (SpriteInfo.IsNullOrEmpty(f.Value)) continue;
|
||||
if (frameHeight == 0) frameHeight = f.Value.Rect.height;
|
||||
else if (frameHeight != f.Value.Rect.height) throw new Exception("Inconsistent frame height for text component");
|
||||
var tex = f.Value.Frame.Texture;
|
||||
@@ -86,14 +89,17 @@ namespace Cryville.Crtr.Components {
|
||||
var m = new MeshWrapper();
|
||||
m.Init(mesh.MeshTransform);
|
||||
m.Mesh = new Mesh();
|
||||
m.Renderer.material = MeshWrapper.NewMaterial(); // TODO Destroy or add to `materials`
|
||||
m.Renderer.material.mainTexture = tex;
|
||||
var mat = MeshWrapper.NewMaterial();
|
||||
mat.mainTexture = tex;
|
||||
m.Renderer.sharedMaterial = materials[i++] = mat;
|
||||
meshes.Add(tex, m);
|
||||
verts.Add(tex, new List<Vector3>());
|
||||
uvs.Add(tex, new List<Vector2>());
|
||||
tris.Add(tex, new List<int>());
|
||||
}
|
||||
}
|
||||
UpdateColor();
|
||||
UpdateScale();
|
||||
}
|
||||
|
||||
float sum_x;
|
||||
@@ -158,23 +164,6 @@ namespace Cryville.Crtr.Components {
|
||||
get { return new Vector2(-0.5f, -0.5f); }
|
||||
}
|
||||
|
||||
float _opacity = 1;
|
||||
public float Opacity {
|
||||
get { return _opacity; }
|
||||
set {
|
||||
_opacity = value;
|
||||
UpdateOpacity();
|
||||
}
|
||||
}
|
||||
void UpdateOpacity() {
|
||||
if (!mesh.Initialized) return;
|
||||
foreach (var m in meshes) {
|
||||
var c = m.Value.Renderer.material.color;
|
||||
c.a = _opacity;
|
||||
m.Value.Renderer.material.color = c;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
InternalInit();
|
||||
UpdateFrames();
|
||||
|
@@ -93,10 +93,10 @@ namespace Cryville.Crtr.Config {
|
||||
var tsrc = src.Value;
|
||||
bool flag = false;
|
||||
if (proxy.IsUsed(tsrc)) {
|
||||
text.text += " (Used)";
|
||||
text.text += " <size=9>(Used)</size>";
|
||||
}
|
||||
else if (tsrc.Handler.GetDimension(src.Value.Type) < m_configScene.ruleset.Root.inputs[_sel].dim) {
|
||||
text.text += " (Not Applicable)";
|
||||
text.text += " <size=9>(Not Applicable)</size>";
|
||||
}
|
||||
else flag = true;
|
||||
btn.interactable = flag;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using Cryville.Common.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class EffectGroup {
|
||||
@@ -35,22 +36,37 @@ namespace Cryville.Crtr {
|
||||
while (_endQueue.Count > 0) {
|
||||
var item = _endQueue[0];
|
||||
if (item.EndTime > _time) break;
|
||||
item.OnDone();
|
||||
_instances.Remove(item.Index);
|
||||
_pool.Return(item);
|
||||
_endQueue.RemoveAt(0);
|
||||
if (item.OnStateDone()) {
|
||||
QueueInstance(item);
|
||||
}
|
||||
else {
|
||||
item.Tick(time);
|
||||
_instances.Remove(item.Index);
|
||||
_pool.Return(item);
|
||||
}
|
||||
}
|
||||
foreach (var instance in _instances) {
|
||||
instance.Value.Tick(time);
|
||||
}
|
||||
}
|
||||
public void Emit(float index) {
|
||||
public void Emit(float index, Transform target = null) {
|
||||
EffectInstance instance;
|
||||
if (!_instances.TryGetValue(index, out instance)) {
|
||||
_instances.Add(index, instance = _pool.Rent());
|
||||
}
|
||||
bool flag = _instances.TryGetValue(index, out instance);
|
||||
if (!flag) _instances.Add(index, instance = _pool.Rent());
|
||||
instance.Index = index;
|
||||
instance.OnEmit(_time);
|
||||
var i = _endQueue.BinarySearch(instance);
|
||||
if (i < 0) i = ~i;
|
||||
_endQueue.Insert(i, instance);
|
||||
if (instance.CanEmit()) {
|
||||
if (flag) {
|
||||
var i = _endQueue.BinarySearch(instance);
|
||||
_endQueue.RemoveAt(i);
|
||||
}
|
||||
instance.OnEmit(_time, target);
|
||||
QueueInstance(instance);
|
||||
}
|
||||
}
|
||||
void QueueInstance(EffectInstance i) {
|
||||
var index = ~_endQueue.BinarySearch(i);
|
||||
_endQueue.Insert(index, i);
|
||||
}
|
||||
public void Dispose() {
|
||||
_pool.DisposeAll();
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Crtr.Components;
|
||||
using Cryville.Crtr.Event;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -10,37 +11,89 @@ namespace Cryville.Crtr {
|
||||
readonly EffectDefinition _def;
|
||||
readonly SkinContainer _skinContainer;
|
||||
public Transform RootTransform { get; private set; }
|
||||
readonly SkinComponent[] _comps;
|
||||
public EffectInstance(EffectDefinition def) {
|
||||
_def = def;
|
||||
_skinContainer = new SkinContainer(_def.elements);
|
||||
_skinContainer = new SkinContainer(this, _def.elements);
|
||||
RootTransform = new GameObject("effect:" + GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
||||
SkinContext = new SkinContext(RootTransform);
|
||||
ChartPlayer.etor.ContextCascadeInsertBlock();
|
||||
_skinContainer.MatchStatic(this);
|
||||
_skinContainer.MatchStatic();
|
||||
ChartPlayer.etor.ContextCascadeDiscardBlock();
|
||||
foreach (var i in RootTransform.GetComponentsInChildren<SkinComponent>())
|
||||
i.Init();
|
||||
_comps = RootTransform.GetComponentsInChildren<SkinComponent>();
|
||||
foreach (var i in _comps) i.Init();
|
||||
_indexSrc = new PropSrc.Float(() => Index);
|
||||
_durationOp = new PropOp.Float(v => _duration = v);
|
||||
}
|
||||
public float Index { get; set; }
|
||||
static readonly int _var_index = IdentifierManager.SharedInstance.Request("index");
|
||||
public void Rewind(double time, Transform target) {
|
||||
_startTime = time;
|
||||
foreach (var i in _comps) i.Rewind(time, target);
|
||||
}
|
||||
private float m_index;
|
||||
public float Index {
|
||||
get { return m_index; }
|
||||
set {
|
||||
if (m_index == value) return;
|
||||
m_index = value;
|
||||
_indexSrc.Invalidate();
|
||||
}
|
||||
}
|
||||
Transform _currentTarget;
|
||||
Identifier _currentStateName = Identifier.Empty;
|
||||
EffectState _currentState;
|
||||
ChartEvent _ctxev;
|
||||
ContainerState _ctxstate;
|
||||
internal static readonly int _VAR_EFFECT_INDEX = IdentifierManager.SharedInstance.Request("effect_index");
|
||||
readonly PropSrc _indexSrc;
|
||||
double _startTime;
|
||||
float _duration;
|
||||
readonly PropOp _durationOp;
|
||||
public double EndTime { get { return _startTime + _duration; } }
|
||||
public void OnEmit(double time) {
|
||||
_startTime = time;
|
||||
public void Tick(double time) {
|
||||
foreach (var i in _comps) i.Tick(_skinContainer, time);
|
||||
}
|
||||
public bool CanEmit() {
|
||||
return _currentStateName.Key == 0 || _currentState.rewind.Key != 0;
|
||||
}
|
||||
public void OnEmit(double time, Transform target) {
|
||||
_currentTarget = target;
|
||||
_ctxev = ChartPlayer.etor.ContextEvent;
|
||||
_ctxstate = ChartPlayer.etor.ContextState;
|
||||
if (_currentStateName.Key == 0) {
|
||||
EnterState(_def.init, time, _currentTarget, true);
|
||||
}
|
||||
else {
|
||||
if (_currentState.rewind.Key == 0) throw new InvalidOperationException("Cannot rewind");
|
||||
EnterState(_currentState.rewind, time, _currentTarget, true);
|
||||
}
|
||||
}
|
||||
void EnterState(Identifier name, double time, Transform target, bool emitting) {
|
||||
_currentStateName = name;
|
||||
_currentState = _def.states[name];
|
||||
Rewind(time, target);
|
||||
RootTransform.gameObject.SetActive(true);
|
||||
ChartPlayer.etor.ContextCascadeInsert();
|
||||
ChartPlayer.etor.ContextCascadeUpdate(_var_index, _indexSrc);
|
||||
ChartPlayer.etor.Evaluate(_durationOp, _def.duration);
|
||||
_skinContainer.MatchDynamic(this, 0);
|
||||
ChartPlayer.etor.ContextCascadeUpdate(_VAR_EFFECT_INDEX, _indexSrc);
|
||||
ChartPlayer.etor.Evaluate(_durationOp, _currentState.duration);
|
||||
if (emitting) _skinContainer.MatchDynamic(0, true);
|
||||
_skinContainer.MatchDynamic(1, emitting);
|
||||
ChartPlayer.etor.ContextCascadeDiscard();
|
||||
}
|
||||
public void OnDone() {
|
||||
RootTransform.gameObject.SetActive(false);
|
||||
public bool OnStateDone() {
|
||||
if (_currentState.next.Key == 0) {
|
||||
RootTransform.gameObject.SetActive(false);
|
||||
_currentStateName = Identifier.Empty;
|
||||
_currentState = null;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
ChartPlayer.etor.ContextEvent = _ctxev;
|
||||
ChartPlayer.etor.ContextState = _ctxstate;
|
||||
EnterState(_currentState.next, EndTime, _currentTarget, false);
|
||||
ChartPlayer.etor.ContextEvent = null;
|
||||
ChartPlayer.etor.ContextState = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public void Dispose() {
|
||||
GameObject.Destroy(RootTransform.gameObject);
|
||||
@@ -48,7 +101,7 @@ namespace Cryville.Crtr {
|
||||
|
||||
public string TypeName { get { throw new InvalidOperationException("Type name undefined"); } }
|
||||
public SkinContext SkinContext { get; private set; }
|
||||
public Anchor OpenedAnchor { get { throw new InvalidOperationException("Anchor not supported"); } }
|
||||
public int OpenedAnchorName { get { return _currentStateName.Key; } }
|
||||
public void PushAnchorEvent(double time, int name) {
|
||||
throw new InvalidOperationException("Anchor not supported");
|
||||
}
|
||||
@@ -60,7 +113,9 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
|
||||
public int CompareTo(EffectInstance other) {
|
||||
return EndTime.CompareTo(other.EndTime);
|
||||
int r = EndTime.CompareTo(other.EndTime);
|
||||
if (r != 0) return r;
|
||||
return GetHashCode().CompareTo(other.GetHashCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class EffectManager {
|
||||
@@ -15,6 +16,9 @@ namespace Cryville.Crtr {
|
||||
public void Emit(int id, float index) {
|
||||
_groups[id].Emit(index);
|
||||
}
|
||||
public void EmitSelf(int id, float index, Transform target) {
|
||||
_groups[id].Emit(index, target);
|
||||
}
|
||||
public void Dispose() {
|
||||
foreach (var g in _groups) g.Value.Dispose();
|
||||
}
|
||||
|
@@ -37,10 +37,9 @@ namespace Cryville.Crtr.Event {
|
||||
/// </summary>
|
||||
public ContainerState ts;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="GameObject"/> group, the <see cref="Transform"/> containing all the generated elements in the <see cref="ContainerHandler"/>.
|
||||
/// </summary>
|
||||
protected Transform gogroup;
|
||||
protected Transform RootTransform;
|
||||
|
||||
SkinComponent[] _comps;
|
||||
|
||||
public Vector3 Position { get; protected set; }
|
||||
public Quaternion Rotation { get; protected set; }
|
||||
@@ -70,7 +69,7 @@ namespace Cryville.Crtr.Event {
|
||||
SkinContainer skinContainer;
|
||||
protected Judge judge;
|
||||
public void AttachSystems(PdtSkin skin, Judge judge) {
|
||||
skinContainer = new SkinContainer(skin.elements);
|
||||
skinContainer = new SkinContainer(this, skin.elements);
|
||||
this.judge = judge;
|
||||
}
|
||||
|
||||
@@ -80,15 +79,15 @@ namespace Cryville.Crtr.Event {
|
||||
Anchor a_cur;
|
||||
Anchor a_head;
|
||||
Anchor a_tail;
|
||||
readonly static int _a_cur = IdentifierManager.SharedInstance.Request("cur");
|
||||
readonly static int _a_head = IdentifierManager.SharedInstance.Request("head");
|
||||
readonly static int _a_tail = IdentifierManager.SharedInstance.Request("tail");
|
||||
static readonly int _a_cur = IdentifierManager.SharedInstance.Request("cur");
|
||||
static readonly int _a_head = IdentifierManager.SharedInstance.Request("head");
|
||||
static readonly int _a_tail = IdentifierManager.SharedInstance.Request("tail");
|
||||
double atime_head;
|
||||
double atime_tail;
|
||||
public Anchor RegisterAnchor(int name, bool dyn = false, int propSrcCount = 0) {
|
||||
var strname = IdentifierManager.SharedInstance.Retrieve(name);
|
||||
var go = new GameObject("." + strname).transform;
|
||||
go.SetParent(gogroup, false);
|
||||
go.SetParent(RootTransform, false);
|
||||
var result = new Anchor(name, go, propSrcCount);
|
||||
if (dyn) {
|
||||
if (DynamicAnchors.ContainsKey(name))
|
||||
@@ -103,22 +102,22 @@ namespace Cryville.Crtr.Event {
|
||||
return result;
|
||||
}
|
||||
protected void OpenAnchor(Anchor anchor) {
|
||||
if (OpenedAnchor != null) throw new InvalidOperationException("An anchor has been opened");
|
||||
if (_openedAnchor != null) throw new InvalidOperationException("An anchor has been opened");
|
||||
anchor.Transform.gameObject.SetActive(true);
|
||||
OpenedAnchor = anchor;
|
||||
_openedAnchor = anchor;
|
||||
}
|
||||
protected void CloseAnchor() {
|
||||
OpenedAnchor = null;
|
||||
_openedAnchor = null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Logic
|
||||
#region Init methods: Called on prehandle
|
||||
public virtual void PreInit() {
|
||||
gogroup = new GameObject(TypeName + ":" + Container.GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
||||
SkinContext = new SkinContext(gogroup);
|
||||
RootTransform = new GameObject(TypeName + ":" + Container.GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
||||
SkinContext = new SkinContext(RootTransform);
|
||||
if (cs.Parent != null)
|
||||
gogroup.SetParent(cs.Parent.Handler.gogroup, false);
|
||||
RootTransform.SetParent(cs.Parent.Handler.RootTransform, false);
|
||||
a_cur = RegisterAnchor(_a_cur);
|
||||
a_head = RegisterAnchor(_a_head, true);
|
||||
a_tail = RegisterAnchor(_a_tail, true);
|
||||
@@ -126,16 +125,16 @@ namespace Cryville.Crtr.Event {
|
||||
public virtual void Init() {
|
||||
ChartPlayer.etor.ContextState = ps;
|
||||
ChartPlayer.etor.ContextEvent = Container;
|
||||
skinContainer.MatchStatic(this);
|
||||
skinContainer.MatchStatic();
|
||||
ChartPlayer.etor.ContextEvent = null;
|
||||
ChartPlayer.etor.ContextState = null;
|
||||
foreach (var i in gogroup.GetComponentsInChildren<SkinComponent>())
|
||||
i.Init();
|
||||
_comps = RootTransform.GetComponentsInChildren<SkinComponent>();
|
||||
foreach (var i in _comps) i.Init();
|
||||
}
|
||||
public virtual void PostInit() {
|
||||
PropSrcs.Add(_var_current_time, new PropSrc.Float(() => (float)cs.rootPrototype.Time));
|
||||
PropSrcs.Add(_var_invisible_bounds, new PropSrc.Boolean(() => atime_head > atime_tail));
|
||||
gogroup.gameObject.SetActive(false);
|
||||
RootTransform.gameObject.SetActive(false);
|
||||
}
|
||||
#endregion
|
||||
#region Start methods
|
||||
@@ -146,14 +145,14 @@ namespace Cryville.Crtr.Event {
|
||||
public virtual void StartLogicalUpdate(ContainerState s) { }
|
||||
protected virtual void StartPreGraphicalUpdate(ContainerState s) { }
|
||||
protected virtual void StartGraphicalUpdate(ContainerState s) {
|
||||
if (gogroup) gogroup.gameObject.SetActive(true);
|
||||
if (RootTransform) RootTransform.gameObject.SetActive(true);
|
||||
}
|
||||
#endregion
|
||||
public virtual void Update(ContainerState s, StampedEvent ev) {
|
||||
if (s.CloneType == 3) SetPreGraphicalActive(true, s);
|
||||
else if (ev is StampedEvent.Anchor) {
|
||||
var tev = (StampedEvent.Anchor)ev;
|
||||
if (gogroup) {
|
||||
if (RootTransform) {
|
||||
OpenAnchor(tev.Target);
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
tev.Target.Transform.SetPositionAndRotation(Position, Rotation);
|
||||
@@ -172,7 +171,7 @@ namespace Cryville.Crtr.Event {
|
||||
}
|
||||
anchorEvPool.Return(tev);
|
||||
}
|
||||
else if (gogroup && s.CloneType == 2) MatchDynamic(s, 1);
|
||||
else if (RootTransform && s.CloneType == 2) MatchDynamic(s, 1);
|
||||
}
|
||||
#region End methods
|
||||
protected virtual void EndGraphicalUpdate(ContainerState s) { }
|
||||
@@ -180,8 +179,8 @@ namespace Cryville.Crtr.Event {
|
||||
public virtual void EndLogicalUpdate(ContainerState s) { }
|
||||
public virtual void EndPhysicalUpdate(ContainerState s) { }
|
||||
public virtual void Dispose() {
|
||||
if (gogroup)
|
||||
GameObject.Destroy(gogroup.gameObject);
|
||||
if (RootTransform)
|
||||
GameObject.Destroy(RootTransform.gameObject);
|
||||
Alive = false;
|
||||
}
|
||||
public virtual void DisposeAll() { }
|
||||
@@ -193,7 +192,7 @@ namespace Cryville.Crtr.Event {
|
||||
void MatchDynamic(ContainerState s, int dl) {
|
||||
ChartPlayer.etor.ContextState = s;
|
||||
ChartPlayer.etor.ContextEvent = Container;
|
||||
skinContainer.MatchDynamic(this, dl);
|
||||
skinContainer.MatchDynamic(dl);
|
||||
ChartPlayer.etor.ContextEvent = null;
|
||||
ChartPlayer.etor.ContextState = null;
|
||||
}
|
||||
@@ -205,6 +204,7 @@ namespace Cryville.Crtr.Event {
|
||||
atime_head = cs.StampedContainer.Time;
|
||||
atime_tail = atime_head + cs.StampedContainer.Duration;
|
||||
MatchDynamic(cs, 0);
|
||||
foreach (var i in _comps) i.Tick(skinContainer, cs.Time);
|
||||
if (cs.Active) PushAnchorEvent(cs.Time, a_cur);
|
||||
if (double.IsNaN(DynamicAnchorSetTime[_a_head])) DynamicAnchorSetTime[_a_head] = atime_head;
|
||||
if (double.IsNaN(DynamicAnchorSetTime[_a_tail])) DynamicAnchorSetTime[_a_tail] = atime_tail;
|
||||
@@ -241,7 +241,8 @@ namespace Cryville.Crtr.Event {
|
||||
#region ISkinnableGroup
|
||||
public abstract string TypeName { get; }
|
||||
public SkinContext SkinContext { get; private set; }
|
||||
public Anchor OpenedAnchor { get; private set; }
|
||||
Anchor _openedAnchor;
|
||||
public int OpenedAnchorName { get { return _openedAnchor == null ? 0 : _openedAnchor.Name; } }
|
||||
public bool TryGetAnchorsByName(int name, out IReadOnlyCollection<Anchor> result) {
|
||||
List<Anchor> anchors;
|
||||
var ret = Anchors.TryGetValue(name, out anchors);
|
||||
|
@@ -1,24 +1,45 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Crtr.Browsing;
|
||||
using Microsoft.Win32;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Cryville.Crtr.Extensions.Malody {
|
||||
public class MalodyChartFinder : LocalResourceFinder {
|
||||
public override string Name { get { return "Malody beatmaps"; } }
|
||||
|
||||
public override string GetRootPath() {
|
||||
var malodyDataPath = GetMalodyDataPath();
|
||||
var malodyConfigPath = Path.Combine(malodyDataPath, "config.json");
|
||||
if (File.Exists(malodyConfigPath)) {
|
||||
using (var reader = new StreamReader(malodyConfigPath, Encoding.UTF8)) {
|
||||
var config = JsonConvert.DeserializeObject<Dictionary<string, object>>(reader.ReadToEnd());
|
||||
object userPath;
|
||||
if (config.TryGetValue("user_chart_path", out userPath)) {
|
||||
var strUserPath = userPath as string;
|
||||
if (!string.IsNullOrEmpty(strUserPath)) {
|
||||
return strUserPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Path.Combine(malodyDataPath, "beatmap");
|
||||
}
|
||||
|
||||
string GetMalodyDataPath() {
|
||||
switch (Environment.OSVersion.Platform) {
|
||||
case PlatformID.Unix:
|
||||
return "/storage/emulated/0/data/malody/beatmap";
|
||||
return "/storage/emulated/0/data/malody";
|
||||
case PlatformID.Win32NT:
|
||||
var reg = Registry.ClassesRoot.OpenSubKey(@"malody\Shell\Open\Command");
|
||||
if (reg == null) return null;
|
||||
var pathObj = reg.GetValue(null);
|
||||
if (pathObj == null) return null;
|
||||
var path = (string)pathObj;
|
||||
return Path.Combine(new FileInfo(StringUtils.GetProcessPathFromCommand(path)).Directory.FullName, "beatmap");
|
||||
return new FileInfo(StringUtils.GetProcessPathFromCommand(path)).Directory.FullName;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
@@ -60,7 +60,7 @@ namespace Cryville.Crtr.Extensions.Quaver {
|
||||
evs.Sort();
|
||||
|
||||
var longevs = new Dictionary<EventWrapper, ChartEvent>();
|
||||
var tm = new TimeTimingModel(src.TimingPoints[0].StartTime / 1e3);
|
||||
var tm = new TimeTimingModel(src.TimingPoints[0].StartTime / 1e3, 2e-3);
|
||||
foreach (var ev in evs) {
|
||||
tm.ForwardTo(ev.StartTime / 1e3);
|
||||
if (ev is EventWrapper.HitObject) {
|
||||
@@ -84,6 +84,7 @@ namespace Cryville.Crtr.Extensions.Quaver {
|
||||
else if (ev is EventWrapper.TimingPoint) {
|
||||
var tev = (EventWrapper.TimingPoint)ev;
|
||||
tm.BPM = tev.Event.Bpm;
|
||||
tm.ForceSnap();
|
||||
chart.sigs.Add(new Chart.Signature {
|
||||
time = tm.FractionalBeatTime,
|
||||
tempo = tev.Event.Bpm,
|
||||
|
@@ -42,15 +42,24 @@ namespace Cryville.Crtr.Extensions {
|
||||
}
|
||||
}
|
||||
public class TimeTimingModel : TimingModel {
|
||||
public TimeTimingModel(double offset = 0) : base(offset) { }
|
||||
public readonly double InputTimeAccuracy;
|
||||
public TimeTimingModel(double offset = 0, double accuracy = 2e-3) : base(offset) {
|
||||
if (accuracy <= 0) throw new ArgumentOutOfRangeException("accuracy");
|
||||
InputTimeAccuracy = accuracy;
|
||||
}
|
||||
public void ForwardTo(double t) {
|
||||
if (t == Time) return;
|
||||
if (BPM == 0) throw new InvalidOperationException("BPM not determined");
|
||||
BeatTime += (t - Time) * BPM / 60;
|
||||
int n, d;
|
||||
FractionUtils.ToFraction(BeatTime, 1f / 48 / BPM * 60, out n, out d);
|
||||
FractionUtils.ToFraction(BeatTime, Math.Min(1, InputTimeAccuracy * BPM / 60), out n, out d);
|
||||
FractionalBeatTime = new BeatTime(n, d);
|
||||
Time = t;
|
||||
}
|
||||
public void ForceSnap() {
|
||||
var alignedBeat = (int)Math.Round(BeatTime);
|
||||
BeatTime = alignedBeat;
|
||||
FractionalBeatTime = new BeatTime(alignedBeat, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ namespace Cryville.Crtr.Extensions.osu {
|
||||
public class osuChartConverter : ResourceConverter {
|
||||
#pragma warning restore IDE1006
|
||||
static readonly string[] SUPPORTED_FORMATS = { ".osu" };
|
||||
const double OFFSET = 0.05;
|
||||
const double OFFSET = 0.011;
|
||||
|
||||
public override string[] GetSupportedFormats() {
|
||||
return SUPPORTED_FORMATS;
|
||||
@@ -108,10 +108,11 @@ namespace Cryville.Crtr.Extensions.osu {
|
||||
else if (ev is osuEvent.TimingChange) {
|
||||
var tev = (osuEvent.TimingChange)ev;
|
||||
if (tm == null) {
|
||||
tm = new TimeTimingModel(tev.StartTime / 1e3);
|
||||
tm = new TimeTimingModel(tev.StartTime / 1e3, 2e-3);
|
||||
bgmEv.offset = (float)(tev.StartTime / 1e3 + OFFSET);
|
||||
}
|
||||
tm.BeatLength = tev.BeatLength / 1e3;
|
||||
tm.ForceSnap();
|
||||
chart.sigs.Add(new Chart.Signature {
|
||||
time = tm.FractionalBeatTime,
|
||||
tempo = (float)tm.BPM,
|
||||
|
@@ -24,7 +24,7 @@ namespace Cryville.Crtr {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public readonly static string FileProtocolPrefix
|
||||
public static readonly string FileProtocolPrefix
|
||||
#if UNITY_STANDALONE_WIN
|
||||
= "file:///";
|
||||
#elif UNITY_ANDROID
|
||||
@@ -37,9 +37,9 @@ namespace Cryville.Crtr {
|
||||
public static SimpleSequencerSource AudioSequencer;
|
||||
public static SimpleSequencerSession AudioSession;
|
||||
public static InputManager InputManager;
|
||||
public readonly static NetworkTaskWorker NetworkTaskWorker = new NetworkTaskWorker();
|
||||
public static readonly NetworkTaskWorker NetworkTaskWorker = new NetworkTaskWorker();
|
||||
|
||||
public readonly static JsonSerializerSettings GlobalJsonSerializerSettings
|
||||
public static readonly JsonSerializerSettings GlobalJsonSerializerSettings
|
||||
= new JsonSerializerSettings() {
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore,
|
||||
};
|
||||
|
@@ -24,6 +24,7 @@ namespace Cryville.Crtr {
|
||||
Components.Add("polysec", typeof(PolygonSGO));
|
||||
Components.Add("rect", typeof(SpriteRect));
|
||||
Components.Add("scale3", typeof(SpriteScale3));
|
||||
Components.Add("sec", typeof(SectionalGameObject));
|
||||
Components.Add("sprite", typeof(SpriteBase));
|
||||
Components.Add("text", typeof(SpriteText));
|
||||
|
||||
@@ -32,6 +33,9 @@ namespace Cryville.Crtr {
|
||||
|
||||
Materials.Add("-SpriteMat", Resources.Load<Material>("Materials/SpriteMat"));
|
||||
|
||||
Shaders.Add("default", Shader.Find("Sprites/Default"));
|
||||
Shaders.Add("additive", Shader.Find("Sprites/Additive"));
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,8 @@ using Cryville.Common.Unity.Input;
|
||||
using Cryville.Crtr.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Runtime.Serialization;
|
||||
using RVector3 = UnityEngine.Vector3;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class InputProxy : IDisposable {
|
||||
@@ -12,12 +13,11 @@ namespace Cryville.Crtr {
|
||||
readonly PdtRuleset _ruleset;
|
||||
readonly Judge _judge;
|
||||
public InputProxy(PdtRuleset ruleset, Judge judge) {
|
||||
unsafe {
|
||||
fixed (byte* ptr = _vecbuf) {
|
||||
*(int*)(ptr + 3 * sizeof(float)) = PdtInternalType.Number;
|
||||
}
|
||||
for (int i = 0; i <= MAX_DEPTH; i++) {
|
||||
var vecsrc = new InputVectorSrc();
|
||||
_vecsrcs[i] = vecsrc;
|
||||
_vecops[i] = new InputVectorOp(vecsrc);
|
||||
}
|
||||
_vecsrc = new PropSrc.Arbitrary(PdtInternalType.Vector, _vecbuf);
|
||||
_etor = ChartPlayer.etor;
|
||||
_ruleset = ruleset;
|
||||
_judge = judge;
|
||||
@@ -174,14 +174,58 @@ namespace Cryville.Crtr {
|
||||
|
||||
readonly object _lock = new object();
|
||||
static readonly int _var_value = IdentifierManager.SharedInstance.Request("value");
|
||||
static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary();
|
||||
readonly byte[] _vecbuf = new byte[3 * sizeof(float) + sizeof(int)];
|
||||
readonly PropSrc.Arbitrary _vecsrc;
|
||||
const int MAX_DEPTH = 15;
|
||||
const int MAX_DIMENSION = 3;
|
||||
readonly InputVectorSrc[] _vecsrcs = new InputVectorSrc[MAX_DEPTH + 1];
|
||||
readonly InputVectorOp[] _vecops = new InputVectorOp[MAX_DEPTH + 1];
|
||||
unsafe class InputVectorSrc : PropSrc.FixedBuffer {
|
||||
public InputVectorSrc() : base(PdtInternalType.Vector, MAX_DIMENSION * sizeof(float) + sizeof(int)) {
|
||||
fixed (byte* ptr = buf) {
|
||||
*(int*)(ptr + MAX_DIMENSION * sizeof(float)) = PdtInternalType.Number;
|
||||
}
|
||||
}
|
||||
public bool IsNull { get; set; }
|
||||
public void Set(RVector3 vec) {
|
||||
fixed (byte* _ptr = buf) {
|
||||
*(RVector3*)_ptr = vec;
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
class InputVectorOp : PropOp {
|
||||
readonly InputVectorSrc _src;
|
||||
public InputVectorOp(InputVectorSrc src) {
|
||||
_src = src;
|
||||
}
|
||||
protected override void Execute() {
|
||||
var op = GetOperand(0);
|
||||
if (op.Type == PdtInternalType.Null) {
|
||||
_src.IsNull = true;
|
||||
}
|
||||
else {
|
||||
var vec = new RVector3();
|
||||
int dim;
|
||||
if (op.Type == PdtInternalType.Number) dim = 1;
|
||||
else if (op.Type == PdtInternalType.Vector) {
|
||||
int arrtype, _;
|
||||
op.GetArraySuffix(out arrtype, out _);
|
||||
if (arrtype != PdtInternalType.Number)
|
||||
throw new InvalidCastException("Not a vector of numbers");
|
||||
dim = Math.Min(3, (op.Length - sizeof(int)) / sizeof(float));
|
||||
}
|
||||
else throw new InvalidCastException("Invalid vector");
|
||||
for (int i = 0; i < dim; i++) {
|
||||
vec[i] = op.AsNumber(i * sizeof(float));
|
||||
}
|
||||
_src.IsNull = false;
|
||||
_src.Set(vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
readonly Dictionary<InputHandler, double> _timeOrigins = new Dictionary<InputHandler, double>();
|
||||
readonly Dictionary<InputSource, int> _activeCounts = new Dictionary<InputSource, int>();
|
||||
readonly Dictionary<InputIdentifier, float> _vect = new Dictionary<InputIdentifier, float>();
|
||||
readonly Dictionary<ProxiedInputIdentifier, PropSrc> _vecs = new Dictionary<ProxiedInputIdentifier, PropSrc>();
|
||||
static readonly PropSrc.Arbitrary _nullsrc = new PropSrc.Arbitrary(PdtInternalType.Null, new byte[0]);
|
||||
double? _lockTime = null;
|
||||
unsafe void OnInput(InputIdentifier id, InputVector vec) {
|
||||
lock (_lock) {
|
||||
@@ -191,15 +235,12 @@ namespace Cryville.Crtr {
|
||||
float ft, tt = (float)(_lockTime != null ? _lockTime.Value : (vec.Time - _timeOrigins[id.Source.Handler]));
|
||||
if (!_vect.TryGetValue(id, out ft)) ft = tt;
|
||||
if (vec.IsNull) {
|
||||
_etor.ContextCascadeUpdate(_var_value, _nullsrc);
|
||||
_etor.ContextCascadeUpdate(_var_value, PropSrc.Null);
|
||||
OnInput(id, proxy.Target, ft, tt, true);
|
||||
}
|
||||
else {
|
||||
fixed (byte* ptr = _vecbuf) {
|
||||
*(Vector3*)ptr = vec.Vector;
|
||||
}
|
||||
_vecsrc.Invalidate();
|
||||
_etor.ContextCascadeUpdate(_var_value, _vecsrc);
|
||||
_vecsrcs[0].Set(vec.Vector);
|
||||
_etor.ContextCascadeUpdate(_var_value, _vecsrcs[0]);
|
||||
OnInput(id, proxy.Target, ft, tt, false);
|
||||
}
|
||||
_vect[id] = tt;
|
||||
@@ -209,21 +250,27 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
|
||||
static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv");
|
||||
unsafe void OnInput(InputIdentifier id, Identifier target, float ft, float tt, bool nullflag) {
|
||||
unsafe void OnInput(InputIdentifier id, Identifier target, float ft, float tt, bool nullflag, int depth = 0) {
|
||||
if (depth >= MAX_DEPTH) throw new InputProxyException("Input propagation limit reached\nThe ruleset has invalid input definitions");
|
||||
var def = _ruleset.inputs[target];
|
||||
if (def.pass != null) {
|
||||
foreach (var p in def.pass) {
|
||||
_etor.ContextCascadeInsert();
|
||||
_arbop.Name = _var_value;
|
||||
if (!nullflag) _etor.Evaluate(_arbop, p.Value);
|
||||
OnInput(id, p.Key, ft, tt, nullflag);
|
||||
bool newNullFlag = nullflag;
|
||||
if (!newNullFlag) {
|
||||
ChartPlayer.etor.Evaluate(_vecops[depth + 1], p.Value);
|
||||
newNullFlag = _vecsrcs[depth + 1].IsNull;
|
||||
if (newNullFlag) ChartPlayer.etor.ContextCascadeUpdate(_var_value, PropSrc.Null);
|
||||
else ChartPlayer.etor.ContextCascadeUpdate(_var_value, _vecsrcs[depth + 1]);
|
||||
}
|
||||
OnInput(id, p.Key, ft, tt, newNullFlag, depth + 1);
|
||||
_etor.ContextCascadeDiscard();
|
||||
}
|
||||
}
|
||||
else {
|
||||
var pid = new ProxiedInputIdentifier { Source = id, Target = target };
|
||||
PropSrc fv, tv = _etor.ContextCascadeLookup(_var_value);
|
||||
if (!_vecs.TryGetValue(pid, out fv)) fv = _nullsrc;
|
||||
if (!_vecs.TryGetValue(pid, out fv)) fv = PropSrc.Null;
|
||||
if (fv.Type != PdtInternalType.Null || tv.Type != PdtInternalType.Null) {
|
||||
if (fv.Type == PdtInternalType.Null) _activeCounts[id.Source]++;
|
||||
_etor.ContextCascadeInsert();
|
||||
@@ -306,4 +353,12 @@ namespace Cryville.Crtr {
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class InputProxyException : Exception {
|
||||
public InputProxyException() { }
|
||||
public InputProxyException(string message) : base(message) { }
|
||||
public InputProxyException(string message, Exception inner) : base(message, inner) { }
|
||||
protected InputProxyException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text.Formatting;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
@@ -134,7 +135,7 @@ namespace Cryville.Crtr {
|
||||
if (actlist.Count > 0) {
|
||||
_numbuf3 = ft; _numsrc3.Invalidate(); _etor.ContextCascadeUpdate(_var_ft, _numsrc3);
|
||||
_numbuf4 = tt; _numsrc4.Invalidate(); _etor.ContextCascadeUpdate(_var_tt, _numsrc4);
|
||||
var index = 0;
|
||||
int index = 0, iter = 0;
|
||||
while (index >= 0 && index < actlist.Count) {
|
||||
var ev = actlist[index];
|
||||
_numbuf1 = (float)ev.StartTime; _numsrc1.Invalidate(); _etor.ContextCascadeUpdate(_var_fn, _numsrc1);
|
||||
@@ -154,19 +155,21 @@ namespace Cryville.Crtr {
|
||||
if (index < 0) index = ~index;
|
||||
}
|
||||
else index++;
|
||||
if (iter++ >= 16) throw new JudgePropagationException();
|
||||
}
|
||||
else index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool Pass(JudgeEvent ev, float time, Identifier[] ids) {
|
||||
bool Pass(JudgeEvent ev, float time, Identifier[] ids, int depth = 0) {
|
||||
if (depth >= 16) throw new JudgePropagationException();
|
||||
foreach (var i in ids) {
|
||||
var def = _rs.judges[i];
|
||||
if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
|
||||
else _flag = true;
|
||||
if (_flag) {
|
||||
if (def.scores != null) UpdateScore(def.scores);
|
||||
if (def.pass != null) Pass(ev, time, def.pass);
|
||||
if (def.pass != null) Pass(ev, time, def.pass, depth + 1);
|
||||
ev.Handler.ReportJudge(ev, time, i);
|
||||
return true;
|
||||
}
|
||||
@@ -323,4 +326,12 @@ namespace Cryville.Crtr {
|
||||
public string format = "";
|
||||
}
|
||||
#endregion
|
||||
|
||||
[Serializable]
|
||||
public class JudgePropagationException : Exception {
|
||||
public JudgePropagationException() : base("Judge propagation limit reached\nThe ruleset has invalid judge definitions") { }
|
||||
public JudgePropagationException(string message) : base(message) { }
|
||||
public JudgePropagationException(string message, Exception inner) : base(message, inner) { }
|
||||
protected JudgePropagationException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||
}
|
||||
}
|
||||
|
@@ -360,8 +360,8 @@ namespace Cryville.Crtr {
|
||||
public abstract void LerpWith(Vector start, float lerpedTime, ref Vector result);
|
||||
public abstract float DelerpWith(Vector start, Vector value);
|
||||
public abstract bool IsZero();
|
||||
public override abstract string ToString();
|
||||
public abstract float[] ToArray();
|
||||
public abstract override string ToString();
|
||||
public abstract unsafe void ToArray(float* arr);
|
||||
|
||||
public Vector Clone() {
|
||||
return (Vector)MemberwiseClone();
|
||||
@@ -442,8 +442,8 @@ namespace Cryville.Crtr {
|
||||
return Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public override float[] ToArray() {
|
||||
return new float[] { Value };
|
||||
public override unsafe void ToArray(float* arr) {
|
||||
arr[0] = Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,8 +504,8 @@ namespace Cryville.Crtr {
|
||||
return Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public override float[] ToArray() {
|
||||
return new float[] { Value };
|
||||
public override unsafe void ToArray(float* arr) {
|
||||
arr[0] = Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,8 +566,8 @@ namespace Cryville.Crtr {
|
||||
return Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public override float[] ToArray() {
|
||||
return new float[] { Value };
|
||||
public override unsafe void ToArray(float* arr) {
|
||||
arr[0] = Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,8 +610,8 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
w = aw ? rw : (float?)null;
|
||||
h = ah ? rh : (float?)null;
|
||||
w = aw ? rw : null;
|
||||
h = ah ? rh : null;
|
||||
}
|
||||
|
||||
public static VecPtComp Parse(string s) {
|
||||
@@ -669,8 +669,9 @@ namespace Cryville.Crtr {
|
||||
return ToString(w, h);
|
||||
}
|
||||
|
||||
public override float[] ToArray() {
|
||||
return new float[] { w.Value, h.Value };
|
||||
public override unsafe void ToArray(float* arr) {
|
||||
arr[0] = w.Value;
|
||||
arr[1] = h.Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -764,8 +765,10 @@ namespace Cryville.Crtr {
|
||||
);
|
||||
}
|
||||
|
||||
public override float[] ToArray() {
|
||||
return new float[] { x.Value, y.Value, z.Value };
|
||||
public override unsafe void ToArray(float* arr) {
|
||||
arr[0] = x.Value;
|
||||
arr[1] = y.Value;
|
||||
arr[2] = z.Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,8 +848,11 @@ namespace Cryville.Crtr {
|
||||
return VecPtComp.ToString(xw, xh) + "," + VecPtComp.ToString(yw, yh);
|
||||
}
|
||||
|
||||
public override float[] ToArray() {
|
||||
return new float[] { xw.Value, xh.Value, yw.Value, yh.Value };
|
||||
public override unsafe void ToArray(float* arr) {
|
||||
arr[0] = xw.Value;
|
||||
arr[1] = xh.Value;
|
||||
arr[2] = yw.Value;
|
||||
arr[3] = yh.Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -936,40 +942,31 @@ namespace Cryville.Crtr {
|
||||
return VecPtComp.ToString(xw, xh) + "," + VecPtComp.ToString(yw, yh) + "," + (z != null ? z.Value.ToString(CultureInfo.InvariantCulture) : "");
|
||||
}
|
||||
|
||||
public override float[] ToArray() {
|
||||
return new float[] { xw.Value, xh.Value, yw.Value, yh.Value, z.Value };
|
||||
public override unsafe void ToArray(float* arr) {
|
||||
arr[0] = xw.Value;
|
||||
arr[1] = xh.Value;
|
||||
arr[2] = yw.Value;
|
||||
arr[3] = yh.Value;
|
||||
arr[4] = z.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class VectorSrc : PropSrc {
|
||||
public unsafe class VectorSrc : PropSrc.FixedBuffer {
|
||||
const int MAX_DIMENSION = 8;
|
||||
protected readonly Func<Vector> _cb;
|
||||
public VectorSrc(Func<Vector> cb, int type) : base(type) { _cb = cb; }
|
||||
public static VectorSrc Construct(Func<Vector> cb) {
|
||||
if (cb().Dimension == 1) return new INumber(cb);
|
||||
else return new IVector(cb);
|
||||
}
|
||||
class INumber : VectorSrc {
|
||||
public INumber(Func<Vector> cb) : base(cb, PdtInternalType.Number) { }
|
||||
protected override unsafe void InternalGet() {
|
||||
var arr = _cb().ToArray();
|
||||
buf = new byte[sizeof(float)];
|
||||
fixed (byte* ptr = buf) {
|
||||
*(float*)ptr = arr[0];
|
||||
}
|
||||
public VectorSrc(Func<Vector> cb) : base(PdtInternalType.Vector, MAX_DIMENSION * sizeof(float) + sizeof(int)) {
|
||||
_cb = cb;
|
||||
fixed (byte* rptr = buf) {
|
||||
var ptr = (float*)rptr;
|
||||
*(int*)(ptr + MAX_DIMENSION) = PdtInternalType.Number;
|
||||
}
|
||||
}
|
||||
class IVector : VectorSrc {
|
||||
public IVector(Func<Vector> cb) : base(cb, PdtInternalType.Vector) { }
|
||||
protected override unsafe void InternalGet() {
|
||||
var arr = _cb().ToArray();
|
||||
buf = new byte[sizeof(float) * arr.Length + sizeof(int)];
|
||||
fixed (byte* rptr = buf) {
|
||||
var ptr = (float*)rptr;
|
||||
for (int i = 0; i < arr.Length; i++, ptr++) {
|
||||
*ptr = arr[i];
|
||||
}
|
||||
*(int*)ptr = PdtInternalType.Number;
|
||||
}
|
||||
protected override void InternalGet() {
|
||||
var v = _cb();
|
||||
if (v.Dimension > MAX_DIMENSION) throw new NotSupportedException("Vector dimension too large");
|
||||
fixed (byte* rptr = buf) {
|
||||
var ptr = (float*)rptr;
|
||||
v.ToArray(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -977,7 +974,7 @@ namespace Cryville.Crtr {
|
||||
public class VectorOp : PropOp {
|
||||
readonly Action<float[]> _cb;
|
||||
public VectorOp(Action<float[]> cb) { _cb = cb; }
|
||||
protected unsafe override void Execute() {
|
||||
protected override unsafe void Execute() {
|
||||
var op = GetOperand(0);
|
||||
float[] values;
|
||||
if (op.Type == PdtInternalType.Number) {
|
||||
@@ -988,7 +985,7 @@ namespace Cryville.Crtr {
|
||||
op.GetArraySuffix(out type, out _);
|
||||
if (type != PdtInternalType.Number)
|
||||
throw new InvalidOperationException("Not a vector of numbers");
|
||||
values = new float[op.Length - sizeof(int)];
|
||||
values = new float[(op.Length - sizeof(int)) / sizeof(float)];
|
||||
fixed (float* ptr = values) {
|
||||
op.CopyTo((byte*)ptr, 0, op.Length - sizeof(int));
|
||||
}
|
||||
|
@@ -57,7 +57,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
public override void Init() {
|
||||
base.Init();
|
||||
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
|
||||
sgos = RootTransform.GetComponentsInChildren<SectionalGameObject>();
|
||||
foreach (var judge in judges) judge.Value.InitPropSrcs();
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Cryville.Crtr {
|
||||
protected override void StartGraphicalUpdate(ContainerState s) {
|
||||
base.StartGraphicalUpdate(s);
|
||||
TransformAwake(s);
|
||||
if (gogroup) {
|
||||
if (RootTransform) {
|
||||
if (Event.IsLong) {
|
||||
foreach (var i in sgos) {
|
||||
i.Reset();
|
||||
@@ -79,10 +79,10 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
else {
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
gogroup.SetPositionAndRotation(Position, Rotation);
|
||||
RootTransform.SetPositionAndRotation(Position, Rotation);
|
||||
#else
|
||||
gogroup.position = Position;
|
||||
gogroup.rotation = Rotation;
|
||||
RootTransform.position = Position;
|
||||
RootTransform.rotation = Rotation;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,7 @@ namespace Cryville.Crtr {
|
||||
if (s.CloneType <= 2) {
|
||||
Position = GetFramePoint(s.Parent, s.Track);
|
||||
Rotation = GetFrameRotation(s.Parent, s.Track);
|
||||
if (s.CloneType == 2 && gogroup && Event.IsLong) {
|
||||
if (s.CloneType == 2 && RootTransform && Event.IsLong) {
|
||||
foreach (var i in sgos)
|
||||
i.AppendPoint(Position, Rotation);
|
||||
}
|
||||
@@ -128,7 +128,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
|
||||
protected override void EndGraphicalUpdate(ContainerState s) {
|
||||
if (gogroup) {
|
||||
if (RootTransform) {
|
||||
foreach (var i in sgos) i.Seal();
|
||||
}
|
||||
base.EndGraphicalUpdate(s);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Math;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Event;
|
||||
using System;
|
||||
@@ -13,32 +14,40 @@ namespace Cryville.Crtr {
|
||||
|
||||
static readonly byte[] _nullbuf = new byte[0];
|
||||
readonly byte[] _numbuf = new byte[4];
|
||||
readonly PropSrc _vecsrc;
|
||||
Vector _vec;
|
||||
static readonly int _var_w = IdentifierManager.SharedInstance.Request("w");
|
||||
static readonly int _var_h = IdentifierManager.SharedInstance.Request("h");
|
||||
static readonly int _var_current_time = IdentifierManager.SharedInstance.Request("current_time");
|
||||
static readonly int _var_inf = IdentifierManager.SharedInstance.Request("inf");
|
||||
static readonly int _var_true = IdentifierManager.SharedInstance.Request("true");
|
||||
static readonly int _var_false = IdentifierManager.SharedInstance.Request("false");
|
||||
static readonly int _var_null = IdentifierManager.SharedInstance.Request("null");
|
||||
static readonly int _var_current_time = IdentifierManager.SharedInstance.Request("current_time");
|
||||
protected override void GetVariable(int name, bool forced, out int type, out byte[] value) {
|
||||
if (name == _var_w) { LoadNum(ChartPlayer.hitRect.width); type = PdtInternalType.Number; value = _numbuf; }
|
||||
else if (name == _var_h) { LoadNum(ChartPlayer.hitRect.height); type = PdtInternalType.Number; value = _numbuf; }
|
||||
else if (name == _var_inf) { LoadNum(float.PositiveInfinity); type = PdtInternalType.Number; value = _numbuf; }
|
||||
else if (name == _var_true) { LoadNum(1); type = PdtInternalType.Number; value = _numbuf; }
|
||||
else if (name == _var_false) { LoadNum(0); type = PdtInternalType.Number; value = _numbuf; }
|
||||
else if (name == _var_null) { LoadIdent(0); type = PdtInternalType.Undefined; value = _numbuf; }
|
||||
else {
|
||||
var id = new Identifier(name);
|
||||
PropSrc prop;
|
||||
PropSrc prop; SkinVariable variable;
|
||||
if (ContextEvent != null && ContextEvent.PropSrcs.TryGetValue(name, out prop)) {
|
||||
prop.Get(out type, out value);
|
||||
}
|
||||
else if (ContextState != null && ChartPlayer.motionRegistry.ContainsKey(id)) {
|
||||
var vec = ContextState.GetRawValue(id);
|
||||
VectorSrc.Construct(() => vec).Get(out type, out value);
|
||||
_vec = ContextState.GetRawValue(id);
|
||||
_vecsrc.Invalidate();
|
||||
_vecsrc.Get(out type, out value);
|
||||
}
|
||||
else if (ContextState != null && ContextState.Handler.PropSrcs.TryGetValue(name, out prop)) {
|
||||
prop.Get(out type, out value);
|
||||
RevokePotentialConstant();
|
||||
}
|
||||
else if (ContextSkinContainer != null && ContextSkinContainer.Variables.TryGetValue(name, out variable)) {
|
||||
variable.Src.Get(out type, out value);
|
||||
}
|
||||
else if (ContextJudge != null && ContextJudge.TryGetScoreSrc(name, out prop)) {
|
||||
prop.Get(out type, out value);
|
||||
RevokePotentialConstant();
|
||||
@@ -98,11 +107,12 @@ namespace Cryville.Crtr {
|
||||
else throw new KeyNotFoundException(string.Format("Undefined collapse operator {0}", IdentifierManager.SharedInstance.Retrieve(name)));
|
||||
}
|
||||
|
||||
public ChartEvent ContextEvent { private get; set; }
|
||||
public ContainerState ContextState { private get; set; }
|
||||
public Transform ContextTransform { private get; set; }
|
||||
public Judge ContextJudge { private get; set; }
|
||||
public PropSrc ContextSelfValue { private get; set; }
|
||||
public ChartEvent ContextEvent { get; set; }
|
||||
public ContainerState ContextState { get; set; }
|
||||
public SkinContainer ContextSkinContainer { get; set; }
|
||||
public Transform ContextTransform { get; set; }
|
||||
public Judge ContextJudge { get; set; }
|
||||
public PropSrc ContextSelfValue { get; set; }
|
||||
|
||||
readonly Stack<int> ContextCascadeBlocks = new Stack<int>();
|
||||
public void ContextCascadeInsertBlock() {
|
||||
@@ -140,6 +150,7 @@ namespace Cryville.Crtr {
|
||||
public PdtEvaluator() {
|
||||
ContextCascadeBlocks.Push(0);
|
||||
for (int i = 0; i < ContextCascade.Length; i++) ContextCascade[i] = new Dictionary<int, PropSrc>();
|
||||
_vecsrc = new VectorSrc(() => _vec);
|
||||
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("screen_edge"), new func_screen_edge(() => ContextTransform));
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("int"), new func_int(() => ContextSelfValue));
|
||||
@@ -147,6 +158,12 @@ namespace Cryville.Crtr {
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("min"), new func_min(() => ContextSelfValue));
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("max"), new func_max(() => ContextSelfValue));
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("abs"), new func_abs(() => ContextSelfValue));
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("anim"), new func_anim(() => ContextSelfValue));
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("cubic_bezier"), new func_cubic_bezier(() => ContextSelfValue));
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("ease"), new func_cubic_bezier_fixed(0.25f, 0.1f, 0.25f, 1f, () => ContextSelfValue));
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("ease_in"), new func_cubic_bezier_fixed(0.42f, 0f, 1f, 1f, () => ContextSelfValue));
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("ease_out"), new func_cubic_bezier_fixed(0f, 0f, 0.58f, 1f, () => ContextSelfValue));
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("ease_in_out"), new func_cubic_bezier_fixed(0.42f, 0f, 0.58f, 1f, () => ContextSelfValue));
|
||||
|
||||
Func<int, PropSrc> cccb = k => ContextCascadeLookup(k);
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("attack_timing"), new func_attack_timing(cccb));
|
||||
@@ -263,6 +280,7 @@ namespace Cryville.Crtr {
|
||||
protected override void Execute() {
|
||||
var o0 = GetOperand(0);
|
||||
int type = o0.Type;
|
||||
if (type == PdtInternalType.Error) throw new InvalidOperationException("Error");
|
||||
int len = o0.Length;
|
||||
bool blit = !IsBlittable(type);
|
||||
for (var i = 1; i < LoadedOperandCount; i++) {
|
||||
@@ -486,6 +504,85 @@ namespace Cryville.Crtr {
|
||||
ret.SetNumber(Mathf.Abs(arg));
|
||||
}
|
||||
}
|
||||
class func_anim : PdtOperator {
|
||||
readonly Func<PropSrc> _ctxcb;
|
||||
public func_anim(Func<PropSrc> ctxcb) : base(3) {
|
||||
_ctxcb = ctxcb;
|
||||
}
|
||||
protected override unsafe void Execute() {
|
||||
var op1 = GetOperand(0);
|
||||
var op2 = GetOperand(1);
|
||||
var dim1 = GetDimension(op1);
|
||||
var dim2 = GetDimension(op2);
|
||||
var dim0 = Math.Min(dim1, dim2);
|
||||
float time;
|
||||
switch (LoadedOperandCount) {
|
||||
case 2: time = oputil.AsNumber(_ctxcb()); break;
|
||||
case 3: time = GetOperand(2).AsNumber(); break;
|
||||
default: throw new ArgumentException("Argument count not 2 or 3");
|
||||
}
|
||||
if (dim0 == 1) {
|
||||
GetReturnFrame(PdtInternalType.Number, sizeof(float))
|
||||
.SetNumber(op1.AsNumber() * (1 - time) + op2.AsNumber() * time);
|
||||
}
|
||||
else {
|
||||
var ret = GetReturnFrame(PdtInternalType.Vector, dim0 * sizeof(float) + sizeof(int));
|
||||
for (int i = 0; i < dim0 * sizeof(float); i += sizeof(float)) {
|
||||
ret.SetNumber(op1.AsNumber(i) * (1 - time) + op2.AsNumber(i) * time, i);
|
||||
}
|
||||
ret.SetArraySuffix(PdtInternalType.Number);
|
||||
}
|
||||
}
|
||||
static int GetDimension(PdtVariableMemory op) {
|
||||
switch (op.Type) {
|
||||
case PdtInternalType.Number: return 1;
|
||||
case PdtInternalType.Vector:
|
||||
int arrtype, _;
|
||||
op.GetArraySuffix(out arrtype, out _);
|
||||
if (arrtype != PdtInternalType.Number)
|
||||
throw new ArgumentException("Not animatable");
|
||||
return (op.Length - sizeof(int)) / sizeof(float);
|
||||
default: throw new ArgumentException("Not animatable");
|
||||
}
|
||||
}
|
||||
}
|
||||
class func_cubic_bezier : PdtOperator {
|
||||
readonly Func<PropSrc> _ctxcb;
|
||||
public func_cubic_bezier(Func<PropSrc> ctxcb) : base(5) {
|
||||
_ctxcb = ctxcb;
|
||||
}
|
||||
protected override unsafe void Execute() {
|
||||
float x1 = GetOperand(0).AsNumber(), y1 = GetOperand(1).AsNumber();
|
||||
float x2 = GetOperand(2).AsNumber(), y2 = GetOperand(3).AsNumber();
|
||||
float time;
|
||||
switch (LoadedOperandCount) {
|
||||
case 4: time = oputil.AsNumber(_ctxcb()); break;
|
||||
case 5: time = GetOperand(4).AsNumber(); break;
|
||||
default: throw new ArgumentException("Argument count not 4 or 5");
|
||||
}
|
||||
GetReturnFrame(PdtInternalType.Number, sizeof(float))
|
||||
.SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-5f));
|
||||
}
|
||||
}
|
||||
class func_cubic_bezier_fixed : PdtOperator {
|
||||
readonly float x1, y1, x2, y2;
|
||||
readonly Func<PropSrc> _ctxcb;
|
||||
public func_cubic_bezier_fixed(float x1, float y1, float x2, float y2, Func<PropSrc> ctxcb) : base(1) {
|
||||
this.x1 = x1; this.y1 = y1;
|
||||
this.x2 = x2; this.y2 = y2;
|
||||
_ctxcb = ctxcb;
|
||||
}
|
||||
protected override void Execute() {
|
||||
float time;
|
||||
switch (LoadedOperandCount) {
|
||||
case 0: time = oputil.AsNumber(_ctxcb()); break;
|
||||
case 1: time = GetOperand(0).AsNumber(); break;
|
||||
default: throw new ArgumentException("Argument count not 0 or 1");
|
||||
}
|
||||
GetReturnFrame(PdtInternalType.Number, sizeof(float))
|
||||
.SetNumber(CubicBezier.Evaluate(time, x1, y1, x2, y2, 1e-5f));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region Judge Functions
|
||||
static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
|
||||
@@ -554,12 +651,12 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
unsafe static class oputil {
|
||||
static unsafe class oputil {
|
||||
public static float AsNumber(PropSrc src) {
|
||||
if (src == null) throw new ArgumentNullException("src");
|
||||
int type; byte[] value;
|
||||
src.Get(out type, out value);
|
||||
if (type != PdtInternalType.Number)
|
||||
if (type != PdtInternalType.Number && type != PdtInternalType.Vector)
|
||||
throw new ArgumentException("Not a number");
|
||||
fixed (byte* ptr = value) {
|
||||
return *(float*)ptr;
|
||||
|
@@ -63,7 +63,7 @@ namespace Cryville.Crtr {
|
||||
public class StringArray : PropOp {
|
||||
readonly Action<string[]> _cb;
|
||||
public StringArray(Action<string[]> cb) { _cb = cb; }
|
||||
protected unsafe override void Execute() {
|
||||
protected override unsafe void Execute() {
|
||||
var op = GetOperand(0);
|
||||
int arrtype; int len;
|
||||
op.GetArraySuffix(out arrtype, out len);
|
||||
@@ -100,22 +100,25 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
public class Enum<T> : PropOp {
|
||||
readonly static Dictionary<int, int> _cache = new Dictionary<int, int>();
|
||||
static readonly Dictionary<int, int> _cache = new Dictionary<int, int>();
|
||||
readonly Action<T> _cb;
|
||||
readonly Func<int, T> _caster;
|
||||
public Enum(Action<T> cb, Func<int, T> caster) {
|
||||
static Enum() {
|
||||
if (!typeof(T).IsEnum)
|
||||
throw new ArgumentException("Type is not enum");
|
||||
var names = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
_cache[IdentifierManager.SharedInstance.Request(names[i].Name)] = Convert.ToInt32(names[i].GetValue(null));
|
||||
|
||||
}
|
||||
public Enum(Action<T> cb, Func<int, T> caster) {
|
||||
_cb = cb;
|
||||
_caster = caster;
|
||||
}
|
||||
protected override void Execute() {
|
||||
int result = 0;
|
||||
for (int i = 0; i < LoadedOperandCount; i++)
|
||||
result |= _cache[GetOperand(0).AsIdentifier()];
|
||||
result |= _cache[GetOperand(i).AsIdentifier()];
|
||||
_cb(_caster(result));
|
||||
}
|
||||
}
|
||||
|
@@ -54,6 +54,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
public static readonly PropSrc Null = new Arbitrary(PdtInternalType.Null, new byte[0]);
|
||||
public class String : PropSrc {
|
||||
readonly Func<string> _cb;
|
||||
public String(Func<string> cb) : base(PdtInternalType.String) { _cb = cb; }
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Collections.Generic;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Browsing;
|
||||
using Newtonsoft.Json;
|
||||
@@ -64,9 +65,9 @@ namespace Cryville.Crtr {
|
||||
public class Constraint {
|
||||
static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary();
|
||||
[ElementList]
|
||||
public Dictionary<RulesetSelectors, Constraint> Elements = new Dictionary<RulesetSelectors, Constraint>();
|
||||
public PairList<RulesetSelectors, Constraint> Elements = new PairList<RulesetSelectors, Constraint>();
|
||||
[PropertyList]
|
||||
public Dictionary<PropertyKey, PdtExpression> Properties = new Dictionary<PropertyKey, PdtExpression>();
|
||||
public PairList<PropertyKey, PdtExpression> Properties = new PairList<PropertyKey, PdtExpression>();
|
||||
public void Optimize(PdtEvaluatorBase etor) {
|
||||
foreach (var e in Properties) {
|
||||
etor.Optimize(e.Value);
|
||||
|
@@ -6,7 +6,7 @@ using RangeAttribute = Cryville.Common.ComponentModel.RangeAttribute;
|
||||
namespace Cryville.Crtr {
|
||||
public class Settings {
|
||||
[Category("graphics")]
|
||||
[LogarithmicScale][Step(0.5f)][Precision(1e-2)]
|
||||
[LogarithmicScale][Range(0.01f, 20f)][Step(0.5f)][Precision(1e-2)]
|
||||
public float BackwardClippingDistance {
|
||||
get {
|
||||
return PlayerPrefs.GetFloat("BackwardClippingDistance", 0.2f);
|
||||
@@ -62,8 +62,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
|
||||
[Category("gameplay")]
|
||||
[Step(0.01f)]
|
||||
[Precision(1e-3)]
|
||||
[Step(0.01f)][Precision(1e-3)]
|
||||
public float GraphicalOffset {
|
||||
get {
|
||||
return PlayerPrefs.GetFloat("GraphicalOffset", 0);
|
||||
@@ -132,7 +131,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
|
||||
[Category("graphics")]
|
||||
[LogarithmicScale][Step(0.5f)][Precision(1e-1)]
|
||||
[LogarithmicScale][Range(0.1f, 200f)][Step(0.5f)][Precision(1e-1)]
|
||||
public float RenderDistance {
|
||||
get {
|
||||
return PlayerPrefs.GetFloat("RenderDistance", 4);
|
||||
@@ -166,8 +165,8 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[Category("gameplay")]
|
||||
[Description("(Not implemented yet)")]
|
||||
[Category("debug")]
|
||||
[Range(0, float.PositiveInfinity)][Step(10f)][Precision(1e-1)]
|
||||
public float StartOffset {
|
||||
get {
|
||||
return PlayerPrefs.GetFloat("StartOffset", 0);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Collections.Generic;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Browsing;
|
||||
using Newtonsoft.Json;
|
||||
@@ -59,7 +60,10 @@ namespace Cryville.Crtr {
|
||||
foreach (var e in effects) {
|
||||
var effect = e.Value;
|
||||
etor.ContextCascadeInsert();
|
||||
etor.Optimize(effect.duration);
|
||||
etor.ContextCascadeUpdate(EffectInstance._VAR_EFFECT_INDEX, PropSrc.Error);
|
||||
foreach(var s in effect.states) {
|
||||
etor.Optimize(s.Value.duration);
|
||||
}
|
||||
effect.elements.Optimize(etor);
|
||||
etor.ContextCascadeDiscard();
|
||||
}
|
||||
@@ -69,12 +73,12 @@ namespace Cryville.Crtr {
|
||||
|
||||
public class SkinElement {
|
||||
[ElementList]
|
||||
public Dictionary<SkinSelectors, SkinElement> elements
|
||||
= new Dictionary<SkinSelectors, SkinElement>();
|
||||
public PairList<SkinSelectors, SkinElement> elements
|
||||
= new PairList<SkinSelectors, SkinElement>();
|
||||
|
||||
[PropertyList]
|
||||
public Dictionary<SkinPropertyKey, PdtExpression> properties
|
||||
= new Dictionary<SkinPropertyKey, PdtExpression>();
|
||||
public PairList<SkinPropertyKey, PdtExpression> properties
|
||||
= new PairList<SkinPropertyKey, PdtExpression>();
|
||||
|
||||
public bool IsDynamic {
|
||||
get;
|
||||
@@ -98,18 +102,38 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
|
||||
public class EffectDefinition {
|
||||
public PdtExpression duration;
|
||||
static Identifier _ident_init = new Identifier("init");
|
||||
#pragma warning disable IDE1006
|
||||
public PdtExpression duration {
|
||||
set {
|
||||
EffectState s;
|
||||
if (!states.TryGetValue(_ident_init, out s))
|
||||
throw new InvalidOperationException("Cannot set duration and states at the same time");
|
||||
s.duration = value;
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
public Identifier init = _ident_init;
|
||||
public Dictionary<Identifier, EffectState> states = new Dictionary<Identifier, EffectState> {
|
||||
{ _ident_init, new EffectState() { rewind = _ident_init } }
|
||||
};
|
||||
public SkinElement elements;
|
||||
}
|
||||
|
||||
public class EffectState {
|
||||
public PdtExpression duration;
|
||||
public Identifier rewind;
|
||||
public Identifier next;
|
||||
}
|
||||
|
||||
public class AnimationSpan {
|
||||
[ElementList]
|
||||
public Dictionary<Clip, AnimationSpan> spans
|
||||
= new Dictionary<Clip, AnimationSpan>();
|
||||
public PairList<Clip, AnimationSpan> spans
|
||||
= new PairList<Clip, AnimationSpan>();
|
||||
|
||||
[PropertyList]
|
||||
public Dictionary<SkinPropertyKey, PdtExpression> properties
|
||||
= new Dictionary<SkinPropertyKey, PdtExpression>();
|
||||
public PairList<SkinPropertyKey, PdtExpression> properties
|
||||
= new PairList<SkinPropertyKey, PdtExpression>();
|
||||
|
||||
public void Optimize(PdtEvaluator etor) {
|
||||
foreach (var p in properties) {
|
||||
|
@@ -1,13 +1,16 @@
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Event;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class SkinContainer {
|
||||
readonly ISkinnableGroup _group;
|
||||
readonly SkinElement _rootElement;
|
||||
readonly DynamicStack[] _stacks = new DynamicStack[2];
|
||||
readonly HashSet<SkinPropertyKey> _once = new HashSet<SkinPropertyKey>();
|
||||
public readonly Dictionary<int, SkinVariable> Variables = new Dictionary<int, SkinVariable>();
|
||||
|
||||
class DynamicStack {
|
||||
public readonly List<DynamicProperty> Properties = new List<DynamicProperty>();
|
||||
public readonly List<DynamicElement> Elements = new List<DynamicElement>();
|
||||
@@ -26,21 +29,26 @@ namespace Cryville.Crtr {
|
||||
public SkinSelectors Selectors { get; set; }
|
||||
public SkinElement Element { get; set; }
|
||||
}
|
||||
public SkinContainer(SkinElement rootElement) {
|
||||
public SkinContainer(ISkinnableGroup group, SkinElement rootElement) {
|
||||
_group = group;
|
||||
_rootElement = rootElement;
|
||||
for (int i = 0; i < _stacks.Length; i++) _stacks[i] = new DynamicStack();
|
||||
_rtimeSrc = new PropSrc.Float(() => _rtime);
|
||||
}
|
||||
public void MatchStatic(ISkinnableGroup group) {
|
||||
public void MatchStatic() {
|
||||
var stack = _stacks[0];
|
||||
stack.Clear();
|
||||
MatchStatic(_rootElement, group, stack, new RuntimeSkinContext(group.SkinContext));
|
||||
MatchStatic(_rootElement, stack, new RuntimeSkinContext(_group.SkinContext));
|
||||
}
|
||||
void MatchStatic(SkinElement rel, ISkinnableGroup group, DynamicStack stack, RuntimeSkinContext ctx) {
|
||||
void MatchStatic(SkinElement rel, DynamicStack stack, RuntimeSkinContext ctx) {
|
||||
var rc = ctx.ReadContext;
|
||||
ChartPlayer.etor.ContextTransform = rc.Transform;
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeInsert(rc.PropSrcs);
|
||||
foreach (var p in rel.properties) {
|
||||
p.Key.ExecuteStatic(group, ctx, p.Value);
|
||||
try {
|
||||
p.Key.ExecuteStatic(_group, ctx, p.Value, Variables);
|
||||
}
|
||||
catch (EvaluationFailureException) { }
|
||||
if (p.Key.IsValueRequired && !p.Value.IsConstant) stack.Properties.Add(
|
||||
new DynamicProperty { Context = ctx, Key = p.Key, Value = p.Value }
|
||||
);
|
||||
@@ -48,13 +56,13 @@ namespace Cryville.Crtr {
|
||||
ChartPlayer.etor.ContextTransform = null;
|
||||
foreach (var e in rel.elements) {
|
||||
try {
|
||||
var nctxs = e.Key.MatchStatic(group, rc);
|
||||
var nctxs = e.Key.MatchStatic(_group, rc);
|
||||
if (nctxs != null) {
|
||||
var roflag = e.Key.annotations.Contains("if");
|
||||
var woflag = e.Key.annotations.Contains("then");
|
||||
foreach (var nctx in nctxs) {
|
||||
var nrctx = new RuntimeSkinContext(nctx, ctx, roflag, woflag);
|
||||
MatchStatic(e.Value, group, stack, nrctx);
|
||||
MatchStatic(e.Value, stack, nrctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,15 +74,19 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
|
||||
}
|
||||
public void MatchDynamic(ISkinnableGroup group, int dl) {
|
||||
public void MatchDynamic(int dl, bool recursive = false) {
|
||||
var stack = _stacks[dl];
|
||||
if (stack.Properties.Count == 0 && stack.Elements.Count == 0) return;
|
||||
var nstack = dl + 1 < _stacks.Length ? _stacks[dl + 1] : null;
|
||||
if (nstack != null) nstack.Clear();
|
||||
Profiler.BeginSample("SkinContainer.MatchDynamic");
|
||||
if (!recursive) ChartPlayer.etor.ContextSkinContainer = this;
|
||||
for (int i = 0; i < stack.Properties.Count; i++) {
|
||||
DynamicProperty p = stack.Properties[i];
|
||||
p.Key.ExecuteDynamic(group, p.Context, p.Value, dl);
|
||||
p.Key.ExecuteDynamic(_group, p.Context, p.Value, Variables, dl);
|
||||
if (p.Key.annotations.Contains("once")) {
|
||||
stack.Properties.RemoveAt(i--);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < stack.Elements.Count; i++) {
|
||||
DynamicElement e = stack.Elements[i];
|
||||
@@ -82,14 +94,14 @@ namespace Cryville.Crtr {
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeInsert(psrcs);
|
||||
SkinContext nctx = null;
|
||||
try {
|
||||
nctx = e.Selectors.MatchDynamic(group, e.Context.ReadContext);
|
||||
nctx = e.Selectors.MatchDynamic(_group, e.Context.ReadContext);
|
||||
}
|
||||
catch (SelectorNotAvailableException) {
|
||||
if (nstack == null) throw;
|
||||
nstack.Elements.Add(e);
|
||||
}
|
||||
if (nctx != null) {
|
||||
MatchDynamic(e.Element, group, dl, nstack, new RuntimeSkinContext(
|
||||
MatchDynamic(e.Element, dl, nstack, new RuntimeSkinContext(
|
||||
nctx, e.Context, e.Selectors.annotations.Contains("if"), e.Selectors.annotations.Contains("then")
|
||||
));
|
||||
if (e.Selectors.annotations.Contains("once")) {
|
||||
@@ -98,20 +110,28 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
|
||||
}
|
||||
if (!recursive) ChartPlayer.etor.ContextSkinContainer = null;
|
||||
Profiler.EndSample();
|
||||
}
|
||||
void MatchDynamic(SkinElement rel, ISkinnableGroup group, int dl, DynamicStack stack, RuntimeSkinContext ctx) {
|
||||
void MatchDynamic(SkinElement rel, int dl, DynamicStack stack, RuntimeSkinContext ctx) {
|
||||
var rc = ctx.ReadContext;
|
||||
ChartPlayer.etor.ContextTransform = rc.Transform;
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeInsert(rc.PropSrcs);
|
||||
foreach (var p in rel.properties) {
|
||||
p.Key.ExecuteDynamic(group, ctx, p.Value, dl);
|
||||
if (p.Key.annotations.Contains("once")) {
|
||||
if (_once.Contains(p.Key)) continue;
|
||||
p.Key.ExecuteDynamic(_group, ctx, p.Value, Variables, dl);
|
||||
_once.Add(p.Key);
|
||||
}
|
||||
else {
|
||||
p.Key.ExecuteDynamic(_group, ctx, p.Value, Variables, dl);
|
||||
}
|
||||
}
|
||||
ChartPlayer.etor.ContextTransform = null;
|
||||
foreach (var e in rel.elements) {
|
||||
if (e.Key.IsUpdatable(group, dl)) {
|
||||
SkinContext nctx = e.Key.MatchDynamic(group, rc);
|
||||
if (nctx != null) MatchDynamic(e.Value, group, dl, stack, new RuntimeSkinContext(
|
||||
if (e.Key.IsUpdatable(_group, dl)) {
|
||||
SkinContext nctx = e.Key.MatchDynamic(_group, rc);
|
||||
if (nctx != null) MatchDynamic(e.Value, dl, stack, new RuntimeSkinContext(
|
||||
nctx, ctx, e.Key.annotations.Contains("if"), e.Key.annotations.Contains("then")
|
||||
));
|
||||
}
|
||||
@@ -124,6 +144,26 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
|
||||
}
|
||||
float _rtime;
|
||||
readonly PropSrc _rtimeSrc;
|
||||
public void MatchAnimation(AnimationSpan span, float rtime, RuntimeSkinContext ctx) {
|
||||
ChartPlayer.etor.ContextSkinContainer = this;
|
||||
ChartPlayer.etor.ContextSelfValue = _rtimeSrc;
|
||||
MatchAnimationInternal(span, rtime, ctx);
|
||||
ChartPlayer.etor.ContextSelfValue = null;
|
||||
ChartPlayer.etor.ContextSkinContainer = null;
|
||||
}
|
||||
void MatchAnimationInternal(AnimationSpan span, float rtime, RuntimeSkinContext ctx) {
|
||||
_rtime = rtime;
|
||||
_rtimeSrc.Invalidate();
|
||||
foreach (var p in span.properties) {
|
||||
p.Key.ExecuteDynamic(_group, ctx, p.Value, Variables, 0);
|
||||
}
|
||||
foreach (var s in span.spans) {
|
||||
if (rtime < s.Key.Behind || rtime >= s.Key.Ahead) continue;
|
||||
MatchAnimationInternal(s.Value, (rtime - s.Key.Behind) / (s.Key.Ahead - s.Key.Behind), ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
public class SkinContext {
|
||||
public Transform Transform { get; private set; }
|
||||
@@ -162,9 +202,22 @@ namespace Cryville.Crtr {
|
||||
public interface ISkinnableGroup {
|
||||
string TypeName { get; }
|
||||
SkinContext SkinContext { get; }
|
||||
Anchor OpenedAnchor { get; }
|
||||
int OpenedAnchorName { get; }
|
||||
bool TryGetAnchorsByName(int name, out IReadOnlyCollection<Anchor> result);
|
||||
void RegisterAnchor(int name);
|
||||
void PushAnchorEvent(double time, int name);
|
||||
}
|
||||
public class SkinVariable {
|
||||
float _value;
|
||||
public PropOp Op { get; private set; }
|
||||
public PropSrc Src { get; private set; }
|
||||
public SkinVariable() {
|
||||
Op = new PropOp.Float(Set);
|
||||
Src = new PropSrc.Float(() => _value);
|
||||
}
|
||||
void Set(float value) {
|
||||
_value = value;
|
||||
Src.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,4 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Components;
|
||||
using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
@@ -58,41 +56,7 @@ namespace Cryville.Crtr {
|
||||
case ';':
|
||||
case ':':
|
||||
if (invalidKeyFlag) throw new FormatException("Invalid key format");
|
||||
if (a.Contains("has")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid anchor name");
|
||||
return new SkinPropertyKey.CreateAnchor {
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
}
|
||||
else if (a.Contains("at")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid anchor name");
|
||||
return new SkinPropertyKey.SetAnchor {
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
}
|
||||
else if (a.Contains("emit")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid effect name");
|
||||
return new SkinPropertyKey.EmitEffect {
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
}
|
||||
switch (k.Count) {
|
||||
case 1:
|
||||
if (compKeyFlag) return new SkinPropertyKey.CreateComponent {
|
||||
Component = GetComponentByName(k[0])
|
||||
};
|
||||
else return new SkinPropertyKey.SetProperty {
|
||||
Component = typeof(TransformInterface),
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
case 2:
|
||||
return new SkinPropertyKey.SetProperty {
|
||||
Component = GetComponentByName(k[0]),
|
||||
Name = IdentifierManager.SharedInstance.Request(k[1])
|
||||
};
|
||||
default:
|
||||
throw new FormatException("Unknown error"); // Unreachable
|
||||
}
|
||||
return SkinPropertyKey.Construct(a, k, compKeyFlag);
|
||||
case '{':
|
||||
return new SkinSelectors(s, a);
|
||||
case '}':
|
||||
@@ -127,7 +91,7 @@ namespace Cryville.Crtr {
|
||||
if (cc != '{') throw new FormatException("Invalid span format");
|
||||
return new Clip(start, end);
|
||||
}
|
||||
k.Clear();
|
||||
a.Clear(); k.Clear();
|
||||
while (true) {
|
||||
int pp = Position;
|
||||
switch (cc) {
|
||||
@@ -139,20 +103,7 @@ namespace Cryville.Crtr {
|
||||
break;
|
||||
case ';':
|
||||
case ':':
|
||||
switch (k.Count) {
|
||||
case 1:
|
||||
return new SkinPropertyKey.SetProperty {
|
||||
Component = typeof(TransformInterface),
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
case 2:
|
||||
return new SkinPropertyKey.SetProperty {
|
||||
Component = GetComponentByName(k[0]),
|
||||
Name = IdentifierManager.SharedInstance.Request(k[1])
|
||||
};
|
||||
default:
|
||||
throw new FormatException("Unknown error"); // Unreachable
|
||||
}
|
||||
return SkinPropertyKey.Construct(a, k, false);
|
||||
case '{':
|
||||
throw new FormatException("Invalid token");
|
||||
case '}':
|
||||
@@ -167,10 +118,5 @@ namespace Cryville.Crtr {
|
||||
if (Position == pp) throw new FormatException("Invalid selector or key format");
|
||||
}
|
||||
}
|
||||
static Type GetComponentByName(string name) {
|
||||
Type result;
|
||||
if (GenericResources.Components.TryGetValue(name, out result)) return result;
|
||||
throw new ArgumentException(string.Format("Component type \"{0}\" not found", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,38 +2,87 @@
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Components;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public abstract class SkinPropertyKey {
|
||||
public static SkinPropertyKey Construct(HashSet<string> a, IReadOnlyList<string> k, bool compKeyFlag) {
|
||||
if (a.Remove("has")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid anchor name");
|
||||
return new CreateAnchor(a, IdentifierManager.SharedInstance.Request(k[0]));
|
||||
}
|
||||
else if (a.Remove("at")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid anchor name");
|
||||
return new SetAnchor(a, IdentifierManager.SharedInstance.Request(k[0]));
|
||||
}
|
||||
else if (a.Remove("emit")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid effect name");
|
||||
return new EmitEffect(a, IdentifierManager.SharedInstance.Request(k[0]));
|
||||
}
|
||||
else if (a.Remove("emit_self")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid effect name");
|
||||
return new EmitEffect(a, IdentifierManager.SharedInstance.Request(k[0]), true);
|
||||
}
|
||||
else if (a.Remove("var")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid variable name");
|
||||
return new SetVariable(a, IdentifierManager.SharedInstance.Request(k[0]));
|
||||
}
|
||||
switch (k.Count) {
|
||||
case 1:
|
||||
if (compKeyFlag) return new CreateComponent(a, GetComponentByName(k[0]));
|
||||
else return new SetProperty(a, typeof(TransformInterface), IdentifierManager.SharedInstance.Request(k[0]));
|
||||
case 2:
|
||||
return new SetProperty(a, GetComponentByName(k[0]), IdentifierManager.SharedInstance.Request(k[1]));
|
||||
default:
|
||||
throw new FormatException("Unknown error");
|
||||
}
|
||||
static Type GetComponentByName(string name) {
|
||||
Type result;
|
||||
if (GenericResources.Components.TryGetValue(name, out result)) return result;
|
||||
throw new ArgumentException(string.Format("Component type \"{0}\" not found", name));
|
||||
}
|
||||
}
|
||||
public readonly HashSet<string> annotations;
|
||||
public SkinPropertyKey(IEnumerable<string> a) {
|
||||
annotations = a.ToHashSet();
|
||||
}
|
||||
public abstract override string ToString();
|
||||
public abstract bool IsValueRequired { get; }
|
||||
public abstract void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp);
|
||||
public abstract void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl);
|
||||
public abstract void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars);
|
||||
public abstract void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl);
|
||||
public class CreateComponent : SkinPropertyKey {
|
||||
public Type Component { get; set; }
|
||||
public Type Component { get; private set; }
|
||||
public CreateComponent(IEnumerable<string> a, Type component) : base(a) {
|
||||
Component = component;
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("*{0}", Component.Name);
|
||||
}
|
||||
public override bool IsValueRequired { get { return false; } }
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) {
|
||||
ctx.WriteTransform.gameObject.AddComponent(Component);
|
||||
}
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) {
|
||||
throw new InvalidOperationException("Component creation in dynamic context is not allowed");
|
||||
}
|
||||
}
|
||||
public class SetProperty : SkinPropertyKey {
|
||||
public Type Component { get; set; }
|
||||
public int Name { get; set; }
|
||||
public Type Component { get; private set; }
|
||||
public int Name { get; private set; }
|
||||
public SetProperty(IEnumerable<string> a, Type component, int name) : base(a) {
|
||||
Component = component;
|
||||
Name = name;
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("{0}.{1}", Component.Name, IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
}
|
||||
public override bool IsValueRequired { get { return true; } }
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) {
|
||||
Execute(ctx, GetPropOp(ctx.WriteTransform).Operator, exp);
|
||||
}
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) {
|
||||
var prop = GetPropOp(ctx.WriteTransform);
|
||||
if (dl > prop.UpdateDynamicLevel) return;
|
||||
Execute(ctx, prop.Operator, exp);
|
||||
@@ -61,33 +110,37 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
public class CreateAnchor : SkinPropertyKey {
|
||||
public int Name { get; set; }
|
||||
public int Name { get; private set; }
|
||||
public CreateAnchor(IEnumerable<string> a, int name) : base(a) {
|
||||
Name = name;
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("@has {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
}
|
||||
public override bool IsValueRequired { get { return false; } }
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) {
|
||||
group.RegisterAnchor(Name);
|
||||
}
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) {
|
||||
throw new InvalidOperationException("Anchor creation in dynamic context is not allowed");
|
||||
}
|
||||
}
|
||||
public class SetAnchor : SkinPropertyKey {
|
||||
public int Name { get; set; }
|
||||
public SetAnchor() {
|
||||
public int Name { get; private set; }
|
||||
public SetAnchor(IEnumerable<string> a, int name) : base(a) {
|
||||
Name = name;
|
||||
_timeOp = new PropOp.Float(v => _time = v);
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("@at {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
}
|
||||
public override bool IsValueRequired { get { return true; } }
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) {
|
||||
throw new InvalidOperationException("Setting anchor in static context is not allowed");
|
||||
}
|
||||
float _time;
|
||||
readonly PropOp _timeOp;
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) {
|
||||
if (dl > 0) return;
|
||||
var psrcs = ctx.ReadContext.PropSrcs;
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeInsert(psrcs);
|
||||
@@ -97,22 +150,48 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
public class EmitEffect : SkinPropertyKey {
|
||||
public int Name { get; set; }
|
||||
public EmitEffect() {
|
||||
public int Name { get; private set; }
|
||||
public bool IsSelf { get; private set; }
|
||||
public EmitEffect(IEnumerable<string> a, int name, bool isSelf = false) : base(a) {
|
||||
Name = name;
|
||||
IsSelf = isSelf;
|
||||
_op = new PropOp.Float(v => _index = v);
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("@emit {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
return string.Format(IsSelf ? "@emit_self {0}" : "@emit {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
}
|
||||
public override bool IsValueRequired { get { return true; } }
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) {
|
||||
throw new InvalidOperationException("Emitting effect in static context is not allowed");
|
||||
}
|
||||
float _index;
|
||||
readonly PropOp _op;
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) {
|
||||
ChartPlayer.etor.Evaluate(_op, exp);
|
||||
ChartPlayer.effectManager.Emit(Name, _index);
|
||||
if (IsSelf) ChartPlayer.effectManager.EmitSelf(Name, _index, ctx.WriteTransform);
|
||||
else ChartPlayer.effectManager.Emit(Name, _index);
|
||||
}
|
||||
}
|
||||
public class SetVariable : SkinPropertyKey {
|
||||
public int Name { get; private set; }
|
||||
public SetVariable(IEnumerable<string> a, int name) : base(a) {
|
||||
Name = name;
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("@var {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
}
|
||||
public override bool IsValueRequired { get { return true; } }
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars) {
|
||||
SkinVariable v;
|
||||
if (!vars.TryGetValue(Name, out v))
|
||||
vars.Add(Name, v = new SkinVariable());
|
||||
ChartPlayer.etor.Evaluate(v.Op, exp);
|
||||
}
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, Dictionary<int, SkinVariable> vars, int dl) {
|
||||
SkinVariable v;
|
||||
if (!vars.TryGetValue(Name, out v))
|
||||
throw new InvalidOperationException(string.Format("Variable \"{0}\" not defined", IdentifierManager.SharedInstance.Retrieve(Name)));
|
||||
ChartPlayer.etor.Evaluate(v.Op, exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -101,7 +101,7 @@ namespace Cryville.Crtr {
|
||||
public override string ToString() { return string.Format("..{0}", IdentifierManager.SharedInstance.Retrieve(Name)); }
|
||||
|
||||
public override SkinContext MatchDynamic(ISkinnableGroup g, SkinContext c) {
|
||||
return g.OpenedAnchor != null && g.OpenedAnchor.Name == Name ? c : null;
|
||||
return g.OpenedAnchorName == Name ? c : null;
|
||||
}
|
||||
public override bool IsUpdatable(ISkinnableGroup g, int dl) {
|
||||
return dl >= 1;
|
||||
|
@@ -16,7 +16,7 @@ namespace Cryville.Crtr {
|
||||
|
||||
public override void Init() {
|
||||
base.Init();
|
||||
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
|
||||
sgos = RootTransform.GetComponentsInChildren<SectionalGameObject>();
|
||||
}
|
||||
SectionalGameObject[] sgos;
|
||||
Vector3 bpos; Quaternion brot;
|
||||
@@ -33,7 +33,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
protected override void StartGraphicalUpdate(ContainerState s) {
|
||||
base.StartGraphicalUpdate(s);
|
||||
if (gogroup) {
|
||||
if (RootTransform) {
|
||||
TransformAwake(s);
|
||||
var p = GetCurrentWorldPoint();
|
||||
foreach (var i in sgos) {
|
||||
@@ -82,7 +82,7 @@ namespace Cryville.Crtr {
|
||||
|
||||
ptime = s.Time;
|
||||
|
||||
if (!gogroup || s.CloneType == 3) return;
|
||||
if (!RootTransform || s.CloneType == 3) return;
|
||||
var p = GetCurrentWorldPoint();
|
||||
foreach (var i in sgos)
|
||||
i.AppendPoint(p, s.QuatDir);
|
||||
|
@@ -15,6 +15,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
[assembly: SuppressMessage("Style", "IDE0016")]
|
||||
[assembly: SuppressMessage("Style", "IDE0029")]
|
||||
[assembly: SuppressMessage("Style", "IDE0031")]
|
||||
[assembly: SuppressMessage("Style", "IDE0270")]
|
||||
[assembly: SuppressMessage("Style", "IDE1005")]
|
||||
|
||||
// Null compound assignment not supported
|
||||
|
@@ -34,23 +34,25 @@ namespace System.Text.Formatting {
|
||||
}
|
||||
// Iteration 1: Split by semicolon
|
||||
int specifierPositiveEnd = IndexOfSectionSeparator(specifier);
|
||||
int specifierNegativeStart = 0, specifierNegativeEnd, specifierZeroStart = 0;
|
||||
int specifierNegativeStart = 0, specifierNegativeEnd, specifierZeroStart = 0, specifierZeroEnd;
|
||||
if (specifierPositiveEnd == -1) {
|
||||
specifierPositiveEnd = specifierNegativeEnd = specifier.Length;
|
||||
specifierPositiveEnd = specifierNegativeEnd = specifierZeroEnd = specifier.Length;
|
||||
}
|
||||
else {
|
||||
specifierNegativeStart = specifierPositiveEnd + 1;
|
||||
specifierNegativeEnd = IndexOfSectionSeparator(specifier, specifierNegativeStart);
|
||||
if (specifierNegativeEnd == -1) {
|
||||
specifierNegativeEnd = specifier.Length;
|
||||
specifierZeroEnd = specifierPositiveEnd;
|
||||
}
|
||||
else {
|
||||
specifierZeroStart = specifierNegativeEnd + 1;
|
||||
specifierZeroEnd = specifier.Length;
|
||||
}
|
||||
}
|
||||
// Special: Handle zero
|
||||
if (IsZero(ref number)) {
|
||||
FormatCustomFormatString(formatter, ref number, null, specifier, specifierZeroStart, specifier.Length, culture);
|
||||
FormatCustomFormatString(formatter, ref number, null, specifier, specifierZeroStart, specifierZeroEnd, culture);
|
||||
return;
|
||||
}
|
||||
// Iteration 2: Divide and round number
|
||||
@@ -58,7 +60,7 @@ namespace System.Text.Formatting {
|
||||
if (number.Sign == 0) ApplyDivisionAndPrecision(ref number, specifier, 0, specifierPositiveEnd);
|
||||
else ApplyDivisionAndPrecision(ref number, specifier, specifierNegativeStart, specifierNegativeEnd);
|
||||
// Iteration 3: Count; Iteration 4: Format
|
||||
if (IsZero(ref number)) FormatCustomFormatString(formatter, ref number, null, specifier, specifierZeroStart, specifier.Length, culture);
|
||||
if (IsZero(ref number)) FormatCustomFormatString(formatter, ref number, null, specifier, specifierZeroStart, specifierZeroEnd, culture);
|
||||
else if (number.Sign == 0) FormatCustomFormatString(formatter, ref number, originalScale, specifier, 0, specifierPositiveEnd, culture);
|
||||
else {
|
||||
if (specifierNegativeStart == 0) formatter.Append(culture.NegativeSign);
|
||||
|
@@ -400,7 +400,7 @@ namespace System.Text.Formatting {
|
||||
var segmentsLeft = false;
|
||||
var prevArgIndex = 0;
|
||||
do {
|
||||
CheckCapacity((int)(end - curr));
|
||||
CheckCapacity((int)(end - curr) + 1);
|
||||
fixed (char* bufferPtr = &buffer[currentCount])
|
||||
segmentsLeft = AppendSegment(ref curr, end, bufferPtr, ref prevArgIndex, ref args);
|
||||
}
|
||||
|
8
Assets/Resources/Shaders.meta
Normal file
8
Assets/Resources/Shaders.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9bd2dd8289f72d5479fc93154ddaf762
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
74
Assets/Resources/Shaders/Sprites-Additive.shader
Normal file
74
Assets/Resources/Shaders/Sprites-Additive.shader
Normal file
@@ -0,0 +1,74 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Sprites/Additive"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
|
||||
_Color("Tint", Color) = (1,1,1,1)
|
||||
[MaterialToggle] PixelSnap("Pixel snap", Float) = 0
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Tags
|
||||
{
|
||||
"Queue" = "Transparent"
|
||||
"IgnoreProjector" = "True"
|
||||
"RenderType" = "Transparent"
|
||||
"PreviewType" = "Plane"
|
||||
"CanUseSpriteAtlas" = "True"
|
||||
}
|
||||
|
||||
Cull Off
|
||||
Lighting Off
|
||||
ZWrite Off
|
||||
Fog { Mode Off }
|
||||
Blend SrcAlpha One
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma multi_compile DUMMY PIXELSNAP_ON
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata_t {
|
||||
float4 vertex : POSITION;
|
||||
float4 color : COLOR;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f {
|
||||
float4 vertex : SV_POSITION;
|
||||
fixed4 color : COLOR;
|
||||
half2 texcoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
fixed4 _Color;
|
||||
|
||||
v2f vert(appdata_t IN) {
|
||||
v2f OUT;
|
||||
OUT.vertex = UnityObjectToClipPos(IN.vertex);
|
||||
OUT.texcoord = IN.texcoord;
|
||||
OUT.color = IN.color * _Color;
|
||||
#ifdef PIXELSNAP_ON
|
||||
OUT.vertex = UnityPixelSnap(OUT.vertex);
|
||||
#endif
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
fixed4 frag(v2f IN) : SV_Target
|
||||
{
|
||||
fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
|
||||
c.rgb *= c.a;
|
||||
return c;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
10
Assets/Resources/Shaders/Sprites-Additive.shader.meta
Normal file
10
Assets/Resources/Shaders/Sprites-Additive.shader.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 566d6ad96aab9ea4599b9595dc35f01d
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -22,14 +22,14 @@ body {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tgbtn-active {
|
||||
background-color: lightblue;
|
||||
}
|
||||
|
||||
.tgbtn:hover {
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.tgbtn-active, .tgbtn-active:hover {
|
||||
background-color: lightblue;
|
||||
}
|
||||
|
||||
#toolbar .tgbtn {
|
||||
min-width: 64px;
|
||||
height: 100%;
|
||||
@@ -45,29 +45,50 @@ body {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.t-list {
|
||||
.t-list-container {
|
||||
position: absolute;
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
overflow: auto;
|
||||
background-color: floralwhite;
|
||||
box-sizing: border-box;
|
||||
border: solid 1px gray;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.t-list-composed {
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
.t-list {
|
||||
padding: 2px;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.t-li {
|
||||
list-style: none;
|
||||
padding: 0 4px;
|
||||
margin: 1px;
|
||||
cursor: pointer;
|
||||
break-before: avoid;
|
||||
}
|
||||
|
||||
.t-li:hover {
|
||||
background-color: lightblue;
|
||||
}
|
||||
|
||||
.t-li-cat {
|
||||
padding: 0 4px;
|
||||
margin: 1px;
|
||||
border-bottom: solid 1px dimgray;
|
||||
color: dimgray;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.t-li-cat-2 {
|
||||
border-bottom-style: dashed;
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
input {
|
||||
border: none;
|
||||
font-family: sans-serif;
|
||||
@@ -116,17 +137,6 @@ input {
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.btn:only-child {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.btn.t-inline:only-child {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.t-statement > .btn {
|
||||
}
|
||||
|
||||
.t-node:hover > .btn {
|
||||
transition: 0.25s;
|
||||
height: 16px;
|
||||
@@ -140,6 +150,14 @@ input {
|
||||
border: solid 1px green;
|
||||
}
|
||||
|
||||
.btn-add:only-child {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.btn-add.t-inline:only-child {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.mode-hide-add .btn-add {
|
||||
display: none;
|
||||
}
|
||||
@@ -158,15 +176,39 @@ input {
|
||||
|
||||
.t-exp {
|
||||
border-top: solid 1px gray;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.t-exp.t-inline {
|
||||
padding: 2px 4px;
|
||||
margin: 0 2px;
|
||||
padding: 2px 1px;
|
||||
}
|
||||
|
||||
|
||||
.t-exp .t-inline {
|
||||
margin: 0 0 2px 0;
|
||||
}
|
||||
|
||||
.mode-hide-delete .t-exp .t-inline {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mode-hide-delete .t-exp.t-inline {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.t-exp > .t-statement {
|
||||
margin: 0;
|
||||
border-left: solid 1px orangered;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.t-exp:hover {
|
||||
border-top: solid 3px gray;
|
||||
}
|
||||
|
||||
.t-exp > .btn-add:not(:only-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.t-input {
|
||||
display: inline-block;
|
||||
@@ -226,7 +268,8 @@ input {
|
||||
border-left-width: 5px;
|
||||
}
|
||||
|
||||
.mode-sort .t-statement.t-inline {
|
||||
.mode-sort .t-statement.t-inline,
|
||||
.mode-sort .t-exp > .t-statement {
|
||||
border-color: lightgray;
|
||||
}
|
||||
|
||||
@@ -257,22 +300,26 @@ input {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
.t-list {
|
||||
.t-list-container {
|
||||
background-color: darkslategray;
|
||||
}
|
||||
.t-li:hover {
|
||||
background-color: darkblue;
|
||||
}
|
||||
.t-li-cat {
|
||||
border-bottom-color: lightgray;
|
||||
color: lightgray;
|
||||
}
|
||||
input {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
.tgbtn-active {
|
||||
background-color: darkslateblue;
|
||||
}
|
||||
.tgbtn:hover {
|
||||
background-color: gray;
|
||||
}
|
||||
.tgbtn-active, .tgbtn-active:hover {
|
||||
background-color: darkslateblue;
|
||||
}
|
||||
.t-internal {
|
||||
background-color: dimgray;
|
||||
}
|
||||
|
@@ -11,24 +11,26 @@ var cel;
|
||||
var clist;
|
||||
|
||||
var blocklists = {
|
||||
"block.element": ["statement.obj", "statement.select"],
|
||||
"block.filter": ["statement.filter.type", "statement.filter.exp"],
|
||||
"block.object": ["statement.comp", "statement.prop", "statement.filter"],
|
||||
"block.element": ["statement.select", "statement.obj", "statement.comp", "statement.prop"],
|
||||
"block.root": ["statement.select", "statement.define"],
|
||||
"block.select": ["statement.select.type", "statement.select.exp"],
|
||||
"block.select": ["statement.select.type", "statement.select.exp", "statement.select.anchor", "statement.select.atanchor"],
|
||||
"block.exp.op.sep.vec": ["statement.exp.number"],
|
||||
"block.exp.op.sep.arr": ["statement.exp.string"],
|
||||
};
|
||||
|
||||
var ilid = 0;
|
||||
var inputlists = {
|
||||
"input.comp": ["image", "polysec", "rect", "scale3", "text"],
|
||||
"input.comp": ["anim", "image", "polysec", "rect", "scale3", "text"],
|
||||
"input.prop": [
|
||||
"pos", "rot", "scale",
|
||||
"image.fit", "image.frame", "image.opacity",
|
||||
"polysec.body", "polysec.head", "polysec.shape", "polysec.tail", "polysec.transparent",
|
||||
"rect.color",
|
||||
"anim.delay", "anim.direction", "anim.duration", "anim.name", "anim.iteration",
|
||||
"image.fit", "image.frame", "image.frames", "image.index", "image.shader",
|
||||
"mesh.color", "mesh.opacity", "mesh.zindex",
|
||||
"polysec.body", "polysec.head", "polysec.shape", "polysec.tail",
|
||||
"scale3.border",
|
||||
"sprite.bound", "sprite.pivot", "sprite.scale", "sprite.transparent", "sprite.ui", "sprite.zindex",
|
||||
"text.frames", "text.opacity", "text.size", "text.spacing", "text.value",
|
||||
"sec.part", "sec.partial",
|
||||
"sprite.bound", "sprite.pivot", "sprite.scale", "sprite.ui",
|
||||
"text.frames", "text.size", "text.spacing", "text.value",
|
||||
],
|
||||
"input.type": ["chart", "group", "track", "note"],
|
||||
};
|
||||
@@ -36,15 +38,103 @@ var inputlists = {
|
||||
var statementlists = {
|
||||
"statement.comp": ["input.comp"],
|
||||
"statement.define": ["input.ident", "exp"],
|
||||
"statement.filter": ["block.filter", "block.object"],
|
||||
"statement.filter.exp": ["exp"],
|
||||
"statement.filter.type": ["input.type"],
|
||||
"statement.obj": ["block.object"],
|
||||
"statement.exp.cast.vector2number": ["exp.vector"],
|
||||
"statement.exp.const.w": [],
|
||||
"statement.exp.const.h": [],
|
||||
"statement.exp.const.inf": [],
|
||||
"statement.exp.const.null": [],
|
||||
"statement.exp.const.true": [],
|
||||
"statement.exp.const.false": [],
|
||||
"statement.exp.literal.ident": ["input.ident"],
|
||||
"statement.exp.literal.identforced": ["input.ident"],
|
||||
"statement.exp.literal.number": ["input.number"],
|
||||
"statement.exp.literal.string": ["input.string"],
|
||||
"statement.exp.op.add": ["exp.number", "exp.number"],
|
||||
"statement.exp.op.sub": ["exp.number", "exp.number"],
|
||||
"statement.exp.op.mul": ["exp.number", "exp.number"],
|
||||
"statement.exp.op.div": ["exp.number", "exp.number"],
|
||||
"statement.exp.op.mod": ["exp.number", "exp.number"],
|
||||
"statement.exp.op.add1": ["exp.number"],
|
||||
"statement.exp.op.sub1": ["exp.number"],
|
||||
"statement.exp.op.not": ["exp.number"],
|
||||
"statement.exp.op.at": ["exp.number_or_vector", "exp.number"],
|
||||
"statement.exp.op.lt": ["exp.number", "exp.number"],
|
||||
"statement.exp.op.eq": ["exp.number", "exp.number"],
|
||||
"statement.exp.op.gt": ["exp.number", "exp.number"],
|
||||
"statement.exp.op.and": ["exp", "exp"],
|
||||
"statement.exp.op.or": ["exp", "exp"],
|
||||
"statement.exp.op.sep.vec": ["block.exp.op.sep.vec"],
|
||||
"statement.exp.op.sep.arr": ["block.exp.op.sep.arr"],
|
||||
"statement.exp.func.frame_seq": ["exp.string", "exp.number", "exp.number"],
|
||||
"statement.exp.func.int": ["exp.number"],
|
||||
"statement.exp.func.clamp": ["exp.number", "exp.number", "exp.number"],
|
||||
"statement.exp.func.min": ["exp.number", "exp.number"],
|
||||
"statement.exp.func.max": ["exp.number", "exp.number"],
|
||||
"statement.exp.func.abs": ["exp.number"],
|
||||
"statement.exp.func.interval": ["exp.number", "exp.number", "exp.number"],
|
||||
"statement.exp.func.is": ["exp", "exp"],
|
||||
"statement.exp.func.cubic_bezier": ["exp.number", "exp.number", "exp.number", "exp.number", "exp.number"],
|
||||
"statement.exp.func.ease": ["exp.number"],
|
||||
"statement.exp.func.ease_in": ["exp.number"],
|
||||
"statement.exp.func.ease_out": ["exp.number"],
|
||||
"statement.exp.func.ease_in_out": ["exp.number"],
|
||||
"statement.exp.func.attack_timing": ["exp.number", "exp.number"],
|
||||
"statement.exp.func.enter_timing": ["exp.number"],
|
||||
"statement.exp.func.release_timing": ["exp.number", "exp.number"],
|
||||
"statement.exp.func.leave_timing": ["exp.number"],
|
||||
"statement.exp.func.contact_timing": ["exp.number", "exp.number"],
|
||||
"statement.exp.func.screen_edge": ["exp.number"],
|
||||
"statement.exp.func.anim": ["exp.number_or_vector", "exp.number_or_vector", "exp.number"],
|
||||
"statement.exp.number": ["exp.number"],
|
||||
"statement.exp.string": ["exp.string"],
|
||||
"statement.obj": ["block.element"],
|
||||
"statement.prop": ["input.prop", "exp"],
|
||||
"statement.select": ["block.select", "block.element"],
|
||||
"statement.select.exp": ["exp"],
|
||||
"statement.select.anchor": ["input.identanchor"],
|
||||
"statement.select.atanchor": ["input.identanchor"],
|
||||
"statement.select.exp": ["exp.number"],
|
||||
"statement.select.type": ["input.type"],
|
||||
}
|
||||
};
|
||||
|
||||
var explists = {
|
||||
"exp": ["#exp.number", "#exp.vector", "#exp.string", "#exp.array", "#exp.identifier", "#exp.any"],
|
||||
"exp.number_or_vector": ["#exp.number", "#exp.vector", "#exp.any"],
|
||||
"exp.any": [
|
||||
"statement.exp.literal.ident", "statement.exp.literal.identforced",
|
||||
"statement.exp.op.and", "statement.exp.op.or"
|
||||
],
|
||||
"exp.array": [
|
||||
"statement.exp.op.sep.arr",
|
||||
"statement.exp.func.frame_seq",
|
||||
"#exp.any"
|
||||
],
|
||||
"exp.identifier": [
|
||||
"statement.exp.const.null",
|
||||
"#exp.any"
|
||||
],
|
||||
"exp.number": [
|
||||
"statement.exp.literal.number", "statement.exp.cast.vector2number",
|
||||
"-exp.const", "statement.exp.const.w", "statement.exp.const.h", "statement.exp.const.inf", "statement.exp.const.true", "statement.exp.const.false",
|
||||
"-exp.op", "statement.exp.op.add", "statement.exp.op.sub", "statement.exp.op.mul", "statement.exp.op.div", "statement.exp.op.mod",
|
||||
"-", "statement.exp.op.add1", "statement.exp.op.sub1", "statement.exp.op.not",
|
||||
"-", "statement.exp.op.at", "statement.exp.op.lt", "statement.exp.op.eq", "statement.exp.op.gt",
|
||||
"-exp.func", "statement.exp.func.interval", "statement.exp.func.is",
|
||||
"-exp.func.ctx", "statement.exp.func.int", "statement.exp.func.clamp", "statement.exp.func.min", "statement.exp.func.max", "statement.exp.func.abs",
|
||||
"-exp.func.anim", "statement.exp.func.cubic_bezier", "statement.exp.func.ease", "statement.exp.func.ease_in", "statement.exp.func.ease_out", "statement.exp.func.ease_in_out",
|
||||
"-exp.func.judge", "statement.exp.func.attack_timing", "statement.exp.func.enter_timing", "statement.exp.func.release_timing", "statement.exp.func.leave_timing", "statement.exp.func.contact_timing",
|
||||
"#exp.any"
|
||||
],
|
||||
"exp.string": [
|
||||
"statement.exp.literal.string",
|
||||
"#exp.any"
|
||||
],
|
||||
"exp.vector": [
|
||||
"statement.exp.op.sep.vec",
|
||||
"statement.exp.func.screen_edge",
|
||||
"statement.exp.func.anim",
|
||||
"#exp.any"
|
||||
],
|
||||
};
|
||||
|
||||
window.onload = function () {
|
||||
lang = navigator.language.replace("-", "_");
|
||||
@@ -56,12 +146,12 @@ window.onload = function () {
|
||||
app.find("tbr").replaceWith(function () {
|
||||
return msg($(this).text());
|
||||
});
|
||||
addAddButton(tree).on("click", function (event) {
|
||||
addAddButton(tree).on("click", function () {
|
||||
if (clist) clist.remove();
|
||||
});
|
||||
tv.on("mousemove", null, null, onMouseMove);
|
||||
|
||||
$(".tgbtn").on("click", function (event) {
|
||||
$(".tgbtn").on("click", function () {
|
||||
var btn = $(this);
|
||||
btn.toggleClass("tgbtn-active");
|
||||
onToggleButtonClick(btn.attr("id"), btn.hasClass("tgbtn-active"));
|
||||
@@ -95,7 +185,7 @@ function onAddButtonClick(event) {
|
||||
|
||||
function onAddExpButtonClick(event) {
|
||||
cel = el = event.data;
|
||||
generateAddExpList(event);
|
||||
generateAddExpList(event, el.attr("key"));
|
||||
}
|
||||
|
||||
function onAddButtonLiteralClick(event) {
|
||||
@@ -123,14 +213,16 @@ var tblist = {
|
||||
"tb-hide-add": "mode-hide-add",
|
||||
"tb-hide-delete": "mode-hide-delete",
|
||||
"tb-sort": "mode-sort",
|
||||
}
|
||||
};
|
||||
function onToggleButtonClick(id, state) {
|
||||
var cls = tblist[id];
|
||||
if (state) tv.addClass(cls);
|
||||
else tv.removeClass(cls);
|
||||
if (cls == "mode-sort") {
|
||||
var il = tv.find(".t-input");
|
||||
var sl = tv.find(".t-statement").not(".t-inline");
|
||||
var sl = tv.find(".t-statement").not(".t-inline").not(function () {
|
||||
return $(this).parent().is(".t-exp");
|
||||
});
|
||||
if (state) {
|
||||
il.each(function (i) {
|
||||
$(il[i]).children("input").attr("disabled", "");
|
||||
@@ -216,30 +308,49 @@ function generateAddList(event, items) {
|
||||
popup(event, ul);
|
||||
}
|
||||
|
||||
function generateAddExpList(event, items) {
|
||||
function generateAddExpList(event, item) {
|
||||
event.stopPropagation();
|
||||
if (clist) clist.remove();
|
||||
var ul = $("<ul></ul>").addClass("t-list t-exp-list");
|
||||
for (var i in items) {
|
||||
var item = items[i];
|
||||
ul.append($("<li></li>").addClass("t-li").attr("key", item).text(msg("list." + item)).on("click", null, item, onAddItemClick));
|
||||
}
|
||||
(function addExpRecursive(it, depth) {
|
||||
if (depth > 0) {
|
||||
ul.append($("<li></li>").addClass("t-li-cat t-li-cat-" + depth.toString()).text(msg("list.category." + it)));
|
||||
}
|
||||
var items = explists[it];
|
||||
for (var i in items) {
|
||||
var item = items[i];
|
||||
if (item[0] == "#") {
|
||||
if (depth == 0) addExpRecursive(item.substring(1), 1);
|
||||
}
|
||||
else if (item == "-")
|
||||
ul.append($("<li></li>").addClass("t-li-br"));
|
||||
else if (item[0] == "-")
|
||||
ul.append($("<li></li>").addClass("t-li-cat t-li-cat-" + (depth + 1).toString()).text(msg("list.category." + item.substring(1))));
|
||||
else
|
||||
ul.append($("<li></li>").addClass("t-li").attr("key", item).text(msg("list." + item)).on("click", null, item, onAddItemClick));
|
||||
}
|
||||
})(item, 0);
|
||||
popup(event, ul);
|
||||
}
|
||||
|
||||
function popup(event, ul) {
|
||||
clist = ul;
|
||||
app.append(ul);
|
||||
clist = $("<div></div>").addClass("t-list-container").append(ul);
|
||||
app.append(clist);
|
||||
ul.css("column-count", Math.max(1, Math.min(
|
||||
Math.floor(0.6 * window.innerWidth / clist.outerWidth()),
|
||||
Math.ceil((clist.outerHeight() + 256) / window.innerHeight)
|
||||
)));
|
||||
var left = event.pageX;
|
||||
if (left + ul.outerWidth() > window.innerWidth)
|
||||
left = Math.max(0, left - ul.outerWidth());
|
||||
if (left + clist.outerWidth() > window.innerWidth)
|
||||
left = Math.max(0, left - clist.outerWidth());
|
||||
var top = event.pageY;
|
||||
if (top + ul.outerHeight() > window.innerHeight)
|
||||
top = Math.max(0, top - ul.outerHeight());
|
||||
ul.css({
|
||||
if (top + clist.outerHeight() > window.innerHeight)
|
||||
top = Math.max(0, top - clist.outerHeight());
|
||||
clist.css({
|
||||
"left": left,
|
||||
"top": top
|
||||
});
|
||||
clist.addClass("t-list-composed");
|
||||
}
|
||||
|
||||
function generateInputList(el, key) {
|
||||
@@ -349,10 +460,11 @@ function createExp(key) {
|
||||
}
|
||||
|
||||
function createInput(key, target) {
|
||||
var el = $("<input />").attr({
|
||||
"type": "text",
|
||||
"placeholder": msg(key + ".default")
|
||||
});
|
||||
var el = $("<input />").attr("placeholder", msg(key + ".default"));
|
||||
switch (key) {
|
||||
case "input.number": el.attr("type", "number"); break;
|
||||
default: el.attr("type", "text"); break;
|
||||
}
|
||||
var r = $("<span></span>").attr({
|
||||
"key": key,
|
||||
"target": target.index()
|
||||
|
@@ -1,12 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Skin Editor - Cosmo Resona</title>
|
||||
<link type="text/css" rel="stylesheet" href="app.css"/>
|
||||
<script type="text/javascript" src="jquery-3.6.0.min.js"></script>
|
||||
<script type="text/javascript" src="stretchy.min.js"></script>
|
||||
<script type="text/javascript" src="array_util.js"></script>
|
||||
<script type="text/javascript" src="app.js"></script>
|
||||
<script type="text/javascript" src="messages/en_US.js"></script>
|
||||
<script type="text/javascript" src="messages/en_US.js" charset="UTF-8"></script>
|
||||
<script type="text/javascript" src="messages/zh_CN.js" charset="UTF-8"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
@@ -1,71 +1,183 @@
|
||||
messages["en_US"] = {
|
||||
"block.filter": "If {}",
|
||||
"block.select": "Select {}",
|
||||
"input.comp.default": "component",
|
||||
"input.comp.image": "image sprite",
|
||||
"input.comp.polysec": "polygon sectional mesh",
|
||||
"input.comp.rect": "colored rectangle",
|
||||
"input.comp.scale3": "scale3 sprite",
|
||||
"input.comp.text": "text",
|
||||
"input.ident.default": "variable",
|
||||
"input.prop.default": "property",
|
||||
"input.prop.image.fit": "image sprite: scale mode",
|
||||
"input.prop.image.frame": "image sprite: image name",
|
||||
"input.prop.image.opacity": "image sprite: opacity",
|
||||
"input.prop.polysec.body": "polygon sectional mesh: body image name",
|
||||
"input.prop.polysec.head": "polygon sectional mesh: head image name",
|
||||
"input.prop.polysec.shape": "polygon sectional mesh: section shape",
|
||||
"input.prop.polysec.tail": "polygon sectional mesh: tail image name",
|
||||
"input.prop.polysec.transparent": "polygon sectional mesh: transparent mode",
|
||||
"input.prop.pos": "position",
|
||||
"input.prop.rect.color": "colored rectangle: color",
|
||||
"input.prop.rot": "rotation",
|
||||
"input.prop.scale": "scale",
|
||||
"input.prop.scale3.border": "scale3 sprite: unstretched area ratios",
|
||||
"input.prop.sprite.bound": "sprite: secondary anchor position",
|
||||
"input.prop.sprite.pivot": "sprite: anchor",
|
||||
"input.prop.sprite.scale": "sprite: scale",
|
||||
"input.prop.sprite.transparent": "sprite: transparent mode",
|
||||
"input.prop.sprite.ui": "sprite: ui mode",
|
||||
"input.prop.sprite.zindex": "sprite: layer order",
|
||||
"input.prop.text.frames": "text: image mapping",
|
||||
"input.prop.text.opacity": "text: opacity",
|
||||
"input.prop.text.size": "text: font size",
|
||||
"input.prop.text.spacing": "text: character spacing",
|
||||
"input.prop.text.value": "text: content",
|
||||
"input.type.chart": "chart",
|
||||
"input.type.default": "element",
|
||||
"input.type.group": "track group",
|
||||
"input.type.note": "note",
|
||||
"input.type.track": "track",
|
||||
"list.statement.comp": "Attach a component",
|
||||
"list.statement.define": "Define a variable",
|
||||
"list.statement.filter": "Filter element",
|
||||
"list.statement.filter.exp": "Filter expression",
|
||||
"list.statement.filter.type": "Filter element type",
|
||||
"list.statement.obj": "Create a container",
|
||||
"list.statement.prop": "Set property",
|
||||
"list.statement.select": "Select elements",
|
||||
"list.statement.select.exp": "Filter expression",
|
||||
"list.statement.select.type": "Filter element type",
|
||||
"literal.block.filter": "If {statement.filter.exp} {statement.filter.type}",
|
||||
"literal.block.select": "For each {statement.select.type?element} {statement.select.exp}",
|
||||
"literal.statement.filter.exp": "{0}",
|
||||
"literal.statement.filter.type": "it is a {0}",
|
||||
"literal.statement.select.exp": "that {0}",
|
||||
"literal.statement.select.type": "{0}",
|
||||
"statement.comp": "with a {0}",
|
||||
"statement.define": "Define {0} = {1}",
|
||||
"statement.filter": "{0} {1}",
|
||||
"statement.filter.exp": "it matches the expression {0}",
|
||||
"statement.filter.type": "it is a {0}",
|
||||
"statement.obj": "Create a container {0}",
|
||||
"statement.prop": "Set its {0} to {1}",
|
||||
"statement.select": "{0} {1}",
|
||||
"statement.select.exp": "it matches the expression {0}",
|
||||
"statement.select.type": "{0}",
|
||||
"tool.debug": "Debug",
|
||||
"tool.hideadd": "Hide Add",
|
||||
"tool.hidedelete": "Hide Delete",
|
||||
"tool.sort": "Sort",
|
||||
};
|
||||
"input.comp.anim": "animation",
|
||||
"input.comp.default": "component",
|
||||
"input.comp.image": "image sprite",
|
||||
"input.comp.polysec": "polygon sectional mesh",
|
||||
"input.comp.rect": "colored rectangle sprite",
|
||||
"input.comp.scale3": "scale3 image sprite",
|
||||
"input.comp.text": "text sprite",
|
||||
"input.ident.default": "variable",
|
||||
"input.identanchor.default": "anchor",
|
||||
"input.number.default": "123",
|
||||
"input.prop.anim.delay": "animation: start delay",
|
||||
"input.prop.anim.direction": "animation: playback direction",
|
||||
"input.prop.anim.duration": "animation: duration",
|
||||
"input.prop.anim.name": "animation: name",
|
||||
"input.prop.anim.iteration": "animation: iteration count",
|
||||
"input.prop.default": "property",
|
||||
"input.prop.image.fit": "image sprite: scale mode",
|
||||
"input.prop.image.frame": "image sprite: frame name",
|
||||
"input.prop.image.frames": "image sprite: list of frame names",
|
||||
"input.prop.image.index": "image sprite: frame index",
|
||||
"input.prop.image.shader": "image sprite: shader",
|
||||
"input.prop.mesh.color": "mesh: color",
|
||||
"input.prop.mesh.opacity": "mesh: opacity",
|
||||
"input.prop.mesh.zindex": "mesh: layer order",
|
||||
"input.prop.polysec.body": "polygon sectional mesh: body frame name",
|
||||
"input.prop.polysec.head": "polygon sectional mesh: head frame name",
|
||||
"input.prop.polysec.shape": "polygon sectional mesh: section shape",
|
||||
"input.prop.polysec.tail": "polygon sectional mesh: tail frame name",
|
||||
"input.prop.pos": "position",
|
||||
"input.prop.rot": "rotation",
|
||||
"input.prop.scale": "scale",
|
||||
"input.prop.scale3.border": "scale3 image sprite: unstretched area ratios",
|
||||
"input.prop.sec.part": "sectional mesh: current part",
|
||||
"input.prop.sec.partial": "sectional mesh: partial mode",
|
||||
"input.prop.sprite.bound": "sprite: secondary anchor position",
|
||||
"input.prop.sprite.pivot": "sprite: anchor",
|
||||
"input.prop.sprite.scale": "sprite: scale",
|
||||
"input.prop.sprite.ui": "sprite: ui mode",
|
||||
"input.prop.text.frames": "text sprite: frame mapping",
|
||||
"input.prop.text.size": "text sprite: font size",
|
||||
"input.prop.text.spacing": "text sprite: character spacing",
|
||||
"input.prop.text.value": "text sprite: content",
|
||||
"input.string.default": "string",
|
||||
"input.type.chart": "chart",
|
||||
"input.type.default": "element",
|
||||
"input.type.group": "track group",
|
||||
"input.type.note": "note",
|
||||
"input.type.track": "track",
|
||||
"list.category.exp.any": "Any",
|
||||
"list.category.exp.array": "Array",
|
||||
"list.category.exp.const": "Constants",
|
||||
"list.category.exp.func": "Functions",
|
||||
"list.category.exp.func.anim": "Animation Functions",
|
||||
"list.category.exp.func.ctx": "Contextual Functions",
|
||||
"list.category.exp.func.judge": "Judge Functions",
|
||||
"list.category.exp.identifier": "Identifier",
|
||||
"list.category.exp.number": "Number",
|
||||
"list.category.exp.op": "Operators",
|
||||
"list.category.exp.string": "String",
|
||||
"list.category.exp.vector": "Vector",
|
||||
"list.statement.comp": "Attach component",
|
||||
"list.statement.define": "Define static variable",
|
||||
"list.statement.exp.cast.vector2number": "From vector",
|
||||
"list.statement.exp.const.false": "False",
|
||||
"list.statement.exp.const.h": "Screen height",
|
||||
"list.statement.exp.const.inf": "Infinity",
|
||||
"list.statement.exp.const.null": "Null",
|
||||
"list.statement.exp.const.true": "True",
|
||||
"list.statement.exp.const.w": "Screen width",
|
||||
"list.statement.exp.func.abs": "Absolute value",
|
||||
"list.statement.exp.func.anim": "Animate value",
|
||||
"list.statement.exp.func.attack_timing": "Attack in timing",
|
||||
"list.statement.exp.func.clamp": "Clamp",
|
||||
"list.statement.exp.func.contact_timing": "Contact timing",
|
||||
"list.statement.exp.func.cubic_bezier": "Cubic Bézier curve",
|
||||
"list.statement.exp.func.ease": "Ease",
|
||||
"list.statement.exp.func.ease_in": "Ease in",
|
||||
"list.statement.exp.func.ease_in_out": "Ease in out",
|
||||
"list.statement.exp.func.ease_out": "Ease out",
|
||||
"list.statement.exp.func.enter_timing": "Enter timing",
|
||||
"list.statement.exp.func.frame_seq": "Frame sequence",
|
||||
"list.statement.exp.func.int": "Round down",
|
||||
"list.statement.exp.func.interval": "Interval",
|
||||
"list.statement.exp.func.is": "Is equivalent",
|
||||
"list.statement.exp.func.leave_timing": "Leave timing",
|
||||
"list.statement.exp.func.max": "Maximum",
|
||||
"list.statement.exp.func.min": "Minimum",
|
||||
"list.statement.exp.func.release_timing": "Release in timing",
|
||||
"list.statement.exp.func.screen_edge": "Screen edge",
|
||||
"list.statement.exp.literal.ident": "Variable",
|
||||
"list.statement.exp.literal.identforced": "Variable (forced)",
|
||||
"list.statement.exp.literal.number": "Number",
|
||||
"list.statement.exp.literal.string": "String",
|
||||
"list.statement.exp.number": "Add element",
|
||||
"list.statement.exp.string": "Add element",
|
||||
"list.statement.exp.op.add": "a + b",
|
||||
"list.statement.exp.op.add1": "+n",
|
||||
"list.statement.exp.op.and": "p and q",
|
||||
"list.statement.exp.op.at": "n-th element",
|
||||
"list.statement.exp.op.div": "a ÷ b",
|
||||
"list.statement.exp.op.eq": "a = b",
|
||||
"list.statement.exp.op.gt": "a > b",
|
||||
"list.statement.exp.op.lt": "a < b",
|
||||
"list.statement.exp.op.mod": "a % b",
|
||||
"list.statement.exp.op.mul": "a × b",
|
||||
"list.statement.exp.op.not": "Not",
|
||||
"list.statement.exp.op.or": "p or q",
|
||||
"list.statement.exp.op.sep.arr": "Array",
|
||||
"list.statement.exp.op.sep.vec": "Vector",
|
||||
"list.statement.exp.op.sub": "a - b",
|
||||
"list.statement.exp.op.sub1": "-n",
|
||||
"list.statement.obj": "Create container",
|
||||
"list.statement.prop": "Set property",
|
||||
"list.statement.select": "Select elements",
|
||||
"list.statement.select.anchor": "Select anchor",
|
||||
"list.statement.select.atanchor": "Select at anchor",
|
||||
"list.statement.select.exp": "Filter expression",
|
||||
"list.statement.select.type": "Filter element type",
|
||||
"statement.comp": "with a {0}",
|
||||
"statement.define": "Define static {0} = {1}",
|
||||
"statement.exp.cast.vector2number": "vector {0}",
|
||||
"statement.exp.const.false": "false",
|
||||
"statement.exp.const.h": "screen height",
|
||||
"statement.exp.const.inf": "infinity",
|
||||
"statement.exp.const.null": "null",
|
||||
"statement.exp.const.true": "true",
|
||||
"statement.exp.const.w": "screen width",
|
||||
"statement.exp.func.abs": "absolute value of {0}",
|
||||
"statement.exp.func.anim": "animate value from {0} to {1} with {2}",
|
||||
"statement.exp.func.attack_timing": "attack in timing ({0}, {1})",
|
||||
"statement.exp.func.clamp": "clamp {1} between {0} and {2}",
|
||||
"statement.exp.func.contact_timing": "contact timing ({0}, {1})",
|
||||
"statement.exp.func.cubic_bezier": "cubic Bézier curve defined by the control points ({0}, {1}) and ({2}, {3}) with {4}",
|
||||
"statement.exp.func.ease": "ease with {0}",
|
||||
"statement.exp.func.ease_in": "ease in with {0}",
|
||||
"statement.exp.func.ease_in_out": "ease in out with {0}",
|
||||
"statement.exp.func.ease_out": "ease out with {0}",
|
||||
"statement.exp.func.enter_timing": "enter timing ({0}, +∞)",
|
||||
"statement.exp.func.frame_seq": "frame sequence with prefix {0} from {1} to {2}",
|
||||
"statement.exp.func.int": "round down {0}",
|
||||
"statement.exp.func.interval": "interval between {0} and {1}",
|
||||
"statement.exp.func.is": "{0} is equivalent to {1}",
|
||||
"statement.exp.func.leave_timing": "leave timing (-∞, {0})",
|
||||
"statement.exp.func.max": "maximum of {0} and {1}",
|
||||
"statement.exp.func.min": "minimum of {0} and {1}",
|
||||
"statement.exp.func.release_timing": "release in timing ({0}, {1})",
|
||||
"statement.exp.func.screen_edge": "the screen edge #{0}",
|
||||
"statement.exp.literal.ident": "{0}",
|
||||
"statement.exp.literal.identforced": "{0} (forced)",
|
||||
"statement.exp.literal.number": "{0}",
|
||||
"statement.exp.literal.string": "{0}",
|
||||
"statement.exp.number": "{0}",
|
||||
"statement.exp.number_or_vector": "{0}",
|
||||
"statement.exp.string": "{0}",
|
||||
"statement.exp.op.add": "{0} + {1}",
|
||||
"statement.exp.op.add1": "+{0}",
|
||||
"statement.exp.op.and": "{0} and {1}",
|
||||
"statement.exp.op.at": "the {1}th item of {0}",
|
||||
"statement.exp.op.div": "{0} ÷ {1}",
|
||||
"statement.exp.op.eq": "{0} = {1}",
|
||||
"statement.exp.op.gt": "{0} > {1}",
|
||||
"statement.exp.op.lt": "{0} < {1}",
|
||||
"statement.exp.op.mod": "{0} % {1}",
|
||||
"statement.exp.op.mul": "{0} × {1}",
|
||||
"statement.exp.op.not": "not {0}",
|
||||
"statement.exp.op.or": "{0} or {1}",
|
||||
"statement.exp.op.sep.arr": "Array {0}",
|
||||
"statement.exp.op.sep.vec": "Vector {0}",
|
||||
"statement.exp.op.sub": "{0} - {1}",
|
||||
"statement.exp.op.sub1": "-{0}",
|
||||
"statement.obj": "Create a container {0}",
|
||||
"statement.prop": "Set its {0} to {1}",
|
||||
"statement.select": "Select {0} {1}",
|
||||
"statement.select.anchor": "Select its anchor {0}",
|
||||
"statement.select.atanchor": "Select at its anchor {0}",
|
||||
"statement.select.exp": "If it matches the expression {0}",
|
||||
"statement.select.type": "If it is a {0}",
|
||||
"tool.debug": "Debug",
|
||||
"tool.hideadd": "Hide Add",
|
||||
"tool.hidedelete": "Hide Delete",
|
||||
"tool.sort": "Sort",
|
||||
};
|
@@ -1,71 +1,183 @@
|
||||
messages["zh_CN"] = {
|
||||
"block.filter": "如果 {}",
|
||||
"block.select": "选择 {}",
|
||||
"input.comp.anim": "动画",
|
||||
"input.comp.default": "组件",
|
||||
"input.comp.image": "图片",
|
||||
"input.comp.image": "图片图形",
|
||||
"input.comp.polysec": "多边形截面网格",
|
||||
"input.comp.rect": "纯色矩形",
|
||||
"input.comp.scale3": "三段拉伸图片",
|
||||
"input.comp.text": "文字",
|
||||
"input.comp.rect": "纯色矩形图形",
|
||||
"input.comp.scale3": "三段拉伸图片图形",
|
||||
"input.comp.text": "文字图形",
|
||||
"input.ident.default": "变量",
|
||||
"input.identanchor.default": "锚点",
|
||||
"input.number.default": "123",
|
||||
"input.prop.anim.delay": "动画:起始延迟",
|
||||
"input.prop.anim.direction": "动画:播放方向",
|
||||
"input.prop.anim.duration": "动画:时长",
|
||||
"input.prop.anim.name": "动画:名称",
|
||||
"input.prop.anim.iteration": "动画:重复次数",
|
||||
"input.prop.default": "属性",
|
||||
"input.prop.image.fit": "图片:缩放模式",
|
||||
"input.prop.image.frame": "图片:图片名",
|
||||
"input.prop.image.opacity": "图片:不透明度",
|
||||
"input.prop.image.fit": "图片图形:缩放模式",
|
||||
"input.prop.image.frame": "图片图形:帧名称",
|
||||
"input.prop.image.frames": "图片图形:帧名称列表",
|
||||
"input.prop.image.index": "图片图形:帧索引",
|
||||
"input.prop.image.shader": "图片图形:着色器",
|
||||
"input.prop.mesh.color": "网格:颜色",
|
||||
"input.prop.mesh.opacity": "网格:不透明度",
|
||||
"input.prop.mesh.zindex": "网格:叠加次序",
|
||||
"input.prop.polysec.body": "多边形截面网格:中部图片名",
|
||||
"input.prop.polysec.head": "多边形截面网格:头部图片名",
|
||||
"input.prop.polysec.shape": "多边形截面网格:截面形状",
|
||||
"input.prop.polysec.tail": "多边形截面网格:尾部图片名",
|
||||
"input.prop.polysec.transparent": "多边形截面网格:透明模式",
|
||||
"input.prop.pos": "位置",
|
||||
"input.prop.rect.color": "纯色矩形:颜色",
|
||||
"input.prop.rot": "旋转",
|
||||
"input.prop.scale": "缩放",
|
||||
"input.prop.scale3.border": "三段拉伸图片:非拉伸区域占比",
|
||||
"input.prop.sprite.bound": "图像:副锚点位置",
|
||||
"input.prop.sprite.pivot": "图像:锚点",
|
||||
"input.prop.sprite.scale": "图像:缩放",
|
||||
"input.prop.sprite.transparent": "图像:透明模式",
|
||||
"input.prop.sprite.ui": "图像:界面模式",
|
||||
"input.prop.sprite.zindex": "图像:叠加次序",
|
||||
"input.prop.text.frames": "文字:图片映射",
|
||||
"input.prop.text.opacity": "文字:不透明度",
|
||||
"input.prop.text.size": "文字:字体大小",
|
||||
"input.prop.text.spacing": "文字:字符间距",
|
||||
"input.prop.text.value": "文字:内容",
|
||||
"input.prop.scale3.border": "三段拉伸图片图形:非拉伸区域占比",
|
||||
"input.prop.sec.part": "截面网格:当前分段",
|
||||
"input.prop.sec.partial": "截面网格:分段模式",
|
||||
"input.prop.sprite.bound": "图形:副锚点位置",
|
||||
"input.prop.sprite.pivot": "图形:锚点",
|
||||
"input.prop.sprite.scale": "图形:缩放",
|
||||
"input.prop.sprite.ui": "图形:界面模式",
|
||||
"input.prop.text.frames": "文字图形:图片映射",
|
||||
"input.prop.text.size": "文字图形:字体大小",
|
||||
"input.prop.text.spacing": "文字图形:字符间距",
|
||||
"input.prop.text.value": "文字图形:内容",
|
||||
"input.string.default": "字符串",
|
||||
"input.type.chart": "谱面",
|
||||
"input.type.default": "元素",
|
||||
"input.type.group": "轨道组",
|
||||
"input.type.note": "按键",
|
||||
"input.type.track": "轨道",
|
||||
"list.category.exp.any": "任意",
|
||||
"list.category.exp.array": "数组",
|
||||
"list.category.exp.const": "常量",
|
||||
"list.category.exp.func": "函数",
|
||||
"list.category.exp.func.anim": "动画函数",
|
||||
"list.category.exp.func.ctx": "环境函数",
|
||||
"list.category.exp.func.judge": "判定函数",
|
||||
"list.category.exp.identifier": "变量",
|
||||
"list.category.exp.number": "数字",
|
||||
"list.category.exp.op": "运算符",
|
||||
"list.category.exp.string": "字符串",
|
||||
"list.category.exp.vector": "向量",
|
||||
"list.statement.comp": "附加组件",
|
||||
"list.statement.define": "定义变量",
|
||||
"list.statement.filter": "条件分歧",
|
||||
"list.statement.filter.exp": "判断表达式",
|
||||
"list.statement.filter.type": "判断元素类型",
|
||||
"list.statement.define": "定义静态变量",
|
||||
"list.statement.exp.cast.vector2number": "从向量",
|
||||
"list.statement.exp.const.false": "假",
|
||||
"list.statement.exp.const.h": "屏幕高度",
|
||||
"list.statement.exp.const.inf": "无穷大",
|
||||
"list.statement.exp.const.null": "空变量",
|
||||
"list.statement.exp.const.true": "真",
|
||||
"list.statement.exp.const.w": "屏幕宽度",
|
||||
"list.statement.exp.func.abs": "绝对值",
|
||||
"list.statement.exp.func.anim": "动画值",
|
||||
"list.statement.exp.func.attack_timing": "在时间区间中按下",
|
||||
"list.statement.exp.func.clamp": "限制值",
|
||||
"list.statement.exp.func.contact_timing": "接触时间区间",
|
||||
"list.statement.exp.func.cubic_bezier": "三次贝塞尔曲线",
|
||||
"list.statement.exp.func.ease": "缓动",
|
||||
"list.statement.exp.func.ease_in": "缓入",
|
||||
"list.statement.exp.func.ease_in_out": "缓入缓出",
|
||||
"list.statement.exp.func.ease_out": "缓出",
|
||||
"list.statement.exp.func.enter_timing": "进入时间区间",
|
||||
"list.statement.exp.func.frame_seq": "帧序列",
|
||||
"list.statement.exp.func.int": "向下取整",
|
||||
"list.statement.exp.func.interval": "区间",
|
||||
"list.statement.exp.func.is": "等价",
|
||||
"list.statement.exp.func.leave_timing": "离开时间区间",
|
||||
"list.statement.exp.func.max": "最大值",
|
||||
"list.statement.exp.func.min": "最小值",
|
||||
"list.statement.exp.func.release_timing": "在时间区间中松开",
|
||||
"list.statement.exp.func.screen_edge": "屏幕边缘",
|
||||
"list.statement.exp.literal.ident": "变量",
|
||||
"list.statement.exp.literal.identforced": "变量(强制)",
|
||||
"list.statement.exp.literal.number": "数字",
|
||||
"list.statement.exp.literal.string": "字符串",
|
||||
"list.statement.exp.number": "添加元素",
|
||||
"list.statement.exp.string": "添加元素",
|
||||
"list.statement.exp.op.add": "a + b",
|
||||
"list.statement.exp.op.add1": "+n",
|
||||
"list.statement.exp.op.and": "p 且 q",
|
||||
"list.statement.exp.op.at": "索引元素",
|
||||
"list.statement.exp.op.div": "a ÷ b",
|
||||
"list.statement.exp.op.eq": "a = b",
|
||||
"list.statement.exp.op.gt": "a > b",
|
||||
"list.statement.exp.op.lt": "a < b",
|
||||
"list.statement.exp.op.mod": "a % b",
|
||||
"list.statement.exp.op.mul": "a × b",
|
||||
"list.statement.exp.op.not": "非",
|
||||
"list.statement.exp.op.or": "p 或 q",
|
||||
"list.statement.exp.op.sep.arr": "数组",
|
||||
"list.statement.exp.op.sep.vec": "向量",
|
||||
"list.statement.exp.op.sub": "a - b",
|
||||
"list.statement.exp.op.sub1": "-n",
|
||||
"list.statement.obj": "创建容器",
|
||||
"list.statement.prop": "设置属性",
|
||||
"list.statement.select": "选择元素",
|
||||
"list.statement.select.anchor": "选择锚点",
|
||||
"list.statement.select.atanchor": "选择位于锚点",
|
||||
"list.statement.select.exp": "筛选表达式",
|
||||
"list.statement.select.type": "筛选元素类型",
|
||||
"literal.block.filter": "如果 {statement.filter.exp} {statement.filter.type}",
|
||||
"literal.block.select": "对于每个 {statement.select.exp} {statement.select.type?元素}",
|
||||
"literal.statement.filter.exp": "{0}",
|
||||
"literal.statement.filter.type": "元素的类型为 {0}",
|
||||
"literal.statement.select.exp": "{0} 的",
|
||||
"literal.statement.select.type": "{0}",
|
||||
"statement.comp": "创建一个 {0} 组件",
|
||||
"statement.define": "定义变量 {0} = {1}",
|
||||
"statement.filter": "{0} {1}",
|
||||
"statement.filter.exp": "元素符合表达式 {0}",
|
||||
"statement.filter.type": "元素的类型为 {0}",
|
||||
"statement.define": "静态定义 {0} = {1}",
|
||||
"statement.exp.cast.vector2number": "向量 {0}",
|
||||
"statement.exp.const.false": "假",
|
||||
"statement.exp.const.h": "屏幕高度",
|
||||
"statement.exp.const.inf": "无穷大",
|
||||
"statement.exp.const.null": "空变量",
|
||||
"statement.exp.const.true": "真",
|
||||
"statement.exp.const.w": "屏幕宽度",
|
||||
"statement.exp.func.abs": "{0} 的绝对值",
|
||||
"statement.exp.func.anim": "动画值从 {0} 到 {1},使用函数 {2}",
|
||||
"statement.exp.func.attack_timing": "在时间区间 ({0}, {1}) 中按下",
|
||||
"statement.exp.func.clamp": "限制 {1} 在 {0} 和 {2} 之间",
|
||||
"statement.exp.func.contact_timing": "接触时间区间 ({0}, {1})",
|
||||
"statement.exp.func.cubic_bezier": "由控制点 ({0}, {1}) 和 ({2}, {3}) 定义的三次贝塞尔曲线,复合 {4}",
|
||||
"statement.exp.func.ease": "缓动,复合 {0}",
|
||||
"statement.exp.func.ease_in": "缓入,复合 {0}",
|
||||
"statement.exp.func.ease_in_out": "缓入缓出,复合 {0}",
|
||||
"statement.exp.func.ease_out": "缓出,复合 {0}",
|
||||
"statement.exp.func.enter_timing": "进入时间区间 ({0}, +∞)",
|
||||
"statement.exp.func.frame_seq": "前缀为 {0} 从 {1} 的 {2} 帧序列",
|
||||
"statement.exp.func.int": "向下取整 {0}",
|
||||
"statement.exp.func.interval": "{0} 和 {1} 之间的区间",
|
||||
"statement.exp.func.is": "{0} 等价于 {1}",
|
||||
"statement.exp.func.leave_timing": "离开时间区间 (-∞, {0})",
|
||||
"statement.exp.func.max": "{0} 和 {1} 的最大值",
|
||||
"statement.exp.func.min": "{0} 和 {1} 的最小值",
|
||||
"statement.exp.func.release_timing": "在时间区间 ({0}, {1}) 中松开",
|
||||
"statement.exp.func.screen_edge": "屏幕边缘 #{0}",
|
||||
"statement.exp.literal.ident": "{0}",
|
||||
"statement.exp.literal.identforced": "{0}(强制)",
|
||||
"statement.exp.literal.number": "{0}",
|
||||
"statement.exp.literal.string": "{0}",
|
||||
"statement.exp.number": "{0}",
|
||||
"statement.exp.number_or_vector": "{0}",
|
||||
"statement.exp.string": "{0}",
|
||||
"statement.exp.op.add": "{0} + {1}",
|
||||
"statement.exp.op.add1": "+{0}",
|
||||
"statement.exp.op.and": "{0} 且 {1}",
|
||||
"statement.exp.op.at": "{0} 的第 {1} 个元素",
|
||||
"statement.exp.op.div": "{0} ÷ {1}",
|
||||
"statement.exp.op.eq": "{0} = {1}",
|
||||
"statement.exp.op.gt": "{0} > {1}",
|
||||
"statement.exp.op.lt": "{0} < {1}",
|
||||
"statement.exp.op.mod": "{0} % {1}",
|
||||
"statement.exp.op.mul": "{0} × {1}",
|
||||
"statement.exp.op.not": "非 {0}",
|
||||
"statement.exp.op.or": "{0} 或 {1}",
|
||||
"statement.exp.op.sep.arr": "数组 {0}",
|
||||
"statement.exp.op.sep.vec": "向量 {0}",
|
||||
"statement.exp.op.sub": "{0} - {1}",
|
||||
"statement.exp.op.sub1": "-{0}",
|
||||
"statement.obj": "创建一个容器 {0}",
|
||||
"statement.prop": "设置属性 {0} 为 {1}",
|
||||
"statement.select": "{0} {1}",
|
||||
"statement.select.exp": "元素符合表达式 {0}",
|
||||
"statement.select.type": "元素的类型为 {0}",
|
||||
"statement.select": "选择 {0} {1}",
|
||||
"statement.select.anchor": "选择其 {0} 锚点",
|
||||
"statement.select.atanchor": "选择位于其 {0} 锚点",
|
||||
"statement.select.exp": "如果元素符合表达式 {0}",
|
||||
"statement.select.type": "如果元素的类型为 {0}",
|
||||
"tool.debug": "调试",
|
||||
"tool.hideadd": "隐藏添加按钮",
|
||||
"tool.hidedelete": "隐藏删除按钮",
|
||||
"tool.sort": "排序",
|
||||
};
|
||||
};
|
Binary file not shown.
Reference in New Issue
Block a user