// vbaCE.cpp 

#include "stdafx.h"
#include "resource.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <commctrl.h>
#include <commdlg.h>

#ifdef WIN32_PLATFORM_PSPC
#include "GX.h"
#endif

#include "CE.h"
#include "CEKey.h"
#include "system.h"
#include "gb/gb.h"
#include "ppp_stdio.h"

#define MAX_LOADSTRING 512

extern void soundSetQuality(int);
extern int systemQuality;

ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass);
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HWND CreateRpCommandBar(HWND hwnd);
void DoPaint(HWND hWnd);

HINSTANCE g_hInst;
HWND      g_hWnd;
HWND      g_hWndCB;  // menu window handle
HANDLE    GBA_Thread;
int CommandBarVis;
extern int emulating;
extern int statenumber;
extern int systemFrameSkip;
extern int soundQuality;
extern int soundBufferLen;
extern bool AutoLoadState;
extern bool systemSoundOn;
extern bool threadctrl;

int thread_running = FALSE;

#ifdef WIN32_PLATFORM_PSPC
GXKeyList g_gxkl;
#endif

extern char * OpenFileDlg(HWND hWnd, int flg);

LRESULT CALLBACK DLGKeySet(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DLGMisc  (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DLGSound (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DLGVideo (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPTSTR    lpCmdLine,
					int       nCmdShow)
{
	MSG msg;
	HACCEL hAccelTable;

	DEBUGLOG("\n\ndebug start\n");
	
	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow)) return FALSE;
/*
	if( *lpCmdLine ){
        start_gba();
	}
*/
    hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_VBADVANCECE);

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return msg.wParam;
}

// MyRegisterClass
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
	WNDCLASS	wc;

    wc.style			= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc		= (WNDPROC) WndProc;
    wc.cbClsExtra		= 0;
    wc.cbWndExtra		= 0;
    wc.hInstance		= hInstance;
    wc.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_VBADVANCECE));
    wc.hCursor			= 0;
    wc.hbrBackground	= (HBRUSH) GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName		= 0;
    wc.lpszClassName	= szWindowClass;

	return RegisterClass(&wc);
}



//  FUNCTION: InitInstance(HANDLE, int)
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND	hWnd = NULL;
	TCHAR	szTitle[MAX_LOADSTRING];			// The title bar text
	TCHAR	szWindowClass[MAX_LOADSTRING];		// The window class name
    RECT	rect;

DEBUGLOG("InitInstance Start\n");
	
	g_hInst = hInstance;		// Store instance handle in our global variable
	// Initialize global strings
	LoadString(hInstance, IDC_VBADVANCECE  , szWindowClass, MAX_LOADSTRING);
	LoadString(hInstance, IDS_APP_TITLE, szTitle,       MAX_LOADSTRING);

DEBUGLOG("InitInstance 1\n");

	//If it is already running, then focus on the window
	hWnd = FindWindow(szWindowClass, szTitle);	
	if (hWnd) 
	{
		SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01));    
		return 0;
	} 

DEBUGLOG("InitInstance 2\n");

	MyRegisterClass(hInstance, szWindowClass);

DEBUGLOG("InitInstance 3\n");

    GetClientRect(hWnd, &rect);
	
	hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
	if (!hWnd)
	{	
		return FALSE;
	}

DEBUGLOG("InitInstance 4\n");

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);


#ifdef WIN32_PLATFORM_PSPC
DEBUGLOG("InitInstance InitGXInput\n");
	if (!GXOpenInput()){
		MessageBox(hWnd, TEXT("GXOpenInputG["), szTitle, MB_ICONEXCLAMATION);
		return FALSE;
	}
	g_gxkl = GXGetDefaultKeys(GX_NORMALKEYS);
#endif



DEBUGLOG("InitInstance End\n");

	return TRUE;
}

void TrashInstance(void)
{
#ifdef WIN32_PLATFORM_PSPC
    GXCloseInput();
#endif
}
//------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	int x,y;//,num;
//	HMENU hMenu;
#ifdef WIN32_PLATFORM_PSPC
  	short vkKey;
