19 Commits

Author SHA1 Message Date
e8f8593555 Fix conditional compilation. 2023-01-01 20:07:58 +08:00
2b5bc5dd08 Optimize GC for RMV pool. 2023-01-01 19:03:19 +08:00
cf6186aa16 Add judge anchor stub. 2023-01-01 19:02:49 +08:00
4d7773a2ac Cleanup anchor related code. 2023-01-01 19:01:34 +08:00
e8f74399f2 Implement judge report. 2023-01-01 19:00:19 +08:00
ca72f7adb5 Implement temporary event injection. (Amend) 2023-01-01 18:55:22 +08:00
5e19a8b886 Code cleanup. 2023-01-01 18:54:53 +08:00
a416f772d4 Add force sync frames. 2023-01-01 18:52:28 +08:00
989a6b5554 Fix osu chart ruleset and effect point. 2023-01-01 18:50:03 +08:00
732af15d9b Add Discord GameSDK. 2023-01-01 18:48:14 +08:00
8cdab36cd6 Fix handling for first timing point of osu chart. 2022-12-31 18:17:24 +08:00
44180c7e0f Optimize GC for PropSrc. 2022-12-25 22:20:46 +08:00
e589e37640 Code cleanup. 2022-12-24 19:12:16 +08:00
94107de97d Optimize GC for temporary anchor event injection. 2022-12-23 17:46:29 +08:00
13c55dc23e Optimize GC for PropOp.Enum<T>. 2022-12-23 17:45:07 +08:00
617eddc030 Reimplement cur anchor. 2022-12-23 16:28:48 +08:00
7475b19547 Implement temporary event injection. 2022-12-23 16:27:34 +08:00
0049ace91a Refactor polysec.suppressed to polysec.partial and polysec.part. 2022-12-23 16:25:57 +08:00
356f4df9a9 Exception cleanup. Code cleanup. 2022-12-23 15:20:16 +08:00
61 changed files with 5235 additions and 253 deletions

View File

