/******************************************************************************
Ootake
・PCEパッド1〜5にキーボードのキーも含めて自由に割り当てできるようにした。
・Windows用16ボタンパッドとハットスイッチ（アナログ対応パッドでよく使われてい
  る）にも対応した。
・v0.54。ジョイパッド入力の判定部分をゲーム本番同様にDirectInputで行うようにし
  た。（0.53以前の２本以上ジョイパッドをつないでいたときの不具合を解消）
・連射専用ボタンの設定を追加。２ボタン，３ボタンパッド時に、ボタン５,６の割り
  当て領域を使用する。（６ボタンパッド時には設定できない仕様）
・早送り用ボタンの設定を追加。
・ステートセーブ用ボタンの設定を追加。
・ROMファイルを開くボタンの設定を追加。
・CDインストールされたゲーム（CUE）を開くボタンの設定を追加。
・スクリーンショット用ボタンの設定を追加。
・Z軸トリガ（PS4用DS4をInputMapper(XInputへ変換)入れて利用した場合などで存在）
  にも対応した。v2.81
・XInput（Xbox360規格のジョイパッド）への対応。公開用のOotakeの場合、
　古い"dinput.lib"を使ってビルドしているため、場合によってはDirectInputのほう
　が低遅延になる。マイクロソフトのドライバが入っていればXInput用ジョイパッド
　もDirectInput用として利用（自動で両対応）できる。v2.88
・GUI化。v2.94

Copyright(C)2006-2021 Kitao Nakamura.
	改造版・後継版を公開なさるときは必ずソースコードを添付してください。
	その際に事後でかまいませんので、ひとことお知らせいただけると幸いです。
	商的な利用は禁じます。
	あとは「GNU General Public License(一般公衆利用許諾契約書)」に準じます。

*******************************************************************************
	[PadConfig.c]

		Implements a pad configuration window.

	Copyright (C) 2005 Ki

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
******************************************************************************/
#define _CRT_SECURE_NO_DEPRECATE

#define DIRECTINPUT_VERSION	0x0500	//Kitao追加。環境にもよるかもしれないが、DirectInput5が軽い。7だとやや遅延あり。スペースハリアーがわかりやすい。

#include <Windows.h>
#include <string.h>
#include <XInput.h>
#include "PadConfig.h"
#include "resource.h"
#include "WinMain.h"
#include "Input.h"
#include "JoyPad.h"
#include "App.h"


#define PADCONFIG_CAPTION	"Key Setting"


#define KEY_LINE_LEN		71
#define KEY_N_LINES			20

#define N_MAXJOYSTICK		5


//Kitao更新。ハットスイッチ，16ボタン，Ｚ軸トリガにも対応。
static const Sint32	button[INPUT_NUM_BUTTON] =
{
	INPUT_JOYSTICK_UP,       INPUT_JOYSTICK_RIGHT,    INPUT_JOYSTICK_DOWN,     INPUT_JOYSTICK_LEFT,
	INPUT_JOYSTICK_POVUP,    INPUT_JOYSTICK_POVRIGHT, INPUT_JOYSTICK_POVDOWN,  INPUT_JOYSTICK_POVLEFT,
	INPUT_JOYSTICK_BUTTON1,  INPUT_JOYSTICK_BUTTON2,  INPUT_JOYSTICK_BUTTON3,  INPUT_JOYSTICK_BUTTON4,
	INPUT_JOYSTICK_BUTTON5,  INPUT_JOYSTICK_BUTTON6,  INPUT_JOYSTICK_BUTTON7,  INPUT_JOYSTICK_BUTTON8,
	INPUT_JOYSTICK_BUTTON9,  INPUT_JOYSTICK_BUTTON10, INPUT_JOYSTICK_BUTTON11, INPUT_JOYSTICK_BUTTON12,
	INPUT_JOYSTICK_BUTTON13, INPUT_JOYSTICK_BUTTON14, INPUT_JOYSTICK_BUTTON15, INPUT_JOYSTICK_BUTTON16,
	INPUT_JOYSTICK_L2ZTRIGGER, INPUT_JOYSTICK_R2ZTRIGGER
};


//Kitao追加。DirectInputを使用する。
static LPDIRECTINPUT			_pDI		= NULL;			// DirectInput インターフェースポインタ
static LPDIRECTINPUTDEVICE		_pDIDKey	= NULL;			// DirectInput Keyboard device
static LPDIRECTINPUTDEVICE2		_pDIDJoy[N_MAXJOYSTICK];	// DirectInput Joystick device

static Sint32					_OrderNum[26][5] = {1,2,3,4,5, 1,2,4,3,5, 1,3,2,4,5, 1,3,4,2,5, 1,4,2,3,5, 1,4,3,2,5,
													2,1,3,4,5, 2,1,4,3,5, 2,3,1,4,5, 2,3,4,1,5, 2,4,1,3,5, 2,4,3,1,5,
													3,1,2,4,5, 3,1,4,2,5, 3,2,1,4,5, 3,2,4,1,5, 3,4,1,2,5, 3,4,2,1,5,
													4,1,2,3,5, 4,1,3,2,5, 4,2,1,3,5, 4,2,3,1,5, 4,3,1,2,5, 4,3,2,1,5,
													5,1,2,3,4, 5,4,3,2,1}; //Windowsゲームパッドを参照する順序。v2.95

static Uint32		_FontWidth;
static Uint32		_FontHeight;
static const char*	_pCaption = PADCONFIG_CAPTION;
static HWND			_hPWnd;
static HINSTANCE	_hInstance = NULL;
static HWND			_hWnd;
static BOOL			_bWindowCreated; //Kitao追加

static char*		_pText[KEY_N_LINES];
static char			_Text[KEY_N_LINES][KEY_LINE_LEN];
static Uint32		_Line = 0;