#endif
	switch (message) 
	{
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 
			// Parse the menu selections:
			switch (wmId)
			{	
                case ID_MENU_RUN:
                    if( emulating > 0 ){
                        int wt_cnt = 600;
                        emulating = 0;
                        if( threadctrl )ResumeThread(GBA_Thread);
                        while(1){
                            if( emulating == -1 ) break;
                            if( !wt_cnt-- ) break;          // time out
                            Sleep(100);
                        }
                    }
                    start_gba();
					break;
				case ID_MENU_EXIT:
                    if( emulating > 0 ){
                        int wt_cnt = 600;
                        emulating = 0;
                        if( threadctrl )ResumeThread(GBA_Thread);
                        while(1){
                            if( emulating == -1 ) break;
                            if( !wt_cnt-- ) break;          // time out
                            Sleep(100);
                        }
                    }
                    SendMessage (hWnd, WM_CLOSE, 0, 0);
					break;
				case ID_MENU_MISC:
                    DialogBox(g_hInst, (LPCTSTR)IDD_MISC, hWnd, (DLGPROC)DLGMisc);
					break;
				case ID_MENU_VIDEO:
					DialogBox(g_hInst, (LPCTSTR)IDD_VIDEO, hWnd, (DLGPROC)DLGVideo);
					break;
				case ID_MENU_SOUND:
					DialogBox(g_hInst, (LPCTSTR)IDD_SOUND, hWnd, (DLGPROC)DLGSound);
					break;
				case ID_MENU_KEYSET:
					DialogBox(g_hInst, (LPCTSTR)IDD_KEYSET, hWnd, (DLGPROC)DLGKeySet);
					break;
                case ID_MENULOAD_SLOT1 :
                case ID_MENULOAD_SLOT2 :
                case ID_MENULOAD_SLOT3 :
                case ID_MENULOAD_SLOT4 :
                case ID_MENULOAD_SLOT5 :
                case ID_MENULOAD_SLOT6 :
                case ID_MENULOAD_SLOT7 :
                case ID_MENULOAD_SLOT8 :
                case ID_MENULOAD_SLOT9 :
                    statenumber = wmId - ID_MENULOAD_SLOT1 + 1;
                    loadSaveGame(statenumber);
//					emulating = 2;
                    break;
                case ID_MENUSAVE_SLOT1 :
                case ID_MENUSAVE_SLOT2 :
                case ID_MENUSAVE_SLOT3 :
                case ID_MENUSAVE_SLOT4 :
                case ID_MENUSAVE_SLOT5 :
                case ID_MENUSAVE_SLOT6 :
                case ID_MENUSAVE_SLOT7 :
                case ID_MENUSAVE_SLOT8 :
                case ID_MENUSAVE_SLOT9 :
                    statenumber = wmId - ID_MENUSAVE_SLOT1 + 1;
                    writeSaveGame(statenumber);
//					emulating = 3;
                    break;
                default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_CREATE:
			g_hWndCB = CreateRpCommandBar(hWnd);
			LoadOption();
            CEKey_Init("\\KeyBind.cfg");
/*
            if(!InitMachine(hWnd) ){
                DEBUGLOG("start_pce error end [InitMachine err]\n");
            };
*/
            break;
/*		case WM_PAINT:
			DoPaint(hWnd);
			break; 
*/
        case WM_CLOSE:
            TrashMachine();
            TrashInstance();
			CommandBar_Destroy(g_hWndCB);
			DestroyWindow(hWnd);
			break;
        case WM_DESTROY:
			PostQuitMessage(0);
			break;
		case WM_LBUTTONDOWN:
            if( emulating != 0 ){
			    x = LOWORD(lParam); 
			    y = HIWORD(lParam); 
			    CommandBarVis = CommandBar_Show( g_hWndCB, CommandBarVis );
                if( CommandBarVis ){
#ifdef WIN32_PLATFORM_PSPC
                    if( threadctrl )GXResume();
#endif
                    if( threadctrl )ResumeThread(GBA_Thread);
                }else{
                    if( threadctrl )SuspendThread(GBA_Thread);
#ifdef WIN32_PLATFORM_PSPC
                    if( threadctrl )GXSuspend();
#endif
                }
            }
            break;

#ifdef WIN32_PLATFORM_PSPC
		case WM_KEYDOWN:
			vkKey = (short)wParam;
            CEKey_Down(vkKey);
            break;
		case WM_KEYUP:
			vkKey = (short)wParam;
            CEKey_Up(vkKey);
            break;
#endif
        default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}


HWND CreateRpCommandBar(HWND hwnd)
{
	HWND hcb;
	BOOL res;
	hcb = CommandBar_Create( g_hInst, hwnd, 1 );
	res = CommandBar_InsertMenubar( hcb, g_hInst, IDM_MENU, 0 );	

	return hcb;
}
/*
void DoPaint(HWND hWnd)
{
	HDC hdc;
	PAINTSTRUCT ps;
	hdc = BeginPaint(hWnd, &ps);
	EndPaint(hWnd, &ps);
}
*/

// Mesage handler for the Misc Config box.
LRESULT CALLBACK DLGMisc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INITDIALOG:
			SetDlgItemInt( hDlg, IDC_FRAMESKIP , systemFrameSkip, FALSE );
			SendDlgItemMessage( hDlg, IDC_AUTOSTATE, BM_SETCHECK, AutoLoadState, 0 );   //  
			SendDlgItemMessage( hDlg, IDC_THREADCTRL, BM_SETCHECK, threadctrl,   0 );   //  
#ifdef WIN32_PLATFORM_PSPC
			EnableWindow( GetDlgItem(hDlg, IDC_THREADCTRL), FALSE);
#endif
			return TRUE;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK) {
				systemFrameSkip = GetDlgItemInt( hDlg, IDC_FRAMESKIP, NULL, FALSE );
                AutoLoadState   = SendDlgItemMessage( hDlg, IDC_AUTOSTATE,  BM_GETCHECK,0,0 )?true:false;
				threadctrl      = SendDlgItemMessage( hDlg, IDC_THREADCTRL, BM_GETCHECK,0,0 )?true:false;
				EndDialog(hDlg, LOWORD(wParam));
                SaveOption();
				return TRUE;
			} if( LOWORD(wParam) == IDCANCEL) {
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
			break;
	}
    return FALSE;
}
// Mesage handler for the Sound Config box.
LRESULT CALLBACK DLGSound(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    int qty;

    switch (message)
	{
		case WM_INITDIALOG:
            SendDlgItemMessage( hDlg, IDC_RADIO_SOUND_NO    , BM_SETCHECK, !systemSoundOn , 0 );
            SendDlgItemMessage( hDlg, IDC_RADIO_SOUND_11KHZ , BM_SETCHECK, (systemSoundOn && ( soundQuality == 1 )?true:false), 0 );
            SendDlgItemMessage( hDlg, IDC_RADIO_SOUND_22KHZ , BM_SETCHECK, (systemSoundOn && ( soundQuality == 2 )?true:false), 0 );
            SendDlgItemMessage( hDlg, IDC_RADIO_SOUND_44KHZ , BM_SETCHECK, (systemSoundOn && ( soundQuality == 4 )?true:false), 0 );
            return TRUE;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK) {
				systemSoundOn = ! SendDlgItemMessage( hDlg, IDC_RADIO_SOUND_NO, BM_GETCHECK,0,0 );
                if( systemSoundOn ){
                    if( SendDlgItemMessage( hDlg, IDC_RADIO_SOUND_11KHZ, BM_GETCHECK,0,0 ) )qty = 1;
                    if( SendDlgItemMessage( hDlg, IDC_RADIO_SOUND_22KHZ, BM_GETCHECK,0,0 ) )qty = 2;
                    if( SendDlgItemMessage( hDlg, IDC_RADIO_SOUND_44KHZ, BM_GETCHECK,0,0 ) )qty = 4;
                }
			    if(cartridgeType == 1) {
					gbSoundSetQuality(qty);
				}else{
					soundSetQuality(qty);
				}
				SaveOption();
                EndDialog(hDlg, LOWORD(wParam));
                return TRUE;
			} if( LOWORD(wParam) == IDCANCEL) {
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
			break;
	}
    return FALSE;
}

