18 Commits

23 changed files with 195 additions and 83 deletions

1
.gitignore vendored
View File

@@ -61,6 +61,7 @@ crashlytics-build.properties
#
/Docs
/Issues
/Local
/Obsolete
/Snapshots
/UI

Binary file not shown.

View File

@@ -17,7 +17,7 @@ namespace Cryville.Common {
public static void SetLogPath(string path) {
logPath = path;
var dir = new DirectoryInfo(path);
if (!dir.Exists) Directory.CreateDirectory(dir.FullName);
if (!dir.Exists) dir.Create();
}
/// <summary>
/// Logs to the specified logger.

View File

@@ -59,24 +59,27 @@ namespace Cryville.Crtr.Browsing {
public ResourceItemMeta GetItemMeta(int id) {
var item = items[id];
AsyncDelivery<Texture2D> cover = null;
var coverFile = item.GetFiles("cover.*");
if (coverFile.Length > 0) {
cover = new AsyncDelivery<Texture2D>();
var task = new LoadTextureTask(Game.FileProtocolPrefix + coverFile[0].FullName, cover.Deliver);
cover.CancelSource = task.Cancel;
Game.NetworkTaskWorker.SubmitNetworkTask(task);
}
var meta = new ChartMeta();
string name = item.Name;
string desc = "(Unknown)";
var metaFile = new FileInfo(item.FullName + "/meta.json");
if (metaFile.Exists) {
using (var reader = new StreamReader(metaFile.FullName)) {
var meta = JsonConvert.DeserializeObject<ChartMeta>(reader.ReadToEnd());
meta = JsonConvert.DeserializeObject<ChartMeta>(reader.ReadToEnd());
name = meta.song.name;
desc = meta.chart.name;
}
}
AsyncDelivery<Texture2D> cover = null;
if (meta.cover != null && meta.cover != "") {
var coverFile = item.GetFiles(meta.cover);
if (coverFile.Length > 0) {
cover = new AsyncDelivery<Texture2D>();
var task = new LoadTextureTask(Game.FileProtocolPrefix + coverFile[0].FullName, cover.Deliver);
cover.CancelSource = task.Cancel;
Game.NetworkTaskWorker.SubmitNetworkTask(task);
}
}
return new ResourceItemMeta {
IsDirectory = false,
Icon = cover,
@@ -87,21 +90,23 @@ namespace Cryville.Crtr.Browsing {
public ChartDetail GetItemDetail(int id) {
var item = items[id];
AsyncDelivery<Texture2D> cover = null;
var coverFile = item.GetFiles("cover.*");
if (coverFile.Length > 0) {
cover = new AsyncDelivery<Texture2D>();
var task = new LoadTextureTask(Game.FileProtocolPrefix + coverFile[0].FullName, cover.Deliver);
cover.CancelSource = task.Cancel;
Game.NetworkTaskWorker.SubmitNetworkTask(task);
}
ChartMeta meta = new ChartMeta();
var meta = new ChartMeta();
var metaFile = new FileInfo(item.FullName + "/meta.json");
if (metaFile.Exists) {
using (var reader = new StreamReader(metaFile.FullName)) {
meta = JsonConvert.DeserializeObject<ChartMeta>(reader.ReadToEnd());
}
}
AsyncDelivery<Texture2D> cover = null;
if (meta.cover != null && meta.cover != "") {
var coverFile = item.GetFiles(meta.cover);
if (coverFile.Length > 0) {
cover = new AsyncDelivery<Texture2D>();
var task = new LoadTextureTask(Game.FileProtocolPrefix + coverFile[0].FullName, cover.Deliver);
cover.CancelSource = task.Cancel;
Game.NetworkTaskWorker.SubmitNetworkTask(task);
}
}
return new ChartDetail {
Cover = cover,
Meta = meta,
@@ -143,7 +148,7 @@ namespace Cryville.Crtr.Browsing {
var tres = (CoverResource)res;
var dir = new DirectoryInfo(_rootPath + "/charts/" + res.Name);
if (!dir.Exists) dir.Create();
var dest = new FileInfo(_rootPath + "/charts/" + res.Name + "/cover" + tres.Source.Extension);
var dest = new FileInfo(_rootPath + "/charts/" + res.Name + "/" + tres.Source.Name);
if (!dest.Exists) tres.Source.CopyTo(dest.FullName);
}

View File

@@ -0,0 +1,28 @@
using UnityEngine.UI;
namespace Cryville.Crtr.Browsing {
public class PVPString : PropertyValuePanel {
string m_value;
public override object Value {
get {
return m_value;
}
set {
m_value = (string)value;
_inputField.text = m_value;
}
}
InputField _inputField;
void Awake() {
_inputField = GetComponent<InputField>();
_inputField.onValueChanged.AddListener(OnValueChanged);
}
void OnValueChanged(string value) {
m_value = value;
Callback(Value);
}
}
}

View File

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

View File

@@ -10,6 +10,8 @@ namespace Cryville.Crtr.Browsing {
GameObject m_bool;
[SerializeField]
GameObject m_number;
[SerializeField]
GameObject m_string;
PropertyInfo _property;
object _target;
@@ -32,6 +34,7 @@ namespace Cryville.Crtr.Browsing {
GameObject vp;
if (prop.PropertyType == typeof(bool)) vp = m_bool;
else if (prop.PropertyType == typeof(float) || prop.PropertyType == typeof(int)) vp = m_number;
else if (prop.PropertyType == typeof(string)) vp = m_string;
else return;
_value = GameObject.Instantiate(vp, _valueContainer, false).GetComponent<PropertyValuePanel>();
if (_value is PVPNumber) {

View File

@@ -87,7 +87,6 @@ namespace Cryville.Crtr.Browsing {
void SetDataSettings(int id, ChartDetail detail) {
Settings.Default.LoadRuleset = detail.Meta.ruleset + "/.umgr";
Settings.Default.LoadRulesetConfig = detail.Meta.ruleset + ".json";
Settings.Default.LoadSkin = detail.Meta.ruleset + "/Old KeyUI/.umgs";
Settings.Default.LoadChart = MainBrowser.ResourceManager.GetItemPath(id);
}
}
@@ -108,6 +107,7 @@ namespace Cryville.Crtr.Browsing {
}
public string ruleset { get; set; }
public int note_count { get; set; }
public string cover { get; set; }
}
#pragma warning restore IDE1006
}

View File

@@ -52,6 +52,7 @@ namespace Cryville.Crtr {
public static Rect hitRect;
public static Plane[] frustumPlanes;
RulesetConfig _rscfg;
static bool disableGC = true;
static float clippingDist = 1f;
static float renderDist = 6f;
@@ -84,7 +85,14 @@ namespace Cryville.Crtr {
texHandler = new DownloadHandlerTexture();
#if BUILD
Play();
try {
Play();
}
catch (Exception ex) {
Game.LogException("Load/WorkerThread", "An error occured while loading the data", ex);
Popup.CreateException(ex);
ReturnToMenu();
}
#endif
// Camera.main.RenderToCubemap();
@@ -157,26 +165,20 @@ namespace Cryville.Crtr {
#if UNITY_5_4_OR_NEWER
if (texHandler.isDone) {
var tex = texHandler.texture;
tex.wrapMode = TextureWrapMode.Clamp;
texs.Add(name, tex);
Logger.Log("main", 0, "Load/MainThread", "Loaded texture {0} ({1} bytes)", name, texLoader.downloadedBytes);
texLoader.Dispose();
texHandler.Dispose();
texLoader = null;
}
else if (texLoader.downloadProgress != 0) {
Logger.Log("main", 0, "Load/MainThread", "Loading texture {0} {1:P0}", name, texLoader.downloadProgress);
}
#else
if (texLoader.isDone) {
var tex = texLoader.texture;
texs.Add(name, tex);
Logger.Log("main", 0, "Load/MainThread", "Loaded texture {0} ({1} bytes)", name, texLoader.bytesDownloaded);
texLoader.Dispose();
texLoader = null;
}
else if (texLoader.progress != 0) {
Logger.Log("main", 0, "Load/MainThread", "Loading texture {0} {1:P0}", name, texLoader.progress);
}
if (texLoader.isDone) {
var tex = texLoader.texture;
tex.wrapMode = TextureWrapMode.Clamp;
texs.Add(name, tex);
texLoader.Dispose();
texLoader = null;
}
#endif
}
if (texLoader == null)
@@ -307,7 +309,6 @@ namespace Cryville.Crtr {
autoRenderStep = renderStep == 0;
soundOffset = Settings.Default.SoundOffset;
startOffset = Settings.Default.StartOffset;
sv = Settings.Default.ScrollVelocity;
firstFrame = true;
texloaddone = false;
Game.NetworkTaskWorker.SuspendBackgroundTasks();
@@ -331,20 +332,31 @@ namespace Cryville.Crtr {
FileInfo chartFile = new FileInfo(
Game.GameDataPath + "/charts/" + Settings.Default.LoadChart
);
FileInfo rulesetFile = new FileInfo(
Game.GameDataPath + "/rulesets/" + Settings.Default.LoadRuleset
);
if (!rulesetFile.Exists) throw new FileNotFoundException("Ruleset for the chart not found\nMake sure you have imported the ruleset");
FileInfo rulesetConfigFile = new FileInfo(
Game.GameDataPath + "/config/rulesets/" + Settings.Default.LoadRulesetConfig
);
if (!rulesetConfigFile.Exists) throw new FileNotFoundException("Ruleset config not found\nPlease open the config to generate");
using (StreamReader cfgreader = new StreamReader(rulesetConfigFile.FullName, Encoding.UTF8)) {
_rscfg = JsonConvert.DeserializeObject<RulesetConfig>(cfgreader.ReadToEnd(), new JsonSerializerSettings() {
MissingMemberHandling = MissingMemberHandling.Error
});
}
sv = _rscfg.generic.ScrollVelocity;
FileInfo skinFile = new FileInfo(
Game.GameDataPath + "/skins/" + Settings.Default.LoadSkin
string.Format("{0}/skins/{1}/{2}/.umgs", Game.GameDataPath, rulesetFile.Directory.Name, _rscfg.generic.Skin)
);
if (!skinFile.Exists) throw new FileNotFoundException("Skin not found\nPlease specify an available skin in the config");
loadThread = new Thread(new ParameterizedThreadStart(Load));
loadThread.Start(new LoadInfo() {
chartFile = chartFile,
rulesetFile = rulesetFile,
rulesetConfigFile = rulesetConfigFile,
skinFile = skinFile,
});
@@ -399,6 +411,7 @@ namespace Cryville.Crtr {
try {
Logger.Log("main", 1, "Game", "Stopping");
Game.AudioSession = Game.AudioSequencer.NewSession();
inputProxy.Deactivate();
if (cbus != null) { cbus.Dispose(); cbus = null; }
if (bbus != null) { bbus.Dispose(); bbus = null; }
if (tbus != null) { tbus.Dispose(); tbus = null; }
@@ -433,7 +446,6 @@ namespace Cryville.Crtr {
struct LoadInfo {
public FileInfo chartFile;
public FileInfo rulesetFile;
public FileInfo rulesetConfigFile;
public FileInfo skinFile;
}
@@ -471,7 +483,7 @@ namespace Cryville.Crtr {
etor = new PdtEvaluator();
LoadRuleset(info.rulesetFile, info.rulesetConfigFile);
LoadRuleset(info.rulesetFile);
Logger.Log("main", 0, "Load/WorkerThread", "Applying ruleset (iteration 1)");
pruleset.PrePatch(chart);
@@ -530,8 +542,7 @@ namespace Cryville.Crtr {
}
}
RulesetConfig _rscfg;
void LoadRuleset(FileInfo file, FileInfo cfgfile) {
void LoadRuleset(FileInfo file) {
DirectoryInfo dir = file.Directory;
Logger.Log("main", 0, "Load/WorkerThread", "Loading ruleset: {0}", file);
using (StreamReader reader = new StreamReader(file.FullName, Encoding.UTF8)) {
@@ -541,12 +552,6 @@ namespace Cryville.Crtr {
if (ruleset.format != 1) throw new FormatException("Invalid ruleset file version");
ruleset.LoadPdt(dir);
pruleset = ruleset.Root;
if (!cfgfile.Exists) throw new FileNotFoundException("Ruleset config not found\nPlease open the config to generate");
using (StreamReader cfgreader = new StreamReader(cfgfile.FullName, Encoding.UTF8)) {
_rscfg = JsonConvert.DeserializeObject<RulesetConfig>(cfgreader.ReadToEnd(), new JsonSerializerSettings() {
MissingMemberHandling = MissingMemberHandling.Error
});
}
pruleset.Optimize(etor);
}
}

View File

@@ -1,7 +1,7 @@
using Newtonsoft.Json;
using System;
using System.IO;
using System.Text;
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
@@ -10,6 +10,9 @@ namespace Cryville.Crtr.Config {
[SerializeField]
Transform m_content;
[SerializeField]
SettingsPanel m_genericConfigPanel;
[SerializeField]
InputConfigPanel m_inputConfigPanel;
@@ -43,6 +46,9 @@ namespace Cryville.Crtr.Config {
});
}
}
m_genericConfigPanel.Target = _rscfg.generic;
var proxy = new InputProxy(ruleset.Root, null);
proxy.LoadFrom(_rscfg.inputs);
m_inputConfigPanel.proxy = proxy;

View File

@@ -1,12 +1,32 @@
using System.Collections.Generic;
using Cryville.Common.ComponentModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace Cryville.Crtr.Config {
public class RulesetConfig {
public Dictionary<string, InputConfigEntry> inputs
= new Dictionary<string, InputConfigEntry>();
}
public class InputConfigEntry {
public string handler;
public int type;
public Generic generic = new Generic();
public class Generic {
[Category("basic")]
[JsonProperty("skin")]
public string Skin { get; set; }
[Category("deprecated")][Obsolete]
[JsonProperty("scroll_velocity")][DefaultValue(1)]
[LogarithmicScale][Step(0.5f)][Precision(1e-1)]
public float ScrollVelocity { get; set; }
public Generic() {
Skin = "";
ScrollVelocity = 1;
}
}
public Dictionary<string, InputEntry> inputs
= new Dictionary<string, InputEntry>();
public class InputEntry {
public string handler;
public int type;
}
}
}

View File

@@ -18,6 +18,7 @@ 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");
using (var reader = new StreamReader(file.FullName)) {
src = JsonConvert.DeserializeObject<MalodyChart>(reader.ReadToEnd());
}
@@ -148,9 +149,11 @@ namespace Cryville.Crtr.Extensions.Malody {
};
meta.note_count = group.notes.Count;
string chartName = string.Format("{0} - {1}", meta.song.name, meta.chart.name);
result.Add(new ChartResource(chartName, chart, meta));
if (src.meta.background != null)
if (src.meta.background != null) {
result.Add(new CoverResource(chartName, new FileInfo(file.DirectoryName + "/" + src.meta.background)));
meta.cover = src.meta.background;
}
result.Add(new ChartResource(chartName, chart, meta));
return result;
}

View File

@@ -37,7 +37,7 @@ namespace Cryville.Crtr {
readonly Dictionary<string, int> _use = new Dictionary<string, int>();
readonly Dictionary<string, List<string>> _rev = new Dictionary<string, List<string>>();
public event EventHandler<ProxyChangedEventArgs> ProxyChanged;
public void LoadFrom(Dictionary<string, InputConfigEntry> config) {
public void LoadFrom(Dictionary<string, RulesetConfig.InputEntry> config) {
foreach (var cfg in config) {
Set(new InputProxyEntry {
Target = cfg.Key,
@@ -48,10 +48,10 @@ namespace Cryville.Crtr {
});
}
}
public void SaveTo(Dictionary<string, InputConfigEntry> config) {
public void SaveTo(Dictionary<string, RulesetConfig.InputEntry> config) {
config.Clear();
foreach (var p in _tproxies) {
config.Add(p.Key, new InputConfigEntry {
config.Add(p.Key, new RulesetConfig.InputEntry {
handler = ReflectionHelper.GetNamespaceQualifiedName(p.Value.Source.Value.Handler.GetType()),
type = p.Value.Source.Value.Type
});
@@ -182,14 +182,15 @@ namespace Cryville.Crtr {
if (!_vect.TryGetValue(id, out ft)) ft = tt;
if (vec.IsNull) {
_etor.ContextCascadeUpdate(_var_value, new PropSrc.Arbitrary(PdtInternalType.Null, _nullvalue));
OnInput(id, proxy.Target, ft, tt, true);
}
else {
fixed (byte* ptr = _vecbuf) {
*(Vector3*)ptr = vec.Vector;
}
_etor.ContextCascadeUpdate(_var_value, new PropSrc.Arbitrary(PdtInternalType.Vector, _vecbuf));
OnInput(id, proxy.Target, ft, tt, false);
}
OnInput(id, proxy.Target, ft, tt);
_vect[id] = tt;
_etor.ContextCascadeDiscard();
}
@@ -197,14 +198,14 @@ namespace Cryville.Crtr {
}
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv");
unsafe void OnInput(InputIdentifier id, Identifier target, float ft, float tt) {
unsafe void OnInput(InputIdentifier id, Identifier target, float ft, float tt, bool nullflag) {
var def = _ruleset.inputs[target];
if (def.pass != null) {
foreach (var p in def.pass) {
_etor.ContextCascadeInsert();
_arbop.Name = _var_value;
_etor.Evaluate(_arbop, p.Value);
OnInput(id, p.Key, ft, tt);
if (!nullflag) _etor.Evaluate(_arbop, p.Value);
OnInput(id, p.Key, ft, tt, nullflag);
_etor.ContextCascadeDiscard();
}
}

View File

@@ -116,8 +116,8 @@ namespace Cryville.Crtr {
if (def.scores != null) UpdateScore(def.scores);
if (def.pass != null) Pass(def.pass);
actlist.RemoveAt(index);
if (def.stack != def.prop && actlist.Count > 0) {
index = BinarySearchFirst(actlist, ev.StartClip, def.prop);
if (def.prop != 0 && actlist.Count > 0) {
index = BinarySearchFirst(actlist, ev.StartClip, def.stack - def.prop);
if (index < 0) index = ~index;
}
else index++;
@@ -216,7 +216,7 @@ namespace Cryville.Crtr {
public Identifier[] miss;
public Dictionary<ScoreOperation, PdtExpression> scores;
public int stack;
public int prop = -1;
public int prop = 1;
}
public class ScoreOperation {
public Identifier name;

View File

@@ -1,5 +1,4 @@
using System;
using UnityEditor.VersionControl;
using UnityEngine;
using UnityEngine.UI;
@@ -27,7 +26,6 @@ namespace Cryville.Crtr {
timer += Time.deltaTime;
}
public static void CreateException(Exception ex) {
Create(ex.Message);
}

View File

@@ -112,7 +112,7 @@ namespace Cryville.Crtr {
[LogarithmicScale][Step(0.5f)][Precision(1e-1)]
public float RenderDistance {
get {
return PlayerPrefs.GetFloat("RenderDistance", 6);
return PlayerPrefs.GetFloat("RenderDistance", 4);
}
set {
PlayerPrefs.SetFloat("RenderDistance", value);
@@ -131,17 +131,6 @@ namespace Cryville.Crtr {
}
}
[Category("gameplay")]
[LogarithmicScale][Step(0.5f)][Precision(1e-1)]
public float ScrollVelocity {
get {
return PlayerPrefs.GetFloat("ScrollVelocity", 1);
}
set {
PlayerPrefs.SetFloat("ScrollVelocity", value);
}
}
[Category("gameplay")]
[Step(0.04f)][Precision(1e-3)]
public float SoundOffset {

View File

@@ -0,0 +1,24 @@
#if UNITY_EDITOR
using System;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
public class MsvcStdextWorkaround : IPreprocessBuildWithReport {
const string kWorkaroundFlag = "/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS";
public int callbackOrder => 0;
public void OnPreprocessBuild(BuildReport report) {
var clEnv = Environment.GetEnvironmentVariable("_CL_");
if (string.IsNullOrEmpty(clEnv)) {
Environment.SetEnvironmentVariable("_CL_", kWorkaroundFlag);
}
else if (!clEnv.Contains(kWorkaroundFlag)) {
clEnv += " " + kWorkaroundFlag;
Environment.SetEnvironmentVariable("_CL_", clEnv);
}
}
}
#endif // UNITY_EDITOR

View File

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

Binary file not shown.

View File

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

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
../../Local/default_resources.zip