static Sint32		_nJoySticks; //DirectInput接続のジョイパッドの数
static Sint32		_nJoySticksX; //XInput接続のジョイパッドの数。v2.89

static JOYSTICK		_Joystick[N_MAXJOYSTICK]; //DirectInput用
static JOYSTICK		_JoystickX[4]; //Xinput用。v2.88追加
static Sint32		_XJoyNumber[4]; //Xinput用。v3.01追加

static Sint32		_Mode; //Kitao追加。0…通常の設定。1…連射専用ボタンの設定。2…早回し用ボタンの設定。3…ステートセーブ用ボタンの設定。4…ステートロード用ボタンの設定。
						   //			5…スクリーンショット用ボタンの設定。6…ファンクション用ボタンの設定。7…ファンクションボタン時のステートセーブ＆ロード用ボタンの設定。
						   //			8…ポーズ用ボタンの設定。9…スプライトとBGの非表示・表示切替ボタンの設定。10…ROMイメージを開くボタンの設定。
						   //		    11…CDインストールのゲーム（CUE）を開くボタンの設定。12…十字キーの設定。v2.94更新

static Sint32		_PadID; //Kitao追加
static Sint32		_PadButtonN; //v2.94追加
static PCEPAD*		_pPad; //Kitao追加
static Sint32		_SetOk = 0; //Kitao追加。戻り値。設定完了なら1。キャンセルなら-1。設定中は0。
static Sint32*		_pSetOk; //Kitao追加
static char			_DIKeys[256]; //Kitao追加。キーボードの状態用


/* フォントの高さを取得する */
static Uint32
get_font_height(
	HWND			hWnd)
{
	HDC				hDC;
	HFONT			hFont;
	HFONT			hFontOld;
	TEXTMETRIC		tm;

	hDC      = GetDC(hWnd);
	hFont    = (HFONT)GetStockObject(OEM_FIXED_FONT);   /* 固定ピッチフォント */
	hFontOld = (HFONT)SelectObject(hDC, hFont);

	GetTextMetrics(hDC, &tm);

	SelectObject(hDC, hFontOld);
	DeleteObject(hFont);
	ReleaseDC(hWnd, hDC);

	return (Uint32)(tm.tmHeight);
}

/* フォントの横幅を取得する */
static Uint32
get_font_width(
	HWND			hWnd)
{
	HDC				hDC;
	HFONT			hFont;
	HFONT			hFontOld;
	TEXTMETRIC		tm;

	hDC      = GetDC(hWnd);
	hFont    = (HFONT)GetStockObject(OEM_FIXED_FONT);   /* 固定ピッチフォント */
	hFontOld = (HFONT)SelectObject(hDC, hFont);

	GetTextMetrics(hDC, &tm);

	SelectObject(hDC, hFontOld);
	DeleteObject(hFont);
	ReleaseDC(hWnd, hDC);

	return (Uint32)tm.tmAveCharWidth;
}


//Kitao更新
static void
set_window_size(
	HWND			hWnd)
{
	RECT	rc;
	Uint32	wndW = _FontWidth  * KEY_LINE_LEN +4;
	Uint32	wndH = _FontHeight * KEY_N_LINES;
	int		y;

	SetRect(&rc, 0, 0, wndW, wndH);
	AdjustWindowRectEx(&rc, GetWindowLong(hWnd, GWL_STYLE),
						GetMenu(hWnd) != NULL, GetWindowLong(hWnd, GWL_EXSTYLE));
	wndW = rc.right - rc.left;
	wndH = rc.bottom - rc.top;
	GetWindowRect(_hPWnd, &rc);
	y = rc.top;
	if (y + (int)wndH > GetSystemMetrics(SM_CYSCREEN))
	{
		y = GetSystemMetrics(SM_CYSCREEN) - wndH ;
		if (y<0) y=0;
	}
	MoveWindow(hWnd, rc.left, y, wndW, wndH, TRUE);
}


static void
update_window(
	HWND			hWnd)
{
	HDC				hDC;
	HFONT			hFont;
	HFONT			hFontOld;
	PAINTSTRUCT		ps;
	Uint32			i;

	/* 描画準備 */
	hDC      = BeginPaint(hWnd, &ps);
	hFont    = (HFONT)GetStockObject(OEM_FIXED_FONT);
	hFontOld = (HFONT)SelectObject(hDC, hFont);
	SetBkColor(hDC, RGB(0,0,0));
	SetTextColor(hDC, RGB(224, 224, 224));

	/* 文字の背景を塗りつぶす */
	SetBkMode(hDC, OPAQUE);

	for (i=0; i<_Line; i++)
	{
		TextOut(hDC, 0, i*_FontHeight, _pText[i], strlen(_pText[i]));
	}

	/* 終了処理 */
	EndPaint(hWnd, &ps);
	SelectObject(hDC, hFontOld);
	DeleteObject(hFont);
	ReleaseDC(hWnd, hDC);
}


static void
add_text(
	const char*		pText, ...)
{
	Uint32		i;
	va_list		ap;
	char*		p;

	va_start(ap, pText);
	vsprintf(_pText[_Line++], pText, ap);
	va_end(ap);

	// scroll a line
	if (_Line == KEY_N_LINES)
	{
		p = _pText[0];
		for (i = 1; i < KEY_N_LINES; ++i)
		{
			_pText[i-1] = _pText[i];
		}
		_pText[KEY_N_LINES-1] = p;
		*p = '\0';

		--_Line;
	}

	InvalidateRect(_hWnd, NULL, FALSE); //Kitao更新
	UpdateWindow(_hWnd);
}


