OSDN Git Service

#28821 DTXC:DTXManiaをViewerにしたときに、DTXC側から、GRモード, TimeStretch, VSyncWaitの設定ができるようにした。
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / ステージ / CDTXVmode.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Diagnostics;\r
5 using System.IO;\r
6 using System.Threading;\r
7 using FDK;\r
8 \r
9 \r
10 namespace DTXMania\r
11 {\r
12         public class CDTXVmode\r
13         {\r
14                 public enum ECommand\r
15                 {\r
16                         Stop,\r
17                         Play,\r
18                         Preview\r
19                 }\r
20 \r
21                 /// <summary>\r
22                 /// DTXVモードかどうか\r
23                 /// </summary>\r
24                 public bool Enabled\r
25                 {\r
26                         get;\r
27                         set;\r
28                 }\r
29 \r
30                 /// <summary>\r
31                 /// プレビューサウンドの再生が発生した\r
32                 /// </summary>\r
33                 public bool Preview\r
34                 {\r
35                         get;\r
36                         set;\r
37                 }\r
38 \r
39                 /// <summary>\r
40                 /// 外部から再指示が発生したか\r
41                 /// </summary>\r
42                 public bool Refreshed\r
43                 {\r
44                         get;\r
45                         set;\r
46                 }\r
47 \r
48                 /// <summary>\r
49                 /// 演奏開始小節番号\r
50                 /// </summary>\r
51                 public int nStartBar\r
52                 {\r
53                         get;\r
54                         set;\r
55                 }\r
56 \r
57                 /// <summary>\r
58                 /// DTXファイルの再読み込みが必要かどうか\r
59                 /// </summary>\r
60                 public bool NeedReload\r
61                 {\r
62                         get;\r
63                         private set;\r
64 //                      private set;    // 本来はprivate setにすべきだが、デバッグが簡単になるので、しばらくはprivateなしのままにする。\r
65                 }\r
66 \r
67                 /// <summary>\r
68                 /// DTXCからのコマンド\r
69                 /// </summary>\r
70                 public ECommand Command\r
71                 {\r
72                         get;\r
73                         private set;\r
74                 }\r
75 \r
76                 public ESoundDeviceType soundDeviceType\r
77                 {\r
78                         get;\r
79                         private set;\r
80                 }\r
81                 public int nASIOdevice\r
82                 {\r
83                         get;\r
84                         private set;\r
85                 }\r
86                 /// <summary>\r
87                 /// 前回からサウンドデバイスが変更されたか\r
88                 /// </summary>\r
89                 public bool ChangedSoundDevice\r
90                 {\r
91                         get;\r
92                         private set;\r
93                 }\r
94 \r
95                 public string filename\r
96                 {\r
97                         get\r
98                         {\r
99                                 return last_path;\r
100                         }\r
101                 }\r
102 \r
103                 public string previewFilename\r
104                 {\r
105                         get;\r
106                         private set;\r
107                 }\r
108                 public int previewVolume\r
109                 {\r
110                         get;\r
111                         private set;\r
112                 }\r
113                 public int previewPan\r
114                 {\r
115                         get;\r
116                         private set;\r
117                 }\r
118                 public bool GRmode\r
119                 {\r
120                         get;\r
121                         private set;\r
122                 }\r
123                 public bool lastGRmode\r
124                 {\r
125                         get;\r
126                         private set;\r
127                 }\r
128                 public bool TimeStretch\r
129                 {\r
130                         get;\r
131                         private set;\r
132                 }\r
133                 public bool lastTimeStretch\r
134                 {\r
135                         get;\r
136                         private set;\r
137                 }\r
138                 public bool VSyncWait\r
139                 {\r
140                         get;\r
141                         private set;\r
142                 }\r
143                 public bool lastVSyncWait\r
144                 {\r
145                         get;\r
146                         private set;\r
147                 }\r
148 \r
149 \r
150                 /// <summary>\r
151                 /// コンストラクタ\r
152                 /// </summary>\r
153                 public CDTXVmode()\r
154                 {\r
155                         this.last_path = "";\r
156                         this.last_timestamp = DateTime.MinValue;\r
157                         this.Enabled = false;\r
158                         this.nStartBar = 0;\r
159                         this.Refreshed = false;\r
160                         this.NeedReload = false;\r
161                         this.previewFilename = "";\r
162                         this.GRmode = false;\r
163                         this.lastGRmode = false;\r
164                         this.TimeStretch = false;\r
165                         this.lastTimeStretch = false;\r
166                         this.VSyncWait = true;\r
167                         this.lastVSyncWait = true;\r
168                 }\r
169 \r
170                 /// <summary>\r
171                 /// DTXファイルのリロードが必要かどうか判定する\r
172                 /// </summary>\r
173                 /// <param name="filename">DTXファイル名</param>\r
174                 /// <returns>再読込が必要ならtrue</returns>\r
175                 /// <remarks>プロパティNeedReloadにも結果が入る</remarks>\r
176                 /// <remarks>これを呼び出すたびに、Refreshedをtrueにする</remarks>\r
177                 /// <exception cref="FileNotFoundException"></exception>\r
178                 public bool bIsNeedReloadDTX( string filename )\r
179                 {\r
180                         if ( !File.Exists( filename ) )                 // 指定したファイルが存在しないなら例外終了\r
181                         {\r
182                                 Trace.TraceError( "ファイルが見つかりません。({0})", filename );\r
183                                 throw new FileNotFoundException();\r
184                                 //return false;\r
185                         }\r
186 \r
187                         this.Refreshed = true;\r
188 \r
189                         // 前回とファイル名が異なるか、タイムスタンプが更新されているか、\r
190                         // GRmode等の設定を変更したなら、DTX要更新\r
191                         DateTime current_timestamp = File.GetLastWriteTime( filename );\r
192                         if ( last_path != filename || current_timestamp > last_timestamp ||\r
193                                 this.lastGRmode != this.GRmode || this.lastTimeStretch != this.TimeStretch || this.lastVSyncWait != this.VSyncWait )\r
194                         {\r
195                                 this.last_path = filename;\r
196                                 this.last_timestamp = current_timestamp;\r
197                                 this.lastGRmode = this.GRmode;\r
198                                 this.lastTimeStretch = this.TimeStretch;\r
199                                 this.lastVSyncWait = this.VSyncWait;\r
200 \r
201                                 this.NeedReload = true;\r
202                                 return true;\r
203                         }\r
204                         this.NeedReload = false;\r
205                         return false;\r
206                 }\r
207 \r
208                 /// <summary>\r
209                 /// \r
210                 /// </summary>\r
211                 /// <param name="arg"></param>\r
212                 /// <param name="nStartBar"></param>\r
213                 /// <param name="command"></param>\r
214                 /// <returns>DTXV用の引数であればtrue</returns>\r
215                 /// <remarks>内部でEnabled, nStartBar, Command, NeedReload, filename, last_path, last_timestampを設定する</remarks>\r
216                 public bool ParseArguments( string arg )\r
217                 {\r
218                         bool ret = false, analyzing = true;\r
219                         this.nStartBar = 0;\r
220 \r
221                         if ( arg != null ) \r
222                         {\r
223 //Trace.TraceInformation( "arg=" + arg );\r
224                                 while ( analyzing )\r
225                                 {\r
226                                         if ( arg == "" )\r
227                                         {\r
228                                                 analyzing = false;\r
229                                         }\r
230                                         else if ( arg.StartsWith( "-V", StringComparison.OrdinalIgnoreCase ) )          // サウンド再生\r
231                                         {\r
232                                                 // -Vvvv,ppp,"filename"の形式。 vvv=volume, ppp=pan.\r
233                                                 this.Enabled = true;\r
234                                                 this.Command = ECommand.Preview;\r
235                                                 this.Refreshed = true;\r
236                                                 ret = true;\r
237                                                 arg = arg.Substring( 2 );\r
238 \r
239                                                 int pVol = arg.IndexOf( ',' );\r
240 //Trace.TraceInformation( "pVol=" + pVol );\r
241                                                 string strVol = arg.Substring( 0, pVol );\r
242 //Trace.TraceInformation( "strVol=" + strVol );\r
243                                                 this.previewVolume = Convert.ToInt32( strVol );\r
244 //Trace.TraceInformation( "previewVolume=" + previewVolume );\r
245                                                 int pPan = arg.IndexOf( ',', pVol + 1 );\r
246 //Trace.TraceInformation( "pPan=" + pPan );\r
247                                                 string strPan = arg.Substring( pVol + 1, pPan - pVol - 1 );\r
248 //Trace.TraceInformation( "strPan=" + strPan );\r
249                                                 this.previewPan = Convert.ToInt32( strPan );\r
250 //Trace.TraceInformation( "previewPan=" + previewPan );\r
251 \r
252                                                 arg = arg.Substring( pPan + 1 );\r
253                                                 arg = arg.Trim( new char[] { '\"' } );\r
254                                                 this.previewFilename = arg;\r
255                                                 analyzing = false;\r
256                                         }\r
257                                         // -S  -Nxxx  filename\r
258                                         else if ( arg.StartsWith( "-S", StringComparison.OrdinalIgnoreCase ) )          // DTXV再生停止\r
259                                         {\r
260                                                 this.Enabled = true;\r
261                                                 this.Command = ECommand.Stop;\r
262                                                 this.Refreshed = true;\r
263                                                 ret = true;\r
264                                                 arg = arg.Substring( 2 );\r
265                                         }\r
266                                         else if ( arg.StartsWith( "-D", StringComparison.OrdinalIgnoreCase ) )\r
267                                         {\r
268                                                 // -DW, -DA1など\r
269                                                 arg = arg.Substring( 2 );       // -D を削除\r
270                                                 switch ( arg[ 0 ] )\r
271                                                 {\r
272                                                         #region [ DirectSound ]\r
273                                                         case 'D':\r
274                                                                 if ( this.soundDeviceType != ESoundDeviceType.DirectSound )\r
275                                                                 {\r
276                                                                         this.ChangedSoundDevice = true;\r
277                                                                         this.soundDeviceType = ESoundDeviceType.DirectSound;\r
278                                                                 }\r
279                                                                 else\r
280                                                                 {\r
281                                                                         this.ChangedSoundDevice = false;\r
282                                                                 }\r
283                                                                 arg = arg.Substring( 1 );\r
284                                                                 break;\r
285                                                         #endregion\r
286                                                         #region [ WASAPI ]\r
287                                                         case 'W':\r
288                                                                 if ( this.soundDeviceType != ESoundDeviceType.ExclusiveWASAPI )\r
289                                                                 {\r
290                                                                         this.ChangedSoundDevice = true;\r
291                                                                         this.soundDeviceType = ESoundDeviceType.ExclusiveWASAPI;\r
292                                                                 }\r
293                                                                 else\r
294                                                                 {\r
295                                                                         this.ChangedSoundDevice = false;\r
296                                                                 }\r
297                                                                 arg = arg.Substring( 1 );\r
298                                                                 break;\r
299                                                         #endregion\r
300                                                         #region [ ASIO ]\r
301                                                         case 'A':\r
302                                                                 if ( this.soundDeviceType != ESoundDeviceType.ASIO )\r
303                                                                 {\r
304                                                                         this.ChangedSoundDevice = true;\r
305                                                                         this.soundDeviceType = ESoundDeviceType.ASIO;\r
306                                                                 }\r
307                                                                 else\r
308                                                                 {\r
309                                                                         this.ChangedSoundDevice = false;\r
310                                                                 }\r
311                                                                 arg = arg.Substring( 1 );\r
312 \r
313                                                                 int nAsioDev = 0, p = 0;\r
314                                                                 while ( true )\r
315                                                                 {\r
316                                                                         char c = arg[ 0 ];\r
317                                                                         if ( '0' <= c && c <= '9' )\r
318                                                                         {\r
319                                                                                 nAsioDev *= 10;\r
320                                                                                 nAsioDev += c - '0';\r
321                                                                                 p++;\r
322                                                                                 arg = arg.Substring( 1 );\r
323                                                                                 continue;\r
324                                                                         }\r
325                                                                         else\r
326                                                                         {\r
327                                                                                 break;\r
328                                                                         }\r
329                                                                 }\r
330                                                                 if ( this.nASIOdevice != nAsioDev )\r
331                                                                 {\r
332                                                                         this.ChangedSoundDevice = true;\r
333                                                                         this.nASIOdevice = nAsioDev;\r
334                                                                 }\r
335                                                                 break;\r
336                                                         #endregion\r
337                                                 }\r
338                                                 #region [ GRmode, TimeStretch, VSyncWait ]\r
339                                                 {\r
340                                                         // Reload判定は、-Nのところで行う\r
341                                                         this.GRmode =      ( arg[ 0 ] == 'Y' );\r
342                                                         this.TimeStretch = ( arg[ 1 ] == 'Y' );\r
343                                                         this.VSyncWait =   ( arg[ 2 ] == 'Y' );\r
344 \r
345                                                         arg = arg.Substring( 3 );\r
346                                                 }\r
347                                                 #endregion\r
348                                         }\r
349                                         else if ( arg.StartsWith( "-N", StringComparison.OrdinalIgnoreCase ) )\r
350                                         {\r
351                                                 this.Enabled = true;\r
352                                                 this.Command = ECommand.Play;\r
353                                                 ret = true;\r
354 \r
355                                                 arg = arg.Substring( 2 );                                       // "-N"を除去\r
356                                                 string[] p = arg.Split( new char[] { ' ' } );\r
357                                                 this.nStartBar = int.Parse( p[ 0 ] );                   // 再生開始小節\r
358                                                 if ( this.nStartBar < 0 )\r
359                                                 {\r
360                                                         this.nStartBar = -1;\r
361                                                 }\r
362 \r
363                                                 int startIndex = arg.IndexOf( ' ' );\r
364                                                 string filename = arg.Substring( startIndex + 1 );      // 再生ファイル名(フルパス) これで引数が終わっていることを想定\r
365                                                 try\r
366                                                 {\r
367                                                         filename = filename.Trim( new char[] { '\"' } );\r
368                                                         bIsNeedReloadDTX( filename );\r
369                                                 }\r
370                                                 catch   // 指定ファイルが存在しない\r
371                                                 {\r
372                                                 }\r
373                                                 arg = "";\r
374                                                 analyzing = false;\r
375                                         }\r
376                                 }\r
377                         }\r
378                         return ret;\r
379                 }\r
380 \r
381                 /// <summary>\r
382                 /// Viewer関連の設定のみを、Config.iniに書き出す\r
383                 /// </summary>\r
384                 public void tUpdateConfigIni()\r
385                 {\r
386                         CConfigIni cc = new CConfigIni();\r
387                         string path = CDTXMania.strEXEのあるフォルダ + "Config.ini";\r
388                         if ( File.Exists( path ) )\r
389                         {\r
390                                 try\r
391                                 {\r
392                                         cc.tファイルから読み込み( path );\r
393                                 }\r
394                                 catch\r
395                                 {\r
396                                         //ConfigIni = new CConfigIni(); // 存在してなければ新規生成\r
397                                 }\r
398                         }\r
399 \r
400                         cc.nViewerScrollSpeed     = CDTXMania.ConfigIni.n譜面スクロール速度;\r
401                         cc.bViewerShowDebugStatus = CDTXMania.ConfigIni.b演奏情報を表示する;\r
402                         cc.bViewerVSyncWait       = CDTXMania.ConfigIni.b垂直帰線待ちを行う;\r
403                         cc.bViewerTimeStretch     = CDTXMania.ConfigIni.bTimeStretch;\r
404                         cc.bViewerDrums有効       = CDTXMania.ConfigIni.bDrums有効;\r
405                         cc.bViewerGuitar有効      = CDTXMania.ConfigIni.bGuitar有効;\r
406 \r
407                         cc.t書き出し( path );\r
408                 }\r
409 \r
410                 private string last_path;\r
411                 private DateTime last_timestamp;\r
412 \r
413         }\r
414 }\r