void SetScanlineList( HWND hDlg, BOOL flg )
{
	SendDlgItemMessage( hDlg, IDC_SCANLINE,  CB_RESETCONTENT, 0,0 );
    SendDlgItemMessage( hDlg, IDC_SCANLINE,  CB_ADDSTRING,0,(LPARAM)_T("x1 FULL") );
    SendDlgItemMessage( hDlg, IDC_SCANLINE,  CB_ADDSTRING,0,(LPARAM)_T("x1 1/2") );
    SendDlgItemMessage( hDlg, IDC_SCANLINE,  CB_ADDSTRING,0,(LPARAM)_T("x1 Interless") );
	if( flg ){
		SendDlgItemMessage( hDlg, IDC_SCANLINE,  CB_ADDSTRING,0,(LPARAM)_T("x2 FULL") );
		SendDlgItemMessage( hDlg, IDC_SCANLINE,  CB_ADDSTRING,0,(LPARAM)_T("x2 1/2") );
		SendDlgItemMessage( hDlg, IDC_SCANLINE,  CB_ADDSTRING,0,(LPARAM)_T("x2 Interless") );
	}
	SendDlgItemMessage( hDlg, IDC_SCANLINE,  CB_SETCURSEL,scanline,0);
}

LRESULT CALLBACK DLGVideo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{

    switch (message)
	{
		case WM_INITDIALOG:

            SendDlgItemMessage( hDlg, IDC_VIDEOMODE, CB_ADDSTRING,0,(LPARAM)_T("GDI,no frame buf") );
            SendDlgItemMessage( hDlg, IDC_VIDEOMODE, CB_ADDSTRING,0,(LPARAM)_T("GDI,use frame buf") );
#ifdef WIN32_PLATFORM_PSPC
            SendDlgItemMessage( hDlg, IDC_VIDEOMODE, CB_ADDSTRING,0,(LPARAM)_T("GAPI,no frame buf") );
            SendDlgItemMessage( hDlg, IDC_VIDEOMODE, CB_ADDSTRING,0,(LPARAM)_T("GAPI,use frame buf") );
#endif
            SendDlgItemMessage( hDlg, IDC_VIDEOMODE, CB_SETCURSEL,videomode,0);

			SetScanlineList( hDlg, (videomode==1)||(videomode==3) );

			SetDlgItemInt( hDlg, IDC_SCRPOSX , systemScrPosX, FALSE );
			SetDlgItemInt( hDlg, IDC_SCRPOSY , systemScrPosY, FALSE );

            if( emulating > 0 ){
                EnableWindow( GetDlgItem(hDlg, IDC_VIDEOMODE), FALSE);
                EnableWindow( GetDlgItem(hDlg, IDC_SCANLINE), FALSE);
            }else{
                EnableWindow( GetDlgItem(hDlg, IDC_VIDEOMODE), TRUE);
                EnableWindow( GetDlgItem(hDlg, IDC_SCANLINE), TRUE);
            }
            return TRUE;

		case WM_COMMAND:
			switch (LOWORD(wParam)){
			  case IDOK:
                videomode = SendDlgItemMessage( hDlg, IDC_VIDEOMODE, CB_GETCURSEL,0,0);
                scanline  = SendDlgItemMessage( hDlg, IDC_SCANLINE , CB_GETCURSEL,0,0);
				systemScrPosX = GetDlgItemInt( hDlg, IDC_SCRPOSX, NULL, FALSE );
				systemScrPosY = GetDlgItemInt( hDlg, IDC_SCRPOSY, NULL, FALSE );
                SaveOption();
                EndDialog(hDlg, LOWORD(wParam));
                return TRUE;
              case IDCANCEL:
				EndDialog(hDlg, LOWORD(wParam));
                return TRUE;
			  case IDC_VIDEOMODE:
				switch( HIWORD(wParam) ){
				  case CBN_SELCHANGE:
	                videomode = SendDlgItemMessage( hDlg, IDC_VIDEOMODE, CB_GETCURSEL,0,0);
					if( (videomode==0)||(videomode==2) ){     // nobuf
						scanline = 0;
						SetScanlineList( hDlg, false );
					}else{
						SetScanlineList( hDlg, true );
					}
				}
				return TRUE;
			  case IDC_SCANLINE:
				switch( HIWORD(wParam) ){
				  case CBN_SELCHANGE:
	                scanline  = SendDlgItemMessage( hDlg, IDC_SCANLINE , CB_GETCURSEL,0,0);
					if( (scanline >= 3)&&(scanline <=5 ) ){
						if(videomode == 0 ) videomode = 1;
						if(videomode == 2 ) videomode = 3;
			            SendDlgItemMessage( hDlg, IDC_VIDEOMODE, CB_SETCURSEL,videomode,0);
					}
				}
				return TRUE;
			}
			break;
	}
    return FALSE;
}

void CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime )
{ 
	TCHAR buf[128];
	TCHAR sbuf[16];	
	int i;

	buf[0]=0;

	for( i=1;i<255;i++ ){
		if( GetAsyncKeyState(i)&0x8000 ) {
			_itow(i,sbuf,16);
			wcscat( buf, sbuf );
		}
	}
	SetDlgItemText( hwnd,IDC_EDIT1,buf );
}

DWORD   g_pOriginalWndProc = NULL;
bool    g_bSetButtonMode   = false;
int     g_iSetButton;

#define SETBUTTON(a) \
    { \
        SetDlgItemInt(GetParent(hWnd), a, vkKey, false); \
    }


LRESULT CALLBACK ButtonProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_GETDLGCODE:
            return DLGC_WANTARROWS|DLGC_WANTALLKEYS;
        case WM_KEYDOWN:
            if (g_bSetButtonMode)
            {
                short vkKey = (short) wParam;
                if (vkKey == VK_LWIN) return TRUE;
                switch (g_iSetButton)
                {
                    case IDC_BUTTON_UP    : SETBUTTON(IDC_STATIC_UP)     ; break;
                    case IDC_BUTTON_DOWN  : SETBUTTON(IDC_STATIC_DOWN)   ; break;
                    case IDC_BUTTON_LEFT  : SETBUTTON(IDC_STATIC_LEFT)   ; break;
                    case IDC_BUTTON_RIGHT : SETBUTTON(IDC_STATIC_RIGHT)  ; break;
                    case IDC_BUTTON_A     : SETBUTTON(IDC_STATIC_A)      ; break;
                    case IDC_BUTTON_B     : SETBUTTON(IDC_STATIC_B)      ; break;
                    case IDC_BUTTON_START : SETBUTTON(IDC_STATIC_START)  ; break;
                    case IDC_BUTTON_SELECT: SETBUTTON(IDC_STATIC_SELECT) ; break;
                    case IDC_BUTTON_L     : SETBUTTON(IDC_STATIC_L)      ; break;
                    case IDC_BUTTON_R     : SETBUTTON(IDC_STATIC_R)      ; break;
                }
                g_bSetButtonMode = false;
                return TRUE;
            }
            break;
        default:
            break;
    }
