Compare commits
85 Commits
0.6.0-rc2
...
d510fec57b
1
.gitignore
vendored
1
.gitignore
vendored
@@ -68,3 +68,4 @@ crashlytics-build.properties
|
|||||||
/UserSettings
|
/UserSettings
|
||||||
/*.zip
|
/*.zip
|
||||||
*.lnk
|
*.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;
|
return tableDirectoryOffsets;
|
||||||
}
|
}
|
||||||
public override TableDirectory GetSubTable(UInt32 item) {
|
public override TableDirectory GetSubTable(UInt32 item) {
|
||||||
var i = (UInt32)item;
|
var i = item;
|
||||||
return new TableDirectory(Reader, i);
|
return new TableDirectory(Reader, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Cryville.Common {
|
namespace Cryville.Common {
|
||||||
public struct Identifier : IEquatable<Identifier> {
|
public struct Identifier : IEquatable<Identifier> {
|
||||||
|
public static Identifier Empty = new Identifier(0);
|
||||||
public int Key { get; private set; }
|
public int Key { get; private set; }
|
||||||
public object Name { get { return IdentifierManager.SharedInstance.Retrieve(Key); } }
|
public object Name { get { return IdentifierManager.SharedInstance.Retrieve(Key); } }
|
||||||
public Identifier(int 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="error">The error.</param>
|
||||||
/// <param name="n">The numerator.</param>
|
/// <param name="n">The numerator.</param>
|
||||||
/// <param name="d">The denominator.</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) {
|
public static void ToFraction(double value, double error, out int n, out int d) {
|
||||||
if (value < 0.0)
|
if (value < 0.0)
|
||||||
throw new ArgumentOutOfRangeException("value", "Must be >= 0.");
|
throw new ArgumentOutOfRangeException("value", "Must be >= 0.");
|
||||||
if (error <= 0.0 || error >= 1.0)
|
if (error <= 0.0 || error > 1.0)
|
||||||
throw new ArgumentOutOfRangeException("accuracy", "Must be > 0 and < 1.");
|
throw new ArgumentOutOfRangeException("error", "Must be > 0 and <= 1.");
|
||||||
|
|
||||||
int num = (int)System.Math.Floor(value);
|
int num = (int)System.Math.Floor(value);
|
||||||
value -= num;
|
value -= num;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
/// Indicates that the attributed member is an element list.
|
/// Indicates that the attributed member is an element list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <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>
|
/// </remarks>
|
||||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||||
public class ElementListAttribute : Attribute { }
|
public class ElementListAttribute : Attribute { }
|
||||||
@@ -14,7 +14,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
/// Indicates that the attributed member is a property list.
|
/// Indicates that the attributed member is a property list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <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>
|
/// </remarks>
|
||||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||||
public class PropertyListAttribute : Attribute { }
|
public class PropertyListAttribute : Attribute { }
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public partial class PdtInterpreter {
|
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 },
|
{ '@', 7 },
|
||||||
{ '*', 6 }, { '/', 6 }, { '%', 6 },
|
{ '*', 6 }, { '/', 6 }, { '%', 6 },
|
||||||
{ '+', 5 }, { '-', 5 },
|
{ '+', 5 }, { '-', 5 },
|
||||||
@@ -103,7 +103,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
{ ',', 0 },
|
{ ',', 0 },
|
||||||
{ '$', -1 },
|
{ '$', -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 }, { '/', 0 }, { '%', 0 },
|
||||||
{ '+', 0 }, { '-', 0 },
|
{ '+', 0 }, { '-', 0 },
|
||||||
@@ -115,7 +115,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
{ '$', -1 },
|
{ '$', -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly static PdtExpression _emptyexp;
|
static readonly PdtExpression _emptyexp;
|
||||||
static PdtInterpreter() {
|
static PdtInterpreter() {
|
||||||
var ins = new LinkedList<PdtInstruction>();
|
var ins = new LinkedList<PdtInstruction>();
|
||||||
ins.AddLast(new PdtInstruction.PushConstant(
|
ins.AddLast(new PdtInstruction.PushConstant(
|
||||||
@@ -143,7 +143,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return string.Format("0x{0:x4}: {1}", Type, Value);
|
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,
|
Type = 0x0080,
|
||||||
Value = "$",
|
Value = "$",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,30 +6,30 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Error type.
|
/// Error type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly static int Error = 0x00525245;
|
public const int Error = 0x00525245;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Array of a same variable-length type, with a suffix indicating the element count and the element type.
|
/// Array of a same variable-length type, with a suffix indicating the element count and the element type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly static int Array = 0x00525241;
|
public const int Array = 0x00525241;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Null type.
|
/// Null type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly static int Null = 0x4c4c554e;
|
public const int Null = 0x4c4c554e;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IEEE 754 32-bit floating-point number.
|
/// IEEE 754 32-bit floating-point number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly static int Number = 0x004d554e;
|
public const int Number = 0x004d554e;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A sequence of UTF-16 code units, with a prefix indicating the number of the code units.
|
/// A sequence of UTF-16 code units, with a prefix indicating the number of the code units.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly static int String = 0x00525453;
|
public const int String = 0x00525453;
|
||||||
/// <summary>
|
/// <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.
|
/// 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>
|
/// </summary>
|
||||||
public readonly static int Undefined = 0x00444e55;
|
public const int Undefined = 0x00444e55;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Vector of a same constant-length type, with a suffix indicating the element type.
|
/// Vector of a same constant-length type, with a suffix indicating the element type.
|
||||||
/// </summary>
|
/// </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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -27,7 +28,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
/// <item><term><c>0x1000</c></term><description>End of Key</description></item>
|
/// <item><term><c>0x1000</c></term><description>End of Key</description></item>
|
||||||
/// </list>
|
/// </list>
|
||||||
/// </remarks>
|
/// </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
|
// 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, 0x0001, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000,
|
||||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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));
|
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
||||||
Type ptype = ReflectionHelper.GetMemberType(prop);
|
Type ptype = ReflectionHelper.GetMemberType(prop);
|
||||||
if (flag) {
|
if (flag) {
|
||||||
if (!typeof(IDictionary).IsAssignableFrom(ptype))
|
using (var collection = new PairCollection(ReflectionHelper.GetValue(prop, result))) {
|
||||||
throw new InvalidOperationException("Internal error: Element list is not a dictionary");
|
var ktype = ptype.GetGenericArguments()[0];
|
||||||
var ktype = ptype.GetGenericArguments()[0];
|
var vtype = ptype.GetGenericArguments()[1];
|
||||||
var vtype = ptype.GetGenericArguments()[1];
|
object key = _binder.ChangeType(pkey, ktype, null);
|
||||||
object key = _binder.ChangeType(pkey, ktype, null);
|
object value = InterpretObject(vtype);
|
||||||
object value = InterpretObject(vtype);
|
collection.Add(key, value);
|
||||||
((IDictionary)ReflectionHelper.GetValue(prop, result)).Add(key, value);
|
}
|
||||||
}
|
}
|
||||||
else ReflectionHelper.SetValue(prop, result, InterpretObject(ptype));
|
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));
|
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
||||||
var ptype = ReflectionHelper.GetMemberType(prop);
|
var ptype = ReflectionHelper.GetMemberType(prop);
|
||||||
if (flag) {
|
if (flag) {
|
||||||
if (!typeof(IDictionary).IsAssignableFrom(ptype))
|
using (var collection = new PairCollection(ReflectionHelper.GetValue(prop, result))) {
|
||||||
throw new InvalidOperationException("Internal error: Property list is not a dictionary");
|
var ktype = ptype.GetGenericArguments()[0];
|
||||||
var ktype = ptype.GetGenericArguments()[0];
|
var vtype = ptype.GetGenericArguments()[1];
|
||||||
var vtype = ptype.GetGenericArguments()[1];
|
object key = _binder.ChangeType(pkey, ktype, null);
|
||||||
object key = _binder.ChangeType(pkey, ktype, null);
|
object value = _binder.ChangeType(exp, vtype, null);
|
||||||
object value = _binder.ChangeType(exp, vtype, null);
|
collection.Add(key, value);
|
||||||
((IDictionary)ReflectionHelper.GetValue(prop, result)).Add(key, value);
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
object value = _binder.ChangeType(exp, ptype, null);
|
object value = _binder.ChangeType(exp, ptype, null);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// PDT operator.
|
/// PDT operator.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe abstract class PdtOperator {
|
public abstract unsafe class PdtOperator {
|
||||||
byte* _prmem;
|
byte* _prmem;
|
||||||
int _loadindex;
|
int _loadindex;
|
||||||
readonly PdtVariableMemory[] _operands;
|
readonly PdtVariableMemory[] _operands;
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ using UnityEngine;
|
|||||||
namespace Cryville.Common.Unity.UI {
|
namespace Cryville.Common.Unity.UI {
|
||||||
public abstract class SetParameterBehaviour : StateMachineBehaviour {
|
public abstract class SetParameterBehaviour : StateMachineBehaviour {
|
||||||
[SerializeField] protected string m_name;
|
[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 {
|
public override object Value {
|
||||||
get {
|
get {
|
||||||
float s_value = GetDisplayValue();
|
float s_value = GetDisplayValue();
|
||||||
return IntegerMode ? (object)(int)s_value : (object)s_value;
|
return IntegerMode ? (int)s_value : (object)s_value;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if (value is double) m_value = (double)value;
|
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();
|
float s_value = GetDisplayValue();
|
||||||
m_text.text = s_value.ToString();
|
m_text.text = s_value.ToString();
|
||||||
if (Range != null && MaxStep == 0) {
|
if (Range != null && MaxStep == 0) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.ComponentModel;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using UnsafeIL;
|
||||||
|
|
||||||
namespace Cryville.Crtr {
|
namespace Cryville.Crtr {
|
||||||
[JsonConverter(typeof(BeatTimeConverter))]
|
[JsonConverter(typeof(BeatTimeConverter))]
|
||||||
@@ -154,6 +155,10 @@ namespace Cryville.Crtr {
|
|||||||
protected ChartEvent() {
|
protected ChartEvent() {
|
||||||
PropSrcs = new Dictionary<int, PropSrc>();
|
PropSrcs = new Dictionary<int, PropSrc>();
|
||||||
PropOps = new Dictionary<int, PropOp>();
|
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("long", new PropSrc.Boolean(() => IsLong));
|
||||||
SubmitPropSrc("time", new PropSrc.BeatTime(() => time.Value));
|
SubmitPropSrc("time", new PropSrc.BeatTime(() => time.Value));
|
||||||
SubmitPropSrc("endtime", new PropSrc.BeatTime(() => endtime.Value));
|
SubmitPropSrc("endtime", new PropSrc.BeatTime(() => endtime.Value));
|
||||||
@@ -320,7 +325,7 @@ namespace Cryville.Crtr {
|
|||||||
else {
|
else {
|
||||||
AbsoluteValue = Vector.Construct(registry.Type, m.Groups[11].Value);
|
AbsoluteValue = Vector.Construct(registry.Type, m.Groups[11].Value);
|
||||||
}
|
}
|
||||||
SubmitPropSrc("value", VectorSrc.Construct(() => {
|
SubmitPropSrc("value", new VectorSrc(() => {
|
||||||
if (RelativeNode != null) return RelativeNode.Value;
|
if (RelativeNode != null) return RelativeNode.Value;
|
||||||
else return AbsoluteValue;
|
else return AbsoluteValue;
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Cryville.Crtr {
|
|||||||
#region Fields
|
#region Fields
|
||||||
Chart chart;
|
Chart chart;
|
||||||
Skin skin;
|
Skin skin;
|
||||||
PdtSkin pskin;
|
public static PdtSkin pskin;
|
||||||
Ruleset ruleset;
|
Ruleset ruleset;
|
||||||
PdtRuleset pruleset;
|
PdtRuleset pruleset;
|
||||||
Dictionary<string, Texture2D> texs;
|
Dictionary<string, Texture2D> texs;
|
||||||
@@ -175,16 +175,21 @@ namespace Cryville.Crtr {
|
|||||||
string url = texLoader.url;
|
string url = texLoader.url;
|
||||||
string name = StringUtils.TrimExt(url.Substring(url.LastIndexOfAny(new char[] {'/', '\\'}) + 1));
|
string name = StringUtils.TrimExt(url.Substring(url.LastIndexOfAny(new char[] {'/', '\\'}) + 1));
|
||||||
#if UNITY_5_4_OR_NEWER
|
#if UNITY_5_4_OR_NEWER
|
||||||
if (texHandler.isDone) {
|
if (texLoader.isDone) {
|
||||||
var tex = texHandler.texture;
|
if (texHandler.isDone) {
|
||||||
tex.wrapMode = TextureWrapMode.Clamp;
|
var tex = texHandler.texture;
|
||||||
if (frames.ContainsKey(name)) {
|
tex.wrapMode = TextureWrapMode.Clamp;
|
||||||
Logger.Log("main", 3, "Load/Prehandle", "Duplicated texture name: {0}", name);
|
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 {
|
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();
|
texLoader.Dispose();
|
||||||
texHandler.Dispose();
|
texHandler.Dispose();
|
||||||
texLoader = null;
|
texLoader = null;
|
||||||
@@ -468,6 +473,8 @@ namespace Cryville.Crtr {
|
|||||||
Logger.Log("main", 0, "Load/Prehandle", "Cleaning up");
|
Logger.Log("main", 0, "Load/Prehandle", "Cleaning up");
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
if (disableGC) GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
|
if (disableGC) GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
|
||||||
|
cbus.ForwardByTime(startOffset);
|
||||||
|
bbus.ForwardByTime(startOffset);
|
||||||
timer.Stop();
|
timer.Stop();
|
||||||
Logger.Log("main", 1, "Load/Prehandle", "Prehandling done ({0}ms)", timer.Elapsed.TotalMilliseconds);
|
Logger.Log("main", 1, "Load/Prehandle", "Prehandling done ({0}ms)", timer.Elapsed.TotalMilliseconds);
|
||||||
if (Settings.Default.ClearLogOnPlay) {
|
if (Settings.Default.ClearLogOnPlay) {
|
||||||
@@ -478,7 +485,6 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
Game.AudioSequencer.Playing = true;
|
Game.AudioSequencer.Playing = true;
|
||||||
atime0 = Game.AudioClient.BufferPosition;
|
atime0 = Game.AudioClient.BufferPosition;
|
||||||
Thread.Sleep((int)((atime0 - Game.AudioClient.Position) * 1000));
|
|
||||||
inputProxy.SyncTime(cbus.Time);
|
inputProxy.SyncTime(cbus.Time);
|
||||||
started = true;
|
started = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,15 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Cryville.Crtr.Components {
|
namespace Cryville.Crtr.Components {
|
||||||
|
[DisallowMultipleComponent]
|
||||||
public abstract class MeshBase : SkinComponent {
|
public abstract class MeshBase : SkinComponent {
|
||||||
public MeshBase() {
|
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));
|
SubmitProperty("zindex", new PropOp.Integer(v => ZIndex = (short)v));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,12 +35,32 @@ namespace Cryville.Crtr.Components {
|
|||||||
mat.renderQueue = _zindex;
|
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() {
|
protected override void OnDestroy() {
|
||||||
if (materials != null)
|
DestroyMaterials();
|
||||||
foreach (var mat in materials) {
|
|
||||||
Material.Destroy(mat);
|
|
||||||
}
|
|
||||||
mesh.Destroy();
|
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) {
|
public op_set_shape(PolygonSGO self) : base(1) {
|
||||||
_self = self;
|
_self = self;
|
||||||
}
|
}
|
||||||
protected unsafe override void Execute() {
|
protected override unsafe void Execute() {
|
||||||
var o = GetOperand(0);
|
var o = GetOperand(0);
|
||||||
if (o.Type != PdtInternalType.Vector) throw new ArgumentException("Not a vector");
|
if (o.Type != PdtInternalType.Vector) throw new ArgumentException("Not a vector");
|
||||||
_self._shapeLength = (o.Length - sizeof(int)) / sizeof(Vector2);
|
_self._shapeLength = (o.Length - sizeof(int)) / sizeof(Vector2);
|
||||||
@@ -107,7 +107,7 @@ namespace Cryville.Crtr.Components {
|
|||||||
base.Init();
|
base.Init();
|
||||||
mesh.Init(transform);
|
mesh.Init(transform);
|
||||||
|
|
||||||
mesh.Renderer.materials = materials = new Material[] {
|
mesh.Renderer.sharedMaterials = materials = new Material[] {
|
||||||
MeshWrapper.NewMaterial(),
|
MeshWrapper.NewMaterial(),
|
||||||
MeshWrapper.NewMaterial(),
|
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 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() { }
|
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 Init() { }
|
||||||
|
public virtual void Rewind(double time, Transform target) { }
|
||||||
|
public virtual void Tick(SkinContainer c, double time) { }
|
||||||
protected abstract void OnDestroy();
|
protected abstract void OnDestroy();
|
||||||
}
|
}
|
||||||
public struct SkinProperty {
|
public struct SkinProperty {
|
||||||
|
|||||||
@@ -88,8 +88,9 @@ namespace Cryville.Crtr.Components {
|
|||||||
|
|
||||||
protected void InternalInit(string meshName = "quad") {
|
protected void InternalInit(string meshName = "quad") {
|
||||||
mesh.Init(transform);
|
mesh.Init(transform);
|
||||||
mesh.Renderer.materials = materials = new Material[] { MeshWrapper.NewMaterial() };
|
mesh.Renderer.sharedMaterials = materials = new Material[] { MeshWrapper.NewMaterial() };
|
||||||
mesh.Mesh = GenericResources.Meshes[meshName];
|
mesh.Mesh = GenericResources.Meshes[meshName];
|
||||||
|
UpdateColor();
|
||||||
UpdateScale();
|
UpdateScale();
|
||||||
UpdateZIndex();
|
UpdateZIndex();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace Cryville.Crtr.Components {
|
|||||||
SubmitProperty("frames", new PropOp.StringArray(v => Frames = v));
|
SubmitProperty("frames", new PropOp.StringArray(v => Frames = v));
|
||||||
SubmitProperty("index", new PropOp.Integer(v => Index = v));
|
SubmitProperty("index", new PropOp.Integer(v => Index = v));
|
||||||
SubmitProperty("fit", new PropOp.Enum<FitMode>(v => Fit = v, v => (FitMode)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;
|
static Vector2[] _origuv;
|
||||||
@@ -122,9 +122,21 @@ namespace Cryville.Crtr.Components {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mesh.Renderer.enabled = true;
|
mesh.Renderer.enabled = true;
|
||||||
mesh.Renderer.material.mainTexture = frame.Frame.Texture;
|
mesh.Renderer.sharedMaterial.mainTexture = frame.Frame.Texture;
|
||||||
UpdateUV();
|
UpdateUV();
|
||||||
UpdateScale();
|
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();
|
UpdateZIndex();
|
||||||
}
|
}
|
||||||
readonly Vector2[] _uvs = new Vector2[4];
|
readonly Vector2[] _uvs = new Vector2[4];
|
||||||
@@ -138,21 +150,6 @@ namespace Cryville.Crtr.Components {
|
|||||||
mesh.Mesh.uv = _uvs;
|
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;
|
private FitMode m_fit = FitMode.height;
|
||||||
public FitMode Fit {
|
public FitMode Fit {
|
||||||
get { return m_fit; }
|
get { return m_fit; }
|
||||||
@@ -185,7 +182,7 @@ namespace Cryville.Crtr.Components {
|
|||||||
public override void Init() {
|
public override void Init() {
|
||||||
InternalInit();
|
InternalInit();
|
||||||
OnFrameUpdate();
|
OnFrameUpdate();
|
||||||
UpdateOpacity();
|
UpdateShader();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,7 @@
|
|||||||
|
|
||||||
namespace Cryville.Crtr.Components {
|
namespace Cryville.Crtr.Components {
|
||||||
public class SpriteRect : SpriteBase {
|
public class SpriteRect : SpriteBase {
|
||||||
public SpriteRect() {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Vector3 BaseScale {
|
protected override Vector3 BaseScale {
|
||||||
get { return Vector3.one; }
|
get { return Vector3.one; }
|
||||||
@@ -25,7 +10,6 @@ namespace Cryville.Crtr.Components {
|
|||||||
|
|
||||||
public override void Init() {
|
public override void Init() {
|
||||||
InternalInit();
|
InternalInit();
|
||||||
OnColorUpdate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ namespace Cryville.Crtr.Components {
|
|||||||
SubmitProperty("border", new PropOp.Vector2(v => Border = v));
|
SubmitProperty("border", new PropOp.Vector2(v => Border = v));
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly static Dictionary<float, int> uvrefl
|
static readonly Dictionary<float, int> uvrefl
|
||||||
= new Dictionary<float, int>() {
|
= new Dictionary<float, int>() {
|
||||||
{-0.5f, 0}, {-0.4f, 1}, {0.4f, 2}, {0.5f, 3},
|
{-0.5f, 0}, {-0.4f, 1}, {0.4f, 2}, {0.5f, 3},
|
||||||
};
|
};
|
||||||
static Vector2[] _origuv;
|
static Vector2[] _origuv;
|
||||||
protected new static Vector2[] OriginalUV {
|
protected static new Vector2[] OriginalUV {
|
||||||
get {
|
get {
|
||||||
if (_origuv == null) {
|
if (_origuv == null) {
|
||||||
var m = GenericResources.Meshes["quad_scale3h"];
|
var m = GenericResources.Meshes["quad_scale3h"];
|
||||||
@@ -84,7 +84,6 @@ namespace Cryville.Crtr.Components {
|
|||||||
public override void Init() {
|
public override void Init() {
|
||||||
InternalInit("quad_scale3h");
|
InternalInit("quad_scale3h");
|
||||||
OnFrameUpdate();
|
OnFrameUpdate();
|
||||||
UpdateOpacity();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ namespace Cryville.Crtr.Components {
|
|||||||
SubmitProperty("value", new PropOp.TargetString(() => Value));
|
SubmitProperty("value", new PropOp.TargetString(() => Value));
|
||||||
SubmitProperty("size", new PropOp.Float(v => Size = v));
|
SubmitProperty("size", new PropOp.Float(v => Size = v));
|
||||||
SubmitProperty("spacing", new PropOp.Float(v => Spacing = v));
|
SubmitProperty("spacing", new PropOp.Float(v => Spacing = v));
|
||||||
SubmitProperty("opacity", new PropOp.Float(v => Opacity = v));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable IDE1006
|
#pragma warning disable IDE1006
|
||||||
@@ -20,7 +19,7 @@ namespace Cryville.Crtr.Components {
|
|||||||
public op_set_frames(SpriteText self) : base(2) {
|
public op_set_frames(SpriteText self) : base(2) {
|
||||||
_self = self;
|
_self = self;
|
||||||
}
|
}
|
||||||
protected unsafe override void Execute() {
|
protected override unsafe void Execute() {
|
||||||
var keys = GetOperand(0).AsString();
|
var keys = GetOperand(0).AsString();
|
||||||
var values = GetOperand(1);
|
var values = GetOperand(1);
|
||||||
int arrtype; int len;
|
int arrtype; int len;
|
||||||
@@ -47,7 +46,7 @@ namespace Cryville.Crtr.Components {
|
|||||||
Dictionary<char, SpriteInfo> m_frames;
|
Dictionary<char, SpriteInfo> m_frames;
|
||||||
public Dictionary<char, SpriteInfo> Frames {
|
public Dictionary<char, SpriteInfo> Frames {
|
||||||
get { return m_frames; }
|
get { return m_frames; }
|
||||||
set { m_frames = value; UpdateFrames(); UpdateScale(); }
|
set { m_frames = value; UpdateFrames(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly TargetString m_value = new TargetString();
|
readonly TargetString m_value = new TargetString();
|
||||||
@@ -78,7 +77,11 @@ namespace Cryville.Crtr.Components {
|
|||||||
meshes.Clear();
|
meshes.Clear();
|
||||||
verts.Clear();
|
verts.Clear();
|
||||||
uvs.Clear();
|
uvs.Clear();
|
||||||
|
DestroyMaterials();
|
||||||
|
materials = new Material[m_frames.Count];
|
||||||
|
int i = 0;
|
||||||
foreach (var f in m_frames) {
|
foreach (var f in m_frames) {
|
||||||
|
if (SpriteInfo.IsNullOrEmpty(f.Value)) continue;
|
||||||
if (frameHeight == 0) frameHeight = f.Value.Rect.height;
|
if (frameHeight == 0) frameHeight = f.Value.Rect.height;
|
||||||
else if (frameHeight != f.Value.Rect.height) throw new Exception("Inconsistent frame height for text component");
|
else if (frameHeight != f.Value.Rect.height) throw new Exception("Inconsistent frame height for text component");
|
||||||
var tex = f.Value.Frame.Texture;
|
var tex = f.Value.Frame.Texture;
|
||||||
@@ -86,14 +89,17 @@ namespace Cryville.Crtr.Components {
|
|||||||
var m = new MeshWrapper();
|
var m = new MeshWrapper();
|
||||||
m.Init(mesh.MeshTransform);
|
m.Init(mesh.MeshTransform);
|
||||||
m.Mesh = new Mesh();
|
m.Mesh = new Mesh();
|
||||||
m.Renderer.material = MeshWrapper.NewMaterial(); // TODO Destroy or add to `materials`
|
var mat = MeshWrapper.NewMaterial();
|
||||||
m.Renderer.material.mainTexture = tex;
|
mat.mainTexture = tex;
|
||||||
|
m.Renderer.sharedMaterial = materials[i++] = mat;
|
||||||
meshes.Add(tex, m);
|
meshes.Add(tex, m);
|
||||||
verts.Add(tex, new List<Vector3>());
|
verts.Add(tex, new List<Vector3>());
|
||||||
uvs.Add(tex, new List<Vector2>());
|
uvs.Add(tex, new List<Vector2>());
|
||||||
tris.Add(tex, new List<int>());
|
tris.Add(tex, new List<int>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UpdateColor();
|
||||||
|
UpdateScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
float sum_x;
|
float sum_x;
|
||||||
@@ -158,23 +164,6 @@ namespace Cryville.Crtr.Components {
|
|||||||
get { return new Vector2(-0.5f, -0.5f); }
|
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() {
|
public override void Init() {
|
||||||
InternalInit();
|
InternalInit();
|
||||||
UpdateFrames();
|
UpdateFrames();
|
||||||
|
|||||||
@@ -93,10 +93,10 @@ namespace Cryville.Crtr.Config {
|
|||||||
var tsrc = src.Value;
|
var tsrc = src.Value;
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
if (proxy.IsUsed(tsrc)) {
|
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) {
|
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;
|
else flag = true;
|
||||||
btn.interactable = flag;
|
btn.interactable = flag;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Cryville.Common.Buffers;
|
using Cryville.Common.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Cryville.Crtr {
|
namespace Cryville.Crtr {
|
||||||
public class EffectGroup {
|
public class EffectGroup {
|
||||||
@@ -35,22 +36,37 @@ namespace Cryville.Crtr {
|
|||||||
while (_endQueue.Count > 0) {
|
while (_endQueue.Count > 0) {
|
||||||
var item = _endQueue[0];
|
var item = _endQueue[0];
|
||||||
if (item.EndTime > _time) break;
|
if (item.EndTime > _time) break;
|
||||||
item.OnDone();
|
|
||||||
_instances.Remove(item.Index);
|
|
||||||
_pool.Return(item);
|
|
||||||
_endQueue.RemoveAt(0);
|
_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;
|
EffectInstance instance;
|
||||||
if (!_instances.TryGetValue(index, out instance)) {
|
bool flag = _instances.TryGetValue(index, out instance);
|
||||||
_instances.Add(index, instance = _pool.Rent());
|
if (!flag) _instances.Add(index, instance = _pool.Rent());
|
||||||
}
|
|
||||||
instance.Index = index;
|
instance.Index = index;
|
||||||
instance.OnEmit(_time);
|
if (instance.CanEmit()) {
|
||||||
var i = _endQueue.BinarySearch(instance);
|
if (flag) {
|
||||||
if (i < 0) i = ~i;
|
var i = _endQueue.BinarySearch(instance);
|
||||||
_endQueue.Insert(i, 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() {
|
public void Dispose() {
|
||||||
_pool.DisposeAll();
|
_pool.DisposeAll();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Cryville.Common;
|
using Cryville.Common;
|
||||||
using Cryville.Crtr.Components;
|
using Cryville.Crtr.Components;
|
||||||
|
using Cryville.Crtr.Event;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@@ -10,37 +11,89 @@ namespace Cryville.Crtr {
|
|||||||
readonly EffectDefinition _def;
|
readonly EffectDefinition _def;
|
||||||
readonly SkinContainer _skinContainer;
|
readonly SkinContainer _skinContainer;
|
||||||
public Transform RootTransform { get; private set; }
|
public Transform RootTransform { get; private set; }
|
||||||
|
readonly SkinComponent[] _comps;
|
||||||
public EffectInstance(EffectDefinition def) {
|
public EffectInstance(EffectDefinition def) {
|
||||||
_def = def;
|
_def = def;
|
||||||
_skinContainer = new SkinContainer(_def.elements);
|
_skinContainer = new SkinContainer(this, _def.elements);
|
||||||
RootTransform = new GameObject("effect:" + GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
RootTransform = new GameObject("effect:" + GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
||||||
SkinContext = new SkinContext(RootTransform);
|
SkinContext = new SkinContext(RootTransform);
|
||||||
ChartPlayer.etor.ContextCascadeInsertBlock();
|
ChartPlayer.etor.ContextCascadeInsertBlock();
|
||||||
_skinContainer.MatchStatic(this);
|
_skinContainer.MatchStatic();
|
||||||
ChartPlayer.etor.ContextCascadeDiscardBlock();
|
ChartPlayer.etor.ContextCascadeDiscardBlock();
|
||||||
foreach (var i in RootTransform.GetComponentsInChildren<SkinComponent>())
|
_comps = RootTransform.GetComponentsInChildren<SkinComponent>();
|
||||||
i.Init();
|
foreach (var i in _comps) i.Init();
|
||||||
_indexSrc = new PropSrc.Float(() => Index);
|
_indexSrc = new PropSrc.Float(() => Index);
|
||||||
_durationOp = new PropOp.Float(v => _duration = v);
|
_durationOp = new PropOp.Float(v => _duration = v);
|
||||||
}
|
}
|
||||||
public float Index { get; set; }
|
public void Rewind(double time, Transform target) {
|
||||||
static readonly int _var_index = IdentifierManager.SharedInstance.Request("index");
|
_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;
|
readonly PropSrc _indexSrc;
|
||||||
double _startTime;
|
double _startTime;
|
||||||
float _duration;
|
float _duration;
|
||||||
readonly PropOp _durationOp;
|
readonly PropOp _durationOp;
|
||||||
public double EndTime { get { return _startTime + _duration; } }
|
public double EndTime { get { return _startTime + _duration; } }
|
||||||
public void OnEmit(double time) {
|
public void Tick(double time) {
|
||||||
_startTime = 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);
|
RootTransform.gameObject.SetActive(true);
|
||||||
ChartPlayer.etor.ContextCascadeInsert();
|
ChartPlayer.etor.ContextCascadeInsert();
|
||||||
ChartPlayer.etor.ContextCascadeUpdate(_var_index, _indexSrc);
|
ChartPlayer.etor.ContextCascadeUpdate(_VAR_EFFECT_INDEX, _indexSrc);
|
||||||
ChartPlayer.etor.Evaluate(_durationOp, _def.duration);
|
ChartPlayer.etor.Evaluate(_durationOp, _currentState.duration);
|
||||||
_skinContainer.MatchDynamic(this, 0);
|
if (emitting) _skinContainer.MatchDynamic(0, true);
|
||||||
|
_skinContainer.MatchDynamic(1, emitting);
|
||||||
ChartPlayer.etor.ContextCascadeDiscard();
|
ChartPlayer.etor.ContextCascadeDiscard();
|
||||||
}
|
}
|
||||||
public void OnDone() {
|
public bool OnStateDone() {
|
||||||
RootTransform.gameObject.SetActive(false);
|
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() {
|
public void Dispose() {
|
||||||
GameObject.Destroy(RootTransform.gameObject);
|
GameObject.Destroy(RootTransform.gameObject);
|
||||||
@@ -48,7 +101,7 @@ namespace Cryville.Crtr {
|
|||||||
|
|
||||||
public string TypeName { get { throw new InvalidOperationException("Type name undefined"); } }
|
public string TypeName { get { throw new InvalidOperationException("Type name undefined"); } }
|
||||||
public SkinContext SkinContext { get; private set; }
|
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) {
|
public void PushAnchorEvent(double time, int name) {
|
||||||
throw new InvalidOperationException("Anchor not supported");
|
throw new InvalidOperationException("Anchor not supported");
|
||||||
}
|
}
|
||||||
@@ -60,7 +113,9 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int CompareTo(EffectInstance other) {
|
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 System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Cryville.Crtr {
|
namespace Cryville.Crtr {
|
||||||
public class EffectManager {
|
public class EffectManager {
|
||||||
@@ -15,6 +16,9 @@ namespace Cryville.Crtr {
|
|||||||
public void Emit(int id, float index) {
|
public void Emit(int id, float index) {
|
||||||
_groups[id].Emit(index);
|
_groups[id].Emit(index);
|
||||||
}
|
}
|
||||||
|
public void EmitSelf(int id, float index, Transform target) {
|
||||||
|
_groups[id].Emit(index, target);
|
||||||
|
}
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
foreach (var g in _groups) g.Value.Dispose();
|
foreach (var g in _groups) g.Value.Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,10 +37,9 @@ namespace Cryville.Crtr.Event {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ContainerState ts;
|
public ContainerState ts;
|
||||||
|
|
||||||
/// <summary>
|
protected Transform RootTransform;
|
||||||
/// <see cref="GameObject"/> group, the <see cref="Transform"/> containing all the generated elements in the <see cref="ContainerHandler"/>.
|
|
||||||
/// </summary>
|
SkinComponent[] _comps;
|
||||||
protected Transform gogroup;
|
|
||||||
|
|
||||||
public Vector3 Position { get; protected set; }
|
public Vector3 Position { get; protected set; }
|
||||||
public Quaternion Rotation { get; protected set; }
|
public Quaternion Rotation { get; protected set; }
|
||||||
@@ -70,7 +69,7 @@ namespace Cryville.Crtr.Event {
|
|||||||
SkinContainer skinContainer;
|
SkinContainer skinContainer;
|
||||||
protected Judge judge;
|
protected Judge judge;
|
||||||
public void AttachSystems(PdtSkin skin, Judge judge) {
|
public void AttachSystems(PdtSkin skin, Judge judge) {
|
||||||
skinContainer = new SkinContainer(skin.elements);
|
skinContainer = new SkinContainer(this, skin.elements);
|
||||||
this.judge = judge;
|
this.judge = judge;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,15 +79,15 @@ namespace Cryville.Crtr.Event {
|
|||||||
Anchor a_cur;
|
Anchor a_cur;
|
||||||
Anchor a_head;
|
Anchor a_head;
|
||||||
Anchor a_tail;
|
Anchor a_tail;
|
||||||
readonly static int _a_cur = IdentifierManager.SharedInstance.Request("cur");
|
static readonly int _a_cur = IdentifierManager.SharedInstance.Request("cur");
|
||||||
readonly static int _a_head = IdentifierManager.SharedInstance.Request("head");
|
static readonly int _a_head = IdentifierManager.SharedInstance.Request("head");
|
||||||
readonly static int _a_tail = IdentifierManager.SharedInstance.Request("tail");
|
static readonly int _a_tail = IdentifierManager.SharedInstance.Request("tail");
|
||||||
double atime_head;
|
double atime_head;
|
||||||
double atime_tail;
|
double atime_tail;
|
||||||
public Anchor RegisterAnchor(int name, bool dyn = false, int propSrcCount = 0) {
|
public Anchor RegisterAnchor(int name, bool dyn = false, int propSrcCount = 0) {
|
||||||
var strname = IdentifierManager.SharedInstance.Retrieve(name);
|
var strname = IdentifierManager.SharedInstance.Retrieve(name);
|
||||||
var go = new GameObject("." + strname).transform;
|
var go = new GameObject("." + strname).transform;
|
||||||
go.SetParent(gogroup, false);
|
go.SetParent(RootTransform, false);
|
||||||
var result = new Anchor(name, go, propSrcCount);
|
var result = new Anchor(name, go, propSrcCount);
|
||||||
if (dyn) {
|
if (dyn) {
|
||||||
if (DynamicAnchors.ContainsKey(name))
|
if (DynamicAnchors.ContainsKey(name))
|
||||||
@@ -103,22 +102,22 @@ namespace Cryville.Crtr.Event {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
protected void OpenAnchor(Anchor anchor) {
|
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);
|
anchor.Transform.gameObject.SetActive(true);
|
||||||
OpenedAnchor = anchor;
|
_openedAnchor = anchor;
|
||||||
}
|
}
|
||||||
protected void CloseAnchor() {
|
protected void CloseAnchor() {
|
||||||
OpenedAnchor = null;
|
_openedAnchor = null;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Logic
|
#region Logic
|
||||||
#region Init methods: Called on prehandle
|
#region Init methods: Called on prehandle
|
||||||
public virtual void PreInit() {
|
public virtual void PreInit() {
|
||||||
gogroup = new GameObject(TypeName + ":" + Container.GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
RootTransform = new GameObject(TypeName + ":" + Container.GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
||||||
SkinContext = new SkinContext(gogroup);
|
SkinContext = new SkinContext(RootTransform);
|
||||||
if (cs.Parent != null)
|
if (cs.Parent != null)
|
||||||
gogroup.SetParent(cs.Parent.Handler.gogroup, false);
|
RootTransform.SetParent(cs.Parent.Handler.RootTransform, false);
|
||||||
a_cur = RegisterAnchor(_a_cur);
|
a_cur = RegisterAnchor(_a_cur);
|
||||||
a_head = RegisterAnchor(_a_head, true);
|
a_head = RegisterAnchor(_a_head, true);
|
||||||
a_tail = RegisterAnchor(_a_tail, true);
|
a_tail = RegisterAnchor(_a_tail, true);
|
||||||
@@ -126,16 +125,16 @@ namespace Cryville.Crtr.Event {
|
|||||||
public virtual void Init() {
|
public virtual void Init() {
|
||||||
ChartPlayer.etor.ContextState = ps;
|
ChartPlayer.etor.ContextState = ps;
|
||||||
ChartPlayer.etor.ContextEvent = Container;
|
ChartPlayer.etor.ContextEvent = Container;
|
||||||
skinContainer.MatchStatic(this);
|
skinContainer.MatchStatic();
|
||||||
ChartPlayer.etor.ContextEvent = null;
|
ChartPlayer.etor.ContextEvent = null;
|
||||||
ChartPlayer.etor.ContextState = null;
|
ChartPlayer.etor.ContextState = null;
|
||||||
foreach (var i in gogroup.GetComponentsInChildren<SkinComponent>())
|
_comps = RootTransform.GetComponentsInChildren<SkinComponent>();
|
||||||
i.Init();
|
foreach (var i in _comps) i.Init();
|
||||||
}
|
}
|
||||||
public virtual void PostInit() {
|
public virtual void PostInit() {
|
||||||
PropSrcs.Add(_var_current_time, new PropSrc.Float(() => (float)cs.rootPrototype.Time));
|
PropSrcs.Add(_var_current_time, new PropSrc.Float(() => (float)cs.rootPrototype.Time));
|
||||||
PropSrcs.Add(_var_invisible_bounds, new PropSrc.Boolean(() => atime_head > atime_tail));
|
PropSrcs.Add(_var_invisible_bounds, new PropSrc.Boolean(() => atime_head > atime_tail));
|
||||||
gogroup.gameObject.SetActive(false);
|
RootTransform.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region Start methods
|
#region Start methods
|
||||||
@@ -146,14 +145,14 @@ namespace Cryville.Crtr.Event {
|
|||||||
public virtual void StartLogicalUpdate(ContainerState s) { }
|
public virtual void StartLogicalUpdate(ContainerState s) { }
|
||||||
protected virtual void StartPreGraphicalUpdate(ContainerState s) { }
|
protected virtual void StartPreGraphicalUpdate(ContainerState s) { }
|
||||||
protected virtual void StartGraphicalUpdate(ContainerState s) {
|
protected virtual void StartGraphicalUpdate(ContainerState s) {
|
||||||
if (gogroup) gogroup.gameObject.SetActive(true);
|
if (RootTransform) RootTransform.gameObject.SetActive(true);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
public virtual void Update(ContainerState s, StampedEvent ev) {
|
public virtual void Update(ContainerState s, StampedEvent ev) {
|
||||||
if (s.CloneType == 3) SetPreGraphicalActive(true, s);
|
if (s.CloneType == 3) SetPreGraphicalActive(true, s);
|
||||||
else if (ev is StampedEvent.Anchor) {
|
else if (ev is StampedEvent.Anchor) {
|
||||||
var tev = (StampedEvent.Anchor)ev;
|
var tev = (StampedEvent.Anchor)ev;
|
||||||
if (gogroup) {
|
if (RootTransform) {
|
||||||
OpenAnchor(tev.Target);
|
OpenAnchor(tev.Target);
|
||||||
#if UNITY_5_6_OR_NEWER
|
#if UNITY_5_6_OR_NEWER
|
||||||
tev.Target.Transform.SetPositionAndRotation(Position, Rotation);
|
tev.Target.Transform.SetPositionAndRotation(Position, Rotation);
|
||||||
@@ -172,7 +171,7 @@ namespace Cryville.Crtr.Event {
|
|||||||
}
|
}
|
||||||
anchorEvPool.Return(tev);
|
anchorEvPool.Return(tev);
|
||||||
}
|
}
|
||||||
else if (gogroup && s.CloneType == 2) MatchDynamic(s, 1);
|
else if (RootTransform && s.CloneType == 2) MatchDynamic(s, 1);
|
||||||
}
|
}
|
||||||
#region End methods
|
#region End methods
|
||||||
protected virtual void EndGraphicalUpdate(ContainerState s) { }
|
protected virtual void EndGraphicalUpdate(ContainerState s) { }
|
||||||
@@ -180,8 +179,8 @@ namespace Cryville.Crtr.Event {
|
|||||||
public virtual void EndLogicalUpdate(ContainerState s) { }
|
public virtual void EndLogicalUpdate(ContainerState s) { }
|
||||||
public virtual void EndPhysicalUpdate(ContainerState s) { }
|
public virtual void EndPhysicalUpdate(ContainerState s) { }
|
||||||
public virtual void Dispose() {
|
public virtual void Dispose() {
|
||||||
if (gogroup)
|
if (RootTransform)
|
||||||
GameObject.Destroy(gogroup.gameObject);
|
GameObject.Destroy(RootTransform.gameObject);
|
||||||
Alive = false;
|
Alive = false;
|
||||||
}
|
}
|
||||||
public virtual void DisposeAll() { }
|
public virtual void DisposeAll() { }
|
||||||
@@ -193,7 +192,7 @@ namespace Cryville.Crtr.Event {
|
|||||||
void MatchDynamic(ContainerState s, int dl) {
|
void MatchDynamic(ContainerState s, int dl) {
|
||||||
ChartPlayer.etor.ContextState = s;
|
ChartPlayer.etor.ContextState = s;
|
||||||
ChartPlayer.etor.ContextEvent = Container;
|
ChartPlayer.etor.ContextEvent = Container;
|
||||||
skinContainer.MatchDynamic(this, dl);
|
skinContainer.MatchDynamic(dl);
|
||||||
ChartPlayer.etor.ContextEvent = null;
|
ChartPlayer.etor.ContextEvent = null;
|
||||||
ChartPlayer.etor.ContextState = null;
|
ChartPlayer.etor.ContextState = null;
|
||||||
}
|
}
|
||||||
@@ -205,6 +204,7 @@ namespace Cryville.Crtr.Event {
|
|||||||
atime_head = cs.StampedContainer.Time;
|
atime_head = cs.StampedContainer.Time;
|
||||||
atime_tail = atime_head + cs.StampedContainer.Duration;
|
atime_tail = atime_head + cs.StampedContainer.Duration;
|
||||||
MatchDynamic(cs, 0);
|
MatchDynamic(cs, 0);
|
||||||
|
foreach (var i in _comps) i.Tick(skinContainer, cs.Time);
|
||||||
if (cs.Active) PushAnchorEvent(cs.Time, a_cur);
|
if (cs.Active) PushAnchorEvent(cs.Time, a_cur);
|
||||||
if (double.IsNaN(DynamicAnchorSetTime[_a_head])) DynamicAnchorSetTime[_a_head] = atime_head;
|
if (double.IsNaN(DynamicAnchorSetTime[_a_head])) DynamicAnchorSetTime[_a_head] = atime_head;
|
||||||
if (double.IsNaN(DynamicAnchorSetTime[_a_tail])) DynamicAnchorSetTime[_a_tail] = atime_tail;
|
if (double.IsNaN(DynamicAnchorSetTime[_a_tail])) DynamicAnchorSetTime[_a_tail] = atime_tail;
|
||||||
@@ -241,7 +241,8 @@ namespace Cryville.Crtr.Event {
|
|||||||
#region ISkinnableGroup
|
#region ISkinnableGroup
|
||||||
public abstract string TypeName { get; }
|
public abstract string TypeName { get; }
|
||||||
public SkinContext SkinContext { get; private set; }
|
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) {
|
public bool TryGetAnchorsByName(int name, out IReadOnlyCollection<Anchor> result) {
|
||||||
List<Anchor> anchors;
|
List<Anchor> anchors;
|
||||||
var ret = Anchors.TryGetValue(name, out anchors);
|
var ret = Anchors.TryGetValue(name, out anchors);
|
||||||
|
|||||||
@@ -1,24 +1,45 @@
|
|||||||
using Cryville.Common;
|
using Cryville.Common;
|
||||||
using Cryville.Crtr.Browsing;
|
using Cryville.Crtr.Browsing;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Cryville.Crtr.Extensions.Malody {
|
namespace Cryville.Crtr.Extensions.Malody {
|
||||||
public class MalodyChartFinder : LocalResourceFinder {
|
public class MalodyChartFinder : LocalResourceFinder {
|
||||||
public override string Name { get { return "Malody beatmaps"; } }
|
public override string Name { get { return "Malody beatmaps"; } }
|
||||||
|
|
||||||
public override string GetRootPath() {
|
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) {
|
switch (Environment.OSVersion.Platform) {
|
||||||
case PlatformID.Unix:
|
case PlatformID.Unix:
|
||||||
return "/storage/emulated/0/data/malody/beatmap";
|
return "/storage/emulated/0/data/malody";
|
||||||
case PlatformID.Win32NT:
|
case PlatformID.Win32NT:
|
||||||
var reg = Registry.ClassesRoot.OpenSubKey(@"malody\Shell\Open\Command");
|
var reg = Registry.ClassesRoot.OpenSubKey(@"malody\Shell\Open\Command");
|
||||||
if (reg == null) return null;
|
if (reg == null) return null;
|
||||||
var pathObj = reg.GetValue(null);
|
var pathObj = reg.GetValue(null);
|
||||||
if (pathObj == null) return null;
|
if (pathObj == null) return null;
|
||||||
var path = (string)pathObj;
|
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;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace Cryville.Crtr.Extensions.Quaver {
|
|||||||
evs.Sort();
|
evs.Sort();
|
||||||
|
|
||||||
var longevs = new Dictionary<EventWrapper, ChartEvent>();
|
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) {
|
foreach (var ev in evs) {
|
||||||
tm.ForwardTo(ev.StartTime / 1e3);
|
tm.ForwardTo(ev.StartTime / 1e3);
|
||||||
if (ev is EventWrapper.HitObject) {
|
if (ev is EventWrapper.HitObject) {
|
||||||
@@ -84,6 +84,7 @@ namespace Cryville.Crtr.Extensions.Quaver {
|
|||||||
else if (ev is EventWrapper.TimingPoint) {
|
else if (ev is EventWrapper.TimingPoint) {
|
||||||
var tev = (EventWrapper.TimingPoint)ev;
|
var tev = (EventWrapper.TimingPoint)ev;
|
||||||
tm.BPM = tev.Event.Bpm;
|
tm.BPM = tev.Event.Bpm;
|
||||||
|
tm.ForceSnap();
|
||||||
chart.sigs.Add(new Chart.Signature {
|
chart.sigs.Add(new Chart.Signature {
|
||||||
time = tm.FractionalBeatTime,
|
time = tm.FractionalBeatTime,
|
||||||
tempo = tev.Event.Bpm,
|
tempo = tev.Event.Bpm,
|
||||||
|
|||||||
@@ -42,15 +42,24 @@ namespace Cryville.Crtr.Extensions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class TimeTimingModel : TimingModel {
|
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) {
|
public void ForwardTo(double t) {
|
||||||
if (t == Time) return;
|
if (t == Time) return;
|
||||||
if (BPM == 0) throw new InvalidOperationException("BPM not determined");
|
if (BPM == 0) throw new InvalidOperationException("BPM not determined");
|
||||||
BeatTime += (t - Time) * BPM / 60;
|
BeatTime += (t - Time) * BPM / 60;
|
||||||
int n, d;
|
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);
|
FractionalBeatTime = new BeatTime(n, d);
|
||||||
Time = t;
|
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 {
|
public class osuChartConverter : ResourceConverter {
|
||||||
#pragma warning restore IDE1006
|
#pragma warning restore IDE1006
|
||||||
static readonly string[] SUPPORTED_FORMATS = { ".osu" };
|
static readonly string[] SUPPORTED_FORMATS = { ".osu" };
|
||||||
const double OFFSET = 0.05;
|
const double OFFSET = 0.011;
|
||||||
|
|
||||||
public override string[] GetSupportedFormats() {
|
public override string[] GetSupportedFormats() {
|
||||||
return SUPPORTED_FORMATS;
|
return SUPPORTED_FORMATS;
|
||||||
@@ -108,10 +108,11 @@ namespace Cryville.Crtr.Extensions.osu {
|
|||||||
else if (ev is osuEvent.TimingChange) {
|
else if (ev is osuEvent.TimingChange) {
|
||||||
var tev = (osuEvent.TimingChange)ev;
|
var tev = (osuEvent.TimingChange)ev;
|
||||||
if (tm == null) {
|
if (tm == null) {
|
||||||
tm = new TimeTimingModel(tev.StartTime / 1e3);
|
tm = new TimeTimingModel(tev.StartTime / 1e3, 2e-3);
|
||||||
bgmEv.offset = (float)(tev.StartTime / 1e3 + OFFSET);
|
bgmEv.offset = (float)(tev.StartTime / 1e3 + OFFSET);
|
||||||
}
|
}
|
||||||
tm.BeatLength = tev.BeatLength / 1e3;
|
tm.BeatLength = tev.BeatLength / 1e3;
|
||||||
|
tm.ForceSnap();
|
||||||
chart.sigs.Add(new Chart.Signature {
|
chart.sigs.Add(new Chart.Signature {
|
||||||
time = tm.FractionalBeatTime,
|
time = tm.FractionalBeatTime,
|
||||||
tempo = (float)tm.BPM,
|
tempo = (float)tm.BPM,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Cryville.Crtr {
|
|||||||
get;
|
get;
|
||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
public readonly static string FileProtocolPrefix
|
public static readonly string FileProtocolPrefix
|
||||||
#if UNITY_STANDALONE_WIN
|
#if UNITY_STANDALONE_WIN
|
||||||
= "file:///";
|
= "file:///";
|
||||||
#elif UNITY_ANDROID
|
#elif UNITY_ANDROID
|
||||||
@@ -37,9 +37,9 @@ namespace Cryville.Crtr {
|
|||||||
public static SimpleSequencerSource AudioSequencer;
|
public static SimpleSequencerSource AudioSequencer;
|
||||||
public static SimpleSequencerSession AudioSession;
|
public static SimpleSequencerSession AudioSession;
|
||||||
public static InputManager InputManager;
|
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() {
|
= new JsonSerializerSettings() {
|
||||||
DefaultValueHandling = DefaultValueHandling.Ignore,
|
DefaultValueHandling = DefaultValueHandling.Ignore,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace Cryville.Crtr {
|
|||||||
Components.Add("polysec", typeof(PolygonSGO));
|
Components.Add("polysec", typeof(PolygonSGO));
|
||||||
Components.Add("rect", typeof(SpriteRect));
|
Components.Add("rect", typeof(SpriteRect));
|
||||||
Components.Add("scale3", typeof(SpriteScale3));
|
Components.Add("scale3", typeof(SpriteScale3));
|
||||||
|
Components.Add("sec", typeof(SectionalGameObject));
|
||||||
Components.Add("sprite", typeof(SpriteBase));
|
Components.Add("sprite", typeof(SpriteBase));
|
||||||
Components.Add("text", typeof(SpriteText));
|
Components.Add("text", typeof(SpriteText));
|
||||||
|
|
||||||
@@ -32,6 +33,9 @@ namespace Cryville.Crtr {
|
|||||||
|
|
||||||
Materials.Add("-SpriteMat", Resources.Load<Material>("Materials/SpriteMat"));
|
Materials.Add("-SpriteMat", Resources.Load<Material>("Materials/SpriteMat"));
|
||||||
|
|
||||||
|
Shaders.Add("default", Shader.Find("Sprites/Default"));
|
||||||
|
Shaders.Add("additive", Shader.Find("Sprites/Additive"));
|
||||||
|
|
||||||
loaded = true;
|
loaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ using Cryville.Common.Unity.Input;
|
|||||||
using Cryville.Crtr.Config;
|
using Cryville.Crtr.Config;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using System.Runtime.Serialization;
|
||||||
|
using RVector3 = UnityEngine.Vector3;
|
||||||
|
|
||||||
namespace Cryville.Crtr {
|
namespace Cryville.Crtr {
|
||||||
public class InputProxy : IDisposable {
|
public class InputProxy : IDisposable {
|
||||||
@@ -12,12 +13,11 @@ namespace Cryville.Crtr {
|
|||||||
readonly PdtRuleset _ruleset;
|
readonly PdtRuleset _ruleset;
|
||||||
readonly Judge _judge;
|
readonly Judge _judge;
|
||||||
public InputProxy(PdtRuleset ruleset, Judge judge) {
|
public InputProxy(PdtRuleset ruleset, Judge judge) {
|
||||||
unsafe {
|
for (int i = 0; i <= MAX_DEPTH; i++) {
|
||||||
fixed (byte* ptr = _vecbuf) {
|
var vecsrc = new InputVectorSrc();
|
||||||
*(int*)(ptr + 3 * sizeof(float)) = PdtInternalType.Number;
|
_vecsrcs[i] = vecsrc;
|
||||||
}
|
_vecops[i] = new InputVectorOp(vecsrc);
|
||||||
}
|
}
|
||||||
_vecsrc = new PropSrc.Arbitrary(PdtInternalType.Vector, _vecbuf);
|
|
||||||
_etor = ChartPlayer.etor;
|
_etor = ChartPlayer.etor;
|
||||||
_ruleset = ruleset;
|
_ruleset = ruleset;
|
||||||
_judge = judge;
|
_judge = judge;
|
||||||
@@ -174,14 +174,58 @@ namespace Cryville.Crtr {
|
|||||||
|
|
||||||
readonly object _lock = new object();
|
readonly object _lock = new object();
|
||||||
static readonly int _var_value = IdentifierManager.SharedInstance.Request("value");
|
static readonly int _var_value = IdentifierManager.SharedInstance.Request("value");
|
||||||
static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary();
|
const int MAX_DEPTH = 15;
|
||||||
readonly byte[] _vecbuf = new byte[3 * sizeof(float) + sizeof(int)];
|
const int MAX_DIMENSION = 3;
|
||||||
readonly PropSrc.Arbitrary _vecsrc;
|
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<InputHandler, double> _timeOrigins = new Dictionary<InputHandler, double>();
|
||||||
readonly Dictionary<InputSource, int> _activeCounts = new Dictionary<InputSource, int>();
|
readonly Dictionary<InputSource, int> _activeCounts = new Dictionary<InputSource, int>();
|
||||||
readonly Dictionary<InputIdentifier, float> _vect = new Dictionary<InputIdentifier, float>();
|
readonly Dictionary<InputIdentifier, float> _vect = new Dictionary<InputIdentifier, float>();
|
||||||
readonly Dictionary<ProxiedInputIdentifier, PropSrc> _vecs = new Dictionary<ProxiedInputIdentifier, PropSrc>();
|
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;
|
double? _lockTime = null;
|
||||||
unsafe void OnInput(InputIdentifier id, InputVector vec) {
|
unsafe void OnInput(InputIdentifier id, InputVector vec) {
|
||||||
lock (_lock) {
|
lock (_lock) {
|
||||||
@@ -191,15 +235,12 @@ namespace Cryville.Crtr {
|
|||||||
float ft, tt = (float)(_lockTime != null ? _lockTime.Value : (vec.Time - _timeOrigins[id.Source.Handler]));
|
float ft, tt = (float)(_lockTime != null ? _lockTime.Value : (vec.Time - _timeOrigins[id.Source.Handler]));
|
||||||
if (!_vect.TryGetValue(id, out ft)) ft = tt;
|
if (!_vect.TryGetValue(id, out ft)) ft = tt;
|
||||||
if (vec.IsNull) {
|
if (vec.IsNull) {
|
||||||
_etor.ContextCascadeUpdate(_var_value, _nullsrc);
|
_etor.ContextCascadeUpdate(_var_value, PropSrc.Null);
|
||||||
OnInput(id, proxy.Target, ft, tt, true);
|
OnInput(id, proxy.Target, ft, tt, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fixed (byte* ptr = _vecbuf) {
|
_vecsrcs[0].Set(vec.Vector);
|
||||||
*(Vector3*)ptr = vec.Vector;
|
_etor.ContextCascadeUpdate(_var_value, _vecsrcs[0]);
|
||||||
}
|
|
||||||
_vecsrc.Invalidate();
|
|
||||||
_etor.ContextCascadeUpdate(_var_value, _vecsrc);
|
|
||||||
OnInput(id, proxy.Target, ft, tt, false);
|
OnInput(id, proxy.Target, ft, tt, false);
|
||||||
}
|
}
|
||||||
_vect[id] = tt;
|
_vect[id] = tt;
|
||||||
@@ -209,21 +250,27 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
|
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
|
||||||
static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv");
|
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];
|
var def = _ruleset.inputs[target];
|
||||||
if (def.pass != null) {
|
if (def.pass != null) {
|
||||||
foreach (var p in def.pass) {
|
foreach (var p in def.pass) {
|
||||||
_etor.ContextCascadeInsert();
|
_etor.ContextCascadeInsert();
|
||||||
_arbop.Name = _var_value;
|
bool newNullFlag = nullflag;
|
||||||
if (!nullflag) _etor.Evaluate(_arbop, p.Value);
|
if (!newNullFlag) {
|
||||||
OnInput(id, p.Key, ft, tt, nullflag);
|
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();
|
_etor.ContextCascadeDiscard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var pid = new ProxiedInputIdentifier { Source = id, Target = target };
|
var pid = new ProxiedInputIdentifier { Source = id, Target = target };
|
||||||
PropSrc fv, tv = _etor.ContextCascadeLookup(_var_value);
|
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 || tv.Type != PdtInternalType.Null) {
|
||||||
if (fv.Type == PdtInternalType.Null) _activeCounts[id.Source]++;
|
if (fv.Type == PdtInternalType.Null) _activeCounts[id.Source]++;
|
||||||
_etor.ContextCascadeInsert();
|
_etor.ContextCascadeInsert();
|
||||||
@@ -306,4 +353,12 @@ namespace Cryville.Crtr {
|
|||||||
return !lhs.Equals(rhs);
|
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) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user