//DirectInput対応ジョイスティックの入力状況を更新する。
static void
joypad_update_state()
{
	int		i, j;
	int		n;
	HRESULT hResult;

	//DirectX対応ジョイスティックの入力状況を更新
	j = 0;
	for (i = 0; i < _nJoySticks; i++)
	{
		do {
			n = _OrderNum[APP_GetPadOrder()][j++];
		} while ((n > _nJoySticks)&&(j < 5));
		n--;

		// ポーリングを行なう
		hResult = _pDIDJoy[n]->Poll();
		if (hResult != DI_OK) //失敗したときはアクセス権を取り直してやり直す
		{
			hResult = _pDIDJoy[n]->Acquire();
			if (hResult == DI_OK)
				hResult = _pDIDJoy[n]->Poll();
		}

		// ジョイスティックの状態を読む
		if (hResult == DI_OK)
			_pDIDJoy[n]->GetDeviceState(sizeof(DIJOYSTATE2), &_Joystick[i].joyState);

		// ボタンの状態を更新する 。Kitao更新。16個のボタン，ハットスイッチ，Ｚ軸トリガに対応。v2.81
		_Joystick[i].buttonState = 0;
		if (_Joystick[i].joyState.rgbButtons[0] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON1;
		if (_Joystick[i].joyState.rgbButtons[1] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON2;
		if (_Joystick[i].joyState.rgbButtons[2] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON3;
		if (_Joystick[i].joyState.rgbButtons[3] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON4;
		if (_Joystick[i].joyState.rgbButtons[4] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON5;
		if (_Joystick[i].joyState.rgbButtons[5] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON6;
		if (_Joystick[i].joyState.rgbButtons[6] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON7;
		if (_Joystick[i].joyState.rgbButtons[7] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON8;
		if (_Joystick[i].joyState.rgbButtons[8] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON9;
		if (_Joystick[i].joyState.rgbButtons[9] & 0x80)		_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON10;
		if (_Joystick[i].joyState.rgbButtons[10] & 0x80)	_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON11;
		if (_Joystick[i].joyState.rgbButtons[11] & 0x80)	_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON12;
		if (_Joystick[i].joyState.rgbButtons[12] & 0x80)	_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON13;
		if (_Joystick[i].joyState.rgbButtons[13] & 0x80)	_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON14;
		if (_Joystick[i].joyState.rgbButtons[14] & 0x80)	_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON15;
		if (_Joystick[i].joyState.rgbButtons[15] & 0x80)	_Joystick[i].buttonState |= INPUT_JOYSTICK_BUTTON16;
		if (_Joystick[i].joyState.lY < -250)	_Joystick[i].buttonState |= INPUT_JOYSTICK_UP; //設定時は安易にスティックが傾いて誤動作してしまわないように-250まで遊びを許す。
		if (_Joystick[i].joyState.lX > +250)	_Joystick[i].buttonState |= INPUT_JOYSTICK_RIGHT;
		if (_Joystick[i].joyState.lY > +250)	_Joystick[i].buttonState |= INPUT_JOYSTICK_DOWN;
		if (_Joystick[i].joyState.lX < -250)	_Joystick[i].buttonState |= INPUT_JOYSTICK_LEFT;
		//Kitao更新。ハットスイッチ（アナログ対応コントローラの十字ボタンでよく使われる）にも対応。
		if (_Joystick[i].joyState.rgdwPOV[0] == 0)				_Joystick[i].buttonState |= INPUT_JOYSTICK_POVUP;
		if (_Joystick[i].joyState.rgdwPOV[0] == 45*DI_DEGREES)
		{
			_Joystick[i].buttonState |= INPUT_JOYSTICK_POVUP;
			_Joystick[i].buttonState |= INPUT_JOYSTICK_POVRIGHT;
		}
		if (_Joystick[i].joyState.rgdwPOV[0] == 90*DI_DEGREES) _Joystick[i].buttonState |= INPUT_JOYSTICK_POVRIGHT;
		if (_Joystick[i].joyState.rgdwPOV[0] == 135*DI_DEGREES)
		{
			_Joystick[i].buttonState |= INPUT_JOYSTICK_POVRIGHT;
			_Joystick[i].buttonState |= INPUT_JOYSTICK_POVDOWN;
		}
		if (_Joystick[i].joyState.rgdwPOV[0] == 180*DI_DEGREES) _Joystick[i].buttonState |= INPUT_JOYSTICK_POVDOWN;
		if (_Joystick[i].joyState.rgdwPOV[0] == 225*DI_DEGREES)
		{
			_Joystick[i].buttonState |= INPUT_JOYSTICK_POVDOWN;
			_Joystick[i].buttonState |= INPUT_JOYSTICK_POVLEFT;
		}
		if (_Joystick[i].joyState.rgdwPOV[0] == 270*DI_DEGREES)	_Joystick[i].buttonState |= INPUT_JOYSTICK_POVLEFT;
		if (_Joystick[i].joyState.rgdwPOV[0] == 315*DI_DEGREES)
		{
			_Joystick[i].buttonState |= INPUT_JOYSTICK_POVLEFT;
			_Joystick[i].buttonState |= INPUT_JOYSTICK_POVUP;
		}
		//Kitao更新。Ｚ軸トリガ（アナログ対応コントローラのL2,R2ボタンでよく使われる）にも対応。v2.81
		if (_Joystick[i].joyState.lZ > +50) _Joystick[i].buttonState |= INPUT_JOYSTICK_L2ZTRIGGER; //設定時は安易にスティックが傾いて誤動作してしまわないように+50まで遊びを許す。
		if (_Joystick[i].joyState.lZ < -50) _Joystick[i].buttonState |= INPUT_JOYSTICK_R2ZTRIGGER;
	}
}

//Kitao追加。XInput対応ジョイスティックの入力状況を更新する。v2.88
static void
joypadx_update_state()
{
	int				i, j;
	int				n;
	DWORD			dwResult;
	XINPUT_STATE	state;
	
	//InputX対応ジョイスティックの入力状況を更新
	j = 0;
	for (i = 0; i < _nJoySticksX; i++)
	{
		do {
			n = _OrderNum[APP_GetPadOrder()][j++];
		} while ((n > _nJoySticksX)&&(j < 5));
		n--;

		ZeroMemory(&state, sizeof(XINPUT_STATE));
		dwResult = XInputGetState(_XJoyNumber[n], &state);

//char s[100];
//sprintf(s, "nJoySticks = %d, nJoySticksX = %d, n = %d, dwResult = %X", _nJoySticks, _nJoySticksX, n, dwResult);
//MessageBox(WINMAIN_GetHwnd(), s, "Test", MB_OK);//Test

		if (dwResult == ERROR_SUCCESS) //ジョイパッドがつながっていた
		{
			// ボタンの状態を更新する (とりあえず 12 個のボタンに対応) Kitao更新。16個のボタンに対応
			_JoystickX[i].buttonState = 0;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_A)				_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON1;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_B)				_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON2;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_X)				_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON3;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y)				_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON4;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_START)			_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON5;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK)			_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON6;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)		_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON7;//左アナログスティック押し込み
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB)		_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON8;//右アナログスティック押し込み
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER)	_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON9;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)	_JoystickX[i].buttonState |= INPUT_JOYSTICK_BUTTON10;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)			_JoystickX[i].buttonState |= INPUT_JOYSTICK_UP;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)		_JoystickX[i].buttonState |= INPUT_JOYSTICK_RIGHT;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)		_JoystickX[i].buttonState |= INPUT_JOYSTICK_DOWN;
			if(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)		_JoystickX[i].buttonState |= INPUT_JOYSTICK_LEFT;
		}
	}
}


