Compare commits
15 Commits
fcc159ab6c
...
0.5.0-rc0
Author | SHA1 | Date | |
---|---|---|---|
05664a2994 | |||
ba6166068b | |||
d5d6465806 | |||
1f57c299a2 | |||
49431e888c | |||
c31c16792c | |||
7ce73186ae | |||
318a6705be | |||
7fca09ff49 | |||
eff8dd2c35 | |||
252853f4d4 | |||
a47faf0049 | |||
604398cae2 | |||
457d491d89 | |||
0c8e24b079 |
@@ -34,6 +34,16 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Patches an expression with a lefthand variable and a compound operator.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">The name of the lefthand variable.</param>
|
||||||
|
/// <param name="op">The name of the compound operator.</param>
|
||||||
|
/// <param name="exp">The expression.</param>
|
||||||
|
public void PatchCompound(int target, int op, PdtExpression exp) {
|
||||||
|
exp.Instructions.AddFirst(new PdtInstruction.PushVariable(target));
|
||||||
|
exp.Instructions.AddLast(new PdtInstruction.Operate(op, 2));
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
/// Optimizes an expression by merging its instructions.
|
/// Optimizes an expression by merging its instructions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="exp">The expression to optimize.</param>
|
/// <param name="exp">The expression to optimize.</param>
|
||||||
|
@@ -51,9 +51,8 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
public class PushVariable : PdtInstruction {
|
public class PushVariable : PdtInstruction {
|
||||||
public int Name { get; private set; }
|
public int Name { get; private set; }
|
||||||
public PushVariable(string name) {
|
public PushVariable(int name) { Name = name; }
|
||||||
Name = IdentifierManager.SharedInstance.Request(name);
|
public PushVariable(string name) : this(IdentifierManager.SharedInstance.Request(name)) { }
|
||||||
}
|
|
||||||
internal override void Execute(PdtEvaluatorBase etor) {
|
internal override void Execute(PdtEvaluatorBase etor) {
|
||||||
etor.PushVariable(Name);
|
etor.PushVariable(Name);
|
||||||
}
|
}
|
||||||
@@ -63,6 +62,9 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
public class Operate : PdtInstruction {
|
public class Operate : PdtInstruction {
|
||||||
public PdtOperatorSignature Signature { get; private set; }
|
public PdtOperatorSignature Signature { get; private set; }
|
||||||
|
public Operate(int name, int paramCount) {
|
||||||
|
Signature = new PdtOperatorSignature(name, paramCount);
|
||||||
|
}
|
||||||
public Operate(string name, int paramCount) {
|
public Operate(string name, int paramCount) {
|
||||||
Signature = new PdtOperatorSignature(name, paramCount);
|
Signature = new PdtOperatorSignature(name, paramCount);
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,7 @@ namespace Cryville.Common.Unity.Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override double GetCurrentTimestamp() {
|
public override double GetCurrentTimestamp() {
|
||||||
return Time.timeAsDouble;
|
return Time.realtimeSinceStartupAsDouble;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ namespace Cryville.Common.Unity.Input {
|
|||||||
}
|
}
|
||||||
public abstract string GetKeyName(int type);
|
public abstract string GetKeyName(int type);
|
||||||
void Update() {
|
void Update() {
|
||||||
double time = Time.timeAsDouble;
|
double time = Time.realtimeSinceStartupAsDouble;
|
||||||
foreach (var k in Keys) {
|
foreach (var k in Keys) {
|
||||||
Callback(k, 0, new InputVector(time, Vector3.zero));
|
Callback(k, 0, new InputVector(time, Vector3.zero));
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ namespace Cryville.Common.Unity.Input {
|
|||||||
void OnGUI() {
|
void OnGUI() {
|
||||||
var e = Event.current;
|
var e = Event.current;
|
||||||
if (e.keyCode == KeyCode.None) return;
|
if (e.keyCode == KeyCode.None) return;
|
||||||
double time = Time.timeAsDouble;
|
double time = Time.realtimeSinceStartupAsDouble;
|
||||||
var key = (int)e.keyCode;
|
var key = (int)e.keyCode;
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case EventType.KeyDown:
|
case EventType.KeyDown:
|
||||||
@@ -92,7 +92,7 @@ namespace Cryville.Common.Unity.Input {
|
|||||||
}
|
}
|
||||||
void OnGUI() {
|
void OnGUI() {
|
||||||
var e = Event.current;
|
var e = Event.current;
|
||||||
double time = Time.timeAsDouble;
|
double time = Time.realtimeSinceStartupAsDouble;
|
||||||
var key = e.button;
|
var key = e.button;
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case EventType.MouseDown:
|
case EventType.MouseDown:
|
||||||
|
@@ -45,7 +45,7 @@ namespace Cryville.Common.Unity.Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override double GetCurrentTimestamp() {
|
public override double GetCurrentTimestamp() {
|
||||||
return Time.timeAsDouble;
|
return Time.realtimeSinceStartupAsDouble;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UnityMouseReceiver : MonoBehaviour {
|
public class UnityMouseReceiver : MonoBehaviour {
|
||||||
@@ -54,7 +54,7 @@ namespace Cryville.Common.Unity.Input {
|
|||||||
handler = h;
|
handler = h;
|
||||||
}
|
}
|
||||||
void Update() {
|
void Update() {
|
||||||
double time = Time.timeAsDouble;
|
double time = Time.realtimeSinceStartupAsDouble;
|
||||||
Vector3 pos = UnityCameraUtils.ScreenToWorldPoint(unity::Input.mousePosition);
|
Vector3 pos = UnityCameraUtils.ScreenToWorldPoint(unity::Input.mousePosition);
|
||||||
handler.Feed(0, 0, new InputVector(time, pos));
|
handler.Feed(0, 0, new InputVector(time, pos));
|
||||||
}
|
}
|
||||||
|
@@ -45,7 +45,7 @@ namespace Cryville.Common.Unity.Input {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override double GetCurrentTimestamp() {
|
public override double GetCurrentTimestamp() {
|
||||||
return Time.timeAsDouble;
|
return Time.realtimeSinceStartupAsDouble;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UnityPointerReceiver : MonoBehaviour {
|
public class UnityPointerReceiver : MonoBehaviour {
|
||||||
@@ -54,7 +54,7 @@ namespace Cryville.Common.Unity.Input {
|
|||||||
handler = h;
|
handler = h;
|
||||||
}
|
}
|
||||||
void Update() {
|
void Update() {
|
||||||
double time = Time.timeAsDouble;
|
double time = Time.realtimeSinceStartupAsDouble;
|
||||||
for (int i = 0; i < unity::Input.touchCount; i++) {
|
for (int i = 0; i < unity::Input.touchCount; i++) {
|
||||||
var t = unity::Input.GetTouch(i);
|
var t = unity::Input.GetTouch(i);
|
||||||
Vector2 pos = UnityCameraUtils.ScreenToWorldPoint(t.position);
|
Vector2 pos = UnityCameraUtils.ScreenToWorldPoint(t.position);
|
||||||
|
@@ -105,6 +105,7 @@ namespace Cryville.Crtr {
|
|||||||
bool texloaddone;
|
bool texloaddone;
|
||||||
diag::Stopwatch texloadtimer = new diag::Stopwatch();
|
diag::Stopwatch texloadtimer = new diag::Stopwatch();
|
||||||
bool firstFrame;
|
bool firstFrame;
|
||||||
|
double atime0;
|
||||||
void Update() {
|
void Update() {
|
||||||
// if (Input.GetKeyDown(KeyCode.Return)) TogglePlay();
|
// if (Input.GetKeyDown(KeyCode.Return)) TogglePlay();
|
||||||
if (started) {
|
if (started) {
|
||||||
@@ -115,16 +116,9 @@ namespace Cryville.Crtr {
|
|||||||
? 1f / Application.targetFrameRate
|
? 1f / Application.targetFrameRate
|
||||||
: Time.deltaTime;
|
: Time.deltaTime;
|
||||||
firstFrame = false;
|
firstFrame = false;
|
||||||
|
inputProxy.ForceTick();
|
||||||
cbus.ForwardByTime(dt);
|
cbus.ForwardByTime(dt);
|
||||||
bbus.ForwardByTime(dt);
|
bbus.ForwardByTime(dt);
|
||||||
UnityEngine.Profiling.Profiler.BeginSample("ChartPlayer.FeedJudge");
|
|
||||||
/*judge.StartFrame();
|
|
||||||
Game.InputManager.EnumerateEvents(ev => {
|
|
||||||
// Logger.Log("main", 0, "Input", ev.ToString());
|
|
||||||
judge.Feed(ev);
|
|
||||||
});
|
|
||||||
judge.EndFrame();*/
|
|
||||||
UnityEngine.Profiling.Profiler.EndSample();
|
|
||||||
UnityEngine.Profiling.Profiler.BeginSample("ChartPlayer.Forward");
|
UnityEngine.Profiling.Profiler.BeginSample("ChartPlayer.Forward");
|
||||||
UnityEngine.Profiling.Profiler.BeginSample("EventBus.Copy");
|
UnityEngine.Profiling.Profiler.BeginSample("EventBus.Copy");
|
||||||
bbus.CopyTo(2, tbus);
|
bbus.CopyTo(2, tbus);
|
||||||
@@ -245,6 +239,12 @@ namespace Cryville.Crtr {
|
|||||||
UnityEngine.Profiling.Profiler.GetTotalReservedMemory()
|
UnityEngine.Profiling.Profiler.GetTotalReservedMemory()
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
if (started) sttext += string.Format(
|
||||||
|
"\nSTime: {0:R}\nATime: {1:R}\nITime: {2:R}",
|
||||||
|
cbus.Time,
|
||||||
|
Game.AudioClient.Position - atime0,
|
||||||
|
inputProxy.GetTimestampAverage()
|
||||||
|
);
|
||||||
if (judge != null) sttext += "\n== Scores ==\n" + judge.GetFullFormattedScoreString();
|
if (judge != null) sttext += "\n== Scores ==\n" + judge.GetFullFormattedScoreString();
|
||||||
status.text = sttext;
|
status.text = sttext;
|
||||||
}
|
}
|
||||||
@@ -408,8 +408,9 @@ namespace Cryville.Crtr {
|
|||||||
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);
|
||||||
Game.AudioSequencer.Playing = true;
|
Game.AudioSequencer.Playing = true;
|
||||||
Thread.Sleep((int)(Game.AudioClient.BufferPosition - Game.AudioClient.Position));
|
atime0 = Game.AudioClient.BufferPosition;
|
||||||
// TODO SyncTime(cbus.Time);
|
Thread.Sleep((int)((atime0 - Game.AudioClient.Position) * 1000));
|
||||||
|
inputProxy.SyncTime(cbus.Time);
|
||||||
started = true;
|
started = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
@@ -503,11 +504,11 @@ namespace Cryville.Crtr {
|
|||||||
cbus = batcher.Batch();
|
cbus = batcher.Batch();
|
||||||
Logger.Log("main", 0, "Load/WorkerThread", "Batched {0} event batches", cbus.events.Count);
|
Logger.Log("main", 0, "Load/WorkerThread", "Batched {0} event batches", cbus.events.Count);
|
||||||
|
|
||||||
|
LoadSkin(info.skinFile);
|
||||||
|
|
||||||
judge = new Judge(pruleset);
|
judge = new Judge(pruleset);
|
||||||
etor.ContextJudge = judge;
|
etor.ContextJudge = judge;
|
||||||
|
|
||||||
LoadSkin(info.skinFile);
|
|
||||||
|
|
||||||
cbus.AttachSystems(pskin, judge);
|
cbus.AttachSystems(pskin, judge);
|
||||||
Logger.Log("main", 0, "Load/WorkerThread", "Attaching handlers");
|
Logger.Log("main", 0, "Load/WorkerThread", "Attaching handlers");
|
||||||
var ch = new ChartHandler(chart, dir);
|
var ch = new ChartHandler(chart, dir);
|
||||||
|
@@ -96,6 +96,7 @@ namespace Cryville.Crtr.Components {
|
|||||||
|
|
||||||
float sum_x;
|
float sum_x;
|
||||||
void UpdateMeshes() {
|
void UpdateMeshes() {
|
||||||
|
// TODO optimize GC
|
||||||
if (meshes.Count == 0) return;
|
if (meshes.Count == 0) return;
|
||||||
sum_x = 0;
|
sum_x = 0;
|
||||||
int vc = m_value.Length * 4;
|
int vc = m_value.Length * 4;
|
||||||
|
@@ -105,9 +105,11 @@ namespace Cryville.Crtr {
|
|||||||
#region Handling
|
#region Handling
|
||||||
public void Activate() {
|
public void Activate() {
|
||||||
_activeCounts.Clear();
|
_activeCounts.Clear();
|
||||||
foreach (var p in _tproxies.Values) _activeCounts.Add(p.Source.Value, 0);
|
|
||||||
_vect.Clear(); _vecs.Clear();
|
_vect.Clear(); _vecs.Clear();
|
||||||
foreach (var src in _sproxies.Keys) src.Handler.Activate();
|
foreach (var src in _sproxies.Keys) {
|
||||||
|
_activeCounts.Add(src, 0);
|
||||||
|
src.Handler.Activate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public void Deactivate() { foreach (var src in _sproxies.Keys) src.Handler.Deactivate(); }
|
public void Deactivate() { foreach (var src in _sproxies.Keys) src.Handler.Deactivate(); }
|
||||||
|
|
||||||
@@ -115,7 +117,8 @@ namespace Cryville.Crtr {
|
|||||||
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();
|
static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary();
|
||||||
readonly byte[] _vecbuf = new byte[3 * sizeof(float) + sizeof(int)];
|
readonly byte[] _vecbuf = new byte[3 * sizeof(float) + sizeof(int)];
|
||||||
readonly Dictionary<InputSource, int> _activeCounts = new Dictionary<InputSource, int>(); // TODO used for force tick
|
readonly Dictionary<InputHandler, double> _timeOrigins = new Dictionary<InputHandler, double>();
|
||||||
|
readonly Dictionary<InputSource, int> _activeCounts = new Dictionary<InputSource, int>();
|
||||||
readonly Dictionary<InputIdentifier, float> _vect = new Dictionary<InputIdentifier, float>();
|
readonly Dictionary<InputIdentifier, float> _vect = new Dictionary<InputIdentifier, float>();
|
||||||
readonly Dictionary<ProxiedInputIdentifier, PropSrc.Arbitrary> _vecs = new Dictionary<ProxiedInputIdentifier, PropSrc.Arbitrary>();
|
readonly Dictionary<ProxiedInputIdentifier, PropSrc.Arbitrary> _vecs = new Dictionary<ProxiedInputIdentifier, PropSrc.Arbitrary>();
|
||||||
static readonly byte[] _nullvalue = new byte[0];
|
static readonly byte[] _nullvalue = new byte[0];
|
||||||
@@ -124,7 +127,7 @@ namespace Cryville.Crtr {
|
|||||||
InputProxyEntry proxy;
|
InputProxyEntry proxy;
|
||||||
if (_sproxies.TryGetValue(id.Source, out proxy)) {
|
if (_sproxies.TryGetValue(id.Source, out proxy)) {
|
||||||
_etor.ContextCascadeInsert();
|
_etor.ContextCascadeInsert();
|
||||||
float ft, tt = (float)vec.Time;
|
float ft, tt = (float)(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, new PropSrc.Arbitrary(PdtInternalType.Null, _nullvalue));
|
_etor.ContextCascadeUpdate(_var_value, new PropSrc.Arbitrary(PdtInternalType.Null, _nullvalue));
|
||||||
@@ -159,24 +162,39 @@ namespace Cryville.Crtr {
|
|||||||
PropSrc.Arbitrary fv, tv = _etor.ContextCascadeLookup(_var_value);
|
PropSrc.Arbitrary fv, tv = _etor.ContextCascadeLookup(_var_value);
|
||||||
if (!_vecs.TryGetValue(pid, out fv)) fv = new PropSrc.Arbitrary(PdtInternalType.Null, _nullvalue);
|
if (!_vecs.TryGetValue(pid, out fv)) fv = new PropSrc.Arbitrary(PdtInternalType.Null, _nullvalue);
|
||||||
if (fv.Type != PdtInternalType.Null || tv.Type != PdtInternalType.Null) {
|
if (fv.Type != PdtInternalType.Null || tv.Type != PdtInternalType.Null) {
|
||||||
if (fv.Type == PdtInternalType.Null) {
|
if (fv.Type == PdtInternalType.Null) _activeCounts[id.Source]++;
|
||||||
_activeCounts[id.Source]++;
|
|
||||||
Logger.Log("main", 0, "Input/Proxy", "active {0} # {1} (+)", id.Source, _activeCounts[id.Source]);
|
|
||||||
}
|
|
||||||
_etor.ContextCascadeInsert();
|
_etor.ContextCascadeInsert();
|
||||||
_etor.ContextCascadeUpdate(_var_fv, fv);
|
_etor.ContextCascadeUpdate(_var_fv, fv);
|
||||||
_etor.ContextCascadeUpdate(_var_tv, tv);
|
_etor.ContextCascadeUpdate(_var_tv, tv);
|
||||||
_judge.Feed(target, ft, tt);
|
_judge.Feed(target, ft, tt);
|
||||||
_etor.ContextCascadeDiscard();
|
_etor.ContextCascadeDiscard();
|
||||||
if (tv.Type == PdtInternalType.Null) {
|
if (tv.Type == PdtInternalType.Null) _activeCounts[id.Source]--;
|
||||||
_activeCounts[id.Source]--;
|
|
||||||
Logger.Log("main", 0, "Input/Proxy", "active {0} # {1} (-)", id.Source, _activeCounts[id.Source]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_judge.Cleanup(target, ft, tt);
|
_judge.Cleanup(target, ft, tt);
|
||||||
_vecs[pid] = tv;
|
_vecs[pid] = tv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void SyncTime(double time) {
|
||||||
|
foreach (var s in _sproxies.Keys) {
|
||||||
|
var h = s.Handler;
|
||||||
|
if (!_timeOrigins.ContainsKey(h))
|
||||||
|
_timeOrigins.Add(h, h.GetCurrentTimestamp() - time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void ForceTick() {
|
||||||
|
foreach (var src in _sproxies.Keys) {
|
||||||
|
if (_activeCounts[src] == 0) {
|
||||||
|
OnInput(new InputIdentifier { Source = src, Id = 0 }, new InputVector(src.Handler.GetCurrentTimestamp()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public double GetTimestampAverage() {
|
||||||
|
double result = 0;
|
||||||
|
foreach (var src in _sproxies.Keys) {
|
||||||
|
result += src.Handler.GetCurrentTimestamp() - _timeOrigins[src.Handler];
|
||||||
|
}
|
||||||
|
return result / _sproxies.Count;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,50 +5,175 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Cryville.Crtr {
|
namespace Cryville.Crtr {
|
||||||
public class Judge {
|
public class Judge {
|
||||||
|
readonly PdtEvaluator _etor;
|
||||||
readonly PdtRuleset _rs;
|
readonly PdtRuleset _rs;
|
||||||
readonly Dictionary<Identifier, float> ct
|
readonly Dictionary<Identifier, float> ct
|
||||||
= new Dictionary<Identifier, float>();
|
= new Dictionary<Identifier, float>();
|
||||||
readonly Dictionary<Identifier, Dictionary<float, JudgeEvent>> evs
|
readonly Dictionary<Identifier, List<JudgeEvent>> evs
|
||||||
= new Dictionary<Identifier, Dictionary<float, JudgeEvent>>();
|
= new Dictionary<Identifier, List<JudgeEvent>>();
|
||||||
|
readonly Dictionary<Identifier, List<JudgeEvent>> activeEvs
|
||||||
|
= new Dictionary<Identifier, List<JudgeEvent>>();
|
||||||
struct JudgeEvent {
|
struct JudgeEvent {
|
||||||
public float EndTime;
|
public float StartTime { get; set; }
|
||||||
|
public float EndTime { get; set; }
|
||||||
|
public float StartClip { get; set; }
|
||||||
|
public float EndClip { get; set; }
|
||||||
public JudgeDefinition Definition { get; set; }
|
public JudgeDefinition Definition { get; set; }
|
||||||
public ContainerState State { get; set; }
|
public ContainerState State { get; set; }
|
||||||
}
|
}
|
||||||
|
static readonly IComparer<JudgeEvent> _stcmp = new JudgeEventStartTimeComparer();
|
||||||
|
class JudgeEventStartTimeComparer : IComparer<JudgeEvent> {
|
||||||
|
public int Compare(JudgeEvent x, JudgeEvent y) {
|
||||||
|
return x.StartClip.CompareTo(y.StartClip);
|
||||||
|
}
|
||||||
|
}
|
||||||
public Judge(PdtRuleset rs) {
|
public Judge(PdtRuleset rs) {
|
||||||
|
_etor = ChartPlayer.etor;
|
||||||
_rs = rs;
|
_rs = rs;
|
||||||
foreach (var s in rs.scores) {
|
foreach (var s in rs.scores) {
|
||||||
var name = s.Key.Key;
|
var key = s.Key;
|
||||||
scoreDefs.Add(name, s.Value);
|
scoreSrcs.Add(key.Key, new PropSrc.Float(() => scores[key.Key]));
|
||||||
scores.Add(name, s.Value.init);
|
scoreOps.Add(key.Key, new PropOp.Float(v => scores[key.Key] = v));
|
||||||
|
scoreFmtKeys.Add(key.Key, IdentifierManager.SharedInstance.Request("_score_" + (string)key.Name));
|
||||||
|
scoreDefs.Add(key.Key, s.Value);
|
||||||
|
scores.Add(key.Key, s.Value.init);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void Prepare(float time, Identifier input, JudgeDefinition def, ContainerState container) {
|
public void Prepare(float st, float et, Identifier input, JudgeDefinition def, ContainerState container) {
|
||||||
Dictionary<float, JudgeEvent> list;
|
List<JudgeEvent> list;
|
||||||
if (!evs.TryGetValue(input, out list)) {
|
if (!evs.TryGetValue(input, out list)) {
|
||||||
ct.Add(input, 0);
|
ct.Add(input, 0);
|
||||||
evs.Add(input, list = new Dictionary<float, JudgeEvent>());
|
evs.Add(input, list = new List<JudgeEvent>());
|
||||||
|
activeEvs.Add(input, new List<JudgeEvent>());
|
||||||
}
|
}
|
||||||
list.Add(time + def.clip[0], new JudgeEvent { EndTime = time + def.clip[1], Definition = def, State = container });
|
var ev = new JudgeEvent {
|
||||||
|
StartTime = st,
|
||||||
|
EndTime = et,
|
||||||
|
StartClip = st + def.clip[0],
|
||||||
|
EndClip = et + def.clip[1],
|
||||||
|
Definition = def,
|
||||||
|
State = container,
|
||||||
|
};
|
||||||
|
var index = list.BinarySearch(ev, _stcmp);
|
||||||
|
if (index < 0) index = ~index;
|
||||||
|
list.Insert(index, ev);
|
||||||
}
|
}
|
||||||
public void Feed(string target, float ft, float tt) {
|
static bool _flag;
|
||||||
Logger.Log("main", 0, "Judge", "Feed {0}: {1}->{2}", target, ft, tt);
|
static readonly PropOp.Boolean _flagop = new PropOp.Boolean(v => _flag = v);
|
||||||
|
static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
|
||||||
|
static readonly int _var_tn = IdentifierManager.SharedInstance.Request("tn");
|
||||||
|
static readonly int _var_ft = IdentifierManager.SharedInstance.Request("ft");
|
||||||
|
static readonly int _var_tt = IdentifierManager.SharedInstance.Request("tt");
|
||||||
|
readonly byte[] _numbuf1 = new byte[sizeof(float)];
|
||||||
|
readonly byte[] _numbuf2 = new byte[sizeof(float)];
|
||||||
|
readonly byte[] _numbuf3 = new byte[sizeof(float)];
|
||||||
|
readonly byte[] _numbuf4 = new byte[sizeof(float)];
|
||||||
|
unsafe void LoadNum(byte[] buffer, float value) {
|
||||||
|
fixed (byte* ptr = buffer) *(float*)ptr = value;
|
||||||
}
|
}
|
||||||
public void Cleanup(string target, float ft, float tt) {
|
// Adopted from System.Collections.Generic.ArraySortHelper<T>.InternalBinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer)
|
||||||
Logger.Log("main", 0, "Judge", "Cleanup {0}: {1}->{2}", target, ft, tt);
|
int BinarySearch(List<JudgeEvent> list, float time, int stack) {
|
||||||
|
int num = 0;
|
||||||
|
int num2 = list.Count - 1;
|
||||||
|
while (num <= num2) {
|
||||||
|
int num3 = num + (num2 - num >> 1);
|
||||||
|
int num4 = -list[num3].Definition.stack.CompareTo(stack);
|
||||||
|
if (num4 == 0) num4 = list[num3].StartClip.CompareTo(time);
|
||||||
|
if (num4 == 0) return num3;
|
||||||
|
else if (num4 < 0) num = num3 + 1;
|
||||||
|
else num2 = num3 - 1;
|
||||||
|
}
|
||||||
|
return ~num;
|
||||||
}
|
}
|
||||||
public readonly Dictionary<int, ScoreDefinition> scoreDefs = new Dictionary<int, ScoreDefinition>();
|
public void Feed(Identifier target, float ft, float tt) {
|
||||||
|
Forward(target, tt);
|
||||||
|
var actlist = activeEvs[target];
|
||||||
|
if (actlist.Count > 0) {
|
||||||
|
LoadNum(_numbuf3, ft); _etor.ContextCascadeUpdate(_var_ft, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf3));
|
||||||
|
LoadNum(_numbuf4, tt); _etor.ContextCascadeUpdate(_var_tt, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf4));
|
||||||
|
var index = 0;
|
||||||
|
while (index >= 0 && index < actlist.Count) {
|
||||||
|
var ev = actlist[index];
|
||||||
|
LoadNum(_numbuf1, ev.StartTime); _etor.ContextCascadeUpdate(_var_fn, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf1));
|
||||||
|
LoadNum(_numbuf2, ev.EndTime); _etor.ContextCascadeUpdate(_var_tn, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf2));
|
||||||
|
var def = ev.Definition;
|
||||||
|
if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
|
||||||
|
else _flag = true;
|
||||||
|
if (_flag) {
|
||||||
|
if (def.scores != null) UpdateScore(def.scores);
|
||||||
|
if (def.pass != null) Pass(def.pass);
|
||||||
|
actlist.RemoveAt(index);
|
||||||
|
index = BinarySearch(actlist, ev.StartClip, def.prop);
|
||||||
|
if (index < 0) index = ~index;
|
||||||
|
}
|
||||||
|
else index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool Pass(Identifier[] ids) {
|
||||||
|
foreach (var i in ids) {
|
||||||
|
var def = _rs.judges[i];
|
||||||
|
if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
|
||||||
|
else _flag = true;
|
||||||
|
if (_flag) {
|
||||||
|
if (def.scores != null) UpdateScore(def.scores);
|
||||||
|
if (def.pass != null) Pass(def.pass);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public void Cleanup(Identifier target, float ft, float tt) {
|
||||||
|
Forward(target, tt);
|
||||||
|
var actlist = activeEvs[target];
|
||||||
|
for (int i = actlist.Count - 1; i >= 0; i--) {
|
||||||
|
JudgeEvent ev = actlist[i];
|
||||||
|
if (tt > ev.EndClip) {
|
||||||
|
actlist.RemoveAt(i);
|
||||||
|
if (ev.Definition.miss != null) Pass(ev.Definition.miss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Forward(Identifier target, float tt) {
|
||||||
|
var list = evs[target];
|
||||||
|
var actlist = activeEvs[target];
|
||||||
|
JudgeEvent ev;
|
||||||
|
while (list.Count > 0 && (ev = list[0]).StartClip <= tt) {
|
||||||
|
list.RemoveAt(0);
|
||||||
|
var index = BinarySearch(actlist, ev.StartClip, ev.Definition.stack);
|
||||||
|
if (index < 0) index = ~index;
|
||||||
|
actlist.Insert(index, ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void UpdateScore(Dictionary<ScoreOperation, PdtExpression> scoreops) {
|
||||||
|
foreach (var scoreop in scoreops) {
|
||||||
|
var key = scoreop.Key;
|
||||||
|
_etor.ContextSelfValue = scoreSrcs[key.name.Key];
|
||||||
|
_etor.Evaluate(scoreOps[key.name.Key], scoreop.Value);
|
||||||
|
foreach (var s in _rs.scores) {
|
||||||
|
if (s.Value.value != null) {
|
||||||
|
_etor.ContextSelfValue = scoreSrcs[s.Key.Key];
|
||||||
|
_etor.Evaluate(scoreOps[s.Key.Key], s.Value.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScoreCache.Clear();
|
||||||
|
}
|
||||||
|
readonly Dictionary<int, int> scoreFmtKeys = new Dictionary<int, int>();
|
||||||
|
readonly Dictionary<int, PropSrc> scoreSrcs = new Dictionary<int, PropSrc>();
|
||||||
|
readonly Dictionary<int, PropOp> scoreOps = new Dictionary<int, PropOp>();
|
||||||
|
readonly Dictionary<int, ScoreDefinition> scoreDefs = new Dictionary<int, ScoreDefinition>();
|
||||||
public readonly Dictionary<int, float> scores = new Dictionary<int, float>();
|
public readonly Dictionary<int, float> scores = new Dictionary<int, float>();
|
||||||
readonly Dictionary<int, string> ScoreCache = new Dictionary<int, string>();
|
readonly Dictionary<int, string> ScoreCache = new Dictionary<int, string>();
|
||||||
readonly object _lock = new object();
|
readonly object _lock = new object();
|
||||||
public Dictionary<int, string> GetFormattedScoreStrings() {
|
public Dictionary<int, string> GetFormattedScoreStrings() {
|
||||||
lock (_lock) {
|
lock (_lock) {
|
||||||
if (ScoreCache.Count == 0) {
|
if (ScoreCache.Count == 0) {
|
||||||
foreach (var s in scores)
|
foreach (var s in scores)
|
||||||
ScoreCache.Add(s.Key, s.Value.ToString(scoreDefs[s.Key].format));
|
ScoreCache.Add(scoreFmtKeys[s.Key], s.Value.ToString(scoreDefs[s.Key].format));
|
||||||
|
}
|
||||||
|
return ScoreCache;
|
||||||
}
|
}
|
||||||
return ScoreCache;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public string GetFullFormattedScoreString() {
|
public string GetFullFormattedScoreString() {
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
@@ -70,8 +195,10 @@ namespace Cryville.Crtr {
|
|||||||
public PdtExpression input;
|
public PdtExpression input;
|
||||||
public PdtExpression hit;
|
public PdtExpression hit;
|
||||||
public Identifier[] pass;
|
public Identifier[] pass;
|
||||||
public Identifier miss;
|
public Identifier[] miss;
|
||||||
public Dictionary<ScoreOperation, PdtExpression> scores;
|
public Dictionary<ScoreOperation, PdtExpression> scores;
|
||||||
|
public int stack;
|
||||||
|
public int prop = -1;
|
||||||
}
|
}
|
||||||
public class ScoreOperation {
|
public class ScoreOperation {
|
||||||
public Identifier name;
|
public Identifier name;
|
||||||
|
@@ -284,21 +284,15 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adopted from System.Collections.Generic.ArraySortHelper<T>.InternalBinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer)
|
// Adopted from System.Collections.Generic.ArraySortHelper<T>.InternalBinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer)
|
||||||
internal int BinarySearch(float value) {
|
int BinarySearch(float value) {
|
||||||
int num = 0;
|
int num = 0;
|
||||||
int num2 = RelativeNodes.Count - 1;
|
int num2 = RelativeNodes.Count - 1;
|
||||||
while (num <= num2) {
|
while (num <= num2) {
|
||||||
int num3 = num + (num2 - num >> 1);
|
int num3 = num + (num2 - num >> 1);
|
||||||
int num4 = RelativeNodes[num3].Time.Value.CompareTo(value);
|
int num4 = RelativeNodes[num3].Time.Value.CompareTo(value);
|
||||||
if (num4 == 0) {
|
if (num4 == 0) return num3;
|
||||||
return num3;
|
if (num4 < 0) num = num3 + 1;
|
||||||
}
|
else num2 = num3 - 1;
|
||||||
if (num4 < 0) {
|
|
||||||
num = num3 + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
num2 = num3 - 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ~num;
|
return ~num;
|
||||||
}
|
}
|
||||||
|
@@ -99,7 +99,7 @@ namespace Cryville.Crtr {
|
|||||||
ChartPlayer.etor.ContextEvent = tev;
|
ChartPlayer.etor.ContextEvent = tev;
|
||||||
ChartPlayer.etor.ContextState = s;
|
ChartPlayer.etor.ContextState = s;
|
||||||
ChartPlayer.etor.Evaluate(new PropOp.Identifier(v => name = new Identifier(v)), ruleset.judges[tev.Id].input);
|
ChartPlayer.etor.Evaluate(new PropOp.Identifier(v => name = new Identifier(v)), ruleset.judges[tev.Id].input);
|
||||||
judge.Prepare(ps.Time, name, ruleset.judges[tev.Id], cs);
|
judge.Prepare(ev.Time, ev.Time + ev.Duration, name, ruleset.judges[tev.Id], cs);
|
||||||
ChartPlayer.etor.ContextState = null;
|
ChartPlayer.etor.ContextState = null;
|
||||||
ChartPlayer.etor.ContextEvent = null;
|
ChartPlayer.etor.ContextEvent = null;
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,7 @@ namespace Cryville.Crtr {
|
|||||||
var id = new Identifier(name);
|
var id = new Identifier(name);
|
||||||
PropSrc prop;
|
PropSrc prop;
|
||||||
string str;
|
string str;
|
||||||
|
float num;
|
||||||
if (ContextEvent != null && ContextEvent.PropSrcs.TryGetValue(name, out prop)) {
|
if (ContextEvent != null && ContextEvent.PropSrcs.TryGetValue(name, out prop)) {
|
||||||
prop.Get(out type, out value);
|
prop.Get(out type, out value);
|
||||||
}
|
}
|
||||||
@@ -31,6 +32,12 @@ namespace Cryville.Crtr {
|
|||||||
var vec = ContextState.GetRawValue(id);
|
var vec = ContextState.GetRawValue(id);
|
||||||
new VectorSrc(() => vec).Get(out type, out value);
|
new VectorSrc(() => vec).Get(out type, out value);
|
||||||
}
|
}
|
||||||
|
else if (ContextJudge != null && ContextJudge.scores.TryGetValue(name, out num)) {
|
||||||
|
type = PdtInternalType.Number;
|
||||||
|
LoadNum(num);
|
||||||
|
value = _numbuf;
|
||||||
|
RevokePotentialConstant();
|
||||||
|
}
|
||||||
else if (ContextJudge != null && ContextJudge.GetFormattedScoreStrings().TryGetValue(name, out str)) {
|
else if (ContextJudge != null && ContextJudge.GetFormattedScoreStrings().TryGetValue(name, out str)) {
|
||||||
type = PdtInternalType.String;
|
type = PdtInternalType.String;
|
||||||
value = GetBytes(str);
|
value = GetBytes(str);
|
||||||
@@ -92,8 +99,8 @@ namespace Cryville.Crtr {
|
|||||||
static readonly int _colop_and = IdentifierManager.SharedInstance.Request("&");
|
static readonly int _colop_and = IdentifierManager.SharedInstance.Request("&");
|
||||||
static readonly int _colop_or = IdentifierManager.SharedInstance.Request("|");
|
static readonly int _colop_or = IdentifierManager.SharedInstance.Request("|");
|
||||||
protected override bool Collapse(int name, PdtVariableMemory param) {
|
protected override bool Collapse(int name, PdtVariableMemory param) {
|
||||||
if (name == _colop_and) return param.AsNumber() <= 0;
|
if (name == _colop_and) return param.Type == PdtInternalType.Number && param.AsNumber() <= 0;
|
||||||
else if (name == _colop_or) return param.AsNumber() > 0;
|
else if (name == _colop_or) return param.Type != PdtInternalType.Number || param.AsNumber() > 0;
|
||||||
else throw new KeyNotFoundException(string.Format("Undefined collapse operator {0}", name));
|
else throw new KeyNotFoundException(string.Format("Undefined collapse operator {0}", name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,6 +141,11 @@ namespace Cryville.Crtr {
|
|||||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("min"), new func_min(() => ContextSelfValue));
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("min"), new func_min(() => ContextSelfValue));
|
||||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("max"), new func_max(() => ContextSelfValue));
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("max"), new func_max(() => ContextSelfValue));
|
||||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("abs"), new func_abs(() => ContextSelfValue));
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("abs"), new func_abs(() => ContextSelfValue));
|
||||||
|
|
||||||
|
Func<int, PropSrc> cccb = k => ContextCascadeLookup(k);
|
||||||
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("attack_timing"), new func_attack_timing(cccb));
|
||||||
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("enter_timing"), new func_enter_timing(cccb));
|
||||||
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("release_timing"), new func_release_timing(cccb));
|
||||||
}
|
}
|
||||||
static PdtEvaluator() {
|
static PdtEvaluator() {
|
||||||
_shortops.Add(new PdtOperatorSignature("@", 2), new op_at_2());
|
_shortops.Add(new PdtOperatorSignature("@", 2), new op_at_2());
|
||||||
@@ -158,6 +170,7 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
#region Operators
|
#region Operators
|
||||||
#pragma warning disable IDE1006
|
#pragma warning disable IDE1006
|
||||||
|
#region Basic Operators
|
||||||
class op_add_1 : PdtOperator {
|
class op_add_1 : PdtOperator {
|
||||||
public op_add_1() : base(1) { }
|
public op_add_1() : base(1) { }
|
||||||
protected override void Execute() {
|
protected override void Execute() {
|
||||||
@@ -273,6 +286,8 @@ namespace Cryville.Crtr {
|
|||||||
else throw new InvalidOperationException("Not a vector or number");
|
else throw new InvalidOperationException("Not a vector or number");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
#region Basic Functions
|
||||||
class func_frame_seq : PdtOperator {
|
class func_frame_seq : PdtOperator {
|
||||||
public func_frame_seq() : base(3) { }
|
public func_frame_seq() : base(3) { }
|
||||||
protected override unsafe void Execute() {
|
protected override unsafe void Execute() {
|
||||||
@@ -303,6 +318,39 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class func_in_area : PdtOperator {
|
||||||
|
public func_in_area() : base(1) { }
|
||||||
|
protected override unsafe void Execute() {
|
||||||
|
var arg = GetOperand(0);
|
||||||
|
if (arg.Type == PdtInternalType.Error) {
|
||||||
|
throw new InvalidOperationException("Error");
|
||||||
|
}
|
||||||
|
else if (arg.Type == PdtInternalType.Number && arg.AsNumber() <= 0) {
|
||||||
|
GetReturnFrame(PdtInternalType.Null, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var ret = GetReturnFrame(arg.Type, arg.Length);
|
||||||
|
arg.CopyTo(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class func_int_map : PdtOperator {
|
||||||
|
public func_int_map(int pc) : base(pc) {
|
||||||
|
if (pc < 4) throw new ArgumentOutOfRangeException("Too few parameters for int_map");
|
||||||
|
}
|
||||||
|
protected override unsafe void Execute() {
|
||||||
|
var value = GetOperand(0).AsNumber();
|
||||||
|
var offset = GetOperand(1).AsNumber();
|
||||||
|
var step = GetOperand(2).AsNumber();
|
||||||
|
var index = (int)((value - offset) / step);
|
||||||
|
if (index < 0 || index >= LoadedOperandCount - 3) index = 0;
|
||||||
|
var hit = GetOperand(index + 3);
|
||||||
|
var ret = GetReturnFrame(hit.Type, hit.Length);
|
||||||
|
hit.CopyTo(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#region Contextual Functions
|
||||||
class func_screen_edge : PdtOperator {
|
class func_screen_edge : PdtOperator {
|
||||||
readonly Func<Transform> _ctxcb;
|
readonly Func<Transform> _ctxcb;
|
||||||
public func_screen_edge(Func<Transform> ctxcb) : base(1) {
|
public func_screen_edge(Func<Transform> ctxcb) : base(1) {
|
||||||
@@ -408,41 +456,61 @@ namespace Cryville.Crtr {
|
|||||||
ret.SetNumber(Mathf.Abs(arg));
|
ret.SetNumber(Mathf.Abs(arg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class func_in_area : PdtOperator {
|
#endregion
|
||||||
public func_in_area() : base(1) { }
|
#region Judge Functions
|
||||||
protected override unsafe void Execute() {
|
static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
|
||||||
var arg = GetOperand(0);
|
static readonly int _var_tn = IdentifierManager.SharedInstance.Request("tn");
|
||||||
if (arg.Type == PdtInternalType.Error) {
|
static readonly int _var_ft = IdentifierManager.SharedInstance.Request("ft");
|
||||||
throw new InvalidOperationException("Error");
|
static readonly int _var_tt = IdentifierManager.SharedInstance.Request("tt");
|
||||||
}
|
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
|
||||||
else if (arg.Type == PdtInternalType.Number && arg.AsNumber() <= 0) {
|
static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv");
|
||||||
GetReturnFrame(PdtInternalType.Null, 0);
|
abstract class JudgeFunction : PdtOperator {
|
||||||
}
|
readonly Func<int, PropSrc> _ctxcb;
|
||||||
else {
|
protected JudgeFunction(int pc, Func<int, PropSrc> ctxcb) : base(pc) {
|
||||||
var ret = GetReturnFrame(arg.Type, arg.Length);
|
_ctxcb = ctxcb;
|
||||||
arg.CopyTo(ret);
|
}
|
||||||
}
|
protected sealed override void Execute() {
|
||||||
|
var ret = GetReturnFrame(PdtInternalType.Number, sizeof(float));
|
||||||
|
var fn = oputil.AsNumber(_ctxcb(_var_fn));
|
||||||
|
var tn = oputil.AsNumber(_ctxcb(_var_tn));
|
||||||
|
var ft = oputil.AsNumber(_ctxcb(_var_ft));
|
||||||
|
var tt = oputil.AsNumber(_ctxcb(_var_tt));
|
||||||
|
var fv = oputil.AsVector(_ctxcb(_var_fv));
|
||||||
|
var tv = oputil.AsVector(_ctxcb(_var_tv));
|
||||||
|
ret.SetNumber(ExecuteImpl(fn, tn, ft, tt, fv, tv) ? 1 : 0);
|
||||||
|
}
|
||||||
|
protected abstract bool ExecuteImpl(float fn, float tn, float ft, float tt, Vector3? fv, Vector3? tv);
|
||||||
|
}
|
||||||
|
class func_attack_timing : JudgeFunction {
|
||||||
|
public func_attack_timing(Func<int, PropSrc> ctxcb) : base(2, ctxcb) { }
|
||||||
|
protected override bool ExecuteImpl(float fn, float tn, float ft, float tt, Vector3? fv, Vector3? tv) {
|
||||||
|
if (fv != null) return false;
|
||||||
|
var t0 = GetOperand(0).AsNumber() + fn;
|
||||||
|
var t1 = GetOperand(1).AsNumber() + tn;
|
||||||
|
return tt > t0 && tt <= t1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class func_int_map : PdtOperator {
|
class func_enter_timing : JudgeFunction {
|
||||||
public func_int_map(int pc) : base(pc) {
|
public func_enter_timing(Func<int, PropSrc> ctxcb) : base(1, ctxcb) { }
|
||||||
if (pc < 4) throw new ArgumentOutOfRangeException("Too few parameters for int_map");
|
protected override bool ExecuteImpl(float fn, float tn, float ft, float tt, Vector3? fv, Vector3? tv) {
|
||||||
}
|
if (fv == null || tv == null) return false;
|
||||||
protected override unsafe void Execute() {
|
var t0 = GetOperand(0).AsNumber() + fn;
|
||||||
var value = GetOperand(0).AsNumber();
|
return ft < t0 && tt >= t0;
|
||||||
var offset = GetOperand(1).AsNumber();
|
|
||||||
var step = GetOperand(2).AsNumber();
|
|
||||||
var index = (int)((value - offset) / step);
|
|
||||||
if (index < 0 || index >= LoadedOperandCount - 3) index = 0;
|
|
||||||
var hit = GetOperand(index + 3);
|
|
||||||
var ret = GetReturnFrame(hit.Type, hit.Length);
|
|
||||||
hit.CopyTo(ret);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class func_release_timing : JudgeFunction {
|
||||||
|
public func_release_timing(Func<int, PropSrc> ctxcb) : base(2, ctxcb) { }
|
||||||
|
protected override bool ExecuteImpl(float fn, float tn, float ft, float tt, Vector3? fv, Vector3? tv) {
|
||||||
|
if (tv != null) return false;
|
||||||
|
var t0 = GetOperand(0).AsNumber() + fn;
|
||||||
|
var t1 = GetOperand(1).AsNumber() + tn;
|
||||||
|
return ft > t0 && ft <= t1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
unsafe static class oputil {
|
unsafe static class oputil {
|
||||||
public static float AsNumber(PropSrc src) {
|
public static float AsNumber(PropSrc src) {
|
||||||
if (src == null)
|
if (src == null) throw new ArgumentNullException("src");
|
||||||
throw new ArgumentNullException("src");
|
|
||||||
int type; byte[] value;
|
int type; byte[] value;
|
||||||
src.Get(out type, out value);
|
src.Get(out type, out value);
|
||||||
if (type != PdtInternalType.Number)
|
if (type != PdtInternalType.Number)
|
||||||
@@ -451,6 +519,25 @@ namespace Cryville.Crtr {
|
|||||||
return *(float*)ptr;
|
return *(float*)ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static Vector3? AsVector(PropSrc src) {
|
||||||
|
if (src == null) throw new ArgumentNullException("src");
|
||||||
|
int type; byte[] value;
|
||||||
|
src.Get(out type, out value);
|
||||||
|
if (type == PdtInternalType.Vector) {
|
||||||
|
fixed (byte* ptr = value) {
|
||||||
|
return *(Vector3*)ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == PdtInternalType.Number) {
|
||||||
|
fixed (byte* ptr = value) {
|
||||||
|
return new Vector3(*(float*)ptr, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == PdtInternalType.Null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else throw new ArgumentException("Not a number");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#pragma warning restore IDE1006
|
#pragma warning restore IDE1006
|
||||||
#endregion
|
#endregion
|
||||||
|
@@ -21,7 +21,7 @@ namespace Cryville.Crtr {
|
|||||||
readonly Action<bool> _cb;
|
readonly Action<bool> _cb;
|
||||||
public Boolean(Action<bool> cb) { _cb = cb; }
|
public Boolean(Action<bool> cb) { _cb = cb; }
|
||||||
protected override void Execute() {
|
protected override void Execute() {
|
||||||
_cb(GetOperand(0).AsNumber() != 0);
|
_cb(GetOperand(0).AsNumber() > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class Integer : PropOp {
|
public class Integer : PropOp {
|
||||||
|
@@ -45,8 +45,12 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
foreach (var j in judges.Values) {
|
foreach (var j in judges.Values) {
|
||||||
if (j.hit != null) etor.Optimize(j.hit);
|
if (j.hit != null) etor.Optimize(j.hit);
|
||||||
if (j.scores != null) foreach (var e in j.scores.Values) {
|
if (j.scores != null) {
|
||||||
etor.Optimize(e);
|
foreach (var s in j.scores) {
|
||||||
|
if (s.Key.op != default(Identifier))
|
||||||
|
etor.PatchCompound(s.Key.name.Key, s.Key.op.Key, s.Value);
|
||||||
|
etor.Optimize(s.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var s in scores.Values) {
|
foreach (var s in scores.Values) {
|
||||||
|
@@ -37,3 +37,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
|
|
||||||
// Index operator not supported
|
// Index operator not supported
|
||||||
[assembly: SuppressMessage("Style", "IDE0056")]
|
[assembly: SuppressMessage("Style", "IDE0056")]
|
||||||
|
|
||||||
|
// Local function not supported
|
||||||
|
[assembly: SuppressMessage("Style", "IDE0039")]
|
||||||
|
Reference in New Issue
Block a user