2 using System.Collections.Generic;
\r
4 using System.Runtime.InteropServices;
\r
5 using System.Drawing;
\r
6 using System.Drawing.Imaging;
\r
8 using System.Diagnostics;
\r
10 using SlimDX.Direct3D9;
\r
16 /// 演奏画面の共通クラス (ドラム演奏画面, ギター演奏画面の継承元)
\r
18 internal abstract class CStage演奏画面共通 : CStage
\r
22 public bool bAUTOでないチップが1つでもバーを通過した
\r
31 public override void On活性化()
\r
33 this.eフェードアウト完了時の戻り値 = E演奏画面の戻り値.継続;
\r
35 this.r次にくるギターChip = null;
\r
36 this.r次にくるベースChip = null;
\r
38 for ( int i = 0; i < 3; i++ )
\r
40 this.b演奏にキーボードを使った[ i ] = false;
\r
41 this.b演奏にジョイパッドを使った[ i ] = false;
\r
42 this.b演奏にMIDI入力を使った[ i ] = false;
\r
43 this.b演奏にマウスを使った[ i ] = false;
\r
48 this.nInputAdjustTimeMs.Drums = CDTXMania.ConfigIni.nInputAdjustTimeMs.Drums; // #23580 2011.1.3 yyagi
\r
49 this.nInputAdjustTimeMs.Guitar = CDTXMania.ConfigIni.nInputAdjustTimeMs.Guitar; // 2011.1.7 ikanick 修正
\r
50 this.nInputAdjustTimeMs.Bass = CDTXMania.ConfigIni.nInputAdjustTimeMs.Bass; //
\r
51 //this.bIsAutoPlay.Drums = false;
\r
52 //this.bIsAutoPlay.Guitar = CDTXMania.ConfigIni.bAutoPlay.Guitar;
\r
53 //this.bIsAutoPlay.Bass = CDTXMania.ConfigIni.bAutoPlay.Bass;
\r
54 this.bIsAutoPlay = CDTXMania.ConfigIni.bAutoPlay; // #24239 2011.1.23 yyagi
\r
61 #region [ protected ]
\r
63 protected class STHITCOUNTOFRANK
\r
73 public int this[ int index ]
\r
80 return this.Perfect;
\r
94 throw new IndexOutOfRangeException();
\r
101 this.Perfect = value;
\r
105 this.Great = value;
\r
120 throw new IndexOutOfRangeException();
\r
125 [StructLayout( LayoutKind.Sequential )]
\r
126 protected struct STKARAUCHI
\r
128 public CDTX.CChip HH;
\r
129 public CDTX.CChip SD;
\r
130 public CDTX.CChip BD;
\r
131 public CDTX.CChip HT;
\r
132 public CDTX.CChip LT;
\r
133 public CDTX.CChip FT;
\r
134 public CDTX.CChip CY;
\r
135 public CDTX.CChip HHO;
\r
136 public CDTX.CChip RD;
\r
137 public CDTX.CChip LC;
\r
138 public CDTX.CChip this[ int index ]
\r
174 throw new IndexOutOfRangeException();
\r
220 throw new IndexOutOfRangeException();
\r
225 protected CActFIFOBlack actFI;
\r
226 protected CActFIFOBlack actFO;
\r
227 protected CActFIFOWhite actFOClear;
\r
228 protected CAct演奏ゲージ actGauge;
\r
230 protected bool bPAUSE;
\r
231 protected STDGBVALUE<bool> b演奏にMIDI入力を使った;
\r
232 protected STDGBVALUE<bool> b演奏にキーボードを使った;
\r
233 protected STDGBVALUE<bool> b演奏にジョイパッドを使った;
\r
234 protected STDGBVALUE<bool> b演奏にマウスを使った;
\r
236 protected E演奏画面の戻り値 eフェードアウト完了時の戻り値;
\r
238 protected int n現在のトップChip = -1;
\r
240 protected CDTX.CChip r次にくるギターChip;
\r
241 protected CDTX.CChip r次にくるベースChip;
\r
244 protected STDGBVALUE<int> nInputAdjustTimeMs; // #23580 2011.1.3 yyagi
\r
245 protected CConfigIni.STAUTOPLAY bIsAutoPlay; // #24239 2011.1.23 yyagi
\r
250 protected E判定 e指定時刻からChipのJUDGEを返す( long nTime, CDTX.CChip pChip, int nInputAdjustTime )
\r
252 if ( pChip != null )
\r
254 pChip.nLag = (int) ( nTime + nInputAdjustTime - pChip.n発声時刻ms ); // #23580 2011.1.3 yyagi: add "nInputAdjustTime" to add input timing adjust feature
\r
255 int nDeltaTime = Math.Abs( pChip.nLag );
\r
256 //Debug.WriteLine("nAbsTime=" + (nTime - pChip.n発声時刻ms) + ", nDeltaTime=" + (nTime + nInputAdjustTime - pChip.n発声時刻ms));
\r
257 if ( nDeltaTime <= CDTXMania.nPerfect範囲ms )
\r
259 return E判定.Perfect;
\r
261 if ( nDeltaTime <= CDTXMania.nGreat範囲ms )
\r
265 if ( nDeltaTime <= CDTXMania.nGood範囲ms )
\r
269 if ( nDeltaTime <= CDTXMania.nPoor範囲ms )
\r
279 protected CDTX.CChip r指定時刻に一番近いChip・ヒット未済問わず不可視考慮( long nTime, int nChannelFlag, int nInputAdjustTime )
\r
281 nTime += nInputAdjustTime; // #24239 2011.1.23 yyagi InputAdjust
\r
284 if ( this.n現在のトップChip == -1 )
\r
288 int count = CDTXMania.DTX.listChip.Count;
\r
289 int num4 = num5 = this.n現在のトップChip;
\r
290 if ( this.n現在のトップChip >= count )
\r
292 num4 = num5 = count - 1;
\r
295 while ( num2 < count )
\r
297 CDTX.CChip chip = CDTXMania.DTX.listChip[ num2 ];
\r
298 if ( ( ( nChannelFlag >= 0x11 ) && ( nChannelFlag <= 0x1a ) ) && ( ( chip.nチャンネル番号 == nChannelFlag ) || ( chip.nチャンネル番号 == ( nChannelFlag + 0x20 ) ) ) )
\r
300 if ( chip.n発声時刻ms > nTime )
\r
306 else if ( ( ( nChannelFlag == 0x2f ) && ( chip.e楽器パート == E楽器パート.GUITAR ) ) || ( ( ( nChannelFlag >= 0x20 ) && ( nChannelFlag <= 0x28 ) ) && ( chip.nチャンネル番号 == nChannelFlag ) ) )
\r
308 if ( chip.n発声時刻ms > nTime )
\r
314 else if ( ( ( nChannelFlag == 0xaf ) && ( chip.e楽器パート == E楽器パート.BASS ) ) || ( ( ( nChannelFlag >= 0xa0 ) && ( nChannelFlag <= 0xa8 ) ) && ( chip.nチャンネル番号 == nChannelFlag ) ) )
\r
316 if ( chip.n発声時刻ms > nTime )
\r
325 while ( num3 >= 0 )
\r
327 CDTX.CChip chip2 = CDTXMania.DTX.listChip[ num3 ];
\r
328 if ( ( nChannelFlag >= 0x11 ) && ( nChannelFlag <= 0x1a ) )
\r
330 if ( ( chip2.nチャンネル番号 == nChannelFlag ) || ( chip2.nチャンネル番号 == ( nChannelFlag + 0x20 ) ) )
\r
335 else if ( ( ( nChannelFlag == 0x2f ) && ( chip2.e楽器パート == E楽器パート.GUITAR ) ) || ( ( ( nChannelFlag >= 0x20 ) && ( nChannelFlag <= 0x28 ) ) && ( chip2.nチャンネル番号 == nChannelFlag ) ) )
\r
337 if ( ( chip2.nチャンネル番号 >= 0x20 ) && ( chip2.nチャンネル番号 <= 0x28 ) )
\r
342 else if ( ( ( ( nChannelFlag == 0xaf ) && ( chip2.e楽器パート == E楽器パート.BASS ) ) || ( ( ( nChannelFlag >= 0xa0 ) && ( nChannelFlag <= 0xa8 ) ) && ( chip2.nチャンネル番号 == nChannelFlag ) ) ) && ( ( chip2.nチャンネル番号 >= 0xa0 ) && ( chip2.nチャンネル番号 <= 0xa8 ) ) )
\r
348 if ( ( num2 == count ) && ( num3 < 0 ) )
\r
352 if ( num2 == count )
\r
354 return CDTXMania.DTX.listChip[ num3 ];
\r
358 return CDTXMania.DTX.listChip[ num2 ];
\r
360 CDTX.CChip chip3 = CDTXMania.DTX.listChip[ num2 ];
\r
361 CDTX.CChip chip4 = CDTXMania.DTX.listChip[ num3 ];
\r
362 int num6 = Math.Abs( (int) ( nTime - chip3.n発声時刻ms ) );
\r
363 int num7 = Math.Abs( (int) ( nTime - chip4.n発声時刻ms ) );
\r
364 if ( num6 >= num7 )
\r
371 protected CDTX.CChip r指定時刻に一番近い未ヒットChip( long nTime, int nChannelFlag, int nInputAdjustTime, int n検索範囲時間ms )
\r
373 nTime += nInputAdjustTime;
\r
377 if ( this.n現在のトップChip == -1 )
\r
381 int count = CDTXMania.DTX.listChip.Count;
\r
382 int num4 = num5 = this.n現在のトップChip;
\r
383 if ( this.n現在のトップChip >= count )
\r
385 num4 = num5 = count - 1;
\r
388 while ( num2 < count )
\r
390 CDTX.CChip chip = CDTXMania.DTX.listChip[ num2 ];
\r
391 if ( ( !chip.bHit && ( nChannelFlag >= 0x11 ) ) && ( nChannelFlag <= 0x1a ) )
\r
393 if ( ( chip.nチャンネル番号 == nChannelFlag ) || ( chip.nチャンネル番号 == ( nChannelFlag + 0x20 ) ) )
\r
395 if ( chip.n発声時刻ms > nTime )
\r
402 else if ( !chip.bHit && ( ( ( nChannelFlag == 0x2f ) && ( chip.e楽器パート == E楽器パート.GUITAR ) ) || ( ( ( nChannelFlag >= 0x20 ) && ( nChannelFlag <= 40 ) ) && ( chip.nチャンネル番号 == nChannelFlag ) ) ) )
\r
404 if ( chip.n発声時刻ms > nTime )
\r
410 else if ( !chip.bHit && ( ( ( nChannelFlag == 0xaf ) && ( chip.e楽器パート == E楽器パート.BASS ) ) || ( ( ( nChannelFlag >= 160 ) && ( nChannelFlag <= 0xa8 ) ) && ( chip.nチャンネル番号 == nChannelFlag ) ) ) )
\r
412 if ( chip.n発声時刻ms > nTime )
\r
421 while ( num3 >= 0 )
\r
423 CDTX.CChip chip2 = CDTXMania.DTX.listChip[ num3 ];
\r
424 if ( ( ( ( !chip2.bHit && ( nChannelFlag >= 0x11 ) ) && ( ( nChannelFlag <= 0x1a ) && ( ( chip2.nチャンネル番号 == nChannelFlag ) || ( chip2.nチャンネル番号 == ( nChannelFlag + 0x20 ) ) ) ) ) || ( !chip2.bHit && ( ( ( nChannelFlag == 0x2f ) && ( chip2.e楽器パート == E楽器パート.GUITAR ) ) || ( ( ( nChannelFlag >= 0x20 ) && ( nChannelFlag <= 40 ) ) && ( chip2.nチャンネル番号 == nChannelFlag ) ) ) ) ) || ( !chip2.bHit && ( ( ( nChannelFlag == 0xaf ) && ( chip2.e楽器パート == E楽器パート.BASS ) ) || ( ( ( nChannelFlag >= 160 ) && ( nChannelFlag <= 0xa8 ) ) && ( chip2.nチャンネル番号 == nChannelFlag ) ) ) ) )
\r
430 if ( ( num2 == count ) && ( num3 < 0 ) )
\r
434 CDTX.CChip chip3 = null;
\r
435 if ( num2 == count )
\r
437 chip3 = CDTXMania.DTX.listChip[ num3 ];
\r
438 num6 = Math.Abs( (int) ( nTime - chip3.n発声時刻ms ) );
\r
440 else if ( num3 < 0 )
\r
442 chip3 = CDTXMania.DTX.listChip[ num2 ];
\r
443 num6 = Math.Abs( (int) ( nTime - chip3.n発声時刻ms ) );
\r
447 int num7 = Math.Abs( (int) ( nTime - CDTXMania.DTX.listChip[ num2 ].n発声時刻ms ) );
\r
448 int num8 = Math.Abs( (int) ( nTime - CDTXMania.DTX.listChip[ num3 ].n発声時刻ms ) );
\r
451 chip3 = CDTXMania.DTX.listChip[ num2 ];
\r
452 num6 = Math.Abs( (int) ( nTime - chip3.n発声時刻ms ) );
\r
456 chip3 = CDTXMania.DTX.listChip[ num3 ];
\r
457 num6 = Math.Abs( (int) ( nTime - chip3.n発声時刻ms ) );
\r
460 if ( ( n検索範囲時間ms > 0 ) && ( num6 > n検索範囲時間ms ) )
\r
466 protected CDTX.CChip r次にくるギターChipを更新して返す()
\r
468 int nInputAdjustTime = this.bIsAutoPlay.Guitar ? 0 : this.nInputAdjustTimeMs.Guitar;
\r
469 this.r次にくるギターChip = this.r指定時刻に一番近い未ヒットChip( CDTXMania.Timer.n現在時刻, 0x2f, nInputAdjustTime, 500 );
\r
470 return this.r次にくるギターChip;
\r
472 protected CDTX.CChip r次にくるベースChipを更新して返す()
\r
474 int nInputAdjustTime = this.bIsAutoPlay.Bass ? 0 : this.nInputAdjustTimeMs.Bass;
\r
475 this.r次にくるベースChip = this.r指定時刻に一番近い未ヒットChip( CDTXMania.Timer.n現在時刻, 0xaf, nInputAdjustTime, 500 );
\r
476 return this.r次にくるベースChip;
\r
479 protected void ChangeInputAdjustTimeInPlaying( IInputDevice keyboard, int plusminus ) // #23580 2011.1.16 yyagi UI for InputAdjustTime in playing screen.
\r
481 int part, offset = plusminus;
\r
482 if ( keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.LeftShift ) || keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.RightShift ) ) // Guitar InputAdjustTime
\r
484 part = (int) E楽器パート.GUITAR;
\r
486 else if ( keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.LeftAlt ) || keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.RightAlt ) ) // Bass InputAdjustTime
\r
488 part = (int) E楽器パート.BASS;
\r
490 else // Drums InputAdjustTime
\r
492 part = (int) E楽器パート.DRUMS;
\r
494 if ( !keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.LeftControl ) && !keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.RightControl ) )
\r
499 this.nInputAdjustTimeMs[ part ] += offset;
\r
500 if ( this.nInputAdjustTimeMs[ part ] > 0 )
\r
502 this.nInputAdjustTimeMs[ part ] = 0;
\r
504 else if ( this.nInputAdjustTimeMs[ part ] < -99 )
\r
506 this.nInputAdjustTimeMs[ part ] = -99;
\r
508 CDTXMania.ConfigIni.nInputAdjustTimeMs[ part ] = this.nInputAdjustTimeMs[ part ];
\r
511 protected abstract void t入力処理・ドラム();
\r
512 protected abstract void t入力処理・ギター();
\r
513 protected abstract void t入力処理・ベース();
\r
514 protected abstract void ドラムスクロール速度アップ();
\r
515 protected abstract void ドラムスクロール速度ダウン();
\r
516 protected void tキー入力()
\r
518 IInputDevice keyboard = CDTXMania.Input管理.Keyboard;
\r
519 if ( keyboard.bキーが押された( (int) SlimDX.DirectInput.Key.F1 ) &&
\r
520 ( keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.RightShift ) || keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.LeftShift ) ) )
\r
521 { // shift+f1 (pause)
\r
522 this.bPAUSE = !this.bPAUSE;
\r
525 CDTXMania.Timer.t一時停止();
\r
526 CDTXMania.DTX.t全チップの再生一時停止();
\r
530 CDTXMania.Timer.t再開();
\r
531 CDTXMania.DTX.t全チップの再生再開();
\r
534 if ( ( !this.bPAUSE && ( base.eフェーズID != CStage.Eフェーズ.演奏_STAGE_FAILED ) ) && ( base.eフェーズID != CStage.Eフェーズ.演奏_STAGE_FAILED_フェードアウト ) )
\r
539 if ( keyboard.bキーが押された( (int) SlimDX.DirectInput.Key.UpArrow ) && ( keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.RightShift ) || keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.LeftShift ) ) )
\r
540 { // shift (+ctrl) + UpArrow (BGMAdjust)
\r
541 CDTXMania.DTX.t各自動再生音チップの再生時刻を変更する( ( keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.LeftControl ) || keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.RightControl ) ) ? 1 : 10 );
\r
542 CDTXMania.DTX.tWave再生位置自動補正();
\r
544 else if ( keyboard.bキーが押された( (int) SlimDX.DirectInput.Key.DownArrow ) && ( keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.RightShift ) || keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.LeftShift ) ) )
\r
545 { // shift + DownArrow (BGMAdjust)
\r
546 CDTXMania.DTX.t各自動再生音チップの再生時刻を変更する( ( keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.LeftControl ) || keyboard.bキーが押されている( (int) SlimDX.DirectInput.Key.RightControl ) ) ? -1 : -10 );
\r
547 CDTXMania.DTX.tWave再生位置自動補正();
\r
549 else if ( keyboard.bキーが押された( (int) SlimDX.DirectInput.Key.UpArrow ) )
\r
550 { // UpArrow(scrollspeed up)
\r
553 else if ( keyboard.bキーが押された( (int) SlimDX.DirectInput.Key.DownArrow ) )
\r
554 { // DownArrow (scrollspeed down)
\r
557 else if ( keyboard.bキーが押された( (int) SlimDX.DirectInput.Key.Delete ) )
\r
558 { // del (debug info)
\r
559 CDTXMania.ConfigIni.b演奏情報を表示する = !CDTXMania.ConfigIni.b演奏情報を表示する;
\r
561 else if ( keyboard.bキーが押された( (int) SlimDX.DirectInput.Key.LeftArrow ) ) // #24243 2011.1.16 yyagi UI for InputAdjustTime in playing screen.
\r
563 ChangeInputAdjustTimeInPlaying( keyboard, -1 );
\r
565 else if ( keyboard.bキーが押された( (int) SlimDX.DirectInput.Key.RightArrow ) ) // #24243 2011.1.16 yyagi UI for InputAdjustTime in playing screen.
\r
567 ChangeInputAdjustTimeInPlaying( keyboard, +1 );
\r
569 else if ( ( base.eフェーズID == CStage.Eフェーズ.共通_通常状態 ) && ( keyboard.bキーが押された( (int) SlimDX.DirectInput.Key.Escape ) || CDTXMania.Pad.b押されたGB( Eパッド.FT ) ) )
\r
571 this.actFO.tフェードアウト開始();
\r
572 base.eフェーズID = CStage.Eフェーズ.共通_フェードアウト;
\r
573 this.eフェードアウト完了時の戻り値 = E演奏画面の戻り値.演奏中断;
\r
578 protected void t入力メソッド記憶( E楽器パート part )
\r
580 if ( CDTXMania.Pad.st検知したデバイス.Keyboard )
\r
582 this.b演奏にキーボードを使った[ (int) part ] = true;
\r
584 if ( CDTXMania.Pad.st検知したデバイス.Joypad )
\r
586 this.b演奏にジョイパッドを使った[ (int) part ] = true;
\r
588 if ( CDTXMania.Pad.st検知したデバイス.MIDIIN )
\r
590 this.b演奏にMIDI入力を使った[ (int) part ] = true;
\r
592 if ( CDTXMania.Pad.st検知したデバイス.Mouse )
\r
594 this.b演奏にマウスを使った[ (int) part ] = true;
\r
601 protected bool t進行描画・フェードイン・アウト()
\r
603 switch ( base.eフェーズID )
\r
605 case CStage.Eフェーズ.共通_フェードイン:
\r
606 if ( this.actFI.On進行描画() != 0 )
\r
608 base.eフェーズID = CStage.Eフェーズ.共通_通常状態;
\r
612 case CStage.Eフェーズ.共通_フェードアウト:
\r
613 case CStage.Eフェーズ.演奏_STAGE_FAILED_フェードアウト:
\r
614 if ( this.actFO.On進行描画() != 0 )
\r
620 case CStage.Eフェーズ.演奏_STAGE_CLEAR_フェードアウト:
\r
621 if ( this.actFOClear.On進行描画() == 0 )
\r
634 #if true // DAMAGELEVELTUNING
\r
635 #region [ DAMAGELEVELTUNING ]
\r
636 // ----------------------------------
\r
637 public float[ , ] fDamageGaugeDelta = { // #23625 2011.1.10 ickw_284: tuned damage/recover factors
\r
638 // drums, guitar, bass
\r
639 { 0.004f, 0.006f, 0.006f },
\r
640 { 0.002f, 0.003f, 0.003f },
\r
641 { 0.000f, 0.000f, 0.000f },
\r
642 { -0.020f, -0.030f, -0.030f },
\r
643 { -0.050f, -0.050f, -0.050f }
\r
645 public float[] fDamageLevelFactor = {
\r
648 // ----------------------------------
\r
652 protected void t判定にあわせてゲージを増減する( E楽器パート screenmode, E楽器パート part, E判定 e今回の判定 )
\r
656 #if true // DAMAGELEVELTUNING
\r
663 fDamage = fDamageGaugeDelta[ (int) e今回の判定, (int) part ];
\r
666 fDamage = fDamageGaugeDelta[ (int) e今回の判定, (int) part ];
\r
667 switch ( CDTXMania.ConfigIni.eダメージレベル )
\r
672 fDamage *= fDamageLevelFactor[ (int) CDTXMania.ConfigIni.eダメージレベル ];
\r
681 #else // before applying #23625 modifications
\r
685 fDamage = ( part == E楽器パート.DRUMS ) ? 0.01 : 0.015;
\r
689 fDamage = ( part == E楽器パート.DRUMS ) ? 0.006 : 0.009;
\r
693 fDamage = ( part == E楽器パート.DRUMS ) ? 0.002 : 0.003;
\r
697 fDamage = ( part == E楽器パート.DRUMS ) ? 0.0 : 0.0;
\r
701 fDamage = ( part == E楽器パート.DRUMS ) ? -0.035 : -0.035;
\r
702 switch( CDTXMania.ConfigIni.eダメージレベル )
\r
723 if ( screenmode == E楽器パート.DRUMS ) // ドラム演奏画面なら、ギター/ベースのダメージも全部ドラムのゲージに集約する
\r
725 part = E楽器パート.DRUMS;
\r
727 this.actGauge.db現在のゲージ値[ (int) part ] += fDamage;
\r
729 if ( this.actGauge.db現在のゲージ値[ (int) part ] > 1.0 )
\r
730 this.actGauge.db現在のゲージ値[ (int) part ] = 1.0;
\r
732 //-----------------
\r