//Kitao追加。キーボードの状態を読み取って更新する。
static void
keyborad_update_state()
{
	HRESULT hResult;

	// キーボードの状態を読む
	hResult =_pDIDKey->GetDeviceState(256, &_DIKeys);

	// 読み取りに失敗した時の処理
	if (hResult != DI_OK) //失敗したときはアクセス権を取り直してやり直す
	{
		_pDIDKey->Acquire();
		_pDIDKey->GetDeviceState(256, &_DIKeys);
	}
}


static BOOL
pump_message()
{
	MSG			msg;

	if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	if (_hInstance == NULL)
		return FALSE;

	return TRUE;
}


static BOOL
get_button(
	Sint16*		pButton)
{
	Sint16		q,i; //Kitao追加
	Sint16		theJoystick = -1; //Kitao追加
	Sint16		theButton = -1;

	while (theButton < 0)
	{
		Sleep(1);

		if (!pump_message())
			return FALSE;

		if (_SetOk == -1) //Escキーが押されたかウィンドウが閉じられた場合、キャンセル。v3.02
			return FALSE;

		joypadx_update_state(); //XInput対応ジョイスティックの状態を読む。v2.88追加。DInputと比べて反応が早ければこちらが優先される。古いdinput.lib(October 2004)でビルドした場合は、DInputのほうが反応が早い場合もある。
		joypad_update_state(); //DInput対応ジョイスティックの状態を読む。

		//XInput対応のジョイスティック。v2.88追加。基本的にこちらのほうが反応が早いのでDirectInputよりも先に参照する。v2.89
		for (q=0; q<=_nJoySticksX-1; q++) //最大４本のジョイスティック
			for (i=0; i<=INPUT_NUM_BUTTON-1; i++)
				if (_JoystickX[q].buttonState & button[i]) //ボタンが押されていたら
				{
					//押されたボタンが離されるまで待つ
					while (_JoystickX[q].buttonState & button[i])
					{
						Sleep(1);
						if (!pump_message())
							return FALSE;
						joypadx_update_state();
					}
					
					theJoystick = q+1; //Kitao追加。どのジョイスティックのボタンか
					theButton = i;
					if (theButton <= 7) //十字キー
						*pButton = (700 + theJoystick*100) + theButton;
					else //ボタン1〜10
						*pButton = (700 + theJoystick*100 +50) + (theButton -8);
					
					return TRUE;
				}

		//DirectInput対応のジョイスティック
		for (q=0; q<=_nJoySticks-1; q++) //Kitao追加。つながれている全てのジョイスティックのボタンを受け付けるようにした。
			for (i=0; i<=INPUT_NUM_BUTTON-1; i++)
				if (_Joystick[q].buttonState & button[i]) //ボタンが押されていたら
				{
					//押されたボタンが離されるまで待つ
					while (_Joystick[q].buttonState & button[i])
					{
						Sleep(1);
						if (!pump_message())
							return FALSE;
						joypad_update_state();
					}
					
					theJoystick = q+1; //Kitao追加。どのジョイスティックのボタンか
					theButton = i;
					if (theButton <= 7) //十字キーorハットスイッチ
						*pButton = (200 + theJoystick*100) + theButton;
					else if (theButton <= 23) //ボタン1〜16
						*pButton = (200 + theJoystick*100 +50) + (theButton -8);
					else //Ｚ軸トリガ
						*pButton = (200 + theJoystick*100) + (theButton -16);
					
					return TRUE;
				}

		//Kitao追加。キーボード
		keyborad_update_state(); //キーボードの状態を読む
		for (i=0; i<=255; i++)
			if ((_DIKeys[i] & 0x80)&&(i != DIK_ESCAPE)&&(i != DIK_CAPITAL)&&(i != DIK_KANJI)&& //何かキーが押されていたら（Esc＆Caps＆漢字(半角/全角)キー以外）。v0.83更新(Kiさん修正ありがとうございます)
				(i != DIK_KANA)) //「かなキー」も無効に。(押してしまうとキーを受け付けなくなる)。v1.33追加
			{
				//押されたボタンが離されるまで待つ
				while (_DIKeys[i] & 0x80)
				{
					Sleep(1);
					if (!pump_message())
						return FALSE;
					keyborad_update_state();
				}
				
				if (i == DIK_F1) //F1キーなら設定をクリア
					i = -1;
				*pButton = i;
				
				return TRUE;
			}
	}
	return FALSE;
}


