Implement primary judge result passing.

This commit is contained in:
2023-06-02 18:17:10 +08:00
parent 59b4f14fb3
commit d5ba09cbea

View File

@@ -8,9 +8,14 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Text.Formatting; using System.Text.Formatting;
using UnityEngine;
using UnsafeIL; using UnsafeIL;
namespace Cryville.Crtr { namespace Cryville.Crtr {
internal struct JudgeResult {
public float? Time { get; set; }
public Vector4 Vector { get; set; }
}
internal struct JudgeEvent { internal struct JudgeEvent {
public double StartTime { get; set; } public double StartTime { get; set; }
public double EndTime { get; set; } public double EndTime { get; set; }
@@ -19,6 +24,7 @@ namespace Cryville.Crtr {
public Chart.Judge BaseEvent { get; set; } public Chart.Judge BaseEvent { get; set; }
public JudgeDefinition Definition { get; set; } public JudgeDefinition Definition { get; set; }
public NoteHandler Handler { get; set; } public NoteHandler Handler { get; set; }
public JudgeResult JudgeResult { get; set; }
} }
internal interface IJudge { internal interface IJudge {
bool Pass(JudgeEvent ev, float time, Identifier[] ids, int depth); bool Pass(JudgeEvent ev, float time, Identifier[] ids, int depth);
@@ -52,6 +58,8 @@ namespace Cryville.Crtr {
_numsrc2 = new PropSrc.Float(() => _numbuf2); _numsrc2 = new PropSrc.Float(() => _numbuf2);
_numsrc3 = new PropSrc.Float(() => _numbuf3); _numsrc3 = new PropSrc.Float(() => _numbuf3);
_numsrc4 = new PropSrc.Float(() => _numbuf4); _numsrc4 = new PropSrc.Float(() => _numbuf4);
_jnumsrc = new PropSrc.Float(() => _jnumbuf);
_jvecsrc = new PropSrc.Vector4(() => _jvecbuf);
_identop = new PropOp.Identifier(v => _identbuf = new Identifier(v)); _identop = new PropOp.Identifier(v => _identbuf = new Identifier(v));
_clipop = new PropOp.Clip(v => _clipbuf = v); _clipop = new PropOp.Clip(v => _clipbuf = v);
_rs.judges.TryGetValue(new Identifier(_var_pause), out _judgePause); _rs.judges.TryGetValue(new Identifier(_var_pause), out _judgePause);
@@ -113,23 +121,40 @@ namespace Cryville.Crtr {
readonly float[] _buf = new float[MAX_SORTS]; readonly float[] _buf = new float[MAX_SORTS];
readonly float[] _sorts = new float[MAX_SORTS]; readonly float[] _sorts = new float[MAX_SORTS];
public bool LastHit { get; private set; } public bool LastHit { get; private set; }
public JudgeResult JudgeResult { get; private set; }
public HitOp() : base(MAX_SORTS) { } public HitOp() : base(MAX_SORTS) { }
protected override unsafe void Execute() { protected override unsafe void Execute() {
LastHit = false; LastHit = false;
var judgeResult = new JudgeResult();
var judgeVector = new Vector4();
for (int i = 0; i < LoadedOperandCount; i++) { for (int i = 0; i < LoadedOperandCount; i++) {
var sort = GetOperand(i).AsNumber(); var op = GetOperand(i);
var sort = op.AsNumber();
if (sort <= 0) return; if (sort <= 0) return;
if (!LastHit && sort < _sorts[i]) return; if (!LastHit) {
if (sort < _sorts[i]) return;
if (sort > _sorts[i]) LastHit = true; if (sort > _sorts[i]) LastHit = true;
}
_buf[i] = sort; _buf[i] = sort;
if (op.Type == PdtInternalType.Vector) {
var len = (op.Length - sizeof(int)) / sizeof(float);
if (len > 1) {
judgeResult.Time = op.AsNumber(sizeof(float));
for (int j = 0; j < 4; j++) {
if (len > j + 2) judgeVector[j] = op.AsNumber((j + 2) * sizeof(float));
}
judgeResult.Vector = judgeVector;
}
}
} }
if (!LastHit) return; if (!LastHit) return;
Array.Clear(_buf, LoadedOperandCount, MAX_SORTS - LoadedOperandCount); Array.Clear(_buf, LoadedOperandCount, MAX_SORTS - LoadedOperandCount);
fixed (float* ptrsrc = _buf, ptrdest = _sorts) { fixed (float* ptrsrc = _buf, ptrdest = _sorts) {
Unsafe.CopyBlock(ptrdest, ptrsrc, MAX_SORTS * sizeof(float)); Unsafe.CopyBlock(ptrdest, ptrsrc, MAX_SORTS * sizeof(float));
} }
JudgeResult = judgeResult;
} }
public void Clear() { Array.Clear(_sorts, 0, MAX_SORTS); } public void Clear() { Array.Clear(_sorts, 0, MAX_SORTS); }
@@ -140,6 +165,12 @@ namespace Cryville.Crtr {
static readonly int _var_tt = IdentifierManager.Shared.Request("input_time_to"); static readonly int _var_tt = IdentifierManager.Shared.Request("input_time_to");
float _numbuf1, _numbuf2, _numbuf3, _numbuf4; float _numbuf1, _numbuf2, _numbuf3, _numbuf4;
readonly PropSrc _numsrc1, _numsrc2, _numsrc3, _numsrc4; readonly PropSrc _numsrc1, _numsrc2, _numsrc3, _numsrc4;
static readonly int _var_jt = IdentifierManager.Shared.Request("judge_time");
static readonly int _var_jv = IdentifierManager.Shared.Request("judge_vec");
float _jnumbuf; Vector4 _jvecbuf;
readonly PropSrc _jnumsrc, _jvecsrc;
unsafe void LoadNum(byte[] buffer, float value) { unsafe void LoadNum(byte[] buffer, float value) {
fixed (byte* ptr = buffer) *(float*)ptr = value; fixed (byte* ptr = buffer) *(float*)ptr = value;
} }
@@ -191,7 +222,10 @@ namespace Cryville.Crtr {
var def = ev.Definition; var def = ev.Definition;
if (def.hit != null) { if (def.hit != null) {
_etor.Evaluate(_hitop, def.hit); _etor.Evaluate(_hitop, def.hit);
if (_hitop.LastHit) hitIndex = index; if (_hitop.LastHit) {
hitIndex = index;
ev.JudgeResult = _hitop.JudgeResult;
}
} }
else if (hitIndex == -1) hitIndex = index; else if (hitIndex == -1) hitIndex = index;
index++; index++;
@@ -242,6 +276,10 @@ namespace Cryville.Crtr {
} }
} }
void Execute(JudgeEvent ev, float time, PairList<JudgeAction, PdtExpression> actions, int depth = 0) { void Execute(JudgeEvent ev, float time, PairList<JudgeAction, PdtExpression> actions, int depth = 0) {
if (ev.JudgeResult.Time != null) {
_jnumbuf = ev.JudgeResult.Time.Value; _jnumsrc.Invalidate(); _etor.ContextCascadeUpdate(_var_jt, _jnumsrc);
_jvecbuf = ev.JudgeResult.Vector; _jvecsrc.Invalidate(); _etor.ContextCascadeUpdate(_var_jv, _jvecsrc);
}
foreach (var a in actions) { foreach (var a in actions) {
if (a.Key.Execute(this, ev, time, a.Value, depth)) break; if (a.Key.Execute(this, ev, time, a.Value, depth)) break;
} }
@@ -250,10 +288,15 @@ namespace Cryville.Crtr {
if (depth >= 16) throw new JudgePropagationException(); if (depth >= 16) throw new JudgePropagationException();
foreach (var i in ids) { foreach (var i in ids) {
var def = _rs.judges[i]; var def = _rs.judges[i];
if (def.hit != null) _etor.Evaluate(_flagop, def.hit); bool hitFlag;
else _flag = true; if (def.hit != null) {
if (_flag) { _hitop.Clear();
if (def.on_hit != null) Execute(ev, time, def.on_hit, depth + 1); _etor.Evaluate(_hitop, def.hit);
hitFlag = _hitop.LastHit;
}
else hitFlag = true;
if (hitFlag) {
Execute(ev, time, def.on_hit, depth + 1);
ev.Handler.ReportJudge(ev, time, i); ev.Handler.ReportJudge(ev, time, i);
return true; return true;
} }