#if _WIN32_WCE_EMULATION
    return CallWindowProc((WNDPROC)g_pOriginalWndProc, hWnd, message, wParam, lParam);
#else
#if _WIN32_WCE >= 300
    return CallWindowProc((WNDPROC)g_pOriginalWndProc, hWnd, message, wParam, lParam);
#else
    return CallWindowProc((FARPROC)g_pOriginalWndProc, hWnd, message, wParam, lParam);
#endif
#endif
}

// Mesage handler for the Key Check Config box.
LRESULT CALLBACK DLGKeySet(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
//	TCHAR buf[16];
	switch (message)
	{
		case WM_INITDIALOG:
            SetDlgItemInt(hDlg, IDC_STATIC_UP     , Keys[KEY_UP    ].Code, false );
            SetDlgItemInt(hDlg, IDC_STATIC_DOWN   , Keys[KEY_DOWN  ].Code, false );
            SetDlgItemInt(hDlg, IDC_STATIC_LEFT   , Keys[KEY_LEFT  ].Code, false );
            SetDlgItemInt(hDlg, IDC_STATIC_RIGHT  , Keys[KEY_RIGHT ].Code, false );
            SetDlgItemInt(hDlg, IDC_STATIC_B      , Keys[KEY_A     ].Code, false );
            SetDlgItemInt(hDlg, IDC_STATIC_A      , Keys[KEY_B     ].Code, false );
            SetDlgItemInt(hDlg, IDC_STATIC_START  , Keys[KEY_SELECT].Code, false );
            SetDlgItemInt(hDlg, IDC_STATIC_SELECT , Keys[KEY_START ].Code, false );
            SetDlgItemInt(hDlg, IDC_STATIC_L      , Keys[KEY_L     ].Code, false );
            SetDlgItemInt(hDlg, IDC_STATIC_R      , Keys[KEY_R     ].Code, false );

            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_UP),     GWL_WNDPROC, (DWORD) ButtonProc);
            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_DOWN),   GWL_WNDPROC, (DWORD) ButtonProc);
            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_LEFT),   GWL_WNDPROC, (DWORD) ButtonProc);
            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_RIGHT),  GWL_WNDPROC, (DWORD) ButtonProc);
            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_A),      GWL_WNDPROC, (DWORD) ButtonProc);
            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_B),      GWL_WNDPROC, (DWORD) ButtonProc);
            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_START),  GWL_WNDPROC, (DWORD) ButtonProc);
            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_SELECT), GWL_WNDPROC, (DWORD) ButtonProc);
            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_L),      GWL_WNDPROC, (DWORD) ButtonProc);
            g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_R),      GWL_WNDPROC, (DWORD) ButtonProc);
			break;
		case WM_COMMAND:
            switch( LOWORD(wParam) ){
                case IDC_BUTTON_UP:
                case IDC_BUTTON_DOWN:
                case IDC_BUTTON_LEFT:
                case IDC_BUTTON_RIGHT:
                case IDC_BUTTON_A:
                case IDC_BUTTON_B:
                case IDC_BUTTON_START:
                case IDC_BUTTON_SELECT:
                case IDC_BUTTON_L:
                case IDC_BUTTON_R:
                    if (!g_bSetButtonMode)
                    {
                        g_bSetButtonMode = true;
                        g_iSetButton     = LOWORD(wParam);
                    } else {
                        g_bSetButtonMode = false;
                    }
                    break;
                case IDOK:
                    Keys[KEY_UP    ].Code = GetDlgItemInt(hDlg,IDC_STATIC_UP    ,false,false);
                    Keys[KEY_DOWN  ].Code = GetDlgItemInt(hDlg,IDC_STATIC_DOWN  ,false,false);
                    Keys[KEY_LEFT  ].Code = GetDlgItemInt(hDlg,IDC_STATIC_LEFT  ,false,false);
                    Keys[KEY_RIGHT ].Code = GetDlgItemInt(hDlg,IDC_STATIC_RIGHT ,false,false);
                    Keys[KEY_A     ].Code = GetDlgItemInt(hDlg,IDC_STATIC_A     ,false,false);
                    Keys[KEY_B     ].Code = GetDlgItemInt(hDlg,IDC_STATIC_B     ,false,false);
                    Keys[KEY_SELECT].Code = GetDlgItemInt(hDlg,IDC_STATIC_SELECT,false,false);
                    Keys[KEY_START ].Code = GetDlgItemInt(hDlg,IDC_STATIC_START ,false,false);
                    Keys[KEY_L     ].Code = GetDlgItemInt(hDlg,IDC_STATIC_L     ,false,false);
                    Keys[KEY_R     ].Code = GetDlgItemInt(hDlg,IDC_STATIC_R     ,false,false);
                    EndDialog(hDlg, LOWORD(wParam));
				    return TRUE;
                case IDCANCEL:
    				EndDialog(hDlg, LOWORD(wParam));
    				return TRUE;
			}
			break;
        default:
			return DefWindowProc(hDlg, message, wParam, lParam);
	}
    return 0;
}