//Kitao更新
static BOOL
configure(
	Sint32		mode,  //Kitao追加。0…通常のボタン設定(十字キーを除く)。1…連射専用ボタンの設定。2…早回し用ボタンの設定。3…ステートセーブ用ボタンの設定。4…ステートロード用ボタンの設定。5…スクリーンショット用ボタンの設定。
					   //		    6…ファンクション用ボタンの設定。7…ファンクションボタン時のステートセーブ＆ロード用ボタンの設定。8…ポーズ用ボタンの設定。9…スプライトとBGの非表示・表示切替ボタンの設定。
					   //		    10…ROMイメージを開くボタンの設定。11…CDインストールのゲーム（CUE）を開くボタンの設定。12…十字キーの設定。v2.94更新
	Sint32		padID, //Kitao更新。joyID→padID(1〜5)へ。PCエンジンのパッドナンバーで管理するようにした。
	Sint32		padButtonN, //v2.94追加。2…2ボタンパッド。3…3ボタンパッド。6…6ボタンパッド。
	PCEPAD*		pPad)
{
	Sint16		up        = -1;
	Sint16		right     = -1;
	Sint16		down      = -1;
	Sint16		left      = -1;
	Sint16		select    = -1;
	Sint16		run       = -1;
	Sint16		buttonI   = -1;
	Sint16		buttonII  = -1;
	Sint16		buttonIII = -1;
	Sint16		buttonIV  = -1;
	Sint16		buttonV   = -1;
	Sint16		buttonVI  = -1;

	add_text("\n");

	switch (mode)
	{
		case 0:
		case 1:	//通常の設定(十字キー部分は除く)or連射専用ボタンの設定
			if (padButtonN == 6) //Kitao追加
				add_text("Setting of Player#%ld for \"6 Button Pad\": ([Esc]=Abort [F1]=Clear)", padID);
			else if (padButtonN == 3) //Kitao追加
				add_text("Setting of Player#%ld for \"3 Button Pad\": ([Esc]=Abort [F1]=Clear)", padID);
			else
				add_text("Setting of Player#%ld for \"2 Button Pad\": ([Esc]=Abort [F1]=Clear)", padID);
			if (mode == 1)
			{	//連射ボタンの設定時。ボタン５,６に連射専用ボタンを設定。
				up		= pPad->buttonU;
				right	= pPad->buttonR;
				down	= pPad->buttonD;
				left	= pPad->buttonL;
				select	= pPad->buttonSel;
				run		= pPad->buttonRun;
				buttonI	= pPad->button1;
				buttonII= pPad->button2;
				buttonIII=pPad->button3;
				buttonIV= pPad->button4;
				add_text("Press a button for \"turbo button I\"..."); if (!get_button(&buttonV)) return FALSE;
				add_text("Press a button for \"turbo button II\"...");  if (!get_button(&buttonVI))  return FALSE;
			}
			else 
			{	//通常時
				up		= pPad->buttonU;
				right	= pPad->buttonR;
				down	= pPad->buttonD;
				left	= pPad->buttonL;
				if (padButtonN == 6) //Kitao追加
				{
					add_text("Press a button for \"button I\"...");   if (!get_button(&buttonI))   return FALSE;
					add_text("Press a button for \"button II\"...");  if (!get_button(&buttonII))  return FALSE;
					add_text("Press a button for \"button III\"..."); if (!get_button(&buttonIII)) return FALSE;
					add_text("Press a button for \"button IV\"...");  if (!get_button(&buttonIV))  return FALSE;
					add_text("Press a button for \"button V\"...");   if (!get_button(&buttonV))   return FALSE;
					add_text("Press a button for \"button VI\"...");  if (!get_button(&buttonVI))  return FALSE;
				}
				else if (padButtonN == 3) //Kitao追加
				{
					add_text("Press a button for \"button I\"...");   if (!get_button(&buttonI))   return FALSE;
					add_text("Press a button for \"button II\"...");  if (!get_button(&buttonII))  return FALSE;
					if (JOYPAD_GetChange3to12()) //v2.87追加
					{
						add_text("Press a button for \"button IIIr[=I+II]\"..."); if (!get_button(&buttonIII)) return FALSE;
						add_text("Press a button for \"button IIIs[=RUN]\"...");  if (!get_button(&buttonIV)) return FALSE;
					}
					else
					{
						add_text("Press a button for \"button IIIr[=RUN]\"..."); if (!get_button(&buttonIII)) return FALSE;
						add_text("Press a button for \"button IIIs[=SELECT]\"...");  if (!get_button(&buttonIV)) return FALSE;
					}
				}
				else //(padButtonN == 2)
				{
					add_text("Press a button for \"button I\"...");   if (!get_button(&buttonI))   return FALSE;
					add_text("Press a button for \"button II\"...");  if (!get_button(&buttonII))  return FALSE;
				}
				add_text("Press a button for \"SELECT\"...");     if (!get_button(&select))    return FALSE;
				add_text("Press a button for \"RUN\"...");        if (!get_button(&run))       return FALSE;
			}
			break;
		case 2: //早回し用ボタンの設定
			add_text("Setting of \"Video Speed Up Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Video Speed Up Button\"...");   if (!get_button(&buttonI)) return FALSE;
			break;
		case 3: //ステートセーブ用ボタンの設定
			add_text("Setting of \"Save State Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Save State Button\"...");   if (!get_button(&buttonI)) return FALSE;
			break;
		case 4: //ステートロード用ボタンの設定
			add_text("Setting of \"Load State Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Load State Button\"...");   if (!get_button(&buttonI)) return FALSE;
			break;
		case 5: //スクリーンショット用ボタンの設定
			add_text("Setting of \"Screenshot Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Screenshot Button\"...");   if (!get_button(&buttonI)) return FALSE;
			break;
		case 6: //ファンクション用ボタンの設定
			add_text("Setting of \"Function Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Function Button\"...");   if (!get_button(&buttonI)) return FALSE;
			break;
		case 7: //ファンクションボタン時のセーブ＆ロード用ボタンの設定
			add_text("Setting of \"Function SaveState Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Function SaveState Button\"...");   if (!get_button(&buttonI)) return FALSE;
			add_text("Setting of \"Function LoadState Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Function LoadState Button\"...");   if (!get_button(&buttonII)) return FALSE;
			break;
		case 8: //ポーズ用ボタンの設定
			add_text("Setting of \"Pause Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Pause Button\"...");   if (!get_button(&buttonI)) return FALSE;
			break;
		case 9: //スプライトとBGの非表示・表示切替用ボタンの設定
			add_text("Setting of \"Sprite Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Sprite Button\"...");   if (!get_button(&buttonI)) return FALSE;
			add_text("Setting of \"BG Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"BG Button\"...");   if (!get_button(&buttonII)) return FALSE;
			add_text("Setting of \"Sprite2(for SG) Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Sprite2(for SG) Button\"...");   if (!get_button(&buttonIII)) return FALSE;
			add_text("Setting of \"BG2(for SG) Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"BG2(for SG) Button\"...");   if (!get_button(&buttonIV)) return FALSE;
			break;
		case 10: //ROMファイルを開くボタンの設定
			add_text("Setting of \"Rom image Open Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Rom image Open Button\"...");   if (!get_button(&buttonI)) return FALSE;
			break;
		case 11: //CDインストールされたゲーム（CUE）を開くボタンの設定
			add_text("Setting of \"Play FullInst CD-Game Button\": ([Esc]=Abort [F1]=Clear)");
			add_text("Press a button for \"Play FullInstalled CD-Game Button\"...");   if (!get_button(&buttonI)) return FALSE;
			break;
		case 12: //十字キーの設定。v2.94から、通常のパッド設定の十字キー部分を独立。2,3,6ボタンとも十字キー部分は共通設定にした。
			add_text("Setting of Player#%ld for \"2-6 Button Pad\": ([Esc]=Abort [F1]=Clear)", padID);
			add_text("Press a button for \"UP\"...");         if (!get_button(&up))        return FALSE;
			add_text("Press a button for \"RIGHT\"...");      if (!get_button(&right))     return FALSE;
			add_text("Press a button for \"DOWN\"...");       if (!get_button(&down))      return FALSE;
			add_text("Press a button for \"LEFT\"...");       if (!get_button(&left))      return FALSE;
			break;
	}

	//Kitao更新
	pPad->buttonU	= up;		//上キーの設定。※アスキーコード(0〜255)。DirectInputジョイパッド１(300〜399。100ボタンまで対応)。DirectInputジョイパッド２(400〜499)。
	pPad->buttonR	= right;	//右キーの設定    以下DirectInputジョイパッド５本まで同様。XInputジョイパッド１(800〜899。100ボタンまで対応)。XInputジョイパッド２(900〜999)。
	pPad->buttonD	= down;		//下キーの設定    以下XInputジョイパッド４本まで同様。
	pPad->buttonL	= left;		//左キーの設定
	pPad->buttonSel	= select;	//Selectボタンの設定
	pPad->buttonRun	= run;		//Runボタンの設定
	pPad->button1	= buttonI;	//Iボタンの設定
	pPad->button2	= buttonII;	//IIボタンの設定
	pPad->button3	= buttonIII;//IIIボタンの設定
	pPad->button4	= buttonIV;	//IVボタンの設定
	pPad->button5	= buttonV;	//Vボタンの設定
	pPad->button6	= buttonVI;	//VIボタンの設定

	return TRUE;
}


