1
0
mirror of synced 2024-12-20 11:25:55 +01:00
OpenTaiko/FDK19/コード/02.入力/CInput管理.cs

298 lines
8.1 KiB
C#
Raw Normal View History

2021-09-21 00:16:38 +02:00
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using SharpDX.DirectInput;
namespace FDK
{
public class CInput管理 : IDisposable
{
// 定数
public static int n通常音量 = 110;
// プロパティ
public List<IInputDevice> list入力デバイス
{
get;
private set;
}
public IInputDevice Keyboard
{
get
{
if (this._Keyboard != null)
{
return this._Keyboard;
}
foreach (IInputDevice device in this.list入力デバイス)
{
if (device.e入力デバイス種別 == E入力デバイス種別.Keyboard)
{
this._Keyboard = device;
return device;
}
}
return null;
}
}
public IInputDevice Mouse
{
get
{
if (this._Mouse != null)
{
return this._Mouse;
}
foreach (IInputDevice device in this.list入力デバイス)
{
if (device.e入力デバイス種別 == E入力デバイス種別.Mouse)
{
this._Mouse = device;
return device;
}
}
return null;
}
}
// コンストラクタ
public CInput管理(IntPtr hWnd, bool bUseMidiIn = true)
{
CInput管理初期化(hWnd, bUseMidiIn);
}
public void CInput管理初期化(IntPtr hWnd, bool bUseMidiIn)
{
this.directInput = new DirectInput();
// this.timer = new CTimer( CTimer.E種別.MultiMedia );
this.list入力デバイス = new List<IInputDevice>(10);
#region [ Enumerate keyboard/mouse: exception is masked if keyboard/mouse is not connected ]
CInputKeyboard cinputkeyboard = null;
CInputMouse cinputmouse = null;
try
{
cinputkeyboard = new CInputKeyboard(hWnd, directInput);
cinputmouse = new CInputMouse(hWnd, directInput);
}
catch
{
}
if (cinputkeyboard != null)
{
this.list入力デバイス.Add(cinputkeyboard);
}
if (cinputmouse != null)
{
this.list入力デバイス.Add(cinputmouse);
}
#endregion
#region [ Enumerate joypad ]
foreach (DeviceInstance instance in this.directInput.GetDevices(DeviceClass.GameControl, DeviceEnumerationFlags.AttachedOnly))
{
this.list入力デバイス.Add(new CInputJoystick(hWnd, instance, directInput));
}
#endregion
if (bUseMidiIn)
{
this.proc = new CWin32.MidiInProc(this.MidiInCallback);
uint nMidiDevices = CWin32.midiInGetNumDevs();
Trace.TraceInformation("MIDI入力デバイス数: {0}", nMidiDevices);
for (uint i = 0; i < nMidiDevices; i++)
{
CInputMIDI item = new CInputMIDI(i);
CWin32.MIDIINCAPS lpMidiInCaps = new CWin32.MIDIINCAPS();
uint num3 = CWin32.midiInGetDevCaps(i, ref lpMidiInCaps, (uint)Marshal.SizeOf(lpMidiInCaps));
if (num3 != 0)
{
Trace.TraceError("MIDI In: Device{0}: midiInDevCaps(): {1:X2}: ", i, num3);
}
else
{
uint ret = CWin32.midiInOpen(ref item.hMidiIn, i, this.proc, IntPtr.Zero, 0x30000);
Trace.TraceInformation("midiInOpen()==" + ret);
Trace.TraceInformation("item.hMidiIn==" + item.hMidiIn.ToString());
if ((ret == 0) && (item.hMidiIn != IntPtr.Zero))
{
CWin32.midiInStart(item.hMidiIn);
Trace.TraceInformation("MIDI In: [{0}] \"{1}\" の入力受付を開始しました。", i, lpMidiInCaps.szPname);
item.strDeviceName = lpMidiInCaps.szPname;
this.list入力デバイス.Add(item);
continue;
}
}
Trace.TraceError("MIDI In: [{0}] \"{1}\" の入力受付の開始に失敗しました。", i, lpMidiInCaps.szPname);
}
}
else
{
Trace.TraceInformation("DTXVモードのため、MIDI入力は使用しません。");
}
}
// メソッド
public IInputDevice Joystick(int ID)
{
foreach (IInputDevice device in this.list入力デバイス)
{
if ((device.e入力デバイス種別 == E入力デバイス種別.Joystick) && (device.ID == ID))
{
return device;
}
}
return null;
}
public IInputDevice Joystick(string GUID)
{
foreach (IInputDevice device in this.list入力デバイス)
{
if ((device.e入力デバイス種別 == E入力デバイス種別.Joystick) && device.GUID.Equals(GUID))
{
return device;
}
}
return null;
}
public IInputDevice MidiIn(int ID)
{
foreach (IInputDevice device in this.list入力デバイス)
{
if ((device.e入力デバイス種別 == E入力デバイス種別.MidiIn) && (device.ID == ID))
{
return device;
}
}
return null;
}
public void tポーリング(bool bWindowがアクティブ中, bool bバッファ入力を使用する)
{
lock (this.objMidiIn排他用)
{
// foreach( IInputDevice device in this.list入力デバイス )
for (int i = this.list入力デバイス.Count - 1; i >= 0; i--) // #24016 2011.1.6 yyagi: change not to use "foreach" to avoid InvalidOperation exception by Remove().
{
IInputDevice device = this.list入力デバイス[i];
try
{
device.tポーリング(bWindowがアクティブ中, bバッファ入力を使用する);
}
catch (SharpDX.SharpDXException e) // #24016 2011.1.6 yyagi: catch exception for unplugging USB joystick, and remove the device object from the polling items.
{
if (e.ResultCode == ResultCode.OtherApplicationHasPriority)
{
// #xxxxx: 2017.5.9: from: このエラーの時は、何もしない。
}
else
{
// #xxxxx: 2017.5.9: from: その他のエラーの場合は、デバイスが外されたと想定してRemoveする。
this.list入力デバイス.Remove(device);
device.Dispose();
Trace.TraceError("tポーリング時に対象deviceが抜かれており例外発生。同deviceをポーリング対象からRemoveしました。");
}
}
}
}
}
#region [ IDisposableα ]
//-----------------
public void Dispose()
{
this.Dispose(true);
}
public void Dispose(bool disposeManagedObjects)
{
if (!this.bDisposed済み)
{
if (disposeManagedObjects)
{
foreach (IInputDevice device in this.list入力デバイス)
{
CInputMIDI tmidi = device as CInputMIDI;
if (tmidi != null)
{
CWin32.midiInStop(tmidi.hMidiIn);
CWin32.midiInReset(tmidi.hMidiIn);
CWin32.midiInClose(tmidi.hMidiIn);
Trace.TraceInformation("MIDI In: [{0}] を停止しました。", new object[] { tmidi.ID });
}
}
foreach (IInputDevice device2 in this.list入力デバイス)
{
device2.Dispose();
}
lock (this.objMidiIn排他用)
{
this.list入力デバイス.Clear();
}
this.directInput.Dispose();
//if( this.timer != null )
//{
// this.timer.Dispose();
// this.timer = null;
//}
}
this.bDisposed済み = true;
}
}
~CInput管理()
{
this.Dispose(false);
GC.KeepAlive(this);
}
//-----------------
#endregion
// その他
#region [ private ]
//-----------------
private DirectInput directInput;
private IInputDevice _Keyboard;
private IInputDevice _Mouse;
private bool bDisposed済み;
private List<uint> listHMIDIIN = new List<uint>(8);
private object objMidiIn排他用 = new object();
private CWin32.MidiInProc proc;
//private CTimer timer;
private void MidiInCallback(IntPtr hMidiIn, uint wMsg, IntPtr dwInstance, IntPtr dwParam1, IntPtr dwParam2)
{
int p = (int)dwParam1 & 0xF0;
if (wMsg != CWin32.MIM_DATA || (p != 0x80 && p != 0x90 && p != 0xB0))
return;
long time = CSound管理.rc演奏用タイマ.nシステム時刻; // lock前に取得。演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
lock (this.objMidiIn排他用)
{
if ((this.list入力デバイス != null) && (this.list入力デバイス.Count != 0))
{
foreach (IInputDevice device in this.list入力デバイス)
{
CInputMIDI tmidi = device as CInputMIDI;
if ((tmidi != null) && (tmidi.hMidiIn == hMidiIn))
{
tmidi.tメッセージからMIDI信号のみ受信(wMsg, dwInstance, dwParam1, dwParam2, time);
break;
}
}
}
}
}
//-----------------
#endregion
}
}