OSDN Git Service

0df9b045a62de596df2dbf0e3a64b1184dc630a9
[strokestylet/CsWin10Desktop3.git] / SSTFormat / チップ.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Linq;
5
6 namespace SSTFormat
7 {
8         public class チップ : IComparable
9         {
10                 public const int 最大音量 = 4;
11
12                 #region " プロパティ(1)(増減したら CopyFrom() を修正のこと)"
13                 //----------------
14                 public チップ種別 チップ種別 { get; set; } = チップ種別.Unknown;
15                 public int 小節番号 { get; set; } = -1;
16                 public int 小節内位置 { get; set; } = 0;
17                 public int 小節解像度 { get; set; } = 1;
18                 /// <summary>
19                 /// チップの描画時刻[ms]。
20                 /// 譜面の先頭(小節番号 -1 の小節の先頭)からの時刻をミリ秒単位で表す。
21                 /// </summary>
22                 public long 描画時刻ms { get; set; } = FDK.カウンタ.QPCTimer.未使用;
23                 /// <summary>
24                 /// チップの描画時刻[sec]。
25                 /// 譜面の先頭(小節番号 -1 の小節の先頭)からの時刻を秒単位で表す。
26                 /// </summary>
27                 public double 描画時刻sec => ( this.描画時刻ms / 1000.0 );
28                 /// <summary>
29                 /// チップの発声時刻[ms]。
30                 /// 譜面の先頭(小節番号 -1 の小節の先頭)からの時刻をミリ秒単位で表す。
31                 /// </summary>
32                 /// <remarks>
33                 /// サウンドの発声遅延を考慮して、描画時刻よりも遅く設定すること。
34                 /// </remarks>
35                 public long 発声時刻ms { get; set; } = FDK.カウンタ.QPCTimer.未使用;
36                 /// <summary>
37                 /// チップの発声時刻[sec]。
38                 /// 譜面の先頭(小節番号 -1 の小節の先頭)からの時刻を秒単位で表す。
39                 /// </summary>
40                 /// <remarks>
41                 /// サウンドの発声遅延を考慮して、描画時刻よりも遅く設定すること。
42                 /// </remarks>
43                 public double 発声時刻sec => ( this.発声時刻ms / 1000.0 );
44                 /// <summary>
45                 /// チップの音量(小:1~4:大)。
46                 /// </summary>
47                 public int 音量
48                 {
49                         get
50                         {
51                                 return this.bs_音量;
52                         }
53                         set
54                         {
55                                 if( ( 1 > value ) || ( チップ.最大音量 < value ) )
56                                         throw new ArgumentException( $"音量の値域(1~{チップ.最大音量})を超える値 '{value}' が指定されました。" );
57
58                                 this.bs_音量 = value;
59                         }
60                 }
61                 /// <summary>
62                 /// チップが BPM チップである場合は、その BPM 値。それ以外の場合は無効。
63                 /// </summary>
64                 public double BPM { get; set; } = 120.0;
65                 //----------------
66                 #endregion
67                 #region " プロパティ(2) 演奏用(増減したら CopyFrom() を修正のこと)"
68                 //----------------
69                 public bool 可視 { get; set; } = true;
70                 public bool 不可視
71                 {
72                         get { return !this.可視; }
73                         set { this.可視 = !value; }
74                 }
75                 public bool 可視の初期値
76                 {
77                         get
78                         {
79                                 return (
80                                         // ↓これらは不可視。
81                                         ( this.チップ種別 == チップ種別.BPM ) ||
82                                         ( this.チップ種別 == チップ種別.背景動画 ) ||
83                                         ( this.チップ種別 == チップ種別.小節メモ ) ||
84                                         ( this.チップ種別 == チップ種別.小節の先頭 ) ||
85                                         ( this.チップ種別 == チップ種別.Unknown )
86                                         ) ? false : true;
87                         }
88                 }
89                 public bool ヒット済みである { get; set; } = false;
90                 public bool ヒットされていない
91                 {
92                         get { return !this.ヒット済みである; }
93                         set { this.ヒット済みである = !value; }
94                 }
95                 public bool 発声済みである { get; set; } = false;
96                 public bool 発声されていない
97                 {
98                         get { return !this.発声済みである; }
99                         set { this.発声済みである = !value; }
100                 }
101                 //----------------
102                 #endregion
103                 #region " プロパティ(3) SSTFEditor用(増減したら CopyFrom() を修正のこと)"
104                 //----------------
105                 public int 譜面内絶対位置grid { get; set; } = 0;
106                 public bool ドラッグ操作により選択中である { get; set; } = false;
107                 public bool 選択が確定している { get; set; } = false;
108                 public bool 選択が確定していない
109                 {
110                         get { return !this.選択が確定している; }
111                         set { this.選択が確定している = !value; }
112                 }
113                 public bool 移動済みである { get; set; } = true;
114                 public bool 移動されていない
115                 {
116                         get { return !this.移動済みである; }
117                         set { this.移動済みである = !value; }
118                 }
119                 public string チップ内文字列 { get; set; } = null;
120                 public int 枠外レーン数 { get; set; } = 0;
121                 //----------------
122                 #endregion
123
124                 public チップ()
125                 {
126                 }
127                 public チップ( チップ コピー元チップ )
128                 {
129                         this.CopyFrom( コピー元チップ );
130                 }
131                 public void CopyFrom( チップ srcChip )
132                 {
133                         // プロパティ(1)
134                         this.チップ種別 = srcChip.チップ種別;
135                         this.小節番号 = srcChip.小節番号;
136                         this.小節内位置 = srcChip.小節内位置;
137                         this.小節解像度 = srcChip.小節解像度;
138                         this.描画時刻ms = srcChip.描画時刻ms;
139                         this.発声時刻ms = srcChip.発声時刻ms;
140                         this.音量 = srcChip.音量;
141                         this.BPM = srcChip.BPM;
142
143                         // プロパティ(2)
144                         this.可視 = srcChip.可視;
145                         this.ヒット済みである = srcChip.ヒット済みである;
146                         this.発声済みである = srcChip.発声済みである;
147
148                         // プロパティ(3)
149                         this.譜面内絶対位置grid = srcChip.譜面内絶対位置grid;
150                         this.ドラッグ操作により選択中である = srcChip.ドラッグ操作により選択中である;
151                         this.選択が確定している = srcChip.選択が確定している;
152                         this.移動済みである = srcChip.移動済みである;
153                         this.チップ内文字列 = srcChip.チップ内文字列;
154                         this.枠外レーン数 = srcChip.枠外レーン数;
155                 }
156                 public void ヒット前の状態にする()
157                 {
158                         // 演奏用プロパティについて設定する。
159
160                         this.可視 = this.可視の初期値;
161                         this.ヒット済みである = false;
162                         this.発声済みである = false;
163                 }
164                 public void ヒット済みの状態にする()
165                 {
166                         // 演奏用プロパティについて設定する。
167
168                         this.可視 = false;
169                         this.ヒット済みである = true;
170                         this.発声済みである = true;
171                 }
172
173                 #region " IComparable 実装 "
174                 //-----------------
175                 // 概要:
176                 //     現在のインスタンスを同じ型の別のオブジェクトと比較して、並べ替え順序において、現在のインスタンスの位置が同じ型の別のオブジェクトの前、後ろ、または同じのいずれであるかを示す整数を返します。
177                 //
178                 // パラメータ:
179                 //   obj:
180                 //     このインスタンスと比較するオブジェクト。
181                 //
182                 // 戻り値:
183                 //     比較対象オブジェクトの相対順序を示す 32 ビット符号付き整数。戻り値の意味は次のとおりです。 
184                 //
185                 //     値              説明
186                 //     --------------------
187                 //     負数           this < obj
188                 //     0                this = obj
189                 //     正数           this > obj
190                 //
191                 // 例外:
192                 //   System.ArgumentException:
193                 //     obj の型がこのインスタンスの型と異なります。
194                 //
195                 public int CompareTo( object obj )
196                 {
197                         var other = obj as チップ;
198
199                         if( this.小節番号 < other.小節番号 ) { return -1; }
200                         if( this.小節番号 > other.小節番号 ) { return +1; }
201
202                         double dbThis = (double) this.小節内位置 / (double) this.小節解像度;
203                         double dbOther = (double) other.小節内位置 / (double) other.小節解像度;
204
205                         if( dbThis < dbOther ) { return -1; }
206                         if( dbThis > dbOther ) { return +1; }
207
208
209                         // グリッドが完全に等しいなら、チップの種類ごとに定義された深度で順序を決める。
210
211                         if( チップ.チップの深さ[ this.チップ種別 ] > チップ.チップの深さ[ other.チップ種別 ] ) { return -1; }
212                         if( チップ.チップの深さ[ this.チップ種別 ] < チップ.チップの深さ[ other.チップ種別 ] ) { return +1; }
213
214                         return 0;
215                 }
216                 //-----------------
217                 #endregion
218
219                 protected readonly static Dictionary<チップ種別, int> チップの深さ
220                         #region " *** "
221                         //-----------------
222                         = new Dictionary<チップ種別, int>() {
223                                 { チップ種別.Ride_Cup, 50 },
224                                 { チップ種別.HiHat_Open, 50 },
225                                 { チップ種別.HiHat_HalfOpen, 50 },
226                                 { チップ種別.HiHat_Close, 50 },
227                                 { チップ種別.HiHat_Foot, 50 },
228                                 { チップ種別.Snare, 50 },
229                                 { チップ種別.Snare_OpenRim, 50 },
230                                 { チップ種別.Snare_ClosedRim, 50 },
231                                 { チップ種別.Snare_Ghost, 50 },
232                                 { チップ種別.Tom1, 50 },
233                                 { チップ種別.Tom1_Rim, 50 },
234                                 { チップ種別.BPM, 50 },
235                                 { チップ種別.Ride, 60 },
236                                 { チップ種別.Splash, 60 },
237                                 { チップ種別.Tom2, 60 },
238                                 { チップ種別.Tom2_Rim, 60 },
239                                 { チップ種別.LeftCrash, 70 },
240                                 { チップ種別.China, 70 },
241                                 { チップ種別.Tom3, 70 },
242                                 { チップ種別.Tom3_Rim, 70 },
243                                 { チップ種別.RightCrash, 70 },
244                                 { チップ種別.Bass, 75 },
245                                 { チップ種別.LeftCymbal_Mute, 76 },
246                                 { チップ種別.RightCymbal_Mute, 76 },
247                                 { チップ種別.小節線, 80 },
248                                 { チップ種別.拍線, 85 },
249                                 { チップ種別.背景動画, 90 },
250                                 { チップ種別.小節メモ, 99 },
251                                 { チップ種別.Unknown, 99 },
252                         };
253                         //-----------------
254                         #endregion
255
256                 #region " バックストア "
257                 //-----------------
258                 private int bs_音量 = チップ.最大音量;
259                 //-----------------
260                 #endregion
261         }
262 }