//Kitao追加。JoyStickデバイスの軸を取得するコールバック関数
static BOOL
CALLBACK
DIEnumAxisCallback(
	LPCDIDEVICEOBJECTINSTANCE	lpddi,
	LPVOID						pvRef)
{
	DIPROPRANGE				diDR;
	DIPROPDWORD				diDD;

	//見つかった軸の設定をする。
	ZeroMemory(&diDR, sizeof(diDR));
	diDR.diph.dwSize = sizeof(diDR);
	diDR.diph.dwHeaderSize = sizeof(diDR.diph);
	diDR.diph.dwHow = DIPH_BYID;
	diDR.diph.dwObj = lpddi->dwType;
	diDR.lMin = -1000;
	diDR.lMax = +1000;
	_pDIDJoy[_nJoySticks]->SetProperty(DIPROP_RANGE, &diDR.diph);

	//絶対軸に設定。
	ZeroMemory(&diDD, sizeof(diDD));
	diDD.diph.dwSize = sizeof(diDD);
	diDD.diph.dwHeaderSize = sizeof(diDD.diph);
	diDD.diph.dwHow = DIPH_DEVICE;
	diDD.dwData = DIPROPAXISMODE_ABS;
	_pDIDJoy[_nJoySticks]->SetProperty(DIPROP_AXISMODE, &diDD.diph);

	//デッドゾーンを0に設定。デジタルパッドでも有効。DirectX7以降でもこれでだいぶ反応が良くなる。Kitao追加
	ZeroMemory(&diDD, sizeof(diDD));
	diDD.diph.dwSize = sizeof(diDD);
	diDD.diph.dwHeaderSize = sizeof(diDD.diph);
	diDD.diph.dwHow = DIPH_DEVICE;
	diDD.dwData = 0;
	_pDIDJoy[_nJoySticks]->SetProperty(DIPROP_DEADZONE, &diDD.diph);

	//飽和ゾーンを最大に。Kitao追加
	ZeroMemory(&diDD, sizeof(diDD));
	diDD.diph.dwSize = sizeof(diDD);
	diDD.diph.dwHeaderSize = sizeof(diDD.diph);
	diDD.diph.dwHow = DIPH_DEVICE;
	diDD.dwData = 10000;
	_pDIDJoy[_nJoySticks]->SetProperty(DIPROP_SATURATION, &diDD.diph);

	return DIENUM_CONTINUE; //次の軸を探す
}

static BOOL
CALLBACK
DIEnumDevicesCallback(
	LPCDIDEVICEINSTANCE	lpddi,
	LPVOID				pvRef)
{
	HRESULT					hResult;
	LPDIRECTINPUTDEVICE		pDIDJoy; //Kitao追加
	DIPROPDWORD				diDD;

	//見つかったジョイスティックデバイスを作成する
	hResult = _pDI->CreateDevice(lpddi->guidInstance, &pDIDJoy, NULL);
	if (hResult != DI_OK)
		return DIENUM_CONTINUE; //失敗したら中止して次を探す

	//Kitao追加。ここでDirectInputDevice2に拡張しておくようにした（高速化）。
	pDIDJoy->QueryInterface(IID_IDirectInputDevice2, (LPVOID*)&_pDIDJoy[_nJoySticks]);
	pDIDJoy->Release();

	//データフォーマットを設定する
	_pDIDJoy[_nJoySticks]->SetDataFormat(&c_dfDIJoystick2);

	//バッファを最小に。反応が良くなる。Kitao追加
	ZeroMemory(&diDD, sizeof(diDD));
	diDD.diph.dwSize = sizeof(diDD);
	diDD.diph.dwHeaderSize = sizeof(diDD.diph);
	diDD.diph.dwHow = DIPH_DEVICE;
	diDD.dwData = 1;
	_pDIDJoy[_nJoySticks]->SetProperty(DIPROP_BUFFERSIZE, &diDD.diph);

	//協調レベルを指定する  Kitao更新。協調設定をDISCL_NONEXCLUSIVEに＆バックグラウンドでも操作可能にした。
	_pDIDJoy[_nJoySticks]->SetCooperativeLevel(_hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);

	//JoyStickデバイスの軸を列挙する。Kitao追加
	_pDIDJoy[_nJoySticks]->EnumObjects(DIEnumAxisCallback, NULL, DIDFT_AXIS);

	_nJoySticks++;

	//コントローラが5つ検出されたら終了する
	if (_nJoySticks == N_MAXJOYSTICK)
		return DIENUM_STOP; //列挙を終了させる
	else
		return DIENUM_CONTINUE; //次のデバイスを探す
}