@@ -19,7 +19,8 @@ namespace Cryville.Common.Pdt {
/// <returns>The operand at the specified index.</returns>
/// <exception cref="IndexOutOfRangeException"><paramref name="index" /> is not less than <see cref="LoadedOperandCount" /> or less than 0.</exception>
protected PdtVariableMemory GetOperand(int index) {
if (index >= LoadedOperandCount || index < 0) throw new IndexOutOfRangeException();
if (index >= LoadedOperandCount || index < 0)
throw new ArgumentOutOfRangeException("index");
int i = index + _loadindex;
return _operands[i];
}
@@ -33,11 +34,9 @@ namespace Cryville.Common.Pdt {
_operands = new PdtVariableMemory[pc];
}
PdtEvaluatorBase _etor;
bool _failure = false;
bool _rfreq = true;
internal void Begin(PdtEvaluatorBase etor) {
_etor = etor;
_failure = false;
_loadindex = ParamCount;
}
internal void LoadOperand(PdtVariableMemory mem) {
@@ -51,10 +50,6 @@ namespace Cryville.Common.Pdt {
if (_rfreq) _etor.DiscardStack();
throw new InvalidOperationException("Evaluation failed", ex);
}
if (_failure) {
if (_rfreq) _etor.DiscardStack();
throw new InvalidOperationException("Evaluation failed");
}
if (!_rfreq && !noset) throw new InvalidOperationException("Return frame not set");
}
/// <summary>
@@ -69,10 +64,7 @@ namespace Cryville.Common.Pdt {
/// <returns>The return frame.</returns>
/// <exception cref="InvalidOperationException">The return frame has already been requested.</exception>
protected PdtVariableMemory GetReturnFrame(int type, int len) {
if (_rfreq) {
_failure = true;
throw new InvalidOperationException("Return frame already requested");
}
if (_rfreq) throw new InvalidOperationException("Return frame requested twice");
_rfreq = true;
return _etor.StackAlloc(type, _prmem, len);
}

View File

@@ -98,7 +98,7 @@ namespace Cryville.Common.Unity {
#elif UNITY_ANDROID
GameObject sbtn = GameObject.Instantiate<GameObject>(prefabButton);
sbtn.GetComponentInChildren<Text>().text = "Storage";
sbtn.GetComponentInChildren<Button>().onClick.AddListener(() => OnDriveChanged(new DirectoryInfo(androidStorage)));
sbtn.GetComponentInChildren<Button>().onClick.AddListener(() => ChangeDirectory(new DirectoryInfo(androidStorage)));
sbtn.transform.SetParent(drives, false);
#else
#error No update GUI logic

View File

@@ -28,19 +28,19 @@ namespace Cryville.Common.Unity.Input {
}
public override bool IsNullable(int type) {
if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
if (type != 0) throw new ArgumentOutOfRangeException("type");
return false;
}
public override byte GetDimension(int type) {
if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
if (type != 0) throw new ArgumentOutOfRangeException("type");
return 2;
}
public override string GetTypeName(int type) {
switch (type) {
case 0: return "Mouse Position";
default: throw new ArgumentOutOfRangeException(nameof(type));
default: throw new ArgumentOutOfRangeException("type");
}
}

View File

@@ -28,19 +28,19 @@ namespace Cryville.Common.Unity.Input {
}
public override bool IsNullable(int type) {
if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
if (type != 0) throw new ArgumentOutOfRangeException("type");
return true;
}
public override byte GetDimension(int type) {
if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
if (type != 0) throw new ArgumentOutOfRangeException("type");
return 2;
}
public override string GetTypeName(int type) {
switch (type) {
case 0: return "Touch";
default: throw new ArgumentOutOfRangeException(nameof(type));
default: throw new ArgumentOutOfRangeException("type");
}
}

View File

@@ -73,6 +73,9 @@ namespace Cryville.Crtr.Browsing {
Application.LoadLevelAdditive("Play");
#endif
GameObject.Find("/Master").GetComponent<Master>().HideMenu();
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
DiscordController.Instance.SetPlaying(string.Format("{0} - {1}", detail.Meta.song.name, detail.Meta.name), detail.Meta.length);
#endif
}
public void OpenConfig(int id, ChartDetail detail) {

View File

@@ -203,7 +203,7 @@ namespace Cryville.Crtr {
public virtual EventList GetEventsOfType(string type) {
switch (type) {
case "motions": return new EventList<Chart.Motion>(motions);
default: throw new ArgumentException("Unknown type");
default: throw new ArgumentException(string.Format("Unknown event type {0}", type));
}
}
}

View File

@@ -54,8 +54,8 @@ namespace Cryville.Crtr {
static bool disableGC = true;
static float clippingDist = 1f;
static float renderDist = 6f;
static float renderStep = 0.05f;
public static float actualRenderStep = 0f;
static double renderStep = 0.05;
public static double actualRenderStep = 0;
static bool autoRenderStep = false;
public static float soundOffset = 0;
static float startOffset = 0;
@@ -111,7 +111,7 @@ namespace Cryville.Crtr {
bool texloaddone;
diag::Stopwatch texloadtimer = new diag::Stopwatch();
bool firstFrame;
int forceSyncFrames;
double atime0;
void Update() {
if (started) GameUpdate();
@@ -123,10 +123,18 @@ namespace Cryville.Crtr {
try {
if (Screen.width != screenSize.x || Screen.height != screenSize.y)
throw new InvalidOperationException("Window resized while playing");
float dt = firstFrame
? 1f / Application.targetFrameRate
: Time.deltaTime;
firstFrame = false;
double dt, step;
if (forceSyncFrames != 0) {
forceSyncFrames--;
double target = Game.AudioClient.Position - atime0;
dt = target - cbus.Time;
step = autoRenderStep ? 1f / Application.targetFrameRate : renderStep;
inputProxy.SyncTime(target);
}
else {
dt = Time.deltaTime;
step = autoRenderStep ? Time.smoothDeltaTime : renderStep;
}
inputProxy.ForceTick();
cbus.ForwardByTime(dt);
bbus.ForwardByTime(dt);
@@ -135,10 +143,6 @@ namespace Cryville.Crtr {
bbus.CopyTo(2, tbus);
bbus.CopyTo(3, nbus);
UnityEngine.Profiling.Profiler.EndSample();
float step = autoRenderStep ? ( firstFrame
? 1f / Application.targetFrameRate
: Time.smoothDeltaTime
) : renderStep;
actualRenderStep = step;
nbus.ForwardStepByTime(clippingDist, step);
@@ -250,14 +254,15 @@ namespace Cryville.Crtr {
status.text = sttext;
}
void OnCameraPostRender(Camera cam) {
if (!started) return;
if (!logEnabled) return;
if (started) timetext = string.Format(
"\nSTime: {0:R}\nATime: {1:R}\nITime: {2:R}",
timetext = string.Format(
"\nSTime: {0:R}s {3}\ndATime: {1:+0.0ms;-0.0ms;0} {3}\ndITime: {2:+0.0ms;-0.0ms;0} {3}",
cbus.Time,
Game.AudioClient.Position - atime0,
inputProxy.GetTimestampAverage()
(Game.AudioClient.Position - atime0 - cbus.Time) * 1e3,
(inputProxy.GetTimestampAverage() - cbus.Time) * 1e3,
forceSyncFrames != 0 ? "(force sync)" : ""
);
else timetext = string.Empty;
}
#endregion
@@ -278,6 +283,9 @@ namespace Cryville.Crtr {
SceneManager.UnloadSceneAsync("Play");
#elif UNITY_5_3_OR_NEWER
SceneManager.UnloadScene("Play");
#endif
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
DiscordController.Instance.SetIdle();
#endif
}
#pragma warning restore IDE1006
@@ -308,7 +316,7 @@ namespace Cryville.Crtr {
autoRenderStep = renderStep == 0;
soundOffset = Settings.Default.SoundOffset;
startOffset = Settings.Default.StartOffset;
firstFrame = true;
forceSyncFrames= Settings.Default.ForceSyncFrames;
texloaddone = false;
Game.NetworkTaskWorker.SuspendBackgroundTasks();
Game.AudioSession = Game.AudioSequencer.NewSession();
@@ -542,8 +550,6 @@ namespace Cryville.Crtr {
using (var pbus = cbus.Clone(16)) {
pbus.Forward();
}
Logger.Log("main", 0, "Load/WorkerThread", "Patching events");
cbus.DoPatch();
Logger.Log("main", 0, "Load/WorkerThread", "Cloning states (type 1)");
bbus = cbus.Clone(1, -clippingDist);

View File

@@ -9,10 +9,17 @@ namespace Cryville.Crtr.Components {
protected Vector3? prevpt;
protected Quaternion? prevrot;
protected int vertCount = 0;
bool suppressed;
Part part = Part.whole;
enum Part {
whole = 0,
idle = 1,
start = 2,
end = 3,
}
public SectionalGameObject() {
SubmitProperty("suppressed", new PropOp.Boolean(v => suppressed = v), 2);
SubmitProperty("partial", new PropOp.Boolean(v => part = Part.idle));
SubmitProperty("part", new PropOp.Enum<Part>(v => part = v, v => (Part)v));
}
protected override void OnDestroy() {
@@ -28,7 +35,7 @@ namespace Cryville.Crtr.Components {
}
public void AppendPoint(Vector3 p, Quaternion r) {
if (prevpt == p && prevrot == r || suppressed) return;
if (prevpt == p && prevrot == r || ((int)part & 1) == 1) return;
AppendPointInternal(p, r);
// if (!headGenerated) Logger.Log("main", 0, "Skin/Polysec", "{0}", r);
prevpt = p;

View File

@@ -19,7 +19,7 @@ namespace Cryville.Crtr.Components {
private set;
}
public Rect Rect {
get { return Frame.frame; }
get { return Frame.Frame; }
}
/// <summary>
/// The ratio of width divided by height.
@@ -61,7 +61,7 @@ namespace Cryville.Crtr.Components {
public class SpritePlane : SpriteBase {
public SpritePlane() {
SubmitProperty("frame", new PropOp.String(v => Frame = v));
SubmitProperty("fit", new PropOp.Enum<FitMode>(v => Fit = v));
SubmitProperty("fit", new PropOp.Enum<FitMode>(v => Fit = v, v => (FitMode)v));
SubmitProperty("opacity", new PropOp.Float(v => Opacity = v));
}

View File

@@ -63,13 +63,13 @@ namespace Cryville.Crtr.Components {
case 1: x = _border.x; bx = b.x; break;
case 2: x = _border.y; bx = b.y; break;
case 3: x = 1; bx = 1; break;
default: throw new Exception();
default: throw new NotSupportedException("Built-in resource corrupted");
}
float y;
switch ((int)muv[i].y) {
case 0: y = 0; break;
case 3: y = 1; break;
default: throw new Exception();
default: throw new NotSupportedException("Built-in resource corrupted");
}
uv[i] = frameInfo.Frame.GetUV(x, y);
bx -= 0.5f; y -= 0.5f;

View File

@@ -79,7 +79,7 @@ namespace Cryville.Crtr.Components {
foreach (var f in m_frames) {
f.Value.Load();
if (frameHeight == 0) frameHeight = f.Value.Rect.height;
else if (frameHeight != f.Value.Rect.height) throw new Exception("Inconsistent frame height");
else if (frameHeight != f.Value.Rect.height) throw new Exception("Inconsistent frame height for text component");
var tex = f.Value.Frame.Texture;
if (!meshes.ContainsKey(tex)) {
var m = new MeshWrapper();

View File

@@ -0,0 +1,56 @@
using Discord;
using System;
using UnityEngine;
namespace Cryville.Crtr {
internal class DiscordController : MonoBehaviour {
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
public static DiscordController Instance;
const long CLIENT_ID = 1059021675578007622L;
Discord.Discord dc;
ActivityManager am;
long launchTime;
void Start() {
Instance = this;
launchTime = (long)(DateTime.UtcNow - DateTime.UnixEpoch).TotalSeconds;
dc = new Discord.Discord(CLIENT_ID, (UInt64)CreateFlags.Default);
am = dc.GetActivityManager();
SetIdle();
}
void Update() {
dc.RunCallbacks();
}
void OnApplicationQuit() {
dc.Dispose();
}
void Callback(Result result) { }
public void SetIdle() {
am.UpdateActivity(new Activity {
State = "Idle",
Instance = false,
Timestamps = { Start = launchTime },
}, Callback);
}
public void SetPlaying(string detail, double? duration) {
long now = (long)(DateTime.UtcNow - DateTime.UnixEpoch).TotalSeconds;
am.UpdateActivity(new Activity {
State = "Playing a chart",
Details = detail,
Instance = true,
Timestamps = {
Start = now,
End = duration == null ? 0 : now + (long)duration,
},
}, Callback);
}
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7f7c5da9a520bef4e832e2f89f7b737f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,5 @@
using Cryville.Common;
using Cryville.Common.Buffers;
using Cryville.Crtr.Components;
using System;
using System.Collections.Generic;
@@ -41,26 +42,11 @@ namespace Cryville.Crtr.Event {
protected Transform a_cur;
protected Transform a_head;
protected Transform a_tail;
public Vector3 Position {
get;
protected set;
}
public Quaternion Rotation {
get;
protected set;
}
public bool Alive {
get;
private set;
}
public bool Awoken {
get;
private set;
}
public bool Disposed {
get;
private set;
}
public Vector3 Position { get; protected set; }
public Quaternion Rotation { get; protected set; }
public bool Alive { get; private set; }
public bool Awoken { get; private set; }
public bool Disposed { get; private set; }
public EventContainer Container {
get { return cs.Container; }
@@ -84,15 +70,16 @@ namespace Cryville.Crtr.Event {
gogroup = new GameObject(TypeName + ":" + Container.GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
if (cs.Parent != null)
gogroup.SetParent(cs.Parent.Handler.gogroup, false);
a_cur = RegisterAnchor(_a_cur);
a_head = RegisterAnchor(_a_head);
a_tail = RegisterAnchor(_a_tail);
a_cur = RegisterAnchor(_a_cur).Transform;
a_head = RegisterAnchor(_a_head).Transform;
a_tail = RegisterAnchor(_a_tail).Transform;
}
protected Transform RegisterAnchor(int name) {
protected Anchor RegisterAnchor(int name) {
var go = new GameObject("." + IdentifierManager.SharedInstance.Retrieve(name)).transform;
go.SetParent(gogroup, false);
Anchors.Add(name, new Anchor() { Transform = go });
return go;
var result = new Anchor() { Transform = go };
Anchors.Add(name, result);
return result;
}
/// <summary>
@@ -132,13 +119,33 @@ namespace Cryville.Crtr.Event {
Init();
}
}
static readonly SimpleObjectPool<StampedEvent.Anchor> anchorEvPool
= new SimpleObjectPool<StampedEvent.Anchor>(1024);
protected void PushAnchorEvent(int name, double time) {
var tev = anchorEvPool.Rent();
tev.Time = time;
tev.Container = Container;
tev.Name = name;
ts.Bus.PushTempEvent(tev);
}
public virtual void Update(ContainerState s, StampedEvent ev) {
bool flag = !Awoken && s.CloneType >= 2 && s.CloneType < 16;
if (flag) PreAwake(s);
if (s.CloneType <= 2) if (gogroup) skinContainer.MatchDynamic(s);
if (flag) Awake(s);
}
public virtual void ExUpdate(ContainerState s, StampedEvent ev) { }
public virtual void ExUpdate(ContainerState s, StampedEvent ev) {
if (ev is StampedEvent.Anchor) {
var tev = (StampedEvent.Anchor)ev;
if (gogroup) {
OpenAnchor(tev.Name);
Anchors[tev.Name].Transform.SetPositionAndRotation(Position, Rotation);
skinContainer.MatchDynamic(s);
CloseAnchor(tev.Name);
}
anchorEvPool.Return(tev);
}
}
public virtual void MotionUpdate(byte ct, Chart.Motion ev) { }
public virtual void EndUpdate(ContainerState s) {
if (s.CloneType < 16) {
@@ -146,7 +153,9 @@ namespace Cryville.Crtr.Event {
if (gogroup && s.CloneType <= 2) skinContainer.MatchDynamic(s);
}
}
public virtual void Anchor() { }
public virtual void Anchor() {
if (cs.Working) PushAnchorEvent(_a_cur, cs.Time);
}
protected void OpenAnchor(int name) {
if (Anchors.ContainsKey(name)) Anchors[name].Open();
}

View File

@@ -205,7 +205,7 @@ namespace Cryville.Crtr.Event {
public void AttachHandler(ContainerHandler h) {
if (Handler != null)
throw new InvalidOperationException();
throw new InvalidOperationException("Handler attached twice");
Handler = h;
h.cs = this;
}
@@ -219,7 +219,7 @@ namespace Cryville.Crtr.Event {
if (!CachedValues.TryGetValue(key, out tr))
CachedValues.Add(key, tr = new CacheEntry { Valid = false });
if (tr.Value == null)
tr.Value = (Vector)ReflectionHelper.InvokeEmptyConstructor(ChartPlayer.motionRegistry[key].Type);
tr.Value = RMVPool.Rent(key).AbsoluteValue;
Vector r = tr.Value;
#if !DISABLE_CACHE
if (tr.Valid) return r;

View File

@@ -33,6 +33,7 @@ namespace Cryville.Crtr.Event {
r.activeContainers = new List<EventContainer>();
r.workingStates = new HashSet<ContainerState>();
r.invalidatedStates = new HashSet<ContainerState>();
r.tempEvents = new List<StampedEvent>();
r.Time += offsetTime;
r.RootState = RootState.Clone(ct);
r.RootState.StartUpdate();
@@ -99,39 +100,46 @@ namespace Cryville.Crtr.Event {
s.AttachSystems(skin, judge);
}
readonly List<StampedEvent> patch = new List<StampedEvent>();
public void IssuePatch(IEnumerable<StampedEvent> l) {
patch.AddRange(l);
}
public void DoPatch() {
foreach (var ev in patch) {
var batch = new EventBatch(ev.Time);
var batchIndex = events.BinarySearch(batch);
if (batchIndex >= 0) batch = events[batchIndex];
else events.Insert(~batchIndex, batch);
batch.Add(ev);
}
patch.Clear();
List<StampedEvent> tempEvents = new List<StampedEvent>();
public void PushTempEvent(StampedEvent ev) {
var index = tempEvents.BinarySearch(ev);
if (index < 0) index = ~index;
tempEvents.Insert(index, ev);
}
public override void ForwardOnceToTime(double toTime, Action<EventBatch> callback = null) {
if (EventId < events.Count && events[EventId].Time <= toTime) {
Time = events[EventId].Time;
var batch = events[EventId];
double time1 = EventId < events.Count ? events[EventId].Time : double.PositiveInfinity;
double time2 = tempEvents.Count > 0 ? tempEvents[0].Time : double.PositiveInfinity;
double time0 = Math.Min(time1, time2);
if (time0 <= toTime && time0 != double.PositiveInfinity) {
Time = time0;
foreach (var s in workingStates) s.Handle(null);
ValidateStates();
for (var i = 0; i < batch.Count; i++) {
var ev = batch[i];
if (ev.Container != null) {
EnsureActivity(ev.Container);
states[ev.Container].Handle(ev);
if (time1 == time0) {
var batch = events[EventId];
for (var i = 0; i < batch.Count; i++) {
var ev = batch[i];
if (ev.Container != null) {
EnsureActivity(ev.Container);
states[ev.Container].Handle(ev);
}
if (ev.Unstamped is EventContainer) {
if (ev.Container != null) EnsureActivity((EventContainer)ev.Unstamped);
}
}
if (ev.Unstamped is EventContainer) {
if (ev.Container != null) EnsureActivity((EventContainer)ev.Unstamped);
EventId++;
}
if (time2 == time0) {
while (tempEvents.Count > 0) {
var ev = tempEvents[0];
if (ev.Container != null) {
EnsureActivity(ev.Container);
states[ev.Container].Handle(ev);
}
tempEvents.RemoveAt(0);
}
}
ValidateStates();
EventId++;
}
else {
Time = toTime;
@@ -156,6 +164,7 @@ namespace Cryville.Crtr.Event {
public void BroadcastEndUpdate() {
RootState.BroadcastEndUpdate();
tempEvents.Clear();
}
public void Anchor() {

View File

@@ -20,10 +20,13 @@ namespace Cryville.Crtr.Event {
_buckets.Add(reg.Key, new Bucket(reg.Key, 4096));
}
readonly Dictionary<RealtimeMotionValue, Identifier> _rented = new Dictionary<RealtimeMotionValue, Identifier>();
static readonly SimpleObjectPool<Dictionary<RealtimeMotionValue, Identifier>> _dictPool
= new SimpleObjectPool<Dictionary<RealtimeMotionValue, Identifier>>(1024);
Dictionary<RealtimeMotionValue, Identifier> _rented;
public RealtimeMotionValue Rent(Identifier name) {
var n = name;
var obj = _buckets[n].Rent();
if (_rented == null) _rented = _dictPool.Rent();
_rented.Add(obj, n);
return obj;
}
@@ -35,6 +38,7 @@ namespace Cryville.Crtr.Event {
foreach (var obj in _rented)
_buckets[obj.Value].Return(obj.Key);
_rented.Clear();
_dictPool.Return(_rented);
}
}
}

View File

@@ -18,11 +18,11 @@ namespace Cryville.Crtr.Extensions.Malody {
public override IEnumerable<Resource> ConvertFrom(FileInfo file) {
List<Resource> result = new List<Resource>();
MalodyChart src;
if (file.Extension != ".mc") throw new NotImplementedException("mcz file is not supported");
if (file.Extension != ".mc") throw new NotImplementedException("mcz file is not supported yet");
using (var reader = new StreamReader(file.FullName)) {
src = JsonConvert.DeserializeObject<MalodyChart>(reader.ReadToEnd());
}
if (src.meta.mode != 0) throw new NotImplementedException("The chart mode is not supported");
if (src.meta.mode != 0) throw new NotImplementedException(string.Format("{0} mode is not supported yet", MODES[src.meta.mode]));
var ruleset = "malody!" + MODES[src.meta.mode];
if (src.meta.mode == 0) {
@@ -110,7 +110,7 @@ namespace Cryville.Crtr.Extensions.Malody {
offset = -tev.offset / 1000f,
});
}
else throw new NotImplementedException();
else throw new NotImplementedException("Key sounds are not supported yet");
}
else {
var rn = new Chart.Note() {
@@ -135,9 +135,9 @@ namespace Cryville.Crtr.Extensions.Malody {
var sev = tev.StartEvent;
longEvents.Remove(sev);
}
else throw new NotSupportedException();
else throw new NotSupportedException("Unrecognized long event");
}
else throw new NotSupportedException();
else throw new NotSupportedException("Unrecognized event");
}
var endbeat = tm.FractionalBeatTime;
endbeat.b += 4;

View File

@@ -35,6 +35,7 @@ namespace Cryville.Crtr.Extensions.osu {
var diff = new DifficultyInfo();
var evs = new List<osuEvent>();
bool ftc = false;
using (var reader = new StreamReader(file.FullName, Encoding.UTF8)) {
Section section = Section.General;
int version;
@@ -45,7 +46,7 @@ namespace Cryville.Crtr.Extensions.osu {
if (line.StartsWith("osu file format v")) {
version = int.Parse(line.Substring(17), CultureInfo.InvariantCulture);
if (version > 14) throw new NotSupportedException("osu! chart format version too high");
else if (version < 5) throw new NotSupportedException("osu! chart format version too low"); // TODO apply offset
else if (version < 5) throw new NotImplementedException("osu! chart format version too low"); // TODO apply offset
}
else throw new NotSupportedException("Unrecognized osu! chart format");
flag = true;
@@ -57,10 +58,14 @@ namespace Cryville.Crtr.Extensions.osu {
Enum.TryParse(line.Substring(1, line.Length - 2), out section);
continue;
}
ParseLine(meta, chart, diff, evs, section, line);
ParseLine(meta, chart, diff, evs, ref ftc, section, line);
}
}
if (meta.ruleset == "osu!mania") {
chart.ruleset = meta.ruleset += "." + diff.CircleSize.ToString(CultureInfo.InvariantCulture) + "k";
}
if (!ftc) throw new InvalidOperationException("Unconvertible chart: no timing point is present in this beatmap");
result.Add(new RawChartResource(string.Format("{0} - {1}", meta.song.name, meta.name), chart, meta));
var evc = evs.Count;
for (int i = 0; i < evc; i++) if (evs[i].IsLong) evs.Add(new osuEvent.EndEvent(evs[i]));
@@ -81,7 +86,7 @@ namespace Cryville.Crtr.Extensions.osu {
}
else if (ev is osuEvent.EffectPoint) {
var tev = (osuEvent.EffectPoint)ev;
group.motions.Add(new Chart.Motion { motion = string.Format(CultureInfo.InvariantCulture, "svm:{0}", tev.ScrollSpeed) });
group.motions.Add(new Chart.Motion { time = tm.FractionalBeatTime, motion = string.Format(CultureInfo.InvariantCulture, "svm:{0}", tev.ScrollSpeed) });
}
else if (ev is osuEvent.EndEvent) {
if (tm == null) throw new InvalidOperationException("Unconvertible chart: timed event before first timing point");
@@ -122,13 +127,13 @@ namespace Cryville.Crtr.Extensions.osu {
return result;
}
void ParseLine(ChartMeta meta, Chart chart, DifficultyInfo diff, List<osuEvent> evs, Section section, string line) {
void ParseLine(ChartMeta meta, Chart chart, DifficultyInfo diff, List<osuEvent> evs, ref bool ftc, Section section, string line) {
switch (section) {
case Section.General: HandleGeneral(meta, chart, evs, line); return;
case Section.Metadata: HandleMetadata(meta, line); return;
case Section.Difficulty: HandleDifficulty(diff, line); return;
case Section.Events: HandleEvent(evs, line); return;
case Section.TimingPoints: HandleTimingPoint(chart, evs, line); return;
case Section.TimingPoints: HandleTimingPoint(chart, evs, ref ftc, line); return;
case Section.HitObjects: HandleHitObject(evs, line); return;
}
}
@@ -143,9 +148,9 @@ namespace Cryville.Crtr.Extensions.osu {
int rulesetID = int.Parse(pair.Value, CultureInfo.InvariantCulture);
var ruleset = "osu!";
switch (rulesetID) {
case 0: /*ruleset += "standard";*/ throw new NotSupportedException("osu!standard mode is not supported yet");
case 1: /*ruleset += "taiko";*/ throw new NotSupportedException("osu!taiko mode is not supported yet");
case 2: /*ruleset += "catch";*/ throw new NotSupportedException("osu!catch mode is not supported yet");
case 0: /*ruleset += "standard";*/ throw new NotImplementedException("osu!standard mode is not supported yet");
case 1: /*ruleset += "taiko";*/ throw new NotImplementedException("osu!taiko mode is not supported yet");
case 2: /*ruleset += "catch";*/ throw new NotImplementedException("osu!catch mode is not supported yet");
case 3: ruleset += "mania"; break;
}
meta.ruleset = chart.ruleset = ruleset;
@@ -201,7 +206,7 @@ namespace Cryville.Crtr.Extensions.osu {
Animation = 6
}
void HandleTimingPoint(Chart chart, List<osuEvent> evs, string line) {
void HandleTimingPoint(Chart chart, List<osuEvent> evs, ref bool ftc, string line) {
string[] split = line.Split(',');
double time = double.Parse(split[0].Trim(), CultureInfo.InvariantCulture)/* + offset*/;
@@ -230,7 +235,12 @@ namespace Cryville.Crtr.Extensions.osu {
if (timingChange) {
if (double.IsNaN(beatLength))
throw new InvalidDataException("Beat length cannot be NaN in a timing control point");
evs.Add(new osuEvent.TimingChange { StartTime = time, BeatLength = beatLength, TimeSignature = timeSignature });
var ev = new osuEvent.TimingChange { StartTime = time, BeatLength = beatLength, TimeSignature = timeSignature };
if (!ftc) {
ftc = true;
ev.StartTime = time % beatLength - beatLength;
}
evs.Add(ev);
}
// osu!taiko and osu!mania use effect points rather than difficulty points for scroll speed adjustments.

View File

@@ -5,7 +5,7 @@ using System.Linq;
using UnityEngine;
namespace Cryville.Crtr {
class GroupHandler : ContainerHandler {
public class GroupHandler : ContainerHandler {
public ChartHandler ch;
SquareMatrix matFrame;

View File

@@ -232,8 +232,7 @@ namespace Cryville.Crtr {
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);
_timeOrigins[h] = h.GetCurrentTimestamp() - time;
}
}
public void ForceTick() {

View File

@@ -1,13 +1,13 @@
using Cryville.Common;
using Cryville.Common.Buffers;
using Cryville.Common.Pdt;
using Cryville.Crtr.Event;
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Cryville.Crtr {
public class Judge {
#region Data
readonly PdtEvaluator _etor;
readonly PdtRuleset _rs;
readonly Dictionary<Identifier, float> ct
@@ -16,13 +16,14 @@ namespace Cryville.Crtr {
= new Dictionary<Identifier, List<JudgeEvent>>();
readonly Dictionary<Identifier, List<JudgeEvent>> activeEvs
= new Dictionary<Identifier, List<JudgeEvent>>();
struct JudgeEvent {
public struct JudgeEvent {
public double StartTime { get; set; }
public double EndTime { get; set; }
public double StartClip { get; set; }
public double EndClip { get; set; }
public Identifier JudgeId { get; set; }
public JudgeDefinition Definition { get; set; }
public ContainerState State { get; set; }
public NoteHandler Handler { get; set; }
}
static readonly IComparer<JudgeEvent> _stcmp = new JudgeEventStartTimeComparer();
class JudgeEventStartTimeComparer : IComparer<JudgeEvent> {
@@ -33,27 +34,40 @@ namespace Cryville.Crtr {
public Judge(PdtRuleset rs) {
_etor = ChartPlayer.etor;
_rs = rs;
InitJudges();
InitScores();
}
public void Prepare(double st, double et, Identifier input, JudgeDefinition def, ContainerState container) {
public void Prepare(double st, double et, Identifier input, Identifier judge, NoteHandler handler) {
List<JudgeEvent> list;
if (!evs.TryGetValue(input, out list)) {
ct.Add(input, 0);
evs.Add(input, list = new List<JudgeEvent>());
activeEvs.Add(input, new List<JudgeEvent>());
}
var def = _rs.judges[judge];
var ev = new JudgeEvent {
StartTime = st,
EndTime = et,
StartClip = st + def.clip[0],
EndClip = et + def.clip[1],
JudgeId = judge,
Definition = def,
State = container,
Handler = handler,
};
var index = list.BinarySearch(ev, _stcmp);
if (index < 0) index = ~index;
list.Insert(index, ev);
}
#endregion
#region Judge
internal readonly Dictionary<int, int> jtabsMap = new Dictionary<int, int>();
internal readonly Dictionary<int, int> jtrelMap = new Dictionary<int, int>();
void InitJudges() {
foreach (var i in _rs.judges.Keys) {
jtabsMap.Add(i.Key, IdentifierManager.SharedInstance.Request("jtabs_" + i.Name));
jtrelMap.Add(i.Key, IdentifierManager.SharedInstance.Request("jtrel_" + i.Name));
}
}
static bool _flag;
static readonly PropOp.Boolean _flagop = new PropOp.Boolean(v => _flag = v);
static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
@@ -112,7 +126,7 @@ namespace Cryville.Crtr {
else _flag = true;
if (_flag) {
if (def.scores != null) UpdateScore(def.scores);
if (def.pass != null) Pass(def.pass);
if (def.pass != null) Pass(ev, (ft + tt) / 2, def.pass);
actlist.RemoveAt(index);
if (def.prop != 0 && actlist.Count > 0) {
index = BinarySearchFirst(actlist, (float)ev.StartClip, def.stack - def.prop);
@@ -124,14 +138,15 @@ namespace Cryville.Crtr {
}
}
}
bool Pass(Identifier[] ids) {
bool Pass(JudgeEvent ev, float time, 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);
if (def.pass != null) Pass(ev, time, def.pass);
ev.Handler.ReportJudge(ev, time, i);
return true;
}
}
@@ -144,7 +159,7 @@ namespace Cryville.Crtr {
JudgeEvent ev = actlist[i];
if (tt > ev.EndClip) {
actlist.RemoveAt(i);
if (ev.Definition.miss != null) Pass(ev.Definition.miss);
if (ev.Definition.miss != null) Pass(ev, tt, ev.Definition.miss);
}
}
}
@@ -174,6 +189,8 @@ namespace Cryville.Crtr {
}
}
}
#endregion
#region Score
readonly Dictionary<int, int> scoreStringKeys = new Dictionary<int, int>();
readonly Dictionary<int, int> scoreStringKeysRev = new Dictionary<int, int>();
readonly Dictionary<int, PropSrc> scoreSrcs = new Dictionary<int, PropSrc>();
@@ -240,20 +257,22 @@ namespace Cryville.Crtr {
_buf = null;
}
}
protected override unsafe void InternalGet(out int type, out byte[] value) {
protected override unsafe int InternalGet() {
var src = _cb();
int strlen = src.Length;
type = PdtInternalType.String;
value = _pool.Rent(sizeof(int) + strlen * sizeof(char));
fixed (byte* _ptr = value) {
buf = _pool.Rent(sizeof(int) + strlen * sizeof(char));
fixed (byte* _ptr = buf) {
char* ptr = (char*)(_ptr + sizeof(int));
*(int*)_ptr = strlen;
int i = 0;
foreach (var c in src) ptr[i++] = c;
}
return PdtInternalType.String;
}
}
#endregion
}
#region Definitions
public class InputDefinition {
public int dim;
public bool notnull;
@@ -282,4 +301,5 @@ namespace Cryville.Crtr {
public float init = 0;
public string format = "";
}
#endregion
}

View File

@@ -928,25 +928,25 @@ namespace Cryville.Crtr {
public class VectorSrc : PropSrc {
readonly Func<Vector> _cb;
public VectorSrc(Func<Vector> cb) { _cb = cb; }
protected override unsafe void InternalGet(out int type, out byte[] value) {
protected override unsafe int InternalGet() {
var arr = _cb().ToArray();
if (arr.Length == 1) {
type = PdtInternalType.Number;
value = new byte[sizeof(float)];
fixed (byte* ptr = value) {
buf = new byte[sizeof(float)];
fixed (byte* ptr = buf) {
*(float*)ptr = arr[0];
}
return PdtInternalType.Number;
}
else {
type = PdtInternalType.Vector;
value = new byte[sizeof(float) * arr.Length + sizeof(int)];
fixed (byte* rptr = value) {
buf = new byte[sizeof(float) * arr.Length + sizeof(int)];
fixed (byte* rptr = buf) {
var ptr = (float*)rptr;
for (int i = 0; i < arr.Length; i++, ptr++) {
*ptr = arr[i];
}
*(int*)ptr = PdtInternalType.Number;
}
return PdtInternalType.Vector;
}
}
}

View File

@@ -7,7 +7,7 @@ using System.Collections.Generic;
using UnityEngine;
namespace Cryville.Crtr {
class NoteHandler : ContainerHandler {
public class NoteHandler : ContainerHandler {
readonly GroupHandler gh;
public readonly Chart.Note Event;
readonly PdtRuleset ruleset;
@@ -24,7 +24,32 @@ namespace Cryville.Crtr {
}
SectionalGameObject[] sgos;
readonly Dictionary<Identifier, JudgeState> judges = new Dictionary<Identifier, JudgeState>();
class JudgeState {
public int AbsoluteAnchorName { get; set; }
public int RelativeAnchorName { get; set; }
public bool Judged { get; private set; }
public float AbsoluteTime { get; private set; }
public float RelativeTime { get; private set; }
public JudgeState(NoteHandler handler, int name) {
handler.RegisterAnchor(AbsoluteAnchorName = handler.judge.jtabsMap[name]);
handler.RegisterAnchor(RelativeAnchorName = handler.judge.jtrelMap[name]);
}
public void MarkJudged(float abs, float rel) {
Judged = true;
AbsoluteTime = abs;
RelativeTime = rel;
}
}
public override void PreInit() {
base.PreInit();
foreach (var j in Event.judges) {
if (!judges.ContainsKey(j.Id)) {
judges.Add(j.Id, new JudgeState(this, j.Id.Key));
}
}
}
public override void Init() {
base.Init();
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
@@ -65,15 +90,7 @@ namespace Cryville.Crtr {
Position = GetFramePoint(s.Parent, s.Track);
Rotation = GetFrameRotation(s.Parent, s.Track);
}
if (s.CloneType == 0) {
#if UNITY_5_6_OR_NEWER
a_cur.SetPositionAndRotation(Position, Rotation);
#else
a_cur.position = Position;
a_cur.rotation = Rotation;
#endif
}
else if (s.CloneType == 2) {
if (s.CloneType == 2) {
if (!gogroup) return;
Chart.Note tev = Event;
if (tev.IsLong) {
@@ -90,13 +107,24 @@ namespace Cryville.Crtr {
ChartPlayer.etor.ContextEvent = tev;
ChartPlayer.etor.ContextState = s;
ChartPlayer.etor.Evaluate(new PropOp.Identifier(v => name = new Identifier(v)), ruleset.judges[tev.Id].input);
judge.Prepare(ev.Time, ev.Time + ev.Duration, name, ruleset.judges[tev.Id], cs);
judge.Prepare(ev.Time, ev.Time + ev.Duration, name, tev.Id, this);
ChartPlayer.etor.ContextState = null;
ChartPlayer.etor.ContextEvent = null;
}
}
}
public override void Anchor() {
base.Anchor();
if (cs.Working) {
foreach (var j in judges.Values) {
if (!j.Judged) continue;
// PushAnchorEvent(j.AbsoluteAnchorName, j.AbsoluteTime);
// PushAnchorEvent(j.RelativeAnchorName, j.RelativeTime + cs.Time);
}
}
}
public override void EndUpdate(ContainerState s) {
if (s.CloneType == 2 && gogroup) {
foreach (var i in sgos) i.Seal();
@@ -166,5 +194,11 @@ namespace Cryville.Crtr {
}
}
}
public void ReportJudge(Judge.JudgeEvent ev, float time, Identifier result) {
JudgeState state;
if (!judges.TryGetValue(ev.JudgeId, out state)) return;
state.MarkJudged(time, (float)(time - cs.Time));
}
}
}

View File

@@ -86,7 +86,7 @@ namespace Cryville.Crtr {
protected override bool Collapse(int name, PdtVariableMemory param) {
if (name == _colop_and) return param.Type == PdtInternalType.Number && 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}", IdentifierManager.SharedInstance.Retrieve(name)));
}
public ChartEvent ContextEvent { private get; set; }

View File

@@ -72,19 +72,21 @@ namespace Cryville.Crtr {
public class Enum<T> : PropOp {
readonly static Dictionary<int, int> _cache = new Dictionary<int, int>();
readonly Action<T> _cb;
public Enum(Action<T> cb) {
readonly Func<int, T> _caster;
public Enum(Action<T> cb, Func<int, T> caster) {
if (!typeof(T).IsEnum)
throw new ArgumentException("Type is not enum");
var names = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static);
for (int i = 0; i < names.Length; i++)
_cache[IdentifierManager.SharedInstance.Request(names[i].Name)] = Convert.ToInt32(names[i].GetValue(null));
_cb = cb;
_caster = caster;
}
protected override void Execute() {
int result = 0;
for (int i = 0; i < LoadedOperandCount; i++)
result |= _cache[GetOperand(0).AsIdentifier()];
_cb((T)(object)result);
_cb(_caster(result));
}
}
public class BeatTime : PropOp {

View File

@@ -5,14 +5,15 @@ using RBeatTime = Cryville.Crtr.BeatTime;
namespace Cryville.Crtr {
public abstract class PropSrc {
int _type;
byte[] _buf = null;
public virtual void Invalidate() { _buf = null; }
protected byte[] buf = null;
protected virtual bool Invalidated { get { return buf == null; } }
public virtual void Invalidate() { buf = null; }
public void Get(out int type, out byte[] value) {
if (_buf == null) InternalGet(out _type, out _buf);
if (Invalidated) _type = InternalGet();
type = _type;
value = _buf;
value = buf;
}
protected abstract void InternalGet(out int type, out byte[] value);
protected abstract int InternalGet();
public class Arbitrary : PropSrc {
public int Type { get; private set; }
readonly byte[] _value;
@@ -20,65 +21,75 @@ namespace Cryville.Crtr {
Type = type;
_value = value;
}
protected override void InternalGet(out int type, out byte[] value) {
type = Type;
value = _value;
protected override int InternalGet() {
buf = _value;
return Type;
}
}
public class Boolean : PropSrc {
readonly Func<bool> _cb;
public Boolean(Func<bool> cb) { _cb = cb; }
protected override void InternalGet(out int type, out byte[] value) {
type = PdtInternalType.Number;
value = new byte[] { _cb() ? (byte)1 : (byte)0, 0, 0, 0 };
bool m_invalidated = true;
protected override bool Invalidated { get { return m_invalidated; } }
public override void Invalidate() { m_invalidated = true; }
public Boolean(Func<bool> cb) { _cb = cb; buf = new byte[4]; }
protected override int InternalGet() {
m_invalidated = false;
buf[0] = _cb() ? (byte)1 : (byte)0;
return PdtInternalType.Number;
}
}
public class Float : PropSrc {
readonly Func<float> _cb;
public Float(Func<float> cb) { _cb = cb; }
protected override void InternalGet(out int type, out byte[] value) {
type = PdtInternalType.Number;
value = BitConverter.GetBytes(_cb());
bool m_invalidated = true;
protected override bool Invalidated { get { return m_invalidated; } }
public override void Invalidate() { m_invalidated = true; }
public Float(Func<float> cb) { _cb = cb; buf = new byte[4]; }
protected override unsafe int InternalGet() {
m_invalidated = false;
fixed (byte* _ptr = buf) {
*(float*)_ptr = _cb();
}
return PdtInternalType.Number;
}
}
public class String : PropSrc {
readonly Func<string> _cb;
public String(Func<string> cb) { _cb = cb; }
protected override unsafe void InternalGet(out int type, out byte[] value) {
type = PdtInternalType.String;
protected override unsafe int InternalGet() {
var v = _cb();
int strlen = v.Length;
value = new byte[strlen * sizeof(char) + sizeof(int)];
fixed (byte* _ptr = value) {
buf = new byte[strlen * sizeof(char) + sizeof(int)];
fixed (byte* _ptr = buf) {
char* ptr = (char*)(_ptr + sizeof(int));
*(int*)_ptr = strlen;
int i = 0;
foreach (var c in v) ptr[i++] = c;
}
return PdtInternalType.String;
}
}
public class Identifier : PropSrc {
readonly Func<int> _cb;
public Identifier(Func<int> cb) { _cb = cb; }
protected override void InternalGet(out int type, out byte[] value) {
type = PdtInternalType.Undefined;
value = BitConverter.GetBytes(_cb());
protected override int InternalGet() {
buf = BitConverter.GetBytes(_cb());
return PdtInternalType.Undefined;
}
}
public class BeatTime : PropSrc {
readonly Func<RBeatTime> _cb;
public BeatTime(Func<RBeatTime> cb) { _cb = cb; }
protected override unsafe void InternalGet(out int type, out byte[] value) {
protected override unsafe int InternalGet() {
var bt = _cb();
type = PdtInternalType.Vector;
value = new byte[4 * sizeof(int)];
fixed (byte* _ptr = value) {
buf = new byte[4 * sizeof(int)];
fixed (byte* _ptr = buf) {
int* ptr = (int*)_ptr;
*ptr++ = bt.b;
*ptr++ = bt.n;
*ptr++ = bt.d;
*ptr++ = PdtInternalType.Number;
}
return PdtInternalType.Vector;
}
}
}

View File

@@ -34,6 +34,17 @@ namespace Cryville.Crtr {
}
}
[Category("gameplay")]
[Range(-1, 5)]
public int ForceSyncFrames {
get {
return PlayerPrefs.GetInt("ForceSyncFrames", 5);
}
set {
PlayerPrefs.SetInt("ForceSyncFrames", value);
}
}
[Browsable(false)]
[Category("data")]
[Description("The directory where the game files are stored.")]

View File

@@ -1,3 +1,4 @@
using Cryville.Common;
using Cryville.Common.Pdt;
using Cryville.Crtr.Components;
using Cryville.Crtr.Event;
@@ -100,10 +101,16 @@ namespace Cryville.Crtr {
SkinProperty GetPropOp(Transform obj, SkinPropertyKey key) {
var ctype = key.Component;
var comp = (SkinComponent)obj.GetComponent(ctype);
if (comp == null) throw new InvalidOperationException("Component instance not found");
if (comp == null) throw new InvalidOperationException(string.Format(
"Trying to set property {0} but the component is not found",
IdentifierManager.SharedInstance.Retrieve(key.Name)
));
SkinProperty result;
if (!comp.Properties.TryGetValue(key.Name, out result))
throw new ArgumentException(string.Format("Property {0} not found on component", key.Name));
throw new ArgumentException(string.Format(
"Property {0} not found on component",
IdentifierManager.SharedInstance.Retrieve(key.Name)
));
return result;
}
}

View File

@@ -3,32 +3,18 @@ using UnityEngine;
namespace Cryville.Crtr {
public class SpriteFrame {
#pragma warning disable IDE1006
Rect _frame;
public Rect frame {
get { return _frame; }
set { _frame = value; }
}
public Rect textureRect {
get { return _frame; }
set { _frame = value; }
Rect m_frame;
public Rect Frame {
get { return m_frame; }
set { m_frame = value; }
}
bool _rotated = false;
public bool rotated {
get { return _rotated; }
set { _rotated = value; }
bool m_rotated = false;
public bool Rotated {
get { return m_rotated; }
set { m_rotated = value; }
}
public bool textureRotated {
get { return _rotated; }
set { _rotated = value; }
}
#pragma warning restore IDE1006
public Vector2 offset;
public Rect sourceColorRect;
public Vector2 sourceSize;
private Rect _uv;
private Vector2[] cuv;
public Rect UV {
@@ -41,7 +27,7 @@ namespace Cryville.Crtr {
float x1 = Mathf.Max(_uv.xMin, _uv.xMax);
float y0 = Mathf.Min(_uv.yMin, _uv.yMax);
float y1 = Mathf.Max(_uv.yMin, _uv.yMax);
if (_rotated) cuv = new Vector2[]{
if (m_rotated) cuv = new Vector2[]{
new Vector2(x0, y1),
new Vector2(x1, y0),
new Vector2(x0, y0),
@@ -79,28 +65,17 @@ namespace Cryville.Crtr {
public void Init() {
if (Texture == null)
throw new InvalidOperationException("Missing texture");
_frame = new Rect(Vector2.zero, Size);
var w = _frame.width;
var h = _frame.height;
float x = _frame.x / w;
float y = 1 - _frame.y / h;
float tw = (_rotated ? _frame.height : _frame.width) / w;
float th = (_rotated ? _frame.width : _frame.height) / h;
if (_rotated) UV = new Rect(x, y, tw, -th);
m_frame = new Rect(Vector2.zero, Size);
var w = m_frame.width;
var h = m_frame.height;
float x = m_frame.x / w;
float y = 1 - m_frame.y / h;
float tw = (m_rotated ? m_frame.height : m_frame.width) / w;
float th = (m_rotated ? m_frame.width : m_frame.height) / h;
if (m_rotated) UV = new Rect(x, y, tw, -th);
else UV = new Rect(x, y, tw, -th);
}
public void Init(int w, int h, Texture2D _base) {
if (Texture != null)
throw new InvalidOperationException("Missing texture");
Texture = _base;
float x = _frame.x / w;
float y = 1 - _frame.y / h;
float tw = (_rotated ? _frame.height : _frame.width) / w;
float th = (_rotated ? _frame.width : _frame.height) / h;
if (_rotated) UV = new Rect(x, y, tw, -th);
else UV = new Rect(x, y, tw, -th);
}
public SpriteFrame() { }
public SpriteFrame(Texture2D tex) {
Texture = tex;

View File

@@ -27,27 +27,14 @@ namespace Cryville.Crtr {
throw new NotImplementedException();
}
}
public class PlaySound : StampedEvent {
public new Chart.Sound Unstamped;
public class Anchor : StampedEvent {
public int Name;
public override int Priority {
get { return 0; }
}
}
public class Judge : StampedEvent {
public float NoteTime;
public JudgeDefinition TargetJudge;
public Judge StartEvent;
public bool IsEndJudge;
public override int Priority {
get { return StartEvent == null ? 4 : 6; }
}
protected override int CompareExtra(StampedEvent other) {
return Equals(StartEvent, other) ? 1 : 0;
}
}
public StampedEvent AttackEvent {
get {
if (attev == null) attev = Subevents.FirstOrDefault(ev => ev.Time == this.Time);

View File

@@ -39,6 +39,7 @@ namespace Cryville.Crtr {
#endif
}
else if (s.CloneType == 3) {
spos = Vector3.zero;
bpos = cpt;
brot = Quaternion.Euler(s.Direction);
}
@@ -61,18 +62,7 @@ namespace Cryville.Crtr {
public override void Update(ContainerState s, StampedEvent ev) {
base.Update(s, ev);
if (s.CloneType == 0) {
pwp = Vector3.zero;
cpt = s.ScreenPoint;
spos = Vector3.zero;
#if UNITY_5_6_OR_NEWER
a_cur.SetPositionAndRotation(s.ScreenPoint, Quaternion.Euler(s.Direction));
#else
a_cur.position = s.ScreenPoint;
a_cur.rotation = Quaternion.Euler(s.Direction);
#endif
}
else if (s.CloneType == 2 || s.CloneType == 3) {
if (s.CloneType == 2 || s.CloneType == 3) {
var tpt = s.ScreenPoint;
var tsv = s.ScrollVelocity;

View File

@@ -2,7 +2,8 @@
"name": "Cryville.Crtr",
"rootNamespace": "",
"references": [
"GUID:d8ea0e0da3ad53a45b65c912ffcacab0"
"GUID:d8ea0e0da3ad53a45b65c912ffcacab0",
"GUID:5686e5ee69d0e084c843d61c240d7fdb"
],
"includePlatforms": [],
"excludePlatforms": [],

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 431a8644546221a40a73de6618f11332
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
using System;
namespace Discord
{
public partial class ActivityManager
{
public void RegisterCommand()
{
RegisterCommand(null);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4bce5beb292181a43b6427b71e8a7e93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using System;
namespace Discord
{
static class Constants
{
public const string DllName = "discord_game_sdk";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 62db490eb0dffd64785623624a77cfd4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 492875a0b937d86409c5dddd1d597026
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
{
"name": "DiscordGameSDK"
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5686e5ee69d0e084c843d61c240d7fdb
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using System;
using System.Runtime.InteropServices;
#if UNITY_EDITOR || UNITY_STANDALONE
using UnityEngine;
#endif
namespace Discord
{
public partial struct ImageHandle
{
static public ImageHandle User(Int64 id)
{
return User(id, 128);
}
static public ImageHandle User(Int64 id, UInt32 size)
{
return new ImageHandle
{
Type = ImageType.User,
Id = id,
Size = size,
};
}
}
public partial class ImageManager
{
public void Fetch(ImageHandle handle, FetchHandler callback)
{
Fetch(handle, false, callback);
}
public byte[] GetData(ImageHandle handle)
{
var dimensions = GetDimensions(handle);
var data = new byte[dimensions.Width * dimensions.Height * 4];
GetData(handle, data);
return data;
}
#if UNITY_EDITOR || UNITY_STANDALONE
public Texture2D GetTexture(ImageHandle handle)
{
var dimensions = GetDimensions(handle);
var texture = new Texture2D((int)dimensions.Width, (int)dimensions.Height, TextureFormat.RGBA32, false, true);
texture.LoadRawTextureData(GetData(handle));
texture.Apply();
return texture;
}
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a3cfde4503bedc444807a916e1ad2960
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,26 @@
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
namespace Discord
{
public partial class LobbyManager
{
public IEnumerable<User> GetMemberUsers(Int64 lobbyID)
{
var memberCount = MemberCount(lobbyID);
var members = new List<User>();
for (var i = 0; i < memberCount; i++)
{
members.Add(GetMemberUser(lobbyID, GetMemberUserId(lobbyID, i)));
}
return members;
}
public void SendLobbyMessage(Int64 lobbyID, string data, SendLobbyMessageHandler handler)
{
SendLobbyMessage(lobbyID, Encoding.UTF8.GetBytes(data), handler);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d49d4d1d5cee72b40a22bf6f6bdd0309
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Discord
{
public partial class StorageManager
{
public IEnumerable<FileStat> Files()
{
var fileCount = Count();
var files = new List<FileStat>();
for (var i = 0; i < fileCount; i++)
{
files.Add(StatAt(i));
}
return files;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 75e55be5cce5be14ca292ed00ff90a43
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,32 @@
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
namespace Discord
{
public partial class StoreManager
{
public IEnumerable<Entitlement> GetEntitlements()
{
var count = CountEntitlements();
var entitlements = new List<Entitlement>();
for (var i = 0; i < count; i++)
{
entitlements.Add(GetEntitlementAt(i));
}
return entitlements;
}
public IEnumerable<Sku> GetSkus()
{
var count = CountSkus();
var skus = new List<Sku>();
for (var i = 0; i < count; i++)
{
skus.Add(GetSkuAt(i));
}
return skus;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f28abb9e0c9477541bba93c5c21a7111
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 460f7228edb725a48a1fb6b5f4617ee9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 751d95431111781498a1a512ad9edd8c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
fileFormatVersion: 2
guid: 8bbe28aa384b7cf47bae3469ee3357a2
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 0
Exclude OSXUniversal: 0
Exclude Win: 0
Exclude Win64: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 1
settings:
CPU: x86
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: None
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 45f45105fdfb4d348baf39f50ea65c68
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e0215748675da6b43a2f70236d99e492
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
fileFormatVersion: 2
guid: 212370df4e6cbbb4eb87395114fb6885
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux64: 0
Exclude OSXUniversal: 0
Exclude Win: 1
Exclude Win64: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: x86_64
userData:
assetBundleName:
assetBundleVariant: