diff --git a/FDK19/コード/04.グラフィック/CTexture.cs b/FDK19/コード/04.グラフィック/CTexture.cs index d2d2f759..6152d66e 100644 --- a/FDK19/コード/04.グラフィック/CTexture.cs +++ b/FDK19/コード/04.グラフィック/CTexture.cs @@ -96,8 +96,8 @@ namespace FDK /// 論理画面を1とする場合の物理画面の倍率。 /// 論理値×画面比率=物理値。 /// - public static float f画面比率 = 1.0f; - + public static float f画面比率 = 1.0f; + // コンストラクタ public CTexture() @@ -111,6 +111,27 @@ namespace FDK this.fZ軸中心回転 = 0f; this.vc拡大縮小倍率 = new Vector3(1f, 1f, 1f); // this._txData = null; + } + + public CTexture(CTexture tx) + { + this.sz画像サイズ = tx.sz画像サイズ; + this.szテクスチャサイズ = tx.szテクスチャサイズ; + this._opacity = tx._opacity; + this.texture = tx.texture; + this.cvPositionColoredVertexies = tx.cvPositionColoredVertexies; + this.b加算合成 = tx.b加算合成; + this.fZ軸中心回転 = tx.fZ軸中心回転; + this.vc拡大縮小倍率 = tx.vc拡大縮小倍率; + // this._txData = null; + } + + public void UpdateTexture(Device device, Texture texture, int n幅, int n高さ) + { + this.texture = texture; + this.sz画像サイズ = new Size(n幅, n高さ); + this.szテクスチャサイズ = this.t指定されたサイズを超えない最適なテクスチャサイズを返す(device, this.sz画像サイズ); + this.rc全画像 = new Rectangle(0, 0, this.sz画像サイズ.Width, this.sz画像サイズ.Height); } /// @@ -1137,7 +1158,144 @@ namespace FDK device.SetTexture(0, this.texture); device.VertexFormat = PositionColoredTexturedVertex.Format; device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, this.cvPositionColoredVertexies); - } + } + + + + + public void t2D描画SongObj(Device device, float x, float y, float xScale, float yScale) + { + if (this.texture == null) + return; + + float depth = 1f; + Rectangle rc画像内の描画領域 = this.rc全画像; + + if (this.fZ軸中心回転 == 0f) + { + #region [ (A) 回転なし ] + //----------------- + float fx = ((float)rc画像内の描画領域.Width) / 2f; + float fy = ((float)rc画像内の描画領域.Height) / 2f; + float f左U値 = ((float)rc画像内の描画領域.Left) / ((float)this.szテクスチャサイズ.Width); + float f右U値 = ((float)rc画像内の描画領域.Right) / ((float)this.szテクスチャサイズ.Width); + float f上V値 = ((float)rc画像内の描画領域.Top) / ((float)this.szテクスチャサイズ.Height); + float f下V値 = ((float)rc画像内の描画領域.Bottom) / ((float)this.szテクスチャサイズ.Height); + this.color4.Alpha = ((float)this._opacity) / 255f; + int color = ToArgb(this.color4); + + if (this.cvPositionColoredVertexies == null) + this.cvPositionColoredVertexies = new PositionColoredTexturedVertex[4]; + + // #27122 2012.1.13 from: 以下、マネージドオブジェクト(=ガベージ)の量産を抑えるため、new は使わず、メンバに値を1つずつ直接上書きする。 + + this.cvPositionColoredVertexies[0].Position.X = -fx; + this.cvPositionColoredVertexies[0].Position.Y = fy; + this.cvPositionColoredVertexies[0].Position.Z = depth; + this.cvPositionColoredVertexies[0].Color = color; + this.cvPositionColoredVertexies[0].TextureCoordinates.X = f左U値; + this.cvPositionColoredVertexies[0].TextureCoordinates.Y = f上V値; + + this.cvPositionColoredVertexies[1].Position.X = fx; + this.cvPositionColoredVertexies[1].Position.Y = fy; + this.cvPositionColoredVertexies[1].Position.Z = depth; + this.cvPositionColoredVertexies[1].Color = color; + this.cvPositionColoredVertexies[1].TextureCoordinates.X = f右U値; + this.cvPositionColoredVertexies[1].TextureCoordinates.Y = f上V値; + + this.cvPositionColoredVertexies[2].Position.X = -fx; + this.cvPositionColoredVertexies[2].Position.Y = -fy; + this.cvPositionColoredVertexies[2].Position.Z = depth; + this.cvPositionColoredVertexies[2].Color = color; + this.cvPositionColoredVertexies[2].TextureCoordinates.X = f左U値; + this.cvPositionColoredVertexies[2].TextureCoordinates.Y = f下V値; + + this.cvPositionColoredVertexies[3].Position.X = fx; + this.cvPositionColoredVertexies[3].Position.Y = -fy; + this.cvPositionColoredVertexies[3].Position.Z = depth; + this.cvPositionColoredVertexies[3].Color = color; + this.cvPositionColoredVertexies[3].TextureCoordinates.X = f右U値; + this.cvPositionColoredVertexies[3].TextureCoordinates.Y = f下V値; + + this.tレンダリングステートの設定(device); + + var matrix = Matrix.Identity * Matrix.Scaling(new Vector3(xScale, yScale, 1f)); + matrix *= Matrix.Translation(x - SampleFramework.GameWindowSize.Width / 2.0f + fx, -(y - SampleFramework.GameWindowSize.Height / 2.0f + fy), 0f); + + device.SetTransform(TransformState.World, matrix); + device.SetTexture(0, this.texture); + device.VertexFormat = PositionColoredTexturedVertex.Format; + device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, this.cvPositionColoredVertexies); + + //----------------- + #endregion + } + else + { + #region [ (B) 回転あり ] + //----------------- + float fx = ((float)rc画像内の描画領域.Width) / 2f; + float fy = ((float)rc画像内の描画領域.Height) / 2f; + float f左U値 = ((float)rc画像内の描画領域.Left) / ((float)this.szテクスチャサイズ.Width); + float f右U値 = ((float)rc画像内の描画領域.Right) / ((float)this.szテクスチャサイズ.Width); + float f上V値 = ((float)rc画像内の描画領域.Top) / ((float)this.szテクスチャサイズ.Height); + float f下V値 = ((float)rc画像内の描画領域.Bottom) / ((float)this.szテクスチャサイズ.Height); + this.color4.Alpha = ((float)this._opacity) / 255f; + int color = ToArgb(this.color4); + + if (this.cvPositionColoredVertexies == null) + this.cvPositionColoredVertexies = new PositionColoredTexturedVertex[4]; + + // #27122 2012.1.13 from: 以下、マネージドオブジェクト(=ガベージ)の量産を抑えるため、new は使わず、メンバに値を1つずつ直接上書きする。 + + this.cvPositionColoredVertexies[0].Position.X = -fx; + this.cvPositionColoredVertexies[0].Position.Y = fy; + this.cvPositionColoredVertexies[0].Position.Z = depth; + this.cvPositionColoredVertexies[0].Color = color; + this.cvPositionColoredVertexies[0].TextureCoordinates.X = f左U値; + this.cvPositionColoredVertexies[0].TextureCoordinates.Y = f上V値; + + this.cvPositionColoredVertexies[1].Position.X = fx; + this.cvPositionColoredVertexies[1].Position.Y = fy; + this.cvPositionColoredVertexies[1].Position.Z = depth; + this.cvPositionColoredVertexies[1].Color = color; + this.cvPositionColoredVertexies[1].TextureCoordinates.X = f右U値; + this.cvPositionColoredVertexies[1].TextureCoordinates.Y = f上V値; + + this.cvPositionColoredVertexies[2].Position.X = -fx; + this.cvPositionColoredVertexies[2].Position.Y = -fy; + this.cvPositionColoredVertexies[2].Position.Z = depth; + this.cvPositionColoredVertexies[2].Color = color; + this.cvPositionColoredVertexies[2].TextureCoordinates.X = f左U値; + this.cvPositionColoredVertexies[2].TextureCoordinates.Y = f下V値; + + this.cvPositionColoredVertexies[3].Position.X = fx; + this.cvPositionColoredVertexies[3].Position.Y = -fy; + this.cvPositionColoredVertexies[3].Position.Z = depth; + this.cvPositionColoredVertexies[3].Color = color; + this.cvPositionColoredVertexies[3].TextureCoordinates.X = f右U値; + this.cvPositionColoredVertexies[3].TextureCoordinates.Y = f下V値; + + this.tレンダリングステートの設定(device); + + float n描画領域内X = x + (rc画像内の描画領域.Width / 2.0f); + float n描画領域内Y = y + (rc画像内の描画領域.Height / 2.0f); + var vc3移動量 = new Vector3(n描画領域内X - (((float)device.Viewport.Width) / 2f), -(n描画領域内Y - (((float)device.Viewport.Height) / 2f)), 0f); + + var matrix = Matrix.Identity * Matrix.Scaling(new Vector3(xScale, yScale, 1f)); + matrix *= Matrix.Translation(x - SampleFramework.GameWindowSize.Width / 2.0f + fx, -(y - SampleFramework.GameWindowSize.Height / 2.0f + fy), 0f); + matrix *= Matrix.RotationZ(this.fZ軸中心回転); + matrix *= Matrix.Translation(vc3移動量); + device.SetTransform(TransformState.World, matrix); + + device.SetTexture(0, this.texture); + device.VertexFormat = PositionColoredTexturedVertex.Format; + device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, this.cvPositionColoredVertexies); + //----------------- + #endregion + } + } + #region [ IDisposable 実装 ] //----------------- diff --git a/TJAPlayer3/Common/Easing.cs b/TJAPlayer3/Common/Easing.cs index dc863fea..6d4f4ae2 100644 --- a/TJAPlayer3/Common/Easing.cs +++ b/TJAPlayer3/Common/Easing.cs @@ -9,7 +9,7 @@ namespace TJAPlayer3 { class Easing { - public int EaseIn(CCounter counter, int startPoint, int endPoint, CalcType type) + public int EaseIn(CCounter counter, float startPoint, float endPoint, CalcType type) { StartPoint = startPoint; EndPoint = endPoint; @@ -46,11 +46,14 @@ namespace TJAPlayer3 CounterValue /= TimeMs; Value = -Sa * (Math.Sqrt(1 - CounterValue * CounterValue) - 1) + StartPoint; break; + case CalcType.Linear: //Linear + Value = Sa * (CounterValue / TimeMs) + StartPoint; + break; } return (int)Value; } - public int EaseOut(CCounter counter, int startPoint, int endPoint, CalcType type) + public int EaseOut(CCounter counter, float startPoint, float endPoint, CalcType type) { StartPoint = startPoint; EndPoint = endPoint; @@ -91,15 +94,102 @@ namespace TJAPlayer3 CounterValue--; Value = Sa * Math.Sqrt(1 - CounterValue * CounterValue) + StartPoint; break; + case CalcType.Linear: //Linear + CounterValue /= TimeMs; + Value = Sa * CounterValue + StartPoint; + break; } return (int)Value; } + public float EaseInOut(CCounter counter, float startPoint, float endPoint, CalcType type) + { + StartPoint = startPoint; + EndPoint = endPoint; + Sa = EndPoint - StartPoint; + TimeMs = counter.n終了値; + Type = type; + CounterValue = counter.n現在の値; - private int StartPoint; - private int EndPoint; - private int Sa; - private int TimeMs; + switch (Type) + { + case CalcType.Quadratic: //Quadratic + CounterValue /= TimeMs / 2; + if (CounterValue < 1) + { + Value = Sa / 2 * CounterValue * CounterValue + StartPoint; + break; + } + CounterValue--; + Value = -Sa / 2 * (CounterValue * (CounterValue - 2) - 1) + StartPoint; + break; + case CalcType.Cubic: //Cubic + CounterValue /= TimeMs / 2; + if (CounterValue < 1) + { + Value = Sa / 2 * CounterValue * CounterValue * CounterValue + StartPoint; + break; + } + CounterValue -= 2; + Value = Sa / 2 * (CounterValue * CounterValue * CounterValue + 2) + StartPoint; + break; + case CalcType.Quartic: //Quartic + CounterValue /= TimeMs / 2; + if (CounterValue < 1) + { + Value = Sa / 2 * CounterValue * CounterValue * CounterValue * CounterValue + StartPoint; + break; + } + CounterValue -= 2; + Value = -Sa / 2 * (CounterValue * CounterValue * CounterValue * CounterValue - 2) + StartPoint; + break; + case CalcType.Quintic: //Quintic + CounterValue /= TimeMs; + CounterValue /= TimeMs / 2; + if (CounterValue < 1) + { + Value = Sa / 2 * CounterValue * CounterValue * CounterValue * CounterValue * CounterValue + StartPoint; + break; + } + CounterValue -= 2; + Value = Sa / 2 * (CounterValue * CounterValue * CounterValue * CounterValue * CounterValue + 2) + StartPoint; + break; + case CalcType.Sinusoidal: //Sinusoidal + Value = -Sa / 2 * (Math.Cos(Math.PI * CounterValue / TimeMs) - 1) + StartPoint; + break; + case CalcType.Exponential: //Exponential + CounterValue /= TimeMs / 2; + if (CounterValue < 1) + { + Value = Sa / 2 * Math.Pow(2, 10 * (CounterValue - 1)) + StartPoint; + break; + } + CounterValue--; + Value = Sa / 2 * (-Math.Pow(2, -10 * CounterValue) + 2) + StartPoint; + break; + case CalcType.Circular: //Circular + CounterValue /= TimeMs / 2; + if (CounterValue < 1) + { + Value = -Sa / 2 * (Math.Sqrt(1 - CounterValue * CounterValue) - 1) + StartPoint; + break; + } + CounterValue -= 2; + Value = Sa / 2 * (Math.Sqrt(1 - CounterValue * CounterValue) + 1) + StartPoint; + break; + case CalcType.Linear: //Linear + CounterValue /= TimeMs; + Value = Sa * CounterValue + StartPoint; + break; + } + + return (float)Value; + } + + private float StartPoint; + private float EndPoint; + private float Sa; + private double TimeMs; private CalcType Type; private double CounterValue; private double Value; @@ -111,7 +201,8 @@ namespace TJAPlayer3 Quintic, Sinusoidal, Exponential, - Circular + Circular, + Linear } } } \ No newline at end of file diff --git a/TJAPlayer3/Common/TJAPlayer3.cs b/TJAPlayer3/Common/TJAPlayer3.cs index d3a132b1..eb910cc3 100644 --- a/TJAPlayer3/Common/TJAPlayer3.cs +++ b/TJAPlayer3/Common/TJAPlayer3.cs @@ -1944,7 +1944,26 @@ for (int i = 0; i < 3; i++) { break; } - actScanningLoudness.On進行描画(); + actScanningLoudness.On進行描画(); + + if (!ConfigIni.bTokkunMode) + { + float screen_ratiox = TJAPlayer3.Skin.Resolution[0] / 1280.0f; + float screen_ratioy = TJAPlayer3.Skin.Resolution[1] / 720.0f; + var mat = Matrix.LookAtLH(new Vector3(-fCamXOffset * screen_ratiox, fCamYOffset * screen_ratioy, (float)(-SampleFramework.GameWindowSize.Height / (fCamZoomFactor * 2) * Math.Sqrt(3.0))), new Vector3(-fCamXOffset * screen_ratiox, fCamYOffset * screen_ratioy, 0f), new Vector3(0f, 1f, 0f)); + mat *= Matrix.RotationYawPitchRoll(0, 0, C変換.DegreeToRadian(fCamRotation)); + mat *= Matrix.Scaling(fCamXScale, fCamYScale, 1f); + this.Device.SetTransform(TransformState.View, mat); + + if (TJAPlayer3.DTX != null) + { + //object rendering + foreach (KeyValuePair pair in TJAPlayer3.DTX.listObj) + { + pair.Value.tDraw(); + } + } + } if (r現在のステージ != null && r現在のステージ.eステージID != CStage.Eステージ.起動 && TJAPlayer3.Tx.Network_Connection != null) { @@ -1969,16 +1988,40 @@ for (int i = 0; i < 3; i++) { this.Device.EndScene(); // Present()は game.csのOnFrameEnd()に登録された、GraphicsDeviceManager.game_FrameEnd() 内で実行されるので不要 // (つまり、Present()は、Draw()完了後に実行される) #if !GPUFlushAfterPresent - actFlushGPU?.On進行描画(); // Flush GPU // EndScene()~Present()間 (つまりVSync前) でFlush実行 + actFlushGPU?.On進行描画(); // Flush GPU // EndScene()~Present()間 (つまりVSync前) でFlush実行 #endif + foreach(var capture in ConfigIni.KeyAssign.System.Capture) + { + if (TJAPlayer3.Input管理.Keyboard.bキーが押された(capture.コード)) + { + if (TJAPlayer3.Input管理.Keyboard.bキーが押されている((int)SlimDXKeys.Key.LeftControl)) + { + if (r現在のステージ.eステージID != CStage.Eステージ.演奏) + { + RefleshSkin(); + r現在のステージ.On非活性化(); + r現在のステージ.On活性化(); + } + } + else + { + // Debug.WriteLine( "capture: " + string.Format( "{0:2x}", (int) e.KeyCode ) + " " + (int) e.KeyCode ); + string strFullPath = + Path.Combine(TJAPlayer3.strEXEのあるフォルダ, "Capture_img"); + strFullPath = Path.Combine(strFullPath, DateTime.Now.ToString("yyyyMMddHHmmss") + ".png"); + SaveResultScreen(strFullPath); + } + } + } + /* if ( Sound管理?.GetCurrentSoundDeviceType() != "DirectSound" ) { Sound管理?.t再生中の処理をする(); // サウンドバッファの更新; 画面描画と同期させることで、スクロールをスムーズにする } - */ - + */ + #region [ 全画面_ウインドウ切り替え ] if ( this.b次のタイミングで全画面_ウィンドウ切り替えを行う ) { @@ -3389,18 +3432,6 @@ for (int i = 0; i < 3; i++) { } else { - for ( int i = 0; i < 0x10; i++ ) - { - if ( ConfigIni.KeyAssign.System.Capture[ i ].コード > 0 && - e.KeyCode == DeviceConstantConverter.KeyToKeyCode( (SlimDXKeys.Key) ConfigIni.KeyAssign.System.Capture[ i ].コード ) ) - { - // Debug.WriteLine( "capture: " + string.Format( "{0:2x}", (int) e.KeyCode ) + " " + (int) e.KeyCode ); - string strFullPath = - Path.Combine( TJAPlayer3.strEXEのあるフォルダ, "Capture_img" ); - strFullPath = Path.Combine( strFullPath, DateTime.Now.ToString( "yyyyMMddHHmmss" ) + ".png" ); - SaveResultScreen( strFullPath ); - } - } } } private void Window_MouseUp( object sender, MouseEventArgs e ) @@ -3426,8 +3457,21 @@ for (int i = 0; i < 3; i++) { ConfigIni.nウインドウwidth = (ConfigIni.bウィンドウモード) ? base.Window.ClientSize.Width : currentClientSize.Width; // #23510 2010.10.31 yyagi add ConfigIni.nウインドウheight = (ConfigIni.bウィンドウモード) ? base.Window.ClientSize.Height : currentClientSize.Height; - } + } #endregion + #endregion + + #region [ EXTENDED VARIABLES ] + public static float fCamXOffset; + public static float fCamYOffset; + + public static float fCamZoomFactor = 1.0f; + public static float fCamRotation; + + public static float fCamXScale = 1.0f; + public static float fCamYScale = 1.0f; + + public static Color4 borderColor = new Color4(1f, 0f, 0f, 0f); #endregion } } diff --git a/TJAPlayer3/Databases/DBCharacter.cs b/TJAPlayer3/Databases/DBCharacter.cs index 72deb878..aecc1dc3 100644 --- a/TJAPlayer3/Databases/DBCharacter.cs +++ b/TJAPlayer3/Databases/DBCharacter.cs @@ -6,6 +6,18 @@ namespace TJAPlayer3 { class DBCharacter { + public class CharacterEffect + { + public CharacterEffect() + { + Gauge = "Normal"; + } + + + [JsonProperty("gauge")] + public string Gauge; + } + public class CharacterData { public CharacterData() diff --git a/TJAPlayer3/Databases/DBPuchichara.cs b/TJAPlayer3/Databases/DBPuchichara.cs index 0da29ffb..c07467ab 100644 --- a/TJAPlayer3/Databases/DBPuchichara.cs +++ b/TJAPlayer3/Databases/DBPuchichara.cs @@ -6,6 +6,30 @@ namespace TJAPlayer3 { class DBPuchichara { + public class PuchicharaEffect + { + public PuchicharaEffect() + { + AllPurple = false; + Autoroll = 0; + ShowAdlib = false; + SplitLane = false; + } + + + [JsonProperty("allpurple")] + public bool AllPurple; + + [JsonProperty("AutoRoll")] + public int Autoroll; + + [JsonProperty("showadlib")] + public bool ShowAdlib; + + [JsonProperty("splitlane")] + public bool SplitLane; + } + public class PuchicharaData { public PuchicharaData() diff --git a/TJAPlayer3/Songs/CBoxDef.cs b/TJAPlayer3/Songs/CBoxDef.cs index b4c3e19d..c673e5d7 100644 --- a/TJAPlayer3/Songs/CBoxDef.cs +++ b/TJAPlayer3/Songs/CBoxDef.cs @@ -31,10 +31,13 @@ namespace TJAPlayer3 public int BoxChara; public bool IsChangedBoxChara; public string DefaultPreimage; - public string ScenePreset; - - // コンストラクタ - + public string ScenePreset; + + private readonly string langTITLE = "#TITLE" + CLangManager.fetchLang().ToUpper(); + private readonly string langBOXEXPLANATION = "#BOXEXPLANATION" + CLangManager.fetchLang().ToUpper(); + + // コンストラクタ + public CBoxDef() { for (int i = 0; i < 3; i++) @@ -79,11 +82,14 @@ namespace TJAPlayer3 str = str.Substring( 0, str.IndexOf( ';' ) ); } - char[] ignoreChars = new char[] { ':', ' ', '\t' }; - - if ( str.StartsWith( "#TITLE", StringComparison.OrdinalIgnoreCase ) ) + char[] ignoreChars = new char[] { ':', ' ', '\t' }; + if (str.StartsWith(langTITLE, StringComparison.OrdinalIgnoreCase)) { - this.Title = str.Substring( 6 ).Trim( ignoreChars ); + this.Title = str.Substring(8).Trim(ignoreChars); + } + else if(str.StartsWith("#TITLE", StringComparison.OrdinalIgnoreCase)) + { + if (this.Title == "") this.Title = str.Substring(6).Trim(ignoreChars); } else if( str.StartsWith( "#GENRE", StringComparison.OrdinalIgnoreCase ) ) { @@ -142,12 +148,16 @@ namespace TJAPlayer3 } else { - for(int i = 0; i < 3; i++) - { - if (str.StartsWith("#BOXEXPLANATION" + (i + 1).ToString(), StringComparison.OrdinalIgnoreCase)) - { - this.strBoxText[i] = str.Substring(16).Trim(ignoreChars); - } + for(int i = 0; i < 3; i++) + { + if (str.StartsWith(langBOXEXPLANATION + (i + 1).ToString(), StringComparison.OrdinalIgnoreCase)) + { + this.strBoxText[i] = str.Substring(18).Trim(ignoreChars); + } + else if (str.StartsWith("#BOXEXPLANATION" + (i + 1).ToString(), StringComparison.OrdinalIgnoreCase)) + { + if (this.strBoxText[i] == "") this.strBoxText[i] = str.Substring(16).Trim(ignoreChars); + } } } } diff --git a/TJAPlayer3/Songs/CDTX.cs b/TJAPlayer3/Songs/CDTX.cs index 51334777..ea5905e9 100644 --- a/TJAPlayer3/Songs/CDTX.cs +++ b/TJAPlayer3/Songs/CDTX.cs @@ -12,6 +12,10 @@ using FDK; using FDK.ExtensionMethods; using System.Linq; using TJAPlayer3; +using SharpDX; + +using Point = System.Drawing.Point; +using Color = System.Drawing.Color; namespace TJAPlayer3 { @@ -21,6 +25,8 @@ namespace TJAPlayer3 public enum E種別 { DTX, GDA, G2D, BMS, BME, SMF } + public List listErrors = new List(); + private int nNowReadLine; // クラス public class CAVI : IDisposable @@ -410,7 +416,58 @@ namespace TJAPlayer3 public int nList上の位置; public bool IsFixedSENote; public bool IsHitted = false; - public bool IsMissed = false; + public bool IsMissed = false; + + + + //EXTENDED COMMANDS + public int fCamTimeMs; + public string strCamEaseType; + public Easing.CalcType fCamMoveType; + + public float fCamScrollStartX; + public float fCamScrollStartY; + public float fCamScrollEndX; + public float fCamScrollEndY; + + public float fCamRotationStart; + public float fCamRotationEnd; + + public float fCamZoomStart; + public float fCamZoomEnd; + + public float fCamScaleStartX; + public float fCamScaleStartY; + public float fCamScaleEndX; + public float fCamScaleEndY; + + public Color4 borderColor; + + public int fObjTimeMs; + public string strObjName; + public string strObjEaseType; + public Easing.CalcType objCalcType; + + public float fObjX; + public float fObjY; + + public float fObjStart; + public float fObjEnd; + + public CSongObject obj; + + public string strTargetTxName; + public string strNewPath; + + public string strConfigValue; + + public double dbAnimInterval; + + public int intFrame; + + public EGameType eGameType; + // + public bool bBPMチップである { @@ -524,11 +581,11 @@ namespace TJAPlayer3 "小節線", "拍線", "??", "??", "AVI", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", - //システム(移動予定) - "SCROLL", "DELAY", "ゴーゴータイム開始", "ゴーゴータイム終了", "??", "??", "??", "??", - "??", "??", "??", "??", "??", "??", "??", "??", - - "??", "??", "??", "??", "??", "??", "??", "??", + //システム(移動予定) + "SCROLL", "DELAY", "ゴーゴータイム開始", "ゴーゴータイム終了", "カメラ移動開始(縦)", "カメラ移動終了(縦)", "カメラ移動開始(横)", "カメラ移動終了(横)", + "カメラズーム開始", "カメラズーム終了", "カメラ回転開始", "カメラ回転終了", "カメラスケーリング開始(横)", "カメラスケーリング終了(横)", "カメラスケーリング開始(縦)", "カメラスケーリング終了(縦)", + + "ボーダーカラー変更", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", "??", @@ -1383,7 +1440,13 @@ namespace TJAPlayer3 public bool IsEnabledFixSENote; public int FixSENote; - public GaugeIncreaseMode GaugeIncreaseMode; + public GaugeIncreaseMode GaugeIncreaseMode; + + #region [ EXTENDED VARiABLES ] + public Dictionary listObj; + public Dictionary listTextures; + public Dictionary listOriginalTextures; + #endregion @@ -1958,6 +2021,30 @@ namespace TJAPlayer3 case Eランダムモード.OFF: default: break; + } + + if (TJAPlayer3.Tx.Puchichara[PuchiChara.tGetPuchiCharaIndexByName(TJAPlayer3.GetActualPlayer(nPlayerSide))].effect.AllPurple) + { + foreach (var chip in this.listChip) + { + switch (chip.nチャンネル番号) + { + case 0x11: + chip.nチャンネル番号 = 0x101; + break; + case 0x12: + chip.nチャンネル番号 = 0x101; + break; + case 0x13: + chip.nチャンネル番号 = 0x101; + chip.nSenote = 6; + break; + case 0x14: + chip.nチャンネル番号 = 0x101; + chip.nSenote = 5; + break; + } + } } if (eRandom != Eランダムモード.OFF) @@ -3228,6 +3315,7 @@ namespace TJAPlayer3 // private static readonly HashSet valableTokens = new HashSet(@"TIT|LEV|BPM|WAV|OFF|BAL|EXA|DAN|REN|BAL|SON|SEV|SCO|COU|STY|TOW|GAM|LIF|DEM|SID|SUB|GEN|MOV|BGI|BGM|HID|GAU|LYR|#HB|#BM".Split('|')); + private int nDifficulty; /// /// 新型。 @@ -3239,6 +3327,7 @@ namespace TJAPlayer3 /// 譜面のデータ private void t入力_V4(string strInput, int difficulty) { + nDifficulty = difficulty; if (!String.IsNullOrEmpty(strInput)) //空なら通さない { @@ -3412,6 +3501,7 @@ namespace TJAPlayer3 //string strWrite = ""; for (int i = 0; strSplitした後の譜面.Length > i; i++) { + nNowReadLine++; str = strSplitした後の譜面[i]; //strWrite += str; //if( !str.StartsWith( "#" ) && !string.IsNullOrEmpty( this.strTemp ) ) @@ -3489,7 +3579,20 @@ namespace TJAPlayer3 new Regex(@"^(#[A-Z]+)(?:\s?)(.+?)?$", RegexOptions.Compiled); private static readonly Regex BranchStartArgumentRegex = - new Regex(@"^([^,\s]+)\s*,\s*([^,\s]+)\s*,\s*([^,\s]+)$", RegexOptions.Compiled); + new Regex(@"^([^,\s]+)\s*,\s*([^,\s]+)\s*,\s*([^,\s]+)$", RegexOptions.Compiled); + + private void AddError(string command, string argument) + { + listErrors.Add($"コメントアウトを除く{(Difficulty)nDifficulty}の{nNowReadLine}行目の{command}が正しくありません。値が{argument}になっています"); + } + private void AddError_Single(string str) + { + listErrors.Add($"コメントアウトを除く{(Difficulty)nDifficulty}の{nNowReadLine}行目の{str}"); + } + private void AddError(string str) + { + listErrors.Add(str); + } private string[] SplitComma(string input) { @@ -3670,7 +3773,12 @@ namespace TJAPlayer3 else if (command == "#BPMCHANGE") { - double dbBPM = Convert.ToDouble(argument); + double dbBPM; + if (!double.TryParse(argument, out dbBPM)) + { + AddError(command, argument); + dbBPM = 150; + } this.dbNowBPM = dbBPM; if (dbBPM > MaxBPM) @@ -3726,7 +3834,16 @@ namespace TJAPlayer3 //iが入っていた場合、複素数スクロールとみなす。 double[] dbComplexNum = new double[2]; - this.tParsedComplexNumber(argument, ref dbComplexNum); + try + { + this.tParsedComplexNumber(argument, ref dbComplexNum); + } + catch(Exception ex) + { + AddError(command, argument); + dbComplexNum[0] = 1.0; + dbComplexNum[1] = 0.0; + } this.dbNowScroll = dbComplexNum[0]; this.dbNowScrollY = dbComplexNum[1]; @@ -3772,7 +3889,13 @@ namespace TJAPlayer3 } else { - double dbSCROLL = Convert.ToDouble(argument); + double dbSCROLL = 1.0; + if (!double.TryParse(argument, out dbSCROLL)) + { + AddError(command, argument); + dbSCROLL = 1; + } + this.dbNowScroll = dbSCROLL; this.dbNowScrollY = 0.0; @@ -3820,8 +3943,15 @@ namespace TJAPlayer3 WarnSplitLength("#MEASURE subsplit", strArray, 2); double[] dbLength = new double[2]; - dbLength[0] = Convert.ToDouble(strArray[0]); - dbLength[1] = Convert.ToDouble(strArray[1]); + try + { + dbLength[0] = Convert.ToDouble(strArray[0]); + dbLength[1] = Convert.ToDouble(strArray[1]); + } + catch(Exception ex) + { + AddError(command, argument); + } double db小節長倍率 = dbLength[0] / dbLength[1]; this.dbBarLength = db小節長倍率; @@ -3846,7 +3976,13 @@ namespace TJAPlayer3 } else if (command == "#DELAY") { - double nDELAY = (Convert.ToDouble(argument) * 1000.0); + double nDELAY = 0; + if (!double.TryParse(argument, out nDELAY)) + { + AddError(command, argument); + nDELAY = 0; + } + nDELAY *= 1000; this.listDELAY.Add(this.n内部番号DELAY1to, new CDELAY() { n内部番号 = this.n内部番号DELAY1to, n表記上の番号 = 0, nDELAY値 = (int)nDELAY, delay_bmscroll_time = this.dbLastBMScrollTime, delay_bpm = this.dbNowBPM, delay_course = this.n現在のコース, delay_time = this.dbLastTime }); @@ -3903,7 +4039,2121 @@ namespace TJAPlayer3 // チップを配置。 this.listChip.Add(chip); + } + + + else if (command == "#CAMVMOVESTART") + { + if (currentCamVMoveChip == null) + { + //starts vertical camera moving + //arguments: ,,, + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA0; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + try + { + string[] args = argument.Split(','); + chip.fCamScrollStartY = float.Parse(args[0]); + chip.fCamScrollEndY = float.Parse(args[1]); + chip.strCamEaseType = args[2]; + + var type = args[3]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.fCamMoveType = eType; + + currentCamVMoveChip = chip; + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else + { + AddError_Single("Missing #CAMVMOVEEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMVMOVEEND"); + } + } + else if (command == "#CAMVMOVEEND") + { + if (currentCamVMoveChip != null) + { + //ends vertical camera moving + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA1; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + var index = this.listChip.IndexOf(currentCamVMoveChip); + var msDiff = chip.n発声時刻ms - currentCamVMoveChip.n発声時刻ms; + + currentCamVMoveChip.fCamTimeMs = msDiff; + this.listChip[index] = currentCamVMoveChip; + + currentCamVMoveChip = null; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMVMOVESTART"); + Trace.TraceInformation("TJA ERROR: Missing #CAMVMOVESTART"); + } + } + else if (command == "#CAMHMOVESTART") + { + if (currentCamHMoveChip == null) + { + //starts horizontal camera moving + //arguments: ,,, + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA2; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + try + { + string[] args = argument.Split(','); + chip.fCamScrollStartX = float.Parse(args[0]); + chip.fCamScrollEndX = float.Parse(args[1]); + chip.strCamEaseType = args[2]; + + var type = args[3]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.fCamMoveType = eType; + + currentCamHMoveChip = chip; + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else + { + AddError_Single("Missing #CAMHMOVEEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMHMOVEEND"); + } + } + else if (command == "#CAMHMOVEEND") + { + if (currentCamHMoveChip != null) + { + //ends horizontal camera moving + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA3; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + var index = this.listChip.IndexOf(currentCamHMoveChip); + var msDiff = chip.n発声時刻ms - currentCamHMoveChip.n発声時刻ms; + + currentCamHMoveChip.fCamTimeMs = msDiff; + this.listChip[index] = currentCamHMoveChip; + + currentCamHMoveChip = null; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMHMOVESTART"); + Trace.TraceInformation("TJA ERROR: Missing #CAMHMOVESTART"); + } + } + else if (command == "#CAMZOOMSTART") + { + if (currentCamZoomChip == null) + { + //starts zooming in/out the screen + //arguments: ,,, + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA4; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + try + { + string[] args = argument.Split(','); + chip.fCamZoomStart = float.Parse(args[0]); + chip.fCamZoomEnd = float.Parse(args[1]); + chip.strCamEaseType = args[2]; + + var type = args[3]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.fCamMoveType = eType; + + currentCamZoomChip = chip; + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else + { + AddError_Single("Missing #CAMZOOMEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMZOOMEND"); + } + } + else if (command == "#CAMZOOMEND") + { + if (currentCamZoomChip != null) + { + //stops zooming + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA5; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + var index = this.listChip.IndexOf(currentCamZoomChip); + var msDiff = chip.n発声時刻ms - currentCamZoomChip.n発声時刻ms; + + currentCamZoomChip.fCamTimeMs = msDiff; + this.listChip[index] = currentCamZoomChip; + + currentCamZoomChip = null; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMZOOMSTART"); + Trace.TraceInformation("TJA ERROR: Missing #CAMZOOMSTART"); + } + } + else if (command == "#CAMROTATIONSTART") + { + if (currentCamRotateChip == null) + { + //starts rotating the screen + //arguments: ,,, + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA6; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + try + { + string[] args = argument.Split(','); + chip.fCamRotationStart = float.Parse(args[0]); + chip.fCamRotationEnd = float.Parse(args[1]); + chip.strCamEaseType = args[2]; + + var type = args[3]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.fCamMoveType = eType; + + currentCamRotateChip = chip; + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else + { + AddError_Single("Missing #CAMROTATIONEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMROTATIONEND"); + } + } + else if (command == "#CAMROTATIONEND") + { + if (currentCamRotateChip != null) + { + //stops screen rotation + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA7; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + var index = this.listChip.IndexOf(currentCamRotateChip); + var msDiff = chip.n発声時刻ms - currentCamRotateChip.n発声時刻ms; + + currentCamRotateChip.fCamTimeMs = msDiff; + this.listChip[index] = currentCamRotateChip; + + currentCamRotateChip = null; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMROTATIONSTART"); + Trace.TraceInformation("TJA ERROR: Missing #CAMROTATIONSTART"); + } + } + else if (command == "#CAMVSCALESTART") + { + if (currentCamVScaleChip == null) + { + //starts vertical camera scale changing + //arguments: ,,, + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA8; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + try + { + string[] args = argument.Split(','); + chip.fCamScaleStartY = float.Parse(args[0]); + chip.fCamScaleEndY = float.Parse(args[1]); + chip.strCamEaseType = args[2]; + + var type = args[3]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.fCamMoveType = eType; + + currentCamVScaleChip = chip; + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else + { + AddError_Single("Missing #CAMVSCALEEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMVSCALEEND"); + } + } + else if (command == "#CAMVSCALEEND") + { + if (currentCamVScaleChip != null) + { + //ends vertical camera scaling + var chip = new CChip(); + + chip.nチャンネル番号 = 0xA9; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + var index = this.listChip.IndexOf(currentCamVScaleChip); + var msDiff = chip.n発声時刻ms - currentCamVScaleChip.n発声時刻ms; + + currentCamVScaleChip.fCamTimeMs = msDiff; + this.listChip[index] = currentCamVScaleChip; + + currentCamVScaleChip = null; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMVSCALESTART"); + Trace.TraceInformation("TJA ERROR: Missing #CAMVSCALESTART"); + } + } + else if (command == "#CAMHSCALESTART") + { + if (currentCamHScaleChip == null) + { + //starts horizontal camera scale changing + //arguments: ,,, + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB0; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + try + { + string[] args = argument.Split(','); + chip.fCamScaleStartX = float.Parse(args[0]); + chip.fCamScaleEndX = float.Parse(args[1]); + chip.strCamEaseType = args[2]; + + var type = args[3]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.fCamMoveType = eType; + + currentCamHScaleChip = chip; + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else + { + AddError_Single("Missing #CAMHSCALEEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMHSCALEEND"); + } + } + else if (command == "#CAMHSCALEEND") + { + if (currentCamHScaleChip != null) + { + //ends horizontal camera scaling + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB1; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + var index = this.listChip.IndexOf(currentCamHScaleChip); + var msDiff = chip.n発声時刻ms - currentCamHScaleChip.n発声時刻ms; + + currentCamHScaleChip.fCamTimeMs = msDiff; + this.listChip[index] = currentCamHScaleChip; + + currentCamHScaleChip = null; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMHSCALESTART"); + Trace.TraceInformation("TJA ERROR: Missing #CAMHSCALESTART"); + } + } + else if (command == "#BORDERCOLOR") + { + //sets border color + //arguments: ,, + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB2; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + string[] args = argument.Split(','); + chip.borderColor = new Color4(1f, float.Parse(args[0]) / 255, float.Parse(args[1]) / 255, float.Parse(args[2]) / 255); + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#CAMHOFFSET") + { + if (currentCamHMoveChip == null) + { + //sets camera x offset + //argument: + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB3; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + if (float.TryParse(argument, out float value)) + { + chip.fCamScrollStartX = value; + chip.fCamScrollEndX = value; + } + else + { + AddError(command, argument); + } + chip.strCamEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMHMOVEEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMHMOVEEND"); + } + } + else if (command == "#CAMVOFFSET") + { + if (currentCamVMoveChip == null) + { + //sets camera y offset + //argument: + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB4; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + if (float.TryParse(argument, out float value)) + { + chip.fCamScrollStartY = float.Parse(argument); + chip.fCamScrollEndY = float.Parse(argument); + } + else + { + AddError(command, argument); + } + chip.strCamEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMVMOVEEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMVMOVEEND"); + } + } + else if (command == "#CAMZOOM") + { + if (currentCamZoomChip == null) + { + //sets camera zoom factor + //argument: + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB5; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + if (float.TryParse(argument, out float value)) + { + chip.fCamZoomStart = float.Parse(argument); + chip.fCamZoomEnd = float.Parse(argument); + } + else + { + AddError(command, argument); + } + chip.strCamEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMZOOMEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMZOOMEND"); + } + } + else if (command == "#CAMROTATION") + { + if (currentCamRotateChip == null) + { + //sets camera rotation + //argument: + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB6; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + if (float.TryParse(argument, out float value)) + { + chip.fCamRotationStart = float.Parse(argument); + chip.fCamRotationEnd = float.Parse(argument); + } + else + { + AddError(command, argument); + } + chip.strCamEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMROTATIONEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMROTATIONEND"); + } + } + else if (command == "#CAMHSCALE") + { + if (currentCamHScaleChip == null) + { + //sets camera x scale + //argument: + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB7; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + if (float.TryParse(argument, out float value)) + { + chip.fCamScaleStartX = float.Parse(argument); + chip.fCamScaleEndX = float.Parse(argument); + } + else + { + AddError(command, argument); + } + chip.strCamEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMHSCALEEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMHSCALEEND"); + } + } + else if (command == "#CAMVSCALE") + { + if (currentCamVScaleChip == null) + { + //sets camera y scale + //argument: + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB8; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + if (float.TryParse(argument, out float value)) + { + chip.fCamScaleStartY = float.Parse(argument); + chip.fCamScaleEndY = float.Parse(argument); + } + else + { + AddError(command, argument); + } + chip.strCamEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #CAMVSCALEEND"); + Trace.TraceInformation("TJA ERROR: Missing #CAMVSCALEEND"); + } + } + else if (command == "#CAMRESET") + { + //resets camera properties + var chip = new CChip(); + + chip.nチャンネル番号 = 0xB9; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + chip.fCamScrollStartX = 0.0f; + chip.fCamScrollEndX = 0.0f; + chip.fCamScrollStartY = 0.0f; + chip.fCamScrollEndY = 0.0f; + + chip.fCamZoomStart = 1.0f; + chip.fCamZoomEnd = 1.0f; + chip.fCamRotationStart = 0.0f; + chip.fCamRotationEnd = 0.0f; + + chip.fCamScaleStartX = 1.0f; + chip.fCamScaleEndX = 1.0f; + chip.fCamScaleStartY = 1.0f; + chip.fCamScaleEndY = 1.0f; + + chip.strCamEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#ENABLEDORON") + { + //resets camera properties + var chip = new CChip(); + + chip.nチャンネル番号 = 0xBA; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#DISABLEDORON") + { + //resets camera properties + var chip = new CChip(); + + chip.nチャンネル番号 = 0xBB; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#ADDOBJECT") + { + //adds object + var chip = new CChip(); + + chip.nチャンネル番号 = 0xBC; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + try + { + string[] args = argument.Split(','); + + chip.strObjName = args[0]; + chip.fObjX = float.Parse(args[1]); + chip.fObjY = float.Parse(args[2]); + var txPath = this.strフォルダ名 + args[3]; + Trace.TraceInformation("" + this.bSession譜面を読み込む); + if (this.bSession譜面を読み込む) + { + var obj = new CSongObject(chip.strObjName, chip.fObjX, chip.fObjY, txPath); + this.listObj.Add(args[0], obj); + } + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#REMOVEOBJECT") + { + //removes object + var chip = new CChip(); + + chip.nチャンネル番号 = 0xBD; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + chip.strObjName = argument; + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#OBJVMOVESTART") + { + string[] args = argument.Split(','); + + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("vmove_" + name)) + { + //starts vertical object movement + //arguments: ,,, + var chip = new CChip(); + + chip.nチャンネル番号 = 0xBE; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[2]); + chip.strObjEaseType = args[3]; + + var type = args[4]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.objCalcType = eType; + + currentObjAnimations.Add("vmove_" + name, chip); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJVMOVEEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJVMOVEEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJVMOVEEND") + { + string name = argument; + + if (currentObjAnimations.ContainsKey("vmove_" + name)) + { + //ends vertical camera moving + var chip = new CChip(); + + chip.nチャンネル番号 = 0xBF; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + chip.strObjName = argument; + + currentObjAnimations.TryGetValue("vmove_" + name, out CChip startChip); + + var index = this.listChip.IndexOf(startChip); + var msDiff = chip.n発声時刻ms - startChip.n発声時刻ms; + + startChip.fObjTimeMs = msDiff; + this.listChip[index] = startChip; + + currentObjAnimations.Remove("vmove_" + name); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJVMOVESTART"); + Trace.TraceInformation("TJA ERROR: Missing #OBJVMOVESTART"); + } + } + else if (command == "#OBJHMOVESTART") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("hmove_" + name)) + { + //starts horizontal object movement + //arguments: ,,, + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC0; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[2]); + chip.strObjEaseType = args[3]; + + var type = args[4]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.objCalcType = eType; + + currentObjAnimations.Add("hmove_" + name, chip); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJHMOVEEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJHMOVEEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJHMOVEEND") + { + string name = argument; + + if (currentObjAnimations.ContainsKey("hmove_" + name)) + { + //ends horizontal camera moving + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC1; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + chip.strObjName = argument; + + currentObjAnimations.TryGetValue("hmove_" + name, out CChip startChip); + + var index = this.listChip.IndexOf(startChip); + var msDiff = chip.n発声時刻ms - startChip.n発声時刻ms; + + startChip.fObjTimeMs = msDiff; + this.listChip[index] = startChip; + + currentObjAnimations.Remove("hmove_" + name); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJHMOVESTART"); + Trace.TraceInformation("TJA ERROR: Missing #OBJHMOVESTART"); + } + } + else if (command == "#OBJVSCALESTART") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("vscale_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC2; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[2]); + chip.strObjEaseType = args[3]; + + var type = args[4]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.objCalcType = eType; + + currentObjAnimations.Add("vscale_" + name, chip); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJVSCALEEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJVSCALEEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJVSCALEEND") + { + string name = argument; + + if (currentObjAnimations.ContainsKey("vscale_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC3; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + chip.strObjName = argument; + + currentObjAnimations.TryGetValue("vscale_" + name, out CChip startChip); + + var index = this.listChip.IndexOf(startChip); + var msDiff = chip.n発声時刻ms - startChip.n発声時刻ms; + + startChip.fObjTimeMs = msDiff; + this.listChip[index] = startChip; + + currentObjAnimations.Remove("vscale_" + name); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJVSCALESTART"); + Trace.TraceInformation("TJA ERROR: Missing #OBJVSCALESTART"); + } + } + else if (command == "#OBJHSCALESTART") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("hscale_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC4; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[2]); + chip.strObjEaseType = args[3]; + + var type = args[4]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.objCalcType = eType; + + currentObjAnimations.Add("hscale_" + name, chip); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJHSCALEEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJHSCALEEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJHSCALEEND") + { + string name = argument; + + if (currentObjAnimations.ContainsKey("hscale_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC5; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + chip.strObjName = argument; + + currentObjAnimations.TryGetValue("hscale_" + name, out CChip startChip); + + var index = this.listChip.IndexOf(startChip); + var msDiff = chip.n発声時刻ms - startChip.n発声時刻ms; + + startChip.fObjTimeMs = msDiff; + this.listChip[index] = startChip; + + currentObjAnimations.Remove("hscale_" + name); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJHSCALESTART"); + Trace.TraceInformation("TJA ERROR: Missing #OBJHSCALESTART"); + } + } + else if (command == "#OBJROTATIONSTART") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("rotation_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC6; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[2]); + chip.strObjEaseType = args[3]; + + var type = args[4]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.objCalcType = eType; + + currentObjAnimations.Add("rotation_" + name, chip); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJROTATIONEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJROTATIONEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJROTATIONEND") + { + string name = argument; + + if (currentObjAnimations.ContainsKey("rotation_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC7; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + chip.strObjName = argument; + + currentObjAnimations.TryGetValue("rotation_" + name, out CChip startChip); + + var index = this.listChip.IndexOf(startChip); + var msDiff = chip.n発声時刻ms - startChip.n発声時刻ms; + + startChip.fObjTimeMs = msDiff; + this.listChip[index] = startChip; + + currentObjAnimations.Remove("rotation_" + name); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJROTATIONSTART"); + Trace.TraceInformation("TJA ERROR: Missing #OBJROTATIONSTART"); + } + } + else if (command == "#OBJOPACITYSTART") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("opacity_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC8; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[2]); + chip.strObjEaseType = args[3]; + + var type = args[4]; + var eType = Easing.CalcType.Quadratic; + switch (type) + { + case "CUBIC": + eType = Easing.CalcType.Cubic; + break; + case "QUARTIC": + eType = Easing.CalcType.Quartic; + break; + case "QUINTIC": + eType = Easing.CalcType.Quintic; + break; + case "SINUSOIDAL": + eType = Easing.CalcType.Sinusoidal; + break; + case "EXPONENTIAL": + eType = Easing.CalcType.Exponential; + break; + case "CIRCULAR": + eType = Easing.CalcType.Circular; + break; + case "LINEAR": + eType = Easing.CalcType.Linear; + break; + default: + break; + } + + chip.objCalcType = eType; + + currentObjAnimations.Add("opacity_" + name, chip); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJOPACITYEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJOPACITYEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJOPACITYEND") + { + string name = argument; + + if (currentObjAnimations.ContainsKey("opacity_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xC9; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + chip.strObjName = argument; + + currentObjAnimations.TryGetValue("opacity_" + name, out CChip startChip); + + var index = this.listChip.IndexOf(startChip); + var msDiff = chip.n発声時刻ms - startChip.n発声時刻ms; + + startChip.fObjTimeMs = msDiff; + this.listChip[index] = startChip; + + currentObjAnimations.Remove("opacity_" + name); + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJOPACITYSTART"); + Trace.TraceInformation("TJA ERROR: Missing #OBJOPACITYSTART"); + } + } + else if (command == "#OBJCOLOR") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xCA; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + try + { + string[] args = argument.Split(','); + chip.strObjName = args[0]; + chip.borderColor = new Color4(1f, float.Parse(args[1]) / 255, float.Parse(args[2]) / 255, float.Parse(args[3]) / 255); + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJY") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("vmove_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xCB; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[1]); + chip.strObjEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJVMOVEEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJVMOVEEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJX") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("hmove_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xCC; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[1]); + chip.strObjEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJHMOVEEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJHMOVEEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJVSCALE") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("vscale_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xCD; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[1]); + chip.strObjEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJVSCALEEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJVSCALEEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJHSCALE") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("hscale_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xCE; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[1]); + chip.strObjEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJHSCALEEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJHSCALEEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJROTATION") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("rotation_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xCF; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[1]); + chip.strObjEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJROTATIONEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJROTATIONEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJOPACITY") + { + string[] args = argument.Split(','); + try + { + string name = args[0]; + + if (!currentObjAnimations.ContainsKey("opacity_" + name)) + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD0; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 0; + + chip.strObjName = args[0]; + chip.fObjStart = float.Parse(args[1]); + chip.fObjEnd = float.Parse(args[1]); + chip.strObjEaseType = "IN_OUT"; + + // チップを配置。 + this.listChip.Add(chip); + } + else + { + AddError_Single("Missing #OBJOPACITYEND"); + Trace.TraceInformation("TJA ERROR: Missing #OBJOPACITYEND"); + } + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#CHANGETEXTURE") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD1; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + string[] args = argument.Split(','); + try + { + chip.strTargetTxName = args[0].Replace("/", "\\"); + chip.strNewPath = this.strフォルダ名 + args[1]; + + if (this.bSession譜面を読み込む) + { + if (!this.listOriginalTextures.ContainsKey(chip.strTargetTxName)) + { + TJAPlayer3.Tx.trackedTextures.TryGetValue(chip.strTargetTxName, out CTexture oldTx); + this.listOriginalTextures.Add(chip.strTargetTxName, new CTexture(oldTx)); + } + if (!this.listTextures.ContainsKey(chip.strNewPath)) + { + CTexture tx = TJAPlayer3.Tx.TxCSong(chip.strNewPath); + this.listTextures.Add(chip.strNewPath, tx); + } + } + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#RESETTEXTURE") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD2; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + chip.strTargetTxName = argument.Replace("/", "\\"); + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#SETCONFIG") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD3; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + chip.strConfigValue = argument; + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#OBJANIMSTART") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD4; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + string[] args = argument.Split(','); + try + { + chip.strObjName = args[0]; + chip.dbAnimInterval = double.Parse(args[1]); + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJANIMSTARTLOOP") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD5; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + string[] args = argument.Split(','); + try + { + chip.strObjName = args[0]; + chip.dbAnimInterval = double.Parse(args[1]); + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#OBJANIMEND") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD6; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + chip.strObjName = argument; + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#OBJFRAME") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD7; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + string[] args = argument.Split(','); + try + { + chip.strObjName = args[0]; + chip.intFrame = int.Parse(args[1]); + + // チップを配置。 + this.listChip.Add(chip); + } + catch (Exception ex) + { + AddError(command, argument); + } + } + else if (command == "#GAMETYPE") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD8; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + switch(argument) + { + case "Taiko": + chip.eGameType = EGameType.TAIKO; + break; + case "Konga": + chip.eGameType = EGameType.KONGA; + break; + } + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#SPLITLANE") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xD9; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#MERGELANE") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xE3; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + + // チップを配置。 + this.listChip.Add(chip); + } + else if (command == "#BARLINE") + { + var chip = new CChip(); + + chip.nチャンネル番号 = 0xE4; + chip.n発声位置 = ((this.n現在の小節数) * 384); + chip.dbBPM = this.dbNowBPM; + chip.dbSCROLL = this.dbNowScroll; + chip.dbSCROLL_Y = this.dbNowScrollY; + chip.n発声時刻ms = (int)this.dbNowTime; + chip.fNow_Measure_m = this.fNow_Measure_m; + chip.fNow_Measure_s = this.fNow_Measure_s; + chip.n整数値_内部番号 = 1; + chip.bHideBarLine = false; + + // チップを配置。 + this.listChip.Add(chip); } + else if (command == "#SECTION") { //分岐:条件リセット @@ -6358,7 +8608,11 @@ namespace TJAPlayer3 this.listLine = new List(); this.listLyric = new List(); this.listLyric2 = new List(); - this.List_DanSongs = new List(); + this.List_DanSongs = new List(); + this.listObj = new Dictionary(); + this.listTextures = new Dictionary(); + this.listOriginalTextures = new Dictionary(); + this.currentObjAnimations = new Dictionary(); base.On活性化(); } public override void On非活性化() @@ -6467,7 +8721,44 @@ namespace TJAPlayer3 if (this.listLyric2 != null) { this.listLyric2.Clear(); + } + + + + if (this.listObj != null) + { + foreach (KeyValuePair pair in this.listObj) + { + pair.Value.tDispose(); + } + this.listObj.Clear(); + } + + if (this.listOriginalTextures != null) + { + foreach (KeyValuePair pair in this.listOriginalTextures) + { + string txPath = pair.Key; + CTexture originalTx = pair.Value; + TJAPlayer3.Tx.trackedTextures.TryGetValue(txPath, out CTexture oldTx); + + if (oldTx != originalTx) + { + oldTx.UpdateTexture(TJAPlayer3.app.Device, originalTx.texture, originalTx.sz画像サイズ.Width, originalTx.sz画像サイズ.Height); + } + } + this.listOriginalTextures.Clear(); + } + + if (this.listTextures != null) + { + foreach (KeyValuePair pair in this.listTextures) + { + pair.Value.Dispose(); + } + this.listTextures.Clear(); } + base.On非活性化(); } public override void OnManagedリソースの作成() @@ -6542,8 +8833,17 @@ namespace TJAPlayer3 private int[] n無限管理WAV; private int[] nRESULTIMAGE用優先順位; private int[] nRESULTMOVIE用優先順位; - private int[] nRESULTSOUND用優先順位; - + private int[] nRESULTSOUND用優先順位; + + private CChip currentCamVMoveChip; + private CChip currentCamHMoveChip; + private CChip currentCamRotateChip; + private CChip currentCamZoomChip; + private CChip currentCamVScaleChip; + private CChip currentCamHScaleChip; + + private Dictionary currentObjAnimations; + private void t行のコメント処理(ref string strText) { int nCommentPos = strText.IndexOf("//"); diff --git a/TJAPlayer3/Songs/Extended/CSongObject.cs b/TJAPlayer3/Songs/Extended/CSongObject.cs new file mode 100644 index 00000000..bba1ab1d --- /dev/null +++ b/TJAPlayer3/Songs/Extended/CSongObject.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Diagnostics; +using System.IO; +using SharpDX; +using FDK; + +namespace TJAPlayer3 +{ + class CSongObject + { + public CSongObject(string name, float x, float y, string path) + { + this.name = path; + this.isVisible = false; + + this.x = x; + this.y = y; + this.rotation = 0f; + this.opacity = 255; + this.xScale = 1.0f; + this.yScale = 1.0f; + this.color = new Color4(1f, 1f, 1f, 1f); + this.frame = 0; + + FileAttributes attr = File.GetAttributes(path); + + if ((attr & FileAttributes.Directory) == FileAttributes.Directory) + { + textures = TJAPlayer3.Tx.TxCSongFolder(path); + } + else + { + textures = new CTexture[1]; + textures[0] = TJAPlayer3.Tx.TxCSong(path); + } + } + + public void tStartAnimation(double animInterval, bool loop) + { + counter.t開始(0, textures.Length - 1, animInterval, TJAPlayer3.Timer); + counter.n現在の値 = this.frame; + + this.isLooping = loop; + this.isAnimating = true; + } + + public void tStopAnimation() + { + counter.t停止(); + this.isAnimating = false; + } + + public void tDraw() + { + if (isAnimating) + { + if (isLooping) counter.t進行Loop(); + else + { + counter.t進行(); + if (counter.b終了値に達した) this.tStopAnimation(); + } + + frame = counter.n現在の値; + } + + CTexture tx = this.textures[frame]; + if (frame + 1 > textures.Length) return; + if (tx == null) return; + + tx.fZ軸中心回転 = C変換.DegreeToRadian(this.rotation); + tx.color4 = this.color; + tx.Opacity = this.opacity; + + float screen_ratiox = TJAPlayer3.Skin.Resolution[0] / 1280.0f; + float screen_ratioy = TJAPlayer3.Skin.Resolution[1] / 720.0f; + if (isVisible) tx.t2D描画SongObj(TJAPlayer3.app.Device, (int)(this.x * screen_ratiox), (int)(this.y * screen_ratioy), this.xScale * screen_ratiox, this.yScale * screen_ratioy); + } + + public void tDispose() + { + this.isVisible = false; + foreach (CTexture tx in textures) + { + if (tx != null) tx.Dispose(); + } + } + + private CCounter counter = new CCounter(); + private bool isAnimating; + private bool isLooping; + + public CTexture[] textures; + + public string name; + public bool isVisible; + + public float x; + public float y; + public float rotation; + public int opacity; + public float xScale; + public float yScale; + public Color4 color; + + public int frame; + } +} \ No newline at end of file diff --git a/TJAPlayer3/Stages/01.StartUp/CCharacter.cs b/TJAPlayer3/Stages/01.StartUp/CCharacter.cs index e0820e85..c67ac7a5 100644 --- a/TJAPlayer3/Stages/01.StartUp/CCharacter.cs +++ b/TJAPlayer3/Stages/01.StartUp/CCharacter.cs @@ -11,6 +11,7 @@ namespace TJAPlayer3 class CCharacter { public DBCharacter.CharacterData metadata; + public DBCharacter.CharacterEffect effect; public DBUnlockables.CUnlockConditions unlock; public string _path; @@ -24,6 +25,12 @@ namespace TJAPlayer3 else metadata = new DBCharacter.CharacterData(); + // Character metadata + if (File.Exists($@"{path}\Effects.json")) + effect = ConfigManager.GetConfig($@"{path}\Effects.json"); + else + effect = new DBCharacter.CharacterEffect(); + // Character unlockables if (File.Exists($@"{path}\Unlock.json")) unlock = ConfigManager.GetConfig($@"{path}\Unlock.json"); diff --git a/TJAPlayer3/Stages/01.StartUp/CPuchichara.cs b/TJAPlayer3/Stages/01.StartUp/CPuchichara.cs index 8fd06b40..9fbec8a2 100644 --- a/TJAPlayer3/Stages/01.StartUp/CPuchichara.cs +++ b/TJAPlayer3/Stages/01.StartUp/CPuchichara.cs @@ -15,6 +15,7 @@ namespace TJAPlayer3 public CTexture render; public CSkin.Cシステムサウンド welcome; public DBPuchichara.PuchicharaData metadata; + public DBPuchichara.PuchicharaEffect effect; public DBUnlockables.CUnlockConditions unlock; public string _path; @@ -41,6 +42,12 @@ namespace TJAPlayer3 else metadata = new DBPuchichara.PuchicharaData(); + // Puchichara metadata + if (File.Exists($@"{path}\Effects.json")) + effect = ConfigManager.GetConfig($@"{path}\Effects.json"); + else + effect = new DBPuchichara.PuchicharaEffect(); + // Puchichara unlockables if (File.Exists($@"{path}\Unlock.json")) unlock = ConfigManager.GetConfig($@"{path}\Unlock.json"); diff --git a/TJAPlayer3/Stages/01.StartUp/TextureLoader.cs b/TJAPlayer3/Stages/01.StartUp/TextureLoader.cs index a4ba9f2a..a1e5ca14 100644 --- a/TJAPlayer3/Stages/01.StartUp/TextureLoader.cs +++ b/TJAPlayer3/Stages/01.StartUp/TextureLoader.cs @@ -71,6 +71,8 @@ namespace TJAPlayer3 const string ROLL = @"Roll\"; const string SPLASH = @"Splash\"; + public Dictionary trackedTextures = new Dictionary(); + public TextureLoader() { @@ -109,6 +111,33 @@ namespace TJAPlayer3 return TJAPlayer3.tテクスチャの生成(CSkin.Path(BASE + GAME + GENRE + FileName + ".png")); } + internal CTexture TxCSong(string path) + { + return TxCUntrackedSong(path); + } + + private CTexture[] TxCSong(int count, string format, int start = 0) + { + return TxCSong(format, Enumerable.Range(start, count).Select(o => o.ToString()).ToArray()); + } + + private CTexture[] TxCSong(string format, params string[] parts) + { + return parts.Select(o => TxCSong(string.Format(format, o))).ToArray(); + } + + public CTexture[] TxCSongFolder(string folder) + { + var count = TJAPlayer3.t連番画像の枚数を数える(folder); + var texture = count == 0 ? null : TxCSong(count, folder + "{0}.png"); + return texture; + } + + internal CTexture TxCUntrackedSong(string path) + { + return TJAPlayer3.tテクスチャの生成(path); + } + public void LoadTexture() { #region 共通 @@ -400,6 +429,7 @@ namespace TJAPlayer3 Note_Swap = TxC(GAME + @"Swap.png"); Note_Kusu = TxC(GAME + @"Kusu.png"); Note_FuseRoll = TxC(GAME + @"FuseRoll.png"); + Note_Adlib = TxC(GAME + @"Adlib.png"); Judge_Frame = TxC(GAME + @"Notes.png"); @@ -2204,6 +2234,7 @@ namespace TJAPlayer3 Note_Swap, Note_Kusu, Note_FuseRoll, + Note_Adlib, SENotesExtension, Notes_Arm, ChipEffect, diff --git a/TJAPlayer3/Stages/06.SongLoading/CStage曲読み込み.cs b/TJAPlayer3/Stages/06.SongLoading/CStage曲読み込み.cs index 73a0a8dd..0e06b861 100644 --- a/TJAPlayer3/Stages/06.SongLoading/CStage曲読み込み.cs +++ b/TJAPlayer3/Stages/06.SongLoading/CStage曲読み込み.cs @@ -503,6 +503,15 @@ namespace TJAPlayer3 if (TJAPlayer3.ConfigIni.nPlayerCount >= 5) TJAPlayer3.DTX_5P = new CDTX(str, false, 1.0, ini.stファイル.BGMAdjust, 0, 4, true, TJAPlayer3.stage選曲.n確定された曲の難易度[4]); + if (TJAPlayer3.DTX.listErrors.Count != 0) + { + string message = ""; + foreach (var text in TJAPlayer3.DTX.listErrors) + { + System.Windows.Forms.MessageBox.Show(text, "譜面にエラーが見つかりました"); + } + } + Trace.TraceInformation( "---- Song information -----------------" ); Trace.TraceInformation( "TITLE: {0}", TJAPlayer3.DTX.TITLE ); Trace.TraceInformation( "FILE: {0}", TJAPlayer3.DTX.strファイル名の絶対パス ); diff --git a/TJAPlayer3/Stages/07.Game/CAct演奏ゲージ共通.cs b/TJAPlayer3/Stages/07.Game/CAct演奏ゲージ共通.cs index 2070e39d..031e271e 100644 --- a/TJAPlayer3/Stages/07.Game/CAct演奏ゲージ共通.cs +++ b/TJAPlayer3/Stages/07.Game/CAct演奏ゲージ共通.cs @@ -111,8 +111,20 @@ namespace TJAPlayer3 //ダメージ値の計算は太鼓の達人譜面Wikiのものを参考にしました。 for (int i = 0; i < 5; i++) - { - this.db現在のゲージ値[i] = 0; + { + var chara = TJAPlayer3.Tx.Characters[TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(nPlayer)].data.Character]; + switch(chara.effect.Gauge) + { + case "Normal": + this.db現在のゲージ値[i] = 0; + break; + case "Hard": + this.db現在のゲージ値[i] = 100; + break; + case "Extreme": + this.db現在のゲージ値[i] = 100; + break; + } } //ゲージのMAXまでの最低コンボ数を計算 @@ -330,14 +342,42 @@ namespace TJAPlayer3 } for (int i = 0; i < 3; i++) - { - dbゲージ増加量[i][nPlayer] = increase[i]; + { + var chara = TJAPlayer3.Tx.Characters[TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(nPlayer)].data.Character]; + switch (chara.effect.Gauge) + { + case "Normal": + dbゲージ増加量[i][nPlayer] = increase[i]; + break; + case "Hard": + dbゲージ増加量[i][nPlayer] = increase[i] / 2.0f; + break; + case "Extreme": + dbゲージ増加量[i][nPlayer] = increase[i] / 4.0f; + break; + } } for (int i = 0; i < 3; i++) - { - dbゲージ増加量_Branch[i, 0][nPlayer] = increaseBranch[i, 0]; - dbゲージ増加量_Branch[i, 1][nPlayer] = increaseBranch[i, 1]; - dbゲージ増加量_Branch[i, 2][nPlayer] = increaseBranch[i, 2]; + { + var chara = TJAPlayer3.Tx.Characters[TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(nPlayer)].data.Character]; + switch (chara.effect.Gauge) + { + case "Normal": + dbゲージ増加量_Branch[i, 0][nPlayer] = increaseBranch[i, 0]; + dbゲージ増加量_Branch[i, 1][nPlayer] = increaseBranch[i, 1]; + dbゲージ増加量_Branch[i, 2][nPlayer] = increaseBranch[i, 2]; + break; + case "Hard": + dbゲージ増加量_Branch[i, 0][nPlayer] = increaseBranch[i, 0] / 2.0f; + dbゲージ増加量_Branch[i, 1][nPlayer] = increaseBranch[i, 1] / 2.0f; + dbゲージ増加量_Branch[i, 2][nPlayer] = increaseBranch[i, 2] / 2.0f; + break; + case "Extreme": + dbゲージ増加量_Branch[i, 0][nPlayer] = increaseBranch[i, 0] / 4.0f; + dbゲージ増加量_Branch[i, 1][nPlayer] = increaseBranch[i, 1] / 4.0f; + dbゲージ増加量_Branch[i, 2][nPlayer] = increaseBranch[i, 2] / 4.0f; + break; + } } #endregion } @@ -425,10 +465,20 @@ namespace TJAPlayer3 else fDamage = this.dbゲージ増加量[2][nPlayer]; - if (fDamage >= 0) { fDamage = -fDamage; + } + + var chara = TJAPlayer3.Tx.Characters[TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(nPlayer)].data.Character]; + switch (chara.effect.Gauge) + { + case "Hard": + fDamage = -25; + break; + case "Extreme": + fDamage = -50; + break; } if (this.bRisky) diff --git a/TJAPlayer3/Stages/07.Game/CStage演奏画面共通.cs b/TJAPlayer3/Stages/07.Game/CStage演奏画面共通.cs index 55ccdf9f..e29fb913 100644 --- a/TJAPlayer3/Stages/07.Game/CStage演奏画面共通.cs +++ b/TJAPlayer3/Stages/07.Game/CStage演奏画面共通.cs @@ -400,6 +400,8 @@ namespace TJAPlayer3 this.bLEVELHOLD = new bool[]{ false, false, false, false, false }; this.JPOSCROLLX = new int[5]; this.JPOSCROLLY = new int[5]; + eFirstGameType = new EGameType[5]; + bSplitLane = new bool[5]; // Double play set here @@ -418,6 +420,7 @@ namespace TJAPlayer3 for (int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++) { actGauge.Init(TJAPlayer3.ConfigIni.nRisky, i); // #23559 2011.7.28 yyagi + eFirstGameType[i] = TJAPlayer3.ConfigIni.nGameType[i]; } this.nPolyphonicSounds = TJAPlayer3.ConfigIni.nPoliphonicSounds; e判定表示優先度 = TJAPlayer3.ConfigIni.e判定表示優先度; @@ -488,11 +491,27 @@ namespace TJAPlayer3 // this.gclatencymode = GCSettings.LatencyMode; // GCSettings.LatencyMode = GCLatencyMode.Batch; // 演奏画面中はGCを抑止する this.bIsAlreadyCleared = new bool[5]; + for (int player = 0; player < TJAPlayer3.ConfigIni.nPlayerCount; player++) + { + var chara = TJAPlayer3.Tx.Characters[TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character]; + switch (chara.effect.Gauge) + { + case "Normal": + bIsAlreadyCleared[player] = false; + break; + case "Hard": + case "Extreme": + bIsAlreadyCleared[player] = true; + break; + } + } this.bIsAlreadyMaxed = new bool[5]; this.ListDan_Number = 0; this.IsDanFailed = false; - } + + this.objHandlers = new Dictionary(); + } public void ftDanReSetScoreNiji(int songNotes, int ballons) @@ -528,10 +547,27 @@ namespace TJAPlayer3 this.ctチップ模様アニメ.Bass = null; this.ctチップ模様アニメ.Taiko = null; + this.ctCamHMove = null; + this.ctCamVMove = null; + this.ctCamHScale = null; + this.ctCamVScale = null; + this.ctCamRotation = null; + this.ctCamZoom = null; + + TJAPlayer3.borderColor = new SharpDX.Color4(0f, 0f, 0f, 0f); + TJAPlayer3.fCamXOffset = 0.0f; + TJAPlayer3.fCamYOffset = 0.0f; + TJAPlayer3.fCamXScale = 1.0f; + TJAPlayer3.fCamYScale = 1.0f; + TJAPlayer3.fCamRotation = 0.0f; + TJAPlayer3.fCamZoomFactor = 1.0f; + for (int i = 0; i < 5; i++) { ctChipAnime[i] = null; ctChipAnimeLag[i] = null; + TJAPlayer3.ConfigIni.nGameType[i] = eFirstGameType[i]; + bSplitLane[i] = false; } listWAV.Clear(); @@ -876,6 +912,8 @@ namespace TJAPlayer3 protected int nWaitButton; protected int[] nStoredHit; + private EGameType[] eFirstGameType; + protected bool[] bSplitLane; public CDTX.CChip[] chip現在処理中の連打チップ = new CDTX.CChip[ 5 ]; @@ -1653,7 +1691,7 @@ namespace TJAPlayer3 { return tチップのヒット処理( nHitTime, pChip, screenmode, bCorrectLane, nNowInput, 0 ); } - protected unsafe E判定 tチップのヒット処理(long nHitTime, CDTX.CChip pChip, E楽器パート screenmode, bool bCorrectLane, int nNowInput, int nPlayer) + protected unsafe E判定 tチップのヒット処理(long nHitTime, CDTX.CChip pChip, E楽器パート screenmode, bool bCorrectLane, int nNowInput, int nPlayer, bool rollEffectHit = false) { //unsafeコードにつき、デバッグ中の変更厳禁! @@ -1697,16 +1735,18 @@ namespace TJAPlayer3 if (!bAutoPlay && eJudgeResult != E判定.Miss) { CLagLogger.Add(nPlayer, pChip); - } + } + + var puchichara = TJAPlayer3.Tx.Puchichara[PuchiChara.tGetPuchiCharaIndexByName(TJAPlayer3.GetActualPlayer(nPlayer))]; if (NotesManager.IsRoll(pChip)) { #region[ Drumroll ] //--------------------------- this.b連打中[nPlayer] = true; - if (bAutoPlay) + if (bAutoPlay || rollEffectHit) { - int rollSpeed = TJAPlayer3.ConfigIni.nRollsPerSec; + int rollSpeed = bAutoPlay ? TJAPlayer3.ConfigIni.nRollsPerSec : puchichara.effect.Autoroll; if (TJAPlayer3.ConfigIni.bAIBattleMode && nPlayer == 1) rollSpeed = TJAPlayer3.ConfigIni.apAIPerformances[TJAPlayer3.ConfigIni.nAILevel - 1].nRollSpeed; @@ -1740,7 +1780,7 @@ namespace TJAPlayer3 } } } - else + if (!bAutoPlay && !rollEffectHit) { this.eRollState = E連打State.roll; this.tRollProcess(pChip, (CSound管理.rc演奏用タイマ.n現在時刻 * (((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0)), 1, nNowInput, 0, nPlayer); @@ -1757,7 +1797,7 @@ namespace TJAPlayer3 this.b連打中[nPlayer] = true; this.actChara.b風船連打中[nPlayer] = true; - if (bAutoPlay) + if (bAutoPlay || rollEffectHit) { bool IsKusudama = NotesManager.IsKusudama(pChip); @@ -1777,14 +1817,12 @@ namespace TJAPlayer3 if (balloon != 0 && this.bPAUSE == false) { - int rollSpeed = TJAPlayer3.ConfigIni.nRollsPerSec; - if (TJAPlayer3.ConfigIni.bAIBattleMode && nPlayer == 1) - rollSpeed = TJAPlayer3.ConfigIni.apAIPerformances[TJAPlayer3.ConfigIni.nAILevel - 1].nRollSpeed; + int rollSpeed = bAutoPlay ? balloon : puchichara.effect.Autoroll; - int balloonDuration = (pChip.nノーツ終了時刻ms - pChip.n発声時刻ms); + int balloonDuration = bAutoPlay ? (pChip.nノーツ終了時刻ms - pChip.n発声時刻ms) : 1000; if ((CSound管理.rc演奏用タイマ.n現在時刻 * (((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0)) > - (pChip.n発声時刻ms + (balloonDuration / balloon) * rollCount)) + (pChip.n発声時刻ms + (balloonDuration / (double)rollSpeed) * rollCount)) { if (this.nHand[nPlayer] == 0) this.nHand[nPlayer]++; @@ -1798,7 +1836,7 @@ namespace TJAPlayer3 } } } - else + if (!bAutoPlay && !rollEffectHit) { this.tBalloonProcess(pChip, (CSound管理.rc演奏用タイマ.n現在時刻 * (((double)TJAPlayer3.ConfigIni.n演奏速度) / 20.0)), nPlayer); } @@ -1881,6 +1919,19 @@ namespace TJAPlayer3 } } + var chara = TJAPlayer3.Tx.Characters[TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(nPlayer)].data.Character]; + bool cleared = false; + switch (chara.effect.Gauge) + { + case "Normal": + cleared = (int)actGauge.db現在のゲージ値[nPlayer] >= 80; + break; + case "Hard": + case "Extreme": + cleared = (int)actGauge.db現在のゲージ値[nPlayer] > 0; + break; + } + if (eJudgeResult != E判定.Poor && eJudgeResult != E判定.Miss) { double dbUnit = (((60.0 / (TJAPlayer3.stage演奏ドラム画面.actPlayInfo.dbBPM[nPlayer])))); @@ -1898,7 +1949,7 @@ namespace TJAPlayer3 } this.bIsAlreadyMaxed[nPlayer] = true; } - if ((int)actGauge.db現在のゲージ値[nPlayer] >= 80 && this.bIsAlreadyCleared[nPlayer] == false) + if (cleared && this.bIsAlreadyCleared[nPlayer] == false) { if(TJAPlayer3.Skin.Characters_Become_Cleared_Ptn[Character] != 0 && actChara.CharaAction_Balloon_Delay[nPlayer].b終了値に達した) { @@ -1917,11 +1968,22 @@ namespace TJAPlayer3 { this.bIsAlreadyMaxed[nPlayer] = false; } - if ((int)actGauge.db現在のゲージ値[nPlayer] < 80 && this.bIsAlreadyCleared[nPlayer] == true) + if (!cleared && this.bIsAlreadyCleared[nPlayer] == true) { this.bIsAlreadyCleared[nPlayer] = false; TJAPlayer3.stage演奏ドラム画面.actBackground.ClearOut(nPlayer); - //CDTXMania.stage演奏ドラム画面.actBackground.ClearIn(nPlayer); + + switch (chara.effect.Gauge) + { + case "Hard": + case "Extreme": + { + CSound管理.rc演奏用タイマ.t一時停止(); + TJAPlayer3.DTX.t全チップの再生停止(); + ifp[nPlayer] = true; + } + break; + } } cInvisibleChip.ShowChipTemporally( pChip.e楽器パート ); } @@ -3871,49 +3933,361 @@ namespace TJAPlayer3 this.bIsGOGOTIME[ nPlayer ] = false; } break; -#endregion + #endregion -#region [ a0-a8: EmptySlot ] - case 0xa0: - case 0xa1: - case 0xa2: - case 0xa3: - case 0xa4: - case 0xa5: - case 0xa6: - case 0xa7: - case 0xa8: + #region [ EXTENDED COMMANDS ] + case 0xa0: //camera vertical move start + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + this.currentCamVMoveChip = pChip; + this.ctCamVMove = new CCounter(0, pChip.fCamTimeMs, 1, TJAPlayer3.Timer); + } break; -#endregion -#region [ B1~BC EmptySlot ] - case 0xb1: - case 0xb2: - case 0xb3: - case 0xb4: - case 0xb5: - case 0xb6: - case 0xb7: - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: - case 0xbc: - break; -#endregion -#region [ c4, c7, d5-d9: EmptySlot ] - case 0xc4: - case 0xc7: - case 0xd5: - case 0xd6: // BGA画像入れ替え - case 0xd7: + case 0xa1: //camera vertical move end + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + } + break; + case 0xa2: //camera horizontal move start + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + this.currentCamHMoveChip = pChip; + this.ctCamHMove = new CCounter(0, pChip.fCamTimeMs, 1, TJAPlayer3.Timer); + } + break; + case 0xa3: //camera horizontal move end + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + } + break; + case 0xa4: //camera zoom start + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + this.currentCamZoomChip = pChip; + this.ctCamZoom = new CCounter(0, pChip.fCamTimeMs, 1, TJAPlayer3.Timer); + } + break; + case 0xa5: //camera zoom end + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + } + break; + case 0xa6: //camera rotation start + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + this.currentCamRotateChip = pChip; + this.ctCamRotation = new CCounter(0, pChip.fCamTimeMs, 1, TJAPlayer3.Timer); + } + break; + case 0xa7: //camera rotation end + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + } + break; + case 0xa8: //camera vertical scaling start + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + this.currentCamVScaleChip = pChip; + this.ctCamVScale = new CCounter(0, pChip.fCamTimeMs, 1, TJAPlayer3.Timer); + } + break; + case 0xa9: //camera vertical scaling end + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + } + break; + case 0xb0: //camera horizontal scaling start + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + this.currentCamHScaleChip = pChip; + this.ctCamHScale = new CCounter(0, pChip.fCamTimeMs, 1, TJAPlayer3.Timer); + } + break; + case 0xb1: //camera horizontal scaling end + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + } + break; + case 0xb2: //change border color + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + TJAPlayer3.borderColor = pChip.borderColor; + } + break; + case 0xb3: //set camera x offset + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + this.currentCamHMoveChip = pChip; + this.ctCamHMove = new CCounter(0, 0, 1, TJAPlayer3.Timer); + } + break; + case 0xb4: //set camera y offset + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + this.currentCamVMoveChip = pChip; + this.ctCamVMove = new CCounter(0, 0, 1, TJAPlayer3.Timer); + } + break; + case 0xb5: //set camera zoom factor + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + this.currentCamZoomChip = pChip; + this.ctCamZoom = new CCounter(0, 0, 1, TJAPlayer3.Timer); + } + break; + case 0xb6: //set camera rotation + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + this.currentCamRotateChip = pChip; + this.ctCamRotation = new CCounter(0, 0, 1, TJAPlayer3.Timer); + } + break; + case 0xb7: //set camera x scale + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + this.currentCamHScaleChip = pChip; + this.ctCamHScale = new CCounter(0, 0, 1, TJAPlayer3.Timer); + } + break; + case 0xb8: //set camera y scale + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + this.currentCamVScaleChip = pChip; + this.ctCamVScale = new CCounter(0, 0, 1, TJAPlayer3.Timer); + } + break; + case 0xb9: //reset camera + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + TJAPlayer3.borderColor = new SharpDX.Color4(0f, 0f, 0f, 0f); + + this.currentCamVMoveChip = pChip; + this.currentCamHMoveChip = pChip; + + this.currentCamZoomChip = pChip; + this.currentCamRotateChip = pChip; + + this.currentCamVScaleChip = pChip; + this.currentCamHScaleChip = pChip; + + this.ctCamVMove = new CCounter(0, 0, 1, TJAPlayer3.Timer); + this.ctCamHMove = new CCounter(0, 0, 1, TJAPlayer3.Timer); + + this.ctCamZoom = new CCounter(0, 0, 1, TJAPlayer3.Timer); + this.ctCamRotation = new CCounter(0, 0, 1, TJAPlayer3.Timer); + + this.ctCamVScale = new CCounter(0, 0, 1, TJAPlayer3.Timer); + this.ctCamHScale = new CCounter(0, 0, 1, TJAPlayer3.Timer); + } + break; + case 0xba: //enable doron + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + bCustomDoron = true; + } + break; + case 0xbb: //disable doron + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + bCustomDoron = false; + } + break; + case 0xbc: //add object + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + dTX.listObj.TryGetValue(pChip.strObjName, out CSongObject obj); + obj.x = pChip.fObjX; + obj.y = pChip.fObjY; + obj.isVisible = true; + } + break; + case 0xbd: //remove object + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + dTX.listObj.TryGetValue(pChip.strObjName, out CSongObject obj); + obj.isVisible = false; + } + break; + case 0xbe: //object animation start + case 0xc0: + case 0xc2: + case 0xc4: + case 0xc6: + case 0xc8: + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + dTX.listObj.TryGetValue(pChip.strObjName, out pChip.obj); + objHandlers.Add(pChip, new CCounter(0, pChip.fObjTimeMs, 1, TJAPlayer3.Timer)); + } + break; + case 0xbf: //object animation end + case 0xc1: + case 0xc3: + case 0xc5: + case 0xc7: + case 0xc9: + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + } + break; + case 0xca: //set object color + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + dTX.listObj.TryGetValue(pChip.strObjName, out CSongObject obj); + obj.color = pChip.borderColor; + } + break; + case 0xcb: //set object y + case 0xcc: //set object x + case 0xcd: //set object vertical scale + case 0xce: //set object horizontal scale + case 0xcf: //set object rotation + case 0xd0: //set object opacity + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + dTX.listObj.TryGetValue(pChip.strObjName, out pChip.obj); + objHandlers.Add(pChip, new CCounter(0, 0, 1, TJAPlayer3.Timer)); + } + break; + case 0xd1: //change texture + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + if (TJAPlayer3.Tx.trackedTextures.ContainsKey(pChip.strTargetTxName)) + { + TJAPlayer3.Tx.trackedTextures.TryGetValue(pChip.strTargetTxName, out CTexture oldTx); + dTX.listTextures.TryGetValue(pChip.strNewPath, out CTexture newTx); + + newTx.Opacity = oldTx.Opacity; + newTx.fZ軸中心回転 = oldTx.fZ軸中心回転; + newTx.vc拡大縮小倍率 = oldTx.vc拡大縮小倍率; + + oldTx.UpdateTexture(TJAPlayer3.app.Device, newTx.texture, newTx.sz画像サイズ.Width, newTx.sz画像サイズ.Height); + } + } + break; + case 0xd2: //reset texture + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + + if (TJAPlayer3.Tx.trackedTextures.ContainsKey(pChip.strTargetTxName)) + { + TJAPlayer3.Tx.trackedTextures.TryGetValue(pChip.strTargetTxName, out CTexture oldTx); + dTX.listOriginalTextures.TryGetValue(pChip.strTargetTxName, out CTexture originalTx); + + originalTx.Opacity = oldTx.Opacity; + originalTx.fZ軸中心回転 = oldTx.fZ軸中心回転; + originalTx.vc拡大縮小倍率 = oldTx.vc拡大縮小倍率; + + oldTx.UpdateTexture(TJAPlayer3.app.Device, originalTx.texture, originalTx.sz画像サイズ.Width, originalTx.sz画像サイズ.Height); + } + } + break; + case 0xd3: //set config + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + string[] split = pChip.strConfigValue.Split('='); + + //TJAPlayer3.Skin.t文字列から読み込み(pChip.strConfigValue, split[0]); + bConfigUpdated = true; + } + break; + case 0xd4: //start object animation + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + dTX.listObj.TryGetValue(pChip.strObjName, out CSongObject obj); + + obj.tStartAnimation(pChip.dbAnimInterval, false); + } + break; + case 0xd5: //start object animation (looping) + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + dTX.listObj.TryGetValue(pChip.strObjName, out CSongObject obj); + + obj.tStartAnimation(pChip.dbAnimInterval, true); + } + break; + case 0xd6: //end object animation + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + dTX.listObj.TryGetValue(pChip.strObjName, out CSongObject obj); + + obj.tStopAnimation(); + } + break; + case 0xd7: //set object frame + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + pChip.bHit = true; + dTX.listObj.TryGetValue(pChip.strObjName, out CSongObject obj); + + obj.frame = pChip.intFrame; + } + break; + #endregion + +#region [ d8-d9: EXTENDED2 ] case 0xd8: - case 0xd9: - //case 0xe0: - if ( !pChip.bHit && ( pChip.nバーからの距離dot.Drums < 0 ) ) - { - pChip.bHit = true; - } - break; + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + TJAPlayer3.ConfigIni.nGameType[nPlayer] = pChip.eGameType; + pChip.bHit = true; + } + break; + case 0xd9: + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + bSplitLane[nPlayer] = true; + pChip.bHit = true; + } + break; #endregion #region [ da: ミキサーへチップ音追加 ] @@ -4088,10 +4462,27 @@ namespace TJAPlayer3 return true; } break; -#endregion + #endregion -#region [ その他(未定義) ] - default: + #region [ d8-d9: EXTENDED2 ] + case 0xe3: + if (!pChip.bHit && (pChip.nバーからの距離dot.Drums < 0)) + { + bSplitLane[nPlayer] = false; + pChip.bHit = true; + } + break; + case 0xe4: + if (!pChip.bHit && (pChip.nバーからの距離dot.Taiko < 0)) + { + pChip.bHit = true; + } + this.t進行描画_チップ_小節線(configIni, ref dTX, ref pChip, nPlayer); + break; + #endregion + + #region [ その他(未定義) ] + default: if ( !pChip.bHit && ( pChip.nバーからの距離dot.Drums < 0 ) ) { pChip.bHit = true; @@ -4101,7 +4492,146 @@ namespace TJAPlayer3 } } - return false; + + + #region [ EXTENDED CONTROLS ] + if (ctCamVMove != null) //vertical camera move + { + ctCamVMove.t進行(); + float value = 0.0f; + if (currentCamVMoveChip.strCamEaseType.Equals("IN")) value = easing.EaseIn(ctCamVMove, currentCamVMoveChip.fCamScrollStartY, currentCamVMoveChip.fCamScrollEndY, currentCamVMoveChip.fCamMoveType); + if (currentCamVMoveChip.strCamEaseType.Equals("OUT")) value = easing.EaseOut(ctCamVMove, currentCamVMoveChip.fCamScrollStartY, currentCamVMoveChip.fCamScrollEndY, currentCamVMoveChip.fCamMoveType); + if (currentCamVMoveChip.strCamEaseType.Equals("IN_OUT")) value = easing.EaseInOut(ctCamVMove, currentCamVMoveChip.fCamScrollStartY, currentCamVMoveChip.fCamScrollEndY, currentCamVMoveChip.fCamMoveType); + TJAPlayer3.fCamYOffset = float.IsNaN(value) ? currentCamVMoveChip.fCamScrollStartY : value; + + if (ctCamVMove.b終了値に達した) + { + ctCamVMove = null; + TJAPlayer3.fCamYOffset = currentCamVMoveChip.fCamScrollEndY; + } + } + + if (ctCamHMove != null) //horizontal camera move + { + ctCamHMove.t進行(); + float value = 0.0f; + if (currentCamHMoveChip.strCamEaseType.Equals("IN")) value = easing.EaseIn(ctCamHMove, currentCamHMoveChip.fCamScrollStartX, currentCamHMoveChip.fCamScrollEndX, currentCamHMoveChip.fCamMoveType); + if (currentCamHMoveChip.strCamEaseType.Equals("OUT")) value = easing.EaseOut(ctCamHMove, currentCamHMoveChip.fCamScrollStartX, currentCamHMoveChip.fCamScrollEndX, currentCamHMoveChip.fCamMoveType); + if (currentCamHMoveChip.strCamEaseType.Equals("IN_OUT")) value = easing.EaseInOut(ctCamHMove, currentCamHMoveChip.fCamScrollStartX, currentCamHMoveChip.fCamScrollEndX, currentCamHMoveChip.fCamMoveType); + TJAPlayer3.fCamXOffset = float.IsNaN(value) ? currentCamHMoveChip.fCamScrollStartX : value; + + if (ctCamHMove.b終了値に達した) + { + ctCamHMove = null; + TJAPlayer3.fCamXOffset = currentCamHMoveChip.fCamScrollEndX; + } + } + + if (ctCamZoom != null) //camera zoom + { + ctCamZoom.t進行(); + float value = 0.0f; + if (currentCamZoomChip.strCamEaseType.Equals("IN")) value = easing.EaseIn(ctCamZoom, currentCamZoomChip.fCamZoomStart, currentCamZoomChip.fCamZoomEnd, currentCamZoomChip.fCamMoveType); + if (currentCamZoomChip.strCamEaseType.Equals("OUT")) value = easing.EaseOut(ctCamZoom, currentCamZoomChip.fCamZoomStart, currentCamZoomChip.fCamZoomEnd, currentCamZoomChip.fCamMoveType); + if (currentCamZoomChip.strCamEaseType.Equals("IN_OUT")) value = easing.EaseInOut(ctCamZoom, currentCamZoomChip.fCamZoomStart, currentCamZoomChip.fCamZoomEnd, currentCamZoomChip.fCamMoveType); + TJAPlayer3.fCamZoomFactor = float.IsNaN(value) ? currentCamZoomChip.fCamZoomStart : value; + + if (ctCamZoom.b終了値に達した) + { + ctCamZoom = null; + TJAPlayer3.fCamZoomFactor = currentCamZoomChip.fCamZoomEnd; + } + } + + if (ctCamRotation != null) //camera rotation + { + ctCamRotation.t進行(); + float value = 0.0f; + if (currentCamRotateChip.strCamEaseType.Equals("IN")) value = easing.EaseIn(ctCamRotation, currentCamRotateChip.fCamRotationStart, currentCamRotateChip.fCamRotationEnd, currentCamRotateChip.fCamMoveType); + if (currentCamRotateChip.strCamEaseType.Equals("OUT")) value = easing.EaseOut(ctCamRotation, currentCamRotateChip.fCamRotationStart, currentCamRotateChip.fCamRotationEnd, currentCamRotateChip.fCamMoveType); + if (currentCamRotateChip.strCamEaseType.Equals("IN_OUT")) value = easing.EaseInOut(ctCamRotation, currentCamRotateChip.fCamRotationStart, currentCamRotateChip.fCamRotationEnd, currentCamRotateChip.fCamMoveType); + TJAPlayer3.fCamRotation = float.IsNaN(value) ? currentCamRotateChip.fCamRotationStart : value; + + if (ctCamRotation.b終了値に達した) + { + ctCamRotation = null; + TJAPlayer3.fCamRotation = currentCamRotateChip.fCamRotationEnd; + } + } + + if (ctCamVScale != null) //vertical camera scaling + { + ctCamVScale.t進行(); + float value = 0.0f; + if (currentCamVScaleChip.strCamEaseType.Equals("IN")) value = easing.EaseIn(ctCamVScale, currentCamVScaleChip.fCamScaleStartY, currentCamVScaleChip.fCamScaleEndY, currentCamVScaleChip.fCamMoveType); + if (currentCamVScaleChip.strCamEaseType.Equals("OUT")) value = easing.EaseOut(ctCamVScale, currentCamVScaleChip.fCamScaleStartY, currentCamVScaleChip.fCamScaleEndY, currentCamVScaleChip.fCamMoveType); + if (currentCamVScaleChip.strCamEaseType.Equals("IN_OUT")) value = easing.EaseInOut(ctCamVScale, currentCamVScaleChip.fCamScaleStartY, currentCamVScaleChip.fCamScaleEndY, currentCamVScaleChip.fCamMoveType); + TJAPlayer3.fCamYScale = float.IsNaN(value) ? currentCamVScaleChip.fCamScaleStartY : value; + + if (ctCamVScale.b終了値に達した) + { + ctCamVScale = null; + TJAPlayer3.fCamYScale = currentCamVScaleChip.fCamScaleEndY; + } + } + + if (ctCamHScale != null) //horizontal camera scaling + { + ctCamHScale.t進行(); + float value = 0.0f; + if (currentCamHScaleChip.strCamEaseType.Equals("IN")) value = easing.EaseIn(ctCamHScale, currentCamHScaleChip.fCamScaleStartX, currentCamHScaleChip.fCamScaleEndX, currentCamHScaleChip.fCamMoveType); + if (currentCamHScaleChip.strCamEaseType.Equals("OUT")) value = easing.EaseOut(ctCamHScale, currentCamHScaleChip.fCamScaleStartX, currentCamHScaleChip.fCamScaleEndX, currentCamHScaleChip.fCamMoveType); + if (currentCamHScaleChip.strCamEaseType.Equals("IN_OUT")) value = easing.EaseInOut(ctCamHScale, currentCamHScaleChip.fCamScaleStartX, currentCamHScaleChip.fCamScaleEndX, currentCamHScaleChip.fCamMoveType); + TJAPlayer3.fCamXScale = float.IsNaN(value) ? currentCamHScaleChip.fCamScaleStartX : value; + + if (ctCamHScale.b終了値に達した) + { + ctCamHScale = null; + TJAPlayer3.fCamXScale = currentCamHScaleChip.fCamScaleEndX; + } + } + + foreach (KeyValuePair pair in objHandlers) + { + CDTX.CChip chip = pair.Key; + CCounter counter = pair.Value; + + if (counter != null) + { + counter.t進行(); + + float value = 0.0f; + if (counter.b終了値に達した) + { + value = chip.fObjEnd; + counter = null; + } + else + { + if (chip.strObjEaseType.Equals("IN")) value = easing.EaseIn(counter, chip.fObjStart, chip.fObjEnd, chip.objCalcType); + if (chip.strObjEaseType.Equals("OUT")) value = easing.EaseOut(counter, chip.fObjStart, chip.fObjEnd, chip.objCalcType); + if (chip.strObjEaseType.Equals("IN_OUT")) value = easing.EaseInOut(counter, chip.fObjStart, chip.fObjEnd, chip.objCalcType); + value = float.IsNaN(value) ? chip.fObjStart : value; + } + + if (chip.nチャンネル番号 == 0xBE) chip.obj.y = value; + if (chip.nチャンネル番号 == 0xC0) chip.obj.x = value; + if (chip.nチャンネル番号 == 0xC2) chip.obj.yScale = value; + if (chip.nチャンネル番号 == 0xC4) chip.obj.xScale = value; + if (chip.nチャンネル番号 == 0xC6) chip.obj.rotation = value; + if (chip.nチャンネル番号 == 0xC8) chip.obj.opacity = (int)value; + + if (chip.nチャンネル番号 == 0xCB) chip.obj.y = value; + if (chip.nチャンネル番号 == 0xCC) chip.obj.x = value; + if (chip.nチャンネル番号 == 0xCD) chip.obj.yScale = value; + if (chip.nチャンネル番号 == 0xCE) chip.obj.xScale = value; + if (chip.nチャンネル番号 == 0xCF) chip.obj.rotation = value; + if (chip.nチャンネル番号 == 0xD0) chip.obj.opacity = (int)value; + } + } + #endregion + + return false; } protected bool t進行描画_チップ_連打( E楽器パート ePlayMode, int nPlayer ) @@ -4491,6 +5021,29 @@ namespace TJAPlayer3 AIBattleSections[i].IsAnimated = false; } + TJAPlayer3.fCamXOffset = 0; + + TJAPlayer3.fCamYOffset = 0; + + TJAPlayer3.fCamZoomFactor = 1.0f; + TJAPlayer3.fCamRotation = 0; + + TJAPlayer3.fCamXScale = 1.0f; + TJAPlayer3.fCamYScale = 1.0f; + + TJAPlayer3.borderColor = new SharpDX.Color4(1f, 0f, 0f, 0f); + + foreach (var chip in TJAPlayer3.DTX.listChip) + { + if (chip.obj == null) continue; + chip.obj.isVisible = false; + chip.obj.yScale = 1.0f; + chip.obj.xScale = 1.0f; + chip.obj.rotation = 0.0f; + chip.obj.opacity = 255; + chip.obj.frame = 0; + } + TJAPlayer3.DTX.t全チップの再生停止とミキサーからの削除(); this.t数値の初期化( true, true ); this.actAVI.tReset(); @@ -4502,6 +5055,9 @@ namespace TJAPlayer3 JPOSCROLLX[i] = 0; JPOSCROLLY[i] = 0; ifp[i] = false; + + TJAPlayer3.ConfigIni.nGameType[i] = eFirstGameType[i]; + bSplitLane[i] = false; } TJAPlayer3.stage演奏ドラム画面.On活性化(); for( int i = 0; i < TJAPlayer3.ConfigIni.nPlayerCount; i++ ) @@ -4937,5 +5493,30 @@ namespace TJAPlayer3 } } } - } + + + #region [EXTENDED COMMANDS] + private CCounter ctCamVMove; + private CCounter ctCamHMove; + private CCounter ctCamZoom; + private CCounter ctCamRotation; + private CCounter ctCamVScale; + private CCounter ctCamHScale; + + private CDTX.CChip currentCamVMoveChip; + private CDTX.CChip currentCamHMoveChip; + private CDTX.CChip currentCamZoomChip; + private CDTX.CChip currentCamRotateChip; + private CDTX.CChip currentCamVScaleChip; + private CDTX.CChip currentCamHScaleChip; + + private Dictionary camHandlers; + private Dictionary objHandlers; + + private Easing easing = new Easing(); + + public bool bCustomDoron = false; + private bool bConfigUpdated = false; + #endregion + } } diff --git a/TJAPlayer3/Stages/07.Game/Taiko/CStage演奏ドラム画面.cs b/TJAPlayer3/Stages/07.Game/Taiko/CStage演奏ドラム画面.cs index 7db4d1b7..f54d00dc 100644 --- a/TJAPlayer3/Stages/07.Game/Taiko/CStage演奏ドラム画面.cs +++ b/TJAPlayer3/Stages/07.Game/Taiko/CStage演奏ドラム画面.cs @@ -1849,7 +1849,7 @@ namespace TJAPlayer3 int n大音符 = (pChip.nチャンネル番号 == 0x11 || pChip.nチャンネル番号 == 0x12 ? 2 : 0); - this.tチップのヒット処理(pChip.n発声時刻ms, pChip, E楽器パート.TAIKO, true, nLane + n大音符, nPlayer); + this.tチップのヒット処理(pChip.n発声時刻ms, pChip, E楽器パート.TAIKO, true, nLane + n大音符, nPlayer, false); this.tサウンド再生(pChip, nPlayer); return; } @@ -1930,7 +1930,7 @@ namespace TJAPlayer3 #endregion #region[ HIDSUD & STEALTH ] - if( TJAPlayer3.ConfigIni.eSTEALTH[TJAPlayer3.GetActualPlayer(nPlayer)] == Eステルスモード.STEALTH ) + if( TJAPlayer3.ConfigIni.eSTEALTH[TJAPlayer3.GetActualPlayer(nPlayer)] == Eステルスモード.STEALTH || TJAPlayer3.stage演奏ドラム画面.bCustomDoron) { pChip.bShow = false; } @@ -1949,6 +1949,18 @@ namespace TJAPlayer3 float play_bpm_time = this.GetNowPBMTime(dTX, 0); y += NotesManager.GetNoteY(pChip, time * pChip.dbBPM, _scrollSpeed, TJAPlayer3.Skin.Game_Notes_Interval, play_bpm_time, configIni.eScrollMode, false); + } + + if (bSplitLane[nPlayer] || TJAPlayer3.Tx.Puchichara[PuchiChara.tGetPuchiCharaIndexByName(TJAPlayer3.GetActualPlayer(nPlayer))].effect.SplitLane) + { + if (NotesManager.IsDonNote(pChip)) + { + y -= TJAPlayer3.Skin.Game_Notes_Size[1] / 3; + } + else if (NotesManager.IsKaNote(pChip)) + { + y += TJAPlayer3.Skin.Game_Notes_Size[1] / 3; + } } if ( pChip.nバーからの距離dot.Drums < 0 ) @@ -2106,7 +2118,13 @@ namespace TJAPlayer3 } case 0x1F: + { + NotesManager.DisplayNote(nPlayer, x, y, pChip, num9); + } + break; default: + { + } break; } @@ -2203,9 +2221,29 @@ namespace TJAPlayer3 y += NotesManager.GetNoteY(pChip, time * pChip.dbBPM, _scrollSpeed, TJAPlayer3.Skin.Game_Notes_Interval, play_bpm_time, configIni.eScrollMode, false); } + if (bSplitLane[nPlayer] || TJAPlayer3.Tx.Puchichara[PuchiChara.tGetPuchiCharaIndexByName(TJAPlayer3.GetActualPlayer(nPlayer))].effect.SplitLane) + { + if (TJAPlayer3.ConfigIni.nGameType[nPlayer] == EGameType.KONGA) + { + if (NotesManager.IsClapRoll(pChip)) + { + } + else if (NotesManager.IsYellowRoll(pChip)) + { + y += TJAPlayer3.Skin.Game_Notes_Size[1] / 2; + y末端 += TJAPlayer3.Skin.Game_Notes_Size[1] / 2; + } + else if (NotesManager.IsRoll(pChip)) + { + y -= TJAPlayer3.Skin.Game_Notes_Size[1] / 2; + y末端 -= TJAPlayer3.Skin.Game_Notes_Size[1] / 2; + } + } + } + #region[ HIDSUD & STEALTH ] - if (TJAPlayer3.ConfigIni.eSTEALTH[TJAPlayer3.GetActualPlayer(nPlayer)] == Eステルスモード.STEALTH) + if (TJAPlayer3.ConfigIni.eSTEALTH[TJAPlayer3.GetActualPlayer(nPlayer)] == Eステルスモード.STEALTH || TJAPlayer3.stage演奏ドラム画面.bCustomDoron) { pChip.bShow = false; } @@ -2401,11 +2439,17 @@ namespace TJAPlayer3 } } } + if (pChip.n発声時刻ms < nowTime && pChip.nノーツ終了時刻ms > nowTime) - { + { + var puchichara = TJAPlayer3.Tx.Puchichara[PuchiChara.tGetPuchiCharaIndexByName(TJAPlayer3.GetActualPlayer(nPlayer))]; + //時間内でかつ0x9Aじゃないならならヒット処理 - if (!NotesManager.IsRollEnd(pChip) && (nPlayer != 1 ? TJAPlayer3.ConfigIni.b太鼓パートAutoPlay[nPlayer] : (TJAPlayer3.ConfigIni.b太鼓パートAutoPlay[nPlayer] || TJAPlayer3.ConfigIni.bAIBattleMode))) - this.tチップのヒット処理(pChip.n発声時刻ms, pChip, E楽器パート.TAIKO, false, 0, nPlayer); + if (!NotesManager.IsRollEnd(pChip) && + ((nPlayer != 1 ? TJAPlayer3.ConfigIni.b太鼓パートAutoPlay[nPlayer] : + (TJAPlayer3.ConfigIni.b太鼓パートAutoPlay[nPlayer] || TJAPlayer3.ConfigIni.bAIBattleMode)) || + puchichara.effect.Autoroll > 0)) + this.tチップのヒット処理(pChip.n発声時刻ms, pChip, E楽器パート.TAIKO, false, 0, nPlayer, puchichara.effect.Autoroll > 0); } } #endregion @@ -2472,7 +2516,7 @@ namespace TJAPlayer3 else { //this.tx小節線.t2D描画( CDTXMania.app.Device, x - 3, y, new Rectangle( 0, 0, 3, 130 ) ); - TJAPlayer3.Tx.Bar?.t2D描画( TJAPlayer3.app.Device, x + ((TJAPlayer3.Skin.Game_Notes_Size[0] - TJAPlayer3.Tx.Bar.szテクスチャサイズ.Width) / 2), y, new Rectangle( 0, 0, TJAPlayer3.Tx.Bar_Branch.szテクスチャサイズ.Width, TJAPlayer3.Skin.Game_Notes_Size[1]) ); + TJAPlayer3.Tx.Bar?.t2D描画( TJAPlayer3.app.Device, x + ((TJAPlayer3.Skin.Game_Notes_Size[0] - TJAPlayer3.Tx.Bar.szテクスチャサイズ.Width) / 2), y, new Rectangle( 0, 0, TJAPlayer3.Tx.Bar.szテクスチャサイズ.Width, TJAPlayer3.Skin.Game_Notes_Size[1]) ); } } } diff --git a/TJAPlayer3/Stages/07.Game/Taiko/NotesManager.cs b/TJAPlayer3/Stages/07.Game/Taiko/NotesManager.cs index 0f11858b..ea9d7ce8 100644 --- a/TJAPlayer3/Stages/07.Game/Taiko/NotesManager.cs +++ b/TJAPlayer3/Stages/07.Game/Taiko/NotesManager.cs @@ -154,6 +154,18 @@ namespace TJAPlayer3 return chip.nチャンネル番号 == 0x1C; } + public static bool IsDonNote(CDTX.CChip chip) + { + if (chip == null) return false; + return chip.nチャンネル番号 == 0x11 || chip.nチャンネル番号 == 0x13 || chip.nチャンネル番号 == 0x1A; + } + + public static bool IsKaNote(CDTX.CChip chip) + { + if (chip == null) return false; + return chip.nチャンネル番号 == 0x12 || chip.nチャンネル番号 == 0x14 || chip.nチャンネル番号 == 0x1B; + } + public static bool IsSmallNote(CDTX.CChip chip, bool blue) { if (chip == null) return false; @@ -360,6 +372,16 @@ namespace TJAPlayer3 TJAPlayer3.Tx.Note_Kusu?.t2D描画(TJAPlayer3.app.Device, x, y, new Rectangle(0, frame, length, TJAPlayer3.Skin.Game_Notes_Size[1])); return; } + else if (IsADLIB(chip)) + { + var puchichara = TJAPlayer3.Tx.Puchichara[PuchiChara.tGetPuchiCharaIndexByName(TJAPlayer3.GetActualPlayer(player))]; + if (puchichara.effect.ShowAdlib) + { + TJAPlayer3.Tx.Note_Adlib?.tUpdateOpacity(50); + TJAPlayer3.Tx.Note_Adlib?.t2D描画(TJAPlayer3.app.Device, x, y, new Rectangle(0, frame, length, TJAPlayer3.Skin.Game_Notes_Size[1])); + } + return; + } TJAPlayer3.Tx.Notes[(int)_gt]?.t2D描画(TJAPlayer3.app.Device, x, y, new Rectangle(noteType * TJAPlayer3.Skin.Game_Notes_Size[0], frame, length, TJAPlayer3.Skin.Game_Notes_Size[1])); } diff --git a/TJAPlayer3/Stages/08.Result/CStage結果.cs b/TJAPlayer3/Stages/08.Result/CStage結果.cs index b0291367..1e53585b 100644 --- a/TJAPlayer3/Stages/08.Result/CStage結果.cs +++ b/TJAPlayer3/Stages/08.Result/CStage結果.cs @@ -467,6 +467,7 @@ namespace TJAPlayer3 float starRate; float redStarRate; + float[] modMultipliers = { TJAPlayer3.stage選曲.actPlayOption.tGetModMultiplier(CActPlayOption.EBalancingType.COINS, false, 0), @@ -476,6 +477,59 @@ namespace TJAPlayer3 TJAPlayer3.stage選曲.actPlayOption.tGetModMultiplier(CActPlayOption.EBalancingType.COINS, false, 4) }; + float getCoinMul(int player) + { + var chara = TJAPlayer3.Tx.Characters[TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character]; + var puchichara = TJAPlayer3.Tx.Puchichara[PuchiChara.tGetPuchiCharaIndexByName(TJAPlayer3.GetActualPlayer(player))]; + + float charamul = 1.0f; + switch(chara.metadata.Rarity) + { + case "Poor": + charamul = 0.8f; + break; + case "Common": + charamul = 1.0f; + break; + case "Uncommon": + charamul = 1.1f; + break; + case "Rare": + charamul = 1.2f; + break; + case "Epic": + charamul = 1.3f; + break; + case "Legendary": + charamul = 1.5f; + break; + } + + float puchimul = 1.0f; + switch (puchichara.metadata.Rarity) + { + case "Poor": + puchimul = 0.8f; + break; + case "Common": + puchimul = 1.0f; + break; + case "Uncommon": + puchimul = 1.1f; + break; + case "Rare": + puchimul = 1.2f; + break; + case "Epic": + puchimul = 1.3f; + break; + case "Legendary": + puchimul = 1.5f; + break; + } + return charamul * puchimul; + } + if (TJAPlayer3.stage選曲.n確定された曲の難易度[0] == (int)Difficulty.Tower) { diffModifier = 3; @@ -505,7 +559,7 @@ namespace TJAPlayer3 // this.nEarnedMedalsCount[0] = stars; this.nEarnedMedalsCount[0] = 5 + (int)((diffModifier * (starRate + redStarRate)) * (floorRate * lengthBonus)) + clearModifier; - this.nEarnedMedalsCount[0] = Math.Max(5, (int)(this.nEarnedMedalsCount[0] * modMultipliers[0])); + this.nEarnedMedalsCount[0] = Math.Max(5, (int)(this.nEarnedMedalsCount[0] * modMultipliers[0] * getCoinMul(0))); } else if (TJAPlayer3.stage選曲.n確定された曲の難易度[0] == (int)Difficulty.Dan) { @@ -560,7 +614,7 @@ namespace TJAPlayer3 else { this.nEarnedMedalsCount[0] = 10 + goukakuModifier + clearModifier + (int)(partialScore * dAccuracyRate); - this.nEarnedMedalsCount[0] = Math.Max(10, (int)(this.nEarnedMedalsCount[0] * modMultipliers[0])); + this.nEarnedMedalsCount[0] = Math.Max(10, (int)(this.nEarnedMedalsCount[0] * modMultipliers[0] * getCoinMul(0))); } } else @@ -619,7 +673,7 @@ namespace TJAPlayer3 else { this.nEarnedMedalsCount[i] = 5 + (int)((diffModifier * (starRate + redStarRate)) * dAccuracyRate) + clearModifier + scoreRankModifier; - this.nEarnedMedalsCount[i] = Math.Max(5, (int)(this.nEarnedMedalsCount[i] * modMultipliers[i])); + this.nEarnedMedalsCount[i] = Math.Max(5, (int)(this.nEarnedMedalsCount[i] * modMultipliers[i] * getCoinMul(i))); } } } @@ -2018,7 +2072,7 @@ namespace TJAPlayer3 } else { - return new bool[] { actParameterPanel.gaugeValues[0] >= 80, actParameterPanel.gaugeValues[1] >= 80, actParameterPanel.gaugeValues[2] >= 80, actParameterPanel.gaugeValues[3] >= 80, actParameterPanel.gaugeValues[4] >= 80 }; + return new bool[] { TJAPlayer3.stage演奏ドラム画面.bIsAlreadyCleared[0], TJAPlayer3.stage演奏ドラム画面.bIsAlreadyCleared[1], TJAPlayer3.stage演奏ドラム画面.bIsAlreadyCleared[2], TJAPlayer3.stage演奏ドラム画面.bIsAlreadyCleared[3], TJAPlayer3.stage演奏ドラム画面.bIsAlreadyCleared[4] }; } } } diff --git a/TJAPlayer3/TJAPlayer3.csproj b/TJAPlayer3/TJAPlayer3.csproj index 0d85f3fd..94f8b22c 100644 --- a/TJAPlayer3/TJAPlayer3.csproj +++ b/TJAPlayer3/TJAPlayer3.csproj @@ -160,6 +160,7 @@ + diff --git a/Test/Global/Characters/Template/Effects.json b/Test/Global/Characters/Template/Effects.json new file mode 100644 index 00000000..332f0350 --- /dev/null +++ b/Test/Global/Characters/Template/Effects.json @@ -0,0 +1,3 @@ +{ + "gauge":"Normal" +} \ No newline at end of file diff --git a/Test/Global/PuchiChara/Template/Effects.json b/Test/Global/PuchiChara/Template/Effects.json new file mode 100644 index 00000000..a318efb7 --- /dev/null +++ b/Test/Global/PuchiChara/Template/Effects.json @@ -0,0 +1,6 @@ +{ + "allpurple":false, + "autoroll":0, + "showadlib":false, + "splitlane":false +} \ No newline at end of file diff --git a/Test/Licenses/TJAPlayer3-Extended.txt b/Test/Licenses/TJAPlayer3-Extended.txt new file mode 100644 index 00000000..b301a9bc --- /dev/null +++ b/Test/Licenses/TJAPlayer3-Extended.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 J.MIR + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Test/Songs/01 OpenTaiko Chapter I/box.def b/Test/Songs/01 OpenTaiko Chapter I/box.def index efd59f7f..463cb5ef 100644 --- a/Test/Songs/01 OpenTaiko Chapter I/box.def +++ b/Test/Songs/01 OpenTaiko Chapter I/box.def @@ -1,8 +1,12 @@ #TITLE:OpenTaiko Chapter I +#TITLEJA:OpenTaiko チャプター I #GENRE:OpenTaiko Chapter I #BOXEXPLANATION1:Play awesome community- #BOXEXPLANATION2:made songs submitted #BOXEXPLANATION3:for OpenTaiko ! +#BOXEXPLANATIONJA1:OpenTaikoコミュニティの +#BOXEXPLANATIONJA2:方たちが作った曲が +#BOXEXPLANATIONJA3:あそべるよ! #BOXTYPE:3 #BGTYPE:6 #BOXCOLOR:#f76b20 diff --git a/Test/Songs/02 OpenTaiko Chapter II/box.def b/Test/Songs/02 OpenTaiko Chapter II/box.def index a9dc574c..8367b7c0 100644 --- a/Test/Songs/02 OpenTaiko Chapter II/box.def +++ b/Test/Songs/02 OpenTaiko Chapter II/box.def @@ -1,4 +1,5 @@ #TITLE:OpenTaiko Chapter II +#TITLEJA:OpenTaiko チャプター II #GENRE:OpenTaiko Chapter II #BOXEXPLANATION1:Play awesome community- #BOXEXPLANATION2:made songs submitted diff --git a/Test/Songs/L1 Collaborations/box.def b/Test/Songs/L1 Collaborations/box.def index f23fbab1..dfe1da3a 100644 --- a/Test/Songs/L1 Collaborations/box.def +++ b/Test/Songs/L1 Collaborations/box.def @@ -1,8 +1,12 @@ #TITLE:Collaborations +#TITLEJA:コラボ曲 #GENRE:Collaborations #BOXEXPLANATION1:Enjoy songs from projects #BOXEXPLANATION2:the OpenTaiko team #BOXEXPLANATION3:collaborated with ! +#BOXEXPLANATIONJA1:OpenTaikoチームと +#BOXEXPLANATIONJA2:コラボした曲が +#BOXEXPLANATIONJA3:あそべるよ! #BGTYPE:3 #BGCOLOR:#a200ff #BOXTYPE:0 diff --git a/Test/Songs/L2 Custom Charts/box.def b/Test/Songs/L2 Custom Charts/box.def index bbf64abb..98d4e80a 100644 --- a/Test/Songs/L2 Custom Charts/box.def +++ b/Test/Songs/L2 Custom Charts/box.def @@ -1,10 +1,14 @@ #TITLE:Custom Charts +#TITLEJA:カスタム譜面 #GENRE:Custom Charts #FORECOLOR:#FFFFFF #BACKCOLOR:#316700 #BOXEXPLANATION1:Play a wide range #BOXEXPLANATION2:of custom charts #BOXEXPLANATION3:from the community ! +#BOXEXPLANATIONJA1:君自身が導入した +#BOXEXPLANATIONJA2:譜面があそべるよ! +#BOXEXPLANATIONJA3:カスタム譜面はここに入れてね! #BGTYPE:4 #BGCOLOR:#00fc15 #BOXTYPE:0 diff --git a/Test/Songs/L3 Downloaded Songs/box.def b/Test/Songs/L3 Downloaded Songs/box.def index 125b32ba..2f094d09 100644 --- a/Test/Songs/L3 Downloaded Songs/box.def +++ b/Test/Songs/L3 Downloaded Songs/box.def @@ -1,8 +1,12 @@ #TITLE:Downloaded Songs +#TITLEJA:CDNからダウンロードした曲 #GENRE:Download #BOXEXPLANATION1: Play songs downloaded #BOXEXPLANATION2: from the Online Lounge ! #BOXEXPLANATION3: +#BOXEXPLANATIONJA1: オンラインラウンジから +#BOXEXPLANATIONJA2: ダウンロードした曲が +#BOXEXPLANATIONJA3: あそべるよ! #BGCOLOR:#ff00a2 #BOXCOLOR:#ff00a2 #BOXTYPE:0 diff --git a/Test/Songs/S1 Dan-i Dojo/box.def b/Test/Songs/S1 Dan-i Dojo/box.def index cdb1a912..53468db6 100644 --- a/Test/Songs/S1 Dan-i Dojo/box.def +++ b/Test/Songs/S1 Dan-i Dojo/box.def @@ -1,8 +1,12 @@ #TITLE:Dan-i Dojo +#TITLEJA:段位道場 #GENRE:段位道場 #BOXEXPLANATION1:Play multiple charts in continuation #BOXEXPLANATION2:following challenging exams #BOXEXPLANATION3:in order to get a PASS rank ! +#BOXEXPLANATIONJA1:曲を連続で演奏して +#BOXEXPLANATIONJA2:条件をクリアすれば +#BOXEXPLANATIONJA3:称号がもらえるモードだよ! #BOXTYPE:0 #BGTYPE:7 #BOXCOLOR:#3e51c9 diff --git a/Test/Songs/S2 Taiko Towers/01 - Sweet/box.def b/Test/Songs/S2 Taiko Towers/01 - Sweet/box.def index 6237de92..3c853ac1 100644 --- a/Test/Songs/S2 Taiko Towers/01 - Sweet/box.def +++ b/Test/Songs/S2 Taiko Towers/01 - Sweet/box.def @@ -1,7 +1,10 @@ -#TITLE:Tower (甘口) +#TITLE:Tower (Sweet) +#TITLEJA:甘口 #GENRE:太鼓タワー #BOXEXPLANATION1:Easy tower charts for #BOXEXPLANATION2:players of all skill ranges ! +#BOXEXPLANATIONJA1:かんたんだよ! +#BOXEXPLANATIONJA2:楽しんでね! #BACKCOLOR:#222222 #BOXCOLOR:#f6ff00 #BOXTYPE:0 diff --git a/Test/Songs/S2 Taiko Towers/02 - Spicy/box.def b/Test/Songs/S2 Taiko Towers/02 - Spicy/box.def index a89c3ea2..d4ddc583 100644 --- a/Test/Songs/S2 Taiko Towers/02 - Spicy/box.def +++ b/Test/Songs/S2 Taiko Towers/02 - Spicy/box.def @@ -1,7 +1,10 @@ -#TITLE:Tower (辛口) +#TITLE:Tower (Spicy) +#TITLEJA:辛口 #GENRE:太鼓タワー #BOXEXPLANATION1:Difficult Tower charts #BOXEXPLANATION2:for true champions ! +#BOXEXPLANATIONJA1:むずかしいよ! +#BOXEXPLANATIONJA2:楽しんでね! #BACKCOLOR:#222222 #BOXCOLOR:#ff5e00 #BOXTYPE:0 diff --git a/Test/Songs/S2 Taiko Towers/box.def b/Test/Songs/S2 Taiko Towers/box.def index 46245bb6..909b8c0c 100644 --- a/Test/Songs/S2 Taiko Towers/box.def +++ b/Test/Songs/S2 Taiko Towers/box.def @@ -1,8 +1,12 @@ #TITLE:Taiko Towers +#TITLEJA:太鼓タワー #GENRE:太鼓タワー #BOXEXPLANATION1:Play long charts within a limited #BOXEXPLANATION2:count of lives and reach #BOXEXPLANATION3:the top of the tower ! +#BOXEXPLANATIONJA1:曲を演奏して頂上まで +#BOXEXPLANATIONJA2:たどり着いたらクリアだよ! +#BOXEXPLANATIONJA3:ミスをするとHPが減るから気を付けて! #BACKCOLOR:#222222 #BOXCOLOR:#ffb300 #BOXTYPE:0 diff --git a/Test/Songs/X1 Favorite/box.def b/Test/Songs/X1 Favorite/box.def index d083aae7..e16c5e8c 100644 --- a/Test/Songs/X1 Favorite/box.def +++ b/Test/Songs/X1 Favorite/box.def @@ -1,10 +1,14 @@ #TITLE:Favorite songs +#TITLEJA:おきにいり #GENRE:Favorite #FORECOLOR:#FFFFFF #BACKCOLOR:#673100 #BOXEXPLANATION1:Challenge some of #BOXEXPLANATION2:your favorite songs ! #BOXEXPLANATION3:(Toggle with Left CTRL) +#BOXEXPLANATIONJA1:おきにいりに +#BOXEXPLANATIONJA2:登録をした曲が +#BOXEXPLANATIONJA3:遊べるよ!(とても便利!) #BGTYPE:10 #BOXTYPE:0 #BOXCOLOR:#c71b3b \ No newline at end of file diff --git a/Test/Songs/X2 Recent/box.def b/Test/Songs/X2 Recent/box.def index 21b1ed6d..df319920 100644 --- a/Test/Songs/X2 Recent/box.def +++ b/Test/Songs/X2 Recent/box.def @@ -1,7 +1,11 @@ #TITLE:Recently played songs +#TITLEJA:最近遊んだ曲 #GENRE:最近遊んだ曲 #FORECOLOR:#FFFFFF #BACKCOLOR:#164748 #BOXEXPLANATION1:Play recently played songs ! +#BOXEXPLANATIONJA1:何回か前までの +#BOXEXPLANATIONJA2:遊んだ曲が選べるよ +#BOXEXPLANATIONJA3:お気に入りならお気に入り登録をしよう! #BGTYPE:9 #BOXTYPE:9 \ No newline at end of file diff --git a/Test/Songs/X3 Search By Difficulty/box.def b/Test/Songs/X3 Search By Difficulty/box.def index cd5ac27a..62f01838 100644 --- a/Test/Songs/X3 Search By Difficulty/box.def +++ b/Test/Songs/X3 Search By Difficulty/box.def @@ -1,9 +1,12 @@ #TITLE:Search by difficulty +#TITLEJA:むずかしさから探す #GENRE:SearchD #FORECOLOR:#FFFFFF #BACKCOLOR:#213d18 #BOXEXPLANATION1:Search and play songs that #BOXEXPLANATION2:fit your level ! +#BOXEXPLANATIONJA1:難易度やレベルで検索するよ +#BOXEXPLANATIONJA2:とても便利! #BGTYPE:1 #BOXTYPE:0 #BOXCOLOR:#5ac736 diff --git a/Test/System/SimpleStyle (1080p)/Graphics/5_Game/Adlib.png b/Test/System/SimpleStyle (1080p)/Graphics/5_Game/Adlib.png new file mode 100644 index 00000000..60b4cba8 Binary files /dev/null and b/Test/System/SimpleStyle (1080p)/Graphics/5_Game/Adlib.png differ diff --git a/Test/System/SimpleStyle/Graphics/5_Game/Adlib.png b/Test/System/SimpleStyle/Graphics/5_Game/Adlib.png new file mode 100644 index 00000000..b412cc5c Binary files /dev/null and b/Test/System/SimpleStyle/Graphics/5_Game/Adlib.png differ