//Kitao追加。ジョイスティック用の変数を初期化して設定する。v3.01更新
static void
initJoysticks()
{
	int				i;
	XINPUT_STATE	state;

	//Windowsジョイスティック用の変数を初期化
	_nJoySticks = 0;
	ZeroMemory(_Joystick, sizeof(_Joystick));
	_nJoySticksX = 0;
	ZeroMemory(_JoystickX, sizeof(_JoystickX));
	// DirectInputインターフェースを取得する
	DirectInputCreate(WINMAIN_GetHInstance(), DIRECTINPUT_VERSION, &_pDI, NULL);
	//キーボードデバイスを取得する
	_pDI->CreateDevice(GUID_SysKeyboard, &_pDIDKey, NULL);
	//データフォーマットを設定する
	_pDIDKey->SetDataFormat(&c_dfDIKeyboard);
	//協調レベルを指定する
	_pDIDKey->SetCooperativeLevel(_hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
	//キーボードのアクセス権を得ておく。
	_pDIDKey->Acquire();
	//JoyStickデバイスを列挙する
	_pDI->EnumDevices(DIDEVTYPE_JOYSTICK, DIEnumDevicesCallback, NULL, DIEDFL_ATTACHEDONLY);
	//最初にアクセス権を得ておく。
	for (i = 0; i < _nJoySticks; i++)
		_pDIDJoy[i]->Acquire();
	//XInput対応ジョイパッドがつながっている本数をチェック。つながっていないパッドを参照しようとするとめちゃめちゃ重いため、事前にチェックする必要がある。v2.89
	for (i = 0; i < 4; i++) //XInputは最大４つまで。v2.89
	{
		ZeroMemory(&state, sizeof(XINPUT_STATE));
		if (XInputGetState(i, &state) == ERROR_SUCCESS) //ジョイパッドがつながっていた
		{
			_XJoyNumber[_nJoySticksX] = i; //XInputのパッドを繋ぎ変えた時に0番ではなく1番や2番に割り当てられる事もあるので、何番につながっているのかの参照が必要。v3.01修正
			_nJoySticksX++;
		}
	}
}


static LRESULT CALLBACK
padconfig_wnd_proc(
	HWND		hWnd,
	UINT		uMsg,
	WPARAM		wParam,
	LPARAM		lParam)
{
	int		i;

	switch(uMsg)
	{
	case WM_CREATE:
		EnableWindow(_hPWnd, FALSE);//Kitao追加。親ウインドウを無効化してモーダルに。
		_FontWidth  = get_font_width(hWnd);
		_FontHeight = get_font_height(hWnd);
		set_window_size(hWnd);
		break;

	case WM_PAINT:
		update_window(hWnd);
		_bWindowCreated = TRUE; //v0.74追加
		break;

	case WM_ACTIVATE: //Kitao追加
		if (wParam != 0) //アクティブになるとき
		{
			//DirectInputのアクセス権利を得る
			//キーボード
			if (_pDIDKey != NULL)
				_pDIDKey->Acquire();
			//ジョイスティック
			for (i = 0; i < _nJoySticks; ++i)
				if (_pDIDJoy[i] != NULL)
					_pDIDJoy[i]->Acquire();
		}
		break;

	case WM_KEYDOWN:
		if (wParam == VK_ESCAPE)
		{
			_SetOk = -1; //キャンセルした印
			return 0;
		}
		break;

	case WM_SYSKEYDOWN:
		if (wParam == VK_MENU)
			return 1; //Altキーを押した際のメニュー表示処理をカット。v2.87
		break;

	case WM_CLOSE:
		if (_SetOk == 0) _SetOk = -1; //キャンセルした印
		return 0;

	case WM_DEVICECHANGE: //USB等の機器の繋ぎ変えがあった場合。v3.01
		initJoysticks(); //ジョイスティックの設定を初期化する
		return 0;
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


//Kitao更新。キーボードにも対応。ジョイスティックも好きなジョイスティックを好きな番号で使えるようにした。
static void
padconfig_main()
{
	WNDCLASS		wc;
	HWND			hWnd;
	BOOL			bOk;
	RECT			rc;

	ZeroMemory(&wc, sizeof(wc));
	wc.style		 = 0;
	wc.lpfnWndProc	 = padconfig_wnd_proc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = _hInstance;
	wc.hIcon		 = LoadIcon(_hInstance, MAKEINTRESOURCE(IDI_ICON)); //アイコンを読み込み。v2.00更新
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.lpszMenuName	 = "";
	wc.lpszClassName = _pCaption;

	if (RegisterClass(&wc) == 0) return;

	_bWindowCreated = FALSE; //Kitao追加

	hWnd = CreateWindow(
		_pCaption,
		_pCaption,
		WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		0,
		0,
		_hPWnd, //v2.77
		NULL,
		_hInstance,
		NULL
	);

	if (hWnd == NULL) return;

	_hWnd	   = hWnd;

	ShowWindow(hWnd, SW_SHOWNORMAL);
	UpdateWindow(hWnd);
	GetWindowRect(hWnd, &rc);
	SetWindowPos(hWnd, HWND_TOP, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_FRAMECHANGED); //このウィンドウを「常に手前に表示」
	while (_bWindowCreated == FALSE) //ウィンドウの生成完了まで待つ。v0.74
		Sleep(1);
	ImmAssociateContext(hWnd, 0); //Kitao追加。IMEを無効にする。v0.79

	initJoysticks(); //Kitao追加

	//入力設定
	bOk = configure(_Mode, _PadID, _PadButtonN, _pPad);
	if (bOk)
		_SetOk = 1; //設定完了の印
	else
		_SetOk = -1; //キャンセル
}


//Kitao更新。複数人プレイのときもキーボードのボタンを使えるようにした。
BOOL
PADCONFIG_Init(
	HWND		hWnd,
	HINSTANCE	hInstance,
	Sint32	 	mode, //Kitao追加。0…通常のボタン設定(十字キーを除く)。1…連射専用ボタンの設定。2…早回し用ボタンの設定。3…ステートセーブ用ボタンの設定。4…ステートロード用ボタンの設定。5…スクリーンショット用ボタンの設定。
					  //		   6…ファンクション用ボタンの設定。7…ファンクションボタン時のステートセーブ＆ロード用ボタンの設定。8…ポーズ用ボタンの設定。9…スプライトとBGの非表示・表示切替ボタンの設定。
					  //		   10…ROMイメージを開くボタンの設定。11…CDインストールのゲーム（CUE）を開くボタンの設定。12…十字キーの設定。v2.94更新
	Sint32		padID,
	Sint32		padButtonN,
	PCEPAD* 	pPad,
	Sint32*		setOk)
{
	int				i;

	if (_hInstance != NULL)
		PADCONFIG_Deinit();

	INPUT_Init(); //繋いでいるジョイパッドの状態を更新。v2.95

	_hPWnd = hWnd; //親ウィンドウのハンドル。v2.77
	_hInstance = hInstance;
	_Line      = 0;

	_Mode	= mode;
	_PadID	= padID;
	_PadButtonN	= padButtonN;
	_pPad	= pPad;
	_pSetOk	= setOk;
	_SetOk	= 0;

	for (i=0; i<KEY_N_LINES; i++)
		_pText[i] = _Text[i];

	padconfig_main();

	PADCONFIG_Deinit();
	return (_SetOk == 1);
}


void
PADCONFIG_Deinit()
{
	int	i;

	if (_hInstance != NULL)
	{
		if (_pDIDKey != NULL)
		{
			_pDIDKey->Unacquire();
			_pDIDKey->Release();
			_pDIDKey = NULL;
		}
		for (i = 0; i < N_MAXJOYSTICK; ++i)
		{
			if (_pDIDJoy[i] != NULL)
			{
				_pDIDJoy[i]->Unacquire();
				_pDIDJoy[i]->Release();
				_pDIDJoy[i] = NULL;
			}
		}
		if (_pDI != NULL)
		{
			_pDI->Release();
			_pDI = NULL;
		}
		DestroyWindow(_hWnd);
		_hWnd = NULL;
		UnregisterClass(_pCaption, _hInstance);
		_hInstance = NULL;
		
		//メインウィンドウにフォーカスを戻し前面に。
		EnableWindow(_hPWnd, TRUE);
		SetForegroundWindow(_hPWnd);
		
		*_pSetOk = _SetOk; //戻り値を設定。この瞬間に親ウィンドウは動き出す。
	}
}
