project64/Source/nragev20/Interface.cpp

4055 lines
157 KiB
C++
Raw Normal View History

2016-01-27 09:11:59 +00:00
/*
N-Rage`s Dinput8 Plugin
(C) 2002, 2006 Norbert Wladyka
2016-01-27 09:11:59 +00:00
Author`s Email: norbert.wladyka@chello.at
Website: http://go.to/nrage
2016-01-27 09:11:59 +00:00
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.
2016-01-27 09:11:59 +00:00
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.
2016-01-27 09:11:59 +00:00
You should have received a copy of the GNU General Public License
along with this program; if not, write to the free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2016-01-27 09:11:59 +00:00
*/
#include <stdio.h>
2016-01-27 09:11:59 +00:00
#include <windows.h>
2020-02-10 09:57:07 +00:00
#include <commctrl.h>
#include "commonIncludes.h"
2016-01-27 09:11:59 +00:00
#include "DirectInput.h"
#include "FileAccess.h"
#include "Interface.h"
#include "International.h"
#include "NRagePluginV2.h"
#include "PakIO.h"
2016-01-27 09:11:59 +00:00
#include "Version.h"
#include "XInputController.h"
2021-02-28 21:32:50 +00:00
#include <Common/StdString.h>
2016-01-27 09:11:59 +00:00
// Prototypes
2016-01-27 09:11:59 +00:00
BOOL CALLBACK ControllerTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK ControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK XControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); // XInput control main process (comment by tecnicors)
2016-01-27 09:11:59 +00:00
BOOL CALLBACK DevicesTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK ModifierTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK ControllerPakTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK PakProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK MemPakProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK RumblePakProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK TransferPakProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK ShortcutsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
BOOL CALLBACK FoldersDialogProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK BlockerProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
BOOL InitOverlay();
HWND MakeOverlay();
// BOOL CALLBACK EnumGetKeyDesc( LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef ); // Nope, sorry (comment by rabid)
2016-01-27 09:11:59 +00:00
bool GetButtonID( LPDWORD ButtonID, const BYTE bIndex, const BYTE bButtonSet );
bool GetButtonText( const BUTTON& btnButton, LPTSTR Buffer);
DWORD ScanDevices( LPDWORD lpdwCounter, LPBUTTON pButton );
void DeleteControllerSettings( int indexController );
void GetCurrentConfiguration();
void UpdateControllerStructures();
// Global variables
INTERFACEVALUES *g_ivConfig = NULL; // This structure holds all GUI data; it points to a valid struct only if the config window is open
LPDIRECTINPUTDEVICE8 g_pConfigDevice = NULL; // One device handle for current force feedback device; between messages so it needs to be persistent
LPDIRECTINPUTEFFECT g_pConfigEffect = NULL; // Force feedback effect handle
HWND g_hMainDialog = NULL; // Handle of base dialog
2016-01-27 09:11:59 +00:00
// Main dialog control handler
BOOL CALLBACK MainDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
static HWND hTabControl;
HWND hDlgItem;
long i,j;
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
switch(uMsg)
{
case WM_INITDIALOG:
{
DebugWriteA("Config interface: Open\n");
g_ivConfig = (INTERFACEVALUES*)P_malloc( sizeof(INTERFACEVALUES) ); // TODO: Check this malloc!
2020-02-09 11:36:49 +00:00
ZeroMemory( g_ivConfig, sizeof(INTERFACEVALUES) );
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
CopyMemory( &g_ivConfig->Shortcuts, &g_scShortcuts ,sizeof(SHORTCUTS) );
for( i = 0; i < 4; ++i )
DeleteControllerSettings( i );
2016-01-27 09:11:59 +00:00
EnterCriticalSection( &g_critical ); // Block because the InitiateControllers code may still be running
2020-02-09 11:36:49 +00:00
if( !g_strEmuInfo.fInitialisedPlugin )
{
LoadConfigFromINI();
}
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
GetCurrentConfiguration();
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
LeaveCriticalSection( &g_critical );
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
g_hMainDialog = hDlg;
2016-01-27 09:11:59 +00:00
// Display version
2020-02-09 11:36:49 +00:00
{
TCHAR tszBuffer[DEFAULT_BUFFER], tszMsg[DEFAULT_BUFFER / 2];
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
LoadString( g_hResourceDLL, IDS_VERSTRING, tszBuffer, DEFAULT_BUFFER / 2);
2020-06-10 01:48:41 +00:00
_stprintf(tszMsg, tszBuffer, stdstr(VER_FILE_VERSION_STR).ToUTF16().c_str());
2020-02-09 11:36:49 +00:00
SetDlgItemText( hDlg, IDC_VERSIONSTRING, tszMsg );
}
2016-01-27 09:11:59 +00:00
// Tab - control
2020-02-09 11:36:49 +00:00
hTabControl = NULL;
hDlgItem = GetDlgItem( hDlg, IDC_UPPERTAB );
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
TCITEM tcItem;
tcItem.mask = TCIF_TEXT;
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
TCHAR tszText[DEFAULT_BUFFER], tszBuff[DEFAULT_BUFFER];
tcItem.pszText = tszText;
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
LoadString( g_hResourceDLL, IDS_TAB_CONTROLLER, tszBuff, DEFAULT_BUFFER );
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
for (int i = 0; i < 4; i++ )
{
wsprintf( tszText, tszBuff, i + 1 );
TabCtrl_InsertItem( hDlgItem, i, &tcItem );
}
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
LoadString( g_hResourceDLL, IDS_TAB_SHORTCUTS, tszText, DEFAULT_BUFFER );
TabCtrl_InsertItem( hDlgItem, TAB_SHORTCUTS, &tcItem );
// Tab - control end
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
g_ivConfig->ChosenTab = TAB_CONTROLLER1;
TabCtrl_SetCurSel( GetDlgItem( hDlg, IDC_UPPERTAB), g_ivConfig->ChosenTab );
NMHDR nmInit;
nmInit.hwndFrom = hDlgItem;
nmInit.idFrom = IDC_UPPERTAB;
nmInit.code = TCN_SELCHANGE;
MainDlgProc( hDlg, WM_NOTIFY, IDC_UPPERTAB, (LPARAM)&nmInit );
2016-01-27 09:11:59 +00:00
// We can't click "use" without saving when not emulating, because the emulator resets controls before loading a ROM
2020-02-09 11:36:49 +00:00
if( !g_bRunning )
EnableWindow( GetDlgItem( hDlg, IDUSE ), FALSE );
2016-01-27 09:11:59 +00:00
#ifndef _UNICODE
2020-02-09 11:36:49 +00:00
EnableWindow( GetDlgItem( hDlg, IDC_LANGUAGE), FALSE );
2016-01-27 09:11:59 +00:00
#endif // #ifdef _UNICODE
2020-02-09 11:36:49 +00:00
InitOverlay();
}
// Call routine to show content (recursive call)
2020-02-09 11:36:49 +00:00
MainDlgProc( hDlg, WM_USER_UPDATE, 0, 0 );
return TRUE; // The system sets focus to one control element
2020-02-09 11:36:49 +00:00
case WM_NOTIFY:
hDlgItem = ((LPNMHDR)lParam)->hwndFrom;
i = ((LPNMHDR)lParam)->code;
j = ((LPNMHDR)lParam)->idFrom;
switch( j )
{
case IDC_UPPERTAB:
if( i == TCN_SELCHANGE )
{
i = g_ivConfig->ChosenTab;
g_ivConfig->ChosenTab = TabCtrl_GetCurSel( hDlgItem );
if( hTabControl )
{
if( (( i == TAB_CONTROLLER1 ) || ( i == TAB_CONTROLLER2 ) || ( i == TAB_CONTROLLER3 ) || ( i == TAB_CONTROLLER4 )) &&
(( g_ivConfig->ChosenTab == TAB_CONTROLLER1 ) || ( g_ivConfig->ChosenTab == TAB_CONTROLLER2 ) || ( g_ivConfig->ChosenTab == TAB_CONTROLLER3 ) || ( g_ivConfig->ChosenTab == TAB_CONTROLLER4 )))
{
MainDlgProc( hDlg, WM_USER_UPDATE, 0, 0 );
return TRUE;
}
else
DestroyWindow( hTabControl );
}
switch( g_ivConfig->ChosenTab )
{
case TAB_CONTROLLER1:
case TAB_CONTROLLER2:
case TAB_CONTROLLER3:
case TAB_CONTROLLER4:
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_CONTROLLER), hDlg, (DLGPROC)ControllerTabProc);
break;
case TAB_SHORTCUTS:
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_SHORTCUT), hDlg, (DLGPROC)ShortcutsTabProc);
break;
default:
hTabControl = NULL;
return TRUE;
}
RECT rectWindow,
rectTab, rectMain; // Need to know the position of the calling tab window relative to its parent
2020-02-09 11:36:49 +00:00
GetWindowRect( hDlg, &rectMain );
GetWindowRect( hDlgItem, &rectTab );
GetClientRect( hDlgItem, &rectWindow );
TabCtrl_AdjustRect( hDlgItem, FALSE, &rectWindow );
// Second, third parameter: plus Tabwindow's position relative to main
2020-02-09 11:36:49 +00:00
MoveWindow( hTabControl, (rectTab.left - rectMain.left), (rectTab.top - rectMain.top), rectWindow.right - rectWindow.left, rectWindow.bottom - rectWindow.top, FALSE );
ShowWindow( hTabControl, SW_SHOW );
}
return TRUE;
default:
return FALSE;
}
case WM_COMMAND:
hDlgItem = GetDlgItem( hDlg, LOWORD(wParam) );
switch( LOWORD(wParam) )
{
case IDSAVE:
if( hTabControl )
{
DestroyWindow( hTabControl );
hTabControl = NULL;
}
DebugWriteA("Config interface: Save\n");
StoreConfigToINI();
// No break, this is intentional
2020-02-09 11:36:49 +00:00
case IDUSE:
if( hTabControl )
{
DestroyWindow( hTabControl );
hTabControl = NULL;
}
DebugWriteA("Config interface: Use\n");
CopyMemory( &g_scShortcuts ,&g_ivConfig->Shortcuts, sizeof(SHORTCUTS) );
UpdateControllerStructures();
EndDialog( hDlg, TRUE );
return TRUE;
case IDCANCEL:
if( hTabControl )
{
DestroyWindow( hTabControl );
hTabControl = NULL;
}
EndDialog( hDlg, FALSE );
return TRUE;
case IDC_LANGUAGE:
if( HIWORD(wParam) == CBN_SELCHANGE )
{
i = SendMessage( hDlgItem, CB_GETCURSEL, 0, 0 );
g_ivConfig->Language = (LANGID) SendMessage( hDlgItem, CB_GETITEMDATA, i, 0 );
}
return TRUE;
case IDC_STOREINDB:
case IDC_UPDATEDB:
case IDC_ERASEFROMDB:
case IDC_SAVEPROFILE:
case IDC_LOADPROFILE:
// We don't have handlers for these, so fall through to false
2020-02-09 11:36:49 +00:00
default:
return FALSE;
}
case WM_CLOSE:
if( hTabControl )
{
DestroyWindow( hTabControl );
hTabControl = NULL;
}
EndDialog( hDlg, FALSE );
return TRUE;
case WM_DESTROY:
if( hTabControl )
{
DestroyWindow( hTabControl );
hTabControl = NULL;
}
EnterCriticalSection(&g_critical);
ReleaseEffect( g_pConfigEffect );
ReleaseDevice( g_pConfigDevice );
for( i = 0; i < 4; ++i )
{
freePakData( &g_ivConfig->Controllers[i] );
freeModifiers( &g_ivConfig->Controllers[i] );
}
P_free( g_ivConfig );
g_ivConfig = NULL;
DebugWriteA("Config interface: Closed\n");
LeaveCriticalSection(&g_critical);
return TRUE;
case WM_USER_UPDATE:
2016-01-27 09:11:59 +00:00
#ifdef _UNICODE
// Filling DropDownlist with languages
2020-02-09 11:36:49 +00:00
hDlgItem = GetDlgItem( hDlg, IDC_LANGUAGE );
SendMessage (hDlgItem, CB_RESETCONTENT, 0, 0);
{
TCHAR szBuffer[MAX_PATH];
TCHAR * pSlash;
WIN32_FIND_DATA fData;
long lLangFound = 0; // The index matching our current language
2020-02-09 11:36:49 +00:00
VerLanguageName(0x0009, szBuffer, DEFAULT_BUFFER); // English (default resource)
j = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)szBuffer );
SendMessage( hDlgItem, CB_SETITEMDATA, j, 0 );
GetModuleFileName( NULL, szBuffer, MAX_PATH );
pSlash = _tcsrchr( szBuffer, '\\' );
_tcscpy(pSlash + 1, _T("NRage-Language-*.dll"));
// Search for any file available called NRage-Language-XXXX.dll (where X is most likely a number)
2020-02-09 11:36:49 +00:00
HANDLE fSearch = FindFirstFile(szBuffer, &fData);
while ( fSearch != INVALID_HANDLE_VALUE )
{
DWORD dwLangID = 0;
if (_stscanf(fData.cFileName, _T("NRage-Language-%u.dll"), &dwLangID))
{
VerLanguageName(dwLangID, szBuffer, DEFAULT_BUFFER);
j = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)szBuffer );
SendMessage( hDlgItem, CB_SETITEMDATA, j, dwLangID );
if (dwLangID == g_ivConfig->Language)
lLangFound = j;
}
if (!FindNextFile(fSearch, &fData))
fSearch = INVALID_HANDLE_VALUE;
}
FindClose(fSearch);
SendMessage( hDlgItem, CB_SETCURSEL, lLangFound, 0 ); // Set combo box selection
2020-02-09 11:36:49 +00:00
}
// DropDownlist end
2016-01-27 09:11:59 +00:00
#else
2020-02-09 11:36:49 +00:00
hDlgItem = GetDlgItem( hDlg, IDC_LANGUAGE );
SendMessage(hDlgItem, CB_RESETCONTENT, 0, 0);
j = SendMessage(hDlgItem, CB_ADDSTRING, 0, (LPARAM) _T("Language selection disabled"));
SendMessage( hDlgItem, CB_SETITEMDATA, j, 0 );
SendMessage(hDlgItem, CB_SETCURSEL, 0, 0);
2016-01-27 09:11:59 +00:00
#endif // #ifdef _UNICODE
// Call child dialog(s) to update their content as well
2020-02-09 11:36:49 +00:00
if( hTabControl )
SendMessage( hTabControl, WM_USER_UPDATE, 0, 0 );
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
// return TRUE; // Message did get processed
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK ControllerTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
static HWND hTabControl;
CONTROLLER *pcController = &g_ivConfig->Controllers[g_ivConfig->ChosenTab];;
HWND hDlgItem;
long i,j;
switch(uMsg)
{
case WM_INITDIALOG:
hTabControl = NULL;
// Tab - control
2020-02-09 11:36:49 +00:00
hDlgItem = GetDlgItem( hDlg, IDC_CONTROLLERTAB );
TCITEM tcItem;
tcItem.mask = TCIF_TEXT;
TCHAR tszText[DEFAULT_BUFFER];
tcItem.pszText = tszText;
LoadString( g_hResourceDLL, IDS_TAB_CONTROLS, tszText, DEFAULT_BUFFER );
TabCtrl_InsertItem( hDlgItem, TAB_CONTROLS, &tcItem );
LoadString( g_hResourceDLL, IDS_TAB_DEVICES, tszText, DEFAULT_BUFFER );
TabCtrl_InsertItem( hDlgItem, TAB_DEVICES, &tcItem );
LoadString( g_hResourceDLL, IDS_TAB_MODIFIERS, tszText, DEFAULT_BUFFER );
TabCtrl_InsertItem( hDlgItem, TAB_MODIFIERS, &tcItem );
LoadString( g_hResourceDLL, IDS_TAB_CONTROLLERPAK, tszText, DEFAULT_BUFFER );
TabCtrl_InsertItem( hDlgItem, TAB_PAK, &tcItem );
NMHDR nmInit;
nmInit.hwndFrom = hDlgItem;
nmInit.idFrom = IDC_CONTROLLERTAB;
nmInit.code = TCN_SELCHANGE;
// Initiate tab display
2020-02-09 11:36:49 +00:00
ControllerTabProc( hDlg, WM_NOTIFY, IDC_CONTROLLERTAB, (LPARAM)&nmInit );
// Tab - control end
2020-02-09 11:36:49 +00:00
// Call routine to show content (recursive call)
2020-02-09 11:36:49 +00:00
ControllerTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_NOTIFY:
hDlgItem = ((LPNMHDR)lParam)->hwndFrom;
i = ((LPNMHDR)lParam)->code;
j = ((LPNMHDR)lParam)->idFrom;
switch( j )
{
case IDC_CONTROLLERTAB:
if( i == TCN_SELCHANGE )
{
if( hTabControl )
DestroyWindow( hTabControl );
i = TabCtrl_GetCurSel( hDlgItem );
switch( i )
{
case TAB_CONTROLS:
if( pcController->fXInput) // Added to show the XInput controller config tab (comment by tecnicors)
2020-02-09 11:36:49 +00:00
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_XCONTROLS), hDlg, (DLGPROC)XControlsTabProc);
else
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_CONTROLS), hDlg, (DLGPROC)ControlsTabProc);
break;
case TAB_DEVICES:
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_DEVICES), hDlg, (DLGPROC)DevicesTabProc);
break;
case TAB_MODIFIERS:
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_MODIFIER), hDlg, (DLGPROC)ModifierTabProc);
break;
case TAB_PAK:
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_CONTROLLERPAK), hDlg, (DLGPROC)ControllerPakTabProc);
break;
default:
hTabControl = NULL;
return TRUE;
}
hDlgItem = GetDlgItem( hDlg, IDC_CONTROLLERTAB );
RECT rectWindow,
rectTab, rectMain; // Need to know the position of the calling tab window relative to its parent
2020-02-09 11:36:49 +00:00
GetWindowRect( hDlg, &rectMain );
GetWindowRect( hDlgItem, &rectTab );
GetClientRect( hDlgItem, &rectWindow );
TabCtrl_AdjustRect( hDlgItem, FALSE, &rectWindow );
MoveWindow( hTabControl, rectWindow.left + (rectTab.left - rectMain.left), rectWindow.top + (rectTab.top - rectMain.top), rectWindow.right - rectWindow.left, rectWindow.bottom - rectWindow.top, FALSE );
ShowWindow( hTabControl, SW_SHOW );
return TRUE;
}
else
return FALSE;
default:
return FALSE;
}
case WM_COMMAND:
hDlgItem = GetDlgItem( hDlg, LOWORD(wParam) );
switch( LOWORD(wParam) )
{
TCHAR tszTitle[DEFAULT_BUFFER], tszText[DEFAULT_BUFFER];
case IDC_PLUGGED:
pcController->fPlugged = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_CLEARCONTROLLER:
LoadString( g_hResourceDLL, IDS_DLG_CLEAR, tszText, DEFAULT_BUFFER );
LoadString( g_hResourceDLL, IDS_DLG_CLEAR_TITLE, tszTitle, DEFAULT_BUFFER );
if( MessageBox( hDlg, tszText, tszTitle, MB_OKCANCEL | MB_ICONWARNING ) == IDOK )
{
DeleteControllerSettings( g_ivConfig->ChosenTab );
ControllerTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
}
return TRUE;
case IDC_SETDEFAULT:
LoadString( g_hResourceDLL, IDS_DLG_CONTROLRESTORE, tszText, DEFAULT_BUFFER );
LoadString( g_hResourceDLL, IDS_DLG_CONTROLRESTORE_TITLE, tszTitle, DEFAULT_BUFFER );
if( MessageBox( hDlg, tszText, tszTitle, MB_OKCANCEL | MB_ICONWARNING ) == IDOK )
{
DeleteControllerSettings( g_ivConfig->ChosenTab );
LoadProfileFromResource( g_ivConfig->ChosenTab, true);
*(g_ivConfig->FFDevices[g_ivConfig->ChosenTab].szProductName) = '\0'; // Default profile has no force feedback device
2020-02-09 11:36:49 +00:00
g_ivConfig->FFDevices[g_ivConfig->ChosenTab].bProductCounter = 0;
ControllerTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
}
return TRUE;
case IDC_SAVEPROFILE:
{
TCHAR szFilename[MAX_PATH+1] = _T("");
if( BrowseFile( hDlg, szFilename, BF_PROFILE, BF_SAVE ))
{
FILE * fFile = _tfopen( szFilename, _T("wS") );
if (fFile)
{
fprintf(fFile, "@" STRING_PROFILEVERSION "\n\n");
FormatProfileBlock( fFile, g_ivConfig->ChosenTab );
fclose(fFile);
}
else
WarningMessage( IDS_ERR_PROFWRITE, MB_OK );
}
}
return TRUE;
case IDC_LOADPROFILE:
{
TCHAR szFilename[MAX_PATH+1] = TEXT( "" );
if( BrowseFile( hDlg, szFilename, BF_PROFILE, BF_LOAD ))
{
DebugWrite(_T("Config interface: Load shortcuts file: %s\n"), szFilename);
if( LoadProfileFile( szFilename, g_ivConfig->ChosenTab, g_ivConfig->FFDevices[g_ivConfig->ChosenTab].szProductName, &g_ivConfig->FFDevices[g_ivConfig->ChosenTab].bProductCounter ))
ControllerTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
else
WarningMessage( IDS_ERR_PROFREAD, MB_OK );
}
}
return TRUE;
case IDC_XINPUT_ENABLER: // Change to XInput config (comment by tecnicors)
2020-02-09 11:36:49 +00:00
pcController->fXInput = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
if( hTabControl )
DestroyWindow( hTabControl );
if( pcController->fXInput )
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_XCONTROLS), hDlg, (DLGPROC)XControlsTabProc);
else
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_CONTROLS), hDlg, (DLGPROC)ControlsTabProc);
{
hDlgItem = GetDlgItem( hDlg, IDC_CONTROLLERTAB );
RECT rectWindow,
rectTab, rectMain; // Need to know the position of the calling tab window relative to its parent
2020-02-09 11:36:49 +00:00
GetWindowRect( hDlg, &rectMain );
GetWindowRect( hDlgItem, &rectTab );
GetClientRect( hDlgItem, &rectWindow );
TabCtrl_AdjustRect( hDlgItem, FALSE, &rectWindow );
MoveWindow( hTabControl, rectWindow.left + (rectTab.left - rectMain.left), rectWindow.top + (rectTab.top - rectMain.top), rectWindow.right - rectWindow.left, rectWindow.bottom - rectWindow.top, FALSE );
ShowWindow( hTabControl, SW_SHOW );
}
return TRUE; // END IDC_XINPUT_ENABLER
case IDC_N64MOUSE:
pcController->fN64Mouse = (IsDlgButtonChecked(hDlg, LOWORD(wParam)) == BST_CHECKED);
return TRUE;
case IDC_BACKGROUNDINPUT:
pcController->bBackgroundInput = (IsDlgButtonChecked(hDlg, LOWORD(wParam)) == BST_CHECKED);
return TRUE;
default:
return FALSE;
}
case WM_USER_UPDATE:
// For this dialog
2020-02-09 11:36:49 +00:00
CheckDlgButton( hDlg, IDC_PLUGGED, pcController->fPlugged ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_XINPUT_ENABLER, pcController->fXInput ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_N64MOUSE, pcController->fN64Mouse ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton( hDlg, IDC_BACKGROUNDINPUT, pcController->bBackgroundInput ? BST_CHECKED : BST_UNCHECKED);
if( hTabControl )
DestroyWindow( hTabControl );
if( pcController->fXInput )
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_XCONTROLS), hDlg, (DLGPROC)XControlsTabProc);
else
hTabControl = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_CONTROLS), hDlg, (DLGPROC)ControlsTabProc);
{
hDlgItem = GetDlgItem( hDlg, IDC_CONTROLLERTAB );
RECT rectWindow,
rectTab, rectMain; // Need to know the position of the calling tab window relative to its parent
2020-02-09 11:36:49 +00:00
GetWindowRect( hDlg, &rectMain );
GetWindowRect( hDlgItem, &rectTab );
GetClientRect( hDlgItem, &rectWindow );
TabCtrl_AdjustRect( hDlgItem, FALSE, &rectWindow );
MoveWindow( hTabControl, rectWindow.left + (rectTab.left - rectMain.left), rectWindow.top + (rectTab.top - rectMain.top), rectWindow.right - rectWindow.left, rectWindow.bottom - rectWindow.top, FALSE );
ShowWindow( hTabControl, SW_SHOW );
}
// Call child dialog(s) to update their content as well
2020-02-09 11:36:49 +00:00
if( hTabControl )
SendMessage( hTabControl, WM_USER_UPDATE, 0, 0 );
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
// Controls tab
2016-01-27 09:11:59 +00:00
BOOL CALLBACK ControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
static LPBUTTON aButtons = NULL; // Should point to g_ivConfig->Controllers[g_ivConfig->ChosenTab].aButton array
static DWORD dwButtonID[3]; // 0: ID of PushButton 1: ID of TextWindow 2: Offset in aButtons struct
2020-02-09 11:36:49 +00:00
static DWORD dwCounter;
static bool bScanRunning;
static HWND hFocus = NULL;
static HWND hBlocker = NULL;
TCHAR szBuffer[40], szTemp[40];
HWND hDlgItem;
long i;
switch(uMsg)
{
case WM_INITDIALOG:
// SetTicks on TrackBar
hDlgItem = GetDlgItem( hDlg, IDC_CTRRANGE );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 100 ));
SendMessage( hDlgItem, TBM_SETTICFREQ, (WPARAM) 10, 0 );
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
// SetTicks on RapidFire Bar
hDlgItem = GetDlgItem( hDlg, IDC_RAPIDFIRERATE );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 32 ));
SendMessage( hDlgItem, TBM_SETTICFREQ, (WPARAM) 1, 0 );
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
// Call routine to show content (recursive call)
2020-02-09 11:36:49 +00:00
ControlsTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
hDlgItem = GetDlgItem( hDlg, LOWORD(wParam) );
switch( LOWORD(wParam) )
{
case IDC_N64RANGE:
g_ivConfig->Controllers[g_ivConfig->ChosenTab].fRealN64Range = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_RAPIDFIREENABLE:
g_ivConfig->Controllers[g_ivConfig->ChosenTab].bRapidFireEnabled = (IsDlgButtonChecked( hDlg, LOWORD(wParam)) == BST_CHECKED);
return TRUE;
case IDC_CONFIG1:
case IDC_CONFIG2:
case IDC_CONFIG3:
if( HIWORD(wParam) == BN_CLICKED )
{
if( LOWORD(wParam) == IDC_CONFIG1 )
g_ivConfig->Controllers[g_ivConfig->ChosenTab].bAxisSet = 0;
else if( LOWORD(wParam) == IDC_CONFIG2 )
g_ivConfig->Controllers[g_ivConfig->ChosenTab].bAxisSet = 1;
else if( LOWORD(wParam) == IDC_CONFIG3 )
g_ivConfig->Controllers[g_ivConfig->ChosenTab].bAxisSet = 2;
ControlsTabProc( hDlg, WM_USER_UPDATE, 1, 0 );
}
return TRUE;
case IDC_LEFTTRIGGER:
case IDC_RIGHTTRIGGER:
case IDC_ZTRIGGER:
case IDC_DUP:
case IDC_DLEFT:
case IDC_DRIGHT:
case IDC_DDOWN:
case IDC_AUP:
case IDC_ALEFT:
case IDC_ARIGHT:
case IDC_ADOWN:
case IDC_CUP:
case IDC_CLEFT:
case IDC_CRIGHT:
case IDC_CDOWN:
case IDC_ABUTTON:
case IDC_BBUTTON:
case IDC_SBUTTON: // Any of these cases means user wants to assign a button
2020-02-09 11:36:49 +00:00
if( bScanRunning )
{ ; // Do nothing
2020-02-09 11:36:49 +00:00
/* bScanRunning = false;
KillTimer( hDlg, TIMER_BUTTON );
GetButtonText( aButtons[dwButtonID[2]], szBuffer );
SendMessage( GetDlgItem( hDlg, dwButtonID[1] ), WM_SETTEXT , 0, (LPARAM)szBuffer ); */
}
else if( HIWORD(wParam) == BN_CLICKED )
{
EnterCriticalSection(&g_critical);
dwButtonID[0] = LOWORD(wParam);
dwCounter = 0;
GetButtonID( dwButtonID, 0, BSET_CONTROLS );
if( dwButtonID[2] >= PF_APADR )
dwButtonID[2] += g_ivConfig->Controllers[g_ivConfig->ChosenTab].bAxisSet * 4;
if (hFocus == NULL)
hFocus = SetFocus( NULL );
hBlocker = MakeOverlay();
SetTimer( hDlg, TIMER_BUTTON, INTERVAL_BUTTON, NULL );
bScanRunning = true;
LeaveCriticalSection(&g_critical);
}
return TRUE;
default:
return FALSE;
}
case WM_TIMER: // When assigning buttons, this gets called every 20ms (or value in INTERVAL_BUTTON)
2020-02-09 11:36:49 +00:00
if( wParam == TIMER_BUTTON && bScanRunning )
{
BUTTON newButton;
i = ScanDevices( &dwCounter, &newButton);
if( i || dwCounter > 500 )
{
bScanRunning = false;
KillTimer( hDlg, TIMER_BUTTON );
EnterCriticalSection(&g_critical);
if( i == SC_SCANESCAPE ) // Scan aborted
ZeroMemory(&aButtons[dwButtonID[2]], sizeof(BUTTON)); //aButtons[dwButtonID[2]].dwButton = 0;
else if( i == SC_SCANSUCCEED ) // Got a key, mouse click, button press, or axis
2020-02-09 11:36:49 +00:00
aButtons[dwButtonID[2]] = newButton;
DestroyWindow( hBlocker );
LeaveCriticalSection(&g_critical);
GetButtonText( aButtons[dwButtonID[2]], szBuffer );
SendMessage( GetDlgItem( hDlg, dwButtonID[1] ), WM_SETTEXT , 0, (LPARAM)szBuffer );
if( hFocus != NULL )
{
SetFocus( hFocus );
hFocus = NULL;
}
}
else
{
if(( dwCounter % 50 ) == 0 )
{
TCHAR tszText[DEFAULT_BUFFER];
LoadString( g_hResourceDLL, IDS_C_POLLING, tszText, DEFAULT_BUFFER );
wsprintf( szBuffer, tszText, 10 - dwCounter / 50 );
SendMessage( GetDlgItem( hDlg, dwButtonID[1] ), WM_SETTEXT , 0, (LPARAM)szBuffer );
}
++dwCounter;
}
return TRUE;
}
else
return FALSE;
case WM_HSCROLL: // TrackBars
case WM_VSCROLL:
switch ( GetWindowLong( (HWND)lParam, GWL_ID ) )
{
case IDC_CTRRANGE:
TCHAR tszText[DEFAULT_BUFFER];
LoadString( g_hResourceDLL, IDS_C_RANGE, tszText, DEFAULT_BUFFER );
g_ivConfig->Controllers[g_ivConfig->ChosenTab].bStickRange = (BYTE)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
wsprintf( szBuffer, tszText, g_ivConfig->Controllers[g_ivConfig->ChosenTab].bStickRange );
SendMessage( GetDlgItem( hDlg, IDT_RANGE ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
case IDC_RAPIDFIRERATE:
g_ivConfig->Controllers[g_ivConfig->ChosenTab].bRapidFireRate = 33 - (BYTE)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
return TRUE;
default:
return FALSE;
}
case WM_USER_UPDATE:
bScanRunning = false;
KillTimer( hDlg, TIMER_BUTTON );
EnterCriticalSection(&g_critical);
aButtons = g_ivConfig->Controllers[g_ivConfig->ChosenTab].aButton;
LeaveCriticalSection(&g_critical);
if( wParam == 0 )
{
CheckDlgButton( hDlg, IDC_N64RANGE, g_ivConfig->Controllers[g_ivConfig->ChosenTab].fRealN64Range ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_RAPIDFIREENABLE, g_ivConfig->Controllers[g_ivConfig->ChosenTab].bRapidFireEnabled ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_CONFIG1, ( g_ivConfig->Controllers[g_ivConfig->ChosenTab].bAxisSet == 0 ) ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_CONFIG2, ( g_ivConfig->Controllers[g_ivConfig->ChosenTab].bAxisSet == 1 ) ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_CONFIG3, ( g_ivConfig->Controllers[g_ivConfig->ChosenTab].bAxisSet == 2 ) ? BST_CHECKED : BST_UNCHECKED );
SendMessage( GetDlgItem( hDlg, IDC_CTRRANGE ), TBM_SETPOS, TRUE, g_ivConfig->Controllers[g_ivConfig->ChosenTab].bStickRange );
LoadString( g_hResourceDLL, IDS_C_RANGE, szTemp, 40 );
wsprintf( szBuffer, szTemp, g_ivConfig->Controllers[g_ivConfig->ChosenTab].bStickRange );
SendMessage( GetDlgItem( hDlg, IDT_RANGE ), WM_SETTEXT , 0, (LPARAM)szBuffer );
SendMessage( GetDlgItem( hDlg, IDC_RAPIDFIRERATE ), TBM_SETPOS, TRUE, 33 - g_ivConfig->Controllers[g_ivConfig->ChosenTab].bRapidFireRate );
i = 0;
}
else
i = PF_APADR;
for( ;i < 18; ++i )
{
DWORD dwIDs[3];
dwIDs[2] = i;
if( !GetButtonID( dwIDs, 2, BSET_CONTROLS ))
continue;
if( dwIDs[2] >= PF_APADR )
dwIDs[2] += g_ivConfig->Controllers[g_ivConfig->ChosenTab].bAxisSet * 4;
GetButtonText( aButtons[dwIDs[2]], szBuffer );
SendMessage( GetDlgItem( hDlg, dwIDs[1] ), WM_SETTEXT , 0, (LPARAM)szBuffer );
}
return TRUE;
default:
return FALSE; // false means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
// return TRUE; // Message did get processed
2016-01-27 09:11:59 +00:00
}
// XInput controllers tab (comment by tecnicors)
2016-01-27 09:11:59 +00:00
BOOL CALLBACK XControlsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
LPXCONTROLLER gController = &g_ivConfig->Controllers[g_ivConfig->ChosenTab].xiController;
switch( uMsg )
{
case WM_INITDIALOG:
for( int i = IDC_XC_A; i <= IDC_XC_START; i++ )
FillN64ButtonComboBox( hDlg, i );
for( int i = IDC_XC_DPAD; i <= IDC_XC_RTS; i++ )
FillN64AnalogComboBox( hDlg, i );
XControlsTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
return FALSE;
case WM_USER_UPDATE:
{
TCHAR buffer[MAX_PATH];
GetDirectory( buffer, DIRECTORY_CONFIG );
_stprintf_s( buffer, _T("%sXInput Controller %d Config.xcc"), buffer, gController->nControl + 1 );
FILE *saveFile = _tfopen( buffer, _T("rS") );
if( saveFile )
{
LoadXInputConfigFromFile( saveFile, gController );
fclose( saveFile );
}
}
if( !ReadXInputControllerKeys( hDlg, gController ))
for( int i = IDC_XC_A; i <= IDC_XC_RTS; i++ )
SendDlgItemMessage( hDlg, i, CB_SETCURSEL, 0, ( LPARAM )0 );
return TRUE;
case WM_COMMAND:
switch( LOWORD( wParam ))
{
case IDC_XC_USE:
StoreXInputControllerKeys( hDlg, gController );
{
TCHAR buffer[MAX_PATH];
GetDirectory( buffer, DIRECTORY_CONFIG );
_stprintf_s( buffer, _T("%sXInput Controller %d Config.xcc"), buffer, gController->nControl + 1 );
FILE *saveFile = _tfopen( buffer, _T("wS") );
SaveXInputConfigToFile( saveFile, gController );
fclose( saveFile );
}
return TRUE;
}
return FALSE;
default:
return FALSE;
}
}// END XInput controller tab (comment by tecnicors)
2016-01-27 09:11:59 +00:00
BOOL CALLBACK DevicesTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
CONTROLLER *pcController = &g_ivConfig->Controllers[g_ivConfig->ChosenTab];
TCHAR szBuffer[DEFAULT_BUFFER], szTemp[DEFAULT_BUFFER];
HWND hDlgItem;
long i;
switch(uMsg)
{
case WM_INITDIALOG:
// TrackBars
hDlgItem = GetDlgItem( hDlg, IDC_DEADZONE );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 100 ));
SendMessage( hDlgItem, TBM_SETTICFREQ, (WPARAM) 10, 0 );
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
hDlgItem = GetDlgItem( hDlg, IDC_MSSENSITIVITY_X );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 1000 ));
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
hDlgItem = GetDlgItem( hDlg, IDC_MSSENSITIVITY_Y );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 1000 ));
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
{
short sTics[] = { 25, 50, 75, 100, 125, 150, 200, 250, 300, 400, 500, 600, 700, 800, 900 };
for( i = 0; i < (sizeof(sTics) / sizeof(short)); ++i )
SendMessage( hDlgItem, TBM_SETTIC, 0, sTics[i] );
}
// TrackBars End
DevicesTabProc( hDlg, WM_USER_UPDATE, 0, 0 ); // Setting values
2020-02-09 11:36:49 +00:00
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
hDlgItem = GetDlgItem( hDlg, LOWORD(wParam) );
switch( LOWORD(wParam) )
{
case IDC_DEADPANMOUSEX:
if( LOWORD(wParam) == IDC_DEADPANMOUSEX )
i = MM_DEAD;
case IDC_BUFFEREDMOUSEX:
if( LOWORD(wParam) == IDC_BUFFEREDMOUSEX )
i = MM_BUFF;
case IDC_ABSOLUTEMOUSEX:
if( LOWORD(wParam) == IDC_ABSOLUTEMOUSEX )
i = MM_ABS;
if(( HIWORD(wParam) == BN_CLICKED ) && ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED ))
pcController->bMouseMoveX = i;
return TRUE;
case IDC_DEADPANMOUSEY:
if( LOWORD(wParam) == IDC_DEADPANMOUSEY )
i = MM_DEAD;
case IDC_BUFFEREDMOUSEY:
if( LOWORD(wParam) == IDC_BUFFEREDMOUSEY )
i = MM_BUFF;
case IDC_ABSOLUTEMOUSEY:
if( LOWORD(wParam) == IDC_ABSOLUTEMOUSEY )
i = MM_ABS;
if(( HIWORD(wParam) == BN_CLICKED ) && ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED ))
pcController->bMouseMoveY = i;
return TRUE;
case IDC_ACCELERATEX:
pcController->fKeyAbsoluteX = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_ACCELERATEY:
pcController->fKeyAbsoluteY = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
default:
return FALSE;
}
case WM_HSCROLL: // TrackBars
case WM_VSCROLL:
i = GetWindowLong( (HWND)lParam, GWL_ID );
switch( i )
{
case IDC_MSSENSITIVITY_X:
pcController->wMouseSensitivityX = (WORD)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_D_MSX, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->wMouseSensitivityX );
SendMessage( GetDlgItem( hDlg, IDT_MSSENSITIVITY_X ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
case IDC_MSSENSITIVITY_Y:
pcController->wMouseSensitivityY = (WORD)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_D_MSY, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->wMouseSensitivityY );
SendMessage( GetDlgItem( hDlg, IDT_MSSENSITIVITY_Y ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
case IDC_DEADZONE:
pcController->bPadDeadZone = (BYTE)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_D_DEADZONE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bPadDeadZone );
SendMessage( GetDlgItem( hDlg, IDT_DEADZONE ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
default:
return FALSE;
}
case WM_USER_UPDATE:
if( pcController->bMouseMoveX == MM_DEAD )
CheckDlgButton( hDlg, IDC_DEADPANMOUSEX, BST_CHECKED );
else
CheckDlgButton( hDlg, IDC_DEADPANMOUSEX, BST_UNCHECKED );
if( pcController->bMouseMoveX == MM_BUFF )
CheckDlgButton( hDlg, IDC_BUFFEREDMOUSEX, BST_CHECKED );
else
CheckDlgButton( hDlg, IDC_BUFFEREDMOUSEX, BST_UNCHECKED );
if( pcController->bMouseMoveX == MM_ABS )
CheckDlgButton( hDlg, IDC_ABSOLUTEMOUSEX, BST_CHECKED );
else
CheckDlgButton( hDlg, IDC_ABSOLUTEMOUSEX, BST_UNCHECKED );
if( pcController->bMouseMoveY == MM_DEAD )
CheckDlgButton( hDlg, IDC_DEADPANMOUSEY, BST_CHECKED );
else
CheckDlgButton( hDlg, IDC_DEADPANMOUSEY, BST_UNCHECKED );
if( pcController->bMouseMoveY == MM_BUFF )
CheckDlgButton( hDlg, IDC_BUFFEREDMOUSEY, BST_CHECKED );
else
CheckDlgButton( hDlg, IDC_BUFFEREDMOUSEY, BST_UNCHECKED );
if( pcController->bMouseMoveY == MM_ABS )
CheckDlgButton( hDlg, IDC_ABSOLUTEMOUSEY, BST_CHECKED );
else
CheckDlgButton( hDlg, IDC_ABSOLUTEMOUSEY, BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_ACCELERATEX, pcController->fKeyAbsoluteX ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_ACCELERATEY, pcController->fKeyAbsoluteY ? BST_CHECKED : BST_UNCHECKED );
// TrackBars
SendMessage( GetDlgItem( hDlg, IDC_DEADZONE ), TBM_SETPOS, TRUE, pcController->bPadDeadZone );
LoadString( g_hResourceDLL, IDS_D_DEADZONE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bPadDeadZone );
SendMessage( GetDlgItem( hDlg, IDT_DEADZONE ), WM_SETTEXT , 0, (LPARAM)szBuffer );
SendMessage( GetDlgItem( hDlg, IDC_MSSENSITIVITY_X ), TBM_SETPOS, TRUE, pcController->wMouseSensitivityX );
LoadString( g_hResourceDLL, IDS_D_MSX, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->wMouseSensitivityX );
SendMessage( GetDlgItem( hDlg, IDT_MSSENSITIVITY_X ), WM_SETTEXT , 0, (LPARAM)szBuffer );
SendMessage( GetDlgItem( hDlg, IDC_MSSENSITIVITY_Y ), TBM_SETPOS, TRUE, pcController->wMouseSensitivityY );
LoadString( g_hResourceDLL, IDS_D_MSY, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->wMouseSensitivityY );
SendMessage( GetDlgItem( hDlg, IDT_MSSENSITIVITY_Y ), WM_SETTEXT , 0, (LPARAM)szBuffer );
// TrackBars End
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK MoveModifierDialog( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
HWND hDlgItem;
long i,j;
DWORD dwValue;
TCHAR szBuffer[DEFAULT_BUFFER], szTemp[DEFAULT_BUFFER];
switch(uMsg)
{
case WM_INITDIALOG:
// TrackBars
hDlgItem = GetDlgItem( hDlg, IDC_XMODIFIER );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 500 ));
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
{
short sTics[] = { 25, 50, 75, 100, 125, 150, 200, 250, 300, 400, 500 };
for( i = 0; i < (sizeof(sTics) / sizeof(short)); ++i )
SendMessage( hDlgItem, TBM_SETTIC, 0, sTics[i] );
}
hDlgItem = GetDlgItem( hDlg, IDC_YMODIFIER );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 500 ));
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
{
short sTics[] = { 25, 50, 75, 100, 125, 150, 200, 250, 300, 400, 500 };
for( i = 0; i < (sizeof(sTics) / sizeof(short)); ++i )
SendMessage( hDlgItem, TBM_SETTIC, 0, sTics[i] );
}
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_HSCROLL: // TrackBars
case WM_VSCROLL:
switch (GetWindowLong( (HWND)lParam, GWL_ID ))
{
case IDC_XMODIFIER:
i = SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_M_MOVEVALUE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, i );
SendMessage( GetDlgItem( hDlg, IDT_XMODIFIER ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
case IDC_YMODIFIER:
i = SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_M_MOVEVALUE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, i );
SendMessage( GetDlgItem( hDlg, IDT_YMODIFIER ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
default:
return FALSE;
}
case WM_USER_UPDATE:
if( wParam == MDT_MOVE )
dwValue = (DWORD)lParam;
else
dwValue = MAKELONG( 100, 100 );
i = (short)(dwValue & 0x0000FFFF);
if( i < 0 )
{
i = -i;
CheckDlgButton( hDlg, IDC_XNEGATE, BST_CHECKED );
}
else
CheckDlgButton( hDlg, IDC_XNEGATE, BST_UNCHECKED );
SendMessage( GetDlgItem( hDlg, IDC_XMODIFIER ), TBM_SETPOS, TRUE, i );
LoadString( g_hResourceDLL, IDS_M_MOVEVALUE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, i );
SendMessage( GetDlgItem( hDlg, IDT_XMODIFIER ), WM_SETTEXT , 0, (LPARAM)szBuffer );
i = (short)((dwValue >> 16) & 0x0000FFFF);
if( i < 0 )
{
i = -i;
CheckDlgButton( hDlg, IDC_YNEGATE, BST_CHECKED );
}
else
CheckDlgButton( hDlg, IDC_YNEGATE, BST_UNCHECKED );
SendMessage( GetDlgItem( hDlg, IDC_YMODIFIER ), TBM_SETPOS, TRUE, i );
LoadString( g_hResourceDLL, IDS_M_MOVEVALUE, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, i );
SendMessage( GetDlgItem( hDlg, IDT_YMODIFIER ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
case WM_USER_READVALUES:
i = SendMessage( GetDlgItem( hDlg, IDC_XMODIFIER ), TBM_GETPOS, 0, 0 );
if( IsDlgButtonChecked( hDlg, IDC_XNEGATE ) == BST_CHECKED )
i = -i;
j = SendMessage( GetDlgItem( hDlg, IDC_YMODIFIER ), TBM_GETPOS, 0, 0 );
if( IsDlgButtonChecked( hDlg, IDC_YNEGATE ) == BST_CHECKED )
j = -j;
*(DWORD*)wParam = MAKELONG( (short)i, (short)j );
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK MacroModifierDialog( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
long i;
DWORD dwValue;
const DWORD aButtons[] ={ IDC_DRIGHT , IDC_DLEFT , IDC_DDOWN , IDC_DUP,
IDC_SBUTTON , IDC_ZTRIG , IDC_BBUTTON , IDC_ABUTTON,
IDC_CRIGHT , IDC_CLEFT , IDC_CDOWN , IDC_CUP,
IDC_RTRIG , IDC_LTRIG , 0 , 0,
IDC_ARIGHT , IDC_ALEFT , IDC_ADOWN , IDC_AUP,
IDC_RAPIDFIREMODE , IDC_RAPIDFIREMODERATE };
switch(uMsg)
{
case WM_INITDIALOG:
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_USER_UPDATE:
if( wParam == MDT_MACRO )
dwValue = (DWORD)lParam;
else
dwValue = 0;
i = sizeof(aButtons) / sizeof(aButtons[0]) - 1;
while( i >= 0 )
{
if( aButtons[i] )
{
if( dwValue & ( 1 << i ) )
CheckDlgButton( hDlg, aButtons[i], BST_CHECKED );
else
CheckDlgButton( hDlg, aButtons[i], BST_UNCHECKED );
}
i--;
}
return TRUE;
case WM_USER_READVALUES:
dwValue = 0;
i = sizeof(aButtons) / sizeof(aButtons[0]) - 1;
while( i >= 0 )
{
if( aButtons[i] && ( IsDlgButtonChecked( hDlg, aButtons[i] ) == BST_CHECKED ))
dwValue = dwValue | ( 1 << i );
i--;
}
*(DWORD*)wParam = dwValue;
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK ConfigModifierDialog( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
DWORD dwValue;
const DWORD aButtons[] ={ IDC_CONFIG1 , 0x000001,
IDC_CONFIG2 , 0x000003,
IDC_CONFIG3 , 0x000005,
IDC_CONFIGCYCLE , 0x0000FF,
IDC_MOUSEX , 0x000100,
IDC_MOUSEY , 0x000200,
IDC_KEYX , 0x010000,
IDC_KEYY , 0x020000 };
int i;
switch(uMsg)
{
case WM_INITDIALOG:
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDC_CONFIG1:
case IDC_CONFIG2:
case IDC_CONFIG3:
case IDC_CONFIGCYCLE:
if(( HIWORD(wParam) == BN_CLICKED ) || ( HIWORD(wParam) == BN_DBLCLK ))
{
EnterCriticalSection(&g_critical); // This has a possibility of affecting the buttons we're writing to
2020-02-09 11:36:49 +00:00
bool bCheck = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED ) ? false : true;
CheckDlgButton( hDlg, IDC_CONFIG1, BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_CONFIG2, BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_CONFIG3, BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_CONFIGCYCLE, BST_UNCHECKED );
if( bCheck )
CheckDlgButton( hDlg, LOWORD(wParam), BST_CHECKED );
LeaveCriticalSection(&g_critical);
}
return TRUE;
default:
return FALSE;
}
case WM_USER_UPDATE:
if( wParam == MDT_CONFIG )
dwValue = (DWORD)lParam;
else
dwValue = 0;
if( dwValue & 0x01 )
{
BYTE bConfig = (BYTE)((dwValue >> 1) & 0x7F);
if( bConfig >= PF_AXESETS )
{
CheckDlgButton( hDlg, IDC_CONFIG1, BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_CONFIG2, BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_CONFIG3, BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_CONFIGCYCLE, BST_CHECKED );
}
else
{
i = PF_AXESETS - 1;
while( i >= 0 )
{
if( bConfig == i )
CheckDlgButton( hDlg, aButtons[i*2], BST_CHECKED );
else
CheckDlgButton( hDlg, aButtons[i*2], BST_UNCHECKED );
i--;
}
}
}
i = sizeof(aButtons) / sizeof(aButtons[0]) - 2;
while( i >= 8 )
{
if(( dwValue & aButtons[i+1] ) == aButtons[i+1] )
CheckDlgButton( hDlg, aButtons[i], BST_CHECKED );
else
CheckDlgButton( hDlg, aButtons[i], BST_UNCHECKED );
i -= 2;
}
return TRUE;
case WM_USER_READVALUES:
dwValue = 0;
i = sizeof(aButtons) / sizeof(aButtons[0]) - 2;
while( i >= 0 )
{
if( IsDlgButtonChecked( hDlg, aButtons[i] ) == BST_CHECKED )
dwValue |= aButtons[i+1];
i -= 2;
}
*(DWORD*)wParam = dwValue;
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
void ModDescription( HWND hListView, int iEntry, const LPMODIFIER pModifier )
{
2020-02-09 11:36:49 +00:00
TCHAR szBuffer[DEFAULT_BUFFER];
const UINT iModTypes[] = { IDS_M_TAB_NONE, IDS_M_TAB_MOVE, IDS_M_TAB_MACRO, IDS_M_TAB_CONFIG };
TCHAR pszModTypes[4][16];
for (int i = 0; i < ARRAYSIZE(iModTypes); i++ )
LoadString( g_hResourceDLL, iModTypes[i], pszModTypes[i], ARRAYSIZE(pszModTypes[i]) );
GetButtonText( pModifier->btnButton, szBuffer );
ListView_SetItemText( hListView, iEntry, 0,szBuffer );
switch( pModifier->bModType )
{
case MDT_MOVE:
ListView_SetItemText( hListView, iEntry, 1, pszModTypes[1] );
wsprintf( szBuffer, _T("X:%i%% / Y:%i%%"), (short)(pModifier->dwSpecific & 0x0000FFFF), (short)((pModifier->dwSpecific >> 16) & 0x0000FFFF));
break;
case MDT_MACRO:
ListView_SetItemText( hListView, iEntry, 1, pszModTypes[2] );
szBuffer[0] = '\0';
{
bool bGotKey = false;
DWORD dwValue = pModifier->dwSpecific;
const TCHAR *apszButtons[] ={ _T("Dp->"), _T("Dp<-"), _T("Dp\\/"), _T("Dp/\\"), _T("St"), _T("Z"), _T("B"), _T("A"),
_T("Cb->"), _T("Cb<-"), _T("Cb\\/"), _T("Cb/\\"), _T("R"), _T("L"), NULL, NULL,
_T("As->"), _T("As<-"), _T("As\\/"), _T("As/\\"), _T("(<Rf>)") };
int i = sizeof(apszButtons) / sizeof(apszButtons[0]) - 1;
while( i >= 0 )
{
if( apszButtons[i] && ( dwValue & ( 1 << i ) ))
{
if( bGotKey )
lstrcat( szBuffer, _T(" ") );
else
bGotKey = true;
lstrcat( szBuffer, apszButtons[i] );
}
i--;
}
}
break;
case MDT_CONFIG:
ListView_SetItemText( hListView, iEntry, 1, pszModTypes[3] );
szBuffer[0] = '\0';
{
DWORD dwValue = pModifier->dwSpecific;
bool bGotKey = false;
if( dwValue & 0x1 )
{
lstrcat( szBuffer, _T("C-") );
if((( dwValue >> 1 ) & 0x7F ) < PF_AXESETS )
wsprintf( &szBuffer[lstrlen(szBuffer)], _T("%i"), (( dwValue >> 1 ) & 0x7F ));
else
lstrcat( szBuffer, _T("Sw") );
bGotKey = true;
}
if( dwValue & 0x300 )
{
if( bGotKey )
lstrcat( szBuffer, _T(" ") );
else
bGotKey = true;
lstrcat( szBuffer, _T("Ms-") );
if( dwValue & 0x100 )
lstrcat( szBuffer, _T("X") );
if( dwValue & 0x200 )
lstrcat( szBuffer, _T("Y") );
}
if( dwValue & 0x30000 )
{
if( bGotKey )
lstrcat( szBuffer, _T(" ") );
else
bGotKey = true;
lstrcat( szBuffer, _T("Kb-") );
if( dwValue & 0x10000 )
lstrcat( szBuffer, _T("X") );
if( dwValue & 0x20000 )
lstrcat( szBuffer, _T("Y") );
}
}
break;
case MDT_NONE:
default:
ListView_SetItemText( hListView, iEntry, 1, pszModTypes[0] );
szBuffer[0] = '\0';
}
ListView_SetItemText( hListView, iEntry, 2, szBuffer );
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK ModifierTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
static BUTTON storage;
static bool bScanRunning;
static DWORD dwCounter;
static HWND hFocus = NULL, hBlocker;
static int iSelectedMod;
static BYTE bDisplayedProbs;
static HWND hModProperties;
static LPCONTROLLER pcController;
const UINT iModTypes[] = { IDS_M_NONE, IDS_M_MOVE, IDS_M_MACRO, IDS_M_CONFIG };
TCHAR pszModTypes[4][16];
for (int j = 0; j < ARRAYSIZE(iModTypes); j++ )
LoadString( g_hResourceDLL, iModTypes[j], pszModTypes[j], ARRAYSIZE(pszModTypes[j]) );
TCHAR szBuffer[40];
HWND hDlgItem;
long i;
BYTE bByte;
switch(uMsg)
{
case WM_INITDIALOG:
bScanRunning = false;
hModProperties = NULL;
bDisplayedProbs = MDT_NONE;
// List view
2020-02-09 11:36:49 +00:00
hDlgItem = GetDlgItem( hDlg, IDC_MODIFIERLIST );
LVCOLUMN lvColumn;
lvColumn.mask = LVCFMT_CENTER | LVCF_WIDTH | LVCF_TEXT;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.cx = 100;
LoadString( g_hResourceDLL, IDS_M_ASSIGNED, szBuffer, 40 );
lvColumn.pszText = szBuffer;
ListView_InsertColumn( hDlgItem, 0, &lvColumn );
lvColumn.fmt = LVCFMT_CENTER | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvColumn.cx = 43;
lvColumn.iSubItem = 1;
LoadString( g_hResourceDLL, IDS_M_TYPE, szBuffer, 40 );
lvColumn.pszText = szBuffer;
ListView_InsertColumn( hDlgItem, 1, &lvColumn );
lvColumn.cx = 128;
lvColumn.iSubItem = 2;
LoadString( g_hResourceDLL, IDS_M_PARAM, szBuffer, 40 );
lvColumn.pszText = szBuffer;
ListView_InsertColumn( hDlgItem, 2, &lvColumn );
ListView_SetExtendedListViewStyle( hDlgItem, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP );
// List view end
2020-02-09 11:36:49 +00:00
// Drop down
2020-02-09 11:36:49 +00:00
hDlgItem = GetDlgItem( hDlg, IDC_MODTYP );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)pszModTypes[0] );
SendMessage( hDlgItem, CB_SETITEMDATA, i, MDT_NONE );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)pszModTypes[1] );
SendMessage( hDlgItem, CB_SETITEMDATA, i, MDT_MOVE );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)pszModTypes[2] );
SendMessage( hDlgItem, CB_SETITEMDATA, i, MDT_MACRO );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)pszModTypes[3] );
SendMessage( hDlgItem, CB_SETITEMDATA, i, MDT_CONFIG );
// Drop down end
2020-02-09 11:36:49 +00:00
ZeroMemory(&storage, sizeof(BUTTON));
ModifierTabProc( hDlg, WM_USER_UPDATE, 0, 0 ); // Setting values
2020-02-09 11:36:49 +00:00
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
hDlgItem = GetDlgItem( hDlg, LOWORD(wParam) );
switch( LOWORD(wParam) )
{
case IDC_NEWMODIFIER:
if( pcController->nModifiers < MAX_MODIFIERS )
{
EnterCriticalSection(&g_critical);
pcController->nModifiers++;
pcController->pModifiers = (MODIFIER*)P_realloc( pcController->pModifiers, sizeof(MODIFIER) * pcController->nModifiers );
ZeroMemory( &pcController->pModifiers[pcController->nModifiers - 1], sizeof(MODIFIER) );
iSelectedMod = pcController->nModifiers - 1;
LeaveCriticalSection(&g_critical);
ModifierTabProc( hDlg, WM_USER_UPDATE, 0, 1 );
}
return TRUE;
case IDC_KILLMODIFIER:
hDlgItem = GetDlgItem( hDlg, IDC_MODIFIERLIST );
if( ListView_GetSelectedCount( hDlgItem ) > 0 )
{
EnterCriticalSection(&g_critical);
for( i = ListView_GetItemCount( hDlgItem ) - 1; i >= 0; i-- )
{
if( ListView_GetItemState( hDlgItem, i, LVIS_SELECTED ))
{
MoveMemory( &pcController->pModifiers[i], &pcController->pModifiers[i+1], sizeof(MODIFIER) * ( pcController->nModifiers - 1 - i ));
pcController->nModifiers--;
}
}
pcController->pModifiers = (MODIFIER*)P_realloc( pcController->pModifiers, sizeof(MODIFIER) * pcController->nModifiers );
LeaveCriticalSection(&g_critical);
ModifierTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
}
return TRUE;
case IDC_ASSIGNMOD:
EnterCriticalSection(&g_critical);
hDlgItem = GetDlgItem( hDlg, IDC_MODIFIERLIST );
if( bScanRunning )
{
/* bScanRunning = false;
KillTimer( hDlg, TIMER_BUTTON );
BUTTON btnButton;
btnButton = storage; // btnButton.dwButton = GetWindowLong( hDlgItem, GWL_USERDATA );
GetButtonText( btnButton, szBuffer );
SendMessage( GetDlgItem( hDlg, IDT_ASSIGNMOD ), WM_SETTEXT , 0, (LPARAM)szBuffer ); */ ;
}
else if( HIWORD(wParam) == BN_CLICKED && ListView_GetItemCount( hDlgItem ))
{
dwCounter = 0;
if (hFocus == NULL)
hFocus = SetFocus( NULL );
hBlocker = MakeOverlay();
SetTimer( hDlg, TIMER_BUTTON, INTERVAL_BUTTON, NULL );
bScanRunning = true;
}
LeaveCriticalSection(&g_critical);
return TRUE;
case IDC_MODTYP:
if( HIWORD (wParam) == CBN_SELCHANGE )
{
ModifierTabProc( hDlg, WM_USER_UPDATE, 1, 1 );
}
return TRUE;
case IDC_APPCHANGES:
// Mod type
2020-02-09 11:36:49 +00:00
EnterCriticalSection(&g_critical);
hDlgItem = GetDlgItem( hDlg, IDC_MODTYP );
i = SendMessage( hDlgItem, CB_GETCURSEL, 0, 0 );
pcController->pModifiers[iSelectedMod].bModType = (BYTE)SendMessage( hDlgItem, CB_GETITEMDATA, i, 0 );
// Toggle
pcController->pModifiers[iSelectedMod].fToggle = ( IsDlgButtonChecked( hDlg, IDC_TOGGLE ) == BST_CHECKED );
// Status
pcController->pModifiers[iSelectedMod].fStatus = ( IsDlgButtonChecked( hDlg, IDC_STATE ) == BST_CHECKED );
// Specific data
2020-02-09 11:36:49 +00:00
if( hModProperties )
SendMessage( hModProperties, WM_USER_READVALUES, (WPARAM)&pcController->pModifiers[iSelectedMod].dwSpecific, 0 );
else
pcController->pModifiers[iSelectedMod].dwSpecific = 0;
// Mod button
2020-02-09 11:36:49 +00:00
pcController->pModifiers[iSelectedMod].btnButton = storage;
LeaveCriticalSection(&g_critical);
ModDescription( GetDlgItem( hDlg, IDC_MODIFIERLIST ), iSelectedMod, &pcController->pModifiers[iSelectedMod] );
return TRUE;
case IDC_RESET:
ModifierTabProc( hDlg, WM_USER_UPDATE, 1, 0 );
return TRUE;
case IDC_TOGGLE:
EnableWindow( GetDlgItem( hDlg, IDC_STATE ), ( IsDlgButtonChecked( hDlg, IDC_TOGGLE ) == BST_CHECKED ) ? TRUE : FALSE );
return TRUE;
case IDC_STATE:
return TRUE;
default:
return FALSE;
}
case WM_TIMER: // When assigning modifiers, this gets called every 20ms (or value in INTERVAL_BUTTON)
2020-02-09 11:36:49 +00:00
if( wParam == TIMER_BUTTON && bScanRunning )
{
BUTTON newButton;
i = ScanDevices( &dwCounter, &newButton );
if( i || dwCounter > 500 )
{
bScanRunning = false;
KillTimer( hDlg, TIMER_BUTTON );
hDlgItem = GetDlgItem( hDlg, IDC_ASSIGNMOD );
EnterCriticalSection(&g_critical);
if( i == SC_SCANESCAPE ) // Got an escape character from keyboard; cancel
2020-02-09 11:36:49 +00:00
ZeroMemory(&storage, sizeof(BUTTON));
else if( i == SC_SCANSUCCEED ) // Got a button or axis
storage = newButton;
newButton = storage;
DestroyWindow( hBlocker );
LeaveCriticalSection(&g_critical);
GetButtonText( newButton, szBuffer );
SendMessage( GetDlgItem( hDlg, IDT_ASSIGNMOD ), WM_SETTEXT , 0, (LPARAM)szBuffer );
if( hFocus != NULL )
{
SetFocus( hFocus );
hFocus = NULL;
}
}
else
{
if(( dwCounter % 50 ) == 0 )
{
TCHAR tszText[DEFAULT_BUFFER];
LoadString( g_hResourceDLL, IDS_C_POLLING, tszText, DEFAULT_BUFFER );
wsprintf( szBuffer, tszText, 10 - dwCounter / 50 );
SendMessage( GetDlgItem( hDlg, IDT_ASSIGNMOD ), WM_SETTEXT , 0, (LPARAM)szBuffer );
}
++dwCounter;
}
return TRUE;
}
else
return FALSE;
case WM_NOTIFY:
switch( ((LPNMHDR)lParam)->idFrom )
{
case IDC_MODIFIERLIST:
switch( ((LPNMHDR)lParam)->code )
{
case LVN_ITEMCHANGED:
ModifierTabProc( hDlg, WM_USER_UPDATE, 1, 0 );
return TRUE;
default:
return FALSE;
}
default:
return FALSE;
}
case WM_USER_UPDATE:
pcController = &g_ivConfig->Controllers[g_ivConfig->ChosenTab];
hDlgItem = GetDlgItem( hDlg, IDC_MODIFIERLIST );
if( wParam == 0 )
{
// Update modifier list
2020-02-09 11:36:49 +00:00
ListView_DeleteAllItems( hDlgItem );
if( lParam == 0 )
iSelectedMod = -1;
LVITEM lvItem;
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.pszText = _T("");
ListView_SetItemCount( hDlgItem, pcController->nModifiers );
for( lvItem.lParam = 0; lvItem.lParam < pcController->nModifiers; ++lvItem.lParam )
{
lvItem.iItem = lvItem.lParam;
i = ListView_InsertItem( hDlgItem, &lvItem );
ModDescription( hDlgItem, i, &pcController->pModifiers[lvItem.lParam] );
}
if( iSelectedMod >= 0 && iSelectedMod < ListView_GetItemCount( hDlgItem ))
ListView_SetItemState( hDlgItem, iSelectedMod, LVIS_SELECTED, LVIS_SELECTED )
else
iSelectedMod = -1;
}
else
{
// Get selected modifier
2020-02-09 11:36:49 +00:00
iSelectedMod = -1;
if( ListView_GetSelectedCount( hDlgItem ) > 0 )
{
for( i = ListView_GetItemCount( hDlgItem ) - 1; i >= 0; i-- )
{
if( ListView_GetItemState( hDlgItem, i, LVIS_SELECTED ))
{
iSelectedMod = i;
i = -1;
}
}
}
}
hDlgItem = GetDlgItem( hDlg, IDC_MODTYP );
if( lParam == 0 )
{
if( iSelectedMod >= 0 )
{ // A mod is selected
2020-02-09 11:36:49 +00:00
EnableWindow( GetDlgItem( hDlg, IDC_ASSIGNMOD ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDT_ASSIGNMOD ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDC_TOGGLE ), TRUE );
EnableWindow( hDlgItem, TRUE );
EnableWindow( GetDlgItem( hDlg, IDT_MODTYP ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDC_APPCHANGES ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDC_RESET ), TRUE );
for( i = SendMessage( hDlgItem, CB_GETCOUNT, 0, 0 )-1; i >= 0; i-- )
{ // Looking at which mod type
2020-02-09 11:36:49 +00:00
bByte = (BYTE)SendMessage( hDlgItem, CB_GETITEMDATA, i, 0 );
if( pcController->pModifiers[iSelectedMod].bModType == bByte )
{
SendMessage( hDlgItem, CB_SETCURSEL, i, 0 );
i = -10;
}
}
if( i > -5 )
SendMessage( hDlgItem, CB_SETCURSEL, 0, 0 );
CheckDlgButton( hDlg, IDC_TOGGLE, pcController->pModifiers[iSelectedMod].fToggle ? BST_CHECKED : BST_UNCHECKED );
EnableWindow( GetDlgItem( hDlg, IDC_STATE ), pcController->pModifiers[iSelectedMod].fToggle ? TRUE : FALSE );
CheckDlgButton( hDlg, IDC_STATE, pcController->pModifiers[iSelectedMod].fStatus ? BST_CHECKED : BST_UNCHECKED );
storage = pcController->pModifiers[iSelectedMod].btnButton;
GetButtonText( pcController->pModifiers[iSelectedMod].btnButton, szBuffer );
SendMessage( GetDlgItem( hDlg, IDT_ASSIGNMOD ), WM_SETTEXT , 0, (LPARAM)szBuffer );
}
else
{
EnableWindow( GetDlgItem( hDlg, IDC_ASSIGNMOD ), FALSE );
EnterCriticalSection(&g_critical);
ZeroMemory(&storage, sizeof(BUTTON));
LeaveCriticalSection(&g_critical);
SendMessage( GetDlgItem( hDlg, IDT_ASSIGNMOD ), WM_SETTEXT , 0, (LPARAM) _T("") );
EnableWindow( GetDlgItem( hDlg, IDT_ASSIGNMOD ), FALSE );
SendMessage( hDlgItem, CB_SETCURSEL, 0, 0 );
EnableWindow( hDlgItem, FALSE );
EnableWindow( GetDlgItem( hDlg, IDT_MODTYP ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_TOGGLE ), FALSE );
CheckDlgButton( hDlg, IDC_TOGGLE , BST_UNCHECKED );
EnableWindow( GetDlgItem( hDlg, IDC_STATE ), FALSE );
CheckDlgButton( hDlg, IDC_STATE , BST_UNCHECKED );
EnableWindow( GetDlgItem( hDlg, IDC_APPCHANGES ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_RESET ), FALSE );
}
}
i = SendMessage( hDlgItem, CB_GETCURSEL, 0, 0 );
bByte = (BYTE)SendMessage( hDlgItem, CB_GETITEMDATA, i, 0 );
if(( bByte == bDisplayedProbs ) && hModProperties )
SendMessage( hModProperties, WM_USER_UPDATE, pcController->pModifiers[iSelectedMod].bModType, pcController->pModifiers[iSelectedMod].dwSpecific );
else
{
if( hModProperties )
DestroyWindow( hModProperties );
switch( bByte )
{
case MDT_MOVE:
hModProperties = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_MOD_MOVE), hDlg, (DLGPROC)MoveModifierDialog);
break;
case MDT_MACRO:
hModProperties = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_MOD_MACRO), hDlg, (DLGPROC)MacroModifierDialog);
break;
case MDT_CONFIG:
hModProperties = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_MOD_CONFIG), hDlg, (DLGPROC)ConfigModifierDialog);
break;
case MDT_NONE:
default:
hModProperties = NULL;
}
hDlgItem = GetDlgItem( hDlg, IDC_PROPWINDOW );
if( hModProperties )
{
RECT rectProp, rectMain; // Need to know the position of the calling tab window relative to its parent
2020-02-09 11:36:49 +00:00
GetWindowRect( hDlg, &rectMain );
GetWindowRect( hDlgItem, &rectProp );
MoveWindow( hModProperties, rectProp.left - rectMain.left, rectProp.top - rectMain.top, rectProp.right - rectProp.left, rectProp.bottom - rectProp.top, FALSE );
SendMessage( hModProperties, WM_USER_UPDATE, pcController->pModifiers[iSelectedMod].bModType, pcController->pModifiers[iSelectedMod].dwSpecific );
ShowWindow( hModProperties, SW_SHOW );
}
bDisplayedProbs = bByte;
}
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK ControllerPakTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
static HWND hPakWindow;
static bool bAdaptoidInList;
static BYTE bCurrentPak;
HWND hDlgItem;
long i,j;
BYTE bByte;
TCHAR tszMsg[DEFAULT_BUFFER];
switch(uMsg)
{
case WM_INITDIALOG:
hPakWindow = NULL;
bAdaptoidInList = false;
bCurrentPak = (BYTE)(-1);
// Drop down list
2020-02-09 11:36:49 +00:00
hDlgItem = GetDlgItem( hDlg, IDC_PAKTYPE );
LoadString( g_hResourceDLL, IDS_P_NONE, tszMsg, DEFAULT_BUFFER );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)tszMsg );
SendMessage( hDlgItem, CB_SETITEMDATA, i, PAK_NONE );
LoadString( g_hResourceDLL, IDS_P_MEMPAK, tszMsg, DEFAULT_BUFFER );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)tszMsg );
SendMessage( hDlgItem, CB_SETITEMDATA, i, PAK_MEM );
LoadString( g_hResourceDLL, IDS_P_RUMBLEPAK, tszMsg, DEFAULT_BUFFER );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)tszMsg );
SendMessage( hDlgItem, CB_SETITEMDATA, i, PAK_RUMBLE );
2016-01-27 09:11:59 +00:00
#ifdef V_TRANSFERPAK
2020-02-09 11:36:49 +00:00
LoadString( g_hResourceDLL, IDS_P_TRANSFERPAK, tszMsg, DEFAULT_BUFFER );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)tszMsg );
SendMessage( hDlgItem, CB_SETITEMDATA, i, PAK_TRANSFER );
2016-01-27 09:11:59 +00:00
#pragma message( "Transferpak enabled in Interface" )
#endif
#ifdef V_VOICEPAK
2020-02-09 11:36:49 +00:00
LoadString( g_hResourceDLL, IDS_P_VOICEPAK, tszMsg, DEFAULT_BUFFER );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)tszMsg );
SendMessage( hDlgItem, CB_SETITEMDATA, i, PAK_VOICE );
2016-01-27 09:11:59 +00:00
#pragma message( "Voicepak enabled in Interface" )
#endif
2020-02-09 11:36:49 +00:00
ControllerPakTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
hDlgItem = GetDlgItem( hDlg, LOWORD(wParam) );
switch( LOWORD(wParam) )
{
case IDC_PAKTYPE:
if( HIWORD (wParam) == CBN_SELCHANGE )
{
i = SendMessage( hDlgItem, CB_GETCURSEL, 0, 0 );
g_ivConfig->Controllers[g_ivConfig->ChosenTab].PakType = SendMessage( hDlgItem, CB_GETITEMDATA, i, 0 );
ControllerPakTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
}
return TRUE;
case IDC_RAWMODE:
g_ivConfig->Controllers[g_ivConfig->ChosenTab].fRawData = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
ControllerPakTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
return TRUE;
default:
return FALSE;
}
case WM_USER_UPDATE:
CheckDlgButton( hDlg, IDC_RAWMODE, g_ivConfig->Controllers[g_ivConfig->ChosenTab].fRawData ? BST_CHECKED : BST_UNCHECKED );
// Set drop down list
2020-02-09 11:36:49 +00:00
hDlgItem = GetDlgItem( hDlg, IDC_PAKTYPE );
if( g_ivConfig->Controllers[g_ivConfig->ChosenTab].fRawData &&
!lstrcmp( g_ivConfig->FFDevices[g_ivConfig->ChosenTab].szProductName, _T(STRING_ADAPTOID) ) &&
!bAdaptoidInList )
{
// Add Adaptoid pak to list
2020-02-09 11:36:49 +00:00
LoadString( g_hResourceDLL, IDS_P_ADAPTOIDPAK, tszMsg, DEFAULT_BUFFER );
i = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)tszMsg );
SendMessage( hDlgItem, CB_SETITEMDATA, i, PAK_ADAPTOID );
bAdaptoidInList = true;
}
if( bAdaptoidInList &&
( lstrcmp( g_ivConfig->FFDevices[g_ivConfig->ChosenTab].szProductName, _T(STRING_ADAPTOID) ) ||
!g_ivConfig->Controllers[g_ivConfig->ChosenTab].fRawData ))
{
// Remove Adaptoid pak from list
2020-02-09 11:36:49 +00:00
i = SendMessage( hDlgItem, CB_GETCOUNT, 0, 0 ) - 1;
while(( i >= 0 ))
{
j = SendMessage( hDlgItem, CB_GETITEMDATA, i, 0 );
if( j == PAK_ADAPTOID )
{
SendMessage( hDlgItem, CB_DELETESTRING, i, 0 );
i = -1;
}
i--;
}
bAdaptoidInList = false;
}
i = SendMessage( hDlgItem, CB_GETCOUNT, 0, 0 ) - 1;
while(( i >= 0 ))
{
bByte = (BYTE)SendMessage( hDlgItem, CB_GETITEMDATA, i, 0 );
if( g_ivConfig->Controllers[g_ivConfig->ChosenTab].PakType == bByte )
{
SendMessage( hDlgItem, CB_SETCURSEL, i, 0 );
i = -10;
}
else
i--;
}
if( i != -10 )
SendMessage( hDlgItem, CB_SETCURSEL, 0, 0 );
// Update pak display
2020-02-09 11:36:49 +00:00
if( g_ivConfig->Controllers[g_ivConfig->ChosenTab].fRawData )
{
i = SendMessage( GetDlgItem( hDlg, IDC_PAKTYPE ), CB_GETCURSEL, 0, 0 );
bByte = (BYTE)SendMessage( hDlgItem, CB_GETITEMDATA, i, 0 );
}
else
bByte = PAK_NONRAW;
if( bByte == bCurrentPak && hPakWindow )
SendMessage( hPakWindow, WM_USER_UPDATE, 0, 0 );
else
{
if( hPakWindow )
DestroyWindow( hPakWindow );
hDlgItem = GetDlgItem( hDlg, IDC_PAKAREA );
switch( bByte )
{
case PAK_MEM:
hPakWindow = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_PAK_MEMPAK), hDlg, (DLGPROC)MemPakProc);
break;
case PAK_RUMBLE:
hPakWindow = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_PAK_RUMBLE), hDlg, (DLGPROC)RumblePakProc);
break;
case PAK_TRANSFER:
hPakWindow = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_PAK_TRANSFER), hDlg, (DLGPROC)TransferPakProc);
break;
case PAK_ADAPTOID:
hPakWindow = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_PAK_ADAPTOID), hDlg, (DLGPROC)PakProc);
break;
case PAK_VOICE:
case PAK_NONRAW:
case PAK_NONE:
default:
hPakWindow = CreateDialog(g_hResourceDLL, MAKEINTRESOURCE(IDD_PAK_TEXT), hDlg, (DLGPROC)PakProc);
}
if( hPakWindow )
{
RECT rectProp, rectMain; // Need to know the position of the calling tab window relative to its parent
2020-02-09 11:36:49 +00:00
GetWindowRect( hDlg, &rectMain );
GetWindowRect( hDlgItem, &rectProp );
MoveWindow( hPakWindow, rectProp.left - rectMain.left, rectProp.top - rectMain.top, rectProp.right - rectProp.left, rectProp.bottom - rectProp.top, FALSE );
ShowWindow( hPakWindow, SW_SHOW );
}
bCurrentPak = bByte;
}
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK PakProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
TCHAR tszLineOne[DEFAULT_BUFFER] = _T(""), tszLineTwo[DEFAULT_BUFFER] = _T("");
TCHAR *pszDescription[2] = { tszLineOne, tszLineTwo };
bool bRAW;
switch(uMsg)
{
case WM_INITDIALOG:
PakProc( hDlg, WM_USER_UPDATE, 0, 0 );
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_USER_UPDATE:
bRAW = g_ivConfig->Controllers[g_ivConfig->ChosenTab].fRawData ? 1 : 0;
switch( g_ivConfig->Controllers[g_ivConfig->ChosenTab].PakType )
{
case PAK_MEM:
LoadString( g_hResourceDLL, IDS_P_MEM_NORAW, pszDescription[0], DEFAULT_BUFFER );
break;
case PAK_RUMBLE:
LoadString( g_hResourceDLL, IDS_P_RUMBLE_NORAW, pszDescription[0], DEFAULT_BUFFER );
break;
case PAK_TRANSFER:
LoadString( g_hResourceDLL, IDS_P_TRANSFER_NORAW, pszDescription[0], DEFAULT_BUFFER );
break;
case PAK_VOICE:
LoadString( g_hResourceDLL, IDS_P_VOICE_RAW, pszDescription[1], DEFAULT_BUFFER );
pszDescription[0] = pszDescription[1];
break;
case PAK_ADAPTOID:
LoadString( g_hResourceDLL, IDS_P_ADAPTOID_NORAW, pszDescription[0], DEFAULT_BUFFER );
break;
case PAK_NONE:
default:
LoadString( g_hResourceDLL, IDS_P_NONE_RAWNORAW, pszDescription[1], DEFAULT_BUFFER );
pszDescription[0] = pszDescription[1];
}
SendMessage( GetDlgItem( hDlg, IDT_PAKDESC ), WM_SETTEXT, 0, (LPARAM)pszDescription[bRAW] );
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK MemPakProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
static TCHAR *pszMemPakFile;
static WORD wMemPakState;
static int iSelectedNote;
TCHAR szBuffer[MAX_PATH+1], szTemp[MAX_PATH+1];
HWND hDlgItem;
long i,j;
switch(uMsg)
{
case WM_INITDIALOG:
if( g_bRunning )
{
EnableWindow( GetDlgItem( hDlg, IDC_CHGDIR ), FALSE );
LoadString( g_hResourceDLL, IDS_P_MEM_NOCHANGE, szBuffer, MAX_PATH + 1 );
SendMessage( GetDlgItem( hDlg, IDC_CHGDIR ), WM_SETTEXT, 0, (LPARAM)szBuffer );
}
iSelectedNote = -1;
// Browser
hDlgItem = GetDlgItem( hDlg, IDC_MEMPAKBROWSER );
LVCOLUMN lvColumn;
lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.cx = 147;
LoadString( g_hResourceDLL, IDS_P_MEM_NAME, szBuffer, MAX_PATH + 1 );
lvColumn.pszText = szBuffer;
ListView_InsertColumn( hDlgItem, 0, &lvColumn );
lvColumn.fmt = LVCFMT_CENTER | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvColumn.cx = 70;
lvColumn.iSubItem = 1;
LoadString( g_hResourceDLL, IDS_P_MEM_REGION, szBuffer, MAX_PATH + 1 );
lvColumn.pszText = szBuffer;
ListView_InsertColumn( hDlgItem, 1, &lvColumn );
lvColumn.cx = 50;
lvColumn.iSubItem = 2;
LoadString( g_hResourceDLL, IDS_P_MEM_BLOCKS, szBuffer, MAX_PATH + 1 );
lvColumn.pszText = szBuffer;
ListView_InsertColumn( hDlgItem, 2, &lvColumn );
ListView_SetExtendedListViewStyle( hDlgItem, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP );
MemPakProc( hDlg, WM_USER_UPDATE, 0, 0 ); // Setting values
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
hDlgItem = GetDlgItem( hDlg, LOWORD(wParam) );
switch( LOWORD(wParam) )
{
TCHAR tszTitle[DEFAULT_BUFFER], tszText[DEFAULT_BUFFER];
case IDC_MEMPAKLIST:
if( HIWORD(wParam) == LBN_SELCHANGE )
{
i = SendMessage( hDlgItem, LB_GETCURSEL, 0, 0 );
SendMessage( hDlgItem, LB_GETTEXT, i, (LPARAM)pszMemPakFile );
MemPakProc( hDlg, WM_USER_UPDATE, 1, 0 );
}
return TRUE;
case IDC_BROWSE:
lstrcpyn( szBuffer, pszMemPakFile, ARRAYSIZE(szBuffer) );
if( BrowseFile( hDlg, szBuffer, BF_MEMPAK, BF_LOAD ))
{
if( !CheckFileExists( szBuffer ) )
{
BYTE aMemPak[PAK_MEM_SIZE];
FormatMemPak( aMemPak );
WriteMemPakFile( szBuffer, aMemPak, true );
}
if( CheckFileExists( szBuffer ) )
{
lstrcpyn( pszMemPakFile, szBuffer, MAX_PATH );
MemPakProc( hDlg, WM_USER_UPDATE, 0, 0 );
}
}
return TRUE;
case IDC_CHGDIR:
if (DialogBox(g_hResourceDLL, MAKEINTRESOURCE(IDD_FOLDERS), hDlg, (DLGPROC)FoldersDialogProc) == TRUE)
MemPakProc( hDlg, WM_USER_UPDATE, 0, 0 );
return TRUE;
case IDC_DELMEMPAK:
LoadString( g_hResourceDLL, IDS_DLG_DELETEPAK, tszText, DEFAULT_BUFFER );
LoadString( g_hResourceDLL, IDS_DLG_MSG_TITLE, tszTitle, DEFAULT_BUFFER );
if( MessageBox( hDlg, tszText, tszTitle, MB_OKCANCEL | MB_ICONQUESTION ) == IDOK )
{
GetAbsoluteFileName( szBuffer, pszMemPakFile, DIRECTORY_MEMPAK );
DeleteFile( szBuffer );
pszMemPakFile[0] = '\0';
MemPakProc( hDlg, WM_USER_UPDATE, 0, 0 );
}
return TRUE;
case IDC_FORMATMEMPAK:
LoadString( g_hResourceDLL, IDS_DLG_FORMATPAK, tszText, DEFAULT_BUFFER );
LoadString( g_hResourceDLL, IDS_DLG_MSG_TITLE, tszTitle, DEFAULT_BUFFER );
if( MessageBox( hDlg, tszText, tszTitle, MB_OKCANCEL | MB_ICONQUESTION ) == IDOK )
{
GetAbsoluteFileName( szBuffer, pszMemPakFile, DIRECTORY_MEMPAK );
BYTE aMemPak[PAK_MEM_SIZE];
FormatMemPak( aMemPak );
WriteMemPakFile( szBuffer, aMemPak, false );
MemPakProc( hDlg, WM_USER_UPDATE, 1, 0 );
}
return TRUE;
case IDC_SAVENOTE:
{
BYTE aMemPak[PAK_MEM_SIZE];
if( g_bRunning && ( HIWORD(wMemPakState) == MPAK_INUSE )
&& g_pcControllers[g_ivConfig->ChosenTab].pPakData
&& ( *(BYTE*)g_pcControllers[g_ivConfig->ChosenTab].pPakData == PAK_MEM ))
{
EnterCriticalSection( &g_critical );
CopyMemory( aMemPak, ((MEMPAK*)g_pcControllers[g_ivConfig->ChosenTab].pPakData)->aMemPakData, PAK_MEM_SIZE );
LeaveCriticalSection( &g_critical );
}
else
{
GetAbsoluteFileName( szBuffer, pszMemPakFile, DIRECTORY_MEMPAK );
ReadMemPakFile( szBuffer, aMemPak, false );
}
int iChars = TranslateNotes( &aMemPak[0x300 + iSelectedNote * 32 + 0x10], szBuffer, 16 );
if( TranslateNotes( &aMemPak[0x300 + iSelectedNote * 32 + 0x0C], &szBuffer[iChars + 1], 1 ) )
szBuffer[iChars] = _T('_');
if( BrowseFile( hDlg, szBuffer, BF_NOTE, BF_SAVE ))
{
TCHAR szAbsoluteMemPak[MAX_PATH+1];
GetAbsoluteFileName( szAbsoluteMemPak, pszMemPakFile, DIRECTORY_MEMPAK );
SaveNoteFileA( aMemPak, iSelectedNote, szBuffer );
}
}
return TRUE;
case IDC_INSERTNOTE:
{
GetAbsoluteFileName( szBuffer, pszMemPakFile, DIRECTORY_MEMPAK );
BYTE aMemPak[PAK_MEM_SIZE];
ReadMemPakFile( szBuffer, aMemPak, false );
szBuffer[0] = '\0';
if( BrowseFile( hDlg, szBuffer, BF_NOTE, BF_LOAD ))
{
if( InsertNoteFile( aMemPak, szBuffer ) )
{
GetAbsoluteFileName( szBuffer, pszMemPakFile, DIRECTORY_MEMPAK );
WriteMemPakFile( szBuffer, aMemPak, false );
MemPakProc( hDlg, WM_USER_UPDATE, 1, 0 );
}
}
}
return TRUE;
case IDC_DELETENOTE:
LoadString( g_hResourceDLL, IDS_DLG_DELETENOTE, tszText, DEFAULT_BUFFER );
LoadString( g_hResourceDLL, IDS_DLG_MSG_TITLE, tszTitle, DEFAULT_BUFFER );
if( MessageBox( hDlg, tszText, tszTitle, MB_OKCANCEL | MB_ICONQUESTION ) == IDOK )
{
GetAbsoluteFileName( szBuffer, pszMemPakFile, DIRECTORY_MEMPAK );
BYTE aMemPak[PAK_MEM_SIZE];
ReadMemPakFile( szBuffer, aMemPak, false );
if( RemoveNote( aMemPak, iSelectedNote ) )
{
WriteMemPakFile( szBuffer, aMemPak, false );
MemPakProc( hDlg, WM_USER_UPDATE, 1, 0 );
}
}
return TRUE;
default:
return FALSE;
}
case WM_NOTIFY:
switch( ((LPNMHDR)lParam)->idFrom )
{
case IDC_MEMPAKBROWSER:
switch( ((LPNMHDR)lParam)->code )
{
case LVN_ITEMCHANGED:
if( ((LPNMLISTVIEW)lParam)->uNewState & LVIS_SELECTED )
{
iSelectedNote = ((LPNMLISTVIEW)lParam)->lParam;
if( HIBYTE(wMemPakState) & MPAK_READABLE )
EnableWindow( GetDlgItem( hDlg, IDC_SAVENOTE ), TRUE );
if( HIBYTE(wMemPakState) & MPAK_WRITEABLE )
EnableWindow( GetDlgItem( hDlg, IDC_DELETENOTE ), TRUE );
}
else
{
iSelectedNote = -1;
EnableWindow( GetDlgItem( hDlg, IDC_SAVENOTE ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_DELETENOTE ), FALSE );
}
return TRUE;
default:
return FALSE;
}
default:
return FALSE;
}
case WM_USER_UPDATE:
pszMemPakFile = g_ivConfig->Controllers[g_ivConfig->ChosenTab].szMempakFile;
iSelectedNote = -1;
// Memory pak list window
2020-02-09 11:36:49 +00:00
if( wParam == 0 && lParam == 0 )
{
hDlgItem = GetDlgItem( hDlg, IDC_MEMPAKLIST );
SendMessage( hDlgItem, LB_RESETCONTENT, 0, 0 );
SendFilestoList( hDlgItem, FILIST_MEM );
if( pszMemPakFile[1] == ':' || ( pszMemPakFile[1] == '\\' && pszMemPakFile[0] == '\\' ))
{
GetDirectory( szBuffer, DIRECTORY_MEMPAK );
i = lstrlen( szBuffer );
if( !_tcsncmp( szBuffer, pszMemPakFile, i ))
{
lstrcpyn( szBuffer, &pszMemPakFile[i], MAX_PATH );
lstrcpyn( pszMemPakFile, szBuffer, MAX_PATH );
}
}
j = -1;
if( !( pszMemPakFile[1] == ':' || ( pszMemPakFile[1] == '\\' && pszMemPakFile[0] == '\\' )) )
{
i = SendMessage( hDlgItem, LB_FINDSTRINGEXACT, (WPARAM)(-1), (LPARAM)pszMemPakFile );
if( i != LB_ERR )
j = i;
}
SendMessage( hDlgItem, LB_SETCURSEL, j, 0 );
}
// Memory pak list window end
2020-02-09 11:36:49 +00:00
// Memory pak full path and name
2020-02-09 11:36:49 +00:00
GetAbsoluteFileName( szBuffer, pszMemPakFile, DIRECTORY_MEMPAK );
// Memory pak browser
2020-02-09 11:36:49 +00:00
ListView_DeleteAllItems( GetDlgItem( hDlg, IDC_MEMPAKBROWSER ));
if( (!lstrcmpi( &szBuffer[lstrlen(szBuffer)-4], _T(".mpk") ))
|| (!lstrcmpi( &szBuffer[lstrlen(szBuffer)-4], _T(".n64") )))
{
BYTE aMemPakHeader[0x500];
bool bMemPakUsed = false;
// First, if we're running an emulation instance we need to make sure we haven't selected a file that's currently in use
2020-02-09 11:36:49 +00:00
if (g_bRunning)
{
TCHAR szMemPakFile[MAX_PATH+1];
for( i = 0; i < 4; ++i )
{
if( g_pcControllers[i].pPakData && ( *(BYTE*)g_pcControllers[i].pPakData == PAK_MEM ) && !((LPMEMPAK)g_pcControllers[i].pPakData)->fReadonly )
{
GetAbsoluteFileName( szMemPakFile, g_pcControllers[i].szMempakFile, DIRECTORY_MEMPAK );
if( !lstrcmp( szMemPakFile, szBuffer ))
{
// Grab the file info from memory instead of the file...but keep in mind we can't do anything dangerous with it
2020-02-09 11:36:49 +00:00
EnterCriticalSection( &g_critical );
wMemPakState = ShowMemPakContent( ((MEMPAK*)g_pcControllers[i].pPakData)->aMemPakData, GetDlgItem( hDlg, IDC_MEMPAKBROWSER ));
LeaveCriticalSection( &g_critical );
if (HIBYTE(wMemPakState) == MPAK_OK)
{
LoadString( g_hResourceDLL, IDS_P_MEM_INUSE, szTemp, MAX_PATH + 1 );
wsprintf( szBuffer, szTemp, LOBYTE(wMemPakState) );
wMemPakState = MAKEWORD( MPAK_READABLE, MPAK_INUSE );
}
bMemPakUsed = true;
}
}
}
}
if( !bMemPakUsed )
{
HANDLE hFile;
hFile = CreateFile( szBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
if ( hFile != INVALID_HANDLE_VALUE )
{
DWORD dwFileSize = GetFileSize( hFile, NULL );
DWORD dwCorrectFileSize = PAK_MEM_SIZE;
TCHAR *pcPoint = _tcsrchr( szBuffer, _T('.') );
if( !lstrcmpi( pcPoint, _T(".n64") ) )
{
SetFilePointer( hFile, PAK_MEM_DEXOFFSET, NULL, FILE_BEGIN );
dwCorrectFileSize += PAK_MEM_DEXOFFSET;
}
else
SetFilePointer( hFile, 0L, NULL, FILE_BEGIN );
if( dwFileSize > ( dwCorrectFileSize - 0x7500 ))
{
DWORD dwBytesRead;
ReadFile( hFile, aMemPakHeader, 0x500, &dwBytesRead, NULL);
ListView_DeleteAllItems( GetDlgItem( hDlg, IDC_MEMPAKBROWSER ));
wMemPakState = ShowMemPakContent( aMemPakHeader, GetDlgItem( hDlg, IDC_MEMPAKBROWSER ));
}
else
wMemPakState = MAKEWORD( 0, MPAK_DAMAGED );
if( HIBYTE( wMemPakState ) == MPAK_OK &&
dwFileSize != dwCorrectFileSize )
wMemPakState = MAKEWORD( LOBYTE( wMemPakState ), MPAK_WRONGSIZE );
CloseHandle( hFile );
}
else
wMemPakState = MAKEWORD( 0, MPAK_ERROR );
}
}
else
wMemPakState = MAKEWORD( 0, MPAK_NOSELECTION );
switch( HIBYTE(wMemPakState) )
{
case MPAK_OK:
LoadString( g_hResourceDLL, IDS_P_MEM_BLOCKSFREE, szTemp, MAX_PATH + 1 );
wsprintf( szBuffer, szTemp, LOBYTE(wMemPakState) );
break;
case MPAK_INUSE:
// Text field already set
2020-02-09 11:36:49 +00:00
break;
case MPAK_WRONGSIZE:
LoadString( g_hResourceDLL, IDS_P_MEM_WRONGSIZE, szTemp, MAX_PATH + 1 );
wsprintf( szBuffer, szTemp, LOBYTE(wMemPakState) );
break;
case MPAK_NOSELECTION:
LoadString( g_hResourceDLL, IDS_P_MEM_NONESELECTED, szBuffer, MAX_PATH + 1 );
break;
case MPAK_DAMAGED:
LoadString( g_hResourceDLL, IDS_P_MEM_DAMAGED, szBuffer, MAX_PATH + 1 );
break;
case MPAK_ERROR:
default:
{
LoadString( g_hResourceDLL, IDS_P_MEM_ERROR, szTemp, MAX_PATH + 1 );
DWORD dwError = GetLastError();
DWORD dwLength = wsprintf( szBuffer, szTemp, dwError );
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError , 0, &szBuffer[dwLength], ARRAYSIZE(szBuffer) - dwLength - 1, NULL );
}
break;
}
SendMessage( GetDlgItem( hDlg, IDT_MEMPAKSTATE ), WM_SETTEXT, 0, (LPARAM)szBuffer );
if( HIBYTE(wMemPakState) & MPAK_FORMATABLE )
{
EnableWindow( GetDlgItem( hDlg, IDC_FORMATMEMPAK ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDC_DELMEMPAK ), TRUE );
}
else
{
EnableWindow( GetDlgItem( hDlg, IDC_FORMATMEMPAK ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_DELMEMPAK ), FALSE );
}
if( HIBYTE(wMemPakState) & MPAK_WRITEABLE )
EnableWindow( GetDlgItem( hDlg, IDC_INSERTNOTE ), TRUE );
else
EnableWindow( GetDlgItem( hDlg, IDC_INSERTNOTE ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_SAVENOTE ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_DELETENOTE ), FALSE );
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK RumblePakProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
static BOOL bNewRumbleTyp = true;
IFDEVICE *pifDevice = &g_ivConfig->FFDevices[g_ivConfig->ChosenTab];
CONTROLLER *pcController = &g_ivConfig->Controllers[g_ivConfig->ChosenTab];
TCHAR szBuffer[DEFAULT_BUFFER], szTemp[DEFAULT_BUFFER];
HWND hDlgItem;
long i = 0,j;
switch(uMsg)
{
case WM_INITDIALOG:
hDlgItem = GetDlgItem( hDlg, IDC_RUMBLESTRENGTH );
SendMessage( hDlgItem, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG( 0, 100 ));
SendMessage( hDlgItem, TBM_SETTICFREQ, (WPARAM) 10, 0 );
SendMessage( hDlgItem, TBM_SETPAGESIZE, (WPARAM) 0, 1 );
RumblePakProc( hDlg, WM_USER_UPDATE, 0, 0 );
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
hDlgItem = GetDlgItem( hDlg, LOWORD(wParam) );
switch( LOWORD(wParam) )
{
case IDC_CTRDEVICE:
if( HIWORD(wParam) == CBN_SELCHANGE )
{
i = SendMessage( hDlgItem, CB_GETCURSEL, 0, 0 );
j = SendMessage( hDlgItem, CB_GETITEMDATA, i, 0 );
EnterCriticalSection(&g_critical);
if( j == -1 )
{
pifDevice->bProductCounter = 0;
pifDevice->szProductName[0] = '\0';
}
else
{
pifDevice->bProductCounter = g_devList[j].bProductCounter;
lstrcpyn( pifDevice->szProductName, g_devList[j].szProductName, sizeof(pifDevice->szProductName) / sizeof(TCHAR) );
}
LeaveCriticalSection(&g_critical);
RumblePakProc( hDlg, WM_USER_UPDATE, 0, 0 ); // Enabling/disabling rumble options
2020-02-09 11:36:49 +00:00
}
return TRUE;
// The following three cases use fall through assignment
2020-02-09 11:36:49 +00:00
case IDC_RUMBLE1:
if( LOWORD(wParam) == IDC_RUMBLE1 )
i = RUMBLE_EFF1;
case IDC_RUMBLE2:
if( LOWORD(wParam) == IDC_RUMBLE2 )
i = RUMBLE_EFF2;
case IDC_RUMBLE3:
if( LOWORD(wParam) == IDC_RUMBLE3 )
i = RUMBLE_EFF3;
if(( HIWORD(wParam) == BN_CLICKED ) &&
( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED ))
{
pcController->bRumbleTyp = (BYTE)i;
bNewRumbleTyp = true;
}
return TRUE;
case IDC_VISUALRUMBLE:
pcController->fVisualRumble = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_RUMBLETEST:
if ( !g_pConfigEffect || bNewRumbleTyp )
{
EnterCriticalSection(&g_critical);
ReleaseEffect( g_pConfigEffect );
if ( !CreateEffectHandle(g_hMainDialog, g_pConfigDevice, g_pConfigEffect, pcController->bRumbleTyp, pcController->bRumbleStrength) )
{
DebugWriteA("Interface: CreateEffectHandle failed\n");
}
bNewRumbleTyp = false;
LeaveCriticalSection(&g_critical);
}
g_pConfigDevice->Acquire();
{
HRESULT hRslt = g_pConfigEffect->Start(1, 0);
if (hRslt != DI_OK )
{
switch (hRslt)
{
case DIERR_INCOMPLETEEFFECT:
DebugWriteA("Test rumble: DIError: incomplete effect.\n");
2020-02-09 11:36:49 +00:00
break;
case DIERR_INVALIDPARAM:
DebugWriteA("Test rumble: DIError: invalid parameter.\n");
2020-02-09 11:36:49 +00:00
break;
case DIERR_NOTEXCLUSIVEACQUIRED:
DebugWriteA("Test rumble: DIError: not exclusive acquired.\n");
2020-02-09 11:36:49 +00:00
break;
case DIERR_NOTINITIALIZED:
DebugWriteA("Test rumble: DIError: not initialized.\n");
2020-02-09 11:36:49 +00:00
break;
case DIERR_UNSUPPORTED:
DebugWriteA("Test rumble: DIError: unsupported.\n");
2020-02-09 11:36:49 +00:00
break;
default:
DebugWriteA("Test rumble: DIError: undocumented: %lX\n", hRslt);
2020-02-09 11:36:49 +00:00
}
}
else
DebugWriteA("Test rumble: OK\n");
2020-02-09 11:36:49 +00:00
}
return TRUE;
default:
return FALSE;
}
case WM_HSCROLL: // Track bars
2020-02-09 11:36:49 +00:00
case WM_VSCROLL:
i = GetWindowLong( (HWND)lParam, GWL_ID );
switch( i )
{
case IDC_RUMBLESTRENGTH:
pcController->bRumbleStrength = (BYTE)SendMessage( (HWND)lParam, TBM_GETPOS, 0, 0 );
LoadString( g_hResourceDLL, IDS_D_RUMBLESTR, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bRumbleStrength );
SendMessage( GetDlgItem( hDlg, IDT_RUMBLESTRENGTH ), WM_SETTEXT , 0, (LPARAM)szBuffer );
bNewRumbleTyp = true;
return TRUE;
default:
return FALSE;
}
case WM_USER_UPDATE:
// Filling drop down list with devices
2020-02-09 11:36:49 +00:00
hDlgItem = GetDlgItem( hDlg, IDC_CTRDEVICE );
SendMessage (hDlgItem, CB_RESETCONTENT, 0, 0); // Hack: Yeah this isn't the best way to do this, but it works.
2020-02-09 11:36:49 +00:00
LoadString( g_hResourceDLL, IDS_P_R_NODEVICE, szBuffer, DEFAULT_BUFFER );
j = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)szBuffer );
SendMessage( hDlgItem, CB_SETITEMDATA, j, -1 );
for( i = 0; i < g_nDevices; i++ )
{
bool bMatch = false;
// If device is not already set as a force feedback device in some other tab
2020-02-09 11:36:49 +00:00
for( int m = 0; m < 4; m++)
{
if( g_ivConfig->ChosenTab != m)
if (g_devList[i].bProductCounter == g_ivConfig->FFDevices[m].bProductCounter && !lstrcmp( g_devList[i].szProductName, g_ivConfig->FFDevices[m].szProductName ) )
bMatch = true;
}
if (!bMatch && g_devList[i].bEffType != 0 )
{
if( g_devList[i].bProductCounter == 0 )
lstrcpyn( szBuffer, g_devList[i].szProductName, ARRAYSIZE(szBuffer) );
else
wsprintf( szBuffer, _T("%s %i"), g_devList[i].szProductName, g_devList[i].bProductCounter );
j = SendMessage( hDlgItem, CB_ADDSTRING, 0, (LPARAM)szBuffer );
SendMessage( hDlgItem, CB_SETITEMDATA, j, i );
}
}
// Drop down list end
2020-02-09 11:36:49 +00:00
EnterCriticalSection(&g_critical);
j = FindDeviceinList( pifDevice->szProductName, pifDevice->bProductCounter, true );
hDlgItem = GetDlgItem( hDlg, IDC_CTRDEVICE );
ReleaseEffect( g_pConfigEffect );
ReleaseDevice( g_pConfigDevice );
if( j == -1 || !g_devList[j].bEffType)
{
SendMessage( hDlgItem, CB_SETCURSEL, 0, 0 ); // Set "none"
2020-02-09 11:36:49 +00:00
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLE1 ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLE2 ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLE3 ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLESTRENGTH ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDT_RUMBLESTRENGTH ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLETEST ), FALSE );
}
else
{
if (! GetInputDevice( g_hMainDialog, g_pConfigDevice, g_devList[j].guidInstance, g_devList[j].dwDevType, DIB_FF ) )
{
g_pConfigDevice = NULL;
DebugWriteA("Could not GetInputDevice in user update, RumblePakProc.\n");
}
else
{
DebugWriteA("GetInputDevice in RumblePakProc: OK\n");
}
// Drop down list
2020-02-09 11:36:49 +00:00
if( g_devList[j].bProductCounter == 0 )
i = SendMessage( hDlgItem, CB_FINDSTRINGEXACT, (WPARAM)(-1), (LPARAM)g_devList[j].szProductName );
else
{
wsprintf( szBuffer, _T("%s %i"), g_devList[j].szProductName, g_devList[j].bProductCounter );
i = SendMessage( hDlgItem, CB_FINDSTRINGEXACT, (WPARAM)(-1), (LPARAM)szBuffer ); // Search index of device string
2020-02-09 11:36:49 +00:00
}
SendMessage( hDlgItem, CB_SETCURSEL, i, 0 ); // Select the right string
2020-02-09 11:36:49 +00:00
if( g_devList[j].bEffType & RUMBLE_EFF1 )
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLE1 ), TRUE );
else
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLE1 ), FALSE );
if( g_devList[j].bEffType & RUMBLE_EFF2 )
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLE2 ), TRUE );
else
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLE2 ), FALSE );
if( g_devList[j].bEffType & RUMBLE_EFF3 )
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLE3 ), TRUE );
else
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLE3 ), FALSE );
if( ( g_devList[j].bEffType & RUMBLE_EFF1 ) ||
( g_devList[j].bEffType & RUMBLE_EFF2 ))
{
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLESTRENGTH ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDT_RUMBLESTRENGTH ), TRUE );
}
else
{
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLESTRENGTH ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDT_RUMBLESTRENGTH ), FALSE );
}
if( g_devList[j].bEffType != RUMBLE_NONE )
{
// if (!CreateEffectHandle(g_hMainDialog, g_pConfigDevice, g_pConfigEffect, pcController->bRumbleTyp, pcController->bRumbleStrength) )
// {
// DebugWriteA("Interface: CreateEffectHandle failed\n");
// }
bNewRumbleTyp = true;
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLETEST ), TRUE );
}
else
EnableWindow( GetDlgItem( hDlg, IDC_RUMBLETEST ), FALSE );
}
LeaveCriticalSection(&g_critical);
if( pcController->bRumbleTyp == RUMBLE_EFF1 )
CheckDlgButton( hDlg, IDC_RUMBLE1, BST_CHECKED );
else
CheckDlgButton( hDlg, IDC_RUMBLE1, BST_UNCHECKED );
if( pcController->bRumbleTyp == RUMBLE_EFF2 )
CheckDlgButton( hDlg, IDC_RUMBLE2, BST_CHECKED );
else
CheckDlgButton( hDlg, IDC_RUMBLE2, BST_UNCHECKED );
if( pcController->bRumbleTyp == RUMBLE_EFF3 )
CheckDlgButton( hDlg, IDC_RUMBLE3, BST_CHECKED );
else
CheckDlgButton( hDlg, IDC_RUMBLE3, BST_UNCHECKED );
CheckDlgButton( hDlg, IDC_VISUALRUMBLE, pcController->fVisualRumble ? BST_CHECKED : BST_UNCHECKED );
// Track bars
2020-02-09 11:36:49 +00:00
SendMessage( GetDlgItem( hDlg, IDC_RUMBLESTRENGTH ), TBM_SETPOS, TRUE, pcController->bRumbleStrength );
LoadString( g_hResourceDLL, IDS_D_RUMBLESTR, szTemp, DEFAULT_BUFFER );
wsprintf( szBuffer, szTemp, pcController->bRumbleStrength );
SendMessage( GetDlgItem( hDlg, IDT_RUMBLESTRENGTH ), WM_SETTEXT , 0, (LPARAM)szBuffer );
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK TransferPakProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
static LPTSTR pszGBRomFile = NULL;
static LPTSTR pszGBSaveFile = NULL;
TCHAR tszMsg[DEFAULT_BUFFER];
switch(uMsg)
{
case WM_INITDIALOG:
if( g_bRunning )
{
EnableWindow( GetDlgItem( hDlg, IDC_CHGDIR ), FALSE );
LoadString( g_hResourceDLL, IDS_P_TRANS_NOCHANGE, tszMsg, DEFAULT_BUFFER );
SendMessage( GetDlgItem( hDlg, IDC_CHGDIR ), WM_SETTEXT, 0, (LPARAM)tszMsg );
}
TransferPakProc( hDlg, WM_USER_UPDATE, 0, 0 ); // Setting values
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDC_GBROM_EDIT:
if( HIWORD(wParam) == EN_CHANGE )
GetDlgItemText( hDlg, IDC_GBROM_EDIT, pszGBRomFile, ARRAYSIZE(g_ivConfig->Controllers->szTransferRom) );
return TRUE;
case IDC_GBSAVE_EDIT:
if( HIWORD(wParam) == EN_CHANGE )
GetDlgItemText( hDlg, IDC_GBSAVE_EDIT, pszGBSaveFile, ARRAYSIZE(g_ivConfig->Controllers->szTransferSave) );
return TRUE;
case IDC_GBROM_BROWSE:
{
TCHAR szBuffer[MAX_PATH+1];
GetAbsoluteFileName( szBuffer, pszGBRomFile, DIRECTORY_GBROMS );
if( BrowseFile( hDlg, szBuffer, BF_GBROM, BF_LOAD ))
{
lstrcpyn( pszGBRomFile, szBuffer, ARRAYSIZE(g_ivConfig->Controllers->szTransferRom) );
TransferPakProc( hDlg, WM_USER_UPDATE, 0, 0 );
}
}
return TRUE;
case IDC_GBSAVE_BROWSE:
{
TCHAR szBuffer[MAX_PATH+1];
GetAbsoluteFileName( szBuffer, pszGBSaveFile, DIRECTORY_GBSAVES );
if( BrowseFile( hDlg, szBuffer, BF_GBSAVE, BF_LOAD ))
{
lstrcpyn( pszGBSaveFile, szBuffer, ARRAYSIZE(g_ivConfig->Controllers->szTransferSave) );
TransferPakProc( hDlg, WM_USER_UPDATE, 0, 0 );
}
}
return TRUE;
case IDC_CHGDIR:
if (DialogBox(g_hResourceDLL, MAKEINTRESOURCE(IDD_FOLDERS), hDlg, (DLGPROC)FoldersDialogProc) == TRUE)
TransferPakProc( hDlg, WM_USER_UPDATE, 0, 0 );
return TRUE;
default:
return FALSE;
}
case WM_USER_UPDATE:
pszGBRomFile = g_ivConfig->Controllers[g_ivConfig->ChosenTab].szTransferRom;
pszGBSaveFile = g_ivConfig->Controllers[g_ivConfig->ChosenTab].szTransferSave;
SetDlgItemText( hDlg, IDC_GBROM_EDIT, pszGBRomFile );
SetDlgItemText( hDlg, IDC_GBSAVE_EDIT, pszGBSaveFile );
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK ShortcutsTabProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
static bool bScanRunning;
static DWORD dwButtonID[3];
static DWORD dwCounter;
static HWND hFocus = NULL;
static int iPlayer = 5; // Hack: Player "5" is obviously out of bounds, so indicates no control has been set
2020-02-09 11:36:49 +00:00
long i;
static HWND hBlocker = NULL;
TCHAR szBuffer[40];
switch(uMsg)
{
case WM_INITDIALOG:
bScanRunning = false;
iPlayer = 5;
ShortcutsTabProc( hDlg, WM_USER_UPDATE, 0, 0 ); // Setting values
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDC_SHOWMESSAGES:
g_ivConfig->fDisplayShortPop = ( IsDlgButtonChecked( hDlg, LOWORD(wParam) ) == BST_CHECKED );
return TRUE;
case IDC_LOCKMOUSE:
iPlayer = -1;
case IDC_SETNOPAK_P1:
case IDC_SETMEMPAK_P1:
case IDC_SETRUMBLEPAK_P1:
case IDC_SETTRANSFERPAK_P1:
case IDC_SETADAPTOIDPAK_P1:
case IDC_SWMEMRUMBLE_P1:
case IDC_SWMEMADAPTOID_P1:
if (iPlayer > -1)
iPlayer = 0;
case IDC_SETNOPAK_P2:
case IDC_SETMEMPAK_P2:
case IDC_SETRUMBLEPAK_P2:
case IDC_SETTRANSFERPAK_P2:
case IDC_SETADAPTOIDPAK_P2:
case IDC_SWMEMRUMBLE_P2:
case IDC_SWMEMADAPTOID_P2:
if (iPlayer > 0)
iPlayer = 1;
case IDC_SETNOPAK_P3:
case IDC_SETMEMPAK_P3:
case IDC_SETRUMBLEPAK_P3:
case IDC_SETTRANSFERPAK_P3:
case IDC_SETADAPTOIDPAK_P3:
case IDC_SWMEMRUMBLE_P3:
case IDC_SWMEMADAPTOID_P3:
if (iPlayer > 1)
iPlayer = 2;
case IDC_SETNOPAK_P4:
case IDC_SETMEMPAK_P4:
case IDC_SETRUMBLEPAK_P4:
case IDC_SETTRANSFERPAK_P4:
case IDC_SETADAPTOIDPAK_P4:
case IDC_SWMEMRUMBLE_P4:
case IDC_SWMEMADAPTOID_P4:
if (iPlayer > 2)
iPlayer = 3;
if( bScanRunning )
{
/* bScanRunning = false;
KillTimer( hDlg, TIMER_BUTTON );
if( ((LPBYTE)&g_ivConfig->Shortcuts)[dwButtonID[2]] == VK_ESCAPE )
lstrcpyn( szKeyname, "Unassigned", sizeof(szKeyname) );
else
GetKeyNameText(( MapVirtualKey( ((LPBYTE)&g_ivConfig->Shortcuts)[dwButtonID[2]], 0 ) << 16 ), szKeyname, sizeof(szKeyname) );
SendMessage( GetDlgItem( hDlg, dwButtonID[1] ), WM_SETTEXT, 0, (LPARAM)szKeyname ); */; // do nothing!
}
if( HIWORD(wParam) == BN_CLICKED )
{
EnterCriticalSection(&g_critical);
dwButtonID[0] = LOWORD(wParam);
dwCounter = 0;
GetButtonID( dwButtonID, 0, BSET_SHORTCUTS );
if (hFocus == NULL)
hFocus = SetFocus( NULL );
hBlocker = MakeOverlay();
SetTimer( hDlg, TIMER_BUTTON, INTERVAL_BUTTON, NULL );
bScanRunning = true;
LeaveCriticalSection(&g_critical);
}
return TRUE;
case IDC_SETDEFAULTSC:
{
TCHAR tszTitle[DEFAULT_BUFFER], tszMsg[DEFAULT_BUFFER];
LoadString( g_hResourceDLL, IDS_DLG_SHORTCUTRESTORE, tszMsg, DEFAULT_BUFFER );
LoadString( g_hResourceDLL, IDS_DLG_CONTROLRESTORE_TITLE, tszTitle, DEFAULT_BUFFER );
if( MessageBox( hDlg, tszMsg, tszTitle, MB_OKCANCEL | MB_ICONWARNING ) == IDOK )
{
LoadShortcutsFromResource(true);
ShortcutsTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
}
}
return TRUE;
case IDC_SAVESHORTCUTS:
{
TCHAR szFilename[MAX_PATH+1] = _T( "" );
if( BrowseFile( hDlg, szFilename, BF_SHORTCUTS, BF_SAVE ))
{
FILE * fFile = _tfopen( szFilename, _T("wS") );
if (fFile)
{
fprintf(fFile, "@" STRING_PROFILEVERSION "\n\n");
FormatShortcutsBlock( fFile, false );
fclose(fFile);
}
else
WarningMessage( IDS_ERR_PROFWRITE, MB_OK );
}
}
return TRUE;
case IDC_LOADSHORTCUTS:
{
TCHAR szFilename[MAX_PATH+1] = TEXT( "" );
if( BrowseFile( hDlg, szFilename, BF_SHORTCUTS, BF_LOAD ))
{
DebugWrite(_T("Config interface: Load shortcuts file: %s\n"), szFilename);
if( LoadShortcutsFile( szFilename ))
ShortcutsTabProc( hDlg, WM_USER_UPDATE, 0, 0 );
else
WarningMessage( IDS_ERR_SHORTREAD, MB_OK );
}
}
return TRUE;
default:
return FALSE;
}
case WM_TIMER: // When assigning shortcuts, this gets called every 20ms (or value in INTERVAL_BUTTON)
2020-02-09 11:36:49 +00:00
if( wParam == TIMER_BUTTON && bScanRunning )
{
BUTTON newButton;
i = ScanDevices( &dwCounter, &newButton);
if( i || dwCounter > 500 )
{
bScanRunning = false;
KillTimer( hDlg, TIMER_BUTTON );
EnterCriticalSection(&g_critical);
if( i == SC_SCANESCAPE ) // Scan aborted
{
if (iPlayer == -1)
ZeroMemory(&g_ivConfig->Shortcuts.bMouseLock, sizeof(BUTTON) );
else
ZeroMemory(&g_ivConfig->Shortcuts.Player[iPlayer].aButtons[dwButtonID[2] % SC_TOTAL], sizeof(BUTTON));
}
else if( i == SC_SCANSUCCEED ) // Got a key, mouse click, button press, or axis
2020-02-09 11:36:49 +00:00
if (iPlayer == -1)
g_ivConfig->Shortcuts.bMouseLock = newButton;
else
g_ivConfig->Shortcuts.Player[iPlayer].aButtons[dwButtonID[2] % SC_TOTAL] = newButton;
DestroyWindow( hBlocker );
if (iPlayer == -1)
GetButtonText( g_ivConfig->Shortcuts.bMouseLock, szBuffer );
else
GetButtonText( g_ivConfig->Shortcuts.Player[iPlayer].aButtons[dwButtonID[2] % SC_TOTAL], szBuffer );
iPlayer = 5; // Reset invalid player value
2020-02-09 11:36:49 +00:00
LeaveCriticalSection(&g_critical);
SendMessage( GetDlgItem( hDlg, dwButtonID[1] ), WM_SETTEXT , 0, (LPARAM)szBuffer );
if( hFocus != NULL )
{
SetFocus( hFocus );
hFocus = NULL;
}
}
else
{
if(( dwCounter % 50 ) == 0 )
{
TCHAR tszText[DEFAULT_BUFFER];
LoadString( g_hResourceDLL, IDS_C_POLLING, tszText, DEFAULT_BUFFER );
wsprintf( szBuffer, tszText, 10 - dwCounter / 50 );
SendMessage( GetDlgItem( hDlg, dwButtonID[1] ), WM_SETTEXT , 0, (LPARAM)szBuffer );
}
++dwCounter;
}
return TRUE;
}
else
return FALSE;
case WM_USER_UPDATE:
bScanRunning = false;
KillTimer( hDlg, TIMER_BUTTON );
for ( i = 0; i < 4; i++ ) // Controllers
for( int j = 0; j < SC_TOTAL * 4; j++ ) // Shortcuts
2020-02-09 11:36:49 +00:00
{
DWORD aIDs[3];
aIDs[2] = i * SC_TOTAL + j;
if( !GetButtonID( aIDs, 2, BSET_SHORTCUTS ))
continue; // For not implemented buttons, otherwise the behavior is unsafe
2020-02-09 11:36:49 +00:00
GetButtonText( g_ivConfig->Shortcuts.Player[i].aButtons[j], szBuffer );
SendMessage( GetDlgItem( hDlg, aIDs[1] ), WM_SETTEXT , 0, (LPARAM)szBuffer );
}
DWORD aIDs[3];
aIDs[2] = (DWORD)(-1);
if( GetButtonID( aIDs, 2, BSET_SHORTCUTS ) )
{
GetButtonText( g_ivConfig->Shortcuts.bMouseLock, szBuffer );
SendMessage( GetDlgItem( hDlg, aIDs[1] ), WM_SETTEXT , 0, (LPARAM)szBuffer );
}
CheckDlgButton( hDlg, IDC_SHOWMESSAGES, g_ivConfig->fDisplayShortPop ? BST_CHECKED : BST_UNCHECKED );
return TRUE;
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
BOOL CALLBACK FoldersDialogProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
2020-02-09 11:36:49 +00:00
long i,j;
TCHAR szBuffer[MAX_PATH+1];
TCHAR szApplication[MAX_PATH+1],
*pcSlash;
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
switch(uMsg)
{
case WM_INITDIALOG:
2016-01-27 09:11:59 +00:00
#if defined(HIDEUNIMPLEMENTED) && !defined(V_TRANSFERPAK)
2020-02-09 11:36:49 +00:00
{
RECT rRect, rGBSave;
GetWindowRect( GetDlgItem( hDlg, IDC_GBSAVEPANEL ), &rGBSave );
GetWindowRect( GetDlgItem( hDlg, IDC_MEMPAKPANEL ), &rRect );
int iShift = rRect.bottom - rGBSave.bottom;
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
WINDOWPLACEMENT pos;
pos.length = sizeof(WINDOWPLACEMENT);
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
GetWindowPlacement( GetDlgItem( hDlg, IDOK ), &pos );
pos.rcNormalPosition.top += iShift;
pos.rcNormalPosition.bottom += iShift;
SetWindowPlacement( GetDlgItem( hDlg, IDOK ), &pos );
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
GetWindowPlacement( GetDlgItem( hDlg, IDCANCEL ), &pos );
pos.rcNormalPosition.top += iShift;
pos.rcNormalPosition.bottom += iShift;
SetWindowPlacement( GetDlgItem( hDlg, IDCANCEL ), &pos );
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
GetWindowRect( hDlg, &rRect );
rRect.bottom += iShift;
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
SetWindowPos( hDlg, NULL, rRect.left, rRect.top, rRect.right-rRect.left, rRect.bottom-rRect.top, SWP_NOMOVE | SWP_NOZORDER );
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
int aChilds[] = { IDC_GBROMPANEL, IDC_GBROM_REL, IDC_GBROM_REL_EDIT, IDC_GBROM_BROWSE_REL, IDC_GBROM_ABS,
IDC_GBROM_ABS_EDIT, IDC_GBROM_BROWSE_ABS, IDC_GBSAVEPANEL, IDC_GBSAVE_SAME, IDC_GBSAVE_REL,
IDC_GBSAVE_REL_EDIT, IDC_GBSAVE_BROWSE_REL, IDC_GBSAVE_ABS, IDC_GBSAVE_ABS_EDIT, IDC_GBSAVE_BROWSE_ABS };
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
for( int i = 0; i < sizeof(aChilds)/sizeof(int); ++i )
DestroyWindow( GetDlgItem( hDlg, aChilds[i] ));
}
#pragma message( "unimplemented features from the folder dialog will be removed" )
2016-01-27 09:11:59 +00:00
#endif // #ifdef HIDEUNIMPLEMENTED
2020-02-09 11:36:49 +00:00
GetDirectory( szApplication, DIRECTORY_GBROMS );
GetDirectory( szBuffer, DIRECTORY_GBSAVES );
j = lstrcmp( szApplication, szBuffer );
GetDirectory( szApplication, DIRECTORY_APPLICATION );
i = lstrlen( szApplication );
// Memory pak directory
2020-02-09 11:36:49 +00:00
lstrcpyn(szBuffer, g_aszDefFolders[DIRECTORY_MEMPAK], MAX_PATH);
if( szBuffer[0] != 0 && ( szBuffer[1] == ':' || ( szBuffer[1] == '\\' && szBuffer[0] == '\\' )))
{
CheckDlgButton( hDlg, IDC_MEMPAK_ABS, BST_CHECKED );
GetDirectory( szBuffer, DIRECTORY_MEMPAK );
if( !_tcsncmp( szBuffer, szApplication, i ))
{
TCHAR *pcSub = &szBuffer[i];
pcSlash = _tcsrchr( pcSub, _T('\\') );
if( pcSlash && ( pcSlash[1] == '\0' )) *pcSlash = '\0';
SendMessage( GetDlgItem( hDlg, IDC_MEMPAK_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)pcSub );
}
else
SendMessage( GetDlgItem( hDlg, IDC_MEMPAK_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)STRING_DEF_MEMPAKFILE );
}
else
{
CheckDlgButton( hDlg, IDC_MEMPAK_REL, BST_CHECKED );
if( szBuffer[0] != 0 )
SendMessage( GetDlgItem( hDlg, IDC_MEMPAK_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
else
SendMessage( GetDlgItem( hDlg, IDC_MEMPAK_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)STRING_DEF_MEMPAKFILE );
}
GetDirectory( szBuffer, DIRECTORY_MEMPAK );
pcSlash = _tcsrchr( szBuffer, '\\' );
if( pcSlash && ( pcSlash[1] == '\0' )) *pcSlash = '\0';
SendMessage( GetDlgItem( hDlg, IDC_MEMPAK_ABS_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
// Game Boy ROM directory
2020-02-09 11:36:49 +00:00
lstrcpyn(szBuffer, g_aszDefFolders[DIRECTORY_GBROMS], MAX_PATH);
if( szBuffer[0] != 0 && ( szBuffer[1] == _T(':') || ( szBuffer[1] == _T('\\') && szBuffer[0] == _T('\\') )))
{
CheckDlgButton( hDlg, IDC_GBROM_ABS, BST_CHECKED );
GetDirectory( szBuffer, DIRECTORY_GBROMS );
if( !_tcsncmp( szBuffer, szApplication, i ))
{
TCHAR *pcSub = &szBuffer[i];
pcSlash = _tcsrchr( pcSub, _T('\\') );
if( pcSlash && ( pcSlash[1] == '\0' )) *pcSlash = '\0';
SendMessage( GetDlgItem( hDlg, IDC_GBROM_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
}
else
SendMessage( GetDlgItem( hDlg, IDC_GBROM_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)STRING_DEF_GBROMFILE );
}
else
{
CheckDlgButton( hDlg, IDC_GBROM_REL, BST_CHECKED );
if( szBuffer[0] != 0 )
SendMessage( GetDlgItem( hDlg, IDC_GBROM_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
else
SendMessage( GetDlgItem( hDlg, IDC_GBROM_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)STRING_DEF_GBROMFILE );
}
GetDirectory( szBuffer, DIRECTORY_GBROMS );
pcSlash = _tcsrchr( szBuffer, _T('\\') );
if( pcSlash && ( pcSlash[1] == _T('\0') )) *pcSlash = '\0';
SendMessage( GetDlgItem( hDlg, IDC_GBROM_ABS_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
// Game Boy save directory
2020-02-09 11:36:49 +00:00
lstrcpyn(szBuffer, g_aszDefFolders[DIRECTORY_GBSAVES], MAX_PATH);
if( !j )
{
CheckDlgButton( hDlg, IDC_GBSAVE_SAME, BST_CHECKED );
FoldersDialogProc( hDlg, WM_COMMAND, (WPARAM)MAKELONG( IDC_GBSAVE_SAME, BN_CLICKED ), (LPARAM)GetDlgItem( hDlg, IDC_GBSAVE_SAME ));
SendMessage( GetDlgItem( hDlg, IDC_GBROM_REL_EDIT ), WM_GETTEXT, sizeof(szBuffer), (LPARAM)szBuffer );
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
}
else
{
if( szBuffer[0] != 0 && ( szBuffer[1] == _T(':') || ( szBuffer[1] == _T('\\') && szBuffer[0] == _T('\\') )))
{
CheckDlgButton( hDlg, IDC_GBSAVE_ABS, BST_CHECKED );
GetDirectory( szBuffer, DIRECTORY_GBSAVES );
if( !_tcsncmp( szBuffer, szApplication, i ))
{
TCHAR *pcSub = &szBuffer[i];
pcSlash = _tcsrchr( pcSub, '\\' );
if( pcSlash && ( pcSlash[1] == '\0' )) *pcSlash = '\0';
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
}
else
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)STRING_DEF_GBROMSAVE );
}
else
{
CheckDlgButton( hDlg, IDC_GBSAVE_REL, BST_CHECKED );
if( szBuffer[0] != 0 )
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
else
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)STRING_DEF_GBROMSAVE );
}
}
GetDirectory( szBuffer, DIRECTORY_GBSAVES );
pcSlash = _tcsrchr( szBuffer, _T('\\') );
if( pcSlash && ( pcSlash[1] == _T('\0') )) *pcSlash = '\0';
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_ABS_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
return FALSE; // Don't give it focus
2020-02-09 11:36:49 +00:00
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDC_GBSAVE_ABS:
case IDC_GBSAVE_REL:
EnableWindow( GetDlgItem( hDlg, IDC_GBSAVE_REL_EDIT ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDC_GBSAVE_ABS_EDIT ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDC_GBSAVE_BROWSE_REL ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDC_GBSAVE_BROWSE_ABS ), TRUE );
return TRUE;
case IDC_GBSAVE_SAME:
EnableWindow( GetDlgItem( hDlg, IDC_GBSAVE_REL_EDIT ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_GBSAVE_ABS_EDIT ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_GBSAVE_BROWSE_REL ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_GBSAVE_BROWSE_ABS ), FALSE );
return TRUE;
case IDC_MEMPAK_BROWSE_ABS:
szBuffer[0] = '\0';
if( BrowseFolders( hDlg, NULL, szBuffer ))
SendMessage( GetDlgItem( hDlg, IDC_MEMPAK_ABS_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
return TRUE;
case IDC_GBROM_BROWSE_ABS:
szBuffer[0] = '\0';
if( BrowseFolders( hDlg, NULL, szBuffer ))
SendMessage( GetDlgItem( hDlg, IDC_GBROM_ABS_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
return TRUE;
case IDC_GBSAVE_BROWSE_ABS:
szBuffer[0] = '\0';
if( BrowseFolders( hDlg, NULL, szBuffer ))
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_ABS_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
return TRUE;
case IDC_MEMPAK_BROWSE_REL:
GetDirectory( szApplication, DIRECTORY_APPLICATION );
lstrcpyn( szBuffer, szApplication, ARRAYSIZE(szBuffer) );
if( BrowseFolders( hDlg, NULL, szBuffer ))
{
i = lstrlen( szApplication );
lstrcpyn( szBuffer, &szBuffer[i], ARRAYSIZE(szBuffer) ); // Hack: The lstrcpyn function has an undefined behavior if source and destination buffers overlap
2020-02-09 11:36:49 +00:00
SendMessage( GetDlgItem( hDlg, IDC_MEMPAK_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
}
return TRUE;
case IDC_GBROM_BROWSE_REL:
GetDirectory( szApplication, DIRECTORY_APPLICATION );
lstrcpyn( szBuffer, szApplication, ARRAYSIZE(szBuffer) );
if( BrowseFolders( hDlg, NULL, szBuffer ))
{
i = lstrlen( szApplication );
lstrcpyn( szBuffer, &szBuffer[i], ARRAYSIZE(szBuffer) ); // Hack: The lstrcpyn function has an undefined behavior if source and destination buffers overlap
2020-02-09 11:36:49 +00:00
SendMessage( GetDlgItem( hDlg, IDC_GBROM_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
}
return TRUE;
case IDC_GBSAVE_BROWSE_REL:
GetDirectory( szApplication, DIRECTORY_APPLICATION );
lstrcpyn( szBuffer, szApplication, ARRAYSIZE(szBuffer) );
if( BrowseFolders( hDlg, NULL, szBuffer ))
{
i = lstrlen( szApplication );
lstrcpyn( szBuffer, &szBuffer[i], ARRAYSIZE(szBuffer) ); // Hack: The lstrcpyn function has an undefined behavior if source and destination buffers overlap
2020-02-09 11:36:49 +00:00
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_REL_EDIT ), WM_SETTEXT, 0, (LPARAM)szBuffer );
}
return TRUE;
case IDOK:
if( IsDlgButtonChecked( hDlg, IDC_MEMPAK_ABS ) == BST_CHECKED )
{
SendMessage( GetDlgItem( hDlg, IDC_MEMPAK_ABS_EDIT ), WM_GETTEXT, ARRAYSIZE(szApplication), (LPARAM)szApplication );
GetFullPathName( szApplication, ARRAYSIZE(szBuffer), szBuffer, &pcSlash );
}
else
SendMessage( GetDlgItem( hDlg, IDC_MEMPAK_REL_EDIT ), WM_GETTEXT, ARRAYSIZE(szBuffer), (LPARAM)szBuffer );
pcSlash = _tcsrchr( szBuffer, '\\' );
if( pcSlash && ( pcSlash[1] == '\0' ))
*pcSlash = '\0';
if( !lstrcmp( szBuffer, STRING_DEF_MEMPAKFILE ))
g_aszDefFolders[DIRECTORY_MEMPAK][0] = 0;
else
lstrcpyn(g_aszDefFolders[DIRECTORY_MEMPAK], szBuffer, MAX_PATH);
if( IsDlgButtonChecked( hDlg, IDC_GBROM_ABS ) == BST_CHECKED )
{
SendMessage( GetDlgItem( hDlg, IDC_GBROM_ABS_EDIT ), WM_GETTEXT, ARRAYSIZE(szApplication), (LPARAM)szApplication );
GetFullPathName( szApplication, ARRAYSIZE(szBuffer), szBuffer, &pcSlash );
}
else
SendMessage( GetDlgItem( hDlg, IDC_GBROM_REL_EDIT ), WM_GETTEXT, ARRAYSIZE(szBuffer), (LPARAM)szBuffer );
pcSlash = _tcsrchr( szBuffer, '\\' );
if( pcSlash && ( pcSlash[1] == '\0' )) *pcSlash = '\0';
if( !lstrcmp( szBuffer, STRING_DEF_GBROMFILE ))
g_aszDefFolders[DIRECTORY_GBROMS][0] = 0;
else
lstrcpyn(g_aszDefFolders[DIRECTORY_GBROMS], szBuffer, MAX_PATH);
if( !IsDlgButtonChecked( hDlg, IDC_GBSAVE_SAME ) == BST_CHECKED )
{
if( IsDlgButtonChecked( hDlg, IDC_GBSAVE_ABS ) == BST_CHECKED )
{
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_ABS_EDIT ), WM_GETTEXT, ARRAYSIZE(szApplication), (LPARAM)szApplication );
GetFullPathName( szApplication, ARRAYSIZE(szBuffer), szBuffer, &pcSlash );
}
else
SendMessage( GetDlgItem( hDlg, IDC_GBSAVE_REL_EDIT ), WM_GETTEXT, ARRAYSIZE(szBuffer), (LPARAM)szBuffer );
}
pcSlash = _tcsrchr( szBuffer, _T('\\') );
if( pcSlash && ( pcSlash[1] == '\0' )) *pcSlash = '\0';
if( !lstrcmp( szBuffer, STRING_DEF_GBROMSAVE ))
g_aszDefFolders[DIRECTORY_GBSAVES][0] = 0;
else
lstrcpyn(g_aszDefFolders[DIRECTORY_GBSAVES], szBuffer, MAX_PATH);
EndDialog( hDlg, TRUE );
return TRUE;
case IDCANCEL:
EndDialog( hDlg, FALSE );
return TRUE;
default:
return FALSE; // Unhandled WM_COMMAND
2020-02-09 11:36:49 +00:00
}
default:
return FALSE; // False means the message didn't get processed
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
}
// TODO: Check this for possible removal or updating
// A wonderful n squared algorithm to store the key names in a string
// called by EnumObjects in MainDlgProcess to enumerate the keys on the keyboard
2016-01-27 09:11:59 +00:00
/* BOOL CALLBACK EnumGetKeyDesc( LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef )
{
2020-02-09 11:36:49 +00:00
// REMOVED //
} // I am putting this function out of its misery before it causes more grief. (comment by rabid) */
2016-01-27 09:11:59 +00:00
// ButtonID is where we store an array of 3 DWORDs: ID of pushbutton, ID of text window, and an offset in the button structure controls
2016-01-27 09:11:59 +00:00
// bIndex tells us what information to copy, but in a confusing way
// bButtonSet tells us whether we want the data from the controls array or the shortcuts array below
// This function is confusing, but not much I can do to fix it now. I'm sorry. (comment by rabid)
2016-01-27 09:11:59 +00:00
bool GetButtonID( LPDWORD ButtonID, const BYTE bIndex, const BYTE bButtonSet )
{
// TODO: Check this
// TODO: make these constant, read from a resource or a define, or something...I don't know
2020-02-09 11:36:49 +00:00
LPDWORD ButtonTable = NULL;
int nEntries = 0;
// ID of PushButton ID of TextWindow place in Button-structure
const DWORD Controls[][3] = { { IDC_DRIGHT , IDT_DRIGHT , PF_DPADR }, // Controls
{ IDC_DLEFT , IDT_DLEFT , PF_DPADL },
{ IDC_DDOWN , IDT_DDOWN , PF_DPADD },
{ IDC_DUP , IDT_DUP , PF_DPADU },
{ IDC_SBUTTON , IDT_SBUTTON , PF_START },
{ IDC_ZTRIGGER , IDT_ZTRIGGER , PF_TRIGGERZ },
{ IDC_BBUTTON , IDT_BBUTTON , PF_BBUTTON },
{ IDC_ABUTTON , IDT_ABUTTON , PF_ABUTTON },
{ IDC_CRIGHT , IDT_CRIGHT , PF_CBUTTONR },
{ IDC_CLEFT , IDT_CLEFT , PF_CBUTTONL },
{ IDC_CDOWN , IDT_CDOWN , PF_CBUTTOND },
{ IDC_CUP , IDT_CUP , PF_CBUTTONU },
{ IDC_RIGHTTRIGGER , IDT_RIGHTTRIGGER , PF_TRIGGERR },
{ IDC_LEFTTRIGGER , IDT_LEFTTRIGGER , PF_TRIGGERL },
{ IDC_ARIGHT , IDT_ARIGHT , PF_APADR },
{ IDC_ALEFT , IDT_ALEFT , PF_APADL },
{ IDC_ADOWN , IDT_ADOWN , PF_APADD },
{ IDC_AUP , IDT_AUP , PF_APADU } };
const DWORD Shortcuts[][3]= {
{ IDC_SETNOPAK_P1 , IDC_SETNOPAK_P1 , SC_NOPAK },
{ IDC_SETMEMPAK_P1 , IDC_SETMEMPAK_P1 , SC_MEMPAK },
{ IDC_SETRUMBLEPAK_P1 , IDC_SETRUMBLEPAK_P1 , SC_RUMBPAK },
{ IDC_SETTRANSFERPAK_P1 , IDC_SETTRANSFERPAK_P1 , SC_TRANSPAK },
{ IDC_SETADAPTOIDPAK_P1 , IDC_SETADAPTOIDPAK_P1 , SC_ADAPTPAK },
{ IDC_SWMEMRUMBLE_P1 , IDC_SWMEMRUMBLE_P1 , SC_SWMEMRUMB },
{ IDC_SWMEMADAPTOID_P1 , IDC_SWMEMADAPTOID_P1 , SC_SWMEMADAPT },
{ IDC_SETNOPAK_P2 , IDC_SETNOPAK_P2 , SC_NOPAK + SC_TOTAL },
{ IDC_SETMEMPAK_P2 , IDC_SETMEMPAK_P2 , SC_MEMPAK + SC_TOTAL },
{ IDC_SETRUMBLEPAK_P2 , IDC_SETRUMBLEPAK_P2 , SC_RUMBPAK + SC_TOTAL },
{ IDC_SETTRANSFERPAK_P2 , IDC_SETTRANSFERPAK_P2 , SC_TRANSPAK + SC_TOTAL },
{ IDC_SETADAPTOIDPAK_P2 , IDC_SETADAPTOIDPAK_P2 , SC_ADAPTPAK + SC_TOTAL },
{ IDC_SWMEMRUMBLE_P2 , IDC_SWMEMRUMBLE_P2 , SC_SWMEMRUMB + SC_TOTAL },
{ IDC_SWMEMADAPTOID_P2 , IDC_SWMEMADAPTOID_P2 , SC_SWMEMADAPT + SC_TOTAL },
{ IDC_SETNOPAK_P3 , IDC_SETNOPAK_P3 , SC_NOPAK + SC_TOTAL * 2 },
{ IDC_SETMEMPAK_P3 , IDC_SETMEMPAK_P3 , SC_MEMPAK + SC_TOTAL * 2 },
{ IDC_SETRUMBLEPAK_P3 , IDC_SETRUMBLEPAK_P3 , SC_RUMBPAK + SC_TOTAL * 2 },
{ IDC_SETTRANSFERPAK_P3 , IDC_SETTRANSFERPAK_P3 , SC_TRANSPAK + SC_TOTAL * 2 },
{ IDC_SETADAPTOIDPAK_P3 , IDC_SETADAPTOIDPAK_P3 , SC_ADAPTPAK + SC_TOTAL * 2 },
{ IDC_SWMEMRUMBLE_P3 , IDC_SWMEMRUMBLE_P3 , SC_SWMEMRUMB + SC_TOTAL * 2 },
{ IDC_SWMEMADAPTOID_P3 , IDC_SWMEMADAPTOID_P3 , SC_SWMEMADAPT + SC_TOTAL * 2 },
{ IDC_SETNOPAK_P4 , IDC_SETNOPAK_P4 , SC_NOPAK + SC_TOTAL * 3 },
{ IDC_SETMEMPAK_P4 , IDC_SETMEMPAK_P4 , SC_MEMPAK + SC_TOTAL * 3 },
{ IDC_SETRUMBLEPAK_P4 , IDC_SETRUMBLEPAK_P4 , SC_RUMBPAK + SC_TOTAL * 3 },
{ IDC_SETTRANSFERPAK_P4 , IDC_SETTRANSFERPAK_P4 , SC_TRANSPAK + SC_TOTAL * 3 },
{ IDC_SETADAPTOIDPAK_P4 , IDC_SETADAPTOIDPAK_P4 , SC_ADAPTPAK + SC_TOTAL * 3 },
{ IDC_SWMEMRUMBLE_P4 , IDC_SWMEMRUMBLE_P4 , SC_SWMEMRUMB + SC_TOTAL * 3 },
{ IDC_SWMEMADAPTOID_P4 , IDC_SWMEMADAPTOID_P4 , SC_SWMEMADAPT + SC_TOTAL * 3 },
{ IDC_LOCKMOUSE , IDC_LOCKMOUSE , (DWORD)(-1) }
};
if( bButtonSet == BSET_CONTROLS )
{
ButtonTable = (LPDWORD)Controls; // TODO: Hack: what an ugly solution, using a cast like that
2020-02-09 11:36:49 +00:00
nEntries = ARRAYSIZE( Controls );
}
if( bButtonSet == BSET_SHORTCUTS )
{
ButtonTable = (LPDWORD)Shortcuts;
nEntries = ARRAYSIZE( Shortcuts );
}
bool bReturn = false;
// TODO: Fix this! Just use 2 dimensional arrays?
2020-02-09 11:36:49 +00:00
if( ButtonTable != NULL )
{
nEntries *= 3;
for( int i = 0; i < nEntries; i+=3 )
{
if( ButtonTable[i+bIndex] == ButtonID[bIndex] )
{
ButtonID[0] = ButtonTable[i+0];
ButtonID[1] = ButtonTable[i+1];
ButtonID[2] = ButtonTable[i+2];
bReturn = true;
break;
}
}
}
return bReturn;
2016-01-27 09:11:59 +00:00
}
// A text munging routine to spit out what PC control was assigned to a button
2016-01-27 09:11:59 +00:00
bool GetButtonText( const BUTTON& btnButton, LPTSTR Buffer )
{
2020-02-09 11:36:49 +00:00
const UINT iDevice[] ={ IDS_BUTTON_UNASSIGNED,
IDS_C_GAMEPAD,
IDS_C_KEYBOARD,
IDS_C_MOUSE };
const UINT iGamepad[] ={ IDS_C_XAXIS,
IDS_C_YAXIS,
IDS_C_ZAXIS,
IDS_C_XROT,
IDS_C_YROT,
IDS_C_ZROT,
IDS_C_SLIDER,
IDS_C_SLIDER,
IDS_C_POV,
IDS_C_POV,
IDS_C_POV,
IDS_C_POV,
IDS_C_BUTTON };
const UINT iMouse[] = { IDS_C_XAXIS,
IDS_C_YAXIS,
IDS_C_WHEEL,
IDS_C_BUTTON };
const LPTSTR AxeID[] = { TEXT( " +" ),
TEXT( " -" ),
TEXT( " /\\" ),
TEXT( " >" ),
TEXT( " \\/" ),
TEXT( " <" ) };
TCHAR a[16], b[16], buff[16]; // We have to allocate the space, stack is easier than P_malloc
2020-02-09 11:36:49 +00:00
TCHAR Btn[6];
LPTSTR Text[] = {a, b, NULL };
bool bReturn = true;
DIDEVICEOBJECTINSTANCE didoi;
didoi.dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
switch ( btnButton.bBtnType )
{
case DT_JOYBUTTON:
LoadString( g_hResourceDLL, iDevice[1], Text[0], 16 );
LoadString( g_hResourceDLL, iGamepad[12], Text[1], 16 );
Text[2] = Btn;
wsprintf( Btn, TEXT( "%02u" ), btnButton.bOffset );
break;
case DT_JOYAXE:
LoadString( g_hResourceDLL, iDevice[1], Text[0], 16 );
LoadString( g_hResourceDLL, iGamepad[btnButton.bOffset], Text[1], 16 );
Text[2] = AxeID[btnButton.bAxisID];
break;
case DT_JOYSLIDER:
LoadString( g_hResourceDLL, iDevice[1], Text[0], 16 );
LoadString( g_hResourceDLL, iGamepad[btnButton.bOffset], buff, 16 );
wsprintf(Text[1], buff, btnButton.bOffset - 5 );
Text[2] = AxeID[btnButton.bAxisID];
case DT_JOYPOV:
LoadString( g_hResourceDLL, iDevice[1], Text[0], 16 );
LoadString( g_hResourceDLL, iGamepad[btnButton.bOffset], buff, 16 );
wsprintf(Text[1], buff, btnButton.bOffset - 7 );
Text[2] = AxeID[2 + btnButton.bAxisID];
break;
case DT_KEYBUTTON:
LoadString( g_hResourceDLL, iDevice[2], Text[0], 16 );
// TODO: This is great! Can we do this for all of them?
2020-02-09 11:36:49 +00:00
if (btnButton.parentDevice->didHandle->GetObjectInfo(&didoi, btnButton.bOffset, DIPH_BYOFFSET) == DI_OK)
Text[1] = didoi.tszName;
else
LoadString( g_hResourceDLL, IDS_C_UNKNOWN, Text[1], 16 );
Text[2] = TEXT( "" );
break;
case DT_MOUSEBUTTON:
LoadString( g_hResourceDLL, iDevice[3], Text[0], 16 );
LoadString( g_hResourceDLL, iMouse[3], Text[1], 16 );
Text[2] = Btn;
wsprintf( Btn, TEXT( "%02u" ), btnButton.bOffset );
break;
case DT_MOUSEAXE:
LoadString( g_hResourceDLL, iDevice[3], Text[0], 16 );
LoadString( g_hResourceDLL, iMouse[btnButton.bOffset], Text[1], 16 );
Text[2] = AxeID[btnButton.bAxisID];
break;
case DT_UNASSIGNED:
default:
LoadString( g_hResourceDLL, iDevice[0], Text[0], 16 );
Text[1] = Text[2] = TEXT( "" );
bReturn = false;
}
wsprintf( Buffer, TEXT( "%s%s%s" ), Text[0], Text[1], Text[2] );
return ( bReturn );
2016-01-27 09:11:59 +00:00
}
// Called when scanning devices to assign N64 buttons
2016-01-27 09:11:59 +00:00
DWORD ScanKeyboard( LPDEVICE lpDevice, LPDWORD lpdwCounter, LPBUTTON pButton )
{
2020-02-09 11:36:49 +00:00
HRESULT hr;
BYTE cKeys[256];
hr = lpDevice->didHandle->GetDeviceState( sizeof( cKeys ), (LPVOID)&cKeys );
if ( FAILED(hr) )
{
lpDevice->didHandle->Acquire();
return FALSE;
}
int iGotKey = FALSE;
int i = 0;
for( i = 0; i < ARRAYSIZE( cKeys ); ++i )
{
if (( cKeys[i] & 0x80 ) )
{
if( i == DIK_ESCAPE )
iGotKey = SC_SCANESCAPE;
else
{
iGotKey = SC_SCANSUCCEED;
pButton->bBtnType = (BYTE)DT_KEYBUTTON;
pButton->bAxisID = (BYTE)0;
pButton->bOffset = (BYTE)i;
pButton->parentDevice = lpDevice;
}
}
}
return iGotKey;
2016-01-27 09:11:59 +00:00
}
// Called when scanning devices to assign N64 buttons
2016-01-27 09:11:59 +00:00
DWORD ScanMouse( LPDEVICE lpDevice, LPDWORD lpdwCounter, LPBUTTON pButton )
{
2020-02-09 11:36:49 +00:00
static BYTE rgbInitButtons[8];
static bool bFirstScan = true;
DIMOUSESTATE2 dm_Current;
HRESULT hr;
if ( *lpdwCounter == 0 )
bFirstScan = true;
hr = lpDevice->didHandle->GetDeviceState( sizeof(DIMOUSESTATE2), &dm_Current );
if ( FAILED(hr) )
{
lpDevice->didHandle->Acquire();
return FALSE;
}
if ( bFirstScan )
{
CopyMemory( rgbInitButtons, dm_Current.rgbButtons, sizeof(rgbInitButtons));
bFirstScan = false;
lpDevice->didHandle->GetDeviceState( sizeof(DIMOUSESTATE2), &dm_Current );
}
int iGotKey = FALSE;
int i = 0;
BYTE bAxeDirection = 0;
long Mouse[] ={ FIELD_OFFSET( DIMOUSESTATE2, lX ) / sizeof(long),
FIELD_OFFSET( DIMOUSESTATE2, lY ) / sizeof(long),
FIELD_OFFSET( DIMOUSESTATE2, lZ ) / sizeof(long) };
long lValue;
for( i = 0; i < ARRAYSIZE(Mouse); ++i )
{
lValue = ((long*)&dm_Current)[Mouse[i]];
if( lValue > MOUSE_THRESHOLD )
{
iGotKey = SC_SCANSUCCEED;
bAxeDirection = AI_AXE_P;
}
if( lValue < -MOUSE_THRESHOLD )
{
iGotKey = SC_SCANSUCCEED;
bAxeDirection = AI_AXE_N;
}
if( iGotKey )
break;
}
if( iGotKey == SC_SCANSUCCEED )
{
pButton->bBtnType = (BYTE)DT_MOUSEAXE;
pButton->bAxisID = (BYTE)bAxeDirection;
pButton->bOffset = (BYTE)Mouse[i];
pButton->parentDevice = lpDevice;
}
else
{
for( i = 0; i < ARRAYSIZE( dm_Current.rgbButtons ); ++i )
{
if(( dm_Current.rgbButtons[i] != rgbInitButtons[i] ) && ( dm_Current.rgbButtons[i] & 0x80 ))
{
iGotKey = SC_SCANSUCCEED;
pButton->bBtnType = (BYTE)DT_MOUSEBUTTON;
pButton->bAxisID = (BYTE)0;
pButton->bOffset = (BYTE)i;
pButton->parentDevice = lpDevice;
break;
}
}
}
CopyMemory( rgbInitButtons, dm_Current.rgbButtons, sizeof(rgbInitButtons));
return iGotKey;
2016-01-27 09:11:59 +00:00
}
// Called when scanning devices to assign N64 buttons
// Tries to read any possible button presses or axes from lpDirectInputDevice; called by ScanDevices
2016-01-27 09:11:59 +00:00
DWORD ScanGamePad ( LPDEVICE lpDevice, LPDWORD lpdwCounter, LPBUTTON pButton, int iDeviceNumber )
{
2020-02-09 11:36:49 +00:00
static DIJOYSTATE dj_Initial[MAX_DEVICES];
static bool bFirstScan = true;
HRESULT hr;
if ( *lpdwCounter == 0 )
bFirstScan = true;
hr = lpDevice->didHandle->GetDeviceState( sizeof(DIJOYSTATE), &lpDevice->stateAs.joyState );
if ( FAILED(hr) )
{
hr = lpDevice->didHandle->Acquire();
return FALSE;
}
if ( bFirstScan )
{
dj_Initial[iDeviceNumber] = lpDevice->stateAs.joyState;
bFirstScan = false;
return FALSE; // Initial scan done; we have to wait until next time
2020-02-09 11:36:49 +00:00
}
long lAxePos = ZEROVALUE + ( RANGERELATIVE * CONFIGTHRESHOLD / 100 );
long lAxeNeg = ZEROVALUE - ( RANGERELATIVE * CONFIGTHRESHOLD / 100 );
long lValue;
int iGotKey = FALSE;
BYTE bAxeDirection = 0;
int JoyPad[][2] ={ { FIELD_OFFSET( DIJOYSTATE, lX ) / sizeof(long) , DT_JOYAXE },
{ FIELD_OFFSET( DIJOYSTATE, lY ) / sizeof(long) , DT_JOYAXE },
{ FIELD_OFFSET( DIJOYSTATE, lZ ) / sizeof(long) , DT_JOYAXE },
{ FIELD_OFFSET( DIJOYSTATE, lRx ) / sizeof(long) , DT_JOYAXE },
{ FIELD_OFFSET( DIJOYSTATE, lRy ) / sizeof(long) , DT_JOYAXE },
{ FIELD_OFFSET( DIJOYSTATE, lRz ) / sizeof(long) , DT_JOYAXE },
{ FIELD_OFFSET( DIJOYSTATE, rglSlider[0] ) / sizeof(long) , DT_JOYSLIDER },
{ FIELD_OFFSET( DIJOYSTATE, rglSlider[1] ) / sizeof(long) , DT_JOYSLIDER },
{ FIELD_OFFSET( DIJOYSTATE, rgdwPOV[0] ) / sizeof(long) , DT_JOYPOV },
{ FIELD_OFFSET( DIJOYSTATE, rgdwPOV[1] ) / sizeof(long) , DT_JOYPOV },
{ FIELD_OFFSET( DIJOYSTATE, rgdwPOV[2] ) / sizeof(long) , DT_JOYPOV },
{ FIELD_OFFSET( DIJOYSTATE, rgdwPOV[3] ) / sizeof(long) , DT_JOYPOV } };
int i;
for( i = 0; i < ARRAYSIZE( JoyPad ); ++i )
{
lValue = ((long*)&lpDevice->stateAs.joyState)[JoyPad[i][0]];
if( lValue != ((long*)&(dj_Initial[iDeviceNumber]))[JoyPad[i][0]] )
{
if(( JoyPad[i][1] == DT_JOYAXE ) || ( JoyPad[i][1] == DT_JOYSLIDER ))
{
if( lValue - ((long*)&(dj_Initial[iDeviceNumber]))[JoyPad[i][0]] > lAxePos )
{
iGotKey = SC_SCANSUCCEED;
bAxeDirection = AI_AXE_P;
break;
}
else if( lValue - ((long*)&(dj_Initial[iDeviceNumber]))[JoyPad[i][0]] < lAxeNeg )
{
iGotKey = SC_SCANSUCCEED;
bAxeDirection = AI_AXE_N;
break;
}
}
if( JoyPad[i][1] == DT_JOYPOV && LOWORD( lValue ) != 0xFFFF )
{
iGotKey = SC_SCANSUCCEED;
if (( lValue > 31500 ) || ( lValue < 4500 ))
bAxeDirection = AI_POV_UP;
if (( lValue > 4500 ) && ( lValue < 13500 ))
bAxeDirection = AI_POV_RIGHT;
if (( lValue > 13500 ) && ( lValue < 22500 ))
bAxeDirection = AI_POV_DOWN;
if (( lValue > 22500 ) && ( lValue < 31500 ))
bAxeDirection = AI_POV_LEFT;
break;
}
}
}
if( iGotKey == SC_SCANSUCCEED )
{
pButton->bBtnType = (BYTE)JoyPad[i][1];
pButton->bAxisID = (BYTE)bAxeDirection;
pButton->bOffset = (BYTE)JoyPad[i][0];
pButton->parentDevice = lpDevice;
}
else
{
for( i = 0; i < ARRAYSIZE( lpDevice->stateAs.joyState.rgbButtons ); ++i )
{
if (( lpDevice->stateAs.joyState.rgbButtons[i] & 0x80 ))
{
iGotKey = SC_SCANSUCCEED;
pButton->bBtnType = (BYTE)DT_JOYBUTTON;
pButton->bAxisID = (BYTE)0;
pButton->bOffset = (BYTE)i;
pButton->parentDevice = lpDevice;
break;
}
}
}
return iGotKey;
2016-01-27 09:11:59 +00:00
}
// Called when we assign a control to an N64 button
// Returns FALSE if no key scans recorded, SC_SCANESCAPE if escape pressed on keyboard (to abort), or SC_SUCCEED for a good read
2016-01-27 09:11:59 +00:00
// *apDirectInputDevices is an array of only 2 devices; sys keyboard, sys mouse
DWORD ScanDevices( LPDWORD lpdwCounter, LPBUTTON pButton )
{
// Do all our polling first, this ensures consistency (i.e. every device always gets polled at same interval)
2020-02-09 11:36:49 +00:00
/* if( g_sysKeyboard.didHandle )
{
if( FAILED(g_sysKeyboard.didHandle->Poll()))
g_sysKeyboard.didHandle->Acquire();
} */
if( g_sysMouse.didHandle )
{
if( FAILED(g_sysMouse.didHandle->Poll()))
g_sysMouse.didHandle->Acquire();
}
for (int i = 0; i < g_nDevices; i++)
if (g_devList[i].didHandle)
if (FAILED(g_devList[i].didHandle->Poll()))
g_devList[i].didHandle->Acquire();
// While we have devices to scan,
// if it's a keyboard, ScanKeyboard; if it's a mouse, ScanMouse;
// otherwise ScanGamePad
2020-02-09 11:36:49 +00:00
DWORD dwReturn = FALSE;
// if( !dwReturn && g_sysKeyboard.didHandle )
// dwReturn = ScanKeyboard( &g_sysKeyboard, lpdwCounter, pButton );
if( !dwReturn && g_sysMouse.didHandle )
dwReturn = ScanMouse( &g_sysMouse, lpdwCounter, pButton );
// ScanGamePad on all remaining devices
2020-02-09 11:36:49 +00:00
for (int i = 0; !dwReturn && i < g_nDevices; i++)
if (g_devList[i].didHandle)
{
switch (LOBYTE(g_devList[i].dwDevType))
{
case DI8DEVTYPE_KEYBOARD:
dwReturn = ScanKeyboard( &g_devList[i], lpdwCounter, pButton );
break;
case DI8DEVTYPE_MOUSE:
dwReturn = ScanMouse( &g_devList[i], lpdwCounter, pButton );
break;
default:
dwReturn = ScanGamePad( &g_devList[i], lpdwCounter, pButton, i );
}
}
return dwReturn;
2016-01-27 09:11:59 +00:00
}
// Sets controller defaults; called when user clicks on "Clear Controller" or "Default Config"
// Also called before loading stuff from the INI or from profile files, in case something isn't defined
// Defaults to not connected. Make sure you "connect" the first controller manually.
2016-01-27 09:11:59 +00:00
void SetControllerDefaults( LPCONTROLLER pcController )
{
2020-02-09 11:36:49 +00:00
freePakData( pcController );
freeModifiers( pcController );
ZeroMemory( pcController, sizeof(CONTROLLER) );
pcController->fRawData = true;
pcController->fRealN64Range = true;
pcController->bRapidFireEnabled = false;
pcController->bRapidFireRate = 3; // Set default rapid fire rate here
pcController->bStickRange = DEFAULT_STICKRANGE;
pcController->bPadDeadZone = DEFAULT_DEADZONE;
pcController->bRumbleTyp = DEFAULT_RUMBLETYP;
pcController->bRumbleStrength = DEFAULT_RUMBLESTRENGTH;
pcController->wMouseSensitivityX = DEFAULT_MOUSESENSIVITY;
pcController->wMouseSensitivityY = DEFAULT_MOUSESENSIVITY;
pcController->PakType = DEFAULT_PAKTYPE;
pcController->bMouseMoveX = DEFAULT_MOUSEMOVE;
pcController->bMouseMoveY = DEFAULT_MOUSEMOVE;
2016-01-27 09:11:59 +00:00
}
void DeleteControllerSettings( int indexController )
{
2020-02-09 11:36:49 +00:00
if( !g_ivConfig )
return;
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
SetControllerDefaults( &g_ivConfig->Controllers[indexController] );
g_ivConfig->FFDevices[indexController].bProductCounter = 0;
g_ivConfig->FFDevices[indexController].szProductName[0] = _T('\0');
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
return;
2016-01-27 09:11:59 +00:00
}
// SetModifier activates certain "always on" Config modifiers after they've been inserted or loaded
void SetModifier( LPCONTROLLER pcController )
{
2020-02-09 11:36:49 +00:00
for( int i = 0; i < pcController->nModifiers; i++ )
{
if( pcController->pModifiers[i].bModType == MDT_CONFIG && pcController->pModifiers[i].fStatus )
{
MODSPEC_CONFIG args;
args.dwValue = pcController->pModifiers[i].dwSpecific;
if( args.fChangeAnalogConfig )
{
BYTE bConfig = (BYTE)args.fAnalogStickMode;
if( bConfig < PF_AXESETS )
pcController->bAxisSet = bConfig;
else
{
if( pcController->bAxisSet == PF_AXESETS-1 )
pcController->bAxisSet = 0;
else
++pcController->bAxisSet;
}
}
if( args.fChangeMouseXAxis )
if (pcController->bMouseMoveX == MM_BUFF)
pcController->bMouseMoveX = MM_ABS;
else if (pcController->bMouseMoveX == MM_ABS)
pcController->bMouseMoveX = MM_BUFF;
if( args.fChangeMouseYAxis )
if (pcController->bMouseMoveY == MM_BUFF)
pcController->bMouseMoveY = MM_ABS;
else if (pcController->bMouseMoveY == MM_ABS)
pcController->bMouseMoveY = MM_BUFF;
if( args.fChangeKeyboardXAxis )
pcController->fKeyAbsoluteX = !pcController->fKeyAbsoluteX;
if( args.fChangeKeyboardYAxis )
pcController->fKeyAbsoluteY = !pcController->fKeyAbsoluteY;
}
}
2016-01-27 09:11:59 +00:00
}
// Copies over the existing g_pcControllers' idea of configuration over to the interface.
void GetCurrentConfiguration()
{
2020-02-09 11:36:49 +00:00
EnterCriticalSection( &g_critical );
g_ivConfig->Language = g_strEmuInfo.Language;
g_ivConfig->fDisplayShortPop = g_strEmuInfo.fDisplayShortPop;
LPCONTROLLER pcController;
for( int i = 0; i < 4; i++ )
{
pcController = &g_ivConfig->Controllers[i];
CopyMemory( pcController, &g_pcControllers[i], sizeof(CONTROLLER));
if( pcController->nModifiers > 0 )
{
pcController->pModifiers = (LPMODIFIER)P_malloc( sizeof(MODIFIER) * pcController->nModifiers );
CopyMemory( pcController->pModifiers, g_pcControllers[i].pModifiers, sizeof(MODIFIER) * pcController->nModifiers );
SetModifier( pcController );
}
else
pcController->pModifiers = NULL;
pcController->pPakData = NULL;
for( int iDevice = 0; iDevice < ARRAYSIZE(g_devList) && g_devList[iDevice].dwDevType; ++iDevice )
{
if( g_devList[iDevice].guidInstance == pcController->guidFFDevice )
{
g_ivConfig->FFDevices[i].bProductCounter = g_devList[iDevice].bProductCounter;
lstrcpyn( g_ivConfig->FFDevices[i].szProductName, g_devList[iDevice].szProductName, MAX_PATH );
break;
}
}
}
LeaveCriticalSection( &g_critical );
return;
2016-01-27 09:11:59 +00:00
}
// Copies over the interface's idea of configuration over to g_pcControllers.
void UpdateControllerStructures()
{
2020-02-09 11:36:49 +00:00
// bDebug = g_ivConfig->bAutoConfig;
EnterCriticalSection( &g_critical );
2016-01-27 09:11:59 +00:00
2020-02-09 11:36:49 +00:00
g_iFirstController = -1;
2016-01-27 09:11:59 +00:00
#ifdef _UNICODE
// Might as well use this time to copy over language info and open the new DLL as well (comment by rabid)
2020-02-09 11:36:49 +00:00
g_strEmuInfo.Language = g_ivConfig->Language;
if (g_hResourceDLL != g_strEmuInfo.hinst)
FreeLibrary(g_hResourceDLL);
g_hResourceDLL = LoadLanguageDLL(g_strEmuInfo.Language);
if( g_hResourceDLL == NULL )
{
g_strEmuInfo.Language = 0;
g_hResourceDLL = g_strEmuInfo.hinst;
DebugWriteA("Couldn't load language DLL, falling back to defaults\n");
2020-02-09 11:36:49 +00:00
}
2016-01-27 09:11:59 +00:00
#endif // #ifdef _UNICODE
2020-02-09 11:36:49 +00:00
g_strEmuInfo.fDisplayShortPop = g_ivConfig->fDisplayShortPop;
LPCONTROLLER pcController;
for( int i = 3; i >= 0; i-- )
{
pcController = &g_ivConfig->Controllers[i];
SaveControllerPak( i );
CloseControllerPak( i );
// freePakData( &g_pcControllers[i] ); // Called already by CloseControllerPak
2020-02-09 11:36:49 +00:00
freeModifiers( &g_pcControllers[i] );
CopyMemory( &g_pcControllers[i], pcController, sizeof(CONTROLLER));
g_pcControllers[i].pPakData = NULL;
g_pcControllers[i].pModifiers = NULL;
if( g_pcControllers[i].nModifiers > 0 )
{
g_pcControllers[i].pModifiers = (LPMODIFIER)P_malloc( sizeof(MODIFIER) * g_pcControllers[i].nModifiers );
CopyMemory( g_pcControllers[i].pModifiers, pcController->pModifiers, sizeof(MODIFIER) * g_pcControllers[i].nModifiers );
SetModifier( &g_pcControllers[i] );
}
int iDevice = FindDeviceinList( g_ivConfig->FFDevices[i].szProductName, g_ivConfig->FFDevices[i].bProductCounter, true );
if( iDevice != -1 && g_devList[iDevice].bEffType )
{
g_pcControllers[i].guidFFDevice = g_devList[iDevice].guidInstance;
}
else
{
g_pcControllers[i].guidFFDevice = GUID_NULL;
}
g_pcControllers[i].fPakCRCError = false;
g_pcControllers[i].fPakInitialized = false;
if (g_pcControllers[i].fPlugged)
g_iFirstController = i;
}
LeaveCriticalSection( &g_critical );
return;
2016-01-27 09:11:59 +00:00
}
LRESULT CALLBACK BlockerProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
2020-02-09 11:36:49 +00:00
PAINTSTRUCT ps;
switch (msg)
{
case WM_CREATE:
return 0;
case WM_PAINT:
BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
// return 0;
2016-01-27 09:11:59 +00:00
}
BOOL InitOverlay(void)
{
// Registers our overlay class
2016-01-27 09:11:59 +00:00
WNDCLASS wc;
// Fill in the window class structure with parameters
// that describe the main window.
wc.style = 0;
wc.lpfnWndProc = BlockerProc; // Window procedure
wc.cbClsExtra = 0; // No extra class memory
wc.cbWndExtra = 0; // No extra window memory
2016-01-27 09:11:59 +00:00
wc.hInstance = g_strEmuInfo.hinst;
wc.hIcon = 0;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = _T("BlockerClass"); // Name of window class
2016-01-27 09:11:59 +00:00
// Register the window class
2016-01-27 09:11:59 +00:00
return RegisterClass(&wc);
}
HWND MakeOverlay()
{
2020-02-09 11:36:49 +00:00
HWND hwnd;
RECT size;
GetWindowRect(g_hMainDialog, &size);
// Create the main window.
hwnd = CreateWindowEx(
WS_EX_TOPMOST | WS_EX_TRANSPARENT,
_T("BlockerClass"),
_T("Blocker"),
WS_POPUP,
size.left, // Horizontal position
size.top, // Vertical position
size.right - size.left, // Width
size.bottom - size.top, // Height
g_hMainDialog, // Owner window
(HMENU) NULL, // Menu
g_strEmuInfo.hinst, // Handle to application instance
(LPVOID) NULL // Window creation data
2020-02-09 11:36:49 +00:00
);
if (!hwnd)
return NULL;
// Show the window (necessary to block input)
ShowWindow(hwnd, SW_SHOWNOACTIVATE);
return hwnd;
2016-01-27 09:11:59